[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH] libxl: sane disk backend selection and validation
On Wed, 2011-07-06 at 16:07 +0100, Ian Jackson wrote: > Introduce a new function libxl__device_disk_set_backend which > does some sanity checks and determines which backend ought to be used. > > If the caller specifies LIBXL_DISK_BACKEND_UNKNOWN (which has the > value 0), it tries PHY, TAP and QDISK in that order. Otherwise it > tries only the specified value. > > libxl__device_disk_set_backend (and its helper function > disk_try_backend) inherit the role (and small amounts of the code) > from validate_virtual_disk. This is called during do_domain_create > and also from libxl_disk_device_add (for the benefit of hotplug > devices). do_domain_create adds disks using libxl_disk_device_add, so is it really needed in both? > > It also now takes over the role of the scattered fragments of backend > selection found in libxl_device_disk_add, > libxl_device_disk_local_attach and libxl__need_xenpv_qemu. These > latter functions now simply do the job for the backend they find has > already been specified and checked. > > The restrictions on the capabilities of each backend, as expressed in > disk_try_backend (and to an extent in libxl_device_disk_local_attach) > are intended to be identical to the previous arrangements. > > In 23618:3173b68c8a94 combined with 23622:160f7f39841b, > 23623:c7180c353eb2, "xl" effectively became much more likely to select > TAP as the backend. With this change to libxl the default backend > selected by the libxl__device_disk_set_backend is intended to once > again to be PHY where possible. > > Signed-off-by: Ian Jackson <ian.jackson@xxxxxxxxxxxxx> > diff -r 7e4404a8f5f9 tools/libxl/libxl_create.c > --- a/tools/libxl/libxl_create.c Mon Jul 04 07:57:32 2011 +0100 > +++ b/tools/libxl/libxl_create.c Wed Jul 06 16:06:32 2011 +0100 > @@ -424,6 +424,13 @@ static int do_domain_create(libxl__gc *g > goto error_out; > } > > + > + for (i = 0; i < d_config->num_disks; i++) { > + ret = libxl__device_disk_set_backend(gc, &d_config->disks[i], > + dm_info); > + if (ret) goto error_out; > + } I presume this happens too late for the locally attached case since you call it there too? > + > if ( restore_fd < 0 ) { > ret = libxl_run_bootloader(ctx, &d_config->b_info, > d_config->num_disks > 0 ? &d_config->disks[0] : NULL, domid); > if (ret) { > diff -r 7e4404a8f5f9 tools/libxl/libxl_device.c > --- a/tools/libxl/libxl_device.c Mon Jul 04 07:57:32 2011 +0100 > +++ b/tools/libxl/libxl_device.c Wed Jul 06 16:06:32 2011 +0100 > @@ -116,6 +116,140 @@ retry_transaction: > rc = 0; > out: > return rc; > +} > + > +typedef struct { > + libxl__gc *gc; > + libxl_device_disk *disk; > + const libxl_device_model_info *dm_info; > + struct stat stab; > +} disk_try_backend_args; The struct seems a little like overkill compared with just passing the arguments but nevermind. > + > +static int disk_try_backend(disk_try_backend_args *a, > + libxl_disk_backend backend) { > + /* returns 0 (ie, DISK_BACKEND_UNKNOWN) on failure, or > + * backend on success */ > + libxl_ctx *ctx = libxl__gc_owner(a->gc); > + switch (backend) { > + > + case LIBXL_DISK_BACKEND_PHY: > + if (!(a->disk->format == LIBXL_DISK_FORMAT_RAW || > + a->disk->format == LIBXL_DISK_FORMAT_EMPTY)) { > + LIBXL__LOG(ctx, LIBXL__LOG_DEBUG, "Disk vdev=%s, backend phy" > + " unsuitable due to format %s", > + a->disk->vdev, > + libxl__device_disk_string_of_format(a->disk->format)); > + return 0; > + } > + if (a->disk->format != LIBXL_DISK_FORMAT_EMPTY && > + !S_ISBLK(a->stab.st_mode)) { > + LIBXL__LOG(ctx, LIBXL__LOG_DEBUG, "Disk vdev=%s, backend phy" > + " unsuitable as phys path not a block device", > + a->disk->vdev); > + return ERROR_INVAL; Can phy devices really be empty? Or must they refer to a block device (which may itself be an empty CD-ROM device but that's not the same)? > + } > + > + return backend; > + > + case LIBXL_DISK_BACKEND_TAP: > + if (!libxl__blktap_enabled(a->gc)) { > + LIBXL__LOG(ctx, LIBXL__LOG_DEBUG, "Disk vdev=%s, backend tap" > + " unsuitable because blktap not available", > + a->disk->vdev); > + return 0; > + } > + if (a->disk->format == LIBXL_DISK_FORMAT_EMPTY || > + (S_ISREG(a->stab.st_mode) && !a->stab.st_size)) { > + LIBXL__LOG(ctx, LIBXL__LOG_DEBUG, "Disk vdev=%s, backend tap" > + " unsuitable because empty devices not supported", > + a->disk->vdev); > + return 0; > + } > + return backend; > + > + case LIBXL_DISK_BACKEND_QDISK: > + if (!a->dm_info) { > + LIBXL__LOG(ctx, LIBXL__LOG_DEBUG, "Disk vdev=%s, backend qdisk" > + " unsuitable for dynamic attach", > + a->disk->vdev); > + return 0; > + } > + switch (a->dm_info->device_model_version) { > + case LIBXL_DEVICE_MODEL_VERSION_QEMU_XEN_TRADITIONAL: > + LIBXL__LOG(ctx, LIBXL__LOG_DEBUG, "Disk vdev=%s, backend qdisk" > + " unsuitable because using old qemu", > + a->disk->vdev); Wasn't that support backported at one point? > + return 0; > + case LIBXL_DEVICE_MODEL_VERSION_QEMU_XEN: > + return backend; > + } > + abort(); > + > + default: > + LIBXL__LOG(ctx, LIBXL__LOG_DEBUG, "Disk vdev=%s, backend " > + " %d unknown", a->disk->vdev, backend); > + return 0; > + > + } > +} > + > +int libxl__device_disk_set_backend(libxl__gc *gc, libxl_device_disk *disk, > + const libxl_device_model_info *dm_info) { > + libxl_ctx *ctx = libxl__gc_owner(gc); > + libxl_disk_backend ok; > + disk_try_backend_args a; > + > + a.gc = gc; > + a.disk = disk; > + a.dm_info = dm_info; > + > + LIBXL__LOG(ctx, LIBXL__LOG_DEBUG, "Disk vdev=%s spec.backend=%s", > + disk->vdev, > + libxl__device_disk_string_of_backend(disk->backend)); This (and other similar) could be libxl_disk_backend_to_string since 23568:d67133289286. In fact the original could possibly be nuked? (or is it used to lookups the xenstore name in some cases which may not match the enum name?). > + > + if (disk->format == LIBXL_DISK_FORMAT_EMPTY) { > + if (!disk->is_cdrom) { > + LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "Disk vdev=%s is empty" > + " but not cdrom", > + disk->vdev); > + return ERROR_INVAL; > + } > + memset(&a.stab, 0, sizeof(a.stab)); > + } else { > + if (stat(disk->pdev_path, &a.stab)) { > + LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "Disk vdev=%s " > + "failed to stat: %s", > + disk->vdev, disk->pdev_path); > + return ERROR_INVAL; > + } > + if (!S_ISBLK(a.stab.st_mode) & > + !S_ISREG(a.stab.st_mode)) { > + LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "Disk vdev=%s " > + "phys path is not a block dev or file: %s", > + disk->vdev, disk->pdev_path); > + return ERROR_INVAL; > + } > + } > + > + if (disk->backend != LIBXL_DISK_BACKEND_UNKNOWN) { > + ok= disk_try_backend(&a, disk->backend); > + } else { > + ok= > + disk_try_backend(&a, LIBXL_DISK_BACKEND_PHY) ?: > + disk_try_backend(&a, LIBXL_DISK_BACKEND_TAP) ?: > + disk_try_backend(&a, LIBXL_DISK_BACKEND_QDISK); > + if (ok) > + LIBXL__LOG(ctx, LIBXL__LOG_DEBUG, "Disk vdev=%s, using backend > %s", > + disk->vdev, > + libxl__device_disk_string_of_backend(ok)); > + } > + if (!ok) { > + LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "no suitable backend for disk %s", > + disk->vdev); > + return ERROR_INVAL; > + } > + disk->backend = ok; > + return 0; > } > > char *libxl__device_disk_string_of_format(libxl_disk_format format) > diff -r 7e4404a8f5f9 tools/libxl/libxl_dm.c > --- a/tools/libxl/libxl_dm.c Mon Jul 04 07:57:32 2011 +0100 > +++ b/tools/libxl/libxl_dm.c Wed Jul 06 16:06:32 2011 +0100 > @@ -1001,25 +1001,18 @@ int libxl__need_xenpv_qemu(libxl__gc *gc > } > > if (nr_disks > 0) { > - int blktap_enabled = -1; > for (i = 0; i < nr_disks; i++) { > switch (disks[i].backend) { > - case LIBXL_DISK_BACKEND_TAP: > - if (blktap_enabled == -1) > - blktap_enabled = libxl__blktap_enabled(gc); > - if (!blktap_enabled) { > - ret = 1; > - goto out; > - } > - break; > - > case LIBXL_DISK_BACKEND_QDISK: > ret = 1; > goto out; > > + case LIBXL_DISK_BACKEND_TAP: > case LIBXL_DISK_BACKEND_PHY: > - case LIBXL_DISK_BACKEND_UNKNOWN: > break; > + > + case LIBXL_DISK_FORMAT_UNKNOWN: > + abort(); /* impossible due to libxl__device_disk_set_backend > */ This switch could become a simple if (x == .... QDISK) now... > } > } > } > diff -r 7e4404a8f5f9 tools/libxl/libxl_internal.h > --- a/tools/libxl/libxl_internal.h Mon Jul 04 07:57:32 2011 +0100 > +++ b/tools/libxl/libxl_internal.h Wed Jul 06 16:06:32 2011 +0100 > @@ -205,6 +205,8 @@ _hidden void libxl__userdata_destroyall( > /* from xl_device */ > _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 > *disk, > + const libxl_device_model_info *dm_info); > > _hidden int libxl__device_physdisk_major_minor(const char *physpath, int > *major, int *minor); > _hidden int libxl__device_disk_dev_number(const char *virtpath, > > _______________________________________________ > Xen-devel mailing list > Xen-devel@xxxxxxxxxxxxxxxxxxx > http://lists.xensource.com/xen-devel _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |