1 /* libguestfs - the guestfsd daemon
2 * Copyright (C) 2009 Red Hat Inc.
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 #define _BSD_SOURCE /* for daemon(3) */
31 #include <rpc/types.h>
34 #include <sys/param.h>
35 #include <sys/types.h>
40 #include <sys/select.h>
48 #include "ignore-value.h"
52 static char *read_cmdline (void);
54 /* Also in guestfs.c */
55 #define GUESTFWD_ADDR "10.0.2.4"
56 #define GUESTFWD_PORT "6666"
58 /* This is only a hint. If not defined, ignore it. */
60 #define AI_ADDRCONFIG 0
64 #define MAX(a,b) ((a)>(b)?(a):(b))
69 static int print_shell_quote (FILE *stream, const struct printf_info *info, const void *const *args);
70 static int print_sysroot_shell_quote (FILE *stream, const struct printf_info *info, const void *const *args);
71 #ifdef HAVE_REGISTER_PRINTF_SPECIFIER
72 static int print_arginfo (const struct printf_info *info, size_t n, int *argtypes, int *size);
74 #ifdef HAVE_REGISTER_PRINTF_FUNCTION
75 static int print_arginfo (const struct printf_info *info, size_t n, int *argtypes);
77 #error "HAVE_REGISTER_PRINTF_{SPECIFIER|FUNCTION} not defined"
81 /* Location to mount root device. */
82 const char *sysroot = "/sysroot"; /* No trailing slash. */
89 "guestfsd [-f|--foreground] [-c|--channel vmchannel] [-v|--verbose]\n");
93 main (int argc, char *argv[])
95 static const char *options = "fc:v?";
96 static const struct option long_options[] = {
97 { "channel", required_argument, 0, 'c' },
98 { "foreground", 0, 0, 'f' },
99 { "help", 0, 0, '?' },
100 { "verbose", 0, 0, 'v' },
106 char *vmchannel = NULL;
108 #ifdef HAVE_REGISTER_PRINTF_SPECIFIER
109 /* http://udrepper.livejournal.com/20948.html */
110 register_printf_specifier ('Q', print_shell_quote, print_arginfo);
111 register_printf_specifier ('R', print_sysroot_shell_quote, print_arginfo);
113 #ifdef HAVE_REGISTER_PRINTF_FUNCTION
114 register_printf_function ('Q', print_shell_quote, print_arginfo);
115 register_printf_function ('R', print_sysroot_shell_quote, print_arginfo);
117 #error "HAVE_REGISTER_PRINTF_{SPECIFIER|FUNCTION} not defined"
122 c = getopt_long (argc, argv, options, long_options, NULL);
143 fprintf (stderr, "guestfsd: unexpected command line option 0x%x\n", c);
153 cmdline = read_cmdline ();
155 /* Set the verbose flag. */
157 (cmdline && strstr (cmdline, "guestfs_verbose=1") != NULL);
159 printf ("verbose daemon enabled\n");
163 printf ("linux commmand line: %s\n", cmdline);
165 printf ("could not read linux command line\n");
169 /* Make sure SIGPIPE doesn't kill us. */
171 memset (&sa, 0, sizeof sa);
172 sa.sa_handler = SIG_IGN;
174 if (sigaction (SIGPIPE, &sa, NULL) == -1)
175 perror ("sigaction SIGPIPE"); /* but try to continue anyway ... */
179 #define setenv(n,v,f) _putenv(n "=" v)
181 /* Set up a basic environment. After we are called by /init the
182 * environment is essentially empty.
183 * https://bugzilla.redhat.com/show_bug.cgi?id=502074#c5
185 setenv ("PATH", "/usr/bin:/bin", 1);
186 setenv ("SHELL", "/bin/sh", 1);
187 setenv ("LC_ALL", "C", 1);
190 /* We document that umask defaults to 022 (it should be this anyway). */
193 /* This is the default for Windows anyway. It's not even clear if
194 * Windows ever uses this -- the MSDN documentation for the function
195 * contains obvious errors.
200 /* Get the vmchannel string.
203 * --channel/-c option on the command line
204 * guestfs_vmchannel=... from the kernel command line
205 * guestfs=... from the kernel command line
208 * At the moment we expect this to contain "tcp:ip:port" but in
209 * future it might contain a device name, eg. "/dev/vcon4" for
210 * virtio-console vmchannel.
212 if (vmchannel == NULL && cmdline) {
216 p = strstr (cmdline, "guestfs_vmchannel=");
218 len = strcspn (p + 18, " \t\n");
219 vmchannel = strndup (p + 18, len);
226 /* Old libraries passed guestfs=host:port. Rewrite it as tcp:host:port. */
227 if (vmchannel == NULL) {
228 /* We will rewrite it part of the "guestfs=" string with
229 * "tcp:" hence p + 4 below. */
230 p = strstr (cmdline, "guestfs=");
232 len = strcspn (p + 4, " \t\n");
233 vmchannel = strndup (p + 4, len);
238 memcpy (vmchannel, "tcp:", 4);
243 /* Default vmchannel. */
244 if (vmchannel == NULL) {
245 vmchannel = strdup ("tcp:" GUESTFWD_ADDR ":" GUESTFWD_PORT);
253 printf ("vmchannel: %s\n", vmchannel);
255 /* Connect to vmchannel. */
258 if (STREQLEN (vmchannel, "tcp:", 4)) {
259 /* Resolve the hostname. */
260 struct addrinfo *res, *rr;
261 struct addrinfo hints;
266 port = strchr (host, ':');
271 fprintf (stderr, "vmchannel: expecting \"tcp:<ip>:<port>\": %s\n",
276 memset (&hints, 0, sizeof hints);
277 hints.ai_socktype = SOCK_STREAM;
278 hints.ai_flags = AI_ADDRCONFIG;
279 r = getaddrinfo (host, port, &hints, &res);
281 fprintf (stderr, "%s:%s: %s\n",
282 host, port, gai_strerror (r));
286 /* Connect to the given TCP socket. */
287 for (rr = res; rr != NULL; rr = rr->ai_next) {
288 sock = socket (rr->ai_family, rr->ai_socktype, rr->ai_protocol);
290 if (connect (sock, rr->ai_addr, rr->ai_addrlen) == 0)
301 "unknown vmchannel connection type: %s\n"
302 "expecting \"tcp:<ip>:<port>\"\n",
310 "Failed to connect to any vmchannel implementation.\n"
313 "This is a fatal error and the appliance will now exit.\n"
315 "Usually this error is caused by either QEMU or the appliance\n"
316 "kernel not supporting the vmchannel method that the\n"
317 "libguestfs library chose to use. Please run\n"
318 "'libguestfs-test-tool' and provide the complete, unedited\n"
319 "output to the libguestfs developers, either in a bug report\n"
320 "or on the libguestfs redhat com mailing list.\n"
326 /* Send the magic length message which indicates that
327 * userspace is up inside the guest.
331 uint32_t len = GUESTFS_LAUNCH_FLAG;
332 xdrmem_create (&xdr, lenbuf, sizeof lenbuf, XDR_ENCODE);
333 xdr_u_int (&xdr, &len);
335 if (xwrite (sock, lenbuf, sizeof lenbuf) == -1)
340 /* Fork into the background. */
343 if (daemon (0, 1) == -1) {
348 fprintf (stderr, "On Windows the daemon does not support forking into the background.\nYou *must* run the daemon with the -f option.\n");
353 /* Enter the main loop, reading and performing actions. */
359 /* Read /proc/cmdline. */
363 int fd = open ("/proc/cmdline", O_RDONLY);
365 perror ("/proc/cmdline");
375 n = read (fd, buf, sizeof buf);
384 char *newr = realloc (r, len + n + 1); /* + 1 is for terminating NUL */
392 memcpy (&r[len], buf, n);
399 if (close (fd) == -1) {
408 /* Turn "/path" into "/sysroot/path".
410 * Caller must check for NULL and call reply_with_perror ("malloc")
411 * if it is. Caller must also free the string.
413 * See also the custom %R printf formatter which does shell quoting too.
416 sysroot_path (const char *path)
419 int len = strlen (path) + sysroot_len + 1;
425 snprintf (r, len, "%s%s", sysroot, path);
430 xwrite (int sock, const void *v_buf, size_t len)
433 const char *buf = v_buf;
436 r = write (sock, buf, len);
449 xread (int sock, void *v_buf, size_t len)
455 r = read (sock, buf, len);
461 fprintf (stderr, "read: unexpected end of file on fd %d\n", sock);
472 add_string (char ***argv, int *size, int *alloc, const char *str)
477 if (*size >= *alloc) {
479 new_argv = realloc (*argv, *alloc * sizeof (char *));
480 if (new_argv == NULL) {
481 reply_with_perror ("realloc");
482 free_strings (*argv);
489 new_str = strdup (str);
490 if (new_str == NULL) {
491 reply_with_perror ("strdup");
492 free_strings (*argv);
497 (*argv)[*size] = new_str;
504 count_strings (char *const *argv)
508 for (argc = 0; argv[argc] != NULL; ++argc)
514 compare (const void *vp1, const void *vp2)
516 char * const *p1 = (char * const *) vp1;
517 char * const *p2 = (char * const *) vp2;
518 return strcmp (*p1, *p2);
522 sort_strings (char **argv, int len)
524 qsort (argv, len, sizeof (char *), compare);
528 free_strings (char **argv)
532 for (argc = 0; argv[argc] != NULL; ++argc)
538 free_stringslen (char **argv, int len)
542 for (i = 0; i < len; ++i)
547 /* Easy ways to run external commands. For full documentation, see
548 * 'commandrvf' below.
551 commandf (char **stdoutput, char **stderror, int flags, const char *name, ...)
558 /* Collect the command line arguments into an array. */
560 argv = malloc (sizeof (char *) * i);
565 argv[0] = (char *) name;
568 va_start (args, name);
570 while ((s = va_arg (args, char *)) != NULL) {
571 const char **p = realloc (argv, sizeof (char *) * (++i));
585 r = commandvf (stdoutput, stderror, flags, (const char * const*) argv);
587 /* NB: Mustn't free the strings which are on the stack. */
593 /* Same as 'command', but we allow the status code from the
594 * subcommand to be non-zero, and return that status code.
595 * We still return -1 if there was some other error.
598 commandrf (char **stdoutput, char **stderror, int flags, const char *name, ...)
605 /* Collect the command line arguments into an array. */
607 argv = malloc (sizeof (char *) * i);
612 argv[0] = (char *) name;
615 va_start (args, name);
617 while ((s = va_arg (args, char *)) != NULL) {
618 const char **p = realloc (argv, sizeof (char *) * (++i));
632 r = commandrvf (stdoutput, stderror, flags, argv);
634 /* NB: Mustn't free the strings which are on the stack. */
640 /* Same as 'command', but passing an argv. */
642 commandvf (char **stdoutput, char **stderror, int flags,
643 char const *const *argv)
647 r = commandrvf (stdoutput, stderror, flags, (void *) argv);
654 /* This is a more sane version of 'system(3)' for running external
655 * commands. It uses fork/execvp, so we don't need to worry about
656 * quoting of parameters, and it allows us to capture any error
657 * messages in a buffer.
659 * If stdoutput is not NULL, then *stdoutput will return the stdout
662 * If stderror is not NULL, then *stderror will return the stderr
663 * of the command. If there is a final \n character, it is removed
664 * so you can use the error string directly in a call to
669 * COMMAND_FLAG_FOLD_STDOUT_ON_STDERR: For broken external commands
670 * that send error messages to stdout (hello, parted) but that don't
671 * have any useful stdout information, use this flag to capture the
672 * error messages in the *stderror buffer. If using this flag,
673 * you should pass stdoutput as NULL because nothing could ever be
674 * captured in that buffer.
677 commandrvf (char **stdoutput, char **stderror, int flags,
678 char const* const *argv)
680 int so_size = 0, se_size = 0;
681 int so_fd[2], se_fd[2];
688 if (stdoutput) *stdoutput = NULL;
689 if (stderror) *stderror = NULL;
692 printf ("%s", argv[0]);
693 for (i = 1; argv[i] != NULL; ++i)
694 printf (" %s", argv[i]);
698 if (pipe (so_fd) == -1 || pipe (se_fd) == -1) {
713 if (pid == 0) { /* Child process. */
715 open ("/dev/null", O_RDONLY); /* Set stdin to /dev/null (ignore failure) */
718 if (!(flags & COMMAND_FLAG_FOLD_STDOUT_ON_STDERR))
726 execvp (argv[0], (void *) argv);
731 /* Parent process. */
736 FD_SET (so_fd[0], &rset);
737 FD_SET (se_fd[0], &rset);
742 r = select (MAX (so_fd[0], se_fd[0]) + 1, &rset2, NULL, NULL, NULL);
746 if (stdoutput) free (*stdoutput);
747 if (stderror) free (*stderror);
750 waitpid (pid, NULL, 0);
754 if (FD_ISSET (so_fd[0], &rset2)) { /* something on stdout */
755 r = read (so_fd[0], buf, sizeof buf);
760 if (r == 0) { FD_CLR (so_fd[0], &rset); quit++; }
762 if (r > 0 && stdoutput) {
764 p = realloc (*stdoutput, so_size);
770 memcpy (*stdoutput + so_size - r, buf, r);
774 if (FD_ISSET (se_fd[0], &rset2)) { /* something on stderr */
775 r = read (se_fd[0], buf, sizeof buf);
780 if (r == 0) { FD_CLR (se_fd[0], &rset); quit++; }
784 ignore_value (write (2, buf, r));
788 p = realloc (*stderror, se_size);
794 memcpy (*stderror + se_size - r, buf, r);
803 /* Make sure the output buffers are \0-terminated. Also remove any
804 * trailing \n characters from the error buffer (not from stdout).
807 void *q = realloc (*stdoutput, so_size+1);
814 (*stdoutput)[so_size] = '\0';
817 void *q = realloc (*stderror, se_size+1);
824 (*stderror)[se_size] = '\0';
826 while (se_size >= 0 && (*stderror)[se_size] == '\n')
827 (*stderror)[se_size--] = '\0';
831 /* Get the exit status of the command. */
832 if (waitpid (pid, &r, 0) != pid) {
838 return WEXITSTATUS (r);
843 /* Split an output string into a NULL-terminated list of lines.
844 * Typically this is used where we have run an external command
845 * which has printed out a list of things, and we want to return
848 * The corner cases here are quite tricky. Note in particular:
852 * "a\nb" -> ["a"; "b"]
853 * "a\nb\n" -> ["a"; "b"]
854 * "a\nb\n\n" -> ["a"; "b"; ""]
856 * The original string is written over and destroyed by this
857 * function (which is usually OK because it's the 'out' string
858 * from command()). You can free the original string, because
859 * add_string() strdups the strings.
862 split_lines (char *str)
865 int size = 0, alloc = 0;
873 /* Empty last line? */
877 pend = strchr (p, '\n');
883 if (add_string (&lines, &size, &alloc, p) == -1) {
891 if (add_string (&lines, &size, &alloc, NULL) == -1)
897 /* printf helper function so we can use %Q ("quoted") and %R to print
898 * shell-quoted strings. See HACKING file for more details.
901 print_shell_quote (FILE *stream,
902 const struct printf_info *info ATTRIBUTE_UNUSED,
903 const void *const *args)
905 #define SAFE(c) (c_isalnum((c)) || \
906 (c) == '/' || (c) == '-' || (c) == '_' || (c) == '.')
908 const char *str = *((const char **) (args[0]));
910 for (i = len = 0; str[i]; ++i) {
915 putc (str[i], stream);
923 print_sysroot_shell_quote (FILE *stream,
924 const struct printf_info *info,
925 const void *const *args)
927 fputs (sysroot, stream);
928 return sysroot_len + print_shell_quote (stream, info, args);
931 #ifdef HAVE_REGISTER_PRINTF_SPECIFIER
933 print_arginfo (const struct printf_info *info ATTRIBUTE_UNUSED,
934 size_t n, int *argtypes, int *size)
937 argtypes[0] = PA_STRING;
938 size[0] = sizeof (const char *);
943 #ifdef HAVE_REGISTER_PRINTF_FUNCTION
945 print_arginfo (const struct printf_info *info, size_t n, int *argtypes)
948 argtypes[0] = PA_STRING;
952 #error "HAVE_REGISTER_PRINTF_{SPECIFIER|FUNCTION} not defined"
956 /* Perform device name translation. Don't call this directly -
957 * use the RESOLVE_DEVICE macro.
959 * See guestfs(3) for the algorithm.
961 * We have to open the device and test for ENXIO, because
962 * the device nodes themselves will exist in the appliance.
965 device_name_translation (char *device, const char *func)
969 fd = open (device, O_RDONLY);
975 if (errno != ENXIO && errno != ENOENT) {
977 reply_with_perror ("%s: %s", func, device);
981 /* If the name begins with "/dev/sd" then try the alternatives. */
982 if (STRNEQLEN (device, "/dev/sd", 7))
985 device[5] = 'h'; /* /dev/hd (old IDE driver) */
986 fd = open (device, O_RDONLY);
992 device[5] = 'v'; /* /dev/vd (for virtio devices) */
993 fd = open (device, O_RDONLY);
999 device[5] = 's'; /* Restore original device name. */
1003 /* LVM and other commands aren't synchronous, especially when udev is
1004 * involved. eg. You can create or remove some device, but the /dev
1005 * device node won't appear until some time later. This means that
1006 * you get an error if you run one command followed by another.
1007 * Use 'udevadm settle' after certain commands, but don't be too
1008 * fussed if it fails.
1013 static int which_prog = 0;
1015 if (which_prog == 0) {
1016 if (access ("/sbin/udevsettle", X_OK) == 0)
1018 else if (access ("/sbin/udevadm", X_OK) == 0)
1024 switch (which_prog) {
1026 command (NULL, NULL, "/sbin/udevadm", "settle", NULL);
1029 command (NULL, NULL, "/sbin/udevsettle", NULL);