X-Git-Url: http://git.annexia.org/?p=libguestfs.git;a=blobdiff_plain;f=daemon%2Fguestfsd.c;h=38cfd1a1873a4fb90adec805b98916ede9d9eb37;hp=36328893c9ce38f65d69923b31e795d328edd8cb;hb=HEAD;hpb=42938f6faf9e724130be28f8e67d3c291bb81cba diff --git a/daemon/guestfsd.c b/daemon/guestfsd.c index 3632889..38cfd1a 100644 --- a/daemon/guestfsd.c +++ b/daemon/guestfsd.c @@ -13,7 +13,7 @@ * * 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 @@ -103,7 +103,7 @@ 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; @@ -111,6 +111,9 @@ 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) { @@ -236,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" @@ -253,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); } @@ -408,10 +415,9 @@ xread (int sock, void *v_buf, size_t len) } int -add_string (char ***argv, int *size, int *alloc, const char *str) +add_string_nodup (char ***argv, int *size, int *alloc, char *str) { char **new_argv; - char *new_str; if (*size >= *alloc) { *alloc += 64; @@ -419,24 +425,36 @@ add_string (char ***argv, int *size, int *alloc, const char *str) if (new_argv == NULL) { reply_with_perror ("realloc"); free_strings (*argv); + *argv = NULL; return -1; } *argv = new_argv; } + (*argv)[*size] = str; + + (*size)++; + return 0; +} + +int +add_string (char ***argv, int *size, int *alloc, const char *str) +{ + char *new_str; + if (str) { new_str = strdup (str); if (new_str == NULL) { reply_with_perror ("strdup"); free_strings (*argv); + *argv = NULL; + return -1; } - } else + } else { new_str = NULL; + } - (*argv)[*size] = new_str; - - (*size)++; - return 0; + return add_string_nodup (argv, size, alloc, new_str); } size_t @@ -679,6 +697,7 @@ 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) { @@ -687,7 +706,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]); @@ -768,13 +787,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);