Beispiel #1
0
static int setup_shutdown_watcher(void)
{
	int err;

	(void)xenbus_scanf(XBT_NIL, "control",
		     "platform-feature-multiprocessor-suspend",
		     "%d", &fast_suspend);

	err = register_xenbus_watch(&shutdown_watch);
	if (err) {
		printk(KERN_ERR "Failed to set shutdown watcher\n");
		return err;
	}

	err = register_xenbus_watch(&sysrq_watch);
	if (err) {
		printk(KERN_ERR "Failed to set sysrq watcher\n");
		return err;
	}

	/* suspend event channel */
	err = setup_suspend_evtchn();
	if (err) {
		printk(KERN_ERR "Failed to register suspend event channel\n");
		return err;
	}

	return 0;
}
Beispiel #2
0
static int xen_suspend(void *__unused)
{
	int err, old_state;

	daemonize("suspend");
	err = set_cpus_allowed(current, cpumask_of_cpu(0));
	if (err) {
		printk(KERN_ERR "Xen suspend can't run on CPU0 (%d)\n", err);
		goto fail;
	}

	do {
		err = __xen_suspend(fast_suspend, xen_resume_notifier);
		if (err) {
			printk(KERN_ERR "Xen suspend failed (%d)\n", err);
			goto fail;
		}
		if (!suspend_cancelled)
			setup_suspend_evtchn();
		old_state = cmpxchg(
			&shutting_down, SHUTDOWN_RESUMING, SHUTDOWN_INVALID);
	} while (old_state == SHUTDOWN_SUSPEND);

	switch (old_state) {
	case SHUTDOWN_INVALID:
	case SHUTDOWN_SUSPEND:
		BUG();
	case SHUTDOWN_RESUMING:
		break;
	default:
		schedule_work(&shutdown_work);
		break;
	}

	return 0;

 fail:
	old_state = xchg(&shutting_down, SHUTDOWN_INVALID);
	BUG_ON(old_state != SHUTDOWN_SUSPEND);
	return 0;
}
Beispiel #3
0
/* open a checkpoint session to guest domid */
int checkpoint_open(checkpoint_state* s, unsigned int domid)
{
    xc_dominfo_t dominfo;
    unsigned long pvirq;

    s->domid = domid;

    s->xch = xc_interface_open();
    if (s->xch < 0) {
       s->errstr = "could not open control interface (are you root?)";

       return -1;
    }

    s->xsh = xs_daemon_open();
    if (!s->xsh) {
       checkpoint_close(s);
       s->errstr = "could not open xenstore handle";

       return -1;
    }

    s->xce = xc_evtchn_open();
    if (s->xce < 0) {
       checkpoint_close(s);
       s->errstr = "could not open event channel handle";

       return -1;
    }

    if (xc_domain_getinfo(s->xch, s->domid, 1, &dominfo) < 0) {
       checkpoint_close(s);
       s->errstr = "could not get domain info";

       return -1;
    }
    if (dominfo.hvm) {
       if (xc_get_hvm_param(s->xch, s->domid, HVM_PARAM_CALLBACK_IRQ, &pvirq)) {
           checkpoint_close(s);
           s->errstr = "could not get HVM callback IRQ";

           return -1;
       }
       s->domtype = pvirq ? dt_pvhvm : dt_hvm;
    } else
       s->domtype = dt_pv;

    if (setup_shutdown_watch(s) < 0) {
       checkpoint_close(s);

       return -1;
    }

    if (s->domtype == dt_pv) {
	if (setup_suspend_evtchn(s) < 0) {
	    fprintf(stderr, "WARNING: suspend event channel unavailable, "
		    "falling back to slow xenstore signalling\n");
	}
    } else if (s->domtype == dt_pvhvm) {
       checkpoint_close(s);
       s->errstr = "PV-on-HVM is unsupported";

       return -1;
    }

    return 0;
}