For now, only these three helpers are needed: virDomainChrFind - to find a duplicate chardev within VM def virDomainChrInsert - wrapper for inserting a new chardev into VM def virDomainChrRemove - wrapper for removing chardev from VM def There is, however, one internal helper as well: virDomainChrGetDomainPtrs which sets given pointers to one of vmdef->{parallels,serials,consoles,channels} based on passed chardev type. --- src/conf/domain_conf.c | 160 +++++++++++++++++++++++++++++++++++++++++++++++ src/conf/domain_conf.h | 11 ++++ src/libvirt_private.syms | 4 ++ 3 files changed, 175 insertions(+) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index a16ebd1..37f0ce9 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -10056,6 +10056,166 @@ virDomainLeaseRemove(virDomainDefPtr def, return virDomainLeaseRemoveAt(def, i); } +static bool +virDomainChrEquals(virDomainChrDefPtr src, + virDomainChrDefPtr tgt) +{ + if (!src || !tgt) + return src == tgt; + + if (!virDomainChrSourceDefIsEqual(&src->source, &tgt->source)) + return false; + + if (src->targetTypeAttr != tgt->targetTypeAttr) + return false; + + if (!src->targetTypeAttr) + return true; + + switch ((enum virDomainChrChannelTargetType) src->targetType) { + case VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_VIRTIO: + return STREQ_NULLABLE(src->target.name, tgt->target.name); + break; + case VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_GUESTFWD: + if (!src->target.addr || !tgt->target.addr) + return src->target.addr == tgt->target.addr; + return memcmp(src->target.addr, tgt->target.addr, + sizeof(*src->target.addr)) == 0; + break; + + case VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_NONE: + case VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_LAST: + default: + return true; + } +} + +virDomainChrDefPtr +virDomainChrFind(virDomainDefPtr def, + virDomainChrDefPtr target) +{ + size_t i; + + for (i = 0; i < def->nparallels; i++) { + virDomainChrDefPtr chr = def->parallels[i]; + + if (virDomainChrEquals(chr, target)) + return chr; + } + + for (i = 0; i < def->nserials; i++) { + virDomainChrDefPtr chr = def->serials[i]; + + if (virDomainChrEquals(chr, target)) + return chr; + } + + + for (i = 0; i < def->nconsoles; i++) { + virDomainChrDefPtr chr = def->consoles[i]; + + if (virDomainChrEquals(chr, target)) + return chr; + } + + for (i = 0; i < def->nchannels; i++) { + virDomainChrDefPtr chr = def->channels[i]; + + if (virDomainChrEquals(chr, target)) + return chr; + } + + return NULL; +} + +int +virDomainChrGetDomainPtrs(virDomainDefPtr vmdef, + virDomainChrDefPtr chr, + virDomainChrDefPtr ***arrPtr, + size_t **cntPtr) +{ + switch ((enum virDomainChrDeviceType) chr->deviceType) { + case VIR_DOMAIN_CHR_DEVICE_TYPE_PARALLEL: + *arrPtr = &vmdef->parallels; + *cntPtr = &vmdef->nparallels; + break; + + case VIR_DOMAIN_CHR_DEVICE_TYPE_SERIAL: + *arrPtr = &vmdef->serials; + *cntPtr = &vmdef->nserials; + break; + + case VIR_DOMAIN_CHR_DEVICE_TYPE_CONSOLE: + *arrPtr = &vmdef->consoles; + *cntPtr = &vmdef->nconsoles; + break; + + case VIR_DOMAIN_CHR_DEVICE_TYPE_CHANNEL: + *arrPtr = &vmdef->channels; + *cntPtr = &vmdef->nchannels; + break; + + default: + virReportError(VIR_ERR_OPERATION_INVALID, + _("Unsupported device type '%d'"), + chr->deviceType); + return -1; + } + return 0; +} + +int virDomainChrInsert(virDomainDefPtr vmdef, + virDomainChrDefPtr chr) +{ + virDomainChrDefPtr **arrPtr; + size_t *cntPtr; + + if (virDomainChrGetDomainPtrs(vmdef, chr, &arrPtr, &cntPtr) < 0) + return -1; + + if (VIR_REALLOC_N(*arrPtr, *cntPtr + 1) < 0) { + virReportOOMError(); + return -1; + } + + (*arrPtr)[*cntPtr] = chr; + (*cntPtr)++; + + return 0; +} + +int virDomainChrRemove(virDomainDefPtr vmdef, + virDomainChrDefPtr chr) +{ + virDomainChrDefPtr **arrPtr; + size_t i, *cntPtr; + + if (virDomainChrGetDomainPtrs(vmdef, chr, &arrPtr, &cntPtr) < 0) + return -1; + + for (i = 0; i < *cntPtr; i++) { + virDomainChrDefPtr tmp = (*arrPtr)[i]; + + if (virDomainChrEquals(tmp, chr)) + break; + } + + if (i == *cntPtr) + return -1; + + virDomainChrDefFree((*arrPtr)[i]); + if (*cntPtr > 1) { + memmove(*arrPtr + i, + *arrPtr + i + 1, + sizeof(**arrPtr) * (*cntPtr - (i + 1))); + ignore_value(VIR_REALLOC_N(*arrPtr, *cntPtr - 1)); + } else { + VIR_FREE(*arrPtr); + } + (*cntPtr)--; + + return 0; +} char * virDomainDefGetDefaultEmulator(virDomainDefPtr def, diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 3a71d6c..6d650ff 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -2355,6 +2355,17 @@ virDomainLeaseDefPtr virDomainLeaseRemove(virDomainDefPtr def, virDomainLeaseDefPtr lease); +int virDomainChrGetDomainPtrs(virDomainDefPtr vmdef, + virDomainChrDefPtr chr, + virDomainChrDefPtr ***arrPtr, + size_t **cntPtr); +virDomainChrDefPtr virDomainChrFind(virDomainDefPtr def, + virDomainChrDefPtr target); +int virDomainChrInsert(virDomainDefPtr vmdef, + virDomainChrDefPtr chr); +int virDomainChrRemove(virDomainDefPtr vmdef, + virDomainChrDefPtr chr); + int virDomainSaveXML(const char *configDir, virDomainDefPtr def, const char *xml); diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index b93629f..b9ba731 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -77,6 +77,10 @@ virDomainChrConsoleTargetTypeToString; virDomainChrDefForeach; virDomainChrDefFree; virDomainChrDefNew; +virDomainChrFind; +virDomainChrGetDomainPtrs; +virDomainChrInsert; +virDomainChrRemove; virDomainChrSerialTargetTypeFromString; virDomainChrSerialTargetTypeToString; virDomainChrSourceDefCopy; -- 1.8.2.1 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list