#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;
};
if (g->state != CONFIG)
guestfs_kill_subprocess (g);
+ /* Close any sockets and deregister any handlers. */
+ if (g->stdout_watch >= 0)
+ g->main_loop->remove_handle (g->main_loop, g, g->stdout_watch);
+ if (g->sock_watch >= 0)
+ g->main_loop->remove_handle (g->main_loop, g, g->sock_watch);
+ g->stdout_watch = -1;
+ g->sock_watch = -1;
+
+ if (g->fd[0] >= 0)
+ close (g->fd[0]);
+ if (g->fd[1] >= 0)
+ close (g->fd[1]);
+ if (g->sock >= 0)
+ close (g->sock);
+ g->fd[0] = -1;
+ g->fd[1] = -1;
+ g->sock = -1;
+
+ /* Remove tmpfiles. */
if (g->tmpdir) {
snprintf (filename, sizeof filename, "%s/sock", g->tmpdir);
unlink (filename);
{
va_list args;
char *msg;
- int err = errno;
+ int errnum = errno;
va_start (args, fs);
- vasprintf (&msg, fs, args);
+ int err = vasprintf (&msg, fs, args);
va_end (args);
+ if (err < 0) return;
+
#ifndef _GNU_SOURCE
char buf[256];
- strerror_r (err, buf, sizeof buf);
+ strerror_r (errnum, buf, sizeof buf);
#else
char _buf[256];
char *buf;
- buf = strerror_r (err, _buf, sizeof _buf);
+ buf = strerror_r (errnum, _buf, sizeof _buf);
#endif
msg = safe_realloc (g, msg, strlen (msg) + 2 + strlen (buf) + 1);
}
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) {
r = read (fd, buf, len);
if (r == -1) {
if (errno == EINTR || errno == EAGAIN)
- continue;
+ continue;
return -1;
}
}
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)
}
}
+struct guestfs_version *
+guestfs_version (guestfs_h *g)
+{
+ struct guestfs_version *r;
+
+ r = safe_malloc (g, sizeof *r);
+ r->major = PACKAGE_VERSION_MAJOR;
+ r->minor = PACKAGE_VERSION_MINOR;
+ r->release = PACKAGE_VERSION_RELEASE;
+ r->extra = safe_strdup (g, PACKAGE_VERSION_EXTRA);
+ return r;
+}
+
/* Add a string to the current command line. */
static void
incr_cmdline_size (guestfs_h *g)
int
guestfs_config (guestfs_h *g,
- const char *qemu_param, const char *qemu_value)
+ const char *qemu_param, const char *qemu_value)
{
if (qemu_param[0] != '-') {
error (g, _("guestfs_config: parameter must begin with '-' character"));
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";
int
guestfs_launch (guestfs_h *g)
{
- static const char *dir_template = "/tmp/libguestfsXXXXXX";
- int r, i, pmore;
+ const char *tmpdir;
+ char dir_template[PATH_MAX];
+ int r, pmore;
size_t len;
int wfd[2], rfd[2];
int tries;
char unixsock[256];
struct sockaddr_un addr;
+#ifdef P_tmpdir
+ tmpdir = P_tmpdir;
+#else
+ tmpdir = "/tmp";
+#endif
+
+ tmpdir = getenv ("TMPDIR") ? : tmpdir;
+ snprintf (dir_template, sizeof dir_template, "%s/libguestfsXXXXXX", tmpdir);
+
/* Configured? */
if (!g->cmdline) {
error (g, _("you must call guestfs_add_drive before guestfs_launch"));
/* Empty element of "." means cwd. */
if (len == 0 || (len == 1 && *pelem == '.')) {
if (g->verbose)
- fprintf (stderr,
- "looking for supermin appliance in current directory\n");
+ fprintf (stderr,
+ "looking for supermin appliance in current directory\n");
if (dir_contains_files (".",
- supermin_name, supermin_hostfiles_name,
- "kmod.whitelist", NULL)) {
- if (build_supermin_appliance (g, ".", &kernel, &initrd) == -1)
- return -1;
- break;
+ supermin_name, supermin_hostfiles_name,
+ "kmod.whitelist", NULL)) {
+ if (build_supermin_appliance (g, ".", &kernel, &initrd) == -1)
+ return -1;
+ break;
}
}
/* Look at <path>/supermin* etc. */
else {
if (g->verbose)
- fprintf (stderr, "looking for supermin appliance in %s\n", pelem);
+ fprintf (stderr, "looking for supermin appliance in %s\n", pelem);
if (dir_contains_files (pelem,
- supermin_name, supermin_hostfiles_name,
- "kmod.whitelist", NULL)) {
- if (build_supermin_appliance (g, pelem, &kernel, &initrd) == -1)
- return -1;
- break;
+ supermin_name, supermin_hostfiles_name,
+ "kmod.whitelist", NULL)) {
+ if (build_supermin_appliance (g, pelem, &kernel, &initrd) == -1)
+ return -1;
+ break;
}
}
/* Empty element or "." means cwd. */
if (len == 0 || (len == 1 && *pelem == '.')) {
- if (g->verbose)
- fprintf (stderr,
- "looking for appliance in current directory\n");
- if (dir_contains_files (".", kernel_name, initrd_name, NULL)) {
- kernel = safe_strdup (g, kernel_name);
- initrd = safe_strdup (g, initrd_name);
- break;
- }
+ if (g->verbose)
+ fprintf (stderr,
+ "looking for appliance in current directory\n");
+ if (dir_contains_files (".", kernel_name, initrd_name, NULL)) {
+ kernel = safe_strdup (g, kernel_name);
+ initrd = safe_strdup (g, initrd_name);
+ break;
+ }
}
/* Look at <path>/kernel etc. */
else {
- if (g->verbose)
- fprintf (stderr, "looking for appliance in %s\n", pelem);
-
- if (dir_contains_files (pelem, kernel_name, initrd_name, NULL)) {
- kernel = safe_malloc (g, len + strlen (kernel_name) + 2);
- initrd = safe_malloc (g, len + strlen (initrd_name) + 2);
- sprintf (kernel, "%s/%s", pelem, kernel_name);
- sprintf (initrd, "%s/%s", pelem, initrd_name);
- break;
- }
+ if (g->verbose)
+ fprintf (stderr, "looking for appliance in %s\n", pelem);
+
+ if (dir_contains_files (pelem, kernel_name, initrd_name, NULL)) {
+ kernel = safe_malloc (g, len + strlen (kernel_name) + 2);
+ initrd = safe_malloc (g, len + strlen (initrd_name) + 2);
+ sprintf (kernel, "%s/%s", pelem, kernel_name);
+ sprintf (initrd, "%s/%s", pelem, initrd_name);
+ break;
+ }
}
pelem = pend + 1;
if (kernel == NULL || initrd == NULL) {
error (g, _("cannot find %s or %s on LIBGUESTFS_PATH (current path = %s)"),
- kernel_name, initrd_name, g->path);
+ kernel_name, initrd_name, g->path);
goto cleanup0;
}
*/
g->cmdline[0] = g->qemu;
- /* Construct the -net channel parameter for qemu. */
- snprintf (vmchannel, sizeof vmchannel,
- "channel,%d:unix:%s,server,nowait",
- VMCHANNEL_PORT, unixsock);
+#define LINUX_CMDLINE \
+ "panic=1 " /* force kernel to panic if daemon exits */ \
+ "console=ttyS0 " /* serial console */ \
+ "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 */
/* Linux kernel command line. */
snprintf (append, sizeof append,
- "panic=1 console=ttyS0 guestfs=%s:%d%s%s%s",
- VMCHANNEL_ADDR, VMCHANNEL_PORT,
- g->verbose ? " guestfs_verbose=1" : "",
- g->append ? " " : "", g->append ? g->append : "");
+ LINUX_CMDLINE
+ "guestfs=%s:%d "
+ "%s" /* (selinux) */
+ "%s" /* (verbose) */
+ "%s", /* (append) */
+ VMCHANNEL_ADDR, VMCHANNEL_PORT,
+ 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);
add_cmdline (g, "-nographic");
add_cmdline (g, "-serial");
add_cmdline (g, "stdio");
+
+#if 0
+ /* Doesn't work. See:
+ * http://lists.gnu.org/archive/html/qemu-devel/2009-07/threads.html
+ * Subject "guestfwd option doesn't allow supplementary ,server,nowait"
+ */
+ if (qemu_supports (g, "guestfwd")) {
+ /* New-style -net user,guestfwd=... syntax for vmchannel. See:
+ * http://git.savannah.gnu.org/cgit/qemu.git/commit/?id=c92ef6a22d3c71538fcc48fb61ad353f7ba03b62
+ */
+ snprintf (vmchannel, sizeof vmchannel,
+ "user,vlan=0,net=10.0.2.0/8,guestfwd=tcp:%s:%d-unix:%s,server,nowait",
+ VMCHANNEL_ADDR, VMCHANNEL_PORT, unixsock);
+
+ add_cmdline (g, "-net");
+ add_cmdline (g, vmchannel);
+ } else {
+#endif
+ /* Not guestfwd. HOPEFULLY this qemu uses the older -net channel
+ * syntax, or if not then we'll get a quick failure.
+ */
+ snprintf (vmchannel, sizeof vmchannel,
+ "channel,%d:unix:%s,server,nowait",
+ VMCHANNEL_PORT, unixsock);
+
+ add_cmdline (g, "-net");
+ add_cmdline (g, vmchannel);
+ add_cmdline (g, "-net");
+ add_cmdline (g, "user,vlan=0,net=10.0.2.0/8");
+#if 0
+ }
+#endif
add_cmdline (g, "-net");
- add_cmdline (g, vmchannel);
- add_cmdline (g, "-net");
- add_cmdline (g, "user,vlan=0");
- add_cmdline (g, "-net");
- add_cmdline (g, "nic,model=virtio,vlan=0");
+ 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]);
*/
for (;;) {
if (kill (qemu_pid, 0) == -1) /* qemu's gone away, we aren't needed */
- _exit (0);
+ _exit (0);
if (kill (parent_pid, 0) == -1) {
- /* Parent's gone away, qemu still around, so kill qemu. */
- kill (qemu_pid, 9);
- _exit (0);
+ /* Parent's gone away, qemu still around, so kill qemu. */
+ kill (qemu_pid, 9);
+ _exit (0);
}
sleep (2);
}
g->stdout_watch =
g->main_loop->add_handle (g->main_loop, g, g->fd[1],
- GUESTFS_HANDLE_READABLE,
- stdout_event, NULL);
+ GUESTFS_HANDLE_READABLE,
+ stdout_event, NULL);
if (g->stdout_watch == -1) {
error (g, _("could not watch qemu stdout"));
goto cleanup3;
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
*/
static int
build_supermin_appliance (guestfs_h *g, const char *path,
- char **kernel, char **initrd)
+ char **kernel, char **initrd)
{
char cmd[4096];
int r, len;
snprintf (*initrd, len+8, "%s/initrd", g->tmpdir);
snprintf (cmd, sizeof cmd,
- "PATH='%s':$PATH "
- "libguestfs-supermin-helper '%s' %s %s",
- path,
- path, *kernel, *initrd);
+ "PATH='%s':$PATH "
+ "libguestfs-supermin-helper '%s' %s %s",
+ path,
+ path, *kernel, *initrd);
r = system (cmd);
if (r == -1 || WEXITSTATUS(r) != 0) {
{
if (g->state != BUSY) {
error (g, _("guestfs_set_ready: called when in state %d != BUSY"),
- g->state);
+ g->state);
return -1;
}
g->state = READY;
{
if (g->state != READY) {
error (g, _("guestfs_set_busy: called when in state %d != READY"),
- g->state);
+ g->state);
return -1;
}
g->state = BUSY;
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;
}
return 0;
}
-/* Structure-freeing functions. These rely on the fact that the
- * structure format is identical to the XDR format. See note in
- * generator.ml.
- */
-void
-guestfs_free_int_bool (struct guestfs_int_bool *x)
-{
- free (x);
-}
-
-void
-guestfs_free_lvm_pv_list (struct guestfs_lvm_pv_list *x)
-{
- xdr_free ((xdrproc_t) xdr_guestfs_lvm_int_pv_list, (char *) x);
- free (x);
-}
-
-void
-guestfs_free_lvm_vg_list (struct guestfs_lvm_vg_list *x)
-{
- xdr_free ((xdrproc_t) xdr_guestfs_lvm_int_vg_list, (char *) x);
- free (x);
-}
-
-void
-guestfs_free_lvm_lv_list (struct guestfs_lvm_lv_list *x)
-{
- xdr_free ((xdrproc_t) xdr_guestfs_lvm_int_lv_list, (char *) x);
- free (x);
-}
-
-void
-guestfs_free_dirent_list (struct guestfs_dirent_list *x)
-{
- xdr_free ((xdrproc_t) xdr_guestfs_int_dirent_list, (char *) x);
- free (x);
-}
-
/* We don't know if stdout_event or sock_read_event will be the
* first to receive EOF if the qemu process dies. This function
* has the common cleanup code for both.
*/
static void
stdout_event (struct guestfs_main_loop *ml, guestfs_h *g, void *data,
- int watch, int fd, int events)
+ int watch, int fd, int events)
{
char buf[4096];
int n;
#if 0
if (g->verbose)
fprintf (stderr,
- "stdout_event: %p g->state = %d, fd = %d, events = 0x%x\n",
- g, g->state, fd, events);
+ "stdout_event: %p g->state = %d, fd = %d, events = 0x%x\n",
+ g, g->state, fd, events);
#endif
if (g->fd[1] != fd) {
/* 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)
*/
static void
sock_read_event (struct guestfs_main_loop *ml, guestfs_h *g, void *data,
- int watch, int fd, int events)
+ int watch, int fd, int events)
{
XDR xdr;
u_int32_t len;
if (g->verbose)
fprintf (stderr,
- "sock_read_event: %p g->state = %d, fd = %d, events = 0x%x\n",
- g, g->state, fd, events);
+ "sock_read_event: %p g->state = %d, fd = %d, events = 0x%x\n",
+ g, g->state, fd, events);
if (g->sock != fd) {
error (g, _("sock_read_event: internal error: %d != %d"), g->sock, fd);
g->msg_in = safe_realloc (g, g->msg_in, g->msg_in_allocated);
}
n = read (g->sock, g->msg_in + g->msg_in_size,
- g->msg_in_allocated - g->msg_in_size);
+ g->msg_in_allocated - g->msg_in_size);
if (n == 0) {
/* Disconnected. */
child_cleanup (g);
if (len == GUESTFS_LAUNCH_FLAG) {
if (g->state != LAUNCHING)
error (g, _("received magic signature from guestfsd, but in state %d"),
- g->state);
+ g->state);
else if (g->msg_in_size != 4)
error (g, _("received magic signature from guestfsd, but msg size is %d"),
- g->msg_in_size);
+ g->msg_in_size);
else {
g->state = READY;
if (g->launch_done_cb)
- g->launch_done_cb (g, g->launch_done_cb_data);
+ g->launch_done_cb (g, g->launch_done_cb_data);
}
goto cleanup;
*/
if (len > GUESTFS_MESSAGE_MAX) {
error (g, _("message length (%u) > maximum possible size (%d)"),
- len, GUESTFS_MESSAGE_MAX);
+ len, GUESTFS_MESSAGE_MAX);
goto cleanup;
}
for (i = 0; i < g->msg_in_size; i += 16) {
printf ("%04x: ", i);
for (j = i; j < MIN (i+16, g->msg_in_size); ++j)
- printf ("%02x ", (unsigned char) g->msg_in[j]);
+ printf ("%02x ", (unsigned char) g->msg_in[j]);
for (; j < i+16; ++j)
- printf (" ");
+ printf (" ");
printf ("|");
for (j = i; j < MIN (i+16, g->msg_in_size); ++j)
- if (isprint (g->msg_in[j]))
- printf ("%c", g->msg_in[j]);
- else
- printf (".");
+ if (isprint (g->msg_in[j]))
+ printf ("%c", g->msg_in[j]);
+ else
+ printf (".");
for (; j < i+16; ++j)
- printf (" ");
+ printf (" ");
printf ("|\n");
}
}
*/
static void
sock_write_event (struct guestfs_main_loop *ml, guestfs_h *g, void *data,
- int watch, int fd, int events)
+ int watch, int fd, int events)
{
int n, err;
if (g->verbose)
fprintf (stderr,
- "sock_write_event: %p g->state = %d, fd = %d, events = 0x%x\n",
- g, g->state, fd, events);
+ "sock_write_event: %p g->state = %d, fd = %d, events = 0x%x\n",
+ g, g->state, fd, events);
if (g->sock != fd) {
error (g, _("sock_write_event: internal error: %d != %d"), g->sock, fd);
if (g->verbose)
fprintf (stderr, "sock_write_event: writing %d bytes ...\n",
- g->msg_out_size - g->msg_out_pos);
+ g->msg_out_size - g->msg_out_pos);
n = write (g->sock, g->msg_out + g->msg_out_pos,
- g->msg_out_size - g->msg_out_pos);
+ g->msg_out_size - g->msg_out_pos);
if (n == -1) {
err = errno;
if (err != EAGAIN)
void
guestfs_set_send_callback (guestfs_h *g,
- guestfs_send_cb cb, void *opaque)
+ guestfs_send_cb cb, void *opaque)
{
g->send_cb = cb;
g->send_cb_data = opaque;
void
guestfs_set_reply_callback (guestfs_h *g,
- guestfs_reply_cb cb, void *opaque)
+ guestfs_reply_cb cb, void *opaque)
{
g->reply_cb = cb;
g->reply_cb_data = opaque;
void
guestfs_set_log_message_callback (guestfs_h *g,
- guestfs_log_message_cb cb, void *opaque)
+ guestfs_log_message_cb cb, void *opaque)
{
g->log_message_cb = cb;
g->log_message_cb_data = opaque;
void
guestfs_set_subprocess_quit_callback (guestfs_h *g,
- guestfs_subprocess_quit_cb cb, void *opaque)
+ guestfs_subprocess_quit_cb cb, void *opaque)
{
g->subprocess_quit_cb = cb;
g->subprocess_quit_cb_data = opaque;
void
guestfs_set_launch_done_callback (guestfs_h *g,
- guestfs_launch_done_cb cb, void *opaque)
+ guestfs_launch_done_cb cb, void *opaque)
{
g->launch_done_cb = cb;
g->launch_done_cb_data = opaque;
g->sock_watch =
g->main_loop->add_handle (g->main_loop, g, g->sock,
- GUESTFS_HANDLE_WRITABLE,
- sock_write_event, NULL);
+ GUESTFS_HANDLE_WRITABLE,
+ sock_write_event, NULL);
if (g->sock_watch == -1) {
error (g, _("add_handle failed"));
return -1;
g->sock_watch =
g->main_loop->add_handle (g->main_loop, g, g->sock,
- GUESTFS_HANDLE_READABLE,
- sock_read_event, NULL);
+ GUESTFS_HANDLE_READABLE,
+ sock_read_event, NULL);
if (g->sock_watch == -1) {
error (g, _("add_handle failed"));
return -1;
int
guestfs__send_sync (guestfs_h *g, int proc_nr,
- xdrproc_t xdrp, char *args)
+ xdrproc_t xdrp, char *args)
{
struct guestfs_message_header hdr;
XDR xdr;
err = send_file_data_sync (g, buf, r);
if (err < 0) {
if (err == -2) /* daemon sent cancellation */
- send_file_cancellation_sync (g);
+ send_file_cancellation_sync (g);
return err;
}
}
if (!xdr_guestfs_chunk (&xdr, &chunk)) {
error (g, _("xdr_guestfs_chunk failed (buf = %p, buflen = %zu)"),
- buf, buflen);
+ buf, buflen);
xdr_destroy (&xdr);
goto cleanup1;
}
if (flag != GUESTFS_CANCEL_FLAG) {
error (g, _("check_for_daemon_cancellation: read 0x%x from daemon, expected 0x%x\n"),
- flag, GUESTFS_CANCEL_FLAG);
+ flag, GUESTFS_CANCEL_FLAG);
return 0;
}
char fbuf[4];
uint32_t flag = GUESTFS_CANCEL_FLAG;
+ if (g->verbose)
+ fprintf (stderr, "%s: waiting for daemon to acknowledge cancellation\n",
+ __func__);
+
xdrmem_create (&xdr, fbuf, sizeof fbuf, XDR_ENCODE);
xdr_uint32_t (&xdr, &flag);
xdr_destroy (&xdr);
*/
struct receive_file_ctx {
int count; /* 0 if receive_file_cb not called, or
- * else count number of chunks.
- */
+ * else count number of chunks.
+ */
guestfs_chunk *chunks; /* Array of chunks. */
};
/* Copy the chunk to the list. */
ctx->chunks = safe_realloc (g, ctx->chunks,
- sizeof (guestfs_chunk) * (ctx->count+1));
+ sizeof (guestfs_chunk) * (ctx->count+1));
ctx->chunks[ctx->count] = chunk;
ctx->count++;
}
if (buf) {
*buf = safe_realloc (g, *buf, len + ctx.chunks[i].data.data_len);
- memcpy (*buf+len, ctx.chunks[i].data.data_val,
- ctx.chunks[i].data.data_len);
+ 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
select_add_handle (guestfs_main_loop *mlv, guestfs_h *g, int fd, int events,
- guestfs_handle_event_cb cb, void *data)
+ guestfs_handle_event_cb cb, void *data)
{
struct select_main_loop *ml = (struct select_main_loop *) mlv;
}
if ((events & ~(GUESTFS_HANDLE_READABLE |
- GUESTFS_HANDLE_WRITABLE |
- GUESTFS_HANDLE_HANGUP |
- GUESTFS_HANDLE_ERROR)) != 0) {
+ GUESTFS_HANDLE_WRITABLE |
+ GUESTFS_HANDLE_HANGUP |
+ GUESTFS_HANDLE_ERROR)) != 0) {
error (g, _("set of events (0x%x) contains unknown events"), events);
return -1;
}
ml->max_fd = fd;
ml->handle_cb_data =
safe_realloc (g, ml->handle_cb_data,
- sizeof (struct select_handle_cb_data) * (ml->max_fd+1));
+ sizeof (struct select_handle_cb_data) * (ml->max_fd+1));
}
ml->handle_cb_data[fd].cb = cb;
ml->handle_cb_data[fd].g = g;
ml->max_fd--;
ml->handle_cb_data =
safe_realloc (g, ml->handle_cb_data,
- sizeof (struct select_handle_cb_data) * (ml->max_fd+1));
+ sizeof (struct select_handle_cb_data) * (ml->max_fd+1));
}
ml->nr_fds--;
}
static int
+__attribute__((noreturn))
select_add_timeout (guestfs_main_loop *mlv, guestfs_h *g, int interval,
- guestfs_handle_timeout_cb cb, void *data)
+ guestfs_handle_timeout_cb cb, void *data)
{
//struct select_main_loop *ml = (struct select_main_loop *) mlv;
}
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;
r = select (ml->max_fd+1, &rset2, &wset2, &xset2, NULL);
if (r == -1) {
if (errno == EINTR || errno == EAGAIN)
- continue;
+ continue;
perrorf (g, "select");
ml->is_running = 0;
return -1;
for (fd = 0; r > 0 && fd <= ml->max_fd; ++fd) {
events = 0;
if (FD_ISSET (fd, &rset2))
- events |= GUESTFS_HANDLE_READABLE;
+ events |= GUESTFS_HANDLE_READABLE;
if (FD_ISSET (fd, &wset2))
- events |= GUESTFS_HANDLE_WRITABLE;
+ events |= GUESTFS_HANDLE_WRITABLE;
if (FD_ISSET (fd, &xset2))
- events |= GUESTFS_HANDLE_ERROR | GUESTFS_HANDLE_HANGUP;
+ events |= GUESTFS_HANDLE_ERROR | GUESTFS_HANDLE_HANGUP;
if (events) {
- r--;
- ml->handle_cb_data[fd].cb ((guestfs_main_loop *) ml,
- ml->handle_cb_data[fd].g,
- ml->handle_cb_data[fd].data,
- fd, fd, events);
+ r--;
+ ml->handle_cb_data[fd].cb ((guestfs_main_loop *) ml,
+ ml->handle_cb_data[fd].g,
+ ml->handle_cb_data[fd].data,
+ fd, fd, events);
}
}
}