Expose QEMU's 9pfs 'fmode' and 'dmode' options via attributes on the
'filesystem' node in the domain XML. These options control the creation
mode of files and directories, respectively, when using
accessmode=mapped. QEMU defaults to creating files with mode 0600 and
directories with mode 0700.
Signed-off-by: Brian Turek <brian.turek(a)gmail.com>
---
src/conf/domain_conf.c | 27 ++++++++
src/conf/domain_conf.h | 2 +
src/qemu/qemu_command.c | 6 ++
src/qemu/qemu_validate.c | 18 ++++++
.../virtio-9p-createmode.x86_64-latest.args | 45 ++++++++++++++
.../qemuxml2argvdata/virtio-9p-createmode.xml | 58 ++++++++++++++++++
.../virtio-9p-createmode.x86_64-latest.xml | 61 +++++++++++++++++++
tests/qemuxml2xmltest.c | 1 +
8 files changed, 218 insertions(+)
create mode 100644 tests/qemuxml2argvdata/virtio-9p-createmode.x86_64-latest.args
create mode 100644 tests/qemuxml2argvdata/virtio-9p-createmode.xml
create mode 100644 tests/qemuxml2xmloutdata/virtio-9p-createmode.x86_64-latest.xml
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 175b632a38..e80b3b7ef6 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -11496,6 +11496,8 @@ virDomainFSDefParseXML(virDomainXMLOptionPtr xmlopt,
g_autofree char *units = NULL;
g_autofree char *model = NULL;
g_autofree char *multidevs = NULL;
+ g_autofree char *fmode = NULL;
+ g_autofree char *dmode = NULL;
ctxt->node = node;
@@ -11524,6 +11526,24 @@ virDomainFSDefParseXML(virDomainXMLOptionPtr xmlopt,
def->accessmode = VIR_DOMAIN_FS_ACCESSMODE_PASSTHROUGH;
}
+ fmode = virXMLPropString(node, "fmode");
+ if (fmode) {
+ if (virStrToLong_uip(fmode, NULL, 8, &def->fmode) < 0) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("invalid fmode: '%s'"), fmode);
+ goto error;
+ }
+ }
+
+ dmode = virXMLPropString(node, "dmode");
+ if (dmode) {
+ if (virStrToLong_uip(dmode, NULL, 8, &def->dmode) < 0) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("invalid dmode: '%s'"), dmode);
+ goto error;
+ }
+ }
+
model = virXMLPropString(node, "model");
if (model) {
if ((def->model = virDomainFSModelTypeFromString(model)) < 0 ||
@@ -26211,6 +26231,13 @@ virDomainFSDefFormat(virBufferPtr buf,
}
if (def->multidevs)
virBufferAsprintf(buf, " multidevs='%s'", multidevs);
+
+ if (def->fmode)
+ virBufferAsprintf(buf, " fmode='%04o'", def->fmode);
+
+ if (def->dmode)
+ virBufferAsprintf(buf, " dmode='%04o'", def->dmode);
+
virBufferAddLit(buf, ">\n");
virBufferAdjustIndent(buf, 2);
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 450686dfb5..51f70f9dd4 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -849,6 +849,8 @@ struct _virDomainFSDef {
int wrpolicy; /* enum virDomainFSWrpolicy */
int format; /* virStorageFileFormat */
int model; /* virDomainFSModel */
+ unsigned int fmode;
+ unsigned int dmode;
int multidevs; /* virDomainFSMultidevs */
unsigned long long usage; /* in bytes */
virStorageSourcePtr src;
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 476cf6972e..b2da53c664 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -2275,6 +2275,12 @@ qemuBuildFSStr(virDomainFSDefPtr fs)
} else if (fs->multidevs == VIR_DOMAIN_FS_MULTIDEVS_WARN) {
virBufferAddLit(&opt, ",multidevs=warn");
}
+ if (fs->fmode) {
+ virBufferAsprintf(&opt, ",fmode=%04o", fs->fmode);
+ }
+ if (fs->dmode) {
+ virBufferAsprintf(&opt, ",dmode=%04o", fs->dmode);
+ }
} else if (fs->fsdriver == VIR_DOMAIN_FS_DRIVER_TYPE_HANDLE) {
/* removed since qemu 4.0.0 see v3.1.0-29-g93aee84f57 */
virBufferAddLit(&opt, "handle");
diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c
index a212605579..4757c55e13 100644
--- a/src/qemu/qemu_validate.c
+++ b/src/qemu/qemu_validate.c
@@ -3530,6 +3530,19 @@ qemuValidateDomainDeviceDefFS(virDomainFSDefPtr fs,
return -1;
}
+ if ((fs->fmode != 0) || (fs->dmode != 0)) {
+ if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_FSDEV_CREATEMODE)) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("fmode and dmode are not supported with this QEMU
binary"));
+ return -1;
+ }
+ if (fs->accessmode != VIR_DOMAIN_FS_ACCESSMODE_MAPPED) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("fmode and dmode must be used with
accessmode=mapped"));
+ return -1;
+ }
+ }
+
switch ((virDomainFSDriverType) fs->fsdriver) {
case VIR_DOMAIN_FS_DRIVER_TYPE_DEFAULT:
case VIR_DOMAIN_FS_DRIVER_TYPE_PATH:
@@ -3591,6 +3604,11 @@ qemuValidateDomainDeviceDefFS(virDomainFSDefPtr fs,
_("virtiofs does not support multidevs"));
return -1;
}
+ if ((fs->fmode != 0) || (fs->dmode != 0)) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("virtiofs does not support fmode and dmode"));
+ return -1;
+ }
if (qemuValidateDomainDefVirtioFSSharedMemory(def) < 0)
return -1;
break;
diff --git a/tests/qemuxml2argvdata/virtio-9p-createmode.x86_64-latest.args
b/tests/qemuxml2argvdata/virtio-9p-createmode.x86_64-latest.args
new file mode 100644
index 0000000000..c4ef07a1fd
--- /dev/null
+++ b/tests/qemuxml2argvdata/virtio-9p-createmode.x86_64-latest.args
@@ -0,0 +1,45 @@
+LC_ALL=C \
+PATH=/bin \
+HOME=/tmp/lib/domain--1-QEMUGuest1 \
+USER=test \
+LOGNAME=test \
+XDG_DATA_HOME=/tmp/lib/domain--1-QEMUGuest1/.local/share \
+XDG_CACHE_HOME=/tmp/lib/domain--1-QEMUGuest1/.cache \
+XDG_CONFIG_HOME=/tmp/lib/domain--1-QEMUGuest1/.config \
+QEMU_AUDIO_DRV=none \
+/usr/bin/qemu-system-x86_64 \
+-name guest=QEMUGuest1,debug-threads=on \
+-S \
+-object secret,id=masterKey0,format=raw,\
+file=/tmp/lib/domain--1-QEMUGuest1/master-key.aes \
+-machine pc,accel=tcg,usb=off,dump-guest-core=off \
+-cpu qemu64 \
+-m 214 \
+-overcommit mem-lock=off \
+-smp 1,sockets=1,cores=1,threads=1 \
+-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \
+-display none \
+-no-user-config \
+-nodefaults \
+-chardev socket,id=charmonitor,fd=1729,server,nowait \
+-mon chardev=charmonitor,id=monitor,mode=control \
+-rtc base=utc \
+-no-shutdown \
+-no-acpi \
+-boot strict=on \
+-device piix3-usb-uhci,id=usb,bus=pci.0,addr=0x1.0x2 \
+-fsdev local,security_model=mapped,fmode=0644,id=fsdev-fs0,path=/export/fs0 \
+-device virtio-9p-pci,id=fs0,fsdev=fsdev-fs0,mount_tag=fs0,bus=pci.0,addr=0x2 \
+-fsdev local,security_model=mapped,dmode=0755,id=fsdev-fs1,path=/export/fs1 \
+-device virtio-9p-pci,id=fs1,fsdev=fsdev-fs1,mount_tag=fs1,bus=pci.0,addr=0x3 \
+-fsdev local,security_model=mapped,fmode=0644,dmode=0755,id=fsdev-fs2,\
+path=/export/fs2 \
+-device virtio-9p-pci,id=fs2,fsdev=fsdev-fs2,mount_tag=fs2,bus=pci.0,addr=0x4 \
+-chardev pty,id=charserial0 \
+-fsdev local,security_model=mapped,id=fsdev-fs3,path=/export/fs2 \
+-device virtio-9p-pci,id=fs3,fsdev=fsdev-fs3,mount_tag=fs3,bus=pci.0,addr=0x5 \
+-device isa-serial,chardev=charserial0,id=serial0 \
+-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0xc \
+-sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,\
+resourcecontrol=deny \
+-msg timestamp=on
diff --git a/tests/qemuxml2argvdata/virtio-9p-createmode.xml
b/tests/qemuxml2argvdata/virtio-9p-createmode.xml
new file mode 100644
index 0000000000..bca9db02ad
--- /dev/null
+++ b/tests/qemuxml2argvdata/virtio-9p-createmode.xml
@@ -0,0 +1,58 @@
+<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'
fmode='644'>
+ <source dir='/export/fs0'/>
+ <target dir='fs0'/>
+ <address type='pci' domain='0x0000' bus='0x00'
slot='0x02' function='0x0'/>
+ </filesystem>
+ <filesystem type='mount' accessmode='mapped'
dmode='755'>
+ <source dir='/export/fs1'/>
+ <target dir='fs1'/>
+ <address type='pci' domain='0x0000' bus='0x00'
slot='0x03' function='0x0'/>
+ </filesystem>
+ <filesystem type='mount' accessmode='mapped' fmode='640'
dmode='750'>
+ <source dir='/export/fs2'/>
+ <target dir='fs2'/>
+ <address type='pci' domain='0x0000' bus='0x00'
slot='0x04' function='0x0'/>
+ </filesystem>
+ <filesystem type='mount' accessmode='mapped'>
+ <source dir='/export/fs3'/>
+ <target dir='fs3'/>
+ <address type='pci' domain='0x0000' bus='0x00'
slot='0x05' 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>
diff --git a/tests/qemuxml2xmloutdata/virtio-9p-createmode.x86_64-latest.xml
b/tests/qemuxml2xmloutdata/virtio-9p-createmode.x86_64-latest.xml
new file mode 100644
index 0000000000..7c374ca3a6
--- /dev/null
+++ b/tests/qemuxml2xmloutdata/virtio-9p-createmode.x86_64-latest.xml
@@ -0,0 +1,61 @@
+<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'
fmode='0644'>
+ <source dir='/export/fs0'/>
+ <target dir='fs0'/>
+ <address type='pci' domain='0x0000' bus='0x00'
slot='0x02' function='0x0'/>
+ </filesystem>
+ <filesystem type='mount' accessmode='mapped'
dmode='0755'>
+ <source dir='/export/fs1'/>
+ <target dir='fs1'/>
+ <address type='pci' domain='0x0000' bus='0x00'
slot='0x03' function='0x0'/>
+ </filesystem>
+ <filesystem type='mount' accessmode='mapped' fmode='0640'
dmode='0750'>
+ <source dir='/export/fs2'/>
+ <target dir='fs2'/>
+ <address type='pci' domain='0x0000' bus='0x00'
slot='0x04' function='0x0'/>
+ </filesystem>
+ <filesystem type='mount' accessmode='mapped'>
+ <source dir='/export/fs3'/>
+ <target dir='fs3'/>
+ <address type='pci' domain='0x0000' bus='0x00'
slot='0x05' 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>
diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c
index 2bf8dd5b14..17cbed97f9 100644
--- a/tests/qemuxml2xmltest.c
+++ b/tests/qemuxml2xmltest.c
@@ -1496,6 +1496,7 @@ mymain(void)
DO_TEST_CAPS_ARCH_LATEST("x86_64-default-cpu-tcg-q35-4.2",
"x86_64");
DO_TEST_CAPS_LATEST("virtio-9p-multidevs");
+ DO_TEST_CAPS_LATEST("virtio-9p-createmode");
DO_TEST("downscript", NONE);
cleanup:
--
2.25.1