cbd-new-magic-version-with-fixed-time-size-and-dump-switch-20090319
[openafs.git] / src / viced / callback.c
index 8629d92..24f17e5 100644 (file)
@@ -124,7 +124,10 @@ RCSID
 
 extern afsUUID FS_HostUUID;
 extern int hostCount;
+
+#ifndef INTERPRET_DUMP
 static int ShowProblems = 1;
+#endif
 
 struct cbcounters cbstuff;
 
@@ -153,7 +156,9 @@ static int TimeOuts[] = {
 };                             /* Anything more: MinTimeOut */
 
 /* minimum time given for a call back */
+#ifndef INTERPRET_DUMP
 static int MinTimeOut = (7 * 60);
+#endif
 
 /* Heads of CB queues; a timeout index is 1+index into this array */
 static afs_uint32 timeout[CB_NUM_TIMEOUT_QUEUES];
@@ -168,6 +173,8 @@ struct object {
 
 /* Prototypes for static routines */
 static struct FileEntry *FindFE(register AFSFid * fid);
+
+#ifndef INTERPRET_DUMP
 static struct CallBack *iGetCB(register int *nused);
 static int iFreeCB(register struct CallBack *cb, register int *nused);
 static struct FileEntry *iGetFE(register int *nused);
@@ -188,11 +195,12 @@ static void MultiBreakCallBack_r(struct cbstruct cba[], int ncbas,
 static int MultiBreakVolumeCallBack_r(struct host *host, int isheld,
                                      struct VCBParams *parms, int deletefe);
 static int MultiBreakVolumeCallBack(struct host *host, int isheld,
-                                   struct VCBParams *parms);
+                                   void *rock);
 static int MultiBreakVolumeLaterCallBack(struct host *host, int isheld,
-                                        struct VCBParams *parms);
+                                        void *rock);
 static int GetSomeSpace_r(struct host *hostp, int locked);
 static int ClearHostCallbacks_r(struct host *hp, int locked);
+#endif
 
 #define GetCB() ((struct CallBack *)iGetCB(&cbstuff.nCBs))
 #define GetFE() ((struct FileEntry *)iGetFE(&cbstuff.nFEs))
@@ -381,7 +389,7 @@ CDelPtr(register struct FileEntry *fe, register afs_uint32 * cbp,
        CcdelB++;
     *cbp = cb->cnext;
     FreeCB(cb);
-    if (deletefe && (--fe->ncbs == 0))
+    if ((--fe->ncbs == 0) && deletefe)
        FDel(fe);
     return 0;
 }
@@ -532,11 +540,13 @@ AddCallBack1_r(struct host *host, AFSFid * fid, afs_uint32 * thead, int type,
     struct FileEntry *fe;
     struct CallBack *cb = 0, *lastcb = 0;
     struct FileEntry *newfe = 0;
-    afs_uint32 time_out;
+    afs_uint32 time_out = 0;
     afs_uint32 *Thead = thead;
     struct CallBack *newcb = 0;
     int safety;
 
+    cbstuff.AddCallBacks++;
+
     host->Console |= 2;
 
     /* allocate these guys first, since we can't call the allocator with
@@ -644,6 +654,14 @@ AddCallBack1_r(struct host *host, AFSFid * fid, afs_uint32 * thead, int type,
     return 0;
 }
 
+static int
+CompareCBA(const void *e1, const void *e2)
+{
+    const struct cbstruct *cba1 = (const struct cbstruct *)e1;
+    const struct cbstruct *cba2 = (const struct cbstruct *)e2;
+    return ((cba1->hp)->index - (cba2->hp)->index);
+}
+
 /* Take an array full of hosts, all held.  Break callbacks to them, and 
  * release the holds once you're done, except don't release xhost.  xhost 
  * may be NULL.  Currently only works for a single Fid in afidp array.
@@ -673,6 +691,9 @@ MultiBreakCallBack_r(struct cbstruct cba[], int ncbas,
 
     assert(ncbas <= MAX_CB_HOSTS);
 
+    /* sort cba list to avoid makecall issues */
+    qsort(cba, ncbas, sizeof(struct cbstruct), CompareCBA);
+
     /* set up conns for multi-call */
     for (i = 0, j = 0; i < ncbas; i++) {
        struct host *thishost = cba[i].hp;
@@ -861,9 +882,9 @@ DeleteCallBack(struct host *host, AFSFid * fid)
     register afs_uint32 *pcb;
     char hoststr[16];
 
+    H_LOCK;
     cbstuff.DeleteCallBacks++;
 
-    H_LOCK;
     h_Lock_r(host);
     fe = FindFE(fid);
     if (!fe) {
@@ -922,6 +943,7 @@ DeleteFileCallBacks(AFSFid * fid)
        TDel(cb);
        HDel(cb);
        FreeCB(cb);
+       fe->ncbs--;
     }
     FDel(fe);
     H_UNLOCK;
@@ -1143,9 +1165,10 @@ MultiBreakVolumeCallBack_r(struct host *host, int isheld,
 ** isheld is 1 if the host is held in BreakVolumeCallBacks
 */
 static int
-MultiBreakVolumeCallBack(struct host *host, int isheld,
-                        struct VCBParams *parms)
+MultiBreakVolumeCallBack(struct host *host, int isheld, void *rock)
 {
+    struct VCBParams *parms = (struct VCBParams *) rock;
+    
     int retval;
     H_LOCK;
     retval = MultiBreakVolumeCallBack_r(host, isheld, parms, 1);
@@ -1158,9 +1181,9 @@ MultiBreakVolumeCallBack(struct host *host, int isheld,
 ** isheld is 1 if the host is held in BreakVolumeCallBacks
 */
 static int
-MultiBreakVolumeLaterCallBack(struct host *host, int isheld,
-                             struct VCBParams *parms)
+MultiBreakVolumeLaterCallBack(struct host *host, int isheld, void *rock)
 {
+    struct VCBParams *parms = (struct VCBParams *)rock;
     int retval;
     H_LOCK;
     retval = MultiBreakVolumeCallBack_r(host, isheld, parms, 0);
@@ -1229,7 +1252,7 @@ BreakVolumeCallBacks(afs_uint32 volume)
     henumParms.fid = &fid;
     henumParms.thead = tthead;
     H_UNLOCK;
-    h_Enumerate(MultiBreakVolumeCallBack, (char *)&henumParms);
+    h_Enumerate(MultiBreakVolumeCallBack, &henumParms);
     H_LOCK;
     if (henumParms.ncbas) {    /* do left-overs */
        struct AFSCBFids tf;
@@ -1457,9 +1480,9 @@ static int lih_host_held;
  * are held by other threads.
  */
 static int
-lih0_r(register struct host *host, register int held,
-      register struct host *hostp)
+lih0_r(register struct host *host, register int held, void *rock)
 {
+    struct host *hostp = (struct host *) rock;
     if (host->cblist
        && (hostp && host != hostp) 
        && (!held && !h_OtherHolds_r(host))
@@ -1481,9 +1504,10 @@ lih0_r(register struct host *host, register int held,
  * prevent held hosts from being selected.
  */
 static int
-lih1_r(register struct host *host, register int held,
-      register struct host *hostp)
+lih1_r(register struct host *host, register int held, void *rock)
 {
+    struct host *hostp = (struct host *) rock;
+
     if (host->cblist
        && (hostp && host != hostp) 
        && (!lih_host || host->ActiveCall < lih_host->ActiveCall) 
@@ -1667,6 +1691,8 @@ PrintCallBackStats(void)
 }
 
 #define MAGIC 0x12345678       /* To check byte ordering of dump when it is read in */
+#define MAGICV2 0x12345679      /* To check byte ordering & version of dump when it is read in */
+
 
 #ifndef INTERPRET_DUMP
 
@@ -2638,11 +2664,14 @@ cb_OldToNew(struct fs_dump_state * state, afs_uint32 old, afs_uint32 * new)
 int
 DumpCallBackState(void)
 {
-    int fd;
-    afs_uint32 magic = MAGIC, now = FT_ApproxTime(), freelisthead;
+    int fd, oflag;
+    afs_uint32 magic = MAGICV2, now = (afs_int32) FT_ApproxTime(), freelisthead;
 
-    fd = open(AFSDIR_SERVER_CBKDUMP_FILEPATH, O_WRONLY | O_CREAT | O_TRUNC,
-             0666);
+    oflag = O_WRONLY | O_CREAT | O_TRUNC;
+#ifdef AFS_NT40_ENV
+    oflag |= O_BINARY;
+#endif
+    fd = open(AFSDIR_SERVER_CBKDUMP_FILEPATH, oflag, 0666);
     if (fd < 0) {
        ViceLog(0,
                ("Couldn't create callback dump file %s\n",
@@ -2674,27 +2703,44 @@ DumpCallBackState(void)
 /* This is only compiled in for the callback analyzer program */
 /* Returns the time of the dump */
 time_t
-ReadDump(char *file)
+ReadDump(char *file, int timebits)
 {
-    int fd;
+    int fd, oflag;
     afs_uint32 magic, freelisthead;
-    time_t now;
+    afs_uint32 now;
+#ifdef AFS_64BIT_ENV
+    afs_int64 now64;
+#endif
 
-    fd = open(file, O_RDONLY);
+    oflag = O_RDONLY;
+#ifdef AFS_NT40_ENV
+    oflag |= O_BINARY;
+#endif
+    fd = open(file, oflag);
     if (fd < 0) {
        fprintf(stderr, "Couldn't read dump file %s\n", file);
        exit(1);
     }
     read(fd, &magic, sizeof(magic));
-    if (magic != MAGIC) {
-       fprintf(stderr,
-               "Magic number of %s is invalid.  You might be trying to\n",
-               file);
-       fprintf(stderr,
-               "run this program on a machine type with a different byte ordering.\n");
-       exit(1);
+    if (magic == MAGICV2) {
+       timebits = 32;
+    } else {
+       if (magic != MAGIC) {
+           fprintf(stderr,
+                   "Magic number of %s is invalid.  You might be trying to\n",
+                   file);
+           fprintf(stderr,
+                   "run this program on a machine type with a different byte ordering.\n");
+           exit(1);
+       }
     }
-    read(fd, &now, sizeof(now));
+#ifdef AFS_64BIT_ENV
+    if (timebits == 64) {
+       read(fd, &now64, sizeof(afs_int64));
+       now = (afs_int32) now64;
+    } else
+#endif
+       read(fd, &now, sizeof(afs_int32));
     read(fd, &cbstuff, sizeof(cbstuff));
     read(fd, TimeOuts, sizeof(TimeOuts));
     read(fd, timeout, sizeof(timeout));
@@ -2730,8 +2776,9 @@ main(int argc, char **argv)
     static AFSFid fid;
     register struct FileEntry *fe;
     register struct CallBack *cb;
-    time_t now;
-
+    afs_int32 now;
+    int timebits = 32;
+    
     memset(&fid, 0, sizeof(fid));
     argc--;
     argv++;
@@ -2763,6 +2810,19 @@ main(int argc, char **argv)
            all = 1;
        } else if (!strcmp(*argv, "-raw")) {
            raw = 1;
+       } else if (!strcmp(*argv, "-timebits")) {
+           if (argc < 1) {
+               err++;
+               break;
+           }
+           argc--;
+           timebits = atoi(*++argv);
+           if ((timebits != 32)
+#ifdef AFS_64BIT_ENV
+               && (timebits != 64)
+#endif
+               ) 
+               err++;
        } else if (!strcmp(*argv, "-volume")) {
            if (argc < 1) {
                err++;
@@ -2776,16 +2836,20 @@ main(int argc, char **argv)
     }
     if (err || argc != 1) {
        fprintf(stderr,
-               "Usage: cbd [-host cbid] [-fid volume vnode] [-stats] [-all] callbackdumpfile\n");
+               "Usage: cbd [-host cbid] [-fid volume vnode] [-stats] [-all] [-timebits 32"
+#ifdef AFS_64BIT_ENV
+               "|64"
+#endif
+               "] callbackdumpfile\n");
        fprintf(stderr,
                "[cbid is shown for each host in the hosts.dump file]\n");
        exit(1);
     }
-    now = ReadDump(*argv);
+    now = ReadDump(*argv, timebits);
     if (stats || noptions == 0) {
        time_t uxtfirst = UXtime(tfirst);
-       printf("The time of the dump was %u %s", now, ctime(&now));
-       printf("The last time cleanup ran was %u %s", uxtfirst,
+       printf("The time of the dump was %u %s", (unsigned int) now, ctime(&now));
+       printf("The last time cleanup ran was %u %s", (unsigned int) uxtfirst,
               ctime(&uxtfirst));
        PrintCallBackStats();
     }
@@ -2849,7 +2913,7 @@ PrintCB(register struct CallBack *cb, afs_uint32 now)
     if (fe == NULL)
        return;
 
-    printf("vol=%u vn=%u cbs=%d hi=%d st=%d fest=%d, exp in %d secs at %s",
+    printf("vol=%u vn=%u cbs=%d hi=%d st=%d fest=%d, exp in %lu secs at %s",
           fe->volid, fe->vnode, fe->ncbs, cb->hhead, cb->status, fe->status,
           expires - now, ctime(&expires));
 }