X-Git-Url: http://git.annexia.org/?p=libguestfs.git;a=blobdiff_plain;f=src%2Fguestfs.c;h=1cd4f9efcb9253312f4455e3aaf1c16f23170e3d;hp=9560aec02f1092cbf4f47d410ad961b037935cc9;hb=93ab20eb367b1c177a73620222afdf1f616dea1c;hpb=f0d6be10c2d7bbf49bfa1cdbcb99e356458aa60f diff --git a/src/guestfs.c b/src/guestfs.c index 9560aec..1cd4f9e 100644 --- a/src/guestfs.c +++ b/src/guestfs.c @@ -59,6 +59,7 @@ #include "guestfs.h" #include "guestfs_protocol.h" +#include "ignore-value.h" #ifdef HAVE_GETTEXT #include "gettext.h" @@ -177,6 +178,8 @@ struct guestfs_h int memsize; /* Size of RAM (megabytes). */ + int selinux; /* selinux enabled? */ + char *last_error; /* Callbacks. */ @@ -689,6 +692,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 +800,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); } @@ -1047,15 +1080,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); @@ -1125,11 +1162,18 @@ guestfs_launch (guestfs_h *g) close (1); close (wfd[1]); close (rfd[0]); - dup (wfd[0]); - dup (rfd[1]); + + int fail = 0; + fail |= dup (wfd[0]); + fail |= dup (rfd[1]); close (wfd[0]); close (rfd[1]); + if (fail) { + perror ("dup failed"); + _exit (1); + } + #if 0 /* Set up a new process group, so we can signal this process * and all subprocesses (eg. if qemu is really a shell script). @@ -1661,7 +1705,7 @@ stdout_event (struct guestfs_main_loop *ml, guestfs_h *g, void *data, /* In verbose mode, copy all log messages to stderr. */ if (g->verbose) - write (2, buf, n); + ignore_value (write (STDERR_FILENO, buf, n)); /* It's an actual log message, send it upwards if anyone is listening. */ if (g->log_message_cb)