]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
conf: Add loadparm boot option for a boot device
authorFarhan Ali <alifm@linux.vnet.ibm.com>
Thu, 1 Jun 2017 16:36:24 +0000 (12:36 -0400)
committerJohn Ferlan <jferlan@redhat.com>
Tue, 20 Jun 2017 11:03:22 +0000 (07:03 -0400)
Update the per device boot schema to add an optional loadparm parameter.

eg: <boot order='1' loadparm='2'/>

Extend the virDomainDeviceInfo to support loadparm option.
Modify the appropriate functions to parse loadparm from boot device xml.
Add the xml2xml test to validate the field.

Signed-off-by: Farhan Ali <alifm@linux.vnet.ibm.com>
Reviewed-by: Bjoern Walk <bwalk@linux.vnet.ibm.com>
Reviewed-by: Boris Fiuczynski <fiuczy@linux.vnet.ibm.com>
Reviewed-by: Marc Hartmayer <mhartmay@linux.vnet.ibm.com>
docs/formatdomain.html.in
docs/schemas/domaincommon.rng
src/conf/device_conf.h
src/conf/domain_conf.c
tests/qemuxml2argvdata/qemuxml2argv-machine-loadparm-multiple-disks-nets-s390.xml [new file with mode: 0644]
tests/qemuxml2xmloutdata/qemuxml2xmlout-machine-loadparm-multiple-disks-nets-s390.xml [new file with mode: 0644]
tests/qemuxml2xmltest.c

index 52119f0a0a8fea8009ac4cd58d4fd2cf533df0a8..a55a9e13920d5e65a2f51f5b909f99de2111fa1a 100644 (file)
       <dt><code>boot</code></dt>
       <dd>Specifies that the disk is bootable. The <code>order</code>
         attribute determines the order in which devices will be tried during
-        boot sequence. The per-device <code>boot</code> elements cannot be
-        used together with general boot elements in
+        boot sequence. On the S390 architecture only the first boot device is
+        used. The optional <code>loadparm</code> attribute is an 8 character
+        string which can be queried by guests on S390 via sclp or diag 308.
+        Linux guests on S390 can use <code>loadparm</code> to select a boot
+        entry. <span class="since">Since 3.5.0</span>
+        The per-device <code>boot</code> elements cannot be used together
+        with general boot elements in
         <a href="#elementsOSBIOS">BIOS bootloader</a> section.
         <span class="since">Since 0.8.8</span>
       </dd>
index 4950ddc10915c7fd3f5e04cf3831988a42268896..e259e3ee2583ea74b9a97594bedacaf12ae401dd 100644 (file)
       <attribute name="order">
         <ref name="positiveInteger"/>
       </attribute>
+      <optional>
+        <attribute name="loadparm">
+          <data type="string">
+            <param name="pattern">[a-zA-Z0-9.\s]{1,8}</param>
+          </data>
+        </attribute>
+      </optional>
       <empty/>
     </element>
   </define>
index a20de853f8728d1c290b36afaeb72af1bad3d4a1..48782be95e5001bce989bf918778ff24e75953c8 100644 (file)
@@ -167,6 +167,7 @@ struct _virDomainDeviceInfo {
      * assignment, never saved and never reported.
      */
     int pciConnectFlags; /* enum virDomainPCIConnectFlags */
+    char *loadparm;
 };
 
 
index 4f79d38251740ae4d34a13b01857519cdbcf41c3..0409c62eff26781851d6dd1704cefa1927cb34b3 100644 (file)
@@ -3589,6 +3589,7 @@ void virDomainDeviceInfoClear(virDomainDeviceInfoPtr info)
     memset(&info->addr, 0, sizeof(info->addr));
     info->type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE;
     VIR_FREE(info->romfile);
+    VIR_FREE(info->loadparm);
 }
 
 
@@ -5316,6 +5317,50 @@ virDomainDefValidate(virDomainDefPtr def,
 }
 
 
+/**
+ * virDomainDeviceLoadparmIsValid
+ * @loadparm : The string to validate
+ *
+ * The valid set of values for loadparm are [a-zA-Z0-9.]
+ * and blank spaces.
+ * The maximum allowed length is 8 characters.
+ * An empty string is considered invalid
+ */
+static bool
+virDomainDeviceLoadparmIsValid(const char *loadparm)
+{
+    size_t i;
+
+    if (virStringIsEmpty(loadparm)) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                       _("loadparm cannot be an empty string"));
+        return false;
+    }
+
+    if (strlen(loadparm) > 8) {
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       _("loadparm '%s' exceeds 8 characters"), loadparm);
+        return false;
+    }
+
+    for (i = 0; i < strlen(loadparm); i++) {
+        uint8_t c = loadparm[i];
+
+        if (('A' <= c && c <= 'Z') || ('0' <= c && c <= '9') ||
+            (c == '.') || (c == ' ')) {
+            continue;
+        } else {
+            virReportError(VIR_ERR_INTERNAL_ERROR,
+                           _("invalid loadparm char '%c', expecting chars"
+                             " in set of [a-zA-Z0-9.] and blank spaces"), c);
+            return false;
+        }
+    }
+
+    return true;
+}
+
+
 static void
 virDomainVirtioOptionsFormat(virBufferPtr buf,
                              virDomainVirtioOptionsPtr virtio)
@@ -5342,9 +5387,14 @@ virDomainDeviceInfoFormat(virBufferPtr buf,
                           virDomainDeviceInfoPtr info,
                           unsigned int flags)
 {
-    if ((flags & VIR_DOMAIN_DEF_FORMAT_ALLOW_BOOT) && info->bootIndex)
-        virBufferAsprintf(buf, "<boot order='%u'/>\n", info->bootIndex);
+    if ((flags & VIR_DOMAIN_DEF_FORMAT_ALLOW_BOOT) && info->bootIndex) {
+        virBufferAsprintf(buf, "<boot order='%u'", info->bootIndex);
 
+        if (info->loadparm)
+            virBufferAsprintf(buf, " loadparm='%s'", info->loadparm);
+
+        virBufferAddLit(buf, "/>\n");
+    }
     if (info->alias &&
         !(flags & VIR_DOMAIN_DEF_FORMAT_INACTIVE)) {
         virBufferAsprintf(buf, "<alias name='%s'/>\n", info->alias);
@@ -5770,6 +5820,7 @@ virDomainDeviceBootParseXML(xmlNodePtr node,
                             virHashTablePtr bootHash)
 {
     char *order;
+    char *loadparm;
     int ret = -1;
 
     if (!(order = virXMLPropString(node, "order"))) {
@@ -5798,10 +5849,26 @@ virDomainDeviceBootParseXML(xmlNodePtr node,
             goto cleanup;
     }
 
+    loadparm = virXMLPropString(node, "loadparm");
+    if (loadparm) {
+        if (virStringToUpper(&info->loadparm, loadparm) != 1) {
+            virReportError(VIR_ERR_INTERNAL_ERROR,
+                           _("Failed to convert loadparm '%s' to upper case"),
+                           loadparm);
+            goto cleanup;
+        }
+
+        if (!virDomainDeviceLoadparmIsValid(info->loadparm)) {
+            VIR_FREE(info->loadparm);
+            goto cleanup;
+        }
+    }
+
     ret = 0;
 
  cleanup:
     VIR_FREE(order);
+    VIR_FREE(loadparm);
     return ret;
 }
 
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-machine-loadparm-multiple-disks-nets-s390.xml b/tests/qemuxml2argvdata/qemuxml2argv-machine-loadparm-multiple-disks-nets-s390.xml
new file mode 100644 (file)
index 0000000..df442e9
--- /dev/null
@@ -0,0 +1,43 @@
+<domain type='qemu'>
+  <name>QEMUGuest1</name>
+  <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+  <memory>219136</memory>
+  <currentMemory>219136</currentMemory>
+  <vcpu>1</vcpu>
+  <os>
+    <type arch='s390x' machine='s390-ccw-virtio'>hvm</type>
+  </os>
+  <clock offset='utc'/>
+  <on_poweroff>destroy</on_poweroff>
+  <on_reboot>restart</on_reboot>
+  <on_crash>destroy</on_crash>
+  <devices>
+    <emulator>/usr/bin/qemu-system-s390x</emulator>
+    <disk type='block' device='disk'>
+      <source dev='/dev/HostVG/QEMUGuest1'/>
+      <target dev='hda' bus='virtio'/>
+      <boot order='1' loadparm='system1'/>
+      <address type='ccw' cssid='0xfe' ssid='0x0' devno='0x2'/>
+    </disk>
+    <disk type='block' device='disk'>
+      <source dev='/dev/HostVG/QEMUGuest2'/>
+      <target dev='hdb' bus='virtio'/>
+      <boot order='3' loadparm='3'/>
+      <address type='ccw' cssid='0xfe' ssid='0x0' devno='0x3'/>
+    </disk>
+    <interface type='user'>
+      <mac address='00:11:22:33:44:54'/>
+      <model type='virtio'/>
+      <boot order='2' loadparm='2.lp'/>
+      <address type='ccw' cssid='0xfe' ssid='0x0' devno='0x0'/>
+    </interface>
+   <interface type='user'>
+      <mac address='00:11:22:33:42:36'/>
+      <model type='virtio'/>
+      <address type='ccw' cssid='0xfe' ssid='0x0' devno='0x4'/>
+    </interface>
+    <memballoon model='virtio'>
+      <address type='ccw' cssid='0xfe' ssid='0x0' devno='0x1'/>
+    </memballoon>
+  </devices>
+</domain>
diff --git a/tests/qemuxml2xmloutdata/qemuxml2xmlout-machine-loadparm-multiple-disks-nets-s390.xml b/tests/qemuxml2xmloutdata/qemuxml2xmlout-machine-loadparm-multiple-disks-nets-s390.xml
new file mode 100644 (file)
index 0000000..2f0bb83
--- /dev/null
@@ -0,0 +1,44 @@
+<domain type='qemu'>
+  <name>QEMUGuest1</name>
+  <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+  <memory unit='KiB'>219136</memory>
+  <currentMemory unit='KiB'>219136</currentMemory>
+  <vcpu placement='static'>1</vcpu>
+  <os>
+    <type arch='s390x' machine='s390-ccw-virtio'>hvm</type>
+  </os>
+  <clock offset='utc'/>
+  <on_poweroff>destroy</on_poweroff>
+  <on_reboot>restart</on_reboot>
+  <on_crash>destroy</on_crash>
+  <devices>
+    <emulator>/usr/bin/qemu-system-s390x</emulator>
+    <disk type='block' device='disk'>
+      <source dev='/dev/HostVG/QEMUGuest1'/>
+      <target dev='hda' bus='virtio'/>
+      <boot order='1' loadparm='SYSTEM1'/>
+      <address type='ccw' cssid='0xfe' ssid='0x0' devno='0x0002'/>
+    </disk>
+    <disk type='block' device='disk'>
+      <source dev='/dev/HostVG/QEMUGuest2'/>
+      <target dev='hdb' bus='virtio'/>
+      <boot order='3' loadparm='3'/>
+      <address type='ccw' cssid='0xfe' ssid='0x0' devno='0x0003'/>
+    </disk>
+    <interface type='user'>
+      <mac address='00:11:22:33:44:54'/>
+      <model type='virtio'/>
+      <boot order='2' loadparm='2.LP'/>
+      <address type='ccw' cssid='0xfe' ssid='0x0' devno='0x0000'/>
+    </interface>
+    <interface type='user'>
+      <mac address='00:11:22:33:42:36'/>
+      <model type='virtio'/>
+      <address type='ccw' cssid='0xfe' ssid='0x0' devno='0x0004'/>
+    </interface>
+    <memballoon model='virtio'>
+      <address type='ccw' cssid='0xfe' ssid='0x0' devno='0x0001'/>
+    </memballoon>
+    <panic model='s390'/>
+  </devices>
+</domain>
index 1bdd383a59e7f7491aecc931d834d385fa97ccb4..13072996c254ded0d9f65128f3a9c158c0055291 100644 (file)
@@ -362,6 +362,7 @@ mymain(void)
     DO_TEST("minimal", NONE);
     DO_TEST("machine-core-on", NONE);
     DO_TEST("machine-core-off", NONE);
+    DO_TEST("machine-loadparm-multiple-disks-nets-s390", NONE);
     DO_TEST("default-kvm-host-arch", NONE);
     DO_TEST("default-qemu-host-arch", NONE);
     DO_TEST("boot-cdrom", NONE);