* [PATCH] libxl: add custom disconnect functions for different device types
@ 2011-09-23 11:55 Roger Pau Monne
2011-09-23 15:13 ` Ian Campbell
0 siblings, 1 reply; 3+ messages in thread
From: Roger Pau Monne @ 2011-09-23 11:55 UTC (permalink / raw)
To: xen-devel
# HG changeset patch
# User Roger Pau Monne <roger.pau@entel.upc.edu>
# Date 1316778937 -7200
# Node ID 1d42b1b355c231e794a56dfadf3ee450346e3516
# Parent 0ab9f548890e5e58122f73aa1c4164fd6e319b1c
libxl: add custom disconnect functions for different device types.
This patch creates a new struct, called libxl__disconnect that can be used to assign different functions that will be called to check if the device is disconnected and to add it to the shutdown watch. Added a helper function to get the libxl__device_kind from a be_path. The only device that has a different shutdown mechanism right now is vbd.
diff -r 0ab9f548890e -r 1d42b1b355c2 tools/libxl/libxl_device.c
--- a/tools/libxl/libxl_device.c Fri Sep 23 13:31:51 2011 +0200
+++ b/tools/libxl/libxl_device.c Fri Sep 23 13:55:37 2011 +0200
@@ -38,6 +38,27 @@ static const char *string_of_kinds[] = {
[DEVICE_CONSOLE] = "console",
};
+static const libxl__disconnect disconnect_vbd = {
+ .watch_for_disconnect = libxl__watch_for_disconnect_vbd,
+ .has_disconnected = libxl__has_disconnected_vbd,
+};
+
+static const libxl__disconnect disconnect_generic = {
+ .watch_for_disconnect = libxl__watch_for_disconnect_generic,
+ .has_disconnected = libxl__has_disconnected_generic,
+};
+
+static const libxl__disconnect *disconnect_ops[] = {
+ [DEVICE_UNKNOWN] = &disconnect_generic,
+ [DEVICE_VIF] = &disconnect_generic,
+ [DEVICE_VBD] = &disconnect_vbd,
+ [DEVICE_QDISK] = &disconnect_generic,
+ [DEVICE_PCI] = &disconnect_generic,
+ [DEVICE_VFB] = &disconnect_generic,
+ [DEVICE_VKBD] = &disconnect_generic,
+ [DEVICE_CONSOLE] = &disconnect_generic,
+};
+
char *libxl__device_frontend_path(libxl__gc *gc, libxl__device *device)
{
char *dom_path = libxl__xs_get_dompath(gc, device->domid);
@@ -59,6 +80,18 @@ char *libxl__device_backend_path(libxl__
device->domid, device->devid);
}
+libxl__device_kinds libxl__device_identify(char *be_path)
+{
+ int len = sizeof(string_of_kinds)/sizeof(char *);
+
+ for (int j = 1; j < len; j++) {
+ if (strstr(be_path, string_of_kinds[j]))
+ return j;
+ }
+
+ return DEVICE_UNKNOWN;
+}
+
int libxl__device_generic_add(libxl__gc *gc, libxl__device *device,
char **bents, char **fents)
{
@@ -371,15 +404,11 @@ int libxl__device_destroy(libxl__gc *gc,
libxl_ctx *ctx = libxl__gc_owner(gc);
xs_transaction_t t;
char *state_path = libxl__sprintf(gc, "%s/state", be_path);
- char *state = libxl__xs_read(gc, XBT_NULL, state_path);
+ libxl__device_kinds device_type = libxl__device_identify(be_path);
int rc = 0;
- if (!state)
+ if (disconnect_ops[device_type]->has_disconnected(gc, be_path))
goto out;
- if (atoi(state) != 4) {
- xs_rm(ctx->xsh, XBT_NULL, be_path);
- goto out;
- }
retry_transaction:
t = xs_transaction_start(ctx->xsh);
@@ -394,7 +423,7 @@ retry_transaction:
}
}
if (!force) {
- xs_watch(ctx->xsh, state_path, be_path);
+ disconnect_ops[device_type]->watch_for_disconnect(gc, be_path);
rc = 1;
} else {
xs_rm(ctx->xsh, XBT_NULL, be_path);
@@ -410,6 +439,7 @@ static int wait_for_dev_destroy(libxl__g
unsigned int n;
fd_set rfds;
char **l1 = NULL;
+ libxl__device_kinds device_type;
rc = 1;
nfds = xs_fileno(ctx->xsh) + 1;
@@ -418,11 +448,9 @@ static int wait_for_dev_destroy(libxl__g
if (select(nfds, &rfds, NULL, NULL, tv) > 0) {
l1 = xs_read_watch(ctx->xsh, &n);
if (l1 != NULL) {
- char *state = libxl__xs_read(gc, XBT_NULL, l1[XS_WATCH_PATH]);
- if (!state || atoi(state) == 6) {
+ device_type = libxl__device_identify(l1[XS_WATCH_TOKEN]);
+ if (disconnect_ops[device_type]->has_disconnected(gc, l1[XS_WATCH_TOKEN])) {
xs_unwatch(ctx->xsh, l1[0], l1[1]);
- xs_rm(ctx->xsh, XBT_NULL, l1[XS_WATCH_TOKEN]);
- LIBXL__LOG(ctx, LIBXL__LOG_DEBUG, "Destroyed device backend at %s", l1[XS_WATCH_TOKEN]);
rc = 0;
}
free(l1);
@@ -528,6 +556,62 @@ out:
return rc;
}
+int libxl__watch_for_disconnect_vbd(libxl__gc *gc, char *be_path)
+{
+ libxl_ctx *ctx = libxl__gc_owner(gc);
+ char *hotplug_path = libxl__sprintf(gc, "%s/hotplug-status", be_path);
+
+ xs_watch(ctx->xsh, hotplug_path, be_path);
+
+ return 1;
+}
+
+int libxl__has_disconnected_vbd(libxl__gc *gc, char *be_path)
+{
+ libxl_ctx *ctx = libxl__gc_owner(gc);
+ char *hotplug_path = libxl__sprintf(gc, "%s/hotplug-status", be_path);
+ char *hotplug = libxl__xs_read(gc, XBT_NULL, hotplug_path);
+ int rc = 0;
+
+ if (!hotplug || !strcmp(hotplug, "disconnected")) {
+ xs_rm(ctx->xsh, XBT_NULL, be_path);
+ LIBXL__LOG(ctx, LIBXL__LOG_DEBUG,
+ "Destroyed device backend at %s",
+ be_path);
+ rc = 1;
+ }
+
+ return rc;
+}
+
+int libxl__watch_for_disconnect_generic(libxl__gc *gc, char *be_path)
+{
+ libxl_ctx *ctx = libxl__gc_owner(gc);
+ char *state_path = libxl__sprintf(gc, "%s/state", be_path);
+
+ xs_watch(ctx->xsh, state_path, be_path);
+
+ return 1;
+}
+
+int libxl__has_disconnected_generic(libxl__gc *gc, char *be_path)
+{
+ libxl_ctx *ctx = libxl__gc_owner(gc);
+ char *state_path = libxl__sprintf(gc, "%s/state", be_path);
+ char *state = libxl__xs_read(gc, XBT_NULL, state_path);
+ int rc = 0;
+
+ if (!state || atoi(state) != 4) {
+ xs_rm(ctx->xsh, XBT_NULL, be_path);
+ LIBXL__LOG(ctx, LIBXL__LOG_DEBUG,
+ "Destroyed device backend at %s",
+ be_path);
+ rc = 1;
+ }
+
+ return rc;
+}
+
int libxl__wait_for_device_model(libxl__gc *gc,
uint32_t domid, char *state,
libxl__device_model_starting *starting,
diff -r 0ab9f548890e -r 1d42b1b355c2 tools/libxl/libxl_internal.h
--- a/tools/libxl/libxl_internal.h Fri Sep 23 13:31:51 2011 +0200
+++ b/tools/libxl/libxl_internal.h Fri Sep 23 13:55:37 2011 +0200
@@ -95,7 +95,8 @@ struct libxl__ctx {
};
typedef enum {
- DEVICE_VIF = 1,
+ DEVICE_UNKNOWN = 0,
+ DEVICE_VIF,
DEVICE_VBD,
DEVICE_QDISK,
DEVICE_PCI,
@@ -206,6 +207,12 @@ _hidden int libxl__domain_save_device_mo
_hidden void libxl__userdata_destroyall(libxl__gc *gc, uint32_t domid);
/* from xl_device */
+
+typedef struct {
+ int (*watch_for_disconnect)(libxl__gc *gc, char *be_path);
+ int (*has_disconnected)(libxl__gc *gc, char *be_path);
+} libxl__disconnect;
+
_hidden char *libxl__device_disk_string_of_backend(libxl_disk_backend backend);
_hidden char *libxl__device_disk_string_of_format(libxl_disk_format format);
_hidden int libxl__device_disk_set_backend(libxl__gc*, libxl_device_disk*);
@@ -226,6 +233,11 @@ _hidden int libxl__device_del(libxl__gc
_hidden int libxl__device_destroy(libxl__gc *gc, char *be_path, int force);
_hidden int libxl__devices_destroy(libxl__gc *gc, uint32_t domid, int force);
_hidden int libxl__wait_for_backend(libxl__gc *gc, char *be_path, char *state);
+_hidden int libxl__watch_for_disconnect_vbd(libxl__gc *gc, char *be_path);
+_hidden int libxl__has_disconnected_vbd(libxl__gc *gc, char *be_path);
+_hidden int libxl__watch_for_disconnect_generic(libxl__gc *gc, char *be_path);
+_hidden int libxl__has_disconnected_generic(libxl__gc *gc, char *be_path);
+_hidden libxl__device_kinds libxl__device_identify(char *be_path);
/* from libxl_pci */
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH] libxl: add custom disconnect functions for different device types
2011-09-23 11:55 [PATCH] libxl: add custom disconnect functions for different device types Roger Pau Monne
@ 2011-09-23 15:13 ` Ian Campbell
2011-09-26 9:26 ` Roger Pau Monne
0 siblings, 1 reply; 3+ messages in thread
From: Ian Campbell @ 2011-09-23 15:13 UTC (permalink / raw)
To: Roger Pau Monne; +Cc: xen-devel
On Fri, 2011-09-23 at 12:55 +0100, Roger Pau Monne wrote:
> # HG changeset patch
> # User Roger Pau Monne <roger.pau@entel.upc.edu>
> # Date 1316778937 -7200
> # Node ID 1d42b1b355c231e794a56dfadf3ee450346e3516
> # Parent 0ab9f548890e5e58122f73aa1c4164fd6e319b1c
> libxl: add custom disconnect functions for different device types.
>
> This patch creates a new struct, called libxl__disconnect that can be
> used to assign different functions that will be called to check if the
> device is disconnected and to add it to the shutdown watch. Added a
> helper function to get the libxl__device_kind from a be_path. The only
> device that has a different shutdown mechanism right now is vbd.
Looks good. I think all the new functions can be static to
libxl_device.c though.
> diff -r 0ab9f548890e -r 1d42b1b355c2 tools/libxl/libxl_device.c
> --- a/tools/libxl/libxl_device.c Fri Sep 23 13:31:51 2011 +0200
> +++ b/tools/libxl/libxl_device.c Fri Sep 23 13:55:37 2011 +0200
> @@ -59,6 +80,18 @@ char *libxl__device_backend_path(libxl__
> device->domid, device->devid);
> }
>
> +libxl__device_kinds libxl__device_identify(char *be_path)
> +{
> + int len = sizeof(string_of_kinds)/sizeof(char *);
> +
> + for (int j = 1; j < len; j++) {
> + if (strstr(be_path, string_of_kinds[j]))
> + return j;
> + }
> +
> + return DEVICE_UNKNOWN;
You can sscanf out the precise backend rather than using strstr (which I
worry might give false positives and/or rely in the ordering on the enum
in the future).
e.g. something like:
/* /local/domain/<domid>/backend/<kind>/<domid>/<devid> */
char strkind[16]; /* Longest is actually "console" */
uint32_t domain;
int rc = sscanf(path, "/local/domain/%d/backend/%16s/%d/%d",
domid, strkind, &domain, devid);
/* loop and strcmp of strkind vs string_of_kinds */
Ian.
^ permalink raw reply [flat|nested] 3+ messages in thread
* [PATCH] libxl: add custom disconnect functions for different device types
2011-09-23 15:13 ` Ian Campbell
@ 2011-09-26 9:26 ` Roger Pau Monne
0 siblings, 0 replies; 3+ messages in thread
From: Roger Pau Monne @ 2011-09-26 9:26 UTC (permalink / raw)
To: xen-devel; +Cc: Ian.Campbell
# HG changeset patch
# User Roger Pau Monne <roger.pau@entel.upc.edu>
# Date 1317028951 -7200
# Node ID 18c7ed71d2bfe50b65427860bb192ef273568b04
# Parent 0ab9f548890e5e58122f73aa1c4164fd6e319b1c
libxl: add custom disconnect functions for different device types.
This patch creates a new struct, called libxl__disconnect that can be used to assign different functions that will be called to check if the device is disconnected and to add it to the shutdown watch. Added a helper function to get the libxl__device_kind from a be_path. The only device that has a different shutdown mechanism right now is vbd.
diff -r 0ab9f548890e -r 18c7ed71d2bf tools/libxl/libxl_device.c
--- a/tools/libxl/libxl_device.c Fri Sep 23 13:31:51 2011 +0200
+++ b/tools/libxl/libxl_device.c Mon Sep 26 11:22:31 2011 +0200
@@ -28,6 +28,11 @@
#include "libxl.h"
#include "libxl_internal.h"
+static int libxl__watch_for_disconnect_vbd(libxl__gc *gc, char *be_path);
+static int libxl__has_disconnected_vbd(libxl__gc *gc, char *be_path);
+static int libxl__watch_for_disconnect_generic(libxl__gc *gc, char *be_path);
+static int libxl__has_disconnected_generic(libxl__gc *gc, char *be_path);
+
static const char *string_of_kinds[] = {
[DEVICE_VIF] = "vif",
[DEVICE_VBD] = "vbd",
@@ -38,6 +43,27 @@ static const char *string_of_kinds[] = {
[DEVICE_CONSOLE] = "console",
};
+static const libxl__disconnect disconnect_vbd = {
+ .watch_for_disconnect = libxl__watch_for_disconnect_vbd,
+ .has_disconnected = libxl__has_disconnected_vbd,
+};
+
+static const libxl__disconnect disconnect_generic = {
+ .watch_for_disconnect = libxl__watch_for_disconnect_generic,
+ .has_disconnected = libxl__has_disconnected_generic,
+};
+
+static const libxl__disconnect *disconnect_ops[] = {
+ [DEVICE_UNKNOWN] = &disconnect_generic,
+ [DEVICE_VIF] = &disconnect_generic,
+ [DEVICE_VBD] = &disconnect_vbd,
+ [DEVICE_QDISK] = &disconnect_generic,
+ [DEVICE_PCI] = &disconnect_generic,
+ [DEVICE_VFB] = &disconnect_generic,
+ [DEVICE_VKBD] = &disconnect_generic,
+ [DEVICE_CONSOLE] = &disconnect_generic,
+};
+
char *libxl__device_frontend_path(libxl__gc *gc, libxl__device *device)
{
char *dom_path = libxl__xs_get_dompath(gc, device->domid);
@@ -59,6 +85,23 @@ char *libxl__device_backend_path(libxl__
device->domid, device->devid);
}
+static libxl__device_kinds libxl__device_identify(char *be_path)
+{
+ char strkind[16]; /* Longest is actually "console" */
+ int len = sizeof(string_of_kinds)/sizeof(char *);
+
+ /* /local/domain/<domid>/backend/<kind>/<domid>/<devid> */
+ if (sscanf(be_path, "/local/domain/%*d/backend/%16[^/]s", strkind) != 1)
+ return DEVICE_UNKNOWN;
+
+ for (int j = 1; j < len; j++) {
+ if (strncmp(strkind, string_of_kinds[j], 16) == 0)
+ return j;
+ }
+
+ return DEVICE_UNKNOWN;
+}
+
int libxl__device_generic_add(libxl__gc *gc, libxl__device *device,
char **bents, char **fents)
{
@@ -371,15 +414,11 @@ int libxl__device_destroy(libxl__gc *gc,
libxl_ctx *ctx = libxl__gc_owner(gc);
xs_transaction_t t;
char *state_path = libxl__sprintf(gc, "%s/state", be_path);
- char *state = libxl__xs_read(gc, XBT_NULL, state_path);
+ libxl__device_kinds device_type = libxl__device_identify(be_path);
int rc = 0;
- if (!state)
+ if (disconnect_ops[device_type]->has_disconnected(gc, be_path))
goto out;
- if (atoi(state) != 4) {
- xs_rm(ctx->xsh, XBT_NULL, be_path);
- goto out;
- }
retry_transaction:
t = xs_transaction_start(ctx->xsh);
@@ -394,7 +433,7 @@ retry_transaction:
}
}
if (!force) {
- xs_watch(ctx->xsh, state_path, be_path);
+ disconnect_ops[device_type]->watch_for_disconnect(gc, be_path);
rc = 1;
} else {
xs_rm(ctx->xsh, XBT_NULL, be_path);
@@ -410,6 +449,7 @@ static int wait_for_dev_destroy(libxl__g
unsigned int n;
fd_set rfds;
char **l1 = NULL;
+ libxl__device_kinds device_type;
rc = 1;
nfds = xs_fileno(ctx->xsh) + 1;
@@ -418,11 +458,9 @@ static int wait_for_dev_destroy(libxl__g
if (select(nfds, &rfds, NULL, NULL, tv) > 0) {
l1 = xs_read_watch(ctx->xsh, &n);
if (l1 != NULL) {
- char *state = libxl__xs_read(gc, XBT_NULL, l1[XS_WATCH_PATH]);
- if (!state || atoi(state) == 6) {
+ device_type = libxl__device_identify(l1[XS_WATCH_TOKEN]);
+ if (disconnect_ops[device_type]->has_disconnected(gc, l1[XS_WATCH_TOKEN])) {
xs_unwatch(ctx->xsh, l1[0], l1[1]);
- xs_rm(ctx->xsh, XBT_NULL, l1[XS_WATCH_TOKEN]);
- LIBXL__LOG(ctx, LIBXL__LOG_DEBUG, "Destroyed device backend at %s", l1[XS_WATCH_TOKEN]);
rc = 0;
}
free(l1);
@@ -528,6 +566,62 @@ out:
return rc;
}
+static int libxl__watch_for_disconnect_vbd(libxl__gc *gc, char *be_path)
+{
+ libxl_ctx *ctx = libxl__gc_owner(gc);
+ char *hotplug_path = libxl__sprintf(gc, "%s/hotplug-status", be_path);
+
+ xs_watch(ctx->xsh, hotplug_path, be_path);
+
+ return 1;
+}
+
+static int libxl__has_disconnected_vbd(libxl__gc *gc, char *be_path)
+{
+ libxl_ctx *ctx = libxl__gc_owner(gc);
+ char *hotplug_path = libxl__sprintf(gc, "%s/hotplug-status", be_path);
+ char *hotplug = libxl__xs_read(gc, XBT_NULL, hotplug_path);
+ int rc = 0;
+
+ if (!hotplug || !strcmp(hotplug, "disconnected")) {
+ xs_rm(ctx->xsh, XBT_NULL, be_path);
+ LIBXL__LOG(ctx, LIBXL__LOG_DEBUG,
+ "Destroyed device backend at %s",
+ be_path);
+ rc = 1;
+ }
+
+ return rc;
+}
+
+static int libxl__watch_for_disconnect_generic(libxl__gc *gc, char *be_path)
+{
+ libxl_ctx *ctx = libxl__gc_owner(gc);
+ char *state_path = libxl__sprintf(gc, "%s/state", be_path);
+
+ xs_watch(ctx->xsh, state_path, be_path);
+
+ return 1;
+}
+
+static int libxl__has_disconnected_generic(libxl__gc *gc, char *be_path)
+{
+ libxl_ctx *ctx = libxl__gc_owner(gc);
+ char *state_path = libxl__sprintf(gc, "%s/state", be_path);
+ char *state = libxl__xs_read(gc, XBT_NULL, state_path);
+ int rc = 0;
+
+ if (!state || atoi(state) != 4) {
+ xs_rm(ctx->xsh, XBT_NULL, be_path);
+ LIBXL__LOG(ctx, LIBXL__LOG_DEBUG,
+ "Destroyed device backend at %s",
+ be_path);
+ rc = 1;
+ }
+
+ return rc;
+}
+
int libxl__wait_for_device_model(libxl__gc *gc,
uint32_t domid, char *state,
libxl__device_model_starting *starting,
diff -r 0ab9f548890e -r 18c7ed71d2bf tools/libxl/libxl_internal.h
--- a/tools/libxl/libxl_internal.h Fri Sep 23 13:31:51 2011 +0200
+++ b/tools/libxl/libxl_internal.h Mon Sep 26 11:22:31 2011 +0200
@@ -95,7 +95,8 @@ struct libxl__ctx {
};
typedef enum {
- DEVICE_VIF = 1,
+ DEVICE_UNKNOWN = 0,
+ DEVICE_VIF,
DEVICE_VBD,
DEVICE_QDISK,
DEVICE_PCI,
@@ -206,6 +207,12 @@ _hidden int libxl__domain_save_device_mo
_hidden void libxl__userdata_destroyall(libxl__gc *gc, uint32_t domid);
/* from xl_device */
+
+typedef struct {
+ int (*watch_for_disconnect)(libxl__gc *gc, char *be_path);
+ int (*has_disconnected)(libxl__gc *gc, char *be_path);
+} libxl__disconnect;
+
_hidden char *libxl__device_disk_string_of_backend(libxl_disk_backend backend);
_hidden char *libxl__device_disk_string_of_format(libxl_disk_format format);
_hidden int libxl__device_disk_set_backend(libxl__gc*, libxl_device_disk*);
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2011-09-26 9:26 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-09-23 11:55 [PATCH] libxl: add custom disconnect functions for different device types Roger Pau Monne
2011-09-23 15:13 ` Ian Campbell
2011-09-26 9:26 ` Roger Pau Monne
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.