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; }
static int con_init(struct XenDevice *xendev) { struct XenConsole *con = container_of(xendev, struct XenConsole, xendev); char *type, *dom; /* setup */ dom = xs_get_domain_path(xenstore, con->xendev.dom); if (!xendev->dev) snprintf(con->console, sizeof(con->console), "%s/console", dom); else snprintf(con->console, sizeof(con->console), "%s/device/console/%d", dom, xendev->dev); free(dom); type = xenstore_read_str(con->console, "type"); if (!type || 0 != strcmp(type, "ioemu")) { xen_be_printf(xendev, 1, "not for me (type=%s)\n", type); if (type) qemu_free(type); return -1; } qemu_free(type); if (!serial_hds[con->xendev.dev]) xen_be_printf(xendev, 1, "WARNING: serial line %d not configured\n", con->xendev.dev); else con->chr = serial_hds[con->xendev.dev]; return 0; }
static int con_init(struct XenDevice *xendev) { struct XenConsole *con = container_of(xendev, struct XenConsole, xendev); char *type, *dom, label[32]; int ret = 0; const char *output; /* setup */ dom = xs_get_domain_path(xenstore, con->xendev.dom); snprintf(con->console, sizeof(con->console), "%s/console", dom); free(dom); type = xenstore_read_str(con->console, "type"); if (!type || strcmp(type, "ioemu") != 0) { xen_be_printf(xendev, 1, "not for me (type=%s)\n", type); ret = -1; goto out; } output = xenstore_read_str(con->console, "output"); /* no Xen override, use qemu output device */ if (output == NULL) { con->chr = serial_hds[con->xendev.dev]; } else { snprintf(label, sizeof(label), "xencons%d", con->xendev.dev); con->chr = qemu_chr_new(label, output, NULL); } xenstore_store_pv_console_info(con->xendev.dev, con->chr); out: g_free(type); return ret; }
int xenstore_vm_write(int domid, char *key, char *value) { char *buf = NULL, *path = NULL; int rc = -1; if (xsh == NULL) goto out; path = xs_get_domain_path(xsh, domid); if (path == NULL) { fprintf(logfile, "xs_get_domain_path: error\n"); goto out; } pasprintf(&buf, "%s/vm", path); free(path); path = xs_read(xsh, XBT_NULL, buf, NULL); if (path == NULL) { fprintf(logfile, "xs_read(%s): read error\n", buf); goto out; } pasprintf(&buf, "%s/%s", path, key); rc = xs_write(xsh, XBT_NULL, buf, value, strlen(value)); if (rc == 0) { fprintf(logfile, "xs_write(%s, %s): write error\n", buf, key); goto out; } out: free(path); free(buf); return rc; }
char *xenstore_vm_read(int domid, char *key, unsigned int *len) { char *buf = NULL, *path = NULL, *value = NULL; if (xsh == NULL) goto out; path = xs_get_domain_path(xsh, domid); if (path == NULL) { fprintf(logfile, "xs_get_domain_path(%d): error\n", domid); goto out; } pasprintf(&buf, "%s/vm", path); free(path); path = xs_read(xsh, XBT_NULL, buf, NULL); if (path == NULL) { fprintf(logfile, "xs_read(%s): read error\n", buf); goto out; } pasprintf(&buf, "%s/%s", path, key); value = xs_read(xsh, XBT_NULL, buf, len); if (value == NULL) { fprintf(logfile, "xs_read(%s): read error\n", buf); goto out; } out: free(path); free(buf); return value; }
void xenstore_write_vncport(int display) { char *buf = NULL, *path; char *portstr = NULL; if (xsh == NULL) 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/console/vnc-port", path) == -1) goto out; if (pasprintf(&portstr, "%d", display) == -1) goto out; if (xs_write(xsh, XBT_NULL, buf, portstr, strlen(portstr)) == 0) fprintf(logfile, "xs_write() vncport failed\n"); out: free(portstr); free(buf); }
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; }
static int xen_config_dev_dirs(const char *ftype, const char *btype, int vdev, char *fe, char *be, int len) { char *dom; dom = xs_get_domain_path(xenstore, xen_domid); snprintf(fe, len, "%s/device/%s/%d", dom, ftype, vdev); free(dom); dom = xs_get_domain_path(xenstore, 0); snprintf(be, len, "%s/backend/%s/%d/%d", dom, btype, xen_domid, vdev); free(dom); xenstore_mkdir(fe, XS_PERM_READ | XS_PERM_WRITE); xenstore_mkdir(be, XS_PERM_READ); return 0; }
int get_dominfo(int domid, dominfo_t *di) { di->di_domid = domid; di->di_dompath = xs_get_domain_path(xs_handle, di->di_domid); if (!di->di_dompath) { xd_log(LOG_ERR, "Could not get domain %d path from xenstore", domid); return -ENOENT; } di->di_name = xasprintf("Domain-%d", domid); 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 xenstore_read_vncpasswd(int domid, char *pwbuf, size_t pwbuflen) { char *buf = NULL, *path, *uuid = NULL, *passwd = NULL; unsigned int i, len, rc = 0; if (xsh == NULL) { return -1; } path = xs_get_domain_path(xsh, domid); if (path == NULL) { fprintf(logfile, "xs_get_domain_path() error. domid %d.\n", domid); return -1; } pasprintf(&buf, "%s/vm", path); uuid = xs_read(xsh, XBT_NULL, buf, &len); if (uuid == NULL) { fprintf(logfile, "xs_read(): uuid get error. %s.\n", buf); free(path); return -1; } pasprintf(&buf, "%s/vncpasswd", uuid); passwd = xs_read(xsh, XBT_NULL, buf, &len); if (passwd == NULL) { fprintf(logfile, "xs_read(): vncpasswd get error. %s.\n", buf); pwbuf[0] = '\0'; free(uuid); free(path); return rc; } for (i=0; i<len && i<pwbuflen; i++) { pwbuf[i] = passwd[i]; } pwbuf[len < (pwbuflen-1) ? len : (pwbuflen-1)] = '\0'; passwd[0] = '\0'; pasprintf(&buf, "%s/vncpasswd", uuid); if (xs_write(xsh, XBT_NULL, buf, passwd, len) == 0) { fprintf(logfile, "xs_write() vncpasswd failed.\n"); rc = -1; } free(passwd); free(uuid); free(path); return rc; }
static int store_dev_info(int domid, CharDriverState *cs, const char *string) { struct xs_handle *xs = NULL; char *path = NULL; char *newpath = NULL; char *pts = NULL; int ret = -1; /* Only continue if we're talking to a pty. */ if (strncmp(cs->filename, "pty:", 4)) { return 0; } pts = cs->filename + 4; /* We now have everything we need to set the xenstore entry. */ xs = xs_open(0); if (xs == NULL) { fprintf(stderr, "Could not contact XenStore\n"); goto out; } path = xs_get_domain_path(xs, domid); if (path == NULL) { fprintf(stderr, "xs_get_domain_path() error\n"); goto out; } newpath = realloc(path, (strlen(path) + strlen(string) + strlen("/tty") + 1)); if (newpath == NULL) { fprintf(stderr, "realloc error\n"); goto out; } path = newpath; strcat(path, string); strcat(path, "/tty"); if (!xs_write(xs, XBT_NULL, path, pts, strlen(pts))) { fprintf(stderr, "xs_write for '%s' fail", string); goto out; } ret = 0; out: free(path); xs_close(xs); return ret; }
int xenstore_init(void) { unsigned int len, domid; char *buf; char *end; xs = xs_domain_open(); if (xs == NULL) { RTE_LOG(ERR, PMD,"%s: xs_domain_open failed\n", __func__); return -1; } buf = xs_read(xs, XBT_NULL, "domid", &len); if (buf == NULL) { RTE_LOG(ERR, PMD, "%s: failed read domid\n", __func__); return -1; } errno = 0; domid = strtoul(buf, &end, 0); if (errno != 0 || end == NULL || end == buf || domid == 0) return -1; RTE_LOG(INFO, PMD, "retrieved dom ID = %d\n", domid); dompath = xs_get_domain_path(xs, domid); if (dompath == NULL) return -1; xs_transaction_start(xs); /* When to stop transaction */ if (is_xenstore_cleaned_up == 0) { if (xenstore_cleanup()) return -1; is_xenstore_cleaned_up = 1; } return 0; }
static char *xenfb_path_in_dom(struct xs_handle *xsh, char *buf, size_t size, unsigned domid, const char *fmt, ...) { va_list ap; char *domp = xs_get_domain_path(xsh, domid); int n; if (domp == NULL) return NULL; n = snprintf(buf, size, "%s/", domp); free(domp); if (n >= size) return NULL; va_start(ap, fmt); n += vsnprintf(buf + n, size - n, fmt, ap); va_end(ap); if (n >= size) return NULL; return buf; }
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; }
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; }
void libxl__spawn_local_dm(libxl__egc *egc, libxl__dm_spawn_state *dmss) { /* convenience aliases */ const int domid = dmss->guest_domid; libxl__domain_build_state *const state = dmss->build_state; libxl__spawn_state *const spawn = &dmss->spawn; STATE_AO_GC(dmss->spawn.ao); libxl_ctx *ctx = CTX; libxl_domain_config *guest_config = dmss->guest_config; const libxl_domain_create_info *c_info = &guest_config->c_info; const libxl_domain_build_info *b_info = &guest_config->b_info; const libxl_vnc_info *vnc = libxl__dm_vnc(guest_config); char *path, *logfile; int logfile_w, null; int rc; char **args, **arg; xs_transaction_t t; char *vm_path; char **pass_stuff; const char *dm; if (libxl_defbool_val(b_info->device_model_stubdomain)) { abort(); } dm = libxl__domain_device_model(gc, b_info); if (!dm) { rc = ERROR_FAIL; goto out; } if (access(dm, X_OK) < 0) { LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "device model %s is not executable", dm); rc = ERROR_FAIL; goto out; } args = libxl__build_device_model_args(gc, dm, domid, guest_config, state); if (!args) { rc = ERROR_FAIL; goto out; } if (b_info->type == LIBXL_DOMAIN_TYPE_HVM) { path = xs_get_domain_path(ctx->xsh, domid); libxl__xs_write(gc, XBT_NULL, libxl__sprintf(gc, "%s/hvmloader/bios", path), "%s", libxl_bios_type_to_string(b_info->u.hvm.bios)); /* Disable relocating memory to make the MMIO hole larger * unless we're running qemu-traditional */ libxl__xs_write(gc, XBT_NULL, libxl__sprintf(gc, "%s/hvmloader/allow-memory-relocate", path), "%d", b_info->device_model_version==LIBXL_DEVICE_MODEL_VERSION_QEMU_XEN_TRADITIONAL); free(path); } path = libxl__sprintf(gc, "/local/domain/0/device-model/%d", domid); xs_mkdir(ctx->xsh, XBT_NULL, path); if (b_info->type == LIBXL_DOMAIN_TYPE_HVM && b_info->device_model_version == LIBXL_DEVICE_MODEL_VERSION_QEMU_XEN_TRADITIONAL) libxl__xs_write(gc, XBT_NULL, libxl__sprintf(gc, "%s/disable_pf", path), "%d", !libxl_defbool_val(b_info->u.hvm.xen_platform_pci)); libxl_create_logfile(ctx, libxl__sprintf(gc, "qemu-dm-%s", c_info->name), &logfile); logfile_w = open(logfile, O_WRONLY|O_CREAT|O_APPEND, 0644); free(logfile); null = open("/dev/null", O_RDONLY); const char *dom_path = libxl__xs_get_dompath(gc, domid); spawn->pidpath = GCSPRINTF("%s/%s", dom_path, "image/device-model-pid"); if (vnc && vnc->passwd) { /* This xenstore key will only be used by qemu-xen-traditionnal. * The code to supply vncpasswd to qemu-xen is later. */ retry_transaction: /* Find uuid and the write the vnc password to xenstore for qemu. */ t = xs_transaction_start(ctx->xsh); vm_path = libxl__xs_read(gc,t,libxl__sprintf(gc, "%s/vm", dom_path)); if (vm_path) { /* Now write the vncpassword into it. */ pass_stuff = libxl__calloc(gc, 3, sizeof(char *)); pass_stuff[0] = "vncpasswd"; pass_stuff[1] = vnc->passwd; libxl__xs_writev(gc,t,vm_path,pass_stuff); if (!xs_transaction_end(ctx->xsh, t, 0)) if (errno == EAGAIN) goto retry_transaction; } } LIBXL__LOG(CTX, XTL_DEBUG, "Spawning device-model %s with arguments:", dm); for (arg = args; *arg; arg++) LIBXL__LOG(CTX, XTL_DEBUG, " %s", *arg); spawn->what = GCSPRINTF("domain %d device model", domid); spawn->xspath = GCSPRINTF("/local/domain/0/device-model/%d/state", domid); spawn->timeout_ms = LIBXL_DEVICE_MODEL_START_TIMEOUT * 1000; spawn->pidpath = GCSPRINTF("%s/image/device-model-pid", dom_path); spawn->midproc_cb = libxl__spawn_record_pid; spawn->confirm_cb = device_model_confirm; spawn->failure_cb = device_model_startup_failed; spawn->detached_cb = device_model_detached; rc = libxl__spawn_spawn(egc, spawn); if (rc < 0) goto out_close; if (!rc) { /* inner child */ setsid(); libxl__exec(gc, null, logfile_w, logfile_w, dm, args, NULL); } rc = 0; out_close: close(null); close(logfile_w); out: if (rc) device_model_spawn_outcome(egc, dmss, rc); }
/* * dump metrics received from xenstore to the dest file */ int dump_xenstore_metrics(const char *dest_file) { char *buf = NULL, *path = NULL, *metrics = NULL; struct xs_handle *xsh = NULL; unsigned int len; int ret = 0; xmlParserCtxtPtr pctxt = NULL; xmlDocPtr doc = NULL; int domid; FILE *fp; if (dest_file) { fp = fopen(dest_file, "w"); if (fp == NULL) { libmsg("Error, unable to dump metrics from xenstore: %s\n", strerror(errno)); return -1; } } else { fp = stdout; } if ((domid = get_dom_id()) == -1) { libmsg("Unable to derive domID.\n" ); ret = -1; goto out; } xsh = xs_domain_open(); if (xsh == NULL) { libmsg("xs_domain_open() error. errno: %d.\n", errno); ret = -1; goto out; } path = xs_get_domain_path(xsh, domid); if (path == NULL) { libmsg("xs_get_domain_path() error. domid %d.\n", 0); ret = -1; goto out; } asprintf(&buf, "%s/metrics", path); metrics = xs_read(xsh, XBT_NULL, buf, &len); if (metrics == NULL) { libmsg("xs_read(): uuid get error. %s.\n", buf); ret = -1; goto out; } pctxt = xmlNewParserCtxt(); if (!pctxt || !pctxt->sax) { libmsg("%s(): failed to create parser \n", __func__); ret = -1; goto out; } doc = xmlCtxtReadMemory(pctxt, metrics, strlen(metrics), "mdisk.xml", NULL, XML_PARSE_NOENT | XML_PARSE_NONET | XML_PARSE_NOWARNING); if (!doc) { libmsg("%s(): libxml failed to xenstore metrics attribute\n", __func__); ret = -1; goto out; } xmlDocFormatDump(fp, doc, 1); out: if (fp && fp != stdout) fclose(fp); if (doc) xmlFreeDoc(doc); if (pctxt) xmlFreeParserCtxt(pctxt); free(path); free(buf); free(metrics); return ret; }
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; }
int xsd_provision_controller(struct xs_handle *xs, int domid) { xs_transaction_t t; struct xs_permissions xsperms[2]; xsperms[0].id = domid; xsperms[0].perms = XS_PERM_READ | XS_PERM_WRITE; struct stat buf; char s[MAX_PATH]; char s2[MAX_PATH]; char domname[20]; char backend[MAX_PATH]; char frontend[MAX_PATH]; int devno = 0; int result; char* home; char* dom0_home; int provision_status = 0; home = xs_get_domain_path(xs,domid); dom0_home = xs_get_domain_path(xs,0); retry_provision: /* printf("xsd_provision_controller Domain-%d, home %s, dom0_home %s\n", domid, home, dom0_home); */ /* * * Create the vxtcom_controller records Dom0 and the * target domain. The code that follows will: * * * Write the backend vxt controller entry and place it * in Dom-0. i.e. /local/domain/0 .. * * backend = "" * vxtcom_ctrlr = "" * <Domain-id> (9) = "" * <Device-id> (0) = "" * domain = <Domain name> "Domain-9" * frontend = "/local/domain/9/device/vxtcom_ctrlr/0" * frontend-id = "9" * state = "3" * version = "1" * * * Write the front end record in the target domain device * subdirectory: ... e.g. * * device = "" * vxtcom_ctrlr = "" * 0 = "" * backend = "/local/domain/0/backend/vxtcom_ctrlr/9/0" * backend-id = "0" * state = "1" */ t = xs_transaction_start(xs); /* printf("xsd_provision_controller Domain-%d, transaction token %d\n", domid, t); */ sprintf(backend, "%s/backend/vxtcom_ctrlr/%d/%d", dom0_home, domid, devno); sprintf(frontend, "%s/device/vxtcom_ctrlr/%d", home, devno); /* * Create Dom0 device directory for target domain: * ../device/vxtcom_ctrlr/ */ xs_mkdir(xs, t, backend); result = xs_set_permissions(xs, t, backend, xsperms, 1); /* printf("xsd_privision_controller: xs_set_permissions result %d\n", result); */ /* * create the target domain device record * /local/domain/<domain #>/device/vxtcom_ctrlr/<domain #>/backend = * "/local/domain/0/backend/vxtcom_ctrlr/<domain #>/0" * */ sprintf(s, "%s/backend", frontend); xs_write(xs, t, s, backend, strlen(backend)); /* * create target domian backend-id record: * /local/domain/<domain #>/device/vxtcom_ctrlr/<domain #>/backend = 0 * */ sprintf(s, "%s/backend-id", frontend); xs_write(xs, t, s, "0", 1); /* * create target domian state record: * /local/domain/<domain #>/device/vxtcom_ctrlr/<domain #>/state = 1 * */ sprintf(s, "%s/state", frontend); xs_write(xs, t, s, "1", 1); /* * create Dom0 domname (domain-name) record for target domain: * /local/domain/0/backend/vxtcom_ctrlr/<domain#>/0/domname * = Domain-<domain#> */ sprintf(domname, "Domain-%d", domid); sprintf(s, "%s/domain", backend); xs_write(xs, t, s, domname, strlen(domname)); /* * Create Dom0 target vxtctlr device record - "frontend" * * /local/domain/0/device/vxtcom_ctrlr/9/0/frontend = * /local/domain/<domain #>/device/vxtcom_ctrlr/0 * */ sprintf(s, "%s/frontend", backend); xs_write(xs, t, s, frontend, strlen(frontend)); /* * Create Dom0 target vxtctlr device record - "frontend-id" * * /local/domain/0/device/vxtcom_ctrlr/9/0/frontend-id = * <domid> e.g. 9 * */ sprintf(s, "%s/frontend-id", backend); sprintf(s2,"%d",domid); xs_write(xs, t, s, s2, strlen(s2)); /* * Create Dom0 target vxtctlr device record - "state" * * /local/domain/0/device/vxtcom_ctrlr/9/0/state = 1 * */ sprintf(s, "%s/state", backend); xs_write(xs, t, s, "1", 1); /* * Create Dom0 target vxtctlr device record - "frontend" * * /local/domain/0/device/vxtcom_ctrlr/<domain #>/0/frontend = * /local/domain/<domain #>/device/vxtcom_ctrlr/0 * */ sprintf(s, "%s/frontend", backend); xs_write(xs, t, s, frontend, strlen(frontend)); if(!xs_transaction_end(xs, t, 0)) { printf("xsd_privision_controller: xs_transaction_end failed\n"); goto retry_provision; } else { provision_status = 1; } free(home); free(dom0_home); return (provision_status); }
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; }