[libvirt] [PATCH] xen_xs: Guard against set but empty kernel argument
by Guido Guenther
On xen 4.1 I observied configurations that look like:
(image
(hvm
(kernel '')
(loader '/foo/bar')
))
The kernel element is there but unset. This leads to an emtpy <kernel/>
element in the XML and even worse makes us skip the boot order parsing
and therefore not emit a <boot device='$dev>'/> element which breaks CD
booting.
O.k. to apply?
Cheers,
-- Guido
---
src/xenxs/xen_sxpr.c | 6 +++
.../sexpr2xmldata/sexpr2xml-fv-empty-kernel.sexpr | 9 ++++
tests/sexpr2xmldata/sexpr2xml-fv-empty-kernel.xml | 41 ++++++++++++++++++++
tests/sexpr2xmltest.c | 2 +
4 files changed, 58 insertions(+), 0 deletions(-)
create mode 100644 tests/sexpr2xmldata/sexpr2xml-fv-empty-kernel.sexpr
create mode 100644 tests/sexpr2xmldata/sexpr2xml-fv-empty-kernel.xml
diff --git a/src/xenxs/xen_sxpr.c b/src/xenxs/xen_sxpr.c
index 72322a7..15eaf18 100644
--- a/src/xenxs/xen_sxpr.c
+++ b/src/xenxs/xen_sxpr.c
@@ -125,6 +125,12 @@ xenParseSxprOS(const struct sexpr *node,
STREQ(def->os.kernel, def->os.loader)) {
VIR_FREE(def->os.kernel);
}
+ /* Drop kernel argument that has no value */
+ if (hvm &&
+ def->os.kernel && *def->os.kernel == '\0' &&
+ def->os.loader) {
+ VIR_FREE(def->os.kernel);
+ }
if (!def->os.kernel &&
hvm) {
diff --git a/tests/sexpr2xmldata/sexpr2xml-fv-empty-kernel.sexpr b/tests/sexpr2xmldata/sexpr2xml-fv-empty-kernel.sexpr
new file mode 100644
index 0000000..ded668c
--- /dev/null
+++ b/tests/sexpr2xmldata/sexpr2xml-fv-empty-kernel.sexpr
@@ -0,0 +1,9 @@
+(domain (domid 3)(name 'fvtest')(memory 400)(maxmem 400)(vcpus 1)\
+(uuid 'b5d70dd275cdaca517769660b059d8bc')(on_poweroff 'destroy')\
+(on_reboot 'restart')(on_crash 'restart')\
+(image (hvm (loader /usr/lib/xen/boot/hvmloader)(kernel '')\
+(device_model '/usr/lib64/xen/bin/qemu-dm')(boot d)(cdrom '/root/boot.iso')\
+(acpi 1)(vnc 1)(keymap ja)))(device (vbd (dev 'ioemu:hda')\
+(uname 'file:/root/foo.img')(mode 'w')))\
+(device (vif (mac '00:16:3e:1b:b1:47')(bridge 'xenbr0')\
+(script 'vif-bridge')(type ioemu))))
diff --git a/tests/sexpr2xmldata/sexpr2xml-fv-empty-kernel.xml b/tests/sexpr2xmldata/sexpr2xml-fv-empty-kernel.xml
new file mode 100644
index 0000000..2c1c756
--- /dev/null
+++ b/tests/sexpr2xmldata/sexpr2xml-fv-empty-kernel.xml
@@ -0,0 +1,41 @@
+<domain type='xen' id='3'>
+ <name>fvtest</name>
+ <uuid>b5d70dd2-75cd-aca5-1776-9660b059d8bc</uuid>
+ <memory>409600</memory>
+ <currentMemory>409600</currentMemory>
+ <vcpu>1</vcpu>
+ <os>
+ <type>hvm</type>
+ <loader>/usr/lib/xen/boot/hvmloader</loader>
+ <boot dev='cdrom'/>
+ </os>
+ <features>
+ <acpi/>
+ </features>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>restart</on_crash>
+ <devices>
+ <emulator>/usr/lib64/xen/bin/qemu-dm</emulator>
+ <disk type='file' device='disk'>
+ <driver name='file'/>
+ <source file='/root/foo.img'/>
+ <target dev='hda' bus='ide'/>
+ </disk>
+ <disk type='file' device='cdrom'>
+ <driver name='file'/>
+ <source file='/root/boot.iso'/>
+ <target dev='hdc' bus='ide'/>
+ <readonly/>
+ </disk>
+ <interface type='bridge'>
+ <mac address='00:16:3e:1b:b1:47'/>
+ <source bridge='xenbr0'/>
+ <script path='vif-bridge'/>
+ <target dev='vif3.0'/>
+ </interface>
+ <input type='mouse' bus='ps2'/>
+ <graphics type='vnc' port='5903' autoport='no' keymap='ja'/>
+ </devices>
+</domain>
diff --git a/tests/sexpr2xmltest.c b/tests/sexpr2xmltest.c
index 26a987d..126a78c 100644
--- a/tests/sexpr2xmltest.c
+++ b/tests/sexpr2xmltest.c
@@ -180,6 +180,8 @@ mymain(void)
DO_TEST("fv-net-ioemu", "fv-net-ioemu", 1);
DO_TEST("fv-net-netfront", "fv-net-netfront", 1);
+ DO_TEST("fv-empty-kernel", "fv-empty-kernel", 1);
+
DO_TEST("boot-grub", "boot-grub", 1);
virCapabilitiesFree(caps);
--
1.7.6.3
13 years, 1 month
[libvirt] [PATCH 1/2] xen: add error handling to UUID parsing
by Guido Günther
otherwise a missing UUID in a domain config just shows:
libxlDomainXMLFromNative:2600 : Internal Error parsing xm config failed
Now we have:
xenXMConfigGetUUID:186 : Internal Error config value uuid was missing
O.k. to apply?
-- Guido
---
src/xenxs/xen_xm.c | 37 +++++++++++++++++++++++++++----------
1 files changed, 27 insertions(+), 10 deletions(-)
diff --git a/src/xenxs/xen_xm.c b/src/xenxs/xen_xm.c
index 03857c8..d057043 100644
--- a/src/xenxs/xen_xm.c
+++ b/src/xenxs/xen_xm.c
@@ -174,21 +174,38 @@ static int xenXMConfigCopyStringOpt(virConfPtr conf,
/* Convenience method to grab a string UUID from the config file object */
static int xenXMConfigGetUUID(virConfPtr conf, const char *name, unsigned char *uuid) {
virConfValuePtr val;
- if (!uuid || !name || !conf)
- return (-1);
+
+ if (!uuid || !name || !conf) {
+ XENXS_ERROR(VIR_ERR_INVALID_ARG,
+ _("Arguments must be non null"));
+ return -1;
+ }
+
if (!(val = virConfGetValue(conf, name))) {
- return (-1);
+ XENXS_ERROR(VIR_ERR_INTERNAL_ERROR,
+ _("config value %s was missing"), name);
+ return -1;
}
- if (val->type != VIR_CONF_STRING)
- return (-1);
- if (!val->str)
- return (-1);
+ if (val->type != VIR_CONF_STRING) {
+ XENXS_ERROR(VIR_ERR_INTERNAL_ERROR,
+ _("config value %s not a string"), name);
+ return -1;
+ }
+
+ if (!val->str) {
+ XENXS_ERROR(VIR_ERR_INTERNAL_ERROR,
+ _("%s can't be empty"), name);
+ return -1;
+ }
- if (virUUIDParse(val->str, uuid) < 0)
- return (-1);
+ if (virUUIDParse(val->str, uuid) < 0) {
+ XENXS_ERROR(VIR_ERR_INTERNAL_ERROR,
+ _("%s not parseable"), val->str);
+ return -1;
+ }
- return (0);
+ return 0;
}
#define MAX_VFB 1024
--
1.7.6.3
13 years, 1 month
[libvirt] [PATCH] maint: typo fixes
by Eric Blake
I noticed a couple typos in recent commits, and fixed the remaining
instances of them.
* docs/internals/command.html.in: Fix spelling errors.
* include/libvirt/libvirt.h.in (virConnectDomainEventCallback):
Likewise.
* python/libvirt-override.py (virEventAddHandle): Likewise.
* src/lxc/lxc_container.c (lxcContainerChild): Likewise.
* src/util/hash.c (virHashCreateFull): Likewise.
* src/storage/storage_backend_logical.c
(virStorageBackendLogicalMakeVol): Likewise.
* src/esx/esx_driver.c (esxFormatVMXFileName): Likewise.
* src/vbox/vbox_tmpl.c (vboxIIDIsEqual_v3_x): Likewise.
---
Pushing under the trivial rule.
docs/internals/command.html.in | 2 +-
include/libvirt/libvirt.h.in | 4 ++--
python/libvirt-override.py | 4 ++--
src/esx/esx_driver.c | 2 +-
src/lxc/lxc_container.c | 2 +-
src/storage/storage_backend_logical.c | 4 ++--
src/util/hash.c | 2 +-
src/vbox/vbox_tmpl.c | 2 +-
8 files changed, 11 insertions(+), 11 deletions(-)
diff --git a/docs/internals/command.html.in b/docs/internals/command.html.in
index 8a194ec..7dcf462 100644
--- a/docs/internals/command.html.in
+++ b/docs/internals/command.html.in
@@ -445,7 +445,7 @@
<strong>Note:</strong> if the command has been daemonized
this will only block & wait for the intermediate process,
not the real command. <code>virCommandRun</code> will
- report on any errors that have occured upon this point
+ report on any errors that have occurred upon this point
with all previous API calls. If the command fails to
run, or exits with non-zero status an error will be
reported via normal libvirt error infrastructure. If a
diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in
index 07617be..1e4b2a2 100644
--- a/include/libvirt/libvirt.h.in
+++ b/include/libvirt/libvirt.h.in
@@ -2173,8 +2173,8 @@ typedef enum {
/**
* virConnectDomainEventCallback:
* @conn: virConnect connection
- * @dom: The domain on which the event occured
- * @event: The specfic virDomainEventType which occured
+ * @dom: The domain on which the event occurred
+ * @event: The specfic virDomainEventType which occurred
* @detail: event specific detail information
* @opaque: opaque user data
*
diff --git a/python/libvirt-override.py b/python/libvirt-override.py
index 98241d6..387fddf 100644
--- a/python/libvirt-override.py
+++ b/python/libvirt-override.py
@@ -179,8 +179,8 @@ def virEventAddHandle(fd, events, cb, opaque):
Example callback prototype is:
def cb(watch, # int id of the handle
- fd, # int file descriptor the event occured on
- events, # int bitmap of events that have occured
+ fd, # int file descriptor the event occurred on
+ events, # int bitmap of events that have occurred
opaque): # opaque data passed to eventAddHandle
"""
cbData = {"cb" : cb, "opaque" : opaque}
diff --git a/src/esx/esx_driver.c b/src/esx/esx_driver.c
index 3f26557..af30c1b 100644
--- a/src/esx/esx_driver.c
+++ b/src/esx/esx_driver.c
@@ -276,7 +276,7 @@ esxParseVMXFileName(const char *fileName, void *opaque)
*
* Firstly parse the datastore path. Then use the datastore name to lookup the
* datastore and it's mount path. Finally concatenate the mount path, directory
- * and file name to an absolute path and return it. Detect the seperator type
+ * and file name to an absolute path and return it. Detect the separator type
* based on the mount path.
*/
static char *
diff --git a/src/lxc/lxc_container.c b/src/lxc/lxc_container.c
index 69cea8e..e9891f7 100644
--- a/src/lxc/lxc_container.c
+++ b/src/lxc/lxc_container.c
@@ -1117,7 +1117,7 @@ cleanup:
VIR_FORCE_CLOSE(argv->handshakefd);
if (ret == 0) {
- /* this function will only return if an error occured */
+ /* this function will only return if an error occurred */
ret = virCommandExec(cmd);
}
diff --git a/src/storage/storage_backend_logical.c b/src/storage/storage_backend_logical.c
index 6137278..51624a7 100644
--- a/src/storage/storage_backend_logical.c
+++ b/src/storage/storage_backend_logical.c
@@ -167,7 +167,7 @@ virStorageBackendLogicalMakeVol(virStoragePoolObjPtr pool,
goto cleanup;
}
- /* Now parse the "devices" feild seperately */
+ /* Now parse the "devices" field separately */
regex = strdup(regex_unit);
for (i = 1; i < nextents; i++) {
@@ -175,7 +175,7 @@ virStorageBackendLogicalMakeVol(virStoragePoolObjPtr pool,
virReportOOMError();
goto cleanup;
}
- /* "," is the seperator of "devices" field */
+ /* "," is the separator of "devices" field */
strcat(regex, ",");
strncat(regex, regex_unit, strlen(regex_unit));
}
diff --git a/src/util/hash.c b/src/util/hash.c
index b5ec6af..42ccff7 100644
--- a/src/util/hash.c
+++ b/src/util/hash.c
@@ -120,7 +120,7 @@ virHashComputeKey(virHashTablePtr table, const void *name)
*
* Create a new virHashTablePtr.
*
- * Returns the newly created object, or NULL if an error occured.
+ * Returns the newly created object, or NULL if an error occurred.
*/
virHashTablePtr virHashCreateFull(int size,
virHashDataFree dataFree,
diff --git a/src/vbox/vbox_tmpl.c b/src/vbox/vbox_tmpl.c
index 8c53f1f..9b674a9 100644
--- a/src/vbox/vbox_tmpl.c
+++ b/src/vbox/vbox_tmpl.c
@@ -537,7 +537,7 @@ vboxIIDIsEqual_v3_x(vboxGlobalData *data, vboxIID_v3_x *iid1,
unsigned char uuid2[VIR_UUID_BUFLEN];
/* Note: we can't directly compare the utf8 strings here
- * cause the two UUID's may have seperators as space or '-'
+ * cause the two UUID's may have separators as space or '-'
* or mixture of both and we don't want to fail here by
* using direct string comparison. Here virUUIDParse() takes
* care of these cases. */
--
1.7.4.4
13 years, 1 month
[libvirt] [PATCH 1/2] snapshot: sort snapshot-list --tree
by Eric Blake
Otherwise, the results are not repeatable.
* tools/virsh.c (cmdSnapshotList): Print tree in predictable order.
---
tools/virsh.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/tools/virsh.c b/tools/virsh.c
index 9532bc3..20b3dc5 100644
--- a/tools/virsh.c
+++ b/tools/virsh.c
@@ -13209,6 +13209,8 @@ cmdSnapshotList(vshControl *ctl, const vshCmd *cmd)
if (actual < 0)
goto cleanup;
+ qsort(&names[0], actual, sizeof(char*), namesorter);
+
if (tree) {
char indentBuf[INDENT_BUFLEN];
char **parents = vshMalloc(ctl, sizeof(char *) * actual);
@@ -13245,8 +13247,6 @@ cmdSnapshotList(vshControl *ctl, const vshCmd *cmd)
ret = true;
goto cleanup;
} else {
- qsort(&names[0], actual, sizeof(char*), namesorter);
-
for (i = 0; i < actual; i++) {
/* free up memory from previous iterations of the loop */
VIR_FREE(parent);
--
1.7.4.4
13 years, 1 month
[libvirt] [v2] storage: Do not use comma as seperator for lvs output
by Osier Yang
* src/storage/storage_backend_logical.c:
If a logical vol is created as striped. (e.g. --stripes 3),
the "device" field of lvs output will have multiple fileds which are
seperated by comma. Thus the RE we write in the codes will not
work well anymore. E.g. (lvs output for a stripped vol, uses "#" as
seperator here):
test_stripes##fSLSZH-zAS2-yAIb-n4mV-Al9u-HA3V-oo9K1B#\
/dev/sdc1(10240),/dev/sdd1(0)#42949672960#4194304
The RE we use:
const char *regexes[] = {
"^\\s*(\\S+),(\\S*),(\\S+),(\\S+)\\((\\S+)\\),(\\S+),([0-9]+),?\\s*$"
};
Also the RE doesn't match the "devices" field of striped vol properly,
it contains multiple "device path" and "offset".
This patch mainly does:
1) Change the seperator into "#"
2) Change the RE for "devices" field from "(\\S+)\\((\\S+)\\)"
into "(\\S+)".
3) Add two new options for lvs command, (segtype, stripes)
4) Extend the RE to match the value for the two new fields.
5) Parse the "devices" field seperately in virStorageBackendLogicalMakeVol,
multiple "extents" info are generated if the vol is striped. The
number of "extents" is equal to the stripes number of the striped vol.
A incidental fix: (virStorageBackendLogicalMakeVol)
Free "vol" if it's new created and there is error.
Demo on striped vol with the patch applied:
% virsh vol-dumpxml /dev/test_vg/vol_striped2
<volume>
<name>vol_striped2</name>
<key>QuWqmn-kIkZ-IATt-67rc-OWEP-1PHX-Cl2ICs</key>
<source>
<device path='/dev/sda5'>
<extent start='79691776' end='88080384'/>
</device>
<device path='/dev/sda6'>
<extent start='62914560' end='71303168'/>
</device>
</source>
<capacity>8388608</capacity>
<allocation>8388608</allocation>
<target>
<path>/dev/test_vg/vol_striped2</path>
<permissions>
<mode>0660</mode>
<owner>0</owner>
<group>6</group>
<label>system_u:object_r:fixed_disk_device_t:s0</label>
</permissions>
</target>
</volume>
RHBZ: https://bugzilla.redhat.com/show_bug.cgi?id=727474
v1 - v2:
v1 just simply changes the seperator into "#".
---
src/storage/storage_backend_logical.c | 156 +++++++++++++++++++++++++--------
1 files changed, 121 insertions(+), 35 deletions(-)
diff --git a/src/storage/storage_backend_logical.c b/src/storage/storage_backend_logical.c
index 589f486..dda68fd 100644
--- a/src/storage/storage_backend_logical.c
+++ b/src/storage/storage_backend_logical.c
@@ -62,13 +62,22 @@ virStorageBackendLogicalSetActive(virStoragePoolObjPtr pool,
}
+#define VIR_STORAGE_VOL_LOGICAL_SEGTYPE_STRIPED "striped"
+
static int
virStorageBackendLogicalMakeVol(virStoragePoolObjPtr pool,
char **const groups,
void *data)
{
virStorageVolDefPtr vol = NULL;
+ bool is_new_vol = false;
unsigned long long offset, size, length;
+ const char *regex_unit = "(\\S+)\\((\\S+)\\)";
+ char *regex = NULL;
+ regex_t *reg = NULL;
+ regmatch_t *vars = NULL;
+ char *p = NULL;
+ int i, err, nextents, nvars, ret = -1;
/* See if we're only looking for a specific volume */
if (data != NULL) {
@@ -88,19 +97,18 @@ virStorageBackendLogicalMakeVol(virStoragePoolObjPtr pool,
return -1;
}
+ is_new_vol = true;
vol->type = VIR_STORAGE_VOL_BLOCK;
if ((vol->name = strdup(groups[0])) == NULL) {
virReportOOMError();
- virStorageVolDefFree(vol);
- return -1;
+ goto cleanup;
}
if (VIR_REALLOC_N(pool->volumes.objs,
pool->volumes.count + 1)) {
virReportOOMError();
- virStorageVolDefFree(vol);
- return -1;
+ goto cleanup;
}
pool->volumes.objs[pool->volumes.count++] = vol;
}
@@ -109,8 +117,7 @@ virStorageBackendLogicalMakeVol(virStoragePoolObjPtr pool,
if (virAsprintf(&vol->target.path, "%s/%s",
pool->def->target.path, vol->name) < 0) {
virReportOOMError();
- virStorageVolDefFree(vol);
- return -1;
+ goto cleanup;
}
}
@@ -118,8 +125,7 @@ virStorageBackendLogicalMakeVol(virStoragePoolObjPtr pool,
if (virAsprintf(&vol->backingStore.path, "%s/%s",
pool->def->target.path, groups[1]) < 0) {
virReportOOMError();
- virStorageVolDefFree(vol);
- return -1;
+ goto cleanup;
}
vol->backingStore.format = VIR_STORAGE_POOL_LOGICAL_LVM2;
@@ -128,47 +134,127 @@ virStorageBackendLogicalMakeVol(virStoragePoolObjPtr pool,
if (vol->key == NULL &&
(vol->key = strdup(groups[2])) == NULL) {
virReportOOMError();
- return -1;
+ goto cleanup;
}
if (virStorageBackendUpdateVolInfo(vol, 1) < 0)
- return -1;
+ goto cleanup;
+ nextents = 1;
+ if (STREQ(groups[4], VIR_STORAGE_VOL_LOGICAL_SEGTYPE_STRIPED)) {
+ if (virStrToLong_i(groups[5], NULL, 10, &nextents) < 0) {
+ virStorageReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("malformed volume extent stripes value"));
+ goto cleanup;
+ }
+ }
/* Finally fill in extents information */
if (VIR_REALLOC_N(vol->source.extents,
- vol->source.nextent + 1) < 0) {
+ vol->source.nextent + nextents) < 0) {
virReportOOMError();
- return -1;
+ goto cleanup;
}
- if ((vol->source.extents[vol->source.nextent].path =
- strdup(groups[3])) == NULL) {
+ if (virStrToLong_ull(groups[6], NULL, 10, &length) < 0) {
+ virStorageReportError(VIR_ERR_INTERNAL_ERROR,
+ "%s", _("malformed volume extent length value"));
+ goto cleanup;
+ }
+ if (virStrToLong_ull(groups[7], NULL, 10, &size) < 0) {
+ virStorageReportError(VIR_ERR_INTERNAL_ERROR,
+ "%s", _("malformed volume extent size value"));
+ goto cleanup;
+ }
+
+ /* Now parse the "devices" feild seperately */
+ regex = strdup(regex_unit);
+
+ for (i = 1; i < nextents; i++) {
+ if (VIR_REALLOC_N(regex, strlen(regex) + strlen(regex_unit) + 2) < 0) {
+ virReportOOMError();
+ goto cleanup;
+ }
+ /* "," is the seperator of "devices" field */
+ strcat(regex, ",");
+ strncat(regex, regex_unit, strlen(regex_unit));
+ }
+
+ if (VIR_ALLOC(reg) < 0) {
virReportOOMError();
- return -1;
+ goto cleanup;
}
- if (virStrToLong_ull(groups[4], NULL, 10, &offset) < 0) {
- virStorageReportError(VIR_ERR_INTERNAL_ERROR,
- "%s", _("malformed volume extent offset value"));
- return -1;
+ /* Each extent has a "path:offset" pair, and vars[0] will
+ * be the whole matched string.
+ */
+ nvars = (nextents * 2) + 1;
+ if (VIR_ALLOC_N(vars, nvars) < 0) {
+ virReportOOMError();
+ goto cleanup;
}
- if (virStrToLong_ull(groups[5], NULL, 10, &length) < 0) {
+
+ err = regcomp(reg, regex, REG_EXTENDED);
+ if (err != 0) {
+ char error[100];
+ regerror(err, reg, error, sizeof(error));
virStorageReportError(VIR_ERR_INTERNAL_ERROR,
- "%s", _("malformed volume extent length value"));
- return -1;
+ _("Failed to compile regex %s"),
+ error);
+ goto cleanup;
}
- if (virStrToLong_ull(groups[6], NULL, 10, &size) < 0) {
- virStorageReportError(VIR_ERR_INTERNAL_ERROR,
- "%s", _("malformed volume extent size value"));
- return -1;
+
+ if (regexec(reg, groups[3], nvars, vars, 0) != 0) {
+ virStorageReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("malformed volume extent devices value"));
+ goto cleanup;
}
- vol->source.extents[vol->source.nextent].start = offset * size;
- vol->source.extents[vol->source.nextent].end = (offset * size) + length;
- vol->source.nextent++;
+ p = groups[3];
- return 0;
+ /* vars[0] is skipped */
+ for (i = 0; i < nextents; i++) {
+ int j, len;
+ const char *offset_str = NULL;
+
+ j = (i * 2) + 1;
+ len = vars[j].rm_eo - vars[j].rm_so;
+ p[vars[j].rm_eo] = '\0';
+
+ if ((vol->source.extents[vol->source.nextent].path =
+ strndup(p + vars[j].rm_so, len)) == NULL) {
+ virReportOOMError();
+ goto cleanup;
+ }
+
+ len = vars[j + 1].rm_eo - vars[j + 1].rm_so;
+ if (!(offset_str = strndup(p + vars[j + 1].rm_so, len))) {
+ virReportOOMError();
+ goto cleanup;
+ }
+
+ if (virStrToLong_ull(offset_str, NULL, 10, &offset) < 0) {
+ virStorageReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("malformed volume extent offset value"));
+ goto cleanup;
+ }
+
+ VIR_FREE(offset_str);
+
+ vol->source.extents[vol->source.nextent].start = offset * size;
+ vol->source.extents[vol->source.nextent].end = (offset * size) + length;
+ vol->source.nextent++;
+ }
+
+ ret = 0;
+
+cleanup:
+ VIR_FREE(regex);
+ VIR_FREE(reg);
+ VIR_FREE(vars);
+ if (is_new_vol && (ret == -1))
+ virStorageVolDefFree(vol);
+ return ret;
}
static int
@@ -193,15 +279,15 @@ virStorageBackendLogicalFindLVs(virStoragePoolObjPtr pool,
* not a suitable separator (rhbz 470693).
*/
const char *regexes[] = {
- "^\\s*(\\S+),(\\S*),(\\S+),(\\S+)\\((\\S+)\\),(\\S+),([0-9]+),?\\s*$"
+ "^\\s*(\\S+)#(\\S*)#(\\S+)#(\\S+)#(\\S+)#([0-9]+)#(\\S+)#([0-9]+)#?\\s*$"
};
int vars[] = {
- 7
+ 8
};
const char *prog[] = {
- LVS, "--separator", ",", "--noheadings", "--units", "b",
+ LVS, "--separator", "#", "--noheadings", "--units", "b",
"--unbuffered", "--nosuffix", "--options",
- "lv_name,origin,uuid,devices,seg_size,vg_extent_size",
+ "lv_name,origin,uuid,devices,segtype,stripes,seg_size,vg_extent_size",
pool->def->source.name, NULL
};
--
1.7.6
13 years, 1 month
[libvirt] [RFC] Adding new filesystem 'proxy' to 9p
by M. Mohan Kumar
Pass-through security model in QEMU 9p server needs root privilege to do few
file operations (like chown, chmod to any mode/uid:gid). There are two issues
in pass-through security model
1) TOCTTOU vulnerability: Following symbolic links in the server could
provide access to files beyond 9p export path.
2) When libvirt is configured to run qemu as non-root user (for example, if
qemu is configured to run as normal user 'qemu'), running file operations on
pass-through security model would fail because it needs root privileges.
To overcome above issues, following approach is suggested: A new filesytem
type 'proxy' is introduced. Proxy FS uses chroot + socket combination for
securing the vulnerability known with following symbolic links. Intention of
adding a new filesystem type is to allow qemu to run in non-root mode, but
doing privileged operations using socket IO.
A new binary (known as proxy helper) will be provided as part of qemu. Proxy
helper will chroot into 9p export path and create a socket pair or a named
socket based on the command line parameter. Qemu and proxy helper will
communicate using this socket.
We need following changes in the libvirt code to accomodate new 'proxy'
filesystem type:
If qemu 9p server is configured to use 'proxy' FS, libvirt will do
* Create a socket pair
* invoke proxy_helper binary with one of the socket id from the pair as
command line parameters to it with root privilege
* invoke qemu with one of socket id from the pair as paramter to qemu virtfs
after dropping to the configured user privilege.
ie, libvirt will invoke proxy_helper as:
proxy_helper -i <socket_fd_from_socket_pair> -p <9p-path-to-export>
and qemu will be invoked with following virtfs parameter:
-virtfs proxy,id=<id>,sock_fd=<socket_fd_from_socket_pair>
,path=/tmp/,security_model=prox,mount_tag=v_pass
People who want to use proxy_helper without libvirt can use following
interface:
$ proxy_helper -s </socket/path> -p <9p-path-to-export>
With following qemu fsdev parameter:
-virtfs proxy,id=<id>,socket=</socket/path>,path=/tmp/,
security_model=prox,mount_tag=v_pass
--
Regards,
M. Mohan Kumar
13 years, 1 month
[libvirt] [PATCH 0/7] Update systemtap probing
by Daniel P. Berrange
When looking at the keep alive code I needed an easy way to
monitor the RPC messages being sent/received. I toyed with
writing a WireShark plugin, but this seemed very hard work.
So instead I wrote a handy set of DTrace probes for the RPC
layer
At the same time I also needed to track a bug in the RPC
console streams code. These probes were very convenient
for diagnosing the problems there
13 years, 1 month
[libvirt] Qemu/KVM is 3x slower under libvirt
by Reeted
I repost this, this time by also including the libvirt mailing list.
Info on my libvirt: it's the version in Ubuntu 11.04 Natty which is
0.8.8-1ubuntu6.5 . I didn't recompile this one, while Kernel and
qemu-kvm are vanilla and compiled by hand as described below.
My original message follows:
This is really strange.
I just installed a new host with kernel 3.0.3 and Qemu-KVM 0.14.1
compiled by me.
I have created the first VM.
This is on LVM, virtio etc... if I run it directly from bash console, it
boots in 8 seconds (it's a bare ubuntu with no graphics), while if I
boot it under virsh (libvirt) it boots in 20-22 seconds. This is the
time from after Grub to the login prompt, or from after Grub to the
ssh-server up.
I was almost able to replicate the whole libvirt command line on the
bash console, and it still goes almost 3x faster when launched from bash
than with virsh start vmname. The part I wasn't able to replicate is the
-netdev part because I still haven't understood the semantics of it.
This is my bash commandline:
/opt/qemu-kvm-0.14.1/bin/qemu-system-x86_64 -M pc-0.14 -enable-kvm -m
2002 -smp 2,sockets=2,cores=1,threads=1 -name vmname1-1 -uuid
ee75e28a-3bf3-78d9-3cba-65aa63973380 -nodefconfig -nodefaults -chardev
socket,id=charmonitor,path=/var/lib/libvirt/qemu/vmname1-1.monitor,server,nowait
-mon chardev=charmonitor,id=monitor,mode=readline -rtc base=utc -boot
order=dc,menu=on -drive
file=/dev/mapper/vgPtpVM-lvVM_Vmname1_d1,if=none,id=drive-virtio-disk0,boot=on,format=raw,cache=none,aio=native
-device
virtio-blk-pci,bus=pci.0,addr=0x4,drive=drive-virtio-disk0,id=virtio-disk0
-drive
if=none,media=cdrom,id=drive-ide0-1-0,readonly=on,format=raw,cache=none,aio=native
-device ide-drive,bus=ide.1,unit=0,drive=drive-ide0-1-0,id=ide0-1-0 -net
nic,model=virtio -net tap,ifname=tap0,script=no,downscript=no -usb -vnc
127.0.0.1:0 -vga cirrus -device
virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x5
Which was taken from libvirt's command line. The only modifications I
did to the original libvirt commandline (seen with ps aux) were:
- Removed -S
- Network was: -netdev tap,fd=17,id=hostnet0,vhost=on,vhostfd=18 -device
virtio-net-pci,netdev=hostnet0,id=net0,mac=52:54:00:05:36:60,bus=pci.0,addr=0x3
Has been simplified to: -net nic,model=virtio -net
tap,ifname=tap0,script=no,downscript=no
and manual bridging of the tap0 interface.
Firstly I had thought that this could be fault of the VNC: I have
compiled qemu-kvm with no separate vnc thread. I thought that libvirt
might have connected to the vnc server at all times and this could have
slowed down the whole VM.
But then I also tried connecting vith vncviewer to the KVM machine
launched directly from bash, and the speed of it didn't change. So no,
it doesn't seem to be that.
BTW: is the slowdown of the VM on "no separate vnc thread" only in
effect when somebody is actually connected to VNC, or always?
Also, note that the time difference is not visible in dmesg once the
machine has booted. So it's not a slowdown in detecting devices. Devices
are always detected within the first 3 seconds, according to dmesg, at
3.6 seconds the first ext4 mount begins. It seems to be really the OS
boot that is slow... it seems an hard disk performance problem.
Thank you
R.
13 years, 1 month
[libvirt] [PATCH] qemuDomainAttach: Initialize pidfile variable
by Michal Privoznik
If parsing qemu command line fails (e.g. because of non-existing
process number supplied), we jump to cleanup label where we free
pidfile. Therefore it needs to be initialized. Otherwise we free
random pointer.
---
Pushing under trivial rule.
src/qemu/qemu_driver.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 2e6f3e4..5588d93 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -10179,7 +10179,7 @@ static virDomainPtr qemuDomainAttach(virConnectPtr conn,
virDomainPtr dom = NULL;
virDomainChrSourceDefPtr monConfig = NULL;
bool monJSON = false;
- char *pidfile;
+ char *pidfile = NULL;
virCheckFlags(0, NULL);
--
1.7.3.4
13 years, 1 month
[libvirt] [PATCH] qemu: silence Coverity false positive
by Eric Blake
Coverity complained that 4 out of 5 callers to virJSONValueObjectGetBoolean
checked for errors. But we documented that we don't care in this case.
* src/qemu/qemu_monitor_json.c (qemuMonitorJSONGetBlockInfo): Use
ignore_value.
---
Pushing under the trivial rule.
src/qemu/qemu_monitor_json.c | 4 +++-
1 files changed, 3 insertions(+), 1 deletions(-)
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
index c4f8360..3d383c8 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c
@@ -40,6 +40,7 @@
#include "datatypes.h"
#include "virterror_internal.h"
#include "json.h"
+#include "ignore-value.h"
#define VIR_FROM_THIS VIR_FROM_QEMU
@@ -1418,7 +1419,8 @@ int qemuMonitorJSONGetBlockInfo(qemuMonitorPtr mon,
/* Don't check for success here, because 'tray-open' is presented iff
* medium is ejected.
*/
- virJSONValueObjectGetBoolean(dev, "tray-open", &info->tray_open);
+ ignore_value(virJSONValueObjectGetBoolean(dev, "tray-open",
+ &info->tray_open));
break;
}
--
1.7.4.4
13 years, 1 month