#include "guestfs.h"
#include "guestfs_protocol.h"
+#include "ignore-value.h"
#ifdef HAVE_GETTEXT
#include "gettext.h"
#define _(str) dgettext(PACKAGE, (str))
-#define N_(str) dgettext(PACKAGE, (str))
+//#define N_(str) dgettext(PACKAGE, (str))
#else
#define _(str) str
-#define N_(str) str
+//#define N_(str) str
#endif
#define error guestfs_error
#define safe_malloc guestfs_safe_malloc
#define safe_realloc guestfs_safe_realloc
#define safe_strdup guestfs_safe_strdup
-#define safe_memdup guestfs_safe_memdup
+//#define safe_memdup guestfs_safe_memdup
static void default_error_cb (guestfs_h *g, void *data, const char *msg);
static void stdout_event (struct guestfs_main_loop *ml, guestfs_h *g, void *data, int watch, int fd, int events);
int memsize; /* Size of RAM (megabytes). */
+ int selinux; /* selinux enabled? */
+
char *last_error;
/* Callbacks. */
/* Messages sent and received from the daemon. */
char *msg_in;
- int msg_in_size, msg_in_allocated;
+ unsigned int msg_in_size, msg_in_allocated;
char *msg_out;
- int msg_out_size, msg_out_pos;
+ unsigned int msg_out_size, msg_out_pos;
int msg_next_serial;
};
}
static int
-xwrite (int fd, const void *buf, size_t len)
+xwrite (int fd, const void *v_buf, size_t len)
{
+ const char *buf = v_buf;
int r;
while (len > 0) {
}
static int
-xread (int fd, void *buf, size_t len)
+xread (int fd, void *v_buf, size_t len)
{
+ char *buf = v_buf;
int r;
while (len > 0) {
}
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)
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);
}
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";
{
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;
"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);
}
#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"))
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);
close (1);
close (wfd[1]);
close (rfd[0]);
- dup (wfd[0]);
- dup (rfd[1]);
+
+ if (dup (wfd[0]) == -1) {
+ dup_failed:
+ perror ("dup failed");
+ _exit (1);
+ }
+ if (dup (rfd[1]) == -1)
+ goto dup_failed;
+
close (wfd[0]);
close (rfd[1]);
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
case CONFIG:
case READY:
break;
+
case LAUNCHING:
case NO_HANDLE:
+ default:
error (g, _("guestfs_end_busy: called when in state %d"), g->state);
return -1;
}
/* 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)
if (buf) {
*buf = safe_realloc (g, *buf, len + ctx.chunks[i].data.data_len);
- memcpy (*buf+len, ctx.chunks[i].data.data_val,
+ memcpy (((char *)*buf)+len, ctx.chunks[i].data.data_val,
ctx.chunks[i].data.data_len);
}
len += ctx.chunks[i].data.data_len;
}
static int
+__attribute__((noreturn))
select_add_timeout (guestfs_main_loop *mlv, guestfs_h *g, int interval,
guestfs_handle_timeout_cb cb, void *data)
{
}
static int
+__attribute__((noreturn))
select_remove_timeout (guestfs_main_loop *mlv, guestfs_h *g, int timer)
{
//struct select_main_loop *ml = (struct select_main_loop *) mlv;