Files
xen/tools/libxc/xc_suspend.c
T
Ian Campbell 443701ef0c Replace FSF street address with canonical URL
As recommended in http://www.gnu.org/licenses/gpl-howto.en.html.

This is the result of:
$ git grep -El Mass\|Temple\|Franklin | xargs ./fsf.pl

Where fsf.pl is:
    #!/usr/bin/perl -w -pi.bak -0777
    my $repl = 'If not, see <http://www.gnu.org/licenses/>.';
    my $br = qr/(?:\s*\n\s*(?:[\*\#]|\/\/|\.\\" )?\s*|\s+)/;

    my $inwt = qr/[Ii]f${br}not,${br}write${br}(?:to${br})?the${br}Free${br}Software${br}Foundation,(?:${br}Inc\.,)?/;

    my $mass = qr/675${br}Mass${br}Ave,?${br}Cambridge,?${br}MA${br}02139,?${br}USA,?\.?/;
    my $franklin = qr/51${br}Franklin${br}St(?:reet)?(?:,${br}| - )Fifth${br}Floor,?${br}Boston,?${br}MA,?${br}02110-1301,?${br}USA,?\.?/;
    my $temple = qr/59${br}Temple${br}Place(?:,${br}| - )Suite${br}330,?${br}Boston,?${br}MA,?${br}021110?-1307,?${br}USA,?\.?/;

    s|$inwt$br$mass|$repl|m;
    s|$inwt$br$franklin|$repl|m;
    s|$inwt$br$temple|$repl|m;

The only remaining mentions of these addresses are in COPYING files which I
haven't touched.

Some of the changed files are imports from elsewhere, however
filtering them out is tricky, I think it is tolerable to have these
files be modified here and then perhaps reverted on the next sync,
since it's only 1-2 lines and obvious what is going on.

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
2015-07-29 11:14:07 +01:00

201 lines
4.9 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, see <http://www.gnu.org/licenses/>.
*/
#include <unistd.h>
#include <fcntl.h>
#include "xc_private.h"
#include "xenguest.h"
#define SUSPEND_LOCK_FILE XEN_RUN_DIR "/suspend-evtchn-%d.lock"
/*
* locking
*/
#define ERR(x) do{ \
ERROR("Can't " #x " lock file for suspend event channel %s: %s\n", \
suspend_file, strerror(errno)); \
goto err; \
}while(0)
#define SUSPEND_FILE_BUFLEN (sizeof(SUSPEND_LOCK_FILE) + 10)
static void get_suspend_file(char buf[], int domid)
{
snprintf(buf, SUSPEND_FILE_BUFLEN, SUSPEND_LOCK_FILE, domid);
}
static int lock_suspend_event(xc_interface *xch, int domid, int *lockfd)
{
int fd = -1, r;
char suspend_file[SUSPEND_FILE_BUFLEN];
struct stat ours, theirs;
struct flock fl;
get_suspend_file(suspend_file, domid);
*lockfd = -1;
for (;;) {
if (fd >= 0)
close (fd);
fd = open(suspend_file, O_CREAT | O_RDWR, 0600);
if (fd < 0)
ERR("create");
r = fcntl(fd, F_SETFD, FD_CLOEXEC);
if (r)
ERR("fcntl F_SETFD FD_CLOEXEC");
memset(&fl, 0, sizeof(fl));
fl.l_type = F_WRLCK;
fl.l_whence = SEEK_SET;
fl.l_len = 1;
r = fcntl(fd, F_SETLK, &fl);
if (r)
ERR("fcntl F_SETLK");
r = fstat(fd, &ours);
if (r)
ERR("fstat");
r = stat(suspend_file, &theirs);
if (r) {
if (errno == ENOENT)
/* try again */
continue;
ERR("stat");
}
if (ours.st_ino != theirs.st_ino)
/* someone else must have removed it while we were locking it */
continue;
break;
}
*lockfd = fd;
return 0;
err:
if (fd >= 0)
close(fd);
return -1;
}
static int unlock_suspend_event(xc_interface *xch, int domid, int *lockfd)
{
int r;
char suspend_file[SUSPEND_FILE_BUFLEN];
if (*lockfd < 0)
return 0;
get_suspend_file(suspend_file, domid);
r = unlink(suspend_file);
if (r)
ERR("unlink");
r = close(*lockfd);
*lockfd = -1;
if (r)
ERR("close");
err:
if (*lockfd >= 0)
close(*lockfd);
return -1;
}
int xc_await_suspend(xc_interface *xch, xc_evtchn *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;
}
/* Internal callers are allowed to call this with suspend_evtchn<0
* but *lockfd>0. */
int xc_suspend_evtchn_release(xc_interface *xch, xc_evtchn *xce,
int domid, int suspend_evtchn, int *lockfd)
{
if (suspend_evtchn >= 0)
xc_evtchn_unbind(xce, suspend_evtchn);
return unlock_suspend_event(xch, domid, lockfd);
}
int xc_suspend_evtchn_init_sane(xc_interface *xch, xc_evtchn *xce,
int domid, int port, int *lockfd)
{
int rc, suspend_evtchn = -1;
if (lock_suspend_event(xch, domid, lockfd)) {
errno = EINVAL;
goto cleanup;
}
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;
}
return suspend_evtchn;
cleanup:
xc_suspend_evtchn_release(xch, xce, domid, suspend_evtchn, lockfd);
return -1;
}
int xc_suspend_evtchn_init_exclusive(xc_interface *xch, xc_evtchn *xce,
int domid, int port, int *lockfd)
{
int suspend_evtchn;
suspend_evtchn = xc_suspend_evtchn_init_sane(xch, xce, domid, port, lockfd);
if (suspend_evtchn < 0)
return suspend_evtchn;
/* event channel is pending immediately after binding */
xc_await_suspend(xch, xce, suspend_evtchn);
return suspend_evtchn;
}