[libvirt] [PATCH V4] Sheepdog: Auto Adding volume and pool refresh.

From: Joel SIMOES <joel.simoes@laposte.net> Libvirt lose sheepdogs volumes on pool refresh or restart. When restarting sheepdog pool, all volumes are missing. This patch add automatically all volume from the added pool. With Jan Tomko help --- src/storage/storage_backend_sheepdog.c | 68 ++++++++++++++++++++++++++++++++-- 1 file changed, 64 insertions(+), 4 deletions(-) diff --git a/src/storage/storage_backend_sheepdog.c b/src/storage/storage_backend_sheepdog.c index a6981ce..7a139e7 100644 --- a/src/storage/storage_backend_sheepdog.c +++ b/src/storage/storage_backend_sheepdog.c @@ -109,22 +109,82 @@ virStorageBackendSheepdogAddHostArg(virCommandPtr cmd, virCommandAddArgFormat(cmd, "%d", port); } +static int +virStorageBackendSheepdogRefreshAllVol(virConnectPtr conn ATTRIBUTE_UNUSED, + virStoragePoolObjPtr pool) +{ + int ret = -1; + char *output = NULL; + char** lines = NULL; + char** cells = NULL; + size_t i; + + virCommandPtr cmd = virCommandNewArgList(COLLIE, "vdi", "list", "-r", NULL); + virStorageBackendSheepdogAddHostArg(cmd, pool); + virCommandSetOutputBuffer(cmd, &output); + if (virCommandRun(cmd, NULL) < 0) + goto cleanup; + + lines = virStringSplit(output, "\n", 0); + if (lines == NULL) + goto cleanup; + + for (i = 0; lines[i]; i++) { + char *line = lines[i]; + if (line == NULL) + break; + cells = virStringSplit(line, " ", 0); + if (cells == NULL || virStringListLength(cells) <= 2) + continue; + char *cell = cells[1]; + virStorageVolDefPtr vol = NULL; + if (VIR_ALLOC(vol) < 0) + goto cleanup; + + if (VIR_STRDUP(vol->name, cell) < 0) + goto cleanup; + + vol->type = VIR_STORAGE_VOL_BLOCK; + + if (VIR_EXPAND_N(pool->volumes.objs, pool->volumes.count, 1) < 0) + goto cleanup; + pool->volumes.objs[pool->volumes.count - 1] = vol; + + if (virStorageBackendSheepdogRefreshVol(conn, pool, vol) < 0) + goto cleanup; + vol = NULL; + virStringFreeList(cells); + } + + ret = 0; + +cleanup: + virCommandFree(cmd); + virStringFreeList(lines); + virStringFreeList(cells); + return ret; +} + static int virStorageBackendSheepdogRefreshPool(virConnectPtr conn ATTRIBUTE_UNUSED, virStoragePoolObjPtr pool) { - int ret; + int ret = -1; char *output = NULL; virCommandPtr cmd; cmd = virCommandNewArgList(COLLIE, "node", "info", "-r", NULL); virStorageBackendSheepdogAddHostArg(cmd, pool); virCommandSetOutputBuffer(cmd, &output); - ret = virCommandRun(cmd, NULL); - if (ret == 0) - ret = virStorageBackendSheepdogParseNodeInfo(pool->def, output); + if (virCommandRun(cmd, NULL) < 0) + goto cleanup; + + if (virStorageBackendSheepdogParseNodeInfo(pool->def, output) < 0) + goto cleanup; + ret = virStorageBackendSheepdogRefreshAllVol(conn, pool); +cleanup: virCommandFree(cmd); VIR_FREE(output); return ret; -- 1.8.3.2

On Mon, Feb 03, 2014 at 05:55:49PM +0100, joel SIMOES wrote:
From: Joel SIMOES <joel.simoes@laposte.net>
Libvirt lose sheepdogs volumes on pool refresh or restart. When restarting sheepdog pool, all volumes are missing. This patch add automatically all volume from the added pool.
With Jan Tomko help --- src/storage/storage_backend_sheepdog.c | 68 ++++++++++++++++++++++++++++++++-- 1 file changed, 64 insertions(+), 4 deletions(-)
diff --git a/src/storage/storage_backend_sheepdog.c b/src/storage/storage_backend_sheepdog.c index a6981ce..7a139e7 100644 --- a/src/storage/storage_backend_sheepdog.c +++ b/src/storage/storage_backend_sheepdog.c @@ -109,22 +109,82 @@ virStorageBackendSheepdogAddHostArg(virCommandPtr cmd, virCommandAddArgFormat(cmd, "%d", port); }
+static int +virStorageBackendSheepdogRefreshAllVol(virConnectPtr conn ATTRIBUTE_UNUSED, + virStoragePoolObjPtr pool) +{ + int ret = -1; + char *output = NULL; + char** lines = NULL; + char** cells = NULL;
Nitpick - the '**' should associate with the variable name rather than the type name.
+ size_t i; + + virCommandPtr cmd = virCommandNewArgList(COLLIE, "vdi", "list", "-r", NULL); + virStorageBackendSheepdogAddHostArg(cmd, pool); + virCommandSetOutputBuffer(cmd, &output); + if (virCommandRun(cmd, NULL) < 0) + goto cleanup; + + lines = virStringSplit(output, "\n", 0); + if (lines == NULL) + goto cleanup; + + for (i = 0; lines[i]; i++) { + char *line = lines[i]; + if (line == NULL) + break; + cells = virStringSplit(line, " ", 0); + if (cells == NULL || virStringListLength(cells) <= 2) + continue;
If cells != NULL, but the virStringListLength is <= 2 then you leak the memory for 'cells'. You need to fre cells before skiping to the next look iteration.
+ char *cell = cells[1]; + virStorageVolDefPtr vol = NULL; + if (VIR_ALLOC(vol) < 0) + goto cleanup; + + if (VIR_STRDUP(vol->name, cell) < 0) + goto cleanup;
If this strdup fails, then this will leak memory for 'vol', so need to have a free of that.
+ + vol->type = VIR_STORAGE_VOL_BLOCK; + + if (VIR_EXPAND_N(pool->volumes.objs, pool->volumes.count, 1) < 0) + goto cleanup; + pool->volumes.objs[pool->volumes.count - 1] = vol; + + if (virStorageBackendSheepdogRefreshVol(conn, pool, vol) < 0) + goto cleanup; + vol = NULL; + virStringFreeList(cells);
You need to assign 'cells = NULL' here, otherwise if the loop terminates, you may get an attempt to free the pointer/list again.
+ } + + ret = 0; + +cleanup: + virCommandFree(cmd); + virStringFreeList(lines); + virStringFreeList(cells); + return ret; +}
Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|
participants (2)
-
Daniel P. Berrange
-
joel SIMOES