mirror of
https://github.com/libvirt/libvirt.git
synced 2025-02-25 18:55:26 -06:00
util: qemu: Allow for different approaches to format JSON arrays
For use with memory hotplug virQEMUBuildCommandLineJSONRecurse attempted to format JSON arrays as bitmap on the command line. Make the formatter function configurable so that it can be reused with different syntaxes of arrays such as numbered arrays for use with disk sources. This patch extracts the code and adds a parameter for the function that will allow to plug in different formatters.
This commit is contained in:
parent
cd86d6f465
commit
b7eef33df2
@ -2205,6 +2205,7 @@ virProcessWait;
|
|||||||
# util/virqemu.h
|
# util/virqemu.h
|
||||||
virQEMUBuildBufferEscapeComma;
|
virQEMUBuildBufferEscapeComma;
|
||||||
virQEMUBuildCommandLineJSON;
|
virQEMUBuildCommandLineJSON;
|
||||||
|
virQEMUBuildCommandLineJSONArrayBitmap;
|
||||||
virQEMUBuildLuksOpts;
|
virQEMUBuildLuksOpts;
|
||||||
virQEMUBuildObjectCommandlineFromJSON;
|
virQEMUBuildObjectCommandlineFromJSON;
|
||||||
|
|
||||||
|
@ -36,6 +36,7 @@ VIR_LOG_INIT("util.qemu");
|
|||||||
struct virQEMUCommandLineJSONIteratorData {
|
struct virQEMUCommandLineJSONIteratorData {
|
||||||
const char *prefix;
|
const char *prefix;
|
||||||
virBufferPtr buf;
|
virBufferPtr buf;
|
||||||
|
virQEMUBuildCommandLineJSONArrayFormatFunc arrayFunc;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -43,8 +44,41 @@ static int
|
|||||||
virQEMUBuildCommandLineJSONRecurse(const char *key,
|
virQEMUBuildCommandLineJSONRecurse(const char *key,
|
||||||
const virJSONValue *value,
|
const virJSONValue *value,
|
||||||
virBufferPtr buf,
|
virBufferPtr buf,
|
||||||
|
virQEMUBuildCommandLineJSONArrayFormatFunc arrayFunc,
|
||||||
bool nested);
|
bool nested);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
virQEMUBuildCommandLineJSONArrayBitmap(const char *key,
|
||||||
|
const virJSONValue *array,
|
||||||
|
virBufferPtr buf)
|
||||||
|
{
|
||||||
|
ssize_t pos = -1;
|
||||||
|
ssize_t end;
|
||||||
|
virBitmapPtr bitmap = NULL;
|
||||||
|
|
||||||
|
if (virJSONValueGetArrayAsBitmap(array, &bitmap) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
while ((pos = virBitmapNextSetBit(bitmap, pos)) > -1) {
|
||||||
|
if ((end = virBitmapNextClearBit(bitmap, pos)) < 0)
|
||||||
|
end = virBitmapLastSetBit(bitmap) + 1;
|
||||||
|
|
||||||
|
if (end - 1 > pos) {
|
||||||
|
virBufferAsprintf(buf, ",%s=%zd-%zd", key, pos, end - 1);
|
||||||
|
pos = end;
|
||||||
|
} else {
|
||||||
|
virBufferAsprintf(buf, ",%s=%zd", key, pos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
virBitmapFree(bitmap);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* internal iterator to handle nested object formatting */
|
/* internal iterator to handle nested object formatting */
|
||||||
static int
|
static int
|
||||||
virQEMUBuildCommandLineJSONIterate(const char *key,
|
virQEMUBuildCommandLineJSONIterate(const char *key,
|
||||||
@ -59,11 +93,13 @@ virQEMUBuildCommandLineJSONIterate(const char *key,
|
|||||||
if (virAsprintf(&tmpkey, "%s.%s", data->prefix, key) < 0)
|
if (virAsprintf(&tmpkey, "%s.%s", data->prefix, key) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
ret = virQEMUBuildCommandLineJSONRecurse(tmpkey, value, data->buf, false);
|
ret = virQEMUBuildCommandLineJSONRecurse(tmpkey, value, data->buf,
|
||||||
|
data->arrayFunc, false);
|
||||||
|
|
||||||
VIR_FREE(tmpkey);
|
VIR_FREE(tmpkey);
|
||||||
} else {
|
} else {
|
||||||
ret = virQEMUBuildCommandLineJSONRecurse(key, value, data->buf, false);
|
ret = virQEMUBuildCommandLineJSONRecurse(key, value, data->buf,
|
||||||
|
data->arrayFunc, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
@ -74,13 +110,11 @@ static int
|
|||||||
virQEMUBuildCommandLineJSONRecurse(const char *key,
|
virQEMUBuildCommandLineJSONRecurse(const char *key,
|
||||||
const virJSONValue *value,
|
const virJSONValue *value,
|
||||||
virBufferPtr buf,
|
virBufferPtr buf,
|
||||||
|
virQEMUBuildCommandLineJSONArrayFormatFunc arrayFunc,
|
||||||
bool nested)
|
bool nested)
|
||||||
{
|
{
|
||||||
struct virQEMUCommandLineJSONIteratorData data = { key, buf };
|
struct virQEMUCommandLineJSONIteratorData data = { key, buf, arrayFunc };
|
||||||
virJSONValuePtr elem;
|
virJSONValuePtr elem;
|
||||||
virBitmapPtr bitmap = NULL;
|
|
||||||
ssize_t pos = -1;
|
|
||||||
ssize_t end;
|
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
if (!key && value->type != VIR_JSON_TYPE_OBJECT) {
|
if (!key && value->type != VIR_JSON_TYPE_OBJECT) {
|
||||||
@ -115,26 +149,15 @@ virQEMUBuildCommandLineJSONRecurse(const char *key,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (virJSONValueGetArrayAsBitmap(value, &bitmap) == 0) {
|
if (!arrayFunc || arrayFunc(key, value, buf) < 0) {
|
||||||
while ((pos = virBitmapNextSetBit(bitmap, pos)) > -1) {
|
|
||||||
if ((end = virBitmapNextClearBit(bitmap, pos)) < 0)
|
|
||||||
end = virBitmapLastSetBit(bitmap) + 1;
|
|
||||||
|
|
||||||
if (end - 1 > pos) {
|
|
||||||
virBufferAsprintf(buf, ",%s=%zd-%zd", key, pos, end - 1);
|
|
||||||
pos = end;
|
|
||||||
} else {
|
|
||||||
virBufferAsprintf(buf, ",%s=%zd", key, pos);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
/* fallback, treat the array as a non-bitmap, adding the key
|
/* fallback, treat the array as a non-bitmap, adding the key
|
||||||
* for each member */
|
* for each member */
|
||||||
for (i = 0; i < virJSONValueArraySize(value); i++) {
|
for (i = 0; i < virJSONValueArraySize(value); i++) {
|
||||||
elem = virJSONValueArrayGet((virJSONValuePtr)value, i);
|
elem = virJSONValueArrayGet((virJSONValuePtr)value, i);
|
||||||
|
|
||||||
/* recurse to avoid duplicating code */
|
/* recurse to avoid duplicating code */
|
||||||
if (virQEMUBuildCommandLineJSONRecurse(key, elem, buf, true) < 0)
|
if (virQEMUBuildCommandLineJSONRecurse(key, elem, buf,
|
||||||
|
arrayFunc, true) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -153,7 +176,6 @@ virQEMUBuildCommandLineJSONRecurse(const char *key,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
virBitmapFree(bitmap);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -162,6 +184,7 @@ virQEMUBuildCommandLineJSONRecurse(const char *key,
|
|||||||
* virQEMUBuildCommandLineJSON:
|
* virQEMUBuildCommandLineJSON:
|
||||||
* @value: json object containing the value
|
* @value: json object containing the value
|
||||||
* @buf: otuput buffer
|
* @buf: otuput buffer
|
||||||
|
* @arrayFunc: array formatter function to allow for different syntax
|
||||||
*
|
*
|
||||||
* Formats JSON value object into command line parameters suitable for use with
|
* Formats JSON value object into command line parameters suitable for use with
|
||||||
* qemu.
|
* qemu.
|
||||||
@ -170,9 +193,10 @@ virQEMUBuildCommandLineJSONRecurse(const char *key,
|
|||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
virQEMUBuildCommandLineJSON(const virJSONValue *value,
|
virQEMUBuildCommandLineJSON(const virJSONValue *value,
|
||||||
virBufferPtr buf)
|
virBufferPtr buf,
|
||||||
|
virQEMUBuildCommandLineJSONArrayFormatFunc array)
|
||||||
{
|
{
|
||||||
return virQEMUBuildCommandLineJSONRecurse(NULL, value, buf, false);
|
return virQEMUBuildCommandLineJSONRecurse(NULL, value, buf, array, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -186,7 +210,8 @@ virQEMUBuildObjectCommandlineFromJSON(const char *type,
|
|||||||
|
|
||||||
virBufferAsprintf(&buf, "%s,id=%s", type, alias);
|
virBufferAsprintf(&buf, "%s,id=%s", type, alias);
|
||||||
|
|
||||||
if (virQEMUBuildCommandLineJSON(props, &buf) < 0)
|
if (virQEMUBuildCommandLineJSON(props, &buf,
|
||||||
|
virQEMUBuildCommandLineJSONArrayBitmap) < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
if (virBufferCheckError(&buf) < 0)
|
if (virBufferCheckError(&buf) < 0)
|
||||||
|
@ -29,8 +29,16 @@
|
|||||||
# include "virjson.h"
|
# include "virjson.h"
|
||||||
# include "virstorageencryption.h"
|
# include "virstorageencryption.h"
|
||||||
|
|
||||||
int virQEMUBuildCommandLineJSON(const virJSONValue *value,
|
typedef int (*virQEMUBuildCommandLineJSONArrayFormatFunc)(const char *key,
|
||||||
|
const virJSONValue *array,
|
||||||
virBufferPtr buf);
|
virBufferPtr buf);
|
||||||
|
int virQEMUBuildCommandLineJSONArrayBitmap(const char *key,
|
||||||
|
const virJSONValue *array,
|
||||||
|
virBufferPtr buf);
|
||||||
|
|
||||||
|
int virQEMUBuildCommandLineJSON(const virJSONValue *value,
|
||||||
|
virBufferPtr buf,
|
||||||
|
virQEMUBuildCommandLineJSONArrayFormatFunc array);
|
||||||
|
|
||||||
char *virQEMUBuildObjectCommandlineFromJSON(const char *type,
|
char *virQEMUBuildObjectCommandlineFromJSON(const char *type,
|
||||||
const char *alias,
|
const char *alias,
|
||||||
|
@ -51,7 +51,8 @@ testQemuCommandBuildFromJSON(const void *opaque)
|
|||||||
virAsprintf(&expect, ",%s", data->expectprops) < 0)
|
virAsprintf(&expect, ",%s", data->expectprops) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (virQEMUBuildCommandLineJSON(val, &buf) < 0) {
|
if (virQEMUBuildCommandLineJSON(val, &buf,
|
||||||
|
virQEMUBuildCommandLineJSONArrayBitmap) < 0) {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"\nvirQEMUBuildCommandlineJSON failed process JSON:\n%s\n",
|
"\nvirQEMUBuildCommandlineJSON failed process JSON:\n%s\n",
|
||||||
data->props);
|
data->props);
|
||||||
|
Loading…
Reference in New Issue
Block a user