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@xxxxxxxxxxxxxx> Signed-off-by: Shota Hirae <m11g1401@xxxxxxxxxxxxxx> --- 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> -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list