[libvirt] [PATCH v2] Added new attribute accessmode to filesystem element
by Harsh Prateek Bora
This patch introduces new attribute to filesystem element
to support customizable access mode for mount type.
Valid accessmode are: passthrough, mapped and squash.
Usage:
<filesystem type='mount' accessmode='passthrough'>
<source dir='/export/to/guest'/>
<target dir='mount_tag'/>
</filesystem>
Here is the detailed explanation on these access modes:
Access mode: mapped
--------------------
Fileserver intercepts and maps all the file object create requests.
Files on the fileserver will be created with Fileserver's user credentials
and the
client-user's credentials are stored in extended attributes.
During getattr() server extracts the client-user's credentials from extended
attributes and sends to the client.
This adds a great deal of security in the cloud environments where the
guest's(client) user space is kept completely isolated from host's user
space.
Access mode : passthrough
--------------------------
In this security model, Fileserver passes down all requests to the
underlying filesystem. File system objects on the fileserver will be created
with client-user's credentials. This is done by setting setuid()/setgid()
during creation or chmod/chown after file creation. At the end of create
protocol
request, files on the fileserver will be owned by cleint-user's uid/gid.
This model mimic's current NFSv3 level of security.
Access mode: squash
--------------------
In 'squash' mode, the (filesystem) server attempts to preserve user/group
ownership from guest, however:
- If the server is running as root this mode is equivalent to passthrough.
- If the server is running as non-root, all files just have uid/gid matching
the server process.
Note: This patch is based on Daniel's patch to support 9pfs.
It shall be applied after applying Daniel's patch to support 9pfs.
Signed-off-by: Harsh Prateek Bora <harsh(a)linux.vnet.ibm.com>
---
v2:
- fixed compilation errors missed in v1.
docs/schemas/domain.rng | 7 +++++++
src/conf/domain_conf.c | 30 ++++++++++++++++++++++++++++--
src/conf/domain_conf.h | 11 +++++++++++
src/qemu/qemu_conf.c | 11 +++++++++--
4 files changed, 55 insertions(+), 4 deletions(-)
diff --git a/docs/schemas/domain.rng b/docs/schemas/domain.rng
index ccb8cf3..c0e5149 100644
--- a/docs/schemas/domain.rng
+++ b/docs/schemas/domain.rng
@@ -761,6 +761,13 @@
</choice>
<optional>
<ref name="address"/>
+ <attribute name="accessmode">
+ <choice>
+ <value>passthrough</value>
+ <value>mapped</value>
+ <value>squash</value>
+ </choice>
+ </attribute>
</optional>
</element>
</define>
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index e05d5d7..991b284 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",
@@ -1847,6 +1853,7 @@ virDomainFSDefParseXML(xmlNodePtr node,
char *type = NULL;
char *source = NULL;
char *target = NULL;
+ char *accessmode = NULL;
if (VIR_ALLOC(def) < 0) {
virReportOOMError();
@@ -1864,6 +1871,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) {
@@ -5602,6 +5620,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,
@@ -5609,9 +5628,16 @@ virDomainFSDefFormat(virBufferPtr buf,
return -1;
}
+ if (!accessmode) {
+ virDomainReportError(VIR_ERR_INTERNAL_ERROR,
+ _("unexpected accessmode %d"), def->accessmode);
+ return -1;
+ }
+
+
virBufferVSprintf(buf,
- " <filesystem type='%s'>\n",
- type);
+ " <filesystem type='%s' accessmode='%s'>\n",
+ type, accessmode);
if (def->src) {
switch (def->type) {
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 7195c04..0668ce5 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;
@@ -1167,6 +1177,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 18a302a..110b9e2 100644
--- a/src/qemu/qemu_conf.c
+++ b/src/qemu/qemu_conf.c
@@ -2783,11 +2783,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);
--
1.7.1.1
14 years, 1 month
[libvirt] [PATCH] Fix statstest when driver modules are enabled
by Daniel P. Berrange
The statstest is xen specific. Instead of filling the code with
a huge number of #ifdef WITH_XEN, just make its entire compilation
conditional in the Makefile.am. Also ensure it links to the Xen
driver so that it builds when driver modules are enabled
* tests/Makefile.am: Make statstest xen conditional. Link to
xen driver
* tests/Makefile.am: Remove all conditionals
---
tests/Makefile.am | 8 ++++----
tests/statstest.c | 7 -------
2 files changed, 4 insertions(+), 11 deletions(-)
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 64fac75..44fe579 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -238,6 +238,10 @@ reconnect_SOURCES = \
reconnect.c
reconnect_LDADD = $(LDADDS)
+statstest_SOURCES = \
+ statstest.c testutils.h testutils.c
+statstest_LDADD = ../src/libvirt_driver_xen.la $(LDADDS)
+
else
EXTRA_DIST += xml2sexprtest.c sexpr2xmltest.c xmconfigtest.c \
xencapstest.c reconnect.c \
@@ -328,10 +332,6 @@ nodeinfotest_SOURCES = \
nodeinfotest.c testutils.h testutils.c
nodeinfotest_LDADD = $(LDADDS)
-statstest_SOURCES = \
- statstest.c testutils.h testutils.c
-statstest_LDADD = $(LDADDS)
-
if WITH_SECDRIVER_SELINUX
seclabeltest_SOURCES = \
seclabeltest.c
diff --git a/tests/statstest.c b/tests/statstest.c
index 5fad190..551615b 100644
--- a/tests/statstest.c
+++ b/tests/statstest.c
@@ -9,15 +9,12 @@
#include "xen/block_stats.h"
#include "testutils.h"
-#if WITH_XEN
static void testQuietError(void *userData ATTRIBUTE_UNUSED,
virErrorPtr error ATTRIBUTE_UNUSED)
{
/* nada */
}
-#endif
-#if __linux__ && WITH_XEN
static int testDevice(const char *path, int expect)
{
int actual = xenLinuxDomainDeviceID(NULL, 1, path);
@@ -43,14 +40,11 @@ static int testDeviceHelper(const void *data)
return testDevice(info->dev, info->num);
}
-#endif
-
static int
mymain(int argc ATTRIBUTE_UNUSED,
char **argv ATTRIBUTE_UNUSED)
{
int ret = 0;
-#if __linux__ && WITH_XEN
/* Some of our tests delibrately test failure cases, so
* register a handler to stop error messages cluttering
* up display
@@ -201,7 +195,6 @@ mymain(int argc ATTRIBUTE_UNUSED,
DO_TEST("/dev/xvda1", 51713);
DO_TEST("/dev/xvda15", 51727);
-#endif
return(ret==0 ? EXIT_SUCCESS : EXIT_FAILURE);
}
--
1.7.2.3
14 years, 1 month
[libvirt] [PATCH] build: provide URL in 'configure --help'
by Eric Blake
* configure.ac (AC_INIT): Provide email and URL.
---
Before:
Report bugs to the package provider.
After:
Report bugs to <libvir-list(a)redhat.com>.
libvirt home page: <http://libvirt.org>.
configure.ac | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/configure.ac b/configure.ac
index b868e50..2803aa3 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,6 +1,6 @@
dnl Process this file with autoconf to produce a configure script.
-AC_INIT([libvirt], [0.8.4])
+AC_INIT([libvirt], [0.8.4], [libvir-list(a)redhat.com], [], [http://libvirt.org])
AC_CONFIG_SRCDIR([src/libvirt.c])
AC_CONFIG_AUX_DIR([build-aux])
AC_CONFIG_HEADERS([config.h])
--
1.7.2.3
14 years, 1 month
[libvirt] [PATCH] Conditionally include termios.h
by Daniel P. Berrange
The configure.ac file checks for termios.h, but its use is
not protected by HAVE_TERMIOS_H. This breaks the build on
mingw32
* src/util/util.c: Conditionally include termios.h
---
src/util/util.c | 4 +++-
1 files changed, 3 insertions(+), 1 deletions(-)
diff --git a/src/util/util.c b/src/util/util.c
index 586baee..b6b9712 100644
--- a/src/util/util.c
+++ b/src/util/util.c
@@ -43,7 +43,9 @@
#endif
#include <string.h>
#include <signal.h>
-#include <termios.h>
+#if HAVE_TERMIOS_H
+# include <termios.h>
+#endif
#include "c-ctype.h"
#ifdef HAVE_PATHS_H
--
1.7.2.3
14 years, 1 month
[libvirt] [PATCH] Added new attribute accessmode to filesystem element
by Harsh Prateek Bora
This patch introduces new attribute to filesystem element
to support customizable access mode for mount type.
Valid accessmode are: passthrough, mapped and squash.
Usage:
<filesystem type='mount' accessmode='passthrough'>
<source dir='/export/to/guest'/>
<target dir='mount_tag'/>
</filesystem>
Here is the detailed explanation on these access modes:
Access mode: mapped
--------------------
Fileserver intercepts and maps all the file object create requests.
Files on the fileserver will be created with Fileserver's user credentials
and the
client-user's credentials are stored in extended attributes.
During getattr() server extracts the client-user's credentials from extended
attributes and sends to the client.
This adds a great deal of security in the cloud environments where the
guest's(client) user space is kept completely isolated from host's user
space.
Access mode : passthrough
--------------------------
In this security model, Fileserver passes down all requests to the
underlying filesystem. File system objects on the fileserver will be created
with client-user's credentials. This is done by setting setuid()/setgid()
during creation or chmod/chown after file creation. At the end of create
protocol
request, files on the fileserver will be owned by cleint-user's uid/gid.
This model mimic's current NFSv3 level of security.
Access mode: squash
--------------------
In 'squash' mode, the (filesystem) server attempts to preserve user/group
ownership from guest, however:
- If the server is running as root this mode is equivalent to passthrough.
- If the server is running as non-root, all files just have uid/gid matching
the server process.
Note: This patch is based on Daniel's patch to support 9pfs.
It shall be applied after applying Daniel's patch to support 9pfs.
Signed-off-by: Harsh Prateek Bora <harsh(a)linux.vnet.ibm.com>
---
docs/schemas/domain.rng | 7 +++++++
src/conf/domain_conf.c | 30 ++++++++++++++++++++++++++++--
src/conf/domain_conf.h | 11 +++++++++++
src/qemu/qemu_conf.c | 10 ++++++++--
4 files changed, 54 insertions(+), 4 deletions(-)
diff --git a/docs/schemas/domain.rng b/docs/schemas/domain.rng
index ccb8cf3..c0e5149 100644
--- a/docs/schemas/domain.rng
+++ b/docs/schemas/domain.rng
@@ -761,6 +761,13 @@
</choice>
<optional>
<ref name="address"/>
+ <attribute name="accessmode">
+ <choice>
+ <value>passthrough</value>
+ <value>mapped</value>
+ <value>squash</value>
+ </choice>
+ </attribute>
</optional>
</element>
</define>
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index e05d5d7..68c8441 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_SECURITY_LAST,
+ "passthrough",
+ "mapped",
+ "squash")
+
+
VIR_ENUM_IMPL(virDomainNet, VIR_DOMAIN_NET_TYPE_LAST,
"user",
"ethernet",
@@ -1847,6 +1853,7 @@ virDomainFSDefParseXML(xmlNodePtr node,
char *type = NULL;
char *source = NULL;
char *target = NULL;
+ char *accessmode = NULL;
if (VIR_ALLOC(def) < 0) {
virReportOOMError();
@@ -1864,6 +1871,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) {
@@ -5602,6 +5620,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,
@@ -5609,9 +5628,16 @@ virDomainFSDefFormat(virBufferPtr buf,
return -1;
}
+ if (!accessmode) {
+ virDomainReportError(VIR_ERR_INTERNAL_ERROR,
+ _("unexpected accessmode %d"), def->accessmode);
+ return -1;
+ }
+
+
virBufferVSprintf(buf,
- " <filesystem type='%s'>\n",
- type);
+ " <filesystem type='%s' accessmode='%s'>\n",
+ type, accessmode);
if (def->src) {
switch (def->type) {
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 7195c04..0668ce5 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;
@@ -1167,6 +1177,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 18a302a..0961d8a 100644
--- a/src/qemu/qemu_conf.c
+++ b/src/qemu/qemu_conf.c
@@ -2783,11 +2783,17 @@ 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_SQUASH) {
+ virBufferAddLit(&opt, ",security_model=none");
+ } else {
+ virBufferAddLit(&opt, ",security_model=%s",
+ virDomainFSAccessModeTypeToString(fs->accessmode));
+ }
virBufferVSprintf(&opt, ",id=%s%s", QEMU_FSDEV_HOST_PREFIX, fs->info.alias);
virBufferVSprintf(&opt, ",path=%s", fs->src);
--
1.7.1.1
14 years, 1 month
[libvirt] [PATCH] qemu: Prohibit migration of guests with host devices
by Jiri Denemark
Explicitly raising a nice error in the case user tries to migrate a
guest with assigned host devices is much better than waiting for a
mysterious error with no clue for the reason.
---
src/qemu/qemu_driver.c | 19 +++++++++++++++++++
1 files changed, 19 insertions(+), 0 deletions(-)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index f68995f..16f34f7 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -10380,6 +10380,19 @@ static void qemuDomainEventQueue(struct qemud_driver *driver,
/* Migration support. */
+static bool ATTRIBUTE_NONNULL(1)
+qemuDomainIsMigratable(virDomainDefPtr def)
+{
+ if (def->nhostdevs > 0) {
+ qemuReportError(VIR_ERR_OPERATION_INVALID,
+ _("Domain with assigned host devices cannot be migrated"));
+ return false;
+ }
+
+ return true;
+}
+
+
/* Tunnelled migration stream support */
struct qemuStreamMigFile {
int fd;
@@ -10709,6 +10722,9 @@ qemudDomainMigratePrepareTunnel(virConnectPtr dconn,
goto cleanup;
}
+ if (!qemuDomainIsMigratable(def))
+ goto cleanup;
+
/* Target domain name, maybe renamed. */
if (dname) {
VIR_FREE(def->name);
@@ -10976,6 +10992,9 @@ qemudDomainMigratePrepare2 (virConnectPtr dconn,
goto cleanup;
}
+ if (!qemuDomainIsMigratable(def))
+ goto cleanup;
+
/* Target domain name, maybe renamed. */
if (dname) {
VIR_FREE(def->name);
--
1.7.3.1
14 years, 1 month
[libvirt] Xen string2sexpr and sexpr2string lose quotes?
by Thomas Graves
Hello all,
I am running xen on rhel5 and using libvirt0.7.2 (I also tried 0.7.7) and it
looks like the routines string2sexpr and sexpr2string seem to lose the
quotes around the image args in the configuration.
Has anyone seen this and have a patch for this?
I have the following libvirt config:
<os>
<type>linux</type>
<kernel>/usr/lib/xen/boot/pv-grub-x86_64.gz</kernel>
<cmdline>(hd0,0)/grub/menu.lst</cmdline>
</os>
It generates the xm config info:
(image
(linux
(kernel /usr/lib/xen/boot/pv-grub-x86_64.gz)
(args '(hd0,0)/grub/menu.lst')
(device_model /usr/lib64/xen/bin/qemu-dm)
)
)
I call virDomainSetAutostart on the domain and traced it through and saw
that it gets the string quoted (args '(hd0,0)/grub/menu.lst') from xen then
ends up calling string2sexpr, changes the xend_on_start, and then
sexpr2string, and it ends up without quotes (args (hd0,0)/grub/menu.lst) and
that is what it sends back to xen. Xen then seems to chop it off to (args
('hd0,0'))
Thanks,
Tom
14 years, 1 month
[libvirt] [PATCH] Improve error reporting in test suites
by Daniel P. Berrange
Before running each test case clear the thread local error
indicator. After running each test case, dispatch any error
that was reported
* tests/testutils.c: Fix error reporting in test suites
---
tests/testutils.c | 4 ++++
1 files changed, 4 insertions(+), 0 deletions(-)
diff --git a/tests/testutils.c b/tests/testutils.c
index 8171f10..70e7538 100644
--- a/tests/testutils.c
+++ b/tests/testutils.c
@@ -124,8 +124,12 @@ virtTestRun(const char *title, int nloops, int (*body)(const void *data), const
if (ts)
GETTIMEOFDAY(&before);
+ virResetLastError();
if ((ret = body(data)) != 0)
break;
+ virErrorPtr err = virGetLastError();
+ if (err)
+ virDispatchError(NULL);
if (ts) {
GETTIMEOFDAY(&after);
ts[i] = DIFF_MSEC(&after, &before);
--
1.7.2.3
14 years, 1 month