int virQEMUBuildCommandLineJSONArrayBitmap(const char *key, virJSONValuePtr array, virBufferPtr buf) { ssize_t pos = -1; ssize_t end; virBitmapPtr bitmap = NULL; if (virJSONValueGetArrayAsBitmap(array, &bitmap) < 0) return -1; while ((pos = virBitmapNextSetBit(bitmap, pos)) > -1) { if ((end = virBitmapNextClearBit(bitmap, pos)) < 0) end = virBitmapLastSetBit(bitmap) + 1; if (end - 1 > pos) { virBufferAsprintf(buf, "%s=%zd-%zd,", key, pos, end - 1); pos = end; } else { virBufferAsprintf(buf, "%s=%zd,", key, pos); } } virBitmapFree(bitmap); return 0; }
static int virDomainVirtioSerialAddrNextFromController(virDomainVirtioSerialAddrSetPtr addrs, virDomainDeviceVirtioSerialAddress *addr) { ssize_t port; ssize_t i; virBitmapPtr map; i = virDomainVirtioSerialAddrFindController(addrs, addr->controller); if (i < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("virtio-serial controller %u not available"), addr->controller); return -1; } map = addrs->controllers[i]->ports; if ((port = virBitmapNextClearBit(map, 0)) <= 0) { virReportError(VIR_ERR_XML_ERROR, _("Unable to find a free port on virtio-serial controller %u"), addr->controller); return -1; } addr->bus = 0; addr->port = port; VIR_DEBUG("Found free virtio serial controller %u port %u", addr->controller, addr->port); return 0; }
static int virDomainVirtioSerialAddrNext(virDomainDefPtr def, virDomainVirtioSerialAddrSetPtr addrs, virDomainDeviceVirtioSerialAddress *addr, bool allowZero) { int ret = -1; ssize_t port, startPort = 0; ssize_t i; unsigned int controller; /* port number 0 is reserved for virtconsoles */ if (allowZero) startPort = -1; if (addrs->ncontrollers == 0) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("no virtio-serial controllers are available")); goto cleanup; } for (i = 0; i < addrs->ncontrollers; i++) { virBitmapPtr map = addrs->controllers[i]->ports; if ((port = virBitmapNextClearBit(map, startPort)) >= 0) { controller = addrs->controllers[i]->idx; goto success; } } if (def) { for (i = 0; i < INT_MAX; i++) { int idx = virDomainControllerFind(def, VIR_DOMAIN_CONTROLLER_TYPE_VIRTIO_SERIAL, i); if (idx == -1) { if (virDomainVirtioSerialAddrSetAutoaddController(def, addrs, i) < 0) goto cleanup; controller = i; port = startPort + 1; goto success; } } } virReportError(VIR_ERR_XML_ERROR, "%s", _("Unable to find a free virtio-serial port")); cleanup: return ret; success: addr->bus = 0; addr->port = port; addr->controller = controller; VIR_DEBUG("Found free virtio serial controller %u port %u", addr->controller, addr->port); ret = 0; goto cleanup; }
/** * virNetDevMacVLanReserveID: * * @id: id 0 - MACVLAN_MAX_ID+1 to reserve (or -1 for "first free") * @flags: set VIR_NETDEV_MACVLAN_CREATE_WITH_TAP for macvtapN else macvlanN * @quietFail: don't log an error if this name is already in-use * @nextFree: reserve the next free ID *after* @id rather than @id itself * * Reserve the indicated ID in the appropriate bitmap, or find the * first free ID if @id is -1. * * Returns newly reserved ID# on success, or -1 to indicate failure. */ static int virNetDevMacVLanReserveID(int id, unsigned int flags, bool quietFail, bool nextFree) { virBitmapPtr bitmap; if (virNetDevMacVLanInitialize() < 0) return -1; bitmap = (flags & VIR_NETDEV_MACVLAN_CREATE_WITH_TAP) ? macvtapIDs : macvlanIDs; if (id > MACVLAN_MAX_ID) { virReportError(VIR_ERR_INTERNAL_ERROR, _("can't use name %s%d - out of range 0-%d"), (flags & VIR_NETDEV_MACVLAN_CREATE_WITH_TAP) ? MACVTAP_NAME_PREFIX : MACVLAN_NAME_PREFIX, id, MACVLAN_MAX_ID); return -1; } if ((id < 0 || nextFree) && (id = virBitmapNextClearBit(bitmap, id)) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("no unused %s names available"), (flags & VIR_NETDEV_MACVLAN_CREATE_WITH_TAP) ? MACVTAP_NAME_PREFIX : MACVLAN_NAME_PREFIX); return -1; } if (virBitmapIsBitSet(bitmap, id)) { if (quietFail) { VIR_INFO("couldn't reserve name %s%d - already in use", (flags & VIR_NETDEV_MACVLAN_CREATE_WITH_TAP) ? MACVTAP_NAME_PREFIX : MACVLAN_NAME_PREFIX, id); } else { virReportError(VIR_ERR_INTERNAL_ERROR, _("couldn't reserve name %s%d - already in use"), (flags & VIR_NETDEV_MACVLAN_CREATE_WITH_TAP) ? MACVTAP_NAME_PREFIX : MACVLAN_NAME_PREFIX, id); } return -1; } if (virBitmapSetBit(bitmap, id) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("couldn't mark %s%d as used"), (flags & VIR_NETDEV_MACVLAN_CREATE_WITH_TAP) ? MACVTAP_NAME_PREFIX : MACVLAN_NAME_PREFIX, id); return -1; } VIR_INFO("reserving device %s%d", (flags & VIR_NETDEV_MACVLAN_CREATE_WITH_TAP) ? MACVTAP_NAME_PREFIX : MACVLAN_NAME_PREFIX, id); return id; }
static int virQEMUBuildObjectCommandLinePropsInternal(const char *key, const virJSONValue *value, virBufferPtr buf, bool nested) { virJSONValuePtr elem; virBitmapPtr bitmap = NULL; ssize_t pos = -1; ssize_t end; size_t i; switch ((virJSONType) value->type) { case VIR_JSON_TYPE_STRING: virBufferAsprintf(buf, ",%s=%s", key, value->data.string); break; case VIR_JSON_TYPE_NUMBER: virBufferAsprintf(buf, ",%s=%s", key, value->data.number); break; case VIR_JSON_TYPE_BOOLEAN: if (value->data.boolean) virBufferAsprintf(buf, ",%s=yes", key); else virBufferAsprintf(buf, ",%s=no", key); break; case VIR_JSON_TYPE_ARRAY: if (nested) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("nested -object property arrays are not supported")); return -1; } if (virJSONValueGetArrayAsBitmap(value, &bitmap) == 0) { while ((pos = virBitmapNextSetBit(bitmap, pos)) > -1) { if ((end = virBitmapNextClearBit(bitmap, pos)) < 0) end = virBitmapLastSetBit(bitmap) + 1; if (end - 1 > pos) { virBufferAsprintf(buf, ",%s=%zd-%zd", key, pos, end - 1); pos = end; } else { virBufferAsprintf(buf, ",%s=%zd", key, pos); } } } else { /* fallback, treat the array as a non-bitmap, adding the key * for each member */ for (i = 0; i < virJSONValueArraySize(value); i++) { elem = virJSONValueArrayGet((virJSONValuePtr)value, i); /* recurse to avoid duplicating code */ if (virQEMUBuildObjectCommandLinePropsInternal(key, elem, buf, true) < 0) return -1; } } break; case VIR_JSON_TYPE_OBJECT: case VIR_JSON_TYPE_NULL: virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("NULL and OBJECT JSON types can't be converted to " "commandline string")); return -1; } virBitmapFree(bitmap); return 0; }