Modulo some minor problems, ACK.
Even though I reviewed only the incremental diffs, there was a bit of
new material. BTW, nice catch, with the new uses of virBufferEscapeString.
+virNetworkDefPtr virNetworkDefParseNode(virConnectPtr conn,
+ xmlDocPtr xml,
+ xmlNodePtr root)
+{
+ xmlXPathContextPtr ctxt = NULL;
+ virNetworkDefPtr def = NULL;
+
+ if (!xmlStrEqual(root->name, BAD_CAST "network")) {
+ virNetworkReportError(conn, VIR_ERR_INTERNAL_ERROR,
+ "%s", _("incorrect root element"));
+ goto cleanup;
+ }
No big deal, but the above goto could be "return NULL;".
+ ctxt = xmlXPathNewContext(xml);
+ if (ctxt == NULL) {
+ virNetworkReportError(conn, VIR_ERR_NO_MEMORY, NULL);
+ goto cleanup;
+ }
+
+ ctxt->node = root;
+ def = virNetworkDefParseXML(conn, ctxt);
+
+cleanup:
+ xmlXPathFreeContext(ctxt);
+ return def;
+}
...
+int virNetworkSaveConfig(virConnectPtr conn,
+ const char *configDir,
+ const char *autostartDir,
+ virNetworkObjPtr net)
+{
+ char *xml;
+ int fd = -1, ret = -1;
+ int towrite;
Use size_t, not int.
+ int err;
+
+ if (!net->configFile &&
+ asprintf(&net->configFile, "%s/%s.xml",
+ configDir, net->def->name) < 0) {
Upon failure, set net->autostartFile to NULL.
Otherwise, when the caller frees "net", it will free a potentially
undefined pointer.
+ virNetworkReportError(conn, VIR_ERR_NO_MEMORY, NULL);
+ goto cleanup;
+ }
+ if (!net->autostartLink &&
+ asprintf(&net->autostartLink, "%s/%s.xml",
+ autostartDir, net->def->name) < 0) {
Likewise for net->autostartLink.
+ virNetworkReportError(conn, VIR_ERR_NO_MEMORY, NULL);
+ goto cleanup;
+ }
+
+ if (!(xml = virNetworkDefFormat(conn,
+ net->newDef ? net->newDef : net->def)))
+ return -1;
No real problem, but each of the above two goto statements could be
"return -1;", or maybe just change this return -1 to "goto cleanup;".
Otherwise, the inconsistency looks suspicious.
+ if ((err = virFileMakePath(configDir))) {
+ virNetworkReportError(conn, VIR_ERR_INTERNAL_ERROR,
+ _("cannot create config directory %s: %s"),
+ configDir, strerror(err));
+ goto cleanup;
+ }
+
+ if ((err = virFileMakePath(autostartDir))) {
+ virNetworkReportError(conn, VIR_ERR_INTERNAL_ERROR,
+ _("cannot create autostart directory %s: %s"),
+ autostartDir, strerror(err));
+ goto cleanup;
+ }
+
+ if ((fd = open(net->configFile,
+ O_WRONLY | O_CREAT | O_TRUNC,
+ S_IRUSR | S_IWUSR )) < 0) {
+ virNetworkReportError(conn, VIR_ERR_INTERNAL_ERROR,
+ _("cannot create config file %s: %s"),
+ net->configFile, strerror(errno));
+ goto cleanup;
+ }
+
+ towrite = strlen(xml);
+ if (safewrite(fd, xml, towrite) < 0) {
+ virNetworkReportError(conn, VIR_ERR_INTERNAL_ERROR,
+ _("cannot write config file %s: %s"),
+ net->configFile, strerror(errno));
+ goto cleanup;
+ }
+
+ if (close(fd) < 0) {
+ virNetworkReportError(conn, VIR_ERR_INTERNAL_ERROR,
+ _("cannot save config file %s: %s"),
+ net->configFile, strerror(errno));
+ goto cleanup;
+ }
+
+ ret = 0;
+
+ cleanup:
+ VIR_FREE(xml);
+ close(fd);
It's better not to close(-1), so as not to
raise flags via tools like valgrind or strace:
if (fd >= 0)
close(fd);
+ return ret;
+}
+
+virNetworkObjPtr virNetworkLoadConfig(virConnectPtr conn,
+ virNetworkObjPtr *nets,
+ const char *configDir,
+ const char *autostartDir,
+ const char *file)
+{
+ char *configFile, *autostartLink;
+ virNetworkDefPtr def = NULL;
+ virNetworkObjPtr net;
+ int autostart;
+
+ if (asprintf(&configFile, "%s/%s",
+ configDir, file) < 0) {
Upon failed asprintf, here, you need to set configFile = NULL.
Otherwise, the VIR_FREE(configFile) below will free a potentially
undefined pointer.
+ virNetworkReportError(conn, VIR_ERR_NO_MEMORY, NULL);
+ goto error;
+ }
+ if (asprintf(&autostartLink, "%s/%s",
+ autostartDir, file) < 0) {
Same for autostartLink.
+ virNetworkReportError(conn, VIR_ERR_NO_MEMORY, NULL);
+ goto error;
+ }
...
+error:
+ VIR_FREE(configFile);
+ VIR_FREE(autostartLink);
+ virNetworkDefFree(def);
+ return NULL;
+}
...
+int virNetworkDeleteConfig(virConnectPtr conn,
+ virNetworkObjPtr net)
+{
+ if (!net->configFile || !net->autostartLink) {
+ virNetworkReportError(conn, VIR_ERR_INTERNAL_ERROR,
+ _("no config file for %s"),
net->def->name);
+ return -1;
+ }
+
+ /* Not fatal if this doesn't work */
+ unlink(net->autostartLink);
+
+ if (unlink(net->configFile) < 0) {
+ virNetworkReportError(conn, VIR_ERR_INTERNAL_ERROR,
+ _("cannot remove config for %s"),
net->def->name);
Please include strerror(errno), so people know why it fails.
+ return -1;
+ }
+
+ return 0;
+}
diff -r 097ed9d9ae46 src/network_conf.h
...
+typedef struct _virNetworkDef virNetworkDef;
+typedef virNetworkDef *virNetworkDefPtr;
+struct _virNetworkDef {
+ unsigned char uuid[VIR_UUID_BUFLEN];
+ char *name;
+
+ char *bridge; /* Name of bridge device */
+ int stp : 1; /* Spanning tree protocol */
+ unsigned long delay; /* Bridge forward delay (ms) */
Not that it matters, but...
Swapping the two preceding lines should decrease the size of this
struct by 8 bytes on a system with 8-byte pointers and longs.
+
+ int forwardType; /* One of virNetworkForwardType constants */
+ char *forwardDev; /* Destination device for forwarding */
+
+ char *ipAddress; /* Bridge IP address */
+ char *netmask;
+ char *network;
+
+ unsigned int nranges; /* Zero or more dhcp ranges */
+ virNetworkDHCPRangeDefPtr ranges;
+};