]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
find and use kvm-img, qemu-img or qcow-create dynamically
authorDaniel Veillard <veillard@redhat.com>
Thu, 11 Jun 2009 13:18:56 +0000 (13:18 +0000)
committerDaniel Veillard <veillard@redhat.com>
Thu, 11 Jun 2009 13:18:56 +0000 (13:18 +0000)
* configure.in src/libvirt_private.syms src/storage_backend_fs.c
  src/util.c src/util.h: find and use kvm-img, qemu-img or qcow-create
  dynamically at runtime, patch by Doug Goldstein
* AUTHORS: add Doug Goldstein
Daniel

AUTHORS
ChangeLog
configure.in
src/libvirt_private.syms
src/storage_backend_fs.c
src/util.c
src/util.h

diff --git a/AUTHORS b/AUTHORS
index dcb6ea58d7098c8d0e1b6cf2d6420f1809f70ac8..e6f1a9ecdc30d8fe8d7d332ccce0f10918b71b99 100644 (file)
--- a/AUTHORS
+++ b/AUTHORS
@@ -71,6 +71,7 @@ Patches have also been contributed by:
   Soren Hansen         <soren@canonical.com>
   Laine Stump          <laine@redhat.com>
   Abel Míguez Rodríguez<amiguezr@pdi.ucm.es>
+  Doug Goldstein       <cardoe@gentoo.org>
 
   [....send patches to get your name here....]
 
index fe576cc618dfc3429d8fee66a05c524e43d0b2d3..f4e0d8158fce23e99a6fab30211e8e7bf6fb72a6 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+Thu Jun 11 15:14:37 CEST 2009 Daniel Veillard <veillard@redhat.com>
+
+       * configure.in src/libvirt_private.syms src/storage_backend_fs.c
+         src/util.c src/util.h: find and use kvm-img, qemu-img or qcow-create
+         dynamically at runtime, patch by Doug Goldstein
+       * AUTHORS: add Doug Goldstein
+
 Tue Jun  9 15:21:17 CEST 2009 Daniel Veillard <veillard@redhat.com>
 
        * docs/formatdomain.html docs/formatdomain.html.in: typo fix
index 5c0575c873d3dce5c30ae8196cc4384ce6f3e19d..552c76157e7549a185fab1a52be90d2de9f8b1cc 100644 (file)
@@ -889,21 +889,6 @@ if test "$with_storage_fs" = "yes"; then
     [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])
index b39216f2e4929f892e36b4fa813cdc44f1526fe6..0c5568415064ade724200bf787d820c98e54b621 100644 (file)
@@ -330,6 +330,7 @@ virFormatMacAddr;
 virGetHostname;
 virParseMacAddr;
 virFileDeletePid;
+virFindFileInPath;
 virFileExists;
 virFileHasSuffix;
 virFileLinkPointsTo;
index be6d01193c2db739cfd0e347d6658bd6f2f43239..ac7c4240d497023a0d5c969895e33225e66d2280 100644 (file)
@@ -1183,11 +1183,12 @@ static int createFileDir(virConnectPtr conn,
     return 0;
 }
 
-#if HAVE_QEMU_IMG
 static int createQemuImg(virConnectPtr conn,
                          virStorageVolDefPtr vol,
                          virStorageVolDefPtr inputvol) {
     char size[100];
+    char *create_tool;
+    short use_kvmimg;
 
     const char *type = virStorageVolFormatFileSystemTypeToString(vol->target.format);
     const char *backingType = vol->backingStore.path ?
@@ -1203,24 +1204,27 @@ static int createQemuImg(virConnectPtr conn,
 
     const char **imgargv;
     const char *imgargvnormal[] = {
-        QEMU_IMG, "create",
+        NULL, "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 */
+    /* Extra NULL fields are for including "backingType" when using
+     * kvm-img. It's -F backingType
+     */
     const char *imgargvbacking[] = {
-        QEMU_IMG, "create",
+        NULL, "create",
         "-f", type,
         "-b", vol->backingStore.path,
         vol->target.path,
         size,
         NULL,
+        NULL,
+        NULL
     };
     const char *convargv[] = {
-        QEMU_IMG, "convert",
+        NULL, "convert",
         "-f", inputType,
         "-O", type,
         inputPath,
@@ -1228,14 +1232,6 @@ static int createQemuImg(virConnectPtr conn,
         NULL,
     };
 
-    if (inputvol) {
-        imgargv = convargv;
-    } else if (vol->backingStore.path) {
-        imgargv = imgargvbacking;
-    } else {
-        imgargv = imgargvnormal;
-    }
-
     if (type == NULL) {
         virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR,
                               _("unknown storage vol type %d"),
@@ -1277,17 +1273,47 @@ static int createQemuImg(virConnectPtr conn,
         }
     }
 
+    if ((create_tool = virFindFileInPath("kvm-img")) != NULL)
+        use_kvmimg = 1;
+    else if ((create_tool = virFindFileInPath("qemu-img")) != NULL)
+        use_kvmimg = 0;
+    else {
+        virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR,
+                              _("unable to find kvm-img or qemu-img"));
+        return -1;
+    }
+
+    if (inputvol) {
+        convargv[0] = create_tool;
+        imgargv = convargv;
+    } else if (vol->backingStore.path) {
+        imgargvbacking[0] = create_tool;
+        if (use_kvmimg) {
+            imgargvbacking[6] = "-F";
+            imgargvbacking[7] = backingType;
+            imgargvbacking[8] = vol->target.path;
+            imgargvbacking[9] = size;
+        }
+        imgargv = imgargvbacking;
+    } else {
+        imgargvnormal[0] = create_tool;
+        imgargv = imgargvnormal;
+    }
+
+
     /* Size in KB */
     snprintf(size, sizeof(size), "%llu", vol->capacity/1024);
 
     if (virRun(conn, imgargv, NULL) < 0) {
+        VIR_FREE(imgargv[0]);
         return -1;
     }
 
+    VIR_FREE(imgargv[0]);
+
     return 0;
 }
 
-#elif HAVE_QCOW_CREATE
 /*
  * Xen removed the fully-functional qemu-img, and replaced it
  * with a partially functional qcow-create. Go figure ??!?
@@ -1321,18 +1347,20 @@ static int createQemuCreate(virConnectPtr conn,
     /* Size in MB - yes different units to qemu-img :-( */
     snprintf(size, sizeof(size), "%llu", vol->capacity/1024/1024);
 
-    imgargv[0] = QCOW_CREATE;
+    imgargv[0] = virFindFileInPath("qcow-create");
     imgargv[1] = size;
     imgargv[2] = vol->target.path;
     imgargv[3] = NULL;
 
     if (virRun(conn, imgargv, NULL) < 0) {
+        VIR_FREE(imgargv[0]);
         return -1;
     }
 
+    VIR_FREE(imgargv[0]);
+
     return 0;
 }
-#endif /* HAVE_QEMU_IMG, elif HAVE_QCOW_CREATE */
 
 static int
 _virStorageBackendFileSystemVolBuild(virConnectPtr conn,
@@ -1341,6 +1369,7 @@ _virStorageBackendFileSystemVolBuild(virConnectPtr conn,
 {
     int fd;
     createFile create_func;
+    char *create_tool;
 
     if (vol->target.format == VIR_STORAGE_VOL_FILE_RAW &&
         (!inputvol ||
@@ -1353,17 +1382,20 @@ _virStorageBackendFileSystemVolBuild(virConnectPtr conn,
         create_func = createRaw;
     } else if (vol->target.format == VIR_STORAGE_VOL_FILE_DIR) {
         create_func = createFileDir;
-    } else {
-#if HAVE_QEMU_IMG
+    } else if ((create_tool = virFindFileInPath("kvm-img")) != NULL) {
+        VIR_FREE(create_tool);
+        create_func = createQemuImg;
+    } else if ((create_tool = virFindFileInPath("qemu-img")) != NULL) {
+        VIR_FREE(create_tool);
         create_func = createQemuImg;
-#elif HAVE_QCOW_CREATE
+    } else if ((create_tool = virFindFileInPath("qcow-create")) != NULL) {
+        VIR_FREE(create_tool);
         create_func = createQemuCreate;
-#else
+    } else {
         virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR,
                               "%s", _("creation of non-raw images "
                                       "is not supported without qemu-img"));
         return -1;
-#endif
     }
 
     if (create_func(conn, vol, inputvol) < 0)
index 3a8c105c76e875df70e0e9e24c029854fcea1f4e..664fb0f7cf9c053114a63bf1537845bc0fd1d42a 100644 (file)
@@ -1073,7 +1073,35 @@ int virFileResolveLink(const char *linkpath,
 #endif
 }
 
+/*
+ * Finds a requested file in the PATH env. e.g.:
+ * "kvm-img" will return "/usr/bin/kvm-img"
+ *
+ * You must free the result
+ */
+char *virFindFileInPath(const char *file)
+{
+    char pathenv[PATH_MAX];
+    char *penv = &pathenv; /* this is for glibc 2.10 strsep chnages */
+    char *pathseg;
+    char fullpath[PATH_MAX];
+
+    /* copy PATH env so we can tweak it */
+    strncpy(pathenv, getenv("PATH"), PATH_MAX);
+    pathenv[PATH_MAX - 1] = '\0';
+
 
+    /* for each path segment, append the file to search for and test for
+     * it. return it if found.
+     */
+    while ((pathseg = strsep(&penv, ":")) != NULL) {
+       snprintf(fullpath, PATH_MAX, "%s/%s", pathseg, file);
+       if (virFileExists(fullpath))
+           return strdup(fullpath);
+    }
+
+    return NULL;
+}
 int virFileExists(const char *path)
 {
     struct stat st;
index 61e1eb519835ce82881cb6eb1206144174bd03c0..e6e801035509ddfe9f8d9154d5a10cbb465c8b89 100644 (file)
@@ -101,6 +101,8 @@ int virFileLinkPointsTo(const char *checkLink,
 int virFileResolveLink(const char *linkpath,
                        char **resultpath);
 
+char *virFindFileInPath(const char *file);
+
 int virFileExists(const char *path);
 
 int virFileMakePath(const char *path);