提交 c3a18568 编写于 作者: C Christian Schoenebeck 提交者: Ján Tomko

conf: add 'multidevs' option

Introduce new 'multidevs' option for filesystem.

  <filesystem type='mount' accessmode='mapped' multidevs='remap'>
    <source dir='/path'/>
    <target dir='mount_tag'>
  </filesystem>

This option prevents misbehaviours on guest if a qemu 9pfs export
contains multiple devices, due to the potential file ID collisions
this otherwise may cause.
Signed-off-by: NChristian Schoenebeck <qemu_oss@crudebyte.com>
Signed-off-by: NJán Tomko <jtomko@redhat.com>
Reviewed-by: NJán Tomko <jtomko@redhat.com>
上级 8fe6e82d
......@@ -3973,7 +3973,7 @@
&lt;source name='my-vm-template'/&gt;
&lt;target dir='/'/&gt;
&lt;/filesystem&gt;
&lt;filesystem type='mount' accessmode='passthrough'&gt;
&lt;filesystem type='mount' accessmode='passthrough' multidevs='remap'&gt;
&lt;driver type='path' wrpolicy='immediate'/&gt;
&lt;source dir='/export/to/guest'/&gt;
&lt;target dir='/import/from/host'/&gt;
......@@ -4098,6 +4098,44 @@
for more details.
</p>
<p>
The filesystem element has an optional attribute <code>multidevs</code>
which specifies how to deal with a filesystem export containing more than
one device, in order to avoid file ID collisions on guest when using 9pfs
(<span class="since">since 6.3.0, requires QEMU 4.2</span>).
This attribute is not available for virtiofs. The possible values are:
</p>
<dl>
<dt><code>default</code></dt>
<dd>
Use QEMU's default setting (which currently is <code>warn</code>).
</dd>
<dt><code>remap</code></dt>
<dd>
This setting allows guest to access multiple devices per export without
encountering misbehaviours. Inode numbers from host are automatically
remapped on guest to actively prevent file ID collisions if guest
accesses one export containing multiple devices.
</dd>
<dt><code>forbid</code></dt>
<dd>
Only allow to access one device per export by guest. Attempts to access
additional devices on the same export will cause the individual
filesystem access by guest to fail with an error and being logged (once)
as error on host side.
</dd>
<dt><code>warn</code></dt>
<dd>
This setting resembles the behaviour of 9pfs prior to QEMU 4.2, that is
no action is performed to prevent any potential file ID collisions if an
export contains multiple devices, with the only exception: a warning is
logged (once) on host side now. This setting may lead to misbehaviours
on guest side if more than one device is exported per export, due to the
potential file ID collisions this may cause on guest side in that case.
</dd>
</dl>
</dd>
<p>
......
......@@ -2706,6 +2706,16 @@
</choice>
</attribute>
</optional>
<optional>
<attribute name="multidevs">
<choice>
<value>default</value>
<value>remap</value>
<value>forbid</value>
<value>warn</value>
</choice>
</attribute>
</optional>
<optional>
<element name='readonly'>
<empty/>
......
......@@ -502,6 +502,14 @@ VIR_ENUM_IMPL(virDomainFSModel,
"virtio-non-transitional",
);
VIR_ENUM_IMPL(virDomainFSMultidevs,
VIR_DOMAIN_FS_MULTIDEVS_LAST,
"default",
"remap",
"forbid",
"warn",
);
VIR_ENUM_IMPL(virDomainFSCacheMode,
VIR_DOMAIN_FS_CACHE_MODE_LAST,
"default",
......@@ -11389,6 +11397,7 @@ virDomainFSDefParseXML(virDomainXMLOptionPtr xmlopt,
g_autofree char *usage = NULL;
g_autofree char *units = NULL;
g_autofree char *model = NULL;
g_autofree char *multidevs = NULL;
ctxt->node = node;
......@@ -11427,6 +11436,17 @@ virDomainFSDefParseXML(virDomainXMLOptionPtr xmlopt,
}
}
multidevs = virXMLPropString(node, "multidevs");
if (multidevs) {
if ((def->multidevs = virDomainFSMultidevsTypeFromString(multidevs)) < 0) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("unknown multidevs '%s'"), multidevs);
goto error;
}
} else {
def->multidevs = VIR_DOMAIN_FS_MULTIDEVS_DEFAULT;
}
if (virDomainParseScaledValue("./space_hard_limit[1]",
NULL, ctxt, &def->space_hard_limit,
1, ULLONG_MAX, false) < 0)
......@@ -25385,6 +25405,7 @@ virDomainFSDefFormat(virBufferPtr buf,
const char *accessmode = virDomainFSAccessModeTypeToString(def->accessmode);
const char *fsdriver = virDomainFSDriverTypeToString(def->fsdriver);
const char *wrpolicy = virDomainFSWrpolicyTypeToString(def->wrpolicy);
const char *multidevs = virDomainFSMultidevsTypeToString(def->multidevs);
const char *src = def->src->path;
g_auto(virBuffer) driverAttrBuf = VIR_BUFFER_INITIALIZER;
g_auto(virBuffer) driverBuf = VIR_BUFFER_INIT_CHILD(buf);
......@@ -25403,6 +25424,12 @@ virDomainFSDefFormat(virBufferPtr buf,
return -1;
}
if (!multidevs) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("unexpected multidevs %d"), def->multidevs);
return -1;
}
virBufferAsprintf(buf,
"<filesystem type='%s' accessmode='%s'",
type, accessmode);
......@@ -25410,6 +25437,8 @@ virDomainFSDefFormat(virBufferPtr buf,
virBufferAsprintf(buf, " model='%s'",
virDomainFSModelTypeToString(def->model));
}
if (def->multidevs)
virBufferAsprintf(buf, " multidevs='%s'", multidevs);
virBufferAddLit(buf, ">\n");
virBufferAdjustIndent(buf, 2);
......
......@@ -796,6 +796,18 @@ typedef enum {
VIR_DOMAIN_FS_WRPOLICY_LAST
} virDomainFSWrpolicy;
/* How to handle exports containing multiple devices. */
typedef enum {
VIR_DOMAIN_FS_MULTIDEVS_DEFAULT = 0, /* Use QEMU's default setting */
VIR_DOMAIN_FS_MULTIDEVS_REMAP, /* Remap inodes from host to guest */
VIR_DOMAIN_FS_MULTIDEVS_FORBID, /* Prohibit more than one device */
VIR_DOMAIN_FS_MULTIDEVS_WARN, /* Just log a warning if multiple devices */
VIR_DOMAIN_FS_MULTIDEVS_LAST
} virDomainFSMultidevs;
VIR_ENUM_DECL(virDomainFSMultidevs);
typedef enum {
VIR_DOMAIN_FS_MODEL_DEFAULT = 0,
VIR_DOMAIN_FS_MODEL_VIRTIO,
......@@ -820,6 +832,7 @@ struct _virDomainFSDef {
int wrpolicy; /* enum virDomainFSWrpolicy */
int format; /* virStorageFileFormat */
int model; /* virDomainFSModel */
int multidevs; /* virDomainFSMultidevs */
unsigned long long usage; /* in bytes */
virStorageSourcePtr src;
char *dst;
......
<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='x86_64' machine='pc'>hvm</type>
<boot dev='hd'/>
</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-x86_64</emulator>
<controller type='usb' index='0'>
<address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/>
</controller>
<controller type='ide' index='0'>
<address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/>
</controller>
<controller type='pci' index='0' model='pci-root'/>
<filesystem type='mount' accessmode='mapped' multidevs='remap'>
<source dir='/export/fs0'/>
<target dir='fs0'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
</filesystem>
<filesystem type='mount' accessmode='mapped' multidevs='forbid'>
<source dir='/export/fs1'/>
<target dir='fs1'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
</filesystem>
<filesystem type='mount' accessmode='mapped' multidevs='warn'>
<source dir='/export/fs2'/>
<target dir='fs2'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>
</filesystem>
<serial type='pty'>
<target type='isa-serial' port='0'>
<model name='isa-serial'/>
</target>
</serial>
<console type='pty'>
<target type='serial' port='0'/>
</console>
<input type='mouse' bus='ps2'/>
<input type='keyboard' bus='ps2'/>
<memballoon model='virtio'>
<address type='pci' domain='0x0000' bus='0x00' slot='0x0c' function='0x0'/>
</memballoon>
</devices>
</domain>
<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='x86_64' machine='pc'>hvm</type>
<boot dev='hd'/>
</os>
<cpu mode='custom' match='exact' check='none'>
<model fallback='forbid'>qemu64</model>
</cpu>
<clock offset='utc'/>
<on_poweroff>destroy</on_poweroff>
<on_reboot>restart</on_reboot>
<on_crash>destroy</on_crash>
<devices>
<emulator>/usr/bin/qemu-system-x86_64</emulator>
<controller type='usb' index='0' model='piix3-uhci'>
<address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/>
</controller>
<controller type='ide' index='0'>
<address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/>
</controller>
<controller type='pci' index='0' model='pci-root'/>
<filesystem type='mount' accessmode='mapped' multidevs='remap'>
<source dir='/export/fs0'/>
<target dir='fs0'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
</filesystem>
<filesystem type='mount' accessmode='mapped' multidevs='forbid'>
<source dir='/export/fs1'/>
<target dir='fs1'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
</filesystem>
<filesystem type='mount' accessmode='mapped' multidevs='warn'>
<source dir='/export/fs2'/>
<target dir='fs2'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>
</filesystem>
<serial type='pty'>
<target type='isa-serial' port='0'>
<model name='isa-serial'/>
</target>
</serial>
<console type='pty'>
<target type='serial' port='0'/>
</console>
<input type='mouse' bus='ps2'/>
<input type='keyboard' bus='ps2'/>
<memballoon model='virtio'>
<address type='pci' domain='0x0000' bus='0x00' slot='0x0c' function='0x0'/>
</memballoon>
</devices>
</domain>
......@@ -1485,6 +1485,8 @@ mymain(void)
DO_TEST_CAPS_ARCH_LATEST("x86_64-default-cpu-kvm-q35-4.2", "x86_64");
DO_TEST_CAPS_ARCH_LATEST("x86_64-default-cpu-tcg-q35-4.2", "x86_64");
DO_TEST_CAPS_LATEST("virtio-9p-multidevs");
if (getenv("LIBVIRT_SKIP_CLEANUP") == NULL)
virFileDeleteTree(fakerootdir);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册