virinterfaceobj.c 6.5 KB
Newer Older
J
John Ferlan 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
/*
 * 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
 * <http://www.gnu.org/licenses/>.
 */

#include <config.h>

#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 */

39 40
void
virInterfaceObjLock(virInterfaceObjPtr obj)
J
John Ferlan 已提交
41 42 43 44
{
    virMutexLock(&obj->lock);
}

45 46 47

void
virInterfaceObjUnlock(virInterfaceObjPtr obj)
J
John Ferlan 已提交
48 49 50 51
{
    virMutexUnlock(&obj->lock);
}

52 53

void
54
virInterfaceObjFree(virInterfaceObjPtr obj)
J
John Ferlan 已提交
55
{
56
    if (!obj)
J
John Ferlan 已提交
57 58
        return;

59 60 61
    virInterfaceDefFree(obj->def);
    virMutexDestroy(&obj->lock);
    VIR_FREE(obj);
J
John Ferlan 已提交
62 63 64
}


65 66
/* virInterfaceObjList manipulation */
int
67 68 69
virInterfaceObjFindByMACString(virInterfaceObjListPtr interfaces,
                               const char *mac,
                               virInterfaceObjPtr *matches, int maxmatches)
J
John Ferlan 已提交
70 71 72 73 74
{
    size_t i;
    unsigned int matchct = 0;

    for (i = 0; i < interfaces->count; i++) {
75 76
        virInterfaceObjPtr obj = interfaces->objs[i];
        virInterfaceDefPtr def;
J
John Ferlan 已提交
77

78 79 80
        virInterfaceObjLock(obj);
        def = obj->def;
        if (STRCASEEQ(def->mac, mac)) {
J
John Ferlan 已提交
81 82
            matchct++;
            if (matchct <= maxmatches) {
83
                matches[matchct - 1] = obj;
J
John Ferlan 已提交
84 85 86 87 88
                /* keep the lock if we're returning object to caller */
                /* it is the caller's responsibility to unlock *all* matches */
                continue;
            }
        }
89
        virInterfaceObjUnlock(obj);
J
John Ferlan 已提交
90 91 92 93 94

    }
    return matchct;
}

95 96

virInterfaceObjPtr
97 98
virInterfaceObjFindByName(virInterfaceObjListPtr interfaces,
                          const char *name)
J
John Ferlan 已提交
99 100 101 102
{
    size_t i;

    for (i = 0; i < interfaces->count; i++) {
103 104 105 106 107 108 109 110
        virInterfaceObjPtr obj = interfaces->objs[i];
        virInterfaceDefPtr def;

        virInterfaceObjLock(obj);
        def = obj->def;
        if (STREQ(def->name, name))
            return obj;
        virInterfaceObjUnlock(obj);
J
John Ferlan 已提交
111 112 113 114 115
    }

    return NULL;
}

116 117 118

void
virInterfaceObjListFree(virInterfaceObjListPtr interfaces)
J
John Ferlan 已提交
119 120 121 122 123 124 125 126 127 128
{
    size_t i;

    for (i = 0; i < interfaces->count; i++)
        virInterfaceObjFree(interfaces->objs[i]);

    VIR_FREE(interfaces->objs);
    interfaces->count = 0;
}

129 130 131 132

int
virInterfaceObjListClone(virInterfaceObjListPtr src,
                         virInterfaceObjListPtr dest)
J
John Ferlan 已提交
133 134 135 136 137 138 139 140 141 142 143
{
    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++) {
144
        virInterfaceObjPtr srcobj = src->objs[i];
J
John Ferlan 已提交
145
        virInterfaceDefPtr backup;
146
        virInterfaceObjPtr obj;
147
        char *xml = virInterfaceDefFormat(srcobj->def);
J
John Ferlan 已提交
148 149 150 151 152 153 154 155 156 157

        if (!xml)
            goto cleanup;

        if ((backup = virInterfaceDefParseString(xml)) == NULL) {
            VIR_FREE(xml);
            goto cleanup;
        }

        VIR_FREE(xml);
158
        if ((obj = virInterfaceObjAssignDef(dest, backup)) == NULL)
J
John Ferlan 已提交
159
            goto cleanup;
160
        virInterfaceObjUnlock(obj); /* locked by virInterfaceObjAssignDef */
J
John Ferlan 已提交
161 162 163 164 165 166 167 168 169
    }

    ret = cnt;
 cleanup:
    if ((ret < 0) && dest)
       virInterfaceObjListFree(dest);
    return ret;
}

170 171

virInterfaceObjPtr
172 173
virInterfaceObjAssignDef(virInterfaceObjListPtr interfaces,
                         virInterfaceDefPtr def)
J
John Ferlan 已提交
174
{
175
    virInterfaceObjPtr obj;
J
John Ferlan 已提交
176

177 178 179
    if ((obj = virInterfaceObjFindByName(interfaces, def->name))) {
        virInterfaceDefFree(obj->def);
        obj->def = def;
J
John Ferlan 已提交
180

181
        return obj;
J
John Ferlan 已提交
182 183
    }

184
    if (VIR_ALLOC(obj) < 0)
J
John Ferlan 已提交
185
        return NULL;
186
    if (virMutexInit(&obj->lock) < 0) {
J
John Ferlan 已提交
187 188
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       "%s", _("cannot initialize mutex"));
189
        VIR_FREE(obj);
J
John Ferlan 已提交
190 191
        return NULL;
    }
192
    virInterfaceObjLock(obj);
J
John Ferlan 已提交
193 194

    if (VIR_APPEND_ELEMENT_COPY(interfaces->objs,
195 196
                                interfaces->count, obj) < 0) {
        virInterfaceObjFree(obj);
J
John Ferlan 已提交
197 198 199
        return NULL;
    }

200 201
    obj->def = def;
    return obj;
J
John Ferlan 已提交
202 203 204

}

205 206

void
207
virInterfaceObjRemove(virInterfaceObjListPtr interfaces,
208
                      virInterfaceObjPtr obj)
J
John Ferlan 已提交
209 210 211
{
    size_t i;

212
    virInterfaceObjUnlock(obj);
J
John Ferlan 已提交
213 214
    for (i = 0; i < interfaces->count; i++) {
        virInterfaceObjLock(interfaces->objs[i]);
215
        if (interfaces->objs[i] == obj) {
J
John Ferlan 已提交
216 217 218 219 220 221 222 223 224
            virInterfaceObjUnlock(interfaces->objs[i]);
            virInterfaceObjFree(interfaces->objs[i]);

            VIR_DELETE_ELEMENT(interfaces->objs, i, interfaces->count);
            break;
        }
        virInterfaceObjUnlock(interfaces->objs[i]);
    }
}
225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243


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;
}
244 245 246 247 248 249 250 251 252 253 254 255 256


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];
257 258
        virInterfaceDefPtr def;

259
        virInterfaceObjLock(obj);
260
        def = obj->def;
261
        if (wantActive == virInterfaceObjIsActive(obj)) {
262
            if (VIR_STRDUP(names[nnames], def->name) < 0) {
263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278
                virInterfaceObjUnlock(obj);
                goto failure;
            }
            nnames++;
        }
        virInterfaceObjUnlock(obj);
    }

    return nnames;

 failure:
    while (--nnames >= 0)
        VIR_FREE(names[nnames]);

    return -1;
}