コード例 #1
0
/*
 * Remove information about a usb device for this domain from Xenstore
 */
int
xenstore_destroy_usb(dominfo_t *domp, usbinfo_t *usbp)
{
  char value[32];
  char *bepath;
  char *fepath;
  int i;

  xd_log(LOG_INFO, "Deleting VUSB node %d for %d.%d",
	 usbp->usb_virtid, usbp->usb_bus, usbp->usb_device);

  bepath = xs_dev_bepath(domp, "vusb", usbp->usb_virtid);
  fepath = xs_dev_fepath(domp, "vusb", usbp->usb_virtid);

  /* Notify the backend that the device is being shut down */
  xs_set_keyval(XBT_NULL, bepath, "online", "0");
  xs_set_keyval(XBT_NULL, bepath, "physical-device", "0.0");
  snprintf(value, sizeof (value), "%d", XB_CLOSING);
  xs_set_keyval(XBT_NULL, bepath, "state", value);

  for (i = 0; i < 30; ++i) {
    usleep(100000);
    if (test_offline(domp, usbp)) {
      xs_rm(xs_handle, XBT_NULL, fepath);
      xs_rm(xs_handle, XBT_NULL, bepath);
      break;
    }
  }


  free(bepath);
  free(fepath);

  return (0);
}
コード例 #2
0
/* Remove the backend area in xenbus since the framebuffer really is
   going away. */
void xenfb_shutdown(struct xenfb *xenfb)
{
	fprintf(stderr, "FB: Shutting down backend\n");
	xs_rm(xenfb->xsh, XBT_NULL, xenfb->fb.nodename);
	xs_rm(xenfb->xsh, XBT_NULL, xenfb->kbd.nodename);

	xenfb_detach_dom(xenfb);
	if (xenfb->xc >= 0)
		xc_interface_close(xenfb->xc);
	if (xenfb->evt_xch >= 0)
		xc_evtchn_close(xenfb->evt_xch);
	if (xenfb->xsh)
		xs_daemon_close(xenfb->xsh);
	free(xenfb);
}
コード例 #3
0
ファイル: xenbusb_back.c プロジェクト: JabirTech/Source
/**
 * \brief Backend XenBus method implementing responses to local
 *        XenStore changes.
 * 
 * \param bus    The XenBus bus parent of child.
 * \param child  The XenBus child whose peer stat has changed.
 * \param_path   The tree relative sub-path to the modified node.  The empty
 *               string indicates the root of the tree was destroyed.
 */
static void
xenbusb_back_localend_changed(device_t bus, device_t child, const char *path)
{

	xenbusb_localend_changed(bus, child, path);

	if (strcmp(path, "/state") != 0
	 && strcmp(path, "/online") != 0)
		return;

	if (xenbus_get_state(child) != XenbusStateClosed
	 || xenbus_dev_is_online(child) != 0)
		return;

	/*
	 * Cleanup the hotplug entry in the XenStore if
	 * present.  The control domain expects any userland
	 * component associated with this device to destroy
	 * this node in order to signify it is safe to 
	 * teardown the device.  However, not all backends
	 * rely on userland components, and those that
	 * do should either use a communication channel
	 * other than the XenStore, or ensure the hotplug
	 * data is already cleaned up.
	 *
	 * This removal ensures that no matter what path
	 * is taken to mark a back-end closed, the control
	 * domain will understand that it is closed.
	 */
	xs_rm(XST_NIL, xenbus_get_node(child), "hotplug-status");
}
コード例 #4
0
ファイル: exec-xenbus.c プロジェクト: SnakeDoc/GuestVM
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;
}
コード例 #5
0
ファイル: io.c プロジェクト: jgriffiths/qubes-core-vchan-xen
int libvchan_wait(libvchan_t *ctrl) {
    int ret = -2; /* invalid, so can be distinguished from real
                     libxenvchan_wait return code */
    struct xs_handle *xs;

    if (ctrl->xenvchan->is_server && libxenvchan_is_open(ctrl->xenvchan) == 2) {
        /* In case of vchan server waiting for a client, we'll not receive any
         * notification if the remote domain dies before connecting. Because of
         * that, check periodically if remote domain is still alive while
         * waiting for a connection. Actually this doesn't cover all the cases
         * - if remote domain is still alive, but remote process dies before
         * connecting, we'll also not receive any notification. But this, in
         * most cases, can be solved by application using libvchan.
         *
         * During normal operation this shouldn't be long - in most cases vchan
         * client will connect almost instantly. So this sleep(10) loop will
         * not hurt. Alternativelly it could be implemented with
         * xs_watch("@releaseDomain"), but such approach will slow down most
         * common execution path (xs_open+xs_watch even if client connects
         * right away).
         */
        while (ret == -2 && libxenvchan_is_open(ctrl->xenvchan) == 2) {
            fd_set rd_set;
            struct timeval tv = { 10, 0 };
            int vchan_fd = libxenvchan_fd_for_select(ctrl->xenvchan);
            FD_ZERO(&rd_set);
            FD_SET(vchan_fd, &rd_set);
            switch (select(vchan_fd+1, &rd_set, NULL, NULL, &tv)) {
                case 0:
                    if (!libvchan__check_domain_alive(ctrl->xc_handle, ctrl->remote_domain))
                        return -1;
                    break;
                case 1:
                    /* break the loop */
                    ret = -1;
                    break;
                default:
                    if (errno == EINTR)
                        break;
                    perror("select");
                    return -1;
            }
        }
    }
    ret = libxenvchan_wait(ctrl->xenvchan);
    if (ctrl->xs_path) {
        /* remove xenstore entry at first client connection */
        xs = xs_open(0);
        if (xs) {
            /* if xenstore connection failed just do not remove entries, but do
             * not abort whole function, especially still free the memory
             */
            xs_rm(xs, 0, ctrl->xs_path);
            xs_close(xs);
        }
        free(ctrl->xs_path);
        ctrl->xs_path = NULL;
    }
    return ret;
}
コード例 #6
0
ファイル: xen-bus-helper.c プロジェクト: MaddTheSane/qemu
void xs_node_destroy(struct xs_handle *xsh, xs_transaction_t tid,
                     const char *node, Error **errp)
{
    trace_xs_node_destroy(node);

    if (!xs_rm(xsh, tid, node)) {
        error_setg_errno(errp, errno, "failed to destroy node '%s'", node);
    }
}
コード例 #7
0
ファイル: libIVC.c プロジェクト: AlexanderAA/HaLVM
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;
}
コード例 #8
0
ファイル: xenstore_client.c プロジェクト: CrazyXen/XEN_CODE
static int
do_rm(char *path, struct xs_handle *xsh, xs_transaction_t xth)
{
    if (xs_rm(xsh, xth, path)) {
        return 0;
    }
    else {
        warnx("could not remove path %s", path);
        return 1;
    }
}
コード例 #9
0
ファイル: xslib.c プロジェクト: euanh/sm
int generic_remove_xs_entry(struct xs_handle *h, char *path)
{
	int ret = 0;

	if (xs_exists(h, path)) {
		if (!xs_rm(h, XBT_NULL, path)) {
			printf("Failed to remove xs entry %s\n", path);
			goto out;
		}
	}
	ret = 1;
 out:
	return ret;
}
コード例 #10
0
ファイル: libIVC.c プロジェクト: AlexanderAA/HaLVM
ivc_connection_t *acceptConnection(libIVC_t *iface,
                                   char *name,
                                   ivc_contype_t type,
                                   uint32_t num_pages,
                                   float per)
{
  char *key, *val, *domStr = NULL;
  uint32_t me, other, *gs, ps;
  unsigned int len;
  void *buffer;

  /* we can only do this if we create grant references */
  if(!iface->gs) return NULL;
  /* other <- read `fmap` waitForKey xs (targetPath ++ "/LeftDomId) */
  ASPRINTF(&key, "/rendezvous/%s/LeftDomId", name);
  while(!domStr) { domStr = xs_read(iface->xs, 0, key, &len); }
  sscanf(domStr, "dom%d", &other);
  /* me <- xsGetDomId */
  me = getMyDomId(iface);
  /* (gs, ps, confirm) <- makeConnection other extra */
  gs = calloc(num_pages, sizeof(uint32_t));
  buffer = xc_gntshr_share_pages(iface->gs, other, num_pages, gs, 1);
  assert(buffer);
  ps = xc_evtchn_bind_unbound_port(iface->ec, other);
  assert(ps);
  /* xsWrite xs (targetPath ++ "/RightDomId") (show me) */
  free(key), ASPRINTF(&key, "/rendezvous/%s/RightDomId", name);
  free(val), ASPRINTF(&val, "dom%d", me);
  xs_write(iface->xs, 0, key, val, strlen(val));
  /* xsWrite xs (targetPath ++ "/RightGrantRefs") (show gs) */
  free(key), ASPRINTF(&key, "/rendezvous/%s/RightGrantRefs", name);
  free(val), val = showGrantRefList(gs, num_pages);
  xs_write(iface->xs, 0, key, val, strlen(val));
  /* xsWrite xs (targetPath ++ "/RightPorts") (show ps) */
  free(key), ASPRINTF(&key, "/rendezvous/%s/RightPorts", name);
  free(val), ASPRINTF(&val, "[echan:%d]", ps);
  xs_write(iface->xs, 0, key, val, strlen(val));
  /* _ <- waitForKey xs (targetPath ++ "/LeftConnectionConfirmed") */
  free(key), ASPRINTF(&key, "/rendezvous/%s/LeftConnectionConfirmed", name);
  free(val), val = NULL;
  while(!val) { val = xs_read(iface->xs, 0, key, &len); }
  /* removePath xs targetPath */
  free(key), ASPRINTF(&key, "/rendezvous/%s", name);
  xs_rm(iface->xs, 0, key);
  /* confirm */
  return buildChannel(iface, other, type, ps, buffer, 4096 * num_pages, per, 1);
}
コード例 #11
0
ファイル: io.c プロジェクト: jgriffiths/qubes-core-vchan-xen
void libvchan_close(libvchan_t *ctrl) {
    struct xs_handle *xs;

    libxenvchan_close(ctrl->xenvchan);
    if (ctrl->xs_path) {
        /* remove xenstore entry in case of no client connected */
        xs = xs_open(0);
        if (xs) {
            /* if xenstore connection failed just do not remove entries, but do
             * not abort whole function, especially still free the memory
             */
            xs_rm(xs, 0, ctrl->xs_path);
            xs_close(xs);
        }
        free(ctrl->xs_path);
    }
    free(ctrl);
}
コード例 #12
0
ファイル: module-xenpv-sink.c プロジェクト: Oboyma/pulseaudio
static void xen_cleanup() {
    char keybuf[64];
    /*XXX hardcoded*/
    munmap((void*)gref.index, 4096);

    set_state(XenbusStateClosing);
    /* send one last event to unblock the backend */
    xc_evtchn_notify(xce, xen_evtchn_port);
    /* close xen interfaces */
    xc_evtchn_close(xce);
    xc_interface_close(xch);

    /* delete xenstore keys */
    publish_param_int("state", XenbusStateClosed);
    snprintf(keybuf, sizeof(keybuf), "device/audio/%d", device_id);
    xs_rm(xsh, 0, keybuf);
    xs_daemon_close(xsh);
}
コード例 #13
0
ファイル: xslib.c プロジェクト: euanh/sm
int remove_xs_entry(struct xs_handle *h, char *dom_uuid, char *dom_path)
{
	char *path = NULL;
	int ret = 0;

	if (asprintf(&path, "/vss/%s/%s",dom_uuid, dom_path)==-1)
		goto out;

	if (xs_exists(h, path)) {
		if (!xs_rm(h, XBT_NULL, path)) {
			printf("Failed to remove xs entry %s\n", path);
			goto out;
		}
	}
	ret = 1;
 out:
	free(path);
	return ret;
}
コード例 #14
0
ファイル: xen-destroy.c プロジェクト: changliwei/suse_xen
//Shutdown a domain by signalling this via xenstored
void shutdown_domain(char *domname)
{
	int domid;
	char *vm_uuid = NULL;
	char vmpath[64];
	struct xs_handle *xsh = NULL;

	domid = atoi(domname);
	if (domid == 0) {
		perror("Error, dom 0 could not be shutdown\n");
		return; 
	}

	xsh = xs_daemon_open();
	if (!xsh) {
		perror("Couldn't get xsh handle.");
		return;
	}

	//if self._stateGet() in (DOM_STATE_SHUTDOWN, DOM_STATE_HALTED,):
	//    raise XendError('Domain cannot be shutdown')

	vm_uuid = domid_to_vm_uuid(xsh, domid);
	snprintf(vmpath, sizeof(vmpath), "%s/xend/previous_restart_time", vm_uuid);
	free(vm_uuid);

	xs_rm(xsh, XBT_NULL, vmpath);

	memset(vmpath, '\0', 64); 
	snprintf(vmpath, sizeof(vmpath), "/local/domain/%u/control/shutdown", domid);

	xs_write(xsh, XBT_NULL, vmpath, "poweroff", 9);

	//TODO: How about HVM domain	
	//HVM domain shuts itself down only if it has PV drivers
	//if self.info.is_hvm():
	//    hvm_pvdrv = xc.hvm_get_param(self.domid, HVM_PARAM_CALLBACK_IRQ)
	//    if not hvm_pvdrv:
	//        code = REVERSE_DOMAIN_SHUTDOWN_REASONS[reason]

	free(xsh);
	return;
}
コード例 #15
0
ファイル: libxl_dm.c プロジェクト: changliwei/suse_xen
int libxl__destroy_device_model(libxl_ctx *ctx, uint32_t domid)
{
    libxl__gc gc = LIBXL_INIT_GC(ctx);
    char *pid;
    int ret;

    pid = libxl__xs_read(&gc, XBT_NULL, libxl__sprintf(&gc, "/local/domain/%d/image/device-model-pid", domid));
    if (!pid) {
        int stubdomid = libxl_get_stubdom_id(ctx, domid);
        if (!stubdomid) {
            LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "Couldn't find device model's pid");
            ret = ERROR_INVAL;
            goto out;
        }
        LIBXL__LOG(ctx, LIBXL__LOG_DEBUG, "Device model is a stubdom, domid=%d\n", stubdomid);
        ret = libxl_domain_destroy(ctx, stubdomid, 0);
        if (ret)
            goto out;
    } else {
        ret = kill(atoi(pid), SIGHUP);
        if (ret < 0 && errno == ESRCH) {
            LIBXL__LOG(ctx, LIBXL__LOG_DEBUG, "Device Model already exited");
            ret = 0;
        } else if (ret == 0) {
            LIBXL__LOG(ctx, LIBXL__LOG_DEBUG, "Device Model signaled");
            ret = 0;
        } else {
            LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "failed to kill Device Model [%d]",
                    atoi(pid));
            ret = ERROR_FAIL;
            goto out;
        }
    }
    xs_rm(ctx->xsh, XBT_NULL, libxl__sprintf(&gc, "/local/domain/0/device-model/%d", domid));

out:
    libxl__free_all(&gc);
    return ret;
}
コード例 #16
0
ファイル: xen-destroy.c プロジェクト: changliwei/suse_xen
int destroy_domain(char *domname)
{
	int domid, rcode, i, DMid, status;
	int __attribute__((__unused__)) ret;
#ifdef XENCTRL_HAS_XC_INTERFACE
    xc_interface *xc_handle = NULL;
#else
    int xc_handle = 0;
#endif
    unsigned int len;
	char *s;
	char path[256];
	struct xs_handle *xsh = NULL;
        FILE *f;
        char buf[256];
        char *backend;

	xsh = xs_daemon_open();
	if (!xsh) {
		perror("Couldn't get xsh handle.");
		rcode = 1;
		goto out;
	}
	domid = getDomidByName(xsh, domname);

	if (domid < 1) {
		perror("Error,Can't destroy domId, domId should > 0\n");
        rcode = 1;
        goto out;
	}


#ifdef XENCTRL_HAS_XC_INTERFACE
	xc_handle = xc_interface_open(NULL, NULL, 0);
	if (xc_handle == NULL) {
#else
	xc_handle = xc_interface_open();
    if (xc_handle < 0) {
#endif
		perror("Couldn't open xc handle.");
		rcode = 1;
		goto out;
	}

	/* TODO PCI clean
	paths = self._prepare_phantom_paths()
	if self.dompath is not None:
		self._cleanup_phantom_devs(paths)

	xc_domain_destroy_hook(xc_handle, domid);
	*/

	xc_domain_pause(xc_handle, domid);
	rcode = xc_domain_destroy(xc_handle, domid);
        
        // free Device Model
        sprintf(path,"/local/domain/%d/image/device-model-pid", domid); 
        s = xs_read(xsh, XBT_NULL, path, &len);
        if( s != NULL)
        {
            DMid = atoi(s);
            free(s);
            DEBUG("Deivce Model Id is %d\n", DMid);
        }
        else
        {
            rcode = 1;
            DEBUG("can't read Deivce Model Id\n");
            goto out;
        }
        kill(DMid, SIGHUP);
        for( i=0; i< 100; i++)
        {
            if(DMid == waitpid(DMid, &status, WNOHANG))
                break;
            sleep(0.1);
        }
        if( i == 100)
        {
            DEBUG("DeviceModel %d took more than 10s "
                                "to terminate: sending SIGKILL\n", DMid);
            kill(DMid, SIGKILL);
            waitpid(DMid, &status, 0);
        }
        sprintf(path,"/local/domain/0/device-model/%i", domid); 
        xs_rm(xsh, XBT_NULL, path);

        // unlink pipe
        sprintf(path,"/var/run/tap/qemu-read-%d", domid); 
        ret = unlink(path);
        sprintf(path,"/var/run/tap/qemu-write-%d", domid); 
        ret = unlink(path);

        //notify backend to reap the source assigned to this VM
        sprintf(path, "xenstore-ls /local/domain/%d/device > /var/tmp/xdestroy_device.%d", domid, domid); 
        ret = system(path);
        sprintf(path, "/var/tmp/xdestroy_device.%d",  domid); 
        f = fopen(path, "r");
        if ( f == NULL)
        {
            DEBUG(" error to open device file\n");
            return -1;
        }
        DEBUG("- begin to reap\n");
        while(1)
        {
            if( fgets(buf, 256, f)== NULL)
                break;
            else
            {
                if( buf[0] != 0x20)
                {
                    backend = device_backend(xsh, buf, domid);
                    if( backend != NULL)
                    {    
                        notify_backend(xsh, backend);
                        free(backend);
                    }
                }
            }
       }
       DEBUG("- end to reap\n");
       fclose(f);
       sprintf(path, "rm /var/tmp/xdestroy_device.%d",  domid); 
       ret = system(path);
       extra_call(domname, DMid);
out:
	if (xsh)
		xs_daemon_close(xsh);
	if (xc_handle)
		xc_interface_close(xc_handle);
	return rcode;
}

int main(int argc, char **argv)
{
	if (argc != 2) {
		printf("Miss destroy name\n");
		return -1;
	}
	xlist(argc, argv);
	//shutdown_domain(argv[1]);
	destroy_domain(argv[1]);

	return 0;
}
コード例 #17
0
static void
xs_remove(xs_transaction_t xt, char *path)
{
  xd_log(LOG_VERBOSE_DEBUG, "XenStore removing %s", path);
  xs_rm(xs_handle, xt, path);
}
コード例 #18
0
int
grefwatch_from_alloc(uint32_t *gref, void **pptr)
{
	int rv;
	void *ptr;
	int pg_size = getpagesize();
	struct ioctl_gntalloc_alloc_gref arg = {
		.domid = DOM0_DOMID,
		.flags = GNTALLOC_FLAG_WRITABLE,
		.count = 1
	};
	struct ioctl_gntalloc_dealloc_gref arg_d;
	struct ioctl_gntalloc_unmap_notify notify = {
		.action = UNMAP_NOTIFY_CLEAR_BYTE
	};

	rv = ioctl(gntalloc_fd, IOCTL_GNTALLOC_ALLOC_GREF, &arg);
	if (rv) {
		RTE_LOG(ERR, PMD, "%s: ioctl error\n", __func__);
		return -1;
	}

	ptr = (void *)mmap(NULL, pg_size, PROT_READ|PROT_WRITE, MAP_SHARED, gntalloc_fd, arg.index);
	arg_d.index = arg.index;
	arg_d.count = 1;
	if (ptr == MAP_FAILED) {
		RTE_LOG(ERR, PMD, "%s: mmap failed\n", __func__);
		ioctl(gntalloc_fd, IOCTL_GNTALLOC_DEALLOC_GREF, &arg_d);
		return -1;
	}
	if (pptr)
		*pptr = ptr;
	if (gref)
		*gref = arg.gref_ids[0];

	notify.index = arg.index;
	rv = ioctl(gntalloc_fd, IOCTL_GNTALLOC_SET_UNMAP_NOTIFY, &notify);
	if (rv) {
		RTE_LOG(ERR, PMD, "%s: unmap notify failed\n", __func__);
		munmap(ptr, pg_size);
		ioctl(gntalloc_fd, IOCTL_GNTALLOC_DEALLOC_GREF, &arg_d);
		return -1;
	}

	return 0;
}

void
gntfree(void *va, size_t sz, uint64_t start_index)
{
	struct ioctl_gntalloc_dealloc_gref arg_d;

	if (va && sz) {
		munmap(va, sz);
		arg_d.count = sz / getpagesize();
		arg_d.index = start_index;
		ioctl(gntalloc_fd, IOCTL_GNTALLOC_DEALLOC_GREF, &arg_d);
	}
}

static int
xenstore_cleanup(void)
{
	char store_path[PATH_MAX] = {0};

	if (snprintf(store_path, sizeof(store_path),
		"%s%s", dompath, DPDK_XENSTORE_NODE) == -1)
		return -1;

	if (xs_rm(xs, XBT_NULL, store_path) == false) {
		RTE_LOG(ERR, PMD, "%s: failed cleanup node\n", __func__);
		return -1;
	}

	return 0;
}
コード例 #19
0
ファイル: libxl_create.c プロジェクト: CPFL/gxen
int libxl__domain_make(libxl__gc *gc, libxl_domain_create_info *info,
                       uint32_t *domid)
{
    libxl_ctx *ctx = libxl__gc_owner(gc);
    int flags, ret, rc, nb_vm;
    char *uuid_string;
    char *dom_path, *vm_path, *libxl_path;
    struct xs_permissions roperm[2];
    struct xs_permissions rwperm[1];
    struct xs_permissions noperm[1];
    xs_transaction_t t = 0;
    xen_domain_handle_t handle;
    libxl_vminfo *vm_list;


    assert(!libxl_domid_valid_guest(*domid));

    uuid_string = libxl__uuid2string(gc, info->uuid);
    if (!uuid_string) {
        rc = ERROR_NOMEM;
        goto out;
    }

    flags = 0;
    if (info->type == LIBXL_DOMAIN_TYPE_HVM) {
        flags |= XEN_DOMCTL_CDF_hvm_guest;
        flags |= libxl_defbool_val(info->hap) ? XEN_DOMCTL_CDF_hap : 0;
        flags |= libxl_defbool_val(info->oos) ? 0 : XEN_DOMCTL_CDF_oos_off;
    }
    *domid = -1;

    /* Ultimately, handle is an array of 16 uint8_t, same as uuid */
    libxl_uuid_copy((libxl_uuid *)handle, &info->uuid);

    ret = xc_domain_create(ctx->xch, info->ssidref, handle, flags, domid);
    if (ret < 0) {
        LIBXL__LOG_ERRNOVAL(ctx, LIBXL__LOG_ERROR, ret, "domain creation fail");
        rc = ERROR_FAIL;
        goto out;
    }

    ret = xc_cpupool_movedomain(ctx->xch, info->poolid, *domid);
    if (ret < 0) {
        LIBXL__LOG_ERRNOVAL(ctx, LIBXL__LOG_ERROR, ret, "domain move fail");
        rc = ERROR_FAIL;
        goto out;
    }

    dom_path = libxl__xs_get_dompath(gc, *domid);
    if (!dom_path) {
        rc = ERROR_FAIL;
        goto out;
    }

    vm_path = libxl__sprintf(gc, "/vm/%s", uuid_string);
    if (!vm_path) {
        LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "cannot allocate create paths");
        rc = ERROR_FAIL;
        goto out;
    }

    libxl_path = libxl__xs_libxl_path(gc, *domid);
    if (!libxl_path) {
        rc = ERROR_FAIL;
        goto out;
    }

    noperm[0].id = 0;
    noperm[0].perms = XS_PERM_NONE;

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

    rwperm[0].id = *domid;
    rwperm[0].perms = XS_PERM_NONE;

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

    xs_rm(ctx->xsh, t, dom_path);
    libxl__xs_mkdir(gc, t, dom_path, roperm, ARRAY_SIZE(roperm));

    xs_rm(ctx->xsh, t, vm_path);
    libxl__xs_mkdir(gc, t, vm_path, roperm, ARRAY_SIZE(roperm));

    xs_rm(ctx->xsh, t, libxl_path);
    libxl__xs_mkdir(gc, t, libxl_path, noperm, ARRAY_SIZE(noperm));

    xs_write(ctx->xsh, t, libxl__sprintf(gc, "%s/vm", dom_path), vm_path, strlen(vm_path));
    rc = libxl__domain_rename(gc, *domid, 0, info->name, t);
    if (rc)
        goto out;

    libxl__xs_mkdir(gc, t,
                    libxl__sprintf(gc, "%s/cpu", dom_path),
                    roperm, ARRAY_SIZE(roperm));
    libxl__xs_mkdir(gc, t,
                    libxl__sprintf(gc, "%s/memory", dom_path),
                    roperm, ARRAY_SIZE(roperm));
    libxl__xs_mkdir(gc, t,
                    libxl__sprintf(gc, "%s/device", dom_path),
                    roperm, ARRAY_SIZE(roperm));
    libxl__xs_mkdir(gc, t,
                    libxl__sprintf(gc, "%s/control", dom_path),
                    roperm, ARRAY_SIZE(roperm));
    if (info->type == LIBXL_DOMAIN_TYPE_HVM)
        libxl__xs_mkdir(gc, t,
                        libxl__sprintf(gc, "%s/hvmloader", dom_path),
                        roperm, ARRAY_SIZE(roperm));

    libxl__xs_mkdir(gc, t,
                    libxl__sprintf(gc, "%s/control/shutdown", dom_path),
                    rwperm, ARRAY_SIZE(rwperm));
    libxl__xs_mkdir(gc, t,
                    libxl__sprintf(gc, "%s/device/suspend/event-channel", dom_path),
                    rwperm, ARRAY_SIZE(rwperm));
    libxl__xs_mkdir(gc, t,
                    libxl__sprintf(gc, "%s/data", dom_path),
                    rwperm, ARRAY_SIZE(rwperm));
    if (info->type == LIBXL_DOMAIN_TYPE_HVM)
        libxl__xs_mkdir(gc, t,
            libxl__sprintf(gc, "%s/hvmloader/generation-id-address", dom_path),
                        rwperm, ARRAY_SIZE(rwperm));

                    vm_list = libxl_list_vm(ctx, &nb_vm);
    if (!vm_list) {
        LOG(ERROR, "cannot get number of running guests");
        rc = ERROR_FAIL;
        goto out;
    }
    libxl_vminfo_list_free(vm_list, nb_vm);
    int hotplug_setting = libxl__hotplug_settings(gc, t);
    if (hotplug_setting < 0) {
        LOG(ERROR, "unable to get current hotplug scripts execution setting");
        rc = ERROR_FAIL;
        goto out;
    }
    if (libxl_defbool_val(info->run_hotplug_scripts) != hotplug_setting &&
        (nb_vm - 1)) {
        LOG(ERROR, "cannot change hotplug execution option once set, "
                    "please shutdown all guests before changing it");
        rc = ERROR_FAIL;
        goto out;
    }

    if (libxl_defbool_val(info->run_hotplug_scripts)) {
        rc = libxl__xs_write_checked(gc, t, DISABLE_UDEV_PATH, "1");
        if (rc) {
            LOGE(ERROR, "unable to write %s = 1", DISABLE_UDEV_PATH);
            goto out;
        }
    } else {
        rc = libxl__xs_rm_checked(gc, t, DISABLE_UDEV_PATH);
        if (rc) {
            LOGE(ERROR, "unable to delete %s", DISABLE_UDEV_PATH);
            goto out;
        }
    }

    xs_write(ctx->xsh, t, libxl__sprintf(gc, "%s/uuid", vm_path), uuid_string, strlen(uuid_string));
    xs_write(ctx->xsh, t, libxl__sprintf(gc, "%s/name", vm_path), info->name, strlen(info->name));

    libxl__xs_writev(gc, t, dom_path, info->xsdata);
    libxl__xs_writev(gc, t, libxl__sprintf(gc, "%s/platform", dom_path), info->platformdata);

    xs_write(ctx->xsh, t, libxl__sprintf(gc, "%s/control/platform-feature-multiprocessor-suspend", dom_path), "1", 1);
    xs_write(ctx->xsh, t, libxl__sprintf(gc, "%s/control/platform-feature-xs_reset_watches", dom_path), "1", 1);
    if (!xs_transaction_end(ctx->xsh, t, 0)) {
        if (errno == EAGAIN) {
            t = 0;
            goto retry_transaction;
        }
        LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "domain creation "
                         "xenstore transaction commit failed");
        rc = ERROR_FAIL;
        goto out;
    }
    t = 0;

    rc = 0;
 out:
    if (t) xs_transaction_end(ctx->xsh, t, 1);
    return rc;
}
コード例 #20
0
ファイル: frontend.c プロジェクト: comstud/blktap
int
tapback_backend_handle_otherend_watch(backend_t *backend,
		const char * const path)
{
    vbd_t *device = NULL;
    int err = 0, state = 0;
    char *s = NULL, *end = NULL, *_path = NULL;

	ASSERT(backend);
    ASSERT(path);

    /*
     * Find the device that has the same front-end state path.
     *
     * There should definitely be such a device in our list, otherwise this
     * function would not have executed at all, since we would not be waiting
     * on that XenStore path.  The XenStore path we wait for is:
     * /local/domain/<domid>/device/vbd/<devname>/state. In order to watch this
     * path, it means that we have received a device create request, so the
     * device will be there.
     *
     * TODO Instead of this linear search we could do better (hash table etc).
     */
    tapback_backend_find_device(backend, device,
            device->frontend_state_path &&
			!strcmp(device->frontend_state_path, path));
    if (!device) {
        WARN(NULL, "path \'%s\' does not correspond to a known device\n",
                path);
        return ENODEV;
    }

    /*
     * Read the new front-end's state.
     */
	s = tapback_xs_read(device->backend->xs, XBT_NULL, "%s",
			device->frontend_state_path);
    if (!s) {
        err = errno;
		/*
         * If the front-end XenBus node is missing, the XenBus device has been
         * removed: remove the XenBus back-end node.
		 */
		if (err == ENOENT) {
            err = asprintf(&_path, "%s/%s/%d/%d", XENSTORE_BACKEND,
                    device->backend->name, device->domid, device->devid);
            if (err == -1) {
                err = errno;
                WARN(device, "failed to asprintf for %d/%d: %s\n",
                        strerror(err));
                goto out;
            }
            err = 0;
            if (!xs_rm(device->backend->xs, XBT_NULL, _path)) {
                if (errno != ENOENT) {
                    err = errno;
                    WARN(device, "failed to remove %s: %s\n", path,
                            strerror(err));
                }
            }
		}
    } else {
        state = strtol(s, &end, 0);
        if (*end != 0 || end == s) {
            WARN(device, "invalid XenBus state '%s'\n", s);
            err = EINVAL;
        } else
            err = frontend_changed(device, state);
    }

out:
    free(s);
    free(_path);
    return err;
}
コード例 #21
0
ファイル: libxl_domain.c プロジェクト: fdario/xen
/*
 * 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;
}