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>
33 #include "afscp_search.h"
36 #include <afs/vlserver.h>
37 #include <afs/vldbint.h>
38 #include <afs/volint.h>
40 #include "afscp_internal.h"
43 icompare(const void *pa
, const void *pb
)
45 const struct afscp_volume
*va
= pa
, *vb
= pb
;
55 ncompare(const void *pa
, const void *pb
)
57 const struct afscp_volume
*va
= pa
, *vb
= pb
;
59 if (va
->voltype
> vb
->voltype
)
61 if (vb
->voltype
< va
->voltype
)
63 return strcmp(va
->name
, vb
->name
);
73 afscp_VolumeByName(struct afscp_cell
*cell
, const char *vname
,
77 struct afscp_volume
*ret
, key
;
78 struct afscp_server
*server
;
79 afs_int32 code
, vtype
, type
, srv
;
86 else if (intype
== ROVOL
)
88 else if (intype
== BACKVOL
)
95 memset(&key
, 0, sizeof(key
));
96 strlcpy(key
.name
, vname
, sizeof(key
.name
));
98 s
= tfind(&key
, &cell
->volsbyname
, ncompare
);
100 ret
= *(struct afscp_volume
**)s
;
105 code
= ubik_VL_GetEntryByNameU(cell
->vlservers
, 0, (char *)vname
, &u
.u
);
106 if (code
== RXGEN_OPCODE
) {
109 ubik_VL_GetEntryByNameN(cell
->vlservers
, 0, (char *)vname
, &u
.n
);
110 if (code
== RXGEN_OPCODE
) {
112 code
= ubik_VL_GetEntryByNameO(cell
->vlservers
, 0, (char *)vname
,
120 ret
= malloc(sizeof(struct afscp_volume
));
122 afscp_errno
= ENOMEM
;
125 memset(ret
, 0, sizeof(struct afscp_volume
));
126 strlcpy(ret
->name
, u
.u
.name
, sizeof(ret
->name
));
131 ret
->id
= u
.u
.volumeId
[intype
];
132 for (srv
= 0; srv
< u
.u
.nServers
; srv
++) {
133 if ((u
.u
.serverFlags
[srv
] & vtype
) == 0)
135 afs_dprintf(("uvldbentry server %d flags: %x\n", srv
,
136 u
.u
.serverFlags
[srv
]));
138 if ((u
.u
.serverFlags
[srv
] & VLSERVER_FLAG_UUID
) == 0)
140 afscp_ServerByAddr(cell
, u
.u
.serverNumber
[srv
].time_low
);
142 server
= afscp_ServerById(cell
, &u
.u
.serverNumber
[srv
]);
145 ret
->servers
[ret
->nservers
++] = server
->index
;
149 ret
->id
= u
.n
.volumeId
[intype
];
150 for (srv
= 0; srv
< u
.n
.nServers
; srv
++) {
151 if ((u
.n
.serverFlags
[srv
] & vtype
) == 0)
153 server
= afscp_ServerByAddr(cell
, u
.n
.serverNumber
[srv
]);
156 ret
->servers
[ret
->nservers
++] = server
->index
;
160 ret
->id
= u
.o
.volumeId
[intype
];
161 for (srv
= 0; srv
< u
.o
.nServers
; srv
++) {
162 if ((u
.o
.serverFlags
[srv
] & vtype
) == 0)
164 server
= afscp_ServerByAddr(cell
, u
.o
.serverNumber
[srv
]);
167 ret
->servers
[ret
->nservers
++] = server
->index
;
171 if (!ret
->nservers
|| !ret
->id
) {
176 ret
->voltype
= intype
;
177 server
= afscp_ServerByIndex(ret
->servers
[0]);
180 i
.s_addr
= server
->addrs
[0];
184 afs_dprintf(("New volume BYNAME %s (%lu) on %s (%d)\n", ret
->name
,
185 afs_printable_uint32_lu(ret
->id
),
186 inet_ntoa(i
), ret
->servers
[0]));
187 s
= tsearch(&key
, &cell
->volsbyname
, ncompare
);
189 *(struct afscp_volume
**)s
= ret
;
191 s
= tsearch(&key
, &cell
->volsbyid
, icompare
);
193 *(struct afscp_volume
**)s
= ret
;
197 struct afscp_volume
*
198 afscp_VolumeById(struct afscp_cell
*cell
, afs_uint32 id
)
200 union allvldbentry u
;
201 struct afscp_volume
*ret
, key
;
202 struct afscp_server
*server
;
203 afs_int32 code
, vtype
, type
, srv
;
211 memset(&key
, 0, sizeof(key
));
213 s
= tfind(&key
, &cell
->volsbyid
, icompare
);
215 ret
= *(struct afscp_volume
**)s
;
219 snprintf(idbuffer
, sizeof(idbuffer
), "%lu", afs_printable_uint32_lu(id
));
221 code
= ubik_VL_GetEntryByNameU(cell
->vlservers
, 0, idbuffer
, &u
.u
);
222 if (code
== RXGEN_OPCODE
) {
224 code
= ubik_VL_GetEntryByIDN(cell
->vlservers
, 0, id
, -1, &u
.n
);
225 if (code
== RXGEN_OPCODE
) {
227 code
= ubik_VL_GetEntryByID(cell
->vlservers
, 0, id
, -1, &u
.o
);
234 ret
= malloc(sizeof(struct afscp_volume
));
236 afscp_errno
= ENOMEM
;
239 memset(ret
, 0, sizeof(struct afscp_volume
));
240 strlcpy(ret
->name
, u
.u
.name
, sizeof(ret
->name
));
246 if (id
== u
.u
.volumeId
[RWVOL
]) {
249 } else if (id
== u
.u
.volumeId
[ROVOL
]) {
252 } else if (id
== u
.u
.volumeId
[BACKVOL
]) {
253 vtype
= VLSF_BACKVOL
;
259 for (srv
= 0; srv
< u
.u
.nServers
; srv
++) {
260 if ((u
.u
.serverFlags
[srv
] & vtype
) == 0)
262 if ((u
.u
.serverFlags
[srv
] & VLSERVER_FLAG_UUID
) == 0)
264 afscp_ServerByAddr(cell
, u
.u
.serverNumber
[srv
].time_low
);
266 server
= afscp_ServerById(cell
, &u
.u
.serverNumber
[srv
]);
269 ret
->servers
[ret
->nservers
++] = server
->index
;
273 if (id
== u
.n
.volumeId
[RWVOL
]) {
276 } else if (id
== u
.n
.volumeId
[ROVOL
]) {
279 } else if (id
== u
.n
.volumeId
[BACKVOL
]) {
280 vtype
= VLSF_BACKVOL
;
286 for (srv
= 0; srv
< u
.n
.nServers
; srv
++) {
287 if ((u
.n
.serverFlags
[srv
] & vtype
) == 0)
289 server
= afscp_ServerByAddr(cell
, u
.n
.serverNumber
[srv
]);
292 ret
->servers
[ret
->nservers
++] = server
->index
;
296 if (id
== u
.o
.volumeId
[RWVOL
]) {
299 } else if (id
== u
.o
.volumeId
[ROVOL
]) {
302 } else if (id
== u
.o
.volumeId
[BACKVOL
]) {
303 vtype
= VLSF_BACKVOL
;
309 for (srv
= 0; srv
< u
.o
.nServers
; srv
++) {
310 if ((u
.o
.serverFlags
[srv
] & vtype
) == 0)
312 server
= afscp_ServerByAddr(cell
, u
.o
.serverNumber
[srv
]);
315 ret
->servers
[ret
->nservers
++] = server
->index
;
319 ret
->voltype
= voltype
;
320 server
= afscp_ServerByIndex(ret
->servers
[0]);
323 i
.s_addr
= server
->addrs
[0];
327 afs_dprintf(("New volume BYID %s (%lu) on %s (%d)\n", ret
->name
,
328 afs_printable_uint32_lu(ret
->id
), inet_ntoa(i
),
330 s
= tsearch(&key
, &cell
->volsbyid
, icompare
);
332 *(struct afscp_volume
**)s
= ret
;
333 strlcpy(key
.name
, ret
->name
, sizeof(key
.name
));
334 s
= tsearch(&key
, &cell
->volsbyname
, ncompare
);
336 *(struct afscp_volume
**)s
= ret
;