[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [Patch v2 3/3] update libxl__device_disk_from_xs_be() to support blktap device
The API libxl_device_disk_list() will return all disks. But the type is wrong if it is a tapdisk device, because we get the type from the params xenstore node, not the tapdisk-params xenstore node. Update libxl__device_disk_from_xs_be(), try tapdisk-params xenstore node first to support blktap device. But even if we get type from tapdisk-params xenstore node, the type is still wrong, because we store wrong format into tapdisk-params xenstore node: if the format is raw, we store aio into either the tapdisk-params xenstore node. And we cannot use the API libxl_disk_format_from_string() to get the format from the string. So use libxl_disk_format_to_string() to instead of libxl__device_disk_string_of_format() to store the format to tapdisk-params xenstore node. Also update libxl__device_destroy_tapdisk() due to tapdisk-params change. Signed-off-by: Wen Congyang <wency@xxxxxxxxxxxxxx> --- tools/libxl/libxl.c | 109 ++++++++++++++++++++++++++++++++++++-------- tools/libxl/libxl_blktap2.c | 12 ++++- 2 files changed, 101 insertions(+), 20 deletions(-) diff --git a/tools/libxl/libxl.c b/tools/libxl/libxl.c index 9c72df2..efc3ca6 100644 --- a/tools/libxl/libxl.c +++ b/tools/libxl/libxl.c @@ -2404,7 +2404,7 @@ static void device_disk_add(libxl__egc *egc, uint32_t domid, } flexarray_append(back, "tapdisk-params"); flexarray_append(back, libxl__sprintf(gc, "%s:%s", - libxl__device_disk_string_of_format(disk->format), + libxl_disk_format_to_string(disk->format), disk->pdev_path)); /* tap backends with scripts are rejected by @@ -2514,6 +2514,55 @@ void libxl__device_disk_add(libxl__egc *egc, uint32_t domid, device_disk_add(egc, domid, disk, aodev, NULL, NULL); } +/* + * read params from xenstore node. The params's format should be + * "format:path" or "path". If the xenstore node doesn't exist, + * return 0, and both *format and *path are NULL. On success, + * the caller should be free *path by hand. + */ +static int read_params(libxl__gc *gc, const char *be_path, + char **format, char **path) +{ + char *params, *tmp; + + assert(format != NULL && path != NULL); + + *format = NULL; + *path = NULL; + + params = libxl__xs_read(gc, XBT_NULL, be_path); + if (!params) { + if (errno == ENOENT) + return 0; + + LOGE(ERROR, "cannot read %s", be_path); + return ERROR_FAIL; + } + + tmp = strchr(params, ':'); + if (!tmp) { + *path = strdup(params); + if (*path == NULL) + goto out; + + return 0; + } + + *path = strdup(tmp + 1); + if (*path == NULL) + goto out; + + *tmp = '\0'; + *format = params; + + return 0; + +out: + LOGE(ERROR, "no memory to store path"); + + return ERROR_NOMEM; +} + static int libxl__device_disk_from_xs_be(libxl__gc *gc, const char *be_path, libxl_device_disk *disk) @@ -2531,24 +2580,48 @@ static int libxl__device_disk_from_xs_be(libxl__gc *gc, goto cleanup; } - /* "params" may not be present; but everything else must be. */ - tmp = xs_read(ctx->xsh, XBT_NULL, - libxl__sprintf(gc, "%s/params", be_path), &len); - if (tmp && strchr(tmp, ':')) { - disk->pdev_path = strdup(strchr(tmp, ':') + 1); - free(tmp); - } else { - disk->pdev_path = tmp; - } - - - tmp = libxl__xs_read(gc, XBT_NULL, - libxl__sprintf(gc, "%s/type", be_path)); - if (!tmp) { - LOG(ERROR, "Missing xenstore node %s/type", be_path); + /* "tapdisk-params" is only for tapdisk */ + rc = read_params(gc, GCSPRINTF("%s/tapdisk-params", be_path), + &tmp, &disk->pdev_path); + if (rc) goto cleanup; + if (tmp || disk->pdev_path) { + if (!tmp) { + LOG(ERROR, "corrupted tapdisk-params: %s", disk->pdev_path); + goto cleanup; + } + rc = libxl_disk_format_from_string(tmp, &disk->format); + if (rc) { + LOG(ERROR, "unknown disk format: %s", tmp); + goto cleanup; + } + if (disk->format != LIBXL_DISK_FORMAT_VHD && + disk->format != LIBXL_DISK_FORMAT_RAW) { + /* We can get here only when the xenstore node is corrupted */ + LOG(ERROR, "unsupported tapdisk format: %s", tmp); + goto cleanup; + } + + /* + * The backend is tapdisk, so we store tapdev in params, and + * phy in type(see device_disk_add()) + */ + disk->backend = LIBXL_DISK_BACKEND_TAP; + } else { + /* "params" may not be present; but everything else must be. */ + rc = read_params(gc, GCSPRINTF("%s/params", be_path), + &tmp, &disk->pdev_path); + if (rc) + goto cleanup; + + tmp = libxl__xs_read(gc, XBT_NULL, + libxl__sprintf(gc, "%s/type", be_path)); + if (!tmp) { + LOG(ERROR, "Missing xenstore node %s/type", be_path); + goto cleanup; + } + libxl_string_to_backend(ctx, tmp, &(disk->backend)); } - libxl_string_to_backend(ctx, tmp, &(disk->backend)); disk->vdev = xs_read(ctx->xsh, XBT_NULL, libxl__sprintf(gc, "%s/dev", be_path), &len); @@ -2583,8 +2656,6 @@ static int libxl__device_disk_from_xs_be(libxl__gc *gc, } disk->is_cdrom = !strcmp(tmp, "cdrom"); - disk->format = LIBXL_DISK_FORMAT_UNKNOWN; - return 0; cleanup: libxl_device_disk_dispose(disk); diff --git a/tools/libxl/libxl_blktap2.c b/tools/libxl/libxl_blktap2.c index 2053403..7656fe4 100644 --- a/tools/libxl/libxl_blktap2.c +++ b/tools/libxl/libxl_blktap2.c @@ -54,8 +54,9 @@ char *libxl__blktap_devpath(libxl__gc *gc, int libxl__device_destroy_tapdisk(libxl__gc *gc, const char *params) { char *type, *disk; - int err; + int err, rc; tap_list_t tap; + libxl_disk_format format; type = libxl__strdup(gc, params); @@ -67,6 +68,15 @@ int libxl__device_destroy_tapdisk(libxl__gc *gc, const char *params) *disk++ = '\0'; + /* type may be raw */ + rc = libxl_disk_format_from_string(type, &format); + if (rc < 0) { + LOG(ERROR, "invalid disk type %s", type); + return rc; + } + + type = libxl__device_disk_string_of_format(format); + err = tap_ctl_find(type, disk, &tap); if (err < 0) { /* returns -errno */ -- 1.9.3 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |