Files
xen/tools/libxc/xc_suspend.c
T
Ian Campbell 6993e9f5ce # HG changeset patch
# User Ian Campbell <ian.campbell@citrix.com>
# Date 1282671421 -3600
# Node ID d1dd29a470ef1b9d2c77478a123326036dfe90bb
# Parent  d7a4adad9c328decbd384d87b23001aea8951b86
tools/libxc, tools/libelf: Relicense under LGPL v2.1

Relicense these two libraries under LGPL v2.1 only except where
individual files already included the "or later" provision.

Copyright holders have been contacted by Stephen Spector and have all
agreed this change.

Removed tools/libxc/ia64/aclinux.h since it appeared to be
unused. There is a separate, more up to date, copy in
xen/include/acpi/platform/aclinux.h which does appear to be used.

Clarify the license of MiniOS privcmd.h under the same terms as other
tools/include/xen-sys headers.

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
Acked-by: Stephen Spector <stephen.spector@citrix.com>
Signed-off-by: Ian Jackson <ian.jackson@eu.citrix.com>
2010-08-24 18:42:59 +01:00

135 lines
3.4 KiB
C

/*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "xc_private.h"
#include "xenguest.h"
#define SUSPEND_LOCK_FILE "/var/lib/xen/suspend_evtchn"
static int lock_suspend_event(xc_interface *xch, int domid)
{
int fd, rc;
mode_t mask;
char buf[128];
char suspend_file[256];
snprintf(suspend_file, sizeof(suspend_file), "%s_%d_lock.d",
SUSPEND_LOCK_FILE, domid);
mask = umask(022);
fd = open(suspend_file, O_CREAT | O_EXCL | O_RDWR, 0666);
if (fd < 0)
{
ERROR("Can't create lock file for suspend event channel %s\n",
suspend_file);
return -EINVAL;
}
umask(mask);
snprintf(buf, sizeof(buf), "%10ld", (long)getpid());
rc = write_exact(fd, buf, strlen(buf));
close(fd);
return rc;
}
static int unlock_suspend_event(xc_interface *xch, int domid)
{
int fd, pid, n;
char buf[128];
char suspend_file[256];
snprintf(suspend_file, sizeof(suspend_file), "%s_%d_lock.d",
SUSPEND_LOCK_FILE, domid);
fd = open(suspend_file, O_RDWR);
if (fd < 0)
return -EINVAL;
n = read(fd, buf, 127);
close(fd);
if (n > 0)
{
sscanf(buf, "%d", &pid);
/* We are the owner, so we can simply delete the file */
if (pid == getpid())
{
unlink(suspend_file);
return 0;
}
}
return -EPERM;
}
int xc_await_suspend(xc_interface *xch, int xce, int suspend_evtchn)
{
int rc;
do {
rc = xc_evtchn_pending(xce);
if (rc < 0) {
ERROR("error polling suspend notification channel: %d", rc);
return -1;
}
} while (rc != suspend_evtchn);
/* harmless for one-off suspend */
if (xc_evtchn_unmask(xce, suspend_evtchn) < 0)
ERROR("failed to unmask suspend notification channel: %d", rc);
return 0;
}
int xc_suspend_evtchn_release(xc_interface *xch, int xce, int domid, int suspend_evtchn)
{
if (suspend_evtchn >= 0)
xc_evtchn_unbind(xce, suspend_evtchn);
return unlock_suspend_event(xch, domid);
}
int xc_suspend_evtchn_init(xc_interface *xch, int xce, int domid, int port)
{
int rc, suspend_evtchn = -1;
if (lock_suspend_event(xch, domid))
return -EINVAL;
suspend_evtchn = xc_evtchn_bind_interdomain(xce, domid, port);
if (suspend_evtchn < 0) {
ERROR("failed to bind suspend event channel: %d", suspend_evtchn);
goto cleanup;
}
rc = xc_domain_subscribe_for_suspend(xch, domid, port);
if (rc < 0) {
ERROR("failed to subscribe to domain: %d", rc);
goto cleanup;
}
/* event channel is pending immediately after binding */
xc_await_suspend(xch, xce, suspend_evtchn);
return suspend_evtchn;
cleanup:
if (suspend_evtchn != -1)
xc_suspend_evtchn_release(xch, xce, domid, suspend_evtchn);
return -1;
}