lib: Move some appliance functions around.

Move some appliance functions out of src/appliance.c and src/launch.c
into separate files.

No functional change, just code movement.
This commit is contained in:
Richard W.M. Jones
2016-12-24 15:58:36 +00:00
parent 61d26f85fc
commit dd519e8a8e
9 changed files with 432 additions and 323 deletions

View File

@@ -309,6 +309,9 @@ src/actions-6.c
src/actions-support.c
src/actions-variants.c
src/alloc.c
src/appliance-cpu.c
src/appliance-kcmdline.c
src/appliance-uefi.c
src/appliance.c
src/available.c
src/bindtests.c

View File

@@ -381,6 +381,9 @@ src/actions-6.c
src/actions-support.c
src/actions-variants.c
src/alloc.c
src/appliance-cpu.c
src/appliance-kcmdline.c
src/appliance-uefi.c
src/appliance.c
src/available.c
src/bindtests.c

View File

@@ -82,6 +82,9 @@ libguestfs_la_SOURCES = \
actions-variants.c \
alloc.c \
appliance.c \
appliance-cpu.c \
appliance-kcmdline.c \
appliance-uefi.c \
available.c \
bindtests.c \
canonical-name.c \

90
src/appliance-cpu.c Normal file
View File

@@ -0,0 +1,90 @@
/* libguestfs
* Copyright (C) 2009-2016 Red Hat Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* The appliance choice of CPU model.
*/
#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include "guestfs.h"
#include "guestfs-internal.h"
/**
* Return the right CPU model to use as the qemu C<-cpu> parameter or
* its equivalent in libvirt. This returns:
*
* =over 4
*
* =item C<"host">
*
* The literal string C<"host"> means use C<-cpu host>.
*
* =item some string
*
* Some string such as C<"cortex-a57"> means use C<-cpu cortex-a57>.
*
* =item C<NULL>
*
* C<NULL> means no C<-cpu> option at all. Note returning C<NULL>
* does not indicate an error.
*
* =back
*
* This is made unnecessarily hard and fragile because of two stupid
* choices in QEMU:
*
* =over 4
*
* =item *
*
* The default for C<qemu-system-aarch64 -M virt> is to emulate a
* C<cortex-a15> (WTF?).
*
* =item *
*
* We don't know for sure if KVM will work, but C<-cpu host> is broken
* with TCG, so we almost always pass a broken C<-cpu> flag if KVM is
* semi-broken in any way.
*
* =back
*/
const char *
guestfs_int_get_cpu_model (int kvm)
{
#if defined(__aarch64__)
/* With -M virt, the default -cpu is cortex-a15. Stupid. */
if (kvm)
return "host";
else
return "cortex-a57";
#else
/* On most architectures, it is faster to pass the CPU host model to
* the appliance, allowing maximum speed for things like checksums
* and encryption. Only do this with KVM. It is broken in subtle
* ways on TCG, and fairly pointless when you're emulating anyway.
*/
if (kvm)
return "host";
else
return NULL;
#endif
}

219
src/appliance-kcmdline.c Normal file
View File

@@ -0,0 +1,219 @@
/* libguestfs
* Copyright (C) 2009-2016 Red Hat Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* The appliance kernel command line.
*/
#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include "c-ctype.h"
#include "guestfs.h"
#include "guestfs-internal.h"
/**
* Check that the $TERM environment variable is reasonable before
* we pass it through to the appliance.
*/
static bool
valid_term (const char *term)
{
size_t len = strlen (term);
if (len == 0 || len > 16)
return false;
while (len > 0) {
char c = *term++;
len--;
if (!c_isalnum (c) && c != '-' && c != '_')
return false;
}
return true;
}
#if defined(__powerpc64__)
#define SERIAL_CONSOLE "console=hvc0 console=ttyS0"
#elif defined(__arm__) || defined(__aarch64__)
#define SERIAL_CONSOLE "console=ttyAMA0"
#else
#define SERIAL_CONSOLE "console=ttyS0"
#endif
#if defined(__aarch64__)
#define EARLYPRINTK "earlyprintk=pl011,0x9000000"
#endif
/**
* Construct the Linux command line passed to the appliance. This is
* used by the C<direct> and C<libvirt> backends, and is simply
* located in this file because it's a convenient place for this
* common code.
*
* The C<appliance_dev> parameter must be the full device name of the
* appliance disk and must have already been adjusted to take into
* account virtio-blk or virtio-scsi; eg C</dev/sdb>.
*
* The C<flags> parameter can contain the following flags logically
* or'd together (or 0):
*
* =over 4
*
* =item C<APPLIANCE_COMMAND_LINE_IS_TCG>
*
* If we are launching a qemu TCG guest (ie. KVM is known to be
* disabled or unavailable). If you don't know, don't pass this flag.
*
* =back
*
* Note that this function returns a newly allocated buffer which must
* be freed by the caller.
*/
char *
guestfs_int_appliance_command_line (guestfs_h *g, const char *appliance_dev,
int flags)
{
CLEANUP_FREE_STRINGSBUF DECLARE_STRINGSBUF (argv);
char *term = getenv ("TERM");
bool tcg = flags & APPLIANCE_COMMAND_LINE_IS_TCG;
char *ret;
/* We assemble the kernel command line by simply joining the final
* list of strings with spaces. This means (a) the strings are not
* quoted (it's not clear if the kernel can handle quoting in any
* case), and (b) we can append multiple parameters in a single
* argument, as we must do for the g->append parameter.
*/
/* Force kernel to panic if daemon exits. */
guestfs_int_add_string (g, &argv, "panic=1");
#ifdef __arm__
guestfs_int_add_sprintf (g, &argv, "mem=%dM", g->memsize);
#endif
#ifdef __i386__
/* Workaround for RHBZ#857026. */
guestfs_int_add_string (g, &argv, "noapic");
#endif
/* Serial console. */
guestfs_int_add_string (g, &argv, SERIAL_CONSOLE);
#ifdef EARLYPRINTK
/* Get messages from early boot. */
guestfs_int_add_string (g, &argv, EARLYPRINTK);
#endif
#ifdef __aarch64__
guestfs_int_add_string (g, &argv, "ignore_loglevel");
/* This option turns off the EFI RTC device. QEMU VMs don't
* currently provide EFI, and if the device is compiled in it
* will try to call the EFI function GetTime unconditionally
* (causing a call to NULL). However this option requires a
* non-upstream patch.
*/
guestfs_int_add_string (g, &argv, "efi-rtc=noprobe");
#endif
/* RHBZ#1404287 */
guestfs_int_add_string (g, &argv, "edd=off");
/* For slow systems (RHBZ#480319, RHBZ#1096579). */
guestfs_int_add_string (g, &argv, "udevtimeout=6000");
/* Same as above, for newer udevd. */
guestfs_int_add_string (g, &argv, "udev.event-timeout=6000");
/* Fix for RHBZ#502058. */
guestfs_int_add_string (g, &argv, "no_timer_check");
if (tcg) {
const int lpj = guestfs_int_get_lpj (g);
if (lpj > 0)
guestfs_int_add_sprintf (g, &argv, "lpj=%d", lpj);
}
/* Display timestamp before kernel messages. */
guestfs_int_add_string (g, &argv, "printk.time=1");
/* Saves us about 5 MB of RAM. */
guestfs_int_add_string (g, &argv, "cgroup_disable=memory");
/* Disable USB, only saves about 1ms. */
guestfs_int_add_string (g, &argv, "usbcore.nousb");
/* Disable crypto tests, saves 28ms. */
guestfs_int_add_string (g, &argv, "cryptomgr.notests");
/* Don't synch TSCs when using SMP. Saves 21ms for each secondary vCPU. */
guestfs_int_add_string (g, &argv, "tsc=reliable");
/* Don't scan all 8250 UARTS. */
guestfs_int_add_string (g, &argv, "8250.nr_uarts=1");
/* Tell supermin about the appliance device. */
if (appliance_dev)
guestfs_int_add_sprintf (g, &argv, "root=%s", appliance_dev);
/* SELinux - deprecated setting, never worked and should not be enabled. */
if (g->selinux)
guestfs_int_add_string (g, &argv, "selinux=1 enforcing=0");
else
guestfs_int_add_string (g, &argv, "selinux=0");
/* Quiet/verbose. */
if (g->verbose)
guestfs_int_add_string (g, &argv, "guestfs_verbose=1");
else
guestfs_int_add_string (g, &argv, "quiet");
/* Network. */
if (g->enable_network)
guestfs_int_add_string (g, &argv, "guestfs_network=1");
/* TERM environment variable. */
if (term && valid_term (term))
guestfs_int_add_sprintf (g, &argv, "TERM=%s", term);
else
guestfs_int_add_string (g, &argv, "TERM=linux");
/* Handle identifier. */
if (STRNEQ (g->identifier, ""))
guestfs_int_add_sprintf (g, &argv, "guestfs_identifier=%s", g->identifier);
/* Append extra arguments. */
if (g->append)
guestfs_int_add_string (g, &argv, g->append);
guestfs_int_end_stringsbuf (g, &argv);
/* Caller frees. */
ret = guestfs_int_join_strings (" ", argv.argv);
if (ret == NULL)
g->abort_cb ();
return ret;
}

105
src/appliance-uefi.c Normal file
View File

@@ -0,0 +1,105 @@
/* libguestfs
* Copyright (C) 2010-2016 Red Hat Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* Find the UEFI firmware needed to boot the appliance.
*
* See also F<src/uefi.c> (autogenerated file) containing the
* firmware file locations.
*/
#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "guestfs.h"
#include "guestfs-internal.h"
/**
* Return the location of firmware needed to boot the appliance. This
* is aarch64 only currently, since that's the only architecture where
* UEFI is mandatory (and that only for RHEL).
*
* C<*code> is initialized with the path to the read-only UEFI code
* file. C<*vars> is initialized with the path to a copy of the UEFI
* vars file (which is cleaned up automatically on exit).
*
* If C<*code> == C<*vars> == C<NULL> then no UEFI firmware is
* available.
*
* C<*code> and C<*vars> should be freed by the caller.
*
* If the function returns C<-1> then there was a real error which
* should cause appliance building to fail (no UEFI firmware is not an
* error).
*
* See also F<v2v/utils.ml>:find_uefi_firmware
*/
int
guestfs_int_get_uefi (guestfs_h *g, char **code, char **vars, int *flags)
{
#ifdef __aarch64__
size_t i;
for (i = 0; guestfs_int_uefi_aarch64_firmware[i].code != NULL; ++i) {
const char *codefile = guestfs_int_uefi_aarch64_firmware[i].code;
const char *code_debug_file =
guestfs_int_uefi_aarch64_firmware[i].code_debug;
const char *varsfile = guestfs_int_uefi_aarch64_firmware[i].vars;
if (access (codefile, R_OK) == 0 && access (varsfile, R_OK) == 0) {
CLEANUP_CMD_CLOSE struct command *copycmd = guestfs_int_new_command (g);
char *varst;
int r;
/* Make a copy of NVRAM variables file. You can't just map it
* into the address space read-only as that triggers a different
* path inside UEFI.
*/
varst = safe_asprintf (g, "%s/vars.fd.%d", g->tmpdir, ++g->unique);
guestfs_int_cmd_add_arg (copycmd, "cp");
guestfs_int_cmd_add_arg (copycmd, varsfile);
guestfs_int_cmd_add_arg (copycmd, varst);
r = guestfs_int_cmd_run (copycmd);
if (r == -1 || !WIFEXITED (r) || WEXITSTATUS (r) != 0) {
free (varst);
return -1;
}
/* If debugging is enabled and we can find the code file with
* debugging enabled, use that instead.
*/
if (g->verbose && access (code_debug_file, R_OK) == 0)
codefile = code_debug_file;
/* Caller frees. */
*code = safe_strdup (g, codefile);
*vars = varst;
*flags = guestfs_int_uefi_aarch64_firmware[i].flags;
return 0;
}
}
#endif
/* Not found. */
*code = *vars = NULL;
*flags = 0;
return 0;
}

View File

@@ -404,75 +404,3 @@ dir_contains_files (guestfs_h *g, const char *dir, ...)
va_end (args);
return 1;
}
/**
* Return the location of firmware needed to boot the appliance. This
* is aarch64 only currently, since that's the only architecture where
* UEFI is mandatory (and that only for RHEL).
*
* C<*code> is initialized with the path to the read-only UEFI code
* file. C<*vars> is initialized with the path to a copy of the UEFI
* vars file (which is cleaned up automatically on exit).
*
* If C<*code> == C<*vars> == C<NULL> then no UEFI firmware is
* available.
*
* C<*code> and C<*vars> should be freed by the caller.
*
* If the function returns C<-1> then there was a real error which
* should cause appliance building to fail (no UEFI firmware is not an
* error).
*
* See also F<v2v/utils.ml>:find_uefi_firmware
*/
int
guestfs_int_get_uefi (guestfs_h *g, char **code, char **vars, int *flags)
{
#ifdef __aarch64__
size_t i;
for (i = 0; guestfs_int_uefi_aarch64_firmware[i].code != NULL; ++i) {
const char *codefile = guestfs_int_uefi_aarch64_firmware[i].code;
const char *code_debug_file =
guestfs_int_uefi_aarch64_firmware[i].code_debug;
const char *varsfile = guestfs_int_uefi_aarch64_firmware[i].vars;
if (access (codefile, R_OK) == 0 && access (varsfile, R_OK) == 0) {
CLEANUP_CMD_CLOSE struct command *copycmd = guestfs_int_new_command (g);
char *varst;
int r;
/* Make a copy of NVRAM variables file. You can't just map it
* into the address space read-only as that triggers a different
* path inside UEFI.
*/
varst = safe_asprintf (g, "%s/vars.fd.%d", g->tmpdir, ++g->unique);
guestfs_int_cmd_add_arg (copycmd, "cp");
guestfs_int_cmd_add_arg (copycmd, varsfile);
guestfs_int_cmd_add_arg (copycmd, varst);
r = guestfs_int_cmd_run (copycmd);
if (r == -1 || !WIFEXITED (r) || WEXITSTATUS (r) != 0) {
free (varst);
return -1;
}
/* If debugging is enabled and we can find the code file with
* debugging enabled, use that instead.
*/
if (g->verbose && access (code_debug_file, R_OK) == 0)
codefile = code_debug_file;
/* Caller frees. */
*code = safe_strdup (g, codefile);
*vars = varst;
*flags = guestfs_int_uefi_aarch64_firmware[i].flags;
return 0;
}
}
#endif
/* Not found. */
*code = *vars = NULL;
*flags = 0;
return 0;
}

View File

@@ -831,14 +831,20 @@ extern const char *guestfs_int_drive_protocol_to_string (enum drive_protocol pro
/* appliance.c */
extern int guestfs_int_build_appliance (guestfs_h *g, char **kernel, char **initrd, char **appliance);
/* appliance-cpu.c */
const char *guestfs_int_get_cpu_model (int kvm);
/* appliance-kcmdline.c */
extern char *guestfs_int_appliance_command_line (guestfs_h *g, const char *appliance_dev, int flags);
#define APPLIANCE_COMMAND_LINE_IS_TCG 1
/* appliance-uefi.c */
extern int guestfs_int_get_uefi (guestfs_h *g, char **code, char **vars, int *flags);
/* launch.c */
extern int64_t guestfs_int_timeval_diff (const struct timeval *x, const struct timeval *y);
extern void guestfs_int_launch_send_progress (guestfs_h *g, int perdozen);
extern char *guestfs_int_appliance_command_line (guestfs_h *g, const char *appliance_dev, int flags);
#define APPLIANCE_COMMAND_LINE_IS_TCG 1
const char *guestfs_int_get_cpu_model (int kvm);
int guestfs_int_create_socketname (guestfs_h *g, const char *filename, char (*sockname)[UNIX_PATH_MAX]);
extern void guestfs_int_register_backend (const char *name, const struct backend_ops *);
extern int guestfs_int_set_backend (guestfs_h *g, const char *method);

View File

@@ -29,7 +29,6 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <inttypes.h>
#include <unistd.h>
#include <string.h>
@@ -287,253 +286,6 @@ guestfs_impl_config (guestfs_h *g,
return 0;
}
/**
* Check that the $TERM environment variable is reasonable before
* we pass it through to the appliance.
*/
static bool
valid_term (const char *term)
{
size_t len = strlen (term);
if (len == 0 || len > 16)
return false;
while (len > 0) {
char c = *term++;
len--;
if (!c_isalnum (c) && c != '-' && c != '_')
return false;
}
return true;
}
#if defined(__powerpc64__)
#define SERIAL_CONSOLE "console=hvc0 console=ttyS0"
#elif defined(__arm__) || defined(__aarch64__)
#define SERIAL_CONSOLE "console=ttyAMA0"
#else
#define SERIAL_CONSOLE "console=ttyS0"
#endif
#if defined(__aarch64__)
#define EARLYPRINTK "earlyprintk=pl011,0x9000000"
#endif
/**
* Construct the Linux command line passed to the appliance. This is
* used by the C<direct> and C<libvirt> backends, and is simply
* located in this file because it's a convenient place for this
* common code.
*
* The C<appliance_dev> parameter must be the full device name of the
* appliance disk and must have already been adjusted to take into
* account virtio-blk or virtio-scsi; eg C</dev/sdb>.
*
* The C<flags> parameter can contain the following flags logically
* or'd together (or 0):
*
* =over 4
*
* =item C<APPLIANCE_COMMAND_LINE_IS_TCG>
*
* If we are launching a qemu TCG guest (ie. KVM is known to be
* disabled or unavailable). If you don't know, don't pass this flag.
*
* =back
*
* Note that this function returns a newly allocated buffer which must
* be freed by the caller.
*/
char *
guestfs_int_appliance_command_line (guestfs_h *g, const char *appliance_dev,
int flags)
{
CLEANUP_FREE_STRINGSBUF DECLARE_STRINGSBUF (argv);
char *term = getenv ("TERM");
bool tcg = flags & APPLIANCE_COMMAND_LINE_IS_TCG;
char *ret;
/* We assemble the kernel command line by simply joining the final
* list of strings with spaces. This means (a) the strings are not
* quoted (it's not clear if the kernel can handle quoting in any
* case), and (b) we can append multiple parameters in a single
* argument, as we must do for the g->append parameter.
*/
/* Force kernel to panic if daemon exits. */
guestfs_int_add_string (g, &argv, "panic=1");
#ifdef __arm__
guestfs_int_add_sprintf (g, &argv, "mem=%dM", g->memsize);
#endif
#ifdef __i386__
/* Workaround for RHBZ#857026. */
guestfs_int_add_string (g, &argv, "noapic");
#endif
/* Serial console. */
guestfs_int_add_string (g, &argv, SERIAL_CONSOLE);
#ifdef EARLYPRINTK
/* Get messages from early boot. */
guestfs_int_add_string (g, &argv, EARLYPRINTK);
#endif
#ifdef __aarch64__
guestfs_int_add_string (g, &argv, "ignore_loglevel");
/* This option turns off the EFI RTC device. QEMU VMs don't
* currently provide EFI, and if the device is compiled in it
* will try to call the EFI function GetTime unconditionally
* (causing a call to NULL). However this option requires a
* non-upstream patch.
*/
guestfs_int_add_string (g, &argv, "efi-rtc=noprobe");
#endif
/* RHBZ#1404287 */
guestfs_int_add_string (g, &argv, "edd=off");
/* For slow systems (RHBZ#480319, RHBZ#1096579). */
guestfs_int_add_string (g, &argv, "udevtimeout=6000");
/* Same as above, for newer udevd. */
guestfs_int_add_string (g, &argv, "udev.event-timeout=6000");
/* Fix for RHBZ#502058. */
guestfs_int_add_string (g, &argv, "no_timer_check");
if (tcg) {
const int lpj = guestfs_int_get_lpj (g);
if (lpj > 0)
guestfs_int_add_sprintf (g, &argv, "lpj=%d", lpj);
}
/* Display timestamp before kernel messages. */
guestfs_int_add_string (g, &argv, "printk.time=1");
/* Saves us about 5 MB of RAM. */
guestfs_int_add_string (g, &argv, "cgroup_disable=memory");
/* Disable USB, only saves about 1ms. */
guestfs_int_add_string (g, &argv, "usbcore.nousb");
/* Disable crypto tests, saves 28ms. */
guestfs_int_add_string (g, &argv, "cryptomgr.notests");
/* Don't synch TSCs when using SMP. Saves 21ms for each secondary vCPU. */
guestfs_int_add_string (g, &argv, "tsc=reliable");
/* Don't scan all 8250 UARTS. */
guestfs_int_add_string (g, &argv, "8250.nr_uarts=1");
/* Tell supermin about the appliance device. */
if (appliance_dev)
guestfs_int_add_sprintf (g, &argv, "root=%s", appliance_dev);
/* SELinux - deprecated setting, never worked and should not be enabled. */
if (g->selinux)
guestfs_int_add_string (g, &argv, "selinux=1 enforcing=0");
else
guestfs_int_add_string (g, &argv, "selinux=0");
/* Quiet/verbose. */
if (g->verbose)
guestfs_int_add_string (g, &argv, "guestfs_verbose=1");
else
guestfs_int_add_string (g, &argv, "quiet");
/* Network. */
if (g->enable_network)
guestfs_int_add_string (g, &argv, "guestfs_network=1");
/* TERM environment variable. */
if (term && valid_term (term))
guestfs_int_add_sprintf (g, &argv, "TERM=%s", term);
else
guestfs_int_add_string (g, &argv, "TERM=linux");
/* Handle identifier. */
if (STRNEQ (g->identifier, ""))
guestfs_int_add_sprintf (g, &argv, "guestfs_identifier=%s", g->identifier);
/* Append extra arguments. */
if (g->append)
guestfs_int_add_string (g, &argv, g->append);
guestfs_int_end_stringsbuf (g, &argv);
/* Caller frees. */
ret = guestfs_int_join_strings (" ", argv.argv);
if (ret == NULL)
g->abort_cb ();
return ret;
}
/**
* Return the right CPU model to use as the qemu C<-cpu> parameter or
* its equivalent in libvirt. This returns:
*
* =over 4
*
* =item C<"host">
*
* The literal string C<"host"> means use C<-cpu host>.
*
* =item some string
*
* Some string such as C<"cortex-a57"> means use C<-cpu cortex-a57>.
*
* =item C<NULL>
*
* C<NULL> means no C<-cpu> option at all. Note returning C<NULL>
* does not indicate an error.
*
* =back
*
* This is made unnecessarily hard and fragile because of two stupid
* choices in QEMU:
*
* =over 4
*
* =item *
*
* The default for C<qemu-system-aarch64 -M virt> is to emulate a
* C<cortex-a15> (WTF?).
*
* =item *
*
* We don't know for sure if KVM will work, but C<-cpu host> is broken
* with TCG, so we almost always pass a broken C<-cpu> flag if KVM is
* semi-broken in any way.
*
* =back
*/
const char *
guestfs_int_get_cpu_model (int kvm)
{
#if defined(__aarch64__)
/* With -M virt, the default -cpu is cortex-a15. Stupid. */
if (kvm)
return "host";
else
return "cortex-a57";
#else
/* On most architectures, it is faster to pass the CPU host model to
* the appliance, allowing maximum speed for things like checksums
* and encryption. Only do this with KVM. It is broken in subtle
* ways on TCG, and fairly pointless when you're emulating anyway.
*/
if (kvm)
return "host";
else
return NULL;
#endif
}
/**
* Create the path for a socket with the selected filename in the
* tmpdir.