#include "c-ctype.h"
#include "glthread/lock.h"
+#include "ignore-value.h"
#include "guestfs.h"
#include "guestfs-internal.h"
*/
g->cmdline[0] = g->qemu;
+ /* CVE-2011-4127 mitigation: Disable SCSI ioctls on virtio-blk
+ * devices. The -global option must exist, but you can pass any
+ * strings to it so we don't need to check for the specific virtio
+ * feature.
+ */
+ if (qemu_supports (g, "-global")) {
+ add_cmdline (g, "-global");
+ add_cmdline (g, "virtio-blk-pci.scsi=off");
+ }
+
if (qemu_supports (g, "-nodefconfig"))
add_cmdline (g, "-nodefconfig");
*/
if (qemu_supports (g, "-machine")) {
add_cmdline (g, "-machine");
+#if QEMU_MACHINE_TYPE_IS_BROKEN
+ /* Workaround for qemu 0.15: We have to add the '[type=]pc'
+ * since there is no default. This is not a permanent solution
+ * because this only works on PC-like hardware. Other platforms
+ * like ppc would need a different machine type.
+ *
+ * This bug is fixed in qemu commit 2645c6dcaf6ea2a51a, and was
+ * not a problem in qemu < 0.15.
+ */
+ add_cmdline (g, "pc,accel=kvm:tcg");
+#else
add_cmdline (g, "accel=kvm:tcg");
+#endif
} else {
/* qemu sometimes needs this option to enable hardware
* virtualization, but some versions of 'qemu-kvm' will use KVM
free (msg);
}
+static int test_qemu_cmd (guestfs_h *g, const char *cmd, char **ret);
static int read_all (guestfs_h *g, FILE *fp, char **ret);
/* Test qemu binary (or wrapper) runs, and do 'qemu -help' and
char cmd[1024];
FILE *fp;
+ free (g->qemu_help);
+ g->qemu_help = NULL;
+ free (g->qemu_version);
+ g->qemu_version = NULL;
+
snprintf (cmd, sizeof cmd, "LC_ALL=C '%s' -nographic -help", g->qemu);
- fp = popen (cmd, "r");
/* qemu -help should always work (qemu -version OTOH wasn't
* supported by qemu 0.9). If this command doesn't work then it
* probably indicates that the qemu binary is missing.
*/
- if (!fp) {
- /* XXX This error is never printed, even if the qemu binary
- * doesn't exist. Why?
- */
- error:
+ if (test_qemu_cmd (g, cmd, &g->qemu_help) == -1) {
perrorf (g, _("%s: command failed: If qemu is located on a non-standard path, try setting the LIBGUESTFS_QEMU environment variable."), cmd);
return -1;
}
- if (read_all (g, fp, &g->qemu_help) == -1)
- goto error;
-
- if (pclose (fp) == -1)
- goto error;
-
snprintf (cmd, sizeof cmd, "LC_ALL=C '%s' -nographic -version 2>/dev/null",
g->qemu);
+ /* Intentionally ignore errors from qemu -version. */
+ ignore_value (test_qemu_cmd (g, cmd, &g->qemu_version));
+
+ return 0;
+}
+
+static int
+test_qemu_cmd (guestfs_h *g, const char *cmd, char **ret)
+{
+ FILE *fp;
+
fp = popen (cmd, "r");
- if (fp) {
- /* Intentionally ignore errors. */
- read_all (g, fp, &g->qemu_version);
+ if (fp == NULL)
+ return -1;
+
+ if (read_all (g, fp, ret) == -1) {
pclose (fp);
+ return -1;
}
+ if (pclose (fp) != 0)
+ return -1;
+
return 0;
}