mirror of https://gitee.com/openkylin/libvirt.git
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: Christian Schoenebeck <qemu_oss@crudebyte.com> Signed-off-by: Ján Tomko <jtomko@redhat.com> Reviewed-by: Ján Tomko <jtomko@redhat.com>
This commit is contained in:
parent
8fe6e82d1c
commit
c3a1856890
|
@ -3973,7 +3973,7 @@
|
|||
<source name='my-vm-template'/>
|
||||
<target dir='/'/>
|
||||
</filesystem>
|
||||
<filesystem type='mount' accessmode='passthrough'>
|
||||
<filesystem type='mount' accessmode='passthrough' multidevs='remap'>
|
||||
<driver type='path' wrpolicy='immediate'/>
|
||||
<source dir='/export/to/guest'/>
|
||||
<target dir='/import/from/host'/>
|
||||
|
@ -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;
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
<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>
|
|
@ -0,0 +1,56 @@
|
|||
<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);
|
||||
|
||||
|
|
Loading…
Reference in New Issue