[libvirt] [PATCH] Revert "rpc: Discard non-blocking calls only when necessary"
by Jiri Denemark
This reverts commit b1e374a7ac56927cfe62435179bf0bba1e08b372, which was
rather bad since I failed to consider all sides of the issue. Thus, the
reverted patch actually breaks more than what it fixes and clients
(which may even be libvirtd during p2p migrations) will likely end up
with a corrupted dispatch queue.
---
I will send proper replacement for the reverted patch later once I'm convinced
it's correct (more than I was convinced the original one was correct) :-P
src/rpc/virnetclient.c | 21 ++++++++++++---------
1 file changed, 12 insertions(+), 9 deletions(-)
diff --git a/src/rpc/virnetclient.c b/src/rpc/virnetclient.c
index 3a60db6..d88288d 100644
--- a/src/rpc/virnetclient.c
+++ b/src/rpc/virnetclient.c
@@ -1265,13 +1265,6 @@ static void virNetClientIOEventLoopPassTheBuck(virNetClientPtr client, virNetCli
}
client->haveTheBuck = false;
- /* Remove non-blocking calls from the dispatch list since there is no
- * call with a thread in the list which could take care of them.
- */
- virNetClientCallRemovePredicate(&client->waitDispatch,
- virNetClientIOEventLoopRemoveNonBlocking,
- thiscall);
-
VIR_DEBUG("No thread to pass the buck to");
if (client->wantClose) {
virNetClientCloseLocked(client);
@@ -1315,9 +1308,12 @@ static int virNetClientIOEventLoop(virNetClientPtr client,
if (virNetSocketHasCachedData(client->sock) || client->wantClose)
timeout = 0;
- /* If we are non-blocking, we don't want to sleep in poll()
+ /* If there are any non-blocking calls in the queue,
+ * then we don't want to sleep in poll()
*/
- if (thiscall->nonBlock)
+ if (virNetClientCallMatchPredicate(client->waitDispatch,
+ virNetClientIOEventLoopWantNonBlock,
+ NULL))
timeout = 0;
fds[0].events = fds[0].revents = 0;
@@ -1422,6 +1418,13 @@ static int virNetClientIOEventLoop(virNetClientPtr client,
virNetClientIOEventLoopRemoveDone,
thiscall);
+ /* Iterate through waiting calls and if any are
+ * non-blocking, remove them from the dispatch list...
+ */
+ virNetClientCallRemovePredicate(&client->waitDispatch,
+ virNetClientIOEventLoopRemoveNonBlocking,
+ thiscall);
+
/* Now see if *we* are done */
if (thiscall->mode == VIR_NET_CLIENT_MODE_COMPLETE) {
virNetClientCallRemove(&client->waitDispatch, thiscall);
--
1.7.10.2
12 years, 6 months
[libvirt] JSON license is non-free - how are we affected?
by Eric Blake
The QMP monitor uses JSON as its underlying base. However, when you
read the license of JSON [1], you will note that it has a pretty severe
limitation ("The Software shall be used for Good, not Evil"). In fact,
this limitation is severe enough that the FSF has declared that the JSON
license is non-free (even if the limitation is unenforceable), and
therefore cannot be combined with GPL code:
[1] http://www.json.org/license.html
[2] https://www.gnu.org/licenses/license-list.html#JSON
How do we reconcile this? Obviously, qemu must remain GPL, because it
has files that are licensed GPLv2, and the overall license is the
restrictive union of all source licenses. But that implies that we
cannot include any source code or libraries provided by json.org, if
such code is under the incompatible JSON license.
Is the JSON license only applicable to code downloaded from json.org,
but not to the actual JSON language specification? If so, does that
mean that a clean-room implementation of JSON (the language
specification) can be written with different license than JSON (the
license), and that such alternate code could then be linked into qemu?
Is this already the case? It would be a shame to have to reinvent QMP
to use a different language specification if the entire JSON language is
deemed poisoned.
Thoughts? Do we need to seek legal guidance from FSF, Red Hat, or any
other organization on how to proceed?
--
Eric Blake eblake(a)redhat.com +1-919-301-3266
Libvirt virtualization library http://libvirt.org
12 years, 6 months
[libvirt] [PATCH] qemu_hotplug: Don't free the PCI device structure after hot-unplug
by Peter Krempa
The pciDevice structure corresponding to the device being hot-unplugged
was freed after it was "stolen" from activeList. The pointer was still
used for eg-inactive list. This patch removes the free of the structure
and frees it only if reset fails on the device.
---
src/qemu/qemu_hotplug.c | 8 +++++---
1 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index dfca7e2..ee5a9ba 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -2005,12 +2005,14 @@ qemuDomainDetachHostPciDevice(struct qemud_driver *driver,
if (pci) {
activePci = pciDeviceListSteal(driver->activePciHostdevs, pci);
if (pciResetDevice(activePci, driver->activePciHostdevs,
- driver->inactivePciHostdevs) == 0)
+ driver->inactivePciHostdevs) == 0) {
qemuReattachPciDevice(activePci, driver);
- else
+ } else {
+ /* reset of the device failed, treat it as if it was returned */
+ pciFreeDevice(activePci);
ret = -1;
+ }
pciFreeDevice(pci);
- pciFreeDevice(activePci);
} else {
ret = -1;
}
--
1.7.3.4
12 years, 6 months
[libvirt] [PATCH 0/2] Make virsh *edit more bearable
by Michal Privoznik
If there's an error in XML, all changes made by user are lost.
Users (read /me) tends to get angry with this. Allow them to
get back and re-edit.
Michal Privoznik (2):
virsh: Switch from generated cmd*Edit commands to nongenerated
virsh: Allow users to reedit rejected XML
cfg.mk | 4 +-
po/POTFILES.in | 1 +
tools/Makefile.am | 36 +----
tools/console.c | 40 +++--
tools/console.h | 2 +
tools/virsh-edit.c | 75 +++++++++
tools/virsh.c | 439 ++++++++++++++++++++--------------------------------
7 files changed, 277 insertions(+), 320 deletions(-)
create mode 100644 tools/virsh-edit.c
--
1.7.8.5
12 years, 6 months
[libvirt] [PATCH][libvirt-glib] glib-events: Allow zero timeouts for timer
by Michal Privoznik
In libvirt, it's perfectly possible and widely used to have disabled
timers (timeout=-1) and fire them up 'randomly' with timeout=0.
However, with current mapping into glib mainloop it's not possible
and causing troubles.
---
libvirt-glib/libvirt-glib-event.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/libvirt-glib/libvirt-glib-event.c b/libvirt-glib/libvirt-glib-event.c
index 94f4de8..c3eb3c8 100644
--- a/libvirt-glib/libvirt-glib-event.c
+++ b/libvirt-glib/libvirt-glib-event.c
@@ -384,7 +384,7 @@ gvir_event_timeout_update(int timer,
if (interval >= 0) {
if (data->source)
- goto cleanup;
+ g_source_remove(data->source);
data->interval = interval;
data->source = g_timeout_add(data->interval,
--
1.7.8.5
12 years, 6 months
[libvirt] [PATCH] util: export virBufferTrim
by Laine Stump
This was forgotten in commit cdb87b1c4b3c325c61e2a6a7d8edcca3ca73a765.
Pushed under build-breaker rule (broke builds with modules turned on)
---
src/libvirt_private.syms | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 6c907c4..f30219d 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -28,6 +28,7 @@ virBufferEscapeString;
virBufferFreeAndReset;
virBufferGetIndent;
virBufferStrcat;
+virBufferTrim;
virBufferURIEncodeString;
virBufferUse;
virBufferVasprintf;
--
1.7.10.1
12 years, 6 months
[libvirt] [PATCHv2 4/4] Use virParseScaledValue in virDomainParseMemory
by Guido Günther
---
src/conf/domain_conf.c | 37 ++++---------------------------------
1 file changed, 4 insertions(+), 33 deletions(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index d5e01a8..6073dcf 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -7706,53 +7706,24 @@ static int
virDomainParseMemory(const char *xpath, xmlXPathContextPtr ctxt,
unsigned long long *mem, bool required)
{
- char *xpath_full = NULL;
- char *unit = NULL;
int ret = -1;
- unsigned long long bytes;
- unsigned long long max;
+ unsigned long long bytes, max;
- *mem = 0;
- if (virAsprintf(&xpath_full, "string(%s)", xpath) < 0) {
- virReportOOMError();
- goto cleanup;
- }
- ret = virXPathULongLong(xpath_full, ctxt, &bytes);
- if (ret < 0) {
- if (ret == -2)
- virDomainReportError(VIR_ERR_XML_ERROR,
- _("could not parse memory element %s"),
- xpath);
- else if (required)
- virDomainReportError(VIR_ERR_XML_ERROR,
- _("missing memory element %s"),
- xpath);
- else
- ret = 0;
- goto cleanup;
- }
- VIR_FREE(xpath_full);
-
- if (virAsprintf(&xpath_full, "string(%s/@unit)", xpath) < 0) {
- virReportOOMError();
- goto cleanup;
- }
- unit = virXPathString(xpath_full, ctxt);
/* On 32-bit machines, our bound is 0xffffffff * KiB. On 64-bit
* machines, our bound is off_t (2^63). */
if (sizeof(unsigned long) < sizeof(long long))
max = 1024ull * ULONG_MAX;
else
max = LLONG_MAX;
- if (virScaleInteger(&bytes, unit, 1024, max) < 0)
+
+ ret = virDomainParseScaledValue(xpath, ctxt, &bytes, 1024, max, required);
+ if (ret < 0)
goto cleanup;
/* Yes, we really do use kibibytes for our internal sizing. */
*mem = VIR_DIV_UP(bytes, 1024);
ret = 0;
cleanup:
- VIR_FREE(xpath_full);
- VIR_FREE(unit);
return ret;
}
--
1.7.10
12 years, 6 months
[libvirt] [PATCHv2 3/4] openvz: add quota argument when creating container
by Guido Günther
---
src/openvz/openvz_driver.c | 54 +++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 53 insertions(+), 1 deletion(-)
diff --git a/src/openvz/openvz_driver.c b/src/openvz/openvz_driver.c
index c6d25d7..45ab262 100644
--- a/src/openvz/openvz_driver.c
+++ b/src/openvz/openvz_driver.c
@@ -189,6 +189,44 @@ cleanup:
}
+static int
+openvzSetDiskQuota(virDomainDefPtr vmdef,
+ virDomainFSDefPtr fss)
+{
+ int ret = -1;
+ unsigned long long sl, hl;
+ virCommandPtr cmd = virCommandNewArgList(VZCTL,
+ "--quiet",
+ "set",
+ vmdef->name,
+ "--save",
+ NULL);
+
+ if (fss->type == VIR_DOMAIN_FS_TYPE_TEMPLATE) {
+ if (fss->space_soft_limit) {
+ sl = VIR_DIV_UP(fss->space_soft_limit, 1024);
+ virCommandAddArg(cmd, "--diskspace");
+
+ if (fss->space_hard_limit) {
+ hl = VIR_DIV_UP(fss->space_hard_limit, 1024);
+ virCommandAddArgFormat(cmd, "%lld:%lld", sl, hl);
+ } else {
+ virCommandAddArgFormat(cmd, "%lld", sl);
+ }
+ }
+
+ if (virCommandRun(cmd, NULL) < 0)
+ goto cleanup;
+ }
+
+ ret = 0;
+cleanup:
+ virCommandFree(cmd);
+
+ return ret;
+}
+
+
static virDomainPtr openvzDomainLookupByID(virConnectPtr conn,
int id) {
struct openvz_driver *driver = conn->privateData;
@@ -895,7 +933,13 @@ openvzDomainDefineXML(virConnectPtr conn, const char *xml)
goto cleanup;
}
- /* TODO: set quota */
+ if (vm->def->nfss == 1) {
+ if (openvzSetDiskQuota(vm->def, vm->def->fss[0]) < 0) {
+ openvzError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Could not set disk quota"));
+ goto cleanup;
+ }
+ }
if (openvzSetDefinedUUID(strtoI(vm->def->name), vm->def->uuid) < 0) {
openvzError(VIR_ERR_INTERNAL_ERROR, "%s",
@@ -977,6 +1021,14 @@ openvzDomainCreateXML(virConnectPtr conn, const char *xml,
goto cleanup;
}
+ if (vm->def->nfss == 1) {
+ if (openvzSetDiskQuota(vm->def, vm->def->fss[0]) < 0) {
+ openvzError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Could not set disk quota"));
+ goto cleanup;
+ }
+ }
+
if (openvzSetDefinedUUID(strtoI(vm->def->name), vm->def->uuid) < 0) {
openvzError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Could not set UUID"));
--
1.7.10
12 years, 6 months
[libvirt] [PATCHv2 2/4] openvz: support file system quota reporting
by Guido Günther
---
src/openvz/openvz_conf.c | 16 ++++++++++++++++
tests/domainschemadata/domain-openvz-simple.xml | 2 ++
2 files changed, 18 insertions(+)
diff --git a/src/openvz/openvz_conf.c b/src/openvz/openvz_conf.c
index 5f107ed..44637d8 100644
--- a/src/openvz/openvz_conf.c
+++ b/src/openvz/openvz_conf.c
@@ -407,6 +407,8 @@ openvzReadFSConf(virDomainDefPtr def,
virDomainFSDefPtr fs = NULL;
char *veid_str = NULL;
char *temp = NULL;
+ const char *param;
+ unsigned long long barrier, limit;
ret = openvzReadVPSConfigParam(veid, "OSTEMPLATE", &temp);
if (ret < 0) {
@@ -444,6 +446,20 @@ openvzReadFSConf(virDomainDefPtr def,
fs->dst = strdup("/");
+ param = "DISKSPACE";
+ ret = openvzReadVPSConfigParam(veid, param, &temp);
+ if (ret > 0) {
+ if (openvzParseBarrierLimit(temp, &barrier, &limit)) {
+ openvzError(VIR_ERR_INTERNAL_ERROR,
+ _("Could not read '%s' from config for container %d"),
+ param, veid);
+ goto error;
+ } else {
+ fs->space_soft_limit = barrier * 1024; /* unit is bytes */
+ fs->space_hard_limit = limit * 1024; /* unit is bytes */
+ }
+ }
+
if (fs->src == NULL || fs->dst == NULL)
goto no_memory;
diff --git a/tests/domainschemadata/domain-openvz-simple.xml b/tests/domainschemadata/domain-openvz-simple.xml
index a121d39..949e96d 100644
--- a/tests/domainschemadata/domain-openvz-simple.xml
+++ b/tests/domainschemadata/domain-openvz-simple.xml
@@ -21,6 +21,8 @@
<filesystem type='template' accessmode='passthrough'>
<source name='debian'/>
<target dir='/'/>
+ <space_hard_limit>1153024</space_hard_limit>
+ <space_soft_limit>1048576</space_soft_limit>
</filesystem>
</devices>
</domain>
--
1.7.10
12 years, 6 months
[libvirt] [PATCHv2 1/4] Introduce filesystem limits to virDomainFSDef
by Guido Günther
---
docs/formatdomain.html.in | 12 ++++++
docs/schemas/domaincommon.rng | 12 ++++++
src/conf/domain_conf.c | 88 +++++++++++++++++++++++++++++++++++++++--
src/conf/domain_conf.h | 2 +
4 files changed, 111 insertions(+), 3 deletions(-)
diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index e1fe0c4..8ef20c0 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -1673,6 +1673,18 @@
default read-write access is given (currently only works for
QEMU/KVM driver).
</dd>
+
+ <dt><code>space_hard_limit</code></dt>
+ <dd>
+ Maximum space available to this guests's filesystem.
+ </dd>
+
+ <dt><code>space_soft_limit</code></dt>
+ <dd>
+ Maximum space available to this guest's filesystem. The container is
+ is permitted to exceed its soft limits for a grace period of time. Afterwards
+ the hard limit is enforced.
+ </dd>
</dl>
<h4><a name="elementsAddress">Device Addresses</a></h4>
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index 8419ccc..f068ff7 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -1300,6 +1300,18 @@
<ref name="address"/>
</optional>
</interleave>
+ <interleave>
+ <optional>
+ <element name="space_hard_limit">
+ <ref name='scaledInteger'/>
+ </element>
+ </optional>
+ <optional>
+ <element name="space_soft_limit">
+ <ref name='scaledInteger'/>
+ </element>
+ </optional>
+ </interleave>
</element>
</define>
<!--
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 3fce7e5..d5e01a8 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -4086,14 +4086,72 @@ cleanup:
goto cleanup;
}
+
+/* Parse a value located at XPATH within CTXT, and store the
+ * result into val. If REQUIRED, then the value must exist;
+ * otherwise, the value is optional. The value is in bytes.
+ * Return 0 on success, -1 on failure after issuing error. */
+static int
+virDomainParseScaledValue(const char *xpath,
+ xmlXPathContextPtr ctxt,
+ unsigned long long *val,
+ unsigned long long scale,
+ unsigned long long max,
+ bool required)
+{
+ char *xpath_full = NULL;
+ char *unit = NULL;
+ int ret = -1;
+ unsigned long long bytes;
+
+ *val = 0;
+ if (virAsprintf(&xpath_full, "string(%s)", xpath) < 0) {
+ virReportOOMError();
+ goto cleanup;
+ }
+ ret = virXPathULongLong(xpath_full, ctxt, &bytes);
+ if (ret < 0) {
+ if (ret == -2)
+ virDomainReportError(VIR_ERR_XML_ERROR,
+ _("could not parse memory element %s"),
+ xpath);
+ else if (required)
+ virDomainReportError(VIR_ERR_XML_ERROR,
+ _("missing element %s"),
+ xpath);
+ else
+ ret = 0;
+ goto cleanup;
+ }
+ VIR_FREE(xpath_full);
+
+ if (virAsprintf(&xpath_full, "string(%s/@unit)", xpath) < 0) {
+ virReportOOMError();
+ goto cleanup;
+ }
+ unit = virXPathString(xpath_full, ctxt);
+
+ if (virScaleInteger(&bytes, unit, scale, max) < 0)
+ goto cleanup;
+
+ *val = bytes;
+ ret = 0;
+cleanup:
+ VIR_FREE(xpath_full);
+ VIR_FREE(unit);
+ return ret;
+}
+
+
/* Parse the XML definition for a disk
* @param node XML nodeset to parse for disk definition
*/
static virDomainFSDefPtr
virDomainFSDefParseXML(xmlNodePtr node,
+ xmlXPathContextPtr ctxt,
unsigned int flags) {
virDomainFSDefPtr def;
- xmlNodePtr cur;
+ xmlNodePtr cur, safe_node = ctxt->node;
char *type = NULL;
char *fsdriver = NULL;
char *source = NULL;
@@ -4101,6 +4159,8 @@ virDomainFSDefParseXML(xmlNodePtr node,
char *accessmode = NULL;
char *wrpolicy = NULL;
+ ctxt->node = node;
+
if (VIR_ALLOC(def) < 0) {
virReportOOMError();
return NULL;
@@ -4128,6 +4188,18 @@ virDomainFSDefParseXML(xmlNodePtr node,
def->accessmode = VIR_DOMAIN_FS_ACCESSMODE_PASSTHROUGH;
}
+ if (virDomainParseScaledValue("./space_hard_limit[1]", ctxt,
+ &def->space_hard_limit, 1,
+ ULONG_LONG_MAX,
+ false) < 0)
+ goto error;
+
+ if (virDomainParseScaledValue("./space_soft_limit[1]", ctxt,
+ &def->space_soft_limit, 1,
+ ULONG_LONG_MAX,
+ false) < 0)
+ goto error;
+
cur = node->children;
while (cur != NULL) {
if (cur->type == XML_ELEMENT_NODE) {
@@ -4194,6 +4266,7 @@ virDomainFSDefParseXML(xmlNodePtr node,
goto error;
cleanup:
+ ctxt->node = safe_node;
VIR_FREE(type);
VIR_FREE(fsdriver);
VIR_FREE(target);
@@ -6883,7 +6956,7 @@ virDomainDeviceDefPtr virDomainDeviceDefParse(virCapsPtr caps,
goto error;
} else if (xmlStrEqual(node->name, BAD_CAST "filesystem")) {
dev->type = VIR_DOMAIN_DEVICE_FS;
- if (!(dev->data.fs = virDomainFSDefParseXML(node, flags)))
+ if (!(dev->data.fs = virDomainFSDefParseXML(node, ctxt, flags)))
goto error;
} else if (xmlStrEqual(node->name, BAD_CAST "interface")) {
dev->type = VIR_DOMAIN_DEVICE_NET;
@@ -8404,7 +8478,7 @@ static virDomainDefPtr virDomainDefParseXML(virCapsPtr caps,
if (n && VIR_ALLOC_N(def->fss, n) < 0)
goto no_memory;
for (i = 0 ; i < n ; i++) {
- virDomainFSDefPtr fs = virDomainFSDefParseXML(nodes[i],
+ virDomainFSDefPtr fs = virDomainFSDefParseXML(nodes[i], ctxt,
flags);
if (!fs)
goto error;
@@ -11101,6 +11175,14 @@ virDomainFSDefFormat(virBufferPtr buf,
if (virDomainDeviceInfoFormat(buf, &def->info, flags) < 0)
return -1;
+
+ if (def->space_hard_limit)
+ virBufferAsprintf(buf, " <space_hard_limit unit='B'>"
+ "%llu</space_hard_limit>\n", def->space_hard_limit);
+ if (def->space_soft_limit) {
+ virBufferAsprintf(buf, " <space_soft_limit unit='B'>"
+ "%llu</space_soft_limit>\n", def->space_soft_limit);
+ }
virBufferAddLit(buf, " </filesystem>\n");
return 0;
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 5aa8fc1..7331ef5 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -692,6 +692,8 @@ struct _virDomainFSDef {
char *dst;
unsigned int readonly : 1;
virDomainDeviceInfo info;
+ unsigned long long space_hard_limit; /* in bytes */
+ unsigned long long space_soft_limit; /* in bytes */
};
--
1.7.10
12 years, 6 months