Re: [libvirt] [PATCH] virBitmapFree: Change the function to a macro
On Tue, Sep 10, 2013 at 01:29:40AM +, Liuji (Jeremy) wrote: -Original Message- From: Daniel P. Berrange [mailto:berra...@redhat.com] Sent: Monday, September 09, 2013 7:26 PM To: Liuji (Jeremy) Cc: libvir-list@redhat.com; Jinbo (Justin); Luohao (brian); Haofeng Subject: Re: [libvirt] [PATCH] virBitmapFree: Change the function to a macro On Mon, Sep 09, 2013 at 01:39:42AM +, Liuji (Jeremy) wrote: -Original Message- From: Daniel P. Berrange [mailto:berra...@redhat.com] Sent: Friday, September 06, 2013 6:37 PM To: Liuji (Jeremy) Cc: libvir-list@redhat.com; Jinbo (Justin); Luohao (brian); Haofeng Subject: Re: [libvirt] [PATCH] virBitmapFree: Change the function to a macro On Fri, Sep 06, 2013 at 10:30:56AM +, Liuji (Jeremy) wrote: The parameter of virBitmapFree function is just a pointer, not a pointer of pointer. The second VIR_FREE on virBitmapFree only assign NULL to the formal parameter. After calling the virBitmapFree function, the actual parameter are still not NULL. There are many code segment don't assign NULL to the formal parameter after calling the virBitmapFree function. This will bring potential risks. A problem scenario: 1) The XML of VM contain the below segment: numatune memory mode='preferred' placement='auto' nodeset='0'/ /numatune 2)virsh create the VM 3)In the virDomainDefParseXML funtion: /* Ignore 'nodeset' if 'placement' is 'auto' finally */ if (placement_mode == VIR_NUMA_TUNE_MEM_PLACEMENT_MODE_AUTO) { virBitmapFree(def-numatune.memory.nodemask); def-numatune.memory.nodemask = NULL; } 4)Then, virsh destroy the VM. In the virDomainDefFree funtion, it also call the virBitmapFree function to free the nodemask: virBitmapFree(def-numatune.memory.nodemask); But after this call, the value of def-numatune.memory.nodemask is still not NULL. This will generate an exception. Have you got an actual crash happening today, or is this just a theoretical problem you're trying to address ? Yes,it's an actual crash problem. I found the problem in the above problem scenario in my first mail. Then can you send a patch which explicitly fixes that problem on its own, without doing this major refactoring, which obscures what is being fixed. I had sent a patch in my first mail. You can find the mail at the following links: https://www.redhat.com/archives/libvir-list/2013-September/msg00337.html No, I want the root cause fixed. This change to the bitmap APIs is just papering over any root cause bug. Daniel -- |: http://berrange.com -o-http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :| -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [libvirt-php] bug in libvirt_domain_change_vcpus()
On Mon, Sep 09, 2013 at 06:51:54PM +0200, Michal Novotny wrote: Hi Olivier, this is not really a bug as it's intended. The libvirt_domain_change_vcpus() is not the same as (yet unimplemented) virDomainSetVcpus() API so it's not bug. I realize that naming could be a little confusing so if you like, feel free to rename libvirt_domain_change_vcpus() to libvirt_domain_xml_change_vcpus() as this API should be used to change number of vCPUS in the domain XML itself and implement libvirt_domain_set_vcpus() calling real virDomainSetVcpus() API function. That function is also buggy in that it will silently turn a transient guest into a persistent guest, which is almost certainly not what a caller would expect Daniel -- |: http://berrange.com -o-http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :| -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH] Ensure root filesystem is recursively mounted readonly
On Tue, Sep 10, 2013 at 09:58:13AM +0800, Gao feng wrote: On 09/09/2013 11:30 PM, Daniel P. Berrange wrote: From: Daniel P. Berrange berra...@redhat.com If the guest is configured with filesystem type='mount' source dir='/'/ target dir='/'/ readonly/ /filesystem Then any submounts under / should also end up readonly. eg if the user has /home on a separate volume, they'd expect /home to be readonly. Users can selectively make sub-mounts read-write again by simply listing them as new mounts without the readonly flag set filesystem type='mount' source dir='/home'/ target dir='/home'/ /filesystem Signed-off-by: Daniel P. Berrange berra...@redhat.com --- src/lxc/lxc_container.c | 75 +++-- 1 file changed, 73 insertions(+), 2 deletions(-) diff --git a/src/lxc/lxc_container.c b/src/lxc/lxc_container.c index 9c04d06..ae672c8 100644 --- a/src/lxc/lxc_container.c +++ b/src/lxc/lxc_container.c @@ -532,7 +532,6 @@ static int lxcContainerGetSubtree(const char *prefix, } while (getmntent_r(procmnt, mntent, mntbuf, sizeof(mntbuf)) != NULL) { -VIR_DEBUG(Got %s, mntent.mnt_dir); if (!STRPREFIX(mntent.mnt_dir, prefix)) continue; @@ -541,7 +540,6 @@ static int lxcContainerGetSubtree(const char *prefix, if (VIR_STRDUP(mounts[nmounts], mntent.mnt_dir) 0) goto cleanup; nmounts++; -VIR_DEBUG(Grabbed %s, mntent.mnt_dir); } if (mounts) @@ -750,6 +748,61 @@ err: } +static int lxcContainerSetReadOnly(virDomainFSDefPtr root) +{ +FILE *procmnt; +struct mntent mntent; +char mntbuf[1024]; +int ret = -1; +char **mounts = NULL; +size_t nmounts = 0; +size_t i; + +VIR_DEBUG(root=%s, root-src); + +if (!(procmnt = setmntent(/proc/mounts, r))) { +virReportSystemError(errno, %s, + _(Failed to read /proc/mounts)); +return -1; +} + +while (getmntent_r(procmnt, mntent, mntbuf, sizeof(mntbuf)) != NULL) { +if (STREQ(mntent.mnt_dir, /) || +STRPREFIX(mntent.mnt_dir, /.oldroot)) +continue; + +if (VIR_REALLOC_N(mounts, nmounts+1) 0) +goto cleanup; +if (VIR_STRDUP(mounts[nmounts], mntent.mnt_dir) 0) +goto cleanup; +nmounts++; +} + +if (mounts) +qsort(mounts, nmounts, sizeof(mounts[0]), + lxcContainerChildMountSort); + +for (i = 0 ; i nmounts ; i++) { +VIR_DEBUG(Bind readonly %s, mounts[i]); +if (mount(mounts[i], mounts[i], NULL, MS_BIND|MS_REC|MS_RDONLY|MS_REMOUNT, NULL) 0) { +virReportSystemError(errno, + _(Failed to make mount %s readonly), + mounts[i]); +goto cleanup; +} +} + +ret = 0; +cleanup: +for (i = 0; i nmounts; i++) +VIR_FREE(mounts[i]); +VIR_FREE(mounts); +endmntent(procmnt); +return ret; + +} + + static int lxcContainerMountBasicFS(bool userns_enabled) { const struct { @@ -1001,6 +1054,8 @@ static int lxcContainerMountFSBind(virDomainFSDefPtr fs, int ret = -1; struct stat st; +VIR_DEBUG(src=%s dst=%s, fs-src, fs-dst); + if (virAsprintf(src, %s%s, srcprefix, fs-src) 0) goto cleanup; @@ -1057,6 +1112,13 @@ static int lxcContainerMountFSBind(virDomainFSDefPtr fs, _(Failed to make directory %s readonly), fs-dst); } +} else { +VIR_DEBUG(Binding %s readwrite, fs-dst); +if (mount(src, fs-dst, NULL, MS_BIND|MS_REMOUNT, NULL) 0) { +virReportSystemError(errno, + _(Failed to make directory %s readwrite), + fs-dst); +} } ret = 0; @@ -1330,6 +1392,8 @@ static int lxcContainerMountFSBlock(virDomainFSDefPtr fs, char *src = NULL; int ret = -1; +VIR_DEBUG(src=%s dst=%s, fs-src, fs-dst); + if (virAsprintf(src, %s%s, srcprefix, fs-src) 0) goto cleanup; @@ -1349,6 +1413,8 @@ static int lxcContainerMountFSTmpfs(virDomainFSDefPtr fs, int ret = -1; char *data = NULL; +VIR_DEBUG(usage=%lld sec=%s, fs-usage, sec_mount_options); + if (virAsprintf(data, size=%lldk%s, fs-usage, sec_mount_options) 0) goto cleanup; @@ -1536,6 +1602,11 @@ static int lxcContainerSetupPivotRoot(virDomainDefPtr vmDef, if (lxcContainerMountBasicFS(vmDef-idmap.nuidmap) 0) goto cleanup; +/*
[libvirt] [PATCH v3]LXC: Helper function for checking permission of dir when userns enabled
From: Chen Hanxiao chenhanx...@cn.fujitsu.com If we enable userns, the process with uid/gid in idmap should have enough permission to access dir we provided for containers. Currently, the debug log is very implicit or misleading sometimes. This patch will help clarify this for us when using debug log or virsh. v2: syntax-check clean v3: reliable method for checking permission of dir Signed-off-by: Chen Hanxiao chenhanx...@cn.fujitsu.com --- src/lxc/lxc_container.c | 88 + 1 file changed, 88 insertions(+) diff --git a/src/lxc/lxc_container.c b/src/lxc/lxc_container.c index 8abaea0..9a05e30 100644 --- a/src/lxc/lxc_container.c +++ b/src/lxc/lxc_container.c @@ -110,6 +110,13 @@ struct __lxc_child_argv { int handshakefd; }; +typedef struct __lxc_userns_DirPermCheck_argv lxc_userns_DirPermCheck_argv_t; +struct __lxc_userns_DirPermCheck_argv { +uid_t uid; +gid_t gid; +virDomainDefPtr vmDef; +}; + static int lxcContainerMountFSBlock(virDomainFSDefPtr fs, const char *srcprefix); @@ -1829,6 +1836,84 @@ lxcNeedNetworkNamespace(virDomainDefPtr def) return false; } +static +int lxcContainerCheckDirPermissionChild(void *argv) +{ +size_t i; +lxc_userns_DirPermCheck_argv_t *args = argv; +uid_t uid = args-uid; +uid_t gid = args-gid; +virDomainDefPtr vmDef = args-vmDef; +char *path; + +if (virSetUIDGID(uid, gid, NULL, 0) 0) { +virReportSystemError(errno, %s, + _(setuid or setgid failed)); +_exit(-1); +} + +for (i = 0; i vmDef-nfss; i++) { +path = vmDef-fss[i]-src; +if (access(path, R_OK) || access(path, W_OK) || virFileIsExecutable(path)) { +VIR_DEBUG(Src dir '%s' does not belong to uid/gid: %d/%d, + vmDef-fss[i]-src, uid, gid); +_exit(-1); +} +} + +_exit(0); +} + +/* + * Helper function for helping check + * whether we have enough privilege + * to operate the source dir when userns enabled + * @vmDef: pointer to vm definition structure + * Returns 0 on success or -1 in case of error + */ +static int +lxcContainerCheckDirPermission(virDomainDefPtr vmDef) +{ +uid_t uid; +gid_t gid; +int cpid = 0; +int status; +char *childStack; +char *stack; +int flags = SIGCHLD; + +uid = vmDef-idmap.uidmap[0].target; +gid = vmDef-idmap.gidmap[0].target; + +lxc_userns_DirPermCheck_argv_t args = { +.uid = uid, +.gid = gid, +.vmDef = vmDef +}; + +if (VIR_ALLOC_N(stack, getpagesize() * 4) 0) +return -1; + +childStack = stack + (getpagesize() * 4); +cpid = clone(lxcContainerCheckDirPermissionChild, childStack, flags, args); +VIR_FREE(stack); +if (cpid 0) { +virReportSystemError(errno, %s, + _(Unable to clone to check permission of directory)); +return -1; +} else if (virProcessWait(cpid, status) 0) { +return -1; +} + +if (WEXITSTATUS(status) != 0) { +virReportSystemError(errno, %s, + _(Check the permission of source dir provided for container)); +return -1; +} + +return 0; +} + /** * lxcContainerStart: * @def: pointer to virtual machine structure @@ -1880,6 +1965,9 @@ int lxcContainerStart(virDomainDefPtr def, if (userns_supported()) { VIR_DEBUG(Enable user namespace); cflags |= CLONE_NEWUSER; +if (lxcContainerCheckDirPermission(def) 0) { +return -1; +} } else { virReportSystemError(VIR_ERR_CONFIG_UNSUPPORTED, %s, _(Kernel doesn't support user namespace)); -- 1.8.2.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH] virBitmapFree: Change the function to a macro
-Original Message- From: Daniel P. Berrange [mailto:berra...@redhat.com] Sent: Tuesday, September 10, 2013 3:57 PM To: Liuji (Jeremy) Cc: libvir-list@redhat.com; Jinbo (Justin); Luohao (brian); Haofeng Subject: Re: [libvirt] [PATCH] virBitmapFree: Change the function to a macro On Tue, Sep 10, 2013 at 01:29:40AM +, Liuji (Jeremy) wrote: -Original Message- From: Daniel P. Berrange [mailto:berra...@redhat.com] Sent: Monday, September 09, 2013 7:26 PM To: Liuji (Jeremy) Cc: libvir-list@redhat.com; Jinbo (Justin); Luohao (brian); Haofeng Subject: Re: [libvirt] [PATCH] virBitmapFree: Change the function to a macro On Mon, Sep 09, 2013 at 01:39:42AM +, Liuji (Jeremy) wrote: -Original Message- From: Daniel P. Berrange [mailto:berra...@redhat.com] Sent: Friday, September 06, 2013 6:37 PM To: Liuji (Jeremy) Cc: libvir-list@redhat.com; Jinbo (Justin); Luohao (brian); Haofeng Subject: Re: [libvirt] [PATCH] virBitmapFree: Change the function to a macro On Fri, Sep 06, 2013 at 10:30:56AM +, Liuji (Jeremy) wrote: The parameter of virBitmapFree function is just a pointer, not a pointer of pointer. The second VIR_FREE on virBitmapFree only assign NULL to the formal parameter. After calling the virBitmapFree function, the actual parameter are still not NULL. There are many code segment don't assign NULL to the formal parameter after calling the virBitmapFree function. This will bring potential risks. A problem scenario: 1) The XML of VM contain the below segment: numatune memory mode='preferred' placement='auto' nodeset='0'/ /numatune 2)virsh create the VM 3)In the virDomainDefParseXML funtion: /* Ignore 'nodeset' if 'placement' is 'auto' finally */ if (placement_mode == VIR_NUMA_TUNE_MEM_PLACEMENT_MODE_AUTO) { virBitmapFree(def-numatune.memory.nodemask); def-numatune.memory.nodemask = NULL; } 4)Then, virsh destroy the VM. In the virDomainDefFree funtion, it also call the virBitmapFree function to free the nodemask: virBitmapFree(def-numatune.memory.nodemask); But after this call, the value of def-numatune.memory.nodemask is still not NULL. This will generate an exception. Have you got an actual crash happening today, or is this just a theoretical problem you're trying to address ? Yes,it's an actual crash problem. I found the problem in the above problem scenario in my first mail. Then can you send a patch which explicitly fixes that problem on its own, without doing this major refactoring, which obscures what is being fixed. I had sent a patch in my first mail. You can find the mail at the following links: https://www.redhat.com/archives/libvir-list/2013-September/msg00337.html No, I want the root cause fixed. This change to the bitmap APIs is just papering over any root cause bug. This is a simple problem about an address is released twice in some scenario. I think that released twice is the root cause. I'm not sure what you mean about root cause. Did you mean that why the address will be released two times? -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH] Update docs about user namespace for LXC
From: Daniel P. Berrange berra...@redhat.com Mention that user namespace can be enabled using the UID/GID mapping schema. Fix typo in link anchor for container args in domain XML docs. Signed-off-by: Daniel P. Berrange berra...@redhat.com --- docs/drvlxc.html.in | 14 +- docs/formatdomain.html.in | 2 +- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/docs/drvlxc.html.in b/docs/drvlxc.html.in index 640968f..1e6aa1d 100644 --- a/docs/drvlxc.html.in +++ b/docs/drvlxc.html.in @@ -40,15 +40,11 @@ primary host OS environment, the libvirt LXC driver requires that certain kernel namespaces are compiled in. Libvirt currently requires the 'mount', 'ipc', 'pid', and 'uts' namespaces to be available. If separate network interfaces are desired, then the 'net' namespace is -required. In the near future, the 'user' namespace will optionally be -supported. -/p - -p -strongNOTE: In the absence of support for the 'user' namespace, -processes inside containers cannot be securely isolated from host -process without the use of a mandatory access control technology -such as SELinux or AppArmor./strong +required. If the guest configuration declares a +a href=formatdomain.html#elementsOSContainerUID or GID mapping/a, +the 'user' namespace will be enabled to apply these. strongA suitably +configured UID/GID mapping is a pre-requisite to making containers +secure, in the absence of sVirt confinement./strong /p h2a name=initDefault container setup/a/h2 diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index f8bfe0b..971b059 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -263,7 +263,7 @@ span class=sinceSince 1.0.4/span/dd /dl -h4a name=eleemntsOSContainerContainer boot/a/h4 +h4a name=elementsOSContainerContainer boot/a/h4 p When booting a domain using container based virtualization, instead -- 1.8.3.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH v2 3/6] qemu: add usb-bot support from disks points of view
usb-bot only supports 16 luns(0~15) and they must be contiguous, (using lun 0 and 2 without 1 doesn't work). In this case qemu doesn't throw an error, we can not find the lun 2 in guests. So Adding a checking function in libvirt to prevent from this case. --- src/conf/domain_conf.c | 59 src/conf/domain_conf.h | 4 src/libvirt_private.syms | 1 + src/qemu/qemu_command.c | 32 ++ 4 files changed, 96 insertions(+) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 7fd9422..7a4969e 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -4302,6 +4302,65 @@ virDomainDiskDefAssignAddress(virDomainXMLOptionPtr xmlopt, return 0; } +bool +virDomainDiskAttachedToUsbbotLunIsContiguous(virDomainDefPtr def) +{ +size_t i; +int controllerModel; +virBitmapPtr units = NULL; +bool is_set = false; +bool ret = false; + +if (!(units = virBitmapNew(SCSI_CONTROLLER_USB_BOT_MODEL_MAX_LUNS))) +goto cleanup; + +for (i = 0; i def-ndisks; i++) { +virDomainDiskDefPtr disk = def-disks[i]; +int unitValue = disk-info.addr.drive.unit; + +if (disk-bus != VIR_DOMAIN_DISK_BUS_SCSI) +continue; + +controllerModel = +virDomainDeviceFindControllerModel(def, disk-info, + VIR_DOMAIN_CONTROLLER_TYPE_SCSI); +if (controllerModel != VIR_DOMAIN_CONTROLLER_MODEL_SCSI_USB_BOT) +continue; + +/* usb-bot only supports 16 luns */ +if (unitValue ~0xf) { +virReportError(VIR_ERR_XML_ERROR, + _(The address unit value of disk '%s' is too big), + disk-src); +goto cleanup; +} + +if (virBitmapGetBit(units, unitValue, is_set) == 0 is_set) { +virReportError(VIR_ERR_XML_ERROR, + _(The address unit value of disk '%s' is already used), + disk-src); +goto cleanup; +} + +if (unitValue 0) { +if (virBitmapGetBit(units, unitValue - 1, is_set) == 0 !is_set) { +virReportError(VIR_ERR_XML_ERROR, %s, + _(The address unit value of disk + attached to usb-bot controller is not contiguous)); +goto cleanup; +} +} + +ignore_value(virBitmapSetBit(units, unitValue)); +} + +ret = true; + +cleanup: +virBitmapFree(units); +return ret; +} + static virSecurityLabelDefPtr virSecurityLabelDefParseXML(xmlXPathContextPtr ctxt, unsigned int flags) diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 11ed18a..cea979f 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -781,6 +781,8 @@ typedef enum { VIR_DOMAIN_CONTROLLER_MODEL_PCI_LAST } virDomainControllerModelPCI; +# define SCSI_CONTROLLER_USB_BOT_MODEL_MAX_LUNS 16 + enum virDomainControllerModelSCSI { VIR_DOMAIN_CONTROLLER_MODEL_SCSI_AUTO, VIR_DOMAIN_CONTROLLER_MODEL_SCSI_BUSLOGIC, @@ -2365,6 +2367,8 @@ void virDomainDiskInsertPreAlloced(virDomainDefPtr def, int virDomainDiskDefAssignAddress(virDomainXMLOptionPtr xmlopt, virDomainDiskDefPtr def); +bool virDomainDiskAttachedToUsbbotLunIsContiguous(virDomainDefPtr def); + virDomainDiskDefPtr virDomainDiskRemove(virDomainDefPtr def, size_t i); virDomainDiskDefPtr diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 35f0f1b..c1f7da5 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -179,6 +179,7 @@ virDomainDeviceFindControllerModel; virDomainDeviceInfoCopy; virDomainDeviceInfoIterate; virDomainDeviceTypeToString; +virDomainDiskAttachedToUsbbotLunIsContiguous; virDomainDiskBusTypeToString; virDomainDiskCacheTypeFromString; virDomainDiskCacheTypeToString; diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index f40c050..1a6accd 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -4316,6 +4316,32 @@ qemuBuildDriveDevStr(virDomainDefPtr def, disk-info.addr.drive.controller, disk-info.addr.drive.bus, disk-info.addr.drive.unit); +} else if (controllerModel == VIR_DOMAIN_CONTROLLER_MODEL_SCSI_USB_BOT) { +if (disk-info.addr.drive.target != 0) { +virReportError(VIR_ERR_CONFIG_UNSUPPORTED, %s, + _(target must be 0 for controller + model 'usb-bot')); +goto error; +} + +if (disk-device != VIR_DOMAIN_DISK_DEVICE_LUN) { +if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_SCSI_CD)) { +if (disk-device == VIR_DOMAIN_DISK_DEVICE_CDROM) +
[libvirt] [PATCH v2 4/6] qemu: refactor out function to build scsi device qemu commandline
--- src/qemu/qemu_command.c | 124 +++- 1 file changed, 48 insertions(+), 76 deletions(-) diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 1a6accd..aa91f57 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -4153,6 +4153,40 @@ error: return NULL; } +static int +qemuBuildSCSIDriveDevStr(int controllerModel, + virDomainDiskDefPtr disk, + virQEMUCapsPtr qemuCaps, + virBufferPtr opt) +{ +if (disk-device != VIR_DOMAIN_DISK_DEVICE_LUN) { +if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_SCSI_CD)) { +if (disk-device == VIR_DOMAIN_DISK_DEVICE_CDROM) +virBufferAddLit(opt, scsi-cd); +else +virBufferAddLit(opt, scsi-hd); +} else { +virBufferAddLit(opt, scsi-disk); +} +} else { +virBufferAddLit(opt, scsi-block); +} + + +if (controllerModel == VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LSILOGIC) +virBufferAsprintf(opt, ,bus=scsi%d.%d,scsi-id=%d, + disk-info.addr.drive.controller, + disk-info.addr.drive.bus, + disk-info.addr.drive.unit); +else +virBufferAsprintf(opt, ,bus=scsi%d.0,channel=%d,scsi-id=%d,lun=%d, + disk-info.addr.drive.controller, + disk-info.addr.drive.bus, + disk-info.addr.drive.target, + disk-info.addr.drive.unit); +return 0; +} + char * qemuBuildDriveDevStr(virDomainDefPtr def, virDomainDiskDefPtr disk, @@ -4291,94 +4325,32 @@ qemuBuildDriveDevStr(virDomainDefPtr def, if ((qemuSetScsiControllerModel(def, qemuCaps, controllerModel)) 0) goto error; -if (controllerModel == VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LSILOGIC) { +if (controllerModel == VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LSILOGIC || +controllerModel == VIR_DOMAIN_CONTROLLER_MODEL_SCSI_USB_BOT) { if (disk-info.addr.drive.target != 0) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, %s, _(target must be 0 for controller model 'lsilogic')); goto error; } - -if (disk-device == VIR_DOMAIN_DISK_DEVICE_LUN) { -virBufferAddLit(opt, scsi-block); -} else { -if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_SCSI_CD)) { -if (disk-device == VIR_DOMAIN_DISK_DEVICE_CDROM) -virBufferAddLit(opt, scsi-cd); -else -virBufferAddLit(opt, scsi-hd); -} else { -virBufferAddLit(opt, scsi-disk); -} -} - -virBufferAsprintf(opt, ,bus=scsi%d.%d,scsi-id=%d, - disk-info.addr.drive.controller, - disk-info.addr.drive.bus, - disk-info.addr.drive.unit); -} else if (controllerModel == VIR_DOMAIN_CONTROLLER_MODEL_SCSI_USB_BOT) { -if (disk-info.addr.drive.target != 0) { +} else if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_SCSI_DISK_CHANNEL)) { +if (disk-info.addr.drive.target 7) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, %s, - _(target must be 0 for controller - model 'usb-bot')); + _(This QEMU doesn't support target + greater than 7)); goto error; } -if (disk-device != VIR_DOMAIN_DISK_DEVICE_LUN) { -if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_SCSI_CD)) { -if (disk-device == VIR_DOMAIN_DISK_DEVICE_CDROM) -virBufferAddLit(opt, scsi-cd); -else -virBufferAddLit(opt, scsi-hd); -} else { -virBufferAddLit(opt, scsi-disk); -} -} else { -virBufferAddLit(opt, scsi-block); -} - -virBufferAsprintf(opt, ,bus=scsi%d.0,channel=%d,scsi-id=%d,lun=%d, - disk-info.addr.drive.controller, - disk-info.addr.drive.bus, - disk-info.addr.drive.target, - disk-info.addr.drive.unit); -} else { -if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_SCSI_DISK_CHANNEL)) { -if (disk-info.addr.drive.target 7) { -virReportError(VIR_ERR_CONFIG_UNSUPPORTED, %s, - _(This QEMU doesn't support target - greater than 7)); -
[libvirt] [PATCH v2 2/6] qemu: add usb-bot model scsi controller
usb-bot is SCSI HBA which support only one SCSI target with ID 0. we can create one or more SCSI devices connected to it with -device as its luns. For usb-bot the limit is 15 luns. The difference from other SCSI controllers is that usb-bot needs usb-bus support. That means usb-bot is required to be attached to a existing USB controller. libvirt xml example: devices ... controller type='usb' index='0' /controller controller type='scsi' index='0' model='usb-bot' address type='usb' bus='0' port='1'/ /controller ... /devices QEMU commandline should be: -device piix3-usb-uhci,id=usb \ -device usb-bot,id=scsi0,bus=usb.0,port=1 --- docs/formatdomain.html.in | 4 ++-- docs/schemas/domaincommon.rng | 1 + src/conf/domain_conf.c| 52 +-- src/conf/domain_conf.h| 1 + src/qemu/qemu_command.c | 16 + src/vmx/vmx.c | 3 ++- 6 files changed, 72 insertions(+), 5 deletions(-) diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index f8bfe0b..07887f2 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -2417,8 +2417,8 @@ control how many devices can be connected through the controller. A scsi controller has an optional attribute codemodel/code, which is one of auto, buslogic, - ibmvscsi, lsilogic, lsisas1068, lsisas1078, virtio-scsi or - vmpvscsi. A usb controller has an optional attribute + ibmvscsi, lsilogic, lsisas1068, lsisas1078, virtio-scsi, + vmpvscsi or usb-bot. A usb controller has an optional attribute codemodel/code, which is one of piix3-uhci, piix4-uhci, ehci, ich9-ehci1, ich9-uhci1, ich9-uhci2, ich9-uhci3, vt82c686b-uhci, pci-ohci or nec-xhci. Additionally, diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index ecd3a42..7ce9888 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -1537,6 +1537,7 @@ valueibmvscsi/value valuevirtio-scsi/value valuelsisas1078/value + valueusb-bot/value /choice /attribute /optional diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index aed2a9d..7fd9422 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -326,7 +326,8 @@ VIR_ENUM_IMPL(virDomainControllerModelSCSI, VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LAS vmpvscsi, ibmvscsi, virtio-scsi, - lsisas1078); + lsisas1078, + usb-bot); VIR_ENUM_IMPL(virDomainControllerModelUSB, VIR_DOMAIN_CONTROLLER_MODEL_USB_LAST, piix3-uhci, @@ -5772,6 +5773,17 @@ virDomainControllerDefParseXML(xmlNodePtr node, goto error; switch (def-type) { +case VIR_DOMAIN_CONTROLLER_TYPE_SCSI: +if (def-model == VIR_DOMAIN_CONTROLLER_MODEL_SCSI_USB_BOT) { +if (def-info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE +def-info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_USB) { +virReportError(VIR_ERR_XML_ERROR, %s, + _(usb-bot mode of scsi controller requires + address of type 'usb')); +goto error; +} +} +break; case VIR_DOMAIN_CONTROLLER_TYPE_VIRTIO_SERIAL: { char *ports = virXMLPropString(node, ports); if (ports) { @@ -5863,7 +5875,8 @@ virDomainControllerDefParseXML(xmlNodePtr node, def-info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW def-info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_S390 def-info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_MMIO -def-info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) { +def-info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI +def-info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_USB) { virReportError(VIR_ERR_INTERNAL_ERROR, %s, _(Controllers must use the 'pci' address type)); goto error; @@ -13803,6 +13816,38 @@ virDomainDefMaybeAddSmartcardController(virDomainDefPtr def) return 0; } +static int +virDomainDefMaybeAddUSBcontroller(virDomainDefPtr def) +{ +size_t i; +int maxController = -1; + +for (i = 0; i def-ncontrollers; i++) { +virDomainControllerDefPtr cont = def-controllers[i]; + +if (cont-type != VIR_DOMAIN_CONTROLLER_TYPE_SCSI) +continue; + +if (cont-model != VIR_DOMAIN_CONTROLLER_MODEL_SCSI_USB_BOT) +continue; + +if ((int)cont-info.addr.usb.bus maxController) +maxController = cont-info.addr.usb.bus; +} + +if (maxController == -1) +return 0; + +for (i = 0; i = maxController; i++) { +if (virDomainDefMaybeAddController(def, + VIR_DOMAIN_CONTROLLER_TYPE_USB, +
[libvirt] [PATCH v2 0/6]qemu: add usb-bot scsi controller support
BZ:https://bugzilla.redhat.com/show_bug.cgi?id=917702 v2: After discussion in BZ, qemu guys hope the usb-bot(+usb-uas) can be supported although the absence of its hot-plug feature. In this patch, libvirt gives an unsupported error in this case. v1: https://www.redhat.com/archives/libvir-list/2013-September/msg00020.html And as the missing of hot-plug feature, the replacement of usb-storage is not a urgent thing. disk attached to usb-storage supports hot-plug/unplug already. Guannan Ren(6) qemu: add usb-bot qemu cap flag qemu: add usb-bot model scsi controller support qemu: add usb-bot support from disks points of view qemu: refactor out function to build scsi device qemu commandline qemu: no hot-plug/unplug support currently for usb-bot tests: add xml2argv test for usb-bot scsi controller docs/formatdomain.html.in | 4 ++-- docs/schemas/domaincommon.rng | 1 + src/conf/domain_conf.c| 115 --- src/conf/domain_conf.h| 5 + src/libvirt_private.syms | 1 + src/qemu/qemu_capabilities.c | 2 ++ src/qemu/qemu_capabilities.h | 1 + src/qemu/qemu_command.c | 124 src/qemu/qemu_hotplug.c | 14 ++ src/vmx/vmx.c | 3 ++- tests/qemuxml2argvdata/qemuxml2argv-disk-scsi-usbbot.args | 11 +++ tests/qemuxml2argvdata/qemuxml2argv-disk-scsi-usbbot.xml | 33 + tests/qemuxml2argvtest.c | 3 +++ 13 files changed, 259 insertions(+), 58 deletions(-) -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH]LXC doc: Add warns if net namespace not enabled
On Mon, Sep 09, 2013 at 04:33:54PM +0800, Chen Hanxiao wrote: ping... -Original Message- From: libvir-list-boun...@redhat.com [mailto:libvir-list-boun...@redhat.com] On Behalf Of Chen Hanxiao Sent: Tuesday, September 03, 2013 10:04 AM To: 'Daniel P. Berrange' Cc: libvir-list@redhat.com Subject: Re: [libvirt] [PATCH]LXC doc: Add warns if net namespace not enabled Hi Any comments? Thanks -Original Message- From: Chen Hanxiao [mailto:chenhanx...@cn.fujitsu.com] Sent: Friday, August 23, 2013 1:18 PM To: libvir-list@redhat.com Cc: chenhanx...@cn.fujitsu.com Subject: [libvirt][PATCH]LXC doc: Add warns if net namespace not enabled From: Chen Hanxiao chenhanx...@cn.fujitsu.com If we don't enable network namespace, we could shutdown host by executing command 'shutdown' inside container. This patch will add some warnings in LXC docs and give some advice to readers. Signed-off-by: Chen Hanxiao chenhanx...@cn.fujitsu.com --- docs/drvlxc.html.in |7 +++ 1 files changed, 7 insertions(+), 0 deletions(-) diff --git a/docs/drvlxc.html.in b/docs/drvlxc.html.in index 640968f..8f3a36a 100644 --- a/docs/drvlxc.html.in +++ b/docs/drvlxc.html.in @@ -50,6 +50,13 @@ processes inside containers cannot be securely isolated from host process without the use of a mandatory access control technology such as SELinux or AppArmor./strong /p +p +strongWARNING: If 'net' namespace inot/i enabled for container, +host OS could be ishutdown/i by executing command like 'reboot' +inside container.br/So make sure 'net' namespace was available and +set the lt;privnet/gt; feature in the XML, or configure virtual NICs. +Then this issue could be circumvented./strong /p h2a name=initDefault container setup/a/h2 Sorry for the delay in responding. While this text looks fine, I think we actually need much more content about security issues in LXC. So I'm going to create an entire section in the docs about this and include your warning. I'll copy on you any patch i post. Daniel -- |: http://berrange.com -o-http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :| -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH v2 5/6] qemu: no hot-plug/unplug support currently for usb-bot
--- src/conf/domain_conf.c | 4 +++- src/qemu/qemu_hotplug.c | 14 ++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 7a4969e..60ca298 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -17118,7 +17118,9 @@ virDomainDeviceIsUSB(virDomainDeviceDefPtr dev) (t == VIR_DOMAIN_DEVICE_HUB dev-data.hub-type == VIR_DOMAIN_HUB_TYPE_USB) || (t == VIR_DOMAIN_DEVICE_REDIRDEV - dev-data.redirdev-bus == VIR_DOMAIN_REDIRDEV_BUS_USB)) + dev-data.redirdev-bus == VIR_DOMAIN_REDIRDEV_BUS_USB) || +(t == VIR_DOMAIN_DEVICE_CONTROLLER + dev-data.controller-model == VIR_DOMAIN_CONTROLLER_MODEL_SCSI_USB_BOT)) return true; return false; diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index 6cdee44..b6e3c4c 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -365,6 +365,13 @@ int qemuDomainAttachPciControllerDevice(virQEMUDriverPtr driver, return -1; } +if (controller-type == VIR_DOMAIN_CONTROLLER_TYPE_SCSI +controller-model == VIR_DOMAIN_CONTROLLER_MODEL_SCSI_USB_BOT) { +virReportError(VIR_ERR_OPERATION_UNSUPPORTED, %s, + _(device usb-bot hotplug unsupported currently)); +goto cleanup; +} + if (virQEMUCapsGet(priv-qemuCaps, QEMU_CAPS_DEVICE)) { if (qemuDomainPCIAddressEnsureAddr(priv-pciaddrs, controller-info) 0) goto cleanup; @@ -3009,6 +3016,13 @@ int qemuDomainDetachPciControllerDevice(virQEMUDriverPtr driver, detach = vm-def-controllers[idx]; +if (detach-type == VIR_DOMAIN_CONTROLLER_TYPE_SCSI +detach-model == VIR_DOMAIN_CONTROLLER_MODEL_SCSI_USB_BOT) { +virReportError(VIR_ERR_OPERATION_UNSUPPORTED, %s, + _(device usb-bot cannot be detached currently)); +goto cleanup; +} + if (!virDomainDeviceAddressIsValid(detach-info, VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI)) { virReportError(VIR_ERR_OPERATION_FAILED, %s, -- 1.8.3.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH v2 6/6] tests: add xml2argv test for usb-bot scsi controller
--- .../qemuxml2argv-disk-scsi-usbbot.args | 11 .../qemuxml2argv-disk-scsi-usbbot.xml | 33 ++ tests/qemuxml2argvtest.c | 3 ++ 3 files changed, 47 insertions(+) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-scsi-usbbot.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-scsi-usbbot.xml diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-scsi-usbbot.args b/tests/qemuxml2argvdata/qemuxml2argv-disk-scsi-usbbot.args new file mode 100644 index 000..572a8b0 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-scsi-usbbot.args @@ -0,0 +1,11 @@ +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 -nographic -nodefconfig -nodefaults \ +-monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c \ +-device usb-bot,id=scsi0 -usb \ +-drive file=/dev/HostVG/QEMUGuest1,if=none,id=drive-scsi0-0-0-0 \ +-device scsi-disk,bus=scsi0.0,channel=0,scsi-id=0,lun=0,\ +drive=drive-scsi0-0-0-0,id=scsi0-0-0-0 \ +-drive file=/tmp/scsidisk.img,if=none,id=drive-scsi0-0-0-1 \ +-device scsi-disk,bus=scsi0.0,channel=0,scsi-id=0,lun=1,\ +drive=drive-scsi0-0-0-1,id=scsi0-0-0-1 \ +-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3 diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-scsi-usbbot.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-scsi-usbbot.xml new file mode 100644 index 000..4be405f --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-scsi-usbbot.xml @@ -0,0 +1,33 @@ +domain type='qemu' + nameQEMUGuest1/name + uuidc7a5fdbd-edaf-9455-926a-d65c16db1809/uuid + memory unit='KiB'219136/memory + currentMemory unit='KiB'219136/currentMemory + vcpu placement='static'1/vcpu + os +type arch='i686' machine='pc'hvm/type +boot dev='hd'/ + /os + clock offset='utc'/ + on_poweroffdestroy/on_poweroff + on_rebootrestart/on_reboot + on_crashdestroy/on_crash + devices +emulator/usr/bin/qemu/emulator +disk type='block' device='disk' + source dev='/dev/HostVG/QEMUGuest1'/ + target dev='sda' bus='scsi'/ + address type='drive' controller='0' bus='0' target='0' unit='0'/ +/disk +disk type='file' device='disk' + source file='/tmp/scsidisk.img'/ + target dev='sdb' bus='scsi'/ + address type='drive' controller='0' bus='0' target='0' unit='1'/ +/disk +controller type='usb' index='0'/ +controller type='ide' index='0'/ +controller type='scsi' index='0' model='usb-bot'/ +controller type='pci' index='0' model='pci-root'/ +memballoon model='virtio'/ + /devices +/domain diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index 15d3095..a904c71 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -552,6 +552,9 @@ mymain(void) DO_TEST(disk-scsi-device, QEMU_CAPS_DRIVE, QEMU_CAPS_DEVICE, QEMU_CAPS_NODEFCONFIG, QEMU_CAPS_SCSI_LSI); +DO_TEST(disk-scsi-usbbot, +QEMU_CAPS_DRIVE, QEMU_CAPS_DEVICE, QEMU_CAPS_NODEFCONFIG, +QEMU_CAPS_DEVICE_USB_BOT); DO_TEST(disk-scsi-device-auto, QEMU_CAPS_DRIVE, QEMU_CAPS_DEVICE, QEMU_CAPS_NODEFCONFIG, QEMU_CAPS_SCSI_LSI); -- 1.8.3.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH v2 1/6] qemu: add usb-bot qemu cap flag
QEMU_CAPS_DEVICE_USB_BOT /* -device usb-bot */ --- src/qemu/qemu_capabilities.c | 2 ++ src/qemu/qemu_capabilities.h | 1 + 2 files changed, 3 insertions(+) diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index d94188a..5cd7d45 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -241,6 +241,7 @@ VIR_ENUM_IMPL(virQEMUCaps, QEMU_CAPS_LAST, usb-storage, /* 155 */ usb-storage.removable, virtio-mmio, + usb-bot, ); struct _virQEMUCaps { @@ -1379,6 +1380,7 @@ struct virQEMUCapsStringFlags virQEMUCapsObjectTypes[] = { { vmware-svga, QEMU_CAPS_DEVICE_VMWARE_SVGA }, { usb-serial, QEMU_CAPS_DEVICE_USB_SERIAL }, { usb-net, QEMU_CAPS_DEVICE_USB_NET }, +{ usb-bot, QEMU_CAPS_DEVICE_USB_BOT }, { virtio-rng-pci, QEMU_CAPS_DEVICE_VIRTIO_RNG }, { virtio-rng-s390, QEMU_CAPS_DEVICE_VIRTIO_RNG }, { virtio-rng-ccw, QEMU_CAPS_DEVICE_VIRTIO_RNG }, diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h index f3c8fa8..1e17f4f 100644 --- a/src/qemu/qemu_capabilities.h +++ b/src/qemu/qemu_capabilities.h @@ -196,6 +196,7 @@ enum virQEMUCapsFlags { QEMU_CAPS_DEVICE_USB_STORAGE = 155, /* -device usb-storage */ QEMU_CAPS_USB_STORAGE_REMOVABLE = 156, /* usb-storage.removable */ QEMU_CAPS_DEVICE_VIRTIO_MMIO = 157, /* -device virtio-mmio */ +QEMU_CAPS_DEVICE_USB_BOT = 158, /* -device usb-bot */ QEMU_CAPS_LAST, /* this must always be the last item */ }; -- 1.8.3.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH] Ensure root filesystem is recursively mounted readonly
On 09/10/2013 04:11 PM, Daniel P. Berrange wrote: Using SELinux, or dropping certain capabilities will prevent that, so this is still useful protection even if unconfined root can get around it. In addition Eric Biederman has a change to allow the mount state to be locked prevent this approach. Ok, thanks for your information. I need to take a look at it. -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH]LXC doc: Add warns if net namespace not enabled
-Original Message- From: Daniel P. Berrange [mailto:berra...@redhat.com] Sent: Tuesday, September 10, 2013 5:20 PM To: Chen Hanxiao Cc: libvir-list@redhat.com Subject: Re: [libvirt] [PATCH]LXC doc: Add warns if net namespace not enabled On Mon, Sep 09, 2013 at 04:33:54PM +0800, Chen Hanxiao wrote: ping... +Then this issue could be circumvented./strong /p h2a name=initDefault container setup/a/h2 Sorry for the delay in responding. While this text looks fine, I think we actually need much more content about security issues in LXC. So I'm going to create an entire section in the docs about this and include your warning. I'll copy on you any patch i post. A section about security in docs is needed for users of LXC. We should give users some instruction or hint when we using LXC. Looking forward to see your docs. Daniel -- -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH 1/4] build: avoid $(srcdir) in *_SOURCES
On 09.09.2013 17:51, Eric Blake wrote: Trying to enable automake's subdir-objects option resulted in the creation of literal directories such as src/$(srcdir)/remote/. I traced this to the fact that we had used a literal $(srcdir) in a location that later fed an automake *_SOURCES variable. This has also been reported as an automake bug: http://debbugs.gnu.org/cgi/bugreport.cgi?bug=13928 but it's better to fix our code than to wait for an automake fix. Some things to remember that affect VPATH builds, and where an in-tree build is blissfully unaware of the issues: if a VPATH build fails to find a file that was used as a prereq of any other target, then the rule for that file will expand $@ to prefer the current build dir (bad because a VPATH build on a fresh checkout will then stick $@ in the current directory instead of the desired srcdir); conversely, if a VPATH build finds the file in srcdir but decides it needs to be rebuilt, then the rule for that file will expand $@ to include the directory where it was found out-of-date (bad for an explicit listing of $(srcdir)/$@ because an incremental VPATH build will then expand srcdir twice). As we want these files to go into srcdir unconditionally, we have to massage or avoid $@ for any recipe that involves one of these files. Therefore, this patch removes all uses of $(srcdir) from any generated file name that later feeds a *_SOURCES variable, and then rewrites all the recipes to generate those files to hard-code their creation into srcdir without the use of $@. * src/Makefile.am (REMOTE_DRIVER_GENERATED): Drop $(srcdir); VPATH builds know how to find the files, and automake subdir-objects fails with it in place. (LXC_MONITOR_PROTOCOL_GENERATED, (LXC_MONITOR_GENERATED) (ACCESS_DRIVER_GENERATED, LOCK_PROTOCOL_GENERATED): Likewise. (*_client_bodies.h): Hard-code rules to write into srcdir, as VPATH tries to build $@ locally if missing. (util/virkeymaps.h): Likewise. (lxc/lxc_monitor_dispatch.h): Likewise. (access/viraccessapi*): Likewise. (locking/lock_daemon_dispatch_stubs.h): Likewise. * daemon/Makeflie.am (DAEMON_GENERATED, remote_dispatch.h): Likewise. Signed-off-by: Eric Blake ebl...@redhat.com fixup DAEMON_GENERATED --- daemon/Makefile.am | 23 ++- src/Makefile.am| 109 ++--- 2 files changed, 74 insertions(+), 58 deletions(-) diff --git a/daemon/Makefile.am b/daemon/Makefile.am index 90689f8..e0b8744 100644 --- a/daemon/Makefile.am +++ b/daemon/Makefile.am @@ -29,10 +29,10 @@ INCLUDES = \ CLEANFILES = -DAEMON_GENERATED = \ - $(srcdir)/remote_dispatch.h \ - $(srcdir)/lxc_dispatch.h\ - $(srcdir)/qemu_dispatch.h \ +DAEMON_GENERATED = \ + remote_dispatch.h \ + lxc_dispatch.h \ + qemu_dispatch.h \ $(NULL) DAEMON_SOURCES = \ @@ -75,20 +75,23 @@ REMOTE_PROTOCOL = $(top_srcdir)/src/remote/remote_protocol.x LXC_PROTOCOL = $(top_srcdir)/src/remote/lxc_protocol.x QEMU_PROTOCOL = $(top_srcdir)/src/remote/qemu_protocol.x -$(srcdir)/remote_dispatch.h: $(srcdir)/../src/rpc/gendispatch.pl \ +remote_dispatch.h: $(srcdir)/../src/rpc/gendispatch.pl \ $(REMOTE_PROTOCOL) $(AM_V_GEN)$(PERL) -w $(srcdir)/../src/rpc/gendispatch.pl \ - --mode=server remote REMOTE $(REMOTE_PROTOCOL) $@ + --mode=server remote REMOTE $(REMOTE_PROTOCOL) \ +$(srcdir)/remote_dispatch.h The other option is to have this line as: $(srcdir)/$@ But this version is okay as is. ACK. Michal -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH 0/4] build: use subdir-objects
On 09.09.2013 17:51, Eric Blake wrote: Automake 1.14 is annoyingly loud about warning that the future automake 2.0 will turn on subdir-objects by default. Since automake 1.9 also supports subdir-objects, the best course of action is to enable the feature. But we have to fix some problems before doing so. Also, I noticed some issues with .x files while searching for places that needed fixing. Eric Blake (4): build: avoid $(srcdir) in *_SOURCES build: use library rather than cross-directory compilation tests: check remaining .x files build: use automake subdir-objects .gitignore | 1 + cfg.mk | 3 +- configure.ac | 2 +- daemon/Makefile.am | 55 +++- src/Makefile.am | 139 +++ src/lock_protocol-structs| 55 src/lxc_monitor_protocol-structs | 16 + tests/Makefile.am| 4 +- 8 files changed, 198 insertions(+), 77 deletions(-) create mode 100644 src/lock_protocol-structs create mode 100644 src/lxc_monitor_protocol-structs ACK series. Michal -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 05/14] conf: Factor out setting of metadata to simplify code
The code to set the metadata in a domain definition is common to live and inactive domains. Factor it out into a common func. --- src/conf/domain_conf.c | 113 +++-- 1 file changed, 53 insertions(+), 60 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index e157d49..aa07056 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -18583,87 +18583,80 @@ cleanup: return ret; } + +static int +virDomainDefSetMetadata(virDomainDefPtr def, +int type, +const char *metadata, +const char *key ATTRIBUTE_UNUSED, +const char *uri ATTRIBUTE_UNUSED) +{ +int ret = -1; + +switch ((virDomainMetadataType) type) { +case VIR_DOMAIN_METADATA_DESCRIPTION: +VIR_FREE(def-description); +if (VIR_STRDUP(def-description, metadata) 0) +goto cleanup; +break; + +case VIR_DOMAIN_METADATA_TITLE: +VIR_FREE(def-title); +if (VIR_STRDUP(def-title, metadata) 0) +goto cleanup; +break; + +case VIR_DOMAIN_METADATA_ELEMENT: +virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, %s, + _(metadata element is not supported)); +goto cleanup; +break; + +default: +virReportError(VIR_ERR_INVALID_ARG, %s, + _(unknown metadata type)); +goto cleanup; +break; +} + +ret = 0; + +cleanup: +return ret; +} + + int virDomainObjSetMetadata(virDomainObjPtr vm, int type, const char *metadata, -const char *key ATTRIBUTE_UNUSED, -const char *uri ATTRIBUTE_UNUSED, +const char *key, +const char *uri, virCapsPtr caps, virDomainXMLOptionPtr xmlopt, const char *configDir, unsigned int flags) { virDomainDefPtr persistentDef; -int ret = -1; virCheckFlags(VIR_DOMAIN_AFFECT_LIVE | VIR_DOMAIN_AFFECT_CONFIG, -1); if (virDomainLiveConfigHelperMethod(caps, xmlopt, vm, flags, persistentDef) 0) -goto cleanup; - -if (flags VIR_DOMAIN_AFFECT_LIVE) { -switch ((virDomainMetadataType) type) { -case VIR_DOMAIN_METADATA_DESCRIPTION: -VIR_FREE(vm-def-description); -if (VIR_STRDUP(vm-def-description, metadata) 0) -goto cleanup; -break; - -case VIR_DOMAIN_METADATA_TITLE: -VIR_FREE(vm-def-title); -if (VIR_STRDUP(vm-def-title, metadata) 0) -goto cleanup; -break; - -case VIR_DOMAIN_METADATA_ELEMENT: -virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, %s, - _(metadata element is not supported)); -goto cleanup; -break; +return -1; -default: -virReportError(VIR_ERR_INVALID_ARG, %s, - _(unknown metadata type)); -goto cleanup; -break; -} -} +if (flags VIR_DOMAIN_AFFECT_LIVE) +if (virDomainDefSetMetadata(vm-def, type, metadata, key, uri) 0) +return -1; if (flags VIR_DOMAIN_AFFECT_CONFIG) { -switch ((virDomainMetadataType) type) { -case VIR_DOMAIN_METADATA_DESCRIPTION: -VIR_FREE(persistentDef-description); -if (VIR_STRDUP(persistentDef-description, metadata) 0) -goto cleanup; -break; - -case VIR_DOMAIN_METADATA_TITLE: -VIR_FREE(persistentDef-title); -if (VIR_STRDUP(persistentDef-title, metadata) 0) -goto cleanup; -break; - -case VIR_DOMAIN_METADATA_ELEMENT: -virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, %s, - _(metadata element is not supported)); -goto cleanup; - - default: -virReportError(VIR_ERR_INVALID_ARG, %s, - _(unknown metadata type)); -goto cleanup; -break; -} +if (virDomainDefSetMetadata(persistentDef, type, metadata, key, uri) 0) +return -1; if (virDomainSaveConfig(configDir, persistentDef) 0) -goto cleanup; +return -1; } -ret = 0; - -cleanup: -return ret; +return 0; } -- 1.8.3.2 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 10/14] conf: allow to add XML metadata using the virDomainSetMetadata api
The functionality wasn't originally implemented. This patch adds the ability to modify domain's XML metadata using the API. --- src/conf/domain_conf.c | 47 ++- src/util/virxml.c | 32 src/util/virxml.h | 4 3 files changed, 78 insertions(+), 5 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 4269690..69a8748 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -18589,9 +18589,12 @@ static int virDomainDefSetMetadata(virDomainDefPtr def, int type, const char *metadata, -const char *key ATTRIBUTE_UNUSED, -const char *uri ATTRIBUTE_UNUSED) +const char *key, +const char *uri) { +xmlDocPtr doc = NULL; +xmlNodePtr old; +xmlNodePtr new; int ret = -1; switch ((virDomainMetadataType) type) { @@ -18608,9 +18611,42 @@ virDomainDefSetMetadata(virDomainDefPtr def, break; case VIR_DOMAIN_METADATA_ELEMENT: -virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, %s, - _(metadata element is not supported)); -goto cleanup; +if (metadata) { +/* parse and modify the xml from the user */ +if (!(doc = virXMLParseString(metadata, _((metadata_xml) +goto cleanup; + +if (virXMLInjectNamespace(doc-children, uri, key) 0) +goto cleanup; + +/* create the root node if needed */ +if (!def-metadata +!(def-metadata = xmlNewNode(NULL, (unsigned char *)metadata))) { +virReportOOMError(); +goto cleanup; +} + +if (!(new = xmlCopyNode(doc-children, 1))) { +virReportOOMError(); +goto cleanup; +} +} + +/* remove possible other nodes sharing the namespace */ +while ((old = virXMLFindChildNodeByNs(def-metadata, uri))) { +xmlUnlinkNode(old); +xmlFreeNode(old); +} + +/* just delete the metadata */ +if (!metadata) +break; + +if (!(xmlAddChild(def-metadata, new))) { +xmlFreeNode(new); +virReportOOMError(); +goto cleanup; +} break; default: @@ -18623,6 +18659,7 @@ virDomainDefSetMetadata(virDomainDefPtr def, ret = 0; cleanup: +xmlFreeDoc(doc); return ret; } diff --git a/src/util/virxml.c b/src/util/virxml.c index 0fac931..59e04f5 100644 --- a/src/util/virxml.c +++ b/src/util/virxml.c @@ -1050,3 +1050,35 @@ cleanup: xmlFreeNode(nodeCopy); return ret; } + + +static int +virXMLAddElementNamespace(xmlNodePtr node, + void *opaque) +{ +xmlNsPtr ns = opaque; + +if (!node-ns) +xmlSetNs(node, ns); + +return 0; +} + + +int +virXMLInjectNamespace(xmlNodePtr node, + const char *uri, + const char *key) +{ +xmlNsPtr ns; + +if (!(ns = xmlNewNs(node, (const unsigned char *)uri, (const unsigned char *)key))) { +virReportError(VIR_ERR_INTERNAL_ERROR, %s, + _(failed to create a new XML namespace)); +return -1; +} + +virXMLForeachNode(node, virXMLAddElementNamespace, ns); + +return 0; +} diff --git a/src/util/virxml.h b/src/util/virxml.h index aab29fb..ff0265b 100644 --- a/src/util/virxml.h +++ b/src/util/virxml.h @@ -172,4 +172,8 @@ int virXMLExtractNamespaceXML(xmlNodePtr root, const char *uri, char **doc); +int virXMLInjectNamespace(xmlNodePtr node, + const char *uri, + const char *key); + #endif /* __VIR_XML_H__ */ -- 1.8.3.2 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 08/14] virsh-domain: Add command to allow modifications of XML metadata
The metadata modification functions will support modification of the XML metadata. Add a virsh command to allow using this approach. --- tools/virsh-domain.c | 161 +++ 1 file changed, 161 insertions(+) diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c index 0d00440..c880394 100644 --- a/tools/virsh-domain.c +++ b/tools/virsh-domain.c @@ -6810,6 +6810,161 @@ cleanup: return ret; } + +static const vshCmdInfo info_metadata[] = { +{.name = help, + .data = N_(show or set domain's custom XML metadata) +}, +{.name = desc, + .data = N_(Allows to show or modify the XML metadata of a domain.) +}, +{.name = NULL} +}; + +static const vshCmdOptDef opts_metadata[] = { +{.name = domain, + .type = VSH_OT_DATA, + .flags = VSH_OFLAG_REQ, + .help = N_(domain name, id or uuid) +}, +{.name = live, + .type = VSH_OT_BOOL, + .help = N_(modify/get running state) +}, +{.name = config, + .type = VSH_OT_BOOL, + .help = N_(modify/get persistent configuration) +}, +{.name = current, + .type = VSH_OT_BOOL, + .help = N_(modify/get current state configuration) +}, +{.name = edit, + .type = VSH_OT_BOOL, + .help = N_(use an editor to change the metadata) +}, +{.name = uri, + .type = VSH_OT_DATA, + .flags = VSH_OFLAG_REQ, + .help = N_(URI of the namespace) +}, +{.name = key, + .type = VSH_OT_DATA, + .help = N_(key to be used as a namespace identificatior), +}, +{.name = set, + .type = VSH_OT_DATA, + .help = N_(new metadata to set), +}, +{.name = remove, + .type = VSH_OT_BOOL, + .help = N_(remove the metadata corresponding to an uri) +}, +{.name = NULL} +}; + + +/* helper to add new metadata using the --edit option */ +static char * +vshDomainGetEditMetadata(vshControl *ctl, + virDomainPtr dom, + const char *uri, + unsigned int flags) +{ +char *ret; + +if (!(ret = virDomainGetMetadata(dom, VIR_DOMAIN_METADATA_ELEMENT, + uri, flags))) { +vshResetLibvirtError(); +ret = vshStrdup(ctl, \n); +} + +return ret; +} + + +static bool +cmdMetadata(vshControl *ctl, const vshCmd *cmd) +{ +virDomainPtr dom; +bool config = vshCommandOptBool(cmd, config); +bool live = vshCommandOptBool(cmd, live); +bool current = vshCommandOptBool(cmd, current); +bool edit = vshCommandOptBool(cmd, edit); +bool remove = vshCommandOptBool(cmd, remove); +const char *set = NULL; +const char *uri = NULL; +const char *key = NULL; +unsigned int flags = VIR_DOMAIN_AFFECT_CURRENT; +bool ret = false; + +VSH_EXCLUSIVE_OPTIONS_VAR(current, live); +VSH_EXCLUSIVE_OPTIONS_VAR(current, config); +VSH_EXCLUSIVE_OPTIONS(edit, set); +VSH_EXCLUSIVE_OPTIONS(remove, set); +VSH_EXCLUSIVE_OPTIONS(remove, edit); + +if (config) +flags |= VIR_DOMAIN_AFFECT_CONFIG; +if (live) +flags |= VIR_DOMAIN_AFFECT_LIVE; + +if (!(dom = vshCommandOptDomain(ctl, cmd, NULL))) +return false; + +if (vshCommandOptStringReq(ctl, cmd, uri, uri) 0 || +vshCommandOptStringReq(ctl, cmd, key, key) 0 || +vshCommandOptStringReq(ctl, cmd, set, set) 0) +goto cleanup; + +if ((set || edit) !key) { +vshError(ctl, %s, + _(namespace key is required when modifying metadata)); +goto cleanup; +} + +if (set || remove) { +if (virDomainSetMetadata(dom, VIR_DOMAIN_METADATA_ELEMENT, + set, key, uri, flags)) +goto cleanup; + +if (remove) +vshPrint(%s\n, _(Metadata removed)); +else +vshPrint(%s\n, _(Metadata modified)); +} else if (edit) { +#define EDIT_GET_XML \ +vshDomainGetEditMetadata(ctl, dom, uri, flags) +#define EDIT_NOT_CHANGED\ +vshPrint(ctl, %s, _(Metadata not changed)); \ +ret = true; \ +goto edit_cleanup; +#define EDIT_DEFINE \ +(virDomainSetMetadata(dom, VIR_DOMAIN_METADATA_ELEMENT, doc_edited, \ + key, uri, flags) == 0) +#define EDIT_FREE /* nothing */ +#include virsh-edit.c + +vshPrint(%s\n, _(Metadata modified)); +} else { +char *data; +/* get */ +if (!(data = virDomainGetMetadata(dom, VIR_DOMAIN_METADATA_ELEMENT, + uri, flags))) +goto cleanup; + +vshPrint(ctl, %s\n, data); +VIR_FREE(data); +} + +ret = true; + +cleanup: +virDomainFree(dom); +return ret; +} + + /* * inject-nmi command */ @@ -10595,6 +10750,12 @@ const vshCmdDef domManagementCmds[] = {
[libvirt] [PATCH 06/14] util: Add helper to convert libxml2 nodes to a string
--- src/libvirt_private.syms | 1 + src/util/virxml.c| 33 + src/util/virxml.h| 2 ++ 3 files changed, 36 insertions(+) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 0631941..18e9a4b 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -2091,6 +2091,7 @@ virUUIDParse; # util/virxml.h virXMLChildElementCount; +virXMLNodeDump; virXMLParseHelper; virXMLPickShellSafeComment; virXMLPropString; diff --git a/src/util/virxml.c b/src/util/virxml.c index f652ee0..44d6f27 100644 --- a/src/util/virxml.c +++ b/src/util/virxml.c @@ -895,3 +895,36 @@ virXMLChildElementCount(xmlNodePtr node) } return ret; } + + +/** + * virXMLNodeDump: convert a XML node ptr to a XML string + * + * Returns the XML string of the document or NULL on error. + * The caller has to free the string. + */ +char * +virXMLNodeDump(xmlDocPtr doc, + xmlNodePtr node) +{ + xmlBufferPtr xmlbuf = NULL; + char *ret = NULL; + + if (!(xmlbuf = xmlBufferCreate())) { + virReportOOMError(); + return NULL; + } + + if (xmlNodeDump(xmlbuf, doc, node, 0, 1) == 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, %s, +_(failed to dump XML node tree)); + goto cleanup; + } + + ignore_value(VIR_STRDUP(ret, (const char *)xmlBufferContent(xmlbuf))); + +cleanup: + xmlBufferFree(xmlbuf); + + return ret; +} diff --git a/src/util/virxml.h b/src/util/virxml.h index 364288d..9165cb1 100644 --- a/src/util/virxml.h +++ b/src/util/virxml.h @@ -163,4 +163,6 @@ int virXMLSaveFile(const char *path, const char *warnCommand, const char *xml); +char *virXMLNodeDump(xmlDocPtr doc, xmlNodePtr node); + #endif /* __VIR_XML_H__ */ -- 1.8.3.2 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 04/14] qemu: Factor out body of qemuDomainSetMetadata for universal use
The function impelemnted common behavior that can be reused for other hypervisor drivers that use the virDomainObj data structures. Factor out the core into a separate helper func. --- src/conf/domain_conf.c | 85 src/conf/domain_conf.h | 10 ++ src/libvirt_private.syms | 1 + src/qemu/qemu_driver.c | 73 - 4 files changed, 103 insertions(+), 66 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index d9ed985..e157d49 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -18582,3 +18582,88 @@ virDomainObjGetMetadata(virDomainObjPtr vm, cleanup: return ret; } + +int +virDomainObjSetMetadata(virDomainObjPtr vm, +int type, +const char *metadata, +const char *key ATTRIBUTE_UNUSED, +const char *uri ATTRIBUTE_UNUSED, +virCapsPtr caps, +virDomainXMLOptionPtr xmlopt, +const char *configDir, +unsigned int flags) +{ +virDomainDefPtr persistentDef; +int ret = -1; + +virCheckFlags(VIR_DOMAIN_AFFECT_LIVE | + VIR_DOMAIN_AFFECT_CONFIG, -1); + +if (virDomainLiveConfigHelperMethod(caps, xmlopt, vm, flags, +persistentDef) 0) +goto cleanup; + +if (flags VIR_DOMAIN_AFFECT_LIVE) { +switch ((virDomainMetadataType) type) { +case VIR_DOMAIN_METADATA_DESCRIPTION: +VIR_FREE(vm-def-description); +if (VIR_STRDUP(vm-def-description, metadata) 0) +goto cleanup; +break; + +case VIR_DOMAIN_METADATA_TITLE: +VIR_FREE(vm-def-title); +if (VIR_STRDUP(vm-def-title, metadata) 0) +goto cleanup; +break; + +case VIR_DOMAIN_METADATA_ELEMENT: +virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, %s, + _(metadata element is not supported)); +goto cleanup; +break; + +default: +virReportError(VIR_ERR_INVALID_ARG, %s, + _(unknown metadata type)); +goto cleanup; +break; +} +} + +if (flags VIR_DOMAIN_AFFECT_CONFIG) { +switch ((virDomainMetadataType) type) { +case VIR_DOMAIN_METADATA_DESCRIPTION: +VIR_FREE(persistentDef-description); +if (VIR_STRDUP(persistentDef-description, metadata) 0) +goto cleanup; +break; + +case VIR_DOMAIN_METADATA_TITLE: +VIR_FREE(persistentDef-title); +if (VIR_STRDUP(persistentDef-title, metadata) 0) +goto cleanup; +break; + +case VIR_DOMAIN_METADATA_ELEMENT: +virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, %s, + _(metadata element is not supported)); +goto cleanup; + + default: +virReportError(VIR_ERR_INVALID_ARG, %s, + _(unknown metadata type)); +goto cleanup; +break; +} + +if (virDomainSaveConfig(configDir, persistentDef) 0) +goto cleanup; +} + +ret = 0; + +cleanup: +return ret; +} diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 173d302..e4dfee9 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -2745,4 +2745,14 @@ char *virDomainObjGetMetadata(virDomainObjPtr vm, virDomainXMLOptionPtr xmlopt, unsigned int flags); +int virDomainObjSetMetadata(virDomainObjPtr vm, +int type, +const char *metadata, +const char *key, +const char *uri, +virCapsPtr caps, +virDomainXMLOptionPtr xmlopt, +const char *configDir, +unsigned int flags); + #endif /* __DOMAIN_CONF_H */ diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 2516b9c..0631941 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -327,6 +327,7 @@ virDomainObjListRemove; virDomainObjListRemoveLocked; virDomainObjNew; virDomainObjSetDefTransient; +virDomainObjSetMetadata; virDomainObjSetState; virDomainObjTaint; virDomainPausedReasonTypeFromString; diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 9d5e825..2468310 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -15048,22 +15048,21 @@ static int qemuDomainSetMetadata(virDomainPtr dom, int type, const char *metadata, - const char *key ATTRIBUTE_UNUSED, - const char *uri
[libvirt] [PATCH 01/14] virsh-domain: Remove spurious ATTRIBUTE_UNUSED from cmdDesc
The cmd variable is actually used so remove the attribute. --- tools/virsh-domain.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c index 74feca1..f6bfad0 100644 --- a/tools/virsh-domain.c +++ b/tools/virsh-domain.c @@ -6707,7 +6707,7 @@ static const vshCmdOptDef opts_desc[] = { }; static bool -cmdDesc(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED) +cmdDesc(vshControl *ctl, const vshCmd *cmd) { virDomainPtr dom; bool config = vshCommandOptBool(cmd, config); -- 1.8.3.2 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 07/14] virsh-domain: use virXMLNodeDump instead of xmlNodeDump
--- tools/virsh-domain.c | 117 ++- 1 file changed, 31 insertions(+), 86 deletions(-) diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c index 727a42a..0d00440 100644 --- a/tools/virsh-domain.c +++ b/tools/virsh-domain.c @@ -2359,7 +2359,7 @@ cmdDomIfSetLink(vshControl *ctl, const vshCmd *cmd) xmlXPathContextPtr ctxt = NULL; xmlXPathObjectPtr obj = NULL; xmlNodePtr cur = NULL; -xmlBufferPtr xml_buf = NULL; +char *xml_buf = NULL; if (!(dom = vshCommandOptDomain(ctl, cmd, NULL))) return false; @@ -2464,18 +2464,13 @@ hit: goto cleanup; } -xml_buf = xmlBufferCreate(); -if (!xml_buf) { -vshError(ctl, _(Failed to allocate memory)); -goto cleanup; -} - -if (xmlNodeDump(xml_buf, xml, obj-nodesetval-nodeTab[i], 0, 0) 0) { +if (!(xml_buf = virXMLNodeDump(xml, obj-nodesetval-nodeTab[i]))) { +vshSaveLibvirtError(); vshError(ctl, _(Failed to create XML)); goto cleanup; } -if (virDomainUpdateDeviceFlags(dom, (char *)xmlBufferContent(xml_buf), flags) 0) { +if (virDomainUpdateDeviceFlags(dom, xml_buf, flags) 0) { vshError(ctl, _(Failed to update interface link state)); goto cleanup; } else { @@ -2487,10 +2482,8 @@ cleanup: xmlXPathFreeObject(obj); xmlXPathFreeContext(ctxt); xmlFreeDoc(xml); -xmlBufferFree(xml_buf); - -if (dom) -virDomainFree(dom); +VIR_FREE(xml_buf); +virDomainFree(dom); return ret; } @@ -6080,11 +6073,10 @@ cmdCPUCompare(vshControl *ctl, const vshCmd *cmd) bool ret = false; char *buffer; int result; -const char *snippet; +char *snippet = NULL; xmlDocPtr xml = NULL; xmlXPathContextPtr ctxt = NULL; -xmlBufferPtr xml_buf = NULL; xmlNodePtr node; if (vshCommandOptStringReq(ctl, cmd, file, from) 0) @@ -6100,17 +6092,10 @@ cmdCPUCompare(vshControl *ctl, const vshCmd *cmd) if ((node = virXPathNode(/cpu| /domain/cpu| /capabilities/host/cpu, ctxt))) { -if (!(xml_buf = xmlBufferCreate())) { -vshError(ctl, _(Can't create XML buffer to extract CPU element.)); -goto cleanup; -} - -if (xmlNodeDump(xml_buf, xml, node, 0, 0) 0) { -vshError(ctl, _(Failed to extract CPU element snippet from domain XML.)); +if (!(snippet = virXMLNodeDump(xml, node))) { +vshSaveLibvirtError(); goto cleanup; } - -snippet = (const char *) xmlBufferContent(xml_buf); } else { vshError(ctl, _(File '%s' does not contain a cpu element or is not a valid domain or capabilities XML), from); @@ -6146,7 +6131,7 @@ cmdCPUCompare(vshControl *ctl, const vshCmd *cmd) cleanup: VIR_FREE(buffer); -xmlBufferFree(xml_buf); +VIR_FREE(snippet); xmlXPathFreeContext(ctxt); xmlFreeDoc(xml); @@ -6193,7 +6178,6 @@ cmdCPUBaseline(vshControl *ctl, const vshCmd *cmd) xmlDocPtr xml = NULL; xmlNodePtr *node_list = NULL; xmlXPathContextPtr ctxt = NULL; -xmlBufferPtr xml_buf = NULL; virBuffer buf = VIR_BUFFER_INITIALIZER; size_t i; @@ -6229,18 +6213,11 @@ cmdCPUBaseline(vshControl *ctl, const vshCmd *cmd) list = vshCalloc(ctl, count, sizeof(const char *)); -if (!(xml_buf = xmlBufferCreate())) -goto no_memory; - for (i = 0; i count; i++) { -xmlBufferEmpty(xml_buf); - -if (xmlNodeDump(xml_buf, xml, node_list[i], 0, 0) 0) { -vshError(ctl, _(Failed to extract cpu element)); +if (!(list[i] = virXMLNodeDump(xml, node_list[i]))) { +vshSaveLibvirtError(); goto cleanup; } - -list[i] = vshStrdup(ctl, (const char *)xmlBufferContent(xml_buf)); } result = virConnectBaselineCPU(ctl-conn, @@ -6254,7 +6231,6 @@ cmdCPUBaseline(vshControl *ctl, const vshCmd *cmd) cleanup: xmlXPathFreeContext(ctxt); xmlFreeDoc(xml); -xmlBufferFree(xml_buf); VIR_FREE(result); if (list != NULL count 0) { for (i = 0; i count; i++) @@ -9630,7 +9606,7 @@ cmdDetachInterface(vshControl *ctl, const vshCmd *cmd) xmlXPathObjectPtr obj=NULL; xmlXPathContextPtr ctxt = NULL; xmlNodePtr cur = NULL, matchNode = NULL; -xmlBufferPtr xml_buf = NULL; +char *detach_xml = NULL; const char *mac =NULL, *type = NULL; char *doc = NULL; char buf[64]; @@ -9723,25 +9699,16 @@ cmdDetachInterface(vshControl *ctl, const vshCmd *cmd) goto cleanup; } - hit: -xml_buf = xmlBufferCreate(); -if (!xml_buf) { -vshError(ctl, %s, _(Failed to allocate memory)); -goto cleanup; -} - -if (xmlNodeDump(xml_buf, xml, matchNode, 0, 0) 0) { -vshError(ctl, %s, _(Failed to create XML)); +hit: +if (!(detach_xml = virXMLNodeDump(xml,
[libvirt] [PATCH 02/14] virsh-domain: Line up signal names array
Line up the array so that the grid is visible. --- Notes: Not an useful change but it tripped my OCD while looking at the file. tools/virsh-domain.c | 24 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c index f6bfad0..727a42a 100644 --- a/tools/virsh-domain.c +++ b/tools/virsh-domain.c @@ -7009,19 +7009,19 @@ static const vshCmdOptDef opts_send_process_signal[] = { VIR_ENUM_DECL(virDomainProcessSignal) VIR_ENUM_IMPL(virDomainProcessSignal, VIR_DOMAIN_PROCESS_SIGNAL_LAST, - nop, hup, int, quit, ill, /* 0-4 */ - trap, abrt, bus, fpe, kill, /* 5-9 */ - usr1, segv, usr2, pipe, alrm, /* 10-14 */ - term, stkflt, chld, cont, stop, /* 15-19 */ - tstp, ttin, ttou, urg, xcpu, /* 20-24 */ + nop, hup,int, quit, ill, /* 0-4 */ + trap, abrt, bus, fpe, kill, /* 5-9 */ + usr1, segv, usr2, pipe, alrm, /* 10-14 */ + term, stkflt, chld, cont, stop, /* 15-19 */ + tstp, ttin, ttou, urg, xcpu, /* 20-24 */ xfsz, vtalrm, prof, winch, poll, /* 25-29 */ - pwr, sys, rt0,rt1, rt2, /* 30-34 */ - rt3, rt4, rt5, rt6, rt7, /* 35-39 */ - rt8, rt9, rt10, rt11, rt12, /* 40-44 */ - rt13, rt14, rt15, rt16, rt17, /* 45-49 */ - rt18, rt19, rt20, rt21, rt22, /* 50-54 */ - rt23, rt24, rt25, rt26, rt27, /* 55-59 */ - rt28, rt29, rt30, rt31, rt32) /* 60-64 */ + pwr, sys,rt0, rt1, rt2, /* 30-34 */ + rt3, rt4,rt5, rt6, rt7, /* 35-39 */ + rt8, rt9,rt10, rt11, rt12, /* 40-44 */ + rt13, rt14, rt15, rt16, rt17, /* 45-49 */ + rt18, rt19, rt20, rt21, rt22, /* 50-54 */ + rt23, rt24, rt25, rt26, rt27, /* 55-59 */ + rt28, rt29, rt30, rt31, rt32) /* 60-64 */ static int getSignalNumber(vshControl *ctl, const char *signame) { -- 1.8.3.2 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 00/14] Add ability to handle the metadata element using the API
This series adds the initialy omitted functionality of changing the metadata element using the virDomain[Get|Set]Metadata API. First few patches are cleanup of some code noticed during implementation of the other stuff. Peter Krempa (14): virsh-domain: Remove spurious ATTRIBUTE_UNUSED from cmdDesc virsh-domain: Line up signal names array qemu: Factor out body of qemuDomainGetMetadata for universal use qemu: Factor out body of qemuDomainSetMetadata for universal use conf: Factor out setting of metadata to simplify code util: Add helper to convert libxml2 nodes to a string virsh-domain: use virXMLNodeDump instead of xmlNodeDump virsh-domain: Add command to allow modifications of XML metadata conf: Add support for requesting of XML metadata via the API conf: allow to add XML metadata using the virDomainSetMetadata api lib: Don't force the key argument when deleting metadata lxc: Add metadata modification APIs test: Add metadata support into the test driver tests: Add metadata tests src/conf/domain_conf.c | 171 ++ src/conf/domain_conf.h | 17 +++ src/libvirt.c| 3 +- src/libvirt_private.syms | 4 + src/lxc/lxc_driver.c | 70 +++ src/qemu/qemu_driver.c | 122 ++- src/test/test_driver.c | 68 +++ src/util/virxml.c| 187 + src/util/virxml.h| 13 ++ tests/Makefile.am| 7 ++ tests/metadatatest.c | 245 ++ tools/virsh-domain.c | 304 --- 12 files changed, 1001 insertions(+), 210 deletions(-) create mode 100644 tests/metadatatest.c -- 1.8.3.2 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 11/14] lib: Don't force the key argument when deleting metadata
virDomainSetMetadata when operating on the metadata element was requesting the @key argument to be passed even if @metadata was NULL used to delete the corresponding metadata element. This is not needed as the key is only used when adding the element and matching is done via the XML namespace. --- src/libvirt.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/libvirt.c b/src/libvirt.c index 07a3fd5..2c94950 100644 --- a/src/libvirt.c +++ b/src/libvirt.c @@ -10734,7 +10734,8 @@ virDomainSetMetadata(virDomainPtr domain, break; case VIR_DOMAIN_METADATA_ELEMENT: virCheckNonNullArgGoto(uri, error); -virCheckNonNullArgGoto(key, error); +if (metadata) +virCheckNonNullArgGoto(key, error); break; default: /* For future expansion */ -- 1.8.3.2 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 09/14] conf: Add support for requesting of XML metadata via the API
The virDomainGetMetadata function was designed to support also retrieval of app specific metadata from the metadata element. This functionality was never implemented originally. --- src/conf/domain_conf.c | 19 src/libvirt_private.syms | 1 + src/util/virxml.c| 122 +++ src/util/virxml.h| 7 +++ 4 files changed, 140 insertions(+), 9 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index aa07056..4269690 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -18538,7 +18538,6 @@ virDomainObjGetMetadata(virDomainObjPtr vm, unsigned int flags) { virDomainDefPtr def; -char *field = NULL; char *ret = NULL; virCheckFlags(VIR_DOMAIN_AFFECT_LIVE | @@ -18553,17 +18552,21 @@ virDomainObjGetMetadata(virDomainObjPtr vm, switch ((virDomainMetadataType) type) { case VIR_DOMAIN_METADATA_DESCRIPTION: -field = def-description; +if (VIR_STRDUP(ret, def-description) 0) +goto cleanup; break; case VIR_DOMAIN_METADATA_TITLE: -field = def-title; +if (VIR_STRDUP(ret, def-title) 0) +goto cleanup; break; case VIR_DOMAIN_METADATA_ELEMENT: -virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, %s, - _(metadata element is not yet supported)); -goto cleanup; +if (!def-metadata) +break; + +if (virXMLExtractNamespaceXML(def-metadata, uri, ret) 0) +goto cleanup; break; default: @@ -18573,12 +18576,10 @@ virDomainObjGetMetadata(virDomainObjPtr vm, break; } -if (!field) +if (!ret) virReportError(VIR_ERR_NO_DOMAIN_METADATA, %s, _(Requested metadata element is not present)); -ignore_value(VIR_STRDUP(ret, field)); - cleanup: return ret; } diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 18e9a4b..b643c51 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -2091,6 +2091,7 @@ virUUIDParse; # util/virxml.h virXMLChildElementCount; +virXMLExtractNamespaceXML; virXMLNodeDump; virXMLParseHelper; virXMLPickShellSafeComment; diff --git a/src/util/virxml.c b/src/util/virxml.c index 44d6f27..0fac931 100644 --- a/src/util/virxml.c +++ b/src/util/virxml.c @@ -928,3 +928,125 @@ cleanup: return ret; } + +typedef int (*virXMLForeachCallback)(xmlNodePtr node, + void *opaque); + +static int +virXMLForeachNode(xmlNodePtr root, + virXMLForeachCallback cb, + void *opaque); + +static int +virXMLForeachNode(xmlNodePtr root, + virXMLForeachCallback cb, + void *opaque) +{ +xmlNodePtr next; +int ret; + +for (next = root; next; next = next-next) { +if ((ret = cb(next, opaque)) != 0) +return ret; + +/* recurse into children */ +if (next-children) { +if ((ret = virXMLForeachNode(next-children, cb, opaque)) != 0) +return ret; +} +} + +return 0; +} + + +static int +virXMLRemoveElementNamespace(xmlNodePtr node, + void *opaque) +{ +const char *uri = opaque; + +if (node-ns +STREQ_NULLABLE((const char *)node-ns-href, uri)) +xmlSetNs(node, NULL); +return 0; +} + + +xmlNodePtr +virXMLFindChildNodeByNs(xmlNodePtr root, +const char *uri) +{ +xmlNodePtr next; + +for (next = root-children; next; next = next-next) { +if (next-ns +STREQ_NULLABLE((const char *) next-ns-href, uri)) +return next; +} + +return NULL; +} + + +/** + * virXMLExtractNamespaceXML: extract a sub-namespace of a XML as string + */ +int +virXMLExtractNamespaceXML(xmlNodePtr root, + const char *uri, + char **doc) +{ +xmlNodePtr node; +xmlNodePtr nodeCopy = NULL; +xmlNsPtr actualNs; +xmlNsPtr prevNs = NULL; +char *xmlstr = NULL; +int ret = -1; + +if (!(node = virXMLFindChildNodeByNs(root, uri))) { +/* node not found */ +ret = 1; +goto cleanup; +} + +/* copy the node so that we can modify the namespace */ +if (!(nodeCopy = xmlCopyNode(node, 1))) { +virReportError(VIR_ERR_INTERNAL_ERROR, %s, + _(Failed to copy XML node)); +goto cleanup; +} + +virXMLForeachNode(nodeCopy, virXMLRemoveElementNamespace, + (void *)uri); + +/* remove the namespace declaration + * - it's only a single linked list ... doh */ +for (actualNs = nodeCopy-nsDef; actualNs; actualNs = actualNs-next) { +if (STREQ_NULLABLE((const char *)actualNs-href, uri)) { + +/* unlink */ +if (prevNs) +prevNs-next = actualNs-next; +else
[libvirt] [PATCH 14/14] tests: Add metadata tests
This test excercises the virDomain[Get|Set]Metadata API and tests it for regressions --- tests/Makefile.am| 7 ++ tests/metadatatest.c | 245 +++ 2 files changed, 252 insertions(+) create mode 100644 tests/metadatatest.c diff --git a/tests/Makefile.am b/tests/Makefile.am index 1a24367..617b5be 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -220,6 +220,8 @@ test_programs += interfacexml2xmltest test_programs += cputest +test_programs += metadatatest + test_scripts = \ capabilityschematest \ interfaceschematest \ @@ -574,6 +576,11 @@ cputest_SOURCES = \ testutils.c testutils.h cputest_LDADD = $(LDADDS) $(LIBXML_LIBS) +metadatatest_SOURCES = \ + metadatatest.c \ + testutils.c testutils.h +metadatatest_LDADD = $(LDADDS) $(LIBXML_LIBS) + virshtest_SOURCES = \ virshtest.c \ testutils.c testutils.h diff --git a/tests/metadatatest.c b/tests/metadatatest.c new file mode 100644 index 000..a910f68 --- /dev/null +++ b/tests/metadatatest.c @@ -0,0 +1,245 @@ +/* + * Copyright (C) 2013 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, see + * http://www.gnu.org/licenses/. + * + * Author: Peter Krempa pkre...@redhat.com + */ + +#include config.h + +#include testutils.h + +#include virerror.h +#include virxml.h + +#define VIR_FROM_THIS VIR_FROM_NONE + +static const char metadata1[] = +derp xmlns:foobar='http://foo.bar/'\n + barfoobar/bar\n + foo fooish='blurb'foofoo/foo\n + foobar:bazzomg/foobar:baz\n +/derp; + + +static const char metadata1_ns[] = +herp:derp xmlns:foobar='http://foo.bar/' xmlns:herp='http://herp.derp/'\n + herp:barfoobar/herp:bar\n + herp:foo fooish='blurb'foofoo/herp:foo\n + foobar:bazzomg/foobar:baz\n +/herp:derp; + + +static const char metadata2[] = +foo\n + barbaz/bar\n +/foo; + + +static const char metadata2_ns[] = +blurb:foo xmlns:blurb='http://herp.derp/'\n + blurb:barbaz/blurb:bar\n +/blurb:foo; + + +static char * +getMetadataFromXML(virDomainPtr dom) +{ +xmlDocPtr doc = NULL; +xmlXPathContextPtr ctxt = NULL; +xmlNodePtr node; + +char *xml = NULL; +char *ret = NULL; + +if (!(xml = virDomainGetXMLDesc(dom, 0))) +goto cleanup; + +if (!(doc = virXMLParseStringCtxt(xml, (domain_definition), ctxt))) +goto cleanup; + +if (!(node = virXPathNode(//metadata/*, ctxt))) +goto cleanup; + +ret = virXMLNodeDump(node-doc, node); + +cleanup: +VIR_FREE(xml); +xmlFreeDoc(doc); +xmlXPathFreeContext(ctxt); + +return ret; +} + + +static void +metadataXMLConvertApostrophe(char *str) +{ +do { +if (*str == '\') +*str = '\''; +} while ((*++str) != '\0'); +} + + +static bool +verifyMetadata(virDomainPtr dom, + const char *expectXML, + const char *expectAPI, + const char *uri) +{ +bool ret = false; +char *metadataXML = NULL; +char *metadataAPI = NULL; + +if (!expectAPI) { +if ((metadataAPI = virDomainGetMetadata(dom, +VIR_DOMAIN_METADATA_ELEMENT, +uri, 0))) { +virReportError(VIR_ERR_INTERNAL_ERROR, + expected no metadata in API, but got:\n[%s], + metadataAPI); +goto cleanup; +} +} else { +if (!(metadataAPI = virDomainGetMetadata(dom, + VIR_DOMAIN_METADATA_ELEMENT, + uri, 0))) +goto cleanup; + +metadataXMLConvertApostrophe(metadataAPI); + +if (STRNEQ(metadataAPI, expectAPI)) { +virReportError(VIR_ERR_INTERNAL_ERROR, + XML metadata in API doesn't match expected metadata: + expected:\n[%s]\ngot:\n[%s], + expectAPI, metadataAPI); +goto cleanup; +} + +} + +if (!expectXML) { +if ((metadataXML = getMetadataFromXML(dom))) { +virReportError(VIR_ERR_INTERNAL_ERROR, + expected no metadata in XML, but got:\n[%s], + metadataXML); +goto cleanup; +} +} else { +if (!(metadataXML =
[libvirt] [PATCH 12/14] lxc: Add metadata modification APIs
--- src/lxc/lxc_driver.c | 70 1 file changed, 70 insertions(+) diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c index b587c22..d49f524 100644 --- a/src/lxc/lxc_driver.c +++ b/src/lxc/lxc_driver.c @@ -4591,6 +4591,74 @@ lxcNodeSuspendForDuration(virConnectPtr conn, } +static int +lxcDomainSetMetadata(virDomainPtr dom, + int type, + const char *metadata, + const char *key, + const char *uri, + unsigned int flags) +{ +virLXCDriverPtr driver = dom-conn-privateData; +virDomainObjPtr vm; +virLXCDriverConfigPtr cfg = NULL; +virCapsPtr caps = NULL; +int ret = -1; + +virCheckFlags(VIR_DOMAIN_AFFECT_LIVE | + VIR_DOMAIN_AFFECT_CONFIG, -1); + +if (!(vm = lxcDomObjFromDomain(dom))) +return -1; + +cfg = virLXCDriverGetConfig(driver); + +if (virDomainSetMetadataEnsureACL(dom-conn, vm-def, flags) 0) +goto cleanup; + +if (!(caps = virLXCDriverGetCapabilities(driver, false))) +goto cleanup; + +ret = virDomainObjSetMetadata(vm, type, metadata, key, uri, caps, + driver-xmlopt, cfg-configDir, flags); + +cleanup: +virObjectUnlock(vm); +virObjectUnref(caps); +virObjectUnref(cfg); +return ret; +} + + +static char * +lxcDomainGetMetadata(virDomainPtr dom, + int type, + const char *uri, + unsigned int flags) +{ +virLXCDriverPtr driver = dom-conn-privateData; +virCapsPtr caps = NULL; +virDomainObjPtr vm; +char *ret = NULL; + +if (!(vm = lxcDomObjFromDomain(dom))) +return NULL; + +if (virDomainGetMetadataEnsureACL(dom-conn, vm-def) 0) +goto cleanup; + +if (!(caps = virLXCDriverGetCapabilities(driver, false))) +goto cleanup; + +ret = virDomainObjGetMetadata(vm, type, uri, caps, driver-xmlopt, flags); + +cleanup: +virObjectUnlock(vm); +virObjectUnref(caps); +return ret; +} + + /* Function Tables */ static virDriver lxcDriver = { .no = VIR_DRV_LXC, @@ -4665,6 +4733,8 @@ static virDriver lxcDriver = { .domainOpenConsole = lxcDomainOpenConsole, /* 0.8.6 */ .connectIsAlive = lxcConnectIsAlive, /* 0.9.8 */ .nodeSuspendForDuration = lxcNodeSuspendForDuration, /* 0.9.8 */ +.domainSetMetadata = lxcDomainSetMetadata, /* 1.1.3 */ +.domainGetMetadata = lxcDomainGetMetadata, /* 1.1.3 */ .nodeGetMemoryParameters = lxcNodeGetMemoryParameters, /* 0.10.2 */ .nodeSetMemoryParameters = lxcNodeSetMemoryParameters, /* 0.10.2 */ .domainSendProcessSignal = lxcDomainSendProcessSignal, /* 1.0.1 */ -- 1.8.3.2 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 03/14] qemu: Factor out body of qemuDomainGetMetadata for universal use
The function impelemnted common behavior that can be reused for other hypervisor drivers that use the virDomainObj data structures. Factor out the core into a separate helper func. --- src/conf/domain_conf.c | 55 src/conf/domain_conf.h | 7 ++ src/libvirt_private.syms | 1 + src/qemu/qemu_driver.c | 49 +- 4 files changed, 68 insertions(+), 44 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index aed2a9d..d9ed985 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -18527,3 +18527,58 @@ virDomainDiskSourceIsBlockType(virDomainDiskDefPtr def) } return false; } + + +char * +virDomainObjGetMetadata(virDomainObjPtr vm, +int type, +const char *uri ATTRIBUTE_UNUSED, +virCapsPtr caps, +virDomainXMLOptionPtr xmlopt, +unsigned int flags) +{ +virDomainDefPtr def; +char *field = NULL; +char *ret = NULL; + +virCheckFlags(VIR_DOMAIN_AFFECT_LIVE | + VIR_DOMAIN_AFFECT_CONFIG, NULL); + +if (virDomainLiveConfigHelperMethod(caps, xmlopt, vm, flags, def) 0) +goto cleanup; + +/* use correct domain definition according to flags */ +if (flags VIR_DOMAIN_AFFECT_LIVE) +def = vm-def; + +switch ((virDomainMetadataType) type) { +case VIR_DOMAIN_METADATA_DESCRIPTION: +field = def-description; +break; + +case VIR_DOMAIN_METADATA_TITLE: +field = def-title; +break; + +case VIR_DOMAIN_METADATA_ELEMENT: +virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, %s, + _(metadata element is not yet supported)); +goto cleanup; +break; + +default: +virReportError(VIR_ERR_INVALID_ARG, %s, + _(unknown metadata type)); +goto cleanup; +break; +} + +if (!field) +virReportError(VIR_ERR_NO_DOMAIN_METADATA, %s, + _(Requested metadata element is not present)); + +ignore_value(VIR_STRDUP(ret, field)); + +cleanup: +return ret; +} diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 539bc1c..173d302 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -2738,4 +2738,11 @@ bool virDomainDiskSourceIsBlockType(virDomainDiskDefPtr def) void virDomainChrSourceDefClear(virDomainChrSourceDefPtr def); +char *virDomainObjGetMetadata(virDomainObjPtr vm, + int type, + const char *uri, + virCapsPtr caps, + virDomainXMLOptionPtr xmlopt, + unsigned int flags); + #endif /* __DOMAIN_CONF_H */ diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 35f0f1b..2516b9c 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -309,6 +309,7 @@ virDomainNostateReasonTypeFromString; virDomainNostateReasonTypeToString; virDomainObjAssignDef; virDomainObjCopyPersistentDef; +virDomainObjGetMetadata; virDomainObjGetPersistentDef; virDomainObjGetState; virDomainObjListAdd; diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 9b5d126..9d5e825 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -15144,21 +15144,16 @@ cleanup: static char * qemuDomainGetMetadata(virDomainPtr dom, int type, - const char *uri ATTRIBUTE_UNUSED, + const char *uri, unsigned int flags) { virQEMUDriverPtr driver = dom-conn-privateData; +virCapsPtr caps = NULL; virDomainObjPtr vm; -virDomainDefPtr def; char *ret = NULL; -char *field = NULL; -virCapsPtr caps = NULL; - -virCheckFlags(VIR_DOMAIN_AFFECT_LIVE | - VIR_DOMAIN_AFFECT_CONFIG, NULL); if (!(vm = qemuDomObjFromDomain(dom))) -goto cleanup; +return NULL; if (virDomainGetMetadataEnsureACL(dom-conn, vm-def) 0) goto cleanup; @@ -15166,44 +15161,10 @@ qemuDomainGetMetadata(virDomainPtr dom, if (!(caps = virQEMUDriverGetCapabilities(driver, false))) goto cleanup; -if (virDomainLiveConfigHelperMethod(caps, driver-xmlopt, vm, flags, def) 0) -goto cleanup; - -/* use correct domain definition according to flags */ -if (flags VIR_DOMAIN_AFFECT_LIVE) -def = vm-def; - -switch ((virDomainMetadataType) type) { -case VIR_DOMAIN_METADATA_DESCRIPTION: -field = def-description; -break; -case VIR_DOMAIN_METADATA_TITLE: -field = def-title; -break; -case VIR_DOMAIN_METADATA_ELEMENT: -virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, %s, - _(QEMU driver does not support - metadata element)); -goto cleanup;
[libvirt] [PATCH 13/14] test: Add metadata support into the test driver
--- src/test/test_driver.c | 68 ++ 1 file changed, 68 insertions(+) diff --git a/src/test/test_driver.c b/src/test/test_driver.c index c225618..23f7b2e 100644 --- a/src/test/test_driver.c +++ b/src/test/test_driver.c @@ -2585,6 +2585,72 @@ cleanup: return ret; } +static char *testDomainGetMetadata(virDomainPtr dom, + int type, + const char *uri, + unsigned int flags) +{ +testConnPtr privconn = dom-conn-privateData; +virDomainObjPtr privdom; +char *ret = NULL; + +virCheckFlags(VIR_DOMAIN_AFFECT_LIVE | + VIR_DOMAIN_AFFECT_CONFIG, NULL); + +testDriverLock(privconn); +privdom = virDomainObjListFindByName(privconn-domains, + dom-name); +testDriverUnlock(privconn); + +if (privdom == NULL) { +virReportError(VIR_ERR_INVALID_ARG, __FUNCTION__); +goto cleanup; +} + +ret = virDomainObjGetMetadata(privdom, type, uri, privconn-caps, + privconn-xmlopt, flags); + +cleanup: +if (privdom) +virObjectUnlock(privdom); +return ret; +} + +static int testDomainSetMetadata(virDomainPtr dom, + int type, + const char *metadata, + const char *key, + const char *uri, + unsigned int flags) +{ +testConnPtr privconn = dom-conn-privateData; +virDomainObjPtr privdom; +int ret = -1; + +virCheckFlags(VIR_DOMAIN_AFFECT_LIVE | + VIR_DOMAIN_AFFECT_CONFIG, -1); + +testDriverLock(privconn); +privdom = virDomainObjListFindByName(privconn-domains, + dom-name); +testDriverUnlock(privconn); + +if (privdom == NULL) { +virReportError(VIR_ERR_INVALID_ARG, __FUNCTION__); +goto cleanup; +} + +ret = virDomainObjSetMetadata(privdom, type, metadata, key, uri, + privconn-caps, privconn-xmlopt, + NULL, flags); + +cleanup: +if (privdom) +virObjectUnlock(privdom); +return ret; +} + + static int testNodeGetCellsFreeMemory(virConnectPtr conn, unsigned long long *freemems, int startCell, int maxCells) { @@ -5872,6 +5938,8 @@ static virDriver testDriver = { .connectIsAlive = testConnectIsAlive, /* 0.9.8 */ .nodeGetCPUMap = testNodeGetCPUMap, /* 1.0.0 */ .domainScreenshot = testDomainScreenshot, /* 1.0.5 */ +.domainGetMetadata = testDomainGetMetadata, /* 1.1.3 */ +.domainSetMetadata = testDomainSetMetadata, /* 1.1.3 */ }; static virNetworkDriver testNetworkDriver = { -- 1.8.3.2 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH] Add some notes about security considerations when using LXC
From: Daniel P. Berrange berra...@redhat.com Describe some of the issues to be aware of when configuring LXC guests with security isolation as a goal. Signed-off-by: Daniel P. Berrange berra...@redhat.com --- docs/drvlxc.html.in | 93 + 1 file changed, 93 insertions(+) diff --git a/docs/drvlxc.html.in b/docs/drvlxc.html.in index 1e6aa1d..dd2e93c 100644 --- a/docs/drvlxc.html.in +++ b/docs/drvlxc.html.in @@ -168,6 +168,99 @@ Further block or character devices will be made available to containers depending on their configuration. /p +h2a name=securitySecurity considerations/a/h2 + +p +The libvirt LXC driver is fairly flexible in how it can be configured, +and as such does not enforce a requirement for strict security +separation between a container and the host. This allows it to be used +in scenarios where only resource control capabilities are important, +and resource sharing is desired. Applications wishing to ensure secure +isolation between a container and the host must ensure that they are +writing a suitable configuration +/p + +h3a name=securenetworkingNetwork isolation/a/h3 + +p +If the guest configuration does not list any network interfaces, +the codenetwork/code namespace will not be activated, and thus +the container will see all the host's network interfaces. This will +allow apps in the container to bind to/connect from TCP/UDP addresses +and ports from the host OS. It also allows applications to access +UNIX domain sockets associated with the host OS. +/p + +p +It should be noted that codesystemd/code has a UNIX domain socket +hich is used for communication by codesystemctl/code. Thus, with a +container that shares the host's network namespace, it will be possible +for a user in the container to invoke operations on codesystemd/code +in the same way it could if outside the container. In particular this +would allow coderoot/code in the container to do anything including +shutting down the host OS. If this is not desired, then applications +should either specify the UID/GID mapping in the configuration to enable +user namespaces, or should set the codelt;privnet/gt;/code flag +in the codelt;featuresgt;lt;/featuresgt;/code element. +/p + + +h3a name=securefsFilesystem isolation/a/h3 + +p +If the guest confuguration does not list any filesystems, then +the container will be setup with a root filesystem that matches +the host's root filesystem. As noted earlier, only a few locations +such as code/dev/code, code/proc/code and code/sys/code +will be altered. This means that, in the absence of restrictions +from sVirt, a process running as user/group N:M inside the container +will be able to access alnmost exactly the same files as a process +running as user/group N:M in the host. +/p + +p +There are multiple options for restricting this. It is possible to +simply map the existing root filesystem through to the container in +read-only mode. Alternatively a completely separate root filesystem +can be configured for the guest. In both cases, further sub-mounts +can be applied to customize the content that is made visible. Note +that in the absence of sVirt controls, it is still possible for the +root user in a container to unmount any sub-mounts applied. The user +namespace feature can also be used to restrict access to files based +on the UID/GID mappings. +/p + +h3a name=secureusersUser and group isolation/a/h3 + +p +If the guest configuration does not list any ID mapping, then the +user and group IDs used inside the container will match those used +outside the container. In addition, the capabilities associated with +a process in the container will infer the same privileges they would +for a process in the host. This has obvious implications for security, +since a root user inside the container will be able to access any +file owned by root that is visible to the container, and perform more +or less any privileged kernel operation. In the absence of additional +protection from sVirt, this means that the root user inside a container +is effectively as powerful as the root user in the host. There is no +security isolation of the root user. +/p + +p +The ID mapping facility was introduced to allow for stricter control +over the privileges of users inside the container. It allows apps to +define rules such as user ID 0 in the container maps to user ID 1000 +in the host. In addition the privileges associated with capabilities +are somewhat reduced so that they can not be used to escape from the +container environment. A full description of user namespaces is outside +the scope of this document, however LWN has +a href=https://lwn.net/Articles/532593/;a good writeup on the topic/a. +From the libvirt POV, the key thing to remember is that defining an +ID mapping for users and groups in the container XML configuration +causes libvirt to activate the user namespace feature. +/p + + h2a name=activationSystemd Socket Activation
Re: [libvirt] [PATCH] virBitmapFree: Change the function to a macro
On 09/10/2013 02:29 AM, Liuji (Jeremy) wrote: Yes,it's an actual crash problem. I found the problem in the above problem scenario in my first mail. A problem scenario: 1) The XML of VM contain the below segment: numatune memory mode='preferred' placement='auto' nodeset='0'/ /numatune 2)virsh create the VM 3)In the virDomainDefParseXML funtion: /* Ignore 'nodeset' if 'placement' is 'auto' finally */ if (placement_mode == VIR_NUMA_TUNE_MEM_PLACEMENT_MODE_AUTO) { virBitmapFree(def-numatune.memory.nodemask); def-numatune.memory.nodemask = NULL; } 4)Then, virsh destroy the VM. In the virDomainDefFree funtion, it also call the virBitmapFree function to free the nodemask: virBitmapFree(def-numatune.memory.nodemask); Then can you send a patch which explicitly fixes that problem on its own, without doing this major refactoring, which obscures what is being fixed. I had sent a patch in my first mail. You can find the mail at the following links: https://www.redhat.com/archives/libvir-list/2013-September/msg00337.html No, I want the root cause fixed. This change to the bitmap APIs is just papering over any root cause bug. This is a simple problem about an address is released twice in some scenario. I think that released twice is the root cause. I'm not sure what you mean about root cause. Did you mean that why the address will be released two times? What we want is a patch against virDomainDefParseXML - if it frees the bitmap, it must set the bitmap member to NULL (ie. the root cause is step 3 of your trace above). That will then avoid the second free in virDomainDefFree (step 4 of your trace). The root cause is insidious because leaving the bitmap pointer non-NULL after freeing it means that ANY other use of the bitmap (not just the free in virDomainDefFree) is accessing freed memory. Creating a macro to avoid the double free is overkill; compared to fixing the real bug of freeing but not marking the memory freed. -- Eric Blake eblake redhat com+1-919-301-3266 Libvirt virtualization library http://libvirt.org signature.asc Description: OpenPGP digital signature -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH 1/4] build: avoid $(srcdir) in *_SOURCES
On 09/10/2013 03:58 AM, Michal Privoznik wrote: Some things to remember that affect VPATH builds, and where an in-tree build is blissfully unaware of the issues: if a VPATH build fails to find a file that was used as a prereq of any other target, then the rule for that file will expand $@ to prefer the current build dir (bad because a VPATH build on a fresh checkout will then stick $@ in the current directory instead of the desired srcdir); conversely, if a VPATH build finds the file in srcdir but decides it needs to be rebuilt, then the rule for that file will expand $@ to include the directory where it was found out-of-date (bad for an explicit listing of $(srcdir)/$@ because an incremental VPATH build will then expand srcdir twice). As we want these files to go into srcdir unconditionally, we have to massage or avoid $@ for any recipe that involves one of these files. -$(srcdir)/remote_dispatch.h: $(srcdir)/../src/rpc/gendispatch.pl \ +remote_dispatch.h: $(srcdir)/../src/rpc/gendispatch.pl \ $(REMOTE_PROTOCOL) $(AM_V_GEN)$(PERL) -w $(srcdir)/../src/rpc/gendispatch.pl \ - --mode=server remote REMOTE $(REMOTE_PROTOCOL) $@ + --mode=server remote REMOTE $(REMOTE_PROTOCOL) \ + $(srcdir)/remote_dispatch.h The other option is to have this line as: $(srcdir)/$@ No, that explicitly does not work in VPATH setups, as mentioned in my commit message. On the first run (after a fresh checkout), $@ sees that remote_dispatch.h does not exist, so $@ expands to 'remote_dispatch.h', and the recipe creates $(srcdir)/remote_dispatch.h. But in an incremental rebuild, after changing a prerequisite file (such as the .x file embedded in $(REMOTE_PROTOCOL)), $@ discovers that the target file already exists in $(srcdir) via the VPATH lookup, so it expands $@ to '$(srcdir)/remote_dispatch.h', and the recipe attempts to build '$(srcdir)/$(srcdir)/remote_dispatch.h'. If $(srcdir) is .., then you have a mess on your hands (creating the wrong file, and the right file didn't get updated). Hence, the patch HAS to use absolute naming, rather than $@ magic, for anything that we _always_ want placed into srcdir. (For an in-tree build, $(srcdir) is '.', and since you can't tell between './remote_dispatch.h' vs. '././remote_dispatch.h', the problem only affects VPATH builds.) But this version is okay as is. ACK. Thanks for reviewing the series; I'll push shortly. -- Eric Blake eblake redhat com+1-919-301-3266 Libvirt virtualization library http://libvirt.org signature.asc Description: OpenPGP digital signature -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 0/2] Handle read only root in LXC
From: Daniel P. Berrange berra...@redhat.com A v2 of this patch https://www.redhat.com/archives/libvir-list/2013-September/msg00405.html Daniel P. Berrange (2): Move array of mounts out of lxcContainerMountBasicFS Ensure root filesystem is recursively mounted readonly src/lxc/lxc_container.c | 169 +--- 1 file changed, 130 insertions(+), 39 deletions(-) -- 1.8.3.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 1/2] Move array of mounts out of lxcContainerMountBasicFS
From: Daniel P. Berrange berra...@redhat.com Move the array of basic mounts out of the lxcContainerMountBasicFS function, to a global variable. This is to allow it to be referenced by other methods wanting to know what the basic mount paths are. Signed-off-by: Daniel P. Berrange berra...@redhat.com --- src/lxc/lxc_container.c | 79 ++--- 1 file changed, 42 insertions(+), 37 deletions(-) diff --git a/src/lxc/lxc_container.c b/src/lxc/lxc_container.c index 9c04d06..d51cdc4 100644 --- a/src/lxc/lxc_container.c +++ b/src/lxc/lxc_container.c @@ -750,45 +750,50 @@ err: } -static int lxcContainerMountBasicFS(bool userns_enabled) -{ -const struct { -const char *src; -const char *dst; -const char *type; -const char *opts; -int mflags; -} mnts[] = { -/* When we want to make a bind mount readonly, for unknown reasons, - * it is currently necessary to bind it once, and then remount the - * bind with the readonly flag. If this is not done, then the original - * mount point in the main OS becomes readonly too which is not what - * we want. Hence some things have two entries here. - */ -{ proc, /proc, proc, NULL, MS_NOSUID|MS_NOEXEC|MS_NODEV }, -{ /proc/sys, /proc/sys, NULL, NULL, MS_BIND }, -{ /proc/sys, /proc/sys, NULL, NULL, MS_BIND|MS_REMOUNT|MS_RDONLY }, -{ sysfs, /sys, sysfs, NULL, MS_NOSUID|MS_NOEXEC|MS_NODEV }, -{ sysfs, /sys, sysfs, NULL, MS_BIND|MS_REMOUNT|MS_RDONLY }, -{ securityfs, /sys/kernel/security, securityfs, NULL, MS_NOSUID|MS_NOEXEC|MS_NODEV }, -{ securityfs, /sys/kernel/security, securityfs, NULL, MS_BIND|MS_REMOUNT|MS_RDONLY }, +typedef struct { +const char *src; +const char *dst; +const char *type; +const char *opts; +int mflags; +} virLXCBasicMountInfo; + +static const virLXCBasicMountInfo lxcBasicMounts[] = { +/* When we want to make a bind mount readonly, for unknown reasons, + * it is currently necessary to bind it once, and then remount the + * bind with the readonly flag. If this is not done, then the original + * mount point in the main OS becomes readonly too which is not what + * we want. Hence some things have two entries here. + */ +{ proc, /proc, proc, NULL, MS_NOSUID|MS_NOEXEC|MS_NODEV }, +{ /proc/sys, /proc/sys, NULL, NULL, MS_BIND }, +{ /proc/sys, /proc/sys, NULL, NULL, MS_BIND|MS_REMOUNT|MS_RDONLY }, +{ sysfs, /sys, sysfs, NULL, MS_NOSUID|MS_NOEXEC|MS_NODEV }, +{ sysfs, /sys, sysfs, NULL, MS_BIND|MS_REMOUNT|MS_RDONLY }, +{ securityfs, /sys/kernel/security, securityfs, NULL, MS_NOSUID|MS_NOEXEC|MS_NODEV }, +{ securityfs, /sys/kernel/security, securityfs, NULL, MS_BIND|MS_REMOUNT|MS_RDONLY }, #if WITH_SELINUX -{ SELINUX_MOUNT, SELINUX_MOUNT, selinuxfs, NULL, MS_NOSUID|MS_NOEXEC|MS_NODEV }, -{ SELINUX_MOUNT, SELINUX_MOUNT, NULL, NULL, MS_BIND|MS_REMOUNT|MS_RDONLY }, +{ SELINUX_MOUNT, SELINUX_MOUNT, selinuxfs, NULL, MS_NOSUID|MS_NOEXEC|MS_NODEV }, +{ SELINUX_MOUNT, SELINUX_MOUNT, NULL, NULL, MS_BIND|MS_REMOUNT|MS_RDONLY }, #endif -}; +}; + + +static int lxcContainerMountBasicFS(bool userns_enabled) +{ size_t i; int rc = -1; VIR_DEBUG(Mounting basic filesystems); -for (i = 0; i ARRAY_CARDINALITY(mnts); i++) { +for (i = 0; i ARRAY_CARDINALITY(lxcBasicMounts); i++) { +virLXCBasicMountInfo const *mnt = lxcBasicMounts[i]; const char *srcpath = NULL; VIR_DEBUG(Processing %s - %s, - mnts[i].src, mnts[i].dst); + mnt-src, mnt-dst); -srcpath = mnts[i].src; +srcpath = mnt-src; /* Skip if mount doesn't exist in source */ if ((srcpath[0] == '/') @@ -796,34 +801,34 @@ static int lxcContainerMountBasicFS(bool userns_enabled) continue; #if WITH_SELINUX -if (STREQ(mnts[i].src, SELINUX_MOUNT) +if (STREQ(mnt-src, SELINUX_MOUNT) !is_selinux_enabled()) continue; #endif -if (STREQ(mnts[i].src, securityfs) userns_enabled) +if (STREQ(mnt-src, securityfs) userns_enabled) continue; -if (virFileMakePath(mnts[i].dst) 0) { +if (virFileMakePath(mnt-dst) 0) { virReportSystemError(errno, _(Failed to mkdir %s), - mnts[i].src); + mnt-src); goto cleanup; } VIR_DEBUG(Mount %s on %s type=%s flags=%x, opts=%s, - srcpath, mnts[i].dst, mnts[i].type, mnts[i].mflags, mnts[i].opts); -if (mount(srcpath, mnts[i].dst, mnts[i].type, mnts[i].mflags, mnts[i].opts) 0) { + srcpath, mnt-dst, mnt-type, mnt-mflags, mnt-opts); +if (mount(srcpath, mnt-dst, mnt-type, mnt-mflags, mnt-opts) 0) { #if
[libvirt] [PATCH 2/2] Ensure root filesystem is recursively mounted readonly
From: Daniel P. Berrange berra...@redhat.com If the guest is configured with filesystem type='mount' source dir='/'/ target dir='/'/ readonly/ /filesystem Then any submounts under / should also end up readonly, except for those setup as basic mounts. eg if the user has /home on a separate volume, they'd expect /home to be readonly, but we should not touch the /sys, /proc, etc dirs we setup ourselves. Users can selectively make sub-mounts read-write again by simply listing them as new mounts without the readonly flag set filesystem type='mount' source dir='/home'/ target dir='/home'/ /filesystem Signed-off-by: Daniel P. Berrange berra...@redhat.com --- src/lxc/lxc_container.c | 90 +++-- 1 file changed, 88 insertions(+), 2 deletions(-) diff --git a/src/lxc/lxc_container.c b/src/lxc/lxc_container.c index d51cdc4..38d95b0 100644 --- a/src/lxc/lxc_container.c +++ b/src/lxc/lxc_container.c @@ -532,7 +532,6 @@ static int lxcContainerGetSubtree(const char *prefix, } while (getmntent_r(procmnt, mntent, mntbuf, sizeof(mntbuf)) != NULL) { -VIR_DEBUG(Got %s, mntent.mnt_dir); if (!STRPREFIX(mntent.mnt_dir, prefix)) continue; @@ -541,7 +540,6 @@ static int lxcContainerGetSubtree(const char *prefix, if (VIR_STRDUP(mounts[nmounts], mntent.mnt_dir) 0) goto cleanup; nmounts++; -VIR_DEBUG(Grabbed %s, mntent.mnt_dir); } if (mounts) @@ -779,6 +777,76 @@ static const virLXCBasicMountInfo lxcBasicMounts[] = { }; +static bool lxcIsBasicMountLocation(const char *path) +{ +size_t i; + +for (i = 0; i ARRAY_CARDINALITY(lxcBasicMounts); i++) { +if (STRPREFIX(path, lxcBasicMounts[i].dst)) +return true; +} + +return false; +} + + +static int lxcContainerSetReadOnly(virDomainFSDefPtr root) +{ +FILE *procmnt; +struct mntent mntent; +char mntbuf[1024]; +int ret = -1; +char **mounts = NULL; +size_t nmounts = 0; +size_t i; + +VIR_DEBUG(root=%s, root-src); + +if (!(procmnt = setmntent(/proc/mounts, r))) { +virReportSystemError(errno, %s, + _(Failed to read /proc/mounts)); +return -1; +} + +while (getmntent_r(procmnt, mntent, mntbuf, sizeof(mntbuf)) != NULL) { +if (STREQ(mntent.mnt_dir, /) || +STREQ(mntent.mnt_dir, /.oldroot) || +STRPREFIX(mntent.mnt_dir, /.oldroot/) || +lxcIsBasicMountLocation(mntent.mnt_dir)) +continue; + +if (VIR_REALLOC_N(mounts, nmounts + 1) 0) +goto cleanup; +if (VIR_STRDUP(mounts[nmounts], mntent.mnt_dir) 0) +goto cleanup; +nmounts++; +} + +if (mounts) +qsort(mounts, nmounts, sizeof(mounts[0]), + lxcContainerChildMountSort); + +for (i = 0; i nmounts; i++) { +VIR_DEBUG(Bind readonly %s, mounts[i]); +if (mount(mounts[i], mounts[i], NULL, MS_BIND|MS_REC|MS_RDONLY|MS_REMOUNT, NULL) 0) { +virReportSystemError(errno, + _(Failed to make mount %s readonly), + mounts[i]); +goto cleanup; +} +} + +ret = 0; +cleanup: +for (i = 0; i nmounts; i++) +VIR_FREE(mounts[i]); +VIR_FREE(mounts); +endmntent(procmnt); +return ret; + +} + + static int lxcContainerMountBasicFS(bool userns_enabled) { size_t i; @@ -1006,6 +1074,8 @@ static int lxcContainerMountFSBind(virDomainFSDefPtr fs, int ret = -1; struct stat st; +VIR_DEBUG(src=%s dst=%s, fs-src, fs-dst); + if (virAsprintf(src, %s%s, srcprefix, fs-src) 0) goto cleanup; @@ -1062,6 +1132,13 @@ static int lxcContainerMountFSBind(virDomainFSDefPtr fs, _(Failed to make directory %s readonly), fs-dst); } +} else { +VIR_DEBUG(Binding %s readwrite, fs-dst); +if (mount(src, fs-dst, NULL, MS_BIND|MS_REMOUNT, NULL) 0) { +virReportSystemError(errno, + _(Failed to make directory %s readwrite), + fs-dst); +} } ret = 0; @@ -1335,6 +1412,8 @@ static int lxcContainerMountFSBlock(virDomainFSDefPtr fs, char *src = NULL; int ret = -1; +VIR_DEBUG(src=%s dst=%s, fs-src, fs-dst); + if (virAsprintf(src, %s%s, srcprefix, fs-src) 0) goto cleanup; @@ -1354,6 +1433,8 @@ static int lxcContainerMountFSTmpfs(virDomainFSDefPtr fs, int ret = -1; char *data = NULL; +VIR_DEBUG(usage=%lld sec=%s, fs-usage, sec_mount_options); + if (virAsprintf(data, size=%lldk%s, fs-usage, sec_mount_options) 0) goto cleanup; @@ -1541,6 +1622,11 @@ static int lxcContainerSetupPivotRoot(virDomainDefPtr vmDef, if
[libvirt] [PATCH] qemu: Fix connectGetType() API
This patch fixes qemuConnectGetType() API function to return KVM if appropriate, i.e. when /dev/kvm exists as the KVM module is loaded. No further check is being done so it's merely showing the possibility that KVM virtualization is available on the host however we don't have any guest information (as it's connection-only related) so we cannot sure we can use KVM. This can be useful to identify we have KVM (Virt Support) available on the host if host and guest archs are the same. Testing: Done using a simple application with C source code below. [before patch applied]$ ./test Hypervisor type: QEMU [after patch applied]$ ./test Hypervisor type: KVM $ Testing C code: int main() { virConnectPtr conn = NULL; conn = virConnectOpen(qemu:///system); if (!conn) return 1; printf(Hypervisor type: %s\n, virConnectGetType(conn)); virConnectClose(conn); return 0; } Compiled on F-17 x86_64 host using: gcc -o test test.c -lvirt Signed-off-by: Michal Novotny minov...@redhat.com --- src/qemu/qemu_driver.c | 10 ++ 1 file changed, 10 insertions(+) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 9b5d126..b770967 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -1132,6 +1132,16 @@ static const char *qemuConnectGetType(virConnectPtr conn ATTRIBUTE_UNUSED) { if (virConnectGetTypeEnsureACL(conn) 0) return NULL; +/* + * If KVM is available for the host architecture then report KVM support. + * This approach merely shows it is possible to have KVM support as module is + * loaded however if you select different architecture, e.g. ARM on x86_64 host, + * the KVM option will not be available as there is no KVM virtualization + * support for ARM architecture that could be running on top of x86_64 host. + */ +if (access(/dev/kvm, F_OK) == 0) +return KVM; + return QEMU; } -- 1.7.11.7 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] link fow downloading libvirt-0.10.2-19.el6
Hi All, I could finally fix this issue with the patch mentioned in comment 17 in https://bugzilla.redhat.com/show_bug.cgi?id=911609#c28 applied on libvirt-1.0.3 version and all my tests are fine. Thanks a lot for your support. Thanks Abhinay On Wed, Sep 4, 2013 at 2:45 PM, Eric Blake ebl...@redhat.com wrote: On 09/04/2013 05:59 AM, arun abhinay wrote: Hi Laine, [Please don't top-post on technical lists] Thanks a lot for your inputs. We will try to download the code from libvirt-0.10.2-main t and build libvirt with the patch for crash issue. We are using WR kenerl of below version 2.6.34.13-WR4 That still doesn't answer our question of: You haven't said what OS you are running (aside from referencing a bug report filed against a build of libvirt made for RHEL6.x). If you're running RHEL, then you should open a support incident with Red Hat. If you're running some other distro, you should find the most recent pre-built package for that distro. If that doesn't help and you have to build libvirt yourself, then rather than upgrading to some different old version (1.0.5), you would probably do better to upgrade to the latest release (1.1.2). what distro are you trying to build for? If you have a support contract (such as if you are using RHEL), then this is a question for your distro; otherwise, you are MUCH better off trying to get the latest release working than you are trying to do backporting efforts yourself, as this list focuses mainly on upstream development, not debugging backport efforts. -- Eric Blake eblake redhat com+1-919-301-3266 Libvirt virtualization library http://libvirt.org -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [libvirt-php] bug in libvirt_domain_change_vcpus()
On 09/10/2013 10:09 AM, Daniel P. Berrange wrote: On Mon, Sep 09, 2013 at 06:51:54PM +0200, Michal Novotny wrote: Hi Olivier, this is not really a bug as it's intended. The libvirt_domain_change_vcpus() is not the same as (yet unimplemented) virDomainSetVcpus() API so it's not bug. I realize that naming could be a little confusing so if you like, feel free to rename libvirt_domain_change_vcpus() to libvirt_domain_xml_change_vcpus() as this API should be used to change number of vCPUS in the domain XML itself and implement libvirt_domain_set_vcpus() calling real virDomainSetVcpus() API function. That function is also buggy in that it will silently turn a transient guest into a persistent guest, which is almost certainly not what a caller would expect Daniel Ok, I guess dropping libvirt_domain_xml_change_vcpus() and implementing libvirt_domain_xml_set_vcpus() using the virDomainSetVcpus() API function is much better. Thanks, Michal -- Michal Novotny minov...@redhat.com, RHCE, Red Hat Virtualization | libvirt-php bindings | php-virt-control.org -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH] qemu: Fix connectGetType() API
On Tue, Sep 10, 2013 at 03:06:29PM +0200, Michal Novotny wrote: This patch fixes qemuConnectGetType() API function to return KVM if appropriate, i.e. when /dev/kvm exists as the KVM module is loaded. No further check is being done so it's merely showing the possibility that KVM virtualization is available on the host however we don't have any guest information (as it's connection-only related) so we cannot sure we can use KVM. This can be useful to identify we have KVM (Virt Support) available on the host if host and guest archs are the same. NACK, you are confusing two different things. virConnectGetType is intended to return the libvirt driver name. This is *always* 'QEMU'. If you want to know whether kvm virt is possible or not, then query the capabilities XML. Daniel -- |: http://berrange.com -o-http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :| -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH] Fix cgroups when all are mounted on /sys/fs/cgroup
From: Daniel P. Berrange berra...@redhat.com Some users in Ubuntu/Debian seem to have a setup where all the cgroup controllers are mounted on /sys/fs/cgroup rather than any /sys/fs/cgroup/controller name. In the loop which detects which controllers are present for a mount point we were modifying 'mnt_dir' field in the 'struct mntent' var, but not always restoring the original value. This caused detection to break in the all-in-one mount setup. Fix that logic bug and add test case coverage for this mount setup. Signed-off-by: Daniel P. Berrange berra...@redhat.com --- src/util/vircgroup.c | 3 ++- tests/vircgroupmock.c | 42 --- tests/vircgrouptest.c | 55 +++ 3 files changed, 96 insertions(+), 4 deletions(-) diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c index 16458a3..a260356 100644 --- a/src/util/vircgroup.c +++ b/src/util/vircgroup.c @@ -342,10 +342,11 @@ virCgroupDetectMounts(virCgroupPtr group) entry.mnt_dir); goto error; } -*tmp2 = '\0'; + /* If it is a co-mount it has a filename like cpu,cpuacct * and we must identify the symlink path */ if (strchr(tmp2 + 1, ',')) { +*tmp2 = '\0'; if (virAsprintf(linksrc, %s/%s, entry.mnt_dir, typestr) 0) goto error; diff --git a/tests/vircgroupmock.c b/tests/vircgroupmock.c index f1a5700..bf52843 100644 --- a/tests/vircgroupmock.c +++ b/tests/vircgroupmock.c @@ -103,6 +103,27 @@ const char *proccgroups = blkio 8 4 1\n; +const char *procmountsallinone = +rootfs / rootfs rw 0 0\n +sysfs /sys sysfs rw,nosuid,nodev,noexec,relatime 0 0\n +proc /proc proc rw,nosuid,nodev,noexec,relatime 0 0\n +udev /dev devtmpfs rw,relatime,size=16458560k,nr_inodes=4114640,mode=755 0 0\n +devpts /dev/pts devpts rw,nosuid,noexec,relatime,gid=5,mode=620,ptmxmode=000 0 0\n +nfsd /proc/fs/nfsd nfsd rw,relatime 0 0\n +cgroup /not/really/sys/fs/cgroup cgroup rw,relatime,blkio,devices,memory,cpuacct,cpu,cpuset 0 0\n; + +const char *procselfcgroupsallinone = +6:blkio,devices,memory,cpuacct,cpu,cpuset:/; + +const char *proccgroupsallinone = +#subsys_namehierarchy num_cgroups enabled\n +cpuset 6 1 1\n +cpu 6 1 1\n +cpuacct 6 1 1\n +memory 6 1 1\n +devices 6 1 1\n +blkio6 1 1\n; + static int make_file(const char *path, const char *name, const char *value) @@ -378,11 +399,20 @@ static void init_sysfs(void) FILE *fopen(const char *path, const char *mode) { +const char *mock; +bool allinone = false; init_syms(); +mock = getenv(VIR_CGROUP_MOCK_MODE); +if (mock STREQ(mock, allinone)) +allinone = true; + if (STREQ(path, /proc/mounts)) { if (STREQ(mode, r)) { -return fmemopen((void *)procmounts, strlen(procmounts), mode); +if (allinone) +return fmemopen((void *)procmountsallinone, strlen(procmountsallinone), mode); +else +return fmemopen((void *)procmounts, strlen(procmounts), mode); } else { errno = EACCES; return NULL; @@ -390,7 +420,10 @@ FILE *fopen(const char *path, const char *mode) } if (STREQ(path, /proc/cgroups)) { if (STREQ(mode, r)) { -return fmemopen((void *)proccgroups, strlen(proccgroups), mode); +if (allinone) +return fmemopen((void *)proccgroupsallinone, strlen(proccgroupsallinone), mode); +else +return fmemopen((void *)proccgroups, strlen(proccgroups), mode); } else { errno = EACCES; return NULL; @@ -398,7 +431,10 @@ FILE *fopen(const char *path, const char *mode) } if (STREQ(path, /proc/self/cgroup)) { if (STREQ(mode, r)) { -return fmemopen((void *)procselfcgroups, strlen(procselfcgroups), mode); +if (allinone) +return fmemopen((void *)procselfcgroupsallinone, strlen(procselfcgroupsallinone), mode); +else +return fmemopen((void *)procselfcgroups, strlen(procselfcgroups), mode); } else { errno = EACCES; return NULL; diff --git a/tests/vircgrouptest.c b/tests/vircgrouptest.c index 4bdd4c9..f12587c 100644 --- a/tests/vircgrouptest.c +++ b/tests/vircgrouptest.c @@ -99,6 +99,16 @@ const char *mountsFull[VIR_CGROUP_CONTROLLER_LAST] = { [VIR_CGROUP_CONTROLLER_BLKIO] = /not/really/sys/fs/cgroup/blkio, [VIR_CGROUP_CONTROLLER_SYSTEMD] = /not/really/sys/fs/cgroup/systemd, }; +const char *mountsAllInOne[VIR_CGROUP_CONTROLLER_LAST] =
Re: [libvirt] [PATCH] qemu: Fix connectGetType() API
On 09/10/2013 03:19 PM, Daniel P. Berrange wrote: On Tue, Sep 10, 2013 at 03:06:29PM +0200, Michal Novotny wrote: This patch fixes qemuConnectGetType() API function to return KVM if appropriate, i.e. when /dev/kvm exists as the KVM module is loaded. No further check is being done so it's merely showing the possibility that KVM virtualization is available on the host however we don't have any guest information (as it's connection-only related) so we cannot sure we can use KVM. This can be useful to identify we have KVM (Virt Support) available on the host if host and guest archs are the same. NACK, you are confusing two different things. virConnectGetType is intended to return the libvirt driver name. This is *always* 'QEMU'. If you want to know whether kvm virt is possible or not, then query the capabilities XML. Daniel Ok, if this is merely returning the driver name wouldn't it be better to rename it to virConnectGetDriverName() ? According to documentation at [1] it's the name of the hypervisor so the hypervisor may be both QEMU or KVM so why to put QEMU if it's the driver name? At least fixing the documentation with information the function is returning the driver name used (and you cannot rely on it to know whether you're on KVM or QEMU) would be nice... Michal [1] http://libvirt.org/html/libvirt-libvirt.html#virConnectGetType -- Michal Novotny minov...@redhat.com, RHCE, Red Hat Virtualization | libvirt-php bindings | php-virt-control.org -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH] DBus: introduce virDBusIsServiceEnabled
On Tue, Sep 10, 2013 at 11:34:32AM +0800, Gao feng wrote: This patch introduces virDBusIsServiceEnabled, we can use this method to get if the service is supported. In one case, if org.freedesktop.machine1 is unavailable on host, we should skip creating machine through systemd. Signed-off-by: Gao feng gaof...@cn.fujitsu.com --- src/util/virdbus.c| 59 +++ src/util/virdbus.h| 1 + src/util/virsystemd.c | 11 ++ 3 files changed, 62 insertions(+), 9 deletions(-) diff --git a/src/util/virdbus.c b/src/util/virdbus.c index 62c31be..29068b0 100644 --- a/src/util/virdbus.c +++ b/src/util/virdbus.c @@ -1207,6 +1207,58 @@ int virDBusMessageRead(DBusMessage *msg, return ret; } +/** + * virDBusIsServiceEnabled: + * @name: service name + */ +bool virDBusIsServiceEnabled(const char *name) IMHO this should be a tri-state so we can distinguish actual 'service not available' from other fatal errors. +{ +DBusConnection *conn; +DBusMessage *reply = NULL; +DBusMessageIter iter, sub; +bool ret = false; + +if (!virDBusHasSystemBus()) +return ret; + +conn = virDBusGetSystemBus(); + +if (virDBusCallMethod(conn, + reply, + org.freedesktop.DBus, + /org/freedesktop/DBus, + org.freedesktop.DBus, + ListActivatableNames, + DBUS_TYPE_INVALID) 0) { +VIR_DEBUG(ListActivatableNames failed.); +return ret; In particular this is a fatal error condition that should be treated as such. +} + +if (!dbus_message_iter_init(reply, iter) || +dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_ARRAY) { +VIR_DEBUG(Reply message incorrect.); +goto cleanup; +} + +dbus_message_iter_recurse(iter, sub); +while (dbus_message_iter_get_arg_type(sub) == DBUS_TYPE_STRING) { +const char *service = NULL; + +dbus_message_iter_get_basic(sub, service); +dbus_message_iter_next(sub); + +if (STREQ(service, name)) { +ret = true; +goto cleanup; +} +} + + cleanup: +VIR_DEBUG(Service %s is %s, name, ret ? available : unavailable); +dbus_message_unref(reply); +return false; +} Daniel -- |: http://berrange.com -o-http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :| -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH] qemu: Fix connectGetType() API
On 09/10/2013 07:37 AM, Michal Novotny wrote: If you want to know whether kvm virt is possible or not, then query the capabilities XML. Daniel Ok, if this is merely returning the driver name wouldn't it be better to rename it to virConnectGetDriverName() ? Unfortunately, we don't like renaming APIs if avoidable. It introduces a compat problem where new apps have to decide whether they can use the new name or the old name based on what they are targetting (the old name has to remain in the .so to avoid breaking old apps), whereas having only one name available makes it easier (use just the one name). According to documentation at [1] it's the name of the hypervisor so the hypervisor may be both QEMU or KVM so why to put QEMU if it's the driver name? At least fixing the documentation with information the function is returning the driver name used (and you cannot rely on it to know whether you're on KVM or QEMU) would be nice... The qemu:// URI services both qemu and kvm guests; it's up to the capabilities XML to tell you which (or both) of those types it can serve. But a doc patch is welcome, if it would help reduce your confusion. -- Eric Blake eblake redhat com+1-919-301-3266 Libvirt virtualization library http://libvirt.org signature.asc Description: OpenPGP digital signature -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH v2 2/5] cpu_models: implement the remote protocol
On Sat, Sep 07, 2013 at 01:11:23AM +0200, Giuseppe Scrivano wrote: Signed-off-by: Giuseppe Scrivano gscri...@redhat.com --- daemon/remote.c | 47 +++ src/remote/remote_driver.c | 59 src/remote/remote_protocol.x | 20 ++- src/remote_protocol-structs | 11 + 4 files changed, 136 insertions(+), 1 deletion(-) diff --git a/daemon/remote.c b/daemon/remote.c index 2aff7c1..4846ccb 100644 --- a/daemon/remote.c +++ b/daemon/remote.c @@ -5037,6 +5037,53 @@ cleanup: static int +remoteDispatchConnectGetCPUModelNames(virNetServerPtr server ATTRIBUTE_UNUSED, + virNetServerClientPtr client ATTRIBUTE_UNUSED, + virNetMessagePtr msg ATTRIBUTE_UNUSED, + virNetMessageErrorPtr rerr, + remote_connect_get_cpu_model_names_args *args, + remote_connect_get_cpu_model_names_ret *ret) +{ +int rv = -1; +char **models; +struct daemonClientPrivate *priv = +virNetServerClientGetPrivateData(client); + +if (!priv-conn) { +virReportError(VIR_ERR_INTERNAL_ERROR, %s, _(connection not open)); +goto cleanup; +} + +if (virConnectGetCPUModelNames(priv-conn, args-arch, models, + args-flags) 0) +goto cleanup; + +ret-models.models_val = models; +ret-models.models_len = 0; +while (*models++) +ret-models.models_len++; You can avoid this if you make the API return value indicate the number of models. + +if (ret-models.models_len REMOTE_CONNECT_CPU_MODELS_MAX) { +virReportError(VIR_ERR_RPC, + _(Too many CPU models '%d' for limit '%d'), + ret-models.models_len, REMOTE_CONNECT_CPU_MODELS_MAX); + +for (models = ret-models.models_val; *models; models++) +VIR_FREE(*models); +VIR_FREE(ret-models.models_val); virStringFeeList(models) +goto cleanup; +} + +rv = 0; + +cleanup: +if (rv 0) +virNetMessageSaveError(rerr); +return rv; +} + + +static int remoteDispatchDomainCreateXMLWithFiles(virNetServerPtr server ATTRIBUTE_UNUSED, virNetServerClientPtr client, virNetMessagePtr msg ATTRIBUTE_UNUSED, diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c index 62e77a5..1b6635f 100644 --- a/src/remote/remote_driver.c +++ b/src/remote/remote_driver.c @@ -5541,6 +5541,64 @@ done: static int +remoteConnectGetCPUModelNames(virConnectPtr conn, + const char *arch, + char ***models, + unsigned int flags) +{ +int rv = -1; +size_t i; +char **retmodels; +remote_connect_get_cpu_model_names_args args; +remote_connect_get_cpu_model_names_ret ret; +struct private_data *priv = conn-privateData; +remoteDriverLock(priv); + +memset(args, 0, sizeof(args)); +memset(ret, 0, sizeof(ret)); + +args.arch = (char *) arch; +args.flags = flags; + +if (call(conn, priv, 0, REMOTE_PROC_CONNECT_GET_CPU_MODEL_NAMES, + (xdrproc_t) xdr_remote_connect_get_cpu_model_names_args, + (char *) args, + (xdrproc_t) xdr_remote_connect_get_cpu_model_names_ret, + (char *) ret) 0) +goto error; + +/* Check the length of the returned list carefully. */ +if (ret.models.models_len REMOTE_CONNECT_CPU_MODELS_MAX) { +virReportError(VIR_ERR_RPC, %s, + _(remoteConnectGetCPUModelNames: + returned number of CPU models exceeds limit)); +goto error; +} + +if (VIR_ALLOC_N(retmodels, ret.models.models_len + 1) 0) +goto error; + +for (i = 0; i ret.models.models_len; i++) +retmodels[i] = ret.models.models_val[i]; + +/* Caller frees MODELS. */ +*models = retmodels; +rv = 0; + +done: +remoteDriverUnlock(priv); +return rv; + +error: +rv = -1; +for (i = 0; i ret.models.models_len; i++) +VIR_FREE(ret.models.models_val[i]); +VIR_FREE(ret.models.models_val); Daniel -- |: http://berrange.com -o-http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :| -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH v2 4/5] cpu_models: add the support for the test protocol
On Sat, Sep 07, 2013 at 01:11:25AM +0200, Giuseppe Scrivano wrote: Signed-off-by: Giuseppe Scrivano gscri...@redhat.com --- src/test/test_driver.c | 16 1 file changed, 16 insertions(+) diff --git a/src/test/test_driver.c b/src/test/test_driver.c index c225618..03d9c96 100644 --- a/src/test/test_driver.c +++ b/src/test/test_driver.c @@ -5801,6 +5801,21 @@ testDomainScreenshot(virDomainPtr dom ATTRIBUTE_UNUSED, return ret; } +static int +testConnectGetCPUModelNames(virConnectPtr conn ATTRIBUTE_UNUSED, +const char *arch ATTRIBUTE_UNUSED, +char ***models, +unsigned int flags) +{ +char **null_list; + +virCheckFlags(0, -1); +if (VIR_ALLOC_N(null_list, 1) 0) +return -1; + +*models = null_list; +return 0; +} It'd be nice to have a non-NULL list for this IMHO. Daniel -- |: http://berrange.com -o-http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :| -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH v2 1/5] cpu_models: add new public API
On Sat, Sep 07, 2013 at 01:11:22AM +0200, Giuseppe Scrivano wrote: The new function virConnectGetCPUModelNames allows to retrieve the list of CPU models known by the hypervisor for a specific architecture. Signed-off-by: Giuseppe Scrivano gscri...@redhat.com --- include/libvirt/libvirt.h.in | 18 + python/generator.py | 1 + src/cpu/cpu.c| 64 src/cpu/cpu.h| 3 +++ src/driver.h | 7 + src/libvirt.c| 47 src/libvirt_private.syms | 1 + src/libvirt_public.syms | 5 tools/virsh-host.c | 48 + tools/virsh.pod | 5 It is preferrable to have virsh changes separate from the public API addition. Likewise I'd suggest th src/cpu/ changes be a separate patch. diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in index a47e33c..43fb738 100644 --- a/include/libvirt/libvirt.h.in +++ b/include/libvirt/libvirt.h.in @@ -4006,6 +4006,24 @@ int virConnectCompareCPU(virConnectPtr conn, const char *xmlDesc, unsigned int flags); +/** + * virConnectGetCPUModelNames: + * + * @conn: virConnect connection + * @arch: Architecture + * @models: NULL terminated array of the CPU models supported for the specified + * architecture. Each element and the array itself must be freed by the caller + * with free. + * @flags: extra flags; not used yet, so callers should always pass 0. + * + * Get the list of supported CPU models for a specific architecture. + * + * Returns -1 on error, 0 on success. I'd suggest Returns -1 on error, number of elements in @models on success + */ +int virConnectGetCPUModelNames(virConnectPtr conn, + const char *arch, + char ***models, + unsigned int flags); +int +cpuGetModels(const char *arch, char ***models) +{ +struct cpuGetModelsData data; + +*models = data.data = NULL; +data.len = 1; + +if (VIR_ALLOC_N(data.data, data.len) 0) +goto error; + +if (cpuGetArchModels(arch, data) 0) +goto error; + +*models = data.data; +return 0; + +error: +if (data.data) { +char **it; +for (it = data.data; *it; it++) +VIR_FREE(*it); +VIR_FREE(data.data); virFreeStringList(data.data); should do the trick. /** + * virConnectGetCPUModelNames: + * + * @conn: virConnect connection + * @arch: Architecture + * @models: NULL terminated array of the CPU models supported for the specified + * architecture. Each element and the array itself must be freed by the caller + * with free. + * @flags: extra flags; not used yet, so callers should always pass 0. + * + * Get the list of supported CPU models for a specific architecture. + * + * Returns -1 on error, 0 on success. + */ +int +virConnectGetCPUModelNames(virConnectPtr conn, const char *arch, char ***models, + unsigned int flags) +{ +VIR_DEBUG(conn=%p, arch=%s, flags=%x, conn, arch, flags); +virResetLastError(); + +if (!VIR_IS_CONNECT(conn)) { +virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__); +virDispatchError(NULL); +return -1; +} + +if (arch == NULL) { +virLibConnError(VIR_ERR_INVALID_ARG, __FUNCTION__); +goto error; +} This allows access to this API from readonly connections. I think this is ok, but just wanted to mention it explicitly. + +if (conn-driver-connectGetCPUModelNames) { +if (conn-driver-connectGetCPUModelNames(conn, arch, models, flags) 0) +goto error; + +return 0; +} + +virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__); + +error: +virDispatchError(conn); +return -1; +} + + +/** * virConnectBaselineCPU: * * @conn: virConnect connection Daniel -- |: http://berrange.com -o-http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :| -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [v4 1/5] virsh: Add vshCmdCompleter and vshOptCompleter
completer and completer_flags added to the _vshCmdOptDef structure so it will be possible for completion generators to conveniently call option completer functions with desired flags. --- v4 * merged (*vshCmdCompleter) and (*vshOptCompleter) into (*vshCompleter) * deleted completer and completer_flags from the vshCmdDef, now using only opt completer tools/virsh.h | 4 1 file changed, 4 insertions(+) diff --git a/tools/virsh.h b/tools/virsh.h index b5e2715..f978d94 100644 --- a/tools/virsh.h +++ b/tools/virsh.h @@ -148,6 +148,8 @@ typedef struct _vshCmdOptDef vshCmdOptDef; typedef struct _vshControl vshControl; typedef struct _vshCtrlData vshCtrlData; +typedef char **(*vshCompleter)(unsigned int flags); + /* * vshCmdInfo -- name/value pair for information about command * @@ -169,6 +171,8 @@ struct _vshCmdOptDef { unsigned int flags; /* flags */ const char *help; /* non-NULL help string; or for VSH_OT_ALIAS * the name of a later public option */ +vshCompleter completer; /* option completer */ +unsigned int completer_flags; /* option completer flags */ }; /* -- 1.8.3.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH] qemu: endjob returns a bool
On 09/09/2013 01:43 PM, Doug Goldstein wrote: On Mon, Sep 9, 2013 at 2:12 PM, Eric Blake ebl...@redhat.com wrote: Osier Yang pointed out that ever since commit 31cb030, the signature of qemuDomainObjEndJob was changed to return a bool. While comparison against 0 or 0 still gives the right results, it looks fishy; we also had one place that was comparing 0 which is effectively dead code. * src/qemu/qemu_migration.c (qemuMigrationPrepareAny): Fix dead code bug. Signed-off-by: Eric Blake ebl...@redhat.com --- Most of this is mechanical, but the change to qemuMigrationPrepareAny requires special care to ensure that checking for 0 instead of negative isn't introducing a bug on failure to start incoming migration. ACK. Looked fairly mechanical. Only thing I had to check was the goto cleanup going away in a few places and it was all correct. Thanks; pushed. -- Eric Blake eblake redhat com+1-919-301-3266 Libvirt virtualization library http://libvirt.org signature.asc Description: OpenPGP digital signature -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [v4 5/5] virsh: Add vshRebootShutdownModeCompleter
vshRebootShutdownModeCompleter returns available shutdown mode names. This can be used for --mode auto completion for commands such as reboot or shutdown. for example: virsh # reboot --mode TAB acpi agentinitctl signal virsh # reboot --mode iTAB virsh # reboot --mode initctl --- v3 * removed useless if * used virStringFreeList() instead of iteration * moved all .completer = vshRebootShutdownModeCompleter initializations into this patch v4 * rewritten using virStringSplit() tools/virsh-domain.c | 6 -- tools/virsh.c| 6 ++ tools/virsh.h| 1 + 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c index 1406d2e..69014dd 100644 --- a/tools/virsh-domain.c +++ b/tools/virsh-domain.c @@ -4801,7 +4801,8 @@ static const vshCmdOptDef opts_shutdown[] = { }, {.name = mode, .type = VSH_OT_STRING, - .help = N_(shutdown mode: acpi|agent|initctl|signal) + .help = N_(shutdown mode: acpi|agent|initctl|signal), + .completer = vshRebootShutdownModeCompleter }, {.name = NULL} }; @@ -4889,7 +4890,8 @@ static const vshCmdOptDef opts_reboot[] = { }, {.name = mode, .type = VSH_OT_STRING, - .help = N_(shutdown mode: acpi|agent|initctl|signal) + .help = N_(shutdown mode: acpi|agent|initctl|signal), + .completer = vshRebootShutdownModeCompleter }, {.name = NULL} }; diff --git a/tools/virsh.c b/tools/virsh.c index cb89187..7e7a0d5 100644 --- a/tools/virsh.c +++ b/tools/virsh.c @@ -2636,6 +2636,12 @@ vshSuspendTargetCompleter(unsigned int unused_flags ATTRIBUTE_UNUSED) return virStringSplit(mem disk hybrid, , 0); } +char ** +vshRebootShutdownModeCompleter(unsigned int unused_flags ATTRIBUTE_UNUSED) +{ +return virStringSplit(acpi agent initctl signal, , 0); +} + #ifdef USE_READLINE /* - diff --git a/tools/virsh.h b/tools/virsh.h index c8e3d38..4763db3 100644 --- a/tools/virsh.h +++ b/tools/virsh.h @@ -260,6 +260,7 @@ struct _vshCmdGrp { char **vshDomainCompleter(unsigned int flags); char **vshSuspendTargetCompleter(unsigned int unused_flags); +char **vshRebootShutdownModeCompleter(unsigned int unused_flags); void vshError(vshControl *ctl, const char *format, ...) ATTRIBUTE_FMT_PRINTF(2, 3); -- 1.8.3.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [v4 4/5] virsh: Add vshSuspendTargetCompleter
vshSuspendTargetCompleter returns targets available for suspend. This completer can be used for the command option completion (for dompmsuspend, etc.). virsh # dompmsuspend --target TAB mem diskhybrid virsh # dompmsuspend --target hTAB virsh # dompmsuspend --target hybrid --- v2 * label cleanup renamed to error * vshSuspendTargetCompleter added to opts_dom_pm_suspend v3 * removed useless if * used virStringFreeList() instead of iteration v4 * rewritten using virStringSplit() tools/virsh-domain.c | 3 ++- tools/virsh.c| 6 ++ tools/virsh.h| 1 + 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c index 7747446..1406d2e 100644 --- a/tools/virsh-domain.c +++ b/tools/virsh-domain.c @@ -2796,7 +2796,8 @@ static const vshCmdOptDef opts_dom_pm_suspend[] = { .flags = VSH_OFLAG_REQ, .help = N_(mem(Suspend-to-RAM), disk(Suspend-to-Disk), -hybrid(Hybrid-Suspend)) +hybrid(Hybrid-Suspend)), + .completer = vshSuspendTargetCompleter }, {.name = NULL} }; diff --git a/tools/virsh.c b/tools/virsh.c index 271c841..cb89187 100644 --- a/tools/virsh.c +++ b/tools/virsh.c @@ -2630,6 +2630,12 @@ error: #endif } +char ** +vshSuspendTargetCompleter(unsigned int unused_flags ATTRIBUTE_UNUSED) +{ +return virStringSplit(mem disk hybrid, , 0); +} + #ifdef USE_READLINE /* - diff --git a/tools/virsh.h b/tools/virsh.h index 845fc17..c8e3d38 100644 --- a/tools/virsh.h +++ b/tools/virsh.h @@ -259,6 +259,7 @@ struct _vshCmdGrp { }; char **vshDomainCompleter(unsigned int flags); +char **vshSuspendTargetCompleter(unsigned int unused_flags); void vshError(vshControl *ctl, const char *format, ...) ATTRIBUTE_FMT_PRINTF(2, 3); -- 1.8.3.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH v2 1/5] cpu_models: add new public API
On 09/10/2013 08:38 AM, Daniel P. Berrange wrote: On Sat, Sep 07, 2013 at 01:11:22AM +0200, Giuseppe Scrivano wrote: The new function virConnectGetCPUModelNames allows to retrieve the list of CPU models known by the hypervisor for a specific architecture. Signed-off-by: Giuseppe Scrivano gscri...@redhat.com --- include/libvirt/libvirt.h.in | 18 + python/generator.py | 1 + src/cpu/cpu.c| 64 src/cpu/cpu.h| 3 +++ src/driver.h | 7 + src/libvirt.c| 47 src/libvirt_private.syms | 1 + src/libvirt_public.syms | 5 tools/virsh-host.c | 48 + tools/virsh.pod | 5 It is preferrable to have virsh changes separate from the public API addition. Likewise I'd suggest th src/cpu/ changes be a separate patch. I can go either way regarding virsh + libvirt.c - virsh changes at the same time as the public API prove that the public API is usable from a coding perspective. Git history says we've done both approaches in the past. But I totally agree that libvirt.c + src/cpu should be separate; committing the API first and then adding the implementation makes for a nice division. -- Eric Blake eblake redhat com+1-919-301-3266 Libvirt virtualization library http://libvirt.org signature.asc Description: OpenPGP digital signature -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [v4 0/5] virsh: More intelligent auto-completion
This series implements advanced auto-completion for virsh. Using custom option completers (examples in 3/5, 4/5 and 5/5), it is possible to further complete any option with defined completer function. Option completer function should return list of completed names for each desired option. Using C99 initialization, it is easy to enable specific completer for any option. For example, when we want domain completer for start --domain option, we write vshDomainCompleter() and along with desired flags, initialize targeted opts struct. static const vshCmdOptDef opts_start[] = { {.name = domain, .type = VSH_OT_DATA, .flags = VSH_OFLAG_REQ, .help = N_(name of the inactive domain), .completer = vshDomainCompleter, .completer_flags = VIR_CONNECT_LIST_DOMAINS_INACTIVE | VIR_CONNECT_LIST_DOMAINS_PERSISTENT }, Auto-completion itself then works like this: virsh # start --domain TAB domain1 domain2 domainN virsh # vol-key TAB --help --pool --vol vol1 vol2 --- v4: * rewritten to use only option completers v3: https://www.redhat.com/archives/libvir-list/2013-August/msg01294.html v2: https://www.redhat.com/archives/libvir-list/2013-August/msg00992.html v1: https://www.redhat.com/archives/libvir-list/2013-August/msg00371.html Tomas Meszaros (5): virsh: Add vshCmdCompleter and vshOptCompleter virsh: Improve readline generators and readline completion virsh: Add vshDomainCompleter virsh: Add vshSuspendTargetCompleter virsh: Add vshRebootShutdownModeCompleter tools/virsh-domain-monitor.c | 52 +-- tools/virsh-domain.c | 310 +- tools/virsh-snapshot.c | 50 +-- tools/virsh.c| 350 +++ tools/virsh.h| 8 + 5 files changed, 648 insertions(+), 122 deletions(-) -- 1.8.3.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH] Add some notes about security considerations when using LXC
On 09/10/2013 04:43 AM, Daniel P. Berrange wrote: From: Daniel P. Berrange berra...@redhat.com Describe some of the issues to be aware of when configuring LXC guests with security isolation as a goal. Signed-off-by: Daniel P. Berrange berra...@redhat.com --- docs/drvlxc.html.in | 93 + 1 file changed, 93 insertions(+) (This appears to be the patch promised here [1], but the original cc doesn't show evidence of it reaching Chen: https://www.redhat.com/archives/libvir-list/2013-September/msg00474.html) diff --git a/docs/drvlxc.html.in b/docs/drvlxc.html.in index 1e6aa1d..dd2e93c 100644 --- a/docs/drvlxc.html.in +++ b/docs/drvlxc.html.in @@ -168,6 +168,99 @@ Further block or character devices will be made available to containers depending on their configuration. /p +h2a name=securitySecurity considerations/a/h2 + +p +The libvirt LXC driver is fairly flexible in how it can be configured, +and as such does not enforce a requirement for strict security +separation between a container and the host. This allows it to be used +in scenarios where only resource control capabilities are important, +and resource sharing is desired. Applications wishing to ensure secure +isolation between a container and the host must ensure that they are +writing a suitable configuration s/$/./ +/p + +h3a name=securenetworkingNetwork isolation/a/h3 + +p +If the guest configuration does not list any network interfaces, +the codenetwork/code namespace will not be activated, and thus +the container will see all the host's network interfaces. This will +allow apps in the container to bind to/connect from TCP/UDP addresses +and ports from the host OS. It also allows applications to access +UNIX domain sockets associated with the host OS. +/p + +p +It should be noted that codesystemd/code has a UNIX domain socket +hich is used for communication by codesystemctl/code. Thus, with a s/hich/which/ +container that shares the host's network namespace, it will be possible +for a user in the container to invoke operations on codesystemd/code +in the same way it could if outside the container. In particular this +would allow coderoot/code in the container to do anything including +shutting down the host OS. If this is not desired, then applications +should either specify the UID/GID mapping in the configuration to enable +user namespaces, or should set the codelt;privnet/gt;/code flag +in the codelt;featuresgt;lt;/featuresgt;/code element. +/p + + +h3a name=securefsFilesystem isolation/a/h3 + +p +If the guest confuguration does not list any filesystems, then s/confuguration/configuration/ +the container will be setup with a root filesystem that matches s/setup/set up/ +the host's root filesystem. As noted earlier, only a few locations +such as code/dev/code, code/proc/code and code/sys/code +will be altered. This means that, in the absence of restrictions +from sVirt, a process running as user/group N:M inside the container +will be able to access alnmost exactly the same files as a process s/alnmost/almost/ +running as user/group N:M in the host. +/p + +p +There are multiple options for restricting this. It is possible to +simply map the existing root filesystem through to the container in +read-only mode. Alternatively a completely separate root filesystem +can be configured for the guest. In both cases, further sub-mounts +can be applied to customize the content that is made visible. Note +that in the absence of sVirt controls, it is still possible for the +root user in a container to unmount any sub-mounts applied. The user +namespace feature can also be used to restrict access to files based +on the UID/GID mappings. +/p + +h3a name=secureusersUser and group isolation/a/h3 + +p +If the guest configuration does not list any ID mapping, then the +user and group IDs used inside the container will match those used +outside the container. In addition, the capabilities associated with +a process in the container will infer the same privileges they would +for a process in the host. This has obvious implications for security, +since a root user inside the container will be able to access any +file owned by root that is visible to the container, and perform more +or less any privileged kernel operation. In the absence of additional +protection from sVirt, this means that the root user inside a container +is effectively as powerful as the root user in the host. There is no +security isolation of the root user. +/p + +p +The ID mapping facility was introduced to allow for stricter control +over the privileges of users inside the container. It allows apps to +define rules such as user ID 0 in the container maps to user ID 1000 +in the host. In addition the privileges associated with capabilities +are somewhat reduced so that they can not be used to escape from the +container
Re: [libvirt] [PATCH] Fix cgroups when all are mounted on /sys/fs/cgroup
On 09/10/2013 07:35 AM, Daniel P. Berrange wrote: From: Daniel P. Berrange berra...@redhat.com Some users in Ubuntu/Debian seem to have a setup where all the cgroup controllers are mounted on /sys/fs/cgroup rather than any /sys/fs/cgroup/controller name. In the loop which detects which controllers are present for a mount point we were modifying 'mnt_dir' field in the 'struct mntent' var, but not always restoring the original value. This caused detection to break in the all-in-one mount setup. Fix that logic bug and add test case coverage for this mount setup. Signed-off-by: Daniel P. Berrange berra...@redhat.com --- src/util/vircgroup.c | 3 ++- tests/vircgroupmock.c | 42 --- tests/vircgrouptest.c | 55 +++ 3 files changed, 96 insertions(+), 4 deletions(-) @@ -398,7 +431,10 @@ FILE *fopen(const char *path, const char *mode) } if (STREQ(path, /proc/self/cgroup)) { if (STREQ(mode, r)) { -return fmemopen((void *)procselfcgroups, strlen(procselfcgroups), mode); +if (allinone) +return fmemopen((void *)procselfcgroupsallinone, strlen(procselfcgroupsallinone), mode); Maybe worth wrapping to avoid long lines; but that's trivial. ACK. -- Eric Blake eblake redhat com+1-919-301-3266 Libvirt virtualization library http://libvirt.org signature.asc Description: OpenPGP digital signature -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH 0/2] fix configure to require yajl if qemu is new enough
On 09/10/2013 11:43 AM, Jonathan Lebon wrote: I can confirm that configure now happily yells at me. Thanks, Thanks for testing. Jonathan - Original Message - Ping. On 09/05/2013 04:18 PM, Eric Blake wrote: After yet another debug session on IRC about failure to use qemu because yajl-devel wasn't installed, I came up with these patches. The first is just preparation (no change to generated code); and with the second, I validated that uninstalling yajl-devel and then trying to configure once again gives me the desired: checking for yajl_tree_parse in -lyajl... no configure: error: You must install the libyajl library headers to compile libvirt [I can't claim build-breaker or trivial rule for either of these patches, but as I am also the autoconf guru around here, I won't be surprised if the extent of other's reviews is yep, I installed it and it did what you said...] Given your test, I'm comfortable enough with this to have gone ahead and pushed it. -- Eric Blake eblake redhat com+1-919-301-3266 Libvirt virtualization library http://libvirt.org signature.asc Description: OpenPGP digital signature -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH 0/2] fix configure to require yajl if qemu is new enough
I can confirm that configure now happily yells at me. Thanks, Jonathan - Original Message - Ping. On 09/05/2013 04:18 PM, Eric Blake wrote: After yet another debug session on IRC about failure to use qemu because yajl-devel wasn't installed, I came up with these patches. The first is just preparation (no change to generated code); and with the second, I validated that uninstalling yajl-devel and then trying to configure once again gives me the desired: checking for yajl_tree_parse in -lyajl... no configure: error: You must install the libyajl library headers to compile libvirt [I can't claim build-breaker or trivial rule for either of these patches, but as I am also the autoconf guru around here, I won't be surprised if the extent of other's reviews is yep, I installed it and it did what you said...] And yes, I tested on RHEL 5 that it still works with autoconf 2.59. Eric Blake (2): build: avoid obsolete AC_HELP_STRING build: fix regression in requiring yajl for new enough qemu configure.ac| 221 +++- m4/virt-apparmor.m4 | 4 +- m4/virt-lib.m4 | 12 +-- m4/virt-selinux.m4 | 3 +- 4 files changed, 158 insertions(+), 82 deletions(-) -- Eric Blake eblake redhat com+1-919-301-3266 Libvirt virtualization library http://libvirt.org -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH] Update docs about user namespace for LXC
On 09/10/2013 03:08 AM, Daniel P. Berrange wrote: From: Daniel P. Berrange berra...@redhat.com Mention that user namespace can be enabled using the UID/GID mapping schema. Fix typo in link anchor for container args in domain XML docs. Signed-off-by: Daniel P. Berrange berra...@redhat.com --- docs/drvlxc.html.in | 14 +- docs/formatdomain.html.in | 2 +- 2 files changed, 6 insertions(+), 10 deletions(-) ACK. -- Eric Blake eblake redhat com+1-919-301-3266 Libvirt virtualization library http://libvirt.org signature.asc Description: OpenPGP digital signature -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] Help needed in simulating libvirt
Hi All, I'm need to simulate libvirt API's say to mock the libvirt API responses. (Actually I need to simulate qemu API's response). Because of my project needs I need to write this simulated libvirt server in Java. I believe the simulated libvirt can be written as java RPC which should capable to receive the client RPC request calls and by dispatcher we can dispatch to the simulated java functions. I searched for .x file to be used for generating server stubs but unfortunately .x files like remote_protocol.x, virnetprotocol.x, qemu_protocol.x and lxc_monitor_protocol.x are not containing any procedure for libvirt API's that exposed. Please let me know which files will have these exposed procedures and how can I use it in java, Also I'm not sure how to implement the ssl layer support for the libvirt server in java. I need to write a java server in such a way that python client should capable to create a connection with uri qemu+tls://systemip:port?no_tty=1. Also with the created connection object it should able to call the libvirt API's like getCapabilities, etc. Any help and ideas on this will be really helpful. Thanks in Advance, Arun V -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 2/2] storage: btrfs subvolumes for directory pools
This commit adds support for btrfs subvolumes as directory volumes. The directory storage pool can be used to manage btrfs subvolumes on an existing btrfs filesystem. The driver can create new blank subvolumes and snapshots of existing subvolumes as well as delete existing subvolumes. The subvolumes created are automatically made visible on the host side and can be attached to domains using the filesystem tags as defined in 'format domain' documentation. Subvolumes do not implement quotas at the moment because the current (btrfs-progs-0.20.rc1.20130501git7854c8b-4.fc20.x86_64) support for quota management in btrfs-progs is lacking the necessary features, for example it's not possible to see the quota assigned to a certain subvolume and usage information is only updated on syncfs(2). Quota support will be implemented once the tools gain the necessary features. Signed-off-by: Oskari Saarenmaa o...@ohmu.fi --- configure.ac | 25 ++- docs/schemas/storagevol.rng | 1 + docs/storage.html.in | 30 ++- libvirt.spec.in | 4 + src/conf/storage_conf.c | 3 + src/conf/storage_conf.h | 1 + src/storage/storage_backend.c | 15 +- src/storage/storage_backend_fs.c | 222 -- src/util/virstoragefile.c | 4 +- src/util/virstoragefile.h | 1 + tests/storagevolxml2xmlin/vol-btrfs-snapshot.xml | 13 ++ tests/storagevolxml2xmlin/vol-btrfs.xml | 9 + tests/storagevolxml2xmlout/vol-btrfs-snapshot.xml | 26 +++ tests/storagevolxml2xmlout/vol-btrfs.xml | 17 ++ tests/storagevolxml2xmltest.c | 2 + 15 files changed, 343 insertions(+), 30 deletions(-) create mode 100644 tests/storagevolxml2xmlin/vol-btrfs-snapshot.xml create mode 100644 tests/storagevolxml2xmlin/vol-btrfs.xml create mode 100644 tests/storagevolxml2xmlout/vol-btrfs-snapshot.xml create mode 100644 tests/storagevolxml2xmlout/vol-btrfs.xml diff --git a/configure.ac b/configure.ac index cdbe6cc..91b0a8d 100644 --- a/configure.ac +++ b/configure.ac @@ -1642,6 +1642,10 @@ AC_ARG_WITH([storage-sheepdog], [AS_HELP_STRING([--with-storage-sheepdog], [with Sheepdog backend for the storage driver @:@default=check@:@])], [],[with_storage_sheepdog=check]) +AC_ARG_WITH([storage-btrfs], + [AS_HELP_STRING([--with-storage-btrfs], +[with Btrfs backend for the storage driver @:@default=check@:@])], + [],[with_storage_btrfs=check]) if test $with_libvirtd = no; then with_storage_dir=no @@ -1854,6 +1858,24 @@ fi AM_CONDITIONAL([WITH_STORAGE_SHEEPDOG], [test $with_storage_sheepdog = yes]) +if test $with_storage_btrfs = yes || test $with_storage_btrfs = check; then + AC_PATH_PROG([BTRFS], [btrfs], [], [$PATH:/sbin:/usr/sbin]) + + if test $with_storage_btrfs = yes ; then +if test -z $BTRFS ; then AC_MSG_ERROR([We need btrfs -command for btrfs storage driver]) ; fi + else +if test -z $BTRFS ; then with_storage_btrfs=no ; fi +if test $with_storage_btrfs = check ; then with_storage_btrfs=yes ; fi + fi + + if test $with_storage_btrfs = yes ; then +AC_DEFINE_UNQUOTED([WITH_STORAGE_BTRFS], 1, [whether Btrfs backend for storage driver is enabled]) +AC_DEFINE_UNQUOTED([BTRFS],[$BTRFS],[Location of btrfs program]) + fi +fi +AM_CONDITIONAL([WITH_STORAGE_BTRFS], [test $with_storage_btrfs = yes]) + + LIBPARTED_CFLAGS= LIBPARTED_LIBS= @@ -1941,7 +1963,7 @@ AC_SUBST([DEVMAPPER_CFLAGS]) AC_SUBST([DEVMAPPER_LIBS]) with_storage=no -for backend in dir fs lvm iscsi scsi mpath rbd disk; do +for backend in dir fs lvm iscsi scsi mpath rbd disk btrfs; do if eval test \$with_storage_$backend = yes; then with_storage=yes break @@ -2663,6 +2685,7 @@ AC_MSG_NOTICE([ mpath: $with_storage_mpath]) AC_MSG_NOTICE([Disk: $with_storage_disk]) AC_MSG_NOTICE([ RBD: $with_storage_rbd]) AC_MSG_NOTICE([Sheepdog: $with_storage_sheepdog]) +AC_MSG_NOTICE([ Btrfs: $with_storage_btrfs]) AC_MSG_NOTICE([]) AC_MSG_NOTICE([Security Drivers]) AC_MSG_NOTICE([]) diff --git a/docs/schemas/storagevol.rng b/docs/schemas/storagevol.rng index 8bc5907..8814973 100644 --- a/docs/schemas/storagevol.rng +++ b/docs/schemas/storagevol.rng @@ -201,6 +201,7 @@ valueqed/value valuevmdk/value valuevpc/value + valuevolume/value /choice /define diff --git a/docs/storage.html.in b/docs/storage.html.in index 1181444..03018ab 100644 --- a/docs/storage.html.in +++ b/docs/storage.html.in @@ -119,12 +119,15 @@ h2a name=StorageBackendDirDirectory pool/a/h2 p A pool with a type of codedir/code provides the means to manage - files within a directory. The files can be fully allocated raw files, - sparsely allocated raw files, or one of the special disk
Re: [libvirt] [libvirt-php] bug in libvirt_domain_change_vcpus()
On 09/10/2013 10:09 AM, Daniel P. Berrange wrote: On Mon, Sep 09, 2013 at 06:51:54PM +0200, Michal Novotny wrote: Hi Olivier, this is not really a bug as it's intended. The libvirt_domain_change_vcpus() is not the same as (yet unimplemented) virDomainSetVcpus() API so it's not bug. I realize that naming could be a little confusing so if you like, feel free to rename libvirt_domain_change_vcpus() to libvirt_domain_xml_change_vcpus() as this API should be used to change number of vCPUS in the domain XML itself and implement libvirt_domain_set_vcpus() calling real virDomainSetVcpus() API function. That function is also buggy in that it will silently turn a transient guest into a persistent guest, which is almost certainly not what a caller would expect Daniel Thanks for information Daniel. You are correct. I did change the implementation to use virDomainSetVcpusFlags() API function instead. It's already committed to git [1]. Michal [1] http://libvirt.org/git/?p=libvirt-php.git;a=commit;h=cff010a36e382ee26c10a8e467d61de75a73639b -- Michal Novotny minov...@redhat.com, RHCE, Red Hat Virtualization | libvirt-php bindings | php-virt-control.org -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [v4 3/5] virsh: Add vshDomainCompleter
Function vshDomainCompler returns domains names which can be used by various virsh commands, for example: virsh # start --domain TAB fedora domain_foodomain_bar --- v2 * global variable __my_conn renamed to vshConn * @name is now const char * * label cleanup renamed to error v3 * removed useless if * used virStringFreeList() instead of iteration * added vshControl *vshCtl instead of virConnectPtr *vshConn because vshCtl is needed in order to call vshReconnect() * moved all .completer = vshDomainCompleter initializations from other patches into this v4 * vshControl *vshCtl marked static * changed vshMalloc to VIR_ALLOC_N * fixed link error if building without USE_READLINE * fixed @domains[] mem leak * vshDomainCompleter .completer and .completer_flags initializers are now only in cmdOptDef * reconnecting now takes place in the vshReadlineOptionsGenerator() and only just before auto-completion happens tools/virsh-domain-monitor.c | 52 ++-- tools/virsh-domain.c | 301 +-- tools/virsh-snapshot.c | 50 +-- tools/virsh.c| 55 tools/virsh.h| 2 + 5 files changed, 373 insertions(+), 87 deletions(-) diff --git a/tools/virsh-domain-monitor.c b/tools/virsh-domain-monitor.c index b29b82a..f00cdfa 100644 --- a/tools/virsh-domain-monitor.c +++ b/tools/virsh-domain-monitor.c @@ -310,7 +310,9 @@ static const vshCmdOptDef opts_dommemstat[] = { {.name = domain, .type = VSH_OT_DATA, .flags = VSH_OFLAG_REQ, - .help = N_(domain name, id or uuid) + .help = N_(domain name, id or uuid), + .completer = vshDomainCompleter, + .completer_flags = VIR_CONNECT_LIST_DOMAINS_ACTIVE }, {.name = period, .type = VSH_OT_DATA, @@ -434,7 +436,10 @@ static const vshCmdOptDef opts_domblkinfo[] = { {.name = domain, .type = VSH_OT_DATA, .flags = VSH_OFLAG_REQ, - .help = N_(domain name, id or uuid) + .help = N_(domain name, id or uuid), + .completer = vshDomainCompleter, + .completer_flags = VIR_CONNECT_LIST_DOMAINS_ACTIVE | +VIR_CONNECT_LIST_DOMAINS_INACTIVE }, {.name = device, .type = VSH_OT_DATA, @@ -489,7 +494,10 @@ static const vshCmdOptDef opts_domblklist[] = { {.name = domain, .type = VSH_OT_DATA, .flags = VSH_OFLAG_REQ, - .help = N_(domain name, id or uuid) + .help = N_(domain name, id or uuid), + .completer = vshDomainCompleter, + .completer_flags = VIR_CONNECT_LIST_DOMAINS_ACTIVE | +VIR_CONNECT_LIST_DOMAINS_INACTIVE }, {.name = inactive, .type = VSH_OT_BOOL, @@ -603,7 +611,10 @@ static const vshCmdOptDef opts_domiflist[] = { {.name = domain, .type = VSH_OT_DATA, .flags = VSH_OFLAG_REQ, - .help = N_(domain name, id or uuid) + .help = N_(domain name, id or uuid), + .completer = vshDomainCompleter, + .completer_flags = VIR_CONNECT_LIST_DOMAINS_ACTIVE | +VIR_CONNECT_LIST_DOMAINS_INACTIVE }, {.name = inactive, .type = VSH_OT_BOOL, @@ -708,7 +719,10 @@ static const vshCmdOptDef opts_domif_getlink[] = { {.name = domain, .type = VSH_OT_DATA, .flags = VSH_OFLAG_REQ, - .help = N_(domain name, id or uuid) + .help = N_(domain name, id or uuid), + .completer = vshDomainCompleter, + .completer_flags = VIR_CONNECT_LIST_DOMAINS_ACTIVE | +VIR_CONNECT_LIST_DOMAINS_INACTIVE }, {.name = interface, .type = VSH_OT_DATA, @@ -823,7 +837,9 @@ static const vshCmdOptDef opts_domcontrol[] = { {.name = domain, .type = VSH_OT_DATA, .flags = VSH_OFLAG_REQ, - .help = N_(domain name, id or uuid) + .help = N_(domain name, id or uuid), + .completer = vshDomainCompleter, + .completer_flags = VIR_CONNECT_LIST_DOMAINS_ACTIVE }, {.name = NULL} }; @@ -876,7 +892,10 @@ static const vshCmdOptDef opts_domblkstat[] = { {.name = domain, .type = VSH_OT_DATA, .flags = VSH_OFLAG_REQ, - .help = N_(domain name, id or uuid) + .help = N_(domain name, id or uuid), + .completer = vshDomainCompleter, + .completer_flags = VIR_CONNECT_LIST_DOMAINS_ACTIVE | +VIR_CONNECT_LIST_DOMAINS_RUNNING }, {.name = device, .type = VSH_OT_DATA, @@ -1059,7 +1078,10 @@ static const vshCmdOptDef opts_domifstat[] = { {.name = domain, .type = VSH_OT_DATA, .flags = VSH_OFLAG_REQ, - .help = N_(domain name, id or uuid) + .help = N_(domain name, id or uuid), + .completer = vshDomainCompleter, + .completer_flags = VIR_CONNECT_LIST_DOMAINS_ACTIVE | +VIR_CONNECT_LIST_DOMAINS_RUNNING }, {.name = interface, .type = VSH_OT_DATA, @@ -1136,7 +1158,9 @@ static const vshCmdOptDef opts_domblkerror[] = { {.name = domain, .type = VSH_OT_DATA, .flags =
Re: [libvirt] [PATCH] build: require libnl-3 if netcf uses it
ping; I'm debating about pushing this under the build-breaker rule On 09/04/2013 03:19 PM, Eric Blake wrote: Commits 9298bfb and f6c2951 both tried to make it possible to select the correct libnl (1 vs. 3) according to what netcf used, when both libraries are installed. This works to avoid libnl-3 when netcf used libnl-1. But on the converse side, if only libnl-1 development code is installed, while netcf uses libnl-3, then configure happily uses libnl-1 anyways, leading to a test failure: $ VIR_TEST_DEBUG=1 ./virdrivermoduletest TEST: virdrivermoduletest 1) Test driver network ... OK 2) Test driver storage ... OK 3) Test driver nodedev ... OK 4) Test driver secret ... OK 5) Test driver nwfilter... OK 6) Test driver interface ... lt-virdrivermoduletest: route/tc.c:973: rtnl_tc_register: Assertion `0' failed. Aborted It's much nicer to prevent this at configure time, by requiring that if we know what netcf used, then we want the same libnl version. As before, this can be bypassed by someone who knows what they are doing by setting LIBNL_CFLAGS (perhaps useful to the rare person where the build box has a different version of netcf than the installation box). * configure.ac (LIBNL): If we can prove netcf used libnl-3, then don't let configure succeed with libnl-1. Signed-off-by: Eric Blake ebl...@redhat.com --- configure.ac | 3 +++ 1 file changed, 3 insertions(+) diff --git a/configure.ac b/configure.ac index f853e03..9950e3e 100644 --- a/configure.ac +++ b/configure.ac @@ -2416,6 +2416,9 @@ if test $with_linux = yes; then fi done case $libnl_ldd:${LIBNL_CFLAGS+set} in +*libnl-3.so.*:) LIBNL_REQUIRED=3.0 ;; +esac +case $libnl_ldd:${LIBNL_CFLAGS+set} in *libnl.so.1*:) ;; *) PKG_CHECK_MODULES([LIBNL], [libnl-3.0], [ -- Eric Blake eblake redhat com+1-919-301-3266 Libvirt virtualization library http://libvirt.org signature.asc Description: OpenPGP digital signature -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH 0/2] fix configure to require yajl if qemu is new enough
Ping. On 09/05/2013 04:18 PM, Eric Blake wrote: After yet another debug session on IRC about failure to use qemu because yajl-devel wasn't installed, I came up with these patches. The first is just preparation (no change to generated code); and with the second, I validated that uninstalling yajl-devel and then trying to configure once again gives me the desired: checking for yajl_tree_parse in -lyajl... no configure: error: You must install the libyajl library headers to compile libvirt [I can't claim build-breaker or trivial rule for either of these patches, but as I am also the autoconf guru around here, I won't be surprised if the extent of other's reviews is yep, I installed it and it did what you said...] And yes, I tested on RHEL 5 that it still works with autoconf 2.59. Eric Blake (2): build: avoid obsolete AC_HELP_STRING build: fix regression in requiring yajl for new enough qemu configure.ac| 221 +++- m4/virt-apparmor.m4 | 4 +- m4/virt-lib.m4 | 12 +-- m4/virt-selinux.m4 | 3 +- 4 files changed, 158 insertions(+), 82 deletions(-) -- Eric Blake eblake redhat com+1-919-301-3266 Libvirt virtualization library http://libvirt.org signature.asc Description: OpenPGP digital signature -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [v4 2/5] virsh: Improve readline generators and readline completion
This patch is rather big and introduces several new functions, but I kept all new functions in the one patch because they are all connected together. I had to extend vshReadlineOptionsGenerator() a lot, so it is possible to fully complete options by calling appropriate opt-completer(). vshReadlineOptionsCompletionGenerator() is simple new function which is used only when we need to fully complete specific option, e.g.: virsh # vol-key --vol TAB --- v2 * vshMalloc is now used in vshDetermineCommandName * vshStrdup instead of vshMalloc + snprintf * joined if's in vshReadlineOptionsCompletionGenerator v3 * fixed typo * removed useless if's v4 * rewritten so we can use only option completers instead of cmd+opt completers * added --help auto-completion tools/virsh.c | 283 +++--- 1 file changed, 251 insertions(+), 32 deletions(-) diff --git a/tools/virsh.c b/tools/virsh.c index bf2fbf8..321ed5d 100644 --- a/tools/virsh.c +++ b/tools/virsh.c @@ -2587,6 +2587,118 @@ vshCloseLogFile(vshControl *ctl) * - */ +static const vshCmdDef * +vshDetermineCommandName(void) +{ +const vshCmdDef *cmd = NULL; +char *p; +char *cmdname; + +if (!(p = strchr(rl_line_buffer, ' '))) +return NULL; + +cmdname = vshMalloc(NULL, (p - rl_line_buffer) + 1); +memcpy(cmdname, rl_line_buffer, p - rl_line_buffer); + +cmd = vshCmddefSearch(cmdname); +VIR_FREE(cmdname); + +return cmd; +} + +/* + * Check if option with opt_name is already fully completed. + */ +static bool +vshOptFullyCompleted(const char *opt_name) +{ +const vshCmdDef *cmd = NULL; +char *completed_name = NULL; +char **completed_list = NULL; +size_t completed_list_index; +size_t opts_index = 0; +bool opt_fully_completed = false; + +if (!opt_name) +return opt_fully_completed; + +cmd = vshDetermineCommandName(); + +if (!cmd) +return opt_fully_completed; + +while (cmd-opts[opts_index].name) { +const vshCmdOptDef *opt = cmd-opts[opts_index]; +opts_index++; + +if (!STREQ(opt-name, opt_name) || !opt-completer) +continue; + +completed_list_index = 0; +completed_list = opt-completer(opt-completer_flags); + +if (!completed_list) +continue; + +while ((completed_name = completed_list[completed_list_index])) { +completed_list_index++; +if (strstr(rl_line_buffer, completed_name)) +opt_fully_completed = true; +} +virStringFreeList(completed_list); +} +return opt_fully_completed; +} + +/* + * Return option which is present in the rl_line_buffer, but is not fully + * auto-completed (opt-completer() hasn't been used). + */ +static const vshCmdOptDef * +vshGetOptMissingCmp(void) +{ +const vshCmdDef *cmd = NULL; +char *opt_name_prefixed = NULL; +char *completed_name = NULL; +char **completed_list = NULL; +size_t completed_list_index; +size_t opts_index = 0; +bool opt_completed; + +cmd = vshDetermineCommandName(); + +if (!cmd) +return NULL; + +while (cmd-opts[opts_index].name) { +const vshCmdOptDef *opt = cmd-opts[opts_index]; +opts_index++; +opt_name_prefixed = vshMalloc(NULL, strlen(opt-name) + 3); +snprintf(opt_name_prefixed, strlen(opt-name) + 3, --%s, opt-name); + +if (strstr(rl_line_buffer, opt_name_prefixed) opt-completer) { +opt_completed = false; +completed_list_index = 0; +completed_list = opt-completer(opt-completer_flags); + +if (!completed_list) +continue; + +while ((completed_name = completed_list[completed_list_index])) { +completed_list_index++; +if (strstr(rl_line_buffer, completed_name)) +opt_completed = true; +} +virStringFreeList(completed_list); + +if (!opt_completed) +return opt; +} +} + +return NULL; +} + /* * Generator function for command completion. STATE lets us * know whether to start from scratch; without any state @@ -2631,28 +2743,27 @@ vshReadlineCommandGenerator(const char *text, int state) return NULL; } +/* + * Generator function for option completion. Provides --option name + * auto-completion and also advanced option completion by using opt-completer() + * functions. + */ static char * vshReadlineOptionsGenerator(const char *text, int state) { -static int list_index, len; -static const vshCmdDef *cmd = NULL; -const char *name; +static int opt_list_index, completed_list_index, len; +static char **completed_list; +static bool help_completed; +static const vshCmdDef *cmd; +char *opt_name_prefixed = NULL; +char *completed_name = NULL; if (!state) { -/* determine command name */ -char *p; -
[libvirt] [PATCH 1/2] virFileFsType: get filesystem type of a given path
This can be used by storage pools to figure out which actions are available on various paths (for example subvolumes when running on btrfs.) Signed-off-by: Oskari Saarenmaa o...@ohmu.fi --- src/libvirt_private.syms | 1 + src/util/virfile.c | 47 +++ src/util/virfile.h | 1 + 3 files changed, 49 insertions(+) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 35f0f1b..d0238cf 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1370,6 +1370,7 @@ virFileExists; virFileFclose; virFileFdopen; virFileFindMountPoint; +virFileFsType; virFileHasSuffix; virFileIsAbsPath; virFileIsDir; diff --git a/src/util/virfile.c b/src/util/virfile.c index feac3c9..44871d6 100644 --- a/src/util/virfile.c +++ b/src/util/virfile.c @@ -1133,6 +1133,45 @@ cleanup: return ret; } +/* search /proc/mounts for the filesystem type of the given path; + * return pointer to malloc'ed string of type if found, otherwise + * return NULL. + */ +char * +virFileFsType(const char *path) +{ +FILE *f; +struct mntent mb; +char mntbuf[1024]; +char *real = NULL, *ret = NULL; +size_t lookup_len, longest = 0; + +if ((real = realpath(path, NULL)) == NULL) +return NULL; +lookup_len = strlen(real); + +f = setmntent(/proc/mounts, r); +if (!f) { +VIR_FREE(real); +return NULL; +} + +while (getmntent_r(f, mb, mntbuf, sizeof(mntbuf))) { +size_t mnt_dir_len = strlen(mb.mnt_dir); +if (lookup_len = mnt_dir_len mnt_dir_len = longest) { +if (memcmp(mb.mnt_dir, real, mnt_dir_len) == 0) { +longest = mnt_dir_len; +VIR_FREE(ret); +ignore_value(VIR_STRDUP_QUIET(ret, mb.mnt_type)); +} +} +} +endmntent(f); +VIR_FREE(real); + +return ret; +} + #else /* defined HAVE_MNTENT_H defined HAVE_GETMNTENT_R */ char * @@ -1143,6 +1182,14 @@ virFileFindMountPoint(const char *type ATTRIBUTE_UNUSED) return NULL; } +char * +virFileFsType(const char *path) +{ +errno = ENOSYS; + +return NULL; +} + #endif /* defined HAVE_MNTENT_H defined HAVE_GETMNTENT_R */ int diff --git a/src/util/virfile.h b/src/util/virfile.h index 72d35ce..3c01247 100644 --- a/src/util/virfile.h +++ b/src/util/virfile.h @@ -221,6 +221,7 @@ int virFileOpenTty(int *ttymaster, int rawmode); char *virFileFindMountPoint(const char *type); +char *virFileFsType(const char *path); void virFileWaitForDevices(void); -- 1.8.3.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCHv2 RESEND] Add forwarders attribute to dns / element.
Useful to set custom forwarders instead of using the contents of /etc/resolv.conf. It helps me to setup dnsmasq as local nameserver to resolv VM domain names from domain 0, when domain option is used. Signed-off-by: Diego Woitasen diego.woita...@vhgroup.net --- docs/formatnetwork.html.in | 8 docs/schemas/network.rng | 5 +++ src/conf/network_conf.c| 43 -- src/conf/network_conf.h| 2 + src/network/bridge_driver.c| 8 .../nat-network-dns-forwarders.conf| 16 .../nat-network-dns-forwarders.xml | 12 ++ tests/networkxml2conftest.c| 1 + 8 files changed, 92 insertions(+), 3 deletions(-) create mode 100644 tests/networkxml2confdata/nat-network-dns-forwarders.conf create mode 100644 tests/networkxml2confdata/nat-network-dns-forwarders.xml diff --git a/docs/formatnetwork.html.in b/docs/formatnetwork.html.in index e1482db..4dd809a 100644 --- a/docs/formatnetwork.html.in +++ b/docs/formatnetwork.html.in @@ -631,6 +631,8 @@ lt;domain name=example.com/gt; lt;dnsgt; lt;txt name=example value=example value /gt; + lt;forwarders addr=8.8.8.8 /gt; + lt;forwarders addr=8.8.4.4 /gt; lt;srv service='name' protocol='tcp' domain='test-domain-name' target='.' port='1024' priority='10' weight='10'/gt; lt;host ip='192.168.122.2'gt; lt;hostnamegt;myhostlt;/hostnamegt; @@ -685,6 +687,12 @@ Currently supported sub-elements of codelt;dnsgt;/code are: dl + dtcodeforwarders/code/dt + ddA codedns/code element can have 0 or more codeforwarders/code elements. +Each forwarders element defines an IP address to be used as forwarder +in DNS server configuration. The addr attribute is required and defines the +IP address of every forwarder. span class=sinceSince N/A/span + /dd dtcodetxt/code/dt ddA codedns/code element can have 0 or more codetxt/code elements. Each txt element defines a DNS TXT record and has two attributes, both diff --git a/docs/schemas/network.rng b/docs/schemas/network.rng index ab183f1..e0c2b51 100644 --- a/docs/schemas/network.rng +++ b/docs/schemas/network.rng @@ -217,6 +217,11 @@ /attribute /optional zeroOrMore +element name=forwarders + attribute name=addrref name=ipAddr//attribute +/element + /zeroOrMore + zeroOrMore element name=txt attribute name=nameref name=dnsName//attribute attribute name=valuetext//attribute diff --git a/src/conf/network_conf.c b/src/conf/network_conf.c index d54f2aa..1c1aa64 100644 --- a/src/conf/network_conf.c +++ b/src/conf/network_conf.c @@ -175,6 +175,11 @@ virNetworkDNSSrvDefClear(virNetworkDNSSrvDefPtr def) static void virNetworkDNSDefClear(virNetworkDNSDefPtr def) { +if (def-forwarders) { +while (def-nfwds) +VIR_FREE(def-forwarders[--def-nfwds]); +VIR_FREE(def-forwarders); +} if (def-txts) { while (def-ntxts) virNetworkDNSTxtDefClear(def-txts[--def-ntxts]); @@ -1037,8 +1042,9 @@ virNetworkDNSDefParseXML(const char *networkName, xmlNodePtr *hostNodes = NULL; xmlNodePtr *srvNodes = NULL; xmlNodePtr *txtNodes = NULL; +xmlNodePtr *fwdNodes = NULL; char *forwardPlainNames = NULL; -int nhosts, nsrvs, ntxts; +int nfwds, nhosts, nsrvs, ntxts; size_t i; int ret = -1; xmlNodePtr save = ctxt-node; @@ -1058,6 +1064,30 @@ virNetworkDNSDefParseXML(const char *networkName, } } +nfwds = virXPathNodeSet(./forwarders, ctxt, fwdNodes); +if (nfwds 0) { +virReportError(VIR_ERR_XML_ERROR, + _(invalid forwarders element found in dns of network %s), + networkName); +goto cleanup; +} +if (nfwds 0) { +if (VIR_ALLOC_N(def-forwarders, nfwds) 0) +goto cleanup; + +for (i = 0; i nfwds; i++) { +def-forwarders[i] = virXMLPropString(fwdNodes[i], addr); +if (virSocketAddrParse(NULL, def-forwarders[i], AF_UNSPEC) 0) { +virReportError(VIR_ERR_XML_ERROR, + _(Invalid forwarder IP address '%s' + in network '%s'), + def-forwarders[i], networkName); +goto cleanup; +} +def-nfwds++; +} +} + nhosts = virXPathNodeSet(./host, ctxt, hostNodes); if (nhosts 0) { virReportError(VIR_ERR_XML_ERROR, @@ -1121,6 +1151,7 @@ virNetworkDNSDefParseXML(const char *networkName, ret = 0; cleanup:
Re: [libvirt] [Users] VNC/Spice console connection failure
On Tue, Sep 10, 2013 at 05:31:23PM +, SULLIVAN, Chris (WGK) wrote: Hi Itamar, BZ created: https://bugzilla.redhat.com/show_bug.cgi?id=1006490 Thanks, Thanks, but we cannot simply require libvirt 1.1.0, as it does not ship with F19. We need get a fix backported to F19, so that we can change our VNC password there. (Too bad we've been top-posting here. Now that I'm adding libvir-list I'm going to be cursed.) Chris -Original Message- From: Itamar Heim [mailto:ih...@redhat.com] Sent: Monday, September 09, 2013 8:36 PM To: SULLIVAN, Chris (WGK) Cc: us...@ovirt.org; Michal Skrivanek Subject: Re: [Users] VNC/Spice console connection failure On 09/09/2013 12:59 PM, SULLIVAN, Chris (WGK) wrote: Hi, Just to follow up on the below - updating to libvirt 1.1.2-1 from ftp://libvirt.org/libvirt/ has appeared to solve the issue. Console connections via noVNC work as expected. worth opening a bug to require that libvirt version as the minimal version? Cheers, Chris PLEASE CONSIDER THE ENVIRONMENT, DON'T PRINT THIS EMAIL UNLESS YOU REALLY NEED TO. This email and its attachments may contain information which is confidential and/or legally privileged. If you are not the intended recipient of this e-mail please notify the sender immediately by e-mail and delete this e-mail and its attachments from your computer and IT systems. You must not copy, re-transmit, use or disclose (other than to the sender) the existence or contents of this email or its attachments or permit anyone else to do so. - -Original Message- From: SULLIVAN, Chris (WGK) Sent: Monday, September 09, 2013 3:48 PM To: us...@ovirt.org Subject: RE: VNC/Spice console connection failure Hi, I am currently unable to connect to the console of a running VM through the Ovirt web interface. I get the following error (log extracts below): error : qemuDomainChangeGraphics:1873 : internal error cannot change listen address setting on vnc graphics I’m using Fedora 19, ovirt-engine 3.3.0-1, VDSM 4.12.1, qemu 1.4.2 and libvirt 1.0.5. I get a similar error when trying to use Spice. Has anyone come across this problem before, and if so, how to resolve? Based on some quick googling the versions of libvirt/qemu available in F19 do not allow changes to the listen address for a running VM. Should I rollback to a previous version? Kind regards, Chris Sullivan Senior Pipeline Engineer/Technical Development | J P Kenny ovirt-engine.log 2013-09-09 12:22:46,688 INFO [org.ovirt.engine.core.bll.SetVmTicketCommand] (ajp--127.0.0.1-8702-4) Running command: SetVmTicketCommand internal: false. Entities affected : ID: e69df488-ad50-4c8c-9f37-a63463a81702 Type: VM 2013-09-09 12:22:46,692 INFO [org.ovirt.engine.core.vdsbroker.vdsbroker.SetVmTicketVDSCommand] (ajp--127.0.0.1-8702-4) START, SetVmTicketVDSCommand(HostName = r410-02, HostId = d5df2e2b-509c-4b1c-902a-976b932d930b, vmId=e69df488-ad50-4c8c-9f37-a63463a81702, ticket=igRUBsYsw5ds, validTime=120,m userName=admin@internal, userId=fdfc627c-d875-11e0-90f0-83df133b58cc), log id: 53359174 2013-09-09 12:22:46,715 ERROR [org.ovirt.engine.core.vdsbroker.vdsbroker.SetVmTicketVDSCommand] (ajp--127.0.0.1-8702-4) Failed in SetVmTicketVDS method 2013-09-09 12:22:46,715 ERROR [org.ovirt.engine.core.vdsbroker.vdsbroker.SetVmTicketVDSCommand] (ajp--127.0.0.1-8702-4) Error code unexpected and error message VDSGenericException: VDSErrorException: Failed to SetVmTicketVDS, error = Unexpected exception 2013-09-09 12:22:46,716 INFO [org.ovirt.engine.core.vdsbroker.vdsbroker.SetVmTicketVDSCommand] (ajp--127.0.0.1-8702-4) Command org.ovirt.engine.core.vdsbroker.vdsbroker.SetVmTicketVDSCommand return value 2013-09-09 12:22:46,716 INFO [org.ovirt.engine.core.vdsbroker.vdsbroker.SetVmTicketVDSCommand] (ajp--127.0.0.1-8702-4) HostName = r410-02 2013-09-09 12:22:46,717 ERROR [org.ovirt.engine.core.vdsbroker.vdsbroker.SetVmTicketVDSCommand] (ajp--127.0.0.1-8702-4) Command SetVmTicketVDS execution failed. Exception: VDSErrorException: VDSGenericException: VDSErrorException: Failed to SetVmTicketVDS, error = Unexpected exception 2013-09-09 12:22:46,717 INFO [org.ovirt.engine.core.vdsbroker.vdsbroker.SetVmTicketVDSCommand] (ajp--127.0.0.1-8702-4) FINISH, SetVmTicketVDSCommand, log id: 53359174 2013-09-09 12:22:46,718 ERROR [org.ovirt.engine.core.bll.SetVmTicketCommand] (ajp--127.0.0.1-8702-4) Command org.ovirt.engine.core.bll.SetVmTicketCommand throw Vdc Bll exception. With error message VdcBLLException: org.ovirt.engine.core.vdsbroker.vdsbroker.VDSErrorException: VDSGenericException: VDSErrorException: Failed to SetVmTicketVDS, error = Unexpected exception (Failed with VDSM error unexpected and code 16) 2013-09-09 12:22:46,721 ERROR
Re: [libvirt] [Users] VNC/Spice console connection failure
On 09/10/2013 03:52 PM, Dan Kenigsberg wrote: On Tue, Sep 10, 2013 at 05:31:23PM +, SULLIVAN, Chris (WGK) wrote: Hi Itamar, BZ created: https://bugzilla.redhat.com/show_bug.cgi?id=1006490 Thanks, Thanks, but we cannot simply require libvirt 1.1.0, as it does not ship with F19. We need get a fix backported to F19, so that we can change our VNC password there. Can you pinpoint which libvirt commit fixed things, and then clone that vdsm bug to libvirt under Fedora 19? -- Eric Blake eblake redhat com+1-919-301-3266 Libvirt virtualization library http://libvirt.org signature.asc Description: OpenPGP digital signature -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH v2 1/5] cpu_models: add new public API
On 09/06/2013 05:11 PM, Giuseppe Scrivano wrote: The new function virConnectGetCPUModelNames allows to retrieve the list of CPU models known by the hypervisor for a specific architecture. Signed-off-by: Giuseppe Scrivano gscri...@redhat.com --- include/libvirt/libvirt.h.in | 18 + python/generator.py | 1 + src/cpu/cpu.c| 64 src/cpu/cpu.h| 3 +++ src/driver.h | 7 + src/libvirt.c| 47 src/libvirt_private.syms | 1 + src/libvirt_public.syms | 5 tools/virsh-host.c | 48 + tools/virsh.pod | 5 10 files changed, 199 insertions(+) In addition to Daniel's review, +++ b/include/libvirt/libvirt.h.in @@ -4006,6 +4006,24 @@ int virConnectCompareCPU(virConnectPtr conn, const char *xmlDesc, unsigned int flags); +/** + * virConnectGetCPUModelNames: + * + * @conn: virConnect connection + * @arch: Architecture + * @models: NULL terminated array of the CPU models supported for the specified + * architecture. Each element and the array itself must be freed by the caller + * with free. + * @flags: extra flags; not used yet, so callers should always pass 0. + * + * Get the list of supported CPU models for a specific architecture. + * + * Returns -1 on error, 0 on success. + */ +int virConnectGetCPUModelNames(virConnectPtr conn, + const char *arch, + char ***models, + unsigned int flags); Typically we have not documented functions in the .h, just in src/libvirt.c. +static int +cpuGetArchModelsCb(enum cpuMapElement element, + xmlXPathContextPtr ctxt, + void *cbdata) +{ +char *name; +struct cpuGetModelsData *data = cbdata; +if (element != CPU_MAP_ELEMENT_MODEL) +return 0; + +name = virXPathString(string(@name), ctxt); +if (name == NULL) +return -1; + +if (VIR_EXPAND_N(data-data, data-len, 1) 0) +return -1; + +data-data[data-len - 2] = name; +data-data[data-len - 1] = NULL; +return 0; VIR_INSERT_ELEMENT may be simpler to use than VIR_EXPAND_N. Furthermore, VIR_EXPAND_N guarantees zero-initialization of the growth, so the data-data[data-len - 1] = NULL; line is redundant. +int +virConnectGetCPUModelNames(virConnectPtr conn, const char *arch, char ***models, + unsigned int flags) +{ +VIR_DEBUG(conn=%p, arch=%s, flags=%x, conn, arch, flags); +virResetLastError(); + +if (!VIR_IS_CONNECT(conn)) { +virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__); +virDispatchError(NULL); +return -1; +} + +if (arch == NULL) { +virLibConnError(VIR_ERR_INVALID_ARG, __FUNCTION__); +goto error; +} virCheckNonNullArgReturn(arch, -1) + +if (conn-driver-connectGetCPUModelNames) { +if (conn-driver-connectGetCPUModelNames(conn, arch, models, flags) 0) +goto error; + +return 0; I agree with Dan that this should return the number of non-NULL entries (so setting the array to { x86_64, i686, NULL } would return 2, even though the array has allocated room for [at least] 3 pointers). +++ b/tools/virsh-host.c @@ -92,6 +92,25 @@ static const vshCmdOptDef opts_freecell[] = { {.name = NULL} }; +static const vshCmdInfo info_cpu_models[] = { +{.name = help, + .data = N_(CPU models.) We generally don't have trailing '.' in the short help. +}, +{.name = desc, + .data = N_(Get the CPU models for an arch.) +}, +{.name = NULL} +}; + +static const vshCmdOptDef opts_cpu_models[] = { +{.name = arch, + .type = VSH_OT_DATA, + .flags = VSH_OFLAG_REQ, + .help = N_(architecture) +}, +{.name = NULL} +}; + These new [] data should be closer... static bool cmdFreecell(vshControl *ctl, const vshCmd *cmd) { @@ -626,6 +645,29 @@ cmdURI(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED) return true; } +static bool +cmdCPUModelNames(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED) ...to the function they are associated with. (That is, don't split cmdFreecell from its options). +{ +char **models, **it; +const char *arch = NULL; + +if (vshCommandOptStringReq(ctl, cmd, arch, arch) 0) +return false; + +if (virConnectGetCPUModelNames(ctl-conn, arch, models, 0) 0) { +vshError(ctl, %s, _(failed to get CPU Models Names)); Sounds awkward; maybe failed to get CPU model names @@ -851,6 +893,12 @@ const vshCmdDef hostAndHypervisorCmds[] = { .info = info_capabilities, .flags = 0 }, +{.name = cpu-models, +
Re: [libvirt] [PATCH v2 3/5] cpu_models: add the support for qemu
On 09/06/2013 05:11 PM, Giuseppe Scrivano wrote: Signed-off-by: Giuseppe Scrivano gscri...@redhat.com --- src/qemu/qemu_driver.c | 14 ++ 1 file changed, 14 insertions(+) ACK. Would any of the drivers besides qemu and test benefit from an implementation? For example, does this work for libxl? -- Eric Blake eblake redhat com+1-919-301-3266 Libvirt virtualization library http://libvirt.org signature.asc Description: OpenPGP digital signature -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH v2 2/5] cpu_models: implement the remote protocol
On 09/06/2013 05:11 PM, Giuseppe Scrivano wrote: Signed-off-by: Giuseppe Scrivano gscri...@redhat.com --- daemon/remote.c | 47 +++ src/remote/remote_driver.c | 59 src/remote/remote_protocol.x | 20 ++- src/remote_protocol-structs | 11 + 4 files changed, 136 insertions(+), 1 deletion(-) In addition to Dan's comments: +++ b/src/remote/remote_driver.c +error: +rv = -1; +for (i = 0; i ret.models.models_len; i++) +VIR_FREE(ret.models.models_val[i]); +VIR_FREE(ret.models.models_val); Another virStringFreeList() -- Eric Blake eblake redhat com+1-919-301-3266 Libvirt virtualization library http://libvirt.org signature.asc Description: OpenPGP digital signature -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH v2 5/5] cpu_models: add Python bindings
On 09/06/2013 05:11 PM, Giuseppe Scrivano wrote: Signed-off-by: Giuseppe Scrivano gscri...@redhat.com --- python/generator.py | 2 +- python/libvirt-override-api.xml | 7 ++ python/libvirt-override.c | 56 + python/libvirt-override.py | 11 4 files changed, 75 insertions(+), 1 deletion(-) + +len = 0; +for (it = models; *it; it++) +len++; + +if ((rv = PyList_New(len)) == NULL) +goto error; + Again, the C return value should make it so you don't have to re-count len via 'it' yourself. +len = 0; +for (it = models; *it; it++){ Space before { +PyObject *str; +if ((str = PyString_FromString(*it)) == NULL) +goto error; + +PyList_SET_ITEM(rv, len++, str); +} + +done: +if (models) { +for (it = models; *it; it++) +VIR_FREE(*it); +VIR_FREE(models); +} + +return rv; + +error: +rv = VIR_PY_INT_FAIL; Ouch. Memory leak of the former value of rv. -- Eric Blake eblake redhat com+1-919-301-3266 Libvirt virtualization library http://libvirt.org signature.asc Description: OpenPGP digital signature -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH] docs, comments: minor typo fixes
On 09/10/2013 12:10 PM, Oskari Saarenmaa wrote: Signed-off-by: Oskari Saarenmaa o...@ohmu.fi --- 84 files changed, 97 insertions(+), 97 deletions(-) +++ b/docs/news.html.in @@ -13327,7 +13327,7 @@ and check the a href=http://libvirt.org/git/?p=libvirt.git;a=log;GIT log/a h30.1.5: Sep 5 2006/h3 ul liSupport for new hypercalls change in Xen changeset 86d26e6ec89b/li - libug fixes: virParseUUID() was wrong, netwoking for paravirt guestsi + libug fixes: virParseUUID() was wrong, networking for paravirt guestsi s/guestsi/guests/ - also, news.html.in is another awkward file that is generated from 'git shortlog' at release time; but I think DV only adds rather than rewriting old sections, so I made that change. +++ b/po/af.po @@ -20618,7 +20618,7 @@ msgstr #: src/test/test_driver.c:1992 #, c-format -msgid incomplete metdata in '%s' +msgid incomplete metadata in '%s' .po files must not be patched except as part of pulling new files from transifex (otherwise, the patch is just lost); all you need to patch is the original _(...) line. Fixing that greatly reduces the size of your patch :) ACK to all the other changes, and pushed. -- Eric Blake eblake redhat com+1-919-301-3266 Libvirt virtualization library http://libvirt.org signature.asc Description: OpenPGP digital signature -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 0/2] btrfs subvolume management
Moved btrfs subvolume management to storage_backend_fs.c instead of implementing it as a separate pool as suggested by Daniel P. Berrange in https://www.redhat.com/archives/libvir-list/2013-September/msg00316.html Oskari Saarenmaa (2): virFileFsType: get filesystem type of a given path storage: btrfs subvolumes for directory pools configure.ac | 25 ++- docs/schemas/storagevol.rng | 1 + docs/storage.html.in | 30 ++- libvirt.spec.in | 4 + src/conf/storage_conf.c | 3 + src/conf/storage_conf.h | 1 + src/libvirt_private.syms | 1 + src/storage/storage_backend.c | 15 +- src/storage/storage_backend_fs.c | 222 -- src/util/virfile.c| 47 + src/util/virfile.h| 1 + src/util/virstoragefile.c | 4 +- src/util/virstoragefile.h | 1 + tests/storagevolxml2xmlin/vol-btrfs-snapshot.xml | 13 ++ tests/storagevolxml2xmlin/vol-btrfs.xml | 9 + tests/storagevolxml2xmlout/vol-btrfs-snapshot.xml | 26 +++ tests/storagevolxml2xmlout/vol-btrfs.xml | 17 ++ tests/storagevolxml2xmltest.c | 2 + 18 files changed, 392 insertions(+), 30 deletions(-) -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH] docs, comments: minor typo fixes
Signed-off-by: Oskari Saarenmaa o...@ohmu.fi --- 84 files changed, 97 insertions(+), 97 deletions(-) diff --git a/ChangeLog-old b/ChangeLog-old index b5d44d5..e07b11c 100644 --- a/ChangeLog-old +++ b/ChangeLog-old @@ -5504,7 +5504,7 @@ Tue Nov 11 15:51:42 GMT 2008 Daniel P. Berrange berra...@redhat.com Mon Nov 10 12:05:42 GMT 2008 Daniel P. Berrange berra...@redhat.com - * src/openvz_conf.c: Read filesytem template name from config + * src/openvz_conf.c: Read filesystem template name from config files. Increase buffer size when parsing vzctl version number Thu Nov 6 20:45:42 CET 2008 Jim Meyering meyer...@redhat.com diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index f8bfe0b..d656836 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -254,7 +254,7 @@ to the (optional) ramdisk image in the host OS./dd dtcodecmdline/code/dt ddThe contents of this element specify arguments to be passed to -the kernel (or installer) at boottime. This is often used to +the kernel (or installer) at boot time. This is often used to specify an alternate primary console (eg serial port), or the installation media source / kickstart file/dd dtcodedtb/code/dt @@ -426,7 +426,7 @@ process and virtual CPUs can be specified separately by codecputune/code. If attribute codeemulatorpin/code of codecputune/code is specified, codecpuset/code -specified by codevcpu/code here will be ingored; Similarly, +specified by codevcpu/code here will be ignored; Similarly, For virtual CPUs which has codevcpupin/code specified, codecpuset/code specified by codecpuset/code here will be ignored; For virtual CPUs which doesn't have @@ -1235,7 +1235,7 @@ /tr tr tdrelaxed/td - tdRelax contstraints on timers/td + tdRelax constraints on timers/td td on, off/td tdspan class=since1.0.0 (QEMU only)/span/td /tr @@ -1358,7 +1358,7 @@ dd p The codetickpolicy/code attribute determines what -happens whens QEMU misses a deadline for injecting a +happens when QEMU misses a deadline for injecting a tick to the guest: /p dl @@ -2268,7 +2268,7 @@ dtcodereadonly/code/dt dd -Enables exporting filesytem as a readonly mount for guest, by +Enables exporting filesystem as a readonly mount for guest, by default read-write access is given (currently only works for QEMU/KVM driver). /dd @@ -2385,7 +2385,7 @@ h4a name=elementsControllersControllers/a/h4 p - Depending on the guest architecture, some device busses can + Depending on the guest architecture, some device buses can appear more than once, with a group of virtual devices tied to a virtual controller. Normally, libvirt can automatically infer such controllers without requiring explicit XML markup, but sometimes @@ -3773,7 +3773,7 @@ qemu-kvm -net nic,model=? /dev/null span class=sinceSince 1.1.0./span This uses the optional codenativeMode/code attribute on the codelt;taggt;/code element: codenativeMode/code may be set to 'tagged' or - 'untagged'. The id atribute of the element sets the native vlan. + 'untagged'. The id attribute of the element sets the native vlan. /p h5a name=elementLinkModifying virtual link state/a/h5 @@ -4134,7 +4134,7 @@ qemu-kvm -net nic,model=? /dev/null 9216, and codeheads/code with value 1. By default, the first video device in domain xml is the primary one, but the optional attribute codeprimary/code (span class=sincesince 1.0.2/span) -with value 'yes' can be used to mark the primary in cases of mutiple +with value 'yes' can be used to mark the primary in cases of multiple video device. The non-primary must be type of qxl. The optional attribute coderam/code (span class=sincesince 1.0.2/span) is allowed for qxl type only and specifies diff --git a/docs/formatnetwork.html.in b/docs/formatnetwork.html.in index 36c381a..63600b3 100644 --- a/docs/formatnetwork.html.in +++ b/docs/formatnetwork.html.in @@ -478,7 +478,7 @@ span class=sinceSince 1.1.0/span. This uses the optional codenativeMode/code attribute on the codelt;taggt;/code element: codenativeMode/code may be set to 'tagged' or - 'untagged'. The id atribute of the element sets the native vlan. + 'untagged'. The id attribute of the element sets the native vlan. /p p codelt;vlangt;/code elements can also be specified in @@ -591,7 +591,7 @@ This particular route would *not* be preferred if there was another existing rout on the system with the same address and prefix but with a lower value
Re: [libvirt] [libvirt-users] Help needed in simulating libvirt
On 09/10/2013 12:03 PM, Arun Viswanath wrote: Hi All, I'm need to simulate libvirt API's say to mock the libvirt API responses. (Actually I need to simulate qemu API's response). Because of my project needs I need to write this simulated libvirt server in Java. I believe the simulated libvirt can be written as java RPC which should capable to receive the client RPC request calls and by dispatcher we can dispatch to the simulated java functions. I searched for .x file to be used for generating server stubs but unfortunately .x files like remote_protocol.x, virnetprotocol.x, qemu_protocol.x and lxc_monitor_protocol.x are not containing any procedure for libvirt API's that exposed. Please let me know which files will have these exposed procedures and how can I use it in java, Rather than trying to write your own RPC handler, have you considered using the existing libvirt-java bindings and just targetting the test:/// URI connection? This will give you a fairly reliable exposure to the libvirt APIs, without actually needing a working qemu. The .x files implement the driver API; so also does the test driver. Basically, src/libvirt.c is the public API, which then delegates to the appropriate driver based on what URI you connected to; if the URI is remote (as qemu:/// and all other stateful drivers are), then libvirt.so passes it to src/remote/remote_driver.c to be bundled up into RPC calls which mirror the semantics of the public API. If you want to install your own mock driver, it may be easier to build a new URI and implement the same C interface as the test driver (see src/test/test_driver.c) than it is to implement your own RPC parser. Also I'm not sure how to implement the ssl layer support for the libvirt server in java. I need to write a java server in such a way that python client should capable to create a connection with uri qemu+tls://systemip:port?no_tty=1. Also with the created connection object it should able to call the libvirt API's like getCapabilities, etc. Again, instead of trying to write your own RPC server, I'd instead focus on utilizing the existing test:/// driver as your point of mocked calls. As this is mostly development-related, I've set the reply-to to libvir-list (we can drop libvirt-users from the rest of this thread). -- Eric Blake eblake redhat com+1-919-301-3266 Libvirt virtualization library http://libvirt.org signature.asc Description: OpenPGP digital signature -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH] virBitmapFree: Change the function to a macro
-Original Message- From: Eric Blake [mailto:ebl...@redhat.com] Sent: Tuesday, September 10, 2013 8:28 PM To: Liuji (Jeremy) Cc: Daniel P. Berrange; libvir-list@redhat.com; Jinbo (Justin); Luohao (brian); Haofeng Subject: Re: [libvirt] [PATCH] virBitmapFree: Change the function to a macro On 09/10/2013 02:29 AM, Liuji (Jeremy) wrote: Yes,it's an actual crash problem. I found the problem in the above problem scenario in my first mail. A problem scenario: 1) The XML of VM contain the below segment: numatune memory mode='preferred' placement='auto' nodeset='0'/ /numatune 2)virsh create the VM 3)In the virDomainDefParseXML funtion: /* Ignore 'nodeset' if 'placement' is 'auto' finally */ if (placement_mode == VIR_NUMA_TUNE_MEM_PLACEMENT_MODE_AUTO) { virBitmapFree(def-numatune.memory.nodemask); def-numatune.memory.nodemask = NULL; } 4)Then, virsh destroy the VM. In the virDomainDefFree funtion, it also call the virBitmapFree function to free the nodemask: virBitmapFree(def-numatune.memory.nodemask); Then can you send a patch which explicitly fixes that problem on its own, without doing this major refactoring, which obscures what is being fixed. I had sent a patch in my first mail. You can find the mail at the following links: https://www.redhat.com/archives/libvir-list/2013-September/msg00337.h tml No, I want the root cause fixed. This change to the bitmap APIs is just papering over any root cause bug. This is a simple problem about an address is released twice in some scenario. I think that released twice is the root cause. I'm not sure what you mean about root cause. Did you mean that why the address will be released two times? What we want is a patch against virDomainDefParseXML - if it frees the bitmap, it must set the bitmap member to NULL (ie. the root cause is step 3 of your trace above). That will then avoid the second free in virDomainDefFree (step 4 of your trace). The root cause is insidious because leaving the bitmap pointer non-NULL after freeing it means that ANY other use of the bitmap (not just the free in virDomainDefFree) is accessing freed memory. Creating a macro to avoid the double free is overkill; compared to fixing the real bug of freeing but not marking the memory freed. Thank you very much for your detailed advice. The following is the latest patch. From 234d8616dba9fa645146def8a8da2562f6b4802b Mon Sep 17 00:00:00 2001 From: Liuji (Jeremy) jeremy@huawei.com Date: Tue, 10 Sep 2013 22:13:32 -0400 Subject: [PATCH] virDomainDefParseXML: set the argument of virBitmapFree to NULL after calling virBitmapFree After freeing the bitmap pointer, it must set the pointer to NULL. This will avoid any other use of the freed memory of the bitmap pointer. Signed-off-by: Liuji (Jeremy) jeremy@huawei.com --- src/conf/domain_conf.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index e3aec69..9d1e9fc 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -11220,8 +11220,10 @@ virDomainDefParseXML(xmlDocPtr xml, } /* Ignore 'nodeset' if 'placement' is 'auto' finally */ -if (placement_mode == VIR_NUMA_TUNE_MEM_PLACEMENT_MODE_AUTO) +if (placement_mode == VIR_NUMA_TUNE_MEM_PLACEMENT_MODE_AUTO) { virBitmapFree(def-numatune.memory.nodemask); +def-numatune.memory.nodemask = NULL; +} /* Copy 'placement' of numatune to vcpu if its 'placement' * is not specified and 'placement' of numatune is specified. -- 1.8.1.4 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH] Add some notes about security considerations when using LXC
-Original Message- From: Daniel P. Berrange [mailto:berra...@redhat.com] Sent: Tuesday, September 10, 2013 6:44 PM To: libvir-list@redhat.com Cc: Chen Hanxiao; Daniel P. Berrange Subject: [PATCH] Add some notes about security considerations when using LXC From: Daniel P. Berrange berra...@redhat.com Describe some of the issues to be aware of when configuring LXC guests with security isolation as a goal. Signed-off-by: Daniel P. Berrange berra...@redhat.com --- docs/drvlxc.html.in | 93 + 1 file changed, 93 insertions(+) diff --git a/docs/drvlxc.html.in b/docs/drvlxc.html.in index 1e6aa1d..dd2e93c 100644 --- a/docs/drvlxc.html.in +++ b/docs/drvlxc.html.in @@ -168,6 +168,99 @@ Further block or character devices will be made available to containers depending on their configuration. /p +h2a name=securitySecurity considerations/a/h2 + +p +The libvirt LXC driver is fairly flexible in how it can be configured, +and as such does not enforce a requirement for strict security +separation between a container and the host. This allows it to be used +in scenarios where only resource control capabilities are important, +and resource sharing is desired. Applications wishing to ensure secure +isolation between a container and the host must ensure that they are +writing a suitable configuration /p + +h3a name=securenetworkingNetwork isolation/a/h3 + +p +If the guest configuration does not list any network interfaces, the +codenetwork/code namespace will not be activated, and thus the +container will see all the host's network interfaces. This will allow +apps in the container to bind to/connect from TCP/UDP addresses and +ports from the host OS. It also allows applications to access UNIX +domain sockets associated with the host OS. +/p + +p +It should be noted that codesystemd/code has a UNIX domain socket +hich is used for communication by codesystemctl/code. Thus, with a +container that shares the host's network namespace, it will be possible +for a user in the container to invoke operations on +codesystemd/code in the same way it could if outside the container. +In particular this would allow coderoot/code in the container to do +anything including shutting down the host OS. If this is not desired, +then applications should either specify the UID/GID mapping in the +configuration to enable user namespaces, or should set the +codelt;privnet/gt;/code flag in the codelt;featuresgt;lt;/featuresgt;/code element. +/p There might be too much spotlight on 'systemd'. Maybe users may think that this issue only came with systemd. Actually RHEL6.4GA without systemd still suffer from the reboot issue. Some apps like upstart can send reboot request to host via unix sockets. + + +h3a name=securefsFilesystem isolation/a/h3 + +p +If the guest confuguration does not list any filesystems, then the +container will be setup with a root filesystem that matches the host's +root filesystem. As noted earlier, only a few locations such as +code/dev/code, code/proc/code and code/sys/code will be +altered. This means that, in the absence of restrictions from sVirt, a +process running as user/group N:M inside the container will be able to +access alnmost exactly the same files as a process running as +user/group N:M in the host. +/p + +p +There are multiple options for restricting this. It is possible to +simply map the existing root filesystem through to the container in +read-only mode. Alternatively a completely separate root filesystem can +be configured for the guest. In both cases, further sub-mounts can be +applied to customize the content that is made visible. Note that in the +absence of sVirt controls, it is still possible for the root user in a +container to unmount any sub-mounts applied. The user namespace feature +can also be used to restrict access to files based on the UID/GID +mappings. +/p + +h3a name=secureusersUser and group isolation/a/h3 + +p +If the guest configuration does not list any ID mapping, then the user +and group IDs used inside the container will match those used outside +the container. In addition, the capabilities associated with a process +in the container will infer the same privileges they would for a +process in the host. This has obvious implications for security, since +a root user inside the container will be able to access any file owned +by root that is visible to the container, and perform more or less any +privileged kernel operation. In the absence of additional protection +from sVirt, this means that the root user inside a container is +effectively as powerful as the root user in the host. There is no +security isolation of the root user. +/p + +p +The ID mapping facility was introduced to allow for stricter control +over the privileges of users inside the container. It allows apps to +define rules such as user ID 0
Re: [libvirt] [PATCH] Add some notes about security considerations when using LXC
On 09/11/2013 10:33 AM, Chen Hanxiao wrote: -Original Message- From: Daniel P. Berrange [mailto:berra...@redhat.com] Sent: Tuesday, September 10, 2013 6:44 PM To: libvir-list@redhat.com Cc: Chen Hanxiao; Daniel P. Berrange Subject: [PATCH] Add some notes about security considerations when using LXC From: Daniel P. Berrange berra...@redhat.com Describe some of the issues to be aware of when configuring LXC guests with security isolation as a goal. Signed-off-by: Daniel P. Berrange berra...@redhat.com --- docs/drvlxc.html.in | 93 + 1 file changed, 93 insertions(+) diff --git a/docs/drvlxc.html.in b/docs/drvlxc.html.in index 1e6aa1d..dd2e93c 100644 --- a/docs/drvlxc.html.in +++ b/docs/drvlxc.html.in @@ -168,6 +168,99 @@ Further block or character devices will be made available to containers depending on their configuration. /p +h2a name=securitySecurity considerations/a/h2 + +p +The libvirt LXC driver is fairly flexible in how it can be configured, +and as such does not enforce a requirement for strict security +separation between a container and the host. This allows it to be used +in scenarios where only resource control capabilities are important, +and resource sharing is desired. Applications wishing to ensure secure +isolation between a container and the host must ensure that they are +writing a suitable configuration /p + +h3a name=securenetworkingNetwork isolation/a/h3 + +p +If the guest configuration does not list any network interfaces, the +codenetwork/code namespace will not be activated, and thus the +container will see all the host's network interfaces. This will allow +apps in the container to bind to/connect from TCP/UDP addresses and +ports from the host OS. It also allows applications to access UNIX +domain sockets associated with the host OS. +/p + +p +It should be noted that codesystemd/code has a UNIX domain socket +hich is used for communication by codesystemctl/code. Thus, with a +container that shares the host's network namespace, it will be possible +for a user in the container to invoke operations on +codesystemd/code in the same way it could if outside the container. +In particular this would allow coderoot/code in the container to do +anything including shutting down the host OS. If this is not desired, +then applications should either specify the UID/GID mapping in the +configuration to enable user namespaces, or should set the +codelt;privnet/gt;/code flag in the codelt;featuresgt;lt;/featuresgt;/code element. +/p There might be too much spotlight on 'systemd'. Maybe users may think that this issue only came with systemd. Actually RHEL6.4GA without systemd still suffer from the reboot issue. Some apps like upstart can send reboot request to host via unix sockets. Yes, there are two kinds of unix sockets(man 7 unix). one is abstract, this type of unix socket is net namespace aware, and upstarts use this type of unix socket to recv/send reboot message. So in this case, we should enable net namespace. the other one is pathname, this type is not net namespace aware, since it represents a file(inode), systemd uses this type of unix socket to recv/send reboot message. In this case, we should make sure the files aren't shared between host and container, for systemd, this file is /run/systemd/private. Ack for other parts of this doc. Thanks -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH v2] DBus: introduce virDBusIsServiceEnabled
This patch introduces virDBusIsServiceEnabled, we can use this method to get if the service is supported. In one case, if org.freedesktop.machine1 is unavailable on host, we should skip creating machine through systemd. Signed-off-by: Gao feng gaof...@cn.fujitsu.com --- src/util/virdbus.c| 66 +++ src/util/virdbus.h| 1 + src/util/virsystemd.c | 17 + 3 files changed, 73 insertions(+), 11 deletions(-) diff --git a/src/util/virdbus.c b/src/util/virdbus.c index 62c31be..ad3045a 100644 --- a/src/util/virdbus.c +++ b/src/util/virdbus.c @@ -1207,6 +1207,66 @@ int virDBusMessageRead(DBusMessage *msg, return ret; } +/** + * virDBusIsServiceEnabled: + * @name: service name + * + * Retruns 0 if service is available, -1 on fatal error, or -2 if service is not available + */ +int virDBusIsServiceEnabled(const char *name) +{ +DBusConnection *conn; +DBusMessage *reply = NULL; +DBusMessageIter iter, sub; +int ret = -1; + +if (!virDBusHasSystemBus()) +return -2; + +conn = virDBusGetSystemBus(); + +if (virDBusCallMethod(conn, + reply, + org.freedesktop.DBus, + /org/freedesktop/DBus, + org.freedesktop.DBus, + ListActivatableNames, + DBUS_TYPE_INVALID) 0) { + +virReportError(VIR_ERR_INTERNAL_ERROR, %s, + _(ListActivatableNames failed)); +return ret; +} + +if (!dbus_message_iter_init(reply, iter) || +dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_ARRAY) { + +virReportError(VIR_ERR_INTERNAL_ERROR, %s, + _(Reply message incorrect)); +goto cleanup; +} + +ret = -2; +dbus_message_iter_recurse(iter, sub); +while (dbus_message_iter_get_arg_type(sub) == DBUS_TYPE_STRING) { +const char *service = NULL; + +dbus_message_iter_get_basic(sub, service); +dbus_message_iter_next(sub); + +if (STREQ(service, name)) { +ret = 0; +break; +} +} + +VIR_DEBUG(Service %s is %s, name, ret ? unavailable : available); + + cleanup: +dbus_message_unref(reply); +return ret; +} + #else /* ! WITH_DBUS */ DBusConnection *virDBusGetSystemBus(void) @@ -1271,4 +1331,10 @@ int virDBusMessageDecode(DBusMessage* msg ATTRIBUTE_UNUSED, return -1; } +int virDBusIsServiceEnabled(const char *name ATTRIBUTE_UNUSED) +{ +VIR_DEBUG(DBus support not compiled into this binary); +return -2; +} + #endif /* ! WITH_DBUS */ diff --git a/src/util/virdbus.h b/src/util/virdbus.h index a5aab56..194a01a 100644 --- a/src/util/virdbus.h +++ b/src/util/virdbus.h @@ -45,4 +45,5 @@ int virDBusCallMethod(DBusConnection *conn, int virDBusMessageRead(DBusMessage *msg, const char *types, ...); +int virDBusIsServiceEnabled(const char *name); #endif /* __VIR_DBUS_H__ */ diff --git a/src/util/virsystemd.c b/src/util/virsystemd.c index 3e69ef6..7674cc6 100644 --- a/src/util/virsystemd.c +++ b/src/util/virsystemd.c @@ -138,18 +138,20 @@ int virSystemdCreateMachine(const char *name, bool iscontainer, const char *partition) { -int ret = -1; +int ret; DBusConnection *conn; char *machinename = NULL; char *creatorname = NULL; char *username = NULL; char *slicename = NULL; -if (!virDBusHasSystemBus()) -return -2; +ret = virDBusIsServiceEnabled(org.freedesktop.machine1); +if (ret 0) +return ret; conn = virDBusGetSystemBus(); +ret = -1; if (privileged) { if (virAsprintf(machinename, %s-%s, drivername, name) 0) goto cleanup; @@ -228,15 +230,8 @@ int virSystemdCreateMachine(const char *name, (unsigned int)pidleader, rootdir ? rootdir : , 1, Slice, s, - slicename) 0) { -virErrorPtr err = virGetLastError(); -if (err-code == VIR_ERR_DBUS_SERVICE -STREQ(err-str2, org.freedesktop.DBus.Error.ServiceUnknown)) { -virResetLastError(); -ret = -2; -} + slicename) 0) goto cleanup; -} ret = 0; -- 1.8.3.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH] Update docs about user namespace for LXC
On 09/10/2013 05:08 PM, Daniel P. Berrange wrote: From: Daniel P. Berrange berra...@redhat.com Mention that user namespace can be enabled using the UID/GID mapping schema. Fix typo in link anchor for container args in domain XML docs. Signed-off-by: Daniel P. Berrange berra...@redhat.com --- ACK docs/drvlxc.html.in | 14 +- docs/formatdomain.html.in | 2 +- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/docs/drvlxc.html.in b/docs/drvlxc.html.in index 640968f..1e6aa1d 100644 --- a/docs/drvlxc.html.in +++ b/docs/drvlxc.html.in @@ -40,15 +40,11 @@ primary host OS environment, the libvirt LXC driver requires that certain kernel namespaces are compiled in. Libvirt currently requires the 'mount', 'ipc', 'pid', and 'uts' namespaces to be available. If separate network interfaces are desired, then the 'net' namespace is -required. In the near future, the 'user' namespace will optionally be -supported. -/p - -p -strongNOTE: In the absence of support for the 'user' namespace, -processes inside containers cannot be securely isolated from host -process without the use of a mandatory access control technology -such as SELinux or AppArmor./strong +required. If the guest configuration declares a +a href=formatdomain.html#elementsOSContainerUID or GID mapping/a, +the 'user' namespace will be enabled to apply these. strongA suitably +configured UID/GID mapping is a pre-requisite to making containers +secure, in the absence of sVirt confinement./strong /p h2a name=initDefault container setup/a/h2 diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index f8bfe0b..971b059 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -263,7 +263,7 @@ span class=sinceSince 1.0.4/span/dd /dl -h4a name=eleemntsOSContainerContainer boot/a/h4 +h4a name=elementsOSContainerContainer boot/a/h4 p When booting a domain using container based virtualization, instead -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH] tools: add missing 'interface' type and update man page
Signed-off-by: Alex Jia a...@redhat.com --- tools/virt-xml-validate.in | 19 +++ 1 files changed, 19 insertions(+), 0 deletions(-) diff --git a/tools/virt-xml-validate.in b/tools/virt-xml-validate.in index 6bfa68f..8be9595 100644 --- a/tools/virt-xml-validate.in +++ b/tools/virt-xml-validate.in @@ -83,6 +83,9 @@ if [ -z $TYPE ]; then *secret*) TYPE=secret ;; + *interface*) +TYPE=interface +;; *) echo $0: cannot determine schema type for $XMLFILE 2 exit 3 @@ -124,6 +127,10 @@ Valid schema names currently include =over 4 +=item Cdomainsnapshot + +The schema for the XML format used by domain snapshot configuration + =item Cdomain The schema for the XML format used by guest domains configuration @@ -148,6 +155,18 @@ The schema for the XML format used by node device descriptions The schema for the XML format used to declare driver capabilities +=item Cnwfilter + +The schema for the XML format used by network traffic filters + +=item Csecret + +The schema for the XML format used by secrets descriptions + +=item Cinterface + +The schema for the XML format used by virtual interface + =back =head1 OPTIONS -- 1.7.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list