2
* This file is subject to the terms and conditions of the GNU General
3
* Public License. See the file "COPYING" in the main directory of
4
* this archive for more details.
7
#include "xc_private.h"
10
#define SUSPEND_LOCK_FILE "/var/lib/xen/suspend_evtchn_lock.d"
11
static int lock_suspend_event(void)
18
fd = open(SUSPEND_LOCK_FILE, O_CREAT | O_EXCL | O_RDWR, 0666);
21
ERROR("Can't create lock file for suspend event channel\n");
25
snprintf(buf, sizeof(buf), "%10ld", (long)getpid());
27
rc = write_exact(fd, buf, strlen(buf));
33
static int unlock_suspend_event(void)
38
fd = open(SUSPEND_LOCK_FILE, O_RDWR);
43
n = read(fd, buf, 127);
49
sscanf(buf, "%d", &pid);
50
/* We are the owner, so we can simply delete the file */
53
unlink(SUSPEND_LOCK_FILE);
61
int xc_await_suspend(int xce, int suspend_evtchn)
66
rc = xc_evtchn_pending(xce);
68
ERROR("error polling suspend notification channel: %d", rc);
71
} while (rc != suspend_evtchn);
73
/* harmless for one-off suspend */
74
if (xc_evtchn_unmask(xce, suspend_evtchn) < 0)
75
ERROR("failed to unmask suspend notification channel: %d", rc);
80
int xc_suspend_evtchn_release(int xce, int suspend_evtchn)
82
if (suspend_evtchn >= 0)
83
xc_evtchn_unbind(xce, suspend_evtchn);
85
return unlock_suspend_event();
88
int xc_suspend_evtchn_init(int xc, int xce, int domid, int port)
90
int rc, suspend_evtchn = -1;
92
if (lock_suspend_event())
95
suspend_evtchn = xc_evtchn_bind_interdomain(xce, domid, port);
96
if (suspend_evtchn < 0) {
97
ERROR("failed to bind suspend event channel: %d", suspend_evtchn);
101
rc = xc_domain_subscribe_for_suspend(xc, domid, port);
103
ERROR("failed to subscribe to domain: %d", rc);
107
/* event channel is pending immediately after binding */
108
xc_await_suspend(xce, suspend_evtchn);
110
return suspend_evtchn;
113
if (suspend_evtchn != -1)
114
xc_suspend_evtchn_release(xce, suspend_evtchn);