Esempio n. 1
0
XenbusState
xenbus_read_driver_state(const char *path)
{
        XenbusState result;
        int error;

        error = xs_gather(XST_NIL, path, "state", "%d", &result, NULL);
        if (error)
                result = XenbusStateClosed;

        return (result);
}
Esempio n. 2
0
int
xenbus_dev_is_online(device_t dev)
{
	const char *path;
	int error;
	int value;

	path = xenbus_get_node(dev);
	error = xs_gather(XST_NIL, path, "online", "%d", &value, NULL);
	if (error != 0) {
		/* Default to not online. */
		value = 0;
	}

	return (value);
}
Esempio n. 3
0
/**
 * \brief Determine and store the XenStore path for the other end of
 *        a split device whose local end is represented by ivars.
 *
 * If successful, the xd_otherend_path field of the child's instance
 * variables will be updated.
 *
 * \param dev    NewBus device_t for this XenBus front bus instance.
 * \param ivars  Instance variables from the XenBus child device for
 *               which to perform this function.
 *
 * \return  On success, 0. Otherwise an errno value indicating the
 *          type of failure.
 */
int
xenbusb_front_get_otherend_node(device_t dev, struct xenbus_device_ivars *ivars)
{
	char *otherend_path;
	int error;

	if (ivars->xd_otherend_path != NULL) {
		free(ivars->xd_otherend_path, M_XENBUS);
		ivars->xd_otherend_path = NULL;
	}
		
	error = xs_gather(XST_NIL, ivars->xd_node,
	    "backend-id", "%i", &ivars->xd_otherend_id,
	    "backend", NULL, &otherend_path,
	    NULL);

	if (error == 0) {
		ivars->xd_otherend_path = strdup(otherend_path, M_XENBUS);
		ivars->xd_otherend_path_len = strlen(otherend_path);
		free(otherend_path, M_XENSTORE);
	}
	return (error);
}
Esempio n. 4
0
/**
 * Xenstore watch callback entry point. This code replaces the hotplug scripts,
 * and as soon as the xenstore backend driver entries are created, this script
 * gets called.
 */
static void ueblktap_probe(struct xs_handle *h, struct xenbus_watch *w, 
			   const char *bepath_im)
{
	struct backend_info *be = NULL;
	char *frontend = NULL, *bepath = NULL, *p;
	int er, len;
	blkif_t *blkif;
	
	
	bepath = strdup(bepath_im);
	
	if (!bepath) {
		DPRINTF("No path\n");
		return;
	}
	
	/*
	 *asserts that xenstore structure is always 7 levels deep
	 *e.g. /local/domain/0/backend/vbd/1/2049
	 */
	len = strsep_len(bepath, '/', 7);
	if (len < 0) 
		goto free_be;
	if (bepath[len] != '\0')
		goto free_be;
	
	be = malloc(sizeof(*be));
	if (!be) {
		DPRINTF("ERROR: allocating backend structure\n");
		goto free_be;
	}
	memset(be, 0, sizeof(*be));
	frontend = NULL;

	er = xs_gather(h, bepath,
		       "frontend-id", "%li", &be->frontend_id,
		       "frontend", NULL, &frontend,
		       NULL);

	if (er) {
		/*
		 *Unable to find frontend entries, 
		 *bus-id is no longer valid
		 */
		DPRINTF("ERROR: Frontend-id check failed, removing backend: "
			"[%s]\n",bepath);

		/**
		 * BE info should already exist, 
		 * free new mem and find old entry
		 */
		free(be);
		be = be_lookup_be(bepath);
		if ( (be != NULL) && (be->blkif != NULL) ) 
			backend_remove(h, be);
		else goto free_be;
		if (bepath)
			free(bepath);
		return;
	}
	
	/* Are we already tracking this device? */
	if (be_exists_be(bepath))
		goto free_be;
	
	be->backpath = bepath;
	be->frontpath = frontend;
	
	list_add(&be->list, &belist);
	
	DPRINTF("[PROBE]\tADDED NEW DEVICE (%s)\n", bepath);
	DPRINTF("\tFRONTEND (%s),(%ld)\n", frontend,be->frontend_id);
	
	ueblktap_setup(h, bepath);	
	return;
	
 free_be:
	if (frontend)
		free(frontend);
	if (bepath)
		free(bepath);
	if (be) 
		free(be);
}
Esempio n. 5
0
static void ueblktap_setup(struct xs_handle *h, char *bepath)
{
	struct backend_info *be;
	char *path = NULL, *p,*dev;
	int len, er, deverr;
	long int pdev = 0, handle;
	blkif_info_t *blk;
	const char* errmsg = NULL;
	
	be = be_lookup_be(bepath);
	if (be == NULL)
	{
		DPRINTF("ERROR: backend changed called for nonexistent "
			"backend! (%s)\n", bepath);
		goto fail;
	}

	deverr = xs_gather(h, bepath, "physical-device", "%li", &pdev, NULL);
	if (!deverr) {
		DPRINTF("pdev set to %ld\n",pdev);
		if (be->pdev && be->pdev != pdev) {
			DPRINTF("changing physical-device not supported");
			goto fail;
		}
		be->pdev = pdev;
	}

	/* Check to see if device is to be opened read-only. */
	deverr = xs_gather(h, bepath, "mode", NULL, &path, NULL);
	if (deverr) {
		DPRINTF("ERROR: could not find read/write mode\n");
		goto fail;
	} else if (path[0] == 'r')
		be->readonly = 1;

	if (be->blkif == NULL) {
		/* Front end dir is a number, which is used as the handle. */
		p = strrchr(be->frontpath, '/') + 1;
		handle = strtoul(p, NULL, 0);

		be->blkif = alloc_blkif(be->frontend_id);
		if (be->blkif == NULL)
			goto fail;

		be->blkif->be_id = get_be_id(bepath);
		
		/* Insert device specific info, */
		blk = malloc(sizeof(blkif_info_t));
		if (!blk) {
			DPRINTF("Out of memory - blkif_info_t\n");
			goto fail;
		}
		er = xs_gather(h, bepath, "params", NULL, &blk->params, NULL);
		if (er)
			goto fail;
		be->blkif->info = blk;
		
		if (deverr) {
			/*Dev number was not available, try to set manually*/
			pdev = convert_dev_name_to_num(blk->params);
			be->pdev = pdev;
		}

		if (check_image(h, be, &errmsg))
			goto fail;

		er = blkif_init(be->blkif, handle, be->pdev, be->readonly);
		if (er != 0) {
			DPRINTF("Unable to open device %s\n",blk->params);
			goto fail;
		}

		DPRINTF("[BECHG]: ADDED A NEW BLKIF (%s)\n", bepath);
	}

	/* Supply the information about the device to xenstore */
	er = xs_printf(h, be->backpath, "sectors", "%llu",
			be->blkif->ops->get_size(be->blkif));

	if (er == 0) {
		DPRINTF("ERROR: Failed writing sectors");
		goto fail;
	}

	er = xs_printf(h, be->backpath, "sector-size", "%lu",
			be->blkif->ops->get_secsize(be->blkif));

	if (er == 0) {
		DPRINTF("ERROR: Failed writing sector-size");
		goto fail;
	}

	er = xs_printf(h, be->backpath, "info", "%u",
			be->blkif->ops->get_info(be->blkif));

	if (er == 0) {
		DPRINTF("ERROR: Failed writing info");
		goto fail;
	}

	be->blkif->state = CONNECTED;
	xs_printf(h, be->backpath, "hotplug-status", "connected");

	DPRINTF("[SETUP] Complete\n\n");
	goto close;
	
fail:
	if (be) {
		if (errmsg == NULL)
			errmsg = "Setting up the backend failed. See the log "
				"files in /var/log/xen/ for details.";
		xs_printf(h, be->backpath, "hotplug-error", errmsg);
		xs_printf(h, be->backpath, "hotplug-status", "error");

		backend_remove(h, be);
	}
close:
	if (path)
		free(path);
	return;
}
Esempio n. 6
0
static int check_sharing(struct xs_handle *h, struct backend_info *be)
{
	char *dom_uuid;
	char *cur_dom_uuid;
	char *path;
	char *mode;
	char *params;
	char **domains;
	char **devices;
	int i, j;
	unsigned int num_dom, num_dev;
	blkif_info_t *info = be->blkif->info;
	int ret = 0;
	const char *image_path[2];
	int be_domid = get_be_domid(be->backpath);

	image_path[0] = get_image_path(info->params);

	/* If the mode contains '!' or doesn't contain 'w' don't check anything */
	xs_gather(h, be->backpath, "mode", NULL, &mode, NULL);
	if (strchr(mode, '!'))
		goto out;
	if (strchr(mode, 'w') == NULL)
		goto out;

	/* Get the UUID of the domain we want to attach to */
	if (asprintf(&path, "/local/domain/%ld", be->frontend_id) == -1)
		goto fail;
	xs_gather(h, path, "vm", NULL, &dom_uuid, NULL);
	free(path);

	/* Iterate through the devices of all VMs */
	if (asprintf(&path, "/local/domain/%d/backend/tap", be_domid) == -1)
		goto fail;
	domains = xs_directory(h, XBT_NULL, path, &num_dom);
	free(path);
	if (domains == NULL)
		num_dom = 0;

	for (i = 0; !ret && (i < num_dom); i++) {

		/* If it's the same VM, no action needed */
		if (asprintf(&path, "/local/domain/%s", domains[i]) == -1) {
			ret = -1;
			break;
		}
		cur_dom_uuid = NULL;
		xs_gather(h, path, "vm", NULL, &cur_dom_uuid, NULL);
		free(path);
		if (!cur_dom_uuid)
			continue;

		if (!strcmp(cur_dom_uuid, dom_uuid)) {
			free(cur_dom_uuid);
			continue;
		}

		/* Check the devices */
		if (asprintf(&path, "/local/domain/%d/backend/tap/%s", be_domid, domains[i]) == -1) {
			ret = -1;
			free(cur_dom_uuid);
			break;
		}
		devices = xs_directory(h, XBT_NULL, path, &num_dev);
		if (devices == NULL)
			num_dev = 0;
		free(path);

		for (j = 0; !ret && (j < num_dev); j++) {
			if (asprintf(&path, "/local/domain/%d/backend/tap/%s/%s", be_domid, domains[i], devices[j]) == -1) {
				ret = -1;
				break;
			}
			params = NULL;
			xs_gather(h, path, "params", NULL, &params, NULL);
			free(path);
			if (!params)
				continue;

			image_path[1] = get_image_path(params);
			if (!strcmp(image_path[0], image_path[1])) {
				ret = -1;
			}

			free(params);
		}

		free(cur_dom_uuid);
		free(devices);
	}
	free(domains);
	free(dom_uuid);
	goto out;

fail:
	ret = -1;
out:
	free(mode);
	return ret;
}