/** * \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"); }
/** * 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)); }
/** * \brief Backend XenBus method implementing responses to peer state changes. * * \param bus The XenBus bus parent of child. * \param child The XenBus child whose peer stat has changed. * \param state The current state of the peer. */ static void xenbusb_back_otherend_changed(device_t bus, device_t child, enum xenbus_state peer_state) { /* Perform default processing of state. */ xenbusb_otherend_changed(bus, child, peer_state); /* * "Online" devices are never fully detached in the * newbus sense. Only the front<->back connection is * torn down. If the front returns to the initialising * state after closing a previous connection, signal * our willingness to reconnect and that all necessary * XenStore data for feature negotiation is present. */ if (peer_state == XenbusStateInitialising && xenbus_dev_is_online(child) != 0 && xenbus_get_state(child) == XenbusStateClosed) xenbus_set_state(child, XenbusStateInitWait); }