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