X-Git-Url: http://git.annexia.org/?p=libguestfs.git;a=blobdiff_plain;f=src%2Fguestfs.c;h=ad3980ffdc84216b14830cae8ec6c9f45fb94b4d;hp=de6327518ae4914ae6787009f228598aa39df1a0;hb=5a9b41ed4462ec765303b973f74f17d5c0138a9a;hpb=5d78de834c53bfe29d2cc0397ac093428abe8425 diff --git a/src/guestfs.c b/src/guestfs.c index de63275..ad3980f 100644 --- a/src/guestfs.c +++ b/src/guestfs.c @@ -177,6 +177,8 @@ struct guestfs_h int memsize; /* Size of RAM (megabytes). */ + int selinux; /* selinux enabled? */ + char *last_error; /* Callbacks. */ @@ -689,6 +691,19 @@ guestfs_get_memsize (guestfs_h *g) } int +guestfs_set_selinux (guestfs_h *g, int selinux) +{ + g->selinux = selinux; + return 0; +} + +int +guestfs_get_selinux (guestfs_h *g) +{ + return g->selinux; +} + +int guestfs_get_pid (guestfs_h *g) { if (g->pid > 0) @@ -784,14 +799,31 @@ guestfs_add_drive (guestfs_h *g, const char *filename) return -1; } - if (access (filename, F_OK) == -1) { - perrorf (g, "%s", filename); - return -1; + /* cache=off improves reliability in the event of a host crash. + * + * However this option causes qemu to try to open the file with + * O_DIRECT. This fails on some filesystem types (notably tmpfs). + * So we check if we can open the file with or without O_DIRECT, + * and use cache=off (or not) accordingly. + * + * This test also checks for the presence of the file, which + * is a documented semantic of this interface. + */ + int fd = open (filename, O_RDONLY|O_DIRECT); + if (fd >= 0) { + close (fd); + snprintf (buf, len, "file=%s,cache=off,if=" DRIVE_IF, filename); + } else { + fd = open (filename, O_RDONLY); + if (fd >= 0) { + close (fd); + snprintf (buf, len, "file=%s,if=" DRIVE_IF, filename); + } else { + perrorf (g, "%s", filename); + return -1; + } } - /* cache=off improves reliability in the event of a host crash. */ - snprintf (buf, len, "file=%s,cache=off,if=%s", filename, DRIVE_IF); - return guestfs_config (g, "-drive", buf); } @@ -866,6 +898,7 @@ dir_contains_files (const char *dir, ...) static int build_supermin_appliance (guestfs_h *g, const char *path, char **kernel, char **initrd); static int test_qemu (guestfs_h *g); static int qemu_supports (guestfs_h *g, const char *option); +static void print_cmdline (guestfs_h *g); static const char *kernel_name = "vmlinuz." REPO "." host_cpu; static const char *initrd_name = "initramfs." REPO "." host_cpu ".img"; @@ -879,7 +912,7 @@ guestfs_launch (guestfs_h *g) { const char *tmpdir; char dir_template[PATH_MAX]; - int r, i, pmore; + int r, pmore; size_t len; int wfd[2], rfd[2]; int tries; @@ -1046,15 +1079,19 @@ guestfs_launch (guestfs_h *g) "udevtimeout=300 " /* good for very slow systems (RHBZ#480319) */ \ "noapic " /* workaround for RHBZ#502058 - ok if not SMP */ \ "acpi=off " /* we don't need ACPI, turn it off */ \ - "cgroup_disable=memory " /* saves us about 5 MB of RAM */ \ - "selinux=0 " /* SELinux is messed up if there's no policy */ + "cgroup_disable=memory " /* saves us about 5 MB of RAM */ /* Linux kernel command line. */ snprintf (append, sizeof append, - LINUX_CMDLINE "guestfs=%s:%d%s%s%s", + LINUX_CMDLINE + "guestfs=%s:%d " + "%s" /* (selinux) */ + "%s" /* (verbose) */ + "%s", /* (append) */ VMCHANNEL_ADDR, VMCHANNEL_PORT, - g->verbose ? " guestfs_verbose=1" : "", - g->append ? " " : "", g->append ? g->append : ""); + g->selinux ? "selinux=1 enforcing=0 " : "selinux=0 ", + g->verbose ? "guestfs_verbose=1 " : " ", + g->append ? g->append : ""); snprintf (memsize_str, sizeof memsize_str, "%d", g->memsize); @@ -1103,7 +1140,7 @@ guestfs_launch (guestfs_h *g) } #endif add_cmdline (g, "-net"); - add_cmdline (g, "nic,model=virtio,vlan=0"); /* model=ne2k_pci also works */ + add_cmdline (g, "nic,model=" NET_IF ",vlan=0"); /* These options recommended by KVM developers to improve reliability. */ if (qemu_supports (g, "-no-hpet")) @@ -1116,12 +1153,8 @@ guestfs_launch (guestfs_h *g) incr_cmdline_size (g); g->cmdline[g->cmdline_size-1] = NULL; - if (g->verbose) { - fprintf (stderr, "%s", g->qemu); - for (i = 0; g->cmdline[i]; ++i) - fprintf (stderr, " %s", g->cmdline[i]); - fprintf (stderr, "\n"); - } + if (g->verbose) + print_cmdline (g); /* Set up stdin, stdout. */ close (0); @@ -1301,6 +1334,33 @@ guestfs_launch (guestfs_h *g) return -1; } +/* This function is used to print the qemu command line before it gets + * executed, when in verbose mode. + */ +static void +print_cmdline (guestfs_h *g) +{ + int i = 0; + int needs_quote; + + while (g->cmdline[i]) { + if (g->cmdline[i][0] == '-') /* -option starts a new line */ + fprintf (stderr, " \\\n "); + + if (i > 0) fputc (' ', stderr); + + /* Does it need shell quoting? This only deals with simple cases. */ + needs_quote = strcspn (g->cmdline[i], " ") != strlen (g->cmdline[i]); + + if (needs_quote) fputc ('\'', stderr); + fprintf (stderr, "%s", g->cmdline[i]); + if (needs_quote) fputc ('\'', stderr); + i++; + } + + fputc ('\n', stderr); +} + /* This function does the hard work of building the supermin appliance * on the fly. 'path' is the directory containing the control files. * 'kernel' and 'initrd' are where we will return the names of the