/* * virinterfaceobj.c: interface object handling * (derived from interface_conf.c) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see * . */ #include #include "datatypes.h" #include "interface_conf.h" #include "viralloc.h" #include "virerror.h" #include "virinterfaceobj.h" #include "virlog.h" #include "virstring.h" #define VIR_FROM_THIS VIR_FROM_INTERFACE VIR_LOG_INIT("conf.virinterfaceobj"); /* virInterfaceObj manipulation */ void virInterfaceObjLock(virInterfaceObjPtr obj) { virMutexLock(&obj->lock); } void virInterfaceObjUnlock(virInterfaceObjPtr obj) { virMutexUnlock(&obj->lock); } void virInterfaceObjFree(virInterfaceObjPtr obj) { if (!obj) return; virInterfaceDefFree(obj->def); virMutexDestroy(&obj->lock); VIR_FREE(obj); } /* virInterfaceObjList manipulation */ int virInterfaceObjFindByMACString(virInterfaceObjListPtr interfaces, const char *mac, virInterfaceObjPtr *matches, int maxmatches) { size_t i; unsigned int matchct = 0; for (i = 0; i < interfaces->count; i++) { virInterfaceObjLock(interfaces->objs[i]); if (STRCASEEQ(interfaces->objs[i]->def->mac, mac)) { matchct++; if (matchct <= maxmatches) { matches[matchct - 1] = interfaces->objs[i]; /* keep the lock if we're returning object to caller */ /* it is the caller's responsibility to unlock *all* matches */ continue; } } virInterfaceObjUnlock(interfaces->objs[i]); } return matchct; } virInterfaceObjPtr virInterfaceObjFindByName(virInterfaceObjListPtr interfaces, const char *name) { size_t i; for (i = 0; i < interfaces->count; i++) { virInterfaceObjLock(interfaces->objs[i]); if (STREQ(interfaces->objs[i]->def->name, name)) return interfaces->objs[i]; virInterfaceObjUnlock(interfaces->objs[i]); } return NULL; } void virInterfaceObjListFree(virInterfaceObjListPtr interfaces) { size_t i; for (i = 0; i < interfaces->count; i++) virInterfaceObjFree(interfaces->objs[i]); VIR_FREE(interfaces->objs); interfaces->count = 0; } int virInterfaceObjListClone(virInterfaceObjListPtr src, virInterfaceObjListPtr dest) { int ret = -1; size_t i; unsigned int cnt; if (!src || !dest) goto cleanup; virInterfaceObjListFree(dest); /* start with an empty list */ cnt = src->count; for (i = 0; i < cnt; i++) { virInterfaceDefPtr def = src->objs[i]->def; virInterfaceDefPtr backup; virInterfaceObjPtr obj; char *xml = virInterfaceDefFormat(def); if (!xml) goto cleanup; if ((backup = virInterfaceDefParseString(xml)) == NULL) { VIR_FREE(xml); goto cleanup; } VIR_FREE(xml); if ((obj = virInterfaceObjAssignDef(dest, backup)) == NULL) goto cleanup; virInterfaceObjUnlock(obj); /* locked by virInterfaceObjAssignDef */ } ret = cnt; cleanup: if ((ret < 0) && dest) virInterfaceObjListFree(dest); return ret; } virInterfaceObjPtr virInterfaceObjAssignDef(virInterfaceObjListPtr interfaces, virInterfaceDefPtr def) { virInterfaceObjPtr obj; if ((obj = virInterfaceObjFindByName(interfaces, def->name))) { virInterfaceDefFree(obj->def); obj->def = def; return obj; } if (VIR_ALLOC(obj) < 0) return NULL; if (virMutexInit(&obj->lock) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("cannot initialize mutex")); VIR_FREE(obj); return NULL; } virInterfaceObjLock(obj); if (VIR_APPEND_ELEMENT_COPY(interfaces->objs, interfaces->count, obj) < 0) { virInterfaceObjFree(obj); return NULL; } obj->def = def; return obj; } void virInterfaceObjRemove(virInterfaceObjListPtr interfaces, virInterfaceObjPtr obj) { size_t i; virInterfaceObjUnlock(obj); for (i = 0; i < interfaces->count; i++) { virInterfaceObjLock(interfaces->objs[i]); if (interfaces->objs[i] == obj) { virInterfaceObjUnlock(interfaces->objs[i]); virInterfaceObjFree(interfaces->objs[i]); VIR_DELETE_ELEMENT(interfaces->objs, i, interfaces->count); break; } virInterfaceObjUnlock(interfaces->objs[i]); } } int virInterfaceObjNumOfInterfaces(virInterfaceObjListPtr interfaces, bool wantActive) { size_t i; int ninterfaces = 0; for (i = 0; (i < interfaces->count); i++) { virInterfaceObjPtr obj = interfaces->objs[i]; virInterfaceObjLock(obj); if (wantActive == virInterfaceObjIsActive(obj)) ninterfaces++; virInterfaceObjUnlock(obj); } return ninterfaces; } int virInterfaceObjGetNames(virInterfaceObjListPtr interfaces, bool wantActive, char **const names, int maxnames) { int nnames = 0; size_t i; for (i = 0; i < interfaces->count && nnames < maxnames; i++) { virInterfaceObjPtr obj = interfaces->objs[i]; virInterfaceObjLock(obj); if (wantActive == virInterfaceObjIsActive(obj)) { if (VIR_STRDUP(names[nnames], obj->def->name) < 0) { virInterfaceObjUnlock(obj); goto failure; } nnames++; } virInterfaceObjUnlock(obj); } return nnames; failure: while (--nnames >= 0) VIR_FREE(names[nnames]); return -1; }