vos-command-enhancements-20011008
[openafs.git] / src / volser / vsprocs.c
index 45e3786..5ef020f 100644 (file)
@@ -7,7 +7,11 @@
  * directory or online at http://www.openafs.org/dl/license10.html
  */
 
+#include <afsconfig.h>
 #include <afs/param.h>
+
+RCSID("$Header$");
+
 #include <stdio.h>
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -61,12 +65,16 @@ extern int VL_SetLock();
 extern int VL_ReleaseLock();
 extern int VL_DeleteEntry();
 
+void MapNetworkToHost();
+void MapHostToNetwork();
+
 struct release {
   afs_int32 time;
   afs_int32 vldbEntryIndex;
 };
 
 /*map the partition <partId> into partition name <partName>*/
+void
 MapPartIdIntoName(partId, partName)
 afs_int32 partId;
 char *partName;
@@ -75,14 +83,14 @@ char *partName;
        strcpy(partName,"/vicep");
        partName[6] = partId + 'a';
        partName[7] = '\0';
-       return 0;
+       return;
     } else if (partId < VOLMAXPARTS) {
         strcpy(partName,"/vicep");
        partId -= 26;
        partName[6] = 'a' + (partId/26);
        partName[7] = 'a' + (partId%26);
        partName[8] = '\0';
-       return 0;
+       return;
     }
 }
 
@@ -224,12 +232,12 @@ PrintError(msg, errcode)
 
                afs_int32 offset;
 
-               initialize_ka_error_table();
-               initialize_rxk_error_table();
-               initialize_ktc_error_table();
-               initialize_acfg_error_table();
-               initialize_cmd_error_table();
-               initialize_vl_error_table();
+               initialize_KA_error_table();
+               initialize_RXK_error_table();
+               initialize_KTC_error_table();
+               initialize_ACFG_error_table();
+               initialize_CMD_error_table();
+               initialize_VL_error_table();
                
                offset = errcode & ((1<<ERRCODE_RANGE)-1);
                fprintf(STDERR,"%s: %s\n",error_table_name (errcode), error_message (errcode));
@@ -360,9 +368,6 @@ struct nvldbentry *entry;
 void EnumerateEntry(entry)
 struct nvldbentry *entry;
 {
-    int i;
-    char pname[10];
-    int isMixed = 0;
 
     fprintf(STDOUT,"\n");
     fprintf(STDOUT,"%s \n",entry->name);
@@ -439,7 +444,7 @@ afs_int32 *anewid;
     tid = 0;
     aconn = (struct rx_connection *)0;
     error = 0;
-    bzero (&tstatus, sizeof(struct volintInfo));
+    memset(&tstatus, 0, sizeof(struct volintInfo));
     tstatus.dayUse = -1;
     tstatus.maxquota = aquota;
 
@@ -531,9 +536,8 @@ UV_AddVLDBEntry(aserver, apart, aname, aid)
   afs_int32 aid; 
 {
     register struct rx_connection *aconn;
-    register afs_int32 code;
     afs_int32 error;
-    afs_int32 rcode,vcode;
+    afs_int32 vcode;
     struct nvldbentry entry,storeEntry;/*the new vldb entry */
 
     aconn = (struct rx_connection *)0;
@@ -1021,7 +1025,7 @@ UV_MoveVolume(afromvol, afromserver, afrompart, atoserver, atopart)
      * clone the read/write volume locally.
      * ***/
 
-    if (verbose) fprintf(STDOUT,"Starting transaction  on source volume %u ...",afromvol);
+    if (verbose) fprintf(STDOUT,"Starting transaction on source volume %u ...",afromvol);
     fflush(STDOUT);
     code = AFSVolTransCreate(fromconn, afromvol, afrompart, ITBusy, &fromtid);
     ONERR (code, "Failed to create transaction on the volume %u\n", afromvol);
@@ -1756,7 +1760,7 @@ static int DelVol (conn, vid, part, flags)
 struct rx_connection *conn;
 afs_int32 vid, part, flags;
 {
-  afs_int32 acode, bcode, ccode, rcode, tid;
+  afs_int32 acode, ccode, rcode, tid;
   ccode = rcode = tid = 0;
 
   acode = AFSVolTransCreate(conn, vid, part, flags, &tid);
@@ -1927,7 +1931,7 @@ UV_ReleaseVolume(afromvol, afromserver, afrompart, forceflag)
   afs_int32 cloneVolId, roVolId;
   struct replica *replicas=0;
   struct nvldbentry entry,storeEntry;
-  int i, volcount, k, m, n, fullrelease, vldbindex;
+  int i, volcount, m, fullrelease, vldbindex;
   int failure;
   struct restoreCookie cookie;
   struct rx_connection **toconns=0;
@@ -1939,7 +1943,7 @@ UV_ReleaseVolume(afromvol, afromserver, afrompart, forceflag)
   afs_int32 clonetid=0, onlinetid;
   afs_int32 fromtid=0;
   afs_uint32 fromdate, thisdate;
-  int ix, si, s;
+  int s;
   manyDests tr;
   manyResults results;
   int rwindex, roindex, roclone, roexists;
@@ -1951,8 +1955,8 @@ UV_ReleaseVolume(afromvol, afromserver, afrompart, forceflag)
   int releasecount = 0;
   struct volser_status volstatus;
 
-  bzero((char *)remembertime, sizeof(remembertime));
-  bzero((char *)&results, sizeof(results));
+  memset((char *)remembertime, 0, sizeof(remembertime));
+  memset((char *)&results, 0, sizeof(results));
 
   vcode = ubik_Call(VL_SetLock, cstruct, 0, afromvol, RWVOL, VLOP_RELEASE);
   if (vcode != VL_RERELEASE) 
@@ -2143,7 +2147,7 @@ UV_ReleaseVolume(afromvol, afromserver, afrompart, forceflag)
 
   strcpy(vname, entry.name);
   strcat(vname, ".readonly");
-  bzero(&cookie,sizeof(cookie));
+  memset(&cookie, 0, sizeof(cookie));
   strncpy(cookie.name, vname, VOLSER_OLDMAXVOLNAME);
   cookie.type   = ROVOL;
   cookie.parent = entry.volumeId[RWVOL];
@@ -2157,10 +2161,10 @@ UV_ReleaseVolume(afromvol, afromserver, afrompart, forceflag)
   if ( !replicas || !times || !! !results.manyResults_val || !toconns ) 
       ONERROR(ENOMEM, 0, "Failed to create transaction on the release clone\n");
 
-  bzero (replicas,   (sizeof(struct replica)*nservers+1));
-  bzero (times,      (sizeof(struct release)*nservers+1));
-  bzero (toconns,    (sizeof(struct rx_connection *)*nservers+1));
-  bzero (results.manyResults_val, (sizeof(afs_int32)*nservers+1));
+  memset(replicas, 0, (sizeof(struct replica)*nservers+1));
+  memset(times, 0, (sizeof(struct release)*nservers+1));
+  memset(toconns, 0, (sizeof(struct rx_connection *)*nservers+1));
+  memset(results.manyResults_val, 0, (sizeof(afs_int32)*nservers+1));
 
   /* Create a transaction on the cloned volume */
   code = AFSVolTransCreate(fromconn, cloneVolId, afrompart, ITBusy, &fromtid);
@@ -2557,12 +2561,12 @@ 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];
 
 
-    bzero(&cookie,sizeof(cookie));
+    memset(&cookie, 0, sizeof(cookie));
     islocked  = 0;
     success = 0;
     error = 0;
@@ -2573,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 */
@@ -2585,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 */
@@ -2600,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) {
@@ -2636,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;
@@ -2653,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);
 
@@ -2679,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;
@@ -2722,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;
@@ -2736,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
@@ -2768,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;
@@ -2778,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
@@ -2833,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;
@@ -2853,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;
@@ -3058,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;
@@ -3487,7 +3563,6 @@ static afs_int32 CheckVolume(volumeinfo, aserver, apart, modentry, maxvolid)
    int   idx, j;
    afs_int32 code, error = 0;
    struct nvldbentry entry, storeEntry;
-   int sameserver;
    char pname[10];
    int pass=0, islocked=0, createentry, addvolume, modified, mod;
    afs_int32 rwvolid;
@@ -3521,7 +3596,7 @@ static afs_int32 CheckVolume(volumeinfo, aserver, apart, modentry, maxvolid)
         ERROR_EXIT(code);
       }
 
-      bzero(&entry, sizeof(entry));
+      memset(&entry, 0, sizeof(entry));
       vsu_ExtractName(entry.name, volumeinfo->name); /* Store name of RW */
 
       createentry = 1;
@@ -4398,10 +4473,9 @@ afs_int32 CheckVldb(entry, modified)
    afs_int32             *modified;
 {
    afs_int32 code, error=0;
-   int idx;
    struct nvldbentry storeEntry;
    int islocked=0, mod, modentry, delentry=0;
-   int foundro, pass=0;
+   int pass=0;
 
    if (modified) *modified = 0;
    if (verbose) {
@@ -4549,7 +4623,7 @@ UV_SyncServer(aserver, apart, flags, force)
 
     /* While we need to collect more VLDB entries */
     for (si=0; si != -1; si=nsi) {
-       bzero(&arrayEntries, sizeof(arrayEntries));
+       memset(&arrayEntries, 0, sizeof(arrayEntries));
 
        /* Collect set of VLDB entries */
        code = VLDB_ListAttributesN2(&attributes, 0, si,
@@ -4909,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);
@@ -4920,8 +4994,49 @@ 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
 MapNetworkToHost(old, new)
 struct nvldbentry *old, *new;
 {
@@ -4943,10 +5058,10 @@ struct nvldbentry *old, *new;
     new->volumeId[BACKVOL] = old->volumeId[BACKVOL];
     new->cloneId = old->cloneId;
     new->flags = old->flags;
-
 }
 
 /*maps the host entries in <entry> which are present in host byte order to network byte order */
+void
 MapHostToNetwork(entry)
 struct nvldbentry *entry;
 {