@@ -41,6 +41,12 @@ static void xen_backend_table_add(XenBackendImpl *impl)
g_hash_table_insert(xen_backend_table_get(), (void *)impl->type, impl);
}
+static const char **xen_backend_table_keys(unsigned int *count)
+{
+ return (const char **)g_hash_table_get_keys_as_array(
+ xen_backend_table_get(), count);
+}
+
static const XenBackendImpl *xen_backend_table_lookup(const char *type)
{
return g_hash_table_lookup(xen_backend_table_get(), type);
@@ -70,6 +76,11 @@ void xen_backend_register(const XenBackendInfo *info)
xen_backend_table_add(impl);
}
+const char **xen_backend_get_types(unsigned int *count)
+{
+ return xen_backend_table_keys(count);
+}
+
static QLIST_HEAD(, XenBackendInstance) backend_list;
static void xen_backend_list_add(XenBackendInstance *backend)
@@ -430,7 +430,15 @@ static void xen_bus_unrealize(BusState *bus)
trace_xen_bus_unrealize();
if (xenbus->backend_watch) {
- xen_bus_remove_watch(xenbus, xenbus->backend_watch, NULL);
+ unsigned int i;
+
+ for (i = 0; i < xenbus->backend_types; i++) {
+ if (xenbus->backend_watch[i]) {
+ xen_bus_remove_watch(xenbus, xenbus->backend_watch[i], NULL);
+ }
+ }
+
+ g_free(xenbus->backend_watch);
xenbus->backend_watch = NULL;
}
@@ -446,8 +454,11 @@ static void xen_bus_unrealize(BusState *bus)
static void xen_bus_realize(BusState *bus, Error **errp)
{
+ char *key = g_strdup_printf("%u", xen_domid);
XenBus *xenbus = XEN_BUS(bus);
unsigned int domid;
+ const char **type;
+ unsigned int i;
Error *local_err = NULL;
trace_xen_bus_realize();
@@ -469,19 +480,32 @@ static void xen_bus_realize(BusState *bus, Error **errp)
module_call_init(MODULE_INIT_XEN_BACKEND);
- xenbus->backend_watch =
- xen_bus_add_watch(xenbus, "", /* domain root node */
- "backend", xen_bus_backend_changed, &local_err);
- if (local_err) {
- /* This need not be treated as a hard error so don't propagate */
- error_reportf_err(local_err,
- "failed to set up enumeration watch: ");
+ type = xen_backend_get_types(&xenbus->backend_types);
+ xenbus->backend_watch = g_new(XenWatch *, xenbus->backend_types);
+
+ for (i = 0; i < xenbus->backend_types; i++) {
+ char *node = g_strdup_printf("backend/%s", type[i]);
+
+ xenbus->backend_watch[i] =
+ xen_bus_add_watch(xenbus, node, key, xen_bus_backend_changed,
+ &local_err);
+ if (local_err) {
+ /* This need not be treated as a hard error so don't propagate */
+ error_reportf_err(local_err,
+ "failed to set up '%s' enumeration watch: ",
+ type[i]);
+ }
+
+ g_free(node);
}
+ g_free(type);
+ g_free(key);
return;
fail:
xen_bus_unrealize(bus);
+ g_free(key);
}
static void xen_bus_unplug_request(HotplugHandler *hotplug,
@@ -31,6 +31,7 @@ void xen_backend_set_device(XenBackendInstance *backend,
XenDevice *xen_backend_get_device(XenBackendInstance *backend);
void xen_backend_register(const XenBackendInfo *info);
+const char **xen_backend_get_types(unsigned int *nr);
void xen_backend_device_create(XenBus *xenbus, const char *type,
const char *name, QDict *opts, Error **errp);
@@ -66,7 +66,8 @@ struct XenBus {
domid_t backend_id;
struct xs_handle *xsh;
XenWatchList *watch_list;
- XenWatch *backend_watch;
+ unsigned int backend_types;
+ XenWatch **backend_watch;
QLIST_HEAD(, XenDevice) inactive_devices;
};