Expand ProgramType enumeration
authorAndrew Deason <adeason@sinenomine.net>
Fri, 6 Nov 2009 20:03:52 +0000 (14:03 -0600)
committerDerrick Brashear <shadow|account-1000005@unknown>
Thu, 10 Dec 2009 19:49:46 +0000 (11:49 -0800)
The ProgramType values volumeUtility and salvager are overloaded. Expand
the ProgramType enum to include more specific program types, and adjust
conditionals to match.

Also, instead of determining all behavior by checking programType, add
some flags to be passed in to VInitVolumePackage to determine e.g.
whether or not we can use the FSSYNC channel. This makes it easier to
see the intent of some conditionals, and reduces the number of times a
caller must lie about what program it is.

Change-Id: Ic9852a35bb16a6b1f4b0aa9766de63178ecea56f
Reviewed-on: http://gerrit.openafs.org/786
Reviewed-by: Derrick Brashear <shadow@dementia.org>
Tested-by: Derrick Brashear <shadow@dementia.org>

14 files changed:
src/afs/voldefs.h
src/tsalvaged/salvsync-debug.c
src/viced/viced.c
src/vol/fssync-debug.c
src/vol/salvaged.c
src/vol/salvager.c
src/vol/test/testpart.c
src/vol/vol-bless.c
src/vol/voldefs.h
src/vol/volume.c
src/vol/volume.h
src/vol/volume_inline.h
src/volser/vol-dump.c
src/volser/volmain.c

index 633cd95..5a53210 100644 (file)
@@ -29,7 +29,3 @@
 #define VFORMAT "V%010lu.vol"
 #define VMAXPATHLEN 64         /* Maximum length (including null) of a volume
                                 * external path name */
-
-/* Values for connect parameter to VInitVolumePackage */
-#define CONNECT_FS     1
-#define DONT_CONNECT_FS        0
index 3a91cf5..f377535 100644 (file)
@@ -177,6 +177,7 @@ static int
 common_prolog(struct cmd_syndesc * as, struct state * state)
 {
     register struct cmd_item *ti;
+    VolumePackageOptions opts;
 
 #ifdef AFS_NT40_ENV
     if (afs_winsockInit() < 0) {
@@ -184,8 +185,8 @@ common_prolog(struct cmd_syndesc * as, struct state * state)
     }
 #endif
 
-    VInitVolumePackage(debugUtility, 1, 1,
-                      DONT_CONNECT_FS, 0);
+    VOptDefaults(debugUtility, &opts);
+    VInitVolumePackage2(debugUtility, &opts);
     DInit(1);
 
     if ((ti = as->parms[COMMON_PARMS_OFFSET].items)) { /* -reason */
@@ -200,6 +201,10 @@ common_prolog(struct cmd_syndesc * as, struct state * state)
            programType = salvager;
        } else if (!strcmp(ti->data, "salvageServer")) {
            programType = salvageServer;
+       } else if (!strcmp(ti->data, "volumeServer")) {
+           programType = volumeServer;
+       } else if (!strcmp(ti->data, "volumeSalvager")) {
+           programType = volumeSalvager;
        } else {
            programType = (ProgramType) atoi(ti->data);
        }
index a7f38a3..a2c0478 100644 (file)
@@ -1943,6 +1943,7 @@ main(int argc, char *argv[])
     int curLimit;
     time_t t;
     afs_uint32 rx_bindhost;
+    VolumePackageOptions opts;
 
 #ifdef AFS_AIX32_ENV
     struct sigaction nsa;
@@ -2249,7 +2250,12 @@ main(int argc, char *argv[])
      * will be available "real soon now".  Worry about whether we can satisfy the 
      * calls in the volume package itself.
      */
-    if (VInitVolumePackage(fileServer, large, nSmallVns, 0, volcache)) {
+    VOptDefaults(fileServer, &opts);
+    opts.nLargeVnodes = large;
+    opts.nSmallVnodes = nSmallVns;
+    opts.volcache = volcache;
+
+    if (VInitVolumePackage2(fileServer, &opts)) {
        ViceLog(0,
                ("Shutting down: errors encountered initializing volume package\n"));
        VShutdown();
index 48c4be4..c746ed0 100644 (file)
@@ -223,6 +223,7 @@ static int
 common_prolog(struct cmd_syndesc * as, struct state * state)
 {
     register struct cmd_item *ti;
+    VolumePackageOptions opts;
 
 #ifdef AFS_NT40_ENV
     if (afs_winsockInit() < 0) {
@@ -230,8 +231,8 @@ common_prolog(struct cmd_syndesc * as, struct state * state)
     }
 #endif
 
-    VInitVolumePackage(debugUtility, 1, 1,
-                      DONT_CONNECT_FS, 0);
+    VOptDefaults(debugUtility, &opts);
+    VInitVolumePackage2(debugUtility, &opts);
     DInit(1);
 
     if ((ti = as->parms[COMMON_PARMS_OFFSET].items)) { /* -reason */
@@ -246,6 +247,10 @@ common_prolog(struct cmd_syndesc * as, struct state * state)
            programType = salvager;
        } else if (!strcmp(ti->data, "salvageServer")) {
            programType = salvageServer;
+       } else if (!strcmp(ti->data, "volumeServer")) {
+           programType = volumeServer;
+       } else if (!strcmp(ti->data, "volumeSalvager")) {
+           programType = volumeSalvager;
        } else {
            programType = (ProgramType) atoi(ti->data);
        }
index 8ce40f1..2dbbc18 100644 (file)
@@ -420,8 +420,10 @@ SalvageClient(VolumeId vid, char * pname)
     afs_int32 code;
     SYNC_response res;
     SALVSYNC_response_hdr sres;
+    VolumePackageOptions opts;
 
-    VInitVolumePackage(volumeUtility, 5, 5, DONT_CONNECT_FS, 0);
+    VOptDefaults(volumeUtility, &opts);
+    VInitVolumePackage2(volumeUtility, &opts);
     SALVSYNC_clientInit();
     
     code = SALVSYNC_SalvageVolume(vid, pname, SALVSYNC_SALVAGE, SALVSYNC_OPERATOR, 0, NULL);
@@ -472,6 +474,7 @@ SalvageServer(void)
     pthread_t tid;
     pthread_attr_t attrs;
     int slot;
+    VolumePackageOptions opts;
 
     /* All entries to the log will be appended.  Useful if there are
      * multiple salvagers appending to the log.
@@ -492,7 +495,7 @@ SalvageServer(void)
     
     /* Get and hold a lock for the duration of the salvage to make sure
      * that no other salvage runs at the same time.  The routine
-     * VInitVolumePackage (called below) makes sure that a file server or
+     * VInitVolumePackage2 (called below) makes sure that a file server or
      * other volume utilities don't interfere with the salvage.
      */
     
@@ -505,10 +508,10 @@ SalvageServer(void)
     child_slot = (int *) malloc(Parallel * sizeof(int));
     assert(child_slot != NULL);
     memset(child_slot, 0, Parallel * sizeof(int));
-           
+
     /* initialize things */
-    VInitVolumePackage(salvageServer, 5, 5,
-                      1, 0);
+    VOptDefaults(salvageServer, &opts);
+    VInitVolumePackage2(salvageServer, &opts);
     DInit(10);
     queue_Init(&pending_q);
     queue_Init(&log_cleanup_queue);
index 68c2146..093bbac 100644 (file)
@@ -140,11 +140,13 @@ handleit(struct cmd_syndesc *as, void *arock)
     register struct cmd_item *ti;
     char pname[100], *temp;
     afs_int32 seenpart = 0, seenvol = 0, vid = 0;
+    ProgramType pt;
    
 #ifdef FAST_RESTART
     afs_int32  seenany = 0;
 #endif
     
+    VolumePackageOptions opts;
     struct DiskPartition64 *partP;
 
 #ifdef AFS_SGI_VNODE_GLUE
@@ -314,8 +316,15 @@ handleit(struct cmd_syndesc *as, void *arock)
        }
     }
 #endif
-    VInitVolumePackage(seenvol ? volumeUtility : salvager, 5, 5,
-                      DONT_CONNECT_FS, 0);
+
+    if (seenvol) {
+       pt = volumeSalvager;
+    } else {
+       pt = salvager;
+    }
+
+    VOptDefaults(pt, &opts);
+    VInitVolumePackage2(pt, &opts);
     DInit(10);
 #ifdef AFS_NT40_ENV
     if (myjob.cj_number != NOT_CHILD) {
@@ -435,7 +444,7 @@ main(int argc, char **argv)
 
        /* Get and hold a lock for the duration of the salvage to make sure
         * that no other salvage runs at the same time.  The routine
-        * VInitVolumePackage (called below) makes sure that a file server or
+        * VInitVolumePackage2 (called below) makes sure that a file server or
         * other volume utilities don't interfere with the salvage.
         */
        get_salvage_lock = 1;
index f591294..9044c6c 100644 (file)
@@ -38,7 +38,10 @@ main(argc, argv)
      int argc;
      char **argv;
 {
-    VInitVolumePackage(1, 0, 0, 0, 0);
+    VolumePackageOptions opts;
+
+    VOptDefaults(1, &opts);
+    VInitVolumePackage2(1, &opts);
     VPrintDiskStats();
 
 }
index 67f9f65..993cfa1 100644 (file)
@@ -32,6 +32,8 @@ handleit(struct cmd_syndesc *as, void *arock)
     Error ec;
     int bless, unbless, nofssync;
     int volumeId;
+    VolumePackageOptions opts;
+    ProgramType pt;
 
     volumeId = atoi(as->parms[0].items->data);
     bless    = !!(as->parms[1].items);
@@ -43,7 +45,16 @@ handleit(struct cmd_syndesc *as, void *arock)
        exit(1);
     }
 
-    if (VInitVolumePackage(nofssync ? salvager : volumeUtility, 5, 5, 1, 0)) {
+    if (nofssync) {
+       pt = salvager;
+    } else {
+       pt = volumeUtility;
+    }
+
+    VOptDefaults(pt, &opts);
+    opts.canUseFSSYNC = !nofssync;
+
+    if (VInitVolumePackage2(pt, &opts)) {
        fprintf(stderr,"Unable to initialize volume package\n");
        exit(1);
     }
index e83bc90..367e25b 100644 (file)
@@ -57,7 +57,3 @@
 
 /* Pathname for server id definitions--the server id is used to allocate volume numbers */
 #define SERVERLISTPATH "/vice/db/servers"
-
-/* Values for connect parameter to VInitVolumePackage */
-#define CONNECT_FS     1
-#define DONT_CONNECT_FS        0
index 614abd2..46b238a 100644 (file)
@@ -212,6 +212,7 @@ static int VolumeExternalName_r(VolumeId volumeId, char * name, size_t len);
 int LogLevel;                  /* Vice loglevel--not defined as extern so that it will be
                                 * defined when not linked with vice, XXXX */
 ProgramType programType;       /* The type of program using the package */
+static VolumePackageOptions vol_opts;
 
 /* extended volume package statistics */
 VolPkgStats VStats;
@@ -436,14 +437,55 @@ bit32 VolumeCacheCheck;           /* Incremented everytime a volume goes on line--
 /***************************************************/
 /* Startup routines                                */
 /***************************************************/
+/**
+ * assign default values to a VolumePackageOptions struct.
+ *
+ * Always call this on a VolumePackageOptions struct first, then set any
+ * specific options you want, then call VInitVolumePackage2.
+ *
+ * @param[in]  pt   caller's program type
+ * @param[out] opts volume package options
+ */
+void
+VOptDefaults(ProgramType pt, VolumePackageOptions *opts)
+{
+    opts->nLargeVnodes = opts->nSmallVnodes = 5;
+    opts->volcache = 0;
+
+    opts->canScheduleSalvage = 0;
+    opts->canUseFSSYNC = 0;
+    opts->canUseSALVSYNC = 0;
+
+    switch (pt) {
+    case fileServer:
+       opts->canScheduleSalvage = 1;
+       opts->canUseSALVSYNC = 1;
+       break;
+
+    case salvageServer:
+       opts->canUseFSSYNC = 1;
+       break;
+
+    case volumeServer:
+       opts->nLargeVnodes = 0;
+       opts->nSmallVnodes = 0;
+
+       opts->canUseFSSYNC = 1;
+       break;
+
+    default:
+       /* noop */
+       break;
+    }
+}
 
 int
-VInitVolumePackage(ProgramType pt, afs_uint32 nLargeVnodes, afs_uint32 nSmallVnodes,
-                  int connect, afs_uint32 volcache)
+VInitVolumePackage2(ProgramType pt, VolumePackageOptions * opts)
 {
     int errors = 0;            /* Number of errors while finding vice partitions. */
 
     programType = pt;
+    vol_opts = *opts;
 
     memset(&VStats, 0, sizeof(VStats));
     VStats.hdr_cache_size = 200;
@@ -493,18 +535,18 @@ VInitVolumePackage(ProgramType pt, afs_uint32 nLargeVnodes, afs_uint32 nSmallVno
     }
 #endif
 #if defined(AFS_DEMAND_ATTACH_FS) && defined(SALVSYNC_BUILD_CLIENT)
-    if (programType == fileServer) {
+    if (VCanUseSALVSYNC()) {
        /* establish a connection to the salvager at this point */
        assert(VConnectSALV() != 0);
     }
 #endif /* AFS_DEMAND_ATTACH_FS */
 
-    if (volcache > VStats.hdr_cache_size)
-       VStats.hdr_cache_size = volcache;
+    if (opts->volcache > VStats.hdr_cache_size)
+       VStats.hdr_cache_size = opts->volcache;
     VInitVolumeHeaderCache(VStats.hdr_cache_size);
 
-    VInitVnodes(vLarge, nLargeVnodes);
-    VInitVnodes(vSmall, nSmallVnodes);
+    VInitVnodes(vLarge, opts->nLargeVnodes);
+    VInitVnodes(vSmall, opts->nSmallVnodes);
 
 
     errors = VAttachPartitions();
@@ -519,20 +561,17 @@ VInitVolumePackage(ProgramType pt, afs_uint32 nLargeVnodes, afs_uint32 nSmallVno
     }
 
 #ifdef FSSYNC_BUILD_CLIENT
-    if (programType == volumeUtility && connect) {
+    if (VCanUseFSSYNC()) {
        if (!VConnectFS()) {
-           Log("Unable to connect to file server; will retry at need\n");
-           /*exit(1);*/
-       }
-    }
 #ifdef AFS_DEMAND_ATTACH_FS
-    else if (programType == salvageServer) {
-       if (!VConnectFS()) {
-           Log("Unable to connect to file server; aborted\n");
-           exit(1);
+           if (programType == salvageServer) {
+               Log("Unable to connect to file server; aborted\n");
+               exit(1);
+           }
+#endif /* AFS_DEMAND_ATTACH_FS */
+           Log("Unable to connect to file server; will retry at need\n");
        }
     }
-#endif /* AFS_DEMAND_ATTACH_FS */
 #endif /* FSSYNC_BUILD_CLIENT */
     return 0;
 }
@@ -1861,7 +1900,7 @@ VAttachVolumeByName_r(Error * ec, char *partition, char *name, int mode)
        goto done;
     }
 
-    if (programType == volumeUtility) {
+    if (VRequiresPartLock()) {
        assert(VInit == 3);
        VLockPartition_r(partition);
     } else if (programType == fileServer) {
@@ -2019,7 +2058,7 @@ VAttachVolumeByName_r(Error * ec, char *partition, char *name, int mode)
 
     DiskToVolumeHeader(&iheader, &diskHeader);
 #ifdef FSSYNC_BUILD_CLIENT
-    if (programType == volumeUtility && mode != V_SECRETLY && mode != V_PEEK) {
+    if (VCanUseFSSYNC() && mode != V_SECRETLY && mode != V_PEEK) {
         VOL_LOCK;
        if (FSYNC_VolOp(iheader.id, partition, FSYNC_VOL_NEEDVOLUME, mode, NULL)
            != SYNC_OK) {
@@ -2046,7 +2085,7 @@ VAttachVolumeByName_r(Error * ec, char *partition, char *name, int mode)
      * with vol_glock_mutex held */
     vp = attach2(ec, volumeId, path, &iheader, partp, vp, isbusy, mode);
 
-    if (programType == volumeUtility && vp) {
+    if (VCanUseFSSYNC() && vp) {
        if ((mode == V_VOLUPD) || (VolumeWriteable(vp) && (mode == V_CLONE))) {
            /* mark volume header as in use so that volser crashes lead to a
             * salvage attempt */
@@ -2084,7 +2123,7 @@ VAttachVolumeByName_r(Error * ec, char *partition, char *name, int mode)
      * fix is for the server to allow the return of readonly volumes
      * that it doesn't think are really checked out. */
 #ifdef FSSYNC_BUILD_CLIENT
-    if (programType == volumeUtility && vp == NULL &&
+    if (VCanUseFSSYNC() && vp == NULL &&
        mode != V_SECRETLY && mode != V_PEEK) {
        FSYNC_VolOp(iheader.id, partition, FSYNC_VOL_ON, 0, NULL);
     } else 
@@ -2140,7 +2179,7 @@ VAttachVolumeByName_r(Error * ec, char *partition, char *name, int mode)
     }
 
   done:
-    if (programType == volumeUtility) {
+    if (VRequiresPartLock()) {
        VUnlockPartition_r(partition);
     }
     if (*ec) {
@@ -2504,7 +2543,7 @@ attach2(Error * ec, VolId volumeId, char *path, register struct VolumeHeader * h
 #if defined(AFS_DEMAND_ATTACH_FS)
     if (*ec && ((*ec != VOFFLINE) || (V_attachState(vp) != VOL_STATE_UNATTACHED))) {
         VOL_LOCK;
-       if (programType == fileServer) {
+       if (VCanScheduleSalvage()) {
            VRequestSalvage_r(ec, vp, SALVSYNC_ERROR, VOL_SALVAGE_INVALIDATE_HEADER);
            vp->nUsers = 0;
        } else {
@@ -2532,7 +2571,7 @@ attach2(Error * ec, VolId volumeId, char *path, register struct VolumeHeader * h
            vp->specialStatus = 0;
         VOL_LOCK;
 #if defined(AFS_DEMAND_ATTACH_FS)
-       if (programType == fileServer) {
+       if (VCanScheduleSalvage()) {
            VRequestSalvage_r(ec, vp, SALVSYNC_NEEDED, VOL_SALVAGE_INVALIDATE_HEADER);
            vp->nUsers = 0;
        } else {
@@ -2548,7 +2587,7 @@ attach2(Error * ec, VolId volumeId, char *path, register struct VolumeHeader * h
     }
 
     VOL_LOCK;
-    if (programType == fileServer) {
+    if (VShouldCheckInUse(mode)) {
 #ifndef FAST_RESTART
        if (V_inUse(vp) && VolumeWriteable(vp)) {
            if (!V_needsSalvaged(vp)) {
@@ -2567,7 +2606,15 @@ attach2(Error * ec, VolId volumeId, char *path, register struct VolumeHeader * h
        }
 #endif /* FAST_RESTART */
 
-       if (V_destroyMe(vp) == DESTROY_ME) {
+       if (programType == fileServer && V_destroyMe(vp) == DESTROY_ME) {
+           /* Only check destroyMe if we are the fileserver, since the
+            * volserver et al sometimes need to work with volumes with
+            * destroyMe set. Examples are 'temporary' volumes the
+            * volserver creates, and when we create a volume (destroyMe
+            * is set on creation; sometimes a separate volserver
+            * transaction is created to clear destroyMe).
+            */
+
 #if defined(AFS_DEMAND_ATTACH_FS)
            /* schedule a salvage so the volume goes away on disk */
            VRequestSalvage_r(ec, vp, SALVSYNC_ERROR, VOL_SALVAGE_INVALIDATE_HEADER);
@@ -2982,7 +3029,7 @@ GetVolume(Error * ec, Error * client_ec, VolId volumeId, Volume * hint, int flag
                Log("Volume %u: couldn't reread volume header\n",
                    vp->hashid);
 #ifdef AFS_DEMAND_ATTACH_FS
-           if (programType == fileServer) {
+           if (VCanScheduleSalvage()) {
                VRequestSalvage_r(ec, vp, SALVSYNC_ERROR, VOL_SALVAGE_INVALIDATE_HEADER);
            } else {
                FreeVolume(vp);
@@ -3242,7 +3289,7 @@ VOffline_r(Volume * vp, char *message)
     VolumeId vid = V_id(vp);
 #endif
 
-    assert(programType != volumeUtility);
+    assert(programType != volumeUtility && programType != volumeServer);
     if (!V_inUse(vp)) {
        VPutVolume_r(vp);
        return;
@@ -3355,7 +3402,7 @@ VDetachVolume_r(Error * ec, Volume * vp)
     int  useDone = FSYNC_VOL_ON;
 
     *ec = 0;                   /* always "succeeds" */
-    if (programType == volumeUtility) {
+    if (VCanUseFSSYNC()) {
        notifyServer = vp->needsPutBack;
        if (V_destroyMe(vp) == DESTROY_ME)
            useDone = FSYNC_VOL_DONE;
@@ -3383,7 +3430,7 @@ VDetachVolume_r(Error * ec, Volume * vp)
      * is not technically detached until the refcounts reach zero
      */
 #ifdef FSSYNC_BUILD_CLIENT
-    if (programType == volumeUtility && notifyServer) {
+    if (VCanUseFSSYNC() && notifyServer) {
        /* 
         * Note:  The server is not notified in the case of a bogus volume 
         * explicitly to make it possible to create a volume, do a partial 
@@ -3448,7 +3495,7 @@ VCloseVolumeHandles_r(Volume * vp)
 #endif
 
     /* Too time consuming and unnecessary for the volserver */
-    if (programType != volumeUtility) {
+    if (programType == fileServer) {
        IH_CONDSYNC(vp->vnodeIndex[vLarge].handle);
        IH_CONDSYNC(vp->vnodeIndex[vSmall].handle);
        IH_CONDSYNC(vp->diskDataHandle);
@@ -3493,7 +3540,7 @@ VReleaseVolumeHandles_r(Volume * vp)
 #endif
 
     /* Too time consuming and unnecessary for the volserver */
-    if (programType != volumeUtility) {
+    if (programType == fileServer) {
        IH_CONDSYNC(vp->vnodeIndex[vLarge].handle);
        IH_CONDSYNC(vp->vnodeIndex[vSmall].handle);
        IH_CONDSYNC(vp->diskDataHandle);
@@ -4099,7 +4146,7 @@ VRequestSalvage_r(Error * ec, Volume * vp, int reason, int flags)
      * (at some point in the future, we should consider
      *  making volser talk to salsrv)
      */
-    if (programType != fileServer) {
+    if (!VCanScheduleSalvage()) {
        VChangeState_r(vp, VOL_STATE_ERROR);
        *ec = VSALVAGE;
        return 1;
@@ -4463,7 +4510,7 @@ VReconnectSALV_r(void)
 /***************************************************/
 
 /* This must be called by any volume utility which needs to run while the
-   file server is also running.  This is separated from VInitVolumePackage so
+   file server is also running.  This is separated from VInitVolumePackage2 so
    that a utility can fork--and each of the children can independently
    initialize communication with the file server */
 #ifdef FSSYNC_BUILD_CLIENT
@@ -5417,7 +5464,7 @@ static void VLRU_Wait_r(struct VLRU_q * q);
  * @param[in] option  tunable option to modify
  * @param[in] val     new value for tunable parameter
  *
- * @pre @c VInitVolumePackage has not yet been called.
+ * @pre @c VInitVolumePackage2 has not yet been called.
  *
  * @post tunable parameter is modified
  *
@@ -5814,7 +5861,7 @@ VLRU_ScannerThread(void * args)
     }
 
     /* don't start the scanner until VLRU_offline_thresh
-     * plus a small delay for VInitVolumePackage to finish
+     * plus a small delay for VInitVolumePackage2 to finish
      * has gone by */
 
     sleep(VLRU_offline_thresh + 60);
@@ -6661,7 +6708,7 @@ FreeVolumeHeader(register Volume * vp)
  *    @retval 0 success
  *    @retval -1 failure
  *
- * @pre MUST be called prior to VInitVolumePackage
+ * @pre MUST be called prior to VInitVolumePackage2
  *
  * @post Volume Hash Table will have 2^logsize buckets
  */
@@ -7623,3 +7670,21 @@ VPrintExtendedCacheStats(int flags)
     VOL_UNLOCK;
 }
 #endif /* AFS_DEMAND_ATTACH_FS */
+
+afs_int32
+VCanScheduleSalvage(void)
+{
+    return vol_opts.canScheduleSalvage;
+}
+
+afs_int32
+VCanUseFSSYNC(void)
+{
+    return vol_opts.canUseFSSYNC;
+}
+
+afs_int32
+VCanUseSALVSYNC(void)
+{
+    return vol_opts.canUseSALVSYNC;
+}
index 38846cd..f1b71ae 100644 (file)
@@ -119,11 +119,12 @@ extern pthread_t vol_glock_holder;
  */
 typedef enum {
     fileServer          = 1,    /**< the fileserver process */
-    volumeUtility       = 2,    /**< volserver, or a 
-                                *   single volume salvager (non-dafs) */
+    volumeUtility       = 2,    /**< any miscellaneous volume utility */
     salvager            = 3,    /**< standalone whole-partition salvager */
     salvageServer       = 4,    /**< dafs online salvager */
-    debugUtility        = 5     /**< fssync-debug or similar utility */
+    debugUtility        = 5,    /**< fssync-debug or similar utility */
+    volumeServer        = 6,    /**< the volserver process */
+    volumeSalvager      = 7,    /**< the standalone single-volume salvager */
 } ProgramType;
 extern ProgramType programType;        /* The type of program using the package */
 
@@ -237,6 +238,17 @@ extern VThreadOptions_t VThread_defaults;
 
 #endif /* AFS_DEMAND_ATTACH_FS */
 
+typedef struct VolumePackageOptions {
+    afs_uint32 nLargeVnodes;      /**< size of large vnode cache */
+    afs_uint32 nSmallVnodes;      /**< size of small vnode cache */
+    afs_uint32 volcache;          /**< size of volume header cache */
+
+    afs_int32 canScheduleSalvage; /**< can we schedule salvages? (DAFS) */
+                                 /* (if 'no', we will just error out if we
+                                   * find a bad vol) */
+    afs_int32 canUseFSSYNC;       /**< can we use the FSSYNC channel? */
+    afs_int32 canUseSALVSYNC;     /**< can we use the SALVSYNC channel? (DAFS) */
+} VolumePackageOptions;
 
 /* Magic numbers and version stamps for each type of file */
 #define VOLUMEHEADERMAGIC      ((bit32)0x88a1bb3c)
@@ -781,8 +793,8 @@ extern void VReleaseVnodeFiles_r(Volume * vp);
 extern void VCloseVnodeFiles_r(Volume * vp);
 extern struct DiskPartition64 *VGetPartition(char *name, int abortp);
 extern struct DiskPartition64 *VGetPartition_r(char *name, int abortp);
-extern int VInitVolumePackage(ProgramType pt, afs_uint32 nLargeVnodes,
-                             afs_uint32 nSmallVnodes, int connect, afs_uint32 volcache);
+extern void VOptDefaults(ProgramType pt, VolumePackageOptions * opts);
+extern int VInitVolumePackage2(ProgramType pt, VolumePackageOptions * opts);
 extern int VInitAttachVolumes(ProgramType pt);
 extern void DiskToVolumeHeader(VolumeHeader_t * h, VolumeDiskHeader_t * dh);
 extern void VolumeHeaderToDisk(VolumeDiskHeader_t * dh, VolumeHeader_t * h);
@@ -826,6 +838,9 @@ extern int VVolOpSetVBusy_r(Volume * vp, FSSYNC_VolOp_info * vopinfo);
 
 extern void VPurgeVolume(Error * ec, Volume * vp);
 
+extern afs_int32 VCanScheduleSalvage(void);
+extern afs_int32 VCanUseFSSYNC(void);
+extern afs_int32 VCanUseSALVSYNC(void);
 
 /* Naive formula relating number of file size to number of 1K blocks in file */
 /* Note:  we charge 1 block for 0 length files so the user can't store
index b5be2ac..d51c81d 100644 (file)
@@ -27,12 +27,66 @@ VIsSalvager(ProgramType type)
     switch(type) {
     case salvager:
     case salvageServer:
+    case volumeSalvager:
        return 1;
     default:
        return 0;
     }
 }
 
+/**
+ * tells caller whether or not we need to lock the entire partition when
+ * attaching a volume.
+ *
+ * @return whether or not we need to lock the partition
+ *  @retval 0  no, we do not
+ *  @retval 1  yes, we do
+ */
+static_inline int
+VRequiresPartLock(void)
+{
+    switch (programType) {
+    case volumeServer:
+    case volumeUtility:
+        return 1;
+    default:
+        return 0;
+    }
+}
+
+/**
+ * tells caller whether we should check the inUse field in the volume
+ * header when attaching a volume.
+ *
+ * If we check inUse, that generally means we will salvage the volume
+ * (or put it in an error state) if we detect that another program
+ * claims to be using the volume when we try to attach. We don't always
+ * want to do that, since sometimes we know that the volume may be in
+ * use by another program, e.g. when we are attaching with V_PEEK, and
+ * we don't care.
+ *
+ * @param mode  the mode of attachment for the volume
+ *
+ * @return whether or not we should check inUse
+ *  @retval 0  no, we should not check inUse
+ *  @retval 1  yes, we should check inUse
+ */
+static_inline int
+VShouldCheckInUse(int mode)
+{
+    if (programType == fileServer) {
+       return 1;
+    }
+    if (VCanUseFSSYNC() && mode != V_SECRETLY && mode != V_PEEK) {
+       /* If we can FSSYNC, we assume we checked out the volume from
+        * the fileserver, so inUse should not be set. If we checked out
+        * with V_SECRETLY or V_PEEK, though, we didn't ask the
+        * fileserver, so don't check inUse. */
+       return 1;
+    }
+    return 0;
+}
+
 /***************************************************/
 /* demand attach fs state machine routines         */
 /***************************************************/
index 4dff10b..e389c5b 100644 (file)
@@ -299,8 +299,10 @@ main(int argc, char **argv)
 {
     register struct cmd_syndesc *ts;
     afs_int32 code;
+    VolumePackageOptions opts;
 
-    VInitVolumePackage(volumeUtility, 5, 5, DONT_CONNECT_FS, 0);
+    VOptDefaults(volumeUtility, &opts);
+    VInitVolumePackage2(volumeUtility, &opts);
 
     ts = cmd_CreateSyntax(NULL, handleit, NULL,
                          "Dump a volume to a 'vos dump' format file without using volserver");
index 5bf46cb..46e8541 100644 (file)
@@ -251,6 +251,7 @@ main(int argc, char **argv)
     int bufSize = 0;           /* temp variable to read in udp socket buf size */
     afs_uint32 host = ntohl(INADDR_ANY);
     char *auditFileName = NULL;
+    VolumePackageOptions opts;
 
 #ifdef AFS_AIX32_ENV
     /*
@@ -420,11 +421,12 @@ main(int argc, char **argv)
        exit(1);
     }
 #endif
-    /* Open VolserLog and map stdout, stderr into it; VInitVolumePackage can
+    /* Open VolserLog and map stdout, stderr into it; VInitVolumePackage2 can
        log, so we need to do this here */
     OpenLog(AFSDIR_SERVER_VOLSERLOG_FILEPATH);
 
-    VInitVolumePackage(volumeUtility, 0, 0, CONNECT_FS, 0);
+    VOptDefaults(volumeServer, &opts);
+    VInitVolumePackage2(volumeServer, &opts);
     /* For nuke() */
     Lock_Init(&localLock);
     DInit(40);