Devel
Threads by month
- ----- 2026 -----
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- 38 participants
- 40039 discussions
03 Mar '09
The remote driver additions for the sVirt APIs pre-date the time when we
added thread support, and I didn't notice they were mising the lock calls.
This patch adds the missing lock calls, so 'virsh dominfo' doesn't hang
anymore due to an unlock without initial lock. It also fixes two return
values to be -1 rather than -2
Daniel
Index: src/libvirt.c
===================================================================
RCS file: /data/cvs/libvirt/src/libvirt.c,v
retrieving revision 1.198
diff -u -p -r1.198 libvirt.c
--- src/libvirt.c 3 Mar 2009 09:14:28 -0000 1.198
+++ src/libvirt.c 3 Mar 2009 18:32:25 -0000
@@ -4206,7 +4206,7 @@ virDomainGetSecurityLabel(virDomainPtr d
return conn->driver->domainGetSecurityLabel(domain, seclabel);
virLibConnWarning(conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
- return -2;
+ return -1;
}
/**
@@ -4236,7 +4236,7 @@ virNodeGetSecurityModel(virConnectPtr co
return conn->driver->nodeGetSecurityModel(conn, secmodel);
virLibConnWarning(conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
- return -2;
+ return -1;
}
/**
Index: src/remote_internal.c
===================================================================
RCS file: /data/cvs/libvirt/src/remote_internal.c,v
retrieving revision 1.140
diff -u -p -r1.140 remote_internal.c
--- src/remote_internal.c 3 Mar 2009 09:27:03 -0000 1.140
+++ src/remote_internal.c 3 Mar 2009 18:32:25 -0000
@@ -2302,26 +2302,33 @@ remoteDomainGetSecurityLabel (virDomainP
remote_domain_get_security_label_args args;
remote_domain_get_security_label_ret ret;
struct private_data *priv = domain->conn->privateData;
+ int rv = -1;
+
+ remoteDriverLock(priv);
make_nonnull_domain (&args.dom, domain);
memset (&ret, 0, sizeof ret);
if (call (domain->conn, priv, 0, REMOTE_PROC_DOMAIN_GET_SECURITY_LABEL,
(xdrproc_t) xdr_remote_domain_get_security_label_args, (char *)&args,
(xdrproc_t) xdr_remote_domain_get_security_label_ret, (char *)&ret) == -1) {
- return -1;
+ goto done;
}
if (ret.label.label_val != NULL) {
if (strlen (ret.label.label_val) >= sizeof seclabel->label) {
errorf (domain->conn, VIR_ERR_RPC, _("security label exceeds maximum: %zd"),
sizeof seclabel->label - 1);
- return -1;
+ goto done;
}
strcpy (seclabel->label, ret.label.label_val);
seclabel->enforcing = ret.enforcing;
}
- return 0;
+ rv = 0;
+
+done:
+ remoteDriverUnlock(priv);
+ return rv;
}
static int
@@ -2329,19 +2336,22 @@ remoteNodeGetSecurityModel (virConnectPt
{
remote_node_get_security_model_ret ret;
struct private_data *priv = conn->privateData;
+ int rv = -1;
+
+ remoteDriverLock(priv);
memset (&ret, 0, sizeof ret);
if (call (conn, priv, 0, REMOTE_PROC_NODE_GET_SECURITY_MODEL,
(xdrproc_t) xdr_void, NULL,
(xdrproc_t) xdr_remote_node_get_security_model_ret, (char *)&ret) == -1) {
- return -1;
+ goto done;
}
if (ret.model.model_val != NULL) {
if (strlen (ret.model.model_val) >= sizeof secmodel->model) {
errorf (conn, VIR_ERR_RPC, _("security model exceeds maximum: %zd"),
sizeof secmodel->model - 1);
- return -1;
+ goto done;
}
strcpy (secmodel->model, ret.model.model_val);
}
@@ -2350,11 +2360,16 @@ remoteNodeGetSecurityModel (virConnectPt
if (strlen (ret.doi.doi_val) >= sizeof secmodel->doi) {
errorf (conn, VIR_ERR_RPC, _("security doi exceeds maximum: %zd"),
sizeof secmodel->doi - 1);
- return -1;
+ goto done;
}
strcpy (secmodel->doi, ret.doi.doi_val);
}
- return 0;
+
+ rv = 0;
+
+done:
+ remoteDriverUnlock(priv);
+ return rv;
}
static char *
--
|: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :|
|: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :|
|: http://autobuild.org -o- http://search.cpan.org/~danberr/ :|
|: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|
2
1
03 Mar '09
Hello everyone,
I'm working on a open source project (http://www.hynesim.org) in which
we needed libvirt-like functionalities. As at the time, libvirt did not
support OpenVZ, and it did not support VirtualBox, we went and
implemented our own wrappers around Kvm/Qemu, VirtualBox and OpenVz
(Honeyd too, but our wrapper is such an ugly hack that it doesn't really
deserve mention).
Now that time has passed, we'd would like to stop duplicating efforts,
and use libvirt instead, and concentrate on more innovating
functionalities for Hynesim. Also our wrappers are terrible hacks, and
do a lot less error checking than libvirt :)
But before I can replace our wrappers with libvirt, we're missing some
functionalities (that I will propose a patch for if required), and there
are a few questions concerning libvirt I've not managed to find an
answer for, so I'd be very grateful if I could get some advice on them.
Here goes:
-------
Is it possible to add a device for any type of domain that would
correspond to a TAP device on the host, and would be seen as a regular
ethernet interface with a specific MAC address in the virtualized domain ?
The "raw" commands to achieve that in OpenVZ and Qemu, for example, are:
# kvm ... -net nic,macaddr=00:11:22:33:44:55 -net tap,ifname=tap0,script=no
# vzctl set 100 --netif_add eth0,00:11:22:33:44:55,tap0
Is that doable in every driver supported by libvirt ?
-------
Is the libvirtd daemon necessary for drivers other than Qemu ?
I've been using the openvz driver alone for some tests (by connecting to
"openvz:///system"), and yet I get warning messages:
# sudo ./hellolibvirt openvz:///system
Attempting to connect to hypervisor
libvir: Remote error : unable to connect to
'/var/run/libvirt/libvirt-sock': No such file or directory
libvir: warning : Failed to find the network: Is the daemon running ?
libvir: Remote error : unable to connect to
'/var/run/libvirt/libvirt-sock': No such file or directory
libvir: Remote error : unable to connect to
'/var/run/libvirt/libvirt-sock': No such file or directory
libvir: warning : Failed to find a node driver: Is the libvirtd daemon
running ?
Connected to hypervisor at "openvz:///system"
Hypervisor: "OpenVZ" version: 3.0.22
There are 0 active and 1 inactive domains
Inactive domains:
897
Disconnected from hypervisor
The libvirtd daemon is indeed not running, as I don't see why it should
be: I thought it was only useful for qemu guests. Am I right ?
What is the role of the daemon exactly ?
-------
Apparently the only way to start an OpenVZ domain is by specifying a
template. Only problem is, when the VE is stopped, and undefined, all
modifications are lost in the "private" file system of the VE (as it is
deleted). The way we circumvented this in Hynesim is by specifying the
--private option to "vzctl create" instead of the --ostemplate one.
That way one can specify a dir that will be used directly as the
filesystem for the VE.
I was thinking maybe adding something along the lines of:
<filesystem type='directory'>
<source name='/path/to/ve/filesystem' />
<target dir='/'/>
</filesystem>
would do the trick. It looks simple enough to implement, so should I ?
-------
Is there support in libvirt of "cloning" (duplicating a VM disk
/filesystem) ?
-------
Someone mentioned a VirtualBox driver. I'm highly interested in this.
How is it going ? I'd be more than happy to beta test if required. Will
it work with both PUEL and OSE versions ? When will it be ready for
inclusion in libvirt ? How will you handle RDP access, as from what I
saw only VNC is supported in libvirt currently ?
-------
And last but not least, what are "node devices" ? The two pages about it
are blank in the documentation. Are they the host machine, or a device
of the host machine ?
-------
I think that's all.
Thank you for reading all this,
Florian
1
0
pread() and pwrite() do not exist on mingw, and the nodedevxml2xmltest
was adding libvirt_driver_qemu.la for some unknown reason - probably a
cut & paste error. This broke the test compile when qemu was turned off
as it is on mingw32.
Daniel
diff --git a/src/pci.c b/src/pci.c
--- a/src/pci.c
+++ b/src/pci.c
@@ -156,7 +156,8 @@ pciRead(pciDevice *dev, unsigned pos, ui
if (pciOpenConfig(dev) < 0)
return -1;
- if (pread(dev->fd, buf, buflen, pos) < 0) {
+ if (lseek(dev->fd, pos, SEEK_SET) != pos ||
+ read(dev->fd, buf, buflen) < 0) {
char ebuf[1024];
VIR_WARN(_("Failed to read from '%s' : %s"), dev->path,
virStrerror(errno, ebuf, sizeof(ebuf)));
@@ -195,7 +196,8 @@ pciWrite(pciDevice *dev, unsigned pos, u
if (pciOpenConfig(dev) < 0)
return -1;
- if (pwrite(dev->fd, buf, buflen, pos) < 0) {
+ if (lseek(dev->fd, pos, SEEK_SET) != pos ||
+ write(dev->fd, buf, buflen) < 0) {
char ebuf[1024];
VIR_WARN(_("Failed to write to '%s' : %s"), dev->path,
virStrerror(errno, ebuf, sizeof(ebuf)));
diff --git a/tests/Makefile.am b/tests/Makefile.am
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -185,7 +185,7 @@ endif
nodedevxml2xmltest_SOURCES = \
nodedevxml2xmltest.c \
testutils.c testutils.h
-nodedevxml2xmltest_LDADD = ../src/libvirt_driver_qemu.la $(LDADDS)
+nodedevxml2xmltest_LDADD = $(LDADDS)
virshtest_SOURCES = \
virshtest.c \
--
|: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :|
|: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :|
|: http://autobuild.org -o- http://search.cpan.org/~danberr/ :|
|: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|
3
4
[libvirt] PATCH: Mark <seclabel> as dynamic generated, or statically pre-defined
by Daniel P. Berrange 03 Mar '09
by Daniel P. Berrange 03 Mar '09
03 Mar '09
This patch implements the behaviour I was refering to earlier, whereby
the domain XML explicitly says whether the security label is a statically
pre-defined one, or dynamically generated on VM boot by libvirtd
So when creating a new guest, apps like virt-install have 2 options:
- Leave out the <seclabel> tag completely
-> If no security driver is active, just works as normal unconfined VM
-> If a security driver is active, a dynamic seclabel is generated
<seclabel type='dynamic' model='selinux'>
<label>system_u:system_r:qemu_t:s0:c424,c719</label>
<imagelabel>system_u:object_r:virt_image_t:s0:c424,c719</imagelabel>
</seclabel>
- Add an explicit <seclabel> tag with type='static' attribute
-> Security driver uses the defined label & imagelabel
<seclabel type='static' model='selinux'>
<label>system_u:system_r:qemu_t:s0:c25,c100</label>
<imagelabel>system_u:system_r:virt_image_t:s0:c25,c100</imagelabel>
</seclabel>
A static seclabel is visible in the XML, at all times, whether the VM is
active or inactive.
A dynamic seclabel is only visible when the VM is running, since it is
auto-generated at VM boot. If you migrate the VM, or save/restore it,
the dynamic seclabel will change on each boot. The seclabel isn't visible
when not running, or if asking for the inactive XML dump
This patch implements parsing of the 'type' attribute, and makes the
seclabel generation key off this attribute.
It also adds the 'imagelabel' XML element, since that was being used
internally, but was not including in the XML output, or parsing
routines, making it impossible to specify a pre-defined image label
or see the dyanmic one
domain_conf.c | 65 +++++++++++++++++++++++++++++++++++++++++++----------
domain_conf.h | 9 +++++++
qemu_driver.c | 13 ++++++++--
security_selinux.c | 1
4 files changed, 73 insertions(+), 15 deletions(-)
Daniel
Index: src/domain_conf.c
===================================================================
RCS file: /data/cvs/libvirt/src/domain_conf.c,v
retrieving revision 1.70
diff -u -p -r1.70 domain_conf.c
--- src/domain_conf.c 3 Mar 2009 09:44:42 -0000 1.70
+++ src/domain_conf.c 3 Mar 2009 15:36:02 -0000
@@ -168,6 +168,10 @@ VIR_ENUM_IMPL(virDomainState, VIR_DOMAIN
"shutoff",
"crashed")
+VIR_ENUM_IMPL(virDomainSeclabel, VIR_DOMAIN_SECLABEL_LAST,
+ "dynamic",
+ "static")
+
#define virDomainReportError(conn, code, fmt...) \
virReportErrorHelper(conn, VIR_FROM_DOMAIN, code, __FILE__, \
__FUNCTION__, __LINE__, fmt)
@@ -1847,24 +1851,46 @@ static int virDomainLifecycleParseXML(vi
static int
virSecurityLabelDefParseXML(virConnectPtr conn,
const virDomainDefPtr def,
- xmlXPathContextPtr ctxt)
+ xmlXPathContextPtr ctxt,
+ int flags)
{
char *p;
if (virXPathNode(conn, "./seclabel", ctxt) == NULL)
return 0;
- p = virXPathStringLimit(conn, "string(./seclabel/label[1])",
+ p = virXPathStringLimit(conn, "string(./seclabel/@type)",
VIR_SECURITY_LABEL_BUFLEN-1, ctxt);
if (p == NULL)
goto error;
- def->seclabel.label = p;
-
- p = virXPathStringLimit(conn, "string(./seclabel/@model)",
- VIR_SECURITY_MODEL_BUFLEN-1, ctxt);
- if (p == NULL)
+ if ((def->seclabel.type = virDomainSeclabelTypeFromString(p)) < 0)
goto error;
- def->seclabel.model = p;
+ VIR_FREE(p);
+
+ /* Only parse details, if using static labels, or
+ * if the 'live' VM XML is requested
+ */
+ if (def->seclabel.type == VIR_DOMAIN_SECLABEL_STATIC ||
+ !(flags & VIR_DOMAIN_XML_INACTIVE)) {
+ p = virXPathStringLimit(conn, "string(./seclabel/@model)",
+ VIR_SECURITY_MODEL_BUFLEN-1, ctxt);
+ if (p == NULL)
+ goto error;
+ def->seclabel.model = p;
+
+ p = virXPathStringLimit(conn, "string(./seclabel/label[1])",
+ VIR_SECURITY_LABEL_BUFLEN-1, ctxt);
+ if (p == NULL)
+ goto error;
+ def->seclabel.label = p;
+
+ p = virXPathStringLimit(conn, "string(./seclabel/imagelabel[1])",
+ VIR_SECURITY_LABEL_BUFLEN-1, ctxt);
+ if (p == NULL)
+ goto error;
+ def->seclabel.imagelabel = p;
+
+ }
return 0;
@@ -2458,7 +2484,7 @@ static virDomainDefPtr virDomainDefParse
VIR_FREE(nodes);
/* analysis of security label */
- if (virSecurityLabelDefParseXML(conn, def, ctxt) == -1)
+ if (virSecurityLabelDefParseXML(conn, def, ctxt, flags) == -1)
goto error;
return def;
@@ -3480,9 +3506,24 @@ char *virDomainDefFormat(virConnectPtr c
virBufferAddLit(&buf, " </devices>\n");
if (def->seclabel.model) {
- virBufferEscapeString(&buf, " <seclabel model='%s'>\n", def->seclabel.model);
- virBufferEscapeString(&buf, " <label>%s</label>\n", def->seclabel.label);
- virBufferAddLit(&buf, " </seclabel>\n");
+ const char *sectype = virDomainSeclabelTypeToString(def->seclabel.type);
+ if (!sectype)
+ goto cleanup;
+ if (!def->seclabel.label ||
+ (def->seclabel.type == VIR_DOMAIN_SECLABEL_DYNAMIC &&
+ (flags & VIR_DOMAIN_XML_INACTIVE))) {
+ virBufferVSprintf(&buf, " <seclabel type='%s' model='%s'/>\n",
+ sectype, def->seclabel.model);
+ } else {
+ virBufferVSprintf(&buf, " <seclabel type='%s' model='%s'>\n",
+ sectype, def->seclabel.model);
+ virBufferEscapeString(&buf, " <label>%s</label>\n",
+ def->seclabel.label);
+ if (def->seclabel.imagelabel)
+ virBufferEscapeString(&buf, " <imagelabel>%s</imagelabel>\n",
+ def->seclabel.imagelabel);
+ virBufferAddLit(&buf, " </seclabel>\n");
+ }
}
virBufferAddLit(&buf, "</domain>\n");
Index: src/domain_conf.h
===================================================================
RCS file: /data/cvs/libvirt/src/domain_conf.h,v
retrieving revision 1.39
diff -u -p -r1.39 domain_conf.h
--- src/domain_conf.h 3 Mar 2009 09:44:42 -0000 1.39
+++ src/domain_conf.h 3 Mar 2009 15:36:02 -0000
@@ -410,6 +410,13 @@ struct _virDomainOSDef {
char *bootloaderArgs;
};
+enum virDomainSeclabelType {
+ VIR_DOMAIN_SECLABEL_DYNAMIC,
+ VIR_DOMAIN_SECLABEL_STATIC,
+
+ VIR_DOMAIN_SECLABEL_LAST,
+};
+
/* Security configuration for domain */
typedef struct _virSecurityLabelDef virSecurityLabelDef;
typedef virSecurityLabelDef *virSecurityLabelDefPtr;
@@ -417,6 +424,7 @@ struct _virSecurityLabelDef {
char *model; /* name of security model */
char *label; /* security label string */
char *imagelabel; /* security image label string */
+ int type;
};
#define VIR_DOMAIN_CPUMASK_LEN 1024
@@ -650,5 +658,6 @@ VIR_ENUM_DECL(virDomainInputBus)
VIR_ENUM_DECL(virDomainGraphics)
/* from libvirt.h */
VIR_ENUM_DECL(virDomainState)
+VIR_ENUM_DECL(virDomainSeclabel)
#endif /* __DOMAIN_CONF_H */
Index: src/qemu_driver.c
===================================================================
RCS file: /data/cvs/libvirt/src/qemu_driver.c,v
retrieving revision 1.213
diff -u -p -r1.213 qemu_driver.c
--- src/qemu_driver.c 3 Mar 2009 15:18:24 -0000 1.213
+++ src/qemu_driver.c 3 Mar 2009 15:36:02 -0000
@@ -1314,9 +1314,9 @@ static int qemudStartVMDaemon(virConnect
hookData.vm = vm;
hookData.driver = driver;
- /* If you are using a SecurityDriver and there was no security label in
- database, then generate a security label for isolation */
- if (vm->def->seclabel.label == NULL &&
+ /* If you are using a SecurityDriver with dynamic labelling,
+ then generate a security label for isolation */
+ if (vm->def->seclabel.type == VIR_DOMAIN_SECLABEL_DYNAMIC &&
driver->securityDriver &&
driver->securityDriver->domainGenSecurityLabel &&
driver->securityDriver->domainGenSecurityLabel(conn, vm) < 0)
@@ -1525,6 +1525,13 @@ static void qemudShutdownVMDaemon(virCon
if (driver->securityDriver)
driver->securityDriver->domainRestoreSecurityLabel(conn, vm);
+ /* Clear out dynamically assigned labels */
+ if (vm->def->seclabel.type == VIR_DOMAIN_SECLABEL_DYNAMIC) {
+ VIR_FREE(vm->def->seclabel.model);
+ VIR_FREE(vm->def->seclabel.label);
+ VIR_FREE(vm->def->seclabel.imagelabel);
+ }
+
if (qemudRemoveDomainStatus(conn, driver, vm) < 0) {
VIR_WARN(_("Failed to remove domain status for %s"),
vm->def->name);
Index: src/security_selinux.c
===================================================================
RCS file: /data/cvs/libvirt/src/security_selinux.c,v
retrieving revision 1.2
diff -u -p -r1.2 security_selinux.c
--- src/security_selinux.c 3 Mar 2009 15:18:24 -0000 1.2
+++ src/security_selinux.c 3 Mar 2009 15:36:02 -0000
@@ -161,6 +161,7 @@ SELinuxGenSecurityLabel(virConnectPtr co
char *scontext = NULL;
int c1 = 0;
int c2 = 0;
+
if ( ( vm->def->seclabel.label ) ||
( vm->def->seclabel.model ) ||
( vm->def->seclabel.imagelabel )) {
--
|: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :|
|: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :|
|: http://autobuild.org -o- http://search.cpan.org/~danberr/ :|
|: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|
3
3
>From 5cdfbefc15f81b3be7e2d60b3d173fdb2352a83c Mon Sep 17 00:00:00 2001
From: Jim Meyering <meyering(a)redhat.com>
Date: Tue, 3 Mar 2009 15:58:49 +0100
Subject: [PATCH] config: fix a typo
* src/qemu_conf.c (CHECK_TYPE): Fix typo:
s/security_river/security_driver/
---
src/qemu_conf.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/src/qemu_conf.c b/src/qemu_conf.c
index 71fed5a..03f710f 100644
--- a/src/qemu_conf.c
+++ b/src/qemu_conf.c
@@ -152,7 +152,7 @@ int qemudLoadDriverConfig(struct qemud_driver *driver,
}
p = virConfGetValue (conf, "security_driver");
- CHECK_TYPE ("security_river", VIR_CONF_STRING);
+ CHECK_TYPE ("security_driver", VIR_CONF_STRING);
if (p && p->str) {
if (!(driver->securityDriverName = strdup(p->str))) {
virReportOOMError(NULL);
--
1.6.2.rc1.285.gc5f54
2
1
03 Mar '09
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Is this acceptable to upstream?
Dan
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (GNU/Linux)
Comment: Using GnuPG with Fedora - http://enigmail.mozdev.org
iEYEARECAAYFAkma48EACgkQrlYvE4MpobMSBwCfXJnrlgoM0CuwdxF8BzcoQVvr
5pIAoNcKSrh+YsxNMjk8RgM4E7feUc4R
=iLJG
-----END PGP SIGNATURE-----
diff -up libvirt-0.6.0/include/libvirt/libvirt.h.in.svirt libvirt-0.6.0/include/libvirt/libvirt.h.in
--- libvirt-0.6.0/include/libvirt/libvirt.h.in.svirt 2009-01-20 08:48:27.000000000 -0500
+++ libvirt-0.6.0/include/libvirt/libvirt.h.in 2009-02-17 10:07:06.215686000 -0500
@@ -111,6 +111,68 @@ typedef enum {
} virDomainCreateFlags;
/**
+ * VIR_SECURITY_LABEL_BUFLEN:
+ *
+ * Macro providing the maximum length of the virSecurityLabel label string.
+ * Note that this value is based on that used by Labeled NFS.
+ */
+#define VIR_SECURITY_LABEL_BUFLEN (4096 + 1)
+
+/**
+ * virSecurityLabel:
+ *
+ * a virSecurityLabel is a structure filled by virDomainGetSecurityLabel(),
+ * providing the security label and associated attributes for the specified
+ * domain.
+ *
+ */
+typedef struct _virSecurityLabel {
+ char label[VIR_SECURITY_LABEL_BUFLEN]; /* security label string */
+ int enforcing; /* 1 if security policy is being enforced for domain */
+} virSecurityLabel;
+
+/**
+ * virSecurityLabelPtr:
+ *
+ * a virSecurityLabelPtr is a pointer to a virSecurityLabel.
+ */
+typedef virSecurityLabel *virSecurityLabelPtr;
+
+/**
+ * VIR_SECURITY_MODEL_BUFLEN:
+ *
+ * Macro providing the maximum length of the virSecurityModel model string.
+ */
+#define VIR_SECURITY_MODEL_BUFLEN (256 + 1)
+
+/**
+ * VIR_SECURITY_DOI_BUFLEN:
+ *
+ * Macro providing the maximum length of the virSecurityModel doi string.
+ */
+#define VIR_SECURITY_DOI_BUFLEN (256 + 1)
+
+/**
+ * virSecurityModel:
+ *
+ * a virSecurityModel is a structure filled by virNodeGetSecurityModel(),
+ * providing the per-hypervisor security model and DOI attributes for the
+ * specified domain.
+ *
+ */
+typedef struct _virSecurityModel {
+ char model[VIR_SECURITY_MODEL_BUFLEN]; /* security model string */
+ char doi[VIR_SECURITY_DOI_BUFLEN]; /* domain of interpetation */
+} virSecurityModel;
+
+/**
+ * virSecurityModelPtr:
+ *
+ * a virSecurityModelPtr is a pointer to a virSecurityModel.
+ */
+typedef virSecurityModel *virSecurityModelPtr;
+
+/**
* virNodeInfoPtr:
*
* a virNodeInfo is a structure filled by virNodeGetInfo() and providing
@@ -417,6 +479,9 @@ char * virConnectGetCap
unsigned long long virNodeGetFreeMemory (virConnectPtr conn);
+int virNodeGetSecurityModel (virConnectPtr conn,
+ virSecurityModelPtr secmodel);
+
/*
* Gather list of running domains
*/
@@ -506,6 +571,8 @@ int virDomainSetMaxM
int virDomainSetMemory (virDomainPtr domain,
unsigned long memory);
int virDomainGetMaxVcpus (virDomainPtr domain);
+int virDomainGetSecurityLabel (virDomainPtr domain,
+ virSecurityLabelPtr seclabel);
/*
* XML domain description
diff -up libvirt-0.6.0/include/libvirt/libvirt.h.svirt libvirt-0.6.0/include/libvirt/libvirt.h
--- libvirt-0.6.0/include/libvirt/libvirt.h.svirt 2009-01-31 04:20:10.000000000 -0500
+++ libvirt-0.6.0/include/libvirt/libvirt.h 2009-02-17 10:07:32.421570000 -0500
@@ -111,6 +111,68 @@ typedef enum {
} virDomainCreateFlags;
/**
+ * VIR_SECURITY_LABEL_BUFLEN:
+ *
+ * Macro providing the maximum length of the virSecurityLabel label string.
+ * Note that this value is based on that used by Labeled NFS.
+ */
+#define VIR_SECURITY_LABEL_BUFLEN (4096 + 1)
+
+/**
+ * virSecurityLabel:
+ *
+ * a virSecurityLabel is a structure filled by virDomainGetSecurityLabel(),
+ * providing the security label and associated attributes for the specified
+ * domain.
+ *
+ */
+typedef struct _virSecurityLabel {
+ char label[VIR_SECURITY_LABEL_BUFLEN]; /* security label string */
+ int enforcing; /* 1 if security policy is being enforced for domain */
+} virSecurityLabel;
+
+/**
+ * virSecurityLabelPtr:
+ *
+ * a virSecurityLabelPtr is a pointer to a virSecurityLabel.
+ */
+typedef virSecurityLabel *virSecurityLabelPtr;
+
+/**
+ * VIR_SECURITY_MODEL_BUFLEN:
+ *
+ * Macro providing the maximum length of the virSecurityModel model string.
+ */
+#define VIR_SECURITY_MODEL_BUFLEN (256 + 1)
+
+/**
+ * VIR_SECURITY_DOI_BUFLEN:
+ *
+ * Macro providing the maximum length of the virSecurityModel doi string.
+ */
+#define VIR_SECURITY_DOI_BUFLEN (256 + 1)
+
+/**
+ * virSecurityModel:
+ *
+ * a virSecurityModel is a structure filled by virNodeGetSecurityModel(),
+ * providing the per-hypervisor security model and DOI attributes for the
+ * specified domain.
+ *
+ */
+typedef struct _virSecurityModel {
+ char model[VIR_SECURITY_MODEL_BUFLEN]; /* security model string */
+ char doi[VIR_SECURITY_DOI_BUFLEN]; /* domain of interpetation */
+} virSecurityModel;
+
+/**
+ * virSecurityModelPtr:
+ *
+ * a virSecurityModelPtr is a pointer to a virSecurityModel.
+ */
+typedef virSecurityModel *virSecurityModelPtr;
+
+/**
* virNodeInfoPtr:
*
* a virNodeInfo is a structure filled by virNodeGetInfo() and providing
@@ -417,6 +479,9 @@ char * virConnectGetCap
unsigned long long virNodeGetFreeMemory (virConnectPtr conn);
+int virNodeGetSecurityModel (virConnectPtr conn,
+ virSecurityModelPtr secmodel);
+
/*
* Gather list of running domains
*/
@@ -506,6 +571,8 @@ int virDomainSetMaxM
int virDomainSetMemory (virDomainPtr domain,
unsigned long memory);
int virDomainGetMaxVcpus (virDomainPtr domain);
+int virDomainGetSecurityLabel (virDomainPtr domain,
+ virSecurityLabelPtr seclabel);
/*
* XML domain description
diff -up libvirt-0.6.0/include/libvirt/virterror.h.svirt libvirt-0.6.0/include/libvirt/virterror.h
--- libvirt-0.6.0/include/libvirt/virterror.h.svirt 2008-11-25 08:42:33.000000000 -0500
+++ libvirt-0.6.0/include/libvirt/virterror.h 2009-02-17 10:07:06.223677000 -0500
@@ -61,6 +61,7 @@ typedef enum {
VIR_FROM_UML, /* Error at the UML driver */
VIR_FROM_NODEDEV, /* Error from node device monitor */
VIR_FROM_XEN_INOTIFY, /* Error from xen inotify layer */
+ VIR_FROM_SECURITY, /* Error from security framework */
} virErrorDomain;
@@ -154,6 +155,7 @@ typedef enum {
VIR_WAR_NO_NODE, /* failed to start node driver */
VIR_ERR_INVALID_NODE_DEVICE,/* invalid node device object */
VIR_ERR_NO_NODE_DEVICE,/* node device not found */
+ VIR_ERR_NO_SECURITY_MODEL, /* security model not found */
} virErrorNumber;
/**
diff -up libvirt-0.6.0/po/POTFILES.in.svirt libvirt-0.6.0/po/POTFILES.in
--- libvirt-0.6.0/po/POTFILES.in.svirt 2009-01-31 04:04:17.000000000 -0500
+++ libvirt-0.6.0/po/POTFILES.in 2009-02-17 10:07:06.226679000 -0500
@@ -22,6 +22,8 @@ src/proxy_internal.c
src/qemu_conf.c
src/qemu_driver.c
src/remote_internal.c
+src/security.c
+src/security_selinux.c
src/storage_backend.c
src/storage_backend_disk.c
src/storage_backend_fs.c
diff -up libvirt-0.6.0/python/generator.py.svirt libvirt-0.6.0/python/generator.py
--- libvirt-0.6.0/python/generator.py.svirt 2008-11-21 07:47:32.000000000 -0500
+++ libvirt-0.6.0/python/generator.py 2009-02-17 10:07:06.230676000 -0500
@@ -342,6 +342,8 @@ skip_function = (
'virCopyLastError', # Python API is called virGetLastError instead
'virConnectOpenAuth', # Python C code is manually written
'virDefaultErrorFunc', # Python virErrorFuncHandler impl calls this from C
+ 'virDomainGetSecurityLabel', # Needs investigation...
+ 'virNodeGetSecurityModel', # Needs investigation...
'virConnectDomainEventRegister', # overridden in virConnect.py
'virConnectDomainEventDeregister', # overridden in virConnect.py
)
diff -up libvirt-0.6.0/qemud/Makefile.am.svirt libvirt-0.6.0/qemud/Makefile.am
--- libvirt-0.6.0/qemud/Makefile.am.svirt 2009-01-31 04:04:17.000000000 -0500
+++ libvirt-0.6.0/qemud/Makefile.am 2009-02-17 10:07:06.237678000 -0500
@@ -130,6 +130,7 @@ libvirtd_LDADD += ../src/libvirt_driver_
endif
endif
+libvirtd_LDADD += ../src/libvirt_driver_security.la
libvirtd_LDADD += ../src/libvirt.la
if HAVE_POLKIT
diff -up libvirt-0.6.0/qemud/remote.c.svirt libvirt-0.6.0/qemud/remote.c
--- libvirt-0.6.0/qemud/remote.c.svirt 2009-01-31 04:04:17.000000000 -0500
+++ libvirt-0.6.0/qemud/remote.c 2009-02-17 10:07:06.246680000 -0500
@@ -1340,6 +1340,76 @@ remoteDispatchDomainGetMaxVcpus (struct
}
static int
+remoteDispatchDomainGetSecurityLabel(struct qemud_server *server ATTRIBUTE_UNUSED,
+ struct qemud_client *client ATTRIBUTE_UNUSED,
+ virConnectPtr conn,
+ remote_error *rerr,
+ remote_domain_get_security_label_args *args,
+ remote_domain_get_security_label_ret *ret)
+{
+ virDomainPtr dom;
+ virSecurityLabel seclabel;
+
+ dom = get_nonnull_domain(conn, args->dom);
+ if (dom == NULL) {
+ remoteDispatchConnError(rerr, conn);
+ return -1;
+ }
+
+ memset(&seclabel, 0, sizeof seclabel);
+ if (virDomainGetSecurityLabel(dom, &seclabel) == -1) {
+ virDomainFree(dom);
+ remoteDispatchFormatError(rerr, "%s", _("unable to get security label"));
+ return -1;
+ }
+
+ ret->label.label_len = strlen(seclabel.label) + 1;
+ if (VIR_ALLOC_N(ret->label.label_val, ret->label.label_len) < 0) {
+ virDomainFree(dom);
+ remoteDispatchOOMError(rerr);
+ return -1;
+ }
+ strcpy(ret->label.label_val, seclabel.label);
+ ret->enforcing = seclabel.enforcing;
+ virDomainFree(dom);
+
+ return 0;
+}
+
+static int
+remoteDispatchNodeGetSecurityModel(struct qemud_server *server ATTRIBUTE_UNUSED,
+ struct qemud_client *client ATTRIBUTE_UNUSED,
+ virConnectPtr conn,
+ remote_error *rerr,
+ void *args ATTRIBUTE_UNUSED,
+ remote_node_get_security_model_ret *ret)
+{
+ virSecurityModel secmodel;
+
+ memset(&secmodel, 0, sizeof secmodel);
+ if (virNodeGetSecurityModel(conn, &secmodel) == -1) {
+ remoteDispatchFormatError(rerr, "%s", _("unable to get security model"));
+ return -1;
+ }
+
+ ret->model.model_len = strlen(secmodel.model) + 1;
+ if (VIR_ALLOC_N(ret->model.model_val, ret->model.model_len) < 0) {
+ remoteDispatchOOMError(rerr);
+ return -1;
+ }
+ strcpy(ret->model.model_val, secmodel.model);
+
+ ret->doi.doi_len = strlen(secmodel.doi) + 1;
+ if (VIR_ALLOC_N(ret->doi.doi_val, ret->doi.doi_len) < 0) {
+ remoteDispatchOOMError(rerr);
+ return -1;
+ }
+ strcpy(ret->doi.doi_val, secmodel.doi);
+
+ return 0;
+}
+
+static int
remoteDispatchDomainGetOsType (struct qemud_server *server ATTRIBUTE_UNUSED,
struct qemud_client *client ATTRIBUTE_UNUSED,
virConnectPtr conn,
diff -up libvirt-0.6.0/qemud/remote_dispatch_args.h.svirt libvirt-0.6.0/qemud/remote_dispatch_args.h
--- libvirt-0.6.0/qemud/remote_dispatch_args.h.svirt 2008-12-19 09:00:02.000000000 -0500
+++ libvirt-0.6.0/qemud/remote_dispatch_args.h 2009-02-17 10:07:06.250678000 -0500
@@ -99,3 +99,4 @@
remote_node_device_get_parent_args val_remote_node_device_get_parent_args;
remote_node_device_num_of_caps_args val_remote_node_device_num_of_caps_args;
remote_node_device_list_caps_args val_remote_node_device_list_caps_args;
+ remote_domain_get_security_label_args val_remote_domain_get_security_label_args;
diff -up libvirt-0.6.0/qemud/remote_dispatch_prototypes.h.svirt libvirt-0.6.0/qemud/remote_dispatch_prototypes.h
--- libvirt-0.6.0/qemud/remote_dispatch_prototypes.h.svirt 2008-12-19 09:00:02.000000000 -0500
+++ libvirt-0.6.0/qemud/remote_dispatch_prototypes.h 2009-02-17 10:07:06.255676000 -0500
@@ -184,6 +184,13 @@ static int remoteDispatchDomainGetSchedu
remote_error *err,
remote_domain_get_scheduler_type_args *args,
remote_domain_get_scheduler_type_ret *ret);
+static int remoteDispatchDomainGetSecurityLabel(
+ struct qemud_server *server,
+ struct qemud_client *client,
+ virConnectPtr conn,
+ remote_error *err,
+ remote_domain_get_security_label_args *args,
+ remote_domain_get_security_label_ret *ret);
static int remoteDispatchDomainGetVcpus(
struct qemud_server *server,
struct qemud_client *client,
@@ -576,6 +583,13 @@ static int remoteDispatchNodeGetInfo(
remote_error *err,
void *args,
remote_node_get_info_ret *ret);
+static int remoteDispatchNodeGetSecurityModel(
+ struct qemud_server *server,
+ struct qemud_client *client,
+ virConnectPtr conn,
+ remote_error *err,
+ void *args,
+ remote_node_get_security_model_ret *ret);
static int remoteDispatchNodeListDevices(
struct qemud_server *server,
struct qemud_client *client,
diff -up libvirt-0.6.0/qemud/remote_dispatch_ret.h.svirt libvirt-0.6.0/qemud/remote_dispatch_ret.h
--- libvirt-0.6.0/qemud/remote_dispatch_ret.h.svirt 2008-12-19 09:00:02.000000000 -0500
+++ libvirt-0.6.0/qemud/remote_dispatch_ret.h 2009-02-17 10:07:06.259676000 -0500
@@ -86,3 +86,5 @@
remote_node_device_get_parent_ret val_remote_node_device_get_parent_ret;
remote_node_device_num_of_caps_ret val_remote_node_device_num_of_caps_ret;
remote_node_device_list_caps_ret val_remote_node_device_list_caps_ret;
+ remote_domain_get_security_label_ret val_remote_domain_get_security_label_ret;
+ remote_node_get_security_model_ret val_remote_node_get_security_model_ret;
diff -up libvirt-0.6.0/qemud/remote_dispatch_table.h.svirt libvirt-0.6.0/qemud/remote_dispatch_table.h
--- libvirt-0.6.0/qemud/remote_dispatch_table.h.svirt 2008-12-19 09:00:02.000000000 -0500
+++ libvirt-0.6.0/qemud/remote_dispatch_table.h 2009-02-17 10:07:06.263676000 -0500
@@ -592,3 +592,13 @@
.args_filter = (xdrproc_t) xdr_remote_node_device_list_caps_args,
.ret_filter = (xdrproc_t) xdr_remote_node_device_list_caps_ret,
},
+{ /* DomainGetSecurityLabel => 118 */
+ .fn = (dispatch_fn) remoteDispatchDomainGetSecurityLabel,
+ .args_filter = (xdrproc_t) xdr_remote_domain_get_security_label_args,
+ .ret_filter = (xdrproc_t) xdr_remote_domain_get_security_label_ret,
+},
+{ /* NodeGetSecurityModel => 119 */
+ .fn = (dispatch_fn) remoteDispatchNodeGetSecurityModel,
+ .args_filter = (xdrproc_t) xdr_void,
+ .ret_filter = (xdrproc_t) xdr_remote_node_get_security_model_ret,
+},
diff -up libvirt-0.6.0/qemud/remote_protocol.c.svirt libvirt-0.6.0/qemud/remote_protocol.c
--- libvirt-0.6.0/qemud/remote_protocol.c.svirt 2009-01-31 04:04:17.000000000 -0500
+++ libvirt-0.6.0/qemud/remote_protocol.c 2009-02-17 10:07:06.268676000 -0500
@@ -1166,6 +1166,43 @@ xdr_remote_domain_get_max_vcpus_ret (XDR
}
bool_t
+xdr_remote_domain_get_security_label_args (XDR *xdrs, remote_domain_get_security_label_args *objp)
+{
+
+ if (!xdr_remote_nonnull_domain (xdrs, &objp->dom))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_remote_domain_get_security_label_ret (XDR *xdrs, remote_domain_get_security_label_ret *objp)
+{
+ char **objp_cpp0 = (char **) (void *) &objp->label.label_val;
+
+ if (!xdr_array (xdrs, objp_cpp0, (u_int *) &objp->label.label_len, REMOTE_SECURITY_LABEL_MAX,
+ sizeof (char), (xdrproc_t) xdr_char))
+ return FALSE;
+ if (!xdr_int (xdrs, &objp->enforcing))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_remote_node_get_security_model_ret (XDR *xdrs, remote_node_get_security_model_ret *objp)
+{
+ char **objp_cpp1 = (char **) (void *) &objp->doi.doi_val;
+ char **objp_cpp0 = (char **) (void *) &objp->model.model_val;
+
+ if (!xdr_array (xdrs, objp_cpp0, (u_int *) &objp->model.model_len, REMOTE_SECURITY_MODEL_MAX,
+ sizeof (char), (xdrproc_t) xdr_char))
+ return FALSE;
+ if (!xdr_array (xdrs, objp_cpp1, (u_int *) &objp->doi.doi_len, REMOTE_SECURITY_DOI_MAX,
+ sizeof (char), (xdrproc_t) xdr_char))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
xdr_remote_domain_attach_device_args (XDR *xdrs, remote_domain_attach_device_args *objp)
{
diff -up libvirt-0.6.0/qemud/remote_protocol.h.svirt libvirt-0.6.0/qemud/remote_protocol.h
--- libvirt-0.6.0/qemud/remote_protocol.h.svirt 2009-01-31 04:04:17.000000000 -0500
+++ libvirt-0.6.0/qemud/remote_protocol.h 2009-02-17 10:07:06.274679000 -0500
@@ -38,6 +38,9 @@ typedef remote_nonnull_string *remote_st
#define REMOTE_AUTH_TYPE_LIST_MAX 20
#define REMOTE_DOMAIN_BLOCK_PEEK_BUFFER_MAX 65536
#define REMOTE_DOMAIN_MEMORY_PEEK_BUFFER_MAX 65536
+#define REMOTE_SECURITY_MODEL_MAX VIR_SECURITY_MODEL_BUFLEN
+#define REMOTE_SECURITY_LABEL_MAX VIR_SECURITY_LABEL_BUFLEN
+#define REMOTE_SECURITY_DOI_MAX VIR_SECURITY_DOI_BUFLEN
typedef char remote_uuid[VIR_UUID_BUFLEN];
@@ -637,6 +640,32 @@ struct remote_domain_get_max_vcpus_ret {
};
typedef struct remote_domain_get_max_vcpus_ret remote_domain_get_max_vcpus_ret;
+struct remote_domain_get_security_label_args {
+ remote_nonnull_domain dom;
+};
+typedef struct remote_domain_get_security_label_args remote_domain_get_security_label_args;
+
+struct remote_domain_get_security_label_ret {
+ struct {
+ u_int label_len;
+ char *label_val;
+ } label;
+ int enforcing;
+};
+typedef struct remote_domain_get_security_label_ret remote_domain_get_security_label_ret;
+
+struct remote_node_get_security_model_ret {
+ struct {
+ u_int model_len;
+ char *model_val;
+ } model;
+ struct {
+ u_int doi_len;
+ char *doi_val;
+ } doi;
+};
+typedef struct remote_node_get_security_model_ret remote_node_get_security_model_ret;
+
struct remote_domain_attach_device_args {
remote_nonnull_domain dom;
remote_nonnull_string xml;
@@ -1348,6 +1377,8 @@ enum remote_procedure {
REMOTE_PROC_NODE_DEVICE_GET_PARENT = 115,
REMOTE_PROC_NODE_DEVICE_NUM_OF_CAPS = 116,
REMOTE_PROC_NODE_DEVICE_LIST_CAPS = 117,
+ REMOTE_PROC_DOMAIN_GET_SECURITY_LABEL = 118,
+ REMOTE_PROC_NODE_GET_SECURITY_MODEL = 119,
};
typedef enum remote_procedure remote_procedure;
@@ -1474,6 +1505,9 @@ extern bool_t xdr_remote_domain_get_vcp
extern bool_t xdr_remote_domain_get_vcpus_ret (XDR *, remote_domain_get_vcpus_ret*);
extern bool_t xdr_remote_domain_get_max_vcpus_args (XDR *, remote_domain_get_max_vcpus_args*);
extern bool_t xdr_remote_domain_get_max_vcpus_ret (XDR *, remote_domain_get_max_vcpus_ret*);
+extern bool_t xdr_remote_domain_get_security_label_args (XDR *, remote_domain_get_security_label_args*);
+extern bool_t xdr_remote_domain_get_security_label_ret (XDR *, remote_domain_get_security_label_ret*);
+extern bool_t xdr_remote_node_get_security_model_ret (XDR *, remote_node_get_security_model_ret*);
extern bool_t xdr_remote_domain_attach_device_args (XDR *, remote_domain_attach_device_args*);
extern bool_t xdr_remote_domain_detach_device_args (XDR *, remote_domain_detach_device_args*);
extern bool_t xdr_remote_domain_get_autostart_args (XDR *, remote_domain_get_autostart_args*);
@@ -1679,6 +1713,9 @@ extern bool_t xdr_remote_domain_get_vcpu
extern bool_t xdr_remote_domain_get_vcpus_ret ();
extern bool_t xdr_remote_domain_get_max_vcpus_args ();
extern bool_t xdr_remote_domain_get_max_vcpus_ret ();
+extern bool_t xdr_remote_domain_get_security_label_args ();
+extern bool_t xdr_remote_domain_get_security_label_ret ();
+extern bool_t xdr_remote_node_get_security_model_ret ();
extern bool_t xdr_remote_domain_attach_device_args ();
extern bool_t xdr_remote_domain_detach_device_args ();
extern bool_t xdr_remote_domain_get_autostart_args ();
diff -up libvirt-0.6.0/qemud/remote_protocol.x.svirt libvirt-0.6.0/qemud/remote_protocol.x
--- libvirt-0.6.0/qemud/remote_protocol.x.svirt 2008-12-19 07:51:11.000000000 -0500
+++ libvirt-0.6.0/qemud/remote_protocol.x 2009-02-17 10:07:06.279676000 -0500
@@ -115,6 +115,21 @@ const REMOTE_DOMAIN_BLOCK_PEEK_BUFFER_MA
*/
const REMOTE_DOMAIN_MEMORY_PEEK_BUFFER_MAX = 65536;
+/*
+ * Maximum length of a security model field.
+ */
+const REMOTE_SECURITY_MODEL_MAX = VIR_SECURITY_MODEL_BUFLEN;
+
+/*
+ * Maximum length of a security label field.
+ */
+const REMOTE_SECURITY_LABEL_MAX = VIR_SECURITY_LABEL_BUFLEN;
+
+/*
+ * Maximum length of a security DOI field.
+ */
+const REMOTE_SECURITY_DOI_MAX = VIR_SECURITY_DOI_BUFLEN;
+
/* UUID. VIR_UUID_BUFLEN definition comes from libvirt.h */
typedef opaque remote_uuid[VIR_UUID_BUFLEN];
@@ -617,6 +632,20 @@ struct remote_domain_get_max_vcpus_ret {
int num;
};
+struct remote_domain_get_security_label_args {
+ remote_nonnull_domain dom;
+};
+
+struct remote_domain_get_security_label_ret {
+ char label<REMOTE_SECURITY_LABEL_MAX>;
+ int enforcing;
+};
+
+struct remote_node_get_security_model_ret {
+ char model<REMOTE_SECURITY_MODEL_MAX>;
+ char doi<REMOTE_SECURITY_DOI_MAX>;
+};
+
struct remote_domain_attach_device_args {
remote_nonnull_domain dom;
remote_nonnull_string xml;
@@ -1223,7 +1252,10 @@ enum remote_procedure {
REMOTE_PROC_NODE_DEVICE_DUMP_XML = 114,
REMOTE_PROC_NODE_DEVICE_GET_PARENT = 115,
REMOTE_PROC_NODE_DEVICE_NUM_OF_CAPS = 116,
- REMOTE_PROC_NODE_DEVICE_LIST_CAPS = 117
+ REMOTE_PROC_NODE_DEVICE_LIST_CAPS = 117,
+
+ REMOTE_PROC_DOMAIN_GET_SECURITY_LABEL = 118,
+ REMOTE_PROC_NODE_GET_SECURITY_MODEL = 119
};
/* Custom RPC structure. */
diff -up libvirt-0.6.0/src/capabilities.c.svirt libvirt-0.6.0/src/capabilities.c
--- libvirt-0.6.0/src/capabilities.c.svirt 2009-01-31 04:04:17.000000000 -0500
+++ libvirt-0.6.0/src/capabilities.c 2009-02-17 10:07:06.285678000 -0500
@@ -150,6 +150,8 @@ virCapabilitiesFree(virCapsPtr caps) {
VIR_FREE(caps->host.migrateTrans);
VIR_FREE(caps->host.arch);
+ VIR_FREE(caps->host.secModel.model);
+ VIR_FREE(caps->host.secModel.doi);
VIR_FREE(caps);
}
@@ -599,6 +601,14 @@ virCapabilitiesFormatXML(virCapsPtr caps
virBufferAddLit(&xml, " </cells>\n");
virBufferAddLit(&xml, " </topology>\n");
}
+
+ if (caps->host.secModel.model) {
+ virBufferAddLit(&xml, " <secmodel>\n");
+ virBufferVSprintf(&xml, " <model>%s</model>\n", caps->host.secModel.model);
+ virBufferVSprintf(&xml, " <doi>%s</doi>\n", caps->host.secModel.doi);
+ virBufferAddLit(&xml, " </secmodel>\n");
+ }
+
virBufferAddLit(&xml, " </host>\n\n");
diff -up libvirt-0.6.0/src/capabilities.h.svirt libvirt-0.6.0/src/capabilities.h
--- libvirt-0.6.0/src/capabilities.h.svirt 2009-01-31 04:04:17.000000000 -0500
+++ libvirt-0.6.0/src/capabilities.h 2009-02-17 10:07:06.292677000 -0500
@@ -78,6 +78,12 @@ struct _virCapsHostNUMACell {
int *cpus;
};
+typedef struct _virCapsHostSecModel virCapsHostSecModel;
+struct _virCapsHostSecModel {
+ char *model;
+ char *doi;
+};
+
typedef struct _virCapsHost virCapsHost;
typedef virCapsHost *virCapsHostPtr;
struct _virCapsHost {
@@ -90,6 +96,7 @@ struct _virCapsHost {
char **migrateTrans;
int nnumaCell;
virCapsHostNUMACellPtr *numaCell;
+ virCapsHostSecModel secModel;
};
typedef struct _virCaps virCaps;
diff -up libvirt-0.6.0/src/domain_conf.c.svirt libvirt-0.6.0/src/domain_conf.c
--- libvirt-0.6.0/src/domain_conf.c.svirt 2009-02-17 10:07:06.195708000 -0500
+++ libvirt-0.6.0/src/domain_conf.c 2009-02-17 10:07:06.300677000 -0500
@@ -379,6 +379,16 @@ void virDomainDeviceDefFree(virDomainDev
VIR_FREE(def);
}
+void virSecurityLabelDefFree(virDomainDefPtr def);
+
+void virSecurityLabelDefFree(virDomainDefPtr def)
+{
+ if (def->seclabel.model)
+ VIR_FREE(def->seclabel.model);
+ if (def->seclabel.label)
+ VIR_FREE(def->seclabel.label);
+}
+
void virDomainDefFree(virDomainDefPtr def)
{
unsigned int i;
@@ -437,6 +447,8 @@ void virDomainDefFree(virDomainDefPtr de
VIR_FREE(def->cpumask);
VIR_FREE(def->emulator);
+ virSecurityLabelDefFree(def);
+
VIR_FREE(def);
}
@@ -1818,6 +1830,34 @@ static int virDomainLifecycleParseXML(vi
return 0;
}
+static int
+virSecurityLabelDefParseXML(virConnectPtr conn,
+ const virDomainDefPtr def,
+ xmlXPathContextPtr ctxt)
+{
+ char *p;
+
+ if (virXPathNode(conn, "./seclabel", ctxt) == NULL)
+ return 0;
+
+ p = virXPathStringLimit(conn, "string(./seclabel/label[1])",
+ VIR_SECURITY_LABEL_BUFLEN-1, ctxt);
+ if (p == NULL)
+ goto error;
+ def->seclabel.label = p;
+
+ p = virXPathStringLimit(conn, "string(./seclabel/@model)",
+ VIR_SECURITY_MODEL_BUFLEN-1, ctxt);
+ if (p == NULL)
+ goto error;
+ def->seclabel.model = p;
+
+ return 0;
+
+error:
+ virSecurityLabelDefFree(def);
+ return -1;
+}
virDomainDeviceDefPtr virDomainDeviceDefParse(virConnectPtr conn,
virCapsPtr caps,
@@ -2403,6 +2443,10 @@ static virDomainDefPtr virDomainDefParse
}
VIR_FREE(nodes);
+ /* analysis of security label */
+ if (virSecurityLabelDefParseXML(conn, def, ctxt) == -1)
+ goto error;
+
return def;
no_memory:
@@ -3420,6 +3464,13 @@ char *virDomainDefFormat(virConnectPtr c
goto cleanup;
virBufferAddLit(&buf, " </devices>\n");
+
+ if (def->seclabel.model) {
+ virBufferEscapeString(&buf, " <seclabel model='%s'>\n", def->seclabel.model);
+ virBufferEscapeString(&buf, " <label>%s</label>\n", def->seclabel.label);
+ virBufferAddLit(&buf, " </seclabel>\n");
+ }
+
virBufferAddLit(&buf, "</domain>\n");
if (virBufferError(&buf))
diff -up libvirt-0.6.0/src/domain_conf.h.svirt libvirt-0.6.0/src/domain_conf.h
--- libvirt-0.6.0/src/domain_conf.h.svirt 2009-01-31 04:04:17.000000000 -0500
+++ libvirt-0.6.0/src/domain_conf.h 2009-02-17 10:07:06.307676000 -0500
@@ -407,6 +407,14 @@ struct _virDomainOSDef {
char *bootloaderArgs;
};
+/* Security configuration for domain */
+typedef struct _virSecurityLabelDef virSecurityLabelDef;
+typedef virSecurityLabelDef *virSecurityLabelDefPtr;
+struct _virSecurityLabelDef {
+ char *model; /* name of security model */
+ char *label; /* security label string */
+};
+
#define VIR_DOMAIN_CPUMASK_LEN 1024
/* Guest VM main configuration */
@@ -464,6 +472,7 @@ struct _virDomainDef {
/* Only 1 */
virDomainChrDefPtr console;
+ virSecurityLabelDef seclabel;
};
/* Guest VM runtime state */
diff -up libvirt-0.6.0/src/driver.h.svirt libvirt-0.6.0/src/driver.h
--- libvirt-0.6.0/src/driver.h.svirt 2008-12-19 07:51:11.000000000 -0500
+++ libvirt-0.6.0/src/driver.h 2009-02-17 10:07:06.313676000 -0500
@@ -181,6 +181,12 @@ typedef int
typedef int
(*virDrvDomainGetMaxVcpus) (virDomainPtr domain);
typedef int
+ (*virDrvDomainGetSecurityLabel) (virDomainPtr domain,
+ virSecurityLabelPtr seclabel);
+typedef int
+ (*virDrvNodeGetSecurityModel) (virConnectPtr conn,
+ virSecurityModelPtr secmodel);
+typedef int
(*virDrvDomainAttachDevice) (virDomainPtr domain,
const char *xml);
typedef int
@@ -361,6 +367,8 @@ struct _virDriver {
virDrvDomainPinVcpu domainPinVcpu;
virDrvDomainGetVcpus domainGetVcpus;
virDrvDomainGetMaxVcpus domainGetMaxVcpus;
+ virDrvDomainGetSecurityLabel domainGetSecurityLabel;
+ virDrvNodeGetSecurityModel nodeGetSecurityModel;
virDrvDomainDumpXML domainDumpXML;
virDrvListDefinedDomains listDefinedDomains;
virDrvNumOfDefinedDomains numOfDefinedDomains;
diff -up libvirt-0.6.0/src/libvirt.c.svirt libvirt-0.6.0/src/libvirt.c
--- libvirt-0.6.0/src/libvirt.c.svirt 2009-01-31 04:04:17.000000000 -0500
+++ libvirt-0.6.0/src/libvirt.c 2009-02-17 10:07:06.332683000 -0500
@@ -4156,6 +4156,70 @@ error:
return -1;
}
+/**
+ * virDomainGetSecurityLabel:
+ * @domain: a domain object
+ * @seclabel: pointer to a virSecurityLabel structure
+ *
+ * Extract security label of an active domain.
+ *
+ * Returns 0 in case of success, -1 in case of failure, and -2
+ * if the operation is not supported (caller decides if that's
+ * an error).
+ */
+int
+virDomainGetSecurityLabel(virDomainPtr domain, virSecurityLabelPtr seclabel)
+{
+ virConnectPtr conn;
+
+ if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
+ virLibDomainError(NULL, VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
+ return -1;
+ }
+
+ if (seclabel == NULL) {
+ virLibDomainError(domain, VIR_ERR_INVALID_ARG, __FUNCTION__);
+ return -1;
+ }
+
+ conn = domain->conn;
+
+ if (conn->driver->domainGetSecurityLabel)
+ return conn->driver->domainGetSecurityLabel(domain, seclabel);
+
+ virLibConnWarning(conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ return -2;
+}
+
+/**
+ * virNodeGetSecurityModel:
+ * @conn: a connection object
+ * @secmodel: pointer to a virSecurityModel structure
+ *
+ * Extract the security model of a hypervisor.
+ *
+ * Returns 0 in case of success, -1 in case of failure, and -2 if the
+ * operation is not supported (caller decides if that's an error).
+ */
+int
+virNodeGetSecurityModel(virConnectPtr conn, virSecurityModelPtr secmodel)
+{
+ if (!VIR_IS_CONNECT(conn)) {
+ virLibConnError(conn, VIR_ERR_INVALID_CONN, __FUNCTION__);
+ return -1;
+ }
+
+ if (secmodel == NULL) {
+ virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
+ return -1;
+ }
+
+ if (conn->driver->nodeGetSecurityModel)
+ return conn->driver->nodeGetSecurityModel(conn, secmodel);
+
+ virLibConnWarning(conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ return -2;
+}
/**
* virDomainAttachDevice:
diff -up libvirt-0.6.0/src/libvirt_private.syms.svirt libvirt-0.6.0/src/libvirt_private.syms
--- libvirt-0.6.0/src/libvirt_private.syms.svirt 2009-01-31 04:04:17.000000000 -0500
+++ libvirt-0.6.0/src/libvirt_private.syms 2009-02-17 10:36:52.867582000 -0500
@@ -334,3 +334,4 @@ virXPathNode;
virXPathNodeSet;
virXPathString;
virXMLPropString;
+virXPathStringLimit;
diff -up libvirt-0.6.0/src/libvirt_public.syms.svirt libvirt-0.6.0/src/libvirt_public.syms
--- libvirt-0.6.0/src/libvirt_public.syms.svirt 2009-01-20 08:48:28.000000000 -0500
+++ libvirt-0.6.0/src/libvirt_public.syms 2009-02-17 10:37:09.630287000 -0500
@@ -244,7 +244,8 @@ LIBVIRT_0.6.0 {
virStoragePoolRef;
virStorageVolRef;
virNodeDeviceRef;
-
+ virDomainGetSecurityLabel;
+ virNodeGetSecurityModel;
} LIBVIRT_0.5.0;
# .... define new API here using predicted next version number ....
diff -up libvirt-0.6.0/src/lxc_driver.c.svirt libvirt-0.6.0/src/lxc_driver.c
--- libvirt-0.6.0/src/lxc_driver.c.svirt 2009-01-31 04:04:17.000000000 -0500
+++ libvirt-0.6.0/src/lxc_driver.c 2009-02-17 10:07:06.339677000 -0500
@@ -1430,6 +1430,8 @@ static virDriver lxcDriver = {
NULL, /* domainPinVcpu */
NULL, /* domainGetVcpus */
NULL, /* domainGetMaxVcpus */
+ NULL, /* domainGetSecurityLabel */
+ NULL, /* nodeGetSecurityModel */
lxcDomainDumpXML, /* domainDumpXML */
lxcListDefinedDomains, /* listDefinedDomains */
lxcNumDefinedDomains, /* numOfDefinedDomains */
diff -up libvirt-0.6.0/src/Makefile.am.svirt libvirt-0.6.0/src/Makefile.am
--- libvirt-0.6.0/src/Makefile.am.svirt 2009-01-31 04:04:17.000000000 -0500
+++ libvirt-0.6.0/src/Makefile.am 2009-02-17 10:07:06.346676000 -0500
@@ -139,7 +139,7 @@ UML_DRIVER_SOURCES = \
NETWORK_DRIVER_SOURCES = \
network_driver.h network_driver.c
-# And finally storage backend specific impls
+# Storage backend specific impls
STORAGE_DRIVER_SOURCES = \
storage_driver.h storage_driver.c \
storage_backend.h storage_backend.c
@@ -164,6 +164,12 @@ STORAGE_DRIVER_DISK_SOURCES = \
STORAGE_HELPER_DISK_SOURCES = \
parthelper.c
+# Security framework and drivers for various models
+SECURITY_DRIVER_SOURCES = \
+ security.h security.c
+
+SECURITY_DRIVER_SELINUX_SOURCES = \
+ security_selinux.h security_selinux.c
NODE_DEVICE_DRIVER_SOURCES = \
node_device.c node_device.h
@@ -377,6 +383,19 @@ libvirt_driver_nodedev_la_LDFLAGS += -mo
endif
endif
+libvirt_driver_security_la_SOURCES = $(SECURITY_DRIVER_SOURCES)
+if WITH_DRIVER_MODULES
+mod_LTLIBRARIES += libvirt_driver_security.la
+else
+noinst_LTLIBRARIES += libvirt_driver_security.la
+endif
+if WITH_DRIVER_MODULES
+libvirt_driver_security_la_LDFLAGS = -module -avoid-version
+endif
+
+if HAVE_SELINUX
+libvirt_driver_security_la_SOURCES += $(SECURITY_DRIVER_SELINUX_SOURCES)
+endif
# Add all conditional sources just in case...
EXTRA_DIST += \
@@ -395,7 +414,9 @@ EXTRA_DIST += \
$(STORAGE_DRIVER_DISK_SOURCES) \
$(NODE_DEVICE_DRIVER_SOURCES) \
$(NODE_DEVICE_DRIVER_HAL_SOURCES) \
- $(NODE_DEVICE_DRIVER_DEVKIT_SOURCES)
+ $(NODE_DEVICE_DRIVER_DEVKIT_SOURCES) \
+ $(SECURITY_DRIVER_SOURCES) \
+ $(SECURITY_DRIVER_SELINUX_SOURCES)
#
# Build our version script. This is composed of three parts:
diff -up libvirt-0.6.0/src/openvz_driver.c.svirt libvirt-0.6.0/src/openvz_driver.c
--- libvirt-0.6.0/src/openvz_driver.c.svirt 2009-01-31 04:04:18.000000000 -0500
+++ libvirt-0.6.0/src/openvz_driver.c 2009-02-17 10:07:06.362676000 -0500
@@ -1299,6 +1299,8 @@ static virDriver openvzDriver = {
NULL, /* domainPinVcpu */
NULL, /* domainGetVcpus */
openvzDomainGetMaxVcpus, /* domainGetMaxVcpus */
+ NULL, /* domainGetSecurityLabel */
+ NULL, /* nodeGetSecurityModel */
openvzDomainDumpXML, /* domainDumpXML */
openvzListDefinedDomains, /* listDomains */
openvzNumDefinedDomains, /* numOfDomains */
diff -up libvirt-0.6.0/src/qemu_conf.h.svirt libvirt-0.6.0/src/qemu_conf.h
--- libvirt-0.6.0/src/qemu_conf.h.svirt 2009-01-31 04:04:18.000000000 -0500
+++ libvirt-0.6.0/src/qemu_conf.h 2009-02-17 10:07:06.368680000 -0500
@@ -33,6 +33,7 @@
#include "domain_conf.h"
#include "domain_event.h"
#include "threads.h"
+#include "security.h"
#define qemudDebug(fmt, ...) do {} while(0)
@@ -83,6 +84,8 @@ struct qemud_driver {
virDomainEventQueuePtr domainEventQueue;
int domainEventTimer;
int domainEventDispatching;
+
+ virSecurityDriverPtr securityDriver;
};
/* Status needed to reconenct to running VMs */
diff -up libvirt-0.6.0/src/qemu_driver.c.svirt libvirt-0.6.0/src/qemu_driver.c
--- libvirt-0.6.0/src/qemu_driver.c.svirt 2009-01-31 04:04:18.000000000 -0500
+++ libvirt-0.6.0/src/qemu_driver.c 2009-02-17 10:07:06.378682000 -0500
@@ -68,6 +68,7 @@
#include "memory.h"
#include "uuid.h"
#include "domain_conf.h"
+#include "security.h"
#define VIR_FROM_THIS VIR_FROM_QEMU
@@ -383,6 +384,50 @@ next:
return 0;
}
+static int
+qemudSecurityInit(struct qemud_driver *qemud_drv)
+{
+ int ret;
+ const char *doi, *model;
+ virCapsPtr caps;
+ virSecurityDriverPtr security_drv;
+
+ ret = virSecurityDriverStartup(&security_drv);
+ if (ret == -1) {
+ qemudLog(QEMUD_ERR, _("Failed to start security driver"));
+ return -1;
+ }
+ /* No security driver wanted to be enabled: just return */
+ if (ret == -2)
+ return 0;
+
+ qemud_drv->securityDriver = security_drv;
+ doi = virSecurityDriverGetDOI(security_drv);
+ model = virSecurityDriverGetModel(security_drv);
+
+ qemudLog(QEMUD_DEBUG, "Initialized security driver \"%s\" with "
+ "DOI \"%s\".\n", model, doi);
+
+ /*
+ * Add security policy host caps now that the security driver is
+ * initialized.
+ */
+ caps = qemud_drv->caps;
+
+ caps->host.secModel.model = strdup(model);
+ if (!caps->host.secModel.model) {
+ qemudLog(QEMUD_ERR, _("Failed to copy secModel model: %s"), strerror(errno));
+ return -1;
+ }
+
+ caps->host.secModel.doi = strdup(doi);
+ if (!caps->host.secModel.doi) {
+ qemudLog(QEMUD_ERR, _("Failed to copy secModel DOI: %s"), strerror(errno));
+ return -1;
+ }
+
+ return 0;
+}
/**
* qemudStartup:
@@ -474,6 +519,11 @@ qemudStartup(void) {
if ((qemu_driver->caps = qemudCapsInit()) == NULL)
goto out_of_memory;
+ if (qemudSecurityInit(qemu_driver) < 0) {
+ qemudShutdown();
+ return -1;
+ }
+
if (qemudLoadDriverConfig(qemu_driver, driverConf) < 0) {
goto error;
}
@@ -1111,6 +1161,15 @@ static int qemudNextFreeVNCPort(struct q
return -1;
}
+static int qemudDomainSetSecurityLabel(virConnectPtr conn, struct qemud_driver *driver, virDomainObjPtr vm)
+{
+ if (vm->def->seclabel.label != NULL)
+ if (driver->securityDriver && driver->securityDriver->domainSetSecurityLabel)
+ return driver->securityDriver->domainSetSecurityLabel(conn, driver->securityDriver,
+ &vm->def->seclabel);
+ return 0;
+}
+
static virDomainPtr qemudDomainLookupByName(virConnectPtr conn,
const char *name);
@@ -1178,6 +1237,16 @@ static int qemudStartVMDaemon(virConnect
return -1;
}
+ /*
+ * Set up the security label for the domain here, before doing
+ * too much else.
+ */
+ if (qemudDomainSetSecurityLabel(conn, driver, vm) < 0) {
+ qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
+ _("Failed to set security label"));
+ return -1;
+ }
+
if (qemudExtractVersionInfo(emulator,
NULL,
&qemuCmdFlags) < 0) {
@@ -2721,7 +2790,94 @@ cleanup:
return ret;
}
+static int qemudDomainGetSecurityLabel(virDomainPtr dom, virSecurityLabelPtr seclabel)
+{
+ struct qemud_driver *driver = (struct qemud_driver *)dom->conn->privateData;
+ virDomainObjPtr vm;
+ const char *type;
+ int ret = -1;
+
+ qemuDriverLock(driver);
+ vm = virDomainFindByUUID(&driver->domains, dom->uuid);
+ qemuDriverUnlock(driver);
+
+ if (!vm) {
+ char uuidstr[VIR_UUID_STRING_BUFLEN];
+
+ virUUIDFormat(dom->uuid, uuidstr);
+ qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
+ _("no domain with matching uuid '%s'"), uuidstr);
+ goto cleanup;
+ }
+
+ if (!(type = virDomainVirtTypeToString(vm->def->virtType))) {
+ qemudReportError(dom->conn, dom, NULL, VIR_ERR_INTERNAL_ERROR,
+ _("unknown virt type in domain definition '%d'"),
+ vm->def->virtType);
+ goto cleanup;
+ }
+
+ /*
+ * Theoretically, the pid can be replaced during this operation and
+ * return the label of a different process. If atomicity is needed,
+ * further validation will be required.
+ *
+ * Comment from Dan Berrange:
+ *
+ * Well the PID as stored in the virDomainObjPtr can't be changed
+ * because you've got a locked object. The OS level PID could have
+ * exited, though and in extreme circumstances have cycled through all
+ * PIDs back to ours. We could sanity check that our PID still exists
+ * after reading the label, by checking that our FD connecting to the
+ * QEMU monitor hasn't seen SIGHUP/ERR on poll().
+ */
+ if (virDomainIsActive(vm)) {
+ if (driver->securityDriver && driver->securityDriver->domainGetSecurityLabel) {
+ if (driver->securityDriver->domainGetSecurityLabel(dom->conn, vm, seclabel) == -1) {
+ qemudReportError(dom->conn, dom, NULL, VIR_ERR_INTERNAL_ERROR,
+ _("Failed to get security label"));
+ goto cleanup;
+ }
+ }
+ }
+
+ ret = 0;
+
+cleanup:
+ if (vm)
+ virDomainObjUnlock(vm);
+ return ret;
+}
+
+static int qemudNodeGetSecurityModel(virConnectPtr conn, virSecurityModelPtr secmodel)
+{
+ struct qemud_driver *driver = (struct qemud_driver *)conn->privateData;
+ char *p;
+
+ if (!driver->securityDriver)
+ return -2;
+
+ p = driver->caps->host.secModel.model;
+ if (strlen(p) >= VIR_SECURITY_MODEL_BUFLEN-1) {
+ qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
+ _("security model string exceeds max %d bytes"),
+ VIR_SECURITY_MODEL_BUFLEN-1);
+ return -1;
+ }
+ strcpy(secmodel->model, p);
+
+ p = driver->caps->host.secModel.doi;
+ if (strlen(p) >= VIR_SECURITY_DOI_BUFLEN-1) {
+ qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
+ _("security DOI string exceeds max %d bytes"),
+ VIR_SECURITY_DOI_BUFLEN-1);
+ return -1;
+ }
+ strcpy(secmodel->doi, p);
+ return 0;
+}
+/* TODO: check seclabel restore */
static int qemudDomainRestore(virConnectPtr conn,
const char *path) {
struct qemud_driver *driver = conn->privateData;
@@ -4475,6 +4631,8 @@ static virDriver qemuDriver = {
NULL, /* domainGetVcpus */
#endif
qemudDomainGetMaxVcpus, /* domainGetMaxVcpus */
+ qemudDomainGetSecurityLabel, /* domainGetSecurityLabel */
+ qemudNodeGetSecurityModel, /* nodeGetSecurityModel */
qemudDomainDumpXML, /* domainDumpXML */
qemudListDefinedDomains, /* listDomains */
qemudNumDefinedDomains, /* numOfDomains */
diff -up libvirt-0.6.0/src/remote_internal.c.svirt libvirt-0.6.0/src/remote_internal.c
--- libvirt-0.6.0/src/remote_internal.c.svirt 2009-02-17 10:07:06.207699000 -0500
+++ libvirt-0.6.0/src/remote_internal.c 2009-02-17 10:14:28.509959000 -0500
@@ -2299,6 +2299,67 @@ done:
return rv;
}
+static int
+remoteDomainGetSecurityLabel (virDomainPtr domain, virSecurityLabelPtr seclabel)
+{
+ remote_domain_get_security_label_args args;
+ remote_domain_get_security_label_ret ret;
+ struct private_data *priv = domain->conn->privateData;
+
+ make_nonnull_domain (&args.dom, domain);
+ memset (&ret, 0, sizeof ret);
+ if (call (domain->conn, priv, 0, REMOTE_PROC_DOMAIN_GET_SECURITY_LABEL,
+ (xdrproc_t) xdr_remote_domain_get_security_label_args, (char *)&args,
+ (xdrproc_t) xdr_remote_domain_get_security_label_ret, (char *)&ret) == -1) {
+ return -1;
+ }
+
+ if (ret.label.label_val != NULL) {
+ if (strlen (ret.label.label_val) >= sizeof seclabel->label) {
+ errorf (domain->conn, VIR_ERR_RPC, _("security label exceeds maximum: %zd"),
+ sizeof seclabel->label - 1);
+ return -1;
+ }
+ strcpy (seclabel->label, ret.label.label_val);
+ seclabel->enforcing = ret.enforcing;
+ }
+
+ return 0;
+}
+
+static int
+remoteNodeGetSecurityModel (virConnectPtr conn, virSecurityModelPtr secmodel)
+{
+ remote_node_get_security_model_ret ret;
+ struct private_data *priv = conn->privateData;
+
+ memset (&ret, 0, sizeof ret);
+ if (call (conn, priv, 0, REMOTE_PROC_NODE_GET_SECURITY_MODEL,
+ (xdrproc_t) xdr_void, NULL,
+ (xdrproc_t) xdr_remote_node_get_security_model_ret, (char *)&ret) == -1) {
+ return -1;
+ }
+
+ if (ret.model.model_val != NULL) {
+ if (strlen (ret.model.model_val) >= sizeof secmodel->model) {
+ errorf (conn, VIR_ERR_RPC, _("security model exceeds maximum: %zd"),
+ sizeof secmodel->model - 1);
+ return -1;
+ }
+ strcpy (secmodel->model, ret.model.model_val);
+ }
+
+ if (ret.doi.doi_val != NULL) {
+ if (strlen (ret.doi.doi_val) >= sizeof secmodel->doi) {
+ errorf (conn, VIR_ERR_RPC, _("security doi exceeds maximum: %zd"),
+ sizeof secmodel->doi - 1);
+ return -1;
+ }
+ strcpy (secmodel->doi, ret.doi.doi_val);
+ }
+ return 0;
+}
+
static char *
remoteDomainDumpXML (virDomainPtr domain, int flags)
{
@@ -6721,6 +6782,8 @@ static virDriver driver = {
.domainPinVcpu = remoteDomainPinVcpu,
.domainGetVcpus = remoteDomainGetVcpus,
.domainGetMaxVcpus = remoteDomainGetMaxVcpus,
+ .domainGetSecurityLabel = remoteDomainGetSecurityLabel,
+ .nodeGetSecurityModel = remoteNodeGetSecurityModel,
.domainDumpXML = remoteDomainDumpXML,
.listDefinedDomains = remoteListDefinedDomains,
.numOfDefinedDomains = remoteNumOfDefinedDomains,
diff -up /dev/null libvirt-0.6.0/src/security.c
--- /dev/null 2009-02-11 16:31:53.992012235 -0500
+++ libvirt-0.6.0/src/security.c 2009-02-17 10:07:06.396676000 -0500
@@ -0,0 +1,133 @@
+/*
+ * Copyright (C) 2008 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Authors:
+ * James Morris <jmorris(a)namei.org>
+ *
+ */
+#include <config.h>
+#include <string.h>
+
+#include "virterror_internal.h"
+
+#include "security.h"
+
+#if HAVE_SELINUX
+#include "security_selinux.h"
+#endif
+
+static virSecurityDriverStatus testSecurityDriverProbe(void)
+{
+ return SECURITY_DRIVER_DISABLE;
+}
+
+virSecurityDriver virTestSecurityDriver = {
+ .name = "test",
+ .probe = testSecurityDriverProbe,
+};
+
+static virSecurityDriverPtr security_drivers[] = {
+ &virTestSecurityDriver,
+#ifdef HAVE_SELINUX
+ &virSELinuxSecurityDriver,
+#endif
+};
+
+/*
+ * Probe each security driver: each should perform a test to see if it
+ * should be loaded, e.g. if the currently active host security mechanism
+ * matches. If the probe succeeds, initialize the driver and return it.
+ *
+ * Returns 0 on success, and -1 on error. If no security driver wanted to
+ * be enabled, then return -2 and let the caller determine what this really
+ * means.
+ */
+int
+virSecurityDriverStartup(virSecurityDriverPtr * drv)
+{
+ unsigned int i;
+
+ for (i = 0; i < (sizeof(security_drivers) / sizeof(security_drivers[0])); i++) {
+ virSecurityDriverPtr tmp = security_drivers[i];
+ virSecurityDriverStatus ret = tmp->probe();
+
+ switch (ret) {
+ case SECURITY_DRIVER_ENABLE:
+ virSecurityDriverInit(tmp);
+ if (tmp->open(NULL, tmp) == -1) {
+ return -1;
+ } else {
+ *drv = tmp;
+ return 0;
+ }
+ break;
+
+ case SECURITY_DRIVER_DISABLE:
+ break;
+
+ default:
+ return -1;
+ }
+ }
+ return -2;
+}
+
+void
+virSecurityReportError(virConnectPtr conn, int code, const char *fmt, ...)
+{
+ va_list args;
+ char errorMessage[1024];
+
+ if (fmt) {
+ va_start(args, fmt);
+ vsnprintf(errorMessage, sizeof(errorMessage) - 1, fmt, args);
+ va_end(args);
+ } else
+ errorMessage[0] = '\0';
+
+ virRaiseError(conn, NULL, NULL, VIR_FROM_SECURITY, code,
+ VIR_ERR_ERROR, NULL, NULL, NULL, -1, -1, "%s",
+ errorMessage);
+}
+
+/*
+ * Helpers
+ */
+void
+virSecurityDriverInit(virSecurityDriverPtr drv)
+{
+ memset(&drv->_private, 0, sizeof drv->_private);
+}
+
+int
+virSecurityDriverSetDOI(virConnectPtr conn,
+ virSecurityDriverPtr drv,
+ const char *doi)
+{
+ if (strlen(doi) >= VIR_SECURITY_DOI_BUFLEN) {
+ virSecurityReportError(conn, VIR_ERR_ERROR,
+ _("%s: DOI \'%s\' is "
+ "longer than the maximum allowed length of %d"),
+ __func__, doi, VIR_SECURITY_DOI_BUFLEN - 1);
+ return -1;
+ }
+ strcpy(drv->_private.doi, doi);
+ return 0;
+}
+
+const char *
+virSecurityDriverGetDOI(virSecurityDriverPtr drv)
+{
+ return drv->_private.doi;
+}
+
+const char *
+virSecurityDriverGetModel(virSecurityDriverPtr drv)
+{
+ return drv->name;
+}
diff -up /dev/null libvirt-0.6.0/src/security.h
--- /dev/null 2009-02-11 16:31:53.992012235 -0500
+++ libvirt-0.6.0/src/security.h 2009-02-17 10:07:06.402676000 -0500
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2008 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Authors:
+ * James Morris <jmorris(a)namei.org>
+ *
+ */
+#ifndef __VIR_SECURITY_H__
+#define __VIR_SECURITY_H__
+
+#include "internal.h"
+#include "domain_conf.h"
+
+/*
+ * Return values for security driver probing: the driver will determine
+ * whether it should be enabled or disabled.
+ */
+typedef enum {
+ SECURITY_DRIVER_ENABLE = 0,
+ SECURITY_DRIVER_ERROR = -1,
+ SECURITY_DRIVER_DISABLE = -2,
+} virSecurityDriverStatus;
+
+typedef struct _virSecurityDriver virSecurityDriver;
+typedef virSecurityDriver *virSecurityDriverPtr;
+typedef virSecurityDriverStatus (*virSecurityDriverProbe) (void);
+typedef int (*virSecurityDriverOpen) (virConnectPtr conn,
+ virSecurityDriverPtr drv);
+typedef int (*virSecurityDomainGetLabel) (virConnectPtr conn,
+ virDomainObjPtr vm,
+ virSecurityLabelPtr sec);
+typedef int (*virSecurityDomainSetLabel) (virConnectPtr conn,
+ virSecurityDriverPtr drv,
+ virSecurityLabelDefPtr secdef);
+
+struct _virSecurityDriver {
+ const char *name;
+ virSecurityDriverProbe probe;
+ virSecurityDriverOpen open;
+ virSecurityDomainGetLabel domainGetSecurityLabel;
+ virSecurityDomainSetLabel domainSetSecurityLabel;
+
+ /*
+ * This is internally managed driver state and should only be accessed
+ * via helpers below.
+ */
+ struct {
+ char doi[VIR_SECURITY_DOI_BUFLEN];
+ } _private;
+};
+
+/* Global methods */
+int virSecurityDriverStartup(virSecurityDriverPtr * drv);
+
+void
+virSecurityReportError(virConnectPtr conn, int code, const char *fmt, ...)
+ ATTRIBUTE_FORMAT(printf, 3, 4);
+
+/* Helpers */
+void virSecurityDriverInit(virSecurityDriverPtr drv);
+int virSecurityDriverSetDOI(virConnectPtr conn,
+ virSecurityDriverPtr drv,
+ const char *doi);
+const char *virSecurityDriverGetDOI(virSecurityDriverPtr drv);
+const char *virSecurityDriverGetModel(virSecurityDriverPtr drv);
+
+#endif /* __VIR_SECURITY_H__ */
diff -up /dev/null libvirt-0.6.0/src/security_selinux.c
--- /dev/null 2009-02-11 16:31:53.992012235 -0500
+++ libvirt-0.6.0/src/security_selinux.c 2009-02-17 10:07:06.407678000 -0500
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2008 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Authors:
+ * James Morris <jmorris(a)namei.org>
+ *
+ * SELinux security driver.
+ */
+#include <config.h>
+#include <selinux/selinux.h>
+
+#include "security.h"
+#include "security_selinux.h"
+
+#define SECURITY_SELINUX_VOID_DOI "0"
+
+static int
+SELinuxSecurityDriverProbe(void)
+{
+ return is_selinux_enabled() ? SECURITY_DRIVER_ENABLE : SECURITY_DRIVER_DISABLE;
+}
+
+static int
+SELinuxSecurityDriverOpen(virConnectPtr conn, virSecurityDriverPtr drv)
+{
+ /*
+ * Where will the DOI come from? SELinux configuration, or qemu
+ * configuration? For the moment, we'll just set it to "0".
+ */
+ virSecurityDriverSetDOI(conn, drv, SECURITY_SELINUX_VOID_DOI);
+
+ return 0;
+}
+
+static int
+SELinuxSecurityDomainGetSecurityLabel(virConnectPtr conn,
+ virDomainObjPtr vm,
+ virSecurityLabelPtr sec)
+{
+ security_context_t ctx;
+
+ if (getpidcon(vm->pid, &ctx) == -1) {
+ virSecurityReportError(conn, VIR_ERR_ERROR, _("%s: error calling "
+ "getpidcon(): %s"), __func__,
+ strerror(errno));
+ return -1;
+ }
+
+ if (strlen((char *) ctx) >= VIR_SECURITY_LABEL_BUFLEN) {
+ virSecurityReportError(conn, VIR_ERR_ERROR,
+ _("%s: security label exceeds "
+ "maximum length: %d"), __func__,
+ VIR_SECURITY_LABEL_BUFLEN - 1);
+ return -1;
+ }
+
+ strcpy(sec->label, (char *) ctx);
+ free(ctx);
+
+ sec->enforcing = security_getenforce();
+ if (sec->enforcing == -1) {
+ virSecurityReportError(conn, VIR_ERR_ERROR, _("%s: error calling "
+ "security_getenforce(): %s"), __func__,
+ strerror(errno));
+ return -1;
+ }
+
+ return 0;
+}
+
+static int
+SELinuxSecurityDomainSetSecurityLabel(virConnectPtr conn,
+ virSecurityDriverPtr drv,
+ const virSecurityLabelDefPtr secdef)
+{
+ /* TODO: verify DOI */
+
+ if (!STREQ(drv->name, secdef->model)) {
+ virSecurityReportError(conn, VIR_ERR_ERROR,
+ _("%s: security label driver mismatch: "
+ "\'%s\' model configured for domain, but "
+ "hypervisor driver is \'%s\'."),
+ __func__, secdef->model, drv->name);
+ return -1;
+ }
+
+ if (setexeccon(secdef->label) == -1) {
+ virSecurityReportError(conn, VIR_ERR_ERROR,
+ _("%s: unable to set security context "
+ "'\%s\': %s."), __func__, secdef->label,
+ strerror(errno));
+ return -1;
+ }
+ return 0;
+}
+
+virSecurityDriver virSELinuxSecurityDriver = {
+ .name = "selinux",
+ .probe = SELinuxSecurityDriverProbe,
+ .open = SELinuxSecurityDriverOpen,
+ .domainGetSecurityLabel = SELinuxSecurityDomainGetSecurityLabel,
+ .domainSetSecurityLabel = SELinuxSecurityDomainSetSecurityLabel,
+};
diff -up /dev/null libvirt-0.6.0/src/security_selinux.h
--- /dev/null 2009-02-11 16:31:53.992012235 -0500
+++ libvirt-0.6.0/src/security_selinux.h 2009-02-17 10:07:06.413677000 -0500
@@ -0,0 +1,18 @@
+/*
+ * Copyright (C) 2008 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Authors:
+ * James Morris <jmorris(a)namei.org>
+ *
+ */
+#ifndef __VIR_SECURITY_SELINUX_H__
+#define __VIR_SECURITY_SELINUX_H__
+
+extern virSecurityDriver virSELinuxSecurityDriver;
+
+#endif /* __VIR_SECURITY_SELINUX_H__ */
diff -up libvirt-0.6.0/src/storage_backend.c.svirt libvirt-0.6.0/src/storage_backend.c
--- libvirt-0.6.0/src/storage_backend.c.svirt 2009-01-31 04:04:18.000000000 -0500
+++ libvirt-0.6.0/src/storage_backend.c 2009-02-17 10:07:06.419677000 -0500
@@ -276,6 +276,7 @@ virStorageBackendUpdateVolTargetInfoFD(v
VIR_FREE(target->perms.label);
#if HAVE_SELINUX
+ /* XXX: make this a security driver call */
if (fgetfilecon(fd, &filecon) == -1) {
if (errno != ENODATA && errno != ENOTSUP) {
virReportSystemError(conn, errno,
diff -up libvirt-0.6.0/src/test.c.svirt libvirt-0.6.0/src/test.c
--- libvirt-0.6.0/src/test.c.svirt 2009-01-20 15:39:28.000000000 -0500
+++ libvirt-0.6.0/src/test.c 2009-02-17 10:07:06.428677000 -0500
@@ -3510,6 +3510,8 @@ static virDriver testDriver = {
NULL, /* domainPinVcpu */
NULL, /* domainGetVcpus */
NULL, /* domainGetMaxVcpus */
+ NULL, /* domainGetSecurityLabel */
+ NULL, /* nodeGetSecurityModel */
testDomainDumpXML, /* domainDumpXML */
testListDefinedDomains, /* listDefinedDomains */
testNumOfDefinedDomains, /* numOfDefinedDomains */
diff -up libvirt-0.6.0/src/uml_driver.c.svirt libvirt-0.6.0/src/uml_driver.c
--- libvirt-0.6.0/src/uml_driver.c.svirt 2009-01-31 04:04:18.000000000 -0500
+++ libvirt-0.6.0/src/uml_driver.c 2009-02-17 10:07:06.436676000 -0500
@@ -1852,6 +1852,8 @@ static virDriver umlDriver = {
NULL, /* domainPinVcpu */
NULL, /* domainGetVcpus */
NULL, /* domainGetMaxVcpus */
+ NULL, /* domainGetSecurityLabel */
+ NULL, /* nodeGetSecurityModel */
umlDomainDumpXML, /* domainDumpXML */
umlListDefinedDomains, /* listDomains */
umlNumDefinedDomains, /* numOfDomains */
diff -up libvirt-0.6.0/src/virsh.c.svirt libvirt-0.6.0/src/virsh.c
--- libvirt-0.6.0/src/virsh.c.svirt 2009-01-31 04:04:18.000000000 -0500
+++ libvirt-0.6.0/src/virsh.c 2009-02-17 10:07:06.447677000 -0500
@@ -954,6 +954,7 @@ static const vshCmdOptDef opts_undefine[
{NULL, 0, 0, NULL}
};
+/* XXX MAC policy for defining & undefining domains ?? */
static int
cmdUndefine(vshControl *ctl, const vshCmd *cmd)
{
@@ -1515,6 +1516,8 @@ cmdDominfo(vshControl *ctl, const vshCmd
{
virDomainInfo info;
virDomainPtr dom;
+ virSecurityModel secmodel;
+ virSecurityLabel seclabel;
int ret = TRUE, autostart;
unsigned int id;
char *str, uuid[VIR_UUID_STRING_BUFLEN];
@@ -1573,6 +1576,29 @@ cmdDominfo(vshControl *ctl, const vshCmd
autostart ? _("enable") : _("disable") );
}
+ /* Security model and label information */
+ memset(&secmodel, 0, sizeof secmodel);
+ if (virNodeGetSecurityModel(ctl->conn, &secmodel) == -1) {
+ virDomainFree(dom);
+ return FALSE;
+ } else {
+ /* Only print something if a security model is active */
+ if (secmodel.model[0] != '\0') {
+ vshPrint(ctl, "%-15s %s\n", _("Security model:"), secmodel.model);
+ vshPrint(ctl, "%-15s %s\n", _("Security DOI:"), secmodel.doi);
+
+ /* Security labels are only valid for active domains */
+ memset(&seclabel, 0, sizeof seclabel);
+ if (virDomainGetSecurityLabel(dom, &seclabel) == -1) {
+ virDomainFree(dom);
+ return FALSE;
+ } else {
+ if (seclabel.label[0] != '\0')
+ vshPrint(ctl, "%-15s %s (%s)\n", _("Security label:"),
+ seclabel.label, seclabel.enforcing ? "enforcing" : "permissive");
+ }
+ }
+ }
virDomainFree(dom);
return ret;
}
diff -up libvirt-0.6.0/src/virterror.c.svirt libvirt-0.6.0/src/virterror.c
--- libvirt-0.6.0/src/virterror.c.svirt 2009-01-31 04:04:18.000000000 -0500
+++ libvirt-0.6.0/src/virterror.c 2009-02-17 10:07:06.454684000 -0500
@@ -151,6 +151,9 @@ static const char *virErrorDomainName(vi
case VIR_FROM_UML:
dom = "UML ";
break;
+ case VIR_FROM_SECURITY:
+ dom = "Security Labeling ";
+ break;
}
return(dom);
}
@@ -962,6 +965,12 @@ virErrorMsg(virErrorNumber error, const
else
errmsg = _("Node device not found: %s");
break;
+ case VIR_ERR_NO_SECURITY_MODEL:
+ if (info == NULL)
+ errmsg = _("Security model not found");
+ else
+ errmsg = _("Security model not found: %s");
+ break;
}
return (errmsg);
}
diff -up libvirt-0.6.0/src/xml.c.svirt libvirt-0.6.0/src/xml.c
--- libvirt-0.6.0/src/xml.c.svirt 2009-01-31 04:04:18.000000000 -0500
+++ libvirt-0.6.0/src/xml.c 2009-02-17 10:07:06.461676000 -0500
@@ -77,6 +77,39 @@ virXPathString(virConnectPtr conn,
}
/**
+ * virXPathStringLimit:
+ * @xpath: the XPath string to evaluate
+ * @maxlen: maximum length permittred string
+ * @ctxt: an XPath context
+ *
+ * Wrapper for virXPathString, which validates the length of the returned
+ * string.
+ *
+ * Returns a new string which must be deallocated by the caller or NULL if
+ * the evaluation failed.
+ */
+char *
+virXPathStringLimit(virConnectPtr conn,
+ const char *xpath,
+ size_t maxlen,
+ xmlXPathContextPtr ctxt)
+{
+ char *tmp = virXPathString(conn, xpath, ctxt);
+
+ if (tmp != NULL) {
+ if (strlen(tmp) >= maxlen) {
+ virXMLError(conn, VIR_ERR_INTERNAL_ERROR,
+ _("\'%s\' value longer than %Zd bytes in virXPathStringLimit()"),
+ xpath, maxlen);
+ return NULL;
+ }
+ } else
+ virXMLError(conn, VIR_ERR_INTERNAL_ERROR,
+ _("\'%s\' missing in virXPathStringLimit()"), xpath);
+ return tmp;
+}
+
+/**
* virXPathNumber:
* @xpath: the XPath string to evaluate
* @ctxt: an XPath context
diff -up libvirt-0.6.0/src/xml.h.svirt libvirt-0.6.0/src/xml.h
--- libvirt-0.6.0/src/xml.h.svirt 2008-08-12 03:13:00.000000000 -0400
+++ libvirt-0.6.0/src/xml.h 2009-02-17 10:07:06.467677000 -0500
@@ -17,6 +17,10 @@ int virXPathBoolean (virConnectPtr conn
char * virXPathString (virConnectPtr conn,
const char *xpath,
xmlXPathContextPtr ctxt);
+char * virXPathStringLimit(virConnectPtr conn,
+ const char *xpath,
+ size_t maxlen,
+ xmlXPathContextPtr ctxt);
int virXPathNumber (virConnectPtr conn,
const char *xpath,
xmlXPathContextPtr ctxt,
diff -up libvirt-0.6.0/tests/daemon-conf.svirt libvirt-0.6.0/tests/daemon-conf
--- libvirt-0.6.0/tests/daemon-conf.svirt 2008-12-22 08:21:49.000000000 -0500
+++ libvirt-0.6.0/tests/daemon-conf 2009-02-17 10:07:06.470678000 -0500
@@ -63,6 +63,9 @@ while :; do
-e '/^libnuma: Warning: .sys not mounted or no numa system/d' \
err > k && mv k err
+ # Filter out this diagnostic, too.
+ sed '/^Initialized security driver/d' err > k && mv k err
+
printf '%s\n\n' "remoteReadConfigFile: $f: $param_name: $msg" > expected-err
diff -u expected-err err || fail=1
5
24
HI All
I have KVM virtual machine running under bridging.I don't want to use bridging/Nating.I want to use routing via IPTABLES to route traffic toward the virtual machine is that possible.These thing benifit me in flitering .And i have live ip on virtual machine.Please let me how i can achive this.
_________________________________________________________________
Windows Liveâ„¢ Groups: Create an online spot for your favorite groups to meet.
http://windowslive.com/online/groups?ocid=TXT_TAGLM_WL_groups_032009
1
0
[libvirt] [PATCH] virsh: adjust remaining format strings to avoid emitting trailing space
by Jim Meyering 03 Mar '09
by Jim Meyering 03 Mar '09
03 Mar '09
This may help avoid testing churn and makes the format strings more uniform.
This is identical to yesterday's change,
http://git.et.redhat.com/?p=libvirt.git;a=commitdiff;h=b285e110625
but applies the same idea to all of the format strings.
>From 2a837515b419cadd1943b3078e5d7b3b116e42ef Mon Sep 17 00:00:00 2001
From: Jim Meyering <meyering(a)redhat.com>
Date: Tue, 3 Mar 2009 13:28:39 +0100
Subject: [PATCH] virsh: adjust remaining format strings to avoid emitting trailing space
* src/virsh.c (cmdNetworkList, cmdPoolList, cmdVolList): Change
format strings like "%-20s\n" to "%s\n".
---
src/virsh.c | 13 +++++++------
1 files changed, 7 insertions(+), 6 deletions(-)
diff --git a/src/virsh.c b/src/virsh.c
index 6a257ca..9f143a0 100644
--- a/src/virsh.c
+++ b/src/virsh.c
@@ -2640,7 +2640,7 @@ cmdNetworkList(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED)
else
autostartStr = autostart ? "yes" : "no";
- vshPrint(ctl, "%-20s %-10s %-10s\n",
+ vshPrint(ctl, "%-20s %-10s %s\n",
virNetworkGetName(network),
_("active"),
autostartStr);
@@ -3370,7 +3370,8 @@ cmdPoolList(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED)
qsort(&inactiveNames[0], maxinactive, sizeof(char*), namesorter);
}
}
- vshPrintExtra(ctl, "%-20s %-10s %-10s\n", _("Name"), _("State"), _("Autostart"));
+ vshPrintExtra(ctl, "%-20s %-10s %s\n",
+ _("Name"), _("State"), _("Autostart"));
vshPrintExtra(ctl, "-----------------------------------------\n");
for (i = 0; i < maxactive; i++) {
@@ -3389,7 +3390,7 @@ cmdPoolList(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED)
else
autostartStr = autostart ? "yes" : "no";
- vshPrint(ctl, "%-20s %-10s %-10s\n",
+ vshPrint(ctl, "%-20s %-10s %s\n",
virStoragePoolGetName(pool),
_("active"),
autostartStr);
@@ -3412,7 +3413,7 @@ cmdPoolList(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED)
else
autostartStr = autostart ? "yes" : "no";
- vshPrint(ctl, "%-20s %-10s %-10s\n",
+ vshPrint(ctl, "%-20s %-10s %s\n",
inactiveNames[i],
_("inactive"),
autostartStr);
@@ -4155,7 +4156,7 @@ cmdVolList(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED)
qsort(&activeNames[0], maxactive, sizeof(char *), namesorter);
}
- vshPrintExtra(ctl, "%-20s %-40s\n", _("Name"), _("Path"));
+ vshPrintExtra(ctl, "%-20s %s\n", _("Name"), _("Path"));
vshPrintExtra(ctl, "-----------------------------------------\n");
for (i = 0; i < maxactive; i++) {
@@ -4174,7 +4175,7 @@ cmdVolList(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED)
}
- vshPrint(ctl, "%-20s %-40s\n",
+ vshPrint(ctl, "%-20s %s\n",
virStorageVolGetName(vol),
path);
free(path);
--
1.6.2.rc1.285.gc5f54
2
1
[libvirt] [PATCH] don't leak a file descriptor on failed pciGetDevice call
by Jim Meyering 03 Mar '09
by Jim Meyering 03 Mar '09
03 Mar '09
This loop would mistakenly return early (skipping the closedir)
upon pciGetDevice failure.
>From 2d4d1d25edf8f1c3f4770707215bba67d73fd59f Mon Sep 17 00:00:00 2001
From: Jim Meyering <meyering(a)redhat.com>
Date: Tue, 3 Mar 2009 11:11:07 +0100
Subject: [PATCH] don't leak a file descriptor on failed pciGetDevice call
* src/pci.c (pciIterDevices): Always close dir handle.
---
src/pci.c | 14 +++++++++-----
1 files changed, 9 insertions(+), 5 deletions(-)
diff --git a/src/pci.c b/src/pci.c
index 2343be3..501c6aa 100644
--- a/src/pci.c
+++ b/src/pci.c
@@ -233,6 +233,7 @@ pciIterDevices(virConnectPtr conn,
{
DIR *dir;
struct dirent *entry;
+ int ret = 0;
*matched = NULL;
@@ -252,14 +253,17 @@ pciIterDevices(virConnectPtr conn,
if (entry->d_name[0] == '.')
continue;
- if (sscanf(entry->d_name, "%x:%x:%x.%x", &domain, &bus, &slot, &function) < 4) {
+ if (sscanf(entry->d_name, "%x:%x:%x.%x",
+ &domain, &bus, &slot, &function) < 4) {
VIR_WARN("Unusual entry in " PCI_SYSFS "devices: %s", entry->d_name);
continue;
}
try = pciGetDevice(conn, domain, bus, slot, function);
- if (!try)
- return -1;
+ if (!try) {
+ ret = -1;
+ break;
+ }
if (predicate(try, dev)) {
VIR_DEBUG("%s %s: iter matched on %s", dev->id, dev->name, try->name);
@@ -269,7 +273,7 @@ pciIterDevices(virConnectPtr conn,
pciFreeDevice(conn, try);
}
closedir(dir);
- return 0;
+ return ret;
}
static uint8_t
@@ -823,7 +827,7 @@ void
pciFreeDevice(virConnectPtr conn ATTRIBUTE_UNUSED, pciDevice *dev)
{
VIR_DEBUG("%s %s: freeing", dev->id, dev->name);
- if (dev->fd)
+ if (dev->fd >= 0)
close(dev->fd);
VIR_FREE(dev);
}
--
1.6.2.rc1.285.gc5f54
2
4
03 Mar '09
The qemudLog() macro just spews its messages to stderr. This patch changes
it to use the proper logging.h APIs, so the output channel is configurable
in the expected way.
Daniel
diff --git a/src/iptables.c b/src/iptables.c
--- a/src/iptables.c
+++ b/src/iptables.c
@@ -45,8 +45,7 @@
#include "util.h"
#include "memory.h"
#include "virterror_internal.h"
-
-#define qemudLog(level, msg...) fprintf(stderr, msg)
+#include "logging.h"
enum {
ADD = 0,
@@ -101,7 +100,7 @@ notifyRulesUpdated(const char *table,
char ebuf[1024];
if (virRun(NULL, argv, NULL) < 0)
- qemudLog(QEMUD_WARN, _("Failed to run '%s %s': %s"),
+ VIR_WARN(_("Failed to run '%s %s': %s"),
LOKKIT_PATH, arg, virStrerror(errno, ebuf, sizeof ebuf));
}
@@ -149,8 +148,8 @@ notifyRulesRemoved(const char *table,
len = virFileReadAll(SYSCONF_DIR "/sysconfig/system-config-firewall",
MAX_FILE_LEN, &content);
if (len < 0) {
- qemudLog(QEMUD_WARN, "%s", _("Failed to read " SYSCONF_DIR
- "/sysconfig/system-config-firewall"));
+ VIR_WARN("%s", _("Failed to read " SYSCONF_DIR
+ "/sysconfig/system-config-firewall"));
return;
}
@@ -178,8 +177,8 @@ notifyRulesRemoved(const char *table,
write_error:;
char ebuf[1024];
- qemudLog(QEMUD_WARN, _("Failed to write to " SYSCONF_DIR
- "/sysconfig/system-config-firewall : %s"),
+ VIR_WARN(_("Failed to write to " SYSCONF_DIR
+ "/sysconfig/system-config-firewall : %s"),
virStrerror(errno, ebuf, sizeof ebuf));
if (f)
fclose(f);
@@ -244,13 +243,13 @@ iptRulesSave(iptRules *rules)
char ebuf[1024];
if ((err = virFileMakePath(rules->dir))) {
- qemudLog(QEMUD_WARN, _("Failed to create directory %s : %s"),
+ VIR_WARN(_("Failed to create directory %s : %s"),
rules->dir, virStrerror(err, ebuf, sizeof ebuf));
return;
}
if ((err = writeRules(rules->path, rules->rules, rules->nrules))) {
- qemudLog(QEMUD_WARN, _("Failed to saves iptables rules to %s : %s"),
+ VIR_WARN(_("Failed to saves iptables rules to %s : %s"),
rules->path, virStrerror(err, ebuf, sizeof ebuf));
return;
}
@@ -551,8 +550,7 @@ iptRulesReload(iptRules *rules)
rule->argv[rule->command_idx] = (char *) "--delete";
if (virRun(NULL, rule->argv, NULL) < 0)
- qemudLog(QEMUD_WARN,
- _("Failed to remove iptables rule '%s'"
+ VIR_WARN(_("Failed to remove iptables rule '%s'"
" from chain '%s' in table '%s': %s"),
rule->rule, rules->chain, rules->table,
virStrerror(errno, ebuf, sizeof ebuf));
@@ -562,8 +560,8 @@ iptRulesReload(iptRules *rules)
for (i = 0; i < rules->nrules; i++)
if (virRun(NULL, rules->rules[i].argv, NULL) < 0)
- qemudLog(QEMUD_WARN, _("Failed to add iptables rule '%s'"
- " to chain '%s' in table '%s': %s"),
+ VIR_WARN(_("Failed to add iptables rule '%s'"
+ " to chain '%s' in table '%s': %s"),
rules->rules[i].rule, rules->chain, rules->table,
virStrerror(errno, ebuf, sizeof ebuf));
}
diff --git a/src/qemu_conf.c b/src/qemu_conf.c
--- a/src/qemu_conf.c
+++ b/src/qemu_conf.c
@@ -47,6 +47,7 @@
#include "datatypes.h"
#include "xml.h"
#include "nodeinfo.h"
+#include "logging.h"
#define VIR_FROM_THIS VIR_FROM_QEMU
@@ -77,8 +78,6 @@ VIR_ENUM_IMPL(qemuDiskCacheV2, VIR_DOMAI
"writeback");
-#define qemudLog(level, msg...) fprintf(stderr, msg)
-
int qemudLoadDriverConfig(struct qemud_driver *driver,
const char *filename) {
virConfPtr conf;
@@ -469,18 +468,16 @@ rewait:
if (errno == EINTR)
goto rewait;
- qemudLog(QEMUD_ERR,
- _("Unexpected exit status from qemu %d pid %lu"),
- WEXITSTATUS(status), (unsigned long)child);
+ VIR_ERROR(_("Unexpected exit status from qemu %d pid %lu"),
+ WEXITSTATUS(status), (unsigned long)child);
ret = -1;
}
/* Check & log unexpected exit status, but don't fail,
* as there's really no need to throw an error if we did
* actually read a valid version number above */
if (WEXITSTATUS(status) != 0) {
- qemudLog(QEMUD_WARN,
- _("Unexpected exit status '%d', qemu probably failed"),
- WEXITSTATUS(status));
+ VIR_ERROR(_("Unexpected exit status '%d', qemu probably failed"),
+ WEXITSTATUS(status));
}
return ret;
diff --git a/src/qemu_driver.c b/src/qemu_driver.c
--- a/src/qemu_driver.c
+++ b/src/qemu_driver.c
@@ -82,8 +82,6 @@
static int qemudShutdown(void);
-#define qemudLog(level, msg...) fprintf(stderr, msg)
-
static void qemuDriverLock(struct qemud_driver *driver)
{
virMutexLock(&driver->lock);
@@ -220,9 +218,9 @@ qemudAutostartConfigs(struct qemud_drive
int ret = qemudStartVMDaemon(conn, driver, vm, NULL, -1);
if (ret < 0) {
virErrorPtr err = virGetLastError();
- qemudLog(QEMUD_ERROR, _("Failed to autostart VM '%s': %s\n"),
- vm->def->name,
- err ? err->message : NULL);
+ VIR_ERROR(_("Failed to autostart VM '%s': %s\n"),
+ vm->def->name,
+ err ? err->message : NULL);
} else {
virDomainEventPtr event =
virDomainEventNewFromObj(vm,
@@ -306,8 +304,8 @@ qemudReconnectVMs(struct qemud_driver *d
if ((config = virDomainConfigFile(NULL,
driver->stateDir,
vm->def->name)) == NULL) {
- qemudLog(QEMUD_ERROR, _("Failed to read domain status for %s\n"),
- vm->def->name);
+ VIR_ERROR(_("Failed to read domain status for %s\n"),
+ vm->def->name);
goto next_error;
}
@@ -316,14 +314,14 @@ qemudReconnectVMs(struct qemud_driver *d
vm->newDef = vm->def;
vm->def = status->def;
} else {
- qemudLog(QEMUD_ERROR, _("Failed to parse domain status for %s\n"),
- vm->def->name);
+ VIR_ERROR(_("Failed to parse domain status for %s\n"),
+ vm->def->name);
goto next_error;
}
if ((rc = qemudOpenMonitor(NULL, driver, vm, status->monitorpath, 1)) != 0) {
- qemudLog(QEMUD_ERROR, _("Failed to reconnect monitor for %s: %d\n"),
- vm->def->name, rc);
+ VIR_ERROR(_("Failed to reconnect monitor for %s: %d\n"),
+ vm->def->name, rc);
goto next_error;
}
@@ -369,7 +367,7 @@ qemudStartup(void) {
return -1;
if (virMutexInit(&qemu_driver->lock) < 0) {
- qemudLog(QEMUD_ERROR, "%s", _("cannot initialize mutex"));
+ VIR_ERROR("%s", _("cannot initialize mutex"));
VIR_FREE(qemu_driver);
return -1;
}
@@ -422,8 +420,8 @@ qemudStartup(void) {
if (virFileMakePath(qemu_driver->stateDir) < 0) {
char ebuf[1024];
- qemudLog(QEMUD_ERROR, _("Failed to create state dir '%s': %s\n"),
- qemu_driver->stateDir, virStrerror(errno, ebuf, sizeof ebuf));
+ VIR_ERROR(_("Failed to create state dir '%s': %s\n"),
+ qemu_driver->stateDir, virStrerror(errno, ebuf, sizeof ebuf));
goto error;
}
@@ -901,7 +899,7 @@ static int qemudWaitForMonitor(virConnec
"console", 3);
if (close(logfd) < 0) {
char ebuf[1024];
- qemudLog(QEMUD_WARN, _("Unable to close logfile: %s\n"),
+ VIR_WARN(_("Unable to close logfile: %s\n"),
virStrerror(errno, ebuf, sizeof ebuf));
}
@@ -1299,29 +1297,29 @@ static int qemudStartVMDaemon(virConnect
tmp = progenv;
while (*tmp) {
if (safewrite(vm->logfile, *tmp, strlen(*tmp)) < 0)
- qemudLog(QEMUD_WARN, _("Unable to write envv to logfile: %s\n"),
+ VIR_WARN(_("Unable to write envv to logfile: %s\n"),
virStrerror(errno, ebuf, sizeof ebuf));
if (safewrite(vm->logfile, " ", 1) < 0)
- qemudLog(QEMUD_WARN, _("Unable to write envv to logfile: %s\n"),
+ VIR_WARN(_("Unable to write envv to logfile: %s\n"),
virStrerror(errno, ebuf, sizeof ebuf));
tmp++;
}
tmp = argv;
while (*tmp) {
if (safewrite(vm->logfile, *tmp, strlen(*tmp)) < 0)
- qemudLog(QEMUD_WARN, _("Unable to write argv to logfile: %s\n"),
+ VIR_WARN(_("Unable to write argv to logfile: %s\n"),
virStrerror(errno, ebuf, sizeof ebuf));
if (safewrite(vm->logfile, " ", 1) < 0)
- qemudLog(QEMUD_WARN, _("Unable to write argv to logfile: %s\n"),
+ VIR_WARN(_("Unable to write argv to logfile: %s\n"),
virStrerror(errno, ebuf, sizeof ebuf));
tmp++;
}
if (safewrite(vm->logfile, "\n", 1) < 0)
- qemudLog(QEMUD_WARN, _("Unable to write argv to logfile: %s\n"),
+ VIR_WARN(_("Unable to write argv to logfile: %s\n"),
virStrerror(errno, ebuf, sizeof ebuf));
if ((pos = lseek(vm->logfile, 0, SEEK_END)) < 0)
- qemudLog(QEMUD_WARN, _("Unable to seek to end of logfile: %s\n"),
+ VIR_WARN(_("Unable to seek to end of logfile: %s\n"),
virStrerror(errno, ebuf, sizeof ebuf));
for (i = 0 ; i < ntapfds ; i++)
@@ -1399,7 +1397,7 @@ static void qemudShutdownVMDaemon(virCon
if (!virDomainIsActive(vm))
return;
- qemudLog(QEMUD_DEBUG, _("Shutting down VM '%s'\n"), vm->def->name);
+ VIR_DEBUG(_("Shutting down VM '%s'\n"), vm->def->name);
if (virKillProcess(vm->pid, 0) == 0 &&
virKillProcess(vm->pid, SIGTERM) < 0)
@@ -1414,7 +1412,7 @@ static void qemudShutdownVMDaemon(virCon
if (close(vm->logfile) < 0) {
char ebuf[1024];
- qemudLog(QEMUD_WARN, _("Unable to close logfile: %s\n"),
+ VIR_WARN(_("Unable to close logfile: %s\n"),
virStrerror(errno, ebuf, sizeof ebuf));
}
if (vm->monitor != -1)
@@ -1426,7 +1424,7 @@ static void qemudShutdownVMDaemon(virCon
virKillProcess(vm->pid, SIGKILL);
if (qemudRemoveDomainStatus(conn, driver, vm) < 0) {
- qemudLog(QEMUD_WARN, _("Failed to remove domain status for %s"),
+ VIR_WARN(_("Failed to remove domain status for %s"),
vm->def->name);
}
vm->pid = -1;
@@ -1473,8 +1471,8 @@ qemudDispatchVMEvent(int watch, int fd,
if (events & (VIR_EVENT_HANDLE_HANGUP | VIR_EVENT_HANDLE_ERROR))
quit = 1;
else {
- qemudLog(QEMUD_ERROR, _("unhandled fd event %d for %s"),
- events, vm->def->name);
+ VIR_ERROR(_("unhandled fd event %d for %s"),
+ events, vm->def->name);
failed = 1;
}
}
@@ -1587,7 +1585,7 @@ qemudMonitorCommandExtra(const virDomain
/* Log, but ignore failures to write logfile for VM */
if (safewrite(vm->logfile, buf, strlen(buf)) < 0) {
char ebuf[1024];
- qemudLog(QEMUD_WARN, _("Unable to log VM console data: %s\n"),
+ VIR_WARN(_("Unable to log VM console data: %s\n"),
virStrerror(errno, ebuf, sizeof ebuf));
}
@@ -1599,7 +1597,7 @@ qemudMonitorCommandExtra(const virDomain
/* Log, but ignore failures to write logfile for VM */
if (safewrite(vm->logfile, buf, strlen(buf)) < 0) {
char ebuf[1024];
- qemudLog(QEMUD_WARN, _("Unable to log VM console data: %s\n"),
+ VIR_WARN(_("Unable to log VM console data: %s\n"),
virStrerror(errno, ebuf, sizeof ebuf));
}
VIR_FREE(buf);
@@ -3380,7 +3378,7 @@ static int qemudDomainAttachPciDiskDevic
s += strlen(PCI_ATTACH_OK_MSG);
if (virStrToLong_i ((const char*)s, &dummy, 10, &dev->data.disk->slotnum) == -1)
- qemudLog(QEMUD_WARN, "%s", _("Unable to parse slot number\n"));
+ VIR_WARN("%s", _("Unable to parse slot number\n"));
} else {
qemudReportError (conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
_("adding %s disk failed"), type);
@@ -4512,8 +4510,8 @@ cleanup:
* overwrite the previous error, though, so we just throw something
* to the logs and hope for the best
*/
- qemudLog(QEMUD_ERROR, _("Failed to resume guest %s after failure\n"),
- vm->def->name);
+ VIR_ERROR(_("Failed to resume guest %s after failure\n"),
+ vm->def->name);
}
else {
DEBUG ("cont reply: %s", info);
diff --git a/src/uuid.c b/src/uuid.c
--- a/src/uuid.c
+++ b/src/uuid.c
@@ -37,8 +37,7 @@
#include "internal.h"
#include "util.h"
#include "virterror_internal.h"
-
-#define qemudLog(level, msg...) fprintf(stderr, msg)
+#include "logging.h"
#ifndef ENODATA
#define ENODATA EIO
@@ -102,8 +101,7 @@ virUUIDGenerate(unsigned char *uuid)
if ((err = virUUIDGenerateRandomBytes(uuid, VIR_UUID_BUFLEN))) {
char ebuf[1024];
- qemudLog(QEMUD_WARN,
- _("Falling back to pseudorandom UUID,"
+ VIR_WARN(_("Falling back to pseudorandom UUID,"
" failed to generate random bytes: %s"),
virStrerror(err, ebuf, sizeof ebuf));
}
--
|: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :|
|: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :|
|: http://autobuild.org -o- http://search.cpan.org/~danberr/ :|
|: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|
2
2