volinfo: implement -checkout option
authorMichael Meffie <mmeffie@sinenomine.net>
Tue, 26 Jul 2011 02:02:04 +0000 (22:02 -0400)
committerDerrick Brashear <shadow@dementix.org>
Wed, 14 Dec 2011 14:06:34 +0000 (06:06 -0800)
Implement the -checkout option using the FSSYNC communication
channel with the fileserver.

Change-Id: I119fab0c238fd37eb85c9810626ee91210b2efb6
Reviewed-on: http://gerrit.openafs.org/5101
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Reviewed-by: Derrick Brashear <shadow@dementix.org>

src/vol/vol-info.c

index 9e19390..3ba1216 100644 (file)
@@ -37,6 +37,8 @@
 #include "vnode.h"
 #include "volume.h"
 #include "partition.h"
+#include "daemon_com_inline.h"
+#include "fssync_inline.h"
 
 #ifndef AFS_NT40_ENV
 #include "AFS_component_version_number.c"
@@ -46,7 +48,7 @@ static const char *progname = "volinfo";
 
 /* Command line options */
 typedef enum {
-    P_ONLINE,
+    P_CHECKOUT,
     P_VNODE,
     P_DATE,
     P_INODE,
@@ -72,6 +74,7 @@ struct VnodeDetails {
 };
 
 /* Modes */
+static int Checkout = 0;            /**< Use FSSYNC to checkout volumes from the fileserver. */
 static int DumpInfo = 0;            /**< Dump volume information */
 static int DumpHeader = 0;          /**< Dump volume header files info */
 static int DumpVnodes = 0;          /**< Dump vnode info */
@@ -299,7 +302,7 @@ PrintServerTotals(void)
  *   @retval -1 failed to read file
  */
 int
-ReadHdr1(IHandle_t * ih, char *to, int size, u_int magic, u_int version)
+ReadHdr1(IHandle_t * ih, char *to, afs_sfsize_t size, u_int magic, u_int version)
 {
     struct versionStamp *vsn;
     int bad = 0;
@@ -359,6 +362,30 @@ AttachVolume(struct DiskPartition64 * dp, char *volname,
     Volume *vp;
     afs_int32 ec = 0;
 
+    if (Checkout) {
+       afs_int32 code;
+       SYNC_response response;
+       VolumeId volid = header->id;
+
+       memset(&response, 0, sizeof(response));
+       code =
+           FSYNC_VolOp(volid, dp->name, FSYNC_VOL_NEEDVOLUME, V_DUMP,
+                       &response);
+       if (code != SYNC_OK) {
+           if (response.hdr.reason == FSYNC_SALVAGE) {
+               fprintf(stderr,
+                       "%s: file server says volume %lu is salvaging.\n",
+                       progname, afs_printable_uint32_lu(volid));
+               return NULL;
+           } else {
+               fprintf(stderr,
+                       "%s: attach of volume %lu denied by file server.\n",
+                       progname, afs_printable_uint32_lu(volid));
+               return NULL;
+           }
+       }
+    }
+
     vp = (Volume *) calloc(1, sizeof(Volume));
     if (!vp) {
        fprintf(stderr, "%s: Failed to allocate volume object.\n", progname);
@@ -418,6 +445,25 @@ AttachVolume(struct DiskPartition64 * dp, char *volname,
 static void
 DetachVolume(Volume * vp)
 {
+    if (Checkout) {
+       afs_int32 code;
+       SYNC_response response;
+       memset(&response, 0, sizeof(response));
+
+       code = FSYNC_VolOp(V_id(vp), V_partition(vp)->name,
+                          FSYNC_VOL_ON, FSYNC_WHATEVER, &response);
+       if (code != SYNC_OK) {
+           fprintf(stderr, "%s: FSSYNC error %d (%s)\n", progname, code,
+                   SYNC_res2string(code));
+           fprintf(stderr, "%s:  protocol response code was %d (%s)\n",
+                   progname, response.hdr.response,
+                   SYNC_res2string(response.hdr.response));
+           fprintf(stderr, "%s:  protocol reason code was %d (%s)\n",
+                   progname, response.hdr.reason,
+                   FSYNC_reason2string(response.hdr.reason));
+       }
+    }
+
     IH_RELEASE(vp->vnodeIndex[vLarge].handle);
     IH_RELEASE(vp->vnodeIndex[vSmall].handle);
     IH_RELEASE(vp->diskDataHandle);
@@ -441,7 +487,7 @@ DetachVolume(Volume * vp)
 static int
 GetPartitionName(afs_uint32 partId, char *partName, afs_size_t partNameSize)
 {
-    const int OLD_NUM_DEVICES = 26;    /* a..z */
+    const afs_uint32 OLD_NUM_DEVICES = 26;     /* a..z */
 
     if (partId < OLD_NUM_DEVICES) {
        if (partNameSize < 8) {
@@ -495,6 +541,14 @@ ScanPartitions(char *partNameOrId, afs_uint32 volumeId)
     }
 #endif
 
+    if (Checkout) {
+       if (!FSYNC_clientInit()) {
+           fprintf(stderr, "%s: Failed to connect to fileserver.\n",
+                   progname);
+           return 1;
+       }
+    }
+
     DInit(10);
 
     /* Allow user to specify partition by name or id. */
@@ -503,13 +557,15 @@ ScanPartitions(char *partNameOrId, afs_uint32 volumeId)
        if (partId == -1) {
            fprintf(stderr, "%s: Could not parse '%s' as a partition name.\n",
                    progname, partNameOrId);
-           return 1;
+           err = 1;
+           goto cleanup;
        }
        if (GetPartitionName(partId, partName, sizeof(partName))) {
            fprintf(stderr,
                    "%s: Could not format '%s' as a partition name.\n",
                    progname, partNameOrId);
-           return 1;
+           err = 1;
+           goto cleanup;
        }
     }
 
@@ -517,7 +573,8 @@ ScanPartitions(char *partNameOrId, afs_uint32 volumeId)
     if (err) {
        fprintf(stderr, "%s: %d partitions had errors during attach.\n",
                progname, err);
-       return 1;
+       err = 1;
+       goto cleanup;
     }
 
     if (partName[0]) {
@@ -526,7 +583,8 @@ ScanPartitions(char *partNameOrId, afs_uint32 volumeId)
            fprintf(stderr,
                    "%s: %s is not an AFS partition name on this server.\n",
                    progname, partName);
-           return 1;
+           err = 1;
+           goto cleanup;
        }
     }
 
@@ -545,7 +603,8 @@ ScanPartitions(char *partNameOrId, afs_uint32 volumeId)
                fprintf(stderr,
                        "%s: Current partition is not a vice partition.\n",
                        progname);
-               return 1;
+               err = 1;
+               goto cleanup;
            }
        }
        snprintf(name1, sizeof name1, VFORMAT,
@@ -553,7 +612,11 @@ ScanPartitions(char *partNameOrId, afs_uint32 volumeId)
        HandleVolume(partP, name1);
     }
 
-    return 0;
+  cleanup:
+    if (Checkout) {
+       FSYNC_clientFinis();
+    }
+    return err;
 }
 
 /**
@@ -592,9 +655,8 @@ handleit(struct cmd_syndesc *as, void *arock)
 
     DumpInfo = 1;              /* volinfo default mode */
 
-    if (as->parms[P_ONLINE].items) {
-       fprintf(stderr, "%s: -online not supported\n", progname);
-       return 1;
+    if (as->parms[P_CHECKOUT].items) {
+       Checkout = 1;
     }
     if (as->parms[P_VNODE].items) {
        DumpVnodes = 1;
@@ -991,8 +1053,8 @@ main(int argc, char **argv)
 
     ts = cmd_CreateSyntax(NULL, handleit, NULL,
                          "Dump volume's internal state");
-    cmd_AddParmAtOffset(ts, P_ONLINE, "-online", CMD_FLAG, CMD_OPTIONAL,
-                       "Get info from running fileserver");
+    cmd_AddParmAtOffset(ts, P_CHECKOUT, "-checkout", CMD_FLAG, CMD_OPTIONAL,
+                       "Checkout volumes from running fileserver");
     cmd_AddParmAtOffset(ts, P_VNODE, "-vnode", CMD_FLAG, CMD_OPTIONAL,
                        "Dump vnode info");
     cmd_AddParmAtOffset(ts, P_DATE, "-date", CMD_FLAG, CMD_OPTIONAL,
@@ -1191,7 +1253,7 @@ SaveInode(struct VnodeDetails *vdp)
        }
        if (len == 0)
            break;              /* No more input */
-       nBytes = write(ofd, buffer, len);
+       nBytes = write(ofd, buffer, (size_t)len);
        if (nBytes != len) {
            FDH_REALLYCLOSE(fdP);
            IH_RELEASE(ih);