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>
21 #include <sys/types.h>
24 #include <netinet/in.h>
25 #endif /* AFS_NT40_ENV */
28 #include <sys/statfs.h>
35 #include <rx/rx_globals.h>
37 #include <afs/vlserver.h>
38 #include <afs/cellconfig.h>
41 #include <afs/afsint.h>
48 #include "vsutils_prototypes.h"
50 struct ubik_client
*cstruct
;
51 static rxkad_level vsu_rxkad_level
= rxkad_clear
;
54 ovlentry_to_nvlentry(struct vldbentry
*oentryp
,
55 struct nvldbentry
*nentryp
)
59 memset(nentryp
, 0, sizeof(struct nvldbentry
));
60 strncpy(nentryp
->name
, oentryp
->name
, sizeof(nentryp
->name
));
61 for (i
= 0; i
< oentryp
->nServers
; i
++) {
62 nentryp
->serverNumber
[i
] = oentryp
->serverNumber
[i
];
63 nentryp
->serverPartition
[i
] = oentryp
->serverPartition
[i
];
64 nentryp
->serverFlags
[i
] = oentryp
->serverFlags
[i
];
66 nentryp
->nServers
= oentryp
->nServers
;
67 for (i
= 0; i
< MAXTYPES
; i
++)
68 nentryp
->volumeId
[i
] = oentryp
->volumeId
[i
];
69 nentryp
->cloneId
= oentryp
->cloneId
;
70 nentryp
->flags
= oentryp
->flags
;
74 nvlentry_to_ovlentry(struct nvldbentry
*nentryp
,
75 struct vldbentry
*oentryp
)
79 memset(oentryp
, 0, sizeof(struct vldbentry
));
80 strncpy(oentryp
->name
, nentryp
->name
, sizeof(oentryp
->name
));
81 if (nentryp
->nServers
> OMAXNSERVERS
) {
83 * The alternative is to store OMAXSERVERS but it's always better
84 * to know what's going on...
88 for (i
= 0; i
< nentryp
->nServers
; i
++) {
89 oentryp
->serverNumber
[i
] = nentryp
->serverNumber
[i
];
90 oentryp
->serverPartition
[i
] = nentryp
->serverPartition
[i
];
91 oentryp
->serverFlags
[i
] = nentryp
->serverFlags
[i
];
93 oentryp
->nServers
= i
;
94 for (i
= 0; i
< MAXTYPES
; i
++)
95 oentryp
->volumeId
[i
] = nentryp
->volumeId
[i
];
96 oentryp
->cloneId
= nentryp
->cloneId
;
97 oentryp
->flags
= nentryp
->flags
;
101 enum _vlserver_type
{
108 static enum _vlserver_type newvlserver
= vltype_unknown
;
111 VLDB_CreateEntry(struct nvldbentry
*entryp
)
113 struct vldbentry oentry
;
116 if (newvlserver
== vltype_old
) {
118 code
= nvlentry_to_ovlentry(entryp
, &oentry
);
121 code
= ubik_VL_CreateEntry(cstruct
, 0, &oentry
);
124 code
= ubik_VL_CreateEntryN(cstruct
, 0, entryp
);
125 if (newvlserver
== vltype_unknown
) {
126 if (code
== RXGEN_OPCODE
) {
127 newvlserver
= vltype_old
; /* Doesn't support new interface */
130 newvlserver
= vltype_new
;
137 VLDB_GetEntryByID(afs_uint32 volid
, afs_int32 voltype
, struct nvldbentry
*entryp
)
139 struct vldbentry oentry
;
142 if (newvlserver
== vltype_old
) {
145 ubik_VL_GetEntryByID(cstruct
, 0, volid
, voltype
, &oentry
);
147 ovlentry_to_nvlentry(&oentry
, entryp
);
150 code
= ubik_VL_GetEntryByIDN(cstruct
, 0, volid
, voltype
, entryp
);
151 if (newvlserver
== vltype_unknown
) {
152 if (code
== RXGEN_OPCODE
) {
153 newvlserver
= vltype_old
; /* Doesn't support new interface */
156 newvlserver
= vltype_new
;
163 VLDB_GetEntryByName(char *namep
, struct nvldbentry
*entryp
)
165 struct vldbentry oentry
;
168 if (newvlserver
== vltype_old
) {
170 code
= ubik_VL_GetEntryByNameO(cstruct
, 0, namep
, &oentry
);
172 ovlentry_to_nvlentry(&oentry
, entryp
);
175 code
= ubik_VL_GetEntryByNameN(cstruct
, 0, namep
, entryp
);
176 if (newvlserver
== vltype_unknown
) {
177 if (code
== RXGEN_OPCODE
) {
178 newvlserver
= vltype_old
; /* Doesn't support new interface */
181 newvlserver
= vltype_new
;
188 VLDB_ReplaceEntry(afs_uint32 volid
, afs_int32 voltype
, struct nvldbentry
*entryp
, afs_int32 releasetype
)
190 struct vldbentry oentry
;
193 if (newvlserver
== vltype_old
) {
195 code
= nvlentry_to_ovlentry(entryp
, &oentry
);
199 ubik_VL_ReplaceEntry(cstruct
, 0, volid
, voltype
, &oentry
,
204 ubik_VL_ReplaceEntryN(cstruct
, 0, volid
, voltype
, entryp
,
206 if (newvlserver
== vltype_unknown
) {
207 if (code
== RXGEN_OPCODE
) {
208 newvlserver
= vltype_old
; /* Doesn't support new interface */
211 newvlserver
= vltype_new
;
218 convertBulkToNBulk(bulkentries
*bulk
, nbulkentries
*nbulk
) {
221 if (bulk
->bulkentries_len
== 0)
224 nbulk
->nbulkentries_len
= bulk
->bulkentries_len
;
225 nbulk
->nbulkentries_val
=
226 xdr_alloc(bulk
->bulkentries_len
* sizeof(struct nvldbentry
));
228 for (i
= 0; i
< bulk
->bulkentries_len
; i
++) {
229 ovlentry_to_nvlentry(&bulk
->bulkentries_val
[i
],
230 &nbulk
->nbulkentries_val
[i
]);
235 VLDB_ListAttributes(VldbListByAttributes
*attrp
,
237 nbulkentries
*blkentriesp
)
239 bulkentries arrayEntries
;
242 if (newvlserver
== vltype_old
) {
244 memset(&arrayEntries
, 0, sizeof(arrayEntries
));
246 ubik_VL_ListAttributes(cstruct
, 0, attrp
, entriesp
,
252 /* Ensure the number of entries claimed matches the no. returned */
255 if (*entriesp
> arrayEntries
.bulkentries_len
)
256 *entriesp
= arrayEntries
.bulkentries_len
;
258 convertBulkToNBulk(&arrayEntries
, blkentriesp
);
260 xdr_free((xdrproc_t
) xdr_bulkentries
, &arrayEntries
);
264 ubik_VL_ListAttributesN(cstruct
, 0, attrp
, entriesp
, blkentriesp
);
265 if (newvlserver
== vltype_unknown
) {
266 if (code
== RXGEN_OPCODE
) {
267 newvlserver
= vltype_old
; /* Doesn't support new interface */
270 newvlserver
= vltype_new
;
277 /* Ensure the number of entries claimed matches the no. returned */
280 if (*entriesp
> blkentriesp
->nbulkentries_len
)
281 *entriesp
= blkentriesp
->nbulkentries_len
;
287 VLDB_ListAttributesN2(VldbListByAttributes
*attrp
,
290 afs_int32
*nentriesp
,
291 nbulkentries
*blkentriesp
,
292 afs_int32
*nextindexp
)
294 afs_int32 code
= RXGEN_OPCODE
;
296 if (newvlserver
!= vltype_old
) {
298 ubik_VL_ListAttributesN2(cstruct
, 0, attrp
, (name
? name
: ""),
299 thisindex
, nentriesp
, blkentriesp
, nextindexp
);
303 /* Ensure the number of entries claimed matches the no. returned */
306 if (*nentriesp
> blkentriesp
->nbulkentries_len
)
307 *nentriesp
= blkentriesp
->nbulkentries_len
;
315 afs_uint32 addrs
[16];
318 * Increase cache size. This avoids high CPU usage by the vlserver
319 * in environments where there are more than 16 fileservers in the
322 #define GETADDRUCACHESIZE 64
323 struct cacheips cacheips
[GETADDRUCACHESIZE
];
324 int cacheip_index
= 0;
327 VLDB_IsSameAddrs(afs_uint32 serv1
, afs_uint32 serv2
, afs_int32
*errorp
)
330 ListAddrByAttributes attrs
;
332 afs_uint32
*addrp
, i
, j
, f1
, f2
;
333 afs_int32 unique
, nentries
;
335 static int initcache
= 0;
341 if (newvlserver
== vltype_old
|| newvlserver
== vltype_new
) {
345 for (i
= 0; i
< GETADDRUCACHESIZE
; i
++) {
346 cacheips
[i
].server
= cacheips
[i
].count
= 0;
351 /* See if it's cached */
352 for (i
= 0; i
< GETADDRUCACHESIZE
; i
++) {
354 for (j
= 0; j
< cacheips
[i
].count
; j
++) {
355 if (serv1
== cacheips
[i
].addrs
[j
])
357 else if (serv2
== cacheips
[i
].addrs
[j
])
365 if (cacheips
[i
].server
== serv1
)
369 memset(&attrs
, 0, sizeof(attrs
));
370 attrs
.Mask
= VLADDR_IPADDR
;
371 attrs
.ipaddr
= serv1
;
372 memset(&addrs
, 0, sizeof(addrs
));
373 memset(&uuid
, 0, sizeof(uuid
));
375 ubik_VL_GetAddrsU(cstruct
, 0, &attrs
, &uuid
, &unique
, &nentries
,
377 if (newvlserver
== vltype_unknown
) {
378 if (code
== RXGEN_OPCODE
) {
381 newvlserver
= vltype_uuid
;
384 if (code
== VL_NOENT
)
392 if (nentries
> GETADDRUCACHESIZE
)
393 nentries
= GETADDRUCACHESIZE
; /* safety check; should not happen */
394 if (++cacheip_index
>= GETADDRUCACHESIZE
)
396 cacheips
[cacheip_index
].server
= serv1
;
397 cacheips
[cacheip_index
].count
= nentries
;
398 addrp
= addrs
.bulkaddrs_val
;
399 for (i
= 0; i
< nentries
; i
++, addrp
++) {
400 cacheips
[cacheip_index
].addrs
[i
] = *addrp
;
401 if (serv2
== *addrp
) {
410 Set encryption. If 'cryptflag' is nonzero, encrpytion is turned on
411 for authenticated connections; if zero, encryption is turned off.
412 Calling this function always results in a level of at least rxkad_auth;
413 to get a rxkad_clear connection, simply don't call this.
416 vsu_SetCrypt(int cryptflag
)
419 vsu_rxkad_level
= rxkad_crypt
;
421 vsu_rxkad_level
= rxkad_auth
;
427 Get the appropriate type of ubik client structure out from the system.
430 vsu_ClientInit(int noAuthFlag
, const char *confDir
, char *cellName
, afs_int32 sauth
,
431 struct ubik_client
**uclientp
,
432 int (*secproc
)(struct rx_securityClass
*, afs_int32
))
434 return ugen_ClientInit(noAuthFlag
, confDir
, cellName
, sauth
, uclientp
,
435 secproc
, "vsu_ClientInit", vsu_rxkad_level
,
436 VLDB_MAXSERVERS
, AFSCONF_VLDBSERVICE
, 90,
437 0, 0, USER_SERVICE_ID
);
441 /*extract the name of volume <name> without readonly or backup suffixes
442 * and return the result as <rname>.
445 vsu_ExtractName(char rname
[], char name
[])
447 char sname
[VOLSER_OLDMAXVOLNAME
+ 1];
450 strncpy(sname
, name
, sizeof(sname
));
451 sname
[sizeof(sname
) - 1] = '\0';
452 total
= strlen(sname
);
453 if (!strcmp(&sname
[total
- 9], ".readonly")) {
454 /*discard the last 8 chars */
455 sname
[total
- 9] = '\0';
456 strcpy(rname
, sname
);
458 } else if (!strcmp(&sname
[total
- 7], ".backup")) {
459 /*discard last 6 chars */
460 sname
[total
- 7] = '\0';
461 strcpy(rname
, sname
);
464 strncpy(rname
, name
, VOLSER_OLDMAXVOLNAME
);
465 rname
[VOLSER_OLDMAXVOLNAME
] = '\0';
470 /* returns 0 if failed */
472 vsu_GetVolumeID(char *astring
, struct ubik_client
*acstruct
, afs_int32
*errp
)
474 char volname
[VOLSER_OLDMAXVOLNAME
+ 1];
475 struct nvldbentry entry
;
481 if (isdigit(astring
[0])) {
484 result
= strtoul(astring
, &end
, 10);
485 if (result
!= UINT_MAX
&& *end
== '\0')
489 /* It was not a volume number but something else */
490 total
= strlen(astring
);
491 vsu_ExtractName(volname
, astring
);
492 vcode
= VLDB_GetEntryByName(volname
, &entry
);
494 if ((total
>= 9) && (!strcmp(&astring
[total
- 9], ".readonly")))
495 return entry
.volumeId
[ROVOL
];
496 else if ((total
>= 7) && (!strcmp(&astring
[total
- 7], ".backup")))
497 return entry
.volumeId
[BACKVOL
];
499 return (entry
.volumeId
[RWVOL
]);
502 return 0; /* can't find volume */