debuggers.hg

changeset 22273:368957d8b063

libxl: remove console 0 backend directory from xenstore on devices destroy

The first PV console device has an unusual frontend path for
historical reasons (/local/domain/<domid>/console rather than
/local/domain/<domid>/device/console/0).

Therefore we need to check this additional frontend path as well as
those under /local/domain/<domid>/device when tearing down all
backends or else we miss the backend for the console.

As part of this we need to ensure that the frontend directory has a
valid link to the backend, currently this link does not exist.

Fix this by adding libxl__device_frontend_path to return the correct
frontend path, accounting for the special case, and use it from
libxl__device_add_generic. Also add libxl__device_backend_path for
consistency.

This also allows console 0 setup to follow essentially the same code
path as other consoles within libxl_device_console_add, reducing the
special casing required there.

This also fixes the link from backend to frontend which until now gave
a dangling link to the normal device path instead of the exceptional
one.

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
committer: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
author Ian Campbell <ian.campbell@citrix.com>
date Tue Oct 05 17:51:28 2010 +0100 (2010-10-05)
parents 83a97418d9cd
children 02e199c96ece
files tools/libxl/libxl.c tools/libxl/libxl_device.c
line diff
     1.1 --- a/tools/libxl/libxl.c	Tue Oct 05 14:22:19 2010 +0100
     1.2 +++ b/tools/libxl/libxl.c	Tue Oct 05 17:51:28 2010 +0100
     1.3 @@ -2331,30 +2331,6 @@ int libxl_device_console_add(libxl_ctx *
     1.4      libxl__device device;
     1.5      int rc;
     1.6  
     1.7 -    if (console->build_state) {
     1.8 -        xs_transaction_t t;
     1.9 -        char **ents = (char **) libxl__calloc(&gc, 11, sizeof(char *));
    1.10 -        ents[0] = "console/port";
    1.11 -        ents[1] = libxl__sprintf(&gc, "%"PRIu32, console->build_state->console_port);
    1.12 -        ents[2] = "console/ring-ref";
    1.13 -        ents[3] = libxl__sprintf(&gc, "%lu", console->build_state->console_mfn);
    1.14 -        ents[4] = "console/limit";
    1.15 -        ents[5] = libxl__sprintf(&gc, "%d", LIBXL_XENCONSOLE_LIMIT);
    1.16 -        ents[6] = "console/type";
    1.17 -        if (console->consback == LIBXL_CONSBACK_XENCONSOLED)
    1.18 -            ents[7] = "xenconsoled";
    1.19 -        else
    1.20 -            ents[7] = "ioemu";
    1.21 -        ents[8] = "console/output";
    1.22 -        ents[9] = console->output;
    1.23 -retry_transaction:
    1.24 -        t = xs_transaction_start(ctx->xsh);
    1.25 -        libxl__xs_writev(&gc, t, libxl__xs_get_dompath(&gc, console->domid), ents);
    1.26 -        if (!xs_transaction_end(ctx->xsh, t, 0))
    1.27 -            if (errno == EAGAIN)
    1.28 -                goto retry_transaction;
    1.29 -    }
    1.30 -
    1.31      front = flexarray_make(16, 1);
    1.32      if (!front) {
    1.33          rc = ERROR_NOMEM;
    1.34 @@ -2384,24 +2360,32 @@ retry_transaction:
    1.35      flexarray_set(back, boffset++, "protocol");
    1.36      flexarray_set(back, boffset++, LIBXL_XENCONSOLE_PROTOCOL);
    1.37  
    1.38 -    /* if devid == 0 do not add the frontend to device/console/ because
    1.39 -     * it has already been added to console/ */
    1.40 -    if (device.devid > 0) {
    1.41 -        flexarray_set(front, foffset++, "backend-id");
    1.42 -        flexarray_set(front, foffset++, libxl__sprintf(&gc, "%d", console->backend_domid));
    1.43 +    flexarray_set(front, foffset++, "backend-id");
    1.44 +    flexarray_set(front, foffset++, libxl__sprintf(&gc, "%d", console->backend_domid));
    1.45 +    flexarray_set(front, foffset++, "limit");
    1.46 +    flexarray_set(front, foffset++, libxl__sprintf(&gc, "%d", LIBXL_XENCONSOLE_LIMIT));
    1.47 +    flexarray_set(front, foffset++, "type");
    1.48 +    if (console->consback == LIBXL_CONSBACK_XENCONSOLED)
    1.49 +        flexarray_set(front, foffset++, "xenconsoled");
    1.50 +    else
    1.51 +        flexarray_set(front, foffset++, "ioemu");
    1.52 +    flexarray_set(front, foffset++, "output");
    1.53 +    flexarray_set(front, foffset++, console->output);
    1.54 +
    1.55 +    if (device.devid == 0) {
    1.56 +        if (console->build_state == NULL) {
    1.57 +            rc = ERROR_INVAL;
    1.58 +            goto out_free;
    1.59 +        }
    1.60 +        flexarray_set(front, foffset++, "port");
    1.61 +        flexarray_set(front, foffset++, libxl__sprintf(&gc, "%"PRIu32, console->build_state->console_port));
    1.62 +        flexarray_set(front, foffset++, "ring-ref");
    1.63 +        flexarray_set(front, foffset++, libxl__sprintf(&gc, "%lu", console->build_state->console_mfn));
    1.64 +    } else {
    1.65          flexarray_set(front, foffset++, "state");
    1.66          flexarray_set(front, foffset++, libxl__sprintf(&gc, "%d", 1));
    1.67 -        flexarray_set(front, foffset++, "limit");
    1.68 -        flexarray_set(front, foffset++, libxl__sprintf(&gc, "%d", LIBXL_XENCONSOLE_LIMIT));
    1.69          flexarray_set(front, foffset++, "protocol");
    1.70          flexarray_set(front, foffset++, LIBXL_XENCONSOLE_PROTOCOL);
    1.71 -        flexarray_set(front, foffset++, "type");
    1.72 -        if (console->consback == LIBXL_CONSBACK_XENCONSOLED)
    1.73 -            flexarray_set(front, foffset++, "xenconsoled");
    1.74 -        else
    1.75 -            flexarray_set(front, foffset++, "ioemu");
    1.76 -        flexarray_set(front, foffset++, "output");
    1.77 -        flexarray_set(front, foffset++, console->output);
    1.78      }
    1.79  
    1.80      libxl__device_generic_add(ctx, &device,
     2.1 --- a/tools/libxl/libxl_device.c	Tue Oct 05 14:22:19 2010 +0100
     2.2 +++ b/tools/libxl/libxl_device.c	Tue Oct 05 17:51:28 2010 +0100
     2.3 @@ -39,11 +39,32 @@ static const char *string_of_kinds[] = {
     2.4      [DEVICE_CONSOLE] = "console",
     2.5  };
     2.6  
     2.7 +static char *libxl__device_frontend_path(libxl__gc *gc, libxl__device *device)
     2.8 +{
     2.9 +    char *dom_path = libxl__xs_get_dompath(gc, device->domid);
    2.10 +
    2.11 +    /* Console 0 is a special case */
    2.12 +    if (device->kind == DEVICE_CONSOLE && device->devid == 0)
    2.13 +        return libxl__sprintf(gc, "%s/console", dom_path);
    2.14 +
    2.15 +    return libxl__sprintf(gc, "%s/device/%s/%d", dom_path,
    2.16 +                          string_of_kinds[device->kind], device->devid);
    2.17 +}
    2.18 +
    2.19 +static char *libxl__device_backend_path(libxl__gc *gc, libxl__device *device)
    2.20 +{
    2.21 +    char *dom_path = libxl__xs_get_dompath(gc, device->backend_domid);
    2.22 +
    2.23 +    return libxl__sprintf(gc, "%s/backend/%s/%u/%d", dom_path,
    2.24 +                          string_of_kinds[device->backend_kind],
    2.25 +                          device->domid, device->devid);
    2.26 +}
    2.27 +
    2.28  int libxl__device_generic_add(libxl_ctx *ctx, libxl__device *device,
    2.29                               char **bents, char **fents)
    2.30  {
    2.31      libxl__gc gc = LIBXL_INIT_GC(ctx);
    2.32 -    char *dom_path_backend, *dom_path, *frontend_path, *backend_path;
    2.33 +    char *frontend_path, *backend_path;
    2.34      xs_transaction_t t;
    2.35      struct xs_permissions frontend_perms[2];
    2.36      struct xs_permissions backend_perms[2];
    2.37 @@ -54,13 +75,8 @@ int libxl__device_generic_add(libxl_ctx 
    2.38          goto out;
    2.39      }
    2.40  
    2.41 -    dom_path_backend = libxl__xs_get_dompath(&gc, device->backend_domid);
    2.42 -    dom_path = libxl__xs_get_dompath(&gc, device->domid);
    2.43 -
    2.44 -    frontend_path = libxl__sprintf(&gc, "%s/device/%s/%d",
    2.45 -                                  dom_path, string_of_kinds[device->kind], device->devid);
    2.46 -    backend_path = libxl__sprintf(&gc, "%s/backend/%s/%u/%d",
    2.47 -                                 dom_path_backend, string_of_kinds[device->backend_kind], device->domid, device->devid);
    2.48 +    frontend_path = libxl__device_frontend_path(&gc, device);
    2.49 +    backend_path = libxl__device_backend_path(&gc, device);
    2.50  
    2.51      frontend_perms[0].id = device->domid;
    2.52      frontend_perms[0].perms = XS_PERM_NONE;
    2.53 @@ -326,6 +342,16 @@ int libxl__devices_destroy(libxl_ctx *ct
    2.54              }
    2.55          }
    2.56      }
    2.57 +
    2.58 +    /* console 0 frontend directory is not under /local/domain/<domid>/device */
    2.59 +    fe_path = libxl__sprintf(&gc, "/local/domain/%d/console", domid);
    2.60 +    be_path = libxl__xs_read(&gc, XBT_NULL, libxl__sprintf(&gc, "%s/backend", fe_path));
    2.61 +    if (be_path && strcmp(be_path, "")) {
    2.62 +        if (libxl__device_destroy(ctx, be_path, force) > 0)
    2.63 +            n_watches++;
    2.64 +        flexarray_set(toremove, n++, libxl__dirname(&gc, be_path));
    2.65 +    }
    2.66 +
    2.67      if (!force) {
    2.68          /* Linux-ism. Most implementations leave the timeout
    2.69           * untouched after select. Linux, however, will chip
    2.70 @@ -356,15 +382,11 @@ out:
    2.71  int libxl__device_del(libxl_ctx *ctx, libxl__device *dev, int wait)
    2.72  {
    2.73      libxl__gc gc = LIBXL_INIT_GC(ctx);
    2.74 -    char *dom_path_backend, *backend_path;
    2.75 +    char *backend_path;
    2.76      int rc;
    2.77  
    2.78 -    /* Create strings */
    2.79 -    dom_path_backend    = libxl__xs_get_dompath(&gc, dev->backend_domid);
    2.80 -    backend_path        = libxl__sprintf(&gc, "%s/backend/%s/%u/%d",
    2.81 -                                    dom_path_backend, 
    2.82 -                                    string_of_kinds[dev->backend_kind], 
    2.83 -                                    dev->domid, dev->devid);
    2.84 +    backend_path = libxl__device_backend_path(&gc, dev);
    2.85 +
    2.86      rc = libxl__device_destroy(ctx, backend_path, !wait);
    2.87      if (rc == -1) {
    2.88          rc = ERROR_FAIL;