mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-10-30 01:43:23 +00:00
Autodetect QEMU version and adjust command line arg accordingly
This commit is contained in:
parent
66a55a4d48
commit
73048102c0
@ -1,3 +1,10 @@
|
|||||||
|
Fri Feb 23 12:14:34 EST 2007 Daniel P. Berrange <berrange@redhat.com>
|
||||||
|
|
||||||
|
* qemud/driver.c, qemud/internal.h, qemud/qemud.c, qemud/conf.c,
|
||||||
|
qemud/conf.h: Added code to detect QEMU version number. Adapt
|
||||||
|
command line construction code to use correct options for VNC
|
||||||
|
and KQEMU based on version number
|
||||||
|
|
||||||
Fri Feb 23 10:52:23 EST 2007 Daniel P. Berrange <berrange@redhat.com>
|
Fri Feb 23 10:52:23 EST 2007 Daniel P. Berrange <berrange@redhat.com>
|
||||||
|
|
||||||
* qemud/Makefile.am: Fix up name of init script in EXTRA_DIST
|
* qemud/Makefile.am: Fix up name of init script in EXTRA_DIST
|
||||||
|
131
qemud/conf.c
131
qemud/conf.c
@ -31,6 +31,7 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
|
||||||
#include <libxml/parser.h>
|
#include <libxml/parser.h>
|
||||||
#include <libxml/tree.h>
|
#include <libxml/tree.h>
|
||||||
@ -257,6 +258,112 @@ static char *qemudLocateBinaryForArch(struct qemud_server *server,
|
|||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int qemudExtractVersionInfo(const char *qemu, int *version, int *flags) {
|
||||||
|
pid_t child;
|
||||||
|
int newstdout[2];
|
||||||
|
|
||||||
|
*flags = 0;
|
||||||
|
*version = 0;
|
||||||
|
|
||||||
|
if (pipe(newstdout) < 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((child = fork()) < 0) {
|
||||||
|
close(newstdout[0]);
|
||||||
|
close(newstdout[1]);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (child == 0) { /* Kid */
|
||||||
|
if (close(STDIN_FILENO) < 0)
|
||||||
|
goto cleanup1;
|
||||||
|
if (close(STDERR_FILENO) < 0)
|
||||||
|
goto cleanup1;
|
||||||
|
if (close(newstdout[0]) < 0)
|
||||||
|
goto cleanup1;
|
||||||
|
if (dup2(newstdout[1], STDOUT_FILENO) < 0)
|
||||||
|
goto cleanup1;
|
||||||
|
|
||||||
|
/* Just in case QEMU is translated someday.. */
|
||||||
|
setenv("LANG", "C", 1);
|
||||||
|
execl(qemu, qemu, (char*)NULL);
|
||||||
|
|
||||||
|
cleanup1:
|
||||||
|
_exit(-1); /* Just in case */
|
||||||
|
} else { /* Parent */
|
||||||
|
char help[4096]; /* Ought to be enough to hold QEMU help screen */
|
||||||
|
int got, ret = -1;
|
||||||
|
int major, minor, micro;
|
||||||
|
|
||||||
|
if (close(newstdout[1]) < 0)
|
||||||
|
goto cleanup2;
|
||||||
|
|
||||||
|
reread:
|
||||||
|
if ((got = read(newstdout[0], help, sizeof(help)-1)) < 0) {
|
||||||
|
if (errno == EINTR)
|
||||||
|
goto reread;
|
||||||
|
goto cleanup2;
|
||||||
|
}
|
||||||
|
help[got] = '\0';
|
||||||
|
|
||||||
|
if (sscanf(help, "QEMU PC emulator version %d.%d.%d", &major,&minor, µ) != 3) {
|
||||||
|
goto cleanup2;
|
||||||
|
}
|
||||||
|
|
||||||
|
*version = (major * 1000 * 1000) + (minor * 1000) + micro;
|
||||||
|
if (strstr(help, "-no-kqemu"))
|
||||||
|
*flags |= QEMUD_CMD_FLAG_KQEMU;
|
||||||
|
if (*version >= 9000)
|
||||||
|
*flags |= QEMUD_CMD_FLAG_VNC_COLON;
|
||||||
|
ret = 0;
|
||||||
|
|
||||||
|
qemudDebug("Version %d %d %d Cooked version: %d, with flags ? %d",
|
||||||
|
major, minor, micro, *version, *flags);
|
||||||
|
|
||||||
|
cleanup2:
|
||||||
|
if (close(newstdout[0]) < 0)
|
||||||
|
ret = -1;
|
||||||
|
|
||||||
|
rewait:
|
||||||
|
if (waitpid(child, &got, 0) != child) {
|
||||||
|
if (errno == EINTR) {
|
||||||
|
goto rewait;
|
||||||
|
}
|
||||||
|
qemudLog(QEMUD_ERR, "Unexpected exit status from qemu %d pid %lu", got, (unsigned long)child);
|
||||||
|
ret = -1;
|
||||||
|
}
|
||||||
|
/* Check & log unexpected exit status, but don't fail,
|
||||||
|
* as there's really no need to throw an error if we did
|
||||||
|
* actually read a valid version number above */
|
||||||
|
if (WEXITSTATUS(got) != 1) {
|
||||||
|
qemudLog(QEMUD_WARN, "Unexpected exit status '%d', qemu probably failed", got);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int qemudExtractVersion(struct qemud_server *server) {
|
||||||
|
char *binary = NULL;
|
||||||
|
|
||||||
|
if (server->qemuVersion > 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (!(binary = qemudLocateBinaryForArch(server, QEMUD_VIRT_QEMU, "i686")))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (qemudExtractVersionInfo(binary, &server->qemuVersion, &server->qemuCmdFlags) < 0) {
|
||||||
|
free(binary);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(binary);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Parse the XML definition for a disk */
|
/* Parse the XML definition for a disk */
|
||||||
static struct qemud_vm_disk_def *qemudParseDiskXML(struct qemud_server *server,
|
static struct qemud_vm_disk_def *qemudParseDiskXML(struct qemud_server *server,
|
||||||
xmlNodePtr node) {
|
xmlNodePtr node) {
|
||||||
@ -950,9 +1057,13 @@ int qemudBuildCommandLine(struct qemud_server *server,
|
|||||||
struct qemud_vm_disk_def *disk = vm->def->disks;
|
struct qemud_vm_disk_def *disk = vm->def->disks;
|
||||||
struct qemud_vm_net_def *net = vm->def->nets;
|
struct qemud_vm_net_def *net = vm->def->nets;
|
||||||
|
|
||||||
|
if (qemudExtractVersion(server) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
len = 1 + /* qemu */
|
len = 1 + /* qemu */
|
||||||
2 + /* machine type */
|
2 + /* machine type */
|
||||||
(vm->def->virtType == QEMUD_VIRT_QEMU ? 1 : 0) + /* Disable kqemu */
|
(((server->qemuCmdFlags & QEMUD_CMD_FLAG_KQEMU) &&
|
||||||
|
(vm->def->virtType == QEMUD_VIRT_QEMU)) ? 1 : 0) + /* Disable kqemu */
|
||||||
2 * vm->def->ndisks + /* disks*/
|
2 * vm->def->ndisks + /* disks*/
|
||||||
(vm->def->nnets > 0 ? (4 * vm->def->nnets) : 2) + /* networks */
|
(vm->def->nnets > 0 ? (4 * vm->def->nnets) : 2) + /* networks */
|
||||||
2 + /* memory*/
|
2 + /* memory*/
|
||||||
@ -977,9 +1088,10 @@ int qemudBuildCommandLine(struct qemud_server *server,
|
|||||||
goto no_memory;
|
goto no_memory;
|
||||||
if (!((*argv)[++n] = strdup(vm->def->os.machine)))
|
if (!((*argv)[++n] = strdup(vm->def->os.machine)))
|
||||||
goto no_memory;
|
goto no_memory;
|
||||||
if (vm->def->virtType == QEMUD_VIRT_QEMU) {
|
if ((server->qemuCmdFlags & QEMUD_CMD_FLAG_KQEMU) &&
|
||||||
|
(vm->def->virtType == QEMUD_VIRT_QEMU)) {
|
||||||
if (!((*argv)[++n] = strdup("-no-kqemu")))
|
if (!((*argv)[++n] = strdup("-no-kqemu")))
|
||||||
goto no_memory;
|
goto no_memory;
|
||||||
}
|
}
|
||||||
if (!((*argv)[++n] = strdup("-m")))
|
if (!((*argv)[++n] = strdup("-m")))
|
||||||
goto no_memory;
|
goto no_memory;
|
||||||
@ -996,8 +1108,8 @@ int qemudBuildCommandLine(struct qemud_server *server,
|
|||||||
goto no_memory;
|
goto no_memory;
|
||||||
|
|
||||||
if (!(vm->def->features & QEMUD_FEATURE_ACPI)) {
|
if (!(vm->def->features & QEMUD_FEATURE_ACPI)) {
|
||||||
if (!((*argv)[++n] = strdup("-no-acpi")))
|
if (!((*argv)[++n] = strdup("-no-acpi")))
|
||||||
goto no_memory;
|
goto no_memory;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0 ; i < vm->def->os.nBootDevs ; i++) {
|
for (i = 0 ; i < vm->def->os.nBootDevs ; i++) {
|
||||||
@ -1103,7 +1215,14 @@ int qemudBuildCommandLine(struct qemud_server *server,
|
|||||||
|
|
||||||
if (vm->def->graphicsType == QEMUD_GRAPHICS_VNC) {
|
if (vm->def->graphicsType == QEMUD_GRAPHICS_VNC) {
|
||||||
char port[10];
|
char port[10];
|
||||||
snprintf(port, 10, "%d", vm->def->vncActivePort - 5900);
|
int ret;
|
||||||
|
ret = snprintf(port, sizeof(port),
|
||||||
|
((server->qemuCmdFlags & QEMUD_CMD_FLAG_VNC_COLON) ?
|
||||||
|
":%d" : "%d"),
|
||||||
|
vm->def->vncActivePort - 5900);
|
||||||
|
if (ret < 0 || ret >= (int)sizeof(port))
|
||||||
|
goto error;
|
||||||
|
|
||||||
if (!((*argv)[++n] = strdup("-vnc")))
|
if (!((*argv)[++n] = strdup("-vnc")))
|
||||||
goto no_memory;
|
goto no_memory;
|
||||||
if (!((*argv)[++n] = strdup(port)))
|
if (!((*argv)[++n] = strdup(port)))
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
|
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
|
||||||
|
int qemudExtractVersion (struct qemud_server *server);
|
||||||
int qemudBuildCommandLine (struct qemud_server *server,
|
int qemudBuildCommandLine (struct qemud_server *server,
|
||||||
struct qemud_vm *vm,
|
struct qemud_vm *vm,
|
||||||
char ***argv);
|
char ***argv);
|
||||||
|
@ -260,6 +260,9 @@ struct qemud_vm *qemudFindVMByName(const struct qemud_server *server,
|
|||||||
}
|
}
|
||||||
|
|
||||||
int qemudGetVersion(struct qemud_server *server) {
|
int qemudGetVersion(struct qemud_server *server) {
|
||||||
|
if (qemudExtractVersion(server) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
return server->qemuVersion;
|
return server->qemuVersion;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -161,6 +161,13 @@ enum qemud_vm_grapics_type {
|
|||||||
QEMUD_GRAPHICS_VNC,
|
QEMUD_GRAPHICS_VNC,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Internal flags to keep track of qemu command line capabilities */
|
||||||
|
enum qemud_cmd_flags {
|
||||||
|
QEMUD_CMD_FLAG_KQEMU = 1,
|
||||||
|
QEMUD_CMD_FLAG_VNC_COLON = 2,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
enum qemud_vm_features {
|
enum qemud_vm_features {
|
||||||
QEMUD_FEATURE_ACPI = 1,
|
QEMUD_FEATURE_ACPI = 1,
|
||||||
};
|
};
|
||||||
@ -289,6 +296,7 @@ struct qemud_server {
|
|||||||
int nsockets;
|
int nsockets;
|
||||||
struct qemud_socket *sockets;
|
struct qemud_socket *sockets;
|
||||||
int qemuVersion;
|
int qemuVersion;
|
||||||
|
int qemuCmdFlags; /* values from enum qemud_cmd_flags */
|
||||||
int nclients;
|
int nclients;
|
||||||
struct qemud_client *clients;
|
struct qemud_client *clients;
|
||||||
int sigread;
|
int sigread;
|
||||||
|
@ -459,8 +459,6 @@ static struct qemud_server *qemudInitialize(int sys, int sigread) {
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* XXX extract actual version */
|
|
||||||
server->qemuVersion = (0*1000000)+(8*1000)+(0);
|
|
||||||
/* We don't have a dom-0, so start from 1 */
|
/* We don't have a dom-0, so start from 1 */
|
||||||
server->nextvmid = 1;
|
server->nextvmid = 1;
|
||||||
server->sigread = sigread;
|
server->sigread = sigread;
|
||||||
|
Loading…
Reference in New Issue
Block a user