[Libguestfs] [PATCH v2 3/4] daemon: Allow guestfs_channel to override the virtio-serial channel.

Richard W.M. Jones rjones at redhat.com
Fri Aug 9 21:51:02 UTC 2013


From: "Richard W.M. Jones" <rjones at redhat.com>

Also if /dev/ttyS* is specified, make sure the serial port is set to
raw mode.
---
 daemon/guestfsd.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 47 insertions(+), 4 deletions(-)

diff --git a/daemon/guestfsd.c b/daemon/guestfsd.c
index 580315a..fe2bd79 100644
--- a/daemon/guestfsd.c
+++ b/daemon/guestfsd.c
@@ -41,6 +41,7 @@
 #include <netinet/in.h>
 #include <errno.h>
 #include <assert.h>
+#include <termios.h>
 
 #ifdef HAVE_PRINTF_H
 # include <printf.h>
@@ -78,6 +79,7 @@ static dev_t root_device = 0;
 
 int verbose = 0;
 
+static void makeraw (const char *channel, int fd);
 static int print_shell_quote (FILE *stream, const struct printf_info *info, const void *const *args);
 static int print_sysroot_shell_quote (FILE *stream, const struct printf_info *info, const void *const *args);
 #ifdef HAVE_REGISTER_PRINTF_SPECIFIER
@@ -210,8 +212,6 @@ main (int argc, char *argv[])
       printf ("could not read linux command line\n");
   }
 
-  free (cmdline);
-
 #ifndef WIN32
   /* Make sure SIGPIPE doesn't kill us. */
   struct sigaction sa;
@@ -254,7 +254,22 @@ main (int argc, char *argv[])
   copy_lvm ();
 
   /* Connect to virtio-serial channel. */
-  int sock = open (VIRTIO_SERIAL_CHANNEL, O_RDWR|O_CLOEXEC);
+  char *channel, *p;
+  if (cmdline && (p = strstr (cmdline, "guestfs_channel=")) != NULL) {
+    p += 16;
+    channel = strndup (p, strcspn (p, " \n"));
+  }
+  else
+    channel = strdup (VIRTIO_SERIAL_CHANNEL);
+  if (!channel) {
+    perror ("strdup");
+    exit (EXIT_FAILURE);
+  }
+
+  if (verbose)
+    printf ("trying to open virtio-serial channel '%s'\n", channel);
+
+  int sock = open (channel, O_RDWR|O_CLOEXEC);
   if (sock == -1) {
     fprintf (stderr,
              "\n"
@@ -269,10 +284,19 @@ 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 (VIRTIO_SERIAL_CHANNEL);
+    perror (channel);
     exit (EXIT_FAILURE);
   }
 
+  /* If it's a serial-port like device then it probably has echoing
+   * enabled.  Put it into complete raw mode.
+   */
+  if (STRPREFIX (channel, "/dev/ttyS"))
+    makeraw (channel, sock);
+
+  /* cmdline is not used after this point */
+  free (cmdline);
+
   /* Wait for udev devices to be created.  If you start libguestfs,
    * especially with disks that contain complex (eg. mdadm) data
    * already, then it is possible for the 'mdadm' and LVM commands
@@ -355,6 +379,25 @@ read_cmdline (void)
   return r;
 }
 
+/* Try to make the socket raw, but don't fail if it's not possible. */
+static void
+makeraw (const char *channel, int fd)
+{
+  struct termios tt;
+
+  if (tcgetattr (fd, &tt) == -1) {
+    fprintf (stderr, "tcgetattr: ");
+    perror (channel);
+    return;
+  }
+
+  cfmakeraw (&tt);
+  if (tcsetattr (fd, TCSANOW, &tt) == -1) {
+    fprintf (stderr, "tcsetattr: ");
+    perror (channel);
+  }
+}
+
 /* Return true iff device is the root device (and therefore should be
  * ignored from the point of view of user calls).
  */
-- 
1.8.3.1




More information about the Libguestfs mailing list