[libvirt] [PATCH v2 0/5] RFC: grant KVM guests retain arbitrary capabilities

Hi Daniel-san and all, This patchset adds an option for KVM guests to retain arbitrary capabilities. The first version is here: http://www.redhat.com/archives/libvir-list/2011-December/msg00857.html According to Daniel-san's comment, I changed my patch like the following: v1 -> v2 - introduce "process" and "cap" elements in the capability XML - change XML element name of domain XML likewise ; process capabilities host supports are found in the capability XML. # virsh capabilities <capabilities> <host> <uuid>00000000-0000-0000-0000-00199914f1c5</uuid> ... <process> <cap name='chown'/> <cap name='dac_override'/> <cap name='dac_read_search'/> <cap name='fowner'/> ... </process> </host> ... ; VM can retain cap_sys_rawio capability # virsh edit VM ... </features> <process> <cap name='sys_rawio'/> </process> <clock offset='utc'/> ... # virsh start VM # cat /proc/<VM's PID>/status ... CapInh: 0000000000000000 CapPrm: fffffffc00020000 CapEff: fffffffc00020000 CapBnd: fffffffc00020000 ... *[PATCH v2 1/5] conf: add XML schema for capability XML *[PATCH v2 2/5] conf: add XML schema for domain XML *[PATCH v2 3/5] util: add functions to keep capabilities *[PATCH v2 4/5] util: extend virExecWithHook() *[PATCH v2 5/5] qemu: make qemu processes to retain capabilities Best regards, Taku Izumi

This patch introduces XML schema for capability XML. "process" and "cap" element are added. The list of "cap" elements represents process capabilities host supports. <capabilities> <host> ... <process> <cap name='chown'/> <cap name='dac_override'/> ... </process> </host> ... </capabilities> Signed-off-by: Taku Izumi <izumi.taku@jp.fujitsu.com> --- docs/schemas/capability.rng | 50 +++++++++++++++++++++++++++++++ include/libvirt/libvirt.h.in | 45 ++++++++++++++++++++++++++++ src/conf/capabilities.c | 69 +++++++++++++++++++++++++++++++++++++++++++ src/conf/capabilities.h | 5 +++ 4 files changed, 169 insertions(+) Index: libvirt/src/conf/capabilities.h =================================================================== --- libvirt.orig/src/conf/capabilities.h +++ libvirt/src/conf/capabilities.h @@ -119,6 +119,10 @@ struct _virCapsHost { virCapsHostSecModel secModel; virCPUDefPtr cpu; unsigned char host_uuid[VIR_UUID_BUFLEN]; + + unsigned long long processCaps; /* Bitmask of the Process capabilities + * see enum vir + */ }; typedef int (*virDomainDefNamespaceParse)(xmlDocPtr, xmlNodePtr, @@ -263,5 +267,6 @@ virCapabilitiesDefaultGuestEmulator(virC extern char * virCapabilitiesFormatXML(virCapsPtr caps); +VIR_ENUM_DECL(virCapsProcessCaps) #endif /* __VIR_CAPABILITIES_H */ Index: libvirt/src/conf/capabilities.c =================================================================== --- libvirt.orig/src/conf/capabilities.c +++ libvirt/src/conf/capabilities.c @@ -33,6 +33,9 @@ #include "cpu_conf.h" #include "virterror_internal.h" +#if HAVE_CAPNG +# include <cap-ng.h> +#endif #define VIR_FROM_THIS VIR_FROM_CAPABILITIES @@ -40,6 +43,42 @@ VIR_ENUM_DECL(virCapsHostPMTarget) VIR_ENUM_IMPL(virCapsHostPMTarget, VIR_NODE_SUSPEND_TARGET_LAST, "suspend_mem", "suspend_disk", "suspend_hybrid"); +VIR_ENUM_IMPL(virCapsProcessCaps, VIR_PROCESS_CAPABILITY_LAST, + "chown", + "dac_override", + "dac_read_search", + "fowner", + "fsetid", + "kill", + "setgid", + "setuid", + "setpcap", + "linux_immutable", + "net_bind_service", + "net_broadcast", + "net_admin", + "net_raw", + "ipc_lock", + "ipc_owner", + "sys_module", + "sys_rawio", + "sys_chroot", + "sys_ptrace", + "sys_pacct", + "sys_admin", + "sys_boot", + "sys_nice", + "sys_resource", + "sys_time", + "sys_tty_config", + "mknod", + "lease", + "audit_write", + "audit_control", + "setfcap", + "mac_override", + "mac_admin") + /** * virCapabilitiesNew: * @arch: host machine architecture @@ -63,6 +102,8 @@ virCapabilitiesNew(const char *arch, caps->host.offlineMigrate = offlineMigrate; caps->host.liveMigrate = liveMigrate; + virCapabilitiesInitProcessCaps(caps); + return caps; no_memory: @@ -754,6 +795,18 @@ virCapabilitiesFormatXML(virCapsPtr caps virBufferAddLit(&xml, " </secmodel>\n"); } + if (caps->host.processCaps) { + virBufferAddLit(&xml, " <process>\n"); + for (i = 0; i < VIR_PROCESS_CAPABILITY_LAST; i++) { + if (caps->host.processCaps & (1ULL << i)) { + const char *name = virCapsProcessCapsTypeToString(i); + if (name) + virBufferAsprintf(&xml, " <cap name='%s'/>\n", name); + } + } + virBufferAddLit(&xml, " </process>\n"); + } + virBufferAddLit(&xml, " </host>\n\n"); @@ -837,6 +890,22 @@ virCapabilitiesFormatXML(virCapsPtr caps return virBufferContentAndReset(&xml); } +#ifdef HAVE_CAPNG +void +virCapabilitiesInitProcessCaps(virCapsPtr caps) +{ + caps->host.processCaps |= (1ULL << (CAP_LAST_CAP + 1)) - 1; +} + +#else +void +virCapabilitiesInitProcessCaps(virCapsPtr caps) +{ + caps->host.processCaps = 0; +} + +#endif + extern void virCapabilitiesSetMacPrefix(virCapsPtr caps, unsigned char *prefix) Index: libvirt/docs/schemas/capability.rng =================================================================== --- libvirt.orig/docs/schemas/capability.rng +++ libvirt/docs/schemas/capability.rng @@ -46,6 +46,56 @@ <optional> <ref name='secmodel'/> </optional> + <optional> + <ref name='process'/> + </optional> + </element> + </define> + + <define name='process'> + <element name='process'> + <zeroOrMore> + <element name='cap'> + <attribute name='name'> + <choice> + <value>chown</value> + <value>dac_override</value> + <value>dac_read_search</value> + <value>fowner</value> + <value>fsetid</value> + <value>kill</value> + <value>setgid</value> + <value>setuid</value> + <value>setpcap</value> + <value>linux_immutable</value> + <value>net_bind_service</value> + <value>net_broadcast</value> + <value>net_admin</value> + <value>net_raw</value> + <value>ipc_lock</value> + <value>ipc_owner</value> + <value>sys_module</value> + <value>sys_rawio</value> + <value>sys_chroot</value> + <value>sys_ptrace</value> + <value>sys_pacct</value> + <value>sys_admin</value> + <value>sys_boot</value> + <value>sys_nice</value> + <value>sys_resource</value> + <value>sys_time</value> + <value>sys_tty_config</value> + <value>mknod</value> + <value>lease</value> + <value>audit_write</value> + <value>audit_control</value> + <value>setfcap</value> + <value>mac_override</value> + <value>mac_admin</value> + </choice> + </attribute> + </element> + </zeroOrMore> </element> </define> Index: libvirt/include/libvirt/libvirt.h.in =================================================================== --- libvirt.orig/include/libvirt/libvirt.h.in +++ libvirt/include/libvirt/libvirt.h.in @@ -3540,6 +3540,51 @@ int virConnectSetKeepAlive(virConnectPtr int interval, unsigned int count); + +/* + * virProcessCapabilityType + * + * A process capability Type + */ +typedef enum { + VIR_PROCESS_CAPABILITY_CHOWN, + VIR_PROCESS_CAPABILITY_DAC_OVERRIDE, + VIR_PROCESS_CAPABILITY_DAC_READ_SEARCH, + VIR_PROCESS_CAPABILITY_FOWNER, + VIR_PROCESS_CAPABILITY_FSETID, + VIR_PROCESS_CAPABILITY_KILL, + VIR_PROCESS_CAPABILITY_SETGID, + VIR_PROCESS_CAPABILITY_SETUID, + VIR_PROCESS_CAPABILITY_SETPCAP, + VIR_PROCESS_CAPABILITY_LINUX_IMMUTABLE, + VIR_PROCESS_CAPABILITY_NET_BIND_SERVICE, + VIR_PROCESS_CAPABILITY_NET_BROADCAST, + VIR_PROCESS_CAPABILITY_NET_ADMIN, + VIR_PROCESS_CAPABILITY_NET_RAW, + VIR_PROCESS_CAPABILITY_IPC_LOCK, + VIR_PROCESS_CAPABILITY_IPC_OWNER, + VIR_PROCESS_CAPABILITY_SYS_MODULE, + VIR_PROCESS_CAPABILITY_SYS_RAWIO, + VIR_PROCESS_CAPABILITY_SYS_CHROOT, + VIR_PROCESS_CAPABILITY_SYS_PTRACE, + VIR_PROCESS_CAPABILITY_SYS_PACCT, + VIR_PROCESS_CAPABILITY_SYS_ADMIN, + VIR_PROCESS_CAPABILITY_SYS_BOOT, + VIR_PROCESS_CAPABILITY_SYS_NICE, + VIR_PROCESS_CAPABILITY_SYS_RESOURCE, + VIR_PROCESS_CAPABILITY_SYS_TIME, + VIR_PROCESS_CAPABILITY_SYS_TTY_CONFIG, + VIR_PROCESS_CAPABILITY_MKNOD, + VIR_PROCESS_CAPABILITY_LEASE, + VIR_PROCESS_CAPABILITY_AUDIT_WRITE, + VIR_PROCESS_CAPABILITY_AUDIT_CONTROL, + VIR_PROCESS_CAPABILITY_SETFCAP, + VIR_PROCESS_CAPABILITY_MAC_OVERRIDE, + VIR_PROCESS_CAPABILITY_MAC_ADMIN, + + VIR_PROCESS_CAPABILITY_LAST +} virProcessCapabilityType; + #ifdef __cplusplus } #endif

On 2011年12月22日 15:02, Taku Izumi wrote:
This patch introduces XML schema for capability XML. "process" and "cap" element are added. The list of "cap" elements represents process capabilities host supports.
<capabilities> <host> ... <process> <cap name='chown'/> <cap name='dac_override'/> ... </process> </host> ... </capabilities>
Signed-off-by: Taku Izumi<izumi.taku@jp.fujitsu.com> --- docs/schemas/capability.rng | 50 +++++++++++++++++++++++++++++++ include/libvirt/libvirt.h.in | 45 ++++++++++++++++++++++++++++ src/conf/capabilities.c | 69 +++++++++++++++++++++++++++++++++++++++++++ src/conf/capabilities.h | 5 +++ 4 files changed, 169 insertions(+)
Index: libvirt/src/conf/capabilities.h =================================================================== --- libvirt.orig/src/conf/capabilities.h +++ libvirt/src/conf/capabilities.h @@ -119,6 +119,10 @@ struct _virCapsHost { virCapsHostSecModel secModel; virCPUDefPtr cpu; unsigned char host_uuid[VIR_UUID_BUFLEN]; + + unsigned long long processCaps; /* Bitmask of the Process capabilities + * see enum vir
s/vir/virCapsProcessCaps/
+ */ };
typedef int (*virDomainDefNamespaceParse)(xmlDocPtr, xmlNodePtr, @@ -263,5 +267,6 @@ virCapabilitiesDefaultGuestEmulator(virC extern char * virCapabilitiesFormatXML(virCapsPtr caps);
+VIR_ENUM_DECL(virCapsProcessCaps)
#endif /* __VIR_CAPABILITIES_H */ Index: libvirt/src/conf/capabilities.c =================================================================== --- libvirt.orig/src/conf/capabilities.c +++ libvirt/src/conf/capabilities.c @@ -33,6 +33,9 @@ #include "cpu_conf.h" #include "virterror_internal.h"
+#if HAVE_CAPNG +# include<cap-ng.h> +#endif
#define VIR_FROM_THIS VIR_FROM_CAPABILITIES
@@ -40,6 +43,42 @@ VIR_ENUM_DECL(virCapsHostPMTarget) VIR_ENUM_IMPL(virCapsHostPMTarget, VIR_NODE_SUSPEND_TARGET_LAST, "suspend_mem", "suspend_disk", "suspend_hybrid");
+VIR_ENUM_IMPL(virCapsProcessCaps, VIR_PROCESS_CAPABILITY_LAST, + "chown", + "dac_override", + "dac_read_search", + "fowner", + "fsetid", + "kill", + "setgid", + "setuid", + "setpcap", + "linux_immutable", + "net_bind_service", + "net_broadcast", + "net_admin", + "net_raw", + "ipc_lock", + "ipc_owner", + "sys_module", + "sys_rawio", + "sys_chroot", + "sys_ptrace", + "sys_pacct", + "sys_admin", + "sys_boot", + "sys_nice", + "sys_resource", + "sys_time", + "sys_tty_config", + "mknod", + "lease", + "audit_write", + "audit_control", + "setfcap", + "mac_override", + "mac_admin") + /** * virCapabilitiesNew: * @arch: host machine architecture @@ -63,6 +102,8 @@ virCapabilitiesNew(const char *arch, caps->host.offlineMigrate = offlineMigrate; caps->host.liveMigrate = liveMigrate;
+ virCapabilitiesInitProcessCaps(caps);
Mark [1]
+ return caps;
no_memory: @@ -754,6 +795,18 @@ virCapabilitiesFormatXML(virCapsPtr caps virBufferAddLit(&xml, "</secmodel>\n"); }
+ if (caps->host.processCaps) { + virBufferAddLit(&xml, "<process>\n"); + for (i = 0; i< VIR_PROCESS_CAPABILITY_LAST; i++) { + if (caps->host.processCaps& (1ULL<< i)) { + const char *name = virCapsProcessCapsTypeToString(i); + if (name) + virBufferAsprintf(&xml, "<cap name='%s'/>\n", name); + } + } + virBufferAddLit(&xml, "</process>\n"); + } + virBufferAddLit(&xml, "</host>\n\n");
@@ -837,6 +890,22 @@ virCapabilitiesFormatXML(virCapsPtr caps return virBufferContentAndReset(&xml); }
+#ifdef HAVE_CAPNG +void
s/void/static void/
+virCapabilitiesInitProcessCaps(virCapsPtr caps) +{ + caps->host.processCaps |= (1ULL<< (CAP_LAST_CAP + 1)) - 1; +} + +#else +void +virCapabilitiesInitProcessCaps(virCapsPtr caps) +{ + caps->host.processCaps = 0; +}
This is no need IMHO, host.processCaps is already initialized as 0 when doing VIR_ALLOC on caps. And what we need might be an "ifdef HAVE_CAPNG" at [1] (see above).
+ +#endif + extern void virCapabilitiesSetMacPrefix(virCapsPtr caps, unsigned char *prefix) Index: libvirt/docs/schemas/capability.rng =================================================================== --- libvirt.orig/docs/schemas/capability.rng +++ libvirt/docs/schemas/capability.rng @@ -46,6 +46,56 @@ <optional> <ref name='secmodel'/> </optional> +<optional> +<ref name='process'/> +</optional> +</element> +</define> + +<define name='process'> +<element name='process'> +<zeroOrMore> +<element name='cap'> +<attribute name='name'> +<choice> +<value>chown</value> +<value>dac_override</value> +<value>dac_read_search</value> +<value>fowner</value> +<value>fsetid</value> +<value>kill</value> +<value>setgid</value> +<value>setuid</value> +<value>setpcap</value> +<value>linux_immutable</value> +<value>net_bind_service</value> +<value>net_broadcast</value> +<value>net_admin</value> +<value>net_raw</value> +<value>ipc_lock</value> +<value>ipc_owner</value> +<value>sys_module</value> +<value>sys_rawio</value> +<value>sys_chroot</value> +<value>sys_ptrace</value> +<value>sys_pacct</value> +<value>sys_admin</value> +<value>sys_boot</value> +<value>sys_nice</value> +<value>sys_resource</value> +<value>sys_time</value> +<value>sys_tty_config</value> +<value>mknod</value> +<value>lease</value> +<value>audit_write</value> +<value>audit_control</value> +<value>setfcap</value> +<value>mac_override</value> +<value>mac_admin</value> +</choice> +</attribute> +</element> +</zeroOrMore> </element> </define>
Index: libvirt/include/libvirt/libvirt.h.in =================================================================== --- libvirt.orig/include/libvirt/libvirt.h.in +++ libvirt/include/libvirt/libvirt.h.in @@ -3540,6 +3540,51 @@ int virConnectSetKeepAlive(virConnectPtr int interval, unsigned int count);
+ +/* + * virProcessCapabilityType + * + * A process capability Type + */ +typedef enum { + VIR_PROCESS_CAPABILITY_CHOWN, + VIR_PROCESS_CAPABILITY_DAC_OVERRIDE, + VIR_PROCESS_CAPABILITY_DAC_READ_SEARCH, + VIR_PROCESS_CAPABILITY_FOWNER, + VIR_PROCESS_CAPABILITY_FSETID, + VIR_PROCESS_CAPABILITY_KILL, + VIR_PROCESS_CAPABILITY_SETGID, + VIR_PROCESS_CAPABILITY_SETUID, + VIR_PROCESS_CAPABILITY_SETPCAP, + VIR_PROCESS_CAPABILITY_LINUX_IMMUTABLE, + VIR_PROCESS_CAPABILITY_NET_BIND_SERVICE, + VIR_PROCESS_CAPABILITY_NET_BROADCAST, + VIR_PROCESS_CAPABILITY_NET_ADMIN, + VIR_PROCESS_CAPABILITY_NET_RAW, + VIR_PROCESS_CAPABILITY_IPC_LOCK, + VIR_PROCESS_CAPABILITY_IPC_OWNER, + VIR_PROCESS_CAPABILITY_SYS_MODULE, + VIR_PROCESS_CAPABILITY_SYS_RAWIO, + VIR_PROCESS_CAPABILITY_SYS_CHROOT, + VIR_PROCESS_CAPABILITY_SYS_PTRACE, + VIR_PROCESS_CAPABILITY_SYS_PACCT, + VIR_PROCESS_CAPABILITY_SYS_ADMIN, + VIR_PROCESS_CAPABILITY_SYS_BOOT, + VIR_PROCESS_CAPABILITY_SYS_NICE, + VIR_PROCESS_CAPABILITY_SYS_RESOURCE, + VIR_PROCESS_CAPABILITY_SYS_TIME, + VIR_PROCESS_CAPABILITY_SYS_TTY_CONFIG, + VIR_PROCESS_CAPABILITY_MKNOD, + VIR_PROCESS_CAPABILITY_LEASE, + VIR_PROCESS_CAPABILITY_AUDIT_WRITE, + VIR_PROCESS_CAPABILITY_AUDIT_CONTROL, + VIR_PROCESS_CAPABILITY_SETFCAP, + VIR_PROCESS_CAPABILITY_MAC_OVERRIDE, + VIR_PROCESS_CAPABILITY_MAC_ADMIN, + + VIR_PROCESS_CAPABILITY_LAST +} virProcessCapabilityType; +
Perhaps I could get the answer in following patches, but now I'm wondering why it's a public ENUM.
#ifdef __cplusplus } #endif
-- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list

On 2011年12月22日 15:02, Taku Izumi wrote:
This patch introduces XML schema for capability XML. "process" and "cap" element are added. The list of "cap" elements represents process capabilities host supports.
<capabilities> <host> ... <process> <cap name='chown'/> <cap name='dac_override'/> ... </process> </host> ... </capabilities>
Signed-off-by: Taku Izumi<izumi.taku@jp.fujitsu.com> --- docs/schemas/capability.rng | 50 +++++++++++++++++++++++++++++++ include/libvirt/libvirt.h.in | 45 ++++++++++++++++++++++++++++ src/conf/capabilities.c | 69 +++++++++++++++++++++++++++++++++++++++++++ src/conf/capabilities.h | 5 +++ 4 files changed, 169 insertions(+)
Index: libvirt/src/conf/capabilities.h =================================================================== --- libvirt.orig/src/conf/capabilities.h +++ libvirt/src/conf/capabilities.h @@ -119,6 +119,10 @@ struct _virCapsHost { virCapsHostSecModel secModel; virCPUDefPtr cpu; unsigned char host_uuid[VIR_UUID_BUFLEN]; + + unsigned long long processCaps; /* Bitmask of the Process capabilities + * see enum vir + */ };
typedef int (*virDomainDefNamespaceParse)(xmlDocPtr, xmlNodePtr, @@ -263,5 +267,6 @@ virCapabilitiesDefaultGuestEmulator(virC extern char * virCapabilitiesFormatXML(virCapsPtr caps);
+VIR_ENUM_DECL(virCapsProcessCaps)
#endif /* __VIR_CAPABILITIES_H */ Index: libvirt/src/conf/capabilities.c =================================================================== --- libvirt.orig/src/conf/capabilities.c +++ libvirt/src/conf/capabilities.c @@ -33,6 +33,9 @@ #include "cpu_conf.h" #include "virterror_internal.h"
+#if HAVE_CAPNG +# include<cap-ng.h> +#endif
#define VIR_FROM_THIS VIR_FROM_CAPABILITIES
@@ -40,6 +43,42 @@ VIR_ENUM_DECL(virCapsHostPMTarget) VIR_ENUM_IMPL(virCapsHostPMTarget, VIR_NODE_SUSPEND_TARGET_LAST, "suspend_mem", "suspend_disk", "suspend_hybrid");
+VIR_ENUM_IMPL(virCapsProcessCaps, VIR_PROCESS_CAPABILITY_LAST, + "chown", + "dac_override", + "dac_read_search", + "fowner", + "fsetid", + "kill", + "setgid", + "setuid", + "setpcap", + "linux_immutable", + "net_bind_service", + "net_broadcast", + "net_admin", + "net_raw", + "ipc_lock", + "ipc_owner", + "sys_module", + "sys_rawio", + "sys_chroot", + "sys_ptrace", + "sys_pacct", + "sys_admin", + "sys_boot", + "sys_nice", + "sys_resource", + "sys_time", + "sys_tty_config", + "mknod", + "lease", + "audit_write", + "audit_control", + "setfcap", + "mac_override", + "mac_admin") + /** * virCapabilitiesNew: * @arch: host machine architecture @@ -63,6 +102,8 @@ virCapabilitiesNew(const char *arch, caps->host.offlineMigrate = offlineMigrate; caps->host.liveMigrate = liveMigrate;
+ virCapabilitiesInitProcessCaps(caps); + return caps;
no_memory: @@ -754,6 +795,18 @@ virCapabilitiesFormatXML(virCapsPtr caps virBufferAddLit(&xml, "</secmodel>\n"); }
+ if (caps->host.processCaps) { + virBufferAddLit(&xml, "<process>\n"); + for (i = 0; i< VIR_PROCESS_CAPABILITY_LAST; i++) { + if (caps->host.processCaps& (1ULL<< i)) { + const char *name = virCapsProcessCapsTypeToString(i); + if (name) + virBufferAsprintf(&xml, "<cap name='%s'/>\n", name); + } + } + virBufferAddLit(&xml, "</process>\n"); + } + virBufferAddLit(&xml, "</host>\n\n");
@@ -837,6 +890,22 @@ virCapabilitiesFormatXML(virCapsPtr caps return virBufferContentAndReset(&xml); }
+#ifdef HAVE_CAPNG +void +virCapabilitiesInitProcessCaps(virCapsPtr caps) +{ + caps->host.processCaps |= (1ULL<< (CAP_LAST_CAP + 1)) - 1; +} + +#else +void +virCapabilitiesInitProcessCaps(virCapsPtr caps) +{ + caps->host.processCaps = 0; +} + +#endif + extern void virCapabilitiesSetMacPrefix(virCapsPtr caps, unsigned char *prefix) Index: libvirt/docs/schemas/capability.rng =================================================================== --- libvirt.orig/docs/schemas/capability.rng +++ libvirt/docs/schemas/capability.rng @@ -46,6 +46,56 @@ <optional> <ref name='secmodel'/> </optional> +<optional> +<ref name='process'/> +</optional> +</element> +</define> + +<define name='process'> +<element name='process'> +<zeroOrMore> +<element name='cap'> +<attribute name='name'> +<choice> +<value>chown</value> +<value>dac_override</value> +<value>dac_read_search</value> +<value>fowner</value> +<value>fsetid</value> +<value>kill</value> +<value>setgid</value> +<value>setuid</value> +<value>setpcap</value> +<value>linux_immutable</value> +<value>net_bind_service</value> +<value>net_broadcast</value> +<value>net_admin</value> +<value>net_raw</value> +<value>ipc_lock</value> +<value>ipc_owner</value> +<value>sys_module</value> +<value>sys_rawio</value> +<value>sys_chroot</value> +<value>sys_ptrace</value> +<value>sys_pacct</value> +<value>sys_admin</value> +<value>sys_boot</value> +<value>sys_nice</value> +<value>sys_resource</value> +<value>sys_time</value> +<value>sys_tty_config</value> +<value>mknod</value> +<value>lease</value> +<value>audit_write</value> +<value>audit_control</value> +<value>setfcap</value> +<value>mac_override</value> +<value>mac_admin</value> +</choice> +</attribute> +</element> +</zeroOrMore> </element> </define>
Index: libvirt/include/libvirt/libvirt.h.in =================================================================== --- libvirt.orig/include/libvirt/libvirt.h.in +++ libvirt/include/libvirt/libvirt.h.in @@ -3540,6 +3540,51 @@ int virConnectSetKeepAlive(virConnectPtr int interval, unsigned int count);
+ +/* + * virProcessCapabilityType + * + * A process capability Type + */ +typedef enum { + VIR_PROCESS_CAPABILITY_CHOWN, + VIR_PROCESS_CAPABILITY_DAC_OVERRIDE, + VIR_PROCESS_CAPABILITY_DAC_READ_SEARCH, + VIR_PROCESS_CAPABILITY_FOWNER, + VIR_PROCESS_CAPABILITY_FSETID, + VIR_PROCESS_CAPABILITY_KILL, + VIR_PROCESS_CAPABILITY_SETGID, + VIR_PROCESS_CAPABILITY_SETUID, + VIR_PROCESS_CAPABILITY_SETPCAP, + VIR_PROCESS_CAPABILITY_LINUX_IMMUTABLE, + VIR_PROCESS_CAPABILITY_NET_BIND_SERVICE, + VIR_PROCESS_CAPABILITY_NET_BROADCAST, + VIR_PROCESS_CAPABILITY_NET_ADMIN, + VIR_PROCESS_CAPABILITY_NET_RAW, + VIR_PROCESS_CAPABILITY_IPC_LOCK, + VIR_PROCESS_CAPABILITY_IPC_OWNER, + VIR_PROCESS_CAPABILITY_SYS_MODULE, + VIR_PROCESS_CAPABILITY_SYS_RAWIO, + VIR_PROCESS_CAPABILITY_SYS_CHROOT, + VIR_PROCESS_CAPABILITY_SYS_PTRACE, + VIR_PROCESS_CAPABILITY_SYS_PACCT, + VIR_PROCESS_CAPABILITY_SYS_ADMIN, + VIR_PROCESS_CAPABILITY_SYS_BOOT, + VIR_PROCESS_CAPABILITY_SYS_NICE, + VIR_PROCESS_CAPABILITY_SYS_RESOURCE, + VIR_PROCESS_CAPABILITY_SYS_TIME, + VIR_PROCESS_CAPABILITY_SYS_TTY_CONFIG, + VIR_PROCESS_CAPABILITY_MKNOD, + VIR_PROCESS_CAPABILITY_LEASE, + VIR_PROCESS_CAPABILITY_AUDIT_WRITE, + VIR_PROCESS_CAPABILITY_AUDIT_CONTROL, + VIR_PROCESS_CAPABILITY_SETFCAP, + VIR_PROCESS_CAPABILITY_MAC_OVERRIDE, + VIR_PROCESS_CAPABILITY_MAC_ADMIN, + + VIR_PROCESS_CAPABILITY_LAST +} virProcessCapabilityType; + #ifdef __cplusplus } #endif
When trying to compile the patchset, I see warnings as below: conf/capabilities.c: In function 'virCapabilitiesNew': conf/capabilities.c:105:5: warning: implicit declaration of function 'virCapabilitiesInitProcessCaps' [-Wimplicit-function-declaration] conf/capabilities.c:105:5: warning: nested extern declaration of 'virCapabilitiesInitProcessCaps' [-Wnested-externs] conf/capabilities.c: At top level: conf/capabilities.c:895:1: warning: no previous prototype for 'virCapabilitiesInitProcessCaps' [-Wmissing-prototypes] conf/capabilities.c:895:1: warning: conflicting types for 'virCapabilitiesInitProcessCaps' [enabled by default] conf/capabilities.c:105:5: note: previous implicit declaration of 'virCapabilitiesInitProcessCaps' was here You need to declare the function before use it. Regards, Osier

On 2011年12月22日 15:02, Taku Izumi wrote:
This patch introduces XML schema for capability XML. "process" and "cap" element are added. The list of "cap" elements represents process capabilities host supports.
<capabilities> <host> ... <process> <cap name='chown'/> <cap name='dac_override'/> ... </process> </host> ... </capabilities>
Signed-off-by: Taku Izumi<izumi.taku@jp.fujitsu.com> --- docs/schemas/capability.rng | 50 +++++++++++++++++++++++++++++++ include/libvirt/libvirt.h.in | 45 ++++++++++++++++++++++++++++ src/conf/capabilities.c | 69 +++++++++++++++++++++++++++++++++++++++++++ src/conf/capabilities.h | 5 +++ 4 files changed, 169 insertions(+)
Index: libvirt/src/conf/capabilities.h =================================================================== --- libvirt.orig/src/conf/capabilities.h +++ libvirt/src/conf/capabilities.h @@ -119,6 +119,10 @@ struct _virCapsHost { virCapsHostSecModel secModel; virCPUDefPtr cpu; unsigned char host_uuid[VIR_UUID_BUFLEN]; + + unsigned long long processCaps; /* Bitmask of the Process capabilities + * see enum vir + */ };
typedef int (*virDomainDefNamespaceParse)(xmlDocPtr, xmlNodePtr, @@ -263,5 +267,6 @@ virCapabilitiesDefaultGuestEmulator(virC extern char * virCapabilitiesFormatXML(virCapsPtr caps);
+VIR_ENUM_DECL(virCapsProcessCaps)
#endif /* __VIR_CAPABILITIES_H */ Index: libvirt/src/conf/capabilities.c =================================================================== --- libvirt.orig/src/conf/capabilities.c +++ libvirt/src/conf/capabilities.c @@ -33,6 +33,9 @@ #include "cpu_conf.h" #include "virterror_internal.h"
+#if HAVE_CAPNG +# include<cap-ng.h> +#endif
#define VIR_FROM_THIS VIR_FROM_CAPABILITIES
@@ -40,6 +43,42 @@ VIR_ENUM_DECL(virCapsHostPMTarget) VIR_ENUM_IMPL(virCapsHostPMTarget, VIR_NODE_SUSPEND_TARGET_LAST, "suspend_mem", "suspend_disk", "suspend_hybrid");
+VIR_ENUM_IMPL(virCapsProcessCaps, VIR_PROCESS_CAPABILITY_LAST, + "chown", + "dac_override", + "dac_read_search", + "fowner", + "fsetid", + "kill", + "setgid", + "setuid", + "setpcap", + "linux_immutable", + "net_bind_service", + "net_broadcast", + "net_admin", + "net_raw", + "ipc_lock", + "ipc_owner", + "sys_module", + "sys_rawio", + "sys_chroot", + "sys_ptrace", + "sys_pacct", + "sys_admin", + "sys_boot", + "sys_nice", + "sys_resource", + "sys_time", + "sys_tty_config", + "mknod", + "lease", + "audit_write", + "audit_control", + "setfcap", + "mac_override", + "mac_admin") + /** * virCapabilitiesNew: * @arch: host machine architecture @@ -63,6 +102,8 @@ virCapabilitiesNew(const char *arch, caps->host.offlineMigrate = offlineMigrate; caps->host.liveMigrate = liveMigrate;
+ virCapabilitiesInitProcessCaps(caps); + return caps;
no_memory: @@ -754,6 +795,18 @@ virCapabilitiesFormatXML(virCapsPtr caps virBufferAddLit(&xml, "</secmodel>\n"); }
+ if (caps->host.processCaps) { + virBufferAddLit(&xml, "<process>\n"); + for (i = 0; i< VIR_PROCESS_CAPABILITY_LAST; i++) { + if (caps->host.processCaps& (1ULL<< i)) { + const char *name = virCapsProcessCapsTypeToString(i); + if (name) + virBufferAsprintf(&xml, "<cap name='%s'/>\n", name); + } + } + virBufferAddLit(&xml, "</process>\n"); + } + virBufferAddLit(&xml, "</host>\n\n");
@@ -837,6 +890,22 @@ virCapabilitiesFormatXML(virCapsPtr caps return virBufferContentAndReset(&xml); }
+#ifdef HAVE_CAPNG +void +virCapabilitiesInitProcessCaps(virCapsPtr caps) +{ + caps->host.processCaps |= (1ULL<< (CAP_LAST_CAP + 1)) - 1; +} + +#else +void +virCapabilitiesInitProcessCaps(virCapsPtr caps) +{ + caps->host.processCaps = 0; +} + +#endif + extern void virCapabilitiesSetMacPrefix(virCapsPtr caps, unsigned char *prefix) Index: libvirt/docs/schemas/capability.rng =================================================================== --- libvirt.orig/docs/schemas/capability.rng +++ libvirt/docs/schemas/capability.rng @@ -46,6 +46,56 @@ <optional> <ref name='secmodel'/> </optional> +<optional> +<ref name='process'/> +</optional> +</element> +</define> + +<define name='process'> +<element name='process'> +<zeroOrMore> +<element name='cap'> +<attribute name='name'> +<choice> +<value>chown</value> +<value>dac_override</value> +<value>dac_read_search</value> +<value>fowner</value> +<value>fsetid</value> +<value>kill</value> +<value>setgid</value> +<value>setuid</value> +<value>setpcap</value> +<value>linux_immutable</value> +<value>net_bind_service</value> +<value>net_broadcast</value> +<value>net_admin</value> +<value>net_raw</value> +<value>ipc_lock</value> +<value>ipc_owner</value> +<value>sys_module</value> +<value>sys_rawio</value> +<value>sys_chroot</value> +<value>sys_ptrace</value> +<value>sys_pacct</value> +<value>sys_admin</value> +<value>sys_boot</value> +<value>sys_nice</value> +<value>sys_resource</value> +<value>sys_time</value> +<value>sys_tty_config</value> +<value>mknod</value> +<value>lease</value> +<value>audit_write</value> +<value>audit_control</value> +<value>setfcap</value> +<value>mac_override</value> +<value>mac_admin</value> +</choice> +</attribute> +</element> +</zeroOrMore> </element> </define>
Index: libvirt/include/libvirt/libvirt.h.in =================================================================== --- libvirt.orig/include/libvirt/libvirt.h.in +++ libvirt/include/libvirt/libvirt.h.in @@ -3540,6 +3540,51 @@ int virConnectSetKeepAlive(virConnectPtr int interval, unsigned int count);
+ +/* + * virProcessCapabilityType + * + * A process capability Type + */ +typedef enum { + VIR_PROCESS_CAPABILITY_CHOWN, + VIR_PROCESS_CAPABILITY_DAC_OVERRIDE, + VIR_PROCESS_CAPABILITY_DAC_READ_SEARCH, + VIR_PROCESS_CAPABILITY_FOWNER, + VIR_PROCESS_CAPABILITY_FSETID, + VIR_PROCESS_CAPABILITY_KILL, + VIR_PROCESS_CAPABILITY_SETGID, + VIR_PROCESS_CAPABILITY_SETUID, + VIR_PROCESS_CAPABILITY_SETPCAP, + VIR_PROCESS_CAPABILITY_LINUX_IMMUTABLE, + VIR_PROCESS_CAPABILITY_NET_BIND_SERVICE, + VIR_PROCESS_CAPABILITY_NET_BROADCAST, + VIR_PROCESS_CAPABILITY_NET_ADMIN, + VIR_PROCESS_CAPABILITY_NET_RAW, + VIR_PROCESS_CAPABILITY_IPC_LOCK, + VIR_PROCESS_CAPABILITY_IPC_OWNER, + VIR_PROCESS_CAPABILITY_SYS_MODULE, + VIR_PROCESS_CAPABILITY_SYS_RAWIO, + VIR_PROCESS_CAPABILITY_SYS_CHROOT, + VIR_PROCESS_CAPABILITY_SYS_PTRACE, + VIR_PROCESS_CAPABILITY_SYS_PACCT, + VIR_PROCESS_CAPABILITY_SYS_ADMIN, + VIR_PROCESS_CAPABILITY_SYS_BOOT, + VIR_PROCESS_CAPABILITY_SYS_NICE, + VIR_PROCESS_CAPABILITY_SYS_RESOURCE, + VIR_PROCESS_CAPABILITY_SYS_TIME, + VIR_PROCESS_CAPABILITY_SYS_TTY_CONFIG, + VIR_PROCESS_CAPABILITY_MKNOD, + VIR_PROCESS_CAPABILITY_LEASE, + VIR_PROCESS_CAPABILITY_AUDIT_WRITE, + VIR_PROCESS_CAPABILITY_AUDIT_CONTROL, + VIR_PROCESS_CAPABILITY_SETFCAP, + VIR_PROCESS_CAPABILITY_MAC_OVERRIDE, + VIR_PROCESS_CAPABILITY_MAC_ADMIN, + + VIR_PROCESS_CAPABILITY_LAST +} virProcessCapabilityType; + #ifdef __cplusplus } #endif
Also we might want to update docs/formatcaps.html.in, though it's not updated for long time. Regards, Osier

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. <process> <cap name='sys_rawio'/> </process> Signed-off-by: Taku Izumi <izumi.taku@jp.fujitsu.com> Signed-off-by: Shota Hirae <m11g1401@hibikino.ne.jp> --- docs/formatdomain.html.in | 48 ++++++++++++++++++++++++++++++++++++++ docs/schemas/domaincommon.rng | 52 ++++++++++++++++++++++++++++++++++++++++++ src/conf/domain_conf.c | 33 ++++++++++++++++++++++++++ src/conf/domain_conf.h | 2 + 4 files changed, 135 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="process"/> + </optional> <ref name="termination"/> <optional> <ref name="devices"/> @@ -2344,6 +2347,55 @@ </optional> </define> <!-- + Specification of process element + --> + <define name="process"> + <element name="process"> + <zeroOrMore> + <element name="cap"> + <attribute name="name"> + <choice> + <value>chown</value> + <value>dac_override</value> + <value>dac_read_search</value> + <value>fowner</value> + <value>fsetid</value> + <value>kill</value> + <value>setgid</value> + <value>setuid</value> + <value>setpcap</value> + <value>linux_immutable</value> + <value>net_bind_service</value> + <value>net_broadcast</value> + <value>net_admin</value> + <value>net_raw</value> + <value>ipc_lock</value> + <value>ipc_owner</value> + <value>sys_module</value> + <value>sys_rawio</value> + <value>sys_chroot</value> + <value>sys_ptrace</value> + <value>sys_pacct</value> + <value>sys_admin</value> + <value>sys_boot</value> + <value>sys_nice</value> + <value>sys_resource</value> + <value>sys_time</value> + <value>sys_tty_config</value> + <value>mknod</value> + <value>lease</value> + <value>audit_write</value> + <value>audit_control</value> + <value>setfcap</value> + <value>mac_override</value> + <value>mac_admin</value> + </choice> + </attribute> + </element> + </zeroOrMore> + </element> + </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 @@ -7253,6 +7253,23 @@ static virDomainDefPtr virDomainDefParse VIR_FREE(nodes); } + n = virXPathNodeSet("./process/cap", ctxt, &nodes); + if (n < 0) + goto error; + if (n) { + for (i = 0; i < n; i++) { + int val = virCapsProcessCapsTypeFromString(virXMLPropString(nodes[i], "name")); + if (val < 0) { + virDomainReportError(VIR_ERR_INTERNAL_ERROR, + _("unexpected process cap %s"), + virXMLPropString(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) @@ -11520,6 +11537,22 @@ virDomainDefFormatInternal(virDomainDefP virBufferAddLit(buf, " </features>\n"); } + if (def->capabilities) { + virBufferAddLit(buf, " <process>\n"); + for (n = 0; n < VIR_PROCESS_CAPABILITY_LAST; n++) { + if (def->capabilities & (1ULL << n)) { + const char *name = virCapsProcessCapsTypeToString(n); + if (!name) { + virDomainReportError(VIR_ERR_INTERNAL_ERROR, + _("unexpected process cap %d"), n); + goto cleanup; + } + virBufferAsprintf(buf, " <cap name='%s'/>\n", name); + } + } + virBufferAddLit(buf, " </process>\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 @@ -1441,6 +1441,8 @@ struct _virDomainDef { char *emulator; int features; + unsigned long long capabilities; + virDomainClockDef clock; int ngraphics; Index: libvirt/docs/formatdomain.html.in =================================================================== --- libvirt.orig/docs/formatdomain.html.in +++ libvirt/docs/formatdomain.html.in @@ -787,6 +787,54 @@ </dd> </dl> + <h3><a name="elementsProcess">Process Capability</a></h3> + + <p> + Process of Domain are allowed to retain capabilities specified + by cap element. What capabilities host supports can be found at + capability XML. + </p> + +<pre> + ... + <process> + <cap name="chown"/> + <cap name="dac_override"/> + <cap name="dac_read_search"/> + <cap name="fowner"/> + <cap name="fsetid"/> + <cap name="kill"/> + <cap name="setgid"/> + <cap name="setuid"/> + <cap name="setpcap"/> + <cap name="linux_immutable"/> + <cap name="net_bind_service"/> + <cap name="net_broadcast"/> + <cap name="net_admin"/> + <cap name="net_raw"/> + <cap name="ipc_lock"/> + <cap name="ipc_owner"/> + <cap name="sys_module"/> + <cap name="sys_rawio"/> + <cap name="sys_chroot"/> + <cap name="sys_ptrace"/> + <cap name="sys_pacct"/> + <cap name="sys_admin"/> + <cap name="sys_boot"/> + <cap name="sys_nice"/> + <cap name="sys_resource"/> + <cap name="sys_time"/> + <cap name="sys_tty_config"/> + <cap name="mknod"/> + <cap name="lease"/> + <cap name="audit_write"/> + <cap name="audit_control"/> + <cap name="setfcap"/> + <cap name="mac_override"/> + <cap name="mac_admin"/> + </process> + ...</pre> + <h3><a name="elementsTime">Time keeping</a></h3> <p>

On 2011年12月22日 15:04, Taku Izumi wrote:
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.
<process> <cap name='sys_rawio'/> </process>
Signed-off-by: Taku Izumi<izumi.taku@jp.fujitsu.com> Signed-off-by: Shota Hirae<m11g1401@hibikino.ne.jp> --- docs/formatdomain.html.in | 48 ++++++++++++++++++++++++++++++++++++++ docs/schemas/domaincommon.rng | 52 ++++++++++++++++++++++++++++++++++++++++++ src/conf/domain_conf.c | 33 ++++++++++++++++++++++++++ src/conf/domain_conf.h | 2 + 4 files changed, 135 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="process"/> +</optional> <ref name="termination"/> <optional> <ref name="devices"/> @@ -2344,6 +2347,55 @@ </optional> </define> <!-- + Specification of process element + --> +<define name="process"> +<element name="process"> +<zeroOrMore> +<element name="cap"> +<attribute name="name"> +<choice> +<value>chown</value> +<value>dac_override</value> +<value>dac_read_search</value> +<value>fowner</value> +<value>fsetid</value> +<value>kill</value> +<value>setgid</value> +<value>setuid</value> +<value>setpcap</value> +<value>linux_immutable</value> +<value>net_bind_service</value> +<value>net_broadcast</value> +<value>net_admin</value> +<value>net_raw</value> +<value>ipc_lock</value> +<value>ipc_owner</value> +<value>sys_module</value> +<value>sys_rawio</value> +<value>sys_chroot</value> +<value>sys_ptrace</value> +<value>sys_pacct</value> +<value>sys_admin</value> +<value>sys_boot</value> +<value>sys_nice</value> +<value>sys_resource</value> +<value>sys_time</value> +<value>sys_tty_config</value> +<value>mknod</value> +<value>lease</value> +<value>audit_write</value> +<value>audit_control</value> +<value>setfcap</value> +<value>mac_override</value> +<value>mac_admin</value> +</choice> +</attribute> +</element> +</zeroOrMore> +</element> +</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 @@ -7253,6 +7253,23 @@ static virDomainDefPtr virDomainDefParse VIR_FREE(nodes); }
+ n = virXPathNodeSet("./process/cap", ctxt,&nodes); + if (n< 0) + goto error; + if (n) { + for (i = 0; i< n; i++) { + int val = virCapsProcessCapsTypeFromString(virXMLPropString(nodes[i], "name")); + if (val< 0) { + virDomainReportError(VIR_ERR_INTERNAL_ERROR,
s/VIR_ERR_INTERNAL_ERROR/VIR_ERR_CONFIG_UNSUPPORTED/
+ _("unexpected process cap %s"), + virXMLPropString(nodes[i], "name"));
virXMLPropString is used twice, it can be avoided by something like: const char *name = virXMLPropString(nodes[i], name); And use name where you want.
+ goto error; + } + def->capabilities |= (1ULL<< val); + } + VIR_FREE(nodes); + } + if (virDomainLifecycleParseXML(ctxt, "string(./on_reboot[1])", &def->onReboot, VIR_DOMAIN_LIFECYCLE_RESTART, virDomainLifecycleTypeFromString)< 0) @@ -11520,6 +11537,22 @@ virDomainDefFormatInternal(virDomainDefP virBufferAddLit(buf, "</features>\n"); }
+ if (def->capabilities) { + virBufferAddLit(buf, "<process>\n"); + for (n = 0; n< VIR_PROCESS_CAPABILITY_LAST; n++) { + if (def->capabilities& (1ULL<< n)) { + const char *name = virCapsProcessCapsTypeToString(n); + if (!name) { + virDomainReportError(VIR_ERR_INTERNAL_ERROR, + _("unexpected process cap %d"), n); + goto cleanup; + } + virBufferAsprintf(buf, "<cap name='%s'/>\n", name); + } + } + virBufferAddLit(buf, "</process>\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 @@ -1441,6 +1441,8 @@ struct _virDomainDef { char *emulator; int features;
+ unsigned long long capabilities;
Should we choose another name such like "process_caps"? Considering we might need to introduce other capabilities for domain in future.
+ virDomainClockDef clock;
int ngraphics; Index: libvirt/docs/formatdomain.html.in =================================================================== --- libvirt.orig/docs/formatdomain.html.in +++ libvirt/docs/formatdomain.html.in @@ -787,6 +787,54 @@ </dd> </dl>
+<h3><a name="elementsProcess">Process Capability</a></h3> + +<p> + Process of Domain are allowed to retain capabilities specified
Is following better? :-) Domain process is allowed to...
+ by cap element. What capabilities host supports can be found at + capability XML.
Better to add the virsh command. e.g. capability XML (virsh capabilities)
+</p> + +<pre> + ... +<process> +<cap name="chown"/> +<cap name="dac_override"/> +<cap name="dac_read_search"/> +<cap name="fowner"/> +<cap name="fsetid"/> +<cap name="kill"/> +<cap name="setgid"/> +<cap name="setuid"/> +<cap name="setpcap"/> +<cap name="linux_immutable"/> +<cap name="net_bind_service"/> +<cap name="net_broadcast"/> +<cap name="net_admin"/> +<cap name="net_raw"/> +<cap name="ipc_lock"/> +<cap name="ipc_owner"/> +<cap name="sys_module"/> +<cap name="sys_rawio"/> +<cap name="sys_chroot"/> +<cap name="sys_ptrace"/> +<cap name="sys_pacct"/> +<cap name="sys_admin"/> +<cap name="sys_boot"/> +<cap name="sys_nice"/> +<cap name="sys_resource"/> +<cap name="sys_time"/> +<cap name="sys_tty_config"/> +<cap name="mknod"/> +<cap name="lease"/> +<cap name="audit_write"/> +<cap name="audit_control"/> +<cap name="setfcap"/> +<cap name="mac_override"/> +<cap name="mac_admin"/> +</process> + ...</pre> + <h3><a name="elementsTime">Time keeping</a></h3>
<p>
-- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list

On 2011年12月30日 12:06, Osier Yang wrote:
On 2011年12月22日 15:04, Taku Izumi wrote:
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.
<process> <cap name='sys_rawio'/> </process>
Signed-off-by: Taku Izumi<izumi.taku@jp.fujitsu.com> Signed-off-by: Shota Hirae<m11g1401@hibikino.ne.jp> --- docs/formatdomain.html.in | 48 ++++++++++++++++++++++++++++++++++++++ docs/schemas/domaincommon.rng | 52 ++++++++++++++++++++++++++++++++++++++++++ src/conf/domain_conf.c | 33 ++++++++++++++++++++++++++ src/conf/domain_conf.h | 2 + 4 files changed, 135 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="process"/> +</optional> <ref name="termination"/> <optional> <ref name="devices"/> @@ -2344,6 +2347,55 @@ </optional> </define> <!-- + Specification of process element + --> +<define name="process"> +<element name="process"> +<zeroOrMore> +<element name="cap"> +<attribute name="name"> +<choice> +<value>chown</value> +<value>dac_override</value> +<value>dac_read_search</value> +<value>fowner</value> +<value>fsetid</value> +<value>kill</value> +<value>setgid</value> +<value>setuid</value> +<value>setpcap</value> +<value>linux_immutable</value> +<value>net_bind_service</value> +<value>net_broadcast</value> +<value>net_admin</value> +<value>net_raw</value> +<value>ipc_lock</value> +<value>ipc_owner</value> +<value>sys_module</value> +<value>sys_rawio</value> +<value>sys_chroot</value> +<value>sys_ptrace</value> +<value>sys_pacct</value> +<value>sys_admin</value> +<value>sys_boot</value> +<value>sys_nice</value> +<value>sys_resource</value> +<value>sys_time</value> +<value>sys_tty_config</value> +<value>mknod</value> +<value>lease</value> +<value>audit_write</value> +<value>audit_control</value> +<value>setfcap</value> +<value>mac_override</value> +<value>mac_admin</value> +</choice> +</attribute> +</element> +</zeroOrMore> +</element> +</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 @@ -7253,6 +7253,23 @@ static virDomainDefPtr virDomainDefParse VIR_FREE(nodes); }
+ n = virXPathNodeSet("./process/cap", ctxt,&nodes); + if (n< 0) + goto error; + if (n) { + for (i = 0; i< n; i++) { + int val = virCapsProcessCapsTypeFromString(virXMLPropString(nodes[i], "name")); + if (val< 0) { + virDomainReportError(VIR_ERR_INTERNAL_ERROR,
s/VIR_ERR_INTERNAL_ERROR/VIR_ERR_CONFIG_UNSUPPORTED/
+ _("unexpected process cap %s"), + virXMLPropString(nodes[i], "name"));
virXMLPropString is used twice, it can be avoided by something like:
const char *name = virXMLPropString(nodes[i], name);
And use name where you want.
+ goto error; + } + def->capabilities |= (1ULL<< val); + } + VIR_FREE(nodes); + } + if (virDomainLifecycleParseXML(ctxt, "string(./on_reboot[1])", &def->onReboot, VIR_DOMAIN_LIFECYCLE_RESTART, virDomainLifecycleTypeFromString)< 0) @@ -11520,6 +11537,22 @@ virDomainDefFormatInternal(virDomainDefP virBufferAddLit(buf, "</features>\n"); }
+ if (def->capabilities) { + virBufferAddLit(buf, "<process>\n"); + for (n = 0; n< VIR_PROCESS_CAPABILITY_LAST; n++) { + if (def->capabilities& (1ULL<< n)) { + const char *name = virCapsProcessCapsTypeToString(n); + if (!name) { + virDomainReportError(VIR_ERR_INTERNAL_ERROR, + _("unexpected process cap %d"), n); + goto cleanup; + } + virBufferAsprintf(buf, "<cap name='%s'/>\n", name); + } + } + virBufferAddLit(buf, "</process>\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 @@ -1441,6 +1441,8 @@ struct _virDomainDef { char *emulator; int features;
+ unsigned long long capabilities;
Should we choose another name such like "process_caps"? Considering we might need to introduce other capabilities for domain in future.
+ virDomainClockDef clock;
int ngraphics; Index: libvirt/docs/formatdomain.html.in =================================================================== --- libvirt.orig/docs/formatdomain.html.in +++ libvirt/docs/formatdomain.html.in @@ -787,6 +787,54 @@ </dd> </dl>
+<h3><a name="elementsProcess">Process Capability</a></h3> + +<p> + Process of Domain are allowed to retain capabilities specified
Is following better? :-)
Domain process is allowed to...
+ by cap element. What capabilities host supports can be found at + capability XML.
Better to add the virsh command. e.g.
capability XML (virsh capabilities)
Also we need to declare the caps are OS dependant.
+</p> + +<pre> + ... +<process> +<cap name="chown"/> +<cap name="dac_override"/> +<cap name="dac_read_search"/> +<cap name="fowner"/> +<cap name="fsetid"/> +<cap name="kill"/> +<cap name="setgid"/> +<cap name="setuid"/> +<cap name="setpcap"/> +<cap name="linux_immutable"/> +<cap name="net_bind_service"/> +<cap name="net_broadcast"/> +<cap name="net_admin"/> +<cap name="net_raw"/> +<cap name="ipc_lock"/> +<cap name="ipc_owner"/> +<cap name="sys_module"/> +<cap name="sys_rawio"/> +<cap name="sys_chroot"/> +<cap name="sys_ptrace"/> +<cap name="sys_pacct"/> +<cap name="sys_admin"/> +<cap name="sys_boot"/> +<cap name="sys_nice"/> +<cap name="sys_resource"/> +<cap name="sys_time"/> +<cap name="sys_tty_config"/> +<cap name="mknod"/> +<cap name="lease"/> +<cap name="audit_write"/> +<cap name="audit_control"/> +<cap name="setfcap"/> +<cap name="mac_override"/> +<cap name="mac_admin"/> +</process> + ...</pre> + <h3><a name="elementsTime">Time keeping</a></h3>
<p>
-- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
-- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list

On 2011年12月22日 15:04, Taku Izumi wrote:
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.
<process> <cap name='sys_rawio'/> </process>
Signed-off-by: Taku Izumi<izumi.taku@jp.fujitsu.com> Signed-off-by: Shota Hirae<m11g1401@hibikino.ne.jp> --- docs/formatdomain.html.in | 48 ++++++++++++++++++++++++++++++++++++++ docs/schemas/domaincommon.rng | 52 ++++++++++++++++++++++++++++++++++++++++++ src/conf/domain_conf.c | 33 ++++++++++++++++++++++++++ src/conf/domain_conf.h | 2 + 4 files changed, 135 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="process"/> +</optional> <ref name="termination"/> <optional> <ref name="devices"/> @@ -2344,6 +2347,55 @@ </optional> </define> <!-- + Specification of process element + --> +<define name="process"> +<element name="process"> +<zeroOrMore> +<element name="cap"> +<attribute name="name"> +<choice> +<value>chown</value> +<value>dac_override</value> +<value>dac_read_search</value> +<value>fowner</value> +<value>fsetid</value> +<value>kill</value> +<value>setgid</value> +<value>setuid</value> +<value>setpcap</value> +<value>linux_immutable</value> +<value>net_bind_service</value> +<value>net_broadcast</value> +<value>net_admin</value> +<value>net_raw</value> +<value>ipc_lock</value> +<value>ipc_owner</value> +<value>sys_module</value> +<value>sys_rawio</value> +<value>sys_chroot</value> +<value>sys_ptrace</value> +<value>sys_pacct</value> +<value>sys_admin</value> +<value>sys_boot</value> +<value>sys_nice</value> +<value>sys_resource</value> +<value>sys_time</value> +<value>sys_tty_config</value> +<value>mknod</value> +<value>lease</value> +<value>audit_write</value> +<value>audit_control</value> +<value>setfcap</value> +<value>mac_override</value> +<value>mac_admin</value> +</choice> +</attribute> +</element> +</zeroOrMore> +</element> +</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 @@ -7253,6 +7253,23 @@ static virDomainDefPtr virDomainDefParse VIR_FREE(nodes); }
+ n = virXPathNodeSet("./process/cap", ctxt,&nodes); + if (n< 0) + goto error; + if (n) { + for (i = 0; i< n; i++) { + int val = virCapsProcessCapsTypeFromString(virXMLPropString(nodes[i], "name")); + if (val< 0) { + virDomainReportError(VIR_ERR_INTERNAL_ERROR, + _("unexpected process cap %s"), + virXMLPropString(nodes[i], "name")); + goto error; + } + def->capabilities |= (1ULL<< val);
I don't see any checking on the caps with the capabilities exposed in the host & driver capabilities XML (virsh capabilities) in the whole patchset, and IMHO here is the right place to do the checking. (perhaps some helper function). As we don't want to pass the the caps actually unsupported by OS simply to the guest process. And get the error there. If we don't that, that means the exposed host process caps is just useless. Regards, Osier

On 2011年12月22日 15:04, Taku Izumi wrote:
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.
<process> <cap name='sys_rawio'/> </process>
Signed-off-by: Taku Izumi<izumi.taku@jp.fujitsu.com> Signed-off-by: Shota Hirae<m11g1401@hibikino.ne.jp> --- docs/formatdomain.html.in | 48 ++++++++++++++++++++++++++++++++++++++ docs/schemas/domaincommon.rng | 52 ++++++++++++++++++++++++++++++++++++++++++ src/conf/domain_conf.c | 33 ++++++++++++++++++++++++++ src/conf/domain_conf.h | 2 + 4 files changed, 135 insertions(+)
And better to add some tests. Regards, Osier

Thank you for reviewing and sorry for my late response.
Is following better? :-)
Domain process is allowed to...
+ by cap element. What capabilities host supports can be found at + capability XML.
Better to add the virsh command. e.g.
capability XML (virsh capabilities)
Also we need to declare the caps are OS dependant.
I don't know proper "cap" name, so it complied with that of libcap-ng.
+</p> + +<pre> + ... +<process> +<cap name="chown"/> +<cap name="dac_override"/> +<cap name="dac_read_search"/>
....
Signed-off-by: Taku Izumi<izumi.taku@jp.fujitsu.com> Signed-off-by: Shota Hirae<m11g1401@hibikino.ne.jp> --- docs/formatdomain.html.in | 48 ++++++++++++++++++++++++++++++++++++++ docs/schemas/domaincommon.rng | 52 ++++++++++++++++++++++++++++++++++++++++++ src/conf/domain_conf.c | 33 ++++++++++++++++++++++++++ src/conf/domain_conf.h | 2 + 4 files changed, 135 insertions(+)
And better to add some tests.
What type of test? domain schema test? -- Best regards, Taku Izumi <izumi.taku@jp.fujitsu.com>

This patch introduces virKeepCapabilities() function and implements virCommandAllowCap() function. Existing virClearCapabilities() is function to clear all capabilities. Instead virKeepCapabilities() is function to keep arbitrary capabilities. Signed-off-by: Taku Izumi <izumi.taku@jp.fujitsu.com> Signed-off-by: Shota Hirae <m11g1401@hibikino.ne.jp> --- src/util/command.c | 45 ++++++++++++++++++++++++++++++++++++++------- src/util/command.h | 4 +--- 2 files changed, 39 insertions(+), 10 deletions(-) Index: libvirt/src/util/command.c =================================================================== --- libvirt.orig/src/util/command.c +++ libvirt/src/util/command.c @@ -102,6 +102,8 @@ struct _virCommand { pid_t pid; char *pidfile; bool reap; + + unsigned long long capabilities; }; #ifndef WIN32 @@ -121,6 +123,33 @@ static int virClearCapabilities(void) return 0; } + +/** + * virKeepCapabilities: + * @capabilities - capability flag to keep. + * In case of 0, this function is identical to + * virKeepCapabilities() + * + */ +static int virKeepCapabilities(unsigned long long capabilities) +{ + int ret, i; + + capng_clear(CAPNG_SELECT_BOTH); + + for (i = 0; i <= CAP_LAST_CAP; i++) { + if (capabilities & (1ULL << i)) + capng_update(CAPNG_ADD, CAPNG_BOUNDING_SET, i); + } + + if (ret = capng_apply(CAPNG_SELECT_BOTH) < 0) { + virCommandError(VIR_ERR_INTERNAL_ERROR, + _("cannot apply process capabilities %d"), ret); + return -1; + } + + return 0; +} # else static int virClearCapabilities(void) { @@ -128,6 +157,11 @@ static int virClearCapabilities(void) // "capabilities"); return 0; } + +static int virKeepCapabilities(unsigned long long capabilities) +{ + return 0; +} # endif @@ -821,26 +855,23 @@ virCommandClearCaps(virCommandPtr cmd) cmd->flags |= VIR_EXEC_CLEAR_CAPS; } -#if 0 /* XXX Enable if we have a need for capability management. */ - /** * virCommandAllowCap: * @cmd: the command to modify - * @capability: what to allow + * @capabilities: what to allow * - * Re-allow a specific capability + * Allow a specific capability */ void virCommandAllowCap(virCommandPtr cmd, - int capability ATTRIBUTE_UNUSED) + unsigned long long capabilities) { if (!cmd || cmd->has_error) return; - /* XXX ? */ + cmd->capabilities = capabilities; } -#endif /* 0 */ /** Index: libvirt/src/util/command.h =================================================================== --- libvirt.orig/src/util/command.h +++ libvirt/src/util/command.h @@ -60,10 +60,8 @@ void virCommandSetPidFile(virCommandPtr void virCommandClearCaps(virCommandPtr cmd); -# if 0 void virCommandAllowCap(virCommandPtr cmd, - int capability); -# endif + unsigned long long capabilities); void virCommandDaemonize(virCommandPtr cmd);

On 2011年12月22日 15:05, Taku Izumi wrote:
This patch introduces virKeepCapabilities() function and implements virCommandAllowCap() function.
Existing virClearCapabilities() is function to clear all capabilities. Instead virKeepCapabilities() is function to keep arbitrary capabilities.
Signed-off-by: Taku Izumi<izumi.taku@jp.fujitsu.com> Signed-off-by: Shota Hirae<m11g1401@hibikino.ne.jp> --- src/util/command.c | 45 ++++++++++++++++++++++++++++++++++++++------- src/util/command.h | 4 +--- 2 files changed, 39 insertions(+), 10 deletions(-)
Index: libvirt/src/util/command.c =================================================================== --- libvirt.orig/src/util/command.c +++ libvirt/src/util/command.c @@ -102,6 +102,8 @@ struct _virCommand { pid_t pid; char *pidfile; bool reap; + + unsigned long long capabilities; };
#ifndef WIN32 @@ -121,6 +123,33 @@ static int virClearCapabilities(void)
return 0; } + +/** + * virKeepCapabilities: + * @capabilities - capability flag to keep. + * In case of 0, this function is identical to + * virKeepCapabilities()
Guess you mean "virClearCapabilities" here.
+ * + */ +static int virKeepCapabilities(unsigned long long capabilities) +{ + int ret, i; + + capng_clear(CAPNG_SELECT_BOTH); + + for (i = 0; i<= CAP_LAST_CAP; i++) { + if (capabilities& (1ULL<< i)) + capng_update(CAPNG_ADD, CAPNG_BOUNDING_SET, i); + } + + if (ret = capng_apply(CAPNG_SELECT_BOTH)< 0) { + virCommandError(VIR_ERR_INTERNAL_ERROR, + _("cannot apply process capabilities %d"), ret); + return -1; + } + + return 0; +} # else static int virClearCapabilities(void) { @@ -128,6 +157,11 @@ static int virClearCapabilities(void) // "capabilities"); return 0; } + +static int virKeepCapabilities(unsigned long long capabilities) +{ + return 0; +} # endif
@@ -821,26 +855,23 @@ virCommandClearCaps(virCommandPtr cmd) cmd->flags |= VIR_EXEC_CLEAR_CAPS; }
-#if 0 /* XXX Enable if we have a need for capability management. */ - /** * virCommandAllowCap: * @cmd: the command to modify - * @capability: what to allow + * @capabilities: what to allow * - * Re-allow a specific capability + * Allow a specific capability
s/a specific/capability/specific capablitites/ ?
*/ void virCommandAllowCap(virCommandPtr cmd, - int capability ATTRIBUTE_UNUSED) + unsigned long long capabilities) { if (!cmd || cmd->has_error) return;
- /* XXX ? */ + cmd->capabilities = capabilities; }
-#endif /* 0 */
/** Index: libvirt/src/util/command.h =================================================================== --- libvirt.orig/src/util/command.h +++ libvirt/src/util/command.h @@ -60,10 +60,8 @@ void virCommandSetPidFile(virCommandPtr
void virCommandClearCaps(virCommandPtr cmd);
-# if 0 void virCommandAllowCap(virCommandPtr cmd, - int capability); -# endif + unsigned long long capabilities);
void virCommandDaemonize(virCommandPtr cmd);
-- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list

This patch extends virExecWithHook() to receive capability information. Signed-off-by: Taku Izumi <izumi.taku@jp.fujitsu.com> Signed-off-by: Shota Hirae <m11g1401@hibikino.ne.jp> --- src/util/command.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) Index: libvirt/src/util/command.c =================================================================== --- libvirt.orig/src/util/command.c +++ libvirt/src/util/command.c @@ -333,6 +333,7 @@ prepareStdFd(int fd, int std) * @hook optional virExecHook function to call prior to exec * @data data to pass to the hook function * @pidfile path to use as pidfile for daemonized process (needs DAEMON flag) + * @capabilities capabilities to keep */ static int virExecWithHook(const char *const*argv, @@ -343,7 +344,8 @@ virExecWithHook(const char *const*argv, unsigned int flags, virExecHook hook, void *data, - char *pidfile) + char *pidfile, + unsigned long long capabilities) { pid_t pid; int null = -1, i, openmax; @@ -572,9 +574,9 @@ virExecWithHook(const char *const*argv, /* The steps above may need todo something privileged, so * we delay clearing capabilities until the last minute */ - if ((flags & VIR_EXEC_CLEAR_CAPS) && - virClearCapabilities() < 0) - goto fork_error; + if (capabilities || (flags & VIR_EXEC_CLEAR_CAPS)) + if (virKeepCapabilities(capabilities) < 0) + goto fork_error; /* Close logging again to ensure no FDs leak to child */ virLogReset(); @@ -661,7 +663,8 @@ virExecWithHook(const char *const*argv A int flags_unused ATTRIBUTE_UNUSED, virExecHook hook ATTRIBUTE_UNUSED, void *data ATTRIBUTE_UNUSED, - char *pidfile ATTRIBUTE_UNUSED) + char *pidfile ATTRIBUTE_UNUSED, + unsigned long long capabilities ATTRIBUTE_UNUSED) { /* XXX: Some day we can implement pieces of virCommand/virExec on * top of _spawn() or CreateProcess(), but we can't implement @@ -2103,7 +2106,8 @@ virCommandRunAsync(virCommandPtr cmd, pi cmd->flags, virCommandHook, cmd, - cmd->pidfile); + cmd->pidfile, + cmd->capabilities); VIR_DEBUG("Command result %d, with PID %d", ret, (int)cmd->pid);

On 2011年12月22日 15:06, Taku Izumi wrote:
This patch extends virExecWithHook() to receive capability information.
Signed-off-by: Taku Izumi<izumi.taku@jp.fujitsu.com> Signed-off-by: Shota Hirae<m11g1401@hibikino.ne.jp> --- src/util/command.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-)
Index: libvirt/src/util/command.c =================================================================== --- libvirt.orig/src/util/command.c +++ libvirt/src/util/command.c @@ -333,6 +333,7 @@ prepareStdFd(int fd, int std) * @hook optional virExecHook function to call prior to exec * @data data to pass to the hook function * @pidfile path to use as pidfile for daemonized process (needs DAEMON flag) + * @capabilities capabilities to keep */ static int virExecWithHook(const char *const*argv, @@ -343,7 +344,8 @@ virExecWithHook(const char *const*argv, unsigned int flags, virExecHook hook, void *data, - char *pidfile) + char *pidfile, + unsigned long long capabilities) { pid_t pid; int null = -1, i, openmax; @@ -572,9 +574,9 @@ virExecWithHook(const char *const*argv,
/* The steps above may need todo something privileged, so * we delay clearing capabilities until the last minute */ - if ((flags& VIR_EXEC_CLEAR_CAPS)&& - virClearCapabilities()< 0) - goto fork_error; + if (capabilities || (flags& VIR_EXEC_CLEAR_CAPS)) + if (virKeepCapabilities(capabilities)< 0) + goto fork_error;
/* Close logging again to ensure no FDs leak to child */ virLogReset(); @@ -661,7 +663,8 @@ virExecWithHook(const char *const*argv A int flags_unused ATTRIBUTE_UNUSED, virExecHook hook ATTRIBUTE_UNUSED, void *data ATTRIBUTE_UNUSED, - char *pidfile ATTRIBUTE_UNUSED) + char *pidfile ATTRIBUTE_UNUSED, + unsigned long long capabilities ATTRIBUTE_UNUSED) { /* XXX: Some day we can implement pieces of virCommand/virExec on * top of _spawn() or CreateProcess(), but we can't implement @@ -2103,7 +2106,8 @@ virCommandRunAsync(virCommandPtr cmd, pi cmd->flags, virCommandHook, cmd, - cmd->pidfile); + cmd->pidfile, + cmd->capabilities);
VIR_DEBUG("Command result %d, with PID %d", ret, (int)cmd->pid);
This patch just looks fine. ACK. Regards, Osier

This patch revises qemuProcessStart() function for qemu processes to retain arbitrary capabilities. Signed-off-by: Taku Izumi <izumi.taku@jp.fujitsu.com> Signed-off-by: Shota Hirae <m11g1401@hibikino.ne.jp> --- src/qemu/qemu_process.c | 1 + 1 file changed, 1 insertion(+) Index: libvirt/src/qemu/qemu_process.c =================================================================== --- libvirt.orig/src/qemu/qemu_process.c +++ libvirt/src/qemu/qemu_process.c @@ -3145,6 +3145,7 @@ int qemuProcessStart(virConnectPtr conn, driver->clearEmulatorCapabilities); if (driver->clearEmulatorCapabilities) virCommandClearCaps(cmd); + virCommandAllowCap(cmd, vm->def->capabilities); virCommandSetPreExecHook(cmd, qemuProcessHook, &hookData);

On 2011年12月22日 15:07, Taku Izumi wrote:
This patch revises qemuProcessStart() function for qemu processes to retain arbitrary capabilities.
Signed-off-by: Taku Izumi<izumi.taku@jp.fujitsu.com> Signed-off-by: Shota Hirae<m11g1401@hibikino.ne.jp> --- src/qemu/qemu_process.c | 1 + 1 file changed, 1 insertion(+)
Index: libvirt/src/qemu/qemu_process.c =================================================================== --- libvirt.orig/src/qemu/qemu_process.c +++ libvirt/src/qemu/qemu_process.c @@ -3145,6 +3145,7 @@ int qemuProcessStart(virConnectPtr conn, driver->clearEmulatorCapabilities); if (driver->clearEmulatorCapabilities) virCommandClearCaps(cmd); + virCommandAllowCap(cmd, vm->def->capabilities);
Looks fine, ACK

On 2011-12-22 14:49, Taku Izumi wrote:
Hi Daniel-san and all,
This patchset adds an option for KVM guests to retain arbitrary capabilities. The first version is here: http://www.redhat.com/archives/libvir-list/2011-December/msg00857.html
According to Daniel-san's comment, I changed my patch like the following:
v1 -> v2 - introduce "process" and "cap" elements in the capability XML - change XML element name of domain XML likewise
; process capabilities host supports are found in the capability XML. # virsh capabilities <capabilities>
<host> <uuid>00000000-0000-0000-0000-00199914f1c5</uuid> ... <process> <cap name='chown'/> <cap name='dac_override'/> <cap name='dac_read_search'/> <cap name='fowner'/> ... </process> </host> ...
; VM can retain cap_sys_rawio capability # virsh edit VM ... </features> <process> <cap name='sys_rawio'/> </process> <clock offset='utc'/> ...
# virsh start VM # cat /proc/<VM's PID>/status ... CapInh: 0000000000000000 CapPrm: fffffffc00020000 CapEff: fffffffc00020000 CapBnd: fffffffc00020000 ...
Does this mean that if the 'sys_rawio' is not set in the "features" list, there will be no "CapInh", "CapPrm"... in the proc status file? I was just wondering it is more like a QEMU/KVM options instead of a libvirt options, it is more reasonable to make QEMU/KVM to guard these options in proc status file instead of libvirt xml file.
*[PATCH v2 1/5] conf: add XML schema for capability XML *[PATCH v2 2/5] conf: add XML schema for domain XML *[PATCH v2 3/5] util: add functions to keep capabilities *[PATCH v2 4/5] util: extend virExecWithHook() *[PATCH v2 5/5] qemu: make qemu processes to retain capabilities
Best regards, Taku Izumi
-- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
-- Shu Ming<shuming@linux.vnet.ibm.com> IBM China Systems and Technology Laboratory

Thank you for your comment. On Wed, 28 Dec 2011 10:44:50 +0800 Shu Ming <shuming@linux.vnet.ibm.com> wrote:
On 2011-12-22 14:49, Taku Izumi wrote:
Hi Daniel-san and all,
This patchset adds an option for KVM guests to retain arbitrary capabilities. The first version is here: http://www.redhat.com/archives/libvir-list/2011-December/msg00857.html
According to Daniel-san's comment, I changed my patch like the following:
v1 -> v2 - introduce "process" and "cap" elements in the capability XML - change XML element name of domain XML likewise
; process capabilities host supports are found in the capability XML. # virsh capabilities <capabilities>
<host> <uuid>00000000-0000-0000-0000-00199914f1c5</uuid> ... <process> <cap name='chown'/> <cap name='dac_override'/> <cap name='dac_read_search'/> <cap name='fowner'/> ... </process> </host> ...
; VM can retain cap_sys_rawio capability # virsh edit VM ... </features> <process> <cap name='sys_rawio'/> </process> <clock offset='utc'/> ...
# virsh start VM # cat /proc/<VM's PID>/status ... CapInh: 0000000000000000 CapPrm: fffffffc00020000 CapEff: fffffffc00020000 CapBnd: fffffffc00020000 ...
Does this mean that if the 'sys_rawio' is not set in the "features" list, there will be no "CapInh", "CapPrm"... in the proc status file?
By default libvirt executes qemu under non-root user, qemu process has no capability. By specifying user and group option in /etc/libvirt/qemu.conf, libvirt executes qemu under specified user account. By specifying user and group option as "root", libvirt executes qemu under root user. However in that case, qemu process has no capability despite running under root user, because libvirt clears all capability by default. This patch adds option for qemu process to retain arbitrary capabilities instead of clearing all capability. This should be libvirt's option. I hope you have a happy new year.
I was just wondering it is more like a QEMU/KVM options instead of a libvirt options, it is more reasonable to make QEMU/KVM to guard these options in proc status file instead of libvirt xml file.
*[PATCH v2 1/5] conf: add XML schema for capability XML *[PATCH v2 2/5] conf: add XML schema for domain XML *[PATCH v2 3/5] util: add functions to keep capabilities *[PATCH v2 4/5] util: extend virExecWithHook() *[PATCH v2 5/5] qemu: make qemu processes to retain capabilities
Best regards, Taku Izumi
-- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
-- Shu Ming<shuming@linux.vnet.ibm.com> IBM China Systems and Technology Laboratory
-- Taku Izumi <izumi.taku@jp.fujitsu.com>
participants (3)
-
Osier Yang
-
Shu Ming
-
Taku Izumi