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; }
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; }
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; }
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; }
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; }
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; }
/* * 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; }
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); }
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; }
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; }
//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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
/* 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; }
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; }
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); }
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; }
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); }
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; }
/** * 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; }