|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH v2 for-4.6 1/2] libxl: fix devd removal path
On Wed, 2015-09-23 at 12:06 +0200, Roger Pau Monne wrote:
> The current flow of the devd helper (in charge of launching hotplug
> scripts
> inside of driver domains) is to wait for the device backend to switch to
> state 6 (XenbusStateClosed) and then remove it. This is not correct,
> since
> a domain can reconnect it's PV devices as many times as it wants.
>
> In order to fix this, introduce the following logic: the control domain
> will
> set the "online" backend node to 0 when it wants the driver domain to
> disconnect the device, so now the condition applied in devd is that
> "state"
> must be 6 and "online" 0 in order to proceed with the disconnection.
>
> Signed-off-by: Roger Pau Monnà <roger.pau@xxxxxxxxxx>
> Reported-by: Alex Velazquez <alex.j.velazquez@xxxxxxxxx>
> Cc: Alex Velazquez <alex.j.velazquez@xxxxxxxxx>
> Cc: Ian Jackson <ian.jackson@xxxxxxxxxxxxx>
Acked-by: Ian Campbell <ian.campbell@xxxxxxxxxx>
> Cc: Wei Liu <wei.liu2@xxxxxxxxxx>
> ---
> Changes since v1:
> - Use strrchr and strcmp in order to check the event path.
> - Remove superfluous LOG in case of failed xenstore write.
> - Remove uneeded strlen checks.
> ---
> tools/libxl/libxl.c | 32 ++++++++++++++++++--------------
> tools/libxl/libxl_device.c | 9 ++++-----
> 2 files changed, 22 insertions(+), 19 deletions(-)
>
> diff --git a/tools/libxl/libxl.c b/tools/libxl/libxl.c
> index 10d1909..6c4ef6d 100644
> --- a/tools/libxl/libxl.c
> +++ b/tools/libxl/libxl.c
> @@ -4410,32 +4410,36 @@ static void backend_watch_callback(libxl__egc
> *egc, libxl__ev_xswatch *watch,
> libxl__ao *nested_ao = libxl__nested_ao_create(ddomain->ao);
> STATE_AO_GC(nested_ao);
> char *p, *path;
> - const char *sstate;
> - int state, rc, num_devs;
> + const char *sstate, *sonline;
> + int state, online, rc, num_devs;
> libxl__device *dev = NULL;
> libxl__ddomain_device *ddev = NULL;
> libxl__ddomain_guest *dguest = NULL;
> bool free_ao = false;
>
> - /* Check if event_path ends with "state" and truncate it */
> - if (strlen(event_path) < strlen("state"))
> - goto skip;
> -
> + /* Check if event_path ends with "state" or "online" and truncate
> it. */
> path = libxl__strdup(gc, event_path);
> - p = path + strlen(path) - strlen("state") - 1;
> - if (*p != '/')
> + p = strrchr(path, '/');
> + if (p == NULL)
> goto skip;
> - *p = '\0';
> - p++;
> - if (strcmp(p, "state") != 0)
> + if (strcmp(p, "/state") != 0 && strcmp(p, "/online") != 0)
> goto skip;
> + /* Truncate the string so it points to the backend directory. */
> + *p = '\0';
>
> - /* Check if the state is 1 (XenbusStateInitialising) or greater */
> - rc = libxl__xs_read_checked(gc, XBT_NULL, event_path, &sstate);
> + /* Fetch the value of the state and online nodes. */
> + rc = libxl__xs_read_checked(gc, XBT_NULL, GCSPRINTF("%s/state",
> path),
> + &sstate);
> if (rc || !sstate)
> goto skip;
> state = atoi(sstate);
>
> + rc = libxl__xs_read_checked(gc, XBT_NULL, GCSPRINTF("%s/online",
> path),
> + &sonline);
> + if (rc || !sonline)
> + goto skip;
> + online = atoi(sonline);
> +
> dev = libxl__zalloc(NOGC, sizeof(*dev));
> rc = libxl__parse_backend_path(gc, path, dev);
> if (rc)
> @@ -4477,7 +4481,7 @@ static void backend_watch_callback(libxl__egc *egc,
> libxl__ev_xswatch *watch,
> rc = add_device(egc, nested_ao, dguest, ddev);
> if (rc > 0)
> free_ao = true;
> - } else if (state == XenbusStateClosed) {
> + } else if (state == XenbusStateClosed && online == 0) {
> /*
> * Removal of an active device, remove it from the list and
> * free it's data structures if they are no longer needed.
> diff --git a/tools/libxl/libxl_device.c b/tools/libxl/libxl_device.c
> index bee5ed5..85a3662 100644
> --- a/tools/libxl/libxl_device.c
> +++ b/tools/libxl/libxl_device.c
> @@ -837,16 +837,15 @@ void libxl__initiate_device_remove(libxl__egc *egc,
> goto out;
> }
>
> + rc = libxl__xs_write_checked(gc, t, online_path, "0");
> + if (rc)
> + goto out;
> +
> /*
> * Check if device is already in "closed" state, in which case
> * it should not be changed.
> */
> if (state && atoi(state) != XenbusStateClosed) {
> - rc = libxl__xs_write_checked(gc, t, online_path, "0");
> - if (rc) {
> - LOG(ERROR, "unable to write to xenstore path %s",
> online_path);
> - goto out;
> - }
> rc = libxl__xs_write_checked(gc, t, state_path,
> GCSPRINTF("%d", XenbusStateClosing));
> if (rc) {
> LOG(ERROR, "unable to write to xenstore path %s",
> state_path);
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |