find and use kvm-img, qemu-img or qcow-create dynamically

* 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
This commit is contained in:
Daniel Veillard 2009-06-11 13:18:56 +00:00
parent d12a6ef9c2
commit abed6fca87
7 changed files with 93 additions and 37 deletions

View File

@ -71,6 +71,7 @@ Patches have also been contributed by:
Soren Hansen <soren@canonical.com> Soren Hansen <soren@canonical.com>
Laine Stump <laine@redhat.com> Laine Stump <laine@redhat.com>
Abel Míguez Rodríguez<amiguezr@pdi.ucm.es> Abel Míguez Rodríguez<amiguezr@pdi.ucm.es>
Doug Goldstein <cardoe@gentoo.org>
[....send patches to get your name here....] [....send patches to get your name here....]

View File

@ -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> Tue Jun 9 15:21:17 CEST 2009 Daniel Veillard <veillard@redhat.com>
* docs/formatdomain.html docs/formatdomain.html.in: typo fix * docs/formatdomain.html docs/formatdomain.html.in: typo fix

View File

@ -889,21 +889,6 @@ if test "$with_storage_fs" = "yes"; then
[Location or name of the showmount program]) [Location or name of the showmount program])
fi 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 if test "$with_storage_lvm" = "yes" -o "$with_storage_lvm" = "check"; then
AC_PATH_PROG([PVCREATE], [pvcreate], [], [$PATH:/sbin:/usr/sbin]) AC_PATH_PROG([PVCREATE], [pvcreate], [], [$PATH:/sbin:/usr/sbin])
AC_PATH_PROG([VGCREATE], [vgcreate], [], [$PATH:/sbin:/usr/sbin]) AC_PATH_PROG([VGCREATE], [vgcreate], [], [$PATH:/sbin:/usr/sbin])

View File

@ -330,6 +330,7 @@ virFormatMacAddr;
virGetHostname; virGetHostname;
virParseMacAddr; virParseMacAddr;
virFileDeletePid; virFileDeletePid;
virFindFileInPath;
virFileExists; virFileExists;
virFileHasSuffix; virFileHasSuffix;
virFileLinkPointsTo; virFileLinkPointsTo;

View File

@ -1183,11 +1183,12 @@ static int createFileDir(virConnectPtr conn,
return 0; return 0;
} }
#if HAVE_QEMU_IMG
static int createQemuImg(virConnectPtr conn, static int createQemuImg(virConnectPtr conn,
virStorageVolDefPtr vol, virStorageVolDefPtr vol,
virStorageVolDefPtr inputvol) { virStorageVolDefPtr inputvol) {
char size[100]; char size[100];
char *create_tool;
short use_kvmimg;
const char *type = virStorageVolFormatFileSystemTypeToString(vol->target.format); const char *type = virStorageVolFormatFileSystemTypeToString(vol->target.format);
const char *backingType = vol->backingStore.path ? const char *backingType = vol->backingStore.path ?
@ -1203,24 +1204,27 @@ static int createQemuImg(virConnectPtr conn,
const char **imgargv; const char **imgargv;
const char *imgargvnormal[] = { const char *imgargvnormal[] = {
QEMU_IMG, "create", NULL, "create",
"-f", type, "-f", type,
vol->target.path, vol->target.path,
size, size,
NULL, NULL,
}; };
/* XXX including "backingType" here too, once QEMU accepts /* Extra NULL fields are for including "backingType" when using
* the patches to specify it. It'll probably be -F backingType */ * kvm-img. It's -F backingType
*/
const char *imgargvbacking[] = { const char *imgargvbacking[] = {
QEMU_IMG, "create", NULL, "create",
"-f", type, "-f", type,
"-b", vol->backingStore.path, "-b", vol->backingStore.path,
vol->target.path, vol->target.path,
size, size,
NULL, NULL,
NULL,
NULL
}; };
const char *convargv[] = { const char *convargv[] = {
QEMU_IMG, "convert", NULL, "convert",
"-f", inputType, "-f", inputType,
"-O", type, "-O", type,
inputPath, inputPath,
@ -1228,14 +1232,6 @@ static int createQemuImg(virConnectPtr conn,
NULL, NULL,
}; };
if (inputvol) {
imgargv = convargv;
} else if (vol->backingStore.path) {
imgargv = imgargvbacking;
} else {
imgargv = imgargvnormal;
}
if (type == NULL) { if (type == NULL) {
virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR, virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR,
_("unknown storage vol type %d"), _("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 */ /* Size in KB */
snprintf(size, sizeof(size), "%llu", vol->capacity/1024); snprintf(size, sizeof(size), "%llu", vol->capacity/1024);
if (virRun(conn, imgargv, NULL) < 0) { if (virRun(conn, imgargv, NULL) < 0) {
VIR_FREE(imgargv[0]);
return -1; return -1;
} }
VIR_FREE(imgargv[0]);
return 0; return 0;
} }
#elif HAVE_QCOW_CREATE
/* /*
* Xen removed the fully-functional qemu-img, and replaced it * Xen removed the fully-functional qemu-img, and replaced it
* with a partially functional qcow-create. Go figure ??!? * 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 :-( */ /* Size in MB - yes different units to qemu-img :-( */
snprintf(size, sizeof(size), "%llu", vol->capacity/1024/1024); snprintf(size, sizeof(size), "%llu", vol->capacity/1024/1024);
imgargv[0] = QCOW_CREATE; imgargv[0] = virFindFileInPath("qcow-create");
imgargv[1] = size; imgargv[1] = size;
imgargv[2] = vol->target.path; imgargv[2] = vol->target.path;
imgargv[3] = NULL; imgargv[3] = NULL;
if (virRun(conn, imgargv, NULL) < 0) { if (virRun(conn, imgargv, NULL) < 0) {
VIR_FREE(imgargv[0]);
return -1; return -1;
} }
VIR_FREE(imgargv[0]);
return 0; return 0;
} }
#endif /* HAVE_QEMU_IMG, elif HAVE_QCOW_CREATE */
static int static int
_virStorageBackendFileSystemVolBuild(virConnectPtr conn, _virStorageBackendFileSystemVolBuild(virConnectPtr conn,
@ -1341,6 +1369,7 @@ _virStorageBackendFileSystemVolBuild(virConnectPtr conn,
{ {
int fd; int fd;
createFile create_func; createFile create_func;
char *create_tool;
if (vol->target.format == VIR_STORAGE_VOL_FILE_RAW && if (vol->target.format == VIR_STORAGE_VOL_FILE_RAW &&
(!inputvol || (!inputvol ||
@ -1353,17 +1382,20 @@ _virStorageBackendFileSystemVolBuild(virConnectPtr conn,
create_func = createRaw; create_func = createRaw;
} else if (vol->target.format == VIR_STORAGE_VOL_FILE_DIR) { } else if (vol->target.format == VIR_STORAGE_VOL_FILE_DIR) {
create_func = createFileDir; create_func = createFileDir;
} else { } else if ((create_tool = virFindFileInPath("kvm-img")) != NULL) {
#if HAVE_QEMU_IMG VIR_FREE(create_tool);
create_func = createQemuImg; create_func = createQemuImg;
#elif HAVE_QCOW_CREATE } else if ((create_tool = virFindFileInPath("qemu-img")) != NULL) {
VIR_FREE(create_tool);
create_func = createQemuImg;
} else if ((create_tool = virFindFileInPath("qcow-create")) != NULL) {
VIR_FREE(create_tool);
create_func = createQemuCreate; create_func = createQemuCreate;
#else } else {
virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR, virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR,
"%s", _("creation of non-raw images " "%s", _("creation of non-raw images "
"is not supported without qemu-img")); "is not supported without qemu-img"));
return -1; return -1;
#endif
} }
if (create_func(conn, vol, inputvol) < 0) if (create_func(conn, vol, inputvol) < 0)

View File

@ -1073,7 +1073,35 @@ int virFileResolveLink(const char *linkpath,
#endif #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) int virFileExists(const char *path)
{ {
struct stat st; struct stat st;

View File

@ -101,6 +101,8 @@ int virFileLinkPointsTo(const char *checkLink,
int virFileResolveLink(const char *linkpath, int virFileResolveLink(const char *linkpath,
char **resultpath); char **resultpath);
char *virFindFileInPath(const char *file);
int virFileExists(const char *path); int virFileExists(const char *path);
int virFileMakePath(const char *path); int virFileMakePath(const char *path);