/** * virConfParseStatement: * @ctxt: the parsing context * * Parse one statement in the conf file * * Returns 0 in case of success and -1 in case of error */ static int virConfParseStatement(virConfParserCtxtPtr ctxt) { const char *base; char *name; virConfValuePtr value; char *comm = NULL; SKIP_BLANKS_AND_EOL; if (CUR == '#') { return virConfParseComment(ctxt); } name = virConfParseName(ctxt); if (name == NULL) return -1; SKIP_BLANKS; if (CUR != '=') { virConfError(ctxt, VIR_ERR_CONF_SYNTAX, _("expecting an assignment")); VIR_FREE(name); return -1; } NEXT; SKIP_BLANKS; value = virConfParseValue(ctxt); if (value == NULL) { VIR_FREE(name); return -1; } SKIP_BLANKS; if (CUR == '#') { NEXT; base = ctxt->cur; while ((ctxt->cur < ctxt->end) && (!IS_EOL(CUR))) NEXT; comm = strndup(base, ctxt->cur - base); if (comm == NULL) { virReportOOMError(); VIR_FREE(name); virConfFreeValue(value); return -1; } } if (virConfAddEntry(ctxt->conf, name, value, comm) == NULL) { VIR_FREE(name); virConfFreeValue(value); VIR_FREE(comm); return -1; } return 0; }
static int xenFormatXLDomainDisks(virConfPtr conf, virDomainDefPtr def) { int ret = -1; virConfValuePtr diskVal; size_t i; if (VIR_ALLOC(diskVal) < 0) return -1; diskVal->type = VIR_CONF_LIST; diskVal->list = NULL; for (i = 0; i < def->ndisks; i++) { if (def->disks[i]->device == VIR_DOMAIN_DISK_DEVICE_FLOPPY) continue; if (xenFormatXLDisk(diskVal, def->disks[i]) < 0) goto cleanup; } if (diskVal->list != NULL) if (virConfSetValue(conf, "disk", diskVal) == 0) diskVal = NULL; ret = 0; cleanup: virConfFreeValue(diskVal); return ret; }
/** * virConfSetValue: * @conf: a configuration file handle * @entry: the name of the entry * @value: the new configuration value * * Set (or replace) the value associated to this entry in the configuration * file. The passed in 'value' will be owned by the conf object upon return * of this method, even in case of error. It should not be referenced again * by the caller. * * Returns 0 on success, or -1 on failure. */ int virConfSetValue (virConfPtr conf, const char *setting, virConfValuePtr value) { virConfEntryPtr cur, prev = NULL; if (value && value->type == VIR_CONF_STRING && value->str == NULL) return -1; cur = conf->entries; while (cur != NULL) { if ((cur->name != NULL) && (STREQ(cur->name, setting))) { break; } prev = cur; cur = cur->next; } if (!cur) { if (VIR_ALLOC(cur) < 0) { virReportOOMError(); virConfFreeValue(value); return -1; } cur->comment = NULL; if (!(cur->name = strdup(setting))) { virReportOOMError(); virConfFreeValue(value); VIR_FREE(cur); return -1; } cur->value = value; if (prev) { cur->next = prev->next; prev->next = cur; } else { cur->next = conf->entries; conf->entries = cur; } } else { virConfFreeValue(cur->value); cur->value = value; } return 0; }
/** * virConfSetValue: * @conf: a configuration file handle * @setting: the name of the entry * @value: the new configuration value * * Set (or replace) the value associated to this entry in the configuration * file. The passed in 'value' will be owned by the conf object upon return * of this method, even in case of error. It should not be referenced again * by the caller. * * Returns 0 on success, or -1 on failure. */ int virConfSetValue(virConfPtr conf, const char *setting, virConfValuePtr value) { virConfEntryPtr cur, prev = NULL; if (value && value->type == VIR_CONF_STRING && value->str == NULL) { virConfFreeValue(value); return -1; } cur = conf->entries; while (cur != NULL) { if (STREQ_NULLABLE(cur->name, setting)) break; prev = cur; cur = cur->next; } if (!cur) { if (VIR_ALLOC(cur) < 0) { virConfFreeValue(value); return -1; } cur->comment = NULL; if (VIR_STRDUP(cur->name, setting) < 0) { virConfFreeValue(value); VIR_FREE(cur); return -1; } cur->value = value; if (prev) { cur->next = prev->next; prev->next = cur; } else { cur->next = conf->entries; conf->entries = cur; } } else { virConfFreeValue(cur->value); cur->value = value; } return 0; }
/** * virConfFreeList: * @list: the list to free * * Free a list */ static void virConfFreeList(virConfValuePtr list) { virConfValuePtr next; while (list != NULL) { next = list->next; list->next = NULL; virConfFreeValue(list); list = next; } }
/** * virConfFree: * @conf: a configuration file handle * * Frees all data associated to the handle * * Returns 0 in case of success, -1 in case of error. */ int virConfFree(virConfPtr conf) { virConfEntryPtr tmp; if (conf == NULL) return 0; tmp = conf->entries; while (tmp) { virConfEntryPtr next; VIR_FREE(tmp->name); virConfFreeValue(tmp->value); VIR_FREE(tmp->comment); next = tmp->next; VIR_FREE(tmp); tmp = next; } VIR_FREE(conf); return 0; }
static int xenFormatXLUSB(virConfPtr conf, virDomainDefPtr def) { virConfValuePtr usbVal = NULL; int hasUSB = 0; size_t i; for (i = 0; i < def->nhostdevs; i++) { if (def->hostdevs[i]->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS && def->hostdevs[i]->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB) { hasUSB = 1; break; } } if (!hasUSB) return 0; if (VIR_ALLOC(usbVal) < 0) return -1; usbVal->type = VIR_CONF_LIST; usbVal->list = NULL; for (i = 0; i < def->nhostdevs; i++) { if (def->hostdevs[i]->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS && def->hostdevs[i]->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB) { virConfValuePtr val, tmp; char *buf; if (virAsprintf(&buf, "hostbus=%x,hostaddr=%x", def->hostdevs[i]->source.subsys.u.usb.bus, def->hostdevs[i]->source.subsys.u.usb.device) < 0) goto error; if (VIR_ALLOC(val) < 0) { VIR_FREE(buf); goto error; } val->type = VIR_CONF_STRING; val->str = buf; tmp = usbVal->list; while (tmp && tmp->next) tmp = tmp->next; if (tmp) tmp->next = val; else usbVal->list = val; } } if (usbVal->list != NULL) { int ret = virConfSetValue(conf, "usbdev", usbVal); usbVal = NULL; if (ret < 0) return -1; } VIR_FREE(usbVal); return 0; error: virConfFreeValue(usbVal); return -1; }
static int xenFormatXLInputDevs(virConfPtr conf, virDomainDefPtr def) { size_t i; const char *devtype; virConfValuePtr usbdevices = NULL, lastdev; if (def->os.type == VIR_DOMAIN_OSTYPE_HVM) { if (VIR_ALLOC(usbdevices) < 0) goto error; usbdevices->type = VIR_CONF_LIST; usbdevices->list = NULL; lastdev = NULL; for (i = 0; i < def->ninputs; i++) { if (def->inputs[i]->bus == VIR_DOMAIN_INPUT_BUS_USB) { if (xenConfigSetInt(conf, "usb", 1) < 0) goto error; switch (def->inputs[i]->type) { case VIR_DOMAIN_INPUT_TYPE_MOUSE: devtype = "mouse"; break; case VIR_DOMAIN_INPUT_TYPE_TABLET: devtype = "tablet"; break; case VIR_DOMAIN_INPUT_TYPE_KBD: devtype = "keyboard"; break; default: continue; } if (lastdev == NULL) { if (VIR_ALLOC(lastdev) < 0) goto error; usbdevices->list = lastdev; } else { if (VIR_ALLOC(lastdev->next) < 0) goto error; lastdev = lastdev->next; } lastdev->type = VIR_CONF_STRING; if (VIR_STRDUP(lastdev->str, devtype) < 0) goto error; } } if (usbdevices->list != NULL) { if (usbdevices->list->next == NULL) { /* for compatibility with Xen <= 4.2, use old syntax when * only one device present */ if (xenConfigSetString(conf, "usbdevice", usbdevices->list->str) < 0) goto error; virConfFreeValue(usbdevices); } else { virConfSetValue(conf, "usbdevice", usbdevices); } } else { VIR_FREE(usbdevices); } } return 0; error: virConfFreeValue(usbdevices); return -1; }