vos-command-enhancements-20011008
authorJeffrey Hutzelman <jhutz@cmu.edu>
Mon, 8 Oct 2001 23:55:41 +0000 (23:55 +0000)
committerDerrick Brashear <shadow@dementia.org>
Mon, 8 Oct 2001 23:55:41 +0000 (23:55 +0000)
- Adds the -crypt option, which causes rx connections to be encrypted

  - Adds the 'vos setfields' command, which allows volume info fields to
    be set.  Currently, this command allows a volume's quota to be set,
    and allows its dayuse counter to be manually cleared.  At present,
    no other changes are supported by the volserver RPC interface.

  - Adds the 'vos changeloc' command, which allows the VLDB's idea of the
    location of an RW volume to be explicitly changed without actually
    moving the volume.  This can be used in cases where the VLDB has the
    wrong idea of the location of a volume for some reason.  It is
    somewhat more predictable and easy to understand than the syncserv
    and syncvldb commands.

  - Adds the -offline option to 'vos restore'.  This option causes the
    restored volume to be left offline.  This functionality was already
    present in the code but previously had no user interface.

  - Adds the -readonly option to 'vos restore'.  This option causes the
    restored volume to be an RO volume.  It is not permitted to restore
    an RO volume when the associated RW volume already exists.  While
    it is possible to restore an RW volume where an RO volume exists,
    caution should be used to avoid doing this with VLDB entries created
    by 'vos restore -readonly', since such entries have their ROVOL and
    RWVOL ID's set to the same thing.

src/volser/volser.p.h
src/volser/vos.c
src/volser/vsprocs.c
src/volser/vsutils.c

index 4bb1363..74f580d 100644 (file)
@@ -152,6 +152,7 @@ struct partList {   /*used by the backup system */
 /* Values for the UV_RestoreVolume flags parameter */
 #define RV_FULLRST 0x1
 #define RV_OFFLINE 0x2
+#define RV_RDONLY  0x10000
 
 #endif /* _VOLSER_ */
 
index 3957954..6f85065 100644 (file)
@@ -67,6 +67,7 @@ cmd_AddParm(ts, "-cell", CMD_SINGLE, CMD_OPTIONAL, "cell name");\
 cmd_AddParm(ts, "-noauth", CMD_FLAG, CMD_OPTIONAL, "don't authenticate");\
 cmd_AddParm(ts, "-localauth",CMD_FLAG,CMD_OPTIONAL,"use server tickets");\
 cmd_AddParm(ts, "-verbose", CMD_FLAG, CMD_OPTIONAL, "verbose");\
+cmd_AddParm(ts, "-crypt", CMD_FLAG, CMD_OPTIONAL, "encrypt commands");\
 
 #define ERROR_EXIT(code) {error=(code); goto error_exit;}
 
@@ -79,6 +80,8 @@ const char *confdir;
 extern struct rx_connection *UV_Bind();
 extern  struct rx_securityClass *rxnull_NewClientSecurityObject();
 extern int UV_SetSecurity();
+extern int UV_SetVolumeInfo();
+extern int vsu_SetCrypt();
 extern VL_SetLock();
 extern VL_ReleaseLock();
 extern VL_DeleteEntry();
@@ -1275,6 +1278,86 @@ register struct cmd_syndesc *as;
 }
 
 /*------------------------------------------------------------------------
+ * PRIVATE SetFields
+ *
+ * Description:
+ *     Routine used to change the status of a single volume.
+ *
+ * Arguments:
+ *     as : Ptr to parsed command line arguments.
+ *
+ * Returns:
+ *     0 for a successful operation,
+ *     Otherwise, one of the ubik or VolServer error values.
+ *
+ * Environment:
+ *     Nothing interesting.
+ *
+ * Side Effects:
+ *     As advertised.
+ *------------------------------------------------------------------------
+ */
+static SetFields(as)
+register struct cmd_syndesc *as;
+{
+    struct nvldbentry entry;
+    afs_int32 vcode = 0;
+    volintInfo info;
+    afs_int32 volid;
+    afs_int32 code, err;
+    afs_int32 aserver, apart;
+    int previdx = -1;
+
+    volid = vsu_GetVolumeID(as->parms[0].items->data, cstruct, &err);    /* -id */
+    if (volid == 0) {
+       if (err) PrintError("", err);
+       else fprintf(STDERR, "Unknown volume ID or name '%s'\n", as->parms[0].items->data);
+       return -1;
+    }
+
+    code = VLDB_GetEntryByID (volid, RWVOL, &entry);
+    if (code) {
+       fprintf(STDERR, "Could not fetch the entry for volume number %u from VLDB \n",volid);
+       return (code);
+    }
+    MapHostToNetwork(&entry);
+
+    GetServerAndPart(&entry, RWVOL, &aserver, &apart, &previdx);
+    if (previdx == -1) {
+       fprintf(STDERR,"Volume %s does not exist in VLDB\n\n", as->parms[0].items->data);
+       return (ENOENT);
+    }
+
+    memset(&info, 0, sizeof(info));
+    info.volid    = volid;
+    info.type     = RWVOL;
+    info.dayUse   = -1;
+    info.maxquota = -1;
+    info.flags    = -1;
+    info.spare0   = -1;
+    info.spare1   = -1;
+    info.spare2   = -1;
+    info.spare3   = -1;
+
+    if (as->parms[1].items) {
+       /* -max <quota> */
+       code = util_GetInt32(as->parms[1].items->data, &info.maxquota);
+       if (code) {
+           fprintf(STDERR,"invalid quota value\n");
+           return code;
+       }
+    }
+    if (as->parms[2].items) {
+       /* -clearuse */
+       info.dayUse = 0;
+    }
+    code = UV_SetVolumeInfo(aserver, apart, volid, &info);
+    if (code)
+       fprintf(STDERR,"Could not update volume info fields for volume number %u\n",volid);
+    return (code);
+}
+
+/*------------------------------------------------------------------------
  * PRIVATE volOnline
  *
  * Description:
@@ -1882,7 +1965,7 @@ register struct cmd_syndesc *as;
 {    
         afs_int32 avolid, aserver, apart, code,vcode, err;
        afs_int32 aoverwrite = ASK;
-       int restoreflags;
+       int restoreflags, readonly = 0, offline = 0, voltype = RWVOL;
        char prompt;
        char afilename[NameLen], avolname[VOLSER_MAXVOLNAME +1],apartName[10];
        char volname[VOLSER_MAXVOLNAME +1];
@@ -1922,6 +2005,11 @@ register struct cmd_syndesc *as;
                exit(1);
            }
        }
+       if (as->parms[6].items) offline = 1;
+       if (as->parms[7].items) {
+           readonly = 1;
+           voltype = ROVOL;
+       }
 
        aserver = GetServer(as->parms[0].items->data);
        if (aserver == 0) {
@@ -1968,17 +2056,19 @@ register struct cmd_syndesc *as;
                fprintf(STDERR,"Volume does not exist; Will perform a full restore\n");
        }
 
-       else if (Lp_GetRwIndex(&entry) == -1) {    /* RW volume does not exist - do a full */
-          restoreflags = RV_FULLRST;
-          if ( (aoverwrite == INC) || (aoverwrite == ABORT) )
-             fprintf(STDERR,"RW Volume does not exist; Will perform a full restore\n");
+       else if ((!readonly && Lp_GetRwIndex(&entry) == -1)        /* RW volume does not exist - do a full */
+            ||  (readonly && !Lp_ROMatch(0, 0, &entry))) {        /* RO volume does not exist - do a full */
+           restoreflags = RV_FULLRST;
+           if ( (aoverwrite == INC) || (aoverwrite == ABORT) )
+               fprintf(STDERR,"%s Volume does not exist; Will perform a full restore\n",
+                       readonly ? "RO" : "RW");
 
-          if (avolid == 0) {
-             avolid = entry.volumeId[RWVOL];
-          }
-          else if (entry.volumeId[RWVOL] != 0  && entry.volumeId[RWVOL] != avolid) {
-             avolid = entry.volumeId[RWVOL];
-          }
+           if (avolid == 0) {
+               avolid = entry.volumeId[voltype];
+           }
+           else if (entry.volumeId[voltype] != 0  && entry.volumeId[voltype] != avolid) {
+               avolid = entry.volumeId[voltype];
+           }
        }
 
        else {                    /* volume exists - do we do a full incremental or abort */
@@ -1987,10 +2077,10 @@ register struct cmd_syndesc *as;
            char   c, dc;
 
            if(avolid == 0) {
-               avolid = entry.volumeId[RWVOL];
+               avolid = entry.volumeId[voltype];
            }
-           else if(entry.volumeId[RWVOL] != 0  && entry.volumeId[RWVOL] != avolid) {
-               avolid = entry.volumeId[RWVOL];
+           else if(entry.volumeId[voltype] != 0  && entry.volumeId[voltype] != avolid) {
+               avolid = entry.volumeId[voltype];
            }
            
            /* A file name was specified  - check if volume is on another partition */
@@ -2014,14 +2104,14 @@ register struct cmd_syndesc *as;
                /* Ask what to do */
                if (vol_elsewhere) {
                    fprintf(STDERR,"The volume %s %u already exists on a different server/part\n",
-                           volname, entry.volumeId[RWVOL]);
+                           volname, entry.volumeId[voltype]);
                    fprintf(STDERR, 
                            "Do you want to do a full restore or abort? [fa](a): ");
                }
                else
                {
                    fprintf(STDERR,"The volume %s %u already exists in the VLDB\n",
-                           volname, entry.volumeId[RWVOL]);
+                           volname, entry.volumeId[voltype]);
                    fprintf(STDERR, 
                            "Do you want to do a full/incremental restore or abort? [fia](a): ");
                }
@@ -2044,12 +2134,14 @@ register struct cmd_syndesc *as;
                restoreflags = 0;
                if (vol_elsewhere) {
                    fprintf(STDERR,
-                           "RW volume %u already exists on a different server/part; not allowed\n",
-                           avolid);
+                           "%s volume %u already exists on a different server/part; not allowed\n",
+                           readonly ? "RO" : "RW", avolid);
                    exit(1);
                }
            }
        }
+       if (offline)  restoreflags |= RV_OFFLINE;
+       if (readonly) restoreflags |= RV_RDONLY;
        code = UV_RestoreVolume(aserver, apart, avolid, avolname,
                                restoreflags, WriteData, afilename);
        if (code) {
@@ -2167,6 +2259,42 @@ register struct cmd_syndesc *as;
        fprintf(STDOUT,"Removed replication site %s %s for volume %s\n",as->parms[0].items->data,apartName,as->parms[2].items->data);
     return 0;
 }
+static ChangeLocation(as)
+register struct cmd_syndesc *as;
+{
+   afs_int32 avolid, aserver, apart,code, err;
+   char apartName[10];
+
+       avolid = vsu_GetVolumeID(as->parms[2].items->data, cstruct, &err);
+       if (avolid == 0) {
+           if (err) PrintError("", err);
+           else fprintf(STDERR, "vos: can't find volume '%s'\n", as->parms[2].items->data);
+           exit(1);
+       }
+       aserver = GetServer(as->parms[0].items->data);
+       if (aserver == 0) {
+           fprintf(STDERR,"vos: server '%s' not found in host table\n", as->parms[0].items->data);
+           exit(1);
+       }
+       apart = volutil_GetPartitionID(as->parms[1].items->data);
+       if (apart < 0) {
+           fprintf(STDERR,"vos: could not interpret partition name '%s'\n",as->parms[1].items->data );
+           exit(1);
+       }
+       if (!IsPartValid(apart,aserver,&code)){/*check for validity of the partition */
+           if(code) PrintError("",code);
+           else fprintf(STDERR,"vos : partition %s does not exist on the server\n",as->parms[1].items->data);
+           exit(1);
+       }
+       code = UV_ChangeLocation(aserver, apart, avolid);
+       if (code) {
+           PrintDiagnostics("addsite", code);
+           exit(1);
+       }
+       MapPartIdIntoName(apart,apartName);
+       fprintf(STDOUT,"Changed location to %s %s for volume %s\n",as->parms[0].items->data, apartName,as->parms[2].items->data);
+   return 0;
+}
 
 static ListPartitions(as)
 register struct cmd_syndesc *as;
@@ -3799,6 +3927,8 @@ char *arock; {
        tcell = as->parms[12].items->data;
     if(as->parms[14].items)    /* -serverauth specified */
        sauth = 1;
+    if(as->parms[16].items)    /* -crypt specified */
+       vsu_SetCrypt(1);
     if (code = vsu_ClientInit((as->parms[13].items != 0), confdir, tcell, sauth,
                              &cstruct, UV_SetSecurity)) {
        fprintf(STDERR,"could not initialize VLDB library (code=%u) \n",code);
@@ -3896,12 +4026,22 @@ char **argv; {
     cmd_AddParm(ts, "-file", CMD_SINGLE,CMD_OPTIONAL, "dump file");
     cmd_AddParm(ts, "-id", CMD_SINGLE,CMD_OPTIONAL,  "volume ID");
     cmd_AddParm(ts, "-overwrite", CMD_SINGLE,CMD_OPTIONAL,  "abort | full | incremental");
+    cmd_AddParm(ts, "-offline", CMD_FLAG, CMD_OPTIONAL,
+               "leave restored volume offline");
+    cmd_AddParm(ts, "-readonly", CMD_FLAG, CMD_OPTIONAL,
+               "make restored volume read-only");
     COMMONPARMS;
 
     ts = cmd_CreateSyntax("unlock", LockReleaseCmd, 0, "release lock on VLDB entry for a volume");
     cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID");
     COMMONPARMS;
 
+    ts = cmd_CreateSyntax("changeloc", ChangeLocation, 0, "change an RW volume's location in the VLDB");
+    cmd_AddParm(ts, "-server", CMD_SINGLE, 0, "machine name for new location");
+    cmd_AddParm(ts, "-partition", CMD_SINGLE, 0, "partition name for new location");
+    cmd_AddParm(ts, "-id", CMD_SINGLE, 0, "volume name or ID");
+    COMMONPARMS;
+
     ts = cmd_CreateSyntax("addsite", AddSite, 0, "add a replication site");
     cmd_AddParm(ts, "-server", CMD_SINGLE, 0, "machine name for new site");
     cmd_AddParm(ts, "-partition", CMD_SINGLE, 0, "partition name for new site");
@@ -3955,6 +4095,12 @@ char **argv; {
     COMMONPARMS;
     cmd_CreateAlias (ts, "volinfo");
 
+    ts = cmd_CreateSyntax("setfields", SetFields, 0, "change volume info fields");
+    cmd_AddParm(ts, "-id",        CMD_SINGLE, 0, "volume name or ID");
+    cmd_AddParm(ts, "-maxquota", CMD_SINGLE, CMD_OPTIONAL, "quota (KB)");
+    cmd_AddParm(ts, "-clearuse",  CMD_FLAG,   CMD_OPTIONAL, "clear dayUse");
+    COMMONPARMS;
+
     ts = cmd_CreateSyntax("offline", volOffline, 0, (char *) CMD_HIDDEN);
     cmd_AddParm(ts, "-server",    CMD_SINGLE, 0, "server name");
     cmd_AddParm(ts, "-partition", CMD_SINGLE, 0, "partition name");
index 5e5a9c0..5ef020f 100644 (file)
@@ -2561,7 +2561,7 @@ UV_RestoreVolume(toserver, topart, tovolid, tovolname, flags, WriteData, rock)
     int islocked;
     struct restoreCookie cookie;
     int reuseID;
-    afs_int32 newDate, volflag;
+    afs_int32 newDate, volflag, voltype, volsertype;
     int index, same, errcode;
     char apartName[10];
 
@@ -2577,6 +2577,14 @@ UV_RestoreVolume(toserver, topart, tovolid, tovolname, flags, WriteData, rock)
     totid = 0;
     temptid = 0;
 
+    if (flags & RV_RDONLY) {
+       voltype    = ROVOL;
+       volsertype = volser_RO;
+    } else {
+       voltype    = RWVOL;
+       volsertype = volser_RW;
+    }
+
     pvolid = tovolid;
     toconn = UV_Bind(toserver, AFSCONF_VOLUMEPORT);
     if(pvolid == 0) {/*alot a new id if needed */
@@ -2589,8 +2597,19 @@ UV_RestoreVolume(toserver, topart, tovolid, tovolname, flags, WriteData, rock)
                goto refail;
            }
            reuseID = 0;
-        }
-       else{
+        } else if (flags & RV_RDONLY) {
+           if (entry.flags & RW_EXISTS) {
+               fprintf(STDERR,"Entry for ReadWrite volume %s already exists!\n",entry.name);
+               error = VOLSERBADOP;
+               goto refail;
+           }
+           if (!entry.volumeId[ROVOL]) {
+               fprintf(STDERR,"Existing entry for volume %s has no ReadOnly ID\n",tovolname);
+               error = VOLSERBADOP;
+               goto refail;
+           }
+           pvolid = entry.volumeId[ROVOL];
+       } else {
            pvolid = entry.volumeId[RWVOL];
        }
     }/* at this point we have a volume id to use/reuse for the volume to be restored */
@@ -2604,9 +2623,7 @@ UV_RestoreVolume(toserver, topart, tovolid, tovolname, flags, WriteData, rock)
     fprintf(STDOUT,"Restoring volume %s Id %u on server %s partition %s ..", tovolname,
            pvolid, hostutil_GetNameByINet(toserver), partName);
     fflush(STDOUT);
-    /*what should the volume be restored as ? rw or ro or bk ?
-      right now the default is rw always */
-    code = AFSVolCreateVolume(toconn, topart, tovolname, volser_RW, 0,&pvolid, &totid);
+    code = AFSVolCreateVolume(toconn, topart, tovolname, volsertype, 0,&pvolid, &totid);
     if (code){
        if (flags & RV_FULLRST) { /* full restore: delete then create anew */
            if(verbose) {
@@ -2640,7 +2657,7 @@ UV_RestoreVolume(toserver, topart, tovolid, tovolname, flags, WriteData, rock)
                goto refail;
            }
            if (verbose) fprintf(STDOUT," done\n");
-           code = AFSVolCreateVolume(toconn, topart, tovolname, volser_RW, 0,&pvolid, &totid);
+           code = AFSVolCreateVolume(toconn, topart, tovolname, volsertype, 0,&pvolid, &totid);
            if (code){
                fprintf(STDERR,"Could not create new volume %u\n",pvolid);
                error = code;
@@ -2657,7 +2674,7 @@ UV_RestoreVolume(toserver, topart, tovolid, tovolname, flags, WriteData, rock)
        }
     }
     cookie.parent = pvolid;
-    cookie.type = RWVOL;
+    cookie.type = voltype;
     cookie.clone = 0;
     strncpy(cookie.name,tovolname,VOLSER_OLDMAXVOLNAME);
 
@@ -2683,11 +2700,11 @@ UV_RestoreVolume(toserver, topart, tovolid, tovolname, flags, WriteData, rock)
     }
     code = AFSVolGetStatus(toconn,totid, &tstatus);
     if(code) {
-       fprintf(STDERR,"Could not get status information about the volume %u\n",tovolid);
+       fprintf(STDERR,"Could not get status information about the volume %u\n",pvolid);
        error = code;
        goto refail;
     }
-    code = AFSVolSetIdsTypes(toconn,totid, tovolname, RWVOL, pvolid,0,0);
+    code = AFSVolSetIdsTypes(toconn,totid, tovolname, voltype, pvolid,0,0);
     if(code) {
        fprintf(STDERR,"Could not set the right type and ID on %u\n",pvolid); 
        error = code;
@@ -2726,7 +2743,7 @@ UV_RestoreVolume(toserver, topart, tovolid, tovolname, flags, WriteData, rock)
         /* Volume was restored on the file server, update the 
         * VLDB to reflect the change.
         */
-       vcode = VLDB_GetEntryByID(pvolid,RWVOL, &entry);
+       vcode = VLDB_GetEntryByID(pvolid,voltype, &entry);
        if(vcode && vcode != VL_NOENT && vcode != VL_ENTDELETED) {
            fprintf(STDERR,"Could not fetch the entry for volume number %u from VLDB \n",pvolid);
            error = vcode;
@@ -2740,9 +2757,11 @@ UV_RestoreVolume(toserver, topart, tovolid, tovolname, flags, WriteData, rock)
            entry.nServers = 1;
            entry.serverNumber[0] = toserver;/*should be indirect */
            entry.serverPartition[0] = topart;
-           entry.serverFlags[0] = ITSRWVOL;
-           entry.flags = RW_EXISTS;
-           if(tstatus.cloneID != 0){
+           entry.serverFlags[0] = (flags & RV_RDONLY) ? ITSROVOL : ITSRWVOL;
+           entry.flags = (flags & RV_RDONLY) ? RO_EXISTS : RW_EXISTS;
+           if (flags & RV_RDONLY)
+               entry.volumeId[ROVOL] = pvolid;
+           else if(tstatus.cloneID != 0){
                entry.volumeId[ROVOL] = tstatus.cloneID;/*this should come from status info on the volume if non zero */
            }
            else
@@ -2772,7 +2791,7 @@ UV_RestoreVolume(toserver, topart, tovolid, tovolname, flags, WriteData, rock)
                EnumerateEntry(&entry);
                fprintf(STDOUT,"------- New entry -------\n");
            }
-           vcode = ubik_Call(VL_SetLock,cstruct, 0, pvolid, RWVOL, VLOP_RESTORE);
+           vcode = ubik_Call(VL_SetLock,cstruct, 0, pvolid, voltype, VLOP_RESTORE);
            if(vcode) {
                fprintf(STDERR,"Could not lock the entry for volume number %u \n",pvolid);
                error = vcode;
@@ -2782,12 +2801,16 @@ UV_RestoreVolume(toserver, topart, tovolid, tovolname, flags, WriteData, rock)
            strcpy(entry.name, tovolname);
 
            /* Update the vlentry with the new information */
-           index = Lp_GetRwIndex(&entry);
+           if (flags & RV_RDONLY)
+               index = Lp_ROMatch(toserver, topart, &entry) - 1;
+           else
+               index = Lp_GetRwIndex(&entry);
            if (index == -1) {
-              /* Add the rw site for the volume being restored */
+              /* Add the new site for the volume being restored */
               entry.serverNumber[entry.nServers]    = toserver;
               entry.serverPartition[entry.nServers] = topart;
-              entry.serverFlags[entry.nServers]     = ITSRWVOL;
+              entry.serverFlags[entry.nServers]     =
+                       (flags & RV_RDONLY) ? ITSROVOL : ITSRWVOL;
               entry.nServers++;
            } else {
               /* This volume should be deleted on the old site
@@ -2837,9 +2860,9 @@ UV_RestoreVolume(toserver, topart, tovolid, tovolname, flags, WriteData, rock)
               entry.serverPartition[index] = topart;
            }
 
-           entry.flags |= RW_EXISTS;
+           entry.flags |= (flags & RV_RDONLY) ? RO_EXISTS : RW_EXISTS;
            MapNetworkToHost(&entry,&storeEntry);
-           vcode = VLDB_ReplaceEntry(pvolid,RWVOL, &storeEntry,LOCKREL_OPCODE | LOCKREL_AFSID | LOCKREL_TIMESTAMP );
+           vcode = VLDB_ReplaceEntry(pvolid,voltype, &storeEntry,LOCKREL_OPCODE | LOCKREL_AFSID | LOCKREL_TIMESTAMP );
            if(vcode) {
                fprintf(STDERR,"Could not update the entry for volume number %u  \n",pvolid);
                error = vcode;
@@ -2857,7 +2880,7 @@ UV_RestoreVolume(toserver, topart, tovolid, tovolname, flags, WriteData, rock)
          if (!error) error = code;
       }
       if(islocked) {
-         vcode = ubik_Call(VL_ReleaseLock,cstruct, 0, pvolid, RWVOL, LOCKREL_OPCODE | LOCKREL_AFSID | LOCKREL_TIMESTAMP);
+         vcode = ubik_Call(VL_ReleaseLock,cstruct, 0, pvolid, voltype, LOCKREL_OPCODE | LOCKREL_AFSID | LOCKREL_TIMESTAMP);
          if(vcode) {
              fprintf(STDERR,"Could not release lock on the VLDB entry for the volume %u\n",pvolid);
              if(!error) error = vcode;
@@ -3062,6 +3085,55 @@ afs_int32 server, part, volid;
     return 0;
 }
 
+/*sets <server> <part> as read/write site for <volid> in the vldb */
+UV_ChangeLocation(server, part, volid)
+afs_int32 server, part, volid;
+{
+    afs_int32 vcode;
+    struct nvldbentry entry,storeEntry;
+    int index;
+
+    vcode = ubik_Call(VL_SetLock,cstruct, 0,volid,RWVOL, VLOP_ADDSITE);
+    if(vcode) {
+       fprintf(STDERR," Could not lock the VLDB entry for volume %u \n", volid);
+       PrintError("",vcode);
+       return(vcode);
+    }
+    vcode = VLDB_GetEntryByID(volid,RWVOL, &entry);
+    if(vcode) {
+       fprintf(STDERR,"Could not fetch the entry for volume number %u from VLDB \n",volid);
+       PrintError("",vcode);
+       return (vcode);
+    }
+    MapHostToNetwork(&entry);
+    index = Lp_GetRwIndex(&entry);
+    if (index < 0) {
+       /* no RW site exists  */
+       fprintf(STDERR,"No existing RW site for volume %u", volid);
+       vcode = ubik_Call(VL_ReleaseLock,cstruct, 0, volid, RWVOL, LOCKREL_OPCODE | LOCKREL_AFSID | LOCKREL_TIMESTAMP);
+       if(vcode) {
+           fprintf(STDERR,"Could not release lock on entry for volume %u \n",volid);
+           PrintError("",vcode);
+           return(vcode);
+       }
+       return VOLSERBADOP;
+    }
+    else { /* change the RW site */
+       entry.serverNumber[index] = server;
+       entry.serverPartition[index] = part;
+       MapNetworkToHost(&entry,&storeEntry);
+       vcode = VLDB_ReplaceEntry(volid,RWVOL,&storeEntry,LOCKREL_OPCODE | LOCKREL_AFSID | LOCKREL_TIMESTAMP);
+       if(vcode){ 
+           fprintf(STDERR,"Could not update entry for volume %u \n",volid);
+           PrintError("",vcode);
+           ubik_Call(VL_ReleaseLock,cstruct, 0, volid, RWVOL, LOCKREL_OPCODE | LOCKREL_AFSID | LOCKREL_TIMESTAMP);
+           return(vcode);
+       }
+       if(verbose) fprintf(STDOUT," done\n");
+    }
+    return 0;
+}
+
 /*list all the partitions on <aserver> */
 UV_ListPartitions(aserver, ptrPartList, cntp)
     afs_int32 aserver;
@@ -4911,7 +4983,7 @@ UV_SetVolume(server, partition, volid, transflag, setflag, sleeptime)
  error_exit:
   if (tid) {
      rcode = 0;
-     code = AFSVolEndTrans(conn, tid, &code);
+     code = AFSVolEndTrans(conn, tid, &rcode);
      if (code || rcode) {
         fprintf(STDERR, "SetVolumeStatus: EndTrans Failed\n");
        if (!error) error = (code ? code : rcode);
@@ -4922,6 +4994,46 @@ UV_SetVolume(server, partition, volid, transflag, setflag, sleeptime)
   return(error);
 }
 
+UV_SetVolumeInfo(server, partition, volid, infop)
+  afs_int32 server, partition, volid;
+  volintInfo *infop;
+{
+  struct rx_connection *conn = 0;
+  afs_int32 tid=0;
+  afs_int32 code, error=0, rcode;
+
+  conn = UV_Bind(server, AFSCONF_VOLUMEPORT);
+  if (!conn) {
+     fprintf(STDERR, "SetVolumeInfo: Bind Failed");
+     ERROR_EXIT(-1);
+  }
+
+  code = AFSVolTransCreate(conn, volid, partition, ITOffline, &tid);
+  if (code) {
+     fprintf(STDERR, "SetVolumeInfo: TransCreate Failed\n");
+     ERROR_EXIT(code);
+  }
+  
+  code = AFSVolSetInfo(conn, tid, infop);
+  if (code) {
+     fprintf(STDERR, "SetVolumeInfo: SetInfo Failed\n");
+     ERROR_EXIT(code);
+  }
+  
+ error_exit:
+  if (tid) {
+     rcode = 0;
+     code = AFSVolEndTrans(conn, tid, &rcode);
+     if (code || rcode) {
+        fprintf(STDERR, "SetVolumeInfo: EndTrans Failed\n");
+       if (!error) error = (code ? code : rcode);
+     }
+  }
+
+  if (conn) rx_DestroyConnection(conn);
+  return(error);
+}
+
 /*maps the host addresses in <old > (present in network byte order) to
  that in< new> (present in host byte order )*/
 void
index 4160267..3a5d1e3 100644 (file)
@@ -45,6 +45,7 @@ RCSID("$Header$");
 #include "lockdata.h"
 
 struct ubik_client *cstruct;
+static rxkad_level vsu_rxkad_level = rxkad_clear;
 extern int VL_CreateEntry(), VL_CreateEntryN();
 extern int VL_GetEntryByID(), VL_GetEntryByIDN();
 extern int VL_GetEntryByNameO(), VL_GetEntryByNameN();
@@ -366,6 +367,23 @@ afs_int32 subik_Call(aproc, aclient, aflags, p1, p2, p3, p4, p5, p6, p7, p8, p9,
 
 
 /*
+  Set encryption.  If 'cryptflag' is nonzero, encrpytion is turned on
+  for authenticated connections; if zero, encryption is turned off.
+  Calling this function always results in a level of at least rxkad_auth;
+  to get a rxkad_clear connection, simply don't call this.
+*/
+void vsu_SetCrypt(cryptflag)
+    int cryptflag;
+{
+  if (cryptflag) {
+    vsu_rxkad_level = rxkad_crypt;
+  } else {
+    vsu_rxkad_level = rxkad_auth;
+  }
+}
+
+
+/*
   Get the appropriate type of ubik client structure out from the system.
 */
 afs_int32 vsu_ClientInit(noAuthFlag, confDir, cellName, sauth, uclientp, secproc)
@@ -463,7 +481,7 @@ afs_int32 vsu_ClientInit(noAuthFlag, confDir, cellName, sauth, uclientp, secproc
             break;
           case 2:
             sc = (struct rx_securityClass *)rxkad_NewClientSecurityObject(
-                 rxkad_clear, &ttoken.sessionKey, ttoken.kvno,
+                 vsu_rxkad_level, &ttoken.sessionKey, ttoken.kvno,
                  ttoken.ticketLen, ttoken.ticket);
             break;
           default: