diff -Nur libvirt-0.6.3/configure.in libvirt-0.6.3-kvm-img/configure.in --- libvirt-0.6.3/configure.in 2009-04-24 08:14:00.000000000 -0500 +++ libvirt-0.6.3-kvm-img/configure.in 2009-05-27 16:49:07.000000000 -0500 @@ -847,21 +847,6 @@ [Location or name of the showmount program]) fi -AC_PATH_PROG([QEMU_IMG], [qemu-img], [], [$PATH:/sbin:/usr/sbin:/bin:/usr/bin]) -if test -n "$QEMU_IMG" ; then - AC_DEFINE_UNQUOTED([HAVE_QEMU_IMG], 1, [whether qemu-img is available for non-raw files]) - AC_DEFINE_UNQUOTED([QEMU_IMG],["$QEMU_IMG"], - [Location or name of the qemu-img program]) -fi - -AC_PATH_PROG([QCOW_CREATE], [qcow-create], [], [$PATH:/sbin:/usr/sbin:/bin:/usr/bin]) -if test -n "$QCOW_CREATE" ; then - AC_DEFINE_UNQUOTED([HAVE_QCOW_CREATE], 1, [whether qcow-create is available for non-raw files]) - AC_DEFINE_UNQUOTED([QCOW_CREATE],["$QCOW_CREATE"], - [Location or name of the qcow-create program]) -fi - - if test "$with_storage_lvm" = "yes" -o "$with_storage_lvm" = "check"; then AC_PATH_PROG([PVCREATE], [pvcreate], [], [$PATH:/sbin:/usr/sbin]) AC_PATH_PROG([VGCREATE], [vgcreate], [], [$PATH:/sbin:/usr/sbin]) diff -Nur libvirt-0.6.3/src/libvirt_private.syms libvirt-0.6.3-kvm-img/src/libvirt_private.syms --- libvirt-0.6.3/src/libvirt_private.syms 2009-04-24 07:51:46.000000000 -0500 +++ libvirt-0.6.3-kvm-img/src/libvirt_private.syms 2009-05-27 17:15:48.000000000 -0500 @@ -327,6 +327,7 @@ virGetHostname; virParseMacAddr; virFileDeletePid; +virFindFileInPath; virFileExists; virFileHasSuffix; virFileLinkPointsTo; diff -Nur libvirt-0.6.3/src/storage_backend_fs.c libvirt-0.6.3-kvm-img/src/storage_backend_fs.c --- libvirt-0.6.3/src/storage_backend_fs.c 2009-04-17 14:07:48.000000000 -0500 +++ libvirt-0.6.3-kvm-img/src/storage_backend_fs.c 2009-05-28 15:00:48.000000000 -0500 @@ -1013,7 +1013,7 @@ /** * Allocate a new file as a volume. This is either done directly - * for raw/sparse files, or by calling qemu-img/qcow-create for + * for raw/sparse files, or by calling kvm-img/qemu-img/qcow-create for * special kinds of files */ static int @@ -1021,6 +1021,7 @@ virStorageVolDefPtr vol) { int fd; + char *kvmimg = NULL, *qemuimg = NULL, *qcowcreate = NULL; if (vol->target.format == VIR_STORAGE_VOL_FILE_RAW) { if ((fd = open(vol->target.path, O_RDWR | O_CREAT | O_EXCL, @@ -1095,61 +1096,87 @@ vol->target.path); return -1; } - } else { -#if HAVE_QEMU_IMG + } else if (((kvmimg = virFindFileInPath("kvm-img")) != NULL) || + ((qemuimg = virFindFileInPath("qemu-img")) != NULL)) { const char *type = virStorageVolFormatFileSystemTypeToString(vol->target.format); const char *backingType = vol->backingStore.path ? virStorageVolFormatFileSystemTypeToString(vol->backingStore.format) : NULL; char size[100]; - const char **imgargv; - const char *imgargvnormal[] = { - QEMU_IMG, "create", "-f", type, vol->target.path, size, NULL, - }; - /* XXX including "backingType" here too, once QEMU accepts - * the patches to specify it. It'll probably be -F backingType */ - const char *imgargvbacking[] = { - QEMU_IMG, "create", "-f", type, "-b", vol->backingStore.path, vol->target.path, size, NULL, - }; + char *createtool; + const char *imgargv[11]; + int argvoffset; + + if (kvmimg != NULL) + imgargv[0] = kvmimg; + else if (qemuimg != NULL) + imgargv[0] = qemuimg; + else { + virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR, + _("Can not find qemu-img or kvm-img")); + return -1; + } + + /* these values are always the same no matter the command */ + imgargv[1] = "create"; + imgargv[2] = "-f"; + imgargv[3] = type; + argvoffset = 4; if (type == NULL) { virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR, _("unknown storage vol type %d"), vol->target.format); - return -1; + goto qemuimgerr; } - if (vol->backingStore.path == NULL) { - imgargv = imgargvnormal; - } else { + + if (vol->backingStore.path != NULL) { if (backingType == NULL) { virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR, _("unknown storage vol backing store type %d"), vol->backingStore.format); - return -1; + goto qemuimgerr; } + + /* XXX including "backingType" here too, once QEMU accepts + * the patches to specify it. It'll probably be -F backingType */ + if (kvmimg != NULL) { + imgargv[argvoffset++] = "-F"; + imgargv[argvoffset++] = backingType; + } + if (access(vol->backingStore.path, R_OK) != 0) { virReportSystemError(conn, errno, _("inaccessible backing store volume %s"), vol->backingStore.path); - return -1; + goto qemuimgerr; } - imgargv = imgargvbacking; + imgargv[argvoffset++] = "-b"; + imgargv[argvoffset++] = vol->backingStore.path; } + imgargv[argvoffset++] = vol->target.path; + imgargv[argvoffset++] = size; + imgargv[argvoffset] = NULL; + /* Size in KB */ snprintf(size, sizeof(size), "%llu", vol->capacity/1024); if (virRun(conn, imgargv, NULL) < 0) { - return -1; + goto qemuimgerr; } + VIR_FREE(kvmimg); + VIR_FREE(qemuimg); + if ((fd = open(vol->target.path, O_RDONLY)) < 0) { virReportSystemError(conn, errno, _("cannot read path '%s'"), vol->target.path); return -1; } -#elif HAVE_QCOW_CREATE + + } else if ((qcowcreate = virFindFileInPath("qcow-create")) != NULL) { /* * Xen removed the fully-functional qemu-img, and replaced it * with a partially functional qcow-create. Go figure ??!? @@ -1161,39 +1188,41 @@ virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR, _("unsupported storage vol type %d"), vol->target.format); - return -1; + goto qcowcreateerr; } if (vol->backingStore.path != NULL) { virStorageReportError(conn, VIR_ERR_NO_SUPPORT, _("copy-on-write image not supported with " "qcow-create")); - return -1; + goto qcowcreateerr; } /* Size in MB - yes different units to qemu-img :-( */ snprintf(size, sizeof(size), "%llu", vol->capacity/1024/1024); - imgargv[0] = QCOW_CREATE; + imgargv[0] = qcowcreate; imgargv[1] = size; imgargv[2] = vol->target.path; imgargv[3] = NULL; if (virRun(conn, imgargv, NULL) < 0) { - return -1; + goto qcowcreateerr; } + VIR_FREE(qcowcreate); + if ((fd = open(vol->target.path, O_RDONLY)) < 0) { virReportSystemError(conn, errno, _("cannot read path '%s'"), vol->target.path); return -1; } -#else + } else { virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR, "%s", _("creation of non-raw images " - "is not supported without qemu-img")); + "is not supported without kvm-img or " + "qemu-img or qcow-create")); return -1; -#endif } /* We can only chown/grp if root */ @@ -1230,6 +1259,15 @@ } return 0; + +qemuimgerr: /* from the kvm-img/qemu-img section */ + VIR_FREE(kvmimg); + VIR_FREE(qemuimg); + return -1; + +qcowcreateerr: /* from the qcow-create section */ + VIR_FREE(qcowcreate); + return -1; } diff -Nur libvirt-0.6.3/src/util.c libvirt-0.6.3-kvm-img/src/util.c --- libvirt-0.6.3/src/util.c 2009-04-24 04:46:45.000000000 -0500 +++ libvirt-0.6.3-kvm-img/src/util.c 2009-05-28 15:01:55.000000000 -0500 @@ -1002,6 +1002,37 @@ return(0); } +/* + * Find a file in the PATH. You must free + * the result + */ +char *virFindFileInPath(const char *find) +{ + char pathenv[PATH_MAX]; + char *pathseg; + char *fullpath; + + /* copy PATH env so we can tweak it */ + strncpy(pathenv, getenv("PATH"), PATH_MAX); + pathenv[PATH_MAX - 1] = '\0'; + + /* buffer for our file path */ + if (VIR_ALLOC_N(fullpath, PATH_MAX) < 0) + return NULL; + + /* for each path segment, append the file name to search for + * and test for it. return it if successful */ + while ((pathseg = strsep(&pathenv, ":")) != NULL) { + snprintf(fullpath, PATH_MAX, "%s/%s", pathseg, find); + if (virFileExists(fullpath)) + return fullpath; + } + + free(fullpath); + + return NULL; +} + int virFileMakePath(const char *path) { struct stat st; diff -Nur libvirt-0.6.3/src/util.h libvirt-0.6.3-kvm-img/src/util.h --- libvirt-0.6.3/src/util.h 2009-04-24 04:46:45.000000000 -0500 +++ libvirt-0.6.3-kvm-img/src/util.h 2009-05-27 16:15:26.000000000 -0500 @@ -92,6 +92,8 @@ int virFileExists(const char *path); +char *virFindFileInPath(const char *find); + int virFileMakePath(const char *path); int virFileBuildPath(const char *dir,