Example #1
0
bool xenbus_create_request_node(void)
{
    bool ret;
    struct xs_permissions perms;
    
    assert(xsh != NULL);
    xs_rm(xsh, XBT_NULL, WATCH_NODE);
    ret = xs_mkdir(xsh, XBT_NULL, WATCH_NODE); 

    if (!ret) {
        printf("failed to created %s\n", WATCH_NODE);
        return false;
    }

    perms.id = 0;
    perms.perms = XS_PERM_WRITE;
    ret = xs_set_permissions(xsh, XBT_NULL, WATCH_NODE, &perms, 1);
    if (!ret) {
        printf("failed to set write permission on %s\n", WATCH_NODE);
        return false;
    }

    perms.perms = XS_PERM_READ;
    ret = xs_set_permissions(xsh, XBT_NULL, ROOT_NODE, &perms, 1);
    if (!ret) {
      printf("failed to set read permission on %s\n", ROOT_NODE);
    }
    return ret;
}
Example #2
0
File: libxl_dm.c Project: jsgf/xen
static int libxl__write_stub_dmargs(libxl__gc *gc,
                                    int dm_domid, int guest_domid,
                                    char **args)
{
    libxl_ctx *ctx = libxl__gc_owner(gc);
    int i;
    char *vm_path;
    char *dmargs, *path;
    int dmargs_size;
    struct xs_permissions roperm[2];
    xs_transaction_t t;

    roperm[0].id = 0;
    roperm[0].perms = XS_PERM_NONE;
    roperm[1].id = dm_domid;
    roperm[1].perms = XS_PERM_READ;

    vm_path = libxl__xs_read(gc, XBT_NULL, libxl__sprintf(gc, "/local/domain/%d/vm", guest_domid));

    i = 0;
    dmargs_size = 0;
    while (args[i] != NULL) {
        dmargs_size = dmargs_size + strlen(args[i]) + 1;
        i++;
    }
    dmargs_size++;
    dmargs = (char *) malloc(dmargs_size);
    i = 1;
    dmargs[0] = '\0';
    while (args[i] != NULL) {
        if (strcmp(args[i], "-sdl") && strcmp(args[i], "-M") && strcmp(args[i], "xenfv")) {
            strcat(dmargs, " ");
            strcat(dmargs, args[i]);
        }
        i++;
    }
    path = libxl__sprintf(gc, "%s/image/dmargs", vm_path);

retry_transaction:
    t = xs_transaction_start(ctx->xsh);
    xs_write(ctx->xsh, t, path, dmargs, strlen(dmargs));
    xs_set_permissions(ctx->xsh, t, path, roperm, ARRAY_SIZE(roperm));
    xs_set_permissions(ctx->xsh, t, libxl__sprintf(gc, "%s/rtc/timeoffset", vm_path), roperm, ARRAY_SIZE(roperm));
    if (!xs_transaction_end(ctx->xsh, t, 0))
        if (errno == EAGAIN)
            goto retry_transaction;
    free(dmargs);
    return 0;
}
Example #3
0
int setFullPerm(char *path){
  struct xs_permissions perms = {.id = 0, .perms = XS_PERM_READ|XS_PERM_WRITE}; // Full Permissions
  if(!xs_set_permissions(xsd, 0, path, &perms, 1)){
    printf("Could not set directory permissions.\n");
    return 3;
  }
  return 0;
}

int main(int argc, char **argv)
{
  unsigned int num, i;
  char **list;
  bool res;

  xsd = xs_open(0);
  
  mkdir("/rendezvous");
  mkdir("/transport");

  setFullPerm("/rendezvous");
  setFullPerm("/transport");
  setFullPerm("/local/domain");
    
  printf("Base directory added. New root directory:\n");
  list = xs_directory(xsd, 0, "/", &num);
  for(i = 0; i < num; i++)
    printf("  /%s\n", list[i]);

  return 0;
}
Example #4
0
File: init.c Project: Fantu/Xen
static int init_xs_srv(struct libxenvchan *ctrl, int domain, const char* xs_base, int ring_ref)
{
	int ret = -1;
	struct xs_handle *xs;
	struct xs_permissions perms[2];
	char buf[64];
	char ref[16];
	char* domid_str = NULL;
	xs = xs_domain_open();
	if (!xs)
		goto fail;
	domid_str = xs_read(xs, 0, "domid", NULL);
	if (!domid_str)
		goto fail_xs_open;

	// owner domain is us
	perms[0].id = atoi(domid_str);
	// permissions for domains not listed = none
	perms[0].perms = XS_PERM_NONE;
	// other domains
	perms[1].id = domain;
	perms[1].perms = XS_PERM_READ;

	snprintf(ref, sizeof ref, "%d", ring_ref);
	snprintf(buf, sizeof buf, "%s/ring-ref", xs_base);
	if (!xs_write(xs, 0, buf, ref, strlen(ref)))
		goto fail_xs_open;
	if (!xs_set_permissions(xs, 0, buf, perms, 2))
		goto fail_xs_open;

	snprintf(ref, sizeof ref, "%d", ctrl->event_port);
	snprintf(buf, sizeof buf, "%s/event-channel", xs_base);
	if (!xs_write(xs, 0, buf, ref, strlen(ref)))
		goto fail_xs_open;
	if (!xs_set_permissions(xs, 0, buf, perms, 2))
		goto fail_xs_open;

	ret = 0;
 fail_xs_open:
	free(domid_str);
	xs_daemon_close(xs);
 fail:
	return ret;
}
Example #5
0
ivc_connection_t *makeConnection(libIVC_t *iface,
                                 char *name,
                                 ivc_contype_t type,
                                 float per)
{
  char *key, *val, *rdomstr = NULL, *rrefstr = NULL, *rpstr = NULL;
  uint32_t me, other, num_refs, *grants;
  struct xs_permissions perms;
  ivc_connection_t *res;
  evtchn_port_t port;
  unsigned int len;
  void *buffer;

  /* me <- xsGetDomId */
  me = getMyDomId(iface);
  /* removePath xs targetPath */
  ASPRINTF(&key, "/rendezvous/%s", name);
  xs_rm(iface->xs, 0, key);
  /* xsMakeDirectory xs targetPath */
  xs_mkdir(iface->xs, 0, key);
  /* xsSetPermissions xs targetPath [ReadWritePerm me] */
  perms.id = me;
  perms.perms = XS_PERM_READ | XS_PERM_WRITE;
  xs_set_permissions(iface->xs, 0, key, &perms, 1);
  /* xsWrite xs (targetPath ++ "/LeftDomId") (show me) */
  free(key), ASPRINTF(&key, "/rendezvous/%s/LeftDomId", name);
             ASPRINTF(&val, "dom%d", me);
  xs_write(iface->xs, 0, key, val, strlen(val));
  /* other <- read <$> waitForKey xs (targetPAth ++ "/RightDomId") */
  free(key), ASPRINTF(&key, "/rendezvous/%s/RightDomId", name);
  while(!rdomstr) { rdomstr = xs_read(iface->xs, 0, key, &len); };
  sscanf(rdomstr, "dom%d", &other);
  /* grants <- read <$> waitForKey xs (targetPAth ++ "/RightGrantRefs") */
  free(key), ASPRINTF(&key, "/rendezvous/%s/RightGrantRefs", name);
  while(!rrefstr) { rrefstr = xs_read(iface->xs, 0, key, &len); }
  grants = parseRefs(rrefstr, &num_refs);
  buffer = xc_gnttab_map_domain_grant_refs(iface->gt, num_refs, other, grants,
                                           PROT_READWRITE);
  assert(buffer);
  /* ports  <- read <$> waitForKey xs (targetPAth ++ "/RightPorts") */
  free(key), ASPRINTF(&key, "/rendezvous/%s/RightPorts", name);
  while(!rpstr) { rpstr = xs_read(iface->xs, 0, key, &len); }
  sscanf(rpstr, "[echan:%d]", &port);
  port = xc_evtchn_bind_interdomain(iface->ec, other, port);
  assert(port >= 0);
  /* res <- acceptConnection other grants ports extra */
  res = buildChannel(iface, other, type, port, buffer, num_refs * 4096, per, 0);
  /* xsWrite xs (targetPath ++ "/LeftConnectionConfirmed") "True" */
  free(key), ASPRINTF(&key, "/rendezvous/%s/LeftConnectionConfirmed", name);
  free(val), ASPRINTF(&val, "True");
  xs_write(iface->xs, 0, key, val, strlen(val));
  /* return res */
  return res;
}
Example #6
0
int
tapback_device_printf(vbd_t * const device, xs_transaction_t xst,
        const char * const key, const bool mkread, const char * const fmt, ...)
{
    va_list ap;
    int err = 0;
    char *path = NULL, *val = NULL;
    bool nerr = false;

    ASSERT(device);
    ASSERT(key);

    if (-1 == asprintf(&path, "%s/%s/%s", device->backend->path,
                device->name, key)) {
        err = -errno;
        goto fail;
    }

    va_start(ap, fmt);
    if (-1 == vasprintf(&val, fmt, ap))
        val = NULL;
    va_end(ap);

    if (!val) {
        err = -errno;
        goto fail;
    }

    if (!(nerr = xs_write(device->backend->xs, xst, path, val, strlen(val)))) {
        err = -errno;
        goto fail;
    }

    if (mkread) {
        struct xs_permissions perms[2] = {
			{device->backend->domid, XS_PERM_NONE},
			{device->domid, XS_PERM_READ}
        };

        if (!(nerr = xs_set_permissions(device->backend->xs, xst, path, perms,
                        ARRAY_SIZE(perms)))) {
            err = -errno;
            goto fail;
        }
    }

fail:
    free(path);
    free(val);

    return err;
}
Example #7
0
void xs_node_create(struct xs_handle *xsh, xs_transaction_t tid,
                    const char *node, struct xs_permissions perms[],
                    unsigned int nr_perms, Error **errp)
{
    trace_xs_node_create(node);

    if (!xs_write(xsh, tid, node, "", 0)) {
        error_setg_errno(errp, errno, "failed to create node '%s'", node);
        return;
    }

    if (!xs_set_permissions(xsh, tid, node, perms, nr_perms)) {
        error_setg_errno(errp, errno, "failed to set node '%s' permissions",
                         node);
    }
}
Example #8
0
static void
do_chmod(char *path, struct xs_permissions *perms, int nperms, int upto,
	 int recurse, struct xs_handle *xsh, xs_transaction_t xth)
{
    int ret;

    if (!path[0])
	return;

    ret = xs_set_permissions(xsh, xth, path, perms, nperms);
    if (!ret)
	err(1, "Error occurred setting permissions on '%s'", path);

    if (upto) {
	/* apply same permissions to all parent entries: */
	char *path_sep_ptr = strrchr(path, PATH_SEP);
	if (!path_sep_ptr)
	    errx(1, "Unable to locate path separator '%c' in '%s'",
		 PATH_SEP, path);
	
	*path_sep_ptr = '\0'; /* truncate path */
	
	do_chmod(path, perms, nperms, 1, 0, xsh, xth);

	*path_sep_ptr = PATH_SEP;
    }

    if (recurse) {
	char buf[MAX_PATH_LEN];

	/* apply same permissions to all child entries: */
	unsigned int xsval_n;
	char **xsval = xs_directory(xsh, xth, path, &xsval_n);

	if (xsval) {
	    int i;
	    for (i = 0; i < xsval_n; i++) {
		snprintf(buf, MAX_PATH_LEN, "%s/%s", path, xsval[i]);

		do_chmod(buf, perms, nperms, 0, 1, xsh, xth);
	    }

	    free(xsval);
	}
    }
}
Example #9
0
/*
 * Create a new directory in Xenstore
 */
static int
xs_add_dir(xs_transaction_t xt, char *path, int d0, int p0, int d1, int p1)
{
  struct xs_permissions perms[2];

  xd_log(LOG_VERBOSE_DEBUG, "Making %s in XenStore", path);
  if (xs_mkdir(xs_handle, xt, path) == false) {
    xd_log(LOG_ERR, "XenStore error mkdir()ing %s", path);
    return (-1);
  }

  perms[0].perms = p0;
  perms[0].id = d0;
  perms[1].perms = p1;
  perms[1].id = d1;
  if (xs_set_permissions(xs_handle, xt, path, perms, 2) == false) {
    xd_log(LOG_ERR, "XenStore error setting permissions on %s",
	   path);
    xs_remove(xt, path);
    return (-1);
  }

  return (0);
}
Example #10
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);
}
Example #11
0
File: libxl_dm.c Project: jsgf/xen
void libxl__spawn_stub_dm(libxl__egc *egc, libxl__stub_dm_spawn_state *sdss)
{
    STATE_AO_GC(sdss->dm.spawn.ao);
    libxl_ctx *ctx = libxl__gc_owner(gc);
    int ret;
    libxl_device_vfb *vfb;
    libxl_device_vkb *vkb;
    char **args;
    struct xs_permissions perm[2];
    xs_transaction_t t;

    /* convenience aliases */
    libxl_domain_config *const dm_config = &sdss->dm_config;
    libxl_domain_config *const guest_config = sdss->dm.guest_config;
    const int guest_domid = sdss->dm.guest_domid;
    libxl__domain_build_state *const d_state = sdss->dm.build_state;
    libxl__domain_build_state *const stubdom_state = &sdss->dm_state;

    if (guest_config->b_info.device_model_version !=
        LIBXL_DEVICE_MODEL_VERSION_QEMU_XEN_TRADITIONAL) {
        ret = ERROR_INVAL;
        goto out;
    }

    sdss->pvqemu.guest_domid = 0;

    libxl_domain_create_info_init(&dm_config->c_info);
    dm_config->c_info.type = LIBXL_DOMAIN_TYPE_PV;
    dm_config->c_info.name = libxl__stub_dm_name(gc,
                                    libxl__domid_to_name(gc, guest_domid));
    dm_config->c_info.ssidref = guest_config->b_info.device_model_ssidref;

    libxl_uuid_generate(&dm_config->c_info.uuid);

    libxl_domain_build_info_init(&dm_config->b_info);
    libxl_domain_build_info_init_type(&dm_config->b_info, LIBXL_DOMAIN_TYPE_PV);

    dm_config->b_info.max_vcpus = 1;
    dm_config->b_info.max_memkb = 32 * 1024;
    dm_config->b_info.target_memkb = dm_config->b_info.max_memkb;

    dm_config->b_info.u.pv.features = "";

    dm_config->b_info.device_model_version =
        guest_config->b_info.device_model_version;
    dm_config->b_info.device_model =
        guest_config->b_info.device_model;
    dm_config->b_info.extra = guest_config->b_info.extra;
    dm_config->b_info.extra_pv = guest_config->b_info.extra_pv;
    dm_config->b_info.extra_hvm = guest_config->b_info.extra_hvm;

    dm_config->disks = guest_config->disks;
    dm_config->num_disks = guest_config->num_disks;

    libxl__dm_vifs_from_hvm_guest_config(gc, guest_config, dm_config);

    dm_config->c_info.run_hotplug_scripts =
        guest_config->c_info.run_hotplug_scripts;

    ret = libxl__domain_create_info_setdefault(gc, &dm_config->c_info);
    if (ret) goto out;
    ret = libxl__domain_build_info_setdefault(gc, &dm_config->b_info);
    if (ret) goto out;

    GCNEW(vfb);
    GCNEW(vkb);
    libxl__vfb_and_vkb_from_hvm_guest_config(gc, guest_config, vfb, vkb);
    dm_config->vfbs = vfb;
    dm_config->num_vfbs = 1;
    dm_config->vkbs = vkb;
    dm_config->num_vkbs = 1;

    stubdom_state->pv_kernel.path
        = libxl__abs_path(gc, "ioemu-stubdom.gz", libxl__xenfirmwaredir_path());
    stubdom_state->pv_cmdline = libxl__sprintf(gc, " -d %d", guest_domid);
    stubdom_state->pv_ramdisk.path = "";

    /* fixme: this function can leak the stubdom if it fails */
    ret = libxl__domain_make(gc, &dm_config->c_info, &sdss->pvqemu.guest_domid);
    if (ret)
        goto out;
    uint32_t dm_domid = sdss->pvqemu.guest_domid;
    ret = libxl__domain_build(gc, dm_config, dm_domid, stubdom_state);
    if (ret)
        goto out;

    args = libxl__build_device_model_args(gc, "stubdom-dm", guest_domid,
                                          guest_config, d_state);
    if (!args) {
        ret = ERROR_FAIL;
        goto out;
    }

    libxl__write_stub_dmargs(gc, dm_domid, guest_domid, args);
    libxl__xs_write(gc, XBT_NULL,
                   libxl__sprintf(gc, "%s/image/device-model-domid",
                                  libxl__xs_get_dompath(gc, guest_domid)),
                   "%d", dm_domid);
    libxl__xs_write(gc, XBT_NULL,
                   libxl__sprintf(gc, "%s/target",
                                  libxl__xs_get_dompath(gc, dm_domid)),
                   "%d", guest_domid);
    ret = xc_domain_set_target(ctx->xch, dm_domid, guest_domid);
    if (ret<0) {
        LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR,
                         "setting target domain %d -> %d",
                         dm_domid, guest_domid);
        ret = ERROR_FAIL;
        goto out;
    }
    xs_set_target(ctx->xsh, dm_domid, guest_domid);

    perm[0].id = dm_domid;
    perm[0].perms = XS_PERM_NONE;
    perm[1].id = guest_domid;
    perm[1].perms = XS_PERM_READ;
retry_transaction:
    t = xs_transaction_start(ctx->xsh);
    xs_mkdir(ctx->xsh, t,
        libxl__sprintf(gc, "/local/domain/0/device-model/%d", guest_domid));
    xs_set_permissions(ctx->xsh, t,
        libxl__sprintf(gc, "/local/domain/0/device-model/%d", guest_domid),
                       perm, ARRAY_SIZE(perm));
    if (!xs_transaction_end(ctx->xsh, t, 0))
        if (errno == EAGAIN)
            goto retry_transaction;

    libxl__multidev_begin(ao, &sdss->multidev);
    sdss->multidev.callback = spawn_stub_launch_dm;
    libxl__add_disks(egc, ao, dm_domid, dm_config, &sdss->multidev);
    libxl__multidev_prepared(egc, &sdss->multidev, 0);

    return;

out:
    assert(ret);
    spawn_stubdom_pvqemu_cb(egc, &sdss->pvqemu, ret);
}
Example #12
0
/*
 * Preserves a domain but rewrites xenstore etc to make it unique so
 * that the domain can be restarted.
 *
 * Does not modify info so that it may be reused.
 */
int libxl_domain_preserve(libxl_ctx *ctx, uint32_t domid,
                          libxl_domain_create_info *info, const char *name_suffix, libxl_uuid new_uuid)
{
    GC_INIT(ctx);
    struct xs_permissions roperm[2];
    xs_transaction_t t;
    char *preserved_name;
    char *uuid_string;
    char *vm_path;
    char *dom_path;

    int rc;

    preserved_name = GCSPRINTF("%s%s", info->name, name_suffix);
    if (!preserved_name) {
        GC_FREE;
        return ERROR_NOMEM;
    }

    uuid_string = libxl__uuid2string(gc, new_uuid);
    if (!uuid_string) {
        GC_FREE;
        return ERROR_NOMEM;
    }

    dom_path = libxl__xs_get_dompath(gc, domid);
    if (!dom_path) {
        GC_FREE;
        return ERROR_FAIL;
    }

    vm_path = GCSPRINTF("/vm/%s", uuid_string);
    if (!vm_path) {
        GC_FREE;
        return ERROR_FAIL;
    }

    roperm[0].id = 0;
    roperm[0].perms = XS_PERM_NONE;
    roperm[1].id = domid;
    roperm[1].perms = XS_PERM_READ;

 retry_transaction:
    t = xs_transaction_start(ctx->xsh);

    xs_rm(ctx->xsh, t, vm_path);
    xs_mkdir(ctx->xsh, t, vm_path);
    xs_set_permissions(ctx->xsh, t, vm_path, roperm, ARRAY_SIZE(roperm));

    xs_write(ctx->xsh, t, GCSPRINTF("%s/vm", dom_path), vm_path, strlen(vm_path));
    rc = libxl__domain_rename(gc, domid, info->name, preserved_name, t);
    if (rc) {
        GC_FREE;
        return rc;
    }

    xs_write(ctx->xsh, t, GCSPRINTF("%s/uuid", vm_path), uuid_string, strlen(uuid_string));

    if (!xs_transaction_end(ctx->xsh, t, 0))
        if (errno == EAGAIN)
            goto retry_transaction;

    GC_FREE;
    return 0;
}
Example #13
0
static int libxl_create_stubdom(libxl_ctx *ctx,
                                libxl_device_model_info *info,
                                libxl_device_disk *disks, int num_disks,
                                libxl_device_nic *vifs, int num_vifs,
                                libxl_device_vfb *vfb,
                                libxl_device_vkb *vkb,
                                libxl__device_model_starting **starting_r)
{
    libxl__gc gc = LIBXL_INIT_GC(ctx);
    int i, num_console = STUBDOM_SPECIAL_CONSOLES, ret;
    libxl_device_console *console;
    libxl_domain_create_info c_info;
    libxl_domain_build_info b_info;
    libxl_domain_build_state state;
    uint32_t domid;
    char **args;
    struct xs_permissions perm[2];
    xs_transaction_t t;
    libxl__device_model_starting *dm_starting = 0;

    args = libxl_build_device_model_args(&gc, info, vifs, num_vifs);
    if (!args) {
        ret = ERROR_FAIL;
        goto out;
    }

    memset(&c_info, 0x00, sizeof(libxl_domain_create_info));
    c_info.hvm = 0;
    c_info.name = libxl__sprintf(&gc, "%s-dm", libxl__domid_to_name(&gc, info->domid));

    libxl_uuid_copy(&c_info.uuid, &info->uuid);

    memset(&b_info, 0x00, sizeof(libxl_domain_build_info));
    b_info.max_vcpus = 1;
    b_info.max_memkb = 32 * 1024;
    b_info.target_memkb = b_info.max_memkb;
    b_info.kernel.path = libxl__abs_path(&gc, "ioemu-stubdom.gz", libxl_xenfirmwaredir_path());
    b_info.u.pv.cmdline = libxl__sprintf(&gc, " -d %d", info->domid);
    b_info.u.pv.ramdisk.path = "";
    b_info.u.pv.features = "";
    b_info.hvm = 0;

    /* fixme: this function can leak the stubdom if it fails */

    ret = libxl__domain_make(ctx, &c_info, &domid);
    if (ret)
        goto out_free;
    ret = libxl__domain_build(ctx, &b_info, domid, &state);
    if (ret)
        goto out_free;

    libxl_write_dmargs(ctx, domid, info->domid, args);
    libxl__xs_write(&gc, XBT_NULL,
                   libxl__sprintf(&gc, "%s/image/device-model-domid", libxl__xs_get_dompath(&gc, info->domid)),
                   "%d", domid);
    libxl__xs_write(&gc, XBT_NULL,
                   libxl__sprintf(&gc, "%s/target", libxl__xs_get_dompath(&gc, domid)),
                   "%d", info->domid);
    ret = xc_domain_set_target(ctx->xch, domid, info->domid);
    if (ret<0) {
        LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "setting target domain %d -> %d", domid, info->domid);
        ret = ERROR_FAIL;
        goto out_free;
    }
    xs_set_target(ctx->xsh, domid, info->domid);

    perm[0].id = domid;
    perm[0].perms = XS_PERM_NONE;
    perm[1].id = info->domid;
    perm[1].perms = XS_PERM_READ;
retry_transaction:
    t = xs_transaction_start(ctx->xsh);
    xs_mkdir(ctx->xsh, t, libxl__sprintf(&gc, "/local/domain/0/device-model/%d", info->domid));
    xs_set_permissions(ctx->xsh, t, libxl__sprintf(&gc, "/local/domain/0/device-model/%d", info->domid), perm, ARRAY_SIZE(perm));
    xs_mkdir(ctx->xsh, t, libxl__sprintf(&gc, "/local/domain/%d/device/vfs", domid));
    xs_set_permissions(ctx->xsh, t, libxl__sprintf(&gc, "/local/domain/%d/device/vfs",domid), perm, ARRAY_SIZE(perm));
    if (!xs_transaction_end(ctx->xsh, t, 0))
        if (errno == EAGAIN)
            goto retry_transaction;

    for (i = 0; i < num_disks; i++) {
        disks[i].domid = domid;
        ret = libxl_device_disk_add(ctx, domid, &disks[i]);
        if (ret)
            goto out_free;
    }
    for (i = 0; i < num_vifs; i++) {
        vifs[i].domid = domid;
        ret = libxl_device_nic_add(ctx, domid, &vifs[i]);
        if (ret)
            goto out_free;
    }
    vfb->domid = domid;
    ret = libxl_device_vfb_add(ctx, domid, vfb);
    if (ret)
        goto out_free;
    vkb->domid = domid;
    ret = libxl_device_vkb_add(ctx, domid, vkb);
    if (ret)
        goto out_free;

    if (info->serial)
        num_console++;

    console = libxl__calloc(&gc, num_console, sizeof(libxl_device_console));
    if (!console) {
        ret = ERROR_NOMEM;
        goto out_free;
    }

    for (i = 0; i < num_console; i++) {
        console[i].devid = i;
        console[i].consback = LIBXL_CONSBACK_IOEMU;
        console[i].domid = domid;
        /* STUBDOM_CONSOLE_LOGGING (console 0) is for minios logging
         * STUBDOM_CONSOLE_SAVE (console 1) is for writing the save file
         * STUBDOM_CONSOLE_RESTORE (console 2) is for reading the save file
         */
        switch (i) {
            char *filename;
            char *name;
            case STUBDOM_CONSOLE_LOGGING:
                name = libxl__sprintf(&gc, "qemu-dm-%s", libxl_domid_to_name(ctx, info->domid));
                libxl_create_logfile(ctx, name, &filename);
                console[i].output = libxl__sprintf(&gc, "file:%s", filename);
                console[i].build_state = &state;
                free(filename);
                break;
            case STUBDOM_CONSOLE_SAVE:
                console[i].output = libxl__sprintf(&gc, "file:"SAVEFILE".%d", info->domid);
                break;
            case STUBDOM_CONSOLE_RESTORE:
                if (info->saved_state)
                    console[i].output = libxl__sprintf(&gc, "pipe:%s", info->saved_state);
                break;
            default:
                console[i].output = "pty";
                break;
        }
        ret = libxl_device_console_add(ctx, domid, &console[i]);
        if (ret)
            goto out_free;
    }
    if (libxl__create_xenpv_qemu(ctx, domid, vfb, &dm_starting) < 0) {
        ret = ERROR_FAIL;
        goto out_free;
    }
    if (libxl__confirm_device_model_startup(ctx, dm_starting) < 0) {
        ret = ERROR_FAIL;
        goto out_free;
    }

    libxl_domain_unpause(ctx, domid);

    if (starting_r) {
        *starting_r = calloc(sizeof(libxl__device_model_starting), 1);
        (*starting_r)->domid = info->domid;
        (*starting_r)->dom_path = libxl__xs_get_dompath(&gc, info->domid);
        (*starting_r)->for_spawn = NULL;
    }

    ret = 0;

out_free:
    free(args);
out:
    libxl__free_all(&gc);
    return ret;
}