https://bugzilla.redhat.com/show_bug.cgi?id=1180955
Up till now, there was only one format for NVRAM store file.
However, it's possible to convert the file to qcow2 (which
supports interesting features, like snapshotting, for instance).
Therefore, we want to allow format selection over the NVRAM store
file. By default, the format is raw, but users can choose qcow2.
In the domain XML this is expressed as @format attribute to
<nvram/> element.
Signed-off-by: Michal Privoznik <mprivozn(a)redhat.com>
---
docs/formatdomain.html.in | 8 +++--
docs/schemas/domaincommon.rng | 8 +++++
src/conf/domain_conf.c | 40 +++++++++++++++++-----
src/conf/domain_conf.h | 10 ++++++
src/libvirt_private.syms | 2 ++
.../qemuxml2xmlout-bios-nvram.xml | 40 ++++++++++++++++++++++
tests/qemuxml2xmltest.c | 2 +-
7 files changed, 98 insertions(+), 12 deletions(-)
create mode 100644 tests/qemuxml2xmloutdata/qemuxml2xmlout-bios-nvram.xml
diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index 0c3343e..167114a 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -103,7 +103,7 @@
<os>
<type>hvm</type>
<loader readonly='yes'
type='rom'>/usr/lib/xen/boot/hvmloader</loader>
- <nvram
template='/usr/share/OVMF/OVMF_VARS.fd'>/var/lib/libvirt/nvram/guest_VARS.fd</nvram>
+ <nvram template='/usr/share/OVMF/OVMF_VARS.fd'
format='raw'>/var/lib/libvirt/nvram/guest_VARS.fd</nvram>
<boot dev='hd'/>
<boot dev='cdrom'/>
<bootmenu enable='yes' timeout='3000'/>
@@ -150,7 +150,11 @@
from the config file. Note, that for transient domains if the NVRAM file
has been created by libvirt it is left behind and it is management
application's responsibility to save and remove file (if needed to be
- persistent). <span class="since">Since
1.2.8</span></dd>
+ persistent). <span class="since">Since 1.2.8</span>
+ Then, <span class="since">Since 1.2.12</span> it's
possible to choose
+ the NVRAM file format: <code>raw</code> for raw NVRAM file (the
+ default) or <code>qcow2</code> if the file is converted to qcow2
+ format.</dd>
<dt><code>boot</code></dt>
<dd>The <code>dev</code> attribute takes one of the values
"fd", "hd",
"cdrom" or "network" and is used to specify the next boot
device
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index 85b3709..0afd02a 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -269,6 +269,14 @@
</attribute>
</optional>
<optional>
+ <attribute name="format">
+ <choice>
+ <value>raw</value>
+ <value>qcow2</value>
+ </choice>
+ </attribute>
+ </optional>
+ <optional>
<ref name="absFilePath"/>
</optional>
</element>
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 3cbb93d..d3b6378 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -794,6 +794,11 @@ VIR_ENUM_IMPL(virDomainLoader,
"rom",
"pflash")
+VIR_ENUM_IMPL(virDomainLoaderNVRAMFormat,
+ VIR_DOMAIN_LOADER_NVRAM_FORMAT_LAST,
+ "raw",
+ "qcow2")
+
/* Internal mapping: subset of block job types that can be present in
* <mirror> XML (remaining types are not two-phase). */
VIR_ENUM_DECL(virDomainBlockJob)
@@ -12617,16 +12622,18 @@ virDomainDefMaybeAddHostdevSCSIcontroller(virDomainDefPtr def)
}
static int
-virDomainLoaderDefParseXML(xmlNodePtr node,
+virDomainLoaderDefParseXML(xmlNodePtr loader_node,
+ xmlNodePtr nvram_node,
virDomainLoaderDefPtr loader)
{
int ret = -1;
char *readonly_str = NULL;
char *type_str = NULL;
+ char *format_str = NULL;
- readonly_str = virXMLPropString(node, "readonly");
- type_str = virXMLPropString(node, "type");
- loader->path = (char *) xmlNodeGetContent(node);
+ readonly_str = virXMLPropString(loader_node, "readonly");
+ type_str = virXMLPropString(loader_node, "type");
+ loader->path = (char *) xmlNodeGetContent(loader_node);
if (readonly_str &&
(loader->readonly = virTristateBoolTypeFromString(readonly_str)) <= 0) {
@@ -12645,10 +12652,24 @@ virDomainLoaderDefParseXML(xmlNodePtr node,
loader->type = type;
}
+ if (nvram_node) {
+ loader->nvram = (char *)xmlNodeGetContent(nvram_node);
+ loader->templt = virXMLPropString(nvram_node, "template");
+ format_str = virXMLPropString(nvram_node, "format");
+
+ if (format_str &&
+ (loader->nvramFormat =
virDomainLoaderNVRAMFormatTypeFromString(format_str)) < 0) {
+ virReportError(VIR_ERR_XML_DETAIL,
+ _("unknown format value: %s"), format_str);
+ goto cleanup;
+ }
+ }
+
ret = 0;
cleanup:
VIR_FREE(readonly_str);
VIR_FREE(type_str);
+ VIR_FREE(format_str);
return ret;
}
@@ -13735,7 +13756,7 @@ virDomainDefParseXML(xmlDocPtr xml,
if (STREQ(def->os.type, "xen") ||
STREQ(def->os.type, "hvm") ||
STREQ(def->os.type, "uml")) {
- xmlNodePtr loader_node;
+ xmlNodePtr loader_node, nvram_node;
def->os.kernel = virXPathString("string(./os/kernel[1])", ctxt);
def->os.initrd = virXPathString("string(./os/initrd[1])", ctxt);
@@ -13746,11 +13767,10 @@ virDomainDefParseXML(xmlDocPtr xml,
if (VIR_ALLOC(def->os.loader) < 0)
goto error;
- if (virDomainLoaderDefParseXML(loader_node, def->os.loader) < 0)
- goto error;
+ nvram_node = virXPathNode("./os/nvram[1]", ctxt);
- def->os.loader->nvram =
virXPathString("string(./os/nvram[1])", ctxt);
- def->os.loader->templt =
virXPathString("string(./os/nvram[1]/@template)", ctxt);
+ if (virDomainLoaderDefParseXML(loader_node, nvram_node, def->os.loader)
< 0)
+ goto error;
}
}
@@ -19288,6 +19308,8 @@ virDomainLoaderDefFormat(virBufferPtr buf,
if (loader->nvram || loader->templt) {
virBufferAddLit(buf, "<nvram");
virBufferEscapeString(buf, " template='%s'",
loader->templt);
+ virBufferAsprintf(buf, " format='%s'",
+
virDomainLoaderNVRAMFormatTypeToString(loader->nvramFormat));
if (loader->nvram)
virBufferEscapeString(buf, ">%s</nvram>\n",
loader->nvram);
else
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index ac1f4f8..428afcc 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -1729,6 +1729,15 @@ typedef enum {
VIR_ENUM_DECL(virDomainLoader)
+typedef enum {
+ VIR_DOMAIN_LOADER_NVRAM_FORMAT_RAW = 0,
+ VIR_DOMAIN_LOADER_NVRAM_FORMAT_QCOW2,
+
+ VIR_DOMAIN_LOADER_NVRAM_FORMAT_LAST
+} virDomainLoaderNVRAMFormat;
+
+VIR_ENUM_DECL(virDomainLoaderNVRAMFormat)
+
typedef struct _virDomainLoaderDef virDomainLoaderDef;
typedef virDomainLoaderDef *virDomainLoaderDefPtr;
struct _virDomainLoaderDef {
@@ -1737,6 +1746,7 @@ struct _virDomainLoaderDef {
virDomainLoader type;
char *nvram; /* path to non-volatile RAM */
char *templt; /* user override of path to master nvram */
+ virDomainLoaderNVRAMFormat nvramFormat;
};
void virDomainLoaderDefFree(virDomainLoaderDefPtr loader);
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index fb5d003..2dd73db 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -316,6 +316,8 @@ virDomainLifecycleTypeToString;
virDomainListFree;
virDomainLiveConfigHelperMethod;
virDomainLoaderDefFree;
+virDomainLoaderNVRAMFormatTypeFromString;
+virDomainLoaderNVRAMFormatTypeToString;
virDomainLoaderTypeFromString;
virDomainLoaderTypeToString;
virDomainLockFailureTypeFromString;
diff --git a/tests/qemuxml2xmloutdata/qemuxml2xmlout-bios-nvram.xml
b/tests/qemuxml2xmloutdata/qemuxml2xmlout-bios-nvram.xml
new file mode 100644
index 0000000..f622e1c
--- /dev/null
+++ b/tests/qemuxml2xmloutdata/qemuxml2xmlout-bios-nvram.xml
@@ -0,0 +1,40 @@
+<domain type='qemu'>
+ <name>test-bios</name>
+ <uuid>362d1fc1-df7d-193e-5c18-49a71bd1da66</uuid>
+ <memory unit='KiB'>1048576</memory>
+ <currentMemory unit='KiB'>1048576</currentMemory>
+ <vcpu placement='static'>1</vcpu>
+ <os>
+ <type arch='x86_64' machine='pc'>hvm</type>
+ <loader readonly='yes'
type='pflash'>/usr/share/OVMF/OVMF_CODE.fd</loader>
+ <nvram format='raw'>/usr/share/OVMF/OVMF_VARS.fd</nvram>
+ <boot dev='hd'/>
+ <bootmenu enable='yes'/>
+ </os>
+ <features>
+ <acpi/>
+ </features>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>restart</on_crash>
+ <devices>
+ <emulator>/usr/bin/qemu</emulator>
+ <disk type='block' device='disk'>
+ <source dev='/dev/HostVG/QEMUGuest1'/>
+ <target dev='hda' bus='ide'/>
+ <address type='drive' controller='0' bus='0'
target='0' unit='0'/>
+ </disk>
+ <controller type='usb' index='0'/>
+ <controller type='ide' index='0'/>
+ <controller type='pci' index='0' model='pci-root'/>
+ <serial type='pty'>
+ <target port='0'/>
+ </serial>
+ <console type='pty'>
+ <target type='serial' port='0'/>
+ </console>
+ <input type='tablet' bus='usb'/>
+ <memballoon model='virtio'/>
+ </devices>
+</domain>
diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c
index 1166534..5238b09 100644
--- a/tests/qemuxml2xmltest.c
+++ b/tests/qemuxml2xmltest.c
@@ -404,7 +404,7 @@ mymain(void)
DO_TEST_DIFFERENT("numatune-memnode");
DO_TEST("numatune-memnode-no-memory");
- DO_TEST("bios-nvram");
+ DO_TEST_DIFFERENT("bios-nvram");
DO_TEST("tap-vhost");
DO_TEST("shmem");
--
2.0.5