mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-02-04 10:55:19 +00:00
Refactor guest init to support qemu-system-i386 binary too
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
This commit is contained in:
parent
de9be0ab4d
commit
1517099c7b
@ -228,53 +228,6 @@ static int qemuCapsOnceInit(void)
|
|||||||
|
|
||||||
VIR_ONCE_GLOBAL_INIT(qemuCaps)
|
VIR_ONCE_GLOBAL_INIT(qemuCaps)
|
||||||
|
|
||||||
struct qemu_feature_flags {
|
|
||||||
const char *name;
|
|
||||||
const int default_on;
|
|
||||||
const int toggle;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct qemu_arch_info {
|
|
||||||
const char *arch;
|
|
||||||
int wordsize;
|
|
||||||
const char *binary;
|
|
||||||
const char *altbinary;
|
|
||||||
const struct qemu_feature_flags *flags;
|
|
||||||
int nflags;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Feature flags for the architecture info */
|
|
||||||
static const struct qemu_feature_flags const arch_info_i686_flags [] = {
|
|
||||||
{ "pae", 1, 0 },
|
|
||||||
{ "nonpae", 1, 0 },
|
|
||||||
{ "acpi", 1, 1 },
|
|
||||||
{ "apic", 1, 0 },
|
|
||||||
};
|
|
||||||
|
|
||||||
static const struct qemu_feature_flags const arch_info_x86_64_flags [] = {
|
|
||||||
{ "acpi", 1, 1 },
|
|
||||||
{ "apic", 1, 0 },
|
|
||||||
};
|
|
||||||
|
|
||||||
/* The archicture tables for supported QEMU archs */
|
|
||||||
static const struct qemu_arch_info const arch_info_hvm[] = {
|
|
||||||
{ "i686", 32, "qemu",
|
|
||||||
"qemu-system-x86_64", arch_info_i686_flags, 4 },
|
|
||||||
{ "x86_64", 64, "qemu-system-x86_64",
|
|
||||||
NULL, arch_info_x86_64_flags, 2 },
|
|
||||||
{ "arm", 32, "qemu-system-arm", NULL, NULL, 0 },
|
|
||||||
{ "microblaze", 32, "qemu-system-microblaze", NULL, NULL, 0 },
|
|
||||||
{ "microblazeel", 32, "qemu-system-microblazeel", NULL, NULL, 0 },
|
|
||||||
{ "mips", 32, "qemu-system-mips", NULL, NULL, 0 },
|
|
||||||
{ "mipsel", 32, "qemu-system-mipsel", NULL, NULL, 0 },
|
|
||||||
{ "sparc", 32, "qemu-system-sparc", NULL, NULL, 0 },
|
|
||||||
{ "ppc", 32, "qemu-system-ppc", NULL, NULL, 0 },
|
|
||||||
{ "ppc64", 64, "qemu-system-ppc64", NULL, NULL, 0 },
|
|
||||||
{ "itanium", 64, "qemu-system-ia64", NULL, NULL, 0 },
|
|
||||||
{ "s390x", 64, "qemu-system-s390x", NULL, NULL, 0 },
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
static virCommandPtr
|
static virCommandPtr
|
||||||
qemuCapsProbeCommand(const char *qemu,
|
qemuCapsProbeCommand(const char *qemu,
|
||||||
qemuCapsPtr caps)
|
qemuCapsPtr caps)
|
||||||
@ -570,11 +523,70 @@ cleanup:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static char *
|
||||||
|
qemuCapsFindBinaryForArch(const char *hostarch,
|
||||||
|
const char *guestarch)
|
||||||
|
{
|
||||||
|
char *ret;
|
||||||
|
|
||||||
|
if (STREQ(guestarch, "i686")) {
|
||||||
|
ret = virFindFileInPath("qemu-system-i386");
|
||||||
|
if (ret && !virFileIsExecutable(ret))
|
||||||
|
VIR_FREE(ret);
|
||||||
|
|
||||||
|
if (!ret && STREQ(hostarch, "x86_64")) {
|
||||||
|
ret = virFindFileInPath("qemu-system-x86_64");
|
||||||
|
if (ret && !virFileIsExecutable(ret))
|
||||||
|
VIR_FREE(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ret)
|
||||||
|
ret = virFindFileInPath("qemu");
|
||||||
|
} else if (STREQ(guestarch, "itanium")) {
|
||||||
|
ret = virFindFileInPath("qemu-system-ia64");
|
||||||
|
} else {
|
||||||
|
char *bin;
|
||||||
|
if (virAsprintf(&bin, "qemu-system-%s", guestarch) < 0) {
|
||||||
|
virReportOOMError();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
ret = virFindFileInPath(bin);
|
||||||
|
VIR_FREE(bin);
|
||||||
|
}
|
||||||
|
if (ret && !virFileIsExecutable(ret))
|
||||||
|
VIR_FREE(ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
qemuCapsGetArchWordSize(const char *guestarch)
|
||||||
|
{
|
||||||
|
if (STREQ(guestarch, "i686") ||
|
||||||
|
STREQ(guestarch, "ppc") ||
|
||||||
|
STREQ(guestarch, "sparc") ||
|
||||||
|
STREQ(guestarch, "mips") ||
|
||||||
|
STREQ(guestarch, "mipsel"))
|
||||||
|
return 32;
|
||||||
|
return 64;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
qemuCapsIsValidForKVM(const char *hostarch,
|
||||||
|
const char *guestarch)
|
||||||
|
{
|
||||||
|
if (STREQ(hostarch, guestarch))
|
||||||
|
return true;
|
||||||
|
if (STREQ(hostarch, "x86_64") &&
|
||||||
|
STREQ(guestarch, "i686"))
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
qemuCapsInitGuest(virCapsPtr caps,
|
qemuCapsInitGuest(virCapsPtr caps,
|
||||||
qemuCapsCachePtr cache,
|
qemuCapsCachePtr cache,
|
||||||
const char *hostmachine,
|
const char *hostarch,
|
||||||
const struct qemu_arch_info *info)
|
const char *guestarch)
|
||||||
{
|
{
|
||||||
virCapsGuestPtr guest;
|
virCapsGuestPtr guest;
|
||||||
int i;
|
int i;
|
||||||
@ -591,12 +603,7 @@ qemuCapsInitGuest(virCapsPtr caps,
|
|||||||
/* Check for existance of base emulator, or alternate base
|
/* Check for existance of base emulator, or alternate base
|
||||||
* which can be used with magic cpu choice
|
* which can be used with magic cpu choice
|
||||||
*/
|
*/
|
||||||
binary = virFindFileInPath(info->binary);
|
binary = qemuCapsFindBinaryForArch(hostarch, guestarch);
|
||||||
|
|
||||||
if (binary == NULL || !virFileIsExecutable(binary)) {
|
|
||||||
VIR_FREE(binary);
|
|
||||||
binary = virFindFileInPath(info->altbinary);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Ignore binary if extracting version info fails */
|
/* Ignore binary if extracting version info fails */
|
||||||
if (binary) {
|
if (binary) {
|
||||||
@ -612,8 +619,7 @@ qemuCapsInitGuest(virCapsPtr caps,
|
|||||||
* - hostarch is x86_64 and guest arch is i686
|
* - hostarch is x86_64 and guest arch is i686
|
||||||
* The latter simply needs "-cpu qemu32"
|
* The latter simply needs "-cpu qemu32"
|
||||||
*/
|
*/
|
||||||
if (STREQ(info->arch, hostmachine) ||
|
if (qemuCapsIsValidForKVM(hostarch, guestarch)) {
|
||||||
(STREQ(hostmachine, "x86_64") && STREQ(info->arch, "i686"))) {
|
|
||||||
const char *const kvmbins[] = { "/usr/libexec/qemu-kvm", /* RHEL */
|
const char *const kvmbins[] = { "/usr/libexec/qemu-kvm", /* RHEL */
|
||||||
"qemu-kvm", /* Fedora */
|
"qemu-kvm", /* Fedora */
|
||||||
"kvm" }; /* Upstream .spec */
|
"kvm" }; /* Upstream .spec */
|
||||||
@ -660,8 +666,8 @@ qemuCapsInitGuest(virCapsPtr caps,
|
|||||||
* just give -no-kvm to disable acceleration if required */
|
* just give -no-kvm to disable acceleration if required */
|
||||||
if ((guest = virCapabilitiesAddGuest(caps,
|
if ((guest = virCapabilitiesAddGuest(caps,
|
||||||
"hvm",
|
"hvm",
|
||||||
info->arch,
|
guestarch,
|
||||||
info->wordsize,
|
qemuCapsGetArchWordSize(guestarch),
|
||||||
binary,
|
binary,
|
||||||
NULL,
|
NULL,
|
||||||
nmachines,
|
nmachines,
|
||||||
@ -718,15 +724,16 @@ qemuCapsInitGuest(virCapsPtr caps,
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (info->nflags) {
|
if ((STREQ(guestarch, "i686") ||
|
||||||
for (i = 0 ; i < info->nflags ; i++) {
|
STREQ(guestarch, "x86_64")) &&
|
||||||
if (virCapabilitiesAddGuestFeature(guest,
|
(virCapabilitiesAddGuestFeature(guest, "acpi", 1, 1) == NULL ||
|
||||||
info->flags[i].name,
|
virCapabilitiesAddGuestFeature(guest, "apic", 1, 0) == NULL))
|
||||||
info->flags[i].default_on,
|
goto error;
|
||||||
info->flags[i].toggle) == NULL)
|
|
||||||
|
if (STREQ(guestarch, "i686") &&
|
||||||
|
(virCapabilitiesAddGuestFeature(guest, "pae", 1, 0) == NULL ||
|
||||||
|
virCapabilitiesAddGuestFeature(guest, "nonpae", 1, 0) == NULL))
|
||||||
goto error;
|
goto error;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = 0;
|
ret = 0;
|
||||||
|
|
||||||
@ -798,13 +805,20 @@ virCapsPtr qemuCapsInit(qemuCapsCachePtr cache)
|
|||||||
struct utsname utsname;
|
struct utsname utsname;
|
||||||
virCapsPtr caps;
|
virCapsPtr caps;
|
||||||
int i;
|
int i;
|
||||||
|
const char *const arches[] = {
|
||||||
|
"i686", "x86_64", "arm",
|
||||||
|
"microblaze", "microblazeel",
|
||||||
|
"mips", "mipsel", "sparc",
|
||||||
|
"ppc", "ppc64", "itanium",
|
||||||
|
"s390x"
|
||||||
|
};
|
||||||
|
|
||||||
/* Really, this never fails - look at the man-page. */
|
/* Really, this never fails - look at the man-page. */
|
||||||
uname (&utsname);
|
uname (&utsname);
|
||||||
|
|
||||||
if ((caps = virCapabilitiesNew(utsname.machine,
|
if ((caps = virCapabilitiesNew(utsname.machine,
|
||||||
1, 1)) == NULL)
|
1, 1)) == NULL)
|
||||||
goto no_memory;
|
goto error;
|
||||||
|
|
||||||
/* Using KVM's mac prefix for QEMU too */
|
/* Using KVM's mac prefix for QEMU too */
|
||||||
virCapabilitiesSetMacPrefix(caps, (unsigned char[]){ 0x52, 0x54, 0x00 });
|
virCapabilitiesSetMacPrefix(caps, (unsigned char[]){ 0x52, 0x54, 0x00 });
|
||||||
@ -830,11 +844,11 @@ virCapsPtr qemuCapsInit(qemuCapsCachePtr cache)
|
|||||||
"tcp");
|
"tcp");
|
||||||
|
|
||||||
/* First the pure HVM guests */
|
/* First the pure HVM guests */
|
||||||
for (i = 0 ; i < ARRAY_CARDINALITY(arch_info_hvm) ; i++)
|
for (i = 0 ; i < ARRAY_CARDINALITY(arches) ; i++)
|
||||||
if (qemuCapsInitGuest(caps, cache,
|
if (qemuCapsInitGuest(caps, cache,
|
||||||
utsname.machine,
|
utsname.machine,
|
||||||
&arch_info_hvm[i]) < 0)
|
arches[i]) < 0)
|
||||||
goto no_memory;
|
goto error;
|
||||||
|
|
||||||
/* QEMU Requires an emulator in the XML */
|
/* QEMU Requires an emulator in the XML */
|
||||||
virCapabilitiesSetEmulatorRequired(caps);
|
virCapabilitiesSetEmulatorRequired(caps);
|
||||||
@ -843,7 +857,7 @@ virCapsPtr qemuCapsInit(qemuCapsCachePtr cache)
|
|||||||
|
|
||||||
return caps;
|
return caps;
|
||||||
|
|
||||||
no_memory:
|
error:
|
||||||
virCapabilitiesFree(caps);
|
virCapabilitiesFree(caps);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user