X-Git-Url: http://git.annexia.org/?p=libguestfs.git;a=blobdiff_plain;f=daemon%2Fguestfsd.c;h=eacbc1dd870c1f79b44ab02c209c2ac887803f8d;hp=a8b53e730f781e5990d4a272472272ae381a9dec;hb=9ba779ea367b2ea7077da7bdd75e813cd06c7eea;hpb=7eb012f3710bb554d5fc2c4229036901b0b5ad90 diff --git a/daemon/guestfsd.c b/daemon/guestfsd.c index a8b53e7..eacbc1d 100644 --- a/daemon/guestfsd.c +++ b/daemon/guestfsd.c @@ -1,5 +1,5 @@ /* libguestfs - the guestfsd daemon - * Copyright (C) 2009-2010 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 @@ -13,13 +13,11 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include -#define _BSD_SOURCE /* for daemon(3) */ - #ifdef HAVE_WINDOWS_H # include #endif @@ -87,17 +85,6 @@ static int print_arginfo (const struct printf_info *info, size_t n, int *argtype #ifdef WIN32 static int -daemon (int nochdir, int noclose) -{ - fprintf (stderr, - "On Windows the daemon does not support forking into the " - "background.\nYou *must* run the daemon with the -f option.\n"); - exit (EXIT_FAILURE); -} -#endif /* WIN32 */ - -#ifdef WIN32 -static int winsock_init (void) { int r; @@ -116,33 +103,37 @@ winsock_init (void) /* Location to mount root device. */ const char *sysroot = "/sysroot"; /* No trailing slash. */ -int sysroot_len = 8; +size_t sysroot_len = 8; + +/* If set (the default), do 'umount-all' when performing autosync. */ +int autosync_umount = 1; /* Not used explicitly, but required by the gnulib 'error' module. */ const char *program_name = "guestfsd"; +/* Name of the virtio-serial channel. */ +#define VIRTIO_SERIAL_CHANNEL "/dev/virtio-ports/org.libguestfs.channel.0" + static void usage (void) { fprintf (stderr, - "guestfsd [-f|--foreground] [-v|--verbose]\n"); + "guestfsd [-r] [-v|--verbose]\n"); } int main (int argc, char *argv[]) { - static const char *options = "fv?"; + static const char *options = "rv?"; static const struct option long_options[] = { - { "foreground", 0, 0, 'f' }, { "help", 0, 0, '?' }, { "verbose", 0, 0, 'v' }, { 0, 0, 0, 0 } }; int c; - int dont_fork = 0; char *cmdline; - chdir ("/"); + ignore_value (chdir ("/")); if (winsock_init () == -1) error (EXIT_FAILURE, 0, "winsock initialization failed"); @@ -169,8 +160,13 @@ main (int argc, char *argv[]) if (c == -1) break; switch (c) { - case 'f': - dont_fork = 1; + /* The -r flag is used when running standalone. It changes + * several aspects of the daemon. + */ + case 'r': + sysroot = ""; + sysroot_len = 0; + autosync_umount = 0; break; case 'v': @@ -243,9 +239,13 @@ main (int argc, char *argv[]) _umask (0); #endif + /* Make a private copy of /etc/lvm so we can change the config (see + * daemon/lvm-filter.c). + */ + copy_lvm (); + /* Connect to virtio-serial channel. */ - int sock = open ("/dev/virtio-ports/org.libguestfs.channel.0", - O_RDWR | O_CLOEXEC); + int sock = open (VIRTIO_SERIAL_CHANNEL, O_RDWR | O_CLOEXEC); if (sock == -1) { fprintf (stderr, "\n" @@ -260,7 +260,7 @@ main (int argc, char *argv[]) "output to the libguestfs developers, either in a bug report\n" "or on the libguestfs redhat com mailing list.\n" "\n"); - perror ("/dev/virtio-ports/org.libguestfs.channel.0"); + perror (VIRTIO_SERIAL_CHANNEL); exit (EXIT_FAILURE); } @@ -280,14 +280,6 @@ main (int argc, char *argv[]) xdr_destroy (&xdr); - /* Fork into the background. */ - if (!dont_fork) { - if (daemon (0, 1) == -1) { - perror ("daemon"); - exit (EXIT_FAILURE); - } - } - /* Enter the main loop, reading and performing actions. */ main_loop (sock); @@ -444,6 +436,7 @@ add_string (char ***argv, int *size, int *alloc, const char *str) if (new_str == NULL) { reply_with_perror ("strdup"); free_strings (*argv); + return -1; } } else new_str = NULL; @@ -694,6 +687,8 @@ commandrvf (char **stdoutput, char **stderror, int flags, } if (pid == 0) { /* Child process running the command. */ + signal (SIGALRM, SIG_DFL); + signal (SIGPIPE, SIG_DFL); close (0); if (flag_copy_stdin) { dup2 (stdin_fd[0], 0); @@ -701,7 +696,7 @@ commandrvf (char **stdoutput, char **stderror, int flags, close (stdin_fd[1]); } else { /* Set stdin to /dev/null (ignore failure) */ - open ("/dev/null", O_RDONLY); + ignore_value (open ("/dev/null", O_RDONLY)); } close (so_fd[0]); close (se_fd[0]); @@ -782,13 +777,29 @@ commandrvf (char **stdoutput, char **stderror, int flags, quit = 0; while (quit < 2) { + again: rset2 = rset; r = select (MAX (so_fd[0], se_fd[0]) + 1, &rset2, NULL, NULL, NULL); if (r == -1) { + if (errno == EINTR) + goto again; + perror ("select"); quit: - if (stdoutput) free (*stdoutput); - if (stderror) free (*stderror); + if (stdoutput) { + free (*stdoutput); + *stdoutput = NULL; + } + if (stderror) { + free (*stderror); + /* Need to return non-NULL *stderror here since most callers + * will try to print and then free the err string. + * Unfortunately recovery from strdup failure here is not + * possible. + */ + *stderror = strdup ("error running external command, " + "see debug output for details"); + } close (so_fd[0]); close (se_fd[0]); waitpid (pid, NULL, 0);