int virPortAllocatorRelease(virPortAllocatorPtr pa, unsigned short port) { int ret = -1; if (!port) return 0; virObjectLock(pa); if (port < pa->start || port > pa->end) { virReportInvalidArg(port, "port %d must be in range (%d, %d)", port, pa->start, pa->end); goto cleanup; } if (virBitmapClearBit(pa->bitmap, port - pa->start) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Failed to release port %d"), port); goto cleanup; } ret = 0; cleanup: virObjectUnlock(pa); return ret; }
int virPortAllocatorRelease(unsigned short port) { int ret = -1; virPortAllocatorPtr pa = virPortAllocatorGet(); if (!pa) return -1; if (!port) return 0; virObjectLock(pa); if (virBitmapClearBit(pa->bitmap, port) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Failed to release port %d"), port); goto cleanup; } ret = 0; cleanup: virObjectUnlock(pa); return ret; }
/* virDomainVirtioSerialAddrRelease * * Release the virtio serial address of the device */ int virDomainVirtioSerialAddrRelease(virDomainVirtioSerialAddrSetPtr addrs, virDomainDeviceInfoPtr info) { virBitmapPtr map; char *str = NULL; int ret = -1; ssize_t i; if (info->type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_SERIAL || info->addr.vioserial.port == 0) return 0; VIR_DEBUG("Releasing virtio serial %u %u", info->addr.vioserial.controller, info->addr.vioserial.port); i = virDomainVirtioSerialAddrFindController(addrs, info->addr.vioserial.controller); if (i < 0) { virReportError(VIR_ERR_XML_ERROR, _("virtio serial controller %u is missing"), info->addr.vioserial.controller); goto cleanup; } map = addrs->controllers[i]->ports; if (virBitmapClearBit(map, info->addr.vioserial.port) < 0) { virReportError(VIR_ERR_XML_ERROR, _("virtio serial controller %u does not have port %u"), info->addr.vioserial.controller, info->addr.vioserial.port); goto cleanup; } ret = 0; cleanup: VIR_FREE(str); return ret; }
/** * virNetDevMacVLanReleaseID: * @id: id 0 - MACVLAN_MAX_ID+1 to release * * Returns 0 for success or -1 for failure. */ static int virNetDevMacVLanReleaseID(int id, unsigned int flags) { virBitmapPtr bitmap; if (virNetDevMacVLanInitialize() < 0) return 0; bitmap = (flags & VIR_NETDEV_MACVLAN_CREATE_WITH_TAP) ? macvtapIDs : macvlanIDs; if (id > MACVLAN_MAX_ID) { virReportError(VIR_ERR_INTERNAL_ERROR, _("can't free 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) return 0; VIR_INFO("releasing %sdevice %s%d", virBitmapIsBitSet(bitmap, id) ? "" : "unreserved", (flags & VIR_NETDEV_MACVLAN_CREATE_WITH_TAP) ? MACVTAP_NAME_PREFIX : MACVLAN_NAME_PREFIX, id); if (virBitmapClearBit(bitmap, id) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("couldn't mark %s%d as unused"), (flags & VIR_NETDEV_MACVLAN_CREATE_WITH_TAP) ? MACVTAP_NAME_PREFIX : MACVLAN_NAME_PREFIX, id); return -1; } return 0; }
/** * virBitmapParse: * @str: points to a string representing a human-readable bitmap * @terminator: character separating the bitmap to parse * @bitmap: a bitmap created from @str * @bitmapSize: the upper limit of num of bits in created bitmap * * This function is the counterpart of virBitmapFormat. This function creates * a bitmap, in which bits are set according to the content of @str. * * @str is a comma separated string of fields N, which means a number of bit * to set, and ^N, which means to unset the bit, and N-M for ranges of bits * to set. * * To allow parsing of bitmaps within larger strings it is possible to set * a termination character in the argument @terminator. When the character * in @terminator is encountered in @str, the parsing of the bitmap stops. * Pass 0 as @terminator if it is not needed. Whitespace characters may not * be used as terminators. * * Returns the number of bits set in @bitmap, or -1 in case of error. */ int virBitmapParse(const char *str, char terminator, virBitmapPtr *bitmap, size_t bitmapSize) { bool neg = false; const char *cur = str; char *tmp; size_t i; int start, last; if (!(*bitmap = virBitmapNew(bitmapSize))) return -1; if (!str) goto error; virSkipSpaces(&cur); if (*cur == '\0') goto error; while (*cur != 0 && *cur != terminator) { /* * 3 constructs are allowed: * - N : a single CPU number * - N-M : a range of CPU numbers with N < M * - ^N : remove a single CPU number from the current set */ if (*cur == '^') { cur++; neg = true; } if (!c_isdigit(*cur)) goto error; if (virStrToLong_i(cur, &tmp, 10, &start) < 0) goto error; if (start < 0) goto error; cur = tmp; virSkipSpaces(&cur); if (*cur == ',' || *cur == 0 || *cur == terminator) { if (neg) { if (virBitmapClearBit(*bitmap, start) < 0) goto error; } else { if (virBitmapSetBit(*bitmap, start) < 0) goto error; } } else if (*cur == '-') { if (neg) goto error; cur++; virSkipSpaces(&cur); if (virStrToLong_i(cur, &tmp, 10, &last) < 0) goto error; if (last < start) goto error; cur = tmp; for (i = start; i <= last; i++) { if (virBitmapSetBit(*bitmap, i) < 0) goto error; } virSkipSpaces(&cur); } if (*cur == ',') { cur++; virSkipSpaces(&cur); neg = false; } else if (*cur == 0 || *cur == terminator) { break; } else { goto error; } } if (virBitmapIsAllClear(*bitmap)) goto error; return virBitmapCountBits(*bitmap); error: virReportError(VIR_ERR_INVALID_ARG, _("Failed to parse bitmap '%s'"), str); virBitmapFree(*bitmap); *bitmap = NULL; return -1; }
int virBitmapParse(const char *str, char sep, virBitmapPtr *bitmap, size_t bitmapSize) { int ret = 0; bool neg = false; const char *cur; char *tmp; int i, start, last; if (!str) return -1; cur = str; virSkipSpaces(&cur); if (*cur == 0) return -1; *bitmap = virBitmapNew(bitmapSize); if (!*bitmap) return -1; while (*cur != 0 && *cur != sep) { /* * 3 constructs are allowed: * - N : a single CPU number * - N-M : a range of CPU numbers with N < M * - ^N : remove a single CPU number from the current set */ if (*cur == '^') { cur++; neg = true; } if (!c_isdigit(*cur)) goto parse_error; if (virStrToLong_i(cur, &tmp, 10, &start) < 0) goto parse_error; if (start < 0) goto parse_error; cur = tmp; virSkipSpaces(&cur); if (*cur == ',' || *cur == 0 || *cur == sep) { if (neg) { if (virBitmapIsSet(*bitmap, start)) { ignore_value(virBitmapClearBit(*bitmap, start)); ret--; } } else { if (!virBitmapIsSet(*bitmap, start)) { ignore_value(virBitmapSetBit(*bitmap, start)); ret++; } } } else if (*cur == '-') { if (neg) goto parse_error; cur++; virSkipSpaces(&cur); if (virStrToLong_i(cur, &tmp, 10, &last) < 0) goto parse_error; if (last < start) goto parse_error; cur = tmp; for (i = start; i <= last; i++) { if (!virBitmapIsSet(*bitmap, i)) { ignore_value(virBitmapSetBit(*bitmap, i)); ret++; } } virSkipSpaces(&cur); } if (*cur == ',') { cur++; virSkipSpaces(&cur); neg = false; } else if(*cur == 0 || *cur == sep) { break; } else { goto parse_error; } } return ret; parse_error: virBitmapFree(*bitmap); *bitmap = NULL; return -1; }