2 Copyright (C) 2003 - 2010 Chaskiel Grundman
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions
9 1. Redistributions of source code must retain the above copyright
10 notice, this list of conditions and the following disclaimer.
12 2. Redistributions in binary form must reproduce the above copyright
13 notice, this list of conditions and the following disclaimer in the
14 documentation and/or other materials provided with the distribution.
16 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 #include <afsconfig.h>
28 #include <afs/param.h>
34 #include <afs/vlserver.h>
35 #include <afs/vldbint.h>
36 #include <afs/volint.h>
38 #include "afscp_internal.h"
41 icompare(const void *pa, const void *pb)
43 const struct afscp_volume *va = pa, *vb = pb;
53 ncompare(const void *pa, const void *pb)
55 const struct afscp_volume *va = pa, *vb = pb;
57 if (va->voltype > vb->voltype)
59 if (vb->voltype < va->voltype)
61 return strcmp(va->name, vb->name);
71 afscp_VolumeByName(struct afscp_cell *cell, const char *vname,
75 struct afscp_volume *ret, key;
76 struct afscp_server *server;
77 afs_int32 code, vtype, type, srv;
84 else if (intype == ROVOL)
86 else if (intype == BACKVOL)
93 memset(&key, 0, sizeof(key));
94 strlcpy(key.name, vname, sizeof(key.name));
96 s = tfind(&key, &cell->volsbyname, ncompare);
98 ret = *(struct afscp_volume **)s;
103 code = ubik_VL_GetEntryByNameU(cell->vlservers, 0, (char *)vname, &u.u);
104 if (code == RXGEN_OPCODE) {
107 ubik_VL_GetEntryByNameN(cell->vlservers, 0, (char *)vname, &u.n);
108 if (code == RXGEN_OPCODE) {
110 code = ubik_VL_GetEntryByNameO(cell->vlservers, 0, (char *)vname,
118 ret = malloc(sizeof(struct afscp_volume));
120 afscp_errno = ENOMEM;
123 memset(ret, 0, sizeof(struct afscp_volume));
124 strlcpy(ret->name, u.u.name, sizeof(ret->name));
129 ret->id = u.u.volumeId[intype];
130 for (srv = 0; srv < u.u.nServers; srv++) {
131 if ((u.u.serverFlags[srv] & vtype) == 0)
133 afs_dprintf(("uvldbentry server %d flags: %x\n", srv,
134 u.u.serverFlags[srv]));
136 if ((u.u.serverFlags[srv] & VLSERVER_FLAG_UUID) == 0)
138 afscp_ServerByAddr(cell, u.u.serverNumber[srv].time_low);
140 server = afscp_ServerById(cell, &u.u.serverNumber[srv]);
143 ret->servers[ret->nservers++] = server->index;
147 ret->id = u.n.volumeId[intype];
148 for (srv = 0; srv < u.n.nServers; srv++) {
149 if ((u.n.serverFlags[srv] & vtype) == 0)
151 server = afscp_ServerByAddr(cell, u.n.serverNumber[srv]);
154 ret->servers[ret->nservers++] = server->index;
158 ret->id = u.o.volumeId[intype];
159 for (srv = 0; srv < u.o.nServers; srv++) {
160 if ((u.o.serverFlags[srv] & vtype) == 0)
162 server = afscp_ServerByAddr(cell, u.o.serverNumber[srv]);
165 ret->servers[ret->nservers++] = server->index;
169 if (!ret->nservers || !ret->id) {
174 ret->voltype = intype;
175 server = afscp_ServerByIndex(ret->servers[0]);
178 i.s_addr = server->addrs[0];
182 afs_dprintf(("New volume BYNAME %s (%lu) on %s (%d)\n", ret->name,
183 afs_printable_uint32_lu(ret->id),
184 inet_ntoa(i), ret->servers[0]));
185 s = tsearch(&key, &cell->volsbyname, ncompare);
187 *(struct afscp_volume **)s = ret;
189 s = tsearch(&key, &cell->volsbyid, icompare);
191 *(struct afscp_volume **)s = ret;
195 struct afscp_volume *
196 afscp_VolumeById(struct afscp_cell *cell, afs_uint32 id)
198 union allvldbentry u;
199 struct afscp_volume *ret, key;
200 struct afscp_server *server;
201 afs_int32 code, vtype, type, srv;
209 memset(&key, 0, sizeof(key));
211 s = tfind(&key, &cell->volsbyid, icompare);
213 ret = *(struct afscp_volume **)s;
217 snprintf(idbuffer, sizeof(idbuffer), "%lu", afs_printable_uint32_lu(id));
219 code = ubik_VL_GetEntryByNameU(cell->vlservers, 0, idbuffer, &u.u);
220 if (code == RXGEN_OPCODE) {
222 code = ubik_VL_GetEntryByIDN(cell->vlservers, 0, id, -1, &u.n);
223 if (code == RXGEN_OPCODE) {
225 code = ubik_VL_GetEntryByID(cell->vlservers, 0, id, -1, &u.o);
232 ret = malloc(sizeof(struct afscp_volume));
234 afscp_errno = ENOMEM;
237 memset(ret, 0, sizeof(struct afscp_volume));
238 strlcpy(ret->name, u.u.name, sizeof(ret->name));
244 if (id == u.u.volumeId[RWVOL]) {
247 } else if (id == u.u.volumeId[ROVOL]) {
250 } else if (id == u.u.volumeId[BACKVOL]) {
251 vtype = VLSF_BACKVOL;
257 for (srv = 0; srv < u.u.nServers; srv++) {
258 if ((u.u.serverFlags[srv] & vtype) == 0)
260 if ((u.u.serverFlags[srv] & VLSERVER_FLAG_UUID) == 0)
262 afscp_ServerByAddr(cell, u.u.serverNumber[srv].time_low);
264 server = afscp_ServerById(cell, &u.u.serverNumber[srv]);
267 ret->servers[ret->nservers++] = server->index;
271 if (id == u.n.volumeId[RWVOL]) {
274 } else if (id == u.n.volumeId[ROVOL]) {
277 } else if (id == u.n.volumeId[BACKVOL]) {
278 vtype = VLSF_BACKVOL;
284 for (srv = 0; srv < u.n.nServers; srv++) {
285 if ((u.n.serverFlags[srv] & vtype) == 0)
287 server = afscp_ServerByAddr(cell, u.n.serverNumber[srv]);
290 ret->servers[ret->nservers++] = server->index;
294 if (id == u.o.volumeId[RWVOL]) {
297 } else if (id == u.o.volumeId[ROVOL]) {
300 } else if (id == u.o.volumeId[BACKVOL]) {
301 vtype = VLSF_BACKVOL;
307 for (srv = 0; srv < u.o.nServers; srv++) {
308 if ((u.o.serverFlags[srv] & vtype) == 0)
310 server = afscp_ServerByAddr(cell, u.o.serverNumber[srv]);
313 ret->servers[ret->nservers++] = server->index;
317 ret->voltype = voltype;
318 server = afscp_ServerByIndex(ret->servers[0]);
321 i.s_addr = server->addrs[0];
325 afs_dprintf(("New volume BYID %s (%lu) on %s (%d)\n", ret->name,
326 afs_printable_uint32_lu(ret->id), inet_ntoa(i),
328 s = tsearch(&key, &cell->volsbyid, icompare);
330 *(struct afscp_volume **)s = ret;
331 strlcpy(key.name, ret->name, sizeof(key.name));
332 s = tsearch(&key, &cell->volsbyname, ncompare);
334 *(struct afscp_volume **)s = ret;