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 | 135 +++++++++++++++++++++++++++++++++++++++++++++++ src/conf/domain_conf.h | 15 ++++++ src/libvirt_private.syms | 4 ++ 3 files changed, 154 insertions(+) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 21ffc8f..f82ee62 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -10084,6 +10084,141 @@ virDomainLeaseRemove(virDomainDefPtr def, return virDomainLeaseRemoveAt(def, i); } +static bool +virDomainChrEquals(virDomainChrDefPtr src, + virDomainChrDefPtr tgt) +{ + if (!src || !tgt) + return src == tgt; + + if (src->deviceType != tgt->deviceType || + !virDomainChrSourceDefIsEqual(&src->source, &tgt->source)) + return false; + + switch ((enum virDomainChrDeviceType) src->deviceType) { + case VIR_DOMAIN_CHR_DEVICE_TYPE_CHANNEL: + if (src->targetType != tgt->targetType) + return false; + 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: + /* shouldn't happen */ + break; + } + break; + + case VIR_DOMAIN_CHR_DEVICE_TYPE_SERIAL: + if (src->targetTypeAttr != tgt->targetTypeAttr) + return false; + case VIR_DOMAIN_CHR_DEVICE_TYPE_CONSOLE: + case VIR_DOMAIN_CHR_DEVICE_TYPE_PARALLEL: + return src->target.port == tgt->target.port; + break; + case VIR_DOMAIN_CHR_DEVICE_TYPE_LAST: + /* shouldn't happen */ + break; + } + return false; +} + +virDomainChrDefPtr +virDomainChrFind(virDomainDefPtr def, + virDomainChrDefPtr target) +{ + virDomainChrDefPtr chr, **arrPtr; + size_t i, *cntPtr; + + virDomainChrGetDomainPtrs(def, target, &arrPtr, &cntPtr); + + for (i = 0; i < *cntPtr; i++) { + chr = (*arrPtr)[i]; + if (virDomainChrEquals(chr, target)) + return chr; + } + return NULL; +} + +void +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; + + case VIR_DOMAIN_CHR_DEVICE_TYPE_LAST: + break; + } +} + +int +virDomainChrInsert(virDomainDefPtr vmdef, + virDomainChrDefPtr chr) +{ + virDomainChrDefPtr **arrPtr; + size_t *cntPtr; + + virDomainChrGetDomainPtrs(vmdef, chr, &arrPtr, &cntPtr); + + if (VIR_APPEND_ELEMENT(*arrPtr, *cntPtr, chr) < 0) { + virReportOOMError(); + return -1; + } + + return 0; +} + +virDomainChrDefPtr +virDomainChrRemove(virDomainDefPtr vmdef, + virDomainChrDefPtr chr) +{ + virDomainChrDefPtr ret, **arrPtr; + size_t i, *cntPtr; + + virDomainChrGetDomainPtrs(vmdef, chr, &arrPtr, &cntPtr); + + for (i = 0; i < *cntPtr; i++) { + ret = (*arrPtr)[i]; + + if (virDomainChrEquals(ret, chr)) + break; + } + + if (i == *cntPtr) + return NULL; + + VIR_DELETE_ELEMENT(*arrPtr, i, *cntPtr); + return ret; +} char * virDomainDefGetDefaultEmulator(virDomainDefPtr def, diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 2b55de5..b0d7a6a 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -2386,6 +2386,21 @@ virDomainLeaseDefPtr virDomainLeaseRemove(virDomainDefPtr def, virDomainLeaseDefPtr lease); +void +virDomainChrGetDomainPtrs(virDomainDefPtr vmdef, + virDomainChrDefPtr chr, + virDomainChrDefPtr ***arrPtr, + size_t **cntPtr); +virDomainChrDefPtr +virDomainChrFind(virDomainDefPtr def, + virDomainChrDefPtr target); +int +virDomainChrInsert(virDomainDefPtr vmdef, + virDomainChrDefPtr chr); +virDomainChrDefPtr +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 281478f..266329c 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -114,6 +114,10 @@ virDomainChrConsoleTargetTypeToString; virDomainChrDefForeach; virDomainChrDefFree; virDomainChrDefNew; +virDomainChrFind; +virDomainChrGetDomainPtrs; +virDomainChrInsert; +virDomainChrRemove; virDomainChrSerialTargetTypeFromString; virDomainChrSerialTargetTypeToString; virDomainChrSourceDefCopy; -- 1.8.1.5 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list