This patch introduces XML schema for domains to retain arbitrary capabilities.
For example, by adding the following XML to domain configuration,
its domain can retain cap_sys_rawio capability.
...
<domain_capabilities>
<cap_sys_rawio/>
</domain_capabilities>
...
Signed-off-by: Taku Izumi <izumi.taku(a)jp.fujitsu.com>
Signed-off-by: Shota Hirae <m11g1401(a)hibikino.ne.jp>
---
docs/formatdomain.html.in | 46 ++++++++++
docs/schemas/domaincommon.rng | 184 ++++++++++++++++++++++++++++++++++++++++++
src/conf/domain_conf.c | 69 +++++++++++++++
src/conf/domain_conf.h | 42 +++++++++
4 files changed, 341 insertions(+)
Index: libvirt/docs/schemas/domaincommon.rng
===================================================================
--- libvirt.orig/docs/schemas/domaincommon.rng
+++ libvirt/docs/schemas/domaincommon.rng
@@ -35,6 +35,9 @@
<ref name="clock"/>
<ref name="resources"/>
<ref name="features"/>
+ <optional>
+ <ref name="domain_capabilities"/>
+ </optional>
<ref name="termination"/>
<optional>
<ref name="devices"/>
@@ -2337,6 +2340,187 @@
</optional>
</define>
<!--
+ A set of optional domain capabilities
+ -->
+ <define name="domain_capabilities">
+ <optional>
+ <element name="domain_capabilities">
+ <interleave>
+ <optional>
+ <element name="cap_chown">
+ <empty/>
+ </element>
+ </optional>
+ <optional>
+ <element name="cap_dac_override">
+ <empty/>
+ </element>
+ </optional>
+ <optional>
+ <element name="cap_dac_read_search">
+ <empty/>
+ </element>
+ </optional>
+ <optional>
+ <element name="cap_fowner">
+ <empty/>
+ </element>
+ </optional>
+ <optional>
+ <element name="cap_fsetid">
+ <empty/>
+ </element>
+ </optional>
+ <optional>
+ <element name="cap_kill">
+ <empty/>
+ </element>
+ </optional>
+ <optional>
+ <element name="cap_setgid">
+ <empty/>
+ </element>
+ </optional>
+ <optional>
+ <element name="cap_setuid">
+ <empty/>
+ </element>
+ </optional>
+ <optional>
+ <element name="cap_setpcap">
+ <empty/>
+ </element>
+ </optional>
+ <optional>
+ <element name="cap_linux_immutable">
+ <empty/>
+ </element>
+ </optional>
+ <optional>
+ <element name="cap_net_bind_service">
+ <empty/>
+ </element>
+ </optional>
+ <optional>
+ <element name="cap_net_broadcast">
+ <empty/>
+ </element>
+ </optional>
+ <optional>
+ <element name="cap_net_admin">
+ <empty/>
+ </element>
+ </optional>
+ <optional>
+ <element name="cap_net_raw">
+ <empty/>
+ </element>
+ </optional>
+ <optional>
+ <element name="cap_ipc_lock">
+ <empty/>
+ </element>
+ </optional>
+ <optional>
+ <element name="cap_ipc_owner">
+ <empty/>
+ </element>
+ </optional>
+ <optional>
+ <element name="cap_sys_module">
+ <empty/>
+ </element>
+ </optional>
+ <optional>
+ <element name="cap_sys_rawio">
+ <empty/>
+ </element>
+ </optional>
+ <optional>
+ <element name="cap_sys_chroot">
+ <empty/>
+ </element>
+ </optional>
+ <optional>
+ <element name="cap_sys_ptrace">
+ <empty/>
+ </element>
+ </optional>
+ <optional>
+ <element name="cap_sys_pacct">
+ <empty/>
+ </element>
+ </optional>
+ <optional>
+ <element name="cap_sys_admin">
+ <empty/>
+ </element>
+ </optional>
+ <optional>
+ <element name="cap_sys_boot">
+ <empty/>
+ </element>
+ </optional>
+ <optional>
+ <element name="cap_sys_nice">
+ <empty/>
+ </element>
+ </optional>
+ <optional>
+ <element name="cap_sys_resource">
+ <empty/>
+ </element>
+ </optional>
+ <optional>
+ <element name="cap_sys_time">
+ <empty/>
+ </element>
+ </optional>
+ <optional>
+ <element name="cap_sys_tty_config">
+ <empty/>
+ </element>
+ </optional>
+ <optional>
+ <element name="cap_mknod">
+ <empty/>
+ </element>
+ </optional>
+ <optional>
+ <element name="cap_lease">
+ <empty/>
+ </element>
+ </optional>
+ <optional>
+ <element name="cap_audit_write">
+ <empty/>
+ </element>
+ </optional>
+ <optional>
+ <element name="cap_audit_control">
+ <empty/>
+ </element>
+ </optional>
+ <optional>
+ <element name="cap_setfcap">
+ <empty/>
+ </element>
+ </optional>
+ <optional>
+ <element name="cap_mac_override">
+ <empty/>
+ </element>
+ </optional>
+ <optional>
+ <element name="cap_mac_admin">
+ <empty/>
+ </element>
+ </optional>
+ </interleave>
+ </element>
+ </optional>
+ </define>
+ <!--
CPU specification
-->
<define name="cpu">
Index: libvirt/src/conf/domain_conf.c
===================================================================
--- libvirt.orig/src/conf/domain_conf.c
+++ libvirt/src/conf/domain_conf.c
@@ -104,6 +104,42 @@ VIR_ENUM_IMPL(virDomainFeature, VIR_DOMA
"hap",
"viridian")
+VIR_ENUM_IMPL(virDomainCapability, VIR_DOMAIN_CAPABILITY_LAST,
+ "cap_chown",
+ "cap_dac_override",
+ "cap_dac_read_search",
+ "cap_fowner",
+ "cap_fsetid",
+ "cap_kill",
+ "cap_setgid",
+ "cap_setuid",
+ "cap_setpcap",
+ "cap_linux_immutable",
+ "cap_net_bind_service",
+ "cap_net_broadcast",
+ "cap_net_admin",
+ "cap_net_raw",
+ "cap_ipc_lock",
+ "cap_ipc_owner",
+ "cap_sys_module",
+ "cap_sys_rawio",
+ "cap_sys_chroot",
+ "cap_sys_ptrace",
+ "cap_sys_pacct",
+ "cap_sys_admin",
+ "cap_sys_boot",
+ "cap_sys_nice",
+ "cap_sys_resource",
+ "cap_sys_time",
+ "cap_sys_tty_config",
+ "cap_mknod",
+ "cap_lease",
+ "cap_audit_write",
+ "cap_audit_control",
+ "cap_setfcap",
+ "cap_mac_override",
+ "cap_mac_admin")
+
VIR_ENUM_IMPL(virDomainLifecycle, VIR_DOMAIN_LIFECYCLE_LAST,
"destroy",
"restart",
@@ -7213,6 +7249,23 @@ static virDomainDefPtr virDomainDefParse
VIR_FREE(nodes);
}
+ n = virXPathNodeSet("./domain_capabilities/*", ctxt, &nodes);
+ if (n < 0)
+ goto error;
+ if (n) {
+ for (i = 0; i < n; i++) {
+ int val = virDomainCapabilityTypeFromString((const char
*)nodes[i]->name);
+ if (val < 0) {
+ virDomainReportError(VIR_ERR_INTERNAL_ERROR,
+ _("unexpected capability %s"),
+ nodes[i]->name);
+ goto error;
+ }
+ def->capabilities |= (1ULL << val);
+ }
+ VIR_FREE(nodes);
+ }
+
if (virDomainLifecycleParseXML(ctxt, "string(./on_reboot[1])",
&def->onReboot, VIR_DOMAIN_LIFECYCLE_RESTART,
virDomainLifecycleTypeFromString) < 0)
@@ -11480,6 +11533,22 @@ virDomainDefFormatInternal(virDomainDefP
virBufferAddLit(buf, " </features>\n");
}
+ if (def->capabilities) {
+ virBufferAddLit(buf, " <domain_capabilities>\n");
+ for (n = 0; n < VIR_DOMAIN_CAPABILITY_LAST; n++) {
+ if (def->capabilities & (1ULL << n)) {
+ const char *name = virDomainCapabilityTypeToString(n);
+ if (!name) {
+ virDomainReportError(VIR_ERR_INTERNAL_ERROR,
+ _("unexpected capability %d"), n);
+ goto cleanup;
+ }
+ virBufferAsprintf(buf, " <%s/>\n", name);
+ }
+ }
+ virBufferAddLit(buf, " </domain_capabilities>\n");
+ }
+
virBufferAdjustIndent(buf, 2);
if (virCPUDefFormatBufFull(buf, def->cpu) < 0)
goto cleanup;
Index: libvirt/src/conf/domain_conf.h
===================================================================
--- libvirt.orig/src/conf/domain_conf.h
+++ libvirt/src/conf/domain_conf.h
@@ -1175,6 +1175,45 @@ enum virDomainFeature {
VIR_DOMAIN_FEATURE_LAST
};
+enum virDomainCapability {
+ VIR_DOMAIN_CAPABILITY_CHOWN,
+ VIR_DOMAIN_CAPABILITY_DAC_OVERRIDE,
+ VIR_DOMAIN_CAPABILITY_DAC_READ_SEARCH,
+ VIR_DOMAIN_CAPABILITY_FOWNER,
+ VIR_DOMAIN_CAPABILITY_FSETID,
+ VIR_DOMAIN_CAPABILITY_KILL,
+ VIR_DOMAIN_CAPABILITY_SETGID,
+ VIR_DOMAIN_CAPABILITY_SETUID,
+ VIR_DOMAIN_CAPABILITY_SETPCAP,
+ VIR_DOMAIN_CAPABILITY_LINUX_IMMUTABLE,
+ VIR_DOMAIN_CAPABILITY_NET_BIND_SERVICE,
+ VIR_DOMAIN_CAPABILITY_NET_BROADCAST,
+ VIR_DOMAIN_CAPABILITY_NET_ADMIN,
+ VIR_DOMAIN_CAPABILITY_NET_RAW,
+ VIR_DOMAIN_CAPABILITY_IPC_LOCK,
+ VIR_DOMAIN_CAPABILITY_IPC_OWNER,
+ VIR_DOMAIN_CAPABILITY_SYS_MODULE,
+ VIR_DOMAIN_CAPABILITY_SYS_RAWIO,
+ VIR_DOMAIN_CAPABILITY_SYS_CHROOT,
+ VIR_DOMAIN_CAPABILITY_SYS_PTRACE,
+ VIR_DOMAIN_CAPABILITY_SYS_PACCT,
+ VIR_DOMAIN_CAPABILITY_SYS_ADMIN,
+ VIR_DOMAIN_CAPABILITY_SYS_BOOT,
+ VIR_DOMAIN_CAPABILITY_SYS_NICE,
+ VIR_DOMAIN_CAPABILITY_SYS_RESOURCE,
+ VIR_DOMAIN_CAPABILITY_SYS_TIME,
+ VIR_DOMAIN_CAPABILITY_SYS_TTY_CONFIG,
+ VIR_DOMAIN_CAPABILITY_MKNOD,
+ VIR_DOMAIN_CAPABILITY_LEASE,
+ VIR_DOMAIN_CAPABILITY_AUDIT_WRITE,
+ VIR_DOMAIN_CAPABILITY_AUDIT_CONTROL,
+ VIR_DOMAIN_CAPABILITY_SETFCAP,
+ VIR_DOMAIN_CAPABILITY_MAC_OVERRIDE,
+ VIR_DOMAIN_CAPABILITY_MAC_ADMIN,
+
+ VIR_DOMAIN_CAPABILITY_LAST
+};
+
enum virDomainLifecycleAction {
VIR_DOMAIN_LIFECYCLE_DESTROY,
VIR_DOMAIN_LIFECYCLE_RESTART,
@@ -1440,6 +1479,8 @@ struct _virDomainDef {
char *emulator;
int features;
+ unsigned long long capabilities;
+
virDomainClockDef clock;
int ngraphics;
@@ -1951,6 +1992,7 @@ VIR_ENUM_DECL(virDomainTaint)
VIR_ENUM_DECL(virDomainVirt)
VIR_ENUM_DECL(virDomainBoot)
VIR_ENUM_DECL(virDomainFeature)
+VIR_ENUM_DECL(virDomainCapability)
VIR_ENUM_DECL(virDomainLifecycle)
VIR_ENUM_DECL(virDomainLifecycleCrash)
VIR_ENUM_DECL(virDomainDevice)
Index: libvirt/docs/formatdomain.html.in
===================================================================
--- libvirt.orig/docs/formatdomain.html.in
+++ libvirt/docs/formatdomain.html.in
@@ -787,6 +787,52 @@
</dd>
</dl>
+ <h3><a name="elementsDomainCapabilities">Domain
capabilities</a></h3>
+
+ <p>
+ Domain is allowed to retain the specified capabilities.
+ </p>
+
+<pre>
+ ...
+ <domain_capabilities>
+ <cap_chown/>
+ <cap_dac_override/>
+ <cap_dac_read_search/>
+ <cap_fowner/>
+ <cap_fsetid/>
+ <cap_kill/>
+ <cap_setgid/>
+ <cap_setuid/>
+ <cap_setpcap/>
+ <cap_linux_immutable/>
+ <cap_net_bind_service/>
+ <cap_net_broadcast/>
+ <cap_net_admin/>
+ <cap_net_raw/>
+ <cap_ipc_lock/>
+ <cap_ipc_owner/>
+ <cap_sys_module/>
+ <cap_sys_rawio/>
+ <cap_sys_chroot/>
+ <cap_sys_ptrace/>
+ <cap_sys_pacct/>
+ <cap_sys_admin/>
+ <cap_sys_boot/>
+ <cap_sys_nice/>
+ <cap_sys_resource/>
+ <cap_sys_time/>
+ <cap_sys_tty_config/>
+ <cap_mknod/>
+ <cap_lease/>
+ <cap_audit_write/>
+ <cap_audit_control/>
+ <cap_setfcap/>
+ <cap_mac_override/>
+ <cap_mac_admin/>
+ </domain_capabilities>
+ ...</pre>
+
<h3><a name="elementsTime">Time keeping</a></h3>
<p>