[libvirt] PATCH: 2/2: port Test driver to new domain APIs
Jim Meyering
jim at meyering.net
Fri Jul 4 21:03:40 UTC 2008
"Daniel P. Berrange" <berrange at redhat.com> wrote:
> This patch ports the Test driver over to the domain XML apis.
...
> docs/testdomfc4.xml | 2
> src/test.c | 1020 ++++++++++++++++++------------------------------
> tests/read-non-seekable | 3
> tests/testutils.c | 3
> tests/virshtest.c | 4
> 5 files changed, 391 insertions(+), 641 deletions(-)
...
Hi Dan,
Nice work. This will make testing a lot easier.
I've made a few suggestions, spotted some new bugs
and a couple in moved code.
> +static virCapsPtr
> +testBuildCapabilities(virConnectPtr conn) {
> + virCapsPtr caps;
> + virCapsGuestPtr guest;
> + const char *guest_types[] = { "hvm", "xen" };
you can sneak one more "const" in there:
const char *const guest_types[] = { "hvm", "xen" };
> + int i;
> + GET_CONNECTION(conn);
> +
> + if ((caps = virCapabilitiesNew(TEST_MODEL, 0, 0)) == NULL)
> + goto no_memory;
> +
> + if (virCapabilitiesAddHostFeature(caps, "pae") < 0)
> + goto no_memory;
> + if (virCapabilitiesAddHostFeature(caps ,"nonpae") < 0)
> + goto no_memory;
> +
> + for (i = 0; i < privconn->numCells; ++i) {
> + if (virCapabilitiesAddHostNUMACell(caps, i, privconn->cells[i].numCpus,
> + privconn->cells[i].cpus) < 0)
> + goto no_memory;
> + }
> +
> + for (i = 0; i < (sizeof(guest_types)/sizeof(guest_types[0])); ++i) {
With ARRAY_CARDINALITY it's more readable:
for (i = 0; i < ARRAY_CARDINALITY(guest_types); ++i) {
> + if ((guest = virCapabilitiesAddGuest(caps,
> + guest_types[i],
> + TEST_MODEL,
> + TEST_MODEL_WORDSIZE,
> + TEST_EMULATOR,
> + NULL,
> + 0,
> + NULL)) == NULL)
> + goto no_memory;
...
> @@ -538,11 +372,17 @@
> xmlNodePtr *domains, *networks = NULL;
> xmlXPathContextPtr ctxt = NULL;
> virNodeInfoPtr nodeInfo;
> + virDomainObjPtr dom;
> + virNetworkObjPtr net;
> testConnPtr privconn;
> if (VIR_ALLOC(privconn) < 0) {
> testError(NULL, NULL, NULL, VIR_ERR_NO_MEMORY, "testConn");
> return VIR_DRV_OPEN_ERROR;
> }
> + conn->privateData = privconn;
> +
> + if (!(privconn->caps = testBuildCapabilities(conn)))
> + goto error;
>
> if ((fd = open(file, O_RDONLY)) < 0) {
> testError(NULL, NULL, NULL, VIR_ERR_INTERNAL_ERROR, _("loading host definition file"));
> @@ -570,10 +410,7 @@
> goto error;
> }
>
> -
> - conn->privateData = privconn;
> privconn->nextDomID = 1;
> - privconn->numDomains = 0;
> privconn->numCells = 0;
> strncpy(privconn->path, file, PATH_MAX-1);
> privconn->path[PATH_MAX-1] = '\0';
> @@ -645,39 +482,35 @@
> goto error;
> }
>
> +
> ret = virXPathNodeSet("/node/domain", ctxt, &domains);
> - if (ret < 0) {
> - testError(NULL, NULL, NULL, VIR_ERR_XML_ERROR, _("node domain list"));
> - goto error;
> + if (ret > 0) {
> + for (i = 0 ; i < ret ; i++) {
> + xmlChar *netFile = xmlGetProp(domains[i], BAD_CAST "file");
This needs to handle xmlGetProp failure.
[the bug was present before this change: just indented]
> + char *absFile = testBuildFilename(file, (const char *)netFile);
> + VIR_FREE(netFile);
> + if (!absFile) {
> + testError(NULL, NULL, NULL, VIR_ERR_INTERNAL_ERROR, _("resolving domain filename"));
> + goto error;
...
> - for (i = 0 ; i < ret ; i++) {
> - xmlChar *domFile = xmlGetProp(domains[i], BAD_CAST "file");
> - char *absFile = testBuildFilename(file, (const char *)domFile);
> - int domid = privconn->nextDomID++, handle;
> - VIR_FREE(domFile);
> - if (!absFile) {
> - testError(NULL, NULL, NULL, VIR_ERR_INTERNAL_ERROR, _("resolving domain filename"));
> - goto error;
...
> static virDomainPtr
> -testDomainCreateLinux(virConnectPtr conn, const char *xmlDesc,
> +testDomainCreateLinux(virConnectPtr conn, const char *xml,
> unsigned int flags ATTRIBUTE_UNUSED)
> {
...
> - dom = virGetDomain(conn, privconn->domains[handle].name, privconn->domains[handle].uuid);
> - if (dom == NULL) return NULL;
> - privconn->numDomains++;
> - return (dom);
> + ret = virGetDomain(conn, def->name, def->uuid);
Handle virGetDomain failure.
> + ret->id = def->id;
> + return ret;
> }
>
> static virDomainPtr testLookupDomainByID(virConnectPtr conn,
> int id)
> {
...
> + ret = virGetDomain(conn, dom->def->name, dom->def->uuid);
Likewise. Handle virGetDomain failure.
> + ret->id = dom->def->id;
> + return ret;
> }
>
> static virDomainPtr testLookupDomainByUUID(virConnectPtr conn,
> const unsigned char *uuid)
> {
...
> + ret = virGetDomain(conn, dom->def->name, dom->def->uuid);
Likewise.
> + ret->id = dom->def->id;
> + return ret;
> }
>
> static virDomainPtr testLookupDomainByName(virConnectPtr conn,
> const char *name)
> {
...
> + ret = virGetDomain(conn, dom->def->name, dom->def->uuid);
Likewise.
> + ret->id = dom->def->id;
> + return ret;
> }
...
> @@ -1215,8 +970,10 @@
> {
> char *xml;
> char magic[15];
> - int fd, len, ret, domid;
> - GET_CONNECTION(conn, -1);
> + int fd, len;
> + virDomainDefPtr def;
> + virDomainObjPtr dom;
> + GET_CONNECTION(conn);
>
> if ((fd = open(path, O_RDONLY)) < 0) {
> testError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
> @@ -1260,10 +1017,19 @@
> }
> xml[len] = '\0';
> close(fd);
> - domid = privconn->nextDomID++;
> - ret = testLoadDomainFromDoc(conn, domid, xml);
> +
> + if ((def = virDomainDefParse(conn, privconn->caps, xml, NULL)) == NULL) {
> + VIR_FREE(xml);
> + return -1;
> + }
> VIR_FREE(xml);
You can save a VIR_FREE:
def = virDomainDefParse(conn, privconn->caps, xml, NULL);
VIR_FREE(xml);
if (def == NULL)
return -1;
...
> static int testListDefinedDomains(virConnectPtr conn,
> char **const names,
> int maxnames) {
> - int n = 0, i;
> - GET_CONNECTION(conn, -1);
> + int n = 0;
> + virDomainObjPtr dom;
> + GET_CONNECTION(conn);
>
> - for (i = 0, n = 0 ; i < MAX_DOMAINS && n < maxnames ; i++) {
> - if (privconn->domains[i].active &&
> - privconn->domains[i].info.state == VIR_DOMAIN_SHUTOFF) {
> - names[n++] = strdup(privconn->domains[i].name);
> - }
> + dom = privconn->domains;
> + while (dom && n < maxnames) {
> + if (virDomainIsActive(dom))
> + names[n++] = strdup(dom->def->name);
This could be the same problem I pointed out in testListDefinedNetworks:
when strdup fails, some caller may dereference the NULL pointer
we record here. Either skip any NULL pointers as I suggested
before, or return -1 to indicate the error (and update all callers).
> + dom = dom->next;
> }
> - return (n);
> + return n;
> }
>
> static virDomainPtr testDomainDefineXML(virConnectPtr conn,
...
> - if (handle < 0)
> - return (NULL);
> -
> - return virGetDomain(conn, privconn->domains[handle].name, privconn->domains[handle].uuid);
> + ret = virGetDomain(conn, def->name, def->uuid);
Possible NULL deref.
> + ret->id = -1;
> + return ret;
> }
...
More information about the libvir-list
mailing list