libxl: Allow multiple serial ports on HVM domain creation
authorWhite, Edmund H <edmund.h.white@intel.com>
Wed, 13 Aug 2014 19:08:18 +0000 (19:08 +0000)
committerIan Campbell <ian.campbell@citrix.com>
Tue, 26 Aug 2014 20:14:32 +0000 (21:14 +0100)
This patch allows an HVM domain to be created with multiple serial
ports.

Since the previous interface only allowed the passing of a single
device, this requires us to add a new element to the hvm struct of
libxl_domain_build_info -- serial_list.  For API compatibility, the
old element, serial, remains.

If hvm.serial_list is set, each device listed will cause an extra
"-serial [foo]" to be appended to the qemu command line.

Callers may set either hvm.serial or hvm.serial_list, but not
both; libxl will throw an error if both are set.

In order to allow users of libxl to write software compatible with
older versions of libxl, also define LIBXL_HAVE_BUILDINFO_SERIAL_LIST.
If this is defined, callers may use either hvm.serial or
hvm.serial_list; otherwise, only hvm.serial will be available.

This patch borrows substantially from the multiple USB device patch
ac16730d0339d41fd7d129a5cb2d40ed67a303d9.

Signed-off-by: Ed White <edmund.h.white@intel.com>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
tools/libxl/libxl.h
tools/libxl/libxl_dm.c
tools/libxl/libxl_types.idl

index bfeb3bc393147fcdbcffaa92fb3664c2797cb87e..008147679c486706acaf8c35ad8788d56a76f165 100644 (file)
@@ -578,6 +578,22 @@ typedef struct libxl__ctx libxl_ctx;
  */
 #define LIBXL_HAVE_CPUPOOL_NAME 1
 
+/*
+ * LIBXL_HAVE_BUILDINFO_SERIAL_LIST
+ *
+ * If this is defined, then the libxl_domain_build_info structure will
+ * contain hvm.serial_list, a libxl_string_list type that contains
+ * a list of serial ports to specify on the qemu command-line.
+ *
+ * If it is set, callers may use either hvm.serial or
+ * hvm.serial_list, but not both; if both are set, libxl will
+ * throw an error.
+ *
+ * If this is not defined, callers can only use hvm.serial.  Note
+ * that this means only one serial port can be added at domain build time.
+ */
+#define LIBXL_HAVE_BUILDINFO_SERIAL_LIST 1
+
 typedef uint8_t libxl_mac[6];
 #define LIBXL_MAC_FMT "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx"
 #define LIBXL_MAC_FMTLEN ((2*6)+5) /* 6 hex bytes plus 5 colons */
index 69e4d009e5dfd8118c7eb5c1714fcf3a91dbd45c..a224446597cf0ca0a8ff896a9c21f904a4448c9f 100644 (file)
@@ -196,8 +196,25 @@ static char ** libxl__build_device_model_args_old(libxl__gc *gc,
         int nr_set_cpus = 0;
         char *s;
 
-        if (b_info->u.hvm.serial) {
-            flexarray_vappend(dm_args, "-serial", b_info->u.hvm.serial, NULL);
+        if (b_info->u.hvm.serial || b_info->u.hvm.serial_list) {
+            if ( b_info->u.hvm.serial && b_info->u.hvm.serial_list )
+            {
+                LOG(ERROR, "Both serial and serial_list set");
+                return NULL;
+            }
+            if (b_info->u.hvm.serial) {
+                flexarray_vappend(dm_args,
+                                  "-serial", b_info->u.hvm.serial, NULL);
+            } else if (b_info->u.hvm.serial_list) {
+                char **p;
+                for (p = b_info->u.hvm.serial_list;
+                     *p;
+                     p++) {
+                    flexarray_vappend(dm_args,
+                                      "-serial",
+                                      *p, NULL);
+                }
+            }
         }
 
         if (libxl_defbool_val(b_info->u.hvm.nographic) && (!sdl && !vnc)) {
@@ -478,8 +495,25 @@ static char ** libxl__build_device_model_args_new(libxl__gc *gc,
     if (b_info->type == LIBXL_DOMAIN_TYPE_HVM) {
         int ioemu_nics = 0;
 
-        if (b_info->u.hvm.serial) {
-            flexarray_vappend(dm_args, "-serial", b_info->u.hvm.serial, NULL);
+        if (b_info->u.hvm.serial || b_info->u.hvm.serial_list) {
+            if ( b_info->u.hvm.serial && b_info->u.hvm.serial_list )
+            {
+                LOG(ERROR, "Both serial and serial_list set");
+                return NULL;
+            }
+            if (b_info->u.hvm.serial) {
+                flexarray_vappend(dm_args,
+                                  "-serial", b_info->u.hvm.serial, NULL);
+            } else if (b_info->u.hvm.serial_list) {
+                char **p;
+                for (p = b_info->u.hvm.serial_list;
+                     *p;
+                     p++) {
+                    flexarray_vappend(dm_args,
+                                      "-serial",
+                                      *p, NULL);
+                }
+            }
         }
 
         if (libxl_defbool_val(b_info->u.hvm.nographic) && (!sdl && !vnc)) {
index 0b3496fe9460ceceabc9002e762311a5c46f3e4e..78a18af731720bb2492887d03a8b233064f28621 100644 (file)
@@ -396,6 +396,7 @@ libxl_domain_build_info = Struct("domain_build_info",[
                                        ("vendor_device",    libxl_vendor_device),
                                        # See libxl_ms_vm_genid_generate()
                                        ("ms_vm_genid",      libxl_ms_vm_genid),
+                                       ("serial_list",      libxl_string_list),
                                        ])),
                  ("pv", Struct(None, [("kernel", string),
                                       ("slack_memkb", MemKB),