Re: [libvirt] [PATCH] rpc: Fix crash on error paths of message dispatching

2013-02-03 Thread Guido Günther
Hi Eric,
On Tue, Jan 29, 2013 at 02:21:30PM -0700, Eric Blake wrote:
 On 01/29/2013 01:22 PM, Guido Günther wrote:
  Hi,
  On Mon, Jan 28, 2013 at 07:35:38PM +0100, Peter Krempa wrote:
  When reading and dispatching of a message failed the message was freed
  but wasn't removed from the message queue.
 
  After that when the connection was about to be closed the pointer for
  the message was still present in the queue and it was passed to
  virNetMessageFree which tried to call the callback function from an
  uninitialized pointer.
  
  Debian stable is shipping 0.8.2. I checked and it seems this version
  isn't affected siince we properly remove the message from the queue
  before looking at it in daemon/libvirtd.c. I'd be great if somebody
  could double check though!
 
 0.8.2 predates the RPC rewrite, and I concur with your assessment that
 back then, the code was _always_ clearing the queue:
 
 v0.8.2:daemon/libvirtd.c:qemudDispatchClientRead():
 
 /* Grab the completed message */
 struct qemud_client_message *msg =
 qemudClientMessageQueueServe(client-rx);
 struct qemud_client_filter *filter;
 
 /* Decode the header so we can use it for routing decisions */
 if (remoteDecodeClientMessageHeader(msg)  0) {
 VIR_FREE(msg);
 qemudDispatchClientFailure(client);
 }
 
 However, it does look like there might be a missing 'return' statement
 after that error is reported, especially given that the next error
 reporting a few lines later does an early return.

Thanks for double checking. It indeed looks like there's a return
missing (cc:'ing the Debian bugreport to make this information permanent
there too).
Cheers,
 -- Guido

 But the best way to determine if this version is actually vulnerable to
 the CVE would be trying the exploit, and seeing if libvirtd survives
 with proper error logging about an invalid client request; Peter may
 have more details on how best to attempt that (although it may be better
 to discuss those details off-list, even if the CVE is already public, so
 that others are less likely to maliciously use the exploit).


 
 -- 
 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] build: Add libcurl dependency to libvirt_driver.la

2013-02-03 Thread Hu Tao
On Fri, Feb 01, 2013 at 01:45:19PM +0100, Jiri Denemark wrote:
 libvirt.c calls curl_global_init() if WITH_CURL is defined and thus it
 should be linked with libcurl. This fixes link failure in case neither
 xenapi nor esx driver is enabled (they are the only users of libcurl).

In the case we link with libcurl just because user wants it. How about
not exposing --with-curl but define WITH_CURL when needs to(xenapi or
esx driver is enabled, or both)?

-- 
Regards,
Hu Tao

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] How to connect to console of domain on PowerPC?

2013-02-03 Thread Yin Olivia-R63875
Hi,

I tried to use libvirt to run KVM/QEMU on Freescale PowerPC platforms.

So far there's only one serial device (spapr-vty) defined in QEMU to work as 
console for IBM PSeries platform.
There's no serial device support in QEMU for Freescale PowerPC (ePAPR).


libvirt/src/qemu/qemu_command.c

/* This function generates the correct '-device' string for character
 * devices of each architecture.
 */
char *
qemuBuildChrDeviceStr(virDomainChrDefPtr serial,
   virBitmapPtr qemuCaps,
   char *os_arch,
   char *machine)
{
virBuffer cmd = VIR_BUFFER_INITIALIZER;

if (STREQ(os_arch, ppc64)  STREQ(machine, pseries)) {
if (serial-deviceType == VIR_DOMAIN_CHR_DEVICE_TYPE_SERIAL 
serial-source.type == VIR_DOMAIN_CHR_TYPE_PTY 
serial-info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_SPAPRVIO) {
virBufferAsprintf(cmd, spapr-vty,chardev=char%s,
  serial-info.alias);
if (qemuBuildDeviceAddressStr(cmd, serial-info, qemuCaps)  0)
goto error;
}
} else
virBufferAsprintf(cmd, isa-serial,chardev=char%s,id=%s,
  serial-info.alias, serial-info.alias);

if (virBufferError(cmd)) {
virReportOOMError();
goto error;
}

return virBufferContentAndReset(cmd);

 error:
virBufferFreeAndReset(cmd);
return NULL;
}

We usually connect guest with telnet. 
For instance,
/usr/bin/qemu-system-ppc -name demo -M ppce500v2 -enable-kvm -m 256 -nographic 
-kernel /media/ram/uImage -initrd /media/ram/ramdisk -append root=/dev/ram rw 
console=ttyS0,115200 -serial tcp::4445,server

Then to run 'telnet 10.193.20.xxx 4445' could connect the guest.


The temporary workaround is not add '-device' string after '-serial' option.

diff -Nur libvirt-0.10.1.orig/src/qemu/qemu_command.c 
libvirt-0.10.1/src/qemu/qemu_command.c
--- libvirt-0.10.1.orig/src/qemu/qemu_command.c 2012-08-30 15:35:18.0 
+0530
+++ libvirt-0.10.1/src/qemu/qemu_command.c  2012-10-05 17:19:32.060368755 
+0530
@@ -5501,13 +5501,15 @@
 virCommandAddArg(cmd, devstr);
 VIR_FREE(devstr);

-virCommandAddArg(cmd, -device);
-if (!(devstr = qemuBuildChrDeviceStr(serial, qemuCaps,
+if (!STREQ(def-os.arch, ppc)) {
+virCommandAddArg(cmd, -device);
+if (!(devstr = qemuBuildChrDeviceStr(serial, 
+ qemuCaps,
  def-os.arch,
  def-os.machine)))
-   goto error;
-virCommandAddArg(cmd, devstr);
-VIR_FREE(devstr);
+goto error;
+virCommandAddArg(cmd, devstr);
+VIR_FREE(devstr);
+}
 } else {
 virCommandAddArg(cmd, -serial);
 if (!(devstr = qemuBuildChrArgStr(serial-source, NULL)))

Applying the above patch to libvirt, all the other domain control commands 
could work except 'virsh console domain'.

# cat demo.args EOF
 /usr/bin/qemu-system-ppc -name demo -M ppce500v2 -enable-kvm -m 256 
 -nographic -kernel /media/ram/uImage -initrd /media/ram/ramdisk 
 -append root=/dev/ram rw console=ttyS0,115200 -serial 
 tcp::4445,server -net nic EOF

# vi demo.args
/usr/bin/qemu-system-ppc -name demo -M ppce500v2 -enable-kvm -m 256 -nographic 
-kernel /media/ram/uImage -initrd /media/ram/ramdisk -append root=/dev/ram rw 
console=ttyS0,115200 -serial tcp::4445,server -net nic

# virsh domxml-from-native qemu-argv demo.args demo.xml # vi demo.xml domain 
type='kvm'
  namedemo/name
  uuid985d7154-83c8-0763-cbac-ecd159eee8a6/uuid
  memory unit='KiB'262144/memory
  currentMemory unit='KiB'262144/currentMemory
  vcpu placement='static'1/vcpu
  os
type arch='ppc' machine='ppce500v2'hvm/type
kernel/media/ram/uImage/kernel
initrd/media/ram/ramdisk/initrd
cmdlineroot=/dev/ram rw console=ttyS0,115200/cmdline
  /os
  clock offset='utc'/
  on_poweroffdestroy/on_poweroff
  on_rebootrestart/on_reboot
  on_crashdestroy/on_crash
  devices
emulator/usr/bin/qemu-system-ppc/emulator
serial type='tcp'
  source mode='bind' host='' service='4445'/
  protocol type='raw'/
  target port='0'/
/serial
console type='tcp'
  source mode='bind' host='' service='4445'/
  protocol type='raw'/
  target type='serial' port='0'/
/console
memballoon model='virtio'/
  /devices
/domain

# virsh -c qemu:///system define demo.xml # virsh -c qemu:///system start demo


But it seemed that can't connect to the console.
# virsh -c qemu:///system console demo
Connected to domain test
Escape character is ^]
error: internal error character device (null) is not using a PTY


I tried also use '-serial pty' option,
/usr/bin/qemu-system-ppc -name test -M ppce500v2 -enable-kvm -m 256 

[libvirt] A question about booting from the snapshot image by specifying snapshot id in Libvirt

2013-02-03 Thread harryxiyou
Hi all,

I test libvirt boots QEMU VM from Sheepdog snapshot image by specify
snapshot id like following.

1, $ collie vdi list
  NameIdSizeUsed  SharedCreation time   VDI id  Copies  Tag
  Alice1   10 GB  1.3 GB  0.0 MB 2013-02-01 18:59   15d167
2
s testvdi  1   20 MB   20 MB  0.0 MB 2013-02-02 11:45   f348ba
2  name
s testvdi  2   20 MB  0.0 MB   20 MB 2013-02-03 17:56   f348bb
2
  testvdi  3   20 MB   12 MB  8.0 MB 2013-02-03 17:58   f348bc 2

2, $ cat  sheepdog_vm1.xml
domain type='qemu'
nametestvm/name
memory1048576/memory
os
type arch='x86_64'hvm/type
/os
devices
disk type='network'
source protocol=sheepdog name=testvdi:1/
target dev='hda' bus='ide'/
/disk
graphics type='vnc' port='-1' autoport='yes'/
/devices
/domain

3, $ virsh create sheepdog_vm1.xml
domain testvm is created ( from sheepdog_vm1.xml)

4, $ virsh destroy testvm
domain testvm is deleted

5, $ collie vdi list
  NameIdSizeUsed  SharedCreation time   VDI id  Copies  Tag
  Alice1   10 GB  1.3 GB  0.0 MB 2013-02-01 18:59   15d167
2
s testvdi  1   20 MB   20 MB  0.0 MB 2013-02-02 11:45   f348ba
2  name
s testvdi  2   20 MB  0.0 MB   20 MB 2013-02-03 17:56   f348bb
2
s testvdi  3   20 MB   12 MB  8.0 MB 2013-02-03 17:58   f348bc
2
  testvdi  4   20 MB   12 MB  8.0 MB 2013-02-04 13:15   f348bd 2


My question is before i boot VM from sheepdog:testvdi:1, my vdi list like
  NameIdSizeUsed  SharedCreation time   VDI id  Copies  Tag
  Alice1   10 GB  1.3 GB  0.0 MB 2013-02-01 18:59   15d167
2
s testvdi  1   20 MB   20 MB  0.0 MB 2013-02-02 11:45   f348ba
2  name
s testvdi  2   20 MB  0.0 MB   20 MB 2013-02-03 17:56   f348bb
2
  testvdi  3   20 MB   12 MB  8.0 MB 2013-02-03 17:58   f348bc 2

However, after VM is destroied, my vdi list like
  NameIdSizeUsed  SharedCreation time   VDI id  Copies  Tag
  Alice1   10 GB  1.3 GB  0.0 MB 2013-02-01 18:59   15d167
2
s testvdi  1   20 MB   20 MB  0.0 MB 2013-02-02 11:45   f348ba
2  name
s testvdi  2   20 MB  0.0 MB   20 MB 2013-02-03 17:56   f348bb
2
s testvdi  3   20 MB   12 MB  8.0 MB 2013-02-03 17:58   f348bc
2
  testvdi  4   20 MB   12 MB  8.0 MB 2013-02-04 13:15   f348bd 2

There is another snapshot of testvdi created. I am not clear about why another
one is created? I just boot a VM from snapshot testvdi, which id is 1.

Could anyone please give me some suggestions? Thanks in advance ;-)


-- 
Thanks
Harry Wei

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

[libvirt] [PATCH v2 0/5] cgroup refactor

2013-02-03 Thread Hu Tao
This series refactors cgroup code to:

  - provide lazy creation of cgroup directories, despite of what
level they are.
  - remove cgroup directories if no one is using the corresponding
virCgroup.

This series is splitted in a manner for easier review. Patch 2 is
the main implementation. Patch 3, 4, 5 should have been squashed
into one in order to build, but harder to review.

Hu Tao (5):
  refactor virCgroupDetectMounts and virCgroupDetectPlacement
  cgroup: refactor virCgroup
  cgroup: replace old cgroup
  qemu: replace old cgroup
  lxc: replace old cgroup

 src/conf/domain_conf.h|5 +
 src/libvirt_private.syms  |7 +-
 src/lxc/lxc_cgroup.c  |   40 +-
 src/lxc/lxc_cgroup.h  |2 +-
 src/lxc/lxc_controller.c  |   31 +-
 src/lxc/lxc_driver.c  |  177 +++
 src/lxc/lxc_process.c |   19 +-
 src/qemu/qemu_cgroup.c|  162 +++---
 src/qemu/qemu_cgroup.h|3 +-
 src/qemu/qemu_driver.c|  351 +
 src/qemu/qemu_hotplug.c   |   21 +-
 src/qemu/qemu_migration.c |   20 +-
 src/qemu/qemu_process.c   |7 +-
 src/util/vircgroup.c  | 1263 +
 src/util/vircgroup.h  |   19 +-
 15 files changed, 921 insertions(+), 1206 deletions(-)

-- 
1.8.0.1.240.ge8a1f5a

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH v2 5/5] lxc: replace old cgroup

2013-02-03 Thread Hu Tao
---
 src/lxc/lxc_cgroup.c |  40 +++
 src/lxc/lxc_cgroup.h |   2 +-
 src/lxc/lxc_controller.c |  31 -
 src/lxc/lxc_driver.c | 177 +--
 src/lxc/lxc_process.c|  19 +++--
 5 files changed, 111 insertions(+), 158 deletions(-)

diff --git a/src/lxc/lxc_cgroup.c b/src/lxc/lxc_cgroup.c
index 1984c5f..d1a1f16 100644
--- a/src/lxc/lxc_cgroup.c
+++ b/src/lxc/lxc_cgroup.c
@@ -242,7 +242,7 @@ int virLXCCgroupGetMeminfo(virLXCMeminfoPtr meminfo)
 int ret;
 virCgroupPtr cgroup;
 
-ret = virCgroupGetAppRoot(cgroup);
+ret = virCgroupGetAppRoot(cgroup, true);
 if (ret  0) {
 virReportSystemError(-ret, %s,
  _(Unable to get cgroup for container));
@@ -469,53 +469,29 @@ cleanup:
 }
 
 
-int virLXCCgroupSetup(virDomainDefPtr def)
+int virLXCCgroupSetup(virCgroupPtr cgroup, virDomainDefPtr def)
 {
-virCgroupPtr driver = NULL;
-virCgroupPtr cgroup = NULL;
-int ret = -1;
 int rc;
 
-rc = virCgroupForDriver(lxc, driver, 1, 0);
-if (rc != 0) {
-virReportSystemError(-rc, %s,
- _(Unable to get cgroup for driver));
-goto cleanup;
-}
-
-rc = virCgroupForDomain(driver, def-name, cgroup, 1);
-if (rc != 0) {
-virReportSystemError(-rc,
- _(Unable to create cgroup for domain %s),
- def-name);
-goto cleanup;
-}
-
 if (virLXCCgroupSetupCpuTune(def, cgroup)  0)
-goto cleanup;
+return -1;
 
 if (virLXCCgroupSetupBlkioTune(def, cgroup)  0)
-goto cleanup;
+return -1;
 
 if (virLXCCgroupSetupMemTune(def, cgroup)  0)
-goto cleanup;
+return -1;
 
 if (virLXCCgroupSetupDeviceACL(def, cgroup)  0)
-goto cleanup;
+return -1;
 
 rc = virCgroupAddTask(cgroup, getpid());
 if (rc != 0) {
 virReportSystemError(-rc,
  _(Unable to add task %d to cgroup for domain 
%s),
  getpid(), def-name);
-goto cleanup;
+return -1;
 }
 
-ret = 0;
-
-cleanup:
-virCgroupFree(cgroup);
-virCgroupFree(driver);
-
-return ret;
+return 0;
 }
diff --git a/src/lxc/lxc_cgroup.h b/src/lxc/lxc_cgroup.h
index 97b94e5..cd02b46 100644
--- a/src/lxc/lxc_cgroup.h
+++ b/src/lxc/lxc_cgroup.h
@@ -26,7 +26,7 @@
 # include lxc_fuse.h
 # include virusb.h
 
-int virLXCCgroupSetup(virDomainDefPtr def);
+int virLXCCgroupSetup(virCgroupPtr cgroup, virDomainDefPtr def);
 int virLXCCgroupGetMeminfo(virLXCMeminfoPtr meminfo);
 
 int
diff --git a/src/lxc/lxc_controller.c b/src/lxc/lxc_controller.c
index 2673f72..4a7a63b 100644
--- a/src/lxc/lxc_controller.c
+++ b/src/lxc/lxc_controller.c
@@ -130,6 +130,8 @@ struct _virLXCController {
 int timerShutdown;
 
 virLXCFusePtr fuse;
+
+virCgroupPtr cgroup;
 };
 
 #include lxc_controller_dispatch.h
@@ -272,6 +274,8 @@ static void virLXCControllerFree(virLXCControllerPtr ctrl)
 
 VIR_FREE(ctrl-devptmx);
 
+virCgroupFree(ctrl-cgroup);
+
 virDomainDefFree(ctrl-def);
 VIR_FREE(ctrl-name);
 
@@ -548,6 +552,31 @@ static int 
virLXCControllerSetupCpuAffinity(virLXCControllerPtr ctrl)
 return 0;
 }
 
+static int virLXCControllerSetupCgroup(virLXCControllerPtr ctrl)
+{
+virCgroupPtr appCgroup = NULL;
+int rc;
+
+rc = virCgroupGetAppRoot(appCgroup, true);
+if (rc != 0) {
+virReportSystemError(-rc, %s,
+ _(Unable to get cgroup for libvirt));
+goto cleanup;
+}
+
+rc = virCgroupNew(lxc, appCgroup, ctrl-cgroup);
+if (rc != 0) {
+virReportSystemError(-rc, %s,
+ _(Unable to get cgroup for driver));
+goto cleanup;
+}
+
+rc = virLXCCgroupSetup(ctrl-cgroup, ctrl-def);
+
+cleanup:
+virCgroupFree(appCgroup);
+return rc;
+}
 
 /**
  * virLXCControllerSetupResourceLimits
@@ -567,7 +596,7 @@ static int 
virLXCControllerSetupResourceLimits(virLXCControllerPtr ctrl)
 if (virLXCControllerSetupNUMAPolicy(ctrl)  0)
 return -1;
 
-return virLXCCgroupSetup(ctrl-def);
+return virLXCControllerSetupCgroup(ctrl);
 }
 
 
diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c
index 1fe8039..7afe969 100644
--- a/src/lxc/lxc_driver.c
+++ b/src/lxc/lxc_driver.c
@@ -527,7 +527,6 @@ static int lxcDomainGetInfo(virDomainPtr dom,
 {
 virLXCDriverPtr driver = dom-conn-privateData;
 virDomainObjPtr vm;
-virCgroupPtr cgroup = NULL;
 int ret = -1, rc;
 
 lxcDriverLock(driver);
@@ -543,22 +542,16 @@ static int lxcDomainGetInfo(virDomainPtr dom,
 
 info-state = virDomainObjGetState(vm, NULL);
 
-if (!virDomainObjIsActive(vm) || driver-cgroup == NULL) {
+if (!virDomainObjIsActive(vm) || vm-cgroup == NULL) {
 info-cpuTime = 0;
 info-memory = vm-def-mem.cur_balloon;
 } else {
-if 

[libvirt] [PATCH v2 3/5] cgroup: replace old cgroup

2013-02-03 Thread Hu Tao
---
 src/libvirt_private.syms |   9 +-
 src/util/vircgroup.c | 812 +++
 src/util/vircgroup.h |  25 +-
 3 files changed, 112 insertions(+), 734 deletions(-)

diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index f5138af..78e387d 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -73,8 +73,6 @@ virCapabilitiesSetMacPrefix;
 
 
 # cgroup.h
-virCgroup2Free;
-virCgroup2New;
 virCgroupAddTask;
 virCgroupAddTaskController;
 virCgroupAllowDevice;
@@ -86,10 +84,6 @@ virCgroupDenyAllDevices;
 virCgroupDenyDevice;
 virCgroupDenyDeviceMajor;
 virCgroupDenyDevicePath;
-virCgroupForDomain;
-virCgroupForDriver;
-virCgroupForEmulator;
-virCgroupForVcpu;
 virCgroupFree;
 virCgroupGetAppRoot;
 virCgroupGetBlkioWeight;
@@ -110,10 +104,11 @@ virCgroupGetMemSwapUsage;
 virCgroupKill;
 virCgroupKillPainfully;
 virCgroupKillRecursive;
+virCgroupMakePath;
 virCgroupMounted;
 virCgroupMoveTask;
+virCgroupNew;
 virCgroupPathOfController;
-virCgroupRemove;
 virCgroupSetBlkioDeviceWeight;
 virCgroupSetBlkioWeight;
 virCgroupSetCpuCfsPeriod;
diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c
index dbc9688..90ff97c 100644
--- a/src/util/vircgroup.c
+++ b/src/util/vircgroup.c
@@ -80,7 +80,7 @@ struct _virCgroupItem {
 struct virCgroupController controllers[VIR_CGROUP_CONTROLLER_LAST];
 };
 
-struct virCgroup2 {
+struct virCgroup {
 virCgroupItemPtr items[VIR_CGROUP_CONTROLLER_LAST];
 };
 
@@ -145,12 +145,6 @@ static int virCgroupControllersInit(struct 
virCgroupController (*controllers)[VI
 return rc;
 }
 
-struct virCgroup {
-char *path;
-
-struct virCgroupController controllers[VIR_CGROUP_CONTROLLER_LAST];
-};
-
 typedef enum {
 VIR_CGROUP_NONE = 0, /* create subdir under each cgroup if possible. */
 VIR_CGROUP_MEM_HIERACHY = 1  0, /* call virCgroupSetMemoryUseHierarchy
@@ -447,9 +441,21 @@ static int virCgroupItemKeyPath(virCgroupItemPtr 
cgroupItem,
 return ret;
 }
 
-int virCgroup2New(const char *name, virCgroup2Ptr parent, virCgroup2Ptr 
*cgroup)
+int virCgroupMakePath(virCgroupPtr cgroup)
 {
-virCgroup2Ptr newCgroup = NULL;
+int i;
+
+for (i = 0; i  VIR_CGROUP_CONTROLLER_LAST; i++) {
+if (virCgroupItemPath(cgroup-items[i], true, NULL) != 0)
+return -1;
+}
+
+return 0;
+}
+
+int virCgroupNew(const char *name, virCgroupPtr parent, virCgroupPtr *cgroup)
+{
+virCgroupPtr newCgroup = NULL;
 virCgroupItemPtr *parentCgroupItems;
 int ret = -1;
 int i = 0;
@@ -502,40 +508,24 @@ error:
 return ret;
 }
 
-void virCgroup2Free(virCgroup2Ptr *cgroup)
-{
-int i;
-
-if (!cgroup || !*cgroup)
-return;
-
-for (i = 0; i  VIR_CGROUP_CONTROLLER_LAST; i++) {
-virCgroupItemFree((*cgroup)-items[i]);
-}
-
-VIR_FREE(*cgroup);
-*cgroup = NULL;
-}
-
 /**
  * virCgroupFree:
  *
  * @group: The group structure to free
  */
-void virCgroupFree(virCgroupPtr *group)
+void virCgroupFree(virCgroupPtr *cgroup)
 {
 int i;
 
-if (*group == NULL)
+if (!cgroup || !*cgroup)
 return;
 
-for (i = 0 ; i  VIR_CGROUP_CONTROLLER_LAST ; i++) {
-VIR_FREE((*group)-controllers[i].mountPoint);
-VIR_FREE((*group)-controllers[i].placement);
+for (i = 0; i  VIR_CGROUP_CONTROLLER_LAST; i++) {
+virCgroupItemFree((*cgroup)-items[i]);
 }
 
-VIR_FREE((*group)-path);
-VIR_FREE(*group);
+VIR_FREE(*cgroup);
+*cgroup = NULL;
 }
 
 /**
@@ -546,9 +536,13 @@ void virCgroupFree(virCgroupPtr *group)
  *
  * Returns true if a cgroup is subsystem is mounted.
  */
-bool virCgroupMounted(virCgroupPtr cgroup, int controller)
+bool virCgroupMounted(virCgroupPtr cgroup ATTRIBUTE_UNUSED,
+  int controller)
 {
-return cgroup-controllers[controller].mountPoint != NULL;
+if (rootCgroupItems[controller] 
+rootCgroupItems[controller]-controllers[controller].mountPoint)
+return true;
+return false;
 }
 
 #if defined HAVE_MNTENT_H  defined HAVE_GETMNTENT_R
@@ -675,58 +669,8 @@ no_memory:
 
 }
 
-
-static int virCgroupDetect(virCgroupPtr group)
-{
-int any = 0;
-int rc;
-int i;
-
-rc = virCgroupDetectMounts(group-controllers);
-if (rc  0) {
-VIR_ERROR(_(Failed to detect mounts for %s), group-path);
-return rc;
-}
-
-/* Check that at least 1 controller is available */
-for (i = 0 ; i  VIR_CGROUP_CONTROLLER_LAST ; i++) {
-if (group-controllers[i].mountPoint != NULL)
-any = 1;
-}
-if (!any)
-return -ENXIO;
-
-
-rc = virCgroupDetectPlacement(group-controllers);
-
-if (rc == 0) {
-/* Check that for every mounted controller, we found our placement */
-for (i = 0 ; i  VIR_CGROUP_CONTROLLER_LAST ; i++) {
-if (!group-controllers[i].mountPoint)
-continue;
-
-if (!group-controllers[i].placement) {
-VIR_ERROR(_(Could not 

[libvirt] [PATCH v2 1/5] refactor virCgroupDetectMounts and virCgroupDetectPlacement

2013-02-03 Thread Hu Tao
This patch prepares for the next one.
---
 src/util/vircgroup.c | 14 +++---
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c
index 48cba93..71d46c5 100644
--- a/src/util/vircgroup.c
+++ b/src/util/vircgroup.c
@@ -113,7 +113,7 @@ bool virCgroupMounted(virCgroupPtr cgroup, int controller)
  * Process /proc/mounts figuring out what controllers are
  * mounted and where
  */
-static int virCgroupDetectMounts(virCgroupPtr group)
+static int virCgroupDetectMounts(struct virCgroupController 
(*controllers)[VIR_CGROUP_CONTROLLER_LAST])
 {
 int i;
 FILE *mounts = NULL;
@@ -148,8 +148,8 @@ static int virCgroupDetectMounts(virCgroupPtr group)
  * first entry only
  */
 if (typelen == len  STREQLEN(typestr, tmp, len) 
-!group-controllers[i].mountPoint 
-!(group-controllers[i].mountPoint = 
strdup(entry.mnt_dir)))
+!(*controllers)[i].mountPoint 
+!((*controllers)[i].mountPoint = strdup(entry.mnt_dir)))
 goto no_memory;
 tmp = next;
 }
@@ -171,7 +171,7 @@ no_memory:
  * sub-path the current process is assigned to. ie not
  * necessarily in the root
  */
-static int virCgroupDetectPlacement(virCgroupPtr group)
+static int virCgroupDetectPlacement(struct virCgroupController 
(*cgroupControllers)[VIR_CGROUP_CONTROLLER_LAST])
 {
 int i;
 FILE *mapping  = NULL;
@@ -212,7 +212,7 @@ static int virCgroupDetectPlacement(virCgroupPtr group)
 len = strlen(tmp);
 }
 if (typelen == len  STREQLEN(typestr, tmp, len) 
-!(group-controllers[i].placement = strdup(STREQ(path, 
/) ?  : path)))
+!((*cgroupControllers)[i].placement = strdup(STREQ(path, 
/) ?  : path)))
 goto no_memory;
 
 tmp = next;
@@ -236,7 +236,7 @@ static int virCgroupDetect(virCgroupPtr group)
 int rc;
 int i;
 
-rc = virCgroupDetectMounts(group);
+rc = virCgroupDetectMounts(group-controllers);
 if (rc  0) {
 VIR_ERROR(_(Failed to detect mounts for %s), group-path);
 return rc;
@@ -251,7 +251,7 @@ static int virCgroupDetect(virCgroupPtr group)
 return -ENXIO;
 
 
-rc = virCgroupDetectPlacement(group);
+rc = virCgroupDetectPlacement(group-controllers);
 
 if (rc == 0) {
 /* Check that for every mounted controller, we found our placement */
-- 
1.8.0.1.240.ge8a1f5a

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH v2 2/5] cgroup: refactor virCgroup

2013-02-03 Thread Hu Tao
This patch adds a new structure, virCgroupItem, to represent
a cgroup directory(named cgroup item). cgroup directory is
created when needed and removed if no one is using it.
---
 src/libvirt_private.syms |   2 +
 src/util/vircgroup.c | 541 ++-
 src/util/vircgroup.h |   8 +
 3 files changed, 545 insertions(+), 6 deletions(-)

diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index c589236..f5138af 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -73,6 +73,8 @@ virCapabilitiesSetMacPrefix;
 
 
 # cgroup.h
+virCgroup2Free;
+virCgroup2New;
 virCgroupAddTask;
 virCgroupAddTaskController;
 virCgroupAllowDevice;
diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c
index 71d46c5..dbc9688 100644
--- a/src/util/vircgroup.c
+++ b/src/util/vircgroup.c
@@ -37,6 +37,7 @@
 #include libgen.h
 #include dirent.h
 
+#include virobject.h
 #include internal.h
 #include virutil.h
 #include viralloc.h
@@ -45,6 +46,7 @@
 #include virfile.h
 #include virhash.h
 #include virhashcode.h
+#include virthread.h
 
 #define CGROUP_MAX_VAL 512
 
@@ -58,6 +60,91 @@ struct virCgroupController {
 char *placement;
 };
 
+struct _virCgroupItem;
+typedef struct _virCgroupItem virCgroupItem;
+typedef virCgroupItem *virCgroupItemPtr;
+
+struct _virCgroupItem {
+virObjectLockable object;
+
+char *name;
+char *path;
+
+bool created;  /* the path is created or not */
+
+virCgroupItemPtr next;
+virCgroupItemPtr parent;
+virCgroupItemPtr children;
+
+int type;
+struct virCgroupController controllers[VIR_CGROUP_CONTROLLER_LAST];
+};
+
+struct virCgroup2 {
+virCgroupItemPtr items[VIR_CGROUP_CONTROLLER_LAST];
+};
+
+static virClassPtr cgroupItemClass;
+
+static void cgroupItemDispose(void *obj);
+
+static int virCgroupItemOnceInit(void)
+{
+if (!(cgroupItemClass = virClassNew(virClassForObjectLockable(),
+cgroupItem,
+sizeof(virCgroupItem),
+cgroupItemDispose)))
+return -1;
+
+return 0;
+}
+VIR_ONCE_GLOBAL_INIT(virCgroupItem);
+
+static virCgroupItemPtr rootCgroupItems[VIR_CGROUP_CONTROLLER_LAST];
+
+static virCgroupItemPtr virCgroupItemRootNew(int type);
+static int virCgroupDetectMounts(struct virCgroupController 
(*controllers)[VIR_CGROUP_CONTROLLER_LAST]);
+static int virCgroupDetectPlacement(struct virCgroupController 
(*controllers)[VIR_CGROUP_CONTROLLER_LAST]);
+
+static int virCgroupControllersInit(struct virCgroupController 
(*controllers)[VIR_CGROUP_CONTROLLER_LAST])
+{
+int rc;
+int i;
+
+rc = virCgroupDetectMounts(controllers);
+if (rc  0) {
+VIR_ERROR(_(Failed to initialize cgroup controllers));
+return rc;
+}
+
+rc = virCgroupDetectPlacement(controllers);
+
+if (rc == 0) {
+/* Check that for every mounted controller, we found our placement */
+for (i = 0 ; i  VIR_CGROUP_CONTROLLER_LAST ; i++) {
+if (!(*controllers)[i].mountPoint)
+continue;
+
+if (!(*controllers)[i].placement) {
+VIR_ERROR(_(Could not find placement for controller %s at 
%s),
+  virCgroupControllerTypeToString(i),
+  (*controllers)[i].placement);
+rc = -ENOENT;
+break;
+}
+
+VIR_DEBUG(Detected mount/mapping %i:%s at %s in %s, i,
+  virCgroupControllerTypeToString(i),
+  (*controllers)[i].mountPoint,
+  (*controllers)[i].placement);
+}
+} else {
+VIR_ERROR(_(Failed to initialize cgroup controllers));
+}
+
+return rc;
+}
+
 struct virCgroup {
 char *path;
 
@@ -74,6 +161,362 @@ typedef enum {
* cpuacct and cpuset if possible. */
 } virCgroupFlags;
 
+static virCgroupItemPtr virCgroupItemRootNew(int type)
+{
+virCgroupItemPtr rootItem = NULL;
+
+if (type = VIR_CGROUP_CONTROLLER_LAST || type  0)
+return NULL;
+
+if (virCgroupItemInitialize()  0)
+return NULL;
+
+if (!(rootItem = virObjectNew(cgroupItemClass)))
+return NULL;
+
+if (virCgroupControllersInit(rootItem-controllers) != 0) {
+virObjectUnref(rootItem);
+rootItem = NULL;
+return NULL;
+}
+
+rootItem-name = strdup(/);
+rootItem-next = NULL;
+rootItem-parent = NULL;
+rootItem-children = NULL;
+rootItem-created = 1;
+rootItem-type = type;
+if (virAsprintf(rootItem-path, %s%s,
+rootItem-controllers[rootItem-type].mountPoint,
+rootItem-controllers[rootItem-type].placement)  0) {
+virObjectUnref(rootItem);
+rootItem = NULL;
+}
+
+return rootItem;
+}
+
+static virCgroupItemPtr virCgroupHasChildByName(virCgroupItemPtr item,
+