Exemple #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;
}
Exemple #2
0
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;
}
Exemple #3
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;
}
Exemple #4
0
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;
}
Exemple #5
0
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;
}
Exemple #6
0
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);
}
Exemple #7
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;
}
Exemple #8
0
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;
}
Exemple #10
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);
}
Exemple #11
0
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;
}
Exemple #12
0
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;
}
Exemple #14
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;
}
Exemple #15
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;
}
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;
}
Exemple #17
0
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);
}
Exemple #18
0
/*
 * 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;
 }
Exemple #20
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);
}
Exemple #21
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;
 }