Beispiel #1
0
/**
 * \brief XenStore watch callback for the root node of the XenStore
 *        subtree representing a XenBus.
 *
 * This callback performs, or delegates to the xbs_probe_children task,
 * all processing necessary to handle dynmaic device arrival and departure
 * events from a XenBus.
 *
 * \param watch  The XenStore watch object associated with this callback.
 * \param vec    The XenStore watch event data.
 * \param len	 The number of fields in the event data stream.
 */
static void
xenbusb_devices_changed(struct xs_watch *watch, const char **vec,
			unsigned int len)
{
	struct xenbusb_softc *xbs;
	device_t dev;
	char *node;
	char *bus;
	char *type;
	char *id;
	char *p;
	u_int component;

	xbs = (struct xenbusb_softc *)watch->callback_data;
	dev = xbs->xbs_dev;

	if (len <= XS_WATCH_PATH) {
		device_printf(dev, "xenbusb_devices_changed: "
			      "Short Event Data.\n");
		return;
	}

	node = strdup(vec[XS_WATCH_PATH], M_XENBUS);
	p = strchr(node, '/');
	if (p == NULL)
		goto out;
	bus = node;
	*p = 0;
	type = p + 1;

	p = strchr(type, '/');
	if (p == NULL)
		goto out;
	*p++ = 0;

	/*
	 * Extract the device ID.  A device ID has one or more path
	 * components separated by the '/' character.
	 *
	 * e.g. "<frontend vm id>/<frontend dev id>" for backend devices.
	 */
	id = p;
	for (component = 0; component < xbs->xbs_id_components; component++) {
		p = strchr(p, '/');
		if (p == NULL)
			break;
		p++;
	}
	if (p != NULL)
		*p = 0;

	if (*id != 0 && component >= xbs->xbs_id_components - 1) {
		xenbusb_add_device(xbs->xbs_dev, type, id);
		taskqueue_enqueue(taskqueue_thread, &xbs->xbs_probe_children);
	}
out:
	free(node, M_XENBUS);
}
Beispiel #2
0
/**
 * \brief Enumerate all devices of the given type on this bus.
 *
 * \param dev   NewBus device_t for this XenBus backend bus instance.
 * \param type  String indicating the device sub-tree (e.g. "vfb", "vif")
 *              to enumerate. 
 *
 * \return  On success, 0. Otherwise an errno value indicating the
 *          type of failure.
 *
 * Devices that are found are entered into the NewBus hierarchy via
 * xenbusb_add_device().  xenbusb_add_device() ignores duplicate detects
 * and ignores duplicate devices, so it can be called unconditionally
 * for any device found in the XenStore.
 *
 * The backend XenStore hierarchy has the following format:
 *
 *     backend/<device type>/<frontend vm id>/<device id>
 *
 */
static int
xenbusb_back_enumerate_type(device_t dev, const char *type)
{
	struct xenbusb_softc *xbs;
	const char **vms;
	u_int vm_idx;
	u_int vm_count;
	int error;

	xbs = device_get_softc(dev);
	error = xs_directory(XST_NIL, xbs->xbs_node, type, &vm_count, &vms);
	if (error)
		return (error);
	for (vm_idx = 0; vm_idx < vm_count; vm_idx++) {
		struct sbuf *vm_path;
		const char *vm;
		const char **devs;
		u_int dev_idx;
		u_int dev_count;

		vm = vms[vm_idx];

		vm_path = xs_join(type, vm);
		error = xs_directory(XST_NIL, xbs->xbs_node, sbuf_data(vm_path),
		    &dev_count, &devs);
		sbuf_delete(vm_path);
		if (error)
			break;

		for (dev_idx = 0; dev_idx < dev_count; dev_idx++) {
			const char *dev_num;
			struct sbuf *id;
			
			dev_num = devs[dev_idx];
			id = xs_join(vm, dev_num);
			xenbusb_add_device(dev, type, sbuf_data(id));
			sbuf_delete(id);
		}
		free(devs, M_XENSTORE);
	}

	free(vms, M_XENSTORE);

	return (0);
}
Beispiel #3
0
/**
 * \brief Enumerate all devices of the given type on this bus.
 *
 * \param dev   NewBus device_t for this XenBus front bus instance.
 * \param type  String indicating the device sub-tree (e.g. "vfb", "vif")
 *              to enumerate. 
 *
 * \return  On success, 0. Otherwise an errno value indicating the
 *          type of failure.
 *
 * Devices that are found are entered into the NewBus hierarchy via
 * xenbusb_add_device().  xenbusb_add_device() ignores duplicate detects
 * and ignores duplicate devices, so it can be called unconditionally
 * for any device found in the XenStore.
 */
int
xenbusb_front_enumerate_type(device_t dev, const char *type)
{
	struct xenbusb_softc *xbs;
	const char **dir;
	unsigned int i, count;
	int error;

	xbs = device_get_softc(dev);
	error = xs_directory(XST_NIL, xbs->xbs_node, type, &count, &dir);
	if (error)
		return (error);
	for (i = 0; i < count; i++)
		xenbusb_add_device(dev, type, dir[i]);

	free(dir, M_XENSTORE);

	return (0);
}