X-Git-Url: http://git.annexia.org/?p=libguestfs.git;a=blobdiff_plain;f=daemon%2Fdaemon.h;h=b4f99a81a1d8a4a94cca1b778aa1d7465d61e55f;hp=6845e1b306c175cc84a146f86b0eacee2f050169;hb=ffc01285ee4289da90983a3320873f27b3d31c4d;hpb=d2400da92e5e2cc7fd5e33e61220a33214d5241c diff --git a/daemon/daemon.h b/daemon/daemon.h index 6845e1b..b4f99a8 100644 --- a/daemon/daemon.h +++ b/daemon/daemon.h @@ -1,5 +1,5 @@ /* libguestfs - the guestfsd daemon - * Copyright (C) 2009 Red Hat Inc. + * Copyright (C) 2009-2011 Red Hat Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -33,8 +33,10 @@ /*-- in guestfsd.c --*/ extern int verbose; +extern int autosync_umount; + extern const char *sysroot; -extern int sysroot_len; +extern size_t sysroot_len; extern char *sysroot_path (const char *path); @@ -107,7 +109,7 @@ extern uint64_t progress_hint; extern uint64_t optargs_bitmask; /*-- in mount.c --*/ -extern int root_mounted; +extern int is_root_mounted (void); /*-- in stubs.c (auto-generated) --*/ extern void dispatch_incoming_message (XDR *); @@ -126,6 +128,9 @@ extern struct optgroup optgroups[]; /* Use this as a replacement for sync(2). */ extern int sync_disks (void); +/*-- in ext2.c --*/ +extern int e2prog (char *name); /* Massive hack for RHEL 5. */ + /*-- in lvm.c --*/ extern int lv_canonical (const char *device, char **ret); @@ -150,10 +155,6 @@ extern int receive_file (receive_cb cb, void *opaque); /* daemon functions that receive files (FileIn) can call this * to cancel incoming transfers (eg. if there is a local error). - * - * If and only if this function does NOT return -2, they MUST then - * call reply_with_* - * (see https://bugzilla.redhat.com/show_bug.cgi?id=576879#c5). */ extern int cancel_receive (void); @@ -173,14 +174,49 @@ extern void reply (xdrproc_t xdrp, char *ret); */ extern void notify_progress (uint64_t position, uint64_t total); +/* Pulse mode progress messages. + * + * Call pulse_mode_start to start sending progress messages. + * + * Call pulse_mode_end along the ordinary exit path (ie. before a + * reply message is sent). + * + * Call pulse_mode_cancel along all error paths *before* any reply is + * sent. pulse_mode_cancel does not modify errno, so it is safe to + * call it before reply_with_perror. + * + * Pulse mode and ordinary notify_progress must not be mixed. + */ +extern void pulse_mode_start (void); +extern void pulse_mode_end (void); +extern void pulse_mode_cancel (void); + +/* Return true iff the buffer is all zero bytes. + * + * Note that gcc is smart enough to optimize this properly: + * http://stackoverflow.com/questions/1493936/faster-means-of-checking-for-an-empty-buffer-in-c/1493989#1493989 + */ +static inline int +is_zero (const char *buffer, size_t size) +{ + size_t i; + + for (i = 0; i < size; ++i) { + if (buffer[i] != 0) + return 0; + } + + return 1; +} + /* Helper for functions that need a root filesystem mounted. * NB. Cannot be used for FileIn functions. */ #define NEED_ROOT(cancel_stmt,fail_stmt) \ do { \ - if (!root_mounted) { \ - if ((cancel_stmt) != -2) \ - reply_with_error ("%s: you must call 'mount' first to mount the root filesystem", __func__); \ + if (!is_root_mounted ()) { \ + cancel_stmt; \ + reply_with_error ("%s: you must call 'mount' first to mount the root filesystem", __func__); \ fail_stmt; \ } \ } \ @@ -192,8 +228,8 @@ extern void notify_progress (uint64_t position, uint64_t total); #define ABS_PATH(path,cancel_stmt,fail_stmt) \ do { \ if ((path)[0] != '/') { \ - if ((cancel_stmt) != -2) \ - reply_with_error ("%s: path must start with a / character", __func__); \ + cancel_stmt; \ + reply_with_error ("%s: path must start with a / character", __func__); \ fail_stmt; \ } \ } while (0) @@ -208,18 +244,17 @@ extern void notify_progress (uint64_t position, uint64_t total); #define RESOLVE_DEVICE(path,cancel_stmt,fail_stmt) \ do { \ if (STRNEQLEN ((path), "/dev/", 5)) { \ - if ((cancel_stmt) != -2) \ - reply_with_error ("%s: %s: expecting a device name", __func__, (path)); \ + cancel_stmt; \ + reply_with_error ("%s: %s: expecting a device name", __func__, (path)); \ fail_stmt; \ } \ if (is_root_device (path)) \ reply_with_error ("%s: %s: device not found", __func__, path); \ if (device_name_translation ((path)) == -1) { \ int err = errno; \ - int r = cancel_stmt; \ + cancel_stmt; \ errno = err; \ - if (r != -2) \ - reply_with_perror ("%s: %s", __func__, path); \ + reply_with_perror ("%s: %s", __func__, path); \ fail_stmt; \ } \ } while (0) @@ -253,17 +288,21 @@ extern void notify_progress (uint64_t position, uint64_t total); */ #define CHROOT_IN \ do { \ - int __old_errno = errno; \ - if (chroot (sysroot) == -1) \ - perror ("CHROOT_IN: sysroot"); \ - errno = __old_errno; \ + if (sysroot_len > 0) { \ + int __old_errno = errno; \ + if (chroot (sysroot) == -1) \ + perror ("CHROOT_IN: sysroot"); \ + errno = __old_errno; \ + } \ } while (0) #define CHROOT_OUT \ do { \ - int __old_errno = errno; \ - if (chroot (".") == -1) \ - perror ("CHROOT_OUT: ."); \ - errno = __old_errno; \ + if (sysroot_len > 0) { \ + int __old_errno = errno; \ + if (chroot (".") == -1) \ + perror ("CHROOT_OUT: ."); \ + errno = __old_errno; \ + } \ } while (0) /* Marks functions which are not implemented.