diff --git a/.gnulib b/.gnulib
index b6d1430494cdd252cd52eca6abf88b1a00f6c983..2bb63bfb25474ea147ee9f1523c0337997359a4c 160000
--- a/.gnulib
+++ b/.gnulib
@@ -1 +1 @@
-Subproject commit b6d1430494cdd252cd52eca6abf88b1a00f6c983
+Subproject commit 2bb63bfb25474ea147ee9f1523c0337997359a4c
diff --git a/docs/schemas/domain.rng b/docs/schemas/domain.rng
index 1cb77bba119596e2f71906ed1211bf8a3af333af..f230263c946fb0b2245aec37d81b22c82085edc9 100644
--- a/docs/schemas/domain.rng
+++ b/docs/schemas/domain.rng
@@ -794,6 +794,13 @@
+
+
+ passthrough
+ mapped
+ squash
+
+
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 23ccaff29b5bf1d8f24299d7642f39059da31572..ad8085f79f4990652fcabd1698dba33aa8f9ab3b 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -161,6 +161,12 @@ VIR_ENUM_IMPL(virDomainFS, VIR_DOMAIN_FS_TYPE_LAST,
"file",
"template")
+VIR_ENUM_IMPL(virDomainFSAccessMode, VIR_DOMAIN_FS_ACCESSMODE_LAST,
+ "passthrough",
+ "mapped",
+ "squash")
+
+
VIR_ENUM_IMPL(virDomainNet, VIR_DOMAIN_NET_TYPE_LAST,
"user",
"ethernet",
@@ -1853,6 +1859,7 @@ virDomainFSDefParseXML(xmlNodePtr node,
char *type = NULL;
char *source = NULL;
char *target = NULL;
+ char *accessmode = NULL;
if (VIR_ALLOC(def) < 0) {
virReportOOMError();
@@ -1870,6 +1877,17 @@ virDomainFSDefParseXML(xmlNodePtr node,
def->type = VIR_DOMAIN_FS_TYPE_MOUNT;
}
+ accessmode = virXMLPropString(node, "accessmode");
+ if (accessmode) {
+ if ((def->accessmode = virDomainFSAccessModeTypeFromString(accessmode)) < 0) {
+ virDomainReportError(VIR_ERR_INTERNAL_ERROR,
+ _("unknown accessmode '%s'"), accessmode);
+ goto error;
+ }
+ } else {
+ def->accessmode = VIR_DOMAIN_FS_ACCESSMODE_PASSTHROUGH;
+ }
+
cur = node->children;
while (cur != NULL) {
if (cur->type == XML_ELEMENT_NODE) {
@@ -1918,6 +1936,7 @@ cleanup:
VIR_FREE(type);
VIR_FREE(target);
VIR_FREE(source);
+ VIR_FREE(accessmode);
return def;
@@ -5625,6 +5644,7 @@ virDomainFSDefFormat(virBufferPtr buf,
int flags)
{
const char *type = virDomainFSTypeToString(def->type);
+ const char *accessmode = virDomainFSAccessModeTypeToString(def->accessmode);
if (!type) {
virDomainReportError(VIR_ERR_INTERNAL_ERROR,
@@ -5632,9 +5652,16 @@ virDomainFSDefFormat(virBufferPtr buf,
return -1;
}
+ if (!accessmode) {
+ virDomainReportError(VIR_ERR_INTERNAL_ERROR,
+ _("unexpected accessmode %d"), def->accessmode);
+ return -1;
+ }
+
+
virBufferVSprintf(buf,
- " \n",
- type);
+ " \n",
+ type, accessmode);
if (def->src) {
switch (def->type) {
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 7c5215f5807789769bcc0745923c0f37fcf55b0b..db09c23bb53325657528fa2e497ff3431b4a01e0 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -236,10 +236,20 @@ enum virDomainFSType {
VIR_DOMAIN_FS_TYPE_LAST
};
+/* Filesystem mount access mode */
+enum virDomainFSAccessMode {
+ VIR_DOMAIN_FS_ACCESSMODE_PASSTHROUGH,
+ VIR_DOMAIN_FS_ACCESSMODE_MAPPED,
+ VIR_DOMAIN_FS_ACCESSMODE_SQUASH,
+
+ VIR_DOMAIN_FS_ACCESSMODE_LAST
+};
+
typedef struct _virDomainFSDef virDomainFSDef;
typedef virDomainFSDef *virDomainFSDefPtr;
struct _virDomainFSDef {
int type;
+ int accessmode;
char *src;
char *dst;
unsigned int readonly : 1;
@@ -1175,6 +1185,7 @@ VIR_ENUM_DECL(virDomainDiskErrorPolicy)
VIR_ENUM_DECL(virDomainController)
VIR_ENUM_DECL(virDomainControllerModel)
VIR_ENUM_DECL(virDomainFS)
+VIR_ENUM_DECL(virDomainFSAccessMode)
VIR_ENUM_DECL(virDomainNet)
VIR_ENUM_DECL(virDomainChrDevice)
VIR_ENUM_DECL(virDomainChrChannelTarget)
diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c
index de14f92d06173003686546da8b9c07a149fd0a0a..83c0f8370d9ccf7777fa63e8d3c1f96d24c05395 100644
--- a/src/qemu/qemu_conf.c
+++ b/src/qemu/qemu_conf.c
@@ -2789,11 +2789,18 @@ char *qemuBuildFSStr(virDomainFSDefPtr fs,
if (fs->type != VIR_DOMAIN_FS_TYPE_MOUNT) {
qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
- _("can only passthrough directories"));
+ _("only supports mount filesystem type"));
goto error;
}
- virBufferAddLit(&opt, "local,security_model=passthrough");
+ virBufferAddLit(&opt, "local");
+ if (fs->accessmode == VIR_DOMAIN_FS_ACCESSMODE_MAPPED) {
+ virBufferAddLit(&opt, ",security_model=mapped");
+ } else if(fs->accessmode == VIR_DOMAIN_FS_ACCESSMODE_PASSTHROUGH) {
+ virBufferAddLit(&opt, ",security_model=passthrough");
+ } else if(fs->accessmode == VIR_DOMAIN_FS_ACCESSMODE_SQUASH) {
+ virBufferAddLit(&opt, ",security_model=none");
+ }
virBufferVSprintf(&opt, ",id=%s%s", QEMU_FSDEV_HOST_PREFIX, fs->info.alias);
virBufferVSprintf(&opt, ",path=%s", fs->src);