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>
16 #include <sys/types.h>
20 #include <afs/afsutil.h>
27 #include <netinet/in.h>
31 #include "afs/audit.h"
35 #ifdef HAVE_POSIX_REGEX /* use POSIX regexp library */
41 extern struct afsconf_dir *vldb_confdir;
42 extern struct ubik_dbase *VL_dbase;
43 struct vlheader cheader; /* kept in network byte order */
44 extern afs_uint32 HostAddress[]; /* host addresses kept in host byte order */
46 struct extentaddr *ex_addr[VL_MAX_ADDREXTBLKS] = { 0, 0, 0, 0 };
47 static char rxinfo_str[128]; /* Need rxinfo string to be non-local */
48 #define ABORT(c) { errorcode = (c); goto abort; }
50 #define END(c) { errorcode = (c); goto end; }
52 #define VLDBALLOCLIMIT 10000
53 #define VLDBALLOCINCR 2048
55 static int put_attributeentry();
56 static int put_nattributeentry();
57 static int RemoveEntry();
58 static void ReleaseEntry();
59 static int check_vldbentry();
60 static int check_nvldbentry();
61 static int vldbentry_to_vlentry();
62 static int nvldbentry_to_vlentry();
63 static get_vldbupdateentry();
64 static int repsite_exists();
65 static void repsite_compress();
66 static void vlentry_to_vldbentry();
67 static void vlentry_to_nvldbentry();
68 static void vlentry_to_uvldbentry();
69 static int InvalidVolname();
70 static int InvalidVoltype();
71 static int InvalidOperation();
72 static int InvalidReleasetype();
73 static int IpAddrToRelAddr();
74 static int ChangeIPAddr();
78 struct rx_call *rxcall;
81 register struct rx_connection *tconn;
86 struct in_addr hostAddr;
88 tconn = rx_ConnectionOf(rxcall);
89 hostAddr.s_addr = rx_HostOf(rx_PeerOf(tconn));
91 rxkad_GetServerInfo(rxcall->conn, NULL, &exp, tname, tinst, tcell,
94 sprintf(rxinfo_str, "%s %s%s%s%s%s", inet_ntoa(hostAddr), tname,
95 tinst?".":"", tinst?tinst:"", tcell?"@":"", tcell?tcell:"");
97 sprintf(rxinfo_str, "%s noauth", inet_ntoa(hostAddr));
101 /* This is called to initialize the database, set the appropriate locks and make sure that the vldb header is valid */
103 Init_VLdbase(trans, locktype, this_op)
104 struct ubik_trans **trans;
105 int locktype; /* indicate read or write transaction */
108 int errorcode = 0, pass, wl;
110 for (pass = 1; pass <= 3; pass++) {
111 if (pass == 2) { /* take write lock to rebuild the db */
112 errorcode = ubik_BeginTrans(VL_dbase, UBIK_WRITETRANS, trans);
114 } else if (locktype == LOCKREAD) {
116 ubik_BeginTransReadAny(VL_dbase, UBIK_READTRANS, trans);
119 errorcode = ubik_BeginTrans(VL_dbase, UBIK_WRITETRANS, trans);
125 errorcode = ubik_SetLock(*trans, 1, 1, locktype);
128 ubik_AbortTrans(*trans);
132 /* check that dbase is initialized and setup cheader */
133 /* 2nd pass we try to rebuild the header */
134 errorcode = CheckInit(*trans, ((pass == 2) ? 1 : 0));
135 if (!errorcode && wl && extent_mod)
136 errorcode = readExtents(*trans); /* Fix the mh extent blocks */
139 ubik_AbortTrans(*trans);
140 /* Only rebuld if the database is empty */
141 /* Exit if can't rebuild */
142 if ((pass == 1) && (errorcode != VL_EMPTY))
146 } else { /* No errorcode */
148 ubik_EndTrans(*trans); /* Rebuilt db. End trans, then retake original lock */
150 break; /* didn't rebuild and successful - exit */
158 /* Create a new vldb entry; both new volume id and name must be unique (non-existant in vldb). */
161 SVL_CreateEntry(rxcall, newentry)
162 struct rx_call *rxcall;
163 struct vldbentry *newentry;
165 struct ubik_trans *trans;
166 afs_int32 errorcode, blockindex;
167 struct nvlentry tentry;
169 COUNT_REQ(VLCREATEENTRY);
170 if (!afsconf_SuperUser(vldb_confdir, rxcall, NULL)) {
175 /* Do some validity tests on new entry */
176 if ((errorcode = check_vldbentry(newentry))
177 || (errorcode = Init_VLdbase(&trans, LOCKWRITE, this_op)))
181 ("OCreate Volume %d %s\n", newentry->volumeId[RWVOL],
183 /* XXX shouldn't we check to see if the r/o volume is duplicated? */
184 if (newentry->volumeId[RWVOL]
185 && FindByID(trans, newentry->volumeId[RWVOL], RWVOL, &tentry, &errorcode)) { /* entry already exists, we fail */
186 errorcode = VL_IDEXIST;
188 } else if (errorcode) {
192 /* Is this following check (by volume name) necessary?? */
193 /* If entry already exists, we fail */
194 if (FindByName(trans, newentry->name, &tentry, &errorcode)) {
195 errorcode = VL_NAMEEXIST;
197 } else if (errorcode) {
201 blockindex = AllocBlock(trans, &tentry);
202 if (blockindex == 0) {
203 errorcode = VL_CREATEFAIL;
207 memset(&tentry, 0, sizeof(struct nvlentry));
208 /* Convert to its internal representation; both in host byte order */
209 if (errorcode = vldbentry_to_vlentry(trans, newentry, &tentry)) {
210 FreeBlock(trans, blockindex);
214 /* Actually insert the entry in vldb */
215 errorcode = ThreadVLentry(trans, blockindex, &tentry);
217 FreeBlock(trans, blockindex);
220 errorcode = ubik_EndTrans(trans);
226 ubik_AbortTrans(trans);
229 osi_auditU(rxcall, VLCreateEntryEvent, errorcode, AUD_STR,
230 (newentry ? newentry->name : NULL), AUD_END);
236 SVL_CreateEntryN(rxcall, newentry)
237 struct rx_call *rxcall;
238 struct nvldbentry *newentry;
240 struct ubik_trans *trans;
241 afs_int32 errorcode, blockindex;
242 struct nvlentry tentry;
244 COUNT_REQ(VLCREATEENTRYN);
245 if (!afsconf_SuperUser(vldb_confdir, rxcall, NULL)) {
250 /* Do some validity tests on new entry */
251 if ((errorcode = check_nvldbentry(newentry))
252 || (errorcode = Init_VLdbase(&trans, LOCKWRITE, this_op)))
256 ("Create Volume %d %s\n", newentry->volumeId[RWVOL],
258 /* XXX shouldn't we check to see if the r/o volume is duplicated? */
259 if (newentry->volumeId[RWVOL]
260 && FindByID(trans, newentry->volumeId[RWVOL], RWVOL, &tentry, &errorcode)) { /* entry already exists, we fail */
261 errorcode = VL_IDEXIST;
263 } else if (errorcode) {
267 /* Is this following check (by volume name) necessary?? */
268 /* If entry already exists, we fail */
269 if (FindByName(trans, newentry->name, &tentry, &errorcode)) {
270 errorcode = VL_NAMEEXIST;
272 } else if (errorcode) {
276 blockindex = AllocBlock(trans, &tentry);
277 if (blockindex == 0) {
278 errorcode = VL_CREATEFAIL;
282 memset(&tentry, 0, sizeof(struct nvlentry));
283 /* Convert to its internal representation; both in host byte order */
284 if (errorcode = nvldbentry_to_vlentry(trans, newentry, &tentry)) {
285 FreeBlock(trans, blockindex);
289 /* Actually insert the entry in vldb */
290 errorcode = ThreadVLentry(trans, blockindex, &tentry);
292 FreeBlock(trans, blockindex);
295 errorcode = ubik_EndTrans(trans);
301 ubik_AbortTrans(trans);
304 osi_auditU(rxcall, VLCreateEntryEvent, errorcode, AUD_STR,
305 (newentry ? newentry->name : NULL), AUD_END);
311 SVL_ChangeAddr(rxcall, ip1, ip2)
312 struct rx_call *rxcall;
315 struct ubik_trans *trans;
318 COUNT_REQ(VLCHANGEADDR);
319 if (!afsconf_SuperUser(vldb_confdir, rxcall, NULL)) {
324 if (errorcode = Init_VLdbase(&trans, LOCKWRITE, this_op))
327 VLog(1, ("Change Addr %d -> %d %s\n", ip1, ip2, rxinfo(rxcall)));
328 if (errorcode = ChangeIPAddr(ip1, ip2, trans))
331 errorcode = ubik_EndTrans(trans);
337 ubik_AbortTrans(trans);
340 osi_auditU(rxcall, VLChangeAddrEvent, errorcode, AUD_LONG, ip1, AUD_LONG,
345 /* Delete a vldb entry given the volume id. */
347 SVL_DeleteEntry(rxcall, volid, voltype)
348 struct rx_call *rxcall;
352 struct ubik_trans *trans;
353 afs_int32 blockindex, errorcode;
354 struct nvlentry tentry;
356 COUNT_REQ(VLDELETEENTRY);
357 if (!afsconf_SuperUser(vldb_confdir, rxcall, NULL))
360 if ((voltype != -1) && (InvalidVoltype(voltype)))
363 if (errorcode = Init_VLdbase(&trans, LOCKWRITE, this_op))
366 VLog(1, ("Delete Volume %d %s\n", volid, rxinfo(rxcall)));
367 blockindex = FindByID(trans, volid, voltype, &tentry, &errorcode);
368 if (blockindex == 0) { /* volid not found */
370 errorcode = VL_NOENT;
374 if (tentry.flags & VLDELETED) { /* Already deleted; return */
375 ABORT(VL_ENTDELETED);
377 if (errorcode = RemoveEntry(trans, blockindex, &tentry)) {
380 errorcode = (ubik_EndTrans(trans));
385 ubik_AbortTrans(trans);
388 osi_auditU(rxcall, VLDeleteEntryEvent, errorcode, AUD_LONG, volid,
394 /* Get a vldb entry given its volume id; make sure it's not a deleted entry. */
395 GetEntryByID(rxcall, volid, voltype, aentry, new, this_op)
396 struct rx_call *rxcall;
398 afs_int32 voltype, new, this_op;
399 char *aentry; /* entry data copied here */
401 struct ubik_trans *trans;
402 afs_int32 blockindex, errorcode;
403 struct nvlentry tentry;
405 if ((voltype != -1) && (InvalidVoltype(voltype)))
406 return VL_BADVOLTYPE;
407 if (errorcode = Init_VLdbase(&trans, LOCKREAD, this_op))
410 VLog(5, ("GetVolumeByID %d (%d) %s\n", volid, new, rxinfo(rxcall)));
411 blockindex = FindByID(trans, volid, voltype, &tentry, &errorcode);
412 if (blockindex == 0) { /* entry not found */
414 errorcode = VL_NOENT;
416 ubik_AbortTrans(trans);
419 if (tentry.flags & VLDELETED) { /* Entry is deleted! */
421 ubik_AbortTrans(trans);
422 return VL_ENTDELETED;
424 /* Convert from the internal to external form */
426 vlentry_to_nvldbentry(&tentry, (struct nvldbentry *)aentry);
428 vlentry_to_uvldbentry(&tentry, (struct uvldbentry *)aentry);
430 vlentry_to_vldbentry(&tentry, (struct vldbentry *)aentry);
431 return (ubik_EndTrans(trans));
435 SVL_GetEntryByID(rxcall, volid, voltype, aentry)
436 struct rx_call *rxcall;
437 afs_int32 volid, voltype;
438 vldbentry *aentry; /* entry data copied here */
440 COUNT_REQ(VLGETENTRYBYID);
441 return (GetEntryByID(rxcall, volid, voltype, (char *)aentry, 0, this_op));
445 SVL_GetEntryByIDN(rxcall, volid, voltype, aentry)
446 struct rx_call *rxcall;
447 afs_int32 volid, voltype;
448 nvldbentry *aentry; /* entry data copied here */
450 COUNT_REQ(VLGETENTRYBYIDN);
451 return (GetEntryByID(rxcall, volid, voltype, (char *)aentry, 1, this_op));
455 SVL_GetEntryByIDU(rxcall, volid, voltype, aentry)
456 struct rx_call *rxcall;
457 afs_int32 volid, voltype;
458 uvldbentry *aentry; /* entry data copied here */
460 COUNT_REQ(VLGETENTRYBYIDU);
461 return (GetEntryByID(rxcall, volid, voltype, (char *)aentry, 2, this_op));
466 /* returns true if the id is a decimal integer, in which case we interpret it
467 as an id. make the cache manager much simpler */
470 register char *aname;
473 while (tc = *aname++) {
474 if (tc > '9' || tc < '0')
480 /* Get a vldb entry given the volume's name; of course, very similar to VLGetEntryByID() above. */
481 GetEntryByName(rxcall, volname, aentry, new, this_op)
482 struct rx_call *rxcall;
484 char *aentry; /* entry data copied here */
487 struct ubik_trans *trans;
488 afs_int32 blockindex, errorcode;
489 struct nvlentry tentry;
491 if (NameIsId(volname)) {
492 return GetEntryByID(rxcall, atoi(volname), -1, aentry, new, this_op);
494 if (InvalidVolname(volname))
496 if (errorcode = Init_VLdbase(&trans, LOCKREAD, this_op))
498 VLog(5, ("GetVolumeByName %s (%d) %s\n", volname, new, rxinfo(rxcall)));
499 blockindex = FindByName(trans, volname, &tentry, &errorcode);
500 if (blockindex == 0) { /* entry not found */
502 errorcode = VL_NOENT;
504 ubik_AbortTrans(trans);
507 if (tentry.flags & VLDELETED) { /* Entry is deleted */
509 ubik_AbortTrans(trans);
510 return VL_ENTDELETED;
512 /* Convert to external entry representation */
514 vlentry_to_nvldbentry(&tentry, (struct nvldbentry *)aentry);
516 vlentry_to_uvldbentry(&tentry, (struct uvldbentry *)aentry);
518 vlentry_to_vldbentry(&tentry, (struct vldbentry *)aentry);
519 return (ubik_EndTrans(trans));
523 SVL_GetEntryByNameO(rxcall, volname, aentry)
524 struct rx_call *rxcall;
526 struct vldbentry *aentry; /* entry data copied here */
528 COUNT_REQ(VLGETENTRYBYNAME);
529 return (GetEntryByName(rxcall, volname, (char *)aentry, 0, this_op));
534 SVL_GetEntryByNameN(rxcall, volname, aentry)
535 struct rx_call *rxcall;
537 struct nvldbentry *aentry; /* entry data copied here */
539 COUNT_REQ(VLGETENTRYBYNAMEN);
540 return (GetEntryByName(rxcall, volname, (char *)aentry, 1, this_op));
544 SVL_GetEntryByNameU(rxcall, volname, aentry)
545 struct rx_call *rxcall;
547 struct uvldbentry *aentry; /* entry data copied here */
549 COUNT_REQ(VLGETENTRYBYNAMEU);
550 return (GetEntryByName(rxcall, volname, (char *)aentry, 2, this_op));
555 /* Get the current value of the maximum volume id and bump the volume id counter by Maxvolidbump. */
557 SVL_GetNewVolumeId(rxcall, Maxvolidbump, newvolumeid)
558 struct rx_call *rxcall;
559 afs_int32 Maxvolidbump;
560 afs_int32 *newvolumeid;
562 register afs_int32 errorcode, maxvolumeid;
563 struct ubik_trans *trans;
565 COUNT_REQ(VLGETNEWVOLUMEID);
566 if (!afsconf_SuperUser(vldb_confdir, rxcall, NULL))
569 if (Maxvolidbump < 0 || Maxvolidbump > MAXBUMPCOUNT)
570 END(VL_BADVOLIDBUMP);
572 if (errorcode = Init_VLdbase(&trans, LOCKWRITE, this_op))
575 *newvolumeid = maxvolumeid = ntohl(cheader.vital_header.MaxVolumeId);
576 maxvolumeid += Maxvolidbump;
577 VLog(1, ("GetNewVolid newmax=%d %s\n", maxvolumeid, rxinfo(rxcall)));
578 cheader.vital_header.MaxVolumeId = htonl(maxvolumeid);
579 if (write_vital_vlheader(trans)) {
582 errorcode = (ubik_EndTrans(trans));
587 ubik_AbortTrans(trans);
590 osi_auditU(rxcall, VLGetNewVolumeIdEvent, errorcode, AUD_END);
595 /* Simple replace the contents of the vldb entry, volid, with
596 * newentry. No individual checking/updating per field (alike
597 * VLUpdateEntry) is done. */
600 SVL_ReplaceEntry(rxcall, volid, voltype, newentry, releasetype)
601 struct rx_call *rxcall;
604 struct vldbentry *newentry;
605 afs_int32 releasetype;
607 struct ubik_trans *trans;
608 afs_int32 blockindex, errorcode, typeindex;
610 int hashVol[MAXTYPES];
611 struct nvlentry tentry;
613 COUNT_REQ(VLREPLACEENTRY);
614 for (typeindex = 0; typeindex < MAXTYPES; typeindex++)
615 hashVol[typeindex] = 0;
617 if (!afsconf_SuperUser(vldb_confdir, rxcall, NULL))
620 if (errorcode = check_vldbentry(newentry))
623 if (voltype != -1 && InvalidVoltype(voltype))
626 if (releasetype && InvalidReleasetype(releasetype))
627 END(VL_BADRELLOCKTYPE);
628 if (errorcode = Init_VLdbase(&trans, LOCKWRITE, this_op))
631 VLog(1, ("OReplace Volume %d %s\n", volid, rxinfo(rxcall)));
632 /* find vlentry we're changing */
633 blockindex = FindByID(trans, volid, voltype, &tentry, &errorcode);
634 if (blockindex == 0) { /* entry not found */
636 errorcode = VL_NOENT;
640 /* check that we're not trying to change the RW vol ID */
641 if (newentry->volumeId[RWVOL] != tentry.volumeId[RWVOL]) {
645 /* unhash volid entries if they're disappearing or changing.
646 * Remember if we need to hash in the new value (we don't have to
647 * rehash if volid stays same */
648 for (typeindex = ROVOL; typeindex <= BACKVOL; typeindex++) {
649 if (tentry.volumeId[typeindex] != newentry->volumeId[typeindex]) {
650 if (tentry.volumeId[typeindex])
652 UnhashVolid(trans, typeindex, blockindex, &tentry)) {
655 /* we must rehash new id if the id is different and the ID is nonzero */
656 hashVol[typeindex] = 1; /* must rehash this guy if he exists */
660 /* Rehash volname if it changes */
661 if (strcmp(newentry->name, tentry.name)) { /* Name changes; redo hashing */
662 if (errorcode = UnhashVolname(trans, blockindex, &tentry)) {
668 /* after this, tentry is new entry, not old one. vldbentry_to_vlentry
669 * doesn't touch hash chains */
670 if (errorcode = vldbentry_to_vlentry(trans, newentry, &tentry)) {
674 for (typeindex = ROVOL; typeindex <= BACKVOL; typeindex++) {
675 if (hashVol[typeindex] && tentry.volumeId[typeindex]) {
676 if (errorcode = HashVolid(trans, typeindex, blockindex, &tentry)) {
683 HashVolname(trans, blockindex, &tentry);
686 ReleaseEntry(&tentry, releasetype); /* Unlock entry if necessary */
687 if (vlentrywrite(trans, blockindex, &tentry, sizeof(tentry))) {
691 END(ubik_EndTrans(trans));
695 ubik_AbortTrans(trans);
698 osi_auditU(rxcall, VLReplaceVLEntryEvent, errorcode, AUD_LONG, volid,
704 SVL_ReplaceEntryN(rxcall, volid, voltype, newentry, releasetype)
705 struct rx_call *rxcall;
708 struct nvldbentry *newentry;
709 afs_int32 releasetype;
711 struct ubik_trans *trans;
712 afs_int32 blockindex, errorcode, typeindex;
714 int hashVol[MAXTYPES];
715 struct nvlentry tentry;
717 COUNT_REQ(VLREPLACEENTRYN);
718 for (typeindex = 0; typeindex < MAXTYPES; typeindex++)
719 hashVol[typeindex] = 0;
721 if (!afsconf_SuperUser(vldb_confdir, rxcall, NULL))
724 if (errorcode = check_nvldbentry(newentry))
727 if (voltype != -1 && InvalidVoltype(voltype))
730 if (releasetype && InvalidReleasetype(releasetype))
731 END(VL_BADRELLOCKTYPE);
732 if (errorcode = Init_VLdbase(&trans, LOCKWRITE, this_op))
735 VLog(1, ("Replace Volume %d %s\n", volid, rxinfo(rxcall)));
736 /* find vlentry we're changing */
737 blockindex = FindByID(trans, volid, voltype, &tentry, &errorcode);
738 if (blockindex == 0) { /* entry not found */
740 errorcode = VL_NOENT;
744 /* check that we're not trying to change the RW vol ID */
745 if (newentry->volumeId[RWVOL] != tentry.volumeId[RWVOL]) {
749 /* unhash volid entries if they're disappearing or changing.
750 * Remember if we need to hash in the new value (we don't have to
751 * rehash if volid stays same */
752 for (typeindex = ROVOL; typeindex <= BACKVOL; typeindex++) {
753 if (tentry.volumeId[typeindex] != newentry->volumeId[typeindex]) {
754 if (tentry.volumeId[typeindex])
756 UnhashVolid(trans, typeindex, blockindex, &tentry)) {
759 /* we must rehash new id if the id is different and the ID is nonzero */
760 hashVol[typeindex] = 1; /* must rehash this guy if he exists */
764 /* Rehash volname if it changes */
765 if (strcmp(newentry->name, tentry.name)) { /* Name changes; redo hashing */
766 if (errorcode = UnhashVolname(trans, blockindex, &tentry)) {
772 /* after this, tentry is new entry, not old one. vldbentry_to_vlentry
773 * doesn't touch hash chains */
774 if (errorcode = nvldbentry_to_vlentry(trans, newentry, &tentry)) {
778 for (typeindex = ROVOL; typeindex <= BACKVOL; typeindex++) {
779 if (hashVol[typeindex] && tentry.volumeId[typeindex]) {
780 if (errorcode = HashVolid(trans, typeindex, blockindex, &tentry)) {
787 HashVolname(trans, blockindex, &tentry);
790 ReleaseEntry(&tentry, releasetype); /* Unlock entry if necessary */
791 if (vlentrywrite(trans, blockindex, &tentry, sizeof(tentry))) {
795 END(ubik_EndTrans(trans));
799 ubik_AbortTrans(trans);
802 osi_auditU(rxcall, VLReplaceVLEntryEvent, errorcode, AUD_LONG, volid,
808 /* Update a vldb entry (accessed thru its volume id). Almost all of the entry's fields can be modified in a single call by setting the appropriate bits in the Mask field in VldbUpdateentry. */
809 /* this routine may never have been tested; use replace entry instead unless you're brave */
811 SVL_UpdateEntry(rxcall, volid, voltype, updateentry, releasetype)
812 struct rx_call *rxcall;
815 afs_int32 releasetype;
816 struct VldbUpdateEntry *updateentry; /* Update entry copied here */
818 struct ubik_trans *trans;
819 afs_int32 blockindex, errorcode;
820 struct nvlentry tentry;
822 COUNT_REQ(VLUPDATEENTRY);
823 if (!afsconf_SuperUser(vldb_confdir, rxcall, NULL))
825 if ((voltype != -1) && (InvalidVoltype(voltype)))
827 if (releasetype && InvalidReleasetype(releasetype))
828 END(VL_BADRELLOCKTYPE);
829 if (errorcode = Init_VLdbase(&trans, LOCKWRITE, this_op))
832 VLog(1, ("Update Volume %d %s\n", volid, rxinfo(rxcall)));
833 blockindex = FindByID(trans, volid, voltype, &tentry, &errorcode);
834 if (blockindex == 0) { /* entry not found */
836 errorcode = VL_NOENT;
840 /* Do the actual updating of the entry, tentry. */
842 get_vldbupdateentry(trans, blockindex, updateentry, &tentry)) {
846 ReleaseEntry(&tentry, releasetype); /* Unlock entry if necessary */
847 if (vlentrywrite(trans, blockindex, &tentry, sizeof(tentry))) {
850 END(ubik_EndTrans(trans));
854 ubik_AbortTrans(trans);
857 osi_auditU(rxcall, VLUpdateEntryEvent, errorcode, AUD_LONG, volid,
864 SVL_UpdateEntryByName(rxcall, volname, updateentry, releasetype)
865 struct rx_call *rxcall;
867 afs_int32 releasetype;
868 struct VldbUpdateEntry *updateentry; /* Update entry copied here */
870 struct ubik_trans *trans;
871 afs_int32 blockindex, errorcode;
872 struct nvlentry tentry;
874 COUNT_REQ(VLUPDATEENTRYBYNAME);
875 if (!afsconf_SuperUser(vldb_confdir, rxcall, NULL))
877 if (releasetype && InvalidReleasetype(releasetype))
878 END(VL_BADRELLOCKTYPE);
879 if (errorcode = Init_VLdbase(&trans, LOCKWRITE, this_op))
882 blockindex = FindByName(trans, volname, &tentry, &errorcode);
883 if (blockindex == 0) { /* entry not found */
885 errorcode = VL_NOENT;
889 /* Do the actual updating of the entry, tentry. */
891 get_vldbupdateentry(trans, blockindex, updateentry, &tentry)) {
895 ReleaseEntry(&tentry, releasetype); /* Unlock entry if necessary */
896 if (vlentrywrite(trans, blockindex, &tentry, sizeof(tentry))) {
899 END(ubik_EndTrans(trans));
903 ubik_AbortTrans(trans);
906 osi_auditU(rxcall, VLUpdateEntryEvent, errorcode, AUD_LONG, -1, AUD_END);
911 /* Set a lock to the vldb entry for volid (of type voltype if not -1). */
913 SVL_SetLock(rxcall, volid, voltype, voloper)
914 struct rx_call *rxcall;
919 afs_int32 timestamp, blockindex, errorcode;
920 struct ubik_trans *trans;
921 struct nvlentry tentry;
923 COUNT_REQ(VLSETLOCK);
924 if (!afsconf_SuperUser(vldb_confdir, rxcall, NULL))
926 if ((voltype != -1) && (InvalidVoltype(voltype)))
928 if (InvalidOperation(voloper))
930 if (errorcode = Init_VLdbase(&trans, LOCKWRITE, this_op))
933 VLog(1, ("SetLock Volume %d %s\n", volid, rxinfo(rxcall)));
934 blockindex = FindByID(trans, volid, voltype, &tentry, &errorcode);
935 if (blockindex == NULLO) {
937 errorcode = VL_NOENT;
940 if (tentry.flags & VLDELETED) {
941 ABORT(VL_ENTDELETED);
943 timestamp = FT_ApproxTime();
945 /* Check if entry is already locked; note that we unlock any entry
946 * locked more than MAXLOCKTIME seconds */
947 if ((tentry.LockTimestamp)
948 && ((timestamp - tentry.LockTimestamp) < MAXLOCKTIME)) {
949 ABORT(VL_ENTRYLOCKED);
952 /* Consider it an unlocked entry: set current timestamp, caller
953 * and active vol operation */
954 tentry.LockTimestamp = timestamp;
955 tentry.LockAfsId = 0; /* Not implemented yet */
956 if (tentry.flags & VLOP_RELEASE) {
959 tentry.flags &= ~VLOP_ALLOPERS; /* Clear any possible older operation bit */
960 tentry.flags |= voloper;
962 if (vlentrywrite(trans, blockindex, &tentry, sizeof(tentry))) {
965 END(ubik_EndTrans(trans));
969 ubik_AbortTrans(trans);
972 osi_auditU(rxcall, VLSetLockEvent, errorcode, AUD_LONG, volid, AUD_END);
977 /* Release an already locked vldb entry. Releasetype determines what
978 * fields (afsid and/or volume operation) will be cleared along with
979 * the lock time stamp. */
982 SVL_ReleaseLock(rxcall, volid, voltype, releasetype)
983 struct rx_call *rxcall;
986 afs_int32 releasetype;
988 afs_int32 blockindex, errorcode;
989 struct ubik_trans *trans;
990 struct nvlentry tentry;
992 COUNT_REQ(VLRELEASELOCK);
993 if (!afsconf_SuperUser(vldb_confdir, rxcall, NULL))
995 if ((voltype != -1) && (InvalidVoltype(voltype)))
997 if (releasetype && InvalidReleasetype(releasetype))
998 END(VL_BADRELLOCKTYPE);
999 if (errorcode = Init_VLdbase(&trans, LOCKWRITE, this_op))
1002 VLog(1, ("ReleaseLock Volume %d %s\n", volid, rxinfo(rxcall)));
1003 blockindex = FindByID(trans, volid, voltype, &tentry, &errorcode);
1004 if (blockindex == NULLO) {
1006 errorcode = VL_NOENT;
1009 if (tentry.flags & VLDELETED) {
1010 ABORT(VL_ENTDELETED);
1013 ReleaseEntry(&tentry, releasetype); /* Unlock the appropriate fields */
1014 if (vlentrywrite(trans, blockindex, &tentry, sizeof(tentry))) {
1017 END(ubik_EndTrans(trans));
1021 ubik_AbortTrans(trans);
1024 osi_auditU(rxcall, VLReleaseLockEvent, errorcode, AUD_LONG, volid,
1030 /* ListEntry returns a single vldb entry, aentry, with offset previous_index; the remaining parameters (i.e. next_index) are used so that sequential calls to this routine will get the next (all) vldb entries. */
1032 SVL_ListEntry(rxcall, previous_index, count, next_index, aentry)
1033 struct rx_call *rxcall;
1034 afs_int32 previous_index;
1036 afs_int32 *next_index;
1037 struct vldbentry *aentry;
1040 struct ubik_trans *trans;
1041 struct nvlentry tentry;
1043 COUNT_REQ(VLLISTENTRY);
1044 if (errorcode = Init_VLdbase(&trans, LOCKREAD, this_op))
1046 VLog(25, ("OListEntry index=%d %s\n", previous_index, rxinfo(rxcall)));
1047 *next_index = NextEntry(trans, previous_index, &tentry, count);
1049 vlentry_to_vldbentry(&tentry, aentry);
1050 return (ubik_EndTrans(trans));
1053 /* ListEntry returns a single vldb entry, aentry, with offset previous_index; the remaining parameters (i.e. next_index) are used so that sequential calls to this routine will get the next (all) vldb entries. */
1055 SVL_ListEntryN(rxcall, previous_index, count, next_index, aentry)
1056 struct rx_call *rxcall;
1057 afs_int32 previous_index;
1059 afs_int32 *next_index;
1060 struct nvldbentry *aentry;
1063 struct ubik_trans *trans;
1064 struct nvlentry tentry;
1066 COUNT_REQ(VLLISTENTRYN);
1067 if (errorcode = Init_VLdbase(&trans, LOCKREAD, this_op))
1069 VLog(25, ("ListEntry index=%d %s\n", previous_index, rxinfo(rxcall)));
1070 *next_index = NextEntry(trans, previous_index, &tentry, count);
1072 vlentry_to_nvldbentry(&tentry, aentry);
1073 return (ubik_EndTrans(trans));
1077 /* Retrieves in vldbentries all vldb entries that match the specified attributes (by server number, partition, volume type, and flag); if volume id is specified then the associated list for that entry is returned. CAUTION: This could be a very expensive call since in most cases sequential search of all vldb entries is performed. */
1079 SVL_ListAttributes(rxcall, attributes, nentries, vldbentries)
1080 struct rx_call *rxcall;
1081 struct VldbListByAttributes *attributes;
1082 afs_int32 *nentries;
1083 bulkentries *vldbentries;
1085 int errorcode, allocCount = 0;
1086 struct ubik_trans *trans;
1087 struct nvlentry tentry;
1088 struct vldbentry *Vldbentry = 0, *VldbentryFirst = 0, *VldbentryLast = 0;
1091 COUNT_REQ(VLLISTATTRIBUTES);
1092 vldbentries->bulkentries_val = 0;
1093 vldbentries->bulkentries_len = *nentries = 0;
1094 if (errorcode = Init_VLdbase(&trans, LOCKREAD, this_op))
1096 allocCount = VLDBALLOCCOUNT;
1097 Vldbentry = VldbentryFirst = vldbentries->bulkentries_val =
1098 (vldbentry *) malloc(allocCount * sizeof(vldbentry));
1099 if (Vldbentry == NULL) {
1101 ubik_AbortTrans(trans);
1104 VldbentryLast = VldbentryFirst + allocCount;
1105 /* Handle the attribute by volume id totally separate of the rest (thus additional Mask values are ignored if VLLIST_VOLUMEID is set!) */
1106 if (attributes->Mask & VLLIST_VOLUMEID) {
1107 afs_int32 blockindex;
1110 FindByID(trans, attributes->volumeid, -1, &tentry, &errorcode);
1111 if (blockindex == 0) {
1113 errorcode = VL_NOENT;
1115 ubik_AbortTrans(trans);
1116 if (vldbentries->bulkentries_val)
1117 free((char *)vldbentries->bulkentries_val);
1118 vldbentries->bulkentries_val = 0;
1119 vldbentries->bulkentries_len = 0;
1123 put_attributeentry(&Vldbentry, &VldbentryFirst, &VldbentryLast,
1124 vldbentries, &tentry, nentries, &allocCount)) {
1126 ubik_AbortTrans(trans);
1127 if (vldbentries->bulkentries_val)
1128 free((char *)vldbentries->bulkentries_val);
1129 vldbentries->bulkentries_val = 0;
1130 vldbentries->bulkentries_len = 0;
1131 return VL_SIZEEXCEEDED;
1134 afs_int32 nextblockindex = 0, count = 0, k = 0, match = 0;
1135 while (nextblockindex =
1136 NextEntry(trans, nextblockindex, &tentry, &count)) {
1137 if (++pollcount > 50) {
1138 #ifndef AFS_PTHREAD_ENV
1144 if (attributes->Mask & VLLIST_SERVER) {
1147 IpAddrToRelAddr(attributes->server,
1148 (struct ubik_trans *)0)) == -1)
1150 for (k = 0; k < OMAXNSERVERS; k++) {
1151 if (tentry.serverNumber[k] == BADSERVERID)
1153 if (tentry.serverNumber[k] == serverindex) {
1161 if (attributes->Mask & VLLIST_PARTITION) {
1163 if (tentry.serverPartition[k] != attributes->partition)
1166 for (k = 0; k < OMAXNSERVERS; k++) {
1167 if (tentry.serverNumber[k] == BADSERVERID)
1169 if (tentry.serverPartition[k] ==
1170 attributes->partition) {
1180 if (attributes->Mask & VLLIST_FLAG) {
1181 if (!(tentry.flags & attributes->flag))
1185 put_attributeentry(&Vldbentry, &VldbentryFirst,
1186 &VldbentryLast, vldbentries, &tentry,
1187 nentries, &allocCount)) {
1189 ubik_AbortTrans(trans);
1190 if (vldbentries->bulkentries_val)
1191 free((char *)vldbentries->bulkentries_val);
1192 vldbentries->bulkentries_val = 0;
1193 vldbentries->bulkentries_len = 0;
1198 if (vldbentries->bulkentries_len
1199 && (allocCount > vldbentries->bulkentries_len)) {
1201 vldbentries->bulkentries_val =
1202 (vldbentry *) realloc(vldbentries->bulkentries_val,
1203 vldbentries->bulkentries_len *
1205 if (vldbentries->bulkentries_val == NULL) {
1207 ubik_AbortTrans(trans);
1212 ("ListAttrs nentries=%d %s\n", vldbentries->bulkentries_len,
1214 return (ubik_EndTrans(trans));
1218 SVL_ListAttributesN(rxcall, attributes, nentries, vldbentries)
1219 struct rx_call *rxcall;
1220 struct VldbListByAttributes *attributes;
1221 afs_int32 *nentries;
1222 nbulkentries *vldbentries;
1224 int errorcode, allocCount = 0;
1225 struct ubik_trans *trans;
1226 struct nvlentry tentry;
1227 struct nvldbentry *Vldbentry = 0, *VldbentryFirst = 0, *VldbentryLast = 0;
1230 COUNT_REQ(VLLISTATTRIBUTESN);
1231 vldbentries->nbulkentries_val = 0;
1232 vldbentries->nbulkentries_len = *nentries = 0;
1233 if (errorcode = Init_VLdbase(&trans, LOCKREAD, this_op))
1235 allocCount = VLDBALLOCCOUNT;
1236 Vldbentry = VldbentryFirst = vldbentries->nbulkentries_val =
1237 (nvldbentry *) malloc(allocCount * sizeof(nvldbentry));
1238 if (Vldbentry == NULL) {
1240 ubik_AbortTrans(trans);
1243 VldbentryLast = VldbentryFirst + allocCount;
1244 /* Handle the attribute by volume id totally separate of the rest (thus additional Mask values are ignored if VLLIST_VOLUMEID is set!) */
1245 if (attributes->Mask & VLLIST_VOLUMEID) {
1246 afs_int32 blockindex;
1249 FindByID(trans, attributes->volumeid, -1, &tentry, &errorcode);
1250 if (blockindex == 0) {
1252 errorcode = VL_NOENT;
1254 ubik_AbortTrans(trans);
1255 if (vldbentries->nbulkentries_val)
1256 free((char *)vldbentries->nbulkentries_val);
1257 vldbentries->nbulkentries_val = 0;
1258 vldbentries->nbulkentries_len = 0;
1262 put_nattributeentry(&Vldbentry, &VldbentryFirst, &VldbentryLast,
1263 vldbentries, &tentry, 0, 0, nentries,
1266 ubik_AbortTrans(trans);
1267 if (vldbentries->nbulkentries_val)
1268 free((char *)vldbentries->nbulkentries_val);
1269 vldbentries->nbulkentries_val = 0;
1270 vldbentries->nbulkentries_len = 0;
1271 return VL_SIZEEXCEEDED;
1274 afs_int32 nextblockindex = 0, count = 0, k = 0, match = 0;
1275 while (nextblockindex =
1276 NextEntry(trans, nextblockindex, &tentry, &count)) {
1277 if (++pollcount > 50) {
1278 #ifndef AFS_PTHREAD_ENV
1285 if (attributes->Mask & VLLIST_SERVER) {
1288 IpAddrToRelAddr(attributes->server,
1289 (struct ubik_trans *)0)) == -1)
1291 for (k = 0; k < NMAXNSERVERS; k++) {
1292 if (tentry.serverNumber[k] == BADSERVERID)
1294 if (tentry.serverNumber[k] == serverindex) {
1302 if (attributes->Mask & VLLIST_PARTITION) {
1304 if (tentry.serverPartition[k] != attributes->partition)
1307 for (k = 0; k < NMAXNSERVERS; k++) {
1308 if (tentry.serverNumber[k] == BADSERVERID)
1310 if (tentry.serverPartition[k] ==
1311 attributes->partition) {
1321 if (attributes->Mask & VLLIST_FLAG) {
1322 if (!(tentry.flags & attributes->flag))
1326 put_nattributeentry(&Vldbentry, &VldbentryFirst,
1327 &VldbentryLast, vldbentries, &tentry, 0,
1328 0, nentries, &allocCount)) {
1330 ubik_AbortTrans(trans);
1331 if (vldbentries->nbulkentries_val)
1332 free((char *)vldbentries->nbulkentries_val);
1333 vldbentries->nbulkentries_val = 0;
1334 vldbentries->nbulkentries_len = 0;
1339 if (vldbentries->nbulkentries_len
1340 && (allocCount > vldbentries->nbulkentries_len)) {
1342 vldbentries->nbulkentries_val =
1343 (nvldbentry *) realloc(vldbentries->nbulkentries_val,
1344 vldbentries->nbulkentries_len *
1345 sizeof(nvldbentry));
1346 if (vldbentries->nbulkentries_val == NULL) {
1348 ubik_AbortTrans(trans);
1353 ("NListAttrs nentries=%d %s\n", vldbentries->nbulkentries_len,
1355 return (ubik_EndTrans(trans));
1360 SVL_ListAttributesN2(rxcall, attributes, name, startindex, nentries,
1361 vldbentries, nextstartindex)
1362 struct rx_call *rxcall;
1363 struct VldbListByAttributes *attributes;
1364 char *name; /* Wildcarded volume name */
1365 afs_int32 startindex;
1366 afs_int32 *nentries;
1367 nbulkentries *vldbentries;
1368 afs_int32 *nextstartindex;
1370 int errorcode = 0, maxCount = VLDBALLOCCOUNT;
1371 struct ubik_trans *trans;
1372 struct nvlentry tentry;
1373 struct nvldbentry *Vldbentry = 0, *VldbentryFirst = 0, *VldbentryLast = 0;
1374 afs_int32 blockindex = 0, count = 0, k, match;
1375 afs_int32 matchindex = 0;
1376 int serverindex = -1; /* no server found */
1377 int findserver = 0, findpartition = 0, findflag = 0, findname = 0;
1380 int namematchRWBK, namematchRO, thismatch;
1382 char volumename[VL_MAXNAMELEN];
1383 #ifdef HAVE_POSIX_REGEX
1385 int need_regfree = 0;
1388 COUNT_REQ(VLLISTATTRIBUTESN2);
1389 vldbentries->nbulkentries_val = 0;
1390 vldbentries->nbulkentries_len = 0;
1392 *nextstartindex = -1;
1394 errorcode = Init_VLdbase(&trans, LOCKREAD, this_op);
1398 Vldbentry = VldbentryFirst = vldbentries->nbulkentries_val =
1399 (nvldbentry *) malloc(maxCount * sizeof(nvldbentry));
1400 if (Vldbentry == NULL) {
1402 ubik_AbortTrans(trans);
1406 VldbentryLast = VldbentryFirst + maxCount;
1408 /* Handle the attribute by volume id totally separate of the rest
1409 * (thus additional Mask values are ignored if VLLIST_VOLUMEID is set!)
1411 if (attributes->Mask & VLLIST_VOLUMEID) {
1413 FindByID(trans, attributes->volumeid, -1, &tentry, &errorcode);
1414 if (blockindex == 0) {
1416 errorcode = VL_NOENT;
1419 put_nattributeentry(&Vldbentry, &VldbentryFirst,
1420 &VldbentryLast, vldbentries, &tentry, 0,
1421 0, nentries, &maxCount);
1427 /* Search each entry in the database and return all entries
1428 * that match the request. It checks volumename (with
1429 * wildcarding), entry flags, server, and partition.
1432 /* Get the server index for matching server address */
1433 if (attributes->Mask & VLLIST_SERVER) {
1435 IpAddrToRelAddr(attributes->server, (struct ubik_trans *)0);
1436 if (serverindex == -1)
1440 findpartition = ((attributes->Mask & VLLIST_PARTITION) ? 1 : 0);
1441 findflag = ((attributes->Mask & VLLIST_FLAG) ? 1 : 0);
1442 if (name && (strcmp(name, ".*") != 0) && (strcmp(name, "") != 0)) {
1443 sprintf(volumename, "^%s$", name);
1444 #ifdef HAVE_POSIX_REGEX
1445 if (regcomp(&re, volumename, REG_NOSUB) != 0) {
1446 errorcode = VL_BADNAME;
1451 t = (char *)re_comp(volumename);
1453 errorcode = VL_BADNAME;
1460 /* Read each entry and see if it is the one we want */
1461 blockindex = startindex;
1462 while (blockindex = NextEntry(trans, blockindex, &tentry, &count)) {
1463 if (++pollcount > 50) {
1464 #ifndef AFS_PTHREAD_ENV
1470 /* Step through each server index searching for a match.
1471 * Match to an existing RW, BK, or RO volume name (preference
1472 * is in this order). Remember which index we matched against.
1474 namematchRWBK = namematchRO = 0; /* 0->notTried; 1->match; 2->noMatch */
1478 && (tentry.serverNumber[k] != BADSERVERID)); k++) {
1479 thismatch = 0; /* does this index match */
1481 /* Match against the RW or BK volume name. Remember
1482 * results in namematchRWBK. Prefer RW over BK.
1484 if (tentry.serverFlags[k] & VLSF_RWVOL) {
1485 /* Does the name match the RW name */
1486 if (tentry.flags & VLF_RWEXISTS) {
1488 sprintf(volumename, "%s", tentry.name);
1489 #ifdef HAVE_POSIX_REGEX
1490 if (regexec(&re, volumename, 0, NULL, 0) == 0) {
1491 thismatch = VLSF_RWVOL;
1494 if (re_exec(volumename)) {
1495 thismatch = VLSF_RWVOL;
1499 thismatch = VLSF_RWVOL;
1503 /* Does the name match the BK name */
1504 if (!thismatch && (tentry.flags & VLF_BACKEXISTS)) {
1506 sprintf(volumename, "%s.backup", tentry.name);
1507 #ifdef HAVE_POSIX_REGEX
1508 if (regexec(&re, volumename, 0, NULL, 0) == 0) {
1509 thismatch = VLSF_BACKVOL;
1512 if (re_exec(volumename)) {
1513 thismatch = VLSF_BACKVOL;
1517 thismatch = VLSF_BACKVOL;
1521 namematchRWBK = (thismatch ? 1 : 2);
1524 /* Match with the RO volume name. Compare once and
1525 * remember results in namematchRO. Note that this will
1526 * pick up entries marked NEWREPSITEs and DONTUSE.
1529 if (tentry.flags & VLF_ROEXISTS) {
1533 ((namematchRO == 1) ? VLSF_ROVOL : 0);
1535 sprintf(volumename, "%s.readonly",
1537 #ifdef HAVE_POSIX_REGEX
1538 if (regexec(&re, volumename, 0, NULL, 0) == 0) {
1539 thismatch = VLSF_ROVOL;
1542 if (re_exec(volumename))
1543 thismatch = VLSF_ROVOL;
1547 thismatch = VLSF_ROVOL;
1550 namematchRO = (thismatch ? 1 : 2);
1553 /* Is there a server match */
1554 if (thismatch && findserver
1555 && (tentry.serverNumber[k] != serverindex))
1558 /* Is there a partition match */
1559 if (thismatch && findpartition
1560 && (tentry.serverPartition[k] != attributes->partition))
1563 /* Is there a flag match */
1564 if (thismatch && findflag
1565 && !(tentry.flags & attributes->flag))
1568 /* We found a match. Remember the index, and type */
1572 matchtype = thismatch;
1575 /* Since we prefer RW and BK volume matches over RO matches,
1576 * if we have already checked the RWBK name, then we already
1577 * found the best match and so end the search.
1579 * If we tried matching against the RW, BK, and RO volume names
1580 * and both failed, then we end the search (none will match).
1582 if ((match && namematchRWBK)
1583 || ((namematchRWBK == 2) && (namematchRO == 2)))
1587 /* Passed all the tests. Take it */
1590 put_nattributeentry(&Vldbentry, &VldbentryFirst,
1591 &VldbentryLast, vldbentries, &tentry,
1592 matchtype, matchindex, nentries,
1597 if (*nentries >= maxCount)
1598 break; /* collected the max */
1601 *nextstartindex = (blockindex ? blockindex : -1);
1605 #ifdef HAVE_POSIX_REGEX
1612 ubik_AbortTrans(trans);
1613 if (vldbentries->nbulkentries_val)
1614 free((char *)vldbentries->nbulkentries_val);
1615 vldbentries->nbulkentries_val = 0;
1616 vldbentries->nbulkentries_len = 0;
1617 *nextstartindex = -1;
1621 ("N2ListAttrs nentries=%d %s\n", vldbentries->nbulkentries_len,
1623 return (ubik_EndTrans(trans));
1628 /* Retrieves in vldbentries all vldb entries that match the specified
1629 * attributes (by server number, partition, volume type, and flag); if
1630 * volume id is specified then the associated list for that entry is
1631 * returned. CAUTION: This could be a very expensive call since in most
1632 * cases sequential search of all vldb entries is performed.
1635 SVL_LinkedList(rxcall, attributes, nentries, vldbentries)
1636 struct rx_call *rxcall;
1637 struct VldbListByAttributes *attributes;
1638 afs_int32 *nentries;
1639 vldb_list *vldbentries;
1642 struct ubik_trans *trans;
1643 struct nvlentry tentry;
1644 vldblist vllist, *vllistptr;
1645 afs_int32 blockindex, count, match;
1650 COUNT_REQ(VLLINKEDLIST);
1651 if (errorcode = Init_VLdbase(&trans, LOCKREAD, this_op))
1655 vldbentries->node = NULL;
1656 vllistptr = &vldbentries->node;
1658 /* List by volumeid */
1659 if (attributes->Mask & VLLIST_VOLUMEID) {
1661 FindByID(trans, attributes->volumeid, -1, &tentry, &errorcode);
1664 ubik_AbortTrans(trans);
1665 return (errorcode ? errorcode : VL_NOENT);
1668 vllist = (single_vldbentry *) malloc(sizeof(single_vldbentry));
1669 if (vllist == NULL) {
1671 ubik_AbortTrans(trans);
1674 vlentry_to_vldbentry(&tentry, &vllist->VldbEntry);
1675 vllist->next_vldb = NULL;
1677 *vllistptr = vllist; /* Thread onto list */
1678 vllistptr = &vllist->next_vldb;
1682 /* Search by server, partition, and flags */
1684 for (blockindex = NextEntry(trans, 0, &tentry, &count); blockindex;
1685 blockindex = NextEntry(trans, blockindex, &tentry, &count)) {
1688 if (++pollcount > 50) {
1689 #ifndef AFS_PTHREAD_ENV
1695 /* Does this volume exist on the desired server */
1696 if (attributes->Mask & VLLIST_SERVER) {
1698 IpAddrToRelAddr(attributes->server,
1699 (struct ubik_trans *)0);
1700 if (serverindex == -1)
1702 for (k = 0; k < OMAXNSERVERS; k++) {
1703 if (tentry.serverNumber[k] == BADSERVERID)
1705 if (tentry.serverNumber[k] == serverindex) {
1714 /* Does this volume exist on the desired partition */
1715 if (attributes->Mask & VLLIST_PARTITION) {
1717 if (tentry.serverPartition[k] != attributes->partition)
1720 for (k = 0; k < OMAXNSERVERS; k++) {
1721 if (tentry.serverNumber[k] == BADSERVERID)
1723 if (tentry.serverPartition[k] ==
1724 attributes->partition) {
1734 /* Does this volume have the desired flags */
1735 if (attributes->Mask & VLLIST_FLAG) {
1736 if (!(tentry.flags & attributes->flag))
1740 vllist = (single_vldbentry *) malloc(sizeof(single_vldbentry));
1741 if (vllist == NULL) {
1743 ubik_AbortTrans(trans);
1746 vlentry_to_vldbentry(&tentry, &vllist->VldbEntry);
1747 vllist->next_vldb = NULL;
1749 *vllistptr = vllist; /* Thread onto list */
1750 vllistptr = &vllist->next_vldb;
1752 if (smallMem && (*nentries >= VLDBALLOCCOUNT)) {
1754 ubik_AbortTrans(trans);
1755 return VL_SIZEEXCEEDED;
1760 return (ubik_EndTrans(trans));
1764 SVL_LinkedListN(rxcall, attributes, nentries, vldbentries)
1765 struct rx_call *rxcall;
1766 struct VldbListByAttributes *attributes;
1767 afs_int32 *nentries;
1768 nvldb_list *vldbentries;
1771 struct ubik_trans *trans;
1772 struct nvlentry tentry;
1773 nvldblist vllist, *vllistptr;
1774 afs_int32 blockindex, count, match;
1779 COUNT_REQ(VLLINKEDLISTN);
1780 if (errorcode = Init_VLdbase(&trans, LOCKREAD, this_op))
1784 vldbentries->node = NULL;
1785 vllistptr = &vldbentries->node;
1787 /* List by volumeid */
1788 if (attributes->Mask & VLLIST_VOLUMEID) {
1790 FindByID(trans, attributes->volumeid, -1, &tentry, &errorcode);
1793 ubik_AbortTrans(trans);
1794 return (errorcode ? errorcode : VL_NOENT);
1797 vllist = (single_nvldbentry *) malloc(sizeof(single_nvldbentry));
1798 if (vllist == NULL) {
1800 ubik_AbortTrans(trans);
1803 vlentry_to_nvldbentry(&tentry, &vllist->VldbEntry);
1804 vllist->next_vldb = NULL;
1806 *vllistptr = vllist; /* Thread onto list */
1807 vllistptr = &vllist->next_vldb;
1811 /* Search by server, partition, and flags */
1813 for (blockindex = NextEntry(trans, 0, &tentry, &count); blockindex;
1814 blockindex = NextEntry(trans, blockindex, &tentry, &count)) {
1817 if (++pollcount > 50) {
1818 #ifndef AFS_PTHREAD_ENV
1824 /* Does this volume exist on the desired server */
1825 if (attributes->Mask & VLLIST_SERVER) {
1827 IpAddrToRelAddr(attributes->server,
1828 (struct ubik_trans *)0);
1829 if (serverindex == -1)
1831 for (k = 0; k < NMAXNSERVERS; k++) {
1832 if (tentry.serverNumber[k] == BADSERVERID)
1834 if (tentry.serverNumber[k] == serverindex) {
1843 /* Does this volume exist on the desired partition */
1844 if (attributes->Mask & VLLIST_PARTITION) {
1846 if (tentry.serverPartition[k] != attributes->partition)
1849 for (k = 0; k < NMAXNSERVERS; k++) {
1850 if (tentry.serverNumber[k] == BADSERVERID)
1852 if (tentry.serverPartition[k] ==
1853 attributes->partition) {
1863 /* Does this volume have the desired flags */
1864 if (attributes->Mask & VLLIST_FLAG) {
1865 if (!(tentry.flags & attributes->flag))
1869 vllist = (single_nvldbentry *) malloc(sizeof(single_nvldbentry));
1870 if (vllist == NULL) {
1872 ubik_AbortTrans(trans);
1875 vlentry_to_nvldbentry(&tentry, &vllist->VldbEntry);
1876 vllist->next_vldb = NULL;
1878 *vllistptr = vllist; /* Thread onto list */
1879 vllistptr = &vllist->next_vldb;
1881 if (smallMem && (*nentries >= VLDBALLOCCOUNT)) {
1883 ubik_AbortTrans(trans);
1884 return VL_SIZEEXCEEDED;
1889 return (ubik_EndTrans(trans));
1892 /* Get back vldb header statistics (allocs, frees, maxvolumeid, totalentries, etc) and dynamic statistics (number of requests and/or aborts per remote procedure call, etc) */
1894 SVL_GetStats(rxcall, stats, vital_header)
1895 struct rx_call *rxcall;
1897 vital_vlheader *vital_header;
1899 register afs_int32 errorcode;
1900 struct ubik_trans *trans;
1902 COUNT_REQ(VLGETSTATS);
1904 /* Allow users to get statistics freely */
1905 if (!afsconf_SuperUser(vldb_confdir, rxcall, NULL)) /* Must be in 'UserList' to use */
1908 if (errorcode = Init_VLdbase(&trans, LOCKREAD, this_op))
1910 VLog(5, ("GetStats %s\n", rxinfo(rxcall)));
1911 memcpy((char *)vital_header, (char *)&cheader.vital_header,
1912 sizeof(vital_vlheader));
1913 memcpy((char *)stats, (char *)&dynamic_statistics, sizeof(vldstats));
1914 return (ubik_EndTrans(trans));
1917 /* Get the list of file server addresses from the VLDB. Currently it's pretty
1918 * easy to do. In the future, it might require a little bit of grunging
1919 * through the VLDB, but that's life.
1922 SVL_GetAddrs(rxcall, Handle, spare2, spare3, nentries, addrsp)
1923 struct rx_call *rxcall;
1924 afs_int32 Handle, spare2;
1925 struct VLCallBack *spare3;
1926 afs_int32 *nentries;
1929 register afs_int32 errorcode;
1930 struct ubik_trans *trans;
1934 COUNT_REQ(VLGETADDRS);
1935 addrsp->bulkaddrs_len = *nentries = 0;
1936 addrsp->bulkaddrs_val = 0;
1937 memset(spare3, 0, sizeof(struct VLCallBack));
1939 if (errorcode = Init_VLdbase(&trans, LOCKREAD, this_op))
1942 VLog(5, ("GetAddrs\n"));
1943 addrsp->bulkaddrs_val = taddrp =
1944 (afs_uint32 *) malloc(sizeof(afs_int32) * (MAXSERVERID + 1));
1945 nservers = *nentries = addrsp->bulkaddrs_len = 0;
1949 ubik_AbortTrans(trans);
1953 for (i = 0; i <= MAXSERVERID; i++) {
1954 if (*taddrp = ntohl(cheader.IpMappedAddr[i])) {
1960 addrsp->bulkaddrs_len = *nentries = nservers;
1961 return (ubik_EndTrans(trans));
1964 #define PADDR(addr) VLog(0,("%d.%d.%d.%d", (addr>>24)&0xff, (addr>>16)&0xff, (addr>>8) &0xff, addr&0xff));
1967 SVL_RegisterAddrs(rxcall, uuidp, spare1, addrsp)
1968 struct rx_call *rxcall;
1974 struct ubik_trans *trans;
1975 int cnt, h, i, j, k, m, base, index;
1976 struct extentaddr *exp = 0, *tex;
1978 afs_uint32 addrs[VL_MAXIPADDRS_PERMH];
1980 int count, willChangeEntry, foundUuidEntry, willReplaceCnt;
1981 int WillReplaceEntry, WillChange[MAXSERVERID + 1];
1983 int ReplaceEntry = 0;
1986 COUNT_REQ(VLREGADDR);
1987 if (!afsconf_SuperUser(vldb_confdir, rxcall, NULL))
1989 if (code = Init_VLdbase(&trans, LOCKWRITE, this_op))
1992 /* Eliminate duplicates from IP address list */
1993 for (k = 0, cnt = 0; k < addrsp->bulkaddrs_len; k++) {
1994 if (addrsp->bulkaddrs_val[k] == 0)
1996 for (m = 0; m < cnt; m++) {
1997 if (addrs[m] == addrsp->bulkaddrs_val[k])
2001 if (m == VL_MAXIPADDRS_PERMH) {
2003 ("Number of addresses exceeds %d. Cannot register IP addr 0x%x in VLDB\n",
2004 VL_MAXIPADDRS_PERMH, addrsp->bulkaddrs_val[k]));
2006 addrs[m] = addrsp->bulkaddrs_val[k];
2012 ubik_AbortTrans(trans);
2013 return VL_INDEXERANGE;
2019 /* For each server registered within the VLDB */
2020 for (srvidx = 0; srvidx <= MAXSERVERID; srvidx++) {
2021 willChangeEntry = 0;
2022 WillReplaceEntry = 1;
2023 if ((HostAddress[srvidx] & 0xff000000) == 0xff000000) {
2024 /* The server is registered as a multihomed */
2025 base = (HostAddress[srvidx] >> 16) & 0xff;
2026 index = HostAddress[srvidx] & 0x0000ffff;
2027 if (base >= VL_MAX_ADDREXTBLKS) {
2029 ("Internal error: Multihome extent base is too large. Base %d index %d\n",
2033 if (index >= VL_MHSRV_PERBLK) {
2035 ("Internal error: Multihome extent index is too large. Base %d index %d\n",
2039 if (!ex_addr[base]) {
2041 ("Internal error: Multihome extent does not exist. Base %d\n",
2046 /* See if the addresses to register will change this server entry */
2047 exp = &ex_addr[base][index];
2048 tuuid = exp->ex_hostuuid;
2049 afs_ntohuuid(&tuuid);
2050 if (afs_uuid_equal(uuidp, &tuuid)) {
2054 for (mhidx = 0; mhidx < VL_MAXIPADDRS_PERMH; mhidx++) {
2055 if (!exp->ex_addrs[mhidx])
2057 for (k = 0; k < cnt; k++) {
2058 if (ntohl(exp->ex_addrs[mhidx]) == addrs[k]) {
2059 willChangeEntry = 1;
2060 WillChange[count] = srvidx;
2065 WillReplaceEntry = 0;
2069 /* The server is not registered as a multihomed.
2070 * See if the addresses to register will replace this server entry.
2072 for (k = 0; k < cnt; k++) {
2073 if (HostAddress[srvidx] == addrs[k]) {
2074 willChangeEntry = 1;
2075 WillChange[count] = srvidx;
2076 WillReplaceEntry = 1;
2081 if (willChangeEntry) {
2082 if (WillReplaceEntry) {
2084 ReplaceEntry = srvidx;
2090 /* If we found the uuid in the VLDB and if we are replacing another
2091 * entire entry, then complain and fail. Also, if we did not find
2092 * the uuid in the VLDB and the IP addresses being registered was
2093 * found in more than one other entry, then we don't know which one
2094 * to replace and will complain and fail.
2096 if ((foundUuidEntry && (willReplaceCnt > 0))
2097 || (!foundUuidEntry && (count > 1))) {
2099 ("The following fileserver is being registered in the VLDB:\n"));
2101 for (k = 0; k < cnt; k++) {
2108 if (foundUuidEntry) {
2110 (" It would have replaced the existing VLDB server entry:\n"));
2111 VLog(0, (" entry %d: [", FoundUuid));
2112 base = (HostAddress[FoundUuid] >> 16) & 0xff;
2113 index = HostAddress[FoundUuid] & 0x0000ffff;
2114 exp = &ex_addr[base][index];
2115 for (mhidx = 0; mhidx < VL_MAXIPADDRS_PERMH; mhidx++) {
2116 if (!exp->ex_addrs[mhidx])
2120 PADDR(ntohl(exp->ex_addrs[mhidx]));
2126 VLog(0, (" Yet another VLDB server entry exists:\n"));
2128 VLog(0, (" Yet other VLDB server entries exist:\n"));
2129 for (j = 0; j < count; j++) {
2130 srvidx = WillChange[j];
2131 VLog(0, (" entry %d: ", srvidx));
2132 if ((HostAddress[srvidx] & 0xff000000) == 0xff000000) {
2134 base = (HostAddress[srvidx] >> 16) & 0xff;
2135 index = HostAddress[srvidx] & 0x0000ffff;
2136 exp = &ex_addr[base][index];
2137 for (mhidx = 0; mhidx < VL_MAXIPADDRS_PERMH; mhidx++) {
2138 if (!exp->ex_addrs[mhidx])
2142 PADDR(ntohl(exp->ex_addrs[mhidx]));
2146 PADDR(HostAddress[srvidx]);
2152 VLog(0, (" You must 'vos changeaddr' this other server entry\n"));
2155 (" You must 'vos changeaddr' these other server entries\n"));
2158 (" and/or remove the sysid file from the registering fileserver\n"));
2159 VLog(0, (" before the fileserver can be registered in the VLDB.\n"));
2161 ubik_AbortTrans(trans);
2162 return VL_MULTIPADDR;
2165 /* Passed the checks. Now find and update the existing mh entry, or create
2168 if (foundUuidEntry) {
2169 /* Found the entry with same uuid. See if we need to change it */
2172 fbase = (HostAddress[FoundUuid] >> 16) & 0xff;
2173 index = HostAddress[FoundUuid] & 0x0000ffff;
2174 exp = &ex_addr[fbase][index];
2176 /* Determine if the entry has changed */
2177 for (k = 0; ((k < cnt) && !change); k++) {
2178 if (ntohl(exp->ex_addrs[k]) != addrs[k])
2181 for (; ((k < VL_MAXIPADDRS_PERMH) && !change); k++) {
2182 if (exp->ex_addrs[k] != 0)
2186 return (ubik_EndTrans(trans));
2190 VLog(0, ("The following fileserver is being registered in the VLDB:\n"));
2192 for (k = 0; k < cnt; k++) {
2199 if (foundUuidEntry) {
2201 (" It will replace the following existing entry in the VLDB (same uuid):\n"));
2202 VLog(0, (" entry %d: [", FoundUuid));
2203 for (k = 0; k < VL_MAXIPADDRS_PERMH; k++) {
2204 if (exp->ex_addrs[k] == 0)
2208 PADDR(ntohl(exp->ex_addrs[k]));
2211 } else if (willReplaceCnt || (count == 1)) {
2212 /* If we are not replacing an entry and there is only one entry to change,
2213 * then we will replace that entry.
2215 if (!willReplaceCnt) {
2216 ReplaceEntry = WillChange[0];
2220 /* Have an entry that needs to be replaced */
2221 if ((HostAddress[ReplaceEntry] & 0xff000000) == 0xff000000) {
2222 fbase = (HostAddress[ReplaceEntry] >> 16) & 0xff;
2223 index = HostAddress[ReplaceEntry] & 0x0000ffff;
2224 exp = &ex_addr[fbase][index];
2227 (" It will replace the following existing entry in the VLDB (new uuid):\n"));
2228 VLog(0, (" entry %d: [", ReplaceEntry));
2229 for (k = 0; k < VL_MAXIPADDRS_PERMH; k++) {
2230 if (exp->ex_addrs[k] == 0)
2234 PADDR(ntohl(exp->ex_addrs[k]));
2238 /* Not a mh entry. So we have to create a new mh entry and
2239 * put it on the ReplaceEntry slot of the HostAddress array.
2241 VLog(0, (" It will replace existing entry %d, ", ReplaceEntry));
2242 PADDR(HostAddress[ReplaceEntry]);
2243 VLog(0,(", in the VLDB (new uuid):\n"));
2246 FindExtentBlock(trans, uuidp, 1, ReplaceEntry, &exp, &fbase);
2248 ubik_AbortTrans(trans);
2249 return (code ? code : VL_IO);
2253 /* There is no entry for this server, must create a new mh entry as
2254 * well as use a new slot of the HostAddress array.
2256 VLog(0, (" It will create a new entry in the VLDB.\n"));
2257 code = FindExtentBlock(trans, uuidp, 1, -1, &exp, &fbase);
2259 ubik_AbortTrans(trans);
2260 return (code ? code : VL_IO);
2264 /* Now we have a mh entry to fill in. Update the uuid, bump the
2265 * uniquifier, and fill in its IP addresses.
2268 afs_htonuuid(&tuuid);
2269 exp->ex_hostuuid = tuuid;
2270 exp->ex_uniquifier = htonl(ntohl(exp->ex_uniquifier) + 1);
2271 for (k = 0; k < cnt; k++) {
2272 exp->ex_addrs[k] = htonl(addrs[k]);
2274 for (; k < VL_MAXIPADDRS_PERMH; k++) {
2275 exp->ex_addrs[k] = 0;
2278 /* Write the new mh entry out */
2281 DOFFSET(ntohl(ex_addr[0]->ex_contaddrs[fbase]),
2282 (char *)ex_addr[fbase], (char *)exp), (char *)exp,
2284 ubik_AbortTrans(trans);
2288 /* Remove any common addresses from other mh entres. We know these entries
2289 * are being changed and not replaced so they are mh entries.
2292 for (i = 0; i < count; i++) {
2295 /* Skip the entry we replaced */
2296 if (willReplaceCnt && (WillChange[i] == ReplaceEntry))
2299 base = (HostAddress[WillChange[i]] >> 16) & 0xff;
2300 index = HostAddress[WillChange[i]] & 0x0000ffff;
2301 tex = &ex_addr[fbase][index];
2305 (" The following existing entries in the VLDB will be updated:\n"));
2307 VLog(0, (" entry %d: [", WillChange[i]));
2308 for (h = j = 0; j < VL_MAXIPADDRS_PERMH; j++) {
2309 if (tex->ex_addrs[j]) {
2312 PADDR(ntohl(tex->ex_addrs[j]));
2315 for (k = 0; k < cnt; k++) {
2316 if (ntohl(tex->ex_addrs[j]) == addrs[k])
2320 /* Not found, so we keep it */
2321 tex->ex_addrs[h] = tex->ex_addrs[j];
2325 for (j = h; j < VL_MAXIPADDRS_PERMH; j++) {
2326 tex->ex_addrs[j] = 0; /* zero rest of mh entry */
2330 /* Write out the modified mh entry */
2331 tex->ex_uniquifier = htonl(ntohl(tex->ex_uniquifier) + 1);
2333 DOFFSET(ntohl(ex_addr[0]->ex_contaddrs[base]),
2334 (char *)ex_addr[base], (char *)tex);
2335 if (vlwrite(trans, doff, (char *)tex, sizeof(*tex))) {
2336 ubik_AbortTrans(trans);
2341 return (ubik_EndTrans(trans));
2345 SVL_GetAddrsU(rxcall, attributes, uuidpo, uniquifier, nentries, addrsp)
2346 struct rx_call *rxcall;
2347 struct ListAddrByAttributes *attributes;
2349 afs_int32 *uniquifier, *nentries;
2352 register afs_int32 errorcode, index = -1, offset;
2353 struct ubik_trans *trans;
2354 int nservers, i, j, base = 0;
2355 struct extentaddr *exp = 0;
2357 afs_uint32 *taddrp, taddr;
2359 COUNT_REQ(VLGETADDRSU);
2360 addrsp->bulkaddrs_len = *nentries = 0;
2361 addrsp->bulkaddrs_val = 0;
2362 VLog(5, ("GetAddrsU %s\n", rxinfo(rxcall)));
2363 if (errorcode = Init_VLdbase(&trans, LOCKREAD, this_op))
2366 if (attributes->Mask & VLADDR_IPADDR) {
2367 if (attributes->Mask & (VLADDR_INDEX | VLADDR_UUID)) {
2368 ubik_AbortTrans(trans);
2371 for (base = 0; base < VL_MAX_ADDREXTBLKS; base++) {
2374 for (i = 1; i < VL_MHSRV_PERBLK; i++) {
2375 exp = &ex_addr[base][i];
2376 tuuid = exp->ex_hostuuid;
2377 afs_ntohuuid(&tuuid);
2378 if (afs_uuid_is_nil(&tuuid))
2380 for (j = 0; j < VL_MAXIPADDRS_PERMH; j++) {
2381 if (exp->ex_addrs[j]
2382 && (ntohl(exp->ex_addrs[j]) == attributes->ipaddr)) {
2386 if (j < VL_MAXIPADDRS_PERMH)
2389 if (i < VL_MHSRV_PERBLK)
2392 if (base >= VL_MAX_ADDREXTBLKS) {
2393 ubik_AbortTrans(trans);
2396 } else if (attributes->Mask & VLADDR_INDEX) {
2397 if (attributes->Mask & (VLADDR_IPADDR | VLADDR_UUID)) {
2398 ubik_AbortTrans(trans);
2401 index = attributes->index;
2402 if (index < 1 || index >= (VL_MAX_ADDREXTBLKS * VL_MHSRV_PERBLK)) {
2403 ubik_AbortTrans(trans);
2404 return VL_INDEXERANGE;
2406 base = index / VL_MHSRV_PERBLK;
2407 offset = index % VL_MHSRV_PERBLK;
2409 ubik_AbortTrans(trans);
2412 if (!ex_addr[base]) {
2413 ubik_AbortTrans(trans);
2414 return VL_INDEXERANGE;
2416 exp = &ex_addr[base][offset];
2417 } else if (attributes->Mask & VLADDR_UUID) {
2418 if (attributes->Mask & (VLADDR_IPADDR | VLADDR_INDEX)) {
2419 ubik_AbortTrans(trans);
2422 if (!ex_addr[0]) { /* mh servers probably aren't setup on this vldb */
2423 ubik_AbortTrans(trans);
2427 FindExtentBlock(trans, &attributes->uuid, 0, -1, &exp, &base)) {
2428 ubik_AbortTrans(trans);
2432 ubik_AbortTrans(trans);
2437 ubik_AbortTrans(trans);
2440 addrsp->bulkaddrs_val = taddrp =
2441 (afs_uint32 *) malloc(sizeof(afs_int32) * (MAXSERVERID + 1));
2442 nservers = *nentries = addrsp->bulkaddrs_len = 0;
2445 ubik_AbortTrans(trans);
2448 tuuid = exp->ex_hostuuid;
2449 afs_ntohuuid(&tuuid);
2450 if (afs_uuid_is_nil(&tuuid)) {
2451 ubik_AbortTrans(trans);
2457 *uniquifier = ntohl(exp->ex_uniquifier);
2458 for (i = 0; i < VL_MAXIPADDRS_PERMH; i++) {
2459 if (exp->ex_addrs[i]) {
2460 taddr = ntohl(exp->ex_addrs[i]);
2461 /* Weed out duplicates */
2462 for (j = 0; j < nservers; j++) {
2463 if (taddrp[j] == taddr)
2466 if ((j == nservers) && (j <= MAXSERVERID)) {
2467 taddrp[nservers] = taddr;
2472 addrsp->bulkaddrs_len = *nentries = nservers;
2473 return (ubik_EndTrans(trans));
2476 /* ============> End of Exported vldb RPC functions <============= */
2479 /* Routine that copies the given vldb entry to the output buffer, vldbentries. */
2481 put_attributeentry(Vldbentry, VldbentryFirst, VldbentryLast, vldbentries,
2482 entry, nentries, alloccnt)
2483 struct vldbentry **Vldbentry, **VldbentryFirst, **VldbentryLast;
2484 bulkentries *vldbentries;
2485 struct nvlentry *entry;
2486 afs_int32 *nentries, *alloccnt;
2491 if (*Vldbentry == *VldbentryLast) {
2493 return VL_SIZEEXCEEDED; /* no growing if smallMem defined */
2495 /* Allocate another set of memory; each time allocate twice as
2496 * many blocks as the last time. When we reach VLDBALLOCLIMIT,
2497 * then grow in increments of VLDBALLOCINCR.
2499 allo = (*alloccnt > VLDBALLOCLIMIT) ? VLDBALLOCINCR : *alloccnt;
2501 (vldbentry *) realloc(*VldbentryFirst,
2502 (*alloccnt + allo) * sizeof(vldbentry));
2506 *VldbentryFirst = vldbentries->bulkentries_val = reall;
2507 *Vldbentry = *VldbentryFirst + *alloccnt;
2508 *VldbentryLast = *Vldbentry + allo;
2511 vlentry_to_vldbentry(entry, *Vldbentry);
2514 vldbentries->bulkentries_len++;
2519 put_nattributeentry(Vldbentry, VldbentryFirst, VldbentryLast, vldbentries,
2520 entry, matchtype, matchindex, nentries, alloccnt)
2521 struct nvldbentry **Vldbentry, **VldbentryFirst, **VldbentryLast;
2522 nbulkentries *vldbentries;
2523 struct nvlentry *entry;
2524 afs_int32 matchtype, matchindex, *nentries, *alloccnt;
2529 if (*Vldbentry == *VldbentryLast) {
2531 return VL_SIZEEXCEEDED; /* no growing if smallMem defined */
2533 /* Allocate another set of memory; each time allocate twice as
2534 * many blocks as the last time. When we reach VLDBALLOCLIMIT,
2535 * then grow in increments of VLDBALLOCINCR.
2537 allo = (*alloccnt > VLDBALLOCLIMIT) ? VLDBALLOCINCR : *alloccnt;
2539 (nvldbentry *) realloc(*VldbentryFirst,
2540 (*alloccnt + allo) * sizeof(nvldbentry));
2544 *VldbentryFirst = vldbentries->nbulkentries_val = reall;
2545 *Vldbentry = *VldbentryFirst + *alloccnt;
2546 *VldbentryLast = *Vldbentry + allo;
2549 vlentry_to_nvldbentry(entry, *Vldbentry);
2550 (*Vldbentry)->matchindex = (matchtype << 16) + matchindex;
2553 vldbentries->nbulkentries_len++;
2558 /* Common code to actually remove a vldb entry from the database. */
2560 RemoveEntry(trans, entryptr, tentry)
2561 struct ubik_trans *trans;
2563 struct nvlentry *tentry;
2565 register int errorcode;
2567 if (errorcode = UnthreadVLentry(trans, entryptr, tentry))
2569 if (errorcode = FreeBlock(trans, entryptr))
2575 ReleaseEntry(tentry, releasetype)
2576 struct nvlentry *tentry;
2577 afs_int32 releasetype;
2579 if (releasetype & LOCKREL_TIMESTAMP)
2580 tentry->LockTimestamp = 0;
2581 if (releasetype & LOCKREL_OPCODE)
2582 tentry->flags &= ~VLOP_ALLOPERS;
2583 if (releasetype & LOCKREL_AFSID)
2584 tentry->LockAfsId = 0;
2588 /* Verify that the incoming vldb entry is valid; multi type of error codes are returned. */
2590 check_vldbentry(aentry)
2591 struct vldbentry *aentry;
2595 if (InvalidVolname(aentry->name))
2597 if (aentry->nServers <= 0 || aentry->nServers > OMAXNSERVERS)
2598 return VL_BADSERVER;
2599 for (i = 0; i < aentry->nServers; i++) {
2600 /* if (aentry->serverNumber[i] < 0 || aentry->serverNumber[i] > MAXSERVERID)
2601 return VL_BADSERVER; */
2602 if (aentry->serverPartition[i] < 0
2603 || aentry->serverPartition[i] > MAXPARTITIONID)
2604 return VL_BADPARTITION;
2605 if (aentry->serverFlags[i] < 0
2606 || aentry->serverFlags[i] > MAXSERVERFLAG)
2607 return VL_BADSERVERFLAG;
2613 check_nvldbentry(aentry)
2614 struct nvldbentry *aentry;
2618 if (InvalidVolname(aentry->name))
2620 if (aentry->nServers <= 0 || aentry->nServers > NMAXNSERVERS)
2621 return VL_BADSERVER;
2622 for (i = 0; i < aentry->nServers; i++) {
2623 /* if (aentry->serverNumber[i] < 0 || aentry->serverNumber[i] > MAXSERVERID)
2624 return VL_BADSERVER; */
2625 if (aentry->serverPartition[i] < 0
2626 || aentry->serverPartition[i] > MAXPARTITIONID)
2627 return VL_BADPARTITION;
2628 if (aentry->serverFlags[i] < 0
2629 || aentry->serverFlags[i] > MAXSERVERFLAG)
2630 return VL_BADSERVERFLAG;
2636 /* Convert from the external vldb entry representation to its internal
2637 (more compact) form. This call should not change the hash chains! */
2639 vldbentry_to_vlentry(atrans, VldbEntry, VlEntry)
2640 struct ubik_trans *atrans;
2641 struct vldbentry *VldbEntry;
2642 struct nvlentry *VlEntry;
2646 if (strcmp(VlEntry->name, VldbEntry->name))
2647 strncpy(VlEntry->name, VldbEntry->name, sizeof(VlEntry->name));
2648 for (i = 0; i < VldbEntry->nServers; i++) {
2649 serverindex = IpAddrToRelAddr(VldbEntry->serverNumber[i], atrans);
2650 if (serverindex == -1)
2651 return VL_BADSERVER;
2652 VlEntry->serverNumber[i] = serverindex;
2653 VlEntry->serverPartition[i] = VldbEntry->serverPartition[i];
2654 VlEntry->serverFlags[i] = VldbEntry->serverFlags[i];
2656 for (; i < OMAXNSERVERS; i++)
2657 VlEntry->serverNumber[i] = VlEntry->serverPartition[i] =
2658 VlEntry->serverFlags[i] = BADSERVERID;
2659 for (i = 0; i < MAXTYPES; i++)
2660 VlEntry->volumeId[i] = VldbEntry->volumeId[i];
2661 VlEntry->cloneId = VldbEntry->cloneId;
2662 VlEntry->flags = VldbEntry->flags;
2667 nvldbentry_to_vlentry(atrans, VldbEntry, VlEntry)
2668 struct ubik_trans *atrans;
2669 struct nvldbentry *VldbEntry;
2670 struct nvlentry *VlEntry;
2674 if (strcmp(VlEntry->name, VldbEntry->name))
2675 strncpy(VlEntry->name, VldbEntry->name, sizeof(VlEntry->name));
2676 for (i = 0; i < VldbEntry->nServers; i++) {
2677 serverindex = IpAddrToRelAddr(VldbEntry->serverNumber[i], atrans);
2678 if (serverindex == -1)
2679 return VL_BADSERVER;
2680 VlEntry->serverNumber[i] = serverindex;
2681 VlEntry->serverPartition[i] = VldbEntry->serverPartition[i];
2682 VlEntry->serverFlags[i] = VldbEntry->serverFlags[i];
2684 for (; i < NMAXNSERVERS; i++)
2685 VlEntry->serverNumber[i] = VlEntry->serverPartition[i] =
2686 VlEntry->serverFlags[i] = BADSERVERID;
2687 for (i = 0; i < MAXTYPES; i++)
2688 VlEntry->volumeId[i] = VldbEntry->volumeId[i];
2689 VlEntry->cloneId = VldbEntry->cloneId;
2690 VlEntry->flags = VldbEntry->flags;
2695 /* Update the vldb entry with the new fields as indicated by the value of the Mask entry in the updateentry structure. All necessary validation checks are performed. */
2697 get_vldbupdateentry(trans, blockindex, updateentry, VlEntry)
2698 struct ubik_trans *trans;
2699 afs_int32 blockindex;
2700 struct VldbUpdateEntry *updateentry;
2701 struct nvlentry *VlEntry;
2703 int i, j, errorcode, serverindex;
2705 if (updateentry->Mask & VLUPDATE_VOLUMENAME) {
2706 if (InvalidVolname(updateentry->name))
2708 if (errorcode = UnhashVolname(trans, blockindex, VlEntry))
2710 strncpy(VlEntry->name, updateentry->name, sizeof(VlEntry->name));
2711 HashVolname(trans, blockindex, VlEntry);
2714 if (updateentry->Mask & VLUPDATE_VOLNAMEHASH) {
2715 if (errorcode = UnhashVolname(trans, blockindex, VlEntry)) {
2716 if (errorcode != VL_NOENT)
2719 HashVolname(trans, blockindex, VlEntry);
2722 if (updateentry->Mask & VLUPDATE_FLAGS) {
2723 VlEntry->flags = updateentry->flags;
2725 if (updateentry->Mask & VLUPDATE_CLONEID) {
2726 VlEntry->cloneId = updateentry->cloneId;
2728 if (updateentry->Mask & VLUPDATE_RWID) {
2729 if (errorcode = UnhashVolid(trans, RWVOL, blockindex, VlEntry)) {
2730 if (errorcode != VL_NOENT)
2733 VlEntry->volumeId[RWVOL] = updateentry->spares3; /* rw id */
2734 if (errorcode = HashVolid(trans, RWVOL, blockindex, VlEntry))
2737 if (updateentry->Mask & VLUPDATE_READONLYID) {
2738 if (errorcode = UnhashVolid(trans, ROVOL, blockindex, VlEntry)) {
2739 if (errorcode != VL_NOENT)
2742 VlEntry->volumeId[ROVOL] = updateentry->ReadOnlyId;
2743 if (errorcode = HashVolid(trans, ROVOL, blockindex, VlEntry))
2746 if (updateentry->Mask & VLUPDATE_BACKUPID) {
2747 if (errorcode = UnhashVolid(trans, BACKVOL, blockindex, VlEntry)) {
2748 if (errorcode != VL_NOENT)
2751 VlEntry->volumeId[BACKVOL] = updateentry->BackupId;
2752 if (errorcode = HashVolid(trans, BACKVOL, blockindex, VlEntry))
2755 if (updateentry->Mask & VLUPDATE_REPSITES) {
2756 if (updateentry->nModifiedRepsites <= 0
2757 || updateentry->nModifiedRepsites > OMAXNSERVERS)
2758 return VL_BADSERVER;
2759 for (i = 0; i < updateentry->nModifiedRepsites; i++) {
2760 /* if (updateentry->RepsitesTargetServer[i] < 0 || updateentry->RepsitesTargetServer[i] > MAXSERVERID)
2761 return VL_BADSERVER; */
2762 if (updateentry->RepsitesTargetPart[i] < 0
2763 || updateentry->RepsitesTargetPart[i] > MAXPARTITIONID)
2764 return VL_BADPARTITION;
2765 if (updateentry->RepsitesMask[i] & VLUPDATE_REPS_DELETE) {
2767 repsite_exists(VlEntry,
2768 IpAddrToRelAddr(updateentry->
2769 RepsitesTargetServer[i],
2771 updateentry->RepsitesTargetPart[i])) !=
2773 repsite_compress(VlEntry, j);
2775 return VL_NOREPSERVER;
2777 if (updateentry->RepsitesMask[i] & VLUPDATE_REPS_ADD) {
2778 /* if (updateentry->RepsitesNewServer[i] < 0 || updateentry->RepsitesNewServer[i] > MAXSERVERID)
2779 return VL_BADSERVER; */
2780 if (updateentry->RepsitesNewPart[i] < 0
2781 || updateentry->RepsitesNewPart[i] > MAXPARTITIONID)
2782 return VL_BADPARTITION;
2785 IpAddrToRelAddr(updateentry->RepsitesNewServer[i],
2787 updateentry->RepsitesNewPart[i]) != -1)
2788 return VL_DUPREPSERVER;
2790 VlEntry->serverNumber[j] != BADSERVERID
2791 && j < OMAXNSERVERS; j++);
2792 if (j >= OMAXNSERVERS)
2795 IpAddrToRelAddr(updateentry->RepsitesNewServer[i],
2797 return VL_BADSERVER;
2798 VlEntry->serverNumber[j] = serverindex;
2799 VlEntry->serverPartition[j] = updateentry->RepsitesNewPart[i];
2800 if (updateentry->RepsitesNewFlags[i] < 0
2801 || updateentry->RepsitesNewFlags[i] > MAXSERVERFLAG)
2802 return VL_BADSERVERFLAG;
2803 VlEntry->serverFlags[j] = updateentry->RepsitesNewFlags[i];
2805 if (updateentry->RepsitesMask[i] & VLUPDATE_REPS_MODSERV) {
2806 /*n if (updateentry->RepsitesNewServer[i] < 0 || updateentry->RepsitesNewServer[i] > MAXSERVERID)
2807 return VL_BADSERVER; */
2809 repsite_exists(VlEntry,
2810 IpAddrToRelAddr(updateentry->
2811 RepsitesTargetServer[i],
2813 updateentry->RepsitesTargetPart[i])) !=
2815 VlEntry->serverNumber[j] =
2816 IpAddrToRelAddr(updateentry->RepsitesNewServer[i],
2819 return VL_NOREPSERVER;
2821 if (updateentry->RepsitesMask[i] & VLUPDATE_REPS_MODPART) {
2822 if (updateentry->RepsitesNewPart[i] < 0
2823 || updateentry->RepsitesNewPart[i] > MAXPARTITIONID)
2824 return VL_BADPARTITION;
2826 repsite_exists(VlEntry,
2827 IpAddrToRelAddr(updateentry->
2828 RepsitesTargetServer[i],
2830 updateentry->RepsitesTargetPart[i])) !=
2832 VlEntry->serverPartition[j] =
2833 updateentry->RepsitesNewPart[i];
2835 return VL_NOREPSERVER;
2837 if (updateentry->RepsitesMask[i] & VLUPDATE_REPS_MODFLAG) {
2839 repsite_exists(VlEntry,
2840 IpAddrToRelAddr(updateentry->
2841 RepsitesTargetServer[i],
2843 updateentry->RepsitesTargetPart[i])) !=
2845 if (updateentry->RepsitesNewFlags[i] < 0
2846 || updateentry->RepsitesNewFlags[i] > MAXSERVERFLAG)
2847 return VL_BADSERVERFLAG;
2848 VlEntry->serverFlags[j] =
2849 updateentry->RepsitesNewFlags[i];
2851 return VL_NOREPSERVER;
2859 /* Check if the specified [server,partition] entry is found in the vldb entry's repsite table; it's offset in the table is returned, if it's present there. */
2861 repsite_exists(VlEntry, server, partition)
2862 struct nvlentry *VlEntry;
2863 int server, partition;
2867 for (i = 0; VlEntry->serverNumber[i] != BADSERVERID && i < OMAXNSERVERS;
2869 if ((VlEntry->serverNumber[i] == server)
2870 && (VlEntry->serverPartition[i] == partition))
2878 /* Repsite table compression: used when deleting a repsite entry so that all active repsite entries are on the top of the table. */
2880 repsite_compress(VlEntry, offset)
2881 struct nvlentry *VlEntry;
2884 int repsite_offset = offset;
2886 VlEntry->serverNumber[repsite_offset] != BADSERVERID
2887 && repsite_offset < OMAXNSERVERS - 1; repsite_offset++) {
2888 VlEntry->serverNumber[repsite_offset] =
2889 VlEntry->serverNumber[repsite_offset + 1];
2890 VlEntry->serverPartition[repsite_offset] =
2891 VlEntry->serverPartition[repsite_offset + 1];
2892 VlEntry->serverFlags[repsite_offset] =
2893 VlEntry->serverFlags[repsite_offset + 1];
2895 VlEntry->serverNumber[repsite_offset] = BADSERVERID;
2899 /* Convert from the internal (compacted) vldb entry to the external representation used by the interface. */
2901 vlentry_to_vldbentry(VlEntry, VldbEntry)
2902 struct nvlentry *VlEntry;
2903 struct vldbentry *VldbEntry;
2907 memset(VldbEntry, 0, sizeof(struct vldbentry));
2908 strncpy(VldbEntry->name, VlEntry->name, sizeof(VldbEntry->name));
2909 for (i = 0; i < OMAXNSERVERS; i++) {
2910 if (VlEntry->serverNumber[i] == BADSERVERID)
2912 if ((HostAddress[j = VlEntry->serverNumber[i]] & 0xff000000) ==
2914 struct extentaddr *exp;
2917 base = (HostAddress[j] >> 16) & 0xff;
2918 index = HostAddress[j] & 0x0000ffff;
2919 exp = &ex_addr[base][index];
2920 /* For now return the first ip address back */
2921 for (j = 0; j < VL_MAXIPADDRS_PERMH; j++) {
2922 if (exp->ex_addrs[j]) {
2923 VldbEntry->serverNumber[i] = ntohl(exp->ex_addrs[j]);
2928 VldbEntry->serverNumber[i] =
2929 HostAddress[VlEntry->serverNumber[i]];
2930 VldbEntry->serverPartition[i] = VlEntry->serverPartition[i];
2931 VldbEntry->serverFlags[i] = VlEntry->serverFlags[i];
2933 VldbEntry->nServers = i;
2934 for (i = 0; i < MAXTYPES; i++)
2935 VldbEntry->volumeId[i] = VlEntry->volumeId[i];
2936 VldbEntry->cloneId = VlEntry->cloneId;
2937 VldbEntry->flags = VlEntry->flags;
2941 /* Convert from the internal (compacted) vldb entry to the external representation used by the interface. */
2943 vlentry_to_nvldbentry(VlEntry, VldbEntry)
2944 struct nvlentry *VlEntry;
2945 struct nvldbentry *VldbEntry;
2949 memset(VldbEntry, 0, sizeof(struct vldbentry));
2950 strncpy(VldbEntry->name, VlEntry->name, sizeof(VldbEntry->name));
2951 for (i = 0; i < NMAXNSERVERS; i++) {
2952 if (VlEntry->serverNumber[i] == BADSERVERID)
2954 if ((HostAddress[j = VlEntry->serverNumber[i]] & 0xff000000) ==
2956 struct extentaddr *exp;
2959 base = (HostAddress[j] >> 16) & 0xff;
2960 index = HostAddress[j] & 0x0000ffff;
2961 exp = &ex_addr[base][index];
2962 /* For now return the first ip address back */
2963 for (j = 0; j < VL_MAXIPADDRS_PERMH; j++) {
2964 if (exp->ex_addrs[j]) {
2965 VldbEntry->serverNumber[i] = ntohl(exp->ex_addrs[j]);
2970 VldbEntry->serverNumber[i] =
2971 HostAddress[VlEntry->serverNumber[i]];
2972 VldbEntry->serverPartition[i] = VlEntry->serverPartition[i];
2973 VldbEntry->serverFlags[i] = VlEntry->serverFlags[i];
2975 VldbEntry->nServers = i;
2976 for (i = 0; i < MAXTYPES; i++)
2977 VldbEntry->volumeId[i] = VlEntry->volumeId[i];
2978 VldbEntry->cloneId = VlEntry->cloneId;
2979 VldbEntry->flags = VlEntry->flags;
2983 vlentry_to_uvldbentry(VlEntry, VldbEntry)
2984 struct nvlentry *VlEntry;
2985 struct uvldbentry *VldbEntry;
2989 memset(VldbEntry, 0, sizeof(struct vldbentry));
2990 strncpy(VldbEntry->name, VlEntry->name, sizeof(VldbEntry->name));
2991 for (i = 0; i < NMAXNSERVERS; i++) {
2992 if (VlEntry->serverNumber[i] == BADSERVERID)
2994 VldbEntry->serverFlags[i] = VlEntry->serverFlags[i];
2995 VldbEntry->serverUnique[i] = 0;
2996 if ((HostAddress[j = VlEntry->serverNumber[i]] & 0xff000000) ==
2998 struct extentaddr *exp;
3002 base = (HostAddress[j] >> 16) & 0xff;
3003 index = HostAddress[j] & 0x0000ffff;
3004 exp = &ex_addr[base][index];
3005 tuuid = exp->ex_hostuuid;
3006 afs_ntohuuid(&tuuid);
3007 VldbEntry->serverFlags[i] |= VLSERVER_FLAG_UUID;
3008 VldbEntry->serverNumber[i] = tuuid;
3009 VldbEntry->serverUnique[i] = ntohl(exp->ex_uniquifier);
3011 VldbEntry->serverNumber[i].time_low =
3012 HostAddress[VlEntry->serverNumber[i]];
3014 VldbEntry->serverPartition[i] = VlEntry->serverPartition[i];
3017 VldbEntry->nServers = i;
3018 for (i = 0; i < MAXTYPES; i++)
3019 VldbEntry->volumeId[i] = VlEntry->volumeId[i];
3020 VldbEntry->cloneId = VlEntry->cloneId;
3021 VldbEntry->flags = VlEntry->flags;
3024 #define LEGALCHARS ".ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"
3027 /* Verify that the volname is a valid volume name. */
3029 InvalidVolname(volname)
3036 slen = strlen(volname);
3037 if (slen >= VL_MAXNAMELEN)
3039 return (slen != strspn(volname, map));
3043 /* Verify that the given volume type is valid. */
3045 InvalidVoltype(voltype)
3048 if (voltype != RWVOL && voltype != ROVOL && voltype != BACKVOL)
3055 InvalidOperation(voloper)
3058 if (voloper != VLOP_MOVE && voloper != VLOP_RELEASE
3059 && voloper != VLOP_BACKUP && voloper != VLOP_DELETE
3060 && voloper != VLOP_DUMP)
3066 InvalidReleasetype(releasetype)
3067 afs_int32 releasetype;
3069 if ((releasetype & LOCKREL_TIMESTAMP) || (releasetype & LOCKREL_OPCODE)
3070 || (releasetype & LOCKREL_AFSID))
3076 IpAddrToRelAddr(ipaddr, atrans)
3077 struct ubik_trans *atrans;
3078 register afs_uint32 ipaddr;
3081 register afs_int32 code, base, index;
3082 struct extentaddr *exp;
3084 for (i = 0; i <= MAXSERVERID; i++) {
3085 if (HostAddress[i] == ipaddr)
3087 if ((HostAddress[i] & 0xff000000) == 0xff000000) {
3088 base = (HostAddress[i] >> 16) & 0xff;
3089 index = HostAddress[i] & 0x0000ffff;
3090 if (base >= VL_MAX_ADDREXTBLKS) {
3092 ("Internal error: Multihome extent base is too large. Base %d index %d\n",
3094 return -1; /* EINVAL */
3096 if (index >= VL_MHSRV_PERBLK) {
3098 ("Internal error: Multihome extent index is too large. Base %d index %d\n",
3100 return -1; /* EINVAL */
3102 if (!ex_addr[base]) {
3104 ("Internal error: Multihome extent does not exist. Base %d\n",
3106 return -1; /* EINVAL */
3108 exp = &ex_addr[base][index];
3109 for (j = 0; j < VL_MAXIPADDRS_PERMH; j++) {
3110 if (exp->ex_addrs[j] && (ntohl(exp->ex_addrs[j]) == ipaddr)) {
3117 /* allocate the new server a server id pronto */
3119 for (i = 0; i <= MAXSERVERID; i++) {
3120 if (cheader.IpMappedAddr[i] == 0) {
3121 cheader.IpMappedAddr[i] = htonl(ipaddr);
3124 DOFFSET(0, &cheader, &cheader.IpMappedAddr[i]),
3125 (char *)&cheader.IpMappedAddr[i],
3127 HostAddress[i] = ipaddr;
3138 ChangeIPAddr(ipaddr1, ipaddr2, atrans)
3139 struct ubik_trans *atrans;
3140 register afs_uint32 ipaddr1, ipaddr2;
3144 struct extentaddr *exp = NULL;
3148 afs_int32 blockindex, count;
3150 struct nvlentry tentry;
3153 return VL_CREATEFAIL;
3155 /* Don't let addr change to 256.*.*.* : Causes internal error below */
3156 if ((ipaddr2 & 0xff000000) == 0xff000000)
3157 return (VL_BADSERVER);
3159 /* If we are removing an address, ip1 will be -1 and ip2 will be
3160 * the original address. This prevents an older revision vlserver
3161 * from removing the IP address (won't find server 0xfffffff in
3162 * the VLDB). An older revision vlserver does not have the check
3163 * to see if any volumes exist on the server being removed.
3165 if (ipaddr1 == 0xffffffff) {
3170 for (i = 0; i <= MAXSERVERID; i++) {
3171 if ((HostAddress[i] & 0xff000000) == 0xff000000) {
3172 base = (HostAddress[i] >> 16) & 0xff;
3173 index = HostAddress[i] & 0x0000ffff;
3174 if ((base >= VL_MAX_ADDREXTBLKS) || (index >= VL_MHSRV_PERBLK)) {
3176 ("Internal error: Multihome extent addr is too large. Base %d index %d\n",
3178 return -1; /* EINVAL */
3181 exp = &ex_addr[base][index];
3182 for (mhidx = 0; mhidx < VL_MAXIPADDRS_PERMH; mhidx++) {
3183 if (!exp->ex_addrs[mhidx])
3185 if (ntohl(exp->ex_addrs[mhidx]) == ipaddr1)
3188 if (mhidx < VL_MAXIPADDRS_PERMH) {
3191 } else if (HostAddress[i] == ipaddr1) {
3197 if (i >= MAXSERVERID) {
3198 return VL_NOENT; /* not found */
3201 /* If we are removing a server entry, a volume cannot
3202 * exist on the server. If one does, don't remove the
3203 * server entry: return error "volume entry exists".
3206 for (blockindex = NextEntry(atrans, 0, &tentry, &count); blockindex;
3207 blockindex = NextEntry(atrans, blockindex, &tentry, &count)) {
3208 if (++pollcount > 50) {
3209 #ifndef AFS_PTHREAD_ENV
3214 for (j = 0; j < NMAXNSERVERS; j++) {
3215 if (tentry.serverNumber[j] == BADSERVERID)
3217 if (tentry.serverNumber[j] == i) {
3224 /* Log a message saying we are changing/removing an IP address */
3226 ("The following IP address is being %s:\n",
3227 (ipaddr2 ? "changed" : "removed")));
3228 VLog(0, (" entry %d: ", i));
3231 for (mhidx = 0; mhidx < VL_MAXIPADDRS_PERMH; mhidx++) {
3232 if (!exp->ex_addrs[mhidx])
3236 PADDR(ntohl(exp->ex_addrs[mhidx]));
3248 /* Change the registered uuuid addresses */
3250 memset(&tuuid, 0, sizeof(afsUUID));
3251 afs_htonuuid(&tuuid);
3252 exp->ex_hostuuid = tuuid;
3255 DOFFSET(ntohl(ex_addr[0]->ex_contaddrs[base]),
3256 (char *)ex_addr[base], (char *)exp),
3257 (char *)&tuuid, sizeof(tuuid));
3262 /* Now change the host address entry */
3263 cheader.IpMappedAddr[i] = htonl(ipaddr2);
3265 vlwrite(atrans, DOFFSET(0, &cheader, &cheader.IpMappedAddr[i]),
3267 &cheader.IpMappedAddr[i], sizeof(afs_int32));
3268 HostAddress[i] = ipaddr2;
3275 /* see if the vlserver is back yet */
3277 SVL_ProbeServer(rxcall)
3278 struct rx_call *rxcall;