diff options
Diffstat (limited to 'tools/libxl/libxl_device.c')
-rw-r--r-- | tools/libxl/libxl_device.c | 32 |
1 files changed, 24 insertions, 8 deletions
diff --git a/tools/libxl/libxl_device.c b/tools/libxl/libxl_device.c index bc86648af8..ea845b7334 100644 --- a/tools/libxl/libxl_device.c +++ b/tools/libxl/libxl_device.c @@ -84,11 +84,12 @@ out: } int libxl__device_generic_add(libxl__gc *gc, xs_transaction_t t, - libxl__device *device, char **bents, char **fents) + libxl__device *device, char **bents, char **fents, char **ro_fents) { libxl_ctx *ctx = libxl__gc_owner(gc); char *frontend_path, *backend_path; struct xs_permissions frontend_perms[2]; + struct xs_permissions ro_frontend_perms[2]; struct xs_permissions backend_perms[2]; int create_transaction = t == XBT_NULL; @@ -100,22 +101,37 @@ int libxl__device_generic_add(libxl__gc *gc, xs_transaction_t t, frontend_perms[1].id = device->backend_domid; frontend_perms[1].perms = XS_PERM_READ; - backend_perms[0].id = device->backend_domid; - backend_perms[0].perms = XS_PERM_NONE; - backend_perms[1].id = device->domid; - backend_perms[1].perms = XS_PERM_READ; + ro_frontend_perms[0].id = backend_perms[0].id = device->backend_domid; + ro_frontend_perms[0].perms = backend_perms[0].perms = XS_PERM_NONE; + ro_frontend_perms[1].id = backend_perms[1].id = device->domid; + ro_frontend_perms[1].perms = backend_perms[1].perms = XS_PERM_READ; retry_transaction: if (create_transaction) t = xs_transaction_start(ctx->xsh); /* FIXME: read frontend_path and check state before removing stuff */ - if (fents) { + if (fents || ro_fents) { xs_rm(ctx->xsh, t, frontend_path); xs_mkdir(ctx->xsh, t, frontend_path); - xs_set_permissions(ctx->xsh, t, frontend_path, frontend_perms, ARRAY_SIZE(frontend_perms)); + /* Console 0 is a special case. It doesn't use the regular PV + * state machine but also the frontend directory has + * historically contained other information, such as the + * vnc-port, which we don't want the guest fiddling with. + */ + if (device->kind == LIBXL__DEVICE_KIND_CONSOLE && device->devid == 0) + xs_set_permissions(ctx->xsh, t, frontend_path, + ro_frontend_perms, ARRAY_SIZE(ro_frontend_perms)); + else + xs_set_permissions(ctx->xsh, t, frontend_path, + frontend_perms, ARRAY_SIZE(frontend_perms)); xs_write(ctx->xsh, t, libxl__sprintf(gc, "%s/backend", frontend_path), backend_path, strlen(backend_path)); - libxl__xs_writev(gc, t, frontend_path, fents); + if (fents) + libxl__xs_writev_perms(gc, t, frontend_path, fents, + frontend_perms, ARRAY_SIZE(frontend_perms)); + if (ro_fents) + libxl__xs_writev_perms(gc, t, frontend_path, ro_fents, + ro_frontend_perms, ARRAY_SIZE(ro_frontend_perms)); } if (bents) { |