int virQEMUBuildCommandLineJSONArrayNumbered(const char *key, virJSONValuePtr array, virBufferPtr buf) { virJSONValuePtr member; char *prefix = NULL; size_t i; int ret = 0; for (i = 0; i < virJSONValueArraySize(array); i++) { member = virJSONValueArrayGet((virJSONValuePtr) array, i); if (virAsprintf(&prefix, "%s.%zu", key, i) < 0) goto cleanup; if (virQEMUBuildCommandLineJSONRecurse(prefix, member, buf, virQEMUBuildCommandLineJSONArrayNumbered, true) < 0) goto cleanup; VIR_FREE(prefix); } ret = 0; cleanup: VIR_FREE(prefix); return ret; }
virLogHandlerPtr virLogHandlerNewPostExecRestart(virJSONValuePtr object, bool privileged, virLogHandlerShutdownInhibitor inhibitor, void *opaque) { virLogHandlerPtr handler; virJSONValuePtr files; ssize_t n; size_t i; if (!(handler = virLogHandlerNew(privileged, inhibitor, opaque))) return NULL; if (!(files = virJSONValueObjectGet(object, "files"))) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Missing files data from JSON file")); goto error; } if ((n = virJSONValueArraySize(files)) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Malformed files data from JSON file")); goto error; } for (i = 0; i < n; i++) { virLogHandlerLogFilePtr file; virJSONValuePtr child = virJSONValueArrayGet(files, i); if (!(file = virLogHandlerLogFilePostExecRestart(handler, child))) goto error; if (VIR_APPEND_ELEMENT_COPY(handler->files, handler->nfiles, file) < 0) goto error; if ((file->watch = virEventAddHandle(file->pipefd, VIR_EVENT_HANDLE_READABLE, virLogHandlerDomainLogFileEvent, handler, NULL)) < 0) { VIR_DELETE_ELEMENT(handler->files, handler->nfiles - 1, handler->nfiles); goto error; } } return handler; error: virObjectUnref(handler); return NULL; }
virNetServerPtr virNetDaemonAddServerPostExec(virNetDaemonPtr dmn, virNetServerClientPrivNew clientPrivNew, virNetServerClientPrivNewPostExecRestart clientPrivNewPostExecRestart, virNetServerClientPrivPreExecRestart clientPrivPreExecRestart, virFreeCallback clientPrivFree, void *clientPrivOpaque) { virJSONValuePtr object = NULL; virNetServerPtr srv = NULL; virObjectLock(dmn); if (!dmn->srvObject) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Cannot add more servers post-exec than " "there were pre-exec")); goto error; } if (virJSONValueIsArray(dmn->srvObject)) { object = virJSONValueArraySteal(dmn->srvObject, 0); if (virJSONValueArraySize(dmn->srvObject) == 0) { virJSONValueFree(dmn->srvObject); dmn->srvObject = NULL; } } else { object = dmn->srvObject; dmn->srvObject = NULL; } srv = virNetServerNewPostExecRestart(object, clientPrivNew, clientPrivNewPostExecRestart, clientPrivPreExecRestart, clientPrivFree, clientPrivOpaque); if (!srv || VIR_APPEND_ELEMENT_COPY(dmn->servers, dmn->nservers, srv) < 0) goto error; virJSONValueFree(object); virObjectUnlock(dmn); return srv; error: virObjectUnlock(dmn); virObjectUnref(srv); virJSONValueFree(object); return NULL; }
static virJSONValuePtr testQEMUSchemaStealObjectMemberByName(const char *name, virJSONValuePtr members) { virJSONValuePtr member; virJSONValuePtr ret = NULL; size_t i; for (i = 0; i < virJSONValueArraySize(members); i++) { member = virJSONValueArrayGet(members, i); if (STREQ_NULLABLE(name, virJSONValueObjectGetString(member, "name"))) { ret = virJSONValueArraySteal(members, i); break; } } return ret; }
static int parallelsLoadNetworks(parallelsConnPtr privconn) { virJSONValuePtr jobj, jobj2; virNetworkObjPtr net; int ret = -1; int count, i; jobj = parallelsParseOutput("prlsrvctl", "net", "list", "-j", NULL); if (!jobj) { parallelsParseError(); goto cleanup; } count = virJSONValueArraySize(jobj); if (count < 0) { parallelsParseError(); goto cleanup; } for (i = 0; i < count; i++) { jobj2 = virJSONValueArrayGet(jobj, i); if (!jobj2) { parallelsParseError(); goto cleanup; } net = parallelsLoadNetwork(privconn, jobj2); if (!net) goto cleanup; } if (!parallelsAddRoutedNetwork(privconn)) goto cleanup; ret = 0; cleanup: virJSONValueFree(jobj); return ret; }
virNetServerPtr virNetServerNewPostExecRestart(virJSONValuePtr object, virNetServerClientPrivNew clientPrivNew, virNetServerClientPrivNewPostExecRestart clientPrivNewPostExecRestart, virNetServerClientPrivPreExecRestart clientPrivPreExecRestart, virFreeCallback clientPrivFree, void *clientPrivOpaque) { virNetServerPtr srv = NULL; virJSONValuePtr clients; virJSONValuePtr services; size_t i; int n; unsigned int min_workers; unsigned int max_workers; unsigned int priority_workers; unsigned int max_clients; unsigned int max_anonymous_clients; unsigned int keepaliveInterval; unsigned int keepaliveCount; bool keepaliveRequired; const char *mdnsGroupName = NULL; if (virJSONValueObjectGetNumberUint(object, "min_workers", &min_workers) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Missing min_workers data in JSON document")); goto error; } if (virJSONValueObjectGetNumberUint(object, "max_workers", &max_workers) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Missing max_workers data in JSON document")); goto error; } if (virJSONValueObjectGetNumberUint(object, "priority_workers", &priority_workers) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Missing priority_workers data in JSON document")); goto error; } if (virJSONValueObjectGetNumberUint(object, "max_clients", &max_clients) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Missing max_clients data in JSON document")); goto error; } if (virJSONValueObjectHasKey(object, "max_anonymous_clients")) { if (virJSONValueObjectGetNumberUint(object, "max_anonymous_clients", &max_anonymous_clients) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Malformed max_anonymous_clients data in JSON document")); goto error; } } else { max_anonymous_clients = max_clients; } if (virJSONValueObjectGetNumberUint(object, "keepaliveInterval", &keepaliveInterval) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Missing keepaliveInterval data in JSON document")); goto error; } if (virJSONValueObjectGetNumberUint(object, "keepaliveCount", &keepaliveCount) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Missing keepaliveCount data in JSON document")); goto error; } if (virJSONValueObjectGetBoolean(object, "keepaliveRequired", &keepaliveRequired) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Missing keepaliveRequired data in JSON document")); goto error; } if (virJSONValueObjectHasKey(object, "mdnsGroupName") && (!(mdnsGroupName = virJSONValueObjectGetString(object, "mdnsGroupName")))) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Malformed mdnsGroupName data in JSON document")); goto error; } if (!(srv = virNetServerNew(min_workers, max_clients, priority_workers, max_clients, max_anonymous_clients, keepaliveInterval, keepaliveCount, keepaliveRequired, mdnsGroupName, clientPrivNew, clientPrivPreExecRestart, clientPrivFree, clientPrivOpaque))) goto error; if (!(services = virJSONValueObjectGet(object, "services"))) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Missing services data in JSON document")); goto error; } n = virJSONValueArraySize(services); if (n < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Malformed services data in JSON document")); goto error; } for (i = 0; i < n; i++) { virNetServerServicePtr service; virJSONValuePtr child = virJSONValueArrayGet(services, i); if (!child) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Missing service data in JSON document")); goto error; } if (!(service = virNetServerServiceNewPostExecRestart(child))) goto error; /* XXX mdns entry names ? */ if (virNetServerAddService(srv, service, NULL) < 0) { virObjectUnref(service); goto error; } } if (!(clients = virJSONValueObjectGet(object, "clients"))) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Missing clients data in JSON document")); goto error; } n = virJSONValueArraySize(clients); if (n < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Malformed clients data in JSON document")); goto error; } for (i = 0; i < n; i++) { virNetServerClientPtr client; virJSONValuePtr child = virJSONValueArrayGet(clients, i); if (!child) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Missing client data in JSON document")); goto error; } if (!(client = virNetServerClientNewPostExecRestart(child, clientPrivNewPostExecRestart, clientPrivPreExecRestart, clientPrivFree, clientPrivOpaque))) goto error; if (virNetServerAddClient(srv, client) < 0) { virObjectUnref(client); goto error; } virObjectUnref(client); } return srv; error: virObjectUnref(srv); return NULL; }
static int virQEMUBuildCommandLineJSONRecurse(const char *key, virJSONValuePtr value, virBufferPtr buf, virQEMUBuildCommandLineJSONArrayFormatFunc arrayFunc, bool nested) { struct virQEMUCommandLineJSONIteratorData data = { key, buf, arrayFunc }; virJSONValuePtr elem; size_t i; if (!key && value->type != VIR_JSON_TYPE_OBJECT) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("only JSON objects can be top level")); return -1; } switch ((virJSONType) value->type) { case VIR_JSON_TYPE_STRING: virBufferAsprintf(buf, "%s=", key); virQEMUBuildBufferEscapeComma(buf, value->data.string); virBufferAddLit(buf, ","); break; case VIR_JSON_TYPE_NUMBER: virBufferAsprintf(buf, "%s=%s,", key, value->data.number); break; case VIR_JSON_TYPE_BOOLEAN: if (value->data.boolean) virBufferAsprintf(buf, "%s=yes,", key); else virBufferAsprintf(buf, "%s=no,", key); break; case VIR_JSON_TYPE_ARRAY: if (nested) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("nested JSON array to commandline conversion is " "not supported")); return -1; } if (!arrayFunc || arrayFunc(key, value, buf) < 0) { /* fallback, treat the array as a non-bitmap, adding the key * for each member */ for (i = 0; i < virJSONValueArraySize(value); i++) { elem = virJSONValueArrayGet((virJSONValuePtr)value, i); /* recurse to avoid duplicating code */ if (virQEMUBuildCommandLineJSONRecurse(key, elem, buf, arrayFunc, true) < 0) return -1; } } break; case VIR_JSON_TYPE_OBJECT: if (virJSONValueObjectForeachKeyValue(value, virQEMUBuildCommandLineJSONIterate, &data) < 0) return -1; break; case VIR_JSON_TYPE_NULL: virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("NULL JSON type can't be converted to commandline")); return -1; } return 0; }
int qemuAgentGetVCPUs(qemuAgentPtr mon, qemuAgentCPUInfoPtr *info) { int ret = -1; int i; virJSONValuePtr cmd; virJSONValuePtr reply = NULL; virJSONValuePtr data = NULL; int ndata; if (!(cmd = qemuAgentMakeCommand("guest-get-vcpus", NULL))) return -1; if (qemuAgentCommand(mon, cmd, &reply, VIR_DOMAIN_QEMU_AGENT_COMMAND_BLOCK) < 0 || qemuAgentCheckError(cmd, reply) < 0) goto cleanup; if (!(data = virJSONValueObjectGet(reply, "return"))) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("guest-get-vcpus reply was missing return data")); goto cleanup; } if (data->type != VIR_JSON_TYPE_ARRAY) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("guest-get-vcpus return information was not an array")); goto cleanup; } ndata = virJSONValueArraySize(data); if (VIR_ALLOC_N(*info, ndata) < 0) { virReportOOMError(); goto cleanup; } for (i = 0; i < ndata; i++) { virJSONValuePtr entry = virJSONValueArrayGet(data, i); qemuAgentCPUInfoPtr in = *info + i; if (!entry) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("array element missing in guest-get-vcpus return " "value")); goto cleanup; } if (virJSONValueObjectGetNumberUint(entry, "logical-id", &in->id) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("'logical-id' missing in reply of guest-get-vcpus")); goto cleanup; } if (virJSONValueObjectGetBoolean(entry, "online", &in->online) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("'online' missing in reply of guest-get-vcpus")); goto cleanup; } if (virJSONValueObjectGetBoolean(entry, "can-offline", &in->offlinable) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("'can-offline' missing in reply of guest-get-vcpus")); goto cleanup; } } ret = ndata; cleanup: virJSONValueFree(cmd); virJSONValueFree(reply); return ret; }
static int virQEMUBuildObjectCommandLinePropsInternal(const char *key, const virJSONValue *value, virBufferPtr buf, bool nested) { virJSONValuePtr elem; virBitmapPtr bitmap = NULL; ssize_t pos = -1; ssize_t end; size_t i; switch ((virJSONType) value->type) { case VIR_JSON_TYPE_STRING: virBufferAsprintf(buf, ",%s=%s", key, value->data.string); break; case VIR_JSON_TYPE_NUMBER: virBufferAsprintf(buf, ",%s=%s", key, value->data.number); break; case VIR_JSON_TYPE_BOOLEAN: if (value->data.boolean) virBufferAsprintf(buf, ",%s=yes", key); else virBufferAsprintf(buf, ",%s=no", key); break; case VIR_JSON_TYPE_ARRAY: if (nested) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("nested -object property arrays are not supported")); return -1; } if (virJSONValueGetArrayAsBitmap(value, &bitmap) == 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 * for each member */ for (i = 0; i < virJSONValueArraySize(value); i++) { elem = virJSONValueArrayGet((virJSONValuePtr)value, i); /* recurse to avoid duplicating code */ if (virQEMUBuildObjectCommandLinePropsInternal(key, elem, buf, true) < 0) return -1; } } break; case VIR_JSON_TYPE_OBJECT: case VIR_JSON_TYPE_NULL: virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("NULL and OBJECT JSON types can't be converted to " "commandline string")); return -1; } virBitmapFree(bitmap); return 0; }
/** * testQEMUSchemaValidateObjectMergeVariant: * * Merges schema of variant @variantname in @root into @root and removes the * 'variants' array from @root. */ static int testQEMUSchemaValidateObjectMergeVariant(virJSONValuePtr root, const char *variantfield, const char *variantname, virHashTablePtr schema, virBufferPtr debug) { size_t i; virJSONValuePtr variants = NULL; virJSONValuePtr variant; virJSONValuePtr variantschema; virJSONValuePtr variantschemamembers; virJSONValuePtr rootmembers; const char *varianttype = NULL; int ret = -1; if (!(variants = virJSONValueObjectStealArray(root, "variants"))) { virBufferAddLit(debug, "ERROR: missing 'variants' in schema\n"); return -2; } for (i = 0; i < virJSONValueArraySize(variants); i++) { variant = virJSONValueArrayGet(variants, i); if (STREQ_NULLABLE(variantname, virJSONValueObjectGetString(variant, "case"))) { varianttype = virJSONValueObjectGetString(variant, "type"); break; } } if (!varianttype) { virBufferAsprintf(debug, "ERROR: variant '%s' for discriminator '%s' not found\n", variantname, variantfield); goto cleanup; } if (!(variantschema = virHashLookup(schema, varianttype)) || !(variantschemamembers = virJSONValueObjectGetArray(variantschema, "members"))) { virBufferAsprintf(debug, "ERROR: missing schema or schema members for variant '%s'(%s)\n", variantname, varianttype); ret = -2; goto cleanup; } rootmembers = virJSONValueObjectGetArray(root, "members"); if (virJSONValueArrayForeachSteal(variantschemamembers, testQEMUSchemaValidateObjectMergeVariantMember, rootmembers) < 0) { ret = -2; goto cleanup; } ret = 0; cleanup: virJSONValueFree(variants); return ret; }