X-Git-Url: http://git.annexia.org/?p=libguestfs.git;a=blobdiff_plain;f=daemon%2Fguestfsd.c;h=b4fb15e5ee073272f71aacbe6b39be4eb06acbb4;hp=fad49fb64afed997e18284820e6f4b3ff2158416;hb=8b91ee5e2d951ae467ac08421db89af48a642086;hpb=adf20c0c4d9f488d55254f54a79079b9cacbde8d diff --git a/daemon/guestfsd.c b/daemon/guestfsd.c index fad49fb..b4fb15e 100644 --- a/daemon/guestfsd.c +++ b/daemon/guestfsd.c @@ -41,10 +41,11 @@ #include "daemon.h" static void usage (void); +static char *read_cmdline (void); /* Also in guestfs.c */ -#define VMCHANNEL_PORT "6666" -#define VMCHANNEL_ADDR "10.0.2.4" +#define GUESTFWD_ADDR "10.0.2.4" +#define GUESTFWD_PORT "6666" int verbose = 0; @@ -67,27 +68,15 @@ int sysroot_len = 8; int main (int argc, char *argv[]) { - static const char *options = "fh:p:?"; + static const char *options = "f?"; static const struct option long_options[] = { { "foreground", 0, 0, 'f' }, { "help", 0, 0, '?' }, - { "host", 1, 0, 'h' }, - { "port", 1, 0, 'p' }, { 0, 0, 0, 0 } }; - int c, n, r; + int c; int dont_fork = 0; - const char *host = NULL; - const char *port = NULL; - FILE *fp; - char buf[4096]; - char *p, *p2; - int sock; - struct addrinfo *res, *rr; - struct addrinfo hints; - XDR xdr; - uint32_t len; - struct sigaction sa; + char *cmdline; #ifdef HAVE_REGISTER_PRINTF_SPECIFIER /* http://udrepper.livejournal.com/20948.html */ @@ -111,14 +100,6 @@ main (int argc, char *argv[]) dont_fork = 1; break; - case 'h': - host = optarg; - break; - - case 'p': - port = optarg; - break; - case '?': usage (); exit (0); @@ -134,48 +115,22 @@ main (int argc, char *argv[]) exit (1); } - /* If host and port aren't set yet, try /proc/cmdline. */ - if (!host || !port) { - fp = fopen ("/proc/cmdline", "r"); - if (fp == NULL) { - perror ("/proc/cmdline"); - goto next; - } - n = fread (buf, 1, sizeof buf - 1, fp); - fclose (fp); - buf[n] = '\0'; - - /* Set the verbose flag. Not quite right because this will only - * set the flag if host and port aren't set on the command line. - * Don't worry about this for now. (XXX) - */ - verbose = strstr (buf, "guestfs_verbose=1") != NULL; - if (verbose) - printf ("verbose daemon enabled\n"); - - p = strstr (buf, "guestfs="); - - if (p) { - p += 8; - p2 = strchr (p, ':'); - if (p2) { - *p2++ = '\0'; - host = p; - r = strcspn (p2, " \n"); - p2[r] = '\0'; - port = p2; - } - } - } + cmdline = read_cmdline (); - next: - /* Can't parse /proc/cmdline, so use built-in defaults. */ - if (!host || !port) { - host = VMCHANNEL_ADDR; - port = VMCHANNEL_PORT; + /* Set the verbose flag. */ + verbose = cmdline && strstr (cmdline, "guestfs_verbose=1") != NULL; + if (verbose) + printf ("verbose daemon enabled\n"); + + if (verbose) { + if (cmdline) + printf ("linux commmand line: %s\n", cmdline); + else + printf ("could not read linux command line\n"); } /* Make sure SIGPIPE doesn't kill us. */ + struct sigaction sa; memset (&sa, 0, sizeof sa); sa.sa_handler = SIG_IGN; sa.sa_flags = 0; @@ -194,17 +149,21 @@ main (int argc, char *argv[]) umask (022); /* Resolve the hostname. */ + struct addrinfo *res, *rr; + struct addrinfo hints; + int r; memset (&hints, 0, sizeof hints); hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_ADDRCONFIG; - r = getaddrinfo (host, port, &hints, &res); + r = getaddrinfo (GUESTFWD_ADDR, GUESTFWD_PORT, &hints, &res); if (r != 0) { - fprintf (stderr, "%s:%s: %s\n", host, port, gai_strerror (r)); + fprintf (stderr, "%s:%s: %s\n", + GUESTFWD_ADDR, GUESTFWD_PORT, gai_strerror (r)); exit (1); } /* Connect to the given TCP socket. */ - sock = -1; + int sock = -1; for (rr = res; rr != NULL; rr = rr->ai_next) { sock = socket (rr->ai_family, rr->ai_socktype, rr->ai_protocol); if (sock != -1) { @@ -219,21 +178,22 @@ main (int argc, char *argv[]) freeaddrinfo (res); if (sock == -1) { - fprintf (stderr, "connection to %s:%s failed\n", host, port); + fprintf (stderr, "connection to %s:%s failed\n", + GUESTFWD_ADDR, GUESTFWD_PORT); exit (1); } /* Send the magic length message which indicates that * userspace is up inside the guest. */ - len = GUESTFS_LAUNCH_FLAG; - xdrmem_create (&xdr, buf, sizeof buf, XDR_ENCODE); - if (!xdr_uint32_t (&xdr, &len)) { - fprintf (stderr, "xdr_uint32_t failed\n"); - exit (1); - } + char lenbuf[4]; + XDR xdr; + uint32_t len = GUESTFS_LAUNCH_FLAG; + xdrmem_create (&xdr, lenbuf, sizeof lenbuf, XDR_ENCODE); + xdr_uint32_t (&xdr, &len); - (void) xwrite (sock, buf, xdr_getpos (&xdr)); + if (xwrite (sock, lenbuf, sizeof lenbuf) == -1) + exit (1); xdr_destroy (&xdr); @@ -251,6 +211,55 @@ main (int argc, char *argv[]) exit (0); } +/* Read /proc/cmdline. */ +static char * +read_cmdline (void) +{ + int fd = open ("/proc/cmdline", O_RDONLY); + if (fd == -1) { + perror ("/proc/cmdline"); + return NULL; + } + + size_t len = 0; + ssize_t n; + char buf[256]; + char *r = NULL; + + for (;;) { + n = read (fd, buf, sizeof buf); + if (n == -1) { + perror ("read"); + free (r); + close (fd); + return NULL; + } + if (n == 0) + break; + char *newr = realloc (r, len + n + 1); /* + 1 is for terminating NUL */ + if (newr == NULL) { + perror ("realloc"); + free (r); + close (fd); + return NULL; + } + r = newr; + memcpy (&r[len], buf, n); + len += n; + } + + if (r) + r[len] = '\0'; + + if (close (fd) == -1) { + perror ("close"); + free (r); + return NULL; + } + + return r; +} + /* Turn "/path" into "/sysroot/path". * * Caller must check for NULL and call reply_with_perror ("malloc") @@ -273,9 +282,10 @@ sysroot_path (const char *path) } int -xwrite (int sock, const void *buf, size_t len) +xwrite (int sock, const void *v_buf, size_t len) { int r; + const char *buf = v_buf; while (len > 0) { r = write (sock, buf, len); @@ -291,9 +301,10 @@ xwrite (int sock, const void *buf, size_t len) } int -xread (int sock, void *buf, size_t len) +xread (int sock, void *v_buf, size_t len) { int r; + char *buf = v_buf; while (len > 0) { r = read (sock, buf, len); @@ -315,7 +326,7 @@ xread (int sock, void *buf, size_t len) static void usage (void) { - fprintf (stderr, "guestfsd [-f] [-h host -p port]\n"); + fprintf (stderr, "guestfsd [-f]\n"); } int @@ -743,8 +754,6 @@ print_sysroot_shell_quote (FILE *stream, const struct printf_info *info, const void *const *args) { -#define SAFE(c) (isalnum((c)) || \ - (c) == '/' || (c) == '-' || (c) == '_' || (c) == '.') fputs (sysroot, stream); return sysroot_len + print_shell_quote (stream, info, args); }