Devel
Threads by month
- ----- 2026 -----
- April
- March
- 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
- 15 participants
- 40168 discussions
[libvirt] [PATCH] docs: updated memtune info again in virsh command reference
by Justin Clift 10 Jan '11
by Justin Clift 10 Jan '11
10 Jan '11
---
Pushed this under the trivial rule.
docs/virshcmdref.html.in | 16 ++++++++--------
1 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/docs/virshcmdref.html.in b/docs/virshcmdref.html.in
index 76eb822..4845312 100644
--- a/docs/virshcmdref.html.in
+++ b/docs/virshcmdref.html.in
@@ -49,21 +49,21 @@
<ul>
<li>
Standard HTML format, multiple pages
- (<a href="http://libvirt.org/sources/virshcmdref/Virsh_Command_Reference-0.8.7-0-html…">.tar.gz</a>)
- (<a href="http://libvirt.org/sources/virshcmdref/Virsh_Command_Reference-0.8.7-0-html…">.tar.bz2</a>)
- (<a href="http://libvirt.org/sources/virshcmdref/Virsh_Command_Reference-0.8.7-0-html…">.zip</a>)
+ (<a href="http://libvirt.org/sources/virshcmdref/Virsh_Command_Reference-0.8.7-1-html…">.tar.gz</a>)
+ (<a href="http://libvirt.org/sources/virshcmdref/Virsh_Command_Reference-0.8.7-1-html…">.tar.bz2</a>)
+ (<a href="http://libvirt.org/sources/virshcmdref/Virsh_Command_Reference-0.8.7-1-html…">.zip</a>)
</li>
<li>
HTML format, one long page
- (<a href="http://libvirt.org/sources/virshcmdref/Virsh_Command_Reference-0.8.7-0-html…">.tar.gz</a>)
- (<a href="http://libvirt.org/sources/virshcmdref/Virsh_Command_Reference-0.8.7-0-html…">.tar.bz2</a>)
- (<a href="http://libvirt.org/sources/virshcmdref/Virsh_Command_Reference-0.8.7-0-html…">.zip</a>)
+ (<a href="http://libvirt.org/sources/virshcmdref/Virsh_Command_Reference-0.8.7-1-html…">.tar.gz</a>)
+ (<a href="http://libvirt.org/sources/virshcmdref/Virsh_Command_Reference-0.8.7-1-html…">.tar.bz2</a>)
+ (<a href="http://libvirt.org/sources/virshcmdref/Virsh_Command_Reference-0.8.7-1-html…">.zip</a>)
</li>
<li>
- <a href="http://libvirt.org/sources/virshcmdref/Virsh_Command_Reference-0.8.7-0.pdf">PDF format</a>
+ <a href="http://libvirt.org/sources/virshcmdref/Virsh_Command_Reference-0.8.7-1.pdf">PDF format</a>
</li>
<li>
- <a href="http://libvirt.org/sources/virshcmdref/Virsh_Command_Reference-0.8.7-0.epub">ePub format</a>
+ <a href="http://libvirt.org/sources/virshcmdref/Virsh_Command_Reference-0.8.7-1.epub">ePub format</a>
</li>
</ul>
--
1.7.3.2
1
1
On Fedore 14, virt-manager spews a bunch of warnings to the console:
/usr/lib64/python2.7/site-packages/libvirt.py:1781: PendingDeprecationWarning: The CObject type is marked Pending Deprecation in Python 2.7. Please use capsule objects instead.
Have libvirt use the capsule API if available. I've verified this compiles
fine on older python (2.6 in RHEL6 which doesn't have capsules), and
virt-manager seems to function fine.
---
python/typewrappers.c | 89 +++++++++++++++++++++++++++---------------------
1 files changed, 50 insertions(+), 39 deletions(-)
diff --git a/python/typewrappers.c b/python/typewrappers.c
index 733aa20..e39d3cd 100644
--- a/python/typewrappers.c
+++ b/python/typewrappers.c
@@ -16,6 +16,26 @@
#include "typewrappers.h"
+#ifndef Py_CAPSULE_H
+typedef void(*PyCapsule_Destructor)(void *, void *);
+#endif
+
+static PyObject *
+libvirt_buildPyObject(void *cobj,
+ const char *name,
+ PyCapsule_Destructor destr)
+{
+ PyObject *ret;
+
+#ifdef Py_CAPSULE_H
+ ret = PyCapsule_New(cobj, name, destr);
+#else
+ ret = PyCObject_FromVoidPtrAndDesc(cobj, (void *) name, destr);
+#endif /* _TEST_CAPSULE */
+
+ return ret;
+}
+
PyObject *
libvirt_intWrap(int val)
{
@@ -105,9 +125,8 @@ libvirt_virDomainPtrWrap(virDomainPtr node)
Py_INCREF(Py_None);
return (Py_None);
}
- ret =
- PyCObject_FromVoidPtrAndDesc((void *) node, (char *) "virDomainPtr",
- NULL);
+
+ ret = libvirt_buildPyObject(node, "virDomainPtr", NULL);
return (ret);
}
@@ -120,9 +139,8 @@ libvirt_virNetworkPtrWrap(virNetworkPtr node)
Py_INCREF(Py_None);
return (Py_None);
}
- ret =
- PyCObject_FromVoidPtrAndDesc((void *) node, (char *) "virNetworkPtr",
- NULL);
+
+ ret = libvirt_buildPyObject(node, "virNetworkPtr", NULL);
return (ret);
}
@@ -135,9 +153,8 @@ libvirt_virInterfacePtrWrap(virInterfacePtr node)
Py_INCREF(Py_None);
return (Py_None);
}
- ret =
- PyCObject_FromVoidPtrAndDesc((void *) node, (char *) "virInterfacePtr",
- NULL);
+
+ ret = libvirt_buildPyObject(node, "virInterfacePtr", NULL);
return (ret);
}
@@ -150,9 +167,8 @@ libvirt_virStoragePoolPtrWrap(virStoragePoolPtr node)
Py_INCREF(Py_None);
return (Py_None);
}
- ret =
- PyCObject_FromVoidPtrAndDesc((void *) node, (char *) "virStoragePoolPtr",
- NULL);
+
+ ret = libvirt_buildPyObject(node, "virStoragePoolPtr", NULL);
return (ret);
}
@@ -165,9 +181,8 @@ libvirt_virStorageVolPtrWrap(virStorageVolPtr node)
Py_INCREF(Py_None);
return (Py_None);
}
- ret =
- PyCObject_FromVoidPtrAndDesc((void *) node, (char *) "virStorageVolPtr",
- NULL);
+
+ ret = libvirt_buildPyObject(node, "virStorageVolPtr", NULL);
return (ret);
}
@@ -180,9 +195,8 @@ libvirt_virConnectPtrWrap(virConnectPtr node)
Py_INCREF(Py_None);
return (Py_None);
}
- ret =
- PyCObject_FromVoidPtrAndDesc((void *) node, (char *) "virConnectPtr",
- NULL);
+
+ ret = libvirt_buildPyObject(node, "virConnectPtr", NULL);
return (ret);
}
@@ -195,9 +209,8 @@ libvirt_virNodeDevicePtrWrap(virNodeDevicePtr node)
Py_INCREF(Py_None);
return (Py_None);
}
- ret =
- PyCObject_FromVoidPtrAndDesc((void *) node, (char *) "virNodeDevicePtr",
- NULL);
+
+ ret = libvirt_buildPyObject(node, "virNodeDevicePtr", NULL);
return (ret);
}
@@ -210,7 +223,8 @@ libvirt_virSecretPtrWrap(virSecretPtr node)
Py_INCREF(Py_None);
return Py_None;
}
- ret = PyCObject_FromVoidPtrAndDesc(node, (char *) "virSecretPtr", NULL);
+
+ ret = libvirt_buildPyObject(node, "virSecretPtr", NULL);
return (ret);
}
@@ -223,7 +237,8 @@ libvirt_virNWFilterPtrWrap(virNWFilterPtr node)
Py_INCREF(Py_None);
return Py_None;
}
- ret = PyCObject_FromVoidPtrAndDesc(node, (char *) "virNWFilterPtr", NULL);
+
+ ret = libvirt_buildPyObject(node, "virNWFilterPtr", NULL);
return (ret);
}
@@ -236,7 +251,8 @@ libvirt_virStreamPtrWrap(virStreamPtr node)
Py_INCREF(Py_None);
return Py_None;
}
- ret = PyCObject_FromVoidPtrAndDesc(node, (char *) "virStreamPtr", NULL);
+
+ ret = libvirt_buildPyObject(node, "virStreamPtr", NULL);
return (ret);
}
@@ -249,9 +265,8 @@ libvirt_virDomainSnapshotPtrWrap(virDomainSnapshotPtr node)
Py_INCREF(Py_None);
return (Py_None);
}
- ret =
- PyCObject_FromVoidPtrAndDesc((void *) node, (char *) "virDomainSnapshotPtr",
- NULL);
+
+ ret = libvirt_buildPyObject(node, "virDomainSnapshotPtr", NULL);
return (ret);
}
@@ -265,9 +280,8 @@ libvirt_virEventHandleCallbackWrap(virEventHandleCallback node)
printf("%s: WARNING - Wrapping None\n", __func__);
return (Py_None);
}
- ret =
- PyCObject_FromVoidPtrAndDesc((void *) node, (char *) "virEventHandleCallback",
- NULL);
+
+ ret = libvirt_buildPyObject(node, "virEventHandleCallback", NULL);
return (ret);
}
@@ -281,9 +295,8 @@ libvirt_virEventTimeoutCallbackWrap(virEventTimeoutCallback node)
Py_INCREF(Py_None);
return (Py_None);
}
- ret =
- PyCObject_FromVoidPtrAndDesc((void *) node, (char *) "virEventTimeoutCallback",
- NULL);
+
+ ret = libvirt_buildPyObject(node, "virEventTimeoutCallback", NULL);
return (ret);
}
@@ -296,9 +309,8 @@ libvirt_virFreeCallbackWrap(virFreeCallback node)
Py_INCREF(Py_None);
return (Py_None);
}
- ret =
- PyCObject_FromVoidPtrAndDesc((void *) node, (char *) "virFreeCallback",
- NULL);
+
+ ret = libvirt_buildPyObject(node, "virFreeCallback", NULL);
return (ret);
}
@@ -311,8 +323,7 @@ libvirt_virVoidPtrWrap(void* node)
Py_INCREF(Py_None);
return (Py_None);
}
- ret =
- PyCObject_FromVoidPtrAndDesc((void *) node, (char *) "void*",
- NULL);
+
+ ret = libvirt_buildPyObject(node, "void*", NULL);
return (ret);
}
--
1.7.3.2
2
3
10 Jan '11
Hi us,
Quick question... the virsh "memtune" command has a parameter called "--soft-limit".
The draft description for it, for the virsh command reference, is:
Minimum memory allocated to the guest domain during contention,
in kilobytes. QEMU and LXC only.
http://justinclift.fedorapeople.org/virshcmdref/sect-memtune.html
But, Nikunj has pointed out the word "allocated" here isn't correct. His initial
suggestion is to use "ascertained" instead, but that doesn't sound at all right to
me:
Minimum memory ascertained to the guest domain during contention,
in kilobytes. QEMU and LXC only.
"Ascertained" doesn't really make sense to me in this context. Wondering
if anyone has better suggestions? :)
Regards and best wishes,
Justin Clift
5
15
10 Jan '11
I noticed that there is quite a bit of code duplication among the
drivers that support domain events. This patch series is an attempt
to consolidate the shared logic.
Patch #1 is the bugfix for https://bugzilla.redhat.com/show_bug.cgi?id=624252
which started me down this path. It can be applied independently of the
refactoring if need be.
Thanks,
Cole
Cole Robinson (8):
remote: Don't lose track of events when callbacks are slow
event-test: Simplify debug on/off
domain_event: Add virDomainEventState structure
domain_event: Add common domain event queue/flush helpers
qemu: Use virDomainEventState helpers
lxc: Use virDomainEventState helpers
test: Use virDomainEventState helpers
remote: Use virDomainEventState helpers
examples/domain-events/events-python/event-test.py | 37 +++--
src/conf/domain_event.c | 163 +++++++++++++++++---
src/conf/domain_event.h | 64 ++++++--
src/libvirt_private.syms | 6 +
src/lxc/lxc_conf.h | 6 +-
src/lxc/lxc_driver.c | 76 +++------
src/qemu/qemu_conf.h | 6 +-
src/qemu/qemu_driver.c | 80 +++-------
src/remote/remote_driver.c | 162 ++++++++------------
src/test/test_driver.c | 104 ++++---------
10 files changed, 363 insertions(+), 341 deletions(-)
--
1.7.3.3
2
18
10 Jan '11
QEMU supports serving VNC over a unix domain socket rather than traditional
TCP host/port. This is specified with:
<graphics type='vnc' socket='/foo/bar/baz'/>
Currently not hooked up with the security driver, I'll wait for Dan's
big reorg. I also have a virtinst/virt-manager patch queued locally to
handle this change.
To be useful, we probably want a qemu.conf option to use sockets as the
default VNC method, so VMs without hardcoded listen addresses will
magically start up serving over a socket in /var/lib/libvirt/qemu. This
provides better security access control than VNC listening on 127.0.0.1, but
will cause issues with tools that rely on the lax security (virt-manager
in fedora runs as regular user by default, and wouldn't be able to access
a socket owned by 'qemu' or 'root').
---
docs/formatdomain.html.in | 6 ++-
docs/schemas/domain.rng | 5 ++
src/conf/domain_conf.c | 30 +++++++----
src/conf/domain_conf.h | 1 +
src/qemu/qemu_command.c | 52 +++++++++++++-------
src/qemu/qemu_driver.c | 1 +
tests/qemuargv2xmltest.c | 1 +
.../qemuxml2argv-graphics-vnc-socket.args | 1 +
.../qemuxml2argv-graphics-vnc-socket.xml | 30 +++++++++++
tests/qemuxml2argvtest.c | 1 +
10 files changed, 98 insertions(+), 30 deletions(-)
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc-socket.args
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc-socket.xml
diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index e9fcea1..fbcff0b 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -1153,7 +1153,11 @@ qemu-kvm -net nic,model=? /dev/null
in clear text. The <code>keymap</code> attribute specifies the keymap
to use. It is possible to set a limit on the validity of the password
be giving an timestamp <code>passwdValidTo='2010-04-09T15:51:00'</code>
- assumed to be in UTC. NB, this may not be supported by all hypervisors.
+ assumed to be in UTC. NB, this may not be supported by all hypervisors.<br>
+ <br>
+ Rather than using listen/port, QEMU supports a <code>socket</code>
+ attribute for listening on a unix domain socket path.
+ <span class="since">Since 0.8.8</span>
</dd>
<dt><code>"spice"</code></dt>
<dd>
diff --git a/docs/schemas/domain.rng b/docs/schemas/domain.rng
index a524e4b..554a39f 100644
--- a/docs/schemas/domain.rng
+++ b/docs/schemas/domain.rng
@@ -1116,6 +1116,11 @@
</attribute>
</optional>
<optional>
+ <attribute name="socket">
+ <ref name="absFilePath"/>
+ </attribute>
+ </optional>
+ <optional>
<attribute name="passwd">
<text/>
</attribute>
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index c857a89..aec23aa 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -471,6 +471,7 @@ void virDomainGraphicsDefFree(virDomainGraphicsDefPtr def)
switch (def->type) {
case VIR_DOMAIN_GRAPHICS_TYPE_VNC:
VIR_FREE(def->data.vnc.listenAddr);
+ VIR_FREE(def->data.vnc.socket);
VIR_FREE(def->data.vnc.keymap);
virDomainGraphicsAuthDefClear(&def->data.vnc.auth);
break;
@@ -3349,6 +3350,7 @@ virDomainGraphicsDefParseXML(xmlNodePtr node, int flags) {
}
def->data.vnc.listenAddr = virXMLPropString(node, "listen");
+ def->data.vnc.socket = virXMLPropString(node, "socket");
def->data.vnc.keymap = virXMLPropString(node, "keymap");
if (virDomainGraphicsAuthDefParseXML(node, &def->data.vnc.auth) < 0)
@@ -6844,19 +6846,25 @@ virDomainGraphicsDefFormat(virBufferPtr buf,
switch (def->type) {
case VIR_DOMAIN_GRAPHICS_TYPE_VNC:
- if (def->data.vnc.port &&
- (!def->data.vnc.autoport || !(flags & VIR_DOMAIN_XML_INACTIVE)))
- virBufferVSprintf(buf, " port='%d'",
- def->data.vnc.port);
- else if (def->data.vnc.autoport)
- virBufferAddLit(buf, " port='-1'");
+ if (def->data.vnc.socket) {
+ if (def->data.vnc.socket)
+ virBufferVSprintf(buf, " socket='%s'",
+ def->data.vnc.socket);
+ } else {
+ if (def->data.vnc.port &&
+ (!def->data.vnc.autoport || !(flags & VIR_DOMAIN_XML_INACTIVE)))
+ virBufferVSprintf(buf, " port='%d'",
+ def->data.vnc.port);
+ else if (def->data.vnc.autoport)
+ virBufferAddLit(buf, " port='-1'");
- virBufferVSprintf(buf, " autoport='%s'",
- def->data.vnc.autoport ? "yes" : "no");
+ virBufferVSprintf(buf, " autoport='%s'",
+ def->data.vnc.autoport ? "yes" : "no");
- if (def->data.vnc.listenAddr)
- virBufferVSprintf(buf, " listen='%s'",
- def->data.vnc.listenAddr);
+ if (def->data.vnc.listenAddr)
+ virBufferVSprintf(buf, " listen='%s'",
+ def->data.vnc.listenAddr);
+ }
if (def->data.vnc.keymap)
virBufferEscapeString(buf, " keymap='%s'",
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index a459a22..684fc7d 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -574,6 +574,7 @@ struct _virDomainGraphicsDef {
unsigned int autoport :1;
char *listenAddr;
char *keymap;
+ char *socket;
virDomainGraphicsAuthDef auth;
} vnc;
struct {
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 7dd8e03..c0fd00b 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -3511,7 +3511,11 @@ qemuBuildCommandLine(virConnectPtr conn,
def->graphics[0]->type == VIR_DOMAIN_GRAPHICS_TYPE_VNC) {
virBuffer opt = VIR_BUFFER_INITIALIZER;
- if (qemuCmdFlags & QEMUD_CMD_FLAG_VNC_COLON) {
+ if (def->graphics[0]->data.vnc.socket) {
+ virBufferVSprintf(&opt, "unix:%s",
+ def->graphics[0]->data.vnc.socket);
+
+ } else if (qemuCmdFlags & QEMUD_CMD_FLAG_VNC_COLON) {
if (def->graphics[0]->data.vnc.listenAddr)
virBufferAdd(&opt, def->graphics[0]->data.vnc.listenAddr, -1);
else if (driver->vncListen)
@@ -3520,6 +3524,12 @@ qemuBuildCommandLine(virConnectPtr conn,
virBufferVSprintf(&opt, ":%d",
def->graphics[0]->data.vnc.port - 5900);
+ } else {
+ virBufferVSprintf(&opt, "%d",
+ def->graphics[0]->data.vnc.port - 5900);
+ }
+
+ if (qemuCmdFlags & QEMUD_CMD_FLAG_VNC_COLON) {
if (def->graphics[0]->data.vnc.auth.passwd ||
driver->vncPassword)
virBufferAddLit(&opt, ",password");
@@ -3544,9 +3554,6 @@ qemuBuildCommandLine(virConnectPtr conn,
/* TODO: Support ACLs later */
}
- } else {
- virBufferVSprintf(&opt, "%d",
- def->graphics[0]->data.vnc.port - 5900);
}
virCommandAddArg(cmd, "-vnc");
@@ -5174,24 +5181,33 @@ virDomainDefPtr qemuParseCommandLine(virCapsPtr caps,
goto no_memory;
vnc->type = VIR_DOMAIN_GRAPHICS_TYPE_VNC;
- tmp = strchr(val, ':');
- if (tmp) {
- char *opts;
- if (virStrToLong_i(tmp+1, &opts, 10, &vnc->data.vnc.port) < 0) {
- VIR_FREE(vnc);
- qemuReportError(VIR_ERR_INTERNAL_ERROR, \
- _("cannot parse VNC port '%s'"), tmp+1);
- goto error;
- }
- vnc->data.vnc.listenAddr = strndup(val, tmp-val);
- if (!vnc->data.vnc.listenAddr) {
+ if (STRPREFIX(val, "unix:")) {
+ vnc->data.vnc.socket = strdup(val + 5);
+ if (!vnc->data.vnc.socket) {
VIR_FREE(vnc);
goto no_memory;
}
- vnc->data.vnc.port += 5900;
- vnc->data.vnc.autoport = 0;
} else {
- vnc->data.vnc.autoport = 1;
+ tmp = strchr(val, ':');
+ if (tmp) {
+ char *opts;
+ if (virStrToLong_i(tmp+1, &opts, 10,
+ &vnc->data.vnc.port) < 0) {
+ VIR_FREE(vnc);
+ qemuReportError(VIR_ERR_INTERNAL_ERROR,
+ _("cannot parse VNC port '%s'"), tmp+1);
+ goto error;
+ }
+ vnc->data.vnc.listenAddr = strndup(val, tmp-val);
+ if (!vnc->data.vnc.listenAddr) {
+ VIR_FREE(vnc);
+ goto no_memory;
+ }
+ vnc->data.vnc.port += 5900;
+ vnc->data.vnc.autoport = 0;
+ } else {
+ vnc->data.vnc.autoport = 1;
+ }
}
if (VIR_REALLOC_N(def->graphics, def->ngraphics+1) < 0) {
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index e915705..0f2e3b2 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -2684,6 +2684,7 @@ static int qemudStartVMDaemon(virConnectPtr conn,
if (vm->def->ngraphics == 1) {
if (vm->def->graphics[0]->type == VIR_DOMAIN_GRAPHICS_TYPE_VNC &&
+ !vm->def->graphics[0]->data.vnc.socket &&
vm->def->graphics[0]->data.vnc.autoport) {
int port = qemudNextFreePort(driver, QEMU_VNC_PORT_MIN);
if (port < 0) {
diff --git a/tests/qemuargv2xmltest.c b/tests/qemuargv2xmltest.c
index 8338af3..7499ba0 100644
--- a/tests/qemuargv2xmltest.c
+++ b/tests/qemuargv2xmltest.c
@@ -178,6 +178,7 @@ mymain(int argc, char **argv)
DO_TEST("disk-drive-network-sheepdog");
DO_TEST("disk-usb");
DO_TEST("graphics-vnc");
+ DO_TEST("graphics-vnc-socket");
driver.vncSASL = 1;
driver.vncSASLdir = strdup("/root/.sasl2");
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc-socket.args b/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc-socket.args
new file mode 100644
index 0000000..055c562
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc-socket.args
@@ -0,0 +1 @@
+LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test QEMU_AUDIO_DRV=none /usr/bin/qemu -S -M pc -m 214 -smp 1 -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -net none -serial none -parallel none -usb -vnc unix:/tmp/foo.socket
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc-socket.xml b/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc-socket.xml
new file mode 100644
index 0000000..d6ad72b
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc-socket.xml
@@ -0,0 +1,30 @@
+<domain type='qemu'>
+ <name>QEMUGuest1</name>
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+ <memory>219200</memory>
+ <currentMemory>219200</currentMemory>
+ <vcpu>1</vcpu>
+ <os>
+ <type arch='i686' machine='pc'>hvm</type>
+ <boot dev='hd'/>
+ </os>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ <emulator>/usr/bin/qemu</emulator>
+ <disk type='block' device='disk'>
+ <source dev='/dev/HostVG/QEMUGuest1'/>
+ <target dev='hda' bus='ide'/>
+ <address type='drive' controller='0' bus='0' unit='0'/>
+ </disk>
+ <controller type='ide' index='0'/>
+ <input type='mouse' bus='ps2'/>
+ <graphics type='vnc' socket='/tmp/foo.socket'/>
+ <video>
+ <model type='cirrus' vram='9216' heads='1'/>
+ </video>
+ <memballoon model='virtio'/>
+ </devices>
+</domain>
diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
index 6760f67..8a1d5f7 100644
--- a/tests/qemuxml2argvtest.c
+++ b/tests/qemuxml2argvtest.c
@@ -316,6 +316,7 @@ mymain(int argc, char **argv)
DO_TEST("disk-scsi-device-auto", QEMUD_CMD_FLAG_DRIVE |
QEMUD_CMD_FLAG_DEVICE | QEMUD_CMD_FLAG_NODEFCONFIG, false);
DO_TEST("graphics-vnc", 0, false);
+ DO_TEST("graphics-vnc-socket", 0, false);
driver.vncSASL = 1;
driver.vncSASLdir = strdup("/root/.sasl2");
--
1.7.3.3
3
3
[libvirt] [PATCH] conf: Report error if invalid type specified for character device
by Osier Yang 10 Jan '11
by Osier Yang 10 Jan '11
10 Jan '11
If invalid type is specified, e.g.
<serial type='foo'>
<target port='0'/>
</serial>
We replace 'foo' with "null" type implicitly, without reporting an
error message to tell the user, and "start" or "edit" the domain
will be success.
It's not good to guess what the user wants, This patch is to fix
the problem.
* src/conf/domain_conf.c
---
src/conf/domain_conf.c | 10 +++++++---
1 files changed, 7 insertions(+), 3 deletions(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index c857a89..b4df38c 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -2821,10 +2821,14 @@ virDomainChrDefParseXML(virCapsPtr caps,
}
type = virXMLPropString(node, "type");
- if (type == NULL)
+ if (type == NULL) {
def->type = VIR_DOMAIN_CHR_TYPE_PTY;
- else if ((def->type = virDomainChrTypeFromString(type)) < 0)
- def->type = VIR_DOMAIN_CHR_TYPE_NULL;
+ } else if ((def->type = virDomainChrTypeFromString(type)) < 0) {
+ virDomainReportError(VIR_ERR_XML_ERROR,
+ _("unknown type presented to host for character device: %s"),
+ type);
+ goto error;
+ }
nodeName = (const char *) node->name;
if ((def->deviceType = virDomainChrDeviceTypeFromString(nodeName)) < 0) {
--
1.7.3.2
2
1
Hi Matthias,
Just came across an interesting (non fatal) bug with the new VirtualBox code on
windows.
When starting virsh on a windows system that *doesn't* have VirtualBox installed,
virsh prints an error to the users terminal about missing VirtualBox registry keys,
then continues on with it's intended operation. (screenshot attached)
It's not a killer, but the error makes no sense in context when I'm (for example)
trying to connect to a remote qemu box. Heh.
Feel inclined to write a patch for it?
Regards and best wishes,
Justin Clift
2
2
I have seen several messages asking for VDE networking support.
There is an item also in your todo web page.
http://libvirt.org/todo.html
I have developed a patch to provide a basic support for VDE.
It defines and manages the syntax:
<domain ....>
<device>
<interface type='vde'>
...
<switch path='/tmp/vde.ctl'/>
</interface>
</device>
</domain>
the switch tag can be omitted: vde uses the default switch.
I have tested the qemu/kvm support.
user-mode linux support is included but not tested yet.
libvirt vde support for virtualbox has not been coded yet (virtualbox
itself supports vde).
The patch is against libvirt-0.8.7.
renzo
(designer/developer of VDE, university of bologna, wiki.virtualsquare.org)
(I have not subscribed the ML, please Cc: to me your reply messages)
Signed-off-by: Renzo Davoli <renzo(a)cs.unibo.it>
---
--- a/src/lxc/lxc_driver.c 2011-01-10 11:49:49.000000000 +0100
+++ b/src/lxc/lxc_driver.c 2011-01-10 11:50:03.000000000 +0100
@@ -1083,6 +1083,7 @@
case VIR_DOMAIN_NET_TYPE_INTERNAL:
case VIR_DOMAIN_NET_TYPE_DIRECT:
case VIR_DOMAIN_NET_TYPE_LAST:
+ case VIR_DOMAIN_NET_TYPE_VDE:
break;
}
--- a/src/uml/uml_conf.c 2011-01-10 12:03:54.000000000 +0100
+++ b/src/uml/uml_conf.c 2011-01-10 13:26:08.000000000 +0100
@@ -269,6 +269,14 @@
virBufferVSprintf(&buf, "tuntap,%s", def->ifname);
break;
+ case VIR_DOMAIN_NET_TYPE_VDE:
+ /* ethNNN=vde,vde_switch,macaddr,port,group,mode,description */
+ if (def->data.vde.vdeswitch) {
+ virBufferVSprintf(&buf, "vde,%s", def->data.vde.vdeswitch);
+ } else
+ virBufferAddLit(&buf, "vde");
+ break;
+
case VIR_DOMAIN_NET_TYPE_INTERNAL:
umlReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("internal networking type not supported"));
--- a/src/conf/domain_conf.h 2011-01-10 11:41:07.000000000 +0100
+++ b/src/conf/domain_conf.h 2011-01-10 13:21:08.000000000 +0100
@@ -288,6 +288,7 @@
VIR_DOMAIN_NET_TYPE_BRIDGE,
VIR_DOMAIN_NET_TYPE_INTERNAL,
VIR_DOMAIN_NET_TYPE_DIRECT,
+ VIR_DOMAIN_NET_TYPE_VDE,
VIR_DOMAIN_NET_TYPE_LAST,
};
@@ -336,6 +337,9 @@
int mode;
virVirtualPortProfileParams virtPortProfile;
} direct;
+ struct {
+ char *vdeswitch;
+ } vde;
} data;
char *ifname;
virDomainDeviceInfo info;
--- a/src/conf/domain_conf.c 2011-01-10 11:42:04.000000000 +0100
+++ b/src/conf/domain_conf.c 2011-01-10 14:49:46.000000000 +0100
@@ -182,7 +182,8 @@
"network",
"bridge",
"internal",
- "direct")
+ "direct",
+ "vde")
VIR_ENUM_IMPL(virDomainChrChannelTarget,
VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_LAST,
@@ -598,6 +599,10 @@
VIR_FREE(def->data.direct.linkdev);
break;
+ case VIR_DOMAIN_NET_TYPE_VDE:
+ VIR_FREE(def->data.vde.vdeswitch);
+ break;
+
case VIR_DOMAIN_NET_TYPE_USER:
case VIR_DOMAIN_NET_TYPE_LAST:
break;
@@ -2293,6 +2298,7 @@
char *internal = NULL;
char *devaddr = NULL;
char *mode = NULL;
+ char *vdeswitch = NULL;
virNWFilterHashTablePtr filterparams = NULL;
virVirtualPortProfileParams virtPort;
bool virtPortParsed = false;
@@ -2379,7 +2385,11 @@
xmlStrEqual(cur->name, BAD_CAST "state")) {
/* Legacy back-compat. Don't add any more attributes here */
devaddr = virXMLPropString(cur, "devaddr");
- }
+ } else if ((vdeswitch == NULL) &&
+ def->type == VIR_DOMAIN_NET_TYPE_VDE &&
+ xmlStrEqual(cur->name, BAD_CAST "switch")) {
+ vdeswitch = virXMLPropString(cur, "path");
+ }
}
cur = cur->next;
}
@@ -2529,6 +2539,11 @@
break;
+ case VIR_DOMAIN_NET_TYPE_VDE:
+ def->data.vde.vdeswitch = vdeswitch;
+ vdeswitch = NULL;
+ break;
+
case VIR_DOMAIN_NET_TYPE_USER:
case VIR_DOMAIN_NET_TYPE_LAST:
break;
@@ -6263,6 +6278,12 @@
" ");
break;
+ case VIR_DOMAIN_NET_TYPE_VDE:
+ if (def->data.vde.vdeswitch)
+ virBufferEscapeString(buf, " <switch path='%s'/>\n",
+ def->data.vde.vdeswitch);
+ break;
+
case VIR_DOMAIN_NET_TYPE_USER:
case VIR_DOMAIN_NET_TYPE_LAST:
break;
--- a/src/qemu/qemu_command.c 2011-01-10 13:11:17.000000000 +0100
+++ b/src/qemu/qemu_command.c 2011-01-10 13:26:28.000000000 +0100
@@ -1602,12 +1602,21 @@
case VIR_DOMAIN_NET_TYPE_BRIDGE:
case VIR_DOMAIN_NET_TYPE_INTERNAL:
case VIR_DOMAIN_NET_TYPE_DIRECT:
+ case VIR_DOMAIN_NET_TYPE_VDE:
case VIR_DOMAIN_NET_TYPE_LAST:
break;
}
type_sep = ',';
break;
+ case VIR_DOMAIN_NET_TYPE_VDE:
+ virBufferAddLit(&buf, "vde");
+ if (net->data.vde.vdeswitch)
+ virBufferVSprintf(&buf, "%csock=%s",
+ type_sep,
+ net->data.vde.vdeswitch);
+ break;
+
case VIR_DOMAIN_NET_TYPE_USER:
default:
virBufferAddLit(&buf, "user");
1
0
10 Jan '11
Setting unix_sock_group to something else than default "root" in
/etc/libvirt/libvirtd.conf prevents system libvirtd from dumping core on
crash. This is because we used setgid(unix_sock_group) before binding to
/var/run/libvirt/libvirt-sock* and setgid() back to original group.
However, if a process changes its effective or filesystem group ID, it
will be forbidden from leaving core dumps unless fs.suid_dumpable sysctl
is set to something else then 0 (and it is 0 by default).
Changing socket's group ownership after bind works better. And we can do
so without introducing a race condition since we loosen access rights by
changing the group from root to something else.
---
daemon/libvirtd.c | 17 ++++++++---------
1 files changed, 8 insertions(+), 9 deletions(-)
diff --git a/daemon/libvirtd.c b/daemon/libvirtd.c
index 2df9337..b1539b1 100644
--- a/daemon/libvirtd.c
+++ b/daemon/libvirtd.c
@@ -542,7 +542,6 @@ static int qemudListenUnix(struct qemud_server *server,
char *path, int readonly, int auth) {
struct qemud_socket *sock;
mode_t oldmask;
- gid_t oldgrp;
char ebuf[1024];
if (VIR_ALLOC(sock) < 0) {
@@ -579,21 +578,21 @@ static int qemudListenUnix(struct qemud_server *server,
if (sock->addr.data.un.sun_path[0] == '@')
sock->addr.data.un.sun_path[0] = '\0';
- oldgrp = getgid();
oldmask = umask(readonly ? ~unix_sock_ro_mask : ~unix_sock_rw_mask);
- if (server->privileged && setgid(unix_sock_gid)) {
- VIR_ERROR(_("Failed to set group ID to %d"), unix_sock_gid);
- goto cleanup;
- }
-
if (bind(sock->fd, &sock->addr.data.sa, sock->addr.len) < 0) {
VIR_ERROR(_("Failed to bind socket to '%s': %s"),
path, virStrerror(errno, ebuf, sizeof ebuf));
goto cleanup;
}
umask(oldmask);
- if (server->privileged && setgid(oldgrp)) {
- VIR_ERROR(_("Failed to restore group ID to %d"), oldgrp);
+
+ /* chown() doesn't work for abstract sockets but we use them only
+ * if libvirtd runs unprivileged
+ */
+ if (server->privileged && chown(path, -1, unix_sock_gid)) {
+ VIR_ERROR(_("Failed to change group ID of '%s' to %d: %s"),
+ path, unix_sock_gid,
+ virStrerror(errno, ebuf, sizeof ebuf));
goto cleanup;
}
--
1.7.4.rc1
3
4
[libvirt] [PATCH v3] Refactor the security drivers to simplify usage
by Daniel P. Berrange 10 Jan '11
by Daniel P. Berrange 10 Jan '11
10 Jan '11
The current security driver usage requires horrible code like
if (driver->securityDriver &&
driver->securityDriver->domainSetSecurityHostdevLabel &&
driver->securityDriver->domainSetSecurityHostdevLabel(driver->securityDriver,
vm, hostdev) < 0)
This pair of checks for NULL clutters up the code, making the driver
calls 2 lines longer than they really need to be. The goal of the
patchset is to change the calling convention to simply
if (virSecurityManagerSetHostdevLabel(driver->securityDriver,
vm, hostdev) < 0)
The first check for 'driver->securityDriver' being NULL is removed
by introducing a 'no op' security driver that will always be present
if no real driver is enabled. This guarentees driver->securityDriver
!= NULL.
The second check for 'driver->securityDriver->domainSetSecurityHostdevLabel'
being non-NULL is hidden in a new abstraction called virSecurityManager.
This separates the driver callbacks, from main internal API. The addition
of a virSecurityManager object, that is separate from the virSecurityDriver
struct also allows for security drivers to carry state / configuration
information directly. Thus the DAC/Stack drivers from src/qemu which
used to pull config from 'struct qemud_driver' can now be moved into
the 'src/security' directory and store their config directly.
* src/qemu/qemu_conf.h, src/qemu/qemu_driver.c: Update to
use new virSecurityManager APIs
* src/qemu/qemu_security_dac.c, src/qemu/qemu_security_dac.h
src/qemu/qemu_security_stacked.c, src/qemu/qemu_security_stacked.h:
Move into src/security directory
* src/security/security_stack.c, src/security/security_stack.h,
src/security/security_dac.c, src/security/security_dac.h: Generic
versions of previous QEMU specific drivers
* src/security/security_apparmor.c, src/security/security_apparmor.h,
src/security/security_driver.c, src/security/security_driver.h,
src/security/security_selinux.c, src/security/security_selinux.h:
Update to take virSecurityManagerPtr object as the first param
in all callbacks
* src/security/security_nop.c, src/security/security_nop.h: Stub
implementation of all security driver APIs.
* src/security/security_manager.h, src/security/security_manager.c:
New internal API for invoking security drivers
* src/libvirt.c: Add missing debug for security APIs
---
po/POTFILES.in | 2 +-
src/Makefile.am | 12 +-
src/libvirt.c | 4 +
src/libvirt_private.syms | 34 ++-
src/qemu/qemu_conf.h | 6 +-
src/qemu/qemu_driver.c | 167 ++++------
src/qemu/qemu_hotplug.c | 84 ++---
src/qemu/qemu_security_dac.c | 576 ------------------------------
src/qemu/qemu_security_dac.h | 22 --
src/qemu/qemu_security_stacked.c | 418 ----------------------
src/qemu/qemu_security_stacked.h | 22 --
src/security/security_apparmor.c | 152 ++++++---
src/security/security_apparmor.h | 2 +
src/security/security_dac.c | 713 ++++++++++++++++++++++++++++++++++++++
src/security/security_dac.h | 36 ++
src/security/security_driver.c | 125 ++-----
src/security/security_driver.h | 95 +++---
src/security/security_manager.c | 317 +++++++++++++++++
src/security/security_manager.h | 95 +++++
src/security/security_nop.c | 185 ++++++++++
src/security/security_nop.h | 27 ++
src/security/security_selinux.c | 145 +++++---
src/security/security_selinux.h | 2 +-
src/security/security_stack.c | 401 +++++++++++++++++++++
src/security/security_stack.h | 33 ++
25 files changed, 2207 insertions(+), 1468 deletions(-)
delete mode 100644 src/qemu/qemu_security_dac.c
delete mode 100644 src/qemu/qemu_security_dac.h
delete mode 100644 src/qemu/qemu_security_stacked.c
delete mode 100644 src/qemu/qemu_security_stacked.h
create mode 100644 src/security/security_dac.c
create mode 100644 src/security/security_dac.h
create mode 100644 src/security/security_manager.c
create mode 100644 src/security/security_manager.h
create mode 100644 src/security/security_nop.c
create mode 100644 src/security/security_nop.h
create mode 100644 src/security/security_stack.c
create mode 100644 src/security/security_stack.h
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 3d7bc8b..3521ba6 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -61,10 +61,10 @@ src/qemu/qemu_hotplug.c
src/qemu/qemu_monitor.c
src/qemu/qemu_monitor_json.c
src/qemu/qemu_monitor_text.c
-src/qemu/qemu_security_dac.c
src/remote/remote_driver.c
src/secret/secret_driver.c
src/security/security_apparmor.c
+src/security/security_dac.c
src/security/security_driver.c
src/security/security_selinux.c
src/security/virt-aa-helper.c
diff --git a/src/Makefile.am b/src/Makefile.am
index c13724a..f8b8434 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -288,11 +288,7 @@ QEMU_DRIVER_SOURCES = \
qemu/qemu_monitor_json.h \
qemu/qemu_driver.c qemu/qemu_driver.h \
qemu/qemu_bridge_filter.c \
- qemu/qemu_bridge_filter.h \
- qemu/qemu_security_stacked.h \
- qemu/qemu_security_stacked.c \
- qemu/qemu_security_dac.h \
- qemu/qemu_security_dac.c
+ qemu/qemu_bridge_filter.h
XENAPI_DRIVER_SOURCES = \
xenapi/xenapi_driver.c xenapi/xenapi_driver.h \
@@ -390,7 +386,11 @@ NWFILTER_DRIVER_SOURCES = \
# Security framework and drivers for various models
SECURITY_DRIVER_SOURCES = \
- security/security_driver.h security/security_driver.c
+ security/security_driver.h security/security_driver.c \
+ security/security_nop.h security/security_nop.c \
+ security/security_stack.h security/security_stack.c \
+ security/security_dac.h security/security_dac.c \
+ security/security_manager.h security/security_manager.c
SECURITY_DRIVER_SELINUX_SOURCES = \
security/security_selinux.h security/security_selinux.c
diff --git a/src/libvirt.c b/src/libvirt.c
index 89b37c5..a4789bc 100644
--- a/src/libvirt.c
+++ b/src/libvirt.c
@@ -5642,6 +5642,8 @@ virDomainGetSecurityLabel(virDomainPtr domain, virSecurityLabelPtr seclabel)
{
virConnectPtr conn;
+ VIR_DOMAIN_DEBUG(domain, "seclabel=%p", seclabel);
+
if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
virLibDomainError(NULL, VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
virDispatchError(NULL);
@@ -5684,6 +5686,8 @@ error:
int
virNodeGetSecurityModel(virConnectPtr conn, virSecurityModelPtr secmodel)
{
+ DEBUG("conn=%p secmodel=%p", conn, secmodel);
+
if (!VIR_IS_CONNECT(conn)) {
virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
virDispatchError(NULL);
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 19e581c..e9b8cb7 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -701,13 +701,33 @@ virSecretDefParseFile;
virSecretDefParseString;
-# security.h
-virSecurityDriverGetDOI;
-virSecurityDriverGetModel;
-virSecurityDriverInit;
-virSecurityDriverSetDOI;
-virSecurityDriverStartup;
-virSecurityDriverVerify;
+# security_driver.h
+virSecurityDriverLookup;
+
+
+# security_manager.h
+virSecurityManagerClearSocketLabel;
+virSecurityManagerFree;
+virSecurityManagerGenLabel;
+virSecurityManagerGetDOI;
+virSecurityManagerGetModel;
+virSecurityManagerGetProcessLabel;
+virSecurityManagerNew;
+virSecurityManagerNewStack;
+virSecurityManagerNewDAC;
+virSecurityManagerReleaseLabel;
+virSecurityManagerReserveLabel;
+virSecurityManagerRestoreImageLabel;
+virSecurityManagerRestoreAllLabel;
+virSecurityManagerRestoreHostdevLabel;
+virSecurityManagerRestoreSavedStateLabel;
+virSecurityManagerSetAllLabel;
+virSecurityManagerSetImageLabel;
+virSecurityManagerSetHostdevLabel;
+virSecurityManagerSetProcessLabel;
+virSecurityManagerSetSavedStateLabel;
+virSecurityManagerSetSocketLabel;
+virSecurityManagerVerify;
# storage_conf.h
diff --git a/src/qemu/qemu_conf.h b/src/qemu/qemu_conf.h
index 83ddedd..5a5748b 100644
--- a/src/qemu/qemu_conf.h
+++ b/src/qemu/qemu_conf.h
@@ -35,7 +35,7 @@
# include "domain_conf.h"
# include "domain_event.h"
# include "threads.h"
-# include "security/security_driver.h"
+# include "security/security_manager.h"
# include "cgroup.h"
# include "pci.h"
# include "cpu_conf.h"
@@ -114,9 +114,7 @@ struct qemud_driver {
int domainEventDispatching;
char *securityDriverName;
- virSecurityDriverPtr securityDriver;
- virSecurityDriverPtr securityPrimaryDriver;
- virSecurityDriverPtr securitySecondaryDriver;
+ virSecurityManagerPtr securityManager;
char *saveImageFormat;
char *dumpImageFormat;
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index e915705..24e9162 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -73,8 +73,6 @@
#include "pci.h"
#include "hostusb.h"
#include "processinfo.h"
-#include "qemu_security_stacked.h"
-#include "qemu_security_dac.h"
#include "libvirt_internal.h"
#include "xml.h"
#include "cpu/cpu.h"
@@ -861,10 +859,7 @@ qemuConnectMonitor(struct qemud_driver *driver, virDomainObjPtr vm)
qemuDomainObjPrivatePtr priv = vm->privateData;
int ret = -1;
- if (driver->securityDriver &&
- driver->securityDriver->domainSetSecuritySocketLabel &&
- driver->securityDriver->domainSetSecuritySocketLabel
- (driver->securityDriver,vm) < 0) {
+ if (virSecurityManagerSetSocketLabel(driver->securityManager, vm) < 0) {
VIR_ERROR(_("Failed to set security context for monitor for %s"),
vm->def->name);
goto error;
@@ -882,10 +877,7 @@ qemuConnectMonitor(struct qemud_driver *driver, virDomainObjPtr vm)
if (priv->mon == NULL)
virDomainObjUnref(vm);
- if (driver->securityDriver &&
- driver->securityDriver->domainClearSecuritySocketLabel &&
- driver->securityDriver->domainClearSecuritySocketLabel
- (driver->securityDriver,vm) < 0) {
+ if (virSecurityManagerClearSocketLabel(driver->securityManager, vm) < 0) {
VIR_ERROR(_("Failed to clear security context for monitor for %s"),
vm->def->name);
goto error;
@@ -954,10 +946,7 @@ qemuReconnectDomain(void *payload, const char *name ATTRIBUTE_UNUSED, void *opaq
goto error;
}
- if (driver->securityDriver &&
- driver->securityDriver->domainReserveSecurityLabel &&
- driver->securityDriver->domainReserveSecurityLabel(driver->securityDriver,
- obj) < 0)
+ if (virSecurityManagerReserveLabel(driver->securityManager, obj) < 0)
goto error;
if (qemudVMFiltersInstantiate(conn, obj->def))
@@ -995,35 +984,34 @@ qemuReconnectDomains(virConnectPtr conn, struct qemud_driver *driver)
static int
-qemudSecurityInit(struct qemud_driver *qemud_drv)
+qemuSecurityInit(struct qemud_driver *driver)
{
- int ret;
- virSecurityDriverPtr security_drv;
-
- qemuSecurityStackedSetDriver(qemud_drv);
- qemuSecurityDACSetDriver(qemud_drv);
+ virSecurityManagerPtr mgr = virSecurityManagerNew(driver->securityDriverName,
+ driver->allowDiskFormatProbing);
+ if (!mgr)
+ goto error;
- ret = virSecurityDriverStartup(&security_drv,
- qemud_drv->securityDriverName,
- qemud_drv->allowDiskFormatProbing);
- if (ret == -1) {
- VIR_ERROR0(_("Failed to start security driver"));
- return -1;
- }
+ if (driver->privileged) {
+ virSecurityManagerPtr dac = virSecurityManagerNewDAC(driver->user,
+ driver->group,
+ driver->allowDiskFormatProbing,
+ driver->dynamicOwnership);
+ if (!dac)
+ goto error;
- /* No primary security driver wanted to be enabled: just setup
- * the DAC driver on its own */
- if (ret == -2) {
- qemud_drv->securityDriver = &qemuDACSecurityDriver;
- VIR_INFO0(_("No security driver available"));
+ if (!(driver->securityManager = virSecurityManagerNewStack(mgr,
+ dac)))
+ goto error;
} else {
- qemud_drv->securityPrimaryDriver = security_drv;
- qemud_drv->securitySecondaryDriver = &qemuDACSecurityDriver;
- qemud_drv->securityDriver = &qemuStackedSecurityDriver;
- VIR_INFO("Initialized security driver %s", security_drv->name);
+ driver->securityManager = mgr;
}
return 0;
+
+error:
+ VIR_ERROR0("Failed to initialize security drivers");
+ virSecurityManagerFree(mgr);
+ return -1;
}
@@ -1057,21 +1045,20 @@ qemuCreateCapabilities(virCapsPtr oldcaps,
}
/* Security driver data */
- if (driver->securityPrimaryDriver) {
- const char *doi, *model;
-
- doi = virSecurityDriverGetDOI(driver->securityPrimaryDriver);
- model = virSecurityDriverGetModel(driver->securityPrimaryDriver);
+ const char *doi, *model;
+ doi = virSecurityManagerGetDOI(driver->securityManager);
+ model = virSecurityManagerGetModel(driver->securityManager);
+ if (STRNEQ(model, "none")) {
if (!(caps->host.secModel.model = strdup(model)))
goto no_memory;
if (!(caps->host.secModel.doi = strdup(doi)))
goto no_memory;
-
- VIR_DEBUG("Initialized caps for security driver \"%s\" with "
- "DOI \"%s\"", model, doi);
}
+ VIR_DEBUG("Initialized caps for security driver \"%s\" with "
+ "DOI \"%s\"", model, doi);
+
return caps;
no_memory:
@@ -1336,7 +1323,7 @@ qemudStartup(int privileged) {
}
VIR_FREE(driverConf);
- if (qemudSecurityInit(qemu_driver) < 0)
+ if (qemuSecurityInit(qemu_driver) < 0)
goto error;
if ((qemu_driver->caps = qemuCreateCapabilities(NULL,
@@ -1555,10 +1542,11 @@ qemudShutdown(void) {
VIR_FREE(qemu_driver->spicePassword);
VIR_FREE(qemu_driver->hugetlbfs_mount);
VIR_FREE(qemu_driver->hugepage_path);
- VIR_FREE(qemu_driver->securityDriverName);
VIR_FREE(qemu_driver->saveImageFormat);
VIR_FREE(qemu_driver->dumpImageFormat);
+ virSecurityManagerFree(qemu_driver->securityManager);
+
ebtablesContextFree(qemu_driver->ebtables);
if (qemu_driver->cgroupDeviceACL) {
@@ -2573,9 +2561,7 @@ static int qemudSecurityHook(void *data) {
if (qemudInitCpuAffinity(h->vm) < 0)
return -1;
- if (h->driver->securityDriver &&
- h->driver->securityDriver->domainSetSecurityProcessLabel &&
- h->driver->securityDriver->domainSetSecurityProcessLabel(h->driver->securityDriver, h->vm) < 0)
+ if (virSecurityManagerSetProcessLabel(h->driver->securityManager, h->vm) < 0)
return -1;
return 0;
@@ -2660,22 +2646,16 @@ static int qemudStartVMDaemon(virConnectPtr conn,
/* If you are using a SecurityDriver with dynamic labelling,
then generate a security label for isolation */
DEBUG0("Generating domain security label (if required)");
- if (driver->securityDriver &&
- driver->securityDriver->domainGenSecurityLabel) {
- ret = driver->securityDriver->domainGenSecurityLabel(driver->securityDriver,
- vm);
- qemuDomainSecurityLabelAudit(vm, ret >= 0);
- if (ret < 0)
- goto cleanup;
+ if (virSecurityManagerGenLabel(driver->securityManager, vm) < 0) {
+ qemuDomainSecurityLabelAudit(vm, false);
+ goto cleanup;
}
+ qemuDomainSecurityLabelAudit(vm, true);
DEBUG0("Generating setting domain security labels (if required)");
- if (driver->securityDriver &&
- driver->securityDriver->domainSetSecurityAllLabel &&
- driver->securityDriver->domainSetSecurityAllLabel(driver->securityDriver,
- vm, stdin_path) < 0) {
+ if (virSecurityManagerSetAllLabel(driver->securityManager,
+ vm, stdin_path) < 0)
goto cleanup;
- }
/* Ensure no historical cgroup for this VM is lying around bogus
* settings */
@@ -3057,14 +3037,9 @@ static void qemudShutdownVMDaemon(struct qemud_driver *driver,
}
/* Reset Security Labels */
- if (driver->securityDriver &&
- driver->securityDriver->domainRestoreSecurityAllLabel)
- driver->securityDriver->domainRestoreSecurityAllLabel(driver->securityDriver,
- vm, migrated);
- if (driver->securityDriver &&
- driver->securityDriver->domainReleaseSecurityLabel)
- driver->securityDriver->domainReleaseSecurityLabel(driver->securityDriver,
- vm);
+ virSecurityManagerRestoreAllLabel(driver->securityManager,
+ vm, migrated);
+ virSecurityManagerReleaseLabel(driver->securityManager, vm);
/* Clear out dynamically assigned labels */
if (vm->def->seclabel.type == VIR_DOMAIN_SECLABEL_DYNAMIC) {
@@ -3568,7 +3543,7 @@ static virDomainPtr qemudDomainCreate(virConnectPtr conn, const char *xml,
VIR_DOMAIN_XML_INACTIVE)))
goto cleanup;
- if (virSecurityDriverVerify(def) < 0)
+ if (virSecurityManagerVerify(driver->securityManager, def) < 0)
goto cleanup;
if (virDomainObjIsDuplicate(&driver->domains, def, 1) < 0)
@@ -4471,10 +4446,8 @@ static int qemudDomainSaveFlag(struct qemud_driver *driver, virDomainPtr dom,
}
if ((!bypassSecurityDriver) &&
- driver->securityDriver &&
- driver->securityDriver->domainSetSavedStateLabel &&
- driver->securityDriver->domainSetSavedStateLabel(driver->securityDriver,
- vm, path) == -1)
+ virSecurityManagerSetSavedStateLabel(driver->securityManager,
+ vm, path) < 0)
goto endjob;
if (header.compressed == QEMUD_SAVE_FORMAT_RAW) {
@@ -4507,10 +4480,8 @@ static int qemudDomainSaveFlag(struct qemud_driver *driver, virDomainPtr dom,
goto endjob;
if ((!bypassSecurityDriver) &&
- driver->securityDriver &&
- driver->securityDriver->domainRestoreSavedStateLabel &&
- driver->securityDriver->domainRestoreSavedStateLabel(driver->securityDriver,
- vm, path) == -1)
+ virSecurityManagerRestoreSavedStateLabel(driver->securityManager,
+ vm, path) < 0)
VIR_WARN("failed to restore save state label on %s", path);
if (cgroup != NULL) {
@@ -4552,10 +4523,8 @@ endjob:
}
if ((!bypassSecurityDriver) &&
- driver->securityDriver &&
- driver->securityDriver->domainRestoreSavedStateLabel &&
- driver->securityDriver->domainRestoreSavedStateLabel(driver->securityDriver,
- vm, path) == -1)
+ virSecurityManagerRestoreSavedStateLabel(driver->securityManager,
+ vm, path) < 0)
VIR_WARN("failed to restore save state label on %s", path);
}
@@ -4779,10 +4748,8 @@ static int doCoreDump(struct qemud_driver *driver,
goto cleanup;
}
- if (driver->securityDriver &&
- driver->securityDriver->domainSetSavedStateLabel &&
- driver->securityDriver->domainSetSavedStateLabel(driver->securityDriver,
- vm, path) == -1)
+ if (virSecurityManagerSetSavedStateLabel(driver->securityManager,
+ vm, path) < 0)
goto cleanup;
qemuDomainObjEnterMonitorWithDriver(driver, vm);
@@ -4814,10 +4781,8 @@ static int doCoreDump(struct qemud_driver *driver,
if (ret < 0)
goto cleanup;
- if (driver->securityDriver &&
- driver->securityDriver->domainRestoreSavedStateLabel &&
- driver->securityDriver->domainRestoreSavedStateLabel(driver->securityDriver,
- vm, path) == -1)
+ if (virSecurityManagerRestoreSavedStateLabel(driver->securityManager,
+ vm, path) < 0)
goto cleanup;
cleanup:
@@ -5434,10 +5399,8 @@ static int qemudDomainGetSecurityLabel(virDomainPtr dom, virSecurityLabelPtr sec
* QEMU monitor hasn't seen SIGHUP/ERR on poll().
*/
if (virDomainObjIsActive(vm)) {
- if (driver->securityDriver &&
- driver->securityDriver->domainGetSecurityProcessLabel &&
- driver->securityDriver->domainGetSecurityProcessLabel(driver->securityDriver,
- vm, seclabel) < 0) {
+ if (virSecurityManagerGetProcessLabel(driver->securityManager,
+ vm, seclabel) < 0) {
qemuReportError(VIR_ERR_INTERNAL_ERROR,
"%s", _("Failed to get security label"));
goto cleanup;
@@ -5461,10 +5424,12 @@ static int qemudNodeGetSecurityModel(virConnectPtr conn,
int ret = 0;
qemuDriverLock(driver);
- if (!driver->securityPrimaryDriver) {
- memset(secmodel, 0, sizeof (*secmodel));
+ memset(secmodel, 0, sizeof(*secmodel));
+
+ /* NULL indicates no driver, which we treat as
+ * success, but simply return no data in *secmodel */
+ if (driver->caps->host.secModel.model == NULL)
goto cleanup;
- }
p = driver->caps->host.secModel.model;
if (strlen(p) >= VIR_SECURITY_MODEL_BUFLEN-1) {
@@ -5840,10 +5805,8 @@ qemudDomainSaveImageStartVM(virConnectPtr conn,
ret = 0;
out:
- if (driver->securityDriver &&
- driver->securityDriver->domainRestoreSavedStateLabel &&
- driver->securityDriver->domainRestoreSavedStateLabel(driver->securityDriver,
- vm, path) == -1)
+ if (virSecurityManagerRestoreSavedStateLabel(driver->securityManager,
+ vm, path) < 0)
VIR_WARN("failed to restore save state label on %s", path);
return ret;
@@ -6372,7 +6335,7 @@ static virDomainPtr qemudDomainDefine(virConnectPtr conn, const char *xml) {
VIR_DOMAIN_XML_INACTIVE)))
goto cleanup;
- if (virSecurityDriverVerify(def) < 0)
+ if (virSecurityManagerVerify(driver->securityManager, def) < 0)
goto cleanup;
if ((dupVM = virDomainObjIsDuplicate(&driver->domains, def, 0)) < 0)
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index 827bcaf..1dc036c 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -83,10 +83,8 @@ int qemuDomainChangeEjectableMedia(struct qemud_driver *driver,
return -1;
}
- if (driver->securityDriver &&
- driver->securityDriver->domainSetSecurityImageLabel &&
- driver->securityDriver->domainSetSecurityImageLabel(driver->securityDriver,
- vm, disk) < 0)
+ if (virSecurityManagerSetImageLabel(driver->securityManager,
+ vm, disk) < 0)
return -1;
if (!(driveAlias = qemuDeviceDriveHostAlias(origdisk, qemuCmdFlags)))
@@ -115,10 +113,8 @@ int qemuDomainChangeEjectableMedia(struct qemud_driver *driver,
if (ret < 0)
goto error;
- if (driver->securityDriver &&
- driver->securityDriver->domainRestoreSecurityImageLabel &&
- driver->securityDriver->domainRestoreSecurityImageLabel(driver->securityDriver,
- vm, origdisk) < 0)
+ if (virSecurityManagerRestoreImageLabel(driver->securityManager,
+ vm, origdisk) < 0)
VIR_WARN("Unable to restore security label on ejected image %s", origdisk->src);
VIR_FREE(origdisk->src);
@@ -134,10 +130,8 @@ int qemuDomainChangeEjectableMedia(struct qemud_driver *driver,
error:
VIR_FREE(driveAlias);
- if (driver->securityDriver &&
- driver->securityDriver->domainRestoreSecurityImageLabel &&
- driver->securityDriver->domainRestoreSecurityImageLabel(driver->securityDriver,
- vm, disk) < 0)
+ if (virSecurityManagerRestoreImageLabel(driver->securityManager,
+ vm, disk) < 0)
VIR_WARN("Unable to restore security label on new media %s", disk->src);
return -1;
}
@@ -162,10 +156,8 @@ int qemuDomainAttachPciDiskDevice(struct qemud_driver *driver,
}
}
- if (driver->securityDriver &&
- driver->securityDriver->domainSetSecurityImageLabel &&
- driver->securityDriver->domainSetSecurityImageLabel(driver->securityDriver,
- vm, disk) < 0)
+ if (virSecurityManagerSetImageLabel(driver->securityManager,
+ vm, disk) < 0)
return -1;
if (qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE) {
@@ -232,10 +224,8 @@ error:
qemuDomainPCIAddressReleaseAddr(priv->pciaddrs, &disk->info) < 0)
VIR_WARN("Unable to release PCI address on %s", disk->src);
- if (driver->securityDriver &&
- driver->securityDriver->domainRestoreSecurityImageLabel &&
- driver->securityDriver->domainRestoreSecurityImageLabel(driver->securityDriver,
- vm, disk) < 0)
+ if (virSecurityManagerRestoreImageLabel(driver->securityManager,
+ vm, disk) < 0)
VIR_WARN("Unable to restore security label on %s", disk->src);
return -1;
@@ -375,10 +365,8 @@ int qemuDomainAttachSCSIDisk(struct qemud_driver *driver,
}
- if (driver->securityDriver &&
- driver->securityDriver->domainSetSecurityImageLabel &&
- driver->securityDriver->domainSetSecurityImageLabel(driver->securityDriver,
- vm, disk) < 0)
+ if (virSecurityManagerSetImageLabel(driver->securityManager,
+ vm, disk) < 0)
return -1;
/* We should have an address already, so make sure */
@@ -464,10 +452,8 @@ error:
VIR_FREE(devstr);
VIR_FREE(drivestr);
- if (driver->securityDriver &&
- driver->securityDriver->domainRestoreSecurityImageLabel &&
- driver->securityDriver->domainRestoreSecurityImageLabel(driver->securityDriver,
- vm, disk) < 0)
+ if (virSecurityManagerRestoreImageLabel(driver->securityManager,
+ vm, disk) < 0)
VIR_WARN("Unable to restore security label on %s", disk->src);
return -1;
@@ -492,10 +478,8 @@ int qemuDomainAttachUsbMassstorageDevice(struct qemud_driver *driver,
}
}
- if (driver->securityDriver &&
- driver->securityDriver->domainSetSecurityImageLabel &&
- driver->securityDriver->domainSetSecurityImageLabel(driver->securityDriver,
- vm, disk) < 0)
+ if (virSecurityManagerSetImageLabel(driver->securityManager,
+ vm, disk) < 0)
return -1;
if (!disk->src) {
@@ -551,10 +535,8 @@ error:
VIR_FREE(devstr);
VIR_FREE(drivestr);
- if (driver->securityDriver &&
- driver->securityDriver->domainRestoreSecurityImageLabel &&
- driver->securityDriver->domainRestoreSecurityImageLabel(driver->securityDriver,
- vm, disk) < 0)
+ if (virSecurityManagerRestoreImageLabel(driver->securityManager,
+ vm, disk) < 0)
VIR_WARN("Unable to restore security label on %s", disk->src);
return -1;
@@ -979,10 +961,8 @@ int qemuDomainAttachHostDevice(struct qemud_driver *driver,
}
- if (driver->securityDriver &&
- driver->securityDriver->domainSetSecurityHostdevLabel &&
- driver->securityDriver->domainSetSecurityHostdevLabel(driver->securityDriver,
- vm, hostdev) < 0)
+ if (virSecurityManagerSetHostdevLabel(driver->securityManager,
+ vm, hostdev) < 0)
return -1;
switch (hostdev->source.subsys.type) {
@@ -1008,10 +988,8 @@ int qemuDomainAttachHostDevice(struct qemud_driver *driver,
return 0;
error:
- if (driver->securityDriver &&
- driver->securityDriver->domainRestoreSecurityHostdevLabel &&
- driver->securityDriver->domainRestoreSecurityHostdevLabel(driver->securityDriver,
- vm, hostdev) < 0)
+ if (virSecurityManagerRestoreHostdevLabel(driver->securityManager,
+ vm, hostdev) < 0)
VIR_WARN0("Unable to restore host device labelling on hotplug fail");
return -1;
@@ -1183,10 +1161,8 @@ int qemuDomainDetachPciDiskDevice(struct qemud_driver *driver,
virDomainDiskDefFree(detach);
- if (driver->securityDriver &&
- driver->securityDriver->domainRestoreSecurityImageLabel &&
- driver->securityDriver->domainRestoreSecurityImageLabel(driver->securityDriver,
- vm, dev->data.disk) < 0)
+ if (virSecurityManagerRestoreImageLabel(driver->securityManager,
+ vm, dev->data.disk) < 0)
VIR_WARN("Unable to restore security label on %s", dev->data.disk->src);
if (cgroup != NULL) {
@@ -1263,10 +1239,8 @@ int qemuDomainDetachSCSIDiskDevice(struct qemud_driver *driver,
virDomainDiskDefFree(detach);
- if (driver->securityDriver &&
- driver->securityDriver->domainRestoreSecurityImageLabel &&
- driver->securityDriver->domainRestoreSecurityImageLabel(driver->securityDriver,
- vm, dev->data.disk) < 0)
+ if (virSecurityManagerRestoreImageLabel(driver->securityManager,
+ vm, dev->data.disk) < 0)
VIR_WARN("Unable to restore security label on %s", dev->data.disk->src);
if (cgroup != NULL) {
@@ -1699,10 +1673,8 @@ int qemuDomainDetachHostDevice(struct qemud_driver *driver,
return -1;
}
- if (driver->securityDriver &&
- driver->securityDriver->domainRestoreSecurityHostdevLabel &&
- driver->securityDriver->domainRestoreSecurityHostdevLabel(driver->securityDriver,
- vm, dev->data.hostdev) < 0)
+ if (virSecurityManagerRestoreHostdevLabel(driver->securityManager,
+ vm, dev->data.hostdev) < 0)
VIR_WARN0("Failed to restore host device labelling");
return ret;
diff --git a/src/qemu/qemu_security_dac.c b/src/qemu/qemu_security_dac.c
deleted file mode 100644
index 6b6170a..0000000
--- a/src/qemu/qemu_security_dac.c
+++ /dev/null
@@ -1,576 +0,0 @@
-/*
- * Copyright (C) 2010 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.
- *
- * QEMU POSIX DAC security driver
- */
-#include <config.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-
-#include "qemu_security_dac.h"
-#include "qemu_conf.h"
-#include "datatypes.h"
-#include "virterror_internal.h"
-#include "util.h"
-#include "memory.h"
-#include "logging.h"
-#include "pci.h"
-#include "hostusb.h"
-#include "storage_file.h"
-
-#define VIR_FROM_THIS VIR_FROM_QEMU
-
-static struct qemud_driver *driver;
-
-void qemuSecurityDACSetDriver(struct qemud_driver *newdriver)
-{
- driver = newdriver;
-}
-
-
-static int
-qemuSecurityDACSetOwnership(const char *path, int uid, int gid)
-{
- VIR_INFO("Setting DAC user and group on '%s' to '%d:%d'", path, uid, gid);
-
- if (chown(path, uid, gid) < 0) {
- struct stat sb;
- int chown_errno = errno;
-
- if (stat(path, &sb) >= 0) {
- if (sb.st_uid == uid &&
- sb.st_gid == gid) {
- /* It's alright, there's nothing to change anyway. */
- return 0;
- }
- }
-
- if (chown_errno == EOPNOTSUPP) {
- VIR_INFO("Setting user and group to '%d:%d' on '%s' not supported by filesystem",
- uid, gid, path);
- } else if (chown_errno == EPERM) {
- VIR_INFO("Setting user and group to '%d:%d' on '%s' not permitted",
- uid, gid, path);
- } else if (chown_errno == EROFS) {
- VIR_INFO("Setting user and group to '%d:%d' on '%s' not possible on readonly filesystem",
- uid, gid, path);
- } else {
- virReportSystemError(chown_errno,
- _("unable to set user and group to '%d:%d' on '%s'"),
- uid, gid, path);
- return -1;
- }
- }
- return 0;
-}
-
-static int
-qemuSecurityDACRestoreSecurityFileLabel(const char *path)
-{
- struct stat buf;
- int rc = -1;
- char *newpath = NULL;
-
- VIR_INFO("Restoring DAC user and group on '%s'", path);
-
- if (virFileResolveLink(path, &newpath) < 0) {
- virReportSystemError(errno,
- _("cannot resolve symlink %s"), path);
- goto err;
- }
-
- if (stat(newpath, &buf) != 0)
- goto err;
-
- /* XXX record previous ownership */
- rc = qemuSecurityDACSetOwnership(newpath, 0, 0);
-
-err:
- VIR_FREE(newpath);
- return rc;
-}
-
-
-static int
-qemuSecurityDACSetSecurityFileLabel(virDomainDiskDefPtr disk ATTRIBUTE_UNUSED,
- const char *path,
- size_t depth ATTRIBUTE_UNUSED,
- void *opaque ATTRIBUTE_UNUSED)
-{
- return qemuSecurityDACSetOwnership(path, driver->user, driver->group);
-}
-
-
-static int
-qemuSecurityDACSetSecurityImageLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
- virDomainObjPtr vm ATTRIBUTE_UNUSED,
- virDomainDiskDefPtr disk)
-
-{
- if (!driver->privileged || !driver->dynamicOwnership)
- return 0;
-
- return virDomainDiskDefForeachPath(disk,
- driver->allowDiskFormatProbing,
- false,
- qemuSecurityDACSetSecurityFileLabel,
- NULL);
-}
-
-
-static int
-qemuSecurityDACRestoreSecurityImageLabelInt(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
- virDomainObjPtr vm ATTRIBUTE_UNUSED,
- virDomainDiskDefPtr disk,
- int migrated)
-{
- if (!driver->privileged || !driver->dynamicOwnership)
- return 0;
-
- /* Don't restore labels on readoly/shared disks, because
- * other VMs may still be accessing these
- * Alternatively we could iterate over all running
- * domains and try to figure out if it is in use, but
- * this would not work for clustered filesystems, since
- * we can't see running VMs using the file on other nodes
- * Safest bet is thus to skip the restore step.
- */
- if (disk->readonly || disk->shared)
- return 0;
-
- if (!disk->src || disk->type == VIR_DOMAIN_DISK_TYPE_NETWORK)
- return 0;
-
- /* If we have a shared FS & doing migrated, we must not
- * change ownership, because that kills access on the
- * destination host which is sub-optimal for the guest
- * VM's I/O attempts :-)
- */
- if (migrated) {
- int rc = virStorageFileIsSharedFS(disk->src);
- if (rc < 0)
- return -1;
- if (rc == 1) {
- VIR_DEBUG("Skipping image label restore on %s because FS is shared",
- disk->src);
- return 0;
- }
- }
-
- return qemuSecurityDACRestoreSecurityFileLabel(disk->src);
-}
-
-
-static int
-qemuSecurityDACRestoreSecurityImageLabel(virSecurityDriverPtr drv,
- virDomainObjPtr vm,
- virDomainDiskDefPtr disk)
-{
- return qemuSecurityDACRestoreSecurityImageLabelInt(drv, vm, disk, 0);
-}
-
-
-static int
-qemuSecurityDACSetSecurityPCILabel(pciDevice *dev ATTRIBUTE_UNUSED,
- const char *file,
- void *opaque ATTRIBUTE_UNUSED)
-{
- return qemuSecurityDACSetOwnership(file, driver->user, driver->group);
-}
-
-
-static int
-qemuSecurityDACSetSecurityUSBLabel(usbDevice *dev ATTRIBUTE_UNUSED,
- const char *file,
- void *opaque ATTRIBUTE_UNUSED)
-{
- return qemuSecurityDACSetOwnership(file, driver->user, driver->group);
-}
-
-
-static int
-qemuSecurityDACSetSecurityHostdevLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
- virDomainObjPtr vm,
- virDomainHostdevDefPtr dev)
-
-{
- int ret = -1;
-
- if (!driver->privileged || !driver->dynamicOwnership)
- return 0;
-
- if (dev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS)
- return 0;
-
- switch (dev->source.subsys.type) {
- case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB: {
- usbDevice *usb = usbGetDevice(dev->source.subsys.u.usb.bus,
- dev->source.subsys.u.usb.device);
-
- if (!usb)
- goto done;
-
- ret = usbDeviceFileIterate(usb, qemuSecurityDACSetSecurityUSBLabel, vm);
- usbFreeDevice(usb);
- break;
- }
-
- case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI: {
- pciDevice *pci = pciGetDevice(dev->source.subsys.u.pci.domain,
- dev->source.subsys.u.pci.bus,
- dev->source.subsys.u.pci.slot,
- dev->source.subsys.u.pci.function);
-
- if (!pci)
- goto done;
-
- ret = pciDeviceFileIterate(pci, qemuSecurityDACSetSecurityPCILabel, vm);
- pciFreeDevice(pci);
-
- break;
- }
-
- default:
- ret = 0;
- break;
- }
-
-done:
- return ret;
-}
-
-
-static int
-qemuSecurityDACRestoreSecurityPCILabel(pciDevice *dev ATTRIBUTE_UNUSED,
- const char *file,
- void *opaque ATTRIBUTE_UNUSED)
-{
- return qemuSecurityDACRestoreSecurityFileLabel(file);
-}
-
-
-static int
-qemuSecurityDACRestoreSecurityUSBLabel(usbDevice *dev ATTRIBUTE_UNUSED,
- const char *file,
- void *opaque ATTRIBUTE_UNUSED)
-{
- return qemuSecurityDACRestoreSecurityFileLabel(file);
-}
-
-
-static int
-qemuSecurityDACRestoreSecurityHostdevLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
- virDomainObjPtr vm ATTRIBUTE_UNUSED,
- virDomainHostdevDefPtr dev)
-
-{
- int ret = -1;
-
- if (!driver->privileged || !driver->dynamicOwnership)
- return 0;
-
- if (dev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS)
- return 0;
-
- switch (dev->source.subsys.type) {
- case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB: {
- usbDevice *usb = usbGetDevice(dev->source.subsys.u.usb.bus,
- dev->source.subsys.u.usb.device);
-
- if (!usb)
- goto done;
-
- ret = usbDeviceFileIterate(usb, qemuSecurityDACRestoreSecurityUSBLabel, NULL);
- usbFreeDevice(usb);
-
- break;
- }
-
- case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI: {
- pciDevice *pci = pciGetDevice(dev->source.subsys.u.pci.domain,
- dev->source.subsys.u.pci.bus,
- dev->source.subsys.u.pci.slot,
- dev->source.subsys.u.pci.function);
-
- if (!pci)
- goto done;
-
- ret = pciDeviceFileIterate(pci, qemuSecurityDACRestoreSecurityPCILabel, NULL);
- pciFreeDevice(pci);
-
- break;
- }
-
- default:
- ret = 0;
- break;
- }
-
-done:
- return ret;
-}
-
-
-static int
-qemuSecurityDACSetChardevLabel(virDomainObjPtr vm,
- virDomainChrDefPtr dev)
-
-{
- const virSecurityLabelDefPtr secdef = &vm->def->seclabel;
- char *in = NULL, *out = NULL;
- int ret = -1;
-
- if (secdef->type == VIR_DOMAIN_SECLABEL_STATIC)
- return 0;
-
- switch (dev->type) {
- case VIR_DOMAIN_CHR_TYPE_DEV:
- case VIR_DOMAIN_CHR_TYPE_FILE:
- ret = qemuSecurityDACSetOwnership(dev->data.file.path, driver->user, driver->group);
- break;
-
- case VIR_DOMAIN_CHR_TYPE_PIPE:
- if ((virAsprintf(&in, "%s.in", dev->data.file.path) < 0) ||
- (virAsprintf(&out, "%s.out", dev->data.file.path) < 0)) {
- virReportOOMError();
- goto done;
- }
- if ((qemuSecurityDACSetOwnership(in, driver->user, driver->group) < 0) ||
- (qemuSecurityDACSetOwnership(out, driver->user, driver->group) < 0))
- goto done;
- ret = 0;
- break;
-
- default:
- ret = 0;
- break;
- }
-
-done:
- VIR_FREE(in);
- VIR_FREE(out);
- return ret;
-}
-
-static int
-qemuSecurityDACRestoreChardevLabel(virDomainObjPtr vm,
- virDomainChrDefPtr dev)
-
-{
- const virSecurityLabelDefPtr secdef = &vm->def->seclabel;
- char *in = NULL, *out = NULL;
- int ret = -1;
-
- if (secdef->type == VIR_DOMAIN_SECLABEL_STATIC)
- return 0;
-
- switch (dev->type) {
- case VIR_DOMAIN_CHR_TYPE_DEV:
- case VIR_DOMAIN_CHR_TYPE_FILE:
- ret = qemuSecurityDACRestoreSecurityFileLabel(dev->data.file.path);
- break;
-
- case VIR_DOMAIN_CHR_TYPE_PIPE:
- if ((virAsprintf(&out, "%s.out", dev->data.file.path) < 0) ||
- (virAsprintf(&in, "%s.in", dev->data.file.path) < 0)) {
- virReportOOMError();
- goto done;
- }
- if ((qemuSecurityDACRestoreSecurityFileLabel(out) < 0) ||
- (qemuSecurityDACRestoreSecurityFileLabel(in) < 0))
- goto done;
- ret = 0;
- break;
-
- default:
- ret = 0;
- break;
- }
-
-done:
- VIR_FREE(in);
- VIR_FREE(out);
- return ret;
-}
-
-
-static int
-qemuSecurityDACRestoreChardevCallback(virDomainDefPtr def ATTRIBUTE_UNUSED,
- virDomainChrDefPtr dev,
- void *opaque)
-{
- virDomainObjPtr vm = opaque;
-
- return qemuSecurityDACRestoreChardevLabel(vm, dev);
-}
-
-
-static int
-qemuSecurityDACRestoreSecurityAllLabel(virSecurityDriverPtr drv,
- virDomainObjPtr vm,
- int migrated)
-{
- int i;
- int rc = 0;
-
- if (!driver->privileged || !driver->dynamicOwnership)
- return 0;
-
- VIR_DEBUG("Restoring security label on %s migrated=%d",
- vm->def->name, migrated);
-
- for (i = 0 ; i < vm->def->nhostdevs ; i++) {
- if (qemuSecurityDACRestoreSecurityHostdevLabel(drv,
- vm,
- vm->def->hostdevs[i]) < 0)
- rc = -1;
- }
- for (i = 0 ; i < vm->def->ndisks ; i++) {
- if (qemuSecurityDACRestoreSecurityImageLabelInt(drv,
- vm,
- vm->def->disks[i],
- migrated) < 0)
- rc = -1;
- }
-
- if (virDomainChrDefForeach(vm->def,
- false,
- qemuSecurityDACRestoreChardevCallback,
- vm) < 0)
- rc = -1;
-
- if (vm->def->os.kernel &&
- qemuSecurityDACRestoreSecurityFileLabel(vm->def->os.kernel) < 0)
- rc = -1;
-
- if (vm->def->os.initrd &&
- qemuSecurityDACRestoreSecurityFileLabel(vm->def->os.initrd) < 0)
- rc = -1;
-
- return rc;
-}
-
-
-static int
-qemuSecurityDACSetChardevCallback(virDomainDefPtr def ATTRIBUTE_UNUSED,
- virDomainChrDefPtr dev,
- void *opaque)
-{
- virDomainObjPtr vm = opaque;
-
- return qemuSecurityDACSetChardevLabel(vm, dev);
-}
-
-
-static int
-qemuSecurityDACSetSecurityAllLabel(virSecurityDriverPtr drv,
- virDomainObjPtr vm,
- const char *stdin_path ATTRIBUTE_UNUSED)
-{
- int i;
-
- if (!driver->privileged || !driver->dynamicOwnership)
- return 0;
-
- for (i = 0 ; i < vm->def->ndisks ; i++) {
- /* XXX fixme - we need to recursively label the entriy tree :-( */
- if (vm->def->disks[i]->type == VIR_DOMAIN_DISK_TYPE_DIR)
- continue;
- if (qemuSecurityDACSetSecurityImageLabel(drv,
- vm,
- vm->def->disks[i]) < 0)
- return -1;
- }
- for (i = 0 ; i < vm->def->nhostdevs ; i++) {
- if (qemuSecurityDACSetSecurityHostdevLabel(drv,
- vm,
- vm->def->hostdevs[i]) < 0)
- return -1;
- }
-
- if (virDomainChrDefForeach(vm->def,
- true,
- qemuSecurityDACSetChardevCallback,
- vm) < 0)
- return -1;
-
- if (vm->def->os.kernel &&
- qemuSecurityDACSetOwnership(vm->def->os.kernel,
- driver->user,
- driver->group) < 0)
- return -1;
-
- if (vm->def->os.initrd &&
- qemuSecurityDACSetOwnership(vm->def->os.initrd,
- driver->user,
- driver->group) < 0)
- return -1;
-
- return 0;
-}
-
-
-static int
-qemuSecurityDACSetSavedStateLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
- virDomainObjPtr vm ATTRIBUTE_UNUSED,
- const char *savefile)
-{
- if (!driver->privileged)
- return 0;
-
- return qemuSecurityDACSetOwnership(savefile, driver->user, driver->group);
-}
-
-
-static int
-qemuSecurityDACRestoreSavedStateLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
- virDomainObjPtr vm ATTRIBUTE_UNUSED,
- const char *savefile)
-{
- if (!driver->privileged || !driver->dynamicOwnership)
- return 0;
-
- return qemuSecurityDACRestoreSecurityFileLabel(savefile);
-}
-
-
-static int
-qemuSecurityDACSetProcessLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
- virDomainObjPtr vm ATTRIBUTE_UNUSED)
-{
- DEBUG("Dropping privileges of VM to %d:%d", driver->user, driver->group);
-
- if (!driver->privileged)
- return 0;
-
- if (virSetUIDGID(driver->user, driver->group) < 0)
- return -1;
-
- return 0;
-}
-
-
-
-virSecurityDriver qemuDACSecurityDriver = {
- .name = "qemuDAC",
-
- .domainSetSecurityProcessLabel = qemuSecurityDACSetProcessLabel,
-
- .domainSetSecurityImageLabel = qemuSecurityDACSetSecurityImageLabel,
- .domainRestoreSecurityImageLabel = qemuSecurityDACRestoreSecurityImageLabel,
-
- .domainSetSecurityAllLabel = qemuSecurityDACSetSecurityAllLabel,
- .domainRestoreSecurityAllLabel = qemuSecurityDACRestoreSecurityAllLabel,
-
- .domainSetSecurityHostdevLabel = qemuSecurityDACSetSecurityHostdevLabel,
- .domainRestoreSecurityHostdevLabel = qemuSecurityDACRestoreSecurityHostdevLabel,
-
- .domainSetSavedStateLabel = qemuSecurityDACSetSavedStateLabel,
- .domainRestoreSavedStateLabel = qemuSecurityDACRestoreSavedStateLabel,
-};
diff --git a/src/qemu/qemu_security_dac.h b/src/qemu/qemu_security_dac.h
deleted file mode 100644
index a742f7a..0000000
--- a/src/qemu/qemu_security_dac.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Copyright (C) 2010 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.
- *
- * QEMU POSIX DAC security driver
- */
-
-#include "security/security_driver.h"
-#include "qemu_conf.h"
-
-#ifndef __QEMU_SECURITY_DAC
-# define __QEMU_SECURITY_DAC
-
-extern virSecurityDriver qemuDACSecurityDriver;
-
-void qemuSecurityDACSetDriver(struct qemud_driver *driver);
-
-#endif /* __QEMU_SECURITY_DAC */
diff --git a/src/qemu/qemu_security_stacked.c b/src/qemu/qemu_security_stacked.c
deleted file mode 100644
index 432d095..0000000
--- a/src/qemu/qemu_security_stacked.c
+++ /dev/null
@@ -1,418 +0,0 @@
-/*
- * Copyright (C) 2010 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.
- *
- * QEMU stacked security driver
- */
-
-#include <config.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-
-#include "qemu_security_stacked.h"
-
-#include "qemu_conf.h"
-#include "datatypes.h"
-#include "virterror_internal.h"
-#include "util.h"
-#include "memory.h"
-#include "logging.h"
-#include "pci.h"
-#include "hostusb.h"
-#include "storage_file.h"
-
-#define VIR_FROM_THIS VIR_FROM_QEMU
-
-
-static struct qemud_driver *driver;
-
-void qemuSecurityStackedSetDriver(struct qemud_driver *newdriver)
-{
- driver = newdriver;
-}
-
-
-static int
-qemuSecurityStackedVerify(virDomainDefPtr def)
-{
- int rc = 0;
-
- if (driver->securitySecondaryDriver &&
- driver->securitySecondaryDriver->domainSecurityVerify &&
- driver->securitySecondaryDriver->domainSecurityVerify(def) < 0)
- rc = -1;
-
- if (driver->securityPrimaryDriver &&
- driver->securityPrimaryDriver->domainSecurityVerify &&
- driver->securityPrimaryDriver->domainSecurityVerify(def) < 0)
- rc = -1;
-
- return rc;
-}
-
-
-static int
-qemuSecurityStackedGenLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
- virDomainObjPtr vm)
-{
- int rc = 0;
-
- if (driver->securitySecondaryDriver &&
- driver->securitySecondaryDriver->domainGenSecurityLabel &&
- driver->securitySecondaryDriver->domainGenSecurityLabel(driver->securitySecondaryDriver,
- vm) < 0)
- rc = -1;
-
- if (driver->securityPrimaryDriver &&
- driver->securityPrimaryDriver->domainGenSecurityLabel &&
- driver->securityPrimaryDriver->domainGenSecurityLabel(driver->securityPrimaryDriver,
- vm) < 0)
- rc = -1;
-
- return rc;
-}
-
-
-static int
-qemuSecurityStackedReleaseLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
- virDomainObjPtr vm)
-{
- int rc = 0;
-
- if (driver->securitySecondaryDriver &&
- driver->securitySecondaryDriver->domainReleaseSecurityLabel &&
- driver->securitySecondaryDriver->domainReleaseSecurityLabel(driver->securitySecondaryDriver,
- vm) < 0)
- rc = -1;
-
- if (driver->securityPrimaryDriver &&
- driver->securityPrimaryDriver->domainReleaseSecurityLabel &&
- driver->securityPrimaryDriver->domainReleaseSecurityLabel(driver->securityPrimaryDriver,
- vm) < 0)
- rc = -1;
-
- return rc;
-}
-
-
-static int
-qemuSecurityStackedReserveLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
- virDomainObjPtr vm)
-{
- int rc = 0;
-
- if (driver->securitySecondaryDriver &&
- driver->securitySecondaryDriver->domainReserveSecurityLabel &&
- driver->securitySecondaryDriver->domainReserveSecurityLabel(driver->securitySecondaryDriver,
- vm) < 0)
- rc = -1;
-
- if (driver->securityPrimaryDriver &&
- driver->securityPrimaryDriver->domainReserveSecurityLabel &&
- driver->securityPrimaryDriver->domainReserveSecurityLabel(driver->securityPrimaryDriver,
- vm) < 0)
- rc = -1;
-
- return rc;
-}
-
-
-static int
-qemuSecurityStackedSetSecurityImageLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
- virDomainObjPtr vm,
- virDomainDiskDefPtr disk)
-{
- int rc = 0;
-
- if (driver->securitySecondaryDriver &&
- driver->securitySecondaryDriver->domainSetSecurityImageLabel &&
- driver->securitySecondaryDriver->domainSetSecurityImageLabel(driver->securitySecondaryDriver,
- vm, disk) < 0)
- rc = -1;
-
- if (driver->securityPrimaryDriver &&
- driver->securityPrimaryDriver->domainSetSecurityImageLabel &&
- driver->securityPrimaryDriver->domainSetSecurityImageLabel(driver->securityPrimaryDriver,
- vm, disk) < 0)
- rc = -1;
-
- return rc;
-}
-
-
-static int
-qemuSecurityStackedRestoreSecurityImageLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
- virDomainObjPtr vm,
- virDomainDiskDefPtr disk)
-{
- int rc = 0;
-
- if (driver->securitySecondaryDriver &&
- driver->securitySecondaryDriver->domainRestoreSecurityImageLabel &&
- driver->securitySecondaryDriver->domainRestoreSecurityImageLabel(driver->securitySecondaryDriver,
- vm, disk) < 0)
- rc = -1;
-
- if (driver->securityPrimaryDriver &&
- driver->securityPrimaryDriver->domainRestoreSecurityImageLabel &&
- driver->securityPrimaryDriver->domainRestoreSecurityImageLabel(driver->securityPrimaryDriver,
- vm, disk) < 0)
- rc = -1;
-
- return rc;
-}
-
-
-static int
-qemuSecurityStackedSetSecurityHostdevLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
- virDomainObjPtr vm,
- virDomainHostdevDefPtr dev)
-
-{
- int rc = 0;
-
- if (driver->securitySecondaryDriver &&
- driver->securitySecondaryDriver->domainSetSecurityHostdevLabel &&
- driver->securitySecondaryDriver->domainSetSecurityHostdevLabel(driver->securitySecondaryDriver,
- vm, dev) < 0)
- rc = -1;
-
- if (driver->securityPrimaryDriver &&
- driver->securityPrimaryDriver->domainSetSecurityHostdevLabel &&
- driver->securityPrimaryDriver->domainSetSecurityHostdevLabel(driver->securityPrimaryDriver,
- vm, dev) < 0)
- rc = -1;
-
- return rc;
-}
-
-
-static int
-qemuSecurityStackedRestoreSecurityHostdevLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
- virDomainObjPtr vm,
- virDomainHostdevDefPtr dev)
-{
- int rc = 0;
-
- if (driver->securitySecondaryDriver &&
- driver->securitySecondaryDriver->domainRestoreSecurityHostdevLabel &&
- driver->securitySecondaryDriver->domainRestoreSecurityHostdevLabel(driver->securitySecondaryDriver,
- vm, dev) < 0)
- rc = -1;
-
- if (driver->securityPrimaryDriver &&
- driver->securityPrimaryDriver->domainRestoreSecurityHostdevLabel &&
- driver->securityPrimaryDriver->domainRestoreSecurityHostdevLabel(driver->securityPrimaryDriver,
- vm, dev) < 0)
- rc = -1;
-
- return rc;
-}
-
-
-static int
-qemuSecurityStackedSetSecurityAllLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
- virDomainObjPtr vm,
- const char *stdin_path)
-{
- int rc = 0;
-
- if (driver->securitySecondaryDriver &&
- driver->securitySecondaryDriver->domainSetSecurityAllLabel &&
- driver->securitySecondaryDriver->domainSetSecurityAllLabel(driver->securitySecondaryDriver,
- vm, stdin_path) < 0)
- rc = -1;
-
- if (driver->securityPrimaryDriver &&
- driver->securityPrimaryDriver->domainSetSecurityAllLabel &&
- driver->securityPrimaryDriver->domainSetSecurityAllLabel(driver->securityPrimaryDriver,
- vm, stdin_path) < 0)
- rc = -1;
-
- return rc;
-}
-
-
-static int
-qemuSecurityStackedRestoreSecurityAllLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
- virDomainObjPtr vm,
- int migrated)
-{
- int rc = 0;
-
- if (driver->securitySecondaryDriver &&
- driver->securitySecondaryDriver->domainRestoreSecurityAllLabel &&
- driver->securitySecondaryDriver->domainRestoreSecurityAllLabel(driver->securitySecondaryDriver,
- vm, migrated) < 0)
- rc = -1;
-
- if (driver->securityPrimaryDriver &&
- driver->securityPrimaryDriver->domainRestoreSecurityAllLabel &&
- driver->securityPrimaryDriver->domainRestoreSecurityAllLabel(driver->securityPrimaryDriver,
- vm, migrated) < 0)
- rc = -1;
-
- return rc;
-}
-
-
-static int
-qemuSecurityStackedSetSavedStateLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
- virDomainObjPtr vm,
- const char *savefile)
-{
- int rc = 0;
-
- if (driver->securitySecondaryDriver &&
- driver->securitySecondaryDriver->domainSetSavedStateLabel &&
- driver->securitySecondaryDriver->domainSetSavedStateLabel(driver->securitySecondaryDriver,
- vm, savefile) < 0)
- rc = -1;
-
- if (driver->securityPrimaryDriver &&
- driver->securityPrimaryDriver->domainSetSavedStateLabel &&
- driver->securityPrimaryDriver->domainSetSavedStateLabel(driver->securityPrimaryDriver,
- vm, savefile) < 0)
- rc = -1;
-
- return rc;
-}
-
-
-static int
-qemuSecurityStackedRestoreSavedStateLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
- virDomainObjPtr vm,
- const char *savefile)
-{
- int rc = 0;
-
- if (driver->securitySecondaryDriver &&
- driver->securitySecondaryDriver->domainRestoreSavedStateLabel &&
- driver->securitySecondaryDriver->domainRestoreSavedStateLabel(driver->securitySecondaryDriver,
- vm, savefile) < 0)
- rc = -1;
-
- if (driver->securityPrimaryDriver &&
- driver->securityPrimaryDriver->domainRestoreSavedStateLabel &&
- driver->securityPrimaryDriver->domainRestoreSavedStateLabel(driver->securityPrimaryDriver,
- vm, savefile) < 0)
- rc = -1;
-
- return rc;
-}
-
-
-static int
-qemuSecurityStackedSetProcessLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
- virDomainObjPtr vm)
-{
- int rc = 0;
-
- if (driver->securitySecondaryDriver &&
- driver->securitySecondaryDriver->domainSetSecurityProcessLabel &&
- driver->securitySecondaryDriver->domainSetSecurityProcessLabel(driver->securitySecondaryDriver,
- vm) < 0)
- rc = -1;
-
- if (driver->securityPrimaryDriver &&
- driver->securityPrimaryDriver->domainSetSecurityProcessLabel &&
- driver->securityPrimaryDriver->domainSetSecurityProcessLabel(driver->securityPrimaryDriver,
- vm) < 0)
- rc = -1;
-
- return rc;
-}
-
-static int
-qemuSecurityStackedGetProcessLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
- virDomainObjPtr vm,
- virSecurityLabelPtr seclabel)
-{
- int rc = 0;
-
- if (driver->securityPrimaryDriver &&
- driver->securityPrimaryDriver->domainGetSecurityProcessLabel &&
- driver->securityPrimaryDriver->domainGetSecurityProcessLabel(driver->securityPrimaryDriver,
- vm,
- seclabel) < 0)
- rc = -1;
-
- return rc;
-}
-
-
-static int
-qemuSecurityStackedSetSocketLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
- virDomainObjPtr vm)
-{
- int rc = 0;
-
- if (driver->securityPrimaryDriver &&
- driver->securityPrimaryDriver->domainSetSecuritySocketLabel &&
- driver->securityPrimaryDriver->domainSetSecuritySocketLabel(driver->securityPrimaryDriver,
- vm) < 0)
- rc = -1;
-
- if (driver->securitySecondaryDriver &&
- driver->securitySecondaryDriver->domainSetSecuritySocketLabel &&
- driver->securitySecondaryDriver->domainSetSecuritySocketLabel(driver->securitySecondaryDriver,
- vm) < 0)
- rc = -1;
-
- return rc;
-}
-
-
-static int
-qemuSecurityStackedClearSocketLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
- virDomainObjPtr vm)
-{
- int rc = 0;
-
- if (driver->securitySecondaryDriver &&
- driver->securitySecondaryDriver->domainClearSecuritySocketLabel &&
- driver->securitySecondaryDriver->domainClearSecuritySocketLabel(driver->securitySecondaryDriver,
- vm) < 0)
- rc = -1;
-
- if (driver->securityPrimaryDriver &&
- driver->securityPrimaryDriver->domainClearSecuritySocketLabel &&
- driver->securityPrimaryDriver->domainClearSecuritySocketLabel(driver->securityPrimaryDriver,
- vm) < 0)
- rc = -1;
-
- return rc;
-}
-
-
-virSecurityDriver qemuStackedSecurityDriver = {
- .name = "qemuStacked",
- .domainSecurityVerify = qemuSecurityStackedVerify,
-
- .domainGenSecurityLabel = qemuSecurityStackedGenLabel,
- .domainReleaseSecurityLabel = qemuSecurityStackedReleaseLabel,
- .domainReserveSecurityLabel = qemuSecurityStackedReserveLabel,
-
- .domainGetSecurityProcessLabel = qemuSecurityStackedGetProcessLabel,
- .domainSetSecurityProcessLabel = qemuSecurityStackedSetProcessLabel,
-
- .domainSetSecurityImageLabel = qemuSecurityStackedSetSecurityImageLabel,
- .domainRestoreSecurityImageLabel = qemuSecurityStackedRestoreSecurityImageLabel,
-
- .domainSetSecurityAllLabel = qemuSecurityStackedSetSecurityAllLabel,
- .domainRestoreSecurityAllLabel = qemuSecurityStackedRestoreSecurityAllLabel,
-
- .domainSetSecurityHostdevLabel = qemuSecurityStackedSetSecurityHostdevLabel,
- .domainRestoreSecurityHostdevLabel = qemuSecurityStackedRestoreSecurityHostdevLabel,
-
- .domainSetSavedStateLabel = qemuSecurityStackedSetSavedStateLabel,
- .domainRestoreSavedStateLabel = qemuSecurityStackedRestoreSavedStateLabel,
-
- .domainClearSecuritySocketLabel = qemuSecurityStackedClearSocketLabel,
- .domainSetSecuritySocketLabel = qemuSecurityStackedSetSocketLabel,
-};
diff --git a/src/qemu/qemu_security_stacked.h b/src/qemu/qemu_security_stacked.h
deleted file mode 100644
index 07f76d5..0000000
--- a/src/qemu/qemu_security_stacked.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Copyright (C) 2010 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.
- *
- * QEMU stacked security driver
- */
-
-#include "security/security_driver.h"
-#include "qemu_conf.h"
-
-#ifndef __QEMU_SECURITY_STACKED
-# define __QEMU_SECURITY_STACKED
-
-extern virSecurityDriver qemuStackedSecurityDriver;
-
-void qemuSecurityStackedSetDriver(struct qemud_driver *driver);
-
-#endif /* __QEMU_SECURITY_DAC */
diff --git a/src/security/security_apparmor.c b/src/security/security_apparmor.c
index 468d0a3..d82ba73 100644
--- a/src/security/security_apparmor.c
+++ b/src/security/security_apparmor.c
@@ -1,4 +1,3 @@
-
/*
* AppArmor security driver for libvirt
* Copyright (C) 2009-2010 Canonical Ltd.
@@ -28,7 +27,6 @@
#include "internal.h"
-#include "security_driver.h"
#include "security_apparmor.h"
#include "util.h"
#include "memory.h"
@@ -47,7 +45,7 @@
/* Data structure to pass to *FileIterate so we have everything we need */
struct SDPDOP {
- virSecurityDriverPtr drv;
+ virSecurityManagerPtr mgr;
virDomainObjPtr vm;
};
@@ -158,7 +156,7 @@ profile_status_file(const char *str)
* load (add) a profile. Will create one if necessary
*/
static int
-load_profile(virSecurityDriverPtr drv,
+load_profile(virSecurityManagerPtr mgr,
const char *profile,
virDomainObjPtr vm,
const char *fn,
@@ -169,7 +167,7 @@ load_profile(virSecurityDriverPtr drv,
char *xml = NULL;
int pipefd[2];
pid_t child;
- const char *probe = virSecurityDriverGetAllowDiskFormatProbing(drv)
+ const char *probe = virSecurityManagerGetAllowDiskFormatProbing(mgr)
? "1" : "0";
if (pipe(pipefd) < -1) {
@@ -300,7 +298,7 @@ cleanup:
* NULL.
*/
static int
-reload_profile(virSecurityDriverPtr drv,
+reload_profile(virSecurityManagerPtr mgr,
virDomainObjPtr vm,
const char *fn,
bool append)
@@ -317,7 +315,7 @@ reload_profile(virSecurityDriverPtr drv,
/* Update the profile only if it is loaded */
if (profile_loaded(secdef->imagelabel) >= 0) {
- if (load_profile(drv, secdef->imagelabel, vm, fn, append) < 0) {
+ if (load_profile(mgr, secdef->imagelabel, vm, fn, append) < 0) {
virSecurityReportError(VIR_ERR_INTERNAL_ERROR,
_("cannot update AppArmor profile "
"\'%s\'"),
@@ -340,7 +338,7 @@ AppArmorSetSecurityUSBLabel(usbDevice *dev ATTRIBUTE_UNUSED,
struct SDPDOP *ptr = opaque;
virDomainObjPtr vm = ptr->vm;
- if (reload_profile(ptr->drv, vm, file, true) < 0) {
+ if (reload_profile(ptr->mgr, vm, file, true) < 0) {
const virSecurityLabelDefPtr secdef = &vm->def->seclabel;
virSecurityReportError(VIR_ERR_INTERNAL_ERROR,
_("cannot update AppArmor profile "
@@ -358,7 +356,7 @@ AppArmorSetSecurityPCILabel(pciDevice *dev ATTRIBUTE_UNUSED,
struct SDPDOP *ptr = opaque;
virDomainObjPtr vm = ptr->vm;
- if (reload_profile(ptr->drv, vm, file, true) < 0) {
+ if (reload_profile(ptr->mgr, vm, file, true) < 0) {
const virSecurityLabelDefPtr secdef = &vm->def->seclabel;
virSecurityReportError(VIR_ERR_INTERNAL_ERROR,
_("cannot update AppArmor profile "
@@ -371,7 +369,7 @@ AppArmorSetSecurityPCILabel(pciDevice *dev ATTRIBUTE_UNUSED,
/* Called on libvirtd startup to see if AppArmor is available */
static int
-AppArmorSecurityDriverProbe(void)
+AppArmorSecurityManagerProbe(void)
{
char *template = NULL;
int rc = SECURITY_DRIVER_DISABLE;
@@ -403,21 +401,37 @@ AppArmorSecurityDriverProbe(void)
* currently not used.
*/
static int
-AppArmorSecurityDriverOpen(virSecurityDriverPtr drv,
- bool allowDiskFormatProbing)
+AppArmorSecurityManagerOpen(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+static int
+AppArmorSecurityManagerClose(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED)
{
- virSecurityDriverSetDOI(drv, SECURITY_APPARMOR_VOID_DOI);
- virSecurityDriverSetAllowDiskFormatProbing(drv, allowDiskFormatProbing);
return 0;
}
+static const char *
+AppArmorSecurityManagerGetModel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED)
+{
+ return SECURITY_APPARMOR_NAME;
+}
+
+static const char *
+AppArmorSecurityManagerGetDOI(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED)
+{
+ return SECURITY_APPARMOR_VOID_DOI;
+}
+
+
/* Currently called in qemudStartVMDaemon to setup a 'label'. We look for and
* use a profile based on the UUID, otherwise create one based on a template.
* Keep in mind that this is called on 'start' with RestoreSecurityLabel being
* called on shutdown.
*/
static int
-AppArmorGenSecurityLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
+AppArmorGenSecurityLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
virDomainObjPtr vm)
{
int rc = -1;
@@ -472,7 +486,7 @@ AppArmorGenSecurityLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
}
static int
-AppArmorSetSecurityAllLabel(virSecurityDriverPtr drv,
+AppArmorSetSecurityAllLabel(virSecurityManagerPtr mgr,
virDomainObjPtr vm, const char *stdin_path)
{
if (vm->def->seclabel.type == VIR_DOMAIN_SECLABEL_STATIC)
@@ -480,7 +494,7 @@ AppArmorSetSecurityAllLabel(virSecurityDriverPtr drv,
/* if the profile is not already loaded, then load one */
if (profile_loaded(vm->def->seclabel.label) < 0) {
- if (load_profile(drv, vm->def->seclabel.label, vm, stdin_path,
+ if (load_profile(mgr, vm->def->seclabel.label, vm, stdin_path,
false) < 0) {
virSecurityReportError(VIR_ERR_INTERNAL_ERROR,
_("cannot generate AppArmor profile "
@@ -496,7 +510,7 @@ AppArmorSetSecurityAllLabel(virSecurityDriverPtr drv,
* running.
*/
static int
-AppArmorGetSecurityProcessLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
+AppArmorGetSecurityProcessLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
virDomainObjPtr vm,
virSecurityLabelPtr sec)
{
@@ -530,7 +544,7 @@ AppArmorGetSecurityProcessLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
* more details. Currently called via qemudShutdownVMDaemon.
*/
static int
-AppArmorReleaseSecurityLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
+AppArmorReleaseSecurityLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
virDomainObjPtr vm)
{
const virSecurityLabelDefPtr secdef = &vm->def->seclabel;
@@ -544,7 +558,7 @@ AppArmorReleaseSecurityLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
static int
-AppArmorRestoreSecurityAllLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
+AppArmorRestoreSecurityAllLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
virDomainObjPtr vm,
int migrated ATTRIBUTE_UNUSED)
{
@@ -565,7 +579,7 @@ AppArmorRestoreSecurityAllLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
* LOCALSTATEDIR/log/libvirt/qemu/<vm name>.log
*/
static int
-AppArmorSetSecurityProcessLabel(virSecurityDriverPtr drv, virDomainObjPtr vm)
+AppArmorSetSecurityProcessLabel(virSecurityManagerPtr mgr, virDomainObjPtr vm)
{
const virSecurityLabelDefPtr secdef = &vm->def->seclabel;
int rc = -1;
@@ -574,12 +588,12 @@ AppArmorSetSecurityProcessLabel(virSecurityDriverPtr drv, virDomainObjPtr vm)
if ((profile_name = get_profile_name(vm)) == NULL)
return rc;
- if (STRNEQ(drv->name, secdef->model)) {
+ if (STRNEQ(virSecurityManagerGetModel(mgr), secdef->model)) {
virSecurityReportError(VIR_ERR_INTERNAL_ERROR,
_("security label driver mismatch: "
"\'%s\' model configured for domain, but "
"hypervisor driver is \'%s\'."),
- secdef->model, drv->name);
+ secdef->model, virSecurityManagerGetModel(mgr));
if (use_apparmor() > 0)
goto clean;
}
@@ -597,19 +611,33 @@ AppArmorSetSecurityProcessLabel(virSecurityDriverPtr drv, virDomainObjPtr vm)
return rc;
}
+static int
+AppArmorSetSecuritySocketLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
+ virDomainObjPtr vm ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+static int
+AppArmorClearSecuritySocketLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
+ virDomainObjPtr vm ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
/* Called when hotplugging */
static int
-AppArmorRestoreSecurityImageLabel(virSecurityDriverPtr drv,
+AppArmorRestoreSecurityImageLabel(virSecurityManagerPtr mgr,
virDomainObjPtr vm,
virDomainDiskDefPtr disk ATTRIBUTE_UNUSED)
{
- return reload_profile(drv, vm, NULL, false);
+ return reload_profile(mgr, vm, NULL, false);
}
/* Called when hotplugging */
static int
-AppArmorSetSecurityImageLabel(virSecurityDriverPtr drv,
+AppArmorSetSecurityImageLabel(virSecurityManagerPtr mgr,
virDomainObjPtr vm, virDomainDiskDefPtr disk)
{
const virSecurityLabelDefPtr secdef = &vm->def->seclabel;
@@ -635,7 +663,7 @@ AppArmorSetSecurityImageLabel(virSecurityDriverPtr drv,
/* update the profile only if it is loaded */
if (profile_loaded(secdef->imagelabel) >= 0) {
- if (load_profile(drv, secdef->imagelabel, vm, disk->src,
+ if (load_profile(mgr, secdef->imagelabel, vm, disk->src,
false) < 0) {
virSecurityReportError(VIR_ERR_INTERNAL_ERROR,
_("cannot update AppArmor profile "
@@ -654,7 +682,8 @@ AppArmorSetSecurityImageLabel(virSecurityDriverPtr drv,
}
static int
-AppArmorSecurityVerify(virDomainDefPtr def)
+AppArmorSecurityVerify(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
+ virDomainDefPtr def)
{
const virSecurityLabelDefPtr secdef = &def->seclabel;
@@ -670,7 +699,7 @@ AppArmorSecurityVerify(virDomainDefPtr def)
}
static int
-AppArmorReserveSecurityLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
+AppArmorReserveSecurityLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
virDomainObjPtr vm ATTRIBUTE_UNUSED)
{
/* NOOP. Nothing to reserve with AppArmor */
@@ -678,7 +707,7 @@ AppArmorReserveSecurityLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
}
static int
-AppArmorSetSecurityHostdevLabel(virSecurityDriverPtr drv,
+AppArmorSetSecurityHostdevLabel(virSecurityManagerPtr mgr,
virDomainObjPtr vm,
virDomainHostdevDefPtr dev)
@@ -698,7 +727,7 @@ AppArmorSetSecurityHostdevLabel(virSecurityDriverPtr drv,
if (VIR_ALLOC(ptr) < 0)
return -1;
- ptr->drv = drv;
+ ptr->mgr = mgr;
ptr->vm = vm;
switch (dev->source.subsys.type) {
@@ -740,7 +769,7 @@ done:
static int
-AppArmorRestoreSecurityHostdevLabel(virSecurityDriverPtr drv,
+AppArmorRestoreSecurityHostdevLabel(virSecurityManagerPtr mgr,
virDomainObjPtr vm,
virDomainHostdevDefPtr dev ATTRIBUTE_UNUSED)
@@ -749,42 +778,57 @@ AppArmorRestoreSecurityHostdevLabel(virSecurityDriverPtr drv,
if (secdef->type == VIR_DOMAIN_SECLABEL_STATIC)
return 0;
- return reload_profile(drv, vm, NULL, false);
+ return reload_profile(mgr, vm, NULL, false);
}
static int
-AppArmorSetSavedStateLabel(virSecurityDriverPtr drv,
+AppArmorSetSavedStateLabel(virSecurityManagerPtr mgr,
virDomainObjPtr vm,
const char *savefile)
{
- return reload_profile(drv, vm, savefile, true);
+ return reload_profile(mgr, vm, savefile, true);
}
static int
-AppArmorRestoreSavedStateLabel(virSecurityDriverPtr drv,
+AppArmorRestoreSavedStateLabel(virSecurityManagerPtr mgr,
virDomainObjPtr vm,
const char *savefile ATTRIBUTE_UNUSED)
{
- return reload_profile(drv, vm, NULL, false);
+ return reload_profile(mgr, vm, NULL, false);
}
virSecurityDriver virAppArmorSecurityDriver = {
- .name = SECURITY_APPARMOR_NAME,
- .probe = AppArmorSecurityDriverProbe,
- .open = AppArmorSecurityDriverOpen,
- .domainSecurityVerify = AppArmorSecurityVerify,
- .domainSetSecurityImageLabel = AppArmorSetSecurityImageLabel,
- .domainRestoreSecurityImageLabel = AppArmorRestoreSecurityImageLabel,
- .domainGenSecurityLabel = AppArmorGenSecurityLabel,
- .domainReserveSecurityLabel = AppArmorReserveSecurityLabel,
- .domainReleaseSecurityLabel = AppArmorReleaseSecurityLabel,
- .domainGetSecurityProcessLabel = AppArmorGetSecurityProcessLabel,
- .domainSetSecurityProcessLabel = AppArmorSetSecurityProcessLabel,
- .domainRestoreSecurityAllLabel = AppArmorRestoreSecurityAllLabel,
- .domainSetSecurityAllLabel = AppArmorSetSecurityAllLabel,
- .domainSetSecurityHostdevLabel = AppArmorSetSecurityHostdevLabel,
- .domainRestoreSecurityHostdevLabel = AppArmorRestoreSecurityHostdevLabel,
- .domainSetSavedStateLabel = AppArmorSetSavedStateLabel,
- .domainRestoreSavedStateLabel = AppArmorRestoreSavedStateLabel,
+ 0,
+ SECURITY_APPARMOR_NAME,
+ AppArmorSecurityManagerProbe,
+ AppArmorSecurityManagerOpen,
+ AppArmorSecurityManagerClose,
+
+ AppArmorSecurityManagerGetModel,
+ AppArmorSecurityManagerGetDOI,
+
+ AppArmorSecurityVerify,
+
+ AppArmorSetSecurityImageLabel,
+ AppArmorRestoreSecurityImageLabel,
+
+ AppArmorSetSecuritySocketLabel,
+ AppArmorClearSecuritySocketLabel,
+
+ AppArmorGenSecurityLabel,
+ AppArmorReserveSecurityLabel,
+ AppArmorReleaseSecurityLabel,
+
+ AppArmorGetSecurityProcessLabel,
+ AppArmorSetSecurityProcessLabel,
+
+ AppArmorSetSecurityAllLabel,
+ AppArmorRestoreSecurityAllLabel,
+
+ AppArmorSetSecurityHostdevLabel,
+ AppArmorRestoreSecurityHostdevLabel,
+
+ AppArmorSetSavedStateLabel,
+ AppArmorRestoreSavedStateLabel,
};
diff --git a/src/security/security_apparmor.h b/src/security/security_apparmor.h
index eb7e140..ffd8288 100644
--- a/src/security/security_apparmor.h
+++ b/src/security/security_apparmor.h
@@ -14,6 +14,8 @@
#ifndef __VIR_SECURITY_APPARMOR_H__
# define __VIR_SECURITY_APPARMOR_H__
+# include "security_driver.h"
+
extern virSecurityDriver virAppArmorSecurityDriver;
# define AA_PREFIX "libvirt-"
diff --git a/src/security/security_dac.c b/src/security/security_dac.c
new file mode 100644
index 0000000..de5d011
--- /dev/null
+++ b/src/security/security_dac.c
@@ -0,0 +1,713 @@
+/*
+ * Copyright (C) 2010-2011 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.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * POSIX DAC security driver
+ */
+
+#include <config.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include "security_dac.h"
+#include "virterror_internal.h"
+#include "util.h"
+#include "memory.h"
+#include "logging.h"
+#include "pci.h"
+#include "hostusb.h"
+#include "storage_file.h"
+
+#define VIR_FROM_THIS VIR_FROM_SECURITY
+
+typedef struct _virSecurityDACData virSecurityDACData;
+typedef virSecurityDACData *virSecurityDACDataPtr;
+
+struct _virSecurityDACData {
+ uid_t user;
+ gid_t group;
+ bool dynamicOwnership;
+};
+
+void virSecurityDACSetUser(virSecurityManagerPtr mgr,
+ uid_t user)
+{
+ virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+ priv->user = user;
+}
+
+void virSecurityDACSetGroup(virSecurityManagerPtr mgr,
+ gid_t group)
+{
+ virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+ priv->group = group;
+}
+
+void virSecurityDACSetDynamicOwnership(virSecurityManagerPtr mgr,
+ bool dynamicOwnership)
+{
+ virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+ priv->dynamicOwnership = dynamicOwnership;
+}
+
+static virSecurityDriverStatus
+virSecurityDACProbe(void)
+{
+ return SECURITY_DRIVER_ENABLE;
+}
+
+static int
+virSecurityDACOpen(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+static int
+virSecurityDACClose(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+
+static const char * virSecurityDACGetModel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED)
+{
+ return "dac";
+}
+
+static const char * virSecurityDACGetDOI(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED)
+{
+ return "0";
+}
+
+static int
+virSecurityDACSetOwnership(const char *path, int uid, int gid)
+{
+ VIR_INFO("Setting DAC user and group on '%s' to '%d:%d'", path, uid, gid);
+
+ if (chown(path, uid, gid) < 0) {
+ struct stat sb;
+ int chown_errno = errno;
+
+ if (stat(path, &sb) >= 0) {
+ if (sb.st_uid == uid &&
+ sb.st_gid == gid) {
+ /* It's alright, there's nothing to change anyway. */
+ return 0;
+ }
+ }
+
+ if (chown_errno == EOPNOTSUPP) {
+ VIR_INFO("Setting user and group to '%d:%d' on '%s' not supported by filesystem",
+ uid, gid, path);
+ } else if (chown_errno == EPERM) {
+ VIR_INFO("Setting user and group to '%d:%d' on '%s' not permitted",
+ uid, gid, path);
+ } else if (chown_errno == EROFS) {
+ VIR_INFO("Setting user and group to '%d:%d' on '%s' not possible on readonly filesystem",
+ uid, gid, path);
+ } else {
+ virReportSystemError(chown_errno,
+ _("unable to set user and group to '%d:%d' on '%s'"),
+ uid, gid, path);
+ return -1;
+ }
+ }
+ return 0;
+}
+
+static int
+virSecurityDACRestoreSecurityFileLabel(const char *path)
+{
+ struct stat buf;
+ int rc = -1;
+ char *newpath = NULL;
+
+ VIR_INFO("Restoring DAC user and group on '%s'", path);
+
+ if (virFileResolveLink(path, &newpath) < 0) {
+ virReportSystemError(errno,
+ _("cannot resolve symlink %s"), path);
+ goto err;
+ }
+
+ if (stat(newpath, &buf) != 0)
+ goto err;
+
+ /* XXX record previous ownership */
+ rc = virSecurityDACSetOwnership(newpath, 0, 0);
+
+err:
+ VIR_FREE(newpath);
+ return rc;
+}
+
+
+static int
+virSecurityDACSetSecurityFileLabel(virDomainDiskDefPtr disk ATTRIBUTE_UNUSED,
+ const char *path,
+ size_t depth ATTRIBUTE_UNUSED,
+ void *opaque)
+{
+ virSecurityManagerPtr mgr = opaque;
+ virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+
+ return virSecurityDACSetOwnership(path, priv->user, priv->group);
+}
+
+
+static int
+virSecurityDACSetSecurityImageLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm ATTRIBUTE_UNUSED,
+ virDomainDiskDefPtr disk)
+
+{
+ virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+
+ if (!priv->dynamicOwnership)
+ return 0;
+
+ return virDomainDiskDefForeachPath(disk,
+ virSecurityManagerGetAllowDiskFormatProbing(mgr),
+ false,
+ virSecurityDACSetSecurityFileLabel,
+ mgr);
+}
+
+
+static int
+virSecurityDACRestoreSecurityImageLabelInt(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm ATTRIBUTE_UNUSED,
+ virDomainDiskDefPtr disk,
+ int migrated)
+{
+ virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+
+ if (!priv->dynamicOwnership)
+ return 0;
+
+ /* Don't restore labels on readoly/shared disks, because
+ * other VMs may still be accessing these
+ * Alternatively we could iterate over all running
+ * domains and try to figure out if it is in use, but
+ * this would not work for clustered filesystems, since
+ * we can't see running VMs using the file on other nodes
+ * Safest bet is thus to skip the restore step.
+ */
+ if (disk->readonly || disk->shared)
+ return 0;
+
+ if (!disk->src)
+ return 0;
+
+ /* If we have a shared FS & doing migrated, we must not
+ * change ownership, because that kills access on the
+ * destination host which is sub-optimal for the guest
+ * VM's I/O attempts :-)
+ */
+ if (migrated) {
+ int rc = virStorageFileIsSharedFS(disk->src);
+ if (rc < 0)
+ return -1;
+ if (rc == 1) {
+ VIR_DEBUG("Skipping image label restore on %s because FS is shared",
+ disk->src);
+ return 0;
+ }
+ }
+
+ return virSecurityDACRestoreSecurityFileLabel(disk->src);
+}
+
+
+static int
+virSecurityDACRestoreSecurityImageLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm,
+ virDomainDiskDefPtr disk)
+{
+ return virSecurityDACRestoreSecurityImageLabelInt(mgr, vm, disk, 0);
+}
+
+
+static int
+virSecurityDACSetSecurityPCILabel(pciDevice *dev ATTRIBUTE_UNUSED,
+ const char *file,
+ void *opaque)
+{
+ virSecurityManagerPtr mgr = opaque;
+ virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+
+ return virSecurityDACSetOwnership(file, priv->user, priv->group);
+}
+
+
+static int
+virSecurityDACSetSecurityUSBLabel(usbDevice *dev ATTRIBUTE_UNUSED,
+ const char *file,
+ void *opaque)
+{
+ virSecurityManagerPtr mgr = opaque;
+ virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+
+ return virSecurityDACSetOwnership(file, priv->user, priv->group);
+}
+
+
+static int
+virSecurityDACSetSecurityHostdevLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm ATTRIBUTE_UNUSED,
+ virDomainHostdevDefPtr dev)
+{
+ virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+ int ret = -1;
+
+ if (!priv->dynamicOwnership)
+ return 0;
+
+ if (dev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS)
+ return 0;
+
+ switch (dev->source.subsys.type) {
+ case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB: {
+ usbDevice *usb = usbGetDevice(dev->source.subsys.u.usb.bus,
+ dev->source.subsys.u.usb.device);
+
+ if (!usb)
+ goto done;
+
+ ret = usbDeviceFileIterate(usb, virSecurityDACSetSecurityUSBLabel, mgr);
+ usbFreeDevice(usb);
+ break;
+ }
+
+ case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI: {
+ pciDevice *pci = pciGetDevice(dev->source.subsys.u.pci.domain,
+ dev->source.subsys.u.pci.bus,
+ dev->source.subsys.u.pci.slot,
+ dev->source.subsys.u.pci.function);
+
+ if (!pci)
+ goto done;
+
+ ret = pciDeviceFileIterate(pci, virSecurityDACSetSecurityPCILabel, mgr);
+ pciFreeDevice(pci);
+
+ break;
+ }
+
+ default:
+ ret = 0;
+ break;
+ }
+
+done:
+ return ret;
+}
+
+
+static int
+virSecurityDACRestoreSecurityPCILabel(pciDevice *dev ATTRIBUTE_UNUSED,
+ const char *file,
+ void *opaque ATTRIBUTE_UNUSED)
+{
+ return virSecurityDACRestoreSecurityFileLabel(file);
+}
+
+
+static int
+virSecurityDACRestoreSecurityUSBLabel(usbDevice *dev ATTRIBUTE_UNUSED,
+ const char *file,
+ void *opaque ATTRIBUTE_UNUSED)
+{
+ return virSecurityDACRestoreSecurityFileLabel(file);
+}
+
+
+static int
+virSecurityDACRestoreSecurityHostdevLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm ATTRIBUTE_UNUSED,
+ virDomainHostdevDefPtr dev)
+
+{
+ virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+ int ret = -1;
+
+ if (!priv->dynamicOwnership)
+ return 0;
+
+ if (dev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS)
+ return 0;
+
+ switch (dev->source.subsys.type) {
+ case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB: {
+ usbDevice *usb = usbGetDevice(dev->source.subsys.u.usb.bus,
+ dev->source.subsys.u.usb.device);
+
+ if (!usb)
+ goto done;
+
+ ret = usbDeviceFileIterate(usb, virSecurityDACRestoreSecurityUSBLabel, mgr);
+ usbFreeDevice(usb);
+
+ break;
+ }
+
+ case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI: {
+ pciDevice *pci = pciGetDevice(dev->source.subsys.u.pci.domain,
+ dev->source.subsys.u.pci.bus,
+ dev->source.subsys.u.pci.slot,
+ dev->source.subsys.u.pci.function);
+
+ if (!pci)
+ goto done;
+
+ ret = pciDeviceFileIterate(pci, virSecurityDACRestoreSecurityPCILabel, mgr);
+ pciFreeDevice(pci);
+
+ break;
+ }
+
+ default:
+ ret = 0;
+ break;
+ }
+
+done:
+ return ret;
+}
+
+
+static int
+virSecurityDACSetChardevLabel(virSecurityManagerPtr mgr,
+ virDomainChrDefPtr dev)
+
+{
+ virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+ char *in = NULL, *out = NULL;
+ int ret = -1;
+
+ switch (dev->type) {
+ case VIR_DOMAIN_CHR_TYPE_DEV:
+ case VIR_DOMAIN_CHR_TYPE_FILE:
+ ret = virSecurityDACSetOwnership(dev->data.file.path, priv->user, priv->group);
+ break;
+
+ case VIR_DOMAIN_CHR_TYPE_PIPE:
+ if ((virAsprintf(&in, "%s.in", dev->data.file.path) < 0) ||
+ (virAsprintf(&out, "%s.out", dev->data.file.path) < 0)) {
+ virReportOOMError();
+ goto done;
+ }
+ if ((virSecurityDACSetOwnership(in, priv->user, priv->group) < 0) ||
+ (virSecurityDACSetOwnership(out, priv->user, priv->group) < 0))
+ goto done;
+ ret = 0;
+ break;
+
+ default:
+ ret = 0;
+ break;
+ }
+
+done:
+ VIR_FREE(in);
+ VIR_FREE(out);
+ return ret;
+}
+
+static int
+virSecurityDACRestoreChardevLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
+ virDomainChrDefPtr dev)
+{
+ char *in = NULL, *out = NULL;
+ int ret = -1;
+
+ switch (dev->type) {
+ case VIR_DOMAIN_CHR_TYPE_DEV:
+ case VIR_DOMAIN_CHR_TYPE_FILE:
+ ret = virSecurityDACRestoreSecurityFileLabel(dev->data.file.path);
+ break;
+
+ case VIR_DOMAIN_CHR_TYPE_PIPE:
+ if ((virAsprintf(&out, "%s.out", dev->data.file.path) < 0) ||
+ (virAsprintf(&in, "%s.in", dev->data.file.path) < 0)) {
+ virReportOOMError();
+ goto done;
+ }
+ if ((virSecurityDACRestoreSecurityFileLabel(out) < 0) ||
+ (virSecurityDACRestoreSecurityFileLabel(in) < 0))
+ goto done;
+ ret = 0;
+ break;
+
+ default:
+ ret = 0;
+ break;
+ }
+
+done:
+ VIR_FREE(in);
+ VIR_FREE(out);
+ return ret;
+}
+
+
+static int
+virSecurityDACRestoreChardevCallback(virDomainDefPtr def ATTRIBUTE_UNUSED,
+ virDomainChrDefPtr dev,
+ void *opaque)
+{
+ virSecurityManagerPtr mgr = opaque;
+
+ return virSecurityDACRestoreChardevLabel(mgr, dev);
+}
+
+
+static int
+virSecurityDACRestoreSecurityAllLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm,
+ int migrated)
+{
+ virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+ int i;
+ int rc = 0;
+
+ if (!priv->dynamicOwnership)
+ return 0;
+
+
+ VIR_DEBUG("Restoring security label on %s migrated=%d",
+ vm->def->name, migrated);
+
+ for (i = 0 ; i < vm->def->nhostdevs ; i++) {
+ if (virSecurityDACRestoreSecurityHostdevLabel(mgr,
+ vm,
+ vm->def->hostdevs[i]) < 0)
+ rc = -1;
+ }
+ for (i = 0 ; i < vm->def->ndisks ; i++) {
+ if (virSecurityDACRestoreSecurityImageLabelInt(mgr,
+ vm,
+ vm->def->disks[i],
+ migrated) < 0)
+ rc = -1;
+ }
+
+ if (virDomainChrDefForeach(vm->def,
+ false,
+ virSecurityDACRestoreChardevCallback,
+ vm) < 0)
+ rc = -1;
+
+ if (vm->def->os.kernel &&
+ virSecurityDACRestoreSecurityFileLabel(vm->def->os.kernel) < 0)
+ rc = -1;
+
+ if (vm->def->os.initrd &&
+ virSecurityDACRestoreSecurityFileLabel(vm->def->os.initrd) < 0)
+ rc = -1;
+
+ return rc;
+}
+
+
+static int
+virSecurityDACSetChardevCallback(virDomainDefPtr def ATTRIBUTE_UNUSED,
+ virDomainChrDefPtr dev,
+ void *opaque)
+{
+ virSecurityManagerPtr mgr = opaque;
+
+ return virSecurityDACSetChardevLabel(mgr, dev);
+}
+
+
+static int
+virSecurityDACSetSecurityAllLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm,
+ const char *stdin_path ATTRIBUTE_UNUSED)
+{
+ virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+ int i;
+
+ if (!priv->dynamicOwnership)
+ return 0;
+
+ for (i = 0 ; i < vm->def->ndisks ; i++) {
+ /* XXX fixme - we need to recursively label the entire tree :-( */
+ if (vm->def->disks[i]->type == VIR_DOMAIN_DISK_TYPE_DIR)
+ continue;
+ if (virSecurityDACSetSecurityImageLabel(mgr,
+ vm,
+ vm->def->disks[i]) < 0)
+ return -1;
+ }
+ for (i = 0 ; i < vm->def->nhostdevs ; i++) {
+ if (virSecurityDACSetSecurityHostdevLabel(mgr,
+ vm,
+ vm->def->hostdevs[i]) < 0)
+ return -1;
+ }
+
+ if (virDomainChrDefForeach(vm->def,
+ true,
+ virSecurityDACSetChardevCallback,
+ vm) < 0)
+ return -1;
+
+ if (vm->def->os.kernel &&
+ virSecurityDACSetOwnership(vm->def->os.kernel,
+ priv->user,
+ priv->group) < 0)
+ return -1;
+
+ if (vm->def->os.initrd &&
+ virSecurityDACSetOwnership(vm->def->os.initrd,
+ priv->user,
+ priv->group) < 0)
+ return -1;
+
+ return 0;
+}
+
+
+static int
+virSecurityDACSetSavedStateLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm ATTRIBUTE_UNUSED,
+ const char *savefile)
+{
+ virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+
+ return virSecurityDACSetOwnership(savefile, priv->user, priv->group);
+}
+
+
+static int
+virSecurityDACRestoreSavedStateLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm ATTRIBUTE_UNUSED,
+ const char *savefile)
+{
+ virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+
+ if (!priv->dynamicOwnership)
+ return 0;
+
+ return virSecurityDACRestoreSecurityFileLabel(savefile);
+}
+
+
+static int
+virSecurityDACSetProcessLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm ATTRIBUTE_UNUSED)
+{
+ virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+
+ DEBUG("Dropping privileges of VM to %d:%d", priv->user, priv->group);
+
+ if (virSetUIDGID(priv->user, priv->group) < 0)
+ return -1;
+
+ return 0;
+}
+
+
+static int
+virSecurityDACVerify(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
+ virDomainDefPtr def ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+static int
+virSecurityDACGenLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
+ virDomainObjPtr vm ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+static int
+virSecurityDACReleaseLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
+ virDomainObjPtr vm ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+static int
+virSecurityDACReserveLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
+ virDomainObjPtr vm ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+static int
+virSecurityDACGetProcessLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
+ virDomainObjPtr vm ATTRIBUTE_UNUSED,
+ virSecurityLabelPtr seclabel ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+static int
+virSecurityDACSetSocketLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
+ virDomainObjPtr vm ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+
+static int
+virSecurityDACClearSocketLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
+ virDomainObjPtr vm ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+
+virSecurityDriver virSecurityDriverDAC = {
+ sizeof(virSecurityDACData),
+ "virDAC",
+
+ virSecurityDACProbe,
+ virSecurityDACOpen,
+ virSecurityDACClose,
+
+ virSecurityDACGetModel,
+ virSecurityDACGetDOI,
+
+ virSecurityDACVerify,
+
+ virSecurityDACSetSecurityImageLabel,
+ virSecurityDACRestoreSecurityImageLabel,
+
+ virSecurityDACSetSocketLabel,
+ virSecurityDACClearSocketLabel,
+
+ virSecurityDACGenLabel,
+ virSecurityDACReserveLabel,
+ virSecurityDACReleaseLabel,
+
+ virSecurityDACGetProcessLabel,
+ virSecurityDACSetProcessLabel,
+
+ virSecurityDACSetSecurityAllLabel,
+ virSecurityDACRestoreSecurityAllLabel,
+
+ virSecurityDACSetSecurityHostdevLabel,
+ virSecurityDACRestoreSecurityHostdevLabel,
+
+ virSecurityDACSetSavedStateLabel,
+ virSecurityDACRestoreSavedStateLabel,
+};
diff --git a/src/security/security_dac.h b/src/security/security_dac.h
new file mode 100644
index 0000000..ccd9d1c
--- /dev/null
+++ b/src/security/security_dac.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2010-2011 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.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * POSIX DAC security driver
+ */
+
+#include "security_driver.h"
+
+#ifndef __VIR_SECURITY_DAC
+# define __VIR_SECURITY_DAC
+
+extern virSecurityDriver virSecurityDriverDAC;
+
+void virSecurityDACSetUser(virSecurityManagerPtr mgr,
+ uid_t user);
+void virSecurityDACSetGroup(virSecurityManagerPtr mgr,
+ gid_t group);
+
+void virSecurityDACSetDynamicOwnership(virSecurityManagerPtr mgr,
+ bool dynamic);
+
+#endif /* __VIR_SECURITY_DAC */
diff --git a/src/security/security_driver.c b/src/security/security_driver.c
index 9e32fa4..4df73d7 100644
--- a/src/security/security_driver.c
+++ b/src/security/security_driver.c
@@ -14,6 +14,7 @@
#include <string.h>
#include "virterror_internal.h"
+#include "logging.h"
#include "security_driver.h"
#ifdef WITH_SECDRIVER_SELINUX
@@ -24,116 +25,56 @@
# include "security_apparmor.h"
#endif
+#include "security_nop.h"
+
static virSecurityDriverPtr security_drivers[] = {
#ifdef WITH_SECDRIVER_SELINUX
- &virSELinuxSecurityDriver,
+ &virSecurityDriverSELinux,
#endif
#ifdef WITH_SECDRIVER_APPARMOR
&virAppArmorSecurityDriver,
#endif
- NULL
+ &virSecurityDriverNop, /* Must always be last, since it will always probe */
};
-int
-virSecurityDriverVerify(virDomainDefPtr def)
-{
- unsigned int i;
- const virSecurityLabelDefPtr secdef = &def->seclabel;
-
- if (!secdef->model ||
- STREQ(secdef->model, "none"))
- return 0;
-
- for (i = 0; security_drivers[i] != NULL ; i++) {
- if (STREQ(security_drivers[i]->name, secdef->model)) {
- return security_drivers[i]->domainSecurityVerify(def);
- }
- }
- virSecurityReportError(VIR_ERR_XML_ERROR,
- _("invalid security model '%s'"), secdef->model);
- return -1;
-}
-
-int
-virSecurityDriverStartup(virSecurityDriverPtr *drv,
- const char *name,
- bool allowDiskFormatProbing)
+virSecurityDriverPtr virSecurityDriverLookup(const char *name)
{
- unsigned int i;
+ virSecurityDriverPtr drv = NULL;
+ int i;
- if (name && STREQ(name, "none"))
- return -2;
+ VIR_DEBUG("name=%s", NULLSTR(name));
- for (i = 0; security_drivers[i] != NULL ; i++) {
+ for (i = 0; i < ARRAY_CARDINALITY(security_drivers) && !drv ; i++) {
virSecurityDriverPtr tmp = security_drivers[i];
- if (name && STRNEQ(tmp->name, name))
- continue;
-
- switch (tmp->probe()) {
- case SECURITY_DRIVER_ENABLE:
- virSecurityDriverInit(tmp);
- if (tmp->open(tmp, allowDiskFormatProbing) == -1) {
- return -1;
- } else {
- *drv = tmp;
- return 0;
+ if (name) {
+ if (STREQ(tmp->name, name)) {
+ drv = tmp;
+ break;
+ }
+ } else {
+ switch (tmp->probe()) {
+ case SECURITY_DRIVER_ENABLE:
+ VIR_DEBUG("Probed name=%s", tmp->name);
+ drv = tmp;
+ break;
+
+ case SECURITY_DRIVER_DISABLE:
+ VIR_DEBUG("Not enabled name=%s", tmp->name);
+ break;
+
+ default:
+ return NULL;
}
- break;
-
- case SECURITY_DRIVER_DISABLE:
- break;
-
- default:
- return -1;
}
}
- return -2;
-}
-
-/*
- * Helpers
- */
-void
-virSecurityDriverInit(virSecurityDriverPtr drv)
-{
- memset(&drv->_private, 0, sizeof drv->_private);
-}
-int
-virSecurityDriverSetDOI(virSecurityDriverPtr drv,
- const char *doi)
-{
- if (strlen(doi) >= VIR_SECURITY_DOI_BUFLEN) {
+ if (!drv) {
virSecurityReportError(VIR_ERR_INTERNAL_ERROR,
- _("%s: DOI \'%s\' is "
- "longer than the maximum allowed length of %d"),
- __func__, doi, VIR_SECURITY_DOI_BUFLEN - 1);
- return -1;
+ _("Security driver %s not found"),
+ NULLSTR(name));
+ return NULL;
}
- strcpy(drv->_private.doi, doi);
- return 0;
-}
-
-const char *
-virSecurityDriverGetDOI(virSecurityDriverPtr drv)
-{
- return drv->_private.doi;
-}
-const char *
-virSecurityDriverGetModel(virSecurityDriverPtr drv)
-{
- return drv->name;
-}
-
-void virSecurityDriverSetAllowDiskFormatProbing(virSecurityDriverPtr drv,
- bool allowDiskFormatProbing)
-{
- drv->_private.allowDiskFormatProbing = allowDiskFormatProbing;
-}
-
-bool virSecurityDriverGetAllowDiskFormatProbing(virSecurityDriverPtr drv)
-{
- return drv->_private.allowDiskFormatProbing;
+ return drv;
}
diff --git a/src/security/security_driver.h b/src/security/security_driver.h
index d768f32..e5a8d41 100644
--- a/src/security/security_driver.h
+++ b/src/security/security_driver.h
@@ -16,6 +16,8 @@
# include "internal.h"
# include "domain_conf.h"
+# include "security_manager.h"
+
/*
* Return values for security driver probing: the driver will determine
* whether it should be enabled or disabled.
@@ -29,104 +31,91 @@ typedef enum {
typedef struct _virSecurityDriver virSecurityDriver;
typedef virSecurityDriver *virSecurityDriverPtr;
-typedef struct _virSecurityDriverState virSecurityDriverState;
-typedef virSecurityDriverState *virSecurityDriverStatePtr;
-
typedef virSecurityDriverStatus (*virSecurityDriverProbe) (void);
-typedef int (*virSecurityDriverOpen) (virSecurityDriverPtr drv,
- bool allowDiskFormatProbing);
-typedef int (*virSecurityDomainRestoreImageLabel) (virSecurityDriverPtr drv,
+typedef int (*virSecurityDriverOpen) (virSecurityManagerPtr mgr);
+typedef int (*virSecurityDriverClose) (virSecurityManagerPtr mgr);
+
+typedef const char *(*virSecurityDriverGetModel) (virSecurityManagerPtr mgr);
+typedef const char *(*virSecurityDriverGetDOI) (virSecurityManagerPtr mgr);
+
+typedef int (*virSecurityDomainRestoreImageLabel) (virSecurityManagerPtr mgr,
virDomainObjPtr vm,
virDomainDiskDefPtr disk);
-typedef int (*virSecurityDomainSetSocketLabel) (virSecurityDriverPtr drv,
+typedef int (*virSecurityDomainSetSocketLabel) (virSecurityManagerPtr mgr,
virDomainObjPtr vm);
-typedef int (*virSecurityDomainClearSocketLabel)(virSecurityDriverPtr drv,
+typedef int (*virSecurityDomainClearSocketLabel)(virSecurityManagerPtr mgr,
virDomainObjPtr vm);
-typedef int (*virSecurityDomainSetImageLabel) (virSecurityDriverPtr drv,
+typedef int (*virSecurityDomainSetImageLabel) (virSecurityManagerPtr mgr,
virDomainObjPtr vm,
virDomainDiskDefPtr disk);
-typedef int (*virSecurityDomainRestoreHostdevLabel) (virSecurityDriverPtr drv,
+typedef int (*virSecurityDomainRestoreHostdevLabel) (virSecurityManagerPtr mgr,
virDomainObjPtr vm,
virDomainHostdevDefPtr dev);
-typedef int (*virSecurityDomainSetHostdevLabel) (virSecurityDriverPtr drv,
+typedef int (*virSecurityDomainSetHostdevLabel) (virSecurityManagerPtr mgr,
virDomainObjPtr vm,
virDomainHostdevDefPtr dev);
-typedef int (*virSecurityDomainSetSavedStateLabel) (virSecurityDriverPtr drv,
+typedef int (*virSecurityDomainSetSavedStateLabel) (virSecurityManagerPtr mgr,
virDomainObjPtr vm,
const char *savefile);
-typedef int (*virSecurityDomainRestoreSavedStateLabel) (virSecurityDriverPtr drv,
+typedef int (*virSecurityDomainRestoreSavedStateLabel) (virSecurityManagerPtr mgr,
virDomainObjPtr vm,
const char *savefile);
-typedef int (*virSecurityDomainGenLabel) (virSecurityDriverPtr drv,
+typedef int (*virSecurityDomainGenLabel) (virSecurityManagerPtr mgr,
virDomainObjPtr sec);
-typedef int (*virSecurityDomainReserveLabel) (virSecurityDriverPtr drv,
+typedef int (*virSecurityDomainReserveLabel) (virSecurityManagerPtr mgr,
virDomainObjPtr sec);
-typedef int (*virSecurityDomainReleaseLabel) (virSecurityDriverPtr drv,
+typedef int (*virSecurityDomainReleaseLabel) (virSecurityManagerPtr mgr,
virDomainObjPtr sec);
-typedef int (*virSecurityDomainSetAllLabel) (virSecurityDriverPtr drv,
+typedef int (*virSecurityDomainSetAllLabel) (virSecurityManagerPtr mgr,
virDomainObjPtr sec,
const char *stdin_path);
-typedef int (*virSecurityDomainRestoreAllLabel) (virSecurityDriverPtr drv,
+typedef int (*virSecurityDomainRestoreAllLabel) (virSecurityManagerPtr mgr,
virDomainObjPtr vm,
int migrated);
-typedef int (*virSecurityDomainGetProcessLabel) (virSecurityDriverPtr drv,
+typedef int (*virSecurityDomainGetProcessLabel) (virSecurityManagerPtr mgr,
virDomainObjPtr vm,
virSecurityLabelPtr sec);
-typedef int (*virSecurityDomainSetProcessLabel) (virSecurityDriverPtr drv,
+typedef int (*virSecurityDomainSetProcessLabel) (virSecurityManagerPtr mgr,
virDomainObjPtr vm);
-typedef int (*virSecurityDomainSecurityVerify) (virDomainDefPtr def);
+typedef int (*virSecurityDomainSecurityVerify) (virSecurityManagerPtr mgr,
+ virDomainDefPtr def);
+
struct _virSecurityDriver {
+ size_t privateDataLen;
const char *name;
virSecurityDriverProbe probe;
virSecurityDriverOpen open;
+ virSecurityDriverClose close;
+
+ virSecurityDriverGetModel getModel;
+ virSecurityDriverGetDOI getDOI;
+
virSecurityDomainSecurityVerify domainSecurityVerify;
+
+ virSecurityDomainSetImageLabel domainSetSecurityImageLabel;
virSecurityDomainRestoreImageLabel domainRestoreSecurityImageLabel;
+
virSecurityDomainSetSocketLabel domainSetSecuritySocketLabel;
virSecurityDomainClearSocketLabel domainClearSecuritySocketLabel;
- virSecurityDomainSetImageLabel domainSetSecurityImageLabel;
+
virSecurityDomainGenLabel domainGenSecurityLabel;
virSecurityDomainReserveLabel domainReserveSecurityLabel;
virSecurityDomainReleaseLabel domainReleaseSecurityLabel;
+
virSecurityDomainGetProcessLabel domainGetSecurityProcessLabel;
virSecurityDomainSetProcessLabel domainSetSecurityProcessLabel;
+
virSecurityDomainSetAllLabel domainSetSecurityAllLabel;
virSecurityDomainRestoreAllLabel domainRestoreSecurityAllLabel;
- virSecurityDomainRestoreHostdevLabel domainRestoreSecurityHostdevLabel;
+
virSecurityDomainSetHostdevLabel domainSetSecurityHostdevLabel;
+ virSecurityDomainRestoreHostdevLabel domainRestoreSecurityHostdevLabel;
+
virSecurityDomainSetSavedStateLabel domainSetSavedStateLabel;
virSecurityDomainRestoreSavedStateLabel domainRestoreSavedStateLabel;
-
- /*
- * This is internally managed driver state and should only be accessed
- * via helpers below.
- */
- struct {
- char doi[VIR_SECURITY_DOI_BUFLEN];
- bool allowDiskFormatProbing;
- } _private;
};
-/* Global methods */
-int virSecurityDriverStartup(virSecurityDriverPtr *drv,
- const char *name,
- bool allowDiskFormatProbing);
-
-int
-virSecurityDriverVerify(virDomainDefPtr def);
-
-# define virSecurityReportError(code, ...) \
- virReportErrorHelper(NULL, VIR_FROM_SECURITY, code, __FILE__, \
- __FUNCTION__, __LINE__, __VA_ARGS__)
-
-/* Helpers */
-void virSecurityDriverInit(virSecurityDriverPtr drv);
-int virSecurityDriverSetDOI(virSecurityDriverPtr drv,
- const char *doi);
-void virSecurityDriverSetAllowDiskFormatProbing(virSecurityDriverPtr drv,
- bool allowDiskFormatProbing);
-const char *virSecurityDriverGetDOI(virSecurityDriverPtr drv);
-const char *virSecurityDriverGetModel(virSecurityDriverPtr drv);
-bool virSecurityDriverGetAllowDiskFormatProbing(virSecurityDriverPtr drv);
+virSecurityDriverPtr virSecurityDriverLookup(const char *name);
#endif /* __VIR_SECURITY_H__ */
diff --git a/src/security/security_manager.c b/src/security/security_manager.c
new file mode 100644
index 0000000..66cffb5
--- /dev/null
+++ b/src/security/security_manager.c
@@ -0,0 +1,317 @@
+/*
+ * security_manager.c: Internal security manager API
+ *
+ * Copyright (C) 2010-2011 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.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Daniel P. Berrange <berrange(a)redhat.com>
+ */
+
+#include <config.h>
+
+
+#include "security_driver.h"
+#include "security_stack.h"
+#include "security_dac.h"
+#include "virterror_internal.h"
+#include "memory.h"
+#include "logging.h"
+
+#define VIR_FROM_THIS VIR_FROM_SECURITY
+
+
+struct _virSecurityManager {
+ virSecurityDriverPtr drv;
+ bool allowDiskFormatProbing;
+};
+
+static virSecurityManagerPtr virSecurityManagerNewDriver(virSecurityDriverPtr drv,
+ bool allowDiskFormatProbing)
+{
+ virSecurityManagerPtr mgr;
+
+ if (VIR_ALLOC_VAR(mgr, char, drv->privateDataLen) < 0) {
+ virReportOOMError();
+ return NULL;
+ }
+
+ mgr->drv = drv;
+ mgr->allowDiskFormatProbing = allowDiskFormatProbing;
+
+ if (drv->open(mgr) < 0) {
+ virSecurityManagerFree(mgr);
+ return NULL;
+ }
+
+ return mgr;
+}
+
+virSecurityManagerPtr virSecurityManagerNewStack(virSecurityManagerPtr primary,
+ virSecurityManagerPtr secondary)
+{
+ virSecurityManagerPtr mgr =
+ virSecurityManagerNewDriver(&virSecurityDriverStack,
+ virSecurityManagerGetAllowDiskFormatProbing(primary));
+
+ if (!mgr)
+ return NULL;
+
+ virSecurityStackSetPrimary(mgr, primary);
+ virSecurityStackSetSecondary(mgr, secondary);
+
+ return mgr;
+}
+
+virSecurityManagerPtr virSecurityManagerNewDAC(uid_t user,
+ gid_t group,
+ bool allowDiskFormatProbing,
+ bool dynamicOwnership)
+{
+ virSecurityManagerPtr mgr =
+ virSecurityManagerNewDriver(&virSecurityDriverDAC,
+ allowDiskFormatProbing);
+
+ if (!mgr)
+ return NULL;
+
+ virSecurityDACSetUser(mgr, user);
+ virSecurityDACSetGroup(mgr, group);
+ virSecurityDACSetDynamicOwnership(mgr, dynamicOwnership);
+
+ return mgr;
+}
+
+virSecurityManagerPtr virSecurityManagerNew(const char *name,
+ bool allowDiskFormatProbing)
+{
+ virSecurityDriverPtr drv = virSecurityDriverLookup(name);
+ if (!drv)
+ return NULL;
+
+ return virSecurityManagerNewDriver(drv, allowDiskFormatProbing);
+}
+
+
+void *virSecurityManagerGetPrivateData(virSecurityManagerPtr mgr)
+{
+ return ((char*)mgr) + sizeof(mgr);
+}
+
+
+void virSecurityManagerFree(virSecurityManagerPtr mgr)
+{
+ if (!mgr)
+ return;
+
+ if (mgr->drv->close)
+ mgr->drv->close(mgr);
+
+ VIR_FREE(mgr);
+}
+
+const char *
+virSecurityManagerGetDOI(virSecurityManagerPtr mgr)
+{
+ if (mgr->drv->getDOI)
+ return mgr->drv->getDOI(mgr);
+
+ virSecurityReportError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ return NULL;
+}
+
+const char *
+virSecurityManagerGetModel(virSecurityManagerPtr mgr)
+{
+ if (mgr->drv->getModel)
+ return mgr->drv->getModel(mgr);
+
+ virSecurityReportError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ return NULL;
+}
+
+bool virSecurityManagerGetAllowDiskFormatProbing(virSecurityManagerPtr mgr)
+{
+ return mgr->allowDiskFormatProbing;
+}
+
+int virSecurityManagerRestoreImageLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm,
+ virDomainDiskDefPtr disk)
+{
+ if (mgr->drv->domainRestoreSecurityImageLabel)
+ return mgr->drv->domainRestoreSecurityImageLabel(mgr, vm, disk);
+
+ virSecurityReportError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ return -1;
+}
+
+int virSecurityManagerSetSocketLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm)
+{
+ if (mgr->drv->domainSetSecuritySocketLabel)
+ return mgr->drv->domainSetSecuritySocketLabel(mgr, vm);
+
+ virSecurityReportError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ return -1;
+}
+
+int virSecurityManagerClearSocketLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm)
+{
+ if (mgr->drv->domainClearSecuritySocketLabel)
+ return mgr->drv->domainClearSecuritySocketLabel(mgr, vm);
+
+ virSecurityReportError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ return -1;
+}
+
+int virSecurityManagerSetImageLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm,
+ virDomainDiskDefPtr disk)
+{
+ if (mgr->drv->domainSetSecurityImageLabel)
+ return mgr->drv->domainSetSecurityImageLabel(mgr, vm, disk);
+
+ virSecurityReportError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ return -1;
+}
+
+int virSecurityManagerRestoreHostdevLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm,
+ virDomainHostdevDefPtr dev)
+{
+ if (mgr->drv->domainRestoreSecurityHostdevLabel)
+ return mgr->drv->domainRestoreSecurityHostdevLabel(mgr, vm, dev);
+
+ virSecurityReportError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ return -1;
+}
+
+int virSecurityManagerSetHostdevLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm,
+ virDomainHostdevDefPtr dev)
+{
+ if (mgr->drv->domainSetSecurityHostdevLabel)
+ return mgr->drv->domainSetSecurityHostdevLabel(mgr, vm, dev);
+
+ virSecurityReportError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ return -1;
+}
+
+int virSecurityManagerSetSavedStateLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm,
+ const char *savefile)
+{
+ if (mgr->drv->domainSetSavedStateLabel)
+ return mgr->drv->domainSetSavedStateLabel(mgr, vm, savefile);
+
+ virSecurityReportError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ return -1;
+}
+
+int virSecurityManagerRestoreSavedStateLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm,
+ const char *savefile)
+{
+ if (mgr->drv->domainRestoreSavedStateLabel)
+ return mgr->drv->domainRestoreSavedStateLabel(mgr, vm, savefile);
+
+ virSecurityReportError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ return -1;
+}
+
+int virSecurityManagerGenLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm)
+{
+ if (mgr->drv->domainGenSecurityLabel)
+ return mgr->drv->domainGenSecurityLabel(mgr, vm);
+
+ virSecurityReportError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ return -1;
+}
+
+int virSecurityManagerReserveLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm)
+{
+ if (mgr->drv->domainReserveSecurityLabel)
+ return mgr->drv->domainReserveSecurityLabel(mgr, vm);
+
+ virSecurityReportError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ return -1;
+}
+
+int virSecurityManagerReleaseLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm)
+{
+ if (mgr->drv->domainReleaseSecurityLabel)
+ return mgr->drv->domainReleaseSecurityLabel(mgr, vm);
+
+ virSecurityReportError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ return -1;
+}
+
+int virSecurityManagerSetAllLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm,
+ const char *stdin_path)
+{
+ if (mgr->drv->domainSetSecurityAllLabel)
+ return mgr->drv->domainSetSecurityAllLabel(mgr, vm, stdin_path);
+
+ virSecurityReportError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ return -1;
+}
+
+int virSecurityManagerRestoreAllLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm,
+ int migrated)
+{
+ if (mgr->drv->domainRestoreSecurityAllLabel)
+ return mgr->drv->domainRestoreSecurityAllLabel(mgr, vm, migrated);
+
+ virSecurityReportError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ return -1;
+}
+
+int virSecurityManagerGetProcessLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm,
+ virSecurityLabelPtr sec)
+{
+ if (mgr->drv->domainGetSecurityProcessLabel)
+ return mgr->drv->domainGetSecurityProcessLabel(mgr, vm, sec);
+
+ virSecurityReportError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ return -1;
+}
+
+int virSecurityManagerSetProcessLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm)
+{
+ if (mgr->drv->domainSetSecurityProcessLabel)
+ return mgr->drv->domainSetSecurityProcessLabel(mgr, vm);
+
+ virSecurityReportError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ return -1;
+}
+
+int virSecurityManagerVerify(virSecurityManagerPtr mgr,
+ virDomainDefPtr def)
+{
+ if (mgr->drv->domainSecurityVerify)
+ return mgr->drv->domainSecurityVerify(mgr, def);
+
+ virSecurityReportError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ return -1;
+}
diff --git a/src/security/security_manager.h b/src/security/security_manager.h
new file mode 100644
index 0000000..189b6b4
--- /dev/null
+++ b/src/security/security_manager.h
@@ -0,0 +1,95 @@
+/*
+ * security_manager.h: Internal security manager API
+ *
+ * Copyright (C) 2010-2011 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.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Daniel P. Berrange <berrange(a)redhat.com>
+ */
+
+#ifndef VIR_SECURITY_MANAGER_H__
+# define VIR_SECURITY_MANAGER_H__
+
+# define virSecurityReportError(code, ...) \
+ virReportErrorHelper(NULL, VIR_FROM_SECURITY, code, __FILE__, \
+ __FUNCTION__, __LINE__, __VA_ARGS__)
+
+
+typedef struct _virSecurityManager virSecurityManager;
+typedef virSecurityManager *virSecurityManagerPtr;
+
+virSecurityManagerPtr virSecurityManagerNew(const char *name,
+ bool allowDiskFormatProbing);
+
+virSecurityManagerPtr virSecurityManagerNewStack(virSecurityManagerPtr primary,
+ virSecurityManagerPtr secondary);
+
+virSecurityManagerPtr virSecurityManagerNewDAC(uid_t user,
+ gid_t group,
+ bool allowDiskFormatProbing,
+ bool dynamicOwnership);
+
+void *virSecurityManagerGetPrivateData(virSecurityManagerPtr mgr);
+
+void virSecurityManagerFree(virSecurityManagerPtr mgr);
+
+const char *virSecurityManagerGetDOI(virSecurityManagerPtr mgr);
+const char *virSecurityManagerGetModel(virSecurityManagerPtr mgr);
+bool virSecurityManagerGetAllowDiskFormatProbing(virSecurityManagerPtr mgr);
+
+int virSecurityManagerRestoreImageLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm,
+ virDomainDiskDefPtr disk);
+int virSecurityManagerSetSocketLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm);
+int virSecurityManagerClearSocketLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm);
+int virSecurityManagerSetImageLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm,
+ virDomainDiskDefPtr disk);
+int virSecurityManagerRestoreHostdevLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm,
+ virDomainHostdevDefPtr dev);
+int virSecurityManagerSetHostdevLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm,
+ virDomainHostdevDefPtr dev);
+int virSecurityManagerSetSavedStateLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm,
+ const char *savefile);
+int virSecurityManagerRestoreSavedStateLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm,
+ const char *savefile);
+int virSecurityManagerGenLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr sec);
+int virSecurityManagerReserveLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr sec);
+int virSecurityManagerReleaseLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr sec);
+int virSecurityManagerSetAllLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr sec,
+ const char *stdin_path);
+int virSecurityManagerRestoreAllLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm,
+ int migrated);
+int virSecurityManagerGetProcessLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm,
+ virSecurityLabelPtr sec);
+int virSecurityManagerSetProcessLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm);
+int virSecurityManagerVerify(virSecurityManagerPtr mgr,
+ virDomainDefPtr def);
+
+#endif /* VIR_SECURITY_MANAGER_H__ */
diff --git a/src/security/security_nop.c b/src/security/security_nop.c
new file mode 100644
index 0000000..6d7cb47
--- /dev/null
+++ b/src/security/security_nop.c
@@ -0,0 +1,185 @@
+/*
+ * Copyright (C) 2010-2011 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.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <config.h>
+
+#include "security_nop.h"
+
+static virSecurityDriverStatus virSecurityDriverProbeNop(void)
+{
+ return SECURITY_DRIVER_ENABLE;
+}
+
+static int virSecurityDriverOpenNop(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+static int virSecurityDriverCloseNop(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+static const char * virSecurityDriverGetModelNop(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED)
+{
+ return "none";
+}
+
+static const char * virSecurityDriverGetDOINop(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED)
+{
+ return "0";
+}
+
+static int virSecurityDomainRestoreImageLabelNop(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
+ virDomainObjPtr vm ATTRIBUTE_UNUSED,
+ virDomainDiskDefPtr disk ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+static int virSecurityDomainSetSocketLabelNop(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
+ virDomainObjPtr vm ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+static int virSecurityDomainClearSocketLabelNop(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
+ virDomainObjPtr vm ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+static int virSecurityDomainSetImageLabelNop(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
+ virDomainObjPtr vm ATTRIBUTE_UNUSED,
+ virDomainDiskDefPtr disk ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+static int virSecurityDomainRestoreHostdevLabelNop(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
+ virDomainObjPtr vm ATTRIBUTE_UNUSED,
+ virDomainHostdevDefPtr dev ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+static int virSecurityDomainSetHostdevLabelNop(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
+ virDomainObjPtr vm ATTRIBUTE_UNUSED,
+ virDomainHostdevDefPtr dev ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+static int virSecurityDomainSetSavedStateLabelNop(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
+ virDomainObjPtr vm ATTRIBUTE_UNUSED,
+ const char *savefile ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+static int virSecurityDomainRestoreSavedStateLabelNop(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
+ virDomainObjPtr vm ATTRIBUTE_UNUSED,
+ const char *savefile ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+static int virSecurityDomainGenLabelNop(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
+ virDomainObjPtr sec ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+static int virSecurityDomainReserveLabelNop(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
+ virDomainObjPtr sec ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+static int virSecurityDomainReleaseLabelNop(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
+ virDomainObjPtr sec ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+static int virSecurityDomainSetAllLabelNop(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
+ virDomainObjPtr sec ATTRIBUTE_UNUSED,
+ const char *stdin_path ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+static int virSecurityDomainRestoreAllLabelNop(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
+ virDomainObjPtr vm ATTRIBUTE_UNUSED,
+ int migrated ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+static int virSecurityDomainGetProcessLabelNop(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
+ virDomainObjPtr vm ATTRIBUTE_UNUSED,
+ virSecurityLabelPtr sec ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+static int virSecurityDomainSetProcessLabelNop(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
+ virDomainObjPtr vm ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+static int virSecurityDomainVerifyNop(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
+ virDomainDefPtr def ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+virSecurityDriver virSecurityDriverNop = {
+ 0,
+ "none",
+ virSecurityDriverProbeNop,
+ virSecurityDriverOpenNop,
+ virSecurityDriverCloseNop,
+
+ virSecurityDriverGetModelNop,
+ virSecurityDriverGetDOINop,
+
+ virSecurityDomainVerifyNop,
+
+ virSecurityDomainSetImageLabelNop,
+ virSecurityDomainRestoreImageLabelNop,
+
+ virSecurityDomainSetSocketLabelNop,
+ virSecurityDomainClearSocketLabelNop,
+
+ virSecurityDomainGenLabelNop,
+ virSecurityDomainReserveLabelNop,
+ virSecurityDomainReleaseLabelNop,
+
+ virSecurityDomainGetProcessLabelNop,
+ virSecurityDomainSetProcessLabelNop,
+
+ virSecurityDomainSetAllLabelNop,
+ virSecurityDomainRestoreAllLabelNop,
+
+ virSecurityDomainSetHostdevLabelNop,
+ virSecurityDomainRestoreHostdevLabelNop,
+
+ virSecurityDomainSetSavedStateLabelNop,
+ virSecurityDomainRestoreSavedStateLabelNop,
+};
diff --git a/src/security/security_nop.h b/src/security/security_nop.h
new file mode 100644
index 0000000..589a75d
--- /dev/null
+++ b/src/security/security_nop.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2010-2011 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.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef __VIR_SECURITY_NOP_H__
+# define __VIR_SECURITY_NOP_H__
+
+# include "security_driver.h"
+
+extern virSecurityDriver virSecurityDriverNop;
+
+#endif /* __VIR_SECURITY_NOP_H__ */
diff --git a/src/security/security_selinux.c b/src/security/security_selinux.c
index 47da677..d06afde 100644
--- a/src/security/security_selinux.c
+++ b/src/security/security_selinux.c
@@ -160,7 +160,7 @@ SELinuxInitialize(void)
}
static int
-SELinuxGenSecurityLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
+SELinuxGenSecurityLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
virDomainObjPtr vm)
{
int rc = -1;
@@ -225,7 +225,7 @@ done:
}
static int
-SELinuxReserveSecurityLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
+SELinuxReserveSecurityLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
virDomainObjPtr vm)
{
security_context_t pctx;
@@ -270,20 +270,34 @@ SELinuxSecurityDriverProbe(void)
}
static int
-SELinuxSecurityDriverOpen(virSecurityDriverPtr drv,
- bool allowDiskFormatProbing)
+SELinuxSecurityDriverOpen(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED)
+{
+ return SELinuxInitialize();
+}
+
+static int
+SELinuxSecurityDriverClose(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+
+static const char *SELinuxSecurityGetModel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED)
+{
+ return SECURITY_SELINUX_NAME;
+}
+
+static const char *SELinuxSecurityGetDOI(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED)
{
/*
* Where will the DOI come from? SELinux configuration, or qemu
* configuration? For the moment, we'll just set it to "0".
*/
- virSecurityDriverSetDOI(drv, SECURITY_SELINUX_VOID_DOI);
- virSecurityDriverSetAllowDiskFormatProbing(drv, allowDiskFormatProbing);
- return SELinuxInitialize();
+ return SECURITY_SELINUX_VOID_DOI;
}
static int
-SELinuxGetSecurityProcessLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
+SELinuxGetSecurityProcessLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
virDomainObjPtr vm,
virSecurityLabelPtr sec)
{
@@ -415,7 +429,7 @@ err:
}
static int
-SELinuxRestoreSecurityImageLabelInt(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
+SELinuxRestoreSecurityImageLabelInt(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
virDomainObjPtr vm,
virDomainDiskDefPtr disk,
int migrated)
@@ -460,11 +474,11 @@ SELinuxRestoreSecurityImageLabelInt(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
static int
-SELinuxRestoreSecurityImageLabel(virSecurityDriverPtr drv,
+SELinuxRestoreSecurityImageLabel(virSecurityManagerPtr mgr,
virDomainObjPtr vm,
virDomainDiskDefPtr disk)
{
- return SELinuxRestoreSecurityImageLabelInt(drv, vm, disk, 0);
+ return SELinuxRestoreSecurityImageLabelInt(mgr, vm, disk, 0);
}
@@ -498,13 +512,13 @@ SELinuxSetSecurityFileLabel(virDomainDiskDefPtr disk,
}
static int
-SELinuxSetSecurityImageLabel(virSecurityDriverPtr drv,
+SELinuxSetSecurityImageLabel(virSecurityManagerPtr mgr,
virDomainObjPtr vm,
virDomainDiskDefPtr disk)
{
const virSecurityLabelDefPtr secdef = &vm->def->seclabel;
- bool allowDiskFormatProbing = virSecurityDriverGetAllowDiskFormatProbing(drv);
+ bool allowDiskFormatProbing = virSecurityManagerGetAllowDiskFormatProbing(mgr);
if (secdef->type == VIR_DOMAIN_SECLABEL_STATIC)
return 0;
@@ -538,7 +552,7 @@ SELinuxSetSecurityUSBLabel(usbDevice *dev ATTRIBUTE_UNUSED,
}
static int
-SELinuxSetSecurityHostdevLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
+SELinuxSetSecurityHostdevLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
virDomainObjPtr vm,
virDomainHostdevDefPtr dev)
@@ -607,7 +621,7 @@ SELinuxRestoreSecurityUSBLabel(usbDevice *dev ATTRIBUTE_UNUSED,
}
static int
-SELinuxRestoreSecurityHostdevLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
+SELinuxRestoreSecurityHostdevLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
virDomainObjPtr vm,
virDomainHostdevDefPtr dev)
@@ -756,7 +770,7 @@ SELinuxRestoreSecurityChardevCallback(virDomainDefPtr def ATTRIBUTE_UNUSED,
static int
-SELinuxRestoreSecurityAllLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
+SELinuxRestoreSecurityAllLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
virDomainObjPtr vm,
int migrated ATTRIBUTE_UNUSED)
{
@@ -770,13 +784,13 @@ SELinuxRestoreSecurityAllLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
return 0;
for (i = 0 ; i < vm->def->nhostdevs ; i++) {
- if (SELinuxRestoreSecurityHostdevLabel(drv,
+ if (SELinuxRestoreSecurityHostdevLabel(mgr,
vm,
vm->def->hostdevs[i]) < 0)
rc = -1;
}
for (i = 0 ; i < vm->def->ndisks ; i++) {
- if (SELinuxRestoreSecurityImageLabelInt(drv,
+ if (SELinuxRestoreSecurityImageLabelInt(mgr,
vm,
vm->def->disks[i],
migrated) < 0)
@@ -801,7 +815,7 @@ SELinuxRestoreSecurityAllLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
}
static int
-SELinuxReleaseSecurityLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
+SELinuxReleaseSecurityLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
virDomainObjPtr vm)
{
const virSecurityLabelDefPtr secdef = &vm->def->seclabel;
@@ -825,7 +839,7 @@ SELinuxReleaseSecurityLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
static int
-SELinuxSetSavedStateLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
+SELinuxSetSavedStateLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
virDomainObjPtr vm,
const char *savefile)
{
@@ -839,7 +853,7 @@ SELinuxSetSavedStateLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
static int
-SELinuxRestoreSavedStateLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
+SELinuxRestoreSavedStateLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
virDomainObjPtr vm,
const char *savefile)
{
@@ -853,9 +867,19 @@ SELinuxRestoreSavedStateLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
static int
-SELinuxSecurityVerify(virDomainDefPtr def)
+SELinuxSecurityVerify(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
+ virDomainDefPtr def)
{
const virSecurityLabelDefPtr secdef = &def->seclabel;
+ if (!STREQ(virSecurityManagerGetModel(mgr), secdef->model)) {
+ virSecurityReportError(VIR_ERR_INTERNAL_ERROR,
+ _("security label driver mismatch: "
+ "'%s' model configured for domain, but "
+ "hypervisor driver is '%s'."),
+ secdef->model, virSecurityManagerGetModel(mgr));
+ return -1;
+ }
+
if (secdef->type == VIR_DOMAIN_SECLABEL_STATIC) {
if (security_check_context(secdef->label) != 0) {
virSecurityReportError(VIR_ERR_XML_ERROR,
@@ -867,7 +891,7 @@ SELinuxSecurityVerify(virDomainDefPtr def)
}
static int
-SELinuxSetSecurityProcessLabel(virSecurityDriverPtr drv,
+SELinuxSetSecurityProcessLabel(virSecurityManagerPtr mgr,
virDomainObjPtr vm)
{
/* TODO: verify DOI */
@@ -876,12 +900,12 @@ SELinuxSetSecurityProcessLabel(virSecurityDriverPtr drv,
if (vm->def->seclabel.label == NULL)
return 0;
- if (!STREQ(drv->name, secdef->model)) {
+ if (!STREQ(virSecurityManagerGetModel(mgr), secdef->model)) {
virSecurityReportError(VIR_ERR_INTERNAL_ERROR,
_("security label driver mismatch: "
"'%s' model configured for domain, but "
"hypervisor driver is '%s'."),
- secdef->model, drv->name);
+ secdef->model, virSecurityManagerGetModel(mgr));
if (security_getenforce() == 1)
return -1;
}
@@ -898,7 +922,7 @@ SELinuxSetSecurityProcessLabel(virSecurityDriverPtr drv,
}
static int
-SELinuxSetSecuritySocketLabel(virSecurityDriverPtr drv,
+SELinuxSetSecuritySocketLabel(virSecurityManagerPtr mgr,
virDomainObjPtr vm)
{
/* TODO: verify DOI */
@@ -911,12 +935,12 @@ SELinuxSetSecuritySocketLabel(virSecurityDriverPtr drv,
if (vm->def->seclabel.label == NULL)
return 0;
- if (!STREQ(drv->name, secdef->model)) {
+ if (!STREQ(virSecurityManagerGetModel(mgr), secdef->model)) {
virSecurityReportError(VIR_ERR_INTERNAL_ERROR,
_("security label driver mismatch: "
"'%s' model configured for domain, but "
"hypervisor driver is '%s'."),
- secdef->model, drv->name);
+ secdef->model, virSecurityManagerGetModel(mgr));
goto done;
}
@@ -969,7 +993,7 @@ done:
}
static int
-SELinuxClearSecuritySocketLabel(virSecurityDriverPtr drv,
+SELinuxClearSecuritySocketLabel(virSecurityManagerPtr mgr,
virDomainObjPtr vm)
{
/* TODO: verify DOI */
@@ -978,12 +1002,12 @@ SELinuxClearSecuritySocketLabel(virSecurityDriverPtr drv,
if (vm->def->seclabel.label == NULL)
return 0;
- if (!STREQ(drv->name, secdef->model)) {
+ if (!STREQ(virSecurityManagerGetModel(mgr), secdef->model)) {
virSecurityReportError(VIR_ERR_INTERNAL_ERROR,
_("security label driver mismatch: "
"'%s' model configured for domain, but "
"hypervisor driver is '%s'."),
- secdef->model, drv->name);
+ secdef->model, virSecurityManagerGetModel(mgr));
if (security_getenforce() == 1)
return -1;
}
@@ -1011,7 +1035,7 @@ SELinuxSetSecurityChardevCallback(virDomainDefPtr def ATTRIBUTE_UNUSED,
static int
-SELinuxSetSecurityAllLabel(virSecurityDriverPtr drv,
+SELinuxSetSecurityAllLabel(virSecurityManagerPtr mgr,
virDomainObjPtr vm,
const char *stdin_path)
{
@@ -1028,12 +1052,12 @@ SELinuxSetSecurityAllLabel(virSecurityDriverPtr drv,
vm->def->disks[i]->src, vm->def->disks[i]->dst);
continue;
}
- if (SELinuxSetSecurityImageLabel(drv,
+ if (SELinuxSetSecurityImageLabel(mgr,
vm, vm->def->disks[i]) < 0)
return -1;
}
for (i = 0 ; i < vm->def->nhostdevs ; i++) {
- if (SELinuxSetSecurityHostdevLabel(drv,
+ if (SELinuxSetSecurityHostdevLabel(mgr,
vm,
vm->def->hostdevs[i]) < 0)
return -1;
@@ -1063,24 +1087,37 @@ SELinuxSetSecurityAllLabel(virSecurityDriverPtr drv,
return 0;
}
-virSecurityDriver virSELinuxSecurityDriver = {
- .name = SECURITY_SELINUX_NAME,
- .probe = SELinuxSecurityDriverProbe,
- .open = SELinuxSecurityDriverOpen,
- .domainSecurityVerify = SELinuxSecurityVerify,
- .domainSetSecurityImageLabel = SELinuxSetSecurityImageLabel,
- .domainSetSecuritySocketLabel = SELinuxSetSecuritySocketLabel,
- .domainClearSecuritySocketLabel = SELinuxClearSecuritySocketLabel,
- .domainRestoreSecurityImageLabel = SELinuxRestoreSecurityImageLabel,
- .domainGenSecurityLabel = SELinuxGenSecurityLabel,
- .domainReserveSecurityLabel = SELinuxReserveSecurityLabel,
- .domainReleaseSecurityLabel = SELinuxReleaseSecurityLabel,
- .domainGetSecurityProcessLabel = SELinuxGetSecurityProcessLabel,
- .domainSetSecurityProcessLabel = SELinuxSetSecurityProcessLabel,
- .domainRestoreSecurityAllLabel = SELinuxRestoreSecurityAllLabel,
- .domainSetSecurityAllLabel = SELinuxSetSecurityAllLabel,
- .domainSetSecurityHostdevLabel = SELinuxSetSecurityHostdevLabel,
- .domainRestoreSecurityHostdevLabel = SELinuxRestoreSecurityHostdevLabel,
- .domainSetSavedStateLabel = SELinuxSetSavedStateLabel,
- .domainRestoreSavedStateLabel = SELinuxRestoreSavedStateLabel,
+virSecurityDriver virSecurityDriverSELinux = {
+ 0,
+ SECURITY_SELINUX_NAME,
+ SELinuxSecurityDriverProbe,
+ SELinuxSecurityDriverOpen,
+ SELinuxSecurityDriverClose,
+
+ SELinuxSecurityGetModel,
+ SELinuxSecurityGetDOI,
+
+ SELinuxSecurityVerify,
+
+ SELinuxSetSecurityImageLabel,
+ SELinuxRestoreSecurityImageLabel,
+
+ SELinuxSetSecuritySocketLabel,
+ SELinuxClearSecuritySocketLabel,
+
+ SELinuxGenSecurityLabel,
+ SELinuxReserveSecurityLabel,
+ SELinuxReleaseSecurityLabel,
+
+ SELinuxGetSecurityProcessLabel,
+ SELinuxSetSecurityProcessLabel,
+
+ SELinuxSetSecurityAllLabel,
+ SELinuxRestoreSecurityAllLabel,
+
+ SELinuxSetSecurityHostdevLabel,
+ SELinuxRestoreSecurityHostdevLabel,
+
+ SELinuxSetSavedStateLabel,
+ SELinuxRestoreSavedStateLabel,
};
diff --git a/src/security/security_selinux.h b/src/security/security_selinux.h
index 056ba75..aa67421 100644
--- a/src/security/security_selinux.h
+++ b/src/security/security_selinux.h
@@ -13,6 +13,6 @@
#ifndef __VIR_SECURITY_SELINUX_H__
# define __VIR_SECURITY_SELINUX_H__
-extern virSecurityDriver virSELinuxSecurityDriver;
+extern virSecurityDriver virSecurityDriverSELinux;
#endif /* __VIR_SECURITY_SELINUX_H__ */
diff --git a/src/security/security_stack.c b/src/security/security_stack.c
new file mode 100644
index 0000000..e8bb058
--- /dev/null
+++ b/src/security/security_stack.c
@@ -0,0 +1,401 @@
+/*
+ * Copyright (C) 2010-2011 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.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Stacked security driver
+ */
+
+#include <config.h>
+
+#include "security_stack.h"
+
+#include "virterror_internal.h"
+
+#define VIR_FROM_THIS VIR_FROM_SECURITY
+
+typedef struct _virSecurityStackData virSecurityStackData;
+typedef virSecurityStackData *virSecurityStackDataPtr;
+
+struct _virSecurityStackData {
+ virSecurityManagerPtr primary;
+ virSecurityManagerPtr secondary;
+};
+
+void virSecurityStackSetPrimary(virSecurityManagerPtr mgr,
+ virSecurityManagerPtr primary)
+{
+ virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+ priv->primary = primary;
+}
+
+void virSecurityStackSetSecondary(virSecurityManagerPtr mgr,
+ virSecurityManagerPtr secondary)
+{
+ virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+ priv->secondary = secondary;
+}
+
+static virSecurityDriverStatus
+virSecurityStackProbe(void)
+{
+ return SECURITY_DRIVER_ENABLE;
+}
+
+static int
+virSecurityStackOpen(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+static int
+virSecurityStackClose(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+static const char *
+virSecurityStackGetModel(virSecurityManagerPtr mgr)
+{
+ virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+
+ return virSecurityManagerGetModel(priv->primary);
+}
+
+static const char *
+virSecurityStackGetDOI(virSecurityManagerPtr mgr)
+{
+ virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+
+ return virSecurityManagerGetDOI(priv->primary);
+}
+
+static int
+virSecurityStackVerify(virSecurityManagerPtr mgr,
+ virDomainDefPtr def)
+{
+ virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+ int rc = 0;
+
+ if (virSecurityManagerVerify(priv->primary, def) < 0)
+ rc = -1;
+
+ if (virSecurityManagerVerify(priv->secondary, def) < 0)
+ rc = -1;
+
+ return rc;
+}
+
+
+static int
+virSecurityStackGenLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm)
+{
+ virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+ int rc = 0;
+
+ if (virSecurityManagerGenLabel(priv->primary, vm) < 0)
+ rc = -1;
+
+#if 0
+ /* We don't allow secondary drivers to generate labels.
+ * This may have to change in the future, but requires
+ * changes elsewhere in domain_conf.c and capabilities.c
+ * XML formats first, to allow recording of multiple
+ * labels
+ */
+ if (virSecurityManagerGenLabel(priv->secondary, vm) < 0)
+ rc = -1;
+#endif
+
+ return rc;
+}
+
+
+static int
+virSecurityStackReleaseLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm)
+{
+ virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+ int rc = 0;
+
+ if (virSecurityManagerReleaseLabel(priv->primary, vm) < 0)
+ rc = -1;
+#if 0
+ /* XXX See note in GenLabel */
+ if (virSecurityManagerReleaseLabel(priv->secondary, vm) < 0)
+ rc = -1;
+#endif
+
+ return rc;
+}
+
+
+static int
+virSecurityStackReserveLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm)
+{
+ virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+ int rc = 0;
+
+ if (virSecurityManagerReserveLabel(priv->primary, vm) < 0)
+ rc = -1;
+#if 0
+ /* XXX See note in GenLabel */
+ if (virSecurityManagerReserveLabel(priv->secondary, vm) < 0)
+ rc = -1;
+#endif
+
+ return rc;
+}
+
+
+static int
+virSecurityStackSetSecurityImageLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm,
+ virDomainDiskDefPtr disk)
+{
+ virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+ int rc = 0;
+
+ if (virSecurityManagerSetImageLabel(priv->secondary, vm, disk) < 0)
+ rc = -1;
+ if (virSecurityManagerSetImageLabel(priv->primary, vm, disk) < 0)
+ rc = -1;
+
+ return rc;
+}
+
+
+static int
+virSecurityStackRestoreSecurityImageLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm,
+ virDomainDiskDefPtr disk)
+{
+ virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+ int rc = 0;
+
+ if (virSecurityManagerRestoreImageLabel(priv->secondary, vm, disk) < 0)
+ rc = -1;
+ if (virSecurityManagerRestoreImageLabel(priv->primary, vm, disk) < 0)
+ rc = -1;
+
+ return rc;
+}
+
+
+static int
+virSecurityStackSetSecurityHostdevLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm,
+ virDomainHostdevDefPtr dev)
+
+{
+ virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+ int rc = 0;
+
+ if (virSecurityManagerSetHostdevLabel(priv->secondary, vm, dev) < 0)
+ rc = -1;
+ if (virSecurityManagerSetHostdevLabel(priv->primary, vm, dev) < 0)
+ rc = -1;
+
+ return rc;
+}
+
+
+static int
+virSecurityStackRestoreSecurityHostdevLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm,
+ virDomainHostdevDefPtr dev)
+{
+ virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+ int rc = 0;
+
+ if (virSecurityManagerRestoreHostdevLabel(priv->secondary, vm, dev) < 0)
+ rc = -1;
+ if (virSecurityManagerRestoreHostdevLabel(priv->primary, vm, dev) < 0)
+ rc = -1;
+
+ return rc;
+}
+
+
+static int
+virSecurityStackSetSecurityAllLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm,
+ const char *stdin_path)
+{
+ virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+ int rc = 0;
+
+ if (virSecurityManagerSetAllLabel(priv->secondary, vm, stdin_path) < 0)
+ rc = -1;
+ if (virSecurityManagerSetAllLabel(priv->primary, vm, stdin_path) < 0)
+ rc = -1;
+
+ return rc;
+}
+
+
+static int
+virSecurityStackRestoreSecurityAllLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm,
+ int migrated)
+{
+ virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+ int rc = 0;
+
+ if (virSecurityManagerRestoreAllLabel(priv->secondary, vm, migrated) < 0)
+ rc = -1;
+ if (virSecurityManagerRestoreAllLabel(priv->primary, vm, migrated) < 0)
+ rc = -1;
+
+ return rc;
+}
+
+
+static int
+virSecurityStackSetSavedStateLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm,
+ const char *savefile)
+{
+ virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+ int rc = 0;
+
+ if (virSecurityManagerSetSavedStateLabel(priv->secondary, vm, savefile) < 0)
+ rc = -1;
+ if (virSecurityManagerSetSavedStateLabel(priv->primary, vm, savefile) < 0)
+ rc = -1;
+
+ return rc;
+}
+
+
+static int
+virSecurityStackRestoreSavedStateLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm,
+ const char *savefile)
+{
+ virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+ int rc = 0;
+
+ if (virSecurityManagerRestoreSavedStateLabel(priv->secondary, vm, savefile) < 0)
+ rc = -1;
+ if (virSecurityManagerRestoreSavedStateLabel(priv->primary, vm, savefile) < 0)
+ rc = -1;
+
+ return rc;
+}
+
+
+static int
+virSecurityStackSetProcessLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm)
+{
+ virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+ int rc = 0;
+
+ if (virSecurityManagerSetProcessLabel(priv->secondary, vm) < 0)
+ rc = -1;
+ if (virSecurityManagerSetProcessLabel(priv->primary, vm) < 0)
+ rc = -1;
+
+ return rc;
+}
+
+static int
+virSecurityStackGetProcessLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm,
+ virSecurityLabelPtr seclabel)
+{
+ virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+ int rc = 0;
+
+#if 0
+ if (virSecurityManagerGetProcessLabel(priv->secondary, vm, seclabel) < 0)
+ rc = -1;
+#endif
+ if (virSecurityManagerGetProcessLabel(priv->primary, vm, seclabel) < 0)
+ rc = -1;
+
+ return rc;
+}
+
+
+static int
+virSecurityStackSetSocketLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm)
+{
+ virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+ int rc = 0;
+
+ if (virSecurityManagerSetSocketLabel(priv->secondary, vm) < 0)
+ rc = -1;
+ if (virSecurityManagerSetSocketLabel(priv->primary, vm) < 0)
+ rc = -1;
+
+ return rc;
+}
+
+
+static int
+virSecurityStackClearSocketLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm)
+{
+ virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+ int rc = 0;
+
+ if (virSecurityManagerClearSocketLabel(priv->secondary, vm) < 0)
+ rc = -1;
+ if (virSecurityManagerClearSocketLabel(priv->primary, vm) < 0)
+ rc = -1;
+
+ return rc;
+}
+
+
+virSecurityDriver virSecurityDriverStack = {
+ sizeof(virSecurityStackData),
+ "stack",
+ virSecurityStackProbe,
+ virSecurityStackOpen,
+ virSecurityStackClose,
+
+ virSecurityStackGetModel,
+ virSecurityStackGetDOI,
+
+ virSecurityStackVerify,
+
+ virSecurityStackSetSecurityImageLabel,
+ virSecurityStackRestoreSecurityImageLabel,
+
+ virSecurityStackSetSocketLabel,
+ virSecurityStackClearSocketLabel,
+
+ virSecurityStackGenLabel,
+ virSecurityStackReserveLabel,
+ virSecurityStackReleaseLabel,
+
+ virSecurityStackGetProcessLabel,
+ virSecurityStackSetProcessLabel,
+
+ virSecurityStackSetSecurityAllLabel,
+ virSecurityStackRestoreSecurityAllLabel,
+
+ virSecurityStackSetSecurityHostdevLabel,
+ virSecurityStackRestoreSecurityHostdevLabel,
+
+ virSecurityStackSetSavedStateLabel,
+ virSecurityStackRestoreSavedStateLabel,
+};
diff --git a/src/security/security_stack.h b/src/security/security_stack.h
new file mode 100644
index 0000000..bc83ff3
--- /dev/null
+++ b/src/security/security_stack.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2010-2011 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.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Stacked security driver
+ */
+
+#include "security_driver.h"
+
+#ifndef __VIR_SECURITY_STACK
+# define __VIR_SECURITY_STACK
+
+extern virSecurityDriver virSecurityDriverStack;
+
+void virSecurityStackSetPrimary(virSecurityManagerPtr mgr,
+ virSecurityManagerPtr primary);
+void virSecurityStackSetSecondary(virSecurityManagerPtr mgr,
+ virSecurityManagerPtr secondary);
+
+#endif /* __VIR_SECURITY_DAC */
--
1.7.3.4
2
3
Hi,
At the moment SASL VNC authentication in libvirt allows any of the
userids to access any of the VNC consoles on a particular libvirt host.
There is a section in the qemu_command code marked "TODO: Support ACLs
later" and we would really like the ability to have per VM user
authorization to the VNC console from within libvirt.
Essentially the people who are accessing the VNC consoles are not
administrators and have no access to the Host server - so these ACLs
need to be completely based on a separate list of userids to any access
mechanism for the libvirtd itself.
Given that the VNC restrictions are enforced within qemu from the
monitor system, I'm presuming the authorization list is going to have to
be passed in via XML and be capable of being updated throughout the life
of a VM session. Unless there's another way of doing it...
What's the feeling about how this feature should be provided within
libvirt?
If there is somebody out there who has a bit of time at the moment and
fancies having a go at implementing this - and, of course, there is
agreement on a specification here - then we'd look at sponsoring them to
add the feature into Libvirt. Please put your hand up!
Regards,
Neil Wilson
4
14
10 Jan '11
Hey subscribers,
I have a problem with the actual libvirt/virsh release and qemu-kvm
0.13. if i want to save the actual status of my virtual machine i get
the following error:
lserver ~ # virsh save windows /virtual/windows_ram
error: Failed to save domain windows to /virtual/windows_ram
error: internal error unable to execute QEMU command 'migrate': An
undefined error has ocurred
First i asked in OFTC but there was said, that this could be an error
with the qemu console command.
The system details:
lserver ~ # uname -a
Linux lserver 2.6.36.2 #2 SMP PREEMPT Wed Dec 29 02:58:41 Local time
zone must be set-- x86_64 Intel(R) Core(TM) i5 CPU K 655 @ 3.20GHz
GenuineIntel GNU/Linux
lserver ~ # virsh --version
0.8.7
lserver ~ # qemu-kvm --version
QEMU emulator version 0.13.0 (qemu-kvm-0.13.0), Copyright (c)
2003-2008 Fabrice Bellard
root 28673 7.7 81.5 3184544 3092128 ? Sl Jan09 72:19
/usr/bin/qemu-system-x86_64 --enable-kvm -S -M pc-0.13 -enable-kvm -m
3000 -smp 2,sockets=2,cores=1,threads=1 -name windows -uuid
30c59551-5571-a177-9036-1d5d51cb76b2 -nodefconfig -nodefaults -chardev
socket,id=monitor,path=/var/lib/libvirt/qemu/windows.monitor,server,nowait
-mon chardev=monitor,mode=control -rtc base=localtime -boot c -drive
file=/virtual/server2003.img,if=none,id=drive-ide0-0-0,format=raw
-device ide-drive,bus=ide.0,unit=0,drive=drive-ide0-0-0,id=ide0-0-0
-netdev tap,fd=39,id=hostnet0 -device
e1000,netdev=hostnet0,id=net0,mac=52:54:00:12:34:70,bus=pci.0,addr=0x3
-chardev pty,id=serial0 -device isa-serial,chardev=serial0 -usb -device
usb-tablet,id=input0 -vnc 127.0.0.1:0 -k de -vga std -device
virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x4
It was for me not possible to get further debug info from libvirt.
Best regards,
Oliver Lott
1
0
Hello,
got no reaction on this, I try again :-)
-------- Message original --------
Sujet: libvirtd and listen_addr
Date : Sat, 01 Jan 2011 11:33:55 +0100
De : Daniel Huhardeaux <tech(a)tootai.net>
Pour : libvir-list(a)redhat.com
Hi,
at first, best wishes to all for this new year.
We have a request: would it be possible to start libvirtd listen_addr
*after* the VM network is up?
We have VPN through different libvirt+kvm servers and want to virsh
connect to the private VM network address of each server instead of his
VPN IP. The problem is that libvirt doesn't start with unknown IP
address. If network would be already up, libvirt could listen on this
address.
Regards
libvirtd (libvirt) 0.8.3 - Debian stable + backports
--
Daniel
3
10
Hi Matthias,
Have you tried out libvirt 0.8.7 yet with your msys scripts?
Giving it a shot here, but am hitting problems with the --with-remote part. ./configure isn't finding the XDR library.
checking for xdrmem_create in -lportablexdr... no
checking for library containing xdrmem_create... no
configure: error: Cannot find a XDR library
Wondering if you've had a chance to look at 0.8.7 with msys yet, and if you've come across the same problem?
Regards and best wishes,
Justin Clift
3
3
Hi,
Recently, QEMU learned set_password and expire_password monitor commands.
http://qemu.com/qemu.git/commit/?id=7572150c189c6553c2448334116ab717680de66d
The following patches make use of these new commands if available, and
fallback on VNC-only password support.
Marc-André Lureau (2):
qemu: add set_password and expire_password monitor commands
qemu: Update password support in the QEMU driver
src/qemu/qemu_driver.c | 138 ++++++++++++++++++++++++++++++++++++------
src/qemu/qemu_monitor.c | 77 +++++++++++++++++++++++
src/qemu/qemu_monitor.h | 7 ++
src/qemu/qemu_monitor_json.c | 56 +++++++++++++++++
src/qemu/qemu_monitor_json.h | 7 ++
src/qemu/qemu_monitor_text.c | 69 +++++++++++++++++++++
src/qemu/qemu_monitor_text.h | 7 ++
7 files changed, 343 insertions(+), 18 deletions(-)
--
1.7.3.4
2
3
[libvirt] RFC: exposing a config setting to force vhost-net support on/off
by Laine Stump 07 Jan '11
by Laine Stump 07 Jan '11
07 Jan '11
There's a request to allow libvirt to explicitly turn on/off the new
vhost-net feature of virtio network cards. I see a few ways to do it,
and am looking for opinions on which is best.
(For the uninitiated, vhost-net is a new kernel-based virtio
implementation that saves the overhead of having all network traffic be
handled by the userlevel qemu process.)
The original implementation of vhost-net support (what's been in libvirt
for a few releases now) doesn't expose any knobs to the user - if the
vhost-net kernel module is loaded, libvirt uses it for all virtio
network devices of all newly created guests, and if the kernel module
isn't loaded, it reverts to using the old user-level virtio.
It's simple enough to put a bit of extra logic at the point where we
make that decision. I see 3 possibilities:
1) default - use vhost-net if it's loaded, don't if it isn't (current
behavior)
2) require - use vhost-net if it's loaded, and refuse to start the guest
if it isn't (for those who want
to be 100% sure they're using it)
3) disable - don't use vhost-net, whether or not it's loaded (to disable
it, eg in case a compatibility problem
is found between vhost-net and some particular guest)
The question is how to describe that in the XML. Here's what a virtio
network interface might look like currently:
<devices>
<interface type='network'>
<source network='default'/>
<model type='virtio'/>
</interface>
</devices>
1) One possibility (the simplest) would be to add an optional attribute
to <model>:
<devices>
<interface type='network'>
<source network='default'/>
<model type='virtio' vhost='default|require|disable'/> (or 'default|on|off' ?)
</interface>
</devices>
or maybe:
<devices>
<interface type='network'>
<source network='default'/>
<model type='virtio' mode='default|kernel|user'/>
</interface>
</devices>
2) Another possibility would be to define a new sub-element of<interface>, called "<driver>", similar
to what's done in the storage device XML. In the future, other backend driver-related items could be placed there:
<devices>
<interface type='network'>
<source network='default'/>
<model type='virtio'/>
<driver vhost='default|require|disable'/> (or "mode='default|kernel|user'")
</interface>
</devices>
3) A third method, which might make the XML file look less ugly if, in the future, there were *many*
more configurable items for interface backends (this one was inspired by the<memtune> element):
<devices>
<interface type='network'>
<source network='default'/>
<model type='virtio'/>
<driver>
<vhost>default|require|disable</vhost>
</driver>
</interface>
</devices>
(we *might* want to consider naming it something other than "<driver>", eg"<tune>" or something like that, so that
more things could be put in there. The problem with that is I don't really consider vhost a true "tunable", since
as far as I'm aware, it's always faster to use kernel-level virtio than to bounce everything up to userspace; the
setting in question is intended more for testing purposes, or to alleviate unforeseen compatibility problems).
So, any opinions on these three possibilities (or an undescribed 4th?) What about the naming? I'm open to suggestions!
4
6
Hi,
attached patchs adds AM_MAINTAINER_MODE and keeps it enabled by
defaults. This allows downstreams to turn it of via:
./configure --disable-maintainer-mode
as discussed in
https://www.redhat.com/archives/virt-tools-list/2010-October/msg00049.html
O.k. to apply?
Cheers,
-- Guido
2
2
[libvirt] [PATCH] esx: Move occurrence check into esxVI_LookupObjectContentByType
by Matthias Bolte 07 Jan '11
by Matthias Bolte 07 Jan '11
07 Jan '11
This simplifies the callers of esxVI_LookupObjectContentByType.
---
As we're currently in feature freeze this patch is meant to be
applied after the next release.
Matthias
src/esx/esx_driver.c | 19 ++------
src/esx/esx_vi.c | 128 ++++++++++++++++++++++++-------------------------
src/esx/esx_vi.h | 3 +-
3 files changed, 69 insertions(+), 81 deletions(-)
diff --git a/src/esx/esx_driver.c b/src/esx/esx_driver.c
index 6ada663..b582082 100644
--- a/src/esx/esx_driver.c
+++ b/src/esx/esx_driver.c
@@ -3231,13 +3231,7 @@ esxDomainGetAutostart(virDomainPtr domain, int *autostart)
(priv->primary,
priv->primary->hostSystem->configManager->autoStartManager,
"HostAutoStartManager", propertyNameList,
- &hostAutoStartManager) < 0) {
- goto cleanup;
- }
-
- if (hostAutoStartManager == NULL) {
- ESX_ERROR(VIR_ERR_INTERNAL_ERROR, "%s",
- _("Could not retrieve the HostAutoStartManager object"));
+ &hostAutoStartManager, esxVI_Occurrence_RequiredItem) < 0) {
goto cleanup;
}
@@ -3275,13 +3269,7 @@ esxDomainGetAutostart(virDomainPtr domain, int *autostart)
(priv->primary,
priv->primary->hostSystem->configManager->autoStartManager,
"HostAutoStartManager", propertyNameList,
- &hostAutoStartManager) < 0) {
- goto cleanup;
- }
-
- if (hostAutoStartManager == NULL) {
- ESX_ERROR(VIR_ERR_INTERNAL_ERROR, "%s",
- _("Could not retrieve the HostAutoStartManager object"));
+ &hostAutoStartManager, esxVI_Occurrence_RequiredItem) < 0) {
goto cleanup;
}
@@ -3912,7 +3900,8 @@ esxNodeGetFreeMemory(virConnectPtr conn)
esxVI_LookupObjectContentByType(priv->primary,
priv->primary->computeResource->resourcePool,
"ResourcePool", propertyNameList,
- &resourcePool) < 0) {
+ &resourcePool,
+ esxVI_Occurrence_RequiredItem) < 0) {
goto cleanup;
}
diff --git a/src/esx/esx_vi.c b/src/esx/esx_vi.c
index 9eca9f4..7f4447c 100644
--- a/src/esx/esx_vi.c
+++ b/src/esx/esx_vi.c
@@ -499,13 +499,8 @@ esxVI_Context_LookupObjectsByPath(esxVI_Context *ctx,
"hostFolder\0") < 0 ||
esxVI_LookupObjectContentByType(ctx, ctx->service->rootFolder,
"Datacenter", propertyNameList,
- &datacenterList) < 0) {
- goto cleanup;
- }
-
- if (datacenterList == NULL) {
- ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR, "%s",
- _("Could not retrieve datacenter list"));
+ &datacenterList,
+ esxVI_Occurrence_RequiredList) < 0) {
goto cleanup;
}
@@ -548,13 +543,8 @@ esxVI_Context_LookupObjectsByPath(esxVI_Context *ctx,
"resourcePool\0") < 0 ||
esxVI_LookupObjectContentByType(ctx, ctx->datacenter->hostFolder,
"ComputeResource", propertyNameList,
- &computeResourceList) < 0) {
- goto cleanup;
- }
-
- if (computeResourceList == NULL) {
- ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR, "%s",
- _("Could not retrieve compute resource list"));
+ &computeResourceList,
+ esxVI_Occurrence_RequiredList) < 0) {
goto cleanup;
}
@@ -610,13 +600,8 @@ esxVI_Context_LookupObjectsByPath(esxVI_Context *ctx,
"configManager\0") < 0 ||
esxVI_LookupObjectContentByType(ctx, ctx->computeResource->_reference,
"HostSystem", propertyNameList,
- &hostSystemList) < 0) {
- goto cleanup;
- }
-
- if (hostSystemList == NULL) {
- ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR, "%s",
- _("Could not retrieve host system list"));
+ &hostSystemList,
+ esxVI_Occurrence_RequiredList) < 0) {
goto cleanup;
}
@@ -687,17 +672,9 @@ esxVI_Context_LookupObjectsByHostSystemIp(esxVI_Context *ctx,
&managedObjectReference) < 0 ||
esxVI_LookupObjectContentByType(ctx, managedObjectReference,
"HostSystem", propertyNameList,
- &hostSystem) < 0) {
- goto cleanup;
- }
-
- if (hostSystem == NULL) {
- ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR, "%s",
- _("Could not retrieve host system"));
- goto cleanup;
- }
-
- if (esxVI_HostSystem_CastFromObjectContent(hostSystem,
+ &hostSystem,
+ esxVI_Occurrence_RequiredItem) < 0 ||
+ esxVI_HostSystem_CastFromObjectContent(hostSystem,
&ctx->hostSystem) < 0) {
goto cleanup;
}
@@ -711,17 +688,9 @@ esxVI_Context_LookupObjectsByHostSystemIp(esxVI_Context *ctx,
"resourcePool\0") < 0 ||
esxVI_LookupObjectContentByType(ctx, hostSystem->obj,
"ComputeResource", propertyNameList,
- &computeResource) < 0) {
- goto cleanup;
- }
-
- if (computeResource == NULL) {
- ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR, "%s",
- _("Could not retrieve compute resource of host system"));
- goto cleanup;
- }
-
- if (esxVI_ComputeResource_CastFromObjectContent(computeResource,
+ &computeResource,
+ esxVI_Occurrence_RequiredItem) < 0 ||
+ esxVI_ComputeResource_CastFromObjectContent(computeResource,
&ctx->computeResource) < 0) {
goto cleanup;
}
@@ -735,17 +704,9 @@ esxVI_Context_LookupObjectsByHostSystemIp(esxVI_Context *ctx,
"hostFolder\0") < 0 ||
esxVI_LookupObjectContentByType(ctx, computeResource->obj,
"Datacenter", propertyNameList,
- &datacenter) < 0) {
- goto cleanup;
- }
-
- if (datacenter == NULL) {
- ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR, "%s",
- _("Could not retrieve datacenter of compute resource"));
- goto cleanup;
- }
-
- if (esxVI_Datacenter_CastFromObjectContent(datacenter,
+ &datacenter,
+ esxVI_Occurrence_RequiredItem) < 0 ||
+ esxVI_Datacenter_CastFromObjectContent(datacenter,
&ctx->datacenter) < 0) {
goto cleanup;
}
@@ -1586,7 +1547,8 @@ esxVI_EnsureSession(esxVI_Context *ctx)
"currentSession") < 0 ||
esxVI_LookupObjectContentByType(ctx, ctx->service->sessionManager,
"SessionManager", propertyNameList,
- &sessionManager) < 0) {
+ &sessionManager,
+ esxVI_Occurrence_RequiredItem) < 0) {
goto cleanup;
}
@@ -1636,7 +1598,8 @@ esxVI_LookupObjectContentByType(esxVI_Context *ctx,
esxVI_ManagedObjectReference *root,
const char *type,
esxVI_String *propertyNameList,
- esxVI_ObjectContent **objectContentList)
+ esxVI_ObjectContent **objectContentList,
+ esxVI_Occurrence occurrence)
{
int result = -1;
esxVI_ObjectSpec *objectSpec = NULL;
@@ -1710,12 +1673,41 @@ esxVI_LookupObjectContentByType(esxVI_Context *ctx,
esxVI_PropertySpec_AppendToList(&propertyFilterSpec->propSet,
propertySpec) < 0 ||
esxVI_ObjectSpec_AppendToList(&propertyFilterSpec->objectSet,
- objectSpec) < 0) {
+ objectSpec) < 0 ||
+ esxVI_RetrieveProperties(ctx, propertyFilterSpec,
+ objectContentList) < 0) {
goto cleanup;
}
- result = esxVI_RetrieveProperties(ctx, propertyFilterSpec,
- objectContentList);
+ if (objectContentList == NULL) {
+ switch (occurrence) {
+ case esxVI_Occurrence_OptionalItem:
+ case esxVI_Occurrence_OptionalList:
+ result = 0;
+ break;
+
+ case esxVI_Occurrence_RequiredItem:
+ ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR,
+ _("Could not lookup '%s' from '%s'"),
+ type, root->type);
+ break;
+
+ case esxVI_Occurrence_RequiredList:
+ ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR,
+ _("Could not lookup '%s' list from '%s'"),
+ type, root->type);
+ break;
+
+ default:
+ ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Invalid occurrence value"));
+ break;
+ }
+
+ goto cleanup;
+ }
+
+ result = 0;
cleanup:
/*
@@ -2276,7 +2268,8 @@ esxVI_LookupHostSystemProperties(esxVI_Context *ctx,
{
return esxVI_LookupObjectContentByType(ctx, ctx->hostSystem->_reference,
"HostSystem", propertyNameList,
- hostSystem);
+ hostSystem,
+ esxVI_Occurrence_RequiredItem);
}
@@ -2290,7 +2283,8 @@ esxVI_LookupVirtualMachineList(esxVI_Context *ctx,
* for cluster support */
return esxVI_LookupObjectContentByType(ctx, ctx->hostSystem->_reference,
"VirtualMachine", propertyNameList,
- virtualMachineList);
+ virtualMachineList,
+ esxVI_Occurrence_OptionalList);
}
@@ -2332,7 +2326,8 @@ esxVI_LookupVirtualMachineByUuid(esxVI_Context *ctx, const unsigned char *uuid,
if (esxVI_LookupObjectContentByType(ctx, managedObjectReference,
"VirtualMachine", propertyNameList,
- virtualMachine) < 0) {
+ virtualMachine,
+ esxVI_Occurrence_RequiredItem) < 0) {
goto cleanup;
}
@@ -2475,7 +2470,8 @@ esxVI_LookupDatastoreList(esxVI_Context *ctx, esxVI_String *propertyNameList,
* support */
return esxVI_LookupObjectContentByType(ctx, ctx->hostSystem->_reference,
"Datastore", propertyNameList,
- datastoreList);
+ datastoreList,
+ esxVI_Occurrence_OptionalList);
}
@@ -2654,7 +2650,8 @@ esxVI_LookupDatastoreHostMount(esxVI_Context *ctx,
if (esxVI_String_AppendValueToList(&propertyNameList, "host") < 0 ||
esxVI_LookupObjectContentByType(ctx, datastore, "Datastore",
- propertyNameList, &objectContent) < 0) {
+ propertyNameList, &objectContent,
+ esxVI_Occurrence_RequiredItem) < 0) {
goto cleanup;
}
@@ -2719,7 +2716,8 @@ esxVI_LookupTaskInfoByTask(esxVI_Context *ctx,
if (esxVI_String_AppendValueToList(&propertyNameList, "info") < 0 ||
esxVI_LookupObjectContentByType(ctx, task, "Task", propertyNameList,
- &objectContent) < 0) {
+ &objectContent,
+ esxVI_Occurrence_RequiredItem) < 0) {
goto cleanup;
}
diff --git a/src/esx/esx_vi.h b/src/esx/esx_vi.h
index 553967b..7457751 100644
--- a/src/esx/esx_vi.h
+++ b/src/esx/esx_vi.h
@@ -284,7 +284,8 @@ int esxVI_LookupObjectContentByType(esxVI_Context *ctx,
esxVI_ManagedObjectReference *root,
const char *type,
esxVI_String *propertyNameList,
- esxVI_ObjectContent **objectContentList);
+ esxVI_ObjectContent **objectContentList,
+ esxVI_Occurrence occurrence);
int esxVI_GetManagedEntityStatus
(esxVI_ObjectContent *objectContent, const char *propertyName,
--
1.7.0.4
2
2
07 Jan '11
The current security driver usage requires horrible code like
if (driver->securityDriver &&
driver->securityDriver->domainSetSecurityHostdevLabel &&
driver->securityDriver->domainSetSecurityHostdevLabel(driver->securityDriver,
vm, hostdev) < 0)
This pair of checks for NULL clutters up the code, making the driver
calls 2 lines longer than they really need to be. The goal of the
patchset is to change the calling convention to simply
if (virSecurityManagerSetHostdevLabel(driver->securityDriver,
vm, hostdev) < 0)
The first check for 'driver->securityDriver' being NULL is removed
by introducing a 'no op' security driver that will always be present
if no real driver is enabled. This guarentees driver->securityDriver
!= NULL.
The second check for 'driver->securityDriver->domainSetSecurityHostdevLabel'
being non-NULL is hidden in a new abstraction called virSecurityManager.
This separates the driver callbacks, from main internal API. The addition
of a virSecurityManager object, that is separate from the virSecurityDriver
struct also allows for security drivers to carry state / configuration
information directly. Thus the DAC/Stack drivers from src/qemu which
used to pull config from 'struct qemud_driver' can now be moved into
the 'src/security' directory and store their config directly.
* src/qemu/qemu_conf.h, src/qemu/qemu_driver.c: Update to
use new virSecurityManager APIs
* src/qemu/qemu_security_dac.c, src/qemu/qemu_security_dac.h
src/qemu/qemu_security_stacked.c, src/qemu/qemu_security_stacked.h:
Move into src/security directory
* src/security/security_stack.c, src/security/security_stack.h,
src/security/security_dac.c, src/security/security_dac.h: Generic
versions of previous QEMU specific drivers
* src/security/security_apparmor.c, src/security/security_apparmor.h,
src/security/security_driver.c, src/security/security_driver.h,
src/security/security_selinux.c, src/security/security_selinux.h:
Update to take virSecurityManagerPtr object as the first param
in all callbacks
* src/security/security_nop.c, src/security/security_nop.h: Stub
implementation of all security driver APIs.
* src/security/security_manager.h, src/security/security_manager.c:
New internal API for invoking security drivers
---
src/Makefile.am | 12 +-
src/libvirt_private.syms | 33 ++-
src/qemu/qemu_conf.h | 6 +-
src/qemu/qemu_driver.c | 163 ++++------
src/qemu/qemu_hotplug.c | 84 ++---
src/qemu/qemu_security_dac.c | 576 -------------------------------
src/qemu/qemu_security_dac.h | 22 --
src/qemu/qemu_security_stacked.c | 418 ----------------------
src/qemu/qemu_security_stacked.h | 22 --
src/security/security_apparmor.c | 152 ++++++---
src/security/security_apparmor.h | 2 +
src/security/security_dac.c | 703 ++++++++++++++++++++++++++++++++++++++
src/security/security_dac.h | 27 ++
src/security/security_driver.c | 116 ++-----
src/security/security_driver.h | 95 +++---
src/security/security_manager.c | 291 ++++++++++++++++
src/security/security_manager.h | 74 ++++
src/security/security_nop.c | 168 +++++++++
src/security/security_nop.h | 17 +
src/security/security_selinux.c | 145 +++++---
src/security/security_selinux.h | 2 +-
src/security/security_stack.c | 383 +++++++++++++++++++++
src/security/security_stack.h | 24 ++
23 files changed, 2067 insertions(+), 1468 deletions(-)
delete mode 100644 src/qemu/qemu_security_dac.c
delete mode 100644 src/qemu/qemu_security_dac.h
delete mode 100644 src/qemu/qemu_security_stacked.c
delete mode 100644 src/qemu/qemu_security_stacked.h
create mode 100644 src/security/security_dac.c
create mode 100644 src/security/security_dac.h
create mode 100644 src/security/security_manager.c
create mode 100644 src/security/security_manager.h
create mode 100644 src/security/security_nop.c
create mode 100644 src/security/security_nop.h
create mode 100644 src/security/security_stack.c
create mode 100644 src/security/security_stack.h
diff --git a/src/Makefile.am b/src/Makefile.am
index c13724a..f8b8434 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -288,11 +288,7 @@ QEMU_DRIVER_SOURCES = \
qemu/qemu_monitor_json.h \
qemu/qemu_driver.c qemu/qemu_driver.h \
qemu/qemu_bridge_filter.c \
- qemu/qemu_bridge_filter.h \
- qemu/qemu_security_stacked.h \
- qemu/qemu_security_stacked.c \
- qemu/qemu_security_dac.h \
- qemu/qemu_security_dac.c
+ qemu/qemu_bridge_filter.h
XENAPI_DRIVER_SOURCES = \
xenapi/xenapi_driver.c xenapi/xenapi_driver.h \
@@ -390,7 +386,11 @@ NWFILTER_DRIVER_SOURCES = \
# Security framework and drivers for various models
SECURITY_DRIVER_SOURCES = \
- security/security_driver.h security/security_driver.c
+ security/security_driver.h security/security_driver.c \
+ security/security_nop.h security/security_nop.c \
+ security/security_stack.h security/security_stack.c \
+ security/security_dac.h security/security_dac.c \
+ security/security_manager.h security/security_manager.c
SECURITY_DRIVER_SELINUX_SOURCES = \
security/security_selinux.h security/security_selinux.c
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 19e581c..279559b 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -701,13 +701,32 @@ virSecretDefParseFile;
virSecretDefParseString;
-# security.h
-virSecurityDriverGetDOI;
-virSecurityDriverGetModel;
-virSecurityDriverInit;
-virSecurityDriverSetDOI;
-virSecurityDriverStartup;
-virSecurityDriverVerify;
+# security_driver.h
+virSecurityDriverLookup;
+
+
+# security_manager.h
+virSecurityManagerClearSocketLabel;
+virSecurityManagerGenLabel;
+virSecurityManagerGetDOI;
+virSecurityManagerGetModel;
+virSecurityManagerGetProcessLabel;
+virSecurityManagerNew;
+virSecurityManagerNewStack;
+virSecurityManagerNewDAC;
+virSecurityManagerReleaseLabel;
+virSecurityManagerReserveLabel;
+virSecurityManagerRestoreImageLabel;
+virSecurityManagerRestoreAllLabel;
+virSecurityManagerRestoreHostdevLabel;
+virSecurityManagerRestoreSavedStateLabel;
+virSecurityManagerSetAllLabel;
+virSecurityManagerSetImageLabel;
+virSecurityManagerSetHostdevLabel;
+virSecurityManagerSetProcessLabel;
+virSecurityManagerSetSavedStateLabel;
+virSecurityManagerSetSocketLabel;
+virSecurityManagerVerify;
# storage_conf.h
diff --git a/src/qemu/qemu_conf.h b/src/qemu/qemu_conf.h
index 83ddedd..5a5748b 100644
--- a/src/qemu/qemu_conf.h
+++ b/src/qemu/qemu_conf.h
@@ -35,7 +35,7 @@
# include "domain_conf.h"
# include "domain_event.h"
# include "threads.h"
-# include "security/security_driver.h"
+# include "security/security_manager.h"
# include "cgroup.h"
# include "pci.h"
# include "cpu_conf.h"
@@ -114,9 +114,7 @@ struct qemud_driver {
int domainEventDispatching;
char *securityDriverName;
- virSecurityDriverPtr securityDriver;
- virSecurityDriverPtr securityPrimaryDriver;
- virSecurityDriverPtr securitySecondaryDriver;
+ virSecurityManagerPtr securityManager;
char *saveImageFormat;
char *dumpImageFormat;
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index e915705..0f84bb2 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -73,8 +73,6 @@
#include "pci.h"
#include "hostusb.h"
#include "processinfo.h"
-#include "qemu_security_stacked.h"
-#include "qemu_security_dac.h"
#include "libvirt_internal.h"
#include "xml.h"
#include "cpu/cpu.h"
@@ -861,10 +859,7 @@ qemuConnectMonitor(struct qemud_driver *driver, virDomainObjPtr vm)
qemuDomainObjPrivatePtr priv = vm->privateData;
int ret = -1;
- if (driver->securityDriver &&
- driver->securityDriver->domainSetSecuritySocketLabel &&
- driver->securityDriver->domainSetSecuritySocketLabel
- (driver->securityDriver,vm) < 0) {
+ if (virSecurityManagerSetSocketLabel(driver->securityManager, vm) < 0) {
VIR_ERROR(_("Failed to set security context for monitor for %s"),
vm->def->name);
goto error;
@@ -882,10 +877,7 @@ qemuConnectMonitor(struct qemud_driver *driver, virDomainObjPtr vm)
if (priv->mon == NULL)
virDomainObjUnref(vm);
- if (driver->securityDriver &&
- driver->securityDriver->domainClearSecuritySocketLabel &&
- driver->securityDriver->domainClearSecuritySocketLabel
- (driver->securityDriver,vm) < 0) {
+ if (virSecurityManagerClearSocketLabel(driver->securityManager, vm) < 0) {
VIR_ERROR(_("Failed to clear security context for monitor for %s"),
vm->def->name);
goto error;
@@ -954,10 +946,7 @@ qemuReconnectDomain(void *payload, const char *name ATTRIBUTE_UNUSED, void *opaq
goto error;
}
- if (driver->securityDriver &&
- driver->securityDriver->domainReserveSecurityLabel &&
- driver->securityDriver->domainReserveSecurityLabel(driver->securityDriver,
- obj) < 0)
+ if (virSecurityManagerReserveLabel(driver->securityManager, obj) < 0)
goto error;
if (qemudVMFiltersInstantiate(conn, obj->def))
@@ -995,32 +984,26 @@ qemuReconnectDomains(virConnectPtr conn, struct qemud_driver *driver)
static int
-qemudSecurityInit(struct qemud_driver *qemud_drv)
+qemudSecurityInit(struct qemud_driver *driver)
{
- int ret;
- virSecurityDriverPtr security_drv;
-
- qemuSecurityStackedSetDriver(qemud_drv);
- qemuSecurityDACSetDriver(qemud_drv);
-
- ret = virSecurityDriverStartup(&security_drv,
- qemud_drv->securityDriverName,
- qemud_drv->allowDiskFormatProbing);
- if (ret == -1) {
- VIR_ERROR0(_("Failed to start security driver"));
+ virSecurityManagerPtr mgr = virSecurityManagerNew(driver->securityDriverName,
+ driver->allowDiskFormatProbing);
+ if (!mgr)
return -1;
- }
- /* No primary security driver wanted to be enabled: just setup
- * the DAC driver on its own */
- if (ret == -2) {
- qemud_drv->securityDriver = &qemuDACSecurityDriver;
- VIR_INFO0(_("No security driver available"));
+ if (driver->privileged) {
+ virSecurityManagerPtr dac = virSecurityManagerNewDAC(driver->user,
+ driver->group,
+ driver->allowDiskFormatProbing,
+ driver->dynamicOwnership);
+ if (!dac)
+ return -1;
+
+ if (!(driver->securityManager = virSecurityManagerNewStack(mgr,
+ dac)))
+ return -1;
} else {
- qemud_drv->securityPrimaryDriver = security_drv;
- qemud_drv->securitySecondaryDriver = &qemuDACSecurityDriver;
- qemud_drv->securityDriver = &qemuStackedSecurityDriver;
- VIR_INFO("Initialized security driver %s", security_drv->name);
+ driver->securityManager = mgr;
}
return 0;
@@ -1057,20 +1040,22 @@ qemuCreateCapabilities(virCapsPtr oldcaps,
}
/* Security driver data */
- if (driver->securityPrimaryDriver) {
- const char *doi, *model;
+ const char *doi, *model;
- doi = virSecurityDriverGetDOI(driver->securityPrimaryDriver);
- model = virSecurityDriverGetModel(driver->securityPrimaryDriver);
+ doi = virSecurityManagerGetDOI(driver->securityManager);
+ model = virSecurityManagerGetModel(driver->securityManager);
+ if (STREQ(model, "none")) {
+ model = "";
+ doi = "";
+ }
- if (!(caps->host.secModel.model = strdup(model)))
- goto no_memory;
- if (!(caps->host.secModel.doi = strdup(doi)))
- goto no_memory;
+ if (!(caps->host.secModel.model = strdup(model)))
+ goto no_memory;
+ if (!(caps->host.secModel.doi = strdup(doi)))
+ goto no_memory;
- VIR_DEBUG("Initialized caps for security driver \"%s\" with "
- "DOI \"%s\"", model, doi);
- }
+ VIR_DEBUG("Initialized caps for security driver \"%s\" with "
+ "DOI \"%s\"", model, doi);
return caps;
@@ -1555,7 +1540,6 @@ qemudShutdown(void) {
VIR_FREE(qemu_driver->spicePassword);
VIR_FREE(qemu_driver->hugetlbfs_mount);
VIR_FREE(qemu_driver->hugepage_path);
- VIR_FREE(qemu_driver->securityDriverName);
VIR_FREE(qemu_driver->saveImageFormat);
VIR_FREE(qemu_driver->dumpImageFormat);
@@ -2573,9 +2557,7 @@ static int qemudSecurityHook(void *data) {
if (qemudInitCpuAffinity(h->vm) < 0)
return -1;
- if (h->driver->securityDriver &&
- h->driver->securityDriver->domainSetSecurityProcessLabel &&
- h->driver->securityDriver->domainSetSecurityProcessLabel(h->driver->securityDriver, h->vm) < 0)
+ if (virSecurityManagerSetProcessLabel(h->driver->securityManager, h->vm) < 0)
return -1;
return 0;
@@ -2660,22 +2642,16 @@ static int qemudStartVMDaemon(virConnectPtr conn,
/* If you are using a SecurityDriver with dynamic labelling,
then generate a security label for isolation */
DEBUG0("Generating domain security label (if required)");
- if (driver->securityDriver &&
- driver->securityDriver->domainGenSecurityLabel) {
- ret = driver->securityDriver->domainGenSecurityLabel(driver->securityDriver,
- vm);
- qemuDomainSecurityLabelAudit(vm, ret >= 0);
- if (ret < 0)
- goto cleanup;
+ if (virSecurityManagerGenLabel(driver->securityManager, vm) < 0) {
+ qemuDomainSecurityLabelAudit(vm, false);
+ goto cleanup;
}
+ qemuDomainSecurityLabelAudit(vm, true);
DEBUG0("Generating setting domain security labels (if required)");
- if (driver->securityDriver &&
- driver->securityDriver->domainSetSecurityAllLabel &&
- driver->securityDriver->domainSetSecurityAllLabel(driver->securityDriver,
- vm, stdin_path) < 0) {
+ if (virSecurityManagerSetAllLabel(driver->securityManager,
+ vm, stdin_path) < 0)
goto cleanup;
- }
/* Ensure no historical cgroup for this VM is lying around bogus
* settings */
@@ -3057,14 +3033,9 @@ static void qemudShutdownVMDaemon(struct qemud_driver *driver,
}
/* Reset Security Labels */
- if (driver->securityDriver &&
- driver->securityDriver->domainRestoreSecurityAllLabel)
- driver->securityDriver->domainRestoreSecurityAllLabel(driver->securityDriver,
- vm, migrated);
- if (driver->securityDriver &&
- driver->securityDriver->domainReleaseSecurityLabel)
- driver->securityDriver->domainReleaseSecurityLabel(driver->securityDriver,
- vm);
+ virSecurityManagerRestoreAllLabel(driver->securityManager,
+ vm, migrated);
+ virSecurityManagerReleaseLabel(driver->securityManager, vm);
/* Clear out dynamically assigned labels */
if (vm->def->seclabel.type == VIR_DOMAIN_SECLABEL_DYNAMIC) {
@@ -3568,7 +3539,7 @@ static virDomainPtr qemudDomainCreate(virConnectPtr conn, const char *xml,
VIR_DOMAIN_XML_INACTIVE)))
goto cleanup;
- if (virSecurityDriverVerify(def) < 0)
+ if (virSecurityManagerVerify(driver->securityManager, def) < 0)
goto cleanup;
if (virDomainObjIsDuplicate(&driver->domains, def, 1) < 0)
@@ -4471,10 +4442,8 @@ static int qemudDomainSaveFlag(struct qemud_driver *driver, virDomainPtr dom,
}
if ((!bypassSecurityDriver) &&
- driver->securityDriver &&
- driver->securityDriver->domainSetSavedStateLabel &&
- driver->securityDriver->domainSetSavedStateLabel(driver->securityDriver,
- vm, path) == -1)
+ virSecurityManagerSetSavedStateLabel(driver->securityManager,
+ vm, path) < 0)
goto endjob;
if (header.compressed == QEMUD_SAVE_FORMAT_RAW) {
@@ -4507,10 +4476,8 @@ static int qemudDomainSaveFlag(struct qemud_driver *driver, virDomainPtr dom,
goto endjob;
if ((!bypassSecurityDriver) &&
- driver->securityDriver &&
- driver->securityDriver->domainRestoreSavedStateLabel &&
- driver->securityDriver->domainRestoreSavedStateLabel(driver->securityDriver,
- vm, path) == -1)
+ virSecurityManagerRestoreSavedStateLabel(driver->securityManager,
+ vm, path) < 0)
VIR_WARN("failed to restore save state label on %s", path);
if (cgroup != NULL) {
@@ -4552,10 +4519,8 @@ endjob:
}
if ((!bypassSecurityDriver) &&
- driver->securityDriver &&
- driver->securityDriver->domainRestoreSavedStateLabel &&
- driver->securityDriver->domainRestoreSavedStateLabel(driver->securityDriver,
- vm, path) == -1)
+ virSecurityManagerRestoreSavedStateLabel(driver->securityManager,
+ vm, path) < 0)
VIR_WARN("failed to restore save state label on %s", path);
}
@@ -4779,10 +4744,8 @@ static int doCoreDump(struct qemud_driver *driver,
goto cleanup;
}
- if (driver->securityDriver &&
- driver->securityDriver->domainSetSavedStateLabel &&
- driver->securityDriver->domainSetSavedStateLabel(driver->securityDriver,
- vm, path) == -1)
+ if (virSecurityManagerSetSavedStateLabel(driver->securityManager,
+ vm, path) < 0)
goto cleanup;
qemuDomainObjEnterMonitorWithDriver(driver, vm);
@@ -4814,10 +4777,8 @@ static int doCoreDump(struct qemud_driver *driver,
if (ret < 0)
goto cleanup;
- if (driver->securityDriver &&
- driver->securityDriver->domainRestoreSavedStateLabel &&
- driver->securityDriver->domainRestoreSavedStateLabel(driver->securityDriver,
- vm, path) == -1)
+ if (virSecurityManagerRestoreSavedStateLabel(driver->securityManager,
+ vm, path) < 0)
goto cleanup;
cleanup:
@@ -5434,10 +5395,8 @@ static int qemudDomainGetSecurityLabel(virDomainPtr dom, virSecurityLabelPtr sec
* QEMU monitor hasn't seen SIGHUP/ERR on poll().
*/
if (virDomainObjIsActive(vm)) {
- if (driver->securityDriver &&
- driver->securityDriver->domainGetSecurityProcessLabel &&
- driver->securityDriver->domainGetSecurityProcessLabel(driver->securityDriver,
- vm, seclabel) < 0) {
+ if (virSecurityManagerGetProcessLabel(driver->securityManager,
+ vm, seclabel) < 0) {
qemuReportError(VIR_ERR_INTERNAL_ERROR,
"%s", _("Failed to get security label"));
goto cleanup;
@@ -5461,10 +5420,6 @@ static int qemudNodeGetSecurityModel(virConnectPtr conn,
int ret = 0;
qemuDriverLock(driver);
- if (!driver->securityPrimaryDriver) {
- memset(secmodel, 0, sizeof (*secmodel));
- goto cleanup;
- }
p = driver->caps->host.secModel.model;
if (strlen(p) >= VIR_SECURITY_MODEL_BUFLEN-1) {
@@ -5840,10 +5795,8 @@ qemudDomainSaveImageStartVM(virConnectPtr conn,
ret = 0;
out:
- if (driver->securityDriver &&
- driver->securityDriver->domainRestoreSavedStateLabel &&
- driver->securityDriver->domainRestoreSavedStateLabel(driver->securityDriver,
- vm, path) == -1)
+ if (virSecurityManagerRestoreSavedStateLabel(driver->securityManager,
+ vm, path) < 0)
VIR_WARN("failed to restore save state label on %s", path);
return ret;
@@ -6372,7 +6325,7 @@ static virDomainPtr qemudDomainDefine(virConnectPtr conn, const char *xml) {
VIR_DOMAIN_XML_INACTIVE)))
goto cleanup;
- if (virSecurityDriverVerify(def) < 0)
+ if (virSecurityManagerVerify(driver->securityManager, def) < 0)
goto cleanup;
if ((dupVM = virDomainObjIsDuplicate(&driver->domains, def, 0)) < 0)
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index 827bcaf..1dc036c 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -83,10 +83,8 @@ int qemuDomainChangeEjectableMedia(struct qemud_driver *driver,
return -1;
}
- if (driver->securityDriver &&
- driver->securityDriver->domainSetSecurityImageLabel &&
- driver->securityDriver->domainSetSecurityImageLabel(driver->securityDriver,
- vm, disk) < 0)
+ if (virSecurityManagerSetImageLabel(driver->securityManager,
+ vm, disk) < 0)
return -1;
if (!(driveAlias = qemuDeviceDriveHostAlias(origdisk, qemuCmdFlags)))
@@ -115,10 +113,8 @@ int qemuDomainChangeEjectableMedia(struct qemud_driver *driver,
if (ret < 0)
goto error;
- if (driver->securityDriver &&
- driver->securityDriver->domainRestoreSecurityImageLabel &&
- driver->securityDriver->domainRestoreSecurityImageLabel(driver->securityDriver,
- vm, origdisk) < 0)
+ if (virSecurityManagerRestoreImageLabel(driver->securityManager,
+ vm, origdisk) < 0)
VIR_WARN("Unable to restore security label on ejected image %s", origdisk->src);
VIR_FREE(origdisk->src);
@@ -134,10 +130,8 @@ int qemuDomainChangeEjectableMedia(struct qemud_driver *driver,
error:
VIR_FREE(driveAlias);
- if (driver->securityDriver &&
- driver->securityDriver->domainRestoreSecurityImageLabel &&
- driver->securityDriver->domainRestoreSecurityImageLabel(driver->securityDriver,
- vm, disk) < 0)
+ if (virSecurityManagerRestoreImageLabel(driver->securityManager,
+ vm, disk) < 0)
VIR_WARN("Unable to restore security label on new media %s", disk->src);
return -1;
}
@@ -162,10 +156,8 @@ int qemuDomainAttachPciDiskDevice(struct qemud_driver *driver,
}
}
- if (driver->securityDriver &&
- driver->securityDriver->domainSetSecurityImageLabel &&
- driver->securityDriver->domainSetSecurityImageLabel(driver->securityDriver,
- vm, disk) < 0)
+ if (virSecurityManagerSetImageLabel(driver->securityManager,
+ vm, disk) < 0)
return -1;
if (qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE) {
@@ -232,10 +224,8 @@ error:
qemuDomainPCIAddressReleaseAddr(priv->pciaddrs, &disk->info) < 0)
VIR_WARN("Unable to release PCI address on %s", disk->src);
- if (driver->securityDriver &&
- driver->securityDriver->domainRestoreSecurityImageLabel &&
- driver->securityDriver->domainRestoreSecurityImageLabel(driver->securityDriver,
- vm, disk) < 0)
+ if (virSecurityManagerRestoreImageLabel(driver->securityManager,
+ vm, disk) < 0)
VIR_WARN("Unable to restore security label on %s", disk->src);
return -1;
@@ -375,10 +365,8 @@ int qemuDomainAttachSCSIDisk(struct qemud_driver *driver,
}
- if (driver->securityDriver &&
- driver->securityDriver->domainSetSecurityImageLabel &&
- driver->securityDriver->domainSetSecurityImageLabel(driver->securityDriver,
- vm, disk) < 0)
+ if (virSecurityManagerSetImageLabel(driver->securityManager,
+ vm, disk) < 0)
return -1;
/* We should have an address already, so make sure */
@@ -464,10 +452,8 @@ error:
VIR_FREE(devstr);
VIR_FREE(drivestr);
- if (driver->securityDriver &&
- driver->securityDriver->domainRestoreSecurityImageLabel &&
- driver->securityDriver->domainRestoreSecurityImageLabel(driver->securityDriver,
- vm, disk) < 0)
+ if (virSecurityManagerRestoreImageLabel(driver->securityManager,
+ vm, disk) < 0)
VIR_WARN("Unable to restore security label on %s", disk->src);
return -1;
@@ -492,10 +478,8 @@ int qemuDomainAttachUsbMassstorageDevice(struct qemud_driver *driver,
}
}
- if (driver->securityDriver &&
- driver->securityDriver->domainSetSecurityImageLabel &&
- driver->securityDriver->domainSetSecurityImageLabel(driver->securityDriver,
- vm, disk) < 0)
+ if (virSecurityManagerSetImageLabel(driver->securityManager,
+ vm, disk) < 0)
return -1;
if (!disk->src) {
@@ -551,10 +535,8 @@ error:
VIR_FREE(devstr);
VIR_FREE(drivestr);
- if (driver->securityDriver &&
- driver->securityDriver->domainRestoreSecurityImageLabel &&
- driver->securityDriver->domainRestoreSecurityImageLabel(driver->securityDriver,
- vm, disk) < 0)
+ if (virSecurityManagerRestoreImageLabel(driver->securityManager,
+ vm, disk) < 0)
VIR_WARN("Unable to restore security label on %s", disk->src);
return -1;
@@ -979,10 +961,8 @@ int qemuDomainAttachHostDevice(struct qemud_driver *driver,
}
- if (driver->securityDriver &&
- driver->securityDriver->domainSetSecurityHostdevLabel &&
- driver->securityDriver->domainSetSecurityHostdevLabel(driver->securityDriver,
- vm, hostdev) < 0)
+ if (virSecurityManagerSetHostdevLabel(driver->securityManager,
+ vm, hostdev) < 0)
return -1;
switch (hostdev->source.subsys.type) {
@@ -1008,10 +988,8 @@ int qemuDomainAttachHostDevice(struct qemud_driver *driver,
return 0;
error:
- if (driver->securityDriver &&
- driver->securityDriver->domainRestoreSecurityHostdevLabel &&
- driver->securityDriver->domainRestoreSecurityHostdevLabel(driver->securityDriver,
- vm, hostdev) < 0)
+ if (virSecurityManagerRestoreHostdevLabel(driver->securityManager,
+ vm, hostdev) < 0)
VIR_WARN0("Unable to restore host device labelling on hotplug fail");
return -1;
@@ -1183,10 +1161,8 @@ int qemuDomainDetachPciDiskDevice(struct qemud_driver *driver,
virDomainDiskDefFree(detach);
- if (driver->securityDriver &&
- driver->securityDriver->domainRestoreSecurityImageLabel &&
- driver->securityDriver->domainRestoreSecurityImageLabel(driver->securityDriver,
- vm, dev->data.disk) < 0)
+ if (virSecurityManagerRestoreImageLabel(driver->securityManager,
+ vm, dev->data.disk) < 0)
VIR_WARN("Unable to restore security label on %s", dev->data.disk->src);
if (cgroup != NULL) {
@@ -1263,10 +1239,8 @@ int qemuDomainDetachSCSIDiskDevice(struct qemud_driver *driver,
virDomainDiskDefFree(detach);
- if (driver->securityDriver &&
- driver->securityDriver->domainRestoreSecurityImageLabel &&
- driver->securityDriver->domainRestoreSecurityImageLabel(driver->securityDriver,
- vm, dev->data.disk) < 0)
+ if (virSecurityManagerRestoreImageLabel(driver->securityManager,
+ vm, dev->data.disk) < 0)
VIR_WARN("Unable to restore security label on %s", dev->data.disk->src);
if (cgroup != NULL) {
@@ -1699,10 +1673,8 @@ int qemuDomainDetachHostDevice(struct qemud_driver *driver,
return -1;
}
- if (driver->securityDriver &&
- driver->securityDriver->domainRestoreSecurityHostdevLabel &&
- driver->securityDriver->domainRestoreSecurityHostdevLabel(driver->securityDriver,
- vm, dev->data.hostdev) < 0)
+ if (virSecurityManagerRestoreHostdevLabel(driver->securityManager,
+ vm, dev->data.hostdev) < 0)
VIR_WARN0("Failed to restore host device labelling");
return ret;
diff --git a/src/qemu/qemu_security_dac.c b/src/qemu/qemu_security_dac.c
deleted file mode 100644
index 6b6170a..0000000
--- a/src/qemu/qemu_security_dac.c
+++ /dev/null
@@ -1,576 +0,0 @@
-/*
- * Copyright (C) 2010 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.
- *
- * QEMU POSIX DAC security driver
- */
-#include <config.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-
-#include "qemu_security_dac.h"
-#include "qemu_conf.h"
-#include "datatypes.h"
-#include "virterror_internal.h"
-#include "util.h"
-#include "memory.h"
-#include "logging.h"
-#include "pci.h"
-#include "hostusb.h"
-#include "storage_file.h"
-
-#define VIR_FROM_THIS VIR_FROM_QEMU
-
-static struct qemud_driver *driver;
-
-void qemuSecurityDACSetDriver(struct qemud_driver *newdriver)
-{
- driver = newdriver;
-}
-
-
-static int
-qemuSecurityDACSetOwnership(const char *path, int uid, int gid)
-{
- VIR_INFO("Setting DAC user and group on '%s' to '%d:%d'", path, uid, gid);
-
- if (chown(path, uid, gid) < 0) {
- struct stat sb;
- int chown_errno = errno;
-
- if (stat(path, &sb) >= 0) {
- if (sb.st_uid == uid &&
- sb.st_gid == gid) {
- /* It's alright, there's nothing to change anyway. */
- return 0;
- }
- }
-
- if (chown_errno == EOPNOTSUPP) {
- VIR_INFO("Setting user and group to '%d:%d' on '%s' not supported by filesystem",
- uid, gid, path);
- } else if (chown_errno == EPERM) {
- VIR_INFO("Setting user and group to '%d:%d' on '%s' not permitted",
- uid, gid, path);
- } else if (chown_errno == EROFS) {
- VIR_INFO("Setting user and group to '%d:%d' on '%s' not possible on readonly filesystem",
- uid, gid, path);
- } else {
- virReportSystemError(chown_errno,
- _("unable to set user and group to '%d:%d' on '%s'"),
- uid, gid, path);
- return -1;
- }
- }
- return 0;
-}
-
-static int
-qemuSecurityDACRestoreSecurityFileLabel(const char *path)
-{
- struct stat buf;
- int rc = -1;
- char *newpath = NULL;
-
- VIR_INFO("Restoring DAC user and group on '%s'", path);
-
- if (virFileResolveLink(path, &newpath) < 0) {
- virReportSystemError(errno,
- _("cannot resolve symlink %s"), path);
- goto err;
- }
-
- if (stat(newpath, &buf) != 0)
- goto err;
-
- /* XXX record previous ownership */
- rc = qemuSecurityDACSetOwnership(newpath, 0, 0);
-
-err:
- VIR_FREE(newpath);
- return rc;
-}
-
-
-static int
-qemuSecurityDACSetSecurityFileLabel(virDomainDiskDefPtr disk ATTRIBUTE_UNUSED,
- const char *path,
- size_t depth ATTRIBUTE_UNUSED,
- void *opaque ATTRIBUTE_UNUSED)
-{
- return qemuSecurityDACSetOwnership(path, driver->user, driver->group);
-}
-
-
-static int
-qemuSecurityDACSetSecurityImageLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
- virDomainObjPtr vm ATTRIBUTE_UNUSED,
- virDomainDiskDefPtr disk)
-
-{
- if (!driver->privileged || !driver->dynamicOwnership)
- return 0;
-
- return virDomainDiskDefForeachPath(disk,
- driver->allowDiskFormatProbing,
- false,
- qemuSecurityDACSetSecurityFileLabel,
- NULL);
-}
-
-
-static int
-qemuSecurityDACRestoreSecurityImageLabelInt(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
- virDomainObjPtr vm ATTRIBUTE_UNUSED,
- virDomainDiskDefPtr disk,
- int migrated)
-{
- if (!driver->privileged || !driver->dynamicOwnership)
- return 0;
-
- /* Don't restore labels on readoly/shared disks, because
- * other VMs may still be accessing these
- * Alternatively we could iterate over all running
- * domains and try to figure out if it is in use, but
- * this would not work for clustered filesystems, since
- * we can't see running VMs using the file on other nodes
- * Safest bet is thus to skip the restore step.
- */
- if (disk->readonly || disk->shared)
- return 0;
-
- if (!disk->src || disk->type == VIR_DOMAIN_DISK_TYPE_NETWORK)
- return 0;
-
- /* If we have a shared FS & doing migrated, we must not
- * change ownership, because that kills access on the
- * destination host which is sub-optimal for the guest
- * VM's I/O attempts :-)
- */
- if (migrated) {
- int rc = virStorageFileIsSharedFS(disk->src);
- if (rc < 0)
- return -1;
- if (rc == 1) {
- VIR_DEBUG("Skipping image label restore on %s because FS is shared",
- disk->src);
- return 0;
- }
- }
-
- return qemuSecurityDACRestoreSecurityFileLabel(disk->src);
-}
-
-
-static int
-qemuSecurityDACRestoreSecurityImageLabel(virSecurityDriverPtr drv,
- virDomainObjPtr vm,
- virDomainDiskDefPtr disk)
-{
- return qemuSecurityDACRestoreSecurityImageLabelInt(drv, vm, disk, 0);
-}
-
-
-static int
-qemuSecurityDACSetSecurityPCILabel(pciDevice *dev ATTRIBUTE_UNUSED,
- const char *file,
- void *opaque ATTRIBUTE_UNUSED)
-{
- return qemuSecurityDACSetOwnership(file, driver->user, driver->group);
-}
-
-
-static int
-qemuSecurityDACSetSecurityUSBLabel(usbDevice *dev ATTRIBUTE_UNUSED,
- const char *file,
- void *opaque ATTRIBUTE_UNUSED)
-{
- return qemuSecurityDACSetOwnership(file, driver->user, driver->group);
-}
-
-
-static int
-qemuSecurityDACSetSecurityHostdevLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
- virDomainObjPtr vm,
- virDomainHostdevDefPtr dev)
-
-{
- int ret = -1;
-
- if (!driver->privileged || !driver->dynamicOwnership)
- return 0;
-
- if (dev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS)
- return 0;
-
- switch (dev->source.subsys.type) {
- case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB: {
- usbDevice *usb = usbGetDevice(dev->source.subsys.u.usb.bus,
- dev->source.subsys.u.usb.device);
-
- if (!usb)
- goto done;
-
- ret = usbDeviceFileIterate(usb, qemuSecurityDACSetSecurityUSBLabel, vm);
- usbFreeDevice(usb);
- break;
- }
-
- case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI: {
- pciDevice *pci = pciGetDevice(dev->source.subsys.u.pci.domain,
- dev->source.subsys.u.pci.bus,
- dev->source.subsys.u.pci.slot,
- dev->source.subsys.u.pci.function);
-
- if (!pci)
- goto done;
-
- ret = pciDeviceFileIterate(pci, qemuSecurityDACSetSecurityPCILabel, vm);
- pciFreeDevice(pci);
-
- break;
- }
-
- default:
- ret = 0;
- break;
- }
-
-done:
- return ret;
-}
-
-
-static int
-qemuSecurityDACRestoreSecurityPCILabel(pciDevice *dev ATTRIBUTE_UNUSED,
- const char *file,
- void *opaque ATTRIBUTE_UNUSED)
-{
- return qemuSecurityDACRestoreSecurityFileLabel(file);
-}
-
-
-static int
-qemuSecurityDACRestoreSecurityUSBLabel(usbDevice *dev ATTRIBUTE_UNUSED,
- const char *file,
- void *opaque ATTRIBUTE_UNUSED)
-{
- return qemuSecurityDACRestoreSecurityFileLabel(file);
-}
-
-
-static int
-qemuSecurityDACRestoreSecurityHostdevLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
- virDomainObjPtr vm ATTRIBUTE_UNUSED,
- virDomainHostdevDefPtr dev)
-
-{
- int ret = -1;
-
- if (!driver->privileged || !driver->dynamicOwnership)
- return 0;
-
- if (dev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS)
- return 0;
-
- switch (dev->source.subsys.type) {
- case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB: {
- usbDevice *usb = usbGetDevice(dev->source.subsys.u.usb.bus,
- dev->source.subsys.u.usb.device);
-
- if (!usb)
- goto done;
-
- ret = usbDeviceFileIterate(usb, qemuSecurityDACRestoreSecurityUSBLabel, NULL);
- usbFreeDevice(usb);
-
- break;
- }
-
- case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI: {
- pciDevice *pci = pciGetDevice(dev->source.subsys.u.pci.domain,
- dev->source.subsys.u.pci.bus,
- dev->source.subsys.u.pci.slot,
- dev->source.subsys.u.pci.function);
-
- if (!pci)
- goto done;
-
- ret = pciDeviceFileIterate(pci, qemuSecurityDACRestoreSecurityPCILabel, NULL);
- pciFreeDevice(pci);
-
- break;
- }
-
- default:
- ret = 0;
- break;
- }
-
-done:
- return ret;
-}
-
-
-static int
-qemuSecurityDACSetChardevLabel(virDomainObjPtr vm,
- virDomainChrDefPtr dev)
-
-{
- const virSecurityLabelDefPtr secdef = &vm->def->seclabel;
- char *in = NULL, *out = NULL;
- int ret = -1;
-
- if (secdef->type == VIR_DOMAIN_SECLABEL_STATIC)
- return 0;
-
- switch (dev->type) {
- case VIR_DOMAIN_CHR_TYPE_DEV:
- case VIR_DOMAIN_CHR_TYPE_FILE:
- ret = qemuSecurityDACSetOwnership(dev->data.file.path, driver->user, driver->group);
- break;
-
- case VIR_DOMAIN_CHR_TYPE_PIPE:
- if ((virAsprintf(&in, "%s.in", dev->data.file.path) < 0) ||
- (virAsprintf(&out, "%s.out", dev->data.file.path) < 0)) {
- virReportOOMError();
- goto done;
- }
- if ((qemuSecurityDACSetOwnership(in, driver->user, driver->group) < 0) ||
- (qemuSecurityDACSetOwnership(out, driver->user, driver->group) < 0))
- goto done;
- ret = 0;
- break;
-
- default:
- ret = 0;
- break;
- }
-
-done:
- VIR_FREE(in);
- VIR_FREE(out);
- return ret;
-}
-
-static int
-qemuSecurityDACRestoreChardevLabel(virDomainObjPtr vm,
- virDomainChrDefPtr dev)
-
-{
- const virSecurityLabelDefPtr secdef = &vm->def->seclabel;
- char *in = NULL, *out = NULL;
- int ret = -1;
-
- if (secdef->type == VIR_DOMAIN_SECLABEL_STATIC)
- return 0;
-
- switch (dev->type) {
- case VIR_DOMAIN_CHR_TYPE_DEV:
- case VIR_DOMAIN_CHR_TYPE_FILE:
- ret = qemuSecurityDACRestoreSecurityFileLabel(dev->data.file.path);
- break;
-
- case VIR_DOMAIN_CHR_TYPE_PIPE:
- if ((virAsprintf(&out, "%s.out", dev->data.file.path) < 0) ||
- (virAsprintf(&in, "%s.in", dev->data.file.path) < 0)) {
- virReportOOMError();
- goto done;
- }
- if ((qemuSecurityDACRestoreSecurityFileLabel(out) < 0) ||
- (qemuSecurityDACRestoreSecurityFileLabel(in) < 0))
- goto done;
- ret = 0;
- break;
-
- default:
- ret = 0;
- break;
- }
-
-done:
- VIR_FREE(in);
- VIR_FREE(out);
- return ret;
-}
-
-
-static int
-qemuSecurityDACRestoreChardevCallback(virDomainDefPtr def ATTRIBUTE_UNUSED,
- virDomainChrDefPtr dev,
- void *opaque)
-{
- virDomainObjPtr vm = opaque;
-
- return qemuSecurityDACRestoreChardevLabel(vm, dev);
-}
-
-
-static int
-qemuSecurityDACRestoreSecurityAllLabel(virSecurityDriverPtr drv,
- virDomainObjPtr vm,
- int migrated)
-{
- int i;
- int rc = 0;
-
- if (!driver->privileged || !driver->dynamicOwnership)
- return 0;
-
- VIR_DEBUG("Restoring security label on %s migrated=%d",
- vm->def->name, migrated);
-
- for (i = 0 ; i < vm->def->nhostdevs ; i++) {
- if (qemuSecurityDACRestoreSecurityHostdevLabel(drv,
- vm,
- vm->def->hostdevs[i]) < 0)
- rc = -1;
- }
- for (i = 0 ; i < vm->def->ndisks ; i++) {
- if (qemuSecurityDACRestoreSecurityImageLabelInt(drv,
- vm,
- vm->def->disks[i],
- migrated) < 0)
- rc = -1;
- }
-
- if (virDomainChrDefForeach(vm->def,
- false,
- qemuSecurityDACRestoreChardevCallback,
- vm) < 0)
- rc = -1;
-
- if (vm->def->os.kernel &&
- qemuSecurityDACRestoreSecurityFileLabel(vm->def->os.kernel) < 0)
- rc = -1;
-
- if (vm->def->os.initrd &&
- qemuSecurityDACRestoreSecurityFileLabel(vm->def->os.initrd) < 0)
- rc = -1;
-
- return rc;
-}
-
-
-static int
-qemuSecurityDACSetChardevCallback(virDomainDefPtr def ATTRIBUTE_UNUSED,
- virDomainChrDefPtr dev,
- void *opaque)
-{
- virDomainObjPtr vm = opaque;
-
- return qemuSecurityDACSetChardevLabel(vm, dev);
-}
-
-
-static int
-qemuSecurityDACSetSecurityAllLabel(virSecurityDriverPtr drv,
- virDomainObjPtr vm,
- const char *stdin_path ATTRIBUTE_UNUSED)
-{
- int i;
-
- if (!driver->privileged || !driver->dynamicOwnership)
- return 0;
-
- for (i = 0 ; i < vm->def->ndisks ; i++) {
- /* XXX fixme - we need to recursively label the entriy tree :-( */
- if (vm->def->disks[i]->type == VIR_DOMAIN_DISK_TYPE_DIR)
- continue;
- if (qemuSecurityDACSetSecurityImageLabel(drv,
- vm,
- vm->def->disks[i]) < 0)
- return -1;
- }
- for (i = 0 ; i < vm->def->nhostdevs ; i++) {
- if (qemuSecurityDACSetSecurityHostdevLabel(drv,
- vm,
- vm->def->hostdevs[i]) < 0)
- return -1;
- }
-
- if (virDomainChrDefForeach(vm->def,
- true,
- qemuSecurityDACSetChardevCallback,
- vm) < 0)
- return -1;
-
- if (vm->def->os.kernel &&
- qemuSecurityDACSetOwnership(vm->def->os.kernel,
- driver->user,
- driver->group) < 0)
- return -1;
-
- if (vm->def->os.initrd &&
- qemuSecurityDACSetOwnership(vm->def->os.initrd,
- driver->user,
- driver->group) < 0)
- return -1;
-
- return 0;
-}
-
-
-static int
-qemuSecurityDACSetSavedStateLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
- virDomainObjPtr vm ATTRIBUTE_UNUSED,
- const char *savefile)
-{
- if (!driver->privileged)
- return 0;
-
- return qemuSecurityDACSetOwnership(savefile, driver->user, driver->group);
-}
-
-
-static int
-qemuSecurityDACRestoreSavedStateLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
- virDomainObjPtr vm ATTRIBUTE_UNUSED,
- const char *savefile)
-{
- if (!driver->privileged || !driver->dynamicOwnership)
- return 0;
-
- return qemuSecurityDACRestoreSecurityFileLabel(savefile);
-}
-
-
-static int
-qemuSecurityDACSetProcessLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
- virDomainObjPtr vm ATTRIBUTE_UNUSED)
-{
- DEBUG("Dropping privileges of VM to %d:%d", driver->user, driver->group);
-
- if (!driver->privileged)
- return 0;
-
- if (virSetUIDGID(driver->user, driver->group) < 0)
- return -1;
-
- return 0;
-}
-
-
-
-virSecurityDriver qemuDACSecurityDriver = {
- .name = "qemuDAC",
-
- .domainSetSecurityProcessLabel = qemuSecurityDACSetProcessLabel,
-
- .domainSetSecurityImageLabel = qemuSecurityDACSetSecurityImageLabel,
- .domainRestoreSecurityImageLabel = qemuSecurityDACRestoreSecurityImageLabel,
-
- .domainSetSecurityAllLabel = qemuSecurityDACSetSecurityAllLabel,
- .domainRestoreSecurityAllLabel = qemuSecurityDACRestoreSecurityAllLabel,
-
- .domainSetSecurityHostdevLabel = qemuSecurityDACSetSecurityHostdevLabel,
- .domainRestoreSecurityHostdevLabel = qemuSecurityDACRestoreSecurityHostdevLabel,
-
- .domainSetSavedStateLabel = qemuSecurityDACSetSavedStateLabel,
- .domainRestoreSavedStateLabel = qemuSecurityDACRestoreSavedStateLabel,
-};
diff --git a/src/qemu/qemu_security_dac.h b/src/qemu/qemu_security_dac.h
deleted file mode 100644
index a742f7a..0000000
--- a/src/qemu/qemu_security_dac.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Copyright (C) 2010 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.
- *
- * QEMU POSIX DAC security driver
- */
-
-#include "security/security_driver.h"
-#include "qemu_conf.h"
-
-#ifndef __QEMU_SECURITY_DAC
-# define __QEMU_SECURITY_DAC
-
-extern virSecurityDriver qemuDACSecurityDriver;
-
-void qemuSecurityDACSetDriver(struct qemud_driver *driver);
-
-#endif /* __QEMU_SECURITY_DAC */
diff --git a/src/qemu/qemu_security_stacked.c b/src/qemu/qemu_security_stacked.c
deleted file mode 100644
index 432d095..0000000
--- a/src/qemu/qemu_security_stacked.c
+++ /dev/null
@@ -1,418 +0,0 @@
-/*
- * Copyright (C) 2010 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.
- *
- * QEMU stacked security driver
- */
-
-#include <config.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-
-#include "qemu_security_stacked.h"
-
-#include "qemu_conf.h"
-#include "datatypes.h"
-#include "virterror_internal.h"
-#include "util.h"
-#include "memory.h"
-#include "logging.h"
-#include "pci.h"
-#include "hostusb.h"
-#include "storage_file.h"
-
-#define VIR_FROM_THIS VIR_FROM_QEMU
-
-
-static struct qemud_driver *driver;
-
-void qemuSecurityStackedSetDriver(struct qemud_driver *newdriver)
-{
- driver = newdriver;
-}
-
-
-static int
-qemuSecurityStackedVerify(virDomainDefPtr def)
-{
- int rc = 0;
-
- if (driver->securitySecondaryDriver &&
- driver->securitySecondaryDriver->domainSecurityVerify &&
- driver->securitySecondaryDriver->domainSecurityVerify(def) < 0)
- rc = -1;
-
- if (driver->securityPrimaryDriver &&
- driver->securityPrimaryDriver->domainSecurityVerify &&
- driver->securityPrimaryDriver->domainSecurityVerify(def) < 0)
- rc = -1;
-
- return rc;
-}
-
-
-static int
-qemuSecurityStackedGenLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
- virDomainObjPtr vm)
-{
- int rc = 0;
-
- if (driver->securitySecondaryDriver &&
- driver->securitySecondaryDriver->domainGenSecurityLabel &&
- driver->securitySecondaryDriver->domainGenSecurityLabel(driver->securitySecondaryDriver,
- vm) < 0)
- rc = -1;
-
- if (driver->securityPrimaryDriver &&
- driver->securityPrimaryDriver->domainGenSecurityLabel &&
- driver->securityPrimaryDriver->domainGenSecurityLabel(driver->securityPrimaryDriver,
- vm) < 0)
- rc = -1;
-
- return rc;
-}
-
-
-static int
-qemuSecurityStackedReleaseLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
- virDomainObjPtr vm)
-{
- int rc = 0;
-
- if (driver->securitySecondaryDriver &&
- driver->securitySecondaryDriver->domainReleaseSecurityLabel &&
- driver->securitySecondaryDriver->domainReleaseSecurityLabel(driver->securitySecondaryDriver,
- vm) < 0)
- rc = -1;
-
- if (driver->securityPrimaryDriver &&
- driver->securityPrimaryDriver->domainReleaseSecurityLabel &&
- driver->securityPrimaryDriver->domainReleaseSecurityLabel(driver->securityPrimaryDriver,
- vm) < 0)
- rc = -1;
-
- return rc;
-}
-
-
-static int
-qemuSecurityStackedReserveLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
- virDomainObjPtr vm)
-{
- int rc = 0;
-
- if (driver->securitySecondaryDriver &&
- driver->securitySecondaryDriver->domainReserveSecurityLabel &&
- driver->securitySecondaryDriver->domainReserveSecurityLabel(driver->securitySecondaryDriver,
- vm) < 0)
- rc = -1;
-
- if (driver->securityPrimaryDriver &&
- driver->securityPrimaryDriver->domainReserveSecurityLabel &&
- driver->securityPrimaryDriver->domainReserveSecurityLabel(driver->securityPrimaryDriver,
- vm) < 0)
- rc = -1;
-
- return rc;
-}
-
-
-static int
-qemuSecurityStackedSetSecurityImageLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
- virDomainObjPtr vm,
- virDomainDiskDefPtr disk)
-{
- int rc = 0;
-
- if (driver->securitySecondaryDriver &&
- driver->securitySecondaryDriver->domainSetSecurityImageLabel &&
- driver->securitySecondaryDriver->domainSetSecurityImageLabel(driver->securitySecondaryDriver,
- vm, disk) < 0)
- rc = -1;
-
- if (driver->securityPrimaryDriver &&
- driver->securityPrimaryDriver->domainSetSecurityImageLabel &&
- driver->securityPrimaryDriver->domainSetSecurityImageLabel(driver->securityPrimaryDriver,
- vm, disk) < 0)
- rc = -1;
-
- return rc;
-}
-
-
-static int
-qemuSecurityStackedRestoreSecurityImageLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
- virDomainObjPtr vm,
- virDomainDiskDefPtr disk)
-{
- int rc = 0;
-
- if (driver->securitySecondaryDriver &&
- driver->securitySecondaryDriver->domainRestoreSecurityImageLabel &&
- driver->securitySecondaryDriver->domainRestoreSecurityImageLabel(driver->securitySecondaryDriver,
- vm, disk) < 0)
- rc = -1;
-
- if (driver->securityPrimaryDriver &&
- driver->securityPrimaryDriver->domainRestoreSecurityImageLabel &&
- driver->securityPrimaryDriver->domainRestoreSecurityImageLabel(driver->securityPrimaryDriver,
- vm, disk) < 0)
- rc = -1;
-
- return rc;
-}
-
-
-static int
-qemuSecurityStackedSetSecurityHostdevLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
- virDomainObjPtr vm,
- virDomainHostdevDefPtr dev)
-
-{
- int rc = 0;
-
- if (driver->securitySecondaryDriver &&
- driver->securitySecondaryDriver->domainSetSecurityHostdevLabel &&
- driver->securitySecondaryDriver->domainSetSecurityHostdevLabel(driver->securitySecondaryDriver,
- vm, dev) < 0)
- rc = -1;
-
- if (driver->securityPrimaryDriver &&
- driver->securityPrimaryDriver->domainSetSecurityHostdevLabel &&
- driver->securityPrimaryDriver->domainSetSecurityHostdevLabel(driver->securityPrimaryDriver,
- vm, dev) < 0)
- rc = -1;
-
- return rc;
-}
-
-
-static int
-qemuSecurityStackedRestoreSecurityHostdevLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
- virDomainObjPtr vm,
- virDomainHostdevDefPtr dev)
-{
- int rc = 0;
-
- if (driver->securitySecondaryDriver &&
- driver->securitySecondaryDriver->domainRestoreSecurityHostdevLabel &&
- driver->securitySecondaryDriver->domainRestoreSecurityHostdevLabel(driver->securitySecondaryDriver,
- vm, dev) < 0)
- rc = -1;
-
- if (driver->securityPrimaryDriver &&
- driver->securityPrimaryDriver->domainRestoreSecurityHostdevLabel &&
- driver->securityPrimaryDriver->domainRestoreSecurityHostdevLabel(driver->securityPrimaryDriver,
- vm, dev) < 0)
- rc = -1;
-
- return rc;
-}
-
-
-static int
-qemuSecurityStackedSetSecurityAllLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
- virDomainObjPtr vm,
- const char *stdin_path)
-{
- int rc = 0;
-
- if (driver->securitySecondaryDriver &&
- driver->securitySecondaryDriver->domainSetSecurityAllLabel &&
- driver->securitySecondaryDriver->domainSetSecurityAllLabel(driver->securitySecondaryDriver,
- vm, stdin_path) < 0)
- rc = -1;
-
- if (driver->securityPrimaryDriver &&
- driver->securityPrimaryDriver->domainSetSecurityAllLabel &&
- driver->securityPrimaryDriver->domainSetSecurityAllLabel(driver->securityPrimaryDriver,
- vm, stdin_path) < 0)
- rc = -1;
-
- return rc;
-}
-
-
-static int
-qemuSecurityStackedRestoreSecurityAllLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
- virDomainObjPtr vm,
- int migrated)
-{
- int rc = 0;
-
- if (driver->securitySecondaryDriver &&
- driver->securitySecondaryDriver->domainRestoreSecurityAllLabel &&
- driver->securitySecondaryDriver->domainRestoreSecurityAllLabel(driver->securitySecondaryDriver,
- vm, migrated) < 0)
- rc = -1;
-
- if (driver->securityPrimaryDriver &&
- driver->securityPrimaryDriver->domainRestoreSecurityAllLabel &&
- driver->securityPrimaryDriver->domainRestoreSecurityAllLabel(driver->securityPrimaryDriver,
- vm, migrated) < 0)
- rc = -1;
-
- return rc;
-}
-
-
-static int
-qemuSecurityStackedSetSavedStateLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
- virDomainObjPtr vm,
- const char *savefile)
-{
- int rc = 0;
-
- if (driver->securitySecondaryDriver &&
- driver->securitySecondaryDriver->domainSetSavedStateLabel &&
- driver->securitySecondaryDriver->domainSetSavedStateLabel(driver->securitySecondaryDriver,
- vm, savefile) < 0)
- rc = -1;
-
- if (driver->securityPrimaryDriver &&
- driver->securityPrimaryDriver->domainSetSavedStateLabel &&
- driver->securityPrimaryDriver->domainSetSavedStateLabel(driver->securityPrimaryDriver,
- vm, savefile) < 0)
- rc = -1;
-
- return rc;
-}
-
-
-static int
-qemuSecurityStackedRestoreSavedStateLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
- virDomainObjPtr vm,
- const char *savefile)
-{
- int rc = 0;
-
- if (driver->securitySecondaryDriver &&
- driver->securitySecondaryDriver->domainRestoreSavedStateLabel &&
- driver->securitySecondaryDriver->domainRestoreSavedStateLabel(driver->securitySecondaryDriver,
- vm, savefile) < 0)
- rc = -1;
-
- if (driver->securityPrimaryDriver &&
- driver->securityPrimaryDriver->domainRestoreSavedStateLabel &&
- driver->securityPrimaryDriver->domainRestoreSavedStateLabel(driver->securityPrimaryDriver,
- vm, savefile) < 0)
- rc = -1;
-
- return rc;
-}
-
-
-static int
-qemuSecurityStackedSetProcessLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
- virDomainObjPtr vm)
-{
- int rc = 0;
-
- if (driver->securitySecondaryDriver &&
- driver->securitySecondaryDriver->domainSetSecurityProcessLabel &&
- driver->securitySecondaryDriver->domainSetSecurityProcessLabel(driver->securitySecondaryDriver,
- vm) < 0)
- rc = -1;
-
- if (driver->securityPrimaryDriver &&
- driver->securityPrimaryDriver->domainSetSecurityProcessLabel &&
- driver->securityPrimaryDriver->domainSetSecurityProcessLabel(driver->securityPrimaryDriver,
- vm) < 0)
- rc = -1;
-
- return rc;
-}
-
-static int
-qemuSecurityStackedGetProcessLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
- virDomainObjPtr vm,
- virSecurityLabelPtr seclabel)
-{
- int rc = 0;
-
- if (driver->securityPrimaryDriver &&
- driver->securityPrimaryDriver->domainGetSecurityProcessLabel &&
- driver->securityPrimaryDriver->domainGetSecurityProcessLabel(driver->securityPrimaryDriver,
- vm,
- seclabel) < 0)
- rc = -1;
-
- return rc;
-}
-
-
-static int
-qemuSecurityStackedSetSocketLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
- virDomainObjPtr vm)
-{
- int rc = 0;
-
- if (driver->securityPrimaryDriver &&
- driver->securityPrimaryDriver->domainSetSecuritySocketLabel &&
- driver->securityPrimaryDriver->domainSetSecuritySocketLabel(driver->securityPrimaryDriver,
- vm) < 0)
- rc = -1;
-
- if (driver->securitySecondaryDriver &&
- driver->securitySecondaryDriver->domainSetSecuritySocketLabel &&
- driver->securitySecondaryDriver->domainSetSecuritySocketLabel(driver->securitySecondaryDriver,
- vm) < 0)
- rc = -1;
-
- return rc;
-}
-
-
-static int
-qemuSecurityStackedClearSocketLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
- virDomainObjPtr vm)
-{
- int rc = 0;
-
- if (driver->securitySecondaryDriver &&
- driver->securitySecondaryDriver->domainClearSecuritySocketLabel &&
- driver->securitySecondaryDriver->domainClearSecuritySocketLabel(driver->securitySecondaryDriver,
- vm) < 0)
- rc = -1;
-
- if (driver->securityPrimaryDriver &&
- driver->securityPrimaryDriver->domainClearSecuritySocketLabel &&
- driver->securityPrimaryDriver->domainClearSecuritySocketLabel(driver->securityPrimaryDriver,
- vm) < 0)
- rc = -1;
-
- return rc;
-}
-
-
-virSecurityDriver qemuStackedSecurityDriver = {
- .name = "qemuStacked",
- .domainSecurityVerify = qemuSecurityStackedVerify,
-
- .domainGenSecurityLabel = qemuSecurityStackedGenLabel,
- .domainReleaseSecurityLabel = qemuSecurityStackedReleaseLabel,
- .domainReserveSecurityLabel = qemuSecurityStackedReserveLabel,
-
- .domainGetSecurityProcessLabel = qemuSecurityStackedGetProcessLabel,
- .domainSetSecurityProcessLabel = qemuSecurityStackedSetProcessLabel,
-
- .domainSetSecurityImageLabel = qemuSecurityStackedSetSecurityImageLabel,
- .domainRestoreSecurityImageLabel = qemuSecurityStackedRestoreSecurityImageLabel,
-
- .domainSetSecurityAllLabel = qemuSecurityStackedSetSecurityAllLabel,
- .domainRestoreSecurityAllLabel = qemuSecurityStackedRestoreSecurityAllLabel,
-
- .domainSetSecurityHostdevLabel = qemuSecurityStackedSetSecurityHostdevLabel,
- .domainRestoreSecurityHostdevLabel = qemuSecurityStackedRestoreSecurityHostdevLabel,
-
- .domainSetSavedStateLabel = qemuSecurityStackedSetSavedStateLabel,
- .domainRestoreSavedStateLabel = qemuSecurityStackedRestoreSavedStateLabel,
-
- .domainClearSecuritySocketLabel = qemuSecurityStackedClearSocketLabel,
- .domainSetSecuritySocketLabel = qemuSecurityStackedSetSocketLabel,
-};
diff --git a/src/qemu/qemu_security_stacked.h b/src/qemu/qemu_security_stacked.h
deleted file mode 100644
index 07f76d5..0000000
--- a/src/qemu/qemu_security_stacked.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Copyright (C) 2010 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.
- *
- * QEMU stacked security driver
- */
-
-#include "security/security_driver.h"
-#include "qemu_conf.h"
-
-#ifndef __QEMU_SECURITY_STACKED
-# define __QEMU_SECURITY_STACKED
-
-extern virSecurityDriver qemuStackedSecurityDriver;
-
-void qemuSecurityStackedSetDriver(struct qemud_driver *driver);
-
-#endif /* __QEMU_SECURITY_DAC */
diff --git a/src/security/security_apparmor.c b/src/security/security_apparmor.c
index 468d0a3..d82ba73 100644
--- a/src/security/security_apparmor.c
+++ b/src/security/security_apparmor.c
@@ -1,4 +1,3 @@
-
/*
* AppArmor security driver for libvirt
* Copyright (C) 2009-2010 Canonical Ltd.
@@ -28,7 +27,6 @@
#include "internal.h"
-#include "security_driver.h"
#include "security_apparmor.h"
#include "util.h"
#include "memory.h"
@@ -47,7 +45,7 @@
/* Data structure to pass to *FileIterate so we have everything we need */
struct SDPDOP {
- virSecurityDriverPtr drv;
+ virSecurityManagerPtr mgr;
virDomainObjPtr vm;
};
@@ -158,7 +156,7 @@ profile_status_file(const char *str)
* load (add) a profile. Will create one if necessary
*/
static int
-load_profile(virSecurityDriverPtr drv,
+load_profile(virSecurityManagerPtr mgr,
const char *profile,
virDomainObjPtr vm,
const char *fn,
@@ -169,7 +167,7 @@ load_profile(virSecurityDriverPtr drv,
char *xml = NULL;
int pipefd[2];
pid_t child;
- const char *probe = virSecurityDriverGetAllowDiskFormatProbing(drv)
+ const char *probe = virSecurityManagerGetAllowDiskFormatProbing(mgr)
? "1" : "0";
if (pipe(pipefd) < -1) {
@@ -300,7 +298,7 @@ cleanup:
* NULL.
*/
static int
-reload_profile(virSecurityDriverPtr drv,
+reload_profile(virSecurityManagerPtr mgr,
virDomainObjPtr vm,
const char *fn,
bool append)
@@ -317,7 +315,7 @@ reload_profile(virSecurityDriverPtr drv,
/* Update the profile only if it is loaded */
if (profile_loaded(secdef->imagelabel) >= 0) {
- if (load_profile(drv, secdef->imagelabel, vm, fn, append) < 0) {
+ if (load_profile(mgr, secdef->imagelabel, vm, fn, append) < 0) {
virSecurityReportError(VIR_ERR_INTERNAL_ERROR,
_("cannot update AppArmor profile "
"\'%s\'"),
@@ -340,7 +338,7 @@ AppArmorSetSecurityUSBLabel(usbDevice *dev ATTRIBUTE_UNUSED,
struct SDPDOP *ptr = opaque;
virDomainObjPtr vm = ptr->vm;
- if (reload_profile(ptr->drv, vm, file, true) < 0) {
+ if (reload_profile(ptr->mgr, vm, file, true) < 0) {
const virSecurityLabelDefPtr secdef = &vm->def->seclabel;
virSecurityReportError(VIR_ERR_INTERNAL_ERROR,
_("cannot update AppArmor profile "
@@ -358,7 +356,7 @@ AppArmorSetSecurityPCILabel(pciDevice *dev ATTRIBUTE_UNUSED,
struct SDPDOP *ptr = opaque;
virDomainObjPtr vm = ptr->vm;
- if (reload_profile(ptr->drv, vm, file, true) < 0) {
+ if (reload_profile(ptr->mgr, vm, file, true) < 0) {
const virSecurityLabelDefPtr secdef = &vm->def->seclabel;
virSecurityReportError(VIR_ERR_INTERNAL_ERROR,
_("cannot update AppArmor profile "
@@ -371,7 +369,7 @@ AppArmorSetSecurityPCILabel(pciDevice *dev ATTRIBUTE_UNUSED,
/* Called on libvirtd startup to see if AppArmor is available */
static int
-AppArmorSecurityDriverProbe(void)
+AppArmorSecurityManagerProbe(void)
{
char *template = NULL;
int rc = SECURITY_DRIVER_DISABLE;
@@ -403,21 +401,37 @@ AppArmorSecurityDriverProbe(void)
* currently not used.
*/
static int
-AppArmorSecurityDriverOpen(virSecurityDriverPtr drv,
- bool allowDiskFormatProbing)
+AppArmorSecurityManagerOpen(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+static int
+AppArmorSecurityManagerClose(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED)
{
- virSecurityDriverSetDOI(drv, SECURITY_APPARMOR_VOID_DOI);
- virSecurityDriverSetAllowDiskFormatProbing(drv, allowDiskFormatProbing);
return 0;
}
+static const char *
+AppArmorSecurityManagerGetModel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED)
+{
+ return SECURITY_APPARMOR_NAME;
+}
+
+static const char *
+AppArmorSecurityManagerGetDOI(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED)
+{
+ return SECURITY_APPARMOR_VOID_DOI;
+}
+
+
/* Currently called in qemudStartVMDaemon to setup a 'label'. We look for and
* use a profile based on the UUID, otherwise create one based on a template.
* Keep in mind that this is called on 'start' with RestoreSecurityLabel being
* called on shutdown.
*/
static int
-AppArmorGenSecurityLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
+AppArmorGenSecurityLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
virDomainObjPtr vm)
{
int rc = -1;
@@ -472,7 +486,7 @@ AppArmorGenSecurityLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
}
static int
-AppArmorSetSecurityAllLabel(virSecurityDriverPtr drv,
+AppArmorSetSecurityAllLabel(virSecurityManagerPtr mgr,
virDomainObjPtr vm, const char *stdin_path)
{
if (vm->def->seclabel.type == VIR_DOMAIN_SECLABEL_STATIC)
@@ -480,7 +494,7 @@ AppArmorSetSecurityAllLabel(virSecurityDriverPtr drv,
/* if the profile is not already loaded, then load one */
if (profile_loaded(vm->def->seclabel.label) < 0) {
- if (load_profile(drv, vm->def->seclabel.label, vm, stdin_path,
+ if (load_profile(mgr, vm->def->seclabel.label, vm, stdin_path,
false) < 0) {
virSecurityReportError(VIR_ERR_INTERNAL_ERROR,
_("cannot generate AppArmor profile "
@@ -496,7 +510,7 @@ AppArmorSetSecurityAllLabel(virSecurityDriverPtr drv,
* running.
*/
static int
-AppArmorGetSecurityProcessLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
+AppArmorGetSecurityProcessLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
virDomainObjPtr vm,
virSecurityLabelPtr sec)
{
@@ -530,7 +544,7 @@ AppArmorGetSecurityProcessLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
* more details. Currently called via qemudShutdownVMDaemon.
*/
static int
-AppArmorReleaseSecurityLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
+AppArmorReleaseSecurityLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
virDomainObjPtr vm)
{
const virSecurityLabelDefPtr secdef = &vm->def->seclabel;
@@ -544,7 +558,7 @@ AppArmorReleaseSecurityLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
static int
-AppArmorRestoreSecurityAllLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
+AppArmorRestoreSecurityAllLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
virDomainObjPtr vm,
int migrated ATTRIBUTE_UNUSED)
{
@@ -565,7 +579,7 @@ AppArmorRestoreSecurityAllLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
* LOCALSTATEDIR/log/libvirt/qemu/<vm name>.log
*/
static int
-AppArmorSetSecurityProcessLabel(virSecurityDriverPtr drv, virDomainObjPtr vm)
+AppArmorSetSecurityProcessLabel(virSecurityManagerPtr mgr, virDomainObjPtr vm)
{
const virSecurityLabelDefPtr secdef = &vm->def->seclabel;
int rc = -1;
@@ -574,12 +588,12 @@ AppArmorSetSecurityProcessLabel(virSecurityDriverPtr drv, virDomainObjPtr vm)
if ((profile_name = get_profile_name(vm)) == NULL)
return rc;
- if (STRNEQ(drv->name, secdef->model)) {
+ if (STRNEQ(virSecurityManagerGetModel(mgr), secdef->model)) {
virSecurityReportError(VIR_ERR_INTERNAL_ERROR,
_("security label driver mismatch: "
"\'%s\' model configured for domain, but "
"hypervisor driver is \'%s\'."),
- secdef->model, drv->name);
+ secdef->model, virSecurityManagerGetModel(mgr));
if (use_apparmor() > 0)
goto clean;
}
@@ -597,19 +611,33 @@ AppArmorSetSecurityProcessLabel(virSecurityDriverPtr drv, virDomainObjPtr vm)
return rc;
}
+static int
+AppArmorSetSecuritySocketLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
+ virDomainObjPtr vm ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+static int
+AppArmorClearSecuritySocketLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
+ virDomainObjPtr vm ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
/* Called when hotplugging */
static int
-AppArmorRestoreSecurityImageLabel(virSecurityDriverPtr drv,
+AppArmorRestoreSecurityImageLabel(virSecurityManagerPtr mgr,
virDomainObjPtr vm,
virDomainDiskDefPtr disk ATTRIBUTE_UNUSED)
{
- return reload_profile(drv, vm, NULL, false);
+ return reload_profile(mgr, vm, NULL, false);
}
/* Called when hotplugging */
static int
-AppArmorSetSecurityImageLabel(virSecurityDriverPtr drv,
+AppArmorSetSecurityImageLabel(virSecurityManagerPtr mgr,
virDomainObjPtr vm, virDomainDiskDefPtr disk)
{
const virSecurityLabelDefPtr secdef = &vm->def->seclabel;
@@ -635,7 +663,7 @@ AppArmorSetSecurityImageLabel(virSecurityDriverPtr drv,
/* update the profile only if it is loaded */
if (profile_loaded(secdef->imagelabel) >= 0) {
- if (load_profile(drv, secdef->imagelabel, vm, disk->src,
+ if (load_profile(mgr, secdef->imagelabel, vm, disk->src,
false) < 0) {
virSecurityReportError(VIR_ERR_INTERNAL_ERROR,
_("cannot update AppArmor profile "
@@ -654,7 +682,8 @@ AppArmorSetSecurityImageLabel(virSecurityDriverPtr drv,
}
static int
-AppArmorSecurityVerify(virDomainDefPtr def)
+AppArmorSecurityVerify(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
+ virDomainDefPtr def)
{
const virSecurityLabelDefPtr secdef = &def->seclabel;
@@ -670,7 +699,7 @@ AppArmorSecurityVerify(virDomainDefPtr def)
}
static int
-AppArmorReserveSecurityLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
+AppArmorReserveSecurityLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
virDomainObjPtr vm ATTRIBUTE_UNUSED)
{
/* NOOP. Nothing to reserve with AppArmor */
@@ -678,7 +707,7 @@ AppArmorReserveSecurityLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
}
static int
-AppArmorSetSecurityHostdevLabel(virSecurityDriverPtr drv,
+AppArmorSetSecurityHostdevLabel(virSecurityManagerPtr mgr,
virDomainObjPtr vm,
virDomainHostdevDefPtr dev)
@@ -698,7 +727,7 @@ AppArmorSetSecurityHostdevLabel(virSecurityDriverPtr drv,
if (VIR_ALLOC(ptr) < 0)
return -1;
- ptr->drv = drv;
+ ptr->mgr = mgr;
ptr->vm = vm;
switch (dev->source.subsys.type) {
@@ -740,7 +769,7 @@ done:
static int
-AppArmorRestoreSecurityHostdevLabel(virSecurityDriverPtr drv,
+AppArmorRestoreSecurityHostdevLabel(virSecurityManagerPtr mgr,
virDomainObjPtr vm,
virDomainHostdevDefPtr dev ATTRIBUTE_UNUSED)
@@ -749,42 +778,57 @@ AppArmorRestoreSecurityHostdevLabel(virSecurityDriverPtr drv,
if (secdef->type == VIR_DOMAIN_SECLABEL_STATIC)
return 0;
- return reload_profile(drv, vm, NULL, false);
+ return reload_profile(mgr, vm, NULL, false);
}
static int
-AppArmorSetSavedStateLabel(virSecurityDriverPtr drv,
+AppArmorSetSavedStateLabel(virSecurityManagerPtr mgr,
virDomainObjPtr vm,
const char *savefile)
{
- return reload_profile(drv, vm, savefile, true);
+ return reload_profile(mgr, vm, savefile, true);
}
static int
-AppArmorRestoreSavedStateLabel(virSecurityDriverPtr drv,
+AppArmorRestoreSavedStateLabel(virSecurityManagerPtr mgr,
virDomainObjPtr vm,
const char *savefile ATTRIBUTE_UNUSED)
{
- return reload_profile(drv, vm, NULL, false);
+ return reload_profile(mgr, vm, NULL, false);
}
virSecurityDriver virAppArmorSecurityDriver = {
- .name = SECURITY_APPARMOR_NAME,
- .probe = AppArmorSecurityDriverProbe,
- .open = AppArmorSecurityDriverOpen,
- .domainSecurityVerify = AppArmorSecurityVerify,
- .domainSetSecurityImageLabel = AppArmorSetSecurityImageLabel,
- .domainRestoreSecurityImageLabel = AppArmorRestoreSecurityImageLabel,
- .domainGenSecurityLabel = AppArmorGenSecurityLabel,
- .domainReserveSecurityLabel = AppArmorReserveSecurityLabel,
- .domainReleaseSecurityLabel = AppArmorReleaseSecurityLabel,
- .domainGetSecurityProcessLabel = AppArmorGetSecurityProcessLabel,
- .domainSetSecurityProcessLabel = AppArmorSetSecurityProcessLabel,
- .domainRestoreSecurityAllLabel = AppArmorRestoreSecurityAllLabel,
- .domainSetSecurityAllLabel = AppArmorSetSecurityAllLabel,
- .domainSetSecurityHostdevLabel = AppArmorSetSecurityHostdevLabel,
- .domainRestoreSecurityHostdevLabel = AppArmorRestoreSecurityHostdevLabel,
- .domainSetSavedStateLabel = AppArmorSetSavedStateLabel,
- .domainRestoreSavedStateLabel = AppArmorRestoreSavedStateLabel,
+ 0,
+ SECURITY_APPARMOR_NAME,
+ AppArmorSecurityManagerProbe,
+ AppArmorSecurityManagerOpen,
+ AppArmorSecurityManagerClose,
+
+ AppArmorSecurityManagerGetModel,
+ AppArmorSecurityManagerGetDOI,
+
+ AppArmorSecurityVerify,
+
+ AppArmorSetSecurityImageLabel,
+ AppArmorRestoreSecurityImageLabel,
+
+ AppArmorSetSecuritySocketLabel,
+ AppArmorClearSecuritySocketLabel,
+
+ AppArmorGenSecurityLabel,
+ AppArmorReserveSecurityLabel,
+ AppArmorReleaseSecurityLabel,
+
+ AppArmorGetSecurityProcessLabel,
+ AppArmorSetSecurityProcessLabel,
+
+ AppArmorSetSecurityAllLabel,
+ AppArmorRestoreSecurityAllLabel,
+
+ AppArmorSetSecurityHostdevLabel,
+ AppArmorRestoreSecurityHostdevLabel,
+
+ AppArmorSetSavedStateLabel,
+ AppArmorRestoreSavedStateLabel,
};
diff --git a/src/security/security_apparmor.h b/src/security/security_apparmor.h
index eb7e140..90d9ddb 100644
--- a/src/security/security_apparmor.h
+++ b/src/security/security_apparmor.h
@@ -14,6 +14,8 @@
#ifndef __VIR_SECURITY_APPARMOR_H__
# define __VIR_SECURITY_APPARMOR_H__
+#include "security_driver.h"
+
extern virSecurityDriver virAppArmorSecurityDriver;
# define AA_PREFIX "libvirt-"
diff --git a/src/security/security_dac.c b/src/security/security_dac.c
new file mode 100644
index 0000000..edecaf9
--- /dev/null
+++ b/src/security/security_dac.c
@@ -0,0 +1,703 @@
+/*
+ * Copyright (C) 2010 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.
+ *
+ * QEMU POSIX DAC security driver
+ */
+#include <config.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include "security_dac.h"
+#include "virterror_internal.h"
+#include "util.h"
+#include "memory.h"
+#include "logging.h"
+#include "pci.h"
+#include "hostusb.h"
+#include "storage_file.h"
+
+#define VIR_FROM_THIS VIR_FROM_SECURITY
+
+typedef struct _virSecurityDACData virSecurityDACData;
+typedef virSecurityDACData *virSecurityDACDataPtr;
+
+struct _virSecurityDACData {
+ uid_t user;
+ gid_t group;
+ bool dynamicOwnership;
+};
+
+void virSecurityDACSetUser(virSecurityManagerPtr mgr,
+ uid_t user)
+{
+ virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+ priv->user = user;
+}
+
+void virSecurityDACSetGroup(virSecurityManagerPtr mgr,
+ gid_t group)
+{
+ virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+ priv->group = group;
+}
+
+void virSecurityDACSetDynamicOwnership(virSecurityManagerPtr mgr,
+ bool dynamicOwnership)
+{
+ virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+ priv->dynamicOwnership = dynamicOwnership;
+}
+
+static virSecurityDriverStatus
+virSecurityDACProbe(void)
+{
+ return SECURITY_DRIVER_ENABLE;
+}
+
+static int
+virSecurityDACOpen(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+static int
+virSecurityDACClose(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+
+static const char * virSecurityDACGetModel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED)
+{
+ return "dac";
+}
+
+static const char * virSecurityDACGetDOI(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED)
+{
+ return "0";
+}
+
+static int
+virSecurityDACSetOwnership(const char *path, int uid, int gid)
+{
+ VIR_INFO("Setting DAC user and group on '%s' to '%d:%d'", path, uid, gid);
+
+ if (chown(path, uid, gid) < 0) {
+ struct stat sb;
+ int chown_errno = errno;
+
+ if (stat(path, &sb) >= 0) {
+ if (sb.st_uid == uid &&
+ sb.st_gid == gid) {
+ /* It's alright, there's nothing to change anyway. */
+ return 0;
+ }
+ }
+
+ if (chown_errno == EOPNOTSUPP) {
+ VIR_INFO("Setting user and group to '%d:%d' on '%s' not supported by filesystem",
+ uid, gid, path);
+ } else if (chown_errno == EPERM) {
+ VIR_INFO("Setting user and group to '%d:%d' on '%s' not permitted",
+ uid, gid, path);
+ } else if (chown_errno == EROFS) {
+ VIR_INFO("Setting user and group to '%d:%d' on '%s' not possible on readonly filesystem",
+ uid, gid, path);
+ } else {
+ virReportSystemError(chown_errno,
+ _("unable to set user and group to '%d:%d' on '%s'"),
+ uid, gid, path);
+ return -1;
+ }
+ }
+ return 0;
+}
+
+static int
+virSecurityDACRestoreSecurityFileLabel(const char *path)
+{
+ struct stat buf;
+ int rc = -1;
+ char *newpath = NULL;
+
+ VIR_INFO("Restoring DAC user and group on '%s'", path);
+
+ if (virFileResolveLink(path, &newpath) < 0) {
+ virReportSystemError(errno,
+ _("cannot resolve symlink %s"), path);
+ goto err;
+ }
+
+ if (stat(newpath, &buf) != 0)
+ goto err;
+
+ /* XXX record previous ownership */
+ rc = virSecurityDACSetOwnership(newpath, 0, 0);
+
+err:
+ VIR_FREE(newpath);
+ return rc;
+}
+
+
+static int
+virSecurityDACSetSecurityFileLabel(virDomainDiskDefPtr disk ATTRIBUTE_UNUSED,
+ const char *path,
+ size_t depth ATTRIBUTE_UNUSED,
+ void *opaque)
+{
+ virSecurityManagerPtr mgr = opaque;
+ virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+
+ return virSecurityDACSetOwnership(path, priv->user, priv->group);
+}
+
+
+static int
+virSecurityDACSetSecurityImageLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm ATTRIBUTE_UNUSED,
+ virDomainDiskDefPtr disk)
+
+{
+ virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+
+ if (!priv->dynamicOwnership)
+ return 0;
+
+ return virDomainDiskDefForeachPath(disk,
+ virSecurityManagerGetAllowDiskFormatProbing(mgr),
+ false,
+ virSecurityDACSetSecurityFileLabel,
+ mgr);
+}
+
+
+static int
+virSecurityDACRestoreSecurityImageLabelInt(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm ATTRIBUTE_UNUSED,
+ virDomainDiskDefPtr disk,
+ int migrated)
+{
+ virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+
+ if (!priv->dynamicOwnership)
+ return 0;
+
+ /* Don't restore labels on readoly/shared disks, because
+ * other VMs may still be accessing these
+ * Alternatively we could iterate over all running
+ * domains and try to figure out if it is in use, but
+ * this would not work for clustered filesystems, since
+ * we can't see running VMs using the file on other nodes
+ * Safest bet is thus to skip the restore step.
+ */
+ if (disk->readonly || disk->shared)
+ return 0;
+
+ if (!disk->src)
+ return 0;
+
+ /* If we have a shared FS & doing migrated, we must not
+ * change ownership, because that kills access on the
+ * destination host which is sub-optimal for the guest
+ * VM's I/O attempts :-)
+ */
+ if (migrated) {
+ int rc = virStorageFileIsSharedFS(disk->src);
+ if (rc < 0)
+ return -1;
+ if (rc == 1) {
+ VIR_DEBUG("Skipping image label restore on %s because FS is shared",
+ disk->src);
+ return 0;
+ }
+ }
+
+ return virSecurityDACRestoreSecurityFileLabel(disk->src);
+}
+
+
+static int
+virSecurityDACRestoreSecurityImageLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm,
+ virDomainDiskDefPtr disk)
+{
+ return virSecurityDACRestoreSecurityImageLabelInt(mgr, vm, disk, 0);
+}
+
+
+static int
+virSecurityDACSetSecurityPCILabel(pciDevice *dev ATTRIBUTE_UNUSED,
+ const char *file,
+ void *opaque)
+{
+ virSecurityManagerPtr mgr = opaque;
+ virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+
+ return virSecurityDACSetOwnership(file, priv->user, priv->group);
+}
+
+
+static int
+virSecurityDACSetSecurityUSBLabel(usbDevice *dev ATTRIBUTE_UNUSED,
+ const char *file,
+ void *opaque)
+{
+ virSecurityManagerPtr mgr = opaque;
+ virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+
+ return virSecurityDACSetOwnership(file, priv->user, priv->group);
+}
+
+
+static int
+virSecurityDACSetSecurityHostdevLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm ATTRIBUTE_UNUSED,
+ virDomainHostdevDefPtr dev)
+{
+ virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+ int ret = -1;
+
+ if (!priv->dynamicOwnership)
+ return 0;
+
+ if (dev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS)
+ return 0;
+
+ switch (dev->source.subsys.type) {
+ case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB: {
+ usbDevice *usb = usbGetDevice(dev->source.subsys.u.usb.bus,
+ dev->source.subsys.u.usb.device);
+
+ if (!usb)
+ goto done;
+
+ ret = usbDeviceFileIterate(usb, virSecurityDACSetSecurityUSBLabel, mgr);
+ usbFreeDevice(usb);
+ break;
+ }
+
+ case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI: {
+ pciDevice *pci = pciGetDevice(dev->source.subsys.u.pci.domain,
+ dev->source.subsys.u.pci.bus,
+ dev->source.subsys.u.pci.slot,
+ dev->source.subsys.u.pci.function);
+
+ if (!pci)
+ goto done;
+
+ ret = pciDeviceFileIterate(pci, virSecurityDACSetSecurityPCILabel, mgr);
+ pciFreeDevice(pci);
+
+ break;
+ }
+
+ default:
+ ret = 0;
+ break;
+ }
+
+done:
+ return ret;
+}
+
+
+static int
+virSecurityDACRestoreSecurityPCILabel(pciDevice *dev ATTRIBUTE_UNUSED,
+ const char *file,
+ void *opaque ATTRIBUTE_UNUSED)
+{
+ return virSecurityDACRestoreSecurityFileLabel(file);
+}
+
+
+static int
+virSecurityDACRestoreSecurityUSBLabel(usbDevice *dev ATTRIBUTE_UNUSED,
+ const char *file,
+ void *opaque ATTRIBUTE_UNUSED)
+{
+ return virSecurityDACRestoreSecurityFileLabel(file);
+}
+
+
+static int
+virSecurityDACRestoreSecurityHostdevLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm ATTRIBUTE_UNUSED,
+ virDomainHostdevDefPtr dev)
+
+{
+ virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+ int ret = -1;
+
+ if (!priv->dynamicOwnership)
+ return 0;
+
+ if (dev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS)
+ return 0;
+
+ switch (dev->source.subsys.type) {
+ case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB: {
+ usbDevice *usb = usbGetDevice(dev->source.subsys.u.usb.bus,
+ dev->source.subsys.u.usb.device);
+
+ if (!usb)
+ goto done;
+
+ ret = usbDeviceFileIterate(usb, virSecurityDACRestoreSecurityUSBLabel, mgr);
+ usbFreeDevice(usb);
+
+ break;
+ }
+
+ case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI: {
+ pciDevice *pci = pciGetDevice(dev->source.subsys.u.pci.domain,
+ dev->source.subsys.u.pci.bus,
+ dev->source.subsys.u.pci.slot,
+ dev->source.subsys.u.pci.function);
+
+ if (!pci)
+ goto done;
+
+ ret = pciDeviceFileIterate(pci, virSecurityDACRestoreSecurityPCILabel, mgr);
+ pciFreeDevice(pci);
+
+ break;
+ }
+
+ default:
+ ret = 0;
+ break;
+ }
+
+done:
+ return ret;
+}
+
+
+static int
+virSecurityDACSetChardevLabel(virSecurityManagerPtr mgr,
+ virDomainChrDefPtr dev)
+
+{
+ virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+ char *in = NULL, *out = NULL;
+ int ret = -1;
+
+ switch (dev->type) {
+ case VIR_DOMAIN_CHR_TYPE_DEV:
+ case VIR_DOMAIN_CHR_TYPE_FILE:
+ ret = virSecurityDACSetOwnership(dev->data.file.path, priv->user, priv->group);
+ break;
+
+ case VIR_DOMAIN_CHR_TYPE_PIPE:
+ if ((virAsprintf(&in, "%s.in", dev->data.file.path) < 0) ||
+ (virAsprintf(&out, "%s.out", dev->data.file.path) < 0)) {
+ virReportOOMError();
+ goto done;
+ }
+ if ((virSecurityDACSetOwnership(in, priv->user, priv->group) < 0) ||
+ (virSecurityDACSetOwnership(out, priv->user, priv->group) < 0))
+ goto done;
+ ret = 0;
+ break;
+
+ default:
+ ret = 0;
+ break;
+ }
+
+done:
+ VIR_FREE(in);
+ VIR_FREE(out);
+ return ret;
+}
+
+static int
+virSecurityDACRestoreChardevLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
+ virDomainChrDefPtr dev)
+{
+ char *in = NULL, *out = NULL;
+ int ret = -1;
+
+ switch (dev->type) {
+ case VIR_DOMAIN_CHR_TYPE_DEV:
+ case VIR_DOMAIN_CHR_TYPE_FILE:
+ ret = virSecurityDACRestoreSecurityFileLabel(dev->data.file.path);
+ break;
+
+ case VIR_DOMAIN_CHR_TYPE_PIPE:
+ if ((virAsprintf(&out, "%s.out", dev->data.file.path) < 0) ||
+ (virAsprintf(&in, "%s.in", dev->data.file.path) < 0)) {
+ virReportOOMError();
+ goto done;
+ }
+ if ((virSecurityDACRestoreSecurityFileLabel(out) < 0) ||
+ (virSecurityDACRestoreSecurityFileLabel(in) < 0))
+ goto done;
+ ret = 0;
+ break;
+
+ default:
+ ret = 0;
+ break;
+ }
+
+done:
+ VIR_FREE(in);
+ VIR_FREE(out);
+ return ret;
+}
+
+
+static int
+virSecurityDACRestoreChardevCallback(virDomainDefPtr def ATTRIBUTE_UNUSED,
+ virDomainChrDefPtr dev,
+ void *opaque)
+{
+ virSecurityManagerPtr mgr = opaque;
+
+ return virSecurityDACRestoreChardevLabel(mgr, dev);
+}
+
+
+static int
+virSecurityDACRestoreSecurityAllLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm,
+ int migrated)
+{
+ virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+ int i;
+ int rc = 0;
+
+ if (!priv->dynamicOwnership)
+ return 0;
+
+
+ VIR_DEBUG("Restoring security label on %s migrated=%d",
+ vm->def->name, migrated);
+
+ for (i = 0 ; i < vm->def->nhostdevs ; i++) {
+ if (virSecurityDACRestoreSecurityHostdevLabel(mgr,
+ vm,
+ vm->def->hostdevs[i]) < 0)
+ rc = -1;
+ }
+ for (i = 0 ; i < vm->def->ndisks ; i++) {
+ if (virSecurityDACRestoreSecurityImageLabelInt(mgr,
+ vm,
+ vm->def->disks[i],
+ migrated) < 0)
+ rc = -1;
+ }
+
+ if (virDomainChrDefForeach(vm->def,
+ false,
+ virSecurityDACRestoreChardevCallback,
+ vm) < 0)
+ rc = -1;
+
+ if (vm->def->os.kernel &&
+ virSecurityDACRestoreSecurityFileLabel(vm->def->os.kernel) < 0)
+ rc = -1;
+
+ if (vm->def->os.initrd &&
+ virSecurityDACRestoreSecurityFileLabel(vm->def->os.initrd) < 0)
+ rc = -1;
+
+ return rc;
+}
+
+
+static int
+virSecurityDACSetChardevCallback(virDomainDefPtr def ATTRIBUTE_UNUSED,
+ virDomainChrDefPtr dev,
+ void *opaque)
+{
+ virSecurityManagerPtr mgr = opaque;
+
+ return virSecurityDACSetChardevLabel(mgr, dev);
+}
+
+
+static int
+virSecurityDACSetSecurityAllLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm,
+ const char *stdin_path ATTRIBUTE_UNUSED)
+{
+ virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+ int i;
+
+ if (!priv->dynamicOwnership)
+ return 0;
+
+ for (i = 0 ; i < vm->def->ndisks ; i++) {
+ /* XXX fixme - we need to recursively label the entriy tree :-( */
+ if (vm->def->disks[i]->type == VIR_DOMAIN_DISK_TYPE_DIR)
+ continue;
+ if (virSecurityDACSetSecurityImageLabel(mgr,
+ vm,
+ vm->def->disks[i]) < 0)
+ return -1;
+ }
+ for (i = 0 ; i < vm->def->nhostdevs ; i++) {
+ if (virSecurityDACSetSecurityHostdevLabel(mgr,
+ vm,
+ vm->def->hostdevs[i]) < 0)
+ return -1;
+ }
+
+ if (virDomainChrDefForeach(vm->def,
+ true,
+ virSecurityDACSetChardevCallback,
+ vm) < 0)
+ return -1;
+
+ if (vm->def->os.kernel &&
+ virSecurityDACSetOwnership(vm->def->os.kernel,
+ priv->user,
+ priv->group) < 0)
+ return -1;
+
+ if (vm->def->os.initrd &&
+ virSecurityDACSetOwnership(vm->def->os.initrd,
+ priv->user,
+ priv->group) < 0)
+ return -1;
+
+ return 0;
+}
+
+
+static int
+virSecurityDACSetSavedStateLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm ATTRIBUTE_UNUSED,
+ const char *savefile)
+{
+ virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+
+ return virSecurityDACSetOwnership(savefile, priv->user, priv->group);
+}
+
+
+static int
+virSecurityDACRestoreSavedStateLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm ATTRIBUTE_UNUSED,
+ const char *savefile)
+{
+ virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+
+ if (!priv->dynamicOwnership)
+ return 0;
+
+ return virSecurityDACRestoreSecurityFileLabel(savefile);
+}
+
+
+static int
+virSecurityDACSetProcessLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm ATTRIBUTE_UNUSED)
+{
+ virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+
+ DEBUG("Dropping privileges of VM to %d:%d", priv->user, priv->group);
+
+ if (virSetUIDGID(priv->user, priv->group) < 0)
+ return -1;
+
+ return 0;
+}
+
+
+static int
+virSecurityDACVerify(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
+ virDomainDefPtr def ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+static int
+virSecurityDACGenLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
+ virDomainObjPtr vm ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+static int
+virSecurityDACReleaseLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
+ virDomainObjPtr vm ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+static int
+virSecurityDACReserveLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
+ virDomainObjPtr vm ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+static int
+virSecurityDACGetProcessLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
+ virDomainObjPtr vm ATTRIBUTE_UNUSED,
+ virSecurityLabelPtr seclabel ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+static int
+virSecurityDACSetSocketLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
+ virDomainObjPtr vm ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+
+static int
+virSecurityDACClearSocketLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
+ virDomainObjPtr vm ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+
+virSecurityDriver virSecurityDriverDAC = {
+ sizeof(virSecurityDACData),
+ "virDAC",
+
+ virSecurityDACProbe,
+ virSecurityDACOpen,
+ virSecurityDACClose,
+
+ virSecurityDACGetModel,
+ virSecurityDACGetDOI,
+
+ virSecurityDACVerify,
+
+ virSecurityDACSetSecurityImageLabel,
+ virSecurityDACRestoreSecurityImageLabel,
+
+ virSecurityDACSetSocketLabel,
+ virSecurityDACClearSocketLabel,
+
+ virSecurityDACGenLabel,
+ virSecurityDACReserveLabel,
+ virSecurityDACReleaseLabel,
+
+ virSecurityDACGetProcessLabel,
+ virSecurityDACSetProcessLabel,
+
+ virSecurityDACSetSecurityAllLabel,
+ virSecurityDACRestoreSecurityAllLabel,
+
+ virSecurityDACSetSecurityHostdevLabel,
+ virSecurityDACRestoreSecurityHostdevLabel,
+
+ virSecurityDACSetSavedStateLabel,
+ virSecurityDACRestoreSavedStateLabel,
+};
diff --git a/src/security/security_dac.h b/src/security/security_dac.h
new file mode 100644
index 0000000..b690236
--- /dev/null
+++ b/src/security/security_dac.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2010 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.
+ *
+ * POSIX DAC security driver
+ */
+
+#include "security_driver.h"
+
+#ifndef __VIR_SECURITY_DAC
+# define __VIR_SECURITY_DAC
+
+extern virSecurityDriver virSecurityDriverDAC;
+
+void virSecurityDACSetUser(virSecurityManagerPtr mgr,
+ uid_t user);
+void virSecurityDACSetGroup(virSecurityManagerPtr mgr,
+ gid_t group);
+
+void virSecurityDACSetDynamicOwnership(virSecurityManagerPtr mgr,
+ bool dynamic);
+
+#endif /* __VIR_SECURITY_DAC */
diff --git a/src/security/security_driver.c b/src/security/security_driver.c
index 9e32fa4..6d75dcc 100644
--- a/src/security/security_driver.c
+++ b/src/security/security_driver.c
@@ -24,116 +24,52 @@
# include "security_apparmor.h"
#endif
+#include "security_nop.h"
+
static virSecurityDriverPtr security_drivers[] = {
#ifdef WITH_SECDRIVER_SELINUX
- &virSELinuxSecurityDriver,
+ &virSecurityDriverSELinux,
#endif
#ifdef WITH_SECDRIVER_APPARMOR
&virAppArmorSecurityDriver,
#endif
- NULL
+ &virSecurityDriverNop, /* Must always be last, since it will always probe */
};
-int
-virSecurityDriverVerify(virDomainDefPtr def)
-{
- unsigned int i;
- const virSecurityLabelDefPtr secdef = &def->seclabel;
-
- if (!secdef->model ||
- STREQ(secdef->model, "none"))
- return 0;
-
- for (i = 0; security_drivers[i] != NULL ; i++) {
- if (STREQ(security_drivers[i]->name, secdef->model)) {
- return security_drivers[i]->domainSecurityVerify(def);
- }
- }
- virSecurityReportError(VIR_ERR_XML_ERROR,
- _("invalid security model '%s'"), secdef->model);
- return -1;
-}
-
-int
-virSecurityDriverStartup(virSecurityDriverPtr *drv,
- const char *name,
- bool allowDiskFormatProbing)
+virSecurityDriverPtr virSecurityDriverLookup(const char *name)
{
- unsigned int i;
-
- if (name && STREQ(name, "none"))
- return -2;
+ virSecurityDriverPtr drv = NULL;
+ int i;
- for (i = 0; security_drivers[i] != NULL ; i++) {
+ for (i = 0; i < ARRAY_CARDINALITY(security_drivers) ; i++) {
virSecurityDriverPtr tmp = security_drivers[i];
- if (name && STRNEQ(tmp->name, name))
- continue;
-
- switch (tmp->probe()) {
- case SECURITY_DRIVER_ENABLE:
- virSecurityDriverInit(tmp);
- if (tmp->open(tmp, allowDiskFormatProbing) == -1) {
- return -1;
- } else {
- *drv = tmp;
- return 0;
+ if (name) {
+ if (STREQ(tmp->name, name)) {
+ drv = tmp;
+ break;
}
- break;
+ } else {
+ switch (tmp->probe()) {
+ case SECURITY_DRIVER_ENABLE:
+ drv = tmp;
+ break;
- case SECURITY_DRIVER_DISABLE:
- break;
+ case SECURITY_DRIVER_DISABLE:
+ break;
- default:
- return -1;
+ default:
+ return NULL;
+ }
}
}
- return -2;
-}
-
-/*
- * Helpers
- */
-void
-virSecurityDriverInit(virSecurityDriverPtr drv)
-{
- memset(&drv->_private, 0, sizeof drv->_private);
-}
-int
-virSecurityDriverSetDOI(virSecurityDriverPtr drv,
- const char *doi)
-{
- if (strlen(doi) >= VIR_SECURITY_DOI_BUFLEN) {
+ if (!drv) {
virSecurityReportError(VIR_ERR_INTERNAL_ERROR,
- _("%s: DOI \'%s\' is "
- "longer than the maximum allowed length of %d"),
- __func__, doi, VIR_SECURITY_DOI_BUFLEN - 1);
- return -1;
+ "Security driver %s not found", NULLSTR(name));
+ return NULL;
}
- strcpy(drv->_private.doi, doi);
- return 0;
-}
-
-const char *
-virSecurityDriverGetDOI(virSecurityDriverPtr drv)
-{
- return drv->_private.doi;
-}
-const char *
-virSecurityDriverGetModel(virSecurityDriverPtr drv)
-{
- return drv->name;
+ return drv;
}
-void virSecurityDriverSetAllowDiskFormatProbing(virSecurityDriverPtr drv,
- bool allowDiskFormatProbing)
-{
- drv->_private.allowDiskFormatProbing = allowDiskFormatProbing;
-}
-
-bool virSecurityDriverGetAllowDiskFormatProbing(virSecurityDriverPtr drv)
-{
- return drv->_private.allowDiskFormatProbing;
-}
diff --git a/src/security/security_driver.h b/src/security/security_driver.h
index d768f32..e5a8d41 100644
--- a/src/security/security_driver.h
+++ b/src/security/security_driver.h
@@ -16,6 +16,8 @@
# include "internal.h"
# include "domain_conf.h"
+# include "security_manager.h"
+
/*
* Return values for security driver probing: the driver will determine
* whether it should be enabled or disabled.
@@ -29,104 +31,91 @@ typedef enum {
typedef struct _virSecurityDriver virSecurityDriver;
typedef virSecurityDriver *virSecurityDriverPtr;
-typedef struct _virSecurityDriverState virSecurityDriverState;
-typedef virSecurityDriverState *virSecurityDriverStatePtr;
-
typedef virSecurityDriverStatus (*virSecurityDriverProbe) (void);
-typedef int (*virSecurityDriverOpen) (virSecurityDriverPtr drv,
- bool allowDiskFormatProbing);
-typedef int (*virSecurityDomainRestoreImageLabel) (virSecurityDriverPtr drv,
+typedef int (*virSecurityDriverOpen) (virSecurityManagerPtr mgr);
+typedef int (*virSecurityDriverClose) (virSecurityManagerPtr mgr);
+
+typedef const char *(*virSecurityDriverGetModel) (virSecurityManagerPtr mgr);
+typedef const char *(*virSecurityDriverGetDOI) (virSecurityManagerPtr mgr);
+
+typedef int (*virSecurityDomainRestoreImageLabel) (virSecurityManagerPtr mgr,
virDomainObjPtr vm,
virDomainDiskDefPtr disk);
-typedef int (*virSecurityDomainSetSocketLabel) (virSecurityDriverPtr drv,
+typedef int (*virSecurityDomainSetSocketLabel) (virSecurityManagerPtr mgr,
virDomainObjPtr vm);
-typedef int (*virSecurityDomainClearSocketLabel)(virSecurityDriverPtr drv,
+typedef int (*virSecurityDomainClearSocketLabel)(virSecurityManagerPtr mgr,
virDomainObjPtr vm);
-typedef int (*virSecurityDomainSetImageLabel) (virSecurityDriverPtr drv,
+typedef int (*virSecurityDomainSetImageLabel) (virSecurityManagerPtr mgr,
virDomainObjPtr vm,
virDomainDiskDefPtr disk);
-typedef int (*virSecurityDomainRestoreHostdevLabel) (virSecurityDriverPtr drv,
+typedef int (*virSecurityDomainRestoreHostdevLabel) (virSecurityManagerPtr mgr,
virDomainObjPtr vm,
virDomainHostdevDefPtr dev);
-typedef int (*virSecurityDomainSetHostdevLabel) (virSecurityDriverPtr drv,
+typedef int (*virSecurityDomainSetHostdevLabel) (virSecurityManagerPtr mgr,
virDomainObjPtr vm,
virDomainHostdevDefPtr dev);
-typedef int (*virSecurityDomainSetSavedStateLabel) (virSecurityDriverPtr drv,
+typedef int (*virSecurityDomainSetSavedStateLabel) (virSecurityManagerPtr mgr,
virDomainObjPtr vm,
const char *savefile);
-typedef int (*virSecurityDomainRestoreSavedStateLabel) (virSecurityDriverPtr drv,
+typedef int (*virSecurityDomainRestoreSavedStateLabel) (virSecurityManagerPtr mgr,
virDomainObjPtr vm,
const char *savefile);
-typedef int (*virSecurityDomainGenLabel) (virSecurityDriverPtr drv,
+typedef int (*virSecurityDomainGenLabel) (virSecurityManagerPtr mgr,
virDomainObjPtr sec);
-typedef int (*virSecurityDomainReserveLabel) (virSecurityDriverPtr drv,
+typedef int (*virSecurityDomainReserveLabel) (virSecurityManagerPtr mgr,
virDomainObjPtr sec);
-typedef int (*virSecurityDomainReleaseLabel) (virSecurityDriverPtr drv,
+typedef int (*virSecurityDomainReleaseLabel) (virSecurityManagerPtr mgr,
virDomainObjPtr sec);
-typedef int (*virSecurityDomainSetAllLabel) (virSecurityDriverPtr drv,
+typedef int (*virSecurityDomainSetAllLabel) (virSecurityManagerPtr mgr,
virDomainObjPtr sec,
const char *stdin_path);
-typedef int (*virSecurityDomainRestoreAllLabel) (virSecurityDriverPtr drv,
+typedef int (*virSecurityDomainRestoreAllLabel) (virSecurityManagerPtr mgr,
virDomainObjPtr vm,
int migrated);
-typedef int (*virSecurityDomainGetProcessLabel) (virSecurityDriverPtr drv,
+typedef int (*virSecurityDomainGetProcessLabel) (virSecurityManagerPtr mgr,
virDomainObjPtr vm,
virSecurityLabelPtr sec);
-typedef int (*virSecurityDomainSetProcessLabel) (virSecurityDriverPtr drv,
+typedef int (*virSecurityDomainSetProcessLabel) (virSecurityManagerPtr mgr,
virDomainObjPtr vm);
-typedef int (*virSecurityDomainSecurityVerify) (virDomainDefPtr def);
+typedef int (*virSecurityDomainSecurityVerify) (virSecurityManagerPtr mgr,
+ virDomainDefPtr def);
+
struct _virSecurityDriver {
+ size_t privateDataLen;
const char *name;
virSecurityDriverProbe probe;
virSecurityDriverOpen open;
+ virSecurityDriverClose close;
+
+ virSecurityDriverGetModel getModel;
+ virSecurityDriverGetDOI getDOI;
+
virSecurityDomainSecurityVerify domainSecurityVerify;
+
+ virSecurityDomainSetImageLabel domainSetSecurityImageLabel;
virSecurityDomainRestoreImageLabel domainRestoreSecurityImageLabel;
+
virSecurityDomainSetSocketLabel domainSetSecuritySocketLabel;
virSecurityDomainClearSocketLabel domainClearSecuritySocketLabel;
- virSecurityDomainSetImageLabel domainSetSecurityImageLabel;
+
virSecurityDomainGenLabel domainGenSecurityLabel;
virSecurityDomainReserveLabel domainReserveSecurityLabel;
virSecurityDomainReleaseLabel domainReleaseSecurityLabel;
+
virSecurityDomainGetProcessLabel domainGetSecurityProcessLabel;
virSecurityDomainSetProcessLabel domainSetSecurityProcessLabel;
+
virSecurityDomainSetAllLabel domainSetSecurityAllLabel;
virSecurityDomainRestoreAllLabel domainRestoreSecurityAllLabel;
- virSecurityDomainRestoreHostdevLabel domainRestoreSecurityHostdevLabel;
+
virSecurityDomainSetHostdevLabel domainSetSecurityHostdevLabel;
+ virSecurityDomainRestoreHostdevLabel domainRestoreSecurityHostdevLabel;
+
virSecurityDomainSetSavedStateLabel domainSetSavedStateLabel;
virSecurityDomainRestoreSavedStateLabel domainRestoreSavedStateLabel;
-
- /*
- * This is internally managed driver state and should only be accessed
- * via helpers below.
- */
- struct {
- char doi[VIR_SECURITY_DOI_BUFLEN];
- bool allowDiskFormatProbing;
- } _private;
};
-/* Global methods */
-int virSecurityDriverStartup(virSecurityDriverPtr *drv,
- const char *name,
- bool allowDiskFormatProbing);
-
-int
-virSecurityDriverVerify(virDomainDefPtr def);
-
-# define virSecurityReportError(code, ...) \
- virReportErrorHelper(NULL, VIR_FROM_SECURITY, code, __FILE__, \
- __FUNCTION__, __LINE__, __VA_ARGS__)
-
-/* Helpers */
-void virSecurityDriverInit(virSecurityDriverPtr drv);
-int virSecurityDriverSetDOI(virSecurityDriverPtr drv,
- const char *doi);
-void virSecurityDriverSetAllowDiskFormatProbing(virSecurityDriverPtr drv,
- bool allowDiskFormatProbing);
-const char *virSecurityDriverGetDOI(virSecurityDriverPtr drv);
-const char *virSecurityDriverGetModel(virSecurityDriverPtr drv);
-bool virSecurityDriverGetAllowDiskFormatProbing(virSecurityDriverPtr drv);
+virSecurityDriverPtr virSecurityDriverLookup(const char *name);
#endif /* __VIR_SECURITY_H__ */
diff --git a/src/security/security_manager.c b/src/security/security_manager.c
new file mode 100644
index 0000000..7ab6e37
--- /dev/null
+++ b/src/security/security_manager.c
@@ -0,0 +1,291 @@
+
+#include <config.h>
+
+
+#include "security_driver.h"
+#include "security_stack.h"
+#include "security_dac.h"
+#include "virterror_internal.h"
+#include "memory.h"
+#include "logging.h"
+
+#define VIR_FROM_THIS VIR_FROM_SECURITY
+
+
+struct _virSecurityManager {
+ virSecurityDriverPtr drv;
+ bool allowDiskFormatProbing;
+};
+
+static virSecurityManagerPtr virSecurityManagerNewDriver(virSecurityDriverPtr drv,
+ bool allowDiskFormatProbing)
+{
+ virSecurityManagerPtr mgr;
+
+ if (VIR_ALLOC_VAR(mgr, char, drv->privateDataLen) < 0) {
+ virReportOOMError();
+ return NULL;
+ }
+
+ mgr->drv = drv;
+ mgr->allowDiskFormatProbing = allowDiskFormatProbing;
+
+ if (drv->open(mgr) < 0) {
+ virSecurityManagerFree(mgr);
+ return NULL;
+ }
+
+ return mgr;
+}
+
+virSecurityManagerPtr virSecurityManagerNewStack(virSecurityManagerPtr primary,
+ virSecurityManagerPtr secondary)
+{
+ virSecurityManagerPtr mgr =
+ virSecurityManagerNewDriver(&virSecurityDriverStack,
+ virSecurityManagerGetAllowDiskFormatProbing(primary));
+
+ virSecurityStackSetPrimary(mgr, primary);
+ virSecurityStackSetSecondary(mgr, secondary);
+
+ return mgr;
+}
+
+virSecurityManagerPtr virSecurityManagerNewDAC(uid_t user,
+ gid_t group,
+ bool allowDiskFormatProbing,
+ bool dynamicOwnership)
+{
+ virSecurityManagerPtr mgr =
+ virSecurityManagerNewDriver(&virSecurityDriverDAC,
+ allowDiskFormatProbing);
+
+ virSecurityDACSetUser(mgr, user);
+ virSecurityDACSetGroup(mgr, group);
+ virSecurityDACSetDynamicOwnership(mgr, dynamicOwnership);
+
+ return mgr;
+}
+
+virSecurityManagerPtr virSecurityManagerNew(const char *name,
+ bool allowDiskFormatProbing)
+{
+ virSecurityDriverPtr drv = virSecurityDriverLookup(name);
+ if (!drv)
+ return NULL;
+
+ return virSecurityManagerNewDriver(drv, allowDiskFormatProbing);
+}
+
+
+void *virSecurityManagerGetPrivateData(virSecurityManagerPtr mgr)
+{
+ return mgr + sizeof(mgr);
+}
+
+
+void virSecurityManagerFree(virSecurityManagerPtr mgr)
+{
+ if (!mgr)
+ return;
+
+ if (mgr->drv->close)
+ mgr->drv->close(mgr);
+
+ VIR_FREE(mgr);
+}
+
+const char *
+virSecurityManagerGetDOI(virSecurityManagerPtr mgr)
+{
+ if (mgr->drv->getDOI)
+ return mgr->drv->getDOI(mgr);
+
+ virSecurityReportError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ return NULL;
+}
+
+const char *
+virSecurityManagerGetModel(virSecurityManagerPtr mgr)
+{
+ if (mgr->drv->getModel)
+ return mgr->drv->getModel(mgr);
+
+ virSecurityReportError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ return NULL;
+}
+
+bool virSecurityManagerGetAllowDiskFormatProbing(virSecurityManagerPtr mgr)
+{
+ return mgr->allowDiskFormatProbing;
+}
+
+int virSecurityManagerRestoreImageLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm,
+ virDomainDiskDefPtr disk)
+{
+ if (mgr->drv->domainRestoreSecurityImageLabel)
+ return mgr->drv->domainRestoreSecurityImageLabel(mgr, vm, disk);
+
+ virSecurityReportError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ return -1;
+}
+
+int virSecurityManagerSetSocketLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm)
+{
+ if (mgr->drv->domainSetSecuritySocketLabel)
+ return mgr->drv->domainSetSecuritySocketLabel(mgr, vm);
+
+ virSecurityReportError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ return -1;
+}
+
+int virSecurityManagerClearSocketLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm)
+{
+ if (mgr->drv->domainClearSecuritySocketLabel)
+ return mgr->drv->domainClearSecuritySocketLabel(mgr, vm);
+
+ virSecurityReportError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ return -1;
+}
+
+int virSecurityManagerSetImageLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm,
+ virDomainDiskDefPtr disk)
+{
+ if (mgr->drv->domainSetSecurityImageLabel)
+ return mgr->drv->domainSetSecurityImageLabel(mgr, vm, disk);
+
+ virSecurityReportError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ return -1;
+}
+
+int virSecurityManagerRestoreHostdevLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm,
+ virDomainHostdevDefPtr dev)
+{
+ if (mgr->drv->domainRestoreSecurityHostdevLabel)
+ return mgr->drv->domainRestoreSecurityHostdevLabel(mgr, vm, dev);
+
+ virSecurityReportError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ return -1;
+}
+
+int virSecurityManagerSetHostdevLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm,
+ virDomainHostdevDefPtr dev)
+{
+ if (mgr->drv->domainSetSecurityHostdevLabel)
+ return mgr->drv->domainSetSecurityHostdevLabel(mgr, vm, dev);
+
+ virSecurityReportError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ return -1;
+}
+
+int virSecurityManagerSetSavedStateLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm,
+ const char *savefile)
+{
+ if (mgr->drv->domainSetSavedStateLabel)
+ return mgr->drv->domainSetSavedStateLabel(mgr, vm, savefile);
+
+ virSecurityReportError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ return -1;
+}
+
+int virSecurityManagerRestoreSavedStateLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm,
+ const char *savefile)
+{
+ if (mgr->drv->domainRestoreSavedStateLabel)
+ return mgr->drv->domainRestoreSavedStateLabel(mgr, vm, savefile);
+
+ virSecurityReportError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ return -1;
+}
+
+int virSecurityManagerGenLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm)
+{
+ if (mgr->drv->domainGenSecurityLabel)
+ return mgr->drv->domainGenSecurityLabel(mgr, vm);
+
+ virSecurityReportError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ return -1;
+}
+
+int virSecurityManagerReserveLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm)
+{
+ if (mgr->drv->domainReserveSecurityLabel)
+ return mgr->drv->domainReserveSecurityLabel(mgr, vm);
+
+ virSecurityReportError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ return -1;
+}
+
+int virSecurityManagerReleaseLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm)
+{
+ if (mgr->drv->domainReleaseSecurityLabel)
+ return mgr->drv->domainReleaseSecurityLabel(mgr, vm);
+
+ virSecurityReportError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ return -1;
+}
+
+int virSecurityManagerSetAllLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm,
+ const char *stdin_path)
+{
+ if (mgr->drv->domainSetSecurityAllLabel)
+ return mgr->drv->domainSetSecurityAllLabel(mgr, vm, stdin_path);
+
+ virSecurityReportError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ return -1;
+}
+
+int virSecurityManagerRestoreAllLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm,
+ int migrated)
+{
+ if (mgr->drv->domainRestoreSecurityAllLabel)
+ return mgr->drv->domainRestoreSecurityAllLabel(mgr, vm, migrated);
+
+ virSecurityReportError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ return -1;
+}
+
+int virSecurityManagerGetProcessLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm,
+ virSecurityLabelPtr sec)
+{
+ if (mgr->drv->domainGetSecurityProcessLabel)
+ return mgr->drv->domainGetSecurityProcessLabel(mgr, vm, sec);
+
+ virSecurityReportError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ return -1;
+}
+
+int virSecurityManagerSetProcessLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm)
+{
+ if (mgr->drv->domainSetSecurityProcessLabel)
+ return mgr->drv->domainSetSecurityProcessLabel(mgr, vm);
+
+ virSecurityReportError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ return -1;
+}
+
+int virSecurityManagerVerify(virSecurityManagerPtr mgr,
+ virDomainDefPtr def)
+{
+ if (mgr->drv->domainSecurityVerify)
+ return mgr->drv->domainSecurityVerify(mgr, def);
+
+ virSecurityReportError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ return -1;
+}
+
diff --git a/src/security/security_manager.h b/src/security/security_manager.h
new file mode 100644
index 0000000..c0ef84f
--- /dev/null
+++ b/src/security/security_manager.h
@@ -0,0 +1,74 @@
+
+#ifndef VIR_SECURITY_MANAGER_H__
+#define VIR_SECURITY_MANAGER_H__
+
+# define virSecurityReportError(code, ...) \
+ virReportErrorHelper(NULL, VIR_FROM_SECURITY, code, __FILE__, \
+ __FUNCTION__, __LINE__, __VA_ARGS__)
+
+
+typedef struct _virSecurityManager virSecurityManager;
+typedef virSecurityManager *virSecurityManagerPtr;
+
+virSecurityManagerPtr virSecurityManagerNew(const char *name,
+ bool allowDiskFormatProbing);
+
+virSecurityManagerPtr virSecurityManagerNewStack(virSecurityManagerPtr primary,
+ virSecurityManagerPtr secondary);
+
+virSecurityManagerPtr virSecurityManagerNewDAC(uid_t user,
+ gid_t group,
+ bool allowDiskFormatProbing,
+ bool dynamicOwnership);
+
+void *virSecurityManagerGetPrivateData(virSecurityManagerPtr mgr);
+
+void virSecurityManagerFree(virSecurityManagerPtr mgr);
+
+const char *virSecurityManagerGetDOI(virSecurityManagerPtr mgr);
+const char *virSecurityManagerGetModel(virSecurityManagerPtr mgr);
+bool virSecurityManagerGetAllowDiskFormatProbing(virSecurityManagerPtr mgr);
+
+int virSecurityManagerRestoreImageLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm,
+ virDomainDiskDefPtr disk);
+int virSecurityManagerSetSocketLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm);
+int virSecurityManagerClearSocketLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm);
+int virSecurityManagerSetImageLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm,
+ virDomainDiskDefPtr disk);
+int virSecurityManagerRestoreHostdevLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm,
+ virDomainHostdevDefPtr dev);
+int virSecurityManagerSetHostdevLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm,
+ virDomainHostdevDefPtr dev);
+int virSecurityManagerSetSavedStateLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm,
+ const char *savefile);
+int virSecurityManagerRestoreSavedStateLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm,
+ const char *savefile);
+int virSecurityManagerGenLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr sec);
+int virSecurityManagerReserveLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr sec);
+int virSecurityManagerReleaseLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr sec);
+int virSecurityManagerSetAllLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr sec,
+ const char *stdin_path);
+int virSecurityManagerRestoreAllLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm,
+ int migrated);
+int virSecurityManagerGetProcessLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm,
+ virSecurityLabelPtr sec);
+int virSecurityManagerSetProcessLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm);
+int virSecurityManagerVerify(virSecurityManagerPtr mgr,
+ virDomainDefPtr def);
+
+#endif /* VIR_SECURITY_MANAGER_H__ */
diff --git a/src/security/security_nop.c b/src/security/security_nop.c
new file mode 100644
index 0000000..947cf55
--- /dev/null
+++ b/src/security/security_nop.c
@@ -0,0 +1,168 @@
+
+
+#include <config.h>
+
+#include "security_nop.h"
+
+static virSecurityDriverStatus virSecurityDriverProbeNop(void)
+{
+ return SECURITY_DRIVER_ENABLE;
+}
+
+static int virSecurityDriverOpenNop(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+static int virSecurityDriverCloseNop(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+static const char * virSecurityDriverGetModelNop(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED)
+{
+ return "none";
+}
+
+static const char * virSecurityDriverGetDOINop(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED)
+{
+ return "0";
+}
+
+static int virSecurityDomainRestoreImageLabelNop(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
+ virDomainObjPtr vm ATTRIBUTE_UNUSED,
+ virDomainDiskDefPtr disk ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+static int virSecurityDomainSetSocketLabelNop(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
+ virDomainObjPtr vm ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+static int virSecurityDomainClearSocketLabelNop(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
+ virDomainObjPtr vm ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+static int virSecurityDomainSetImageLabelNop(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
+ virDomainObjPtr vm ATTRIBUTE_UNUSED,
+ virDomainDiskDefPtr disk ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+static int virSecurityDomainRestoreHostdevLabelNop(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
+ virDomainObjPtr vm ATTRIBUTE_UNUSED,
+ virDomainHostdevDefPtr dev ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+static int virSecurityDomainSetHostdevLabelNop(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
+ virDomainObjPtr vm ATTRIBUTE_UNUSED,
+ virDomainHostdevDefPtr dev ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+static int virSecurityDomainSetSavedStateLabelNop(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
+ virDomainObjPtr vm ATTRIBUTE_UNUSED,
+ const char *savefile ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+static int virSecurityDomainRestoreSavedStateLabelNop(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
+ virDomainObjPtr vm ATTRIBUTE_UNUSED,
+ const char *savefile ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+static int virSecurityDomainGenLabelNop(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
+ virDomainObjPtr sec ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+static int virSecurityDomainReserveLabelNop(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
+ virDomainObjPtr sec ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+static int virSecurityDomainReleaseLabelNop(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
+ virDomainObjPtr sec ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+static int virSecurityDomainSetAllLabelNop(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
+ virDomainObjPtr sec ATTRIBUTE_UNUSED,
+ const char *stdin_path ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+static int virSecurityDomainRestoreAllLabelNop(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
+ virDomainObjPtr vm ATTRIBUTE_UNUSED,
+ int migrated ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+static int virSecurityDomainGetProcessLabelNop(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
+ virDomainObjPtr vm ATTRIBUTE_UNUSED,
+ virSecurityLabelPtr sec ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+static int virSecurityDomainSetProcessLabelNop(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
+ virDomainObjPtr vm ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+static int virSecurityDomainVerifyNop(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
+ virDomainDefPtr def ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+virSecurityDriver virSecurityDriverNop = {
+ 0,
+ "nop",
+ virSecurityDriverProbeNop,
+ virSecurityDriverOpenNop,
+ virSecurityDriverCloseNop,
+
+ virSecurityDriverGetModelNop,
+ virSecurityDriverGetDOINop,
+
+ virSecurityDomainVerifyNop,
+
+ virSecurityDomainSetImageLabelNop,
+ virSecurityDomainRestoreImageLabelNop,
+
+ virSecurityDomainSetSocketLabelNop,
+ virSecurityDomainClearSocketLabelNop,
+
+ virSecurityDomainGenLabelNop,
+ virSecurityDomainReserveLabelNop,
+ virSecurityDomainReleaseLabelNop,
+
+ virSecurityDomainGetProcessLabelNop,
+ virSecurityDomainSetProcessLabelNop,
+
+ virSecurityDomainSetAllLabelNop,
+ virSecurityDomainRestoreAllLabelNop,
+
+ virSecurityDomainSetHostdevLabelNop,
+ virSecurityDomainRestoreHostdevLabelNop,
+
+ virSecurityDomainSetSavedStateLabelNop,
+ virSecurityDomainRestoreSavedStateLabelNop,
+};
diff --git a/src/security/security_nop.h b/src/security/security_nop.h
new file mode 100644
index 0000000..714e646
--- /dev/null
+++ b/src/security/security_nop.h
@@ -0,0 +1,17 @@
+/*
+ * Copyright (C) 2010 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.
+ *
+ */
+#ifndef __VIR_SECURITY_NOP_H__
+# define __VIR_SECURITY_NOP_H__
+
+#include "security_driver.h"
+
+extern virSecurityDriver virSecurityDriverNop;
+
+#endif /* __VIR_SECURITY_NOP_H__ */
diff --git a/src/security/security_selinux.c b/src/security/security_selinux.c
index 47da677..d06afde 100644
--- a/src/security/security_selinux.c
+++ b/src/security/security_selinux.c
@@ -160,7 +160,7 @@ SELinuxInitialize(void)
}
static int
-SELinuxGenSecurityLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
+SELinuxGenSecurityLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
virDomainObjPtr vm)
{
int rc = -1;
@@ -225,7 +225,7 @@ done:
}
static int
-SELinuxReserveSecurityLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
+SELinuxReserveSecurityLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
virDomainObjPtr vm)
{
security_context_t pctx;
@@ -270,20 +270,34 @@ SELinuxSecurityDriverProbe(void)
}
static int
-SELinuxSecurityDriverOpen(virSecurityDriverPtr drv,
- bool allowDiskFormatProbing)
+SELinuxSecurityDriverOpen(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED)
+{
+ return SELinuxInitialize();
+}
+
+static int
+SELinuxSecurityDriverClose(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+
+static const char *SELinuxSecurityGetModel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED)
+{
+ return SECURITY_SELINUX_NAME;
+}
+
+static const char *SELinuxSecurityGetDOI(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED)
{
/*
* Where will the DOI come from? SELinux configuration, or qemu
* configuration? For the moment, we'll just set it to "0".
*/
- virSecurityDriverSetDOI(drv, SECURITY_SELINUX_VOID_DOI);
- virSecurityDriverSetAllowDiskFormatProbing(drv, allowDiskFormatProbing);
- return SELinuxInitialize();
+ return SECURITY_SELINUX_VOID_DOI;
}
static int
-SELinuxGetSecurityProcessLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
+SELinuxGetSecurityProcessLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
virDomainObjPtr vm,
virSecurityLabelPtr sec)
{
@@ -415,7 +429,7 @@ err:
}
static int
-SELinuxRestoreSecurityImageLabelInt(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
+SELinuxRestoreSecurityImageLabelInt(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
virDomainObjPtr vm,
virDomainDiskDefPtr disk,
int migrated)
@@ -460,11 +474,11 @@ SELinuxRestoreSecurityImageLabelInt(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
static int
-SELinuxRestoreSecurityImageLabel(virSecurityDriverPtr drv,
+SELinuxRestoreSecurityImageLabel(virSecurityManagerPtr mgr,
virDomainObjPtr vm,
virDomainDiskDefPtr disk)
{
- return SELinuxRestoreSecurityImageLabelInt(drv, vm, disk, 0);
+ return SELinuxRestoreSecurityImageLabelInt(mgr, vm, disk, 0);
}
@@ -498,13 +512,13 @@ SELinuxSetSecurityFileLabel(virDomainDiskDefPtr disk,
}
static int
-SELinuxSetSecurityImageLabel(virSecurityDriverPtr drv,
+SELinuxSetSecurityImageLabel(virSecurityManagerPtr mgr,
virDomainObjPtr vm,
virDomainDiskDefPtr disk)
{
const virSecurityLabelDefPtr secdef = &vm->def->seclabel;
- bool allowDiskFormatProbing = virSecurityDriverGetAllowDiskFormatProbing(drv);
+ bool allowDiskFormatProbing = virSecurityManagerGetAllowDiskFormatProbing(mgr);
if (secdef->type == VIR_DOMAIN_SECLABEL_STATIC)
return 0;
@@ -538,7 +552,7 @@ SELinuxSetSecurityUSBLabel(usbDevice *dev ATTRIBUTE_UNUSED,
}
static int
-SELinuxSetSecurityHostdevLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
+SELinuxSetSecurityHostdevLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
virDomainObjPtr vm,
virDomainHostdevDefPtr dev)
@@ -607,7 +621,7 @@ SELinuxRestoreSecurityUSBLabel(usbDevice *dev ATTRIBUTE_UNUSED,
}
static int
-SELinuxRestoreSecurityHostdevLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
+SELinuxRestoreSecurityHostdevLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
virDomainObjPtr vm,
virDomainHostdevDefPtr dev)
@@ -756,7 +770,7 @@ SELinuxRestoreSecurityChardevCallback(virDomainDefPtr def ATTRIBUTE_UNUSED,
static int
-SELinuxRestoreSecurityAllLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
+SELinuxRestoreSecurityAllLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
virDomainObjPtr vm,
int migrated ATTRIBUTE_UNUSED)
{
@@ -770,13 +784,13 @@ SELinuxRestoreSecurityAllLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
return 0;
for (i = 0 ; i < vm->def->nhostdevs ; i++) {
- if (SELinuxRestoreSecurityHostdevLabel(drv,
+ if (SELinuxRestoreSecurityHostdevLabel(mgr,
vm,
vm->def->hostdevs[i]) < 0)
rc = -1;
}
for (i = 0 ; i < vm->def->ndisks ; i++) {
- if (SELinuxRestoreSecurityImageLabelInt(drv,
+ if (SELinuxRestoreSecurityImageLabelInt(mgr,
vm,
vm->def->disks[i],
migrated) < 0)
@@ -801,7 +815,7 @@ SELinuxRestoreSecurityAllLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
}
static int
-SELinuxReleaseSecurityLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
+SELinuxReleaseSecurityLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
virDomainObjPtr vm)
{
const virSecurityLabelDefPtr secdef = &vm->def->seclabel;
@@ -825,7 +839,7 @@ SELinuxReleaseSecurityLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
static int
-SELinuxSetSavedStateLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
+SELinuxSetSavedStateLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
virDomainObjPtr vm,
const char *savefile)
{
@@ -839,7 +853,7 @@ SELinuxSetSavedStateLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
static int
-SELinuxRestoreSavedStateLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
+SELinuxRestoreSavedStateLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
virDomainObjPtr vm,
const char *savefile)
{
@@ -853,9 +867,19 @@ SELinuxRestoreSavedStateLabel(virSecurityDriverPtr drv ATTRIBUTE_UNUSED,
static int
-SELinuxSecurityVerify(virDomainDefPtr def)
+SELinuxSecurityVerify(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
+ virDomainDefPtr def)
{
const virSecurityLabelDefPtr secdef = &def->seclabel;
+ if (!STREQ(virSecurityManagerGetModel(mgr), secdef->model)) {
+ virSecurityReportError(VIR_ERR_INTERNAL_ERROR,
+ _("security label driver mismatch: "
+ "'%s' model configured for domain, but "
+ "hypervisor driver is '%s'."),
+ secdef->model, virSecurityManagerGetModel(mgr));
+ return -1;
+ }
+
if (secdef->type == VIR_DOMAIN_SECLABEL_STATIC) {
if (security_check_context(secdef->label) != 0) {
virSecurityReportError(VIR_ERR_XML_ERROR,
@@ -867,7 +891,7 @@ SELinuxSecurityVerify(virDomainDefPtr def)
}
static int
-SELinuxSetSecurityProcessLabel(virSecurityDriverPtr drv,
+SELinuxSetSecurityProcessLabel(virSecurityManagerPtr mgr,
virDomainObjPtr vm)
{
/* TODO: verify DOI */
@@ -876,12 +900,12 @@ SELinuxSetSecurityProcessLabel(virSecurityDriverPtr drv,
if (vm->def->seclabel.label == NULL)
return 0;
- if (!STREQ(drv->name, secdef->model)) {
+ if (!STREQ(virSecurityManagerGetModel(mgr), secdef->model)) {
virSecurityReportError(VIR_ERR_INTERNAL_ERROR,
_("security label driver mismatch: "
"'%s' model configured for domain, but "
"hypervisor driver is '%s'."),
- secdef->model, drv->name);
+ secdef->model, virSecurityManagerGetModel(mgr));
if (security_getenforce() == 1)
return -1;
}
@@ -898,7 +922,7 @@ SELinuxSetSecurityProcessLabel(virSecurityDriverPtr drv,
}
static int
-SELinuxSetSecuritySocketLabel(virSecurityDriverPtr drv,
+SELinuxSetSecuritySocketLabel(virSecurityManagerPtr mgr,
virDomainObjPtr vm)
{
/* TODO: verify DOI */
@@ -911,12 +935,12 @@ SELinuxSetSecuritySocketLabel(virSecurityDriverPtr drv,
if (vm->def->seclabel.label == NULL)
return 0;
- if (!STREQ(drv->name, secdef->model)) {
+ if (!STREQ(virSecurityManagerGetModel(mgr), secdef->model)) {
virSecurityReportError(VIR_ERR_INTERNAL_ERROR,
_("security label driver mismatch: "
"'%s' model configured for domain, but "
"hypervisor driver is '%s'."),
- secdef->model, drv->name);
+ secdef->model, virSecurityManagerGetModel(mgr));
goto done;
}
@@ -969,7 +993,7 @@ done:
}
static int
-SELinuxClearSecuritySocketLabel(virSecurityDriverPtr drv,
+SELinuxClearSecuritySocketLabel(virSecurityManagerPtr mgr,
virDomainObjPtr vm)
{
/* TODO: verify DOI */
@@ -978,12 +1002,12 @@ SELinuxClearSecuritySocketLabel(virSecurityDriverPtr drv,
if (vm->def->seclabel.label == NULL)
return 0;
- if (!STREQ(drv->name, secdef->model)) {
+ if (!STREQ(virSecurityManagerGetModel(mgr), secdef->model)) {
virSecurityReportError(VIR_ERR_INTERNAL_ERROR,
_("security label driver mismatch: "
"'%s' model configured for domain, but "
"hypervisor driver is '%s'."),
- secdef->model, drv->name);
+ secdef->model, virSecurityManagerGetModel(mgr));
if (security_getenforce() == 1)
return -1;
}
@@ -1011,7 +1035,7 @@ SELinuxSetSecurityChardevCallback(virDomainDefPtr def ATTRIBUTE_UNUSED,
static int
-SELinuxSetSecurityAllLabel(virSecurityDriverPtr drv,
+SELinuxSetSecurityAllLabel(virSecurityManagerPtr mgr,
virDomainObjPtr vm,
const char *stdin_path)
{
@@ -1028,12 +1052,12 @@ SELinuxSetSecurityAllLabel(virSecurityDriverPtr drv,
vm->def->disks[i]->src, vm->def->disks[i]->dst);
continue;
}
- if (SELinuxSetSecurityImageLabel(drv,
+ if (SELinuxSetSecurityImageLabel(mgr,
vm, vm->def->disks[i]) < 0)
return -1;
}
for (i = 0 ; i < vm->def->nhostdevs ; i++) {
- if (SELinuxSetSecurityHostdevLabel(drv,
+ if (SELinuxSetSecurityHostdevLabel(mgr,
vm,
vm->def->hostdevs[i]) < 0)
return -1;
@@ -1063,24 +1087,37 @@ SELinuxSetSecurityAllLabel(virSecurityDriverPtr drv,
return 0;
}
-virSecurityDriver virSELinuxSecurityDriver = {
- .name = SECURITY_SELINUX_NAME,
- .probe = SELinuxSecurityDriverProbe,
- .open = SELinuxSecurityDriverOpen,
- .domainSecurityVerify = SELinuxSecurityVerify,
- .domainSetSecurityImageLabel = SELinuxSetSecurityImageLabel,
- .domainSetSecuritySocketLabel = SELinuxSetSecuritySocketLabel,
- .domainClearSecuritySocketLabel = SELinuxClearSecuritySocketLabel,
- .domainRestoreSecurityImageLabel = SELinuxRestoreSecurityImageLabel,
- .domainGenSecurityLabel = SELinuxGenSecurityLabel,
- .domainReserveSecurityLabel = SELinuxReserveSecurityLabel,
- .domainReleaseSecurityLabel = SELinuxReleaseSecurityLabel,
- .domainGetSecurityProcessLabel = SELinuxGetSecurityProcessLabel,
- .domainSetSecurityProcessLabel = SELinuxSetSecurityProcessLabel,
- .domainRestoreSecurityAllLabel = SELinuxRestoreSecurityAllLabel,
- .domainSetSecurityAllLabel = SELinuxSetSecurityAllLabel,
- .domainSetSecurityHostdevLabel = SELinuxSetSecurityHostdevLabel,
- .domainRestoreSecurityHostdevLabel = SELinuxRestoreSecurityHostdevLabel,
- .domainSetSavedStateLabel = SELinuxSetSavedStateLabel,
- .domainRestoreSavedStateLabel = SELinuxRestoreSavedStateLabel,
+virSecurityDriver virSecurityDriverSELinux = {
+ 0,
+ SECURITY_SELINUX_NAME,
+ SELinuxSecurityDriverProbe,
+ SELinuxSecurityDriverOpen,
+ SELinuxSecurityDriverClose,
+
+ SELinuxSecurityGetModel,
+ SELinuxSecurityGetDOI,
+
+ SELinuxSecurityVerify,
+
+ SELinuxSetSecurityImageLabel,
+ SELinuxRestoreSecurityImageLabel,
+
+ SELinuxSetSecuritySocketLabel,
+ SELinuxClearSecuritySocketLabel,
+
+ SELinuxGenSecurityLabel,
+ SELinuxReserveSecurityLabel,
+ SELinuxReleaseSecurityLabel,
+
+ SELinuxGetSecurityProcessLabel,
+ SELinuxSetSecurityProcessLabel,
+
+ SELinuxSetSecurityAllLabel,
+ SELinuxRestoreSecurityAllLabel,
+
+ SELinuxSetSecurityHostdevLabel,
+ SELinuxRestoreSecurityHostdevLabel,
+
+ SELinuxSetSavedStateLabel,
+ SELinuxRestoreSavedStateLabel,
};
diff --git a/src/security/security_selinux.h b/src/security/security_selinux.h
index 056ba75..aa67421 100644
--- a/src/security/security_selinux.h
+++ b/src/security/security_selinux.h
@@ -13,6 +13,6 @@
#ifndef __VIR_SECURITY_SELINUX_H__
# define __VIR_SECURITY_SELINUX_H__
-extern virSecurityDriver virSELinuxSecurityDriver;
+extern virSecurityDriver virSecurityDriverSELinux;
#endif /* __VIR_SECURITY_SELINUX_H__ */
diff --git a/src/security/security_stack.c b/src/security/security_stack.c
new file mode 100644
index 0000000..9b3753a
--- /dev/null
+++ b/src/security/security_stack.c
@@ -0,0 +1,383 @@
+/*
+ * Copyright (C) 2010 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.
+ *
+ * QEMU stacked security driver
+ */
+
+#include <config.h>
+
+#include "security_stack.h"
+
+#include "virterror_internal.h"
+
+#define VIR_FROM_THIS VIR_FROM_SECURITY
+
+typedef struct _virSecurityStackData virSecurityStackData;
+typedef virSecurityStackData *virSecurityStackDataPtr;
+
+struct _virSecurityStackData {
+ virSecurityManagerPtr primary;
+ virSecurityManagerPtr secondary;
+};
+
+void virSecurityStackSetPrimary(virSecurityManagerPtr mgr,
+ virSecurityManagerPtr primary)
+{
+ virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+ priv->primary = primary;
+}
+
+void virSecurityStackSetSecondary(virSecurityManagerPtr mgr,
+ virSecurityManagerPtr secondary)
+{
+ virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+ priv->secondary = secondary;
+}
+
+static virSecurityDriverStatus
+virSecurityStackProbe(void)
+{
+ return SECURITY_DRIVER_ENABLE;
+}
+
+static int
+virSecurityStackOpen(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+static int
+virSecurityStackClose(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+static const char * virSecurityStackGetModel(virSecurityManagerPtr mgr)
+{
+ virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+
+ return virSecurityManagerGetModel(priv->primary);
+}
+
+static const char * virSecurityStackGetDOI(virSecurityManagerPtr mgr)
+{
+ virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+
+ return virSecurityManagerGetDOI(priv->primary);
+}
+
+static int
+virSecurityStackVerify(virSecurityManagerPtr mgr,
+ virDomainDefPtr def)
+{
+ virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+ int rc = 0;
+
+ if (virSecurityManagerVerify(priv->primary, def) < 0)
+ rc = -1;
+
+#if 0
+ if (virSecurityManagerVerify(priv->secondary, def) < 0)
+ rc = -1;
+#endif
+
+ return rc;
+}
+
+
+static int
+virSecurityStackGenLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm)
+{
+ virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+ int rc = 0;
+
+ if (virSecurityManagerGenLabel(priv->primary, vm) < 0)
+ rc = -1;
+#if 0
+ if (virSecurityManagerGenLabel(priv->secondary, vm) < 0)
+ rc = -1;
+#endif
+
+ return rc;
+}
+
+
+static int
+virSecurityStackReleaseLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm)
+{
+ virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+ int rc = 0;
+
+ if (virSecurityManagerReleaseLabel(priv->primary, vm) < 0)
+ rc = -1;
+#if 0
+ if (virSecurityManagerReleaseLabel(priv->secondary, vm) < 0)
+ rc = -1;
+#endif
+
+ return rc;
+}
+
+
+static int
+virSecurityStackReserveLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm)
+{
+ virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+ int rc = 0;
+
+ if (virSecurityManagerReserveLabel(priv->primary, vm) < 0)
+ rc = -1;
+#if 0
+ if (virSecurityManagerReserveLabel(priv->secondary, vm) < 0)
+ rc = -1;
+#endif
+
+ return rc;
+}
+
+
+static int
+virSecurityStackSetSecurityImageLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm,
+ virDomainDiskDefPtr disk)
+{
+ virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+ int rc = 0;
+
+ if (virSecurityManagerSetImageLabel(priv->secondary, vm, disk) < 0)
+ rc = -1;
+ if (virSecurityManagerSetImageLabel(priv->primary, vm, disk) < 0)
+ rc = -1;
+
+ return rc;
+}
+
+
+static int
+virSecurityStackRestoreSecurityImageLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm,
+ virDomainDiskDefPtr disk)
+{
+ virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+ int rc = 0;
+
+ if (virSecurityManagerRestoreImageLabel(priv->secondary, vm, disk) < 0)
+ rc = -1;
+ if (virSecurityManagerRestoreImageLabel(priv->primary, vm, disk) < 0)
+ rc = -1;
+
+ return rc;
+}
+
+
+static int
+virSecurityStackSetSecurityHostdevLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm,
+ virDomainHostdevDefPtr dev)
+
+{
+ virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+ int rc = 0;
+
+ if (virSecurityManagerSetHostdevLabel(priv->secondary, vm, dev) < 0)
+ rc = -1;
+ if (virSecurityManagerSetHostdevLabel(priv->primary, vm, dev) < 0)
+ rc = -1;
+
+ return rc;
+}
+
+
+static int
+virSecurityStackRestoreSecurityHostdevLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm,
+ virDomainHostdevDefPtr dev)
+{
+ virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+ int rc = 0;
+
+ if (virSecurityManagerRestoreHostdevLabel(priv->secondary, vm, dev) < 0)
+ rc = -1;
+ if (virSecurityManagerRestoreHostdevLabel(priv->primary, vm, dev) < 0)
+ rc = -1;
+
+ return rc;
+}
+
+
+static int
+virSecurityStackSetSecurityAllLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm,
+ const char *stdin_path)
+{
+ virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+ int rc = 0;
+
+ if (virSecurityManagerSetAllLabel(priv->secondary, vm, stdin_path) < 0)
+ rc = -1;
+ if (virSecurityManagerSetAllLabel(priv->primary, vm, stdin_path) < 0)
+ rc = -1;
+
+ return rc;
+}
+
+
+static int
+virSecurityStackRestoreSecurityAllLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm,
+ int migrated)
+{
+ virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+ int rc = 0;
+
+ if (virSecurityManagerRestoreAllLabel(priv->secondary, vm, migrated) < 0)
+ rc = -1;
+ if (virSecurityManagerRestoreAllLabel(priv->primary, vm, migrated) < 0)
+ rc = -1;
+
+ return rc;
+}
+
+
+static int
+virSecurityStackSetSavedStateLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm,
+ const char *savefile)
+{
+ virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+ int rc = 0;
+
+ if (virSecurityManagerSetSavedStateLabel(priv->secondary, vm, savefile) < 0)
+ rc = -1;
+ if (virSecurityManagerSetSavedStateLabel(priv->primary, vm, savefile) < 0)
+ rc = -1;
+
+ return rc;
+}
+
+
+static int
+virSecurityStackRestoreSavedStateLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm,
+ const char *savefile)
+{
+ virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+ int rc = 0;
+
+ if (virSecurityManagerRestoreSavedStateLabel(priv->secondary, vm, savefile) < 0)
+ rc = -1;
+ if (virSecurityManagerRestoreSavedStateLabel(priv->primary, vm, savefile) < 0)
+ rc = -1;
+
+ return rc;
+}
+
+
+static int
+virSecurityStackSetProcessLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm)
+{
+ virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+ int rc = 0;
+
+ if (virSecurityManagerSetProcessLabel(priv->secondary, vm) < 0)
+ rc = -1;
+ if (virSecurityManagerSetProcessLabel(priv->primary, vm) < 0)
+ rc = -1;
+
+ return rc;
+}
+
+static int
+virSecurityStackGetProcessLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm,
+ virSecurityLabelPtr seclabel)
+{
+ virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+ int rc = 0;
+
+#if 0
+ if (virSecurityManagerGetProcessLabel(priv->secondary, vm, seclabel) < 0)
+ rc = -1;
+#endif
+ if (virSecurityManagerGetProcessLabel(priv->primary, vm, seclabel) < 0)
+ rc = -1;
+
+ return rc;
+}
+
+
+static int
+virSecurityStackSetSocketLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm)
+{
+ virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+ int rc = 0;
+
+ if (virSecurityManagerSetSocketLabel(priv->secondary, vm) < 0)
+ rc = -1;
+ if (virSecurityManagerSetSocketLabel(priv->primary, vm) < 0)
+ rc = -1;
+
+ return rc;
+}
+
+
+static int
+virSecurityStackClearSocketLabel(virSecurityManagerPtr mgr,
+ virDomainObjPtr vm)
+{
+ virSecurityStackDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+ int rc = 0;
+
+ if (virSecurityManagerClearSocketLabel(priv->secondary, vm) < 0)
+ rc = -1;
+ if (virSecurityManagerClearSocketLabel(priv->primary, vm) < 0)
+ rc = -1;
+
+ return rc;
+}
+
+
+virSecurityDriver virSecurityDriverStack = {
+ sizeof(virSecurityStackData),
+ "stack",
+ virSecurityStackProbe,
+ virSecurityStackOpen,
+ virSecurityStackClose,
+
+ virSecurityStackGetModel,
+ virSecurityStackGetDOI,
+
+ virSecurityStackVerify,
+
+ virSecurityStackSetSecurityImageLabel,
+ virSecurityStackRestoreSecurityImageLabel,
+
+ virSecurityStackSetSocketLabel,
+ virSecurityStackClearSocketLabel,
+
+ virSecurityStackGenLabel,
+ virSecurityStackReserveLabel,
+ virSecurityStackReleaseLabel,
+
+ virSecurityStackGetProcessLabel,
+ virSecurityStackSetProcessLabel,
+
+ virSecurityStackSetSecurityAllLabel,
+ virSecurityStackRestoreSecurityAllLabel,
+
+ virSecurityStackSetSecurityHostdevLabel,
+ virSecurityStackRestoreSecurityHostdevLabel,
+
+ virSecurityStackSetSavedStateLabel,
+ virSecurityStackRestoreSavedStateLabel,
+};
diff --git a/src/security/security_stack.h b/src/security/security_stack.h
new file mode 100644
index 0000000..c924842
--- /dev/null
+++ b/src/security/security_stack.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2010 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.
+ *
+ * QEMU stacked security driver
+ */
+
+#include "security_driver.h"
+
+#ifndef __VIR_SECURITY_STACK
+# define __VIR_SECURITY_STACK
+
+extern virSecurityDriver virSecurityDriverStack;
+
+void virSecurityStackSetPrimary(virSecurityManagerPtr mgr,
+ virSecurityManagerPtr primary);
+void virSecurityStackSetSecondary(virSecurityManagerPtr mgr,
+ virSecurityManagerPtr secondary);
+
+#endif /* __VIR_SECURITY_DAC */
--
1.7.3.4
2
3
I'm looking into a bug where a libvirt-created xen HVM guest boots
*very* slowly on an EPT-enabled machine, particularly when the guest has
a dedicated PCI device.
xen-unstable c/s 16931 [1] introduced a per-guest HAP (hardware assisted
paging) setting. Unfortunately, the sane default of hap=1 is done by xm
client tool instead of xend, so an HVM guest created with xm tool
(hap=1) boots as expected but takes much longer when created through
libvirt (hap=0).
Should libvirt expose this feature in domain XML? Should it be possible
to enable/disable hardware assisted paging on a per-guest level with
libvirt? If so, where does such a setting belong? It seems analogous
to enabling/disabling PAE and as such belongs under hypervisor
features. On IRC, Eric suggested it might fall under memoryBacking like
huge page support in KVM.
If folks feel this setting should not be exposed, it could be
unconditionally set in the xen driver for HVM guests, similar to the way
usb setting is currently handled (see attached patch). Note that the
xen domain builder will ignore this setting on hardware without the feature.
Thanks for your comments.
Jim
[1] http://xenbits.xensource.com/xen-unstable.hg?rev/98c2665056ea
2
2
[libvirt] [PATCH] Fix instructions on 'vnc_password' to describe current behaviour
by Neil Wilson 07 Jan '11
by Neil Wilson 07 Jan '11
07 Jan '11
This documentation change fixes the description of vnc_password in
qemu.conf to fit the behaviour introduced in commit
ab952024f42726a291d2c0ceda10071b88da7533 which treats a non-existent VNC
password and an empty string password in the same way.
Addresses https://bugzilla.redhat.com/show_bug.cgi?id=667097
diff --git a/src/qemu/qemu.conf b/src/qemu/qemu.conf
index ba41f80..1a050fd 100644
--- a/src/qemu/qemu.conf
+++ b/src/qemu/qemu.conf
@@ -52,10 +52,8 @@
# The default VNC password. Only 8 letters are significant for
# VNC passwords. This parameter is only used if the per-domain
# XML config does not already provide a password. To allow
-# access without passwords, leave this commented out. An empty
-# string will still enable passwords, but be rejected by QEMU
-# effectively preventing any use of VNC. Obviously change this
-# example here before you set this
+# access without passwords, either leave this commented out or use
+# an empty string. Obviously change this example here before you set
this.
#
# vnc_password = "XYZ12345"
2
3
---
v2:
- Don't enable the general autostart option if this affects the autostart
behavior of other domains.
- Refactor the lookup code for AutoStartDefaults and AutoStartPowerInfo into
functions.
src/esx/esx_driver.c | 183 +++++++++++++++++++++++++++++++++++++++-
src/esx/esx_vi.c | 126 +++++++++++++++++++++++++++-
src/esx/esx_vi.h | 6 ++
src/esx/esx_vi_generator.input | 60 +++++++++++++
src/esx/esx_vi_generator.py | 5 +-
src/esx/esx_vi_types.c | 6 ++
src/esx/esx_vi_types.h | 1 +
7 files changed, 382 insertions(+), 5 deletions(-)
diff --git a/src/esx/esx_driver.c b/src/esx/esx_driver.c
index 2241532..67325de 100644
--- a/src/esx/esx_driver.c
+++ b/src/esx/esx_driver.c
@@ -3199,6 +3199,185 @@ esxDomainUndefine(virDomainPtr domain)
+static int
+esxDomainGetAutostart(virDomainPtr domain, int *autostart)
+{
+ int result = -1;
+ esxPrivate *priv = domain->conn->privateData;
+ esxVI_AutoStartDefaults *defaults = NULL;
+ esxVI_String *propertyNameList = NULL;
+ esxVI_ObjectContent *hostAutoStartManager = NULL;
+ esxVI_AutoStartPowerInfo *powerInfo = NULL;
+ esxVI_AutoStartPowerInfo *powerInfoList = NULL;
+ esxVI_ObjectContent *virtualMachine = NULL;
+
+ *autostart = 0;
+
+ if (esxVI_EnsureSession(priv->primary) < 0) {
+ return -1;
+ }
+
+ /* Check general autostart config */
+ if (esxVI_LookupAutoStartDefaults(priv->primary, &defaults) < 0) {
+ goto cleanup;
+ }
+
+ if (defaults->enabled != esxVI_Boolean_True) {
+ /* Autostart is disabled in general, exit early here */
+ result = 0;
+ goto cleanup;
+ }
+
+ /* Check specific autostart config */
+ if (esxVI_LookupAutoStartPowerInfoList(priv->primary, &powerInfoList) < 0) {
+ goto cleanup;
+ }
+
+ if (powerInfoList == NULL) {
+ /* powerInfo list is empty, exit early here */
+ result = 0;
+ goto cleanup;
+ }
+
+ if (esxVI_LookupVirtualMachineByUuid(priv->primary, domain->uuid,
+ NULL, &virtualMachine,
+ esxVI_Occurrence_RequiredItem) < 0) {
+ goto cleanup;
+ }
+
+ for (powerInfo = powerInfoList; powerInfo != NULL;
+ powerInfo = powerInfo->_next) {
+ if (STREQ(powerInfo->key->value, virtualMachine->obj->value)) {
+ if (STRCASEEQ(powerInfo->startAction, "powerOn")) {
+ *autostart = 1;
+ }
+
+ break;
+ }
+ }
+
+ result = 0;
+
+ cleanup:
+ esxVI_String_Free(&propertyNameList);
+ esxVI_ObjectContent_Free(&hostAutoStartManager);
+ esxVI_AutoStartDefaults_Free(&defaults);
+ esxVI_AutoStartPowerInfo_Free(&powerInfoList);
+ esxVI_ObjectContent_Free(&virtualMachine);
+
+ return result;
+}
+
+
+
+static int
+esxDomainSetAutostart(virDomainPtr domain, int autostart)
+{
+ int result = -1;
+ esxPrivate *priv = domain->conn->privateData;
+ esxVI_ObjectContent *virtualMachine = NULL;
+ esxVI_HostAutoStartManagerConfig *spec = NULL;
+ esxVI_AutoStartDefaults *defaults = NULL;
+ esxVI_AutoStartPowerInfo *powerInfoList = NULL;
+ esxVI_AutoStartPowerInfo *powerInfo = NULL;
+ esxVI_AutoStartPowerInfo *newPowerInfo = NULL;
+
+ if (esxVI_EnsureSession(priv->primary) < 0) {
+ return -1;
+ }
+
+ if (esxVI_LookupVirtualMachineByUuid(priv->primary, domain->uuid,
+ NULL, &virtualMachine,
+ esxVI_Occurrence_RequiredItem) < 0 ||
+ esxVI_HostAutoStartManagerConfig_Alloc(&spec) < 0) {
+ goto cleanup;
+ }
+
+ if (autostart) {
+ /*
+ * There is a general autostart option that affects the autostart
+ * behavior of all domains. If it's disabled then no domain does
+ * autostart. If it's enabled then the autostart behavior depends on
+ * the per-domain autostart config.
+ */
+ if (esxVI_LookupAutoStartDefaults(priv->primary, &defaults) < 0) {
+ goto cleanup;
+ }
+
+ if (defaults->enabled != esxVI_Boolean_True) {
+ /*
+ * Autostart is disabled in general. Check if no other domain is
+ * in the list of autostarted domains, so it's safe to enable the
+ * general autostart option without affecting the autostart
+ * behavior of other domains.
+ */
+ if (esxVI_LookupAutoStartPowerInfoList(priv->primary,
+ &powerInfoList) < 0) {
+ goto cleanup;
+ }
+
+ for (powerInfo = powerInfoList; powerInfo != NULL;
+ powerInfo = powerInfo->_next) {
+ if (STRNEQ(powerInfo->key->value, virtualMachine->obj->value)) {
+ ESX_ERROR(VIR_ERR_OPERATION_INVALID, "%s",
+ _("Cannot enable general autostart option "
+ "without affecting other domains"));
+ goto cleanup;
+ }
+ }
+
+ /* Enable autostart in general */
+ if (esxVI_AutoStartDefaults_Alloc(&spec->defaults) < 0) {
+ goto cleanup;
+ }
+
+ spec->defaults->enabled = esxVI_Boolean_True;
+ }
+ }
+
+ if (esxVI_AutoStartPowerInfo_Alloc(&newPowerInfo) < 0 ||
+ esxVI_Int_Alloc(&newPowerInfo->startOrder) < 0 ||
+ esxVI_Int_Alloc(&newPowerInfo->startDelay) < 0 ||
+ esxVI_Int_Alloc(&newPowerInfo->stopDelay) < 0 ||
+ esxVI_AutoStartPowerInfo_AppendToList(&spec->powerInfo,
+ newPowerInfo) < 0) {
+ goto cleanup;
+ }
+
+ newPowerInfo->key = virtualMachine->obj;
+ newPowerInfo->startOrder->value = -1; /* no specific start order */
+ newPowerInfo->startDelay->value = -1; /* use system default */
+ newPowerInfo->waitForHeartbeat = esxVI_AutoStartWaitHeartbeatSetting_SystemDefault;
+ newPowerInfo->startAction = autostart ? (char *)"powerOn" : (char *)"none";
+ newPowerInfo->stopDelay->value = -1; /* use system default */
+ newPowerInfo->stopAction = (char *)"none";
+
+ if (esxVI_ReconfigureAutostart
+ (priv->primary,
+ priv->primary->hostSystem->configManager->autoStartManager,
+ spec) < 0) {
+ goto cleanup;
+ }
+
+ result = 0;
+
+ cleanup:
+ if (newPowerInfo != NULL) {
+ newPowerInfo->key = NULL;
+ newPowerInfo->startAction = NULL;
+ newPowerInfo->stopAction = NULL;
+ }
+
+ esxVI_ObjectContent_Free(&virtualMachine);
+ esxVI_HostAutoStartManagerConfig_Free(&spec);
+ esxVI_AutoStartDefaults_Free(&defaults);
+ esxVI_AutoStartPowerInfo_Free(&powerInfoList);
+
+ return result;
+}
+
+
+
/*
* The scheduler interface exposes basically the CPU ResourceAllocationInfo:
*
@@ -4406,8 +4585,8 @@ static virDriver esxDriver = {
NULL, /* domainDetachDevice */
NULL, /* domainDetachDeviceFlags */
NULL, /* domainUpdateDeviceFlags */
- NULL, /* domainGetAutostart */
- NULL, /* domainSetAutostart */
+ esxDomainGetAutostart, /* domainGetAutostart */
+ esxDomainSetAutostart, /* domainSetAutostart */
esxDomainGetSchedulerType, /* domainGetSchedulerType */
esxDomainGetSchedulerParameters, /* domainGetSchedulerParameters */
esxDomainSetSchedulerParameters, /* domainSetSchedulerParameters */
diff --git a/src/esx/esx_vi.c b/src/esx/esx_vi.c
index 5dbf744..62b28a2 100644
--- a/src/esx/esx_vi.c
+++ b/src/esx/esx_vi.c
@@ -606,7 +606,8 @@ esxVI_Context_LookupObjectsByPath(esxVI_Context *ctx,
esxVI_String_Free(&propertyNameList);
if (esxVI_String_AppendValueListToList(&propertyNameList,
- "name\0") < 0 ||
+ "name\0"
+ "configManager\0") < 0 ||
esxVI_LookupObjectContentByType(ctx, ctx->computeResource->_reference,
"HostSystem", propertyNameList,
&hostSystemList) < 0) {
@@ -680,7 +681,8 @@ esxVI_Context_LookupObjectsByHostSystemIp(esxVI_Context *ctx,
/* Lookup HostSystem */
if (esxVI_String_AppendValueListToList(&propertyNameList,
- "name\0") < 0 ||
+ "name\0"
+ "configManager\0") < 0 ||
esxVI_FindByIp(ctx, NULL, hostSystemIpAddress, esxVI_Boolean_False,
&managedObjectReference) < 0 ||
esxVI_LookupObjectContentByType(ctx, managedObjectReference,
@@ -3375,6 +3377,126 @@ esxVI_LookupStorageVolumeKeyByDatastorePath(esxVI_Context *ctx,
int
+esxVI_LookupAutoStartDefaults(esxVI_Context *ctx,
+ esxVI_AutoStartDefaults **defaults)
+{
+ int result = -1;
+ esxVI_String *propertyNameList = NULL;
+ esxVI_ObjectContent *hostAutoStartManager = NULL;
+ esxVI_DynamicProperty *dynamicProperty = NULL;
+
+ if (defaults == NULL || *defaults != NULL) {
+ ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR, "%s", _("Invalid argument"));
+ return -1;
+ }
+
+ /*
+ * Lookup HostAutoStartManagerConfig from the HostAutoStartManager because
+ * for some reason this is much faster than looking up the same info from
+ * the HostSystem config.
+ */
+ if (esxVI_String_AppendValueToList(&propertyNameList,
+ "config.defaults") < 0 ||
+ esxVI_LookupObjectContentByType
+ (ctx, ctx->hostSystem->configManager->autoStartManager,
+ "HostAutoStartManager", propertyNameList,
+ &hostAutoStartManager) < 0) {
+ goto cleanup;
+ }
+
+ if (hostAutoStartManager == NULL) {
+ ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Could not retrieve the HostAutoStartManager object"));
+ goto cleanup;
+ }
+
+ for (dynamicProperty = hostAutoStartManager->propSet;
+ dynamicProperty != NULL; dynamicProperty = dynamicProperty->_next) {
+ if (STREQ(dynamicProperty->name, "config.defaults")) {
+ if (esxVI_AutoStartDefaults_CastFromAnyType(dynamicProperty->val,
+ defaults) < 0) {
+ goto cleanup;
+ }
+
+ break;
+ }
+ }
+
+ if (*defaults == NULL) {
+ ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Could not retrieve the AutoStartDefaults object"));
+ goto cleanup;
+ }
+
+ result = 0;
+
+ cleanup:
+ esxVI_String_Free(&propertyNameList);
+ esxVI_ObjectContent_Free(&hostAutoStartManager);
+
+ return result;
+}
+
+
+
+int
+esxVI_LookupAutoStartPowerInfoList(esxVI_Context *ctx,
+ esxVI_AutoStartPowerInfo **powerInfoList)
+{
+ int result = -1;
+ esxVI_String *propertyNameList = NULL;
+ esxVI_ObjectContent *hostAutoStartManager = NULL;
+ esxVI_DynamicProperty *dynamicProperty = NULL;
+
+ if (powerInfoList == NULL || *powerInfoList != NULL) {
+ ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR, "%s", _("Invalid argument"));
+ return -1;
+ }
+
+ /*
+ * Lookup HostAutoStartManagerConfig from the HostAutoStartManager because
+ * for some reason this is much faster than looking up the same info from
+ * the HostSystem config.
+ */
+ if (esxVI_String_AppendValueToList(&propertyNameList,
+ "config.powerInfo") < 0 ||
+ esxVI_LookupObjectContentByType
+ (ctx, ctx->hostSystem->configManager->autoStartManager,
+ "HostAutoStartManager", propertyNameList,
+ &hostAutoStartManager) < 0) {
+ goto cleanup;
+ }
+
+ if (hostAutoStartManager == NULL) {
+ ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Could not retrieve the HostAutoStartManager object"));
+ goto cleanup;
+ }
+
+ for (dynamicProperty = hostAutoStartManager->propSet;
+ dynamicProperty != NULL; dynamicProperty = dynamicProperty->_next) {
+ if (STREQ(dynamicProperty->name, "config.powerInfo")) {
+ if (esxVI_AutoStartPowerInfo_CastListFromAnyType
+ (dynamicProperty->val, powerInfoList) < 0) {
+ goto cleanup;
+ }
+
+ break;
+ }
+ }
+
+ result = 0;
+
+ cleanup:
+ esxVI_String_Free(&propertyNameList);
+ esxVI_ObjectContent_Free(&hostAutoStartManager);
+
+ return result;
+}
+
+
+
+int
esxVI_HandleVirtualMachineQuestion
(esxVI_Context *ctx, esxVI_ManagedObjectReference *virtualMachine,
esxVI_VirtualMachineQuestionInfo *questionInfo,
diff --git a/src/esx/esx_vi.h b/src/esx/esx_vi.h
index 553967b..b071c6c 100644
--- a/src/esx/esx_vi.h
+++ b/src/esx/esx_vi.h
@@ -418,6 +418,12 @@ int esxVI_LookupStorageVolumeKeyByDatastorePath(esxVI_Context *ctx,
const char *datastorePath,
char **key);
+int esxVI_LookupAutoStartDefaults(esxVI_Context *ctx,
+ esxVI_AutoStartDefaults **defaults);
+
+int esxVI_LookupAutoStartPowerInfoList(esxVI_Context *ctx,
+ esxVI_AutoStartPowerInfo **powerInfoList);
+
int esxVI_HandleVirtualMachineQuestion
(esxVI_Context *ctx,
esxVI_ManagedObjectReference *virtualMachine,
diff --git a/src/esx/esx_vi_generator.input b/src/esx/esx_vi_generator.input
index 2d903e4..44d1d9b 100644
--- a/src/esx/esx_vi_generator.input
+++ b/src/esx/esx_vi_generator.input
@@ -51,6 +51,13 @@
# Enumerations
#
+enum AutoStartWaitHeartbeatSetting
+ yes
+ no
+ systemDefault
+end
+
+
enum ManagedEntityStatus
gray
green
@@ -140,6 +147,26 @@ object AboutInfo
end
+object AutoStartDefaults
+ Boolean enabled o
+ Int startDelay o
+ Int stopDelay o
+ Boolean waitForHeartbeat o
+ String stopAction o
+end
+
+
+object AutoStartPowerInfo
+ ManagedObjectReference key r
+ Int startOrder r
+ Int startDelay r
+ AutoStartWaitHeartbeatSetting waitForHeartbeat r
+ String startAction r
+ Int stopDelay r
+ String stopAction r
+end
+
+
object ChoiceOption extends OptionType
ElementDescription choiceInfo rl
Int defaultIndex o
@@ -234,6 +261,33 @@ object FolderFileQuery extends FileQuery
end
+object HostAutoStartManagerConfig
+ AutoStartDefaults defaults o
+ AutoStartPowerInfo powerInfo ol
+end
+
+
+object HostConfigManager
+ ManagedObjectReference cpuScheduler o
+ ManagedObjectReference datastoreSystem o
+ ManagedObjectReference memoryManager o
+ ManagedObjectReference storageSystem o
+ ManagedObjectReference networkSystem o
+ ManagedObjectReference vmotionSystem o
+ ManagedObjectReference serviceSystem o
+ ManagedObjectReference firewallSystem o
+ ManagedObjectReference advancedOption o
+ ManagedObjectReference diagnosticSystem o
+ ManagedObjectReference autoStartManager o
+ ManagedObjectReference snmpSystem o
+ ManagedObjectReference dateTimeSystem o
+ ManagedObjectReference patchManager o
+ ManagedObjectReference bootDeviceSystem o
+ ManagedObjectReference firmwareSystem o
+ ManagedObjectReference healthStatusSystem o
+end
+
+
object HostCpuIdInfo
Int level r
String vendor o
@@ -843,6 +897,12 @@ method ReconfigVM_Task returns ManagedObjectReference r
end
+method ReconfigureAutostart
+ ManagedObjectReference _this r
+ HostAutoStartManagerConfig spec r
+end
+
+
method RefreshDatastore
ManagedObjectReference _this r
end
diff --git a/src/esx/esx_vi_generator.py b/src/esx/esx_vi_generator.py
index 4a8a9dc..3d068f3 100755
--- a/src/esx/esx_vi_generator.py
+++ b/src/esx/esx_vi_generator.py
@@ -1148,11 +1148,14 @@ additional_enum_features = { "ManagedEntityStatus" : Enum.FEATURE__ANY_TYPE
"VirtualMachinePowerState" : Enum.FEATURE__ANY_TYPE }
-additional_object_features = { "DatastoreHostMount" : Object.FEATURE__DEEP_COPY | Object.FEATURE__LIST | Object.FEATURE__ANY_TYPE,
+additional_object_features = { "AutoStartDefaults" : Object.FEATURE__ANY_TYPE,
+ "AutoStartPowerInfo" : Object.FEATURE__ANY_TYPE | Object.FEATURE__LIST,
+ "DatastoreHostMount" : Object.FEATURE__DEEP_COPY | Object.FEATURE__LIST | Object.FEATURE__ANY_TYPE,
"DatastoreInfo" : Object.FEATURE__ANY_TYPE | Object.FEATURE__DYNAMIC_CAST,
"Event" : Object.FEATURE__LIST,
"FileInfo" : Object.FEATURE__DYNAMIC_CAST,
"FileQuery" : Object.FEATURE__DYNAMIC_CAST,
+ "HostConfigManager" : Object.FEATURE__ANY_TYPE,
"HostCpuIdInfo" : Object.FEATURE__ANY_TYPE | Object.FEATURE__LIST,
"HostDatastoreBrowserSearchResults" : Object.FEATURE__LIST | Object.FEATURE__ANY_TYPE,
"ManagedObjectReference" : Object.FEATURE__ANY_TYPE,
diff --git a/src/esx/esx_vi_types.c b/src/esx/esx_vi_types.c
index a70e1e0..4ee4110 100644
--- a/src/esx/esx_vi_types.c
+++ b/src/esx/esx_vi_types.c
@@ -1815,6 +1815,7 @@ ESX_VI__TEMPLATE__VALIDATE(HostSystem,
ESX_VI__TEMPLATE__PROPERTY__REQUIRE(name);
/* HostSystem */
+ ESX_VI__TEMPLATE__PROPERTY__REQUIRE(configManager);
})
int
@@ -1851,6 +1852,11 @@ esxVI_HostSystem_CastFromObjectContent(esxVI_ObjectContent *objectContent,
virReportOOMError();
goto failure;
}
+ } else if (STREQ(dynamicProperty->name, "configManager")) {
+ if (esxVI_HostConfigManager_CastFromAnyType
+ (dynamicProperty->val, &(*hostSystem)->configManager) < 0) {
+ goto failure;
+ }
}
}
diff --git a/src/esx/esx_vi_types.h b/src/esx/esx_vi_types.h
index 64bf2dc..1ab39da 100644
--- a/src/esx/esx_vi_types.h
+++ b/src/esx/esx_vi_types.h
@@ -412,6 +412,7 @@ struct _esxVI_HostSystem {
char *name; /* required */
/* HostSystem */
+ esxVI_HostConfigManager *configManager; /* required */
};
int esxVI_HostSystem_Alloc(esxVI_HostSystem **hostSystem);
--
1.7.0.4
2
2
On Thu, 2011-01-06 at 17:00 -0700, Jim Fehlig wrote:
> Laine Stump wrote:
> > As far as I know, the SuSE port was actually complete at one time, and
> > was included in a released product (not sure what the product is),
>
> It hasn't been included in a product yet, but might be in upcoming
> openSUSE 11.4.
Right. As far as I know, it should be in opensuse 11.4. I haven't
heard otherwise. My plan was to upstream the patches but I got
sidetracked with some other projects.
My patches touch drv_initscripts.c, initscripts-get.xsl, and
initscripts-put.xsl. The xsl files are slightly different because
our ifcfg syntax is slightly different. I also have a couple new
augeas lenses that we need for our network configuration to work.
I'll try to apply it against head and send it out to the list soon.
How would you recommend handling the files above and the build
for different distros? Should they just be drv_suse.c,
initscripts-get-suse.xsl, and initscripts-put-suse.xsl and then
changed back during the build?
Thanks.
Patrick
>
> > but I don't know where the source is (aside from earlier versions
> > posted to the list and available in the archives),
>
> It currently resides in network:utilities project in openSUSE Build Service
>
> https://build.opensuse.org/package/show?package=netcf&project=network%3Auti…
>
> > and the developers haven't had the resources available to clean it up
> > and submit it back to the upstream project.
>
> My only involvement was enabling netcf support in libvirt, so I can't
> say much about the work or any progress to upstream it. I've cc'd
> Patrick - he was involved and perhaps could provide an update.
>
> Regards,
> Jim
>
2
1
The New Year gift just arrived :-)
As expected I made the release this morning, it is available
as usual at:
ftp://libvirt.org/libvirt/libvirt-0.8.7.tar.gz
Due to specific condition (without my workstation and networking
troubles) the release was made a bit differently than usual, but hopefully
that won't lead to troubles, the only thing noticeable should be that
the rpm are not signed and I didn't push a tag for the release commit,
maybe Eric or Dan can push a git tag for it with their key.
The release include among other things new hypervisors support, and a
lot of bugs fixes:
Features:
- Initial support for VirtualBox 4.0 (Matthias Bolte)
- IPv6 support (Laine Stump)
- Add VMware Workstation and Player driver (Jean-Baptiste Rouault)
- add network disk support (MORITA Kazutaka and Josh Durgin)
Documentation:
- esx: Fix "occurence" typo (again) (Matthias Bolte)
- update docs for network disks (MORITA Kazutaka)
- docs: Make VMware Workstation / Player page appear in the menu (Matthias Bolte)
- Add info about VMware driver to the libvirt website (Jean-Baptiste Rouault)
- docs: fixed typo, added table of contents (Justin Clift)
- docs: added compiling page and significantly expanded windows page (Justin Clift)
- docs: Add additional indentation to level 3 menu items (Matthias Bolte)
- maint: doc fix (Eric Blake)
- Update documentation of watchdog dump option and add test data for it (Hu Tao)
- virsh: fix a typo in the memtune help description (Justin Clift)
- docs: updated virsh command reference download links to new version (Justin Clift)
- Moved the nodeinfo command to the 'host' help keyword group (Justin Clift)
- man pages: update the description for the virsh help command (Justin Clift)
- virsh: move two commands from domain group to storage pool group (Osier Yang)
- virCommand: docs for usage of new command APIs (Daniel P. Berrange)
- virsh: update help for "virsh help help" (Osier Yang)
- virsh: remove a badly placed line break in virsh -h output (Justin Clift)
- virsh: Categorize commands into groups for virsh help (Osier Yang)
Portability:
- vbox: Handle different IID representation in Version 2.2 on Windows (Matthias Bolte)
- build: make building on cygwin easier (Eric Blake)
- build: improve testsuite results with older automake (Eric Blake)
- build: allow older libselinux again (Eric Blake)
- build: allow autoconf 2.59 again (Eric Blake)
- build: allow mingw compilation with virCommand (Eric Blake)
- build: quote AC_LANG_PROGRAM to avoid warnings with autoconf 2.68 (Diego Elio Pettenò)
- build: properly handle ./configure --with-libpcap (Diego Elio Pettenò)
- build: avoid shadowing devname() on BSD systems (Eric Blake)
- Fix undefined symbol errors when macvtap support is disabled (Matthias Bolte)
- Fix warning when macvtap support is disabled (Jean-Baptiste Rouault)
Bug fixes:
- virExec: fix logic bug (Eric Blake)
- Set broadcast address for IPv4 addresses on virtual network bridges (Laine Stump)
- Fix misuse of VIR_ERR_INVALID_DOMAIN (Matthias Bolte)
- build: fix building error when building without libvirtd (Wen Congyang)
- spec: Enable ESX driver on RHEL (Jiri Denemark)
- bridge: Fix uninitialized variable (Jiri Denemark)
- make the <dhcp> element optional in network.rng (Laine Stump)
- fix syntax error in configure.ac (Wen Congyang)
- qemu: Reparent children when deleting a snapshot (Matthias Bolte)
- Set bitmap size when allocating a bitmap (Jim Fehlig)
- qemu: Return SPICE ports on domain shutdown (Jiri Denemark)
- virterror: avoid API breakage with vmware (Eric Blake)
- Fix memory leak in virsh (Hu Tao)
- Distribute libvirt_vmx.syms (Matthias Bolte)
- vmware: Fix undefine symbol with loadable drivers enabled (Matthias Bolte)
- esx: Fix cluster resource lookup when connecting to a vCenter (Matthias Bolte)
- command: avoid hanging on daemon processes (Eric Blake)
- storage: Ignore dangling symbolic link for filesystem pool (Osier Yang)
- Skip file-based security checks for network disks (Josh Durgin)
- tests: avoid data race (Eric Blake)
- bridge_driver: avoid double call to VIR_FREE (Paweł Krześniak)
- vbox: Don't leak domain names in vboxListDefinedDomains (Matthias Bolte)
- vbox: Don't leak arrays from XPCOM (Matthias Bolte)
- build: fix typo that broke 'make dist' (Eric Blake)
- util: Fix logical error in virReportSystemErrorFull (Jiri Denemark)
- util: Fix error message in __virExec (Jiri Denemark)
- daemon: Change CWD to / before daemonizing (Jiri Denemark)
- daemon, threads: plug a memory leak (Eric Blake)
- daemon: plug a memory leak (Eric Blake)
- conf: plug memory leaks (Eric Blake)
- tests: plug memory leaks (Eric Blake)
- virExec: avoid undefined behavior (Eric Blake)
- command: plug memory leak (Eric Blake)
- build: distribute commandtest files (Eric Blake)
- spec: do not start libvirt-guests if that service is off (Dan Kenigsberg)
- correct the signal's name (Wen Congyang)
- command: avoid memory leak (Eric Blake)
- qemu: call drive_del in DetachPciDiskDevice (Ryan Harper)
- qemu: call drive_unplug in DetachPciDiskDevice (Ryan Harper)
- qemud: fix memory leak in io error events (Anthony Liguori)
- qemu: Enable disabled debug messages (Jiri Denemark)
- qemu: Use -vga none only if it is supported (Jiri Denemark)
- openvz: avoid potential buffer overflow (Eric Blake)
- tests: fix leaks in commandtest (Eric Blake)
- uuid: require smbios uuid and domain uuid to match (Eric Blake)
- qemu: avoid adding "" in smbios arguments (Eric Blake)
- Fix funny off-by-one error in clock-variable (Dan Kenigsberg)
- syntax error "Bad fd number" when stopping libvirt-guests (Laurent Léonard)
- util: Fix bug which will cause libvirtd crash (Osier Yang)
- qemu: Fix a possible deadlock in p2p migration (Jiri Denemark)
- qemu: Don't try to set input FD to -1 (Matthias Bolte)
- Fix memory leak in logging setup (Daniel P. Berrange)
- schemas: Fix cpu element schema (Jiri Denemark)
- virsh: Remove using phy as default disk driver in cmdAttachDisk (Osier Yang)
- OpenVZ: drop fd leackage (Guido Günther)
- qemu: plug memory leak (Eric Blake)
- libvirtd: avoid memory leak on shutdown (Eric Blake)
- Fix flaw in thread creation APIs (Daniel P. Berrange)
Improvements:
- build: avoid compilation warnings (Eric Blake)
- Improve virSocketAddrMask[ByPrefix] API (Laine Stump)
- Utility functions to produce an IPv4 broadcast address (Laine Stump)
- qemu: add -incoming fd:n capability checking (Eric Blake)
- spec: Automatically turn on cgconfig service (Daniel P. Berrange)
- Replace setuid/setgid/initgroups with virSetUIDGID() (Laine Stump)
- new virSetUIDGID() utility function (Laine Stump)
- Preserve errno across calls to error reporting functions & VIR_FREE (Laine Stump)
- Run radvd for virtual networks with IPv6 addresses (Laine Stump)
- Turn on IPv6 support in the bridge_driver.c virtual network driver (Laine Stump)
- Update iptables.c to also support ip6tables. (Laine Stump)
- Support multiple IP addresses on one network in bridge_driver.c (Laine Stump)
- Change virtual network XML parsing/formatting to support IPv6 (Laine Stump)
- Replace brSetInetAddress/brSetInetNetmask with brAddInetAddress (Laine Stump)
- Make virtual network netmasks optional (Laine Stump)
- Pass prefix rather than netmask into iptables functions (Laine Stump)
- Consistently return 0 on success, -1 on failure in bridge_driver.c (Laine Stump)
- Fix logging of failed iptables commands (Laine Stump)
- New virNetworkDef utility functions (Laine Stump)
- New virSocketAddr utility functions (Laine Stump)
- virsh: Add --force option to update-device (Jiri Denemark)
- esx: Add support for storage volume wiping (Matthias Bolte)
- esx: Add support for storage volume deletion (Matthias Bolte)
- maint: avoid space-tab (Eric Blake)
- build: skip vmware driver when building for RHEL (Eric Blake)
- tests: avoid spurious failure of nodeinfotest (Eric Blake)
- libvirt-guests: avoid sourcing failure (Eric Blake)
- vbox: Handle different array representations of XPCOM and MSCOM (Matthias Bolte)
- vbox: Add glue layer for MSCOM on Windows (Matthias Bolte)
- vbox: Match struct layout of the MSCOM implementation on Windows (Matthias Bolte)
- vbox: Use stdcall convention for all COM methods on Windows (Matthias Bolte)
- maint: improve tests distribution (Eric Blake)
- Update QEMU test cases for new file locations & API renames (Daniel P. Berrange)
- Move QEMU hotplug helper code out of the QEMU driver (Daniel P. Berrange)
- Move QEMU domain lock / job helper code to separate file (Daniel P. Berrange)
- Move QEMU driver lock helpers to a separate file (Daniel P. Berrange)
- Move QEMU hostdev helper code out of the QEMU driver (Daniel P. Berrange)
- Move QEMU cgroup helper code out of the QEMU driver (Daniel P. Berrange)
- Move QEMU audit helper code out of the QEMU driver (Daniel P. Berrange)
- Move QEMU private data & namespace code into separate file (Daniel P. Berrange)
- Move QEMU command line management into a separate file (Daniel P. Berrange)
- Move QEMU capabilities management into a separate file (Daniel P. Berrange)
- Add a new function doStartCPUs (Hu Tao)
- Add a new function doStopCPUs (Hu Tao)
- Add a macro timeval_to_ms to compute micro seconds from timeval (Hu Tao)
- cpu: Unify CPUID data structures (Jiri Denemark)
- esx: Add support for storage volume cloning (Matthias Bolte)
- selinux: avoid memory overhead of matchpathcon (Eric Blake)
- tests: test Fedora 14 qemu-kvm -help parsing (Eric Blake)
- tests: test RHEL 6.0 qemu-kvm -help parsing (Eric Blake)
- sysinfo: convert to virCommand (Eric Blake)
- build: update gnulib for pipe on mingw (Eric Blake)
- test: fix commandtest under autobuild.sh (Eric Blake)
- qemu: Introduce two new job types (Osier Yang)
- qemu: Add RBD support and some network disk fixes (Josh Durgin)
- Missing "Default-Stop" field in LSB comment in libvirt-guests (Laurent Léonard)
- 802.1Qbh: Add support for IFLA_VF_MAC (Roopa Prabhu)
- command: ease use with virBuffer, and fix qemu leak (Eric Blake)
- Convert dhcpStartDhcpDaemon from virRun to virCommand (Laine Stump)
- esx: Refactor storage pool type lookup into a function (Matthias Bolte)
- esx: Improve error reporting for failed tasks (Matthias Bolte)
- tests: Add tests for network disks (Josh Durgin)
- Add a watchdog action `dump' (Hu Tao)
- Add a new function doCoreDump (Hu Tao)
- threadpool impl (Hu Tao)
- qemu: Distinguish between domain shutdown and crash (Jiri Denemark)
- qemu: Only build devstr when needs (attach PCI controller) (Osier Yang)
- configure: improve misleading libnl missing error message (Justin Clift)
- maint: update to latest gnulib (Eric Blake)
- openvz: convert popen to virCommand (Eric Blake)
- command: improve behavior on no output (Eric Blake)
- command: enforce fd vs. buffer considerations (Eric Blake)
- tests: Fix commandtest in VPATH build (Jiri Denemark)
- command: improve allocation failure reporting (Eric Blake)
- tests: Fix detection of expected error (Jiri Denemark)
- tests: Fix code formating in commandtest (Jiri Denemark)
- smbios: allow () in smbios strings (Eric Blake)
- smbios: support system family (Eric Blake)
- threads: add virThreadID for debugging use (Eric Blake)
- tests: Don't ignore return value of getcwd() (Jiri Denemark)
- build: Fix internal docs generation in VPATH builds (Jiri Denemark)
- Change return value of VIR_DRV_SUPPORTS_FEATURE to bool (Jiri Denemark)
- Implement virVMOperationType{To|From}String independent from WITH_MACVTAP (Matthias Bolte)
- Create file in virFileWriteStr() if it doesn't exist (Jean-Baptiste Rouault)
- Remove bogus includes (Daniel P. Berrange)
- uml: convert to virCommand (Daniel P. Berrange)
- qemu: convert to virCommand (Eric Blake)
- Port hooks and iptables code to new command execution APIs (Daniel P. Berrange)
- Introduce new APIs for spawning processes (Daniel P. Berrange)
- util: add virVasprintf (Eric Blake)
- util: fix saferead type (Eric Blake)
- Tweak daemon event debug to include errno (Daniel P. Berrange)
- tests: Add tests for CPU selection in qemu driver (Jiri Denemark)
- tests: Support for faking emulator in qemuxml2argv (Jiri Denemark)
- maint: update .gitignore (Eric Blake)
- qemu: Use macro for max and min vnc port instead of number (Osier Yang)
- tests: Add unit tests for internal CPU APIs (Jiri Denemark)
- cpu: Add support for overriding path to CPU map XML file (Jiri Denemark)
- Fall back to QEMUD_SAVE_FORMAT_RAW if compression method fails. (Hu Tao)
Cleanups:
- esx: Move VMX handling code out of the driver directory (Matthias Bolte)
- qemu: use virAsprintf instead of PATH_MAX (Eric Blake)
- build: fix typo that broke 'make dist' (Wen Congyang)
- sysinfo: formatting cleanups (Eric Blake)
- virsh: Remove redundant commands in group domain (Osier Yang)
- virsh: Remove redundant optional option for cmdHelp (Osier Yang)
- qemu: Fix typo in qemuTeardownDiskPathDeny (Osier Yang)
- maint: allow 'make syntax-check' to run again (Eric Blake)
thanks everybody who helped for this release, with ideas, patches
report or documentation !
Daniel
--
Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/
daniel(a)veillard.com | Rpmfind RPM search engine http://rpmfind.net/
http://veillard.com/ | virtualization library http://libvirt.org/
7
14
07 Jan '11
Hi
I am playing with cgroups and try to limit block io for guests.
The proof of concept is:
# mkdir /dev/cgroup/blkio
# mount -t cgroup -o blkio blkio /dev/cgroup/blkio/
# cd blkio/
# mkdir test
# cd test/
# ls -l /dev/vdisks/kirk
lrwxrwxrwx 1 root root 7 2011-01-06 13:46 /dev/vdisks/kirk -> ../dm-5
# ls -l /dev/dm-5
brw-rw---- 1 root disk 253, 5 2011-01-06 13:36 /dev/dm-5
# echo "253:5 1048576" > blkio.throttle.write_bps_device
# echo $$ > tasks
# dd if=/dev/zero of=/dev/dm-5 bs=1M count=20
20+0 records in
20+0 records out
20971520 bytes (21 MB) copied, 20.0223 s, 1.0 MB/s
So limit applies to the dd child of my shell.
Now I assign /dev/dm-5 (/dev/vdisks/kirk) to a vm and echo the qemu-kvm
pid into tasks. Limits are not applied, the guest can happily use max io
bandwidth.
However, if I start the guest manually like
# qemu-kvm <options like libvirt creates> & echo $! >
/dev/cgroup/blkio/test/tasks
The limits _are_ applied.
So, this looks like some sort of race condition to me.
I tried to get information on this on the kernel mailing list [1], but
either noone read it or at least no one replied. Maybe someone here can
shed some light and maybe even fix the issue, if it is an issue.
Need more information? Please ask for it. I don't know what else to
supply at this point.
My current lab is built by:
OpenSuSE 11.3 64bit
Vanilla Kernel 2.6.37
libvirt 0.8.7
qemu-kvm 0.13.0
vm is started like this:
/usr/bin/qemu-kvm -M pc-0.12 -enable-kvm -m 2048 -smp
2,sockets=2,cores=1,threads=1 -name cliff -uuid
a8247e1e-e3d2-d0fc-c5e5-47a173c3e460 -nodefconfig -nodefaults -chardev
socket,id=monitor,path=/var/lib/libvirt/qemu/cliff.monitor,server,nowait
-mon chardev=monitor,mode=readline -rtc base=utc -boot c -device
lsi,id=scsi0,bus=pci.0,addr=0x6 -drive
file=/dev/vdisks/cliff,if=none,id=drive-virtio-disk0,boot=on,format=raw
-device
virtio-blk-pci,bus=pci.0,addr=0x4,drive=drive-virtio-disk0,id=virtio-disk0
-drive
file=/root/openSUSE-11.3-NET-x86_64.iso,if=none,media=cdrom,id=drive-ide0-1-0,readonly=on,format=raw
-device ide-drive,bus=ide.1,unit=0,drive=drive-ide0-1-0,id=ide0-1-0
-drive file=/dev/vdisks/jason,if=none,id=drive-virtio-disk1,format=raw
-device
virtio-blk-pci,bus=pci.0,addr=0x7,drive=drive-virtio-disk1,id=virtio-disk1
-drive file=/dev/vdisks/rob,if=none,id=drive-ide0-0-0,format=raw -device
ide-drive,bus=ide.0,unit=0,drive=drive-ide0-0-0,id=ide0-0-0 -drive
file=/dev/vdisks/james,if=none,id=drive-scsi0-0-0,format=raw -device
scsi-disk,bus=scsi0.0,scsi-id=0,drive=drive-scsi0-0-0,id=scsi0-0-0
-netdev tap,id=hostnet0 -device
virtio-net-pci,netdev=hostnet0,id=net0,mac=52:54:00:37:84:e0,bus=pci.0,addr=0x5
-usb -vnc 127.0.0.1:0 -vga cirrus -device
virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3
Regards
Dominik
[1]
http://help.lockergnome.com/linux/race-condition-net_cls-found-qemu-kvm-env…
3
4