[libvirt] [PATCH] event: fix two event-handling bugs
by Eric Blake
Regression introduced in commit e6b68d7.
Prior to that point, handlesAlloc was always a multiple of
EVENT_ALLOC_EXTENT, and was an integer (so even if the
subtraction wrapped, a negative value was less than the
count and did not try to free the handles array). But after
that point, VIR_RESIZE_N made handlesAlloc grow geometrically,
so handlesAlloc could be 49 when handlesCount was 47, while
still freeing off only 10 at a time, and eventually reach
handlesAlloc 7 and handlesCount 1. Since (size_t)(7 - 10) is
indeed greater than 1, this then tried to free 10 elements,
which had the awful effect of nuking the handles array while
there were still live handles.
Which leads to crashes like this:
https://bugzilla.redhat.com/show_bug.cgi?id=670848
* daemon/event.c (virEventDispatchHandles): Cache watch while the
lock is still held, as eventLoop.handles might be relocated
outside the lock.
(virEventCleanupHandles): Avoid integer wrap-around causing us to
delete the entire handles array while handles are still active.
---
Thanks to Dave Allan for letting me use his faqemu setup for testing
this. Basically, starting 60 faqemu followed by stopping them all
was a reliable way to trigger the handle cleanup integer wraparound.
daemon/event.c | 12 +++++++-----
1 files changed, 7 insertions(+), 5 deletions(-)
diff --git a/daemon/event.c b/daemon/event.c
index 89ca9f0..9cad466 100644
--- a/daemon/event.c
+++ b/daemon/event.c
@@ -1,7 +1,7 @@
/*
* event.c: event loop for monitoring file handles
*
- * Copyright (C) 2007, 2010 Red Hat, Inc.
+ * Copyright (C) 2007, 2010-2011 Red Hat, Inc.
* Copyright (C) 2007 Daniel P. Berrange
*
* This library is free software; you can redistribute it and/or
@@ -435,6 +435,7 @@ static int virEventDispatchTimeouts(void) {
*/
static int virEventDispatchHandles(int nfds, struct pollfd *fds) {
int i, n;
+ int watch;
DEBUG("Dispatch %d", nfds);
/* NB, use nfds not eventLoop.handlesCount, because new
@@ -463,9 +464,9 @@ static int virEventDispatchHandles(int nfds, struct pollfd *fds) {
EVENT_DEBUG("Dispatch n=%d f=%d w=%d e=%d %p", i,
fds[n].fd, eventLoop.handles[i].watch,
fds[n].revents, eventLoop.handles[i].opaque);
+ watch = eventLoop.handles[i].watch;
virMutexUnlock(&eventLoop.lock);
- (cb)(eventLoop.handles[i].watch,
- fds[n].fd, hEvents, opaque);
+ (cb)(watch, fds[n].fd, hEvents, opaque);
virMutexLock(&eventLoop.lock);
}
}
@@ -542,9 +543,10 @@ static int virEventCleanupHandles(void) {
}
/* Release some memory if we've got a big chunk free */
- if ((eventLoop.handlesAlloc - EVENT_ALLOC_EXTENT) > eventLoop.handlesCount) {
+ if (eventLoop.handlesAlloc - eventLoop.handlesCount > EVENT_ALLOC_EXTENT) {
EVENT_DEBUG("Releasing %zu out of %zu handles slots used, releasing %d",
- eventLoop.handlesCount, eventLoop.handlesAlloc, EVENT_ALLOC_EXTENT);
+ eventLoop.handlesCount, eventLoop.handlesAlloc,
+ EVENT_ALLOC_EXTENT);
VIR_SHRINK_N(eventLoop.handles, eventLoop.handlesAlloc,
EVENT_ALLOC_EXTENT);
}
--
1.7.3.4
13 years, 10 months
[libvirt] [PATCH] Prevent overfilling of self-pipe in python event loop
by Daniel P. Berrange
If the event loop takes a very long time todo something, it is
possible for the 'self pipe' buffer to become full at which
point the entire event loop + remote driver deadlock. Use a
boolean flag to ensure we have strict one-in, one-out behaviour
on writes/reads of the 'self pipe'
---
examples/domain-events/events-python/event-test.py | 10 +++++++++-
1 files changed, 9 insertions(+), 1 deletions(-)
diff --git a/examples/domain-events/events-python/event-test.py b/examples/domain-events/events-python/event-test.py
index 903f934..c149ed9 100644
--- a/examples/domain-events/events-python/event-test.py
+++ b/examples/domain-events/events-python/event-test.py
@@ -92,6 +92,8 @@ class virEventLoopPure:
def __init__(self):
self.poll = select.poll()
self.pipetrick = os.pipe()
+ self.pendingWakeup = False
+ self.runningPoll = False
self.nextHandleID = 1
self.nextTimerID = 1
self.handles = []
@@ -166,6 +168,7 @@ class virEventLoopPure:
# these pointless repeated tiny sleeps.
def run_once(self):
sleep = -1
+ self.runningPoll = True
next = self.next_timeout()
debug("Next timeout due at %d" % next)
if next > 0:
@@ -184,6 +187,7 @@ class virEventLoopPure:
# telling us to wakup. if so, then discard
# the data just continue
if fd == self.pipetrick[0]:
+ self.pendingWakeup = False
data = os.read(fd, 1)
continue
@@ -206,6 +210,8 @@ class virEventLoopPure:
t.set_last_fired(now)
t.dispatch()
+ self.runningPoll = False
+
# Actually the event loop forever
def run_loop(self):
@@ -214,7 +220,9 @@ class virEventLoopPure:
self.run_once()
def interrupt(self):
- os.write(self.pipetrick[1], 'c')
+ if self.runningPoll and not self.pendingWakeup:
+ self.pendingWakeup = True
+ os.write(self.pipetrick[1], 'c')
# Registers a new file handle 'fd', monitoring for 'events' (libvirt
--
1.7.3.4
13 years, 10 months
[libvirt] [PATCH] docs: fix incorrect XML element mentioned by setmem text
by Justin Clift
---
Pushed this under the trivial rule, as it's definitely wrong. The setmaxmem
text can follow when ready.
tools/virsh.pod | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/tools/virsh.pod b/tools/virsh.pod
index 1f15fef..4e8b295 100644
--- a/tools/virsh.pod
+++ b/tools/virsh.pod
@@ -580,7 +580,7 @@ paravirtualized or running the PV balloon driver.
Note, this command only works on active guest domains. To change the memory
allocation for an inactive guest domain, use the virsh B<edit> command to
-update the XML <memory> element.
+update the XML <currentMemory> element.
=item B<setmaxmem> I<domain-id> B<kilobytes>
--
1.7.3.5
13 years, 10 months
[libvirt] Planning for next release and discussions on project process
by Daniel Veillard
So we are around the end of the month, i.e. the time where I
usually come out and suggest to enter a freeze within a few days
for the next release.
However, looking at the git history I note that we have only
around 125 patches commited since 0.8.7 was released and while I'm
fairly convinced that time based releases are a really good thing
(allowing people to see their patches out within a predictable
delay, and allowing the whole ecosystem of distros/users to plan
accordingly), it's also time I think to open up the process to the
growing (or at least changing) set of people involved in building
libvirt. I usually ask if everybody agrees on the next freeze but
I have to make the initial selection based on the calendar and
my own agenda (or Red Hat one).
Other projects I know use things like weekly teleconferences to
discuss ther development plans, or IRC meetings. My opinion is that
phone is not alway convenient/eficient, IRC has the advantage of being
more open (no spoken english barrier), less intrusive, and it's
nearly trivial to extract and publish some kind of minutes. But both
suffer from the timezone problem, basically if there is meeting time
it's gonna be during insane hours for someone somewhere (we have a large
set of developpers in the US, Matthias and Dan are in Europe, Justin is
in Australia, I'm in China now and I think the Fujitsu developpers too)
One possibility could be to use a mix of IRC channel gathering and
an Etherpad file (very convenient tool try it), I just created one at
http://ietherpad.com/oETnXKdcFf
to try this out and put my own sugegstions, then others can come and
put their own feedback even if they happen to not be online at the
time of the meeting.
To come back to the release, maybe we can do 2 release for Jan-Mar
since we didn't released early in Jan and Feb is short, so I would
suggest to plan a release before Feb 15, entering a freeze around the
7th Feb. This should allow to put in some of the code already reviewed
but not yet commited that I spotted:
+ migration enhancements from Hu Tao and Wen Congyang
+ integration of locking in the QEmu driver from Dan
+ cgroup blkio support (lxc and qemu) from Gui Jianfeng
+ smartcard support from Eric
but there is certainly things I forgot, and well people may have
specific things they want in ASAP, so let's use IRC (irc.oftc.net #virt)
and
http://ietherpad.com/oETnXKdcFf
and share opinions about next release and features to come,
well unless people have a better idea on how to organize ourselves,
Daniel
--
Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/
daniel(a)veillard.com | Rpmfind RPM search engine http://rpmfind.net/
http://veillard.com/ | virtualization library http://libvirt.org/
13 years, 10 months
[libvirt] [v2] remote: Add extra parameter pkipath for URI
by Osier Yang
This new parameter allows user specifies where the client
cerficate, client key, CA certificate of x509 is, instead of
hardcoding it. If 'pkipath' is not specified, and the user
is not root, try to find files in $HOME/.pki, as long as one
of client cerficate, client key, CA certificate can not be
found, use default global location (LIBVIRT_CACERT, LIBVIRT_CLIENTCERT,
LIBVIRT_CLIENTKEY, see src/remote/remote_driver.h)
e.g.
[root@Osier client]# virsh -c qemu+tls://10.66.93.111/system?pkipath=/tmp/pki/client
error: Cannot access CA certificate '/tmp/pki/client/cacert.pem': No such file or directory
error: failed to connect to the hypervisor
[root@Osier client]# ls -l
total 24
-rwxrwxr-x. 1 root root 6424 Jan 24 21:35 a.out
-rw-r--r--. 1 root root 1245 Jan 23 19:04 clientcert.pem
-rw-r--r--. 1 root root 132 Jan 23 19:04 client.info
-rw-r--r--. 1 root root 1679 Jan 23 19:04 clientkey.pem
[root@Osier client]# cp /tmp/cacert.pem .
[root@Osier client]# virsh -c qemu+tls://10.66.93.111/system?pkipath=/tmp/pki/client
Welcome to virsh, the virtualization interactive terminal.
Type: 'help' for help with commands
'quit' to quit
virsh #
* src/remote/remote_driver.c
---
src/remote/remote_driver.c | 130 ++++++++++++++++++++++++++++++++++++++------
1 files changed, 112 insertions(+), 18 deletions(-)
diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c
index ea119c6..01f1995 100644
--- a/src/remote/remote_driver.c
+++ b/src/remote/remote_driver.c
@@ -268,7 +268,7 @@ void remoteDomainEventQueueFlush(int timer, void *opaque);
static char *get_transport_from_scheme (char *scheme);
/* GnuTLS functions used by remoteOpen. */
-static int initialize_gnutls(void);
+static int initialize_gnutls(char *pkipath, int flags);
static gnutls_session_t negotiate_gnutls_on_connection (virConnectPtr conn, struct private_data *priv, int no_verify);
#ifdef WITH_LIBVIRTD
@@ -430,6 +430,7 @@ doRemoteOpen (virConnectPtr conn,
char *port = NULL, *authtype = NULL, *username = NULL;
int no_verify = 0, no_tty = 0;
char **cmd_argv = NULL;
+ char *pkipath = NULL;
/* Return code from this function, and the private data. */
int retcode = VIR_DRV_OPEN_ERROR;
@@ -509,9 +510,14 @@ doRemoteOpen (virConnectPtr conn,
priv->debugLog = stdout;
else
priv->debugLog = stderr;
- } else
+ } else if (STRCASEEQ(var->name, "pkipath")) {
+ pkipath = strdup(var->value);
+ if (!pkipath) goto out_of_memory;
+ var->ignore = 1;
+ } else {
DEBUG("passing through variable '%s' ('%s') to remote end",
var->name, var->value);
+ }
}
/* Construct the original name. */
@@ -577,7 +583,7 @@ doRemoteOpen (virConnectPtr conn,
/* Connect to the remote service. */
switch (transport) {
case trans_tls:
- if (initialize_gnutls() == -1) goto failed;
+ if (initialize_gnutls(pkipath, flags) == -1) goto failed;
priv->uses_tls = 1;
priv->is_secure = 1;
@@ -947,6 +953,7 @@ doRemoteOpen (virConnectPtr conn,
}
VIR_FREE(cmd_argv);
}
+ VIR_FREE(pkipath);
return retcode;
@@ -1139,11 +1146,17 @@ static void remote_debug_gnutls_log(int level, const char* str) {
}
static int
-initialize_gnutls(void)
+initialize_gnutls(char *pkipath, int flags)
{
static int initialized = 0;
int err;
char *gnutlsdebug;
+ char *libvirt_cacert = NULL;
+ char *libvirt_clientkey = NULL;
+ char *libvirt_clientcert = NULL;
+ int ret = -1;
+ char *userdir = NULL;
+ char *user_pki_path = NULL;
if (initialized) return 0;
@@ -1166,43 +1179,124 @@ initialize_gnutls(void)
return -1;
}
+ if (pkipath) {
+ if ((virAsprintf(&libvirt_cacert, "%s/%s", pkipath,
+ "cacert.pem")) < 0)
+ goto out_of_memory;
- if (check_cert_file("CA certificate", LIBVIRT_CACERT) < 0)
- return -1;
- if (check_cert_file("client key", LIBVIRT_CLIENTKEY) < 0)
- return -1;
- if (check_cert_file("client certificate", LIBVIRT_CLIENTCERT) < 0)
- return -1;
+ if ((virAsprintf(&libvirt_clientkey, "%s/%s", pkipath,
+ "clientkey.pem")) < 0)
+ goto out_of_memory;
+
+ if ((virAsprintf(&libvirt_clientcert, "%s/%s", pkipath,
+ "clientcert.pem")) < 0)
+ goto out_of_memory;
+ } else if (flags & VIR_DRV_OPEN_REMOTE_USER) {
+ userdir = virGetUserDirectory(getuid());
+
+ if (!userdir)
+ goto out_of_memory;
+
+ if (virAsprintf(&user_pki_path, "%s/.pki", userdir) < 0)
+ goto out_of_memory;
+
+ if ((virAsprintf(&libvirt_cacert, "%s/%s", user_pki_path,
+ "cacert.pem")) < 0)
+ goto out_of_memory;
+
+ if ((virAsprintf(&libvirt_clientkey, "%s/%s", user_pki_path,
+ "clientkey.pem")) < 0)
+ goto out_of_memory;
+
+ if ((virAsprintf(&libvirt_clientcert, "%s/%s", user_pki_path,
+ "clientcert.pem")) < 0)
+ goto out_of_memory;
+
+ /* Use default locations as long as one of CA certificate,
+ * client key, and client certificate can not be found in
+ * $HOME/.pki, we don't want to make user confused with one
+ * file is here, and the other is there.
+ */
+ if (!virFileExists(libvirt_cacert) ||
+ !virFileExists(libvirt_clientkey) ||
+ !virFileExists(libvirt_clientcert)) {
+ VIR_FREE(libvirt_cacert);
+ VIR_FREE(libvirt_clientkey);
+ VIR_FREE(libvirt_clientcert);
+
+ libvirt_cacert = strdup(LIBVIRT_CACERT);
+ if (!libvirt_cacert) goto out_of_memory;
+
+ libvirt_clientkey = strdup(LIBVIRT_CLIENTKEY);
+ if (!libvirt_clientkey) goto out_of_memory;
+
+ libvirt_clientcert = strdup(LIBVIRT_CLIENTCERT);
+ if (!libvirt_clientcert) goto out_of_memory;
+ }
+ } else {
+ libvirt_cacert = strdup(LIBVIRT_CACERT);
+ if (!libvirt_cacert) goto out_of_memory;
+
+ libvirt_clientkey = strdup(LIBVIRT_CLIENTKEY);
+ if (!libvirt_clientkey) goto out_of_memory;
+
+ libvirt_clientcert = strdup(LIBVIRT_CLIENTCERT);
+ if (!libvirt_clientcert) goto out_of_memory;
+ }
+
+ if (check_cert_file("CA certificate", libvirt_cacert) < 0)
+ goto error;
+ if (check_cert_file("client key", libvirt_clientkey) < 0)
+ goto error;
+ if (check_cert_file("client certificate", libvirt_clientcert) < 0)
+ goto error;
/* Set the trusted CA cert. */
- DEBUG("loading CA file %s", LIBVIRT_CACERT);
+ DEBUG("loading CA file %s", libvirt_cacert);
err =
- gnutls_certificate_set_x509_trust_file (x509_cred, LIBVIRT_CACERT,
+ gnutls_certificate_set_x509_trust_file (x509_cred, libvirt_cacert,
GNUTLS_X509_FMT_PEM);
if (err < 0) {
remoteError(VIR_ERR_GNUTLS_ERROR,
_("unable to load CA certificate: %s"),
gnutls_strerror (err));
- return -1;
+ goto error;
}
/* Set the client certificate and private key. */
DEBUG("loading client cert and key from files %s and %s",
- LIBVIRT_CLIENTCERT, LIBVIRT_CLIENTKEY);
+ libvirt_clientcert, libvirt_clientkey);
err =
gnutls_certificate_set_x509_key_file (x509_cred,
- LIBVIRT_CLIENTCERT,
- LIBVIRT_CLIENTKEY,
+ libvirt_clientcert,
+ libvirt_clientkey,
GNUTLS_X509_FMT_PEM);
if (err < 0) {
remoteError(VIR_ERR_GNUTLS_ERROR,
_("unable to load private key/certificate: %s"),
gnutls_strerror (err));
- return -1;
+ goto error;
}
initialized = 1;
- return 0;
+ ret = 0;
+
+cleanup:
+ VIR_FREE(libvirt_cacert);
+ VIR_FREE(libvirt_clientkey);
+ VIR_FREE(libvirt_clientcert);
+ VIR_FREE(userdir);
+ VIR_FREE(user_pki_path);
+ return ret;
+
+error:
+ ret = -1;
+ goto cleanup;
+
+out_of_memory:
+ ret = -1;
+ virReportOOMError();
+ goto cleanup;
}
static int verify_certificate (virConnectPtr conn, struct private_data *priv, gnutls_session_t session);
--
1.7.3.2
13 years, 10 months
[libvirt] [PATCH] [v2] storage: Round up capacity for LVM volume creation
by Osier Yang
If vol->capacity is odd, the capacity will be rounded down
by devision, this patch is to round it up instead of rounding
down, to be safer in case of one writes to the volume with the
size he used to create.
* src/storage/storage_backend_logical.c
---
src/storage/storage_backend_logical.c | 5 ++++-
1 files changed, 4 insertions(+), 1 deletions(-)
diff --git a/src/storage/storage_backend_logical.c b/src/storage/storage_backend_logical.c
index 203fe5d..2057692 100644
--- a/src/storage/storage_backend_logical.c
+++ b/src/storage/storage_backend_logical.c
@@ -604,7 +604,10 @@ virStorageBackendLogicalCreateVol(virConnectPtr conn,
cmdargv = cmdargvsnap;
}
- snprintf(size, sizeof(size)-1, "%lluK", vol->capacity/1024);
+ unsigned long long int capacity;
+ capacity = (vol->capacity + 1023) /1024;
+
+ snprintf(size, sizeof(size)-1, "%lluK", capacity);
size[sizeof(size)-1] = '\0';
vol->type = VIR_STORAGE_VOL_BLOCK;
--
1.7.3.2
13 years, 10 months
[libvirt] [PATCH 1/4] cgroup: Enable cgroup hierarchy for blkio cgroup
by Gui Jianfeng
Enable cgroup hierarchy for blkio cgroup.
Signed-off-by: Gui Jianfeng <guijianfeng(a)cn.fujitsu.com>
---
src/util/cgroup.c | 2 +-
src/util/cgroup.h | 1 +
2 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/src/util/cgroup.c b/src/util/cgroup.c
index cd9caba..309f4e9 100644
--- a/src/util/cgroup.c
+++ b/src/util/cgroup.c
@@ -37,7 +37,7 @@
VIR_ENUM_IMPL(virCgroupController, VIR_CGROUP_CONTROLLER_LAST,
"cpu", "cpuacct", "cpuset", "memory", "devices",
- "freezer");
+ "freezer", "blkio");
struct virCgroupController {
int type;
diff --git a/src/util/cgroup.h b/src/util/cgroup.h
index 964da7a..67b1299 100644
--- a/src/util/cgroup.h
+++ b/src/util/cgroup.h
@@ -22,6 +22,7 @@ enum {
VIR_CGROUP_CONTROLLER_MEMORY,
VIR_CGROUP_CONTROLLER_DEVICES,
VIR_CGROUP_CONTROLLER_FREEZER,
+ VIR_CGROUP_CONTROLLER_BLKIO,
VIR_CGROUP_CONTROLLER_LAST
};
--
1.7.1
13 years, 10 months
[libvirt] [PATCH 3/3] qemu: Implement blkio tunable XML configuration and parsing.
by Gui Jianfeng
Implement blkio tunable XML configuration and parsing.
Signed-off-by: Gui Jianfeng <guijianfeng(a)cn.fujitsu.com>
---
src/conf/domain_conf.c | 17 ++++++++++++++++-
src/conf/domain_conf.h | 4 ++++
src/qemu/qemu_cgroup.c | 16 +++++++++++++++-
src/qemu/qemu_conf.c | 3 ++-
4 files changed, 37 insertions(+), 3 deletions(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 645767e..a05ada5 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -4810,7 +4810,7 @@ static virDomainDefPtr virDomainDefParseXML(virCapsPtr caps,
{
xmlNodePtr *nodes = NULL, node = NULL;
char *tmp = NULL;
- int i, n;
+ int i, n, w;
long id = -1;
virDomainDefPtr def;
unsigned long count;
@@ -4887,6 +4887,13 @@ static virDomainDefPtr virDomainDefParseXML(virCapsPtr caps,
if (node)
def->mem.hugepage_backed = 1;
+ /* Extract blkio cgroup tunables */
+ w = virXPathULong("string(./blkiotune/weight)", ctxt,
+ &def->blkio.weight);
+ if (w < 0 || def->blkio.weight > 1000 || def->blkio.weight < 100)
+ virDomainReportError(VIR_ERR_XML_ERROR, "%s",
+ _("I/O weight should fall in [100, 1000]"));
+
/* Extract other memory tunables */
if (virXPathULong("string(./memtune/hard_limit)", ctxt,
&def->mem.hard_limit) < 0)
@@ -7289,6 +7296,14 @@ char *virDomainDefFormat(virDomainDefPtr def,
virBufferVSprintf(&buf, " <currentMemory>%lu</currentMemory>\n",
def->mem.cur_balloon);
+ /* add blkiotune only if there are any */
+ if (def->blkio.weight) {
+ virBufferVSprintf(&buf, " <blkiotune>\n");
+ virBufferVSprintf(&buf, " <weight>%lu</weight>\n",
+ def->blkio.weight);
+ virBufferVSprintf(&buf, " </blkiotune>\n");
+ }
+
/* add memtune only if there are any */
if (def->mem.hard_limit || def->mem.soft_limit || def->mem.min_guarantee ||
def->mem.swap_hard_limit)
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index cf7bdc0..b117869 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -969,6 +969,10 @@ struct _virDomainDef {
char *description;
struct {
+ unsigned long weight;
+ } blkio;
+
+ struct {
unsigned long max_balloon;
unsigned long cur_balloon;
unsigned long hugepage_backed;
diff --git a/src/qemu/qemu_cgroup.c b/src/qemu/qemu_cgroup.c
index e5536c0..a3e8e6a 100644
--- a/src/qemu/qemu_cgroup.c
+++ b/src/qemu/qemu_cgroup.c
@@ -54,7 +54,6 @@ int qemuCgroupControllerActive(struct qemud_driver *driver,
return 0;
}
-
int qemuSetupDiskPathAllow(virDomainDiskDefPtr disk ATTRIBUTE_UNUSED,
const char *path,
size_t depth ATTRIBUTE_UNUSED,
@@ -270,6 +269,21 @@ int qemuSetupCgroup(struct qemud_driver *driver,
}
}
+ if (qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_BLKIO)) {
+ if (vm->def->blkio.weight != 0) {
+ rc = virCgroupSetWeight(cgroup, vm->def->blkio.weight);
+ if(rc != 0) {
+ virReportSystemError(-rc,
+ _("Unable to set io weight for domain %s"),
+ vm->def->name);
+ goto cleanup;
+ }
+ }
+ } else {
+ VIR_WARN("Blkio cgroup is disabled in qemu configuration file: %s",
+ vm->def->name);
+ }
+
if ((rc = qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_MEMORY))) {
if (vm->def->mem.hard_limit != 0) {
rc = virCgroupSetMemoryHardLimit(cgroup, vm->def->mem.hard_limit);
diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c
index e1502dc..121080f 100644
--- a/src/qemu/qemu_conf.c
+++ b/src/qemu/qemu_conf.c
@@ -299,7 +299,8 @@ int qemudLoadDriverConfig(struct qemud_driver *driver,
driver->cgroupControllers =
(1 << VIR_CGROUP_CONTROLLER_CPU) |
(1 << VIR_CGROUP_CONTROLLER_DEVICES) |
- (1 << VIR_CGROUP_CONTROLLER_MEMORY);
+ (1 << VIR_CGROUP_CONTROLLER_MEMORY) |
+ (1 << VIR_CGROUP_CONTROLLER_BLKIO);
}
for (i = 0 ; i < VIR_CGROUP_CONTROLLER_LAST ; i++) {
if (driver->cgroupControllers & (1 << i)) {
--
1.7.1
13 years, 10 months
[libvirt] [PATCH] docs: correct setmem text plus expand setmaxmem text
by Justin Clift
This completes the man page updates required for BZ # 622534:
https://bugzilla.redhat.com/show_bug.cgi?id=622534
---
tools/virsh.pod | 15 +++++++++++----
1 files changed, 11 insertions(+), 4 deletions(-)
diff --git a/tools/virsh.pod b/tools/virsh.pod
index 1f15fef..c0cda79 100644
--- a/tools/virsh.pod
+++ b/tools/virsh.pod
@@ -580,13 +580,20 @@ paravirtualized or running the PV balloon driver.
Note, this command only works on active guest domains. To change the memory
allocation for an inactive guest domain, use the virsh B<edit> command to
-update the XML <memory> element.
+update the XML <currentMemory> element.
=item B<setmaxmem> I<domain-id> B<kilobytes>
-Change the maximum memory allocation limit in the guest domain. This should
-not change the current memory use. The memory limit is specified in
-kilobytes.
+Change the maximum memory allocation limit for an active guest domain.
+
+Some hypervisors require a larger granularity than kilobytes, and requests
+that are not an even multiple will either be rounded down or rejected. For
+example, vSphere/ESX rejects the parameter unless the kB argument is evenly
+divisible by 1024 (that is, the kB argument happens to represent megabytes).
+
+Note, this command only works on active guest domains. To change the memory
+allocation for an inactive guest domain, use the virsh B<edit> command to
+update the XML <memory> element.
=item B<memtune> I<domain-id> optional I<--hard-limit> B<kilobytes>
optional I<--soft-limit> B<kilobytes> optional I<--swap-hard-limit>
--
1.7.3.5
13 years, 10 months