Esempio n. 1
0
static int
xenstore_putsv(int domid, const char *val, const char *fmt, va_list ap)
{
    char *path = NULL;
    struct xs_handle *xsh = NULL;
    int n, m, rc;
    char key[1024];
    bool success;

    rc = 1;
    bzero(key, sizeof(key));
    xsh = xs_daemon_open();
    if (xsh == NULL)
        goto out;

    path = xs_get_domain_path(xsh, domid);
    if (path == NULL)
        goto out;

    n = snprintf(key, sizeof(key), "%s/", path);
    if (n < 0)
        goto out;
    m = vsnprintf(key + n, sizeof(key) - n, fmt, ap);
    if (m < 0)
        goto out;

    success = xs_write(xsh, XBT_NULL, key, val, strlen(val));
    rc = success? 0 : 1;
out:
    xs_daemon_close(xsh);
    free(path);
    return rc;
}
Esempio n. 2
0
int main(int argc, char **argv)
{
  struct xs_handle * xsh;

  if (argc < 2 ||
      strcmp(argv[1], "check"))
  {
    fprintf(stderr,
            "Usage:\n"
            "\n"
            "       %s check\n"
            "\n", argv[0]);
    return 2;
  }

  xsh = xs_daemon_open();

  if (xsh == NULL) {
    fprintf(stderr, "Failed to contact Xenstored.\n");
    return 1;
  }

  xs_debug_command(xsh, argv[1], NULL, 0);

  xs_daemon_close(xsh);

  return 0;
}
Esempio n. 3
0
static char *
xenstore_getsv(int domid, const char *fmt, va_list ap)
{
    char *path = NULL, *s;
    uint64_t value = 0;
    struct xs_handle *xsh = NULL;
    int n, m;
    char key[1024];

    bzero(key, sizeof(key));

    xsh = xs_daemon_open();
    if (xsh == NULL)
        return 0;

    path = xs_get_domain_path(xsh, domid);
    if (path == NULL)
        goto out;

    n = snprintf(key, sizeof(key), "%s/", path);
    if (n < 0)
        goto out;
    m = vsnprintf(key + n, sizeof(key) - n, fmt, ap);
    if (m < 0)
        goto out;

    s = xs_read(xsh, XBT_NULL, key, NULL);
out:
    xs_daemon_close(xsh);
    free(path);
    return s;
}
Esempio n. 4
0
int
xen_setup(void)
{
	
	xs = xs_daemon_open();
	if (xs == NULL) {
		dolog(LOG_ERR,
		    "Failed to contact xenstore (%s).  Is it running?",
		    strerror(errno));
		goto out;
	}

	xc = xc_interface_open();
	if (xc == -1) {
		dolog(LOG_ERR, "Failed to contact hypervisor (%s)",
		    strerror(errno));
		goto out;
	}
	if (!xs_watch(xs, DOMAIN_PATH, "backend")) {
		dolog(LOG_ERR, "xenstore watch on backend fails.");
		goto out;
	}
	return 0;
 out:
	if (xs)
		xs_daemon_close(xs);
	if (xc != -1)
		xc_interface_close(xc);
	return -1;
}
Esempio n. 5
0
bool xen_setup(void)
{
	
	xs = xs_daemon_open();
	if (xs == NULL) {
		dolog(LOG_ERR,
		      "Failed to contact xenstore (%m).  Is it running?");
		goto out;
	}

	xc = xc_interface_open();
	if (xc == -1) {
		dolog(LOG_ERR, "Failed to contact hypervisor (%m)");
		goto out;
	}
	
	if (!xs_watch(xs, "@introduceDomain", "domlist")) {
		dolog(LOG_ERR, "xenstore watch on @introduceDomain fails.");
		goto out;
	}
	
	if (!xs_watch(xs, "@releaseDomain", "domlist")) {
		dolog(LOG_ERR, "xenstore watch on @releaseDomain fails.");
		goto out;
	}

	return true;

 out:
	if (xs)
		xs_daemon_close(xs);
	if (xc != -1)
		xc_interface_close(xc);
	return false;
}
Esempio n. 6
0
static int suspend_evtchn_init(int xc, int domid)
{
    struct xs_handle *xs;
    char path[128];
    char *portstr;
    unsigned int plen;
    int port;
    int rc;

    si.xce = -1;
    si.suspend_evtchn = -1;

    xs = xs_daemon_open();
    if (!xs) {
        warnx("failed to get xenstore handle");
        return -1;
    }
    sprintf(path, "/local/domain/%d/device/suspend/event-channel", domid);
    portstr = xs_read(xs, XBT_NULL, path, &plen);
    xs_daemon_close(xs);

    if (!portstr || !plen) {
        warnx("could not read suspend event channel");
        return -1;
    }

    port = atoi(portstr);
    free(portstr);

    si.xce = xc_evtchn_open();
    if (si.xce < 0) {
        warnx("failed to open event channel handle");
        goto cleanup;
    }

    si.suspend_evtchn = xc_evtchn_bind_interdomain(si.xce, domid, port);
    if (si.suspend_evtchn < 0) {
        warnx("failed to bind suspend event channel: %d", si.suspend_evtchn);
        goto cleanup;
    }

    rc = xc_domain_subscribe_for_suspend(xc, domid, port);
    if (rc < 0) {
        warnx("failed to subscribe to domain: %d", rc);
        goto cleanup;
    }

    /* event channel is pending immediately after binding */
    await_suspend();

    return 0;

  cleanup:
    suspend_evtchn_release();

    return -1;
}
Esempio n. 7
0
/*
 * Initialise xenstore handle and open grant dev driver.
 * @return
 *  0 on success, -1 on failure.
 */
int
xenhost_init(void)
{
	xs = xs_daemon_open();
	if (xs == NULL) {
		rte_panic("failed initialize xen daemon handler");
		return -1;
	}
	if (xen_grant_init())
		return -1;
	return 0;
}
Esempio n. 8
0
static void xenstore_init(int domid)
{
	/* Get a connection to the daemon */
	xs = xs_daemon_open();

	if (!xs) {
		perror("error opening xenstore");
		exit(1);
	}

	/* Get the local domain path */
	domain_root_path = xs_get_domain_path(xs, domid);
}
Esempio n. 9
0
int main(int argc, char *argv[])
{
    struct winsize ws;
    int ret, c, socket = 0, show_perm = 0;
    struct xs_handle *xsh;

#define PAD 2

    memset(&ws, 0, sizeof(ws));
    ret = ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws);
    if (!ret)
        max_width = ws.ws_col - PAD;

    while (0 < (c = getopt(argc, argv, "pswf"))) {
        switch (c) {
        case 'w':
            max_width= STRING_MAX - PAD;
            desired_width = 0;
            break;
        case 'p':
            show_perm = 1;
            break;
        case 's':
            socket = 1;
            break;
        case 'f':
            max_width = INT_MAX/2;
            desired_width = 0;
            show_whole_path = 1;
            break;
        case ':':
        case '?':
        default:
            usage(argc, argv);
            return 0;
        }
    }

    /* Adjust the width here to avoid argument order dependency */
    if ( show_perm ) {
        max_width -= 16;
    }

    xsh = socket ? xs_daemon_open() : xs_domain_open();
    if (xsh == NULL)
        err(1, socket ? "xs_daemon_open" : "xs_domain_open");

    print_dir(xsh, (argc - optind) == 1 ? argv[optind] : "/", 0, show_perm);

    return 0;
}
Esempio n. 10
0
struct xenfb *xenfb_new(int domid, DisplayState *ds)
{
	struct xenfb *xenfb = qemu_malloc(sizeof(struct xenfb));
	int serrno;
	int i;

	if (xenfb == NULL)
		return NULL;

	/* Prepare scancode mapping table */
	for (i = 0; i < 128; i++) {
		scancode2linux[i] = atkbd_set2_keycode[atkbd_unxlate_table[i]];
		scancode2linux[i | 0x80] = 
			atkbd_set2_keycode[atkbd_unxlate_table[i] | 0x80];
	}

	memset(xenfb, 0, sizeof(*xenfb));
	xenfb->evt_xch = xenfb->xc = -1;
	xenfb_device_init(&xenfb->fb, "vfb", xenfb);
	xenfb_device_init(&xenfb->kbd, "vkbd", xenfb);

	xenfb->evt_xch = xc_evtchn_open();
	if (xenfb->evt_xch == -1)
		goto fail;

	xenfb->xc = xc_interface_open();
	if (xenfb->xc == -1)
		goto fail;

	xenfb->xsh = xs_daemon_open();
	if (!xenfb->xsh)
		goto fail;

	xenfb->ds = ds;
	xenfb_device_set_domain(&xenfb->fb, domid);
	xenfb_device_set_domain(&xenfb->kbd, domid);

	fprintf(stderr, "FB: Waiting for KBD backend creation\n");
	xenfb_wait_for_backend(&xenfb->kbd, xenfb_backend_created_kbd);

	return xenfb;

 fail:
	serrno = errno;
	xenfb_shutdown(xenfb);
	errno = serrno;
	return NULL;
}
Esempio n. 11
0
//Shutdown a domain by signalling this via xenstored
void shutdown_domain(char *domname)
{
	int domid;
	char *vm_uuid = NULL;
	char vmpath[64];
	struct xs_handle *xsh = NULL;

	domid = atoi(domname);
	if (domid == 0) {
		perror("Error, dom 0 could not be shutdown\n");
		return; 
	}

	xsh = xs_daemon_open();
	if (!xsh) {
		perror("Couldn't get xsh handle.");
		return;
	}

	//if self._stateGet() in (DOM_STATE_SHUTDOWN, DOM_STATE_HALTED,):
	//    raise XendError('Domain cannot be shutdown')

	vm_uuid = domid_to_vm_uuid(xsh, domid);
	snprintf(vmpath, sizeof(vmpath), "%s/xend/previous_restart_time", vm_uuid);
	free(vm_uuid);

	xs_rm(xsh, XBT_NULL, vmpath);

	memset(vmpath, '\0', 64); 
	snprintf(vmpath, sizeof(vmpath), "/local/domain/%u/control/shutdown", domid);

	xs_write(xsh, XBT_NULL, vmpath, "poweroff", 9);

	//TODO: How about HVM domain	
	//HVM domain shuts itself down only if it has PV drivers
	//if self.info.is_hvm():
	//    hvm_pvdrv = xc.hvm_get_param(self.domid, HVM_PARAM_CALLBACK_IRQ)
	//    if not hvm_pvdrv:
	//        code = REVERSE_DOMAIN_SHUTDOWN_REASONS[reason]

	free(xsh);
	return;
}
Esempio n. 12
0
int switch_qemu_logdirty(int domid, unsigned enable, void *data)
{
    char *path = NULL;
    struct xs_handle *xsh = NULL;
    bool rc;

    pasprintf(&path, "/local/domain/0/device-model/%u/logdirty/cmd", domid);

    xsh = xs_daemon_open();
    if (xsh == NULL)
        errx(1, "Couldn't contact xenstore");

    if (enable)
        rc = xs_write(xsh, XBT_NULL, path, "enable", strlen("enable"));
    else
        rc = xs_write(xsh, XBT_NULL, path, "disable", strlen("disable"));

    xs_daemon_close(xsh);
    free(path);
    return rc ? 0 : 1;

}
Esempio n. 13
0
static void
xenstore_get_host_limits(size_t *kernel_max_size, size_t *ramdisk_max_size)
{
    static const char *kernel_max_path = "/mh/limits/pv-kernel-max-size";
    static const char *ramdisk_max_path = "/mh/limits/pv-ramdisk-max-size";
    struct xs_handle *xsh = NULL;
    size_t value;
    char *s;

    /* Safe defaults */
    *kernel_max_size  =  (32 * 1024 * 1024);
    *ramdisk_max_size = (128 * 1024 * 1024);

    xsh = xs_daemon_open();
    if (xsh == NULL)
        return;

    s = xs_read(xsh, XBT_NULL, kernel_max_path, NULL);
    if (s) {
        errno = 0;
        value = strtoul(s, NULL, 10);
        if ( errno == 0 )
            *kernel_max_size = value;
        free(s);
    }

    s = xs_read(xsh, XBT_NULL, ramdisk_max_path, NULL);
    if (s) {
        errno = 0;
        value = strtoul(s, NULL, 10);
        if ( errno == 0 )
            *ramdisk_max_size = value;
        free(s);
    }

    xs_daemon_close(xsh);
    return;
}
Esempio n. 14
0
static void dm_xenstore_record_pid(void *for_spawn, pid_t innerchild)
{
    libxl__device_model_starting *starting = for_spawn;
    struct xs_handle *xsh;
    char *path = NULL, *pid = NULL;
    int len;

    if (asprintf(&path, "%s/%s", starting->dom_path, "image/device-model-pid") < 0)
        goto out;

    len = asprintf(&pid, "%d", innerchild);
    if (len < 0)
        goto out;

    /* we mustn't use the parent's handle in the child */
    xsh = xs_daemon_open();

    xs_write(xsh, XBT_NULL, path, pid, len);

    xs_daemon_close(xsh);
out:
    free(path);
    free(pid);
}
static int
xen_setup(void)
{
	xs = xs_daemon_open();
	if (xs == NULL) {
		dolog(LOG_ERR,
		    "Failed to contact xenstore (%s).  Is it running?",
		    strerror(errno));
		goto out;
	}

	if (!xs_watch(xs, DOMAIN_PATH, "backend")) {
		dolog(LOG_ERR, "xenstore watch on backend fails.");
		goto out;
	}
	return 0;

 out:
	if (xs) {
		xs_daemon_close(xs);
		xs = NULL;
	}
	return -1;
}
Esempio n. 16
0
int main(int argc, char **argv)
{
  int option = 0;
  int domid = -1, bus = -1, device = -1;
  int vassign = 0, vunassign = 0, attach = 0, detach = 0, list = 0, dump = 0;
  char *action = NULL;
  dominfo_t di;
  usbinfo_t ui;
  int ret = 0;

  xs_handle = xs_daemon_open();
  if (xs_handle == NULL) {
    xd_log(LOG_ERR, "Failed to connect to xenstore");
    exit(1);
  }

  if ((xs_dom0path = xs_get_domain_path(xs_handle, 0)) == NULL) {
    xd_log(LOG_ERR, "Could not get domain 0 path from XenStore");
    exit(1);
  }

  while ((option = getopt(argc, argv, "D:b:d:")) != -1) {
    switch (option) {
    case 'D':
      domid = atoi(optarg);
      if (get_dominfo(domid, &di))
        exit(1);
      break;
    case 'b':
      bus = atoi(optarg);
      break;
    case 'd':
      device = atoi(optarg);
      break;
    }
  }

  if (optind != argc-1) {
    usage();
  }

  action = argv[optind];
  vassign = !strcmp(action, "assign");
  vunassign = !strcmp(action, "unassign");
  attach = !strcmp(action, "attach");
  detach = !strcmp(action, "detach");
  list = !strcmp(action, "list");
  dump = !strcmp(action, "dump");

  if (vassign || vunassign || attach || detach || dump) {
    if (bus < 0 || device < 0)
      usage();

    if (get_usbinfo(bus, device, &ui)) {
      if (detach) {
        /* can proceed detaching without detailed device info, we only need bus & dev num */
      } else if (vunassign) {
        /* no device so nothing to unassign */
        exit(0);
      } else {
        xd_log(LOG_ERR, "Failed to find device %d:%d", bus, device);
        exit(1);
      }
    }
  }

  if (optind == argc) {
    dump_dev(&ui);
    return 0;
  }

  if (dump)
    dump_dev(&ui);
  else if (vassign)
    ret = vusb_assign(ui.usb_vendor, ui.usb_product, 1);
  else if (vunassign)
    ret = vusb_assign(ui.usb_vendor, ui.usb_product, 0);
  else if (attach) {
    if (domid < 0)
      usage();
    ret = xenstore_create_usb(&di, &ui);
  }
  else if (detach) {
    if (domid < 0)
      usage();
    ret = xenstore_destroy_usb(&di, &ui);
  }
  else if (list) {
    if (domid < 0)
      usage();
    list_domain_devs(&di);
  }

  if (ret)
    xd_log(LOG_ERR, "Operation failed");
  return ret == 0 ? 0 : 1;
}
Esempio n. 17
0
int main(int argc, char **argv)
{
	struct termios attr;
	int domid;
	char *sopt = "h";
	int ch;
	int opt_ind=0;
	struct option lopt[] = {
		{ "help",    0, 0, 'h' },
		{ 0 },

	};
	char *path;
	int spty, xsfd;
	struct xs_handle *xs;
	char *end;

	while((ch = getopt_long(argc, argv, sopt, lopt, &opt_ind)) != -1) {
		switch(ch) {
		case 'h':
			usage(argv[0]);
			exit(0);
			break;
		}
	}
	
	if ((argc - optind) != 1) {
		fprintf(stderr, "Invalid number of arguments\n");
		fprintf(stderr, "Try `%s --help' for more information.\n", 
			argv[0]);
		exit(EINVAL);
	}
	
	domid = strtol(argv[optind], &end, 10);
	if (end && *end) {
		fprintf(stderr, "Invalid DOMID `%s'\n", argv[optind]);
		fprintf(stderr, "Try `%s --help' for more information.\n",
			argv[0]);
		exit(EINVAL);
	}

	xs = xs_daemon_open();
	if (xs == NULL) {
		err(errno, "Could not contact XenStore");
	}

	signal(SIGTERM, sighandler);

	path = xs_get_domain_path(xs, domid);
	if (path == NULL)
		err(errno, "xs_get_domain_path()");
	path = realloc(path, strlen(path) + strlen("/console/tty") + 1);
	if (path == NULL)
		err(ENOMEM, "realloc");
	strcat(path, "/console/tty");

	/* FIXME consoled currently does not assume domain-0 doesn't have a
	   console which is good when we break domain-0 up.  To keep us
	   user friendly, we'll bail out here since no data will ever show
	   up on domain-0. */
	if (domid == 0) {
		fprintf(stderr, "Can't specify Domain-0\n");
		exit(EINVAL);
	}

	/* Set a watch on this domain's console pty */
	if (!xs_watch(xs, path, ""))
		err(errno, "Can't set watch for console pty");
	xsfd = xs_fileno(xs);

	/* Wait a little bit for tty to appear.  There is a race
	   condition that occurs after xend creates a domain.  This code
	   might be running before consoled has noticed the new domain
	   and setup a pty for it. */ 
        spty = get_pty_fd(xs, path, 5);
	if (spty == -1) {
		err(errno, "Could not read tty from store");
	}

	init_term(spty, &attr);
	init_term(STDIN_FILENO, &attr);
	console_loop(spty, xs, path);
	restore_term(STDIN_FILENO, &attr);

	free(path);
	return 0;
 }
Esempio n. 18
0
int main(int argc, char **argv)
{
	struct termios attr;
	int domid;
	char *sopt = "hn:";
	int ch;
	unsigned int num = 0;
	int opt_ind=0;
	struct option lopt[] = {
		{ "type",     1, 0, 't' },
		{ "num",     1, 0, 'n' },
		{ "help",    0, 0, 'h' },
		{ 0 },

	};
	char *dom_path = NULL, *path = NULL;
	int spty, xsfd;
	struct xs_handle *xs;
	char *end;
	console_type type = CONSOLE_INVAL;

	while((ch = getopt_long(argc, argv, sopt, lopt, &opt_ind)) != -1) {
		switch(ch) {
		case 'h':
			usage(argv[0]);
			exit(0);
			break;
		case 'n':
			num = atoi(optarg);
			break;
		case 't':
			if (!strcmp(optarg, "serial"))
				type = CONSOLE_SERIAL;
			else if (!strcmp(optarg, "pv"))
				type = CONSOLE_PV;
			else {
				fprintf(stderr, "Invalid type argument\n");
				fprintf(stderr, "Console types supported are: serial, pv\n");
				exit(EINVAL);
			}
			break;
		default:
			fprintf(stderr, "Invalid argument\n");
			fprintf(stderr, "Try `%s --help' for more information.\n", 
					argv[0]);
			exit(EINVAL);
		}
	}

	if (optind >= argc) {
		fprintf(stderr, "DOMID should be specified\n");
		fprintf(stderr, "Try `%s --help' for more information.\n",
			argv[0]);
		exit(EINVAL);
	}
	domid = strtol(argv[optind], &end, 10);
	if (end && *end) {
		fprintf(stderr, "Invalid DOMID `%s'\n", argv[optind]);
		fprintf(stderr, "Try `%s --help' for more information.\n",
			argv[0]);
		exit(EINVAL);
	}

	xs = xs_daemon_open();
	if (xs == NULL) {
		err(errno, "Could not contact XenStore");
	}

	signal(SIGTERM, sighandler);

	dom_path = xs_get_domain_path(xs, domid);
	if (dom_path == NULL)
		err(errno, "xs_get_domain_path()");
	if (type == CONSOLE_INVAL) {
		xc_dominfo_t xcinfo;
		xc_interface *xc_handle = xc_interface_open(0,0,0);
		if (xc_handle == NULL)
			err(errno, "Could not open xc interface");
		xc_domain_getinfo(xc_handle, domid, 1, &xcinfo);
		/* default to pv console for pv guests and serial for hvm guests */
		if (xcinfo.hvm)
			type = CONSOLE_SERIAL;
		else
			type = CONSOLE_PV;
		xc_interface_close(xc_handle);
	}
	path = malloc(strlen(dom_path) + strlen("/device/console/0/tty") + 5);
	if (path == NULL)
		err(ENOMEM, "malloc");
	if (type == CONSOLE_SERIAL)
		snprintf(path, strlen(dom_path) + strlen("/serial/0/tty") + 5, "%s/serial/%d/tty", dom_path, num);
	else {
		if (num == 0)
			snprintf(path, strlen(dom_path) + strlen("/console/tty") + 1, "%s/console/tty", dom_path);
		else
			snprintf(path, strlen(dom_path) + strlen("/device/console/%d/tty") + 5, "%s/device/console/%d/tty", dom_path, num);
	}

	/* FIXME consoled currently does not assume domain-0 doesn't have a
	   console which is good when we break domain-0 up.  To keep us
	   user friendly, we'll bail out here since no data will ever show
	   up on domain-0. */
	if (domid == 0) {
		fprintf(stderr, "Can't specify Domain-0\n");
		exit(EINVAL);
	}

	/* Set a watch on this domain's console pty */
	if (!xs_watch(xs, path, ""))
		err(errno, "Can't set watch for console pty");
	xsfd = xs_fileno(xs);

	/* Wait a little bit for tty to appear.  There is a race
	   condition that occurs after xend creates a domain.  This code
	   might be running before consoled has noticed the new domain
	   and setup a pty for it. */ 
        spty = get_pty_fd(xs, path, 5);
	if (spty == -1) {
		err(errno, "Could not read tty from store");
	}

	init_term(spty, &attr);
	init_term(STDIN_FILENO, &attr);
	console_loop(spty, xs, path);
	restore_term(STDIN_FILENO, &attr);

	free(path);
	free(dom_path);
	return 0;
 }
Esempio n. 19
0
void xenstore_parse_domain_config(int domid)
{
    char **e = NULL;
    char *buf = NULL, *path;
    char *fpath = NULL, *bpath = NULL,
        *dev = NULL, *params = NULL, *type = NULL, *drv = NULL;
    int i, is_scsi, is_hdN = 0;
    unsigned int len, num, hd_index;
    BlockDriverState *bs;

    for(i = 0; i < MAX_DISKS + MAX_SCSI_DISKS; i++)
        media_filename[i] = NULL;

    xsh = xs_daemon_open();
    if (xsh == NULL) {
        fprintf(logfile, "Could not contact xenstore for domain config\n");
        return;
    }

    path = xs_get_domain_path(xsh, domid);
    if (path == NULL) {
        fprintf(logfile, "xs_get_domain_path() error\n");
        goto out;
    }

    if (pasprintf(&buf, "%s/device/vbd", path) == -1)
        goto out;

    e = xs_directory(xsh, XBT_NULL, buf, &num);
    if (e == NULL)
        goto out;

    for (i = 0; i < num; i++) {
        /* read the backend path */
        if (pasprintf(&buf, "%s/device/vbd/%s/backend", path, e[i]) == -1)
            continue;
        free(bpath);
        bpath = xs_read(xsh, XBT_NULL, buf, &len);
        if (bpath == NULL)
            continue;
        /* read the name of the device */
        if (pasprintf(&buf, "%s/dev", bpath) == -1)
            continue;
        free(dev);
        dev = xs_read(xsh, XBT_NULL, buf, &len);
        if (dev == NULL)
            continue;
        if (!strncmp(dev, "hd", 2)) {
            is_hdN = 1;
            break;
        }
    }
        
    for (i = 0; i < num; i++) {
        /* read the backend path */
        if (pasprintf(&buf, "%s/device/vbd/%s/backend", path, e[i]) == -1)
            continue;
        free(bpath);
        bpath = xs_read(xsh, XBT_NULL, buf, &len);
        if (bpath == NULL)
            continue;
        /* read the name of the device */
        if (pasprintf(&buf, "%s/dev", bpath) == -1)
            continue;
        free(dev);
        dev = xs_read(xsh, XBT_NULL, buf, &len);
        if (dev == NULL)
            continue;
        /* Change xvdN to look like hdN */
        if (!is_hdN && !strncmp(dev, "xvd", 3)) {
            fprintf(logfile, "Change xvd%c to look like hd%c\n",
                    dev[3], dev[3]);
            memmove(dev, dev+1, strlen(dev));
            dev[0] = 'h';
            dev[1] = 'd';
        }
        is_scsi = !strncmp(dev, "sd", 2);
        if ((strncmp(dev, "hd", 2) && !is_scsi) || strlen(dev) != 3 )
            continue;
        hd_index = dev[2] - 'a';
        if (hd_index >= (is_scsi ? MAX_SCSI_DISKS : MAX_DISKS))
            continue;
        /* read the type of the device */
        if (pasprintf(&buf, "%s/device/vbd/%s/device-type", path, e[i]) == -1)
            continue;
        free(type);
        type = xs_read(xsh, XBT_NULL, buf, &len);
        if (pasprintf(&buf, "%s/params", bpath) == -1)
            continue;
        free(params);
        params = xs_read(xsh, XBT_NULL, buf, &len);
        if (params == NULL)
            continue;
        /* read the name of the device */
        if (pasprintf(&buf, "%s/type", bpath) == -1)
            continue;
        free(drv);
        drv = xs_read(xsh, XBT_NULL, buf, &len);
        if (drv == NULL)
            continue;
        /* Strip off blktap sub-type prefix aio: - QEMU can autodetect this */
        if (!strcmp(drv, "tap") && params[0]) {
            char *offset = strchr(params, ':'); 
            if (!offset)
                continue ;
            memmove(params, offset+1, strlen(offset+1)+1 );
            fprintf(logfile, "Strip off blktap sub-type prefix to %s\n", params); 
        }
        /* Prefix with /dev/ if needed */
        if (!strcmp(drv, "phy") && params[0] != '/') {
            char *newparams = malloc(5 + strlen(params) + 1);
            sprintf(newparams, "/dev/%s", params);
            free(params);
            params = newparams;
        }

        /* 
         * check if device has a phantom vbd; the phantom is hooked
         * to the frontend device (for ease of cleanup), so lookup 
         * the frontend device, and see if there is a phantom_vbd
         * if there is, we will use resolution as the filename
         */
        if (pasprintf(&buf, "%s/device/vbd/%s/phantom_vbd", path, e[i]) == -1)
            continue;
        free(fpath);
        fpath = xs_read(xsh, XBT_NULL, buf, &len);
        if (fpath) {
            if (pasprintf(&buf, "%s/dev", fpath) == -1)
                continue;
            free(params);
            params = xs_read(xsh, XBT_NULL, buf , &len);
            if (params) {
                /* 
                 * wait for device, on timeout silently fail because we will 
                 * fail to open below
                 */
                waitForDevice(params);
            }
        }

        bs = bs_table[hd_index + (is_scsi ? MAX_DISKS : 0)] = bdrv_new(dev);
        /* check if it is a cdrom */
        if (type && !strcmp(type, "cdrom")) {
            bdrv_set_type_hint(bs, BDRV_TYPE_CDROM);
            if (pasprintf(&buf, "%s/params", bpath) != -1)
                xs_watch(xsh, buf, dev);
        }

        /* open device now if media present */
        if (params[0]) {
            if (bdrv_open(bs, params, 0 /* snapshot */) < 0)
                fprintf(stderr, "qemu: could not open hard disk image '%s'\n",
                        params);
        }
    }

    /* Set a watch for log-dirty requests from the migration tools */
    if (pasprintf(&buf, "/local/domain/0/device-model/%u/logdirty/next-active",
                  domid) != -1) {
        xs_watch(xsh, buf, "logdirty");
        fprintf(logfile, "Watching %s\n", buf);
    }

    /* Set a watch for suspend requests from the migration tools */
    if (pasprintf(&buf, 
                  "/local/domain/0/device-model/%u/command", domid) != -1) {
        xs_watch(xsh, buf, "dm-command");
        fprintf(logfile, "Watching %s\n", buf);
    }

 out:
    free(type);
    free(params);
    free(dev);
    free(bpath);
    free(buf);
    free(path);
    free(e);
    free(drv);
    return;
}
Esempio n. 20
0
static void *init_qemu_maps(int domid, unsigned int bitmap_size)
{
    key_t key;
    char key_ascii[17] = {0,};
    void *seg; 
    char *path, *p;

    /* Make a shared-memory segment */
    do {
        key = rand(); /* No security, just a sequence of numbers */
        qemu_shmid = shmget(key, 2 * bitmap_size, 
                       IPC_CREAT|IPC_EXCL|S_IRUSR|S_IWUSR);
        if (qemu_shmid == -1 && errno != EEXIST)
            errx(1, "can't get shmem to talk to qemu-dm");
    } while (qemu_shmid == -1);

    /* Remember to tidy up after ourselves */
    atexit(qemu_destroy_buffer);

    /* Map it into our address space */
    seg = shmat(qemu_shmid, NULL, 0);
    if (seg == (void *) -1) 
        errx(1, "can't map shmem to talk to qemu-dm");
    memset(seg, 0, 2 * bitmap_size);

    /* Write the size of it into the first 32 bits */
    *(uint32_t *)seg = bitmap_size;

    /* Tell qemu about it */
    if ((xs = xs_daemon_open()) == NULL)
        errx(1, "Couldn't contact xenstore");
    if (!(path = strdup("/local/domain/0/device-model/")))
        errx(1, "can't get domain path in store");
    if (!(path = realloc(path, strlen(path) 
                         + 10 
                         + strlen("/logdirty/next-active") + 1))) 
        errx(1, "no memory for constructing xenstore path");
    snprintf(path + strlen(path), 11, "%i", domid);
    strcat(path, "/logdirty/");
    p = path + strlen(path);

    strcpy(p, "key");
    snprintf(key_ascii, 17, "%16.16llx", (unsigned long long) key);
    if (!xs_write(xs, XBT_NULL, path, key_ascii, 16))
        errx(1, "can't write key (%s) to store path (%s)\n", key_ascii, path);

    /* Watch for qemu's indication of the active buffer, and request it 
     * to start writing to buffer 0 */
    strcpy(p, "active");
    if (!xs_watch(xs, path, "qemu-active-buffer"))
        errx(1, "can't set watch in store (%s)\n", path);
    if (!(qemu_active_path = strdup(path)))
        errx(1, "no memory for copying xenstore path");

    strcpy(p, "next-active");
    if (!(qemu_next_active_path = strdup(path)))
        errx(1, "no memory for copying xenstore path");

    qemu_flip_buffer(domid, 0);

    free(path);
    return seg;
}
Esempio n. 21
0
File: init.c Progetto: Fantu/Xen
struct libxenvchan *libxenvchan_client_init(xentoollog_logger *logger, int domain, const char* xs_path)
{
	struct libxenvchan *ctrl = malloc(sizeof(struct libxenvchan));
	struct xs_handle *xs = NULL;
	char buf[64];
	char *ref;
	int ring_ref;
	unsigned int len;

	if (!ctrl)
		return 0;
	ctrl->ring = NULL;
	ctrl->event = NULL;
	ctrl->gnttab = NULL;
	ctrl->write.order = ctrl->read.order = 0;
	ctrl->is_server = 0;

	xs = xs_daemon_open();
	if (!xs)
		xs = xs_domain_open();
	if (!xs)
		goto fail;

// find xenstore entry
	snprintf(buf, sizeof buf, "%s/ring-ref", xs_path);
	ref = xs_read(xs, 0, buf, &len);
	if (!ref)
		goto fail;
	ring_ref = atoi(ref);
	free(ref);
	if (!ring_ref)
		goto fail;
	snprintf(buf, sizeof buf, "%s/event-channel", xs_path);
	ref = xs_read(xs, 0, buf, &len);
	if (!ref)
		goto fail;
	ctrl->event_port = atoi(ref);
	free(ref);
	if (!ctrl->event_port)
		goto fail;

	ctrl->gnttab = xc_gnttab_open(logger, 0);
	if (!ctrl->gnttab)
		goto fail;

// set up event channel
	if (init_evt_cli(ctrl, domain, logger))
		goto fail;

// set up shared page(s)
	if (init_gnt_cli(ctrl, domain, ring_ref))
		goto fail;

	ctrl->ring->cli_live = 1;
	ctrl->ring->srv_notify = VCHAN_NOTIFY_WRITE;

 out:
	if (xs)
		xs_daemon_close(xs);
	return ctrl;
 fail:
	libxenvchan_close(ctrl);
	ctrl = NULL;
	goto out;
}
Esempio n. 22
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;
}
Esempio n. 23
0
int destroy_domain(char *domname)
{
	int domid, rcode, i, DMid, status;
	int __attribute__((__unused__)) ret;
#ifdef XENCTRL_HAS_XC_INTERFACE
    xc_interface *xc_handle = NULL;
#else
    int xc_handle = 0;
#endif
    unsigned int len;
	char *s;
	char path[256];
	struct xs_handle *xsh = NULL;
        FILE *f;
        char buf[256];
        char *backend;

	xsh = xs_daemon_open();
	if (!xsh) {
		perror("Couldn't get xsh handle.");
		rcode = 1;
		goto out;
	}
	domid = getDomidByName(xsh, domname);

	if (domid < 1) {
		perror("Error,Can't destroy domId, domId should > 0\n");
        rcode = 1;
        goto out;
	}


#ifdef XENCTRL_HAS_XC_INTERFACE
	xc_handle = xc_interface_open(NULL, NULL, 0);
	if (xc_handle == NULL) {
#else
	xc_handle = xc_interface_open();
    if (xc_handle < 0) {
#endif
		perror("Couldn't open xc handle.");
		rcode = 1;
		goto out;
	}

	/* TODO PCI clean
	paths = self._prepare_phantom_paths()
	if self.dompath is not None:
		self._cleanup_phantom_devs(paths)

	xc_domain_destroy_hook(xc_handle, domid);
	*/

	xc_domain_pause(xc_handle, domid);
	rcode = xc_domain_destroy(xc_handle, domid);
        
        // free Device Model
        sprintf(path,"/local/domain/%d/image/device-model-pid", domid); 
        s = xs_read(xsh, XBT_NULL, path, &len);
        if( s != NULL)
        {
            DMid = atoi(s);
            free(s);
            DEBUG("Deivce Model Id is %d\n", DMid);
        }
        else
        {
            rcode = 1;
            DEBUG("can't read Deivce Model Id\n");
            goto out;
        }
        kill(DMid, SIGHUP);
        for( i=0; i< 100; i++)
        {
            if(DMid == waitpid(DMid, &status, WNOHANG))
                break;
            sleep(0.1);
        }
        if( i == 100)
        {
            DEBUG("DeviceModel %d took more than 10s "
                                "to terminate: sending SIGKILL\n", DMid);
            kill(DMid, SIGKILL);
            waitpid(DMid, &status, 0);
        }
        sprintf(path,"/local/domain/0/device-model/%i", domid); 
        xs_rm(xsh, XBT_NULL, path);

        // unlink pipe
        sprintf(path,"/var/run/tap/qemu-read-%d", domid); 
        ret = unlink(path);
        sprintf(path,"/var/run/tap/qemu-write-%d", domid); 
        ret = unlink(path);

        //notify backend to reap the source assigned to this VM
        sprintf(path, "xenstore-ls /local/domain/%d/device > /var/tmp/xdestroy_device.%d", domid, domid); 
        ret = system(path);
        sprintf(path, "/var/tmp/xdestroy_device.%d",  domid); 
        f = fopen(path, "r");
        if ( f == NULL)
        {
            DEBUG(" error to open device file\n");
            return -1;
        }
        DEBUG("- begin to reap\n");
        while(1)
        {
            if( fgets(buf, 256, f)== NULL)
                break;
            else
            {
                if( buf[0] != 0x20)
                {
                    backend = device_backend(xsh, buf, domid);
                    if( backend != NULL)
                    {    
                        notify_backend(xsh, backend);
                        free(backend);
                    }
                }
            }
       }
       DEBUG("- end to reap\n");
       fclose(f);
       sprintf(path, "rm /var/tmp/xdestroy_device.%d",  domid); 
       ret = system(path);
       extra_call(domname, DMid);
out:
	if (xsh)
		xs_daemon_close(xsh);
	if (xc_handle)
		xc_interface_close(xc_handle);
	return rcode;
}

int main(int argc, char **argv)
{
	if (argc != 2) {
		printf("Miss destroy name\n");
		return -1;
	}
	xlist(argc, argv);
	//shutdown_domain(argv[1]);
	destroy_domain(argv[1]);

	return 0;
}
Esempio n. 24
0
int
main (int argc, char **argv)
{
  int i;
  struct xs_handle *xs;
  xs_transaction_t th;
  char *path;
  int fd;
  fd_set set;
  int er;
  char **vec;
  unsigned int num_strings;
  char * buf;
  unsigned int len;
  char *program;
  char **arguments;
  int arguments_count;
  pid_t pid;
  int j;
  char *last_value = NULL;
  int status;

  program_name = argv[0];

  i = decode_switches (argc, argv);
  
  if (argc - i < 1)
    usage(1);
  
  path = argv[i++];
  if (argc - i > 0)
  {
    program = argv[i++];
    arguments_count = argc - i;
    
    arguments = malloc(sizeof(char*) * (argc - i + 2));
    arguments[0] = program;
    for (j=0; j<arguments_count; j++)
      arguments[j + 1] = argv[i + j];
    arguments[j + 1] = NULL;
  } else
  {
    program = NULL;
    arguments = NULL;
    arguments_count = 0;
  }
  
  if (want_verbose) {
    printf("Path: %s\n", path);
    if (program)
    {
      printf("Program: %s", program);
      for (i=1; i<arguments_count + 1; i++)
        printf(" %s", arguments[i]);
      printf("\n");
    }
  }
  
  /* Get a connection to the daemon */
  xs = xs_daemon_open();
  if ( xs == NULL ) xs = xs_domain_open();
  if ( xs == NULL ) {
    error("Unable to connect to XenStore");
    exit(1);
  }

  /* Create a watch on /local/domain/0/mynode. */
  er = xs_watch(xs, path, "token");
  if ( er == 0 ) {
    error("Unable to create watch");
    exit(1);
  }

  /* We are notified of read availability on the watch via the
   * file descriptor.
   */
  fd = xs_fileno(xs);
  while (1)
  {
    FD_ZERO(&set);
    FD_SET(fd, &set);
    /* Poll for data. */
    if ( select(fd + 1, &set, NULL, NULL, NULL) > 0
         && FD_ISSET(fd, &set))
    {
      /* num_strings will be set to the number of elements in vec
       * (typically, 2 - the watched path and the token) */
      vec = xs_read_watch(xs, &num_strings);
      if ( !vec ) {
        error("Unable to read watch");
        continue;
      }
      if (want_verbose)
        printf("Path changed: %s\n", vec[XS_WATCH_PATH]);
      /* Prepare a transaction and do a read. */
      th = xs_transaction_start(xs);
      buf = xs_read(xs, th, vec[XS_WATCH_PATH], &len);
      xs_transaction_end(xs, th, false);
      if (buf)
      {
        if (last_value && strcmp(buf, last_value) == 0) {
          if (want_verbose)
            printf("Value did not change\n");
          continue;
        }
      
        if (want_verbose)
          printf("New value: %s\n", buf);
          
        if (program) {
          pid = fork();
          if (pid == 0) {
            setenv("XENSTORE_WATCH_PATH", vec[XS_WATCH_PATH], 1);
            setenv("XENSTORE_WATCH_VALUE", buf, 1);
            for (i=0; arguments[i]; i++) {
              if (strcmp(arguments[i], "%v") == 0)
                arguments[i] = buf;
              else if (strcmp(arguments[i], "%p") == 0)
                arguments[i] = vec[XS_WATCH_PATH];
            }
            execvp(program, arguments);
            error("Unable to start program");
            exit(1);
          } else {
            waitpid(pid, &status, 0);
          }
        } else {
          if (!want_verbose)
            printf("%s\n", buf);
        }
        
        if (last_value)
          free(last_value);
        last_value = buf;
      }
    }
  }
  /* Cleanup */
  close(fd);
  xs_daemon_close(xs);
  free(path);

  exit(0);
}
Esempio n. 25
0
int main(int argc, char *argv[])
{
    char *devname;
    tapdev_info_t *ctlinfo;
    int tap_pfd, store_pfd, xs_fd, ret, timeout, pfd_count, count=0;
    struct xs_handle *h;
    struct pollfd  pfd[NUM_POLL_FDS];
    pid_t process;
    char buf[128];

    __init_blkif();
    snprintf(buf, sizeof(buf), "BLKTAPCTRL[%d]", getpid());
    openlog(buf, LOG_CONS|LOG_ODELAY, LOG_DAEMON);
    if (daemon(0,0)) {
        DPRINTF("daemon failed (%d)\n", errno);
        goto open_failed;
    }

    print_drivers();
    init_driver_list();
    init_rng();

    register_new_blkif_hook(blktapctrl_new_blkif);
    register_new_devmap_hook(map_new_blktapctrl);
    register_new_unmap_hook(unmap_blktapctrl);

    ctlfd = blktap_interface_open();
    if (ctlfd < 0) {
        DPRINTF("couldn't open blktap interface\n");
        goto open_failed;
    }

#ifdef MEMSHR
    memshr_daemon_initialize();
#endif

retry:
    /* Set up store connection and watch. */
    h = xs_daemon_open();
    if (h == NULL) {
        DPRINTF("xs_daemon_open failed -- "
                "is xenstore running?\n");
        if (count < MAX_ATTEMPTS) {
            count++;
            sleep(2);
            goto retry;
        } else goto open_failed;
    }

    ret = setup_probe_watch(h);
    if (ret != 0) {
        DPRINTF("Failed adding device probewatch\n");
        xs_daemon_close(h);
        goto open_failed;
    }

    ioctl(ctlfd, BLKTAP_IOCTL_SETMODE, BLKTAP_MODE_INTERPOSE );

    process = getpid();
    write_pidfile(process);
    ret = ioctl(ctlfd, BLKTAP_IOCTL_SENDPID, process );

    /*Static pollhooks*/
    pfd_count = 0;
    tap_pfd = pfd_count++;
    pfd[tap_pfd].fd = ctlfd;
    pfd[tap_pfd].events = POLLIN;

    store_pfd = pfd_count++;
    pfd[store_pfd].fd = xs_fileno(h);
    pfd[store_pfd].events = POLLIN;

    while (run) {
        timeout = 1000; /*Milliseconds*/
        ret = poll(pfd, pfd_count, timeout);

        if (ret > 0) {
            if (pfd[store_pfd].revents) {
                ret = xs_fire_next_watch(h);
            }
        }
    }

    xs_daemon_close(h);
    ioctl(ctlfd, BLKTAP_IOCTL_SETMODE, BLKTAP_MODE_PASSTHROUGH );
    close(ctlfd);
    closelog();

    return 0;

open_failed:
    DPRINTF("Unable to start blktapctrl\n");
    closelog();
    return -1;
}
Esempio n. 26
0
int
main (int argc, char **argv)
{
        data_t data = { 0, };
        int retval = EXIT_SUCCESS, i = 0, cat_result = 0;

        openlog (argv[0], LOG_NOWAIT | LOG_PID, LOG_DAEMON);
        if (argc < 2) {
                syslog (LOG_EMERG, "argc is less than 2, that's very wrong");
                retval = EXIT_FAILURE;
                goto exit;
        }
        if (is_selinux_enabled () != 1) {
                syslog (LOG_WARNING, "SELinux is disabled. sVirt will do nothing.");
                goto exit;
        }
        /*  not really parsing parameters, just going on position  */
        data.domid = atoi (argv [1]);
        syslog (LOG_INFO, "domain id: %d", data.domid);

        data.xsh = xs_daemon_open();
        if (data.xsh == NULL) {
                syslog (LOG_CRIT, "ERROR connecting to XenStore. Halting");
                retval = EXIT_FAILURE;
                goto exit;
        }
        /*  get files that we need to relabele  */
        data.files = get_writable_files (data.xsh, data.domid);
        if (data.files == NULL) {
                syslog (LOG_CRIT, "ERROR getting files. Halting");
                retval = EXIT_FAILURE;
                goto exit_session;
        }
        for (i = 0; data.files [i] != NULL; ++i)
                syslog (LOG_INFO, "got file: %s", data.files [i]);
        /*  get category for our domid and save it to xenstore  */
        cat_result = create_category (data.xsh);
        if (cat_result < 0) {
                syslog (LOG_CRIT, "ERROR generating unique category. Halting");
                retval = EXIT_FAILURE;
                goto exit_files;
        }
        data.category = cat_result;
        syslog (LOG_INFO, "got unique mcs: %d", data.category);
        if (set_domid_category (data.xsh, data.domid, data.category) == false) {
                syslog (LOG_CRIT, "ERROR setting category. Halting");
                retval = EXIT_FAILURE;
                goto exit_files;
        }
        /*  SELinux stuff  */
        /*  get SELinux default contexts  */
        if (get_default_contexts (&data) != 0) {
                syslog (LOG_CRIT, "ERROR getting default contexts. Halting");
                retval = EXIT_FAILURE;
                goto exit_files;
        }
        /*  label files  */
        if (file_con_fixup (&data) != 0) {
                syslog (LOG_CRIT,
                        "ERROR setting contexts for VM device files. Halting");
                retval = EXIT_FAILURE;
                goto exit_files;
        }
        /*  Set Execution Context  */
        if (set_exec_context (&data) != true) {
                syslog (LOG_CRIT,
                        "ERROR setting context to %s for qemu execution: %s. Halting",
                        strerror (errno));
                retval = EXIT_FAILURE;
                goto exit_files;
        }
        syslog (LOG_INFO, "Successfully set set MCS label %d for domid %d",
                data.category, data.domid);
exit_files:
        if (data.files != NULL) {
                for (i = 0; data.files [i] != NULL; ++i)
                        free (data.files [i]);
                free (data.files);
        }
exit_session:
        if (data.xsh != NULL) 
                xs_daemon_close (data.xsh);
exit:
        closelog ();
        /*  execute the real qemu if no previous errors prevent it  */
        if (retval != EXIT_FAILURE)
                exec_cmd (argv);
        exit (retval);
}
Esempio n. 27
0
int main(int argc, char *argv[])
{
    int rc;

    atexit(cleanup);

	xch = xc_interface_open(NULL, NULL, 0);
	if (xch == NULL)
    {
        perror("Failed to open xc interface");
        return 1;
    }

	xce_handle = xenevtchn_open(NULL, 0);
	if (xce_handle == NULL)
    {
        perror("Failed to open evtchn device");
        return 2;
    }

    xs_handle = xs_daemon_open();
    if (xs_handle == NULL)
    {
        perror("Failed to open xenstore connection");
        return 3;
    }

	if ((rc = xenevtchn_bind_virq(xce_handle, VIRQ_ENOMEM)) == -1)
    {
        perror("Failed to bind to domain exception virq port");
        return 4;
    }

    virq_port = rc;
    
    while(1)
    {
        evtchn_port_t port;

        if ((port = xenevtchn_pending(xce_handle)) == -1)
        {
            perror("Failed to listen for pending event channel");
            return 5;
        }

        if (port != virq_port)
        {
            char data[BUFSZ];
            snprintf(data, BUFSZ, "Wrong port, got %d expected %d", port, virq_port);
            perror(data);
            return 6;
        }

        if (xenevtchn_unmask(xce_handle, port) == -1)
        {
            perror("Failed to unmask port");
            return 7;
        }

        printf("Got a virq kick, time to get work\n");
        handle_low_mem();
    }

    return 0;
}
Esempio n. 28
0
/**
 * xenStoreOpen:
 * @conn: pointer to the connection block
 * @name: URL for the target, NULL for local
 * @flags: combination of virDrvOpenFlag(s)
 *
 * Connects to the Xen hypervisor.
 *
 * Returns 0 or -1 in case of error.
 */
int
xenStoreOpen(virConnectPtr conn,
             virConnectAuthPtr auth ATTRIBUTE_UNUSED,
             unsigned int flags)
{
    xenUnifiedPrivatePtr priv = conn->privateData;

    virCheckFlags(VIR_CONNECT_RO, -1);

    if (flags & VIR_CONNECT_RO)
        priv->xshandle = xs_daemon_open_readonly();
    else
        priv->xshandle = xs_daemon_open();

    if (priv->xshandle == NULL) {
        /*
         * not being able to connect via the socket as an unprivileged
         * user is rather normal, this should fallback to the proxy (or
         * remote) mechanism.
         */
        if (xenHavePrivilege()) {
            virReportError(VIR_ERR_NO_XEN,
                           "%s", _("failed to connect to Xen Store"));
        }
        return -1;
    }

    /* Init activeDomainList */
    if (VIR_ALLOC(priv->activeDomainList) < 0)
        return -1;

    /* Init watch list before filling in domInfoList,
       so we can know if it is the first time through
       when the callback fires */
    if (VIR_ALLOC(priv->xsWatchList) < 0)
        return -1;

    /* This will get called once at start */
    if (xenStoreAddWatch(conn, "@releaseDomain",
                         "releaseDomain", xenStoreDomainReleased, priv) < 0)
    {
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       "%s", _("adding watch @releaseDomain"));
        return -1;
    }

    /* The initial call of this will fill domInfoList */
    if (xenStoreAddWatch(conn, "@introduceDomain",
                         "introduceDomain", xenStoreDomainIntroduced, priv) < 0)
    {
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       "%s", _("adding watch @introduceDomain"));
        return -1;
    }

    /* Add an event handle */
    if ((priv->xsWatch = virEventAddHandle(xs_fileno(priv->xshandle),
                                           VIR_EVENT_HANDLE_READABLE,
                                           xenStoreWatchEvent,
                                           conn,
                                           NULL)) < 0)
        VIR_DEBUG("Failed to add event handle, disabling events");

    return 0;
}