@@ -3016,8 +3016,9 @@ static char * libxl__alloc_vdev(libxl__gc *gc, void *get_vdev_user,
/* Callbacks */
-static char * libxl__device_disk_find_local_path(libxl__gc *gc,
- const libxl_device_disk *disk) {
+char * libxl__device_disk_find_local_path(libxl__gc *gc,
+ const libxl_device_disk *disk,
+ bool qdisk_direct) {
char *path = NULL;
/* No local paths for driver domains */
@@ -3038,6 +3039,16 @@ static char * libxl__device_disk_find_local_path(libxl__gc *gc,
goto out;
}
+ /*
+ * If we're being called for a qemu path, we can pass the target
+ * string directly as well
+ */
+ if (qdisk_direct && disk->backend == LIBXL_DISK_BACKEND_QDISK ) {
+ path = libxl__strdup(gc, disk->pdev_path);
+ LOG(DEBUG, "Directly accessing local QDISK target %s", path);
+ goto out;
+ }
+
out:
return path;
}
@@ -3062,7 +3073,7 @@ void libxl__device_disk_local_initiate_attach(libxl__egc *egc,
LOG(DEBUG, "Trying to find local path");
- if ((dls->diskpath = libxl__device_disk_find_local_path(gc, in_disk))) {
+ if ((dls->diskpath = libxl__device_disk_find_local_path(gc, in_disk, false))) {
LOG(DEBUG, "Local path found, executing callback.");
dls->callback(egc, dls, 0);
} else {
@@ -1161,9 +1161,9 @@ static int libxl__build_device_model_args_new(libxl__gc *gc,
int disk, part;
int dev_number =
libxl__device_disk_dev_number(disks[i].vdev, &disk, &part);
- const char *format = qemu_disk_format_string(disks[i].format);
+ const char *format;
char *drive;
- const char *pdev_path;
+ const char *target_path;
if (dev_number == -1) {
LOG(WARN, "unable to determine"" disk number for %s",
@@ -1171,22 +1171,22 @@ static int libxl__build_device_model_args_new(libxl__gc *gc,
continue;
}
- if (disks[i].is_cdrom) {
- if (disks[i].format == LIBXL_DISK_FORMAT_EMPTY)
- drive = libxl__sprintf
- (gc, "if=ide,index=%d,readonly=%s,media=cdrom,cache=writeback,id=ide-%i",
- disk, disks[i].readwrite ? "off" : "on", dev_number);
- else
- drive = libxl__sprintf
- (gc, "file=%s,if=ide,index=%d,readonly=%s,media=cdrom,format=%s,cache=writeback,id=ide-%i",
- disks[i].pdev_path, disk, disks[i].readwrite ? "off" : "on", format, dev_number);
- } else {
- if (disks[i].format == LIBXL_DISK_FORMAT_EMPTY) {
+ /*
+ * If qemu isn't doing the interpreting, the parameter is
+ * always raw
+ */
+ if (disks[i].backend == LIBXL_DISK_BACKEND_QDISK)
+ format = qemu_disk_format_string(disks[i].format);
+ else
+ format = qemu_disk_format_string(LIBXL_DISK_FORMAT_RAW);
+
+ if (disks[i].format == LIBXL_DISK_FORMAT_EMPTY) {
+ if (!disks[i].is_cdrom) {
LOG(WARN, "cannot support"" empty disk format for %s",
disks[i].vdev);
continue;
}
-
+ } else {
if (format == NULL) {
LOG(WARN,
"unable to determine"" disk image format %s",
@@ -1194,14 +1194,36 @@ static int libxl__build_device_model_args_new(libxl__gc *gc,
continue;
}
- if (disks[i].backend == LIBXL_DISK_BACKEND_TAP) {
- format = qemu_disk_format_string(LIBXL_DISK_FORMAT_RAW);
- pdev_path = libxl__blktap_devpath(gc, disks[i].pdev_path,
+ /*
+ * We can't call libxl__blktap_devpath from
+ * libxl__device_disk_find_local_path for now because
+ * the bootloader is called before the disks are set
+ * up, so this function would set up a blktap node,
+ * but there's no TAP tear-down on error conditions in
+ * the bootloader path.
+ */
+ if (disks[i].backend == LIBXL_DISK_BACKEND_TAP)
+ target_path = libxl__blktap_devpath(gc, disks[i].pdev_path,
disks[i].format);
- } else {
- pdev_path = disks[i].pdev_path;
+ else
+ target_path = libxl__device_disk_find_local_path(gc,
+ &disks[i], true);
+
+ if (!target_path) {
+ LOG(WARN, "No way to get local access disk to image: %s", disks[i].vdev);
+ continue;
}
+ }
+
+ if (disks[i].is_cdrom) {
+ drive = libxl__sprintf
+ (gc, "if=ide,index=%d,readonly=%s,media=cdrom,cache=writeback,id=ide-%i",
+ disk, disks[i].readwrite ? "off" : "on", dev_number);
+ if (target_path)
+ drive = libxl__sprintf(gc, "%s,file=%s,format=%s",
+ drive, target_path, format);
+ } else {
/*
* Explicit sd disks are passed through as is.
*
@@ -1211,7 +1233,7 @@ static int libxl__build_device_model_args_new(libxl__gc *gc,
if (strncmp(disks[i].vdev, "sd", 2) == 0) {
drive = libxl__sprintf
(gc, "file=%s,if=scsi,bus=0,unit=%d,format=%s,readonly=%s,cache=writeback",
- pdev_path, disk, format, disks[i].readwrite ? "off" : "on");
+ target_path, disk, format, disks[i].readwrite ? "off" : "on");
} else if (strncmp(disks[i].vdev, "xvd", 3) == 0) {
/*
* Do not add any emulated disk when PV disk are
@@ -1225,7 +1247,7 @@ static int libxl__build_device_model_args_new(libxl__gc *gc,
}
flexarray_vappend(dm_args, "-drive",
GCSPRINTF("file=%s,if=none,id=ahcidisk-%d,format=%s,cache=writeback",
- pdev_path, disk, format),
+ target_path, disk, format),
"-device", GCSPRINTF("ide-hd,bus=ahci0.%d,unit=0,drive=ahcidisk-%d",
disk, disk), NULL);
continue;
@@ -1236,7 +1258,7 @@ static int libxl__build_device_model_args_new(libxl__gc *gc,
}
drive = libxl__sprintf
(gc, "file=%s,if=ide,index=%d,media=disk,format=%s,cache=writeback",
- pdev_path, disk, format);
+ target_path, disk, format);
} else {
continue; /* Do not emulate this disk */
}
@@ -2670,6 +2670,14 @@ static inline void libxl__device_disk_local_init(libxl__disk_local_state *dls)
dls->rc = 0;
}
+/*
+ * See if we can find a way to access a disk locally
+ */
+_hidden char * libxl__device_disk_find_local_path(libxl__gc *gc,
+ const libxl_device_disk *disk,
+ bool qdisk_direct);
+
+
/* Make a disk available in this (the control) domain. Always calls
* dls->callback when finished.
* State Idle -> Attaching