2 * Copyright 2000, International Business Machines Corporation and others.
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
10 #include <afsconfig.h>
11 #include <afs/param.h>
18 #include <sys/statfs.h>
24 #include <rx/rx_globals.h>
26 #include <afs/vlserver.h>
27 #include <afs/cellconfig.h>
30 #include <afs/afsint.h>
38 #include "vsutils_prototypes.h"
40 struct ubik_client
*cstruct
;
43 ovlentry_to_nvlentry(struct vldbentry
*oentryp
,
44 struct nvldbentry
*nentryp
)
48 memset(nentryp
, 0, sizeof(struct nvldbentry
));
49 strncpy(nentryp
->name
, oentryp
->name
, sizeof(nentryp
->name
));
50 for (i
= 0; i
< oentryp
->nServers
; i
++) {
51 nentryp
->serverNumber
[i
] = oentryp
->serverNumber
[i
];
52 nentryp
->serverPartition
[i
] = oentryp
->serverPartition
[i
];
53 nentryp
->serverFlags
[i
] = oentryp
->serverFlags
[i
];
55 nentryp
->nServers
= oentryp
->nServers
;
56 for (i
= 0; i
< MAXTYPES
; i
++)
57 nentryp
->volumeId
[i
] = oentryp
->volumeId
[i
];
58 nentryp
->cloneId
= oentryp
->cloneId
;
59 nentryp
->flags
= oentryp
->flags
;
63 nvlentry_to_ovlentry(struct nvldbentry
*nentryp
,
64 struct vldbentry
*oentryp
)
68 memset(oentryp
, 0, sizeof(struct vldbentry
));
69 strncpy(oentryp
->name
, nentryp
->name
, sizeof(oentryp
->name
));
70 if (nentryp
->nServers
> OMAXNSERVERS
) {
72 * The alternative is to store OMAXSERVERS but it's always better
73 * to know what's going on...
77 for (i
= 0; i
< nentryp
->nServers
; i
++) {
78 oentryp
->serverNumber
[i
] = nentryp
->serverNumber
[i
];
79 oentryp
->serverPartition
[i
] = nentryp
->serverPartition
[i
];
80 oentryp
->serverFlags
[i
] = nentryp
->serverFlags
[i
];
82 oentryp
->nServers
= i
;
83 for (i
= 0; i
< MAXTYPES
; i
++)
84 oentryp
->volumeId
[i
] = nentryp
->volumeId
[i
];
85 oentryp
->cloneId
= nentryp
->cloneId
;
86 oentryp
->flags
= nentryp
->flags
;
97 static enum _vlserver_type newvlserver
= vltype_unknown
;
100 VLDB_CreateEntry(struct nvldbentry
*entryp
)
102 struct vldbentry oentry
;
105 if (newvlserver
== vltype_old
) {
107 code
= nvlentry_to_ovlentry(entryp
, &oentry
);
110 code
= ubik_VL_CreateEntry(cstruct
, 0, &oentry
);
113 code
= ubik_VL_CreateEntryN(cstruct
, 0, entryp
);
114 if (newvlserver
== vltype_unknown
) {
115 if (code
== RXGEN_OPCODE
) {
116 newvlserver
= vltype_old
; /* Doesn't support new interface */
119 newvlserver
= vltype_new
;
126 VLDB_GetEntryByID(afs_uint32 volid
, afs_int32 voltype
, struct nvldbentry
*entryp
)
128 struct vldbentry oentry
;
131 if (newvlserver
== vltype_old
) {
134 ubik_VL_GetEntryByID(cstruct
, 0, volid
, voltype
, &oentry
);
136 ovlentry_to_nvlentry(&oentry
, entryp
);
139 code
= ubik_VL_GetEntryByIDN(cstruct
, 0, volid
, voltype
, entryp
);
140 if (newvlserver
== vltype_unknown
) {
141 if (code
== RXGEN_OPCODE
) {
142 newvlserver
= vltype_old
; /* Doesn't support new interface */
145 newvlserver
= vltype_new
;
152 VLDB_GetEntryByName(char *namep
, struct nvldbentry
*entryp
)
154 struct vldbentry oentry
;
157 if (newvlserver
== vltype_old
) {
159 code
= ubik_VL_GetEntryByNameO(cstruct
, 0, namep
, &oentry
);
161 ovlentry_to_nvlentry(&oentry
, entryp
);
164 code
= ubik_VL_GetEntryByNameN(cstruct
, 0, namep
, entryp
);
165 if (newvlserver
== vltype_unknown
) {
166 if (code
== RXGEN_OPCODE
) {
167 newvlserver
= vltype_old
; /* Doesn't support new interface */
170 newvlserver
= vltype_new
;
177 VLDB_ReplaceEntry(afs_uint32 volid
, afs_int32 voltype
, struct nvldbentry
*entryp
, afs_int32 releasetype
)
179 struct vldbentry oentry
;
182 if (newvlserver
== vltype_old
) {
184 code
= nvlentry_to_ovlentry(entryp
, &oentry
);
188 ubik_VL_ReplaceEntry(cstruct
, 0, volid
, voltype
, &oentry
,
193 ubik_VL_ReplaceEntryN(cstruct
, 0, volid
, voltype
, entryp
,
195 if (newvlserver
== vltype_unknown
) {
196 if (code
== RXGEN_OPCODE
) {
197 newvlserver
= vltype_old
; /* Doesn't support new interface */
200 newvlserver
= vltype_new
;
207 convertBulkToNBulk(bulkentries
*bulk
, nbulkentries
*nbulk
) {
210 if (bulk
->bulkentries_len
== 0)
213 nbulk
->nbulkentries_len
= bulk
->bulkentries_len
;
214 nbulk
->nbulkentries_val
=
215 xdr_alloc(bulk
->bulkentries_len
* sizeof(struct nvldbentry
));
217 for (i
= 0; i
< bulk
->bulkentries_len
; i
++) {
218 ovlentry_to_nvlentry(&bulk
->bulkentries_val
[i
],
219 &nbulk
->nbulkentries_val
[i
]);
224 VLDB_ListAttributes(VldbListByAttributes
*attrp
,
226 nbulkentries
*blkentriesp
)
228 bulkentries arrayEntries
;
231 if (newvlserver
== vltype_old
) {
233 memset(&arrayEntries
, 0, sizeof(arrayEntries
));
235 ubik_VL_ListAttributes(cstruct
, 0, attrp
, entriesp
,
241 /* Ensure the number of entries claimed matches the no. returned */
244 if (*entriesp
> arrayEntries
.bulkentries_len
)
245 *entriesp
= arrayEntries
.bulkentries_len
;
247 convertBulkToNBulk(&arrayEntries
, blkentriesp
);
249 xdr_free((xdrproc_t
) xdr_bulkentries
, &arrayEntries
);
253 ubik_VL_ListAttributesN(cstruct
, 0, attrp
, entriesp
, blkentriesp
);
254 if (newvlserver
== vltype_unknown
) {
255 if (code
== RXGEN_OPCODE
) {
256 newvlserver
= vltype_old
; /* Doesn't support new interface */
259 newvlserver
= vltype_new
;
263 /* Ensure the number of entries claimed matches the no. returned */
266 if (*entriesp
> blkentriesp
->nbulkentries_len
)
267 *entriesp
= blkentriesp
->nbulkentries_len
;
273 VLDB_ListAttributesN2(VldbListByAttributes
*attrp
,
276 afs_int32
*nentriesp
,
277 nbulkentries
*blkentriesp
,
278 afs_int32
*nextindexp
)
280 afs_int32 code
= RXGEN_OPCODE
;
282 if (newvlserver
!= vltype_old
) {
284 ubik_VL_ListAttributesN2(cstruct
, 0, attrp
, (name
? name
: ""),
285 thisindex
, nentriesp
, blkentriesp
, nextindexp
);
289 /* Ensure the number of entries claimed matches the no. returned */
292 if (*nentriesp
> blkentriesp
->nbulkentries_len
)
293 *nentriesp
= blkentriesp
->nbulkentries_len
;
301 afs_uint32 addrs
[16];
304 * Increase cache size. This avoids high CPU usage by the vlserver
305 * in environments where there are more than 16 fileservers in the
308 #define GETADDRUCACHESIZE 64
309 struct cacheips cacheips
[GETADDRUCACHESIZE
];
310 int cacheip_index
= 0;
313 VLDB_IsSameAddrs(afs_uint32 serv1
, afs_uint32 serv2
, afs_int32
*errorp
)
316 ListAddrByAttributes attrs
;
318 afs_uint32
*addrp
, j
, f1
, f2
;
319 afs_int32 unique
, nentries
, i
;
321 static int initcache
= 0;
327 if (newvlserver
== vltype_old
|| newvlserver
== vltype_new
) {
331 for (i
= 0; i
< GETADDRUCACHESIZE
; i
++) {
332 cacheips
[i
].server
= cacheips
[i
].count
= 0;
337 /* See if it's cached */
338 for (i
= 0; i
< GETADDRUCACHESIZE
; i
++) {
340 for (j
= 0; j
< cacheips
[i
].count
; j
++) {
341 if (serv1
== cacheips
[i
].addrs
[j
])
343 else if (serv2
== cacheips
[i
].addrs
[j
])
351 if (cacheips
[i
].server
== serv1
)
355 memset(&attrs
, 0, sizeof(attrs
));
356 attrs
.Mask
= VLADDR_IPADDR
;
357 attrs
.ipaddr
= serv1
;
358 memset(&addrs
, 0, sizeof(addrs
));
359 memset(&uuid
, 0, sizeof(uuid
));
361 ubik_VL_GetAddrsU(cstruct
, 0, &attrs
, &uuid
, &unique
, &nentries
,
363 if (newvlserver
== vltype_unknown
) {
364 if (code
== RXGEN_OPCODE
) {
367 newvlserver
= vltype_uuid
;
370 if (code
== VL_NOENT
)
378 if (nentries
> GETADDRUCACHESIZE
)
379 nentries
= GETADDRUCACHESIZE
; /* safety check; should not happen */
380 if (++cacheip_index
>= GETADDRUCACHESIZE
)
382 cacheips
[cacheip_index
].server
= serv1
;
383 cacheips
[cacheip_index
].count
= nentries
;
384 addrp
= addrs
.bulkaddrs_val
;
385 for (i
= 0; i
< nentries
; i
++, addrp
++) {
386 cacheips
[cacheip_index
].addrs
[i
] = *addrp
;
387 if (serv2
== *addrp
) {
395 Get the appropriate type of ubik client structure out from the system.
398 vsu_ClientInit(const char *confDir
, char *cellName
, int secFlags
,
399 int (*secproc
)(struct rx_securityClass
*, afs_int32
),
400 struct ubik_client
**uclientp
)
402 return ugen_ClientInitFlags(confDir
, cellName
, secFlags
, uclientp
,
403 secproc
, VLDB_MAXSERVERS
, AFSCONF_VLDBSERVICE
,
407 /*extract the name of volume <name> without readonly or backup suffixes
408 * and return the result as <rname>.
411 vsu_ExtractName(char rname
[], char name
[])
413 char sname
[VOLSER_OLDMAXVOLNAME
+ 1];
416 strncpy(sname
, name
, sizeof(sname
));
417 sname
[sizeof(sname
) - 1] = '\0';
418 total
= strlen(sname
);
419 if (!strcmp(&sname
[total
- 9], ".readonly")) {
420 /*discard the last 8 chars */
421 sname
[total
- 9] = '\0';
422 strcpy(rname
, sname
);
424 } else if (!strcmp(&sname
[total
- 7], ".backup")) {
425 /*discard last 6 chars */
426 sname
[total
- 7] = '\0';
427 strcpy(rname
, sname
);
430 strncpy(rname
, name
, VOLSER_OLDMAXVOLNAME
);
431 rname
[VOLSER_OLDMAXVOLNAME
] = '\0';
436 /* returns 0 if failed */
438 vsu_GetVolumeID(char *astring
, struct ubik_client
*acstruct
, afs_int32
*errp
)
440 char volname
[VOLSER_OLDMAXVOLNAME
+ 1];
441 struct nvldbentry entry
;
447 if (isdigit(astring
[0])) {
450 result
= strtoul(astring
, &end
, 10);
451 if (result
!= UINT_MAX
&& *end
== '\0')
455 /* It was not a volume number but something else */
456 total
= strlen(astring
);
457 vsu_ExtractName(volname
, astring
);
458 vcode
= VLDB_GetEntryByName(volname
, &entry
);
460 if ((total
>= 9) && (!strcmp(&astring
[total
- 9], ".readonly")))
461 return entry
.volumeId
[ROVOL
];
462 else if ((total
>= 7) && (!strcmp(&astring
[total
- 7], ".backup")))
463 return entry
.volumeId
[BACKVOL
];
465 return (entry
.volumeId
[RWVOL
]);
468 return 0; /* can't find volume */