예제 #1
0
void
xenbus_dev_verror(device_t dev, int err, const char *fmt, va_list ap)
{
	int ret;
	unsigned int len;
	char *printf_buffer = NULL, *path_buffer = NULL;

#define PRINTF_BUFFER_SIZE 4096
	printf_buffer = malloc(PRINTF_BUFFER_SIZE,M_XENBUS, M_WAITOK);

	len = sprintf(printf_buffer, "%i ", err);
	ret = vsnprintf(printf_buffer+len, PRINTF_BUFFER_SIZE-len, fmt, ap);

	KASSERT(len + ret <= PRINTF_BUFFER_SIZE-1, ("xenbus error message too big"));
	device_printf(dev, "Error %s\n", printf_buffer);
	path_buffer = error_path(dev);

	if (path_buffer == NULL) {
		printf("xenbus: failed to write error node for %s (%s)\n",
		       xenbus_get_node(dev), printf_buffer);
		goto fail;
	}

	if (xs_write(XST_NIL, path_buffer, "error", printf_buffer) != 0) {
		printf("xenbus: failed to write error node for %s (%s)\n",
		       xenbus_get_node(dev), printf_buffer);
		goto fail;
	}

 fail:
	if (printf_buffer)
		free(printf_buffer,M_XENBUS);
	if (path_buffer)
		free(path_buffer,M_XENBUS);
}
예제 #2
0
/**
 * \brief Construct the error path corresponding to the given XenBus
 *        device.
 *
 * \param dev  The XenBus device for which we are constructing an error path.
 *
 * \return  On success, the contructed error path.  Otherwise NULL.
 *
 * It is the caller's responsibility to free any returned error path
 * node using the M_XENBUS malloc type.
 */
static char *
error_path(device_t dev)
{
	char *path_buffer = malloc(strlen("error/")
	    + strlen(xenbus_get_node(dev)) + 1,M_XENBUS, M_WAITOK);

	strcpy(path_buffer, "error/");
	strcpy(path_buffer + strlen("error/"), xenbus_get_node(dev));

	return (path_buffer);
}
예제 #3
0
/**
 * Handler for all generic XenBus device systcl nodes.
 */
static int
xenbusb_device_sysctl_handler(SYSCTL_HANDLER_ARGS)  
{
	device_t dev;
        const char *value;

	dev = (device_t)arg1;
        switch (arg2) {
	case XENBUS_IVAR_NODE:
		value = xenbus_get_node(dev);
		break;
	case XENBUS_IVAR_TYPE:
		value = xenbus_get_type(dev);
		break;
	case XENBUS_IVAR_STATE:
		value = xenbus_strstate(xenbus_get_state(dev));
		break;
	case XENBUS_IVAR_OTHEREND_ID:
		return (sysctl_handle_int(oidp, NULL,
					  xenbus_get_otherend_id(dev),
					  req));
		/* NOTREACHED */
	case XENBUS_IVAR_OTHEREND_PATH:
		value = xenbus_get_otherend_path(dev);
                break;
	default:
		return (EINVAL);
	}
	return (SYSCTL_OUT_STR(req, value));
}
예제 #4
0
/**
 * \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");
}
예제 #5
0
/**
 * \param dev    The NewBus device representing this XenBus bus.
 * \param child	 The NewBus device representing a child of dev%'s XenBus bus.
 */
static void
xenbusb_verify_device(device_t dev, device_t child)
{
	if (xs_exists(XST_NIL, xenbus_get_node(child), "") == 0) {

		/*
		 * Device tree has been removed from Xenbus.
		 * Tear down the device.
		 */
		xenbusb_delete_child(dev, child);
	}
}
예제 #6
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);
}