]> xenbits.xensource.com Git - libvirt.git/commitdiff
domain_conf: Introduce chardev hotplug helpers
authorMichal Privoznik <mprivozn@redhat.com>
Tue, 12 Mar 2013 14:55:07 +0000 (15:55 +0100)
committerMichal Privoznik <mprivozn@redhat.com>
Fri, 12 Jul 2013 08:59:52 +0000 (10:59 +0200)
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
src/conf/domain_conf.h
src/libvirt_private.syms

index 33ae4a77596d4992a5599d6d65677eecd62ebec8..1c4cb33d10e02fa72a19dc0c6c813a25083f70c2 100644 (file)
@@ -10055,6 +10055,136 @@ virDomainLeaseRemove(virDomainDefPtr def,
     return virDomainLeaseRemoveAt(def, idx);
 }
 
+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);
+
+    return VIR_APPEND_ELEMENT(*arrPtr, *cntPtr, chr);
+}
+
+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,
index 4a7dcd2f1edd9ca915c38c6dc91309b8f6294268..9c563fe10f4eb06cad0369b4566eaf743387017b 100644 (file)
@@ -2391,6 +2391,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);
index e56c7a9b29dc0daa4544913c12a6ccd105296310..0ab7632564f1302dc1703d1dd0532c0a38ca079e 100644 (file)
@@ -114,6 +114,10 @@ virDomainChrConsoleTargetTypeToString;
 virDomainChrDefForeach;
 virDomainChrDefFree;
 virDomainChrDefNew;
+virDomainChrFind;
+virDomainChrGetDomainPtrs;
+virDomainChrInsert;
+virDomainChrRemove;
 virDomainChrSerialTargetTypeFromString;
 virDomainChrSerialTargetTypeToString;
 virDomainChrSourceDefCopy;