Avoid incomplete function type in casts
[openafs.git] / src / fsprobe / fsprobe.c
index 5b0d959..e19600e 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Copyright 2000, International Business Machines Corporation and others.
  * All Rights Reserved.
- * 
+ *
  * This software has been released under the terms of the IBM Public
  * License.  For details, see the LICENSE file in the top-level source
  * directory or online at http://www.openafs.org/dl/license10.html
 #include <afsconfig.h>
 #include <afs/param.h>
 
-RCSID("$Header$");
-
+#include <roken.h>
 
-#ifdef HAVE_STRING_H
-#include <string.h>
-#else
-#ifdef HAVE_STRINGS_H
-#include <strings.h>
-#endif
-#endif
-
-#include <fsprobe.h>                   /*Interface for this module*/
-#include <lwp.h>                       /*Lightweight process package*/
+#include <pthread.h>
 #include <afs/cellconfig.h>
+#include <afs/afsint.h>
+#include <afs/afsutil.h>
+#include <afs/volser.h>
+#include <afs/volser_prototypes.h>
+#define FSINT_COMMON_XG
+#include <afs/afscbint.h>
 
-#define LWP_STACK_SIZE (16 * 1024)
-
-/*
- * Routines we need that don't have explicit include file definitions.
- */
-extern int RXAFSCB_ExecuteRequest();   /*AFS callback dispatcher*/
-extern char *hostutil_GetNameByINet(); /*Host parsing utility*/
-
-/*
- * Help out the linker by explicitly importing the callback routines.
- */
-extern afs_int32 SRXAFSCB_CallBack();
-extern afs_int32 SRXAFSCB_InitCallBackState2();
-extern afs_int32 SRXAFSCB_Probe();
+#include "fsprobe.h"           /*Interface for this module */
 
 /*
  * Exported variables.
  */
-int fsprobe_numServers;                                 /*Num servers connected*/
-struct fsprobe_ConnectionInfo *fsprobe_ConnInfo; /*Ptr to connection array*/
-struct fsprobe_ProbeResults fsprobe_Results;    /*Latest probe results*/
-int fsprobe_ProbeFreqInSecs;                    /*Probe freq. in seconds*/
+int fsprobe_numServers;                /*Num servers connected */
+struct fsprobe_ConnectionInfo *fsprobe_ConnInfo;       /*Ptr to connection array */
+struct fsprobe_ProbeResults fsprobe_Results;   /*Latest probe results */
+int fsprobe_ProbeFreqInSecs;   /*Probe freq. in seconds */
 
 /*
  * Private globals.
  */
-static int fsprobe_initflag = 0;               /*Was init routine called?*/
-static int fsprobe_debug = 0;                  /*Debugging output enabled?*/
-static int (*fsprobe_Handler)();               /*Probe handler routine*/
-static PROCESS probeLWP_ID;                    /*Probe LWP process ID*/
-static int fsprobe_statsBytes;                 /*Num bytes in stats block*/
-static int fsprobe_probeOKBytes;               /*Num bytes in probeOK block*/
-
-/*
- * We have to pass a port to Rx to start up our callback listener
- * service, but 7001 is already taken up by the Cache Manager.  So,
- * we make up our own.
- */
-#define FSPROBE_CBPORT 7101
-
+static int fsprobe_initflag = 0;       /*Was init routine called? */
+static int fsprobe_debug = 0;  /*Debugging output enabled? */
+static int (*fsprobe_Handler) (void);  /*Probe handler routine */
+static pthread_t fsprobe_thread;       /*Probe thread */
+static int fsprobe_statsBytes; /*Num bytes in stats block */
+static int fsprobe_probeOKBytes;       /*Num bytes in probeOK block */
+static opr_mutex_t fsprobe_force_lock; /*Lock to force probe */
+static opr_cv_t fsprobe_force_cv;      /*Condvar to force probe */
 
 /*------------------------------------------------------------------------
  * [private] fsprobe_CleanupInit
@@ -93,34 +70,34 @@ static int fsprobe_probeOKBytes;            /*Num bytes in probeOK block*/
  *     Zeros out basic data structures.
  *------------------------------------------------------------------------*/
 
-static int fsprobe_CleanupInit()
-
-{ /*fsprobe_CleanupInit*/
+static int
+fsprobe_CleanupInit(void)
+{                              /*fsprobe_CleanupInit */
 
-    afs_int32 code;                    /*Return code from callback stubs*/
-    struct rx_call *rxcall;    /*Bogus param*/
-    AFSCBFids *Fids_Array;     /*Bogus param*/
-    AFSCBs *CallBack_Array;    /*Bogus param*/
-    struct interfaceAddr *interfaceAddr; /*Bogus param*/
+    afs_int32 code;            /*Return code from callback stubs */
+    struct rx_call *rxcall;    /*Bogus param */
+    AFSCBFids *Fids_Array;     /*Bogus param */
+    AFSCBs *CallBack_Array;    /*Bogus param */
+    struct interfaceAddr *interfaceAddr;       /*Bogus param */
 
     fsprobe_ConnInfo = (struct fsprobe_ConnectionInfo *)0;
     memset(&fsprobe_Results, 0, sizeof(struct fsprobe_ProbeResults));
 
-    rxcall        = (struct rx_call *)0;
-    Fids_Array    = (AFSCBFids *)0;
-    CallBack_Array = (AFSCBs *)0;
-    interfaceAddr  = NULL;
+    rxcall = (struct rx_call *)0;
+    Fids_Array = (AFSCBFids *) 0;
+    CallBack_Array = (AFSCBs *) 0;
+    interfaceAddr = NULL;
 
     code = SRXAFSCB_CallBack(rxcall, Fids_Array, CallBack_Array);
     if (code)
-       return(code);
+       return (code);
     code = SRXAFSCB_InitCallBackState2(rxcall, interfaceAddr);
     if (code)
-       return(code);
+       return (code);
     code = SRXAFSCB_Probe(rxcall);
-    return(code);
+    return (code);
 
-} /*fsprobe_CleanupInit*/
+}                              /*fsprobe_CleanupInit */
 
 
 /*------------------------------------------------------------------------
@@ -146,81 +123,78 @@ static int fsprobe_CleanupInit()
  *     (if so directed).
  *------------------------------------------------------------------------*/
 
-int fsprobe_Cleanup(a_releaseMem)
-    int a_releaseMem;
+int
+fsprobe_Cleanup(int a_releaseMem)
+{                              /*fsprobe_Cleanup */
 
-{ /*fsprobe_Cleanup*/
-
-    static char rn[] = "fsprobe_Cleanup";      /*Routine name*/
-    int code;                                  /*Return code*/
-    int conn_idx;                              /*Current connection index*/
-    struct fsprobe_ConnectionInfo *curr_conn;  /*Ptr to fsprobe connection*/
+    static char rn[] = "fsprobe_Cleanup";      /*Routine name */
+    int code;                  /*Return code */
+    int conn_idx;              /*Current connection index */
+    struct fsprobe_ConnectionInfo *curr_conn;  /*Ptr to fsprobe connection */
 
     /*
      * Assume the best, but check the worst.
      */
     if (!fsprobe_initflag) {
-      fprintf(stderr, "[%s] Refused; module not initialized\n", rn);
-      return(-1);
-    }
-    else
-      code = 0;
+       fprintf(stderr, "[%s] Refused; module not initialized\n", rn);
+       return (-1);
+    } else
+       code = 0;
 
     /*
      * Take care of all Rx connections first.  Check to see that the
      * server count is a legal value.
      */
     if (fsprobe_numServers <= 0) {
-      fprintf(stderr,
-             "[%s] Illegal number of servers to clean up (fsprobe_numServers = %d)\n",
-             rn, fsprobe_numServers);
-      code = -1;
-    }
-    else {
-      if (fsprobe_ConnInfo != (struct fsprobe_ConnectionInfo *)0) {
-       /*
-        * The fsprobe connection structure array exists.  Go through it
-        * and close up any Rx connections it holds.
-        */
-       curr_conn = fsprobe_ConnInfo;
-       for (conn_idx = 0; conn_idx < fsprobe_numServers; conn_idx++) {
-         if (curr_conn->rxconn != (struct rx_connection *)0) {
-           rx_DestroyConnection(curr_conn->rxconn);
-           curr_conn->rxconn = (struct rx_connection *)0;
-         }
-         if (curr_conn->rxVolconn != (struct rx_connection *)0) {
-           rx_DestroyConnection(curr_conn->rxVolconn);
-           curr_conn->rxVolconn = (struct rx_connection *)0;
-         }
-         curr_conn++;
-       } /*for each fsprobe connection*/
-      } /*fsprobe connection structure exists*/
-    } /*Legal number of servers*/
+       fprintf(stderr,
+               "[%s] Illegal number of servers to clean up (fsprobe_numServers = %d)\n",
+               rn, fsprobe_numServers);
+       code = -1;
+    } else {
+       if (fsprobe_ConnInfo != (struct fsprobe_ConnectionInfo *)0) {
+           /*
+            * The fsprobe connection structure array exists.  Go through it
+            * and close up any Rx connections it holds.
+            */
+           curr_conn = fsprobe_ConnInfo;
+           for (conn_idx = 0; conn_idx < fsprobe_numServers; conn_idx++) {
+               if (curr_conn->rxconn != (struct rx_connection *)0) {
+                   rx_DestroyConnection(curr_conn->rxconn);
+                   curr_conn->rxconn = (struct rx_connection *)0;
+               }
+               if (curr_conn->rxVolconn != (struct rx_connection *)0) {
+                   rx_DestroyConnection(curr_conn->rxVolconn);
+                   curr_conn->rxVolconn = (struct rx_connection *)0;
+               }
+               curr_conn++;
+           }                   /*for each fsprobe connection */
+       }                       /*fsprobe connection structure exists */
+    }                          /*Legal number of servers */
 
     /*
      * Now, release all the space we've allocated, if asked to.
      */
     if (a_releaseMem) {
-      if (fsprobe_ConnInfo != (struct fsprobe_ConnectionInfo *)0)
-       free(fsprobe_ConnInfo);
-      if (fsprobe_Results.stats != NULL)
-       free(fsprobe_Results.stats);
-      if (fsprobe_Results.probeOK != (int *)0)
-       free(fsprobe_Results.probeOK);
+       if (fsprobe_ConnInfo != (struct fsprobe_ConnectionInfo *)0)
+           free(fsprobe_ConnInfo);
+       if (fsprobe_Results.stats != NULL)
+           free(fsprobe_Results.stats);
+       if (fsprobe_Results.probeOK != (int *)0)
+           free(fsprobe_Results.probeOK);
     }
 
     /*
      * Return the news, whatever it is.
      */
-    return(code);
+    return (code);
 
-} /*fsprobe_Cleanup*/
+}                              /*fsprobe_Cleanup */
 
 /*------------------------------------------------------------------------
  * [private] fsprobe_LWP
  *
  * Description:
- *     This LWP iterates over the server connections and gathers up
+ *     This thread iterates over the server connections and gathers up
  *     the desired statistics from each one on a regular basis.  When
  *     the sweep is done, the associated handler function is called
  *     to process the new data.
@@ -237,137 +211,183 @@ int fsprobe_Cleanup(a_releaseMem)
  * Side Effects:
  *     As advertised.
  *------------------------------------------------------------------------*/
-static void fsprobe_LWP()
-
-{ /*fsprobe_LWP*/
-
-    static char rn[] = "fsprobe_LWP";          /*Routine name*/
-    register afs_int32 code;                           /*Results of calls*/
-    struct timeval tv;                         /*Time structure*/
-    int conn_idx;                              /*Connection index*/
-    struct fsprobe_ConnectionInfo *curr_conn;  /*Current connection*/
-    struct ProbeViceStatistics *curr_stats;    /*Current stats region*/
-    int *curr_probeOK;                         /*Current probeOK field*/
-
-    while (1) { /*Service loop*/
+static void *
+fsprobe_LWP(void *unused)
+{                              /*fsprobe_LWP */
+
+    static char rn[] = "fsprobe_LWP";  /*Routine name */
+    afs_int32 code;    /*Results of calls */
+    struct timeval tv;         /*Time structure */
+    struct timespec wait;      /*Time to wait */
+    int conn_idx;              /*Connection index */
+    struct fsprobe_ConnectionInfo *curr_conn;  /*Current connection */
+    struct ProbeViceStatistics *curr_stats;    /*Current stats region */
+    int *curr_probeOK;         /*Current probeOK field */
+    ViceStatistics64 stats64;      /*Current stats region */
+    stats64.ViceStatistics64_val = malloc(STATS64_VERSION *
+                                         sizeof(afs_uint64));
+    while (1) {                        /*Service loop */
        /*
         * Iterate through the server connections, gathering data.
         * Don't forget to bump the probe count and zero the statistics
         * areas before calling the servers.
         */
-      if (fsprobe_debug)
-       fprintf(stderr, "[%s] Waking up, collecting data from %d connected servers\n",
-               rn, fsprobe_numServers);
-      curr_conn    = fsprobe_ConnInfo;
-      curr_stats   = fsprobe_Results.stats;
-      curr_probeOK = fsprobe_Results.probeOK;
-      fsprobe_Results.probeNum++;
-      memset(fsprobe_Results.stats, 0, fsprobe_statsBytes);
-      memset(fsprobe_Results.probeOK, 0, fsprobe_probeOKBytes);
-
-      for (conn_idx = 0; conn_idx < fsprobe_numServers; conn_idx++) {
-         /*
-          * Grab the statistics for the current FileServer, if the
-          * connection is valid.
-          */
        if (fsprobe_debug)
-         fprintf(stderr, "[%s] Contacting server %s\n", rn, curr_conn->hostName);
-       if (curr_conn->rxconn != (struct rx_connection *)0) {
-         if (fsprobe_debug)
-           fprintf(stderr, "[%s] Connection valid, calling RXAFS_GetStatistics\n", rn);
-         *curr_probeOK = RXAFS_GetStatistics(curr_conn->rxconn, curr_stats);
-
-       } /*Valid Rx connection*/
+           fprintf(stderr,
+                   "[%s] Waking up, collecting data from %d connected servers\n",
+                   rn, fsprobe_numServers);
+       curr_conn = fsprobe_ConnInfo;
+       curr_stats = fsprobe_Results.stats;
+       curr_probeOK = fsprobe_Results.probeOK;
+       fsprobe_Results.probeNum++;
+       memset(fsprobe_Results.stats, 0, fsprobe_statsBytes);
+       memset(fsprobe_Results.probeOK, 0, fsprobe_probeOKBytes);
 
-         /*
-          * Call the Volume Server too to get additional stats
-          */
-       if (fsprobe_debug)
-         fprintf(stderr, "[%s] Contacting volume server %s\n", rn, curr_conn->hostName);
-       if (curr_conn->rxVolconn != (struct rx_connection *)0) {
-           int i, code;
-           char pname[10];
-           struct diskPartition partition;
+       for (conn_idx = 0; conn_idx < fsprobe_numServers; conn_idx++) {
+           /*
+            * Grab the statistics for the current FileServer, if the
+            * connection is valid.
+            */
+           if (fsprobe_debug)
+               fprintf(stderr, "[%s] Contacting server %s\n", rn,
+                       curr_conn->hostName);
+           if (curr_conn->rxconn != (struct rx_connection *)0) {
+               if (fsprobe_debug)
+                   fprintf(stderr,
+                           "[%s] Connection valid, calling RXAFS_GetStatistics\n",
+                           rn);
+               *curr_probeOK =
+                   RXAFS_GetStatistics64(curr_conn->rxconn, STATS64_VERSION, &stats64);
+               if (*curr_probeOK == RXGEN_OPCODE)
+                   *curr_probeOK =
+                       RXAFS_GetStatistics(curr_conn->rxconn, (ViceStatistics *)curr_stats);
+               else if (*curr_probeOK == 0) {
+                   curr_stats->CurrentTime = RoundInt64ToInt32(stats64.ViceStatistics64_val[STATS64_CURRENTTIME]);
+                   curr_stats->BootTime = RoundInt64ToInt32(stats64.ViceStatistics64_val[STATS64_BOOTTIME]);
+                   curr_stats->StartTime = RoundInt64ToInt32(stats64.ViceStatistics64_val[STATS64_STARTTIME]);
+                   curr_stats->CurrentConnections = RoundInt64ToInt32(stats64.ViceStatistics64_val[STATS64_CURRENTCONNECTIONS]);
+                   curr_stats->TotalFetchs = RoundInt64ToInt32(stats64.ViceStatistics64_val[STATS64_TOTALFETCHES]);
+                   curr_stats->TotalStores = RoundInt64ToInt32(stats64.ViceStatistics64_val[STATS64_TOTALSTORES]);
+                   curr_stats->WorkStations = RoundInt64ToInt32(stats64.ViceStatistics64_val[STATS64_WORKSTATIONS]);
+               }
+           }
 
+           /*Valid Rx connection */
+           /*
+            * Call the Volume Server too to get additional stats
+            */
            if (fsprobe_debug)
-               fprintf(stderr, "[%s] Connection valid, calling RXAFS_GetStatistics\n", rn);
-           for (i = 0 ; i < curr_conn->partCnt; i++) {
-               if (curr_conn->partList.partFlags[i] & PARTVALID) {
-                   MapPartIdIntoName(curr_conn->partList.partId[i], pname);
-                   code = AFSVolPartitionInfo(curr_conn->rxVolconn, pname, &partition);
-                   if (code) {
-                       fprintf(stderr, "Could not get information on server %s partition %s\n", curr_conn->hostName, pname);
-                   } else {
-                       curr_stats->Disk[i].BlocksAvailable = partition.free;
-                       curr_stats->Disk[i].TotalBlocks = partition.minFree;
-                       strcpy(curr_stats->Disk[i].Name, pname);
+               fprintf(stderr, "[%s] Contacting volume server %s\n", rn,
+                       curr_conn->hostName);
+           if (curr_conn->rxVolconn != (struct rx_connection *)0) {
+               int i, code;
+               char pname[10];
+               struct diskPartition partition;
+               struct diskPartition64 *partition64p =
+                   malloc(sizeof(struct diskPartition64));
+
+               if (fsprobe_debug)
+                   fprintf(stderr,
+                           "[%s] Connection valid, calling RXAFS_GetStatistics\n",
+                           rn);
+               for (i = 0; i < curr_conn->partCnt; i++) {
+                   if (curr_conn->partList.partFlags[i] & PARTVALID) {
+                       MapPartIdIntoName(curr_conn->partList.partId[i],
+                                         pname);
+                       code =
+                           AFSVolPartitionInfo64(curr_conn->rxVolconn, pname,
+                                                 partition64p);
+
+                       if (!code) {
+                           curr_stats->Disk[i].BlocksAvailable =
+                               RoundInt64ToInt31(partition64p->free);
+                           curr_stats->Disk[i].TotalBlocks =
+                               RoundInt64ToInt31(partition64p->minFree);
+                           strcpy(curr_stats->Disk[i].Name, pname);
+                       }
+                       if (code == RXGEN_OPCODE) {
+                           code =
+                               AFSVolPartitionInfo(curr_conn->rxVolconn,
+                                                   pname, &partition);
+                           if (!code) {
+                               curr_stats->Disk[i].BlocksAvailable =
+                                   partition.free;
+                               curr_stats->Disk[i].TotalBlocks =
+                                   partition.minFree;
+                               strcpy(curr_stats->Disk[i].Name, pname);
+                           }
+                       }
+                       if (code) {
+                           fprintf(stderr,
+                                   "Could not get information on server %s partition %s\n",
+                                   curr_conn->hostName, pname);
+                       }
                    }
                }
-
+               free(partition64p);
            }
-       }
 
 
+           /*
+            * Advance the fsprobe connection pointer & stats pointer.
+            */
+           curr_conn++;
+           curr_stats++;
+           curr_probeOK++;
+
+       }                       /*For each fsprobe connection */
+
        /*
-        * Advance the fsprobe connection pointer & stats pointer.
+        * All (valid) connections have been probed.  Now, call the
+        * associated handler function.  The handler does not take
+        * any explicit parameters, rather gets to the goodies via
+        * some of the objects exported by this module.
         */
-       curr_conn++;
-       curr_stats++;
-       curr_probeOK++;
-
-      } /*For each fsprobe connection*/
-
-      /*
-       * All (valid) connections have been probed.  Now, call the
-       * associated handler function.  The handler does not take
-       * any explicit parameters, rather gets to the goodies via
-       * some of the objects exported by this module.
-       */
-      if (fsprobe_debug)
-       fprintf(stderr, "[%s] Polling complete, calling associated handler routine.\n",
-               rn);
-      code = fsprobe_Handler();
-      if (code)
-       fprintf(stderr, "[%s] Handler routine returned error code %d\n", rn, code);
-
-      /*
-       * Fall asleep for the prescribed number of seconds.
-       */
-      tv.tv_sec  = fsprobe_ProbeFreqInSecs;
-      tv.tv_usec = 0;
-      if (fsprobe_debug)
-       fprintf(stderr, "[%s] Falling asleep for %d seconds\n", rn, fsprobe_ProbeFreqInSecs);
-      code = IOMGR_Select(0,   /*Num fids*/
-                         0,    /*Descriptors ready for reading*/
-                         0,    /*Descriptors ready for writing*/
-                         0,    /*Descriptors w/exceptional conditions*/
-                         &tv); /*Ptr to timeout structure*/
-      if (code)
-       fprintf(stderr, "[%s] IOMGR_Select returned code %d\n", rn, code);
-    } /*Service loop*/
-
-} /*fsprobe_LWP*/
+       if (fsprobe_debug)
+           fprintf(stderr,
+                   "[%s] Polling complete, calling associated handler routine.\n",
+                   rn);
+       code = fsprobe_Handler();
+       if (code)
+           fprintf(stderr, "[%s] Handler routine returned error code %d\n",
+                   rn, code);
+
+       /*
+        * Fall asleep for the prescribed number of seconds or wakeup
+        * sooner if forced.
+        */
+       gettimeofday(&tv, NULL);
+       wait.tv_sec = tv.tv_sec + fsprobe_ProbeFreqInSecs;
+       wait.tv_nsec = tv.tv_usec * 1000;
+       opr_mutex_enter(&fsprobe_force_lock);
+       code = opr_cv_timedwait(&fsprobe_force_cv, &fsprobe_force_lock, &wait);
+       opr_Assert(code == 0 || code == ETIMEDOUT);
+       opr_mutex_exit(&fsprobe_force_lock);
+    }                          /*Service loop */
+    AFS_UNREACHED(free(stats64.ViceStatistics64_val));
+    AFS_UNREACHED(return(NULL));
+}                              /*fsprobe_LWP */
 
 /*list all the partitions on <aserver> */
-static int newvolserver=0;
-XListPartitions(aconn, ptrPartList, cntp)
-    struct rx_connection *aconn;
-    struct partList *ptrPartList;
-    afs_int32 *cntp;
+static int newvolserver = 0;
+
+int
+XListPartitions(struct rx_connection *aconn, struct partList *ptrPartList,
+               afs_int32 *cntp)
 {
     struct pIDs partIds;
     struct partEntries partEnts;
-    register int i, j=0, code;
+    int i, j = 0, code;
 
     *cntp = 0;
     if (newvolserver == 1) {
-       for(i = 0; i < 26; i++)
-           partIds.partIds[i]  = -1;
-tryold:
+       for (i = 0; i < 26; i++)
+           partIds.partIds[i] = -1;
+      tryold:
        code = AFSVolListPartitions(aconn, &partIds);
        if (!code) {
-           for (i = 0;i < 26; i++) {
-               if((partIds.partIds[i]) != -1) {
+           for (i = 0; i < 26; i++) {
+               if ((partIds.partIds[i]) != -1) {
                    ptrPartList->partId[j] = partIds.partIds[i];
                    ptrPartList->partFlags[j] = PARTVALID;
                    j++;
@@ -392,19 +412,21 @@ tryold:
     if (!code) {
        *cntp = partEnts.partEntries_len;
        if (*cntp > VOLMAXPARTS) {
-           fprintf(stderr,"Warning: number of partitions on the server too high %d (process only %d)\n",
+           fprintf(stderr,
+                   "Warning: number of partitions on the server too high %d (process only %d)\n",
                    *cntp, VOLMAXPARTS);
            *cntp = VOLMAXPARTS;
        }
-       for (i = 0;i < *cntp; i++) {
+       for (i = 0; i < *cntp; i++) {
            ptrPartList->partId[i] = partEnts.partEntries_val[i];
            ptrPartList->partFlags[i] = PARTVALID;
        }
        free(partEnts.partEntries_val);
     }
-out:
+  out:
     if (code)
-       fprintf(stderr,"Could not fetch the list of partitions from the server\n");
+       fprintf(stderr,
+               "Could not fetch the list of partitions from the server\n");
     return code;
 }
 
@@ -414,7 +436,7 @@ out:
  *
  * Description:
  *     Initialize the fsprobe module: set up Rx connections to the
- *     given set of servers, start up the probe and callback LWPs,
+ *     given set of servers, start up the probe and callback threads,
  *     and associate the routine to be called when a probe completes.
  *
  * Arguments:
@@ -427,7 +449,7 @@ out:
  * Returns:
  *     0 on success,
  *     -2 for (at least one) connection error,
- *     LWP process creation code, if it failed,
+ *     thread process creation code, if it failed,
  *     -1 for other fatal errors.
  *
  * Environment:
@@ -439,69 +461,67 @@ out:
  *     Sets up just about everything.
  *------------------------------------------------------------------------*/
 
-int fsprobe_Init(a_numServers, a_socketArray, a_ProbeFreqInSecs, a_ProbeHandler, a_debug)
-    int a_numServers;
-    struct sockaddr_in *a_socketArray;
-    int a_ProbeFreqInSecs;
-    int (*a_ProbeHandler)();
-    int a_debug;
-
-{ /*fsprobe_Init*/
-
-    static char rn[] = "fsprobe_Init";         /*Routine name*/
-    register afs_int32 code;                   /*Return value*/
-    static struct rx_securityClass *CBsecobj;  /*Callback security object*/
-    struct rx_securityClass *secobj;           /*Client security object*/
-    struct rx_service *rxsrv_afsserver;                /*Server for AFS*/
-    int arg_errfound;                          /*Argument error found?*/
-    int curr_srv;                              /*Current server idx*/
-    struct fsprobe_ConnectionInfo *curr_conn;  /*Ptr to current conn*/
-    char *hostNameFound;                       /*Ptr to returned host name*/
-    int conn_err;                              /*Connection error?*/
-    int PortToUse;                             /*Callback port to use*/
+int
+fsprobe_Init(int a_numServers, struct sockaddr_in *a_socketArray,
+            int a_ProbeFreqInSecs, int (*a_ProbeHandler)(void),
+            int a_debug)
+{                              /*fsprobe_Init */
+
+    static char rn[] = "fsprobe_Init"; /*Routine name */
+    afs_int32 code;    /*Return value */
+    static struct rx_securityClass *CBsecobj;  /*Callback security object */
+    struct rx_securityClass *secobj;   /*Client security object */
+    struct rx_service *rxsrv_afsserver;        /*Server for AFS */
+    int arg_errfound;          /*Argument error found? */
+    int curr_srv;              /*Current server idx */
+    struct fsprobe_ConnectionInfo *curr_conn;  /*Ptr to current conn */
+    char *hostNameFound;       /*Ptr to returned host name */
+    int conn_err;              /*Connection error? */
 
     /*
      * If we've already been called, snicker at the bozo, gently
      * remind him of his doubtful heritage, and return success.
      */
     if (fsprobe_initflag) {
-      fprintf(stderr, "[%s] Called multiple times!\n", rn);
-      return(0);
-    }
-    else
-     fsprobe_initflag = 1; 
+       fprintf(stderr, "[%s] Called multiple times!\n", rn);
+       return (0);
+    } else
+       fsprobe_initflag = 1;
+
+    opr_mutex_init(&fsprobe_force_lock);
+    opr_cv_init(&fsprobe_force_cv);
 
     /*
      * Check the parameters for bogosities.
      */
     arg_errfound = 0;
     if (a_numServers <= 0) {
-      fprintf(stderr, "[%s] Illegal number of servers: %d\n",
-             rn, a_numServers);
-      arg_errfound = 1;
+       fprintf(stderr, "[%s] Illegal number of servers: %d\n", rn,
+               a_numServers);
+       arg_errfound = 1;
     }
     if (a_socketArray == (struct sockaddr_in *)0) {
-      fprintf(stderr, "[%s] Null server socket array argument\n", rn);
-      arg_errfound = 1;
+       fprintf(stderr, "[%s] Null server socket array argument\n", rn);
+       arg_errfound = 1;
     }
     if (a_ProbeFreqInSecs <= 0) {
-      fprintf(stderr, "[%s] Illegal probe frequency: %d\n",
-             rn, a_ProbeFreqInSecs);
-      arg_errfound = 1;
+       fprintf(stderr, "[%s] Illegal probe frequency: %d\n", rn,
+               a_ProbeFreqInSecs);
+       arg_errfound = 1;
     }
-    if (a_ProbeHandler == (int (*)())0) {
-      fprintf(stderr, "[%s] Null probe handler function argument\n", rn);
-      arg_errfound = 1;
+    if (a_ProbeHandler == NULL) {
+       fprintf(stderr, "[%s] Null probe handler function argument\n", rn);
+       arg_errfound = 1;
     }
     if (arg_errfound)
-      return(-1);
+       return (-1);
 
     /*
      * Record our passed-in info.
      */
-    fsprobe_debug          = a_debug;
-    fsprobe_numServers      = a_numServers;
-    fsprobe_Handler        = a_ProbeHandler;
+    fsprobe_debug = a_debug;
+    fsprobe_numServers = a_numServers;
+    fsprobe_Handler = a_ProbeHandler;
     fsprobe_ProbeFreqInSecs = a_ProbeFreqInSecs;
 
     /*
@@ -514,79 +534,58 @@ int fsprobe_Init(a_numServers, a_socketArray, a_ProbeFreqInSecs, a_ProbeHandler,
      * Allocate the necessary data structures and initialize everything
      * else.
      */
-    fsprobe_ConnInfo =
-      (struct fsprobe_ConnectionInfo *)
+    fsprobe_ConnInfo = (struct fsprobe_ConnectionInfo *)
        malloc(a_numServers * sizeof(struct fsprobe_ConnectionInfo));
     if (fsprobe_ConnInfo == (struct fsprobe_ConnectionInfo *)0) {
-      fprintf(stderr,
-             "[%s] Can't allocate %d connection info structs (%d bytes)\n",
-             rn, a_numServers,
-             (a_numServers * sizeof(struct fsprobe_ConnectionInfo)));
-      return(-1);      /*No cleanup needs to be done yet*/
+       fprintf(stderr,
+               "[%s] Can't allocate %d connection info structs (%"AFS_SIZET_FMT" bytes)\n",
+               rn, a_numServers,
+               (a_numServers * sizeof(struct fsprobe_ConnectionInfo)));
+       return (-1);            /*No cleanup needs to be done yet */
     }
-#if 0
-    else
-      fprintf(stderr, "[%s] fsprobe_ConnInfo allocated (%d bytes)\n",
-             rn, a_numServers * sizeof(struct fsprobe_ConnectionInfo));
-#endif /* 0 */
 
     fsprobe_statsBytes = a_numServers * sizeof(struct ProbeViceStatistics);
     fsprobe_Results.stats = (struct ProbeViceStatistics *)
-      malloc(fsprobe_statsBytes);
+       malloc(fsprobe_statsBytes);
     if (fsprobe_Results.stats == NULL) {
-      fprintf(stderr,
-             "[%s] Can't allocate %d statistics structs (%d bytes)\n",
-             rn, a_numServers, fsprobe_statsBytes);
-      fsprobe_Cleanup(1); /*Delete already-malloc'ed areas*/
-      return(-1);
-    }
-    else
-      if (fsprobe_debug)
+       fprintf(stderr,
+               "[%s] Can't allocate %d statistics structs (%d bytes)\n", rn,
+               a_numServers, fsprobe_statsBytes);
+       fsprobe_Cleanup(1);     /*Delete already-malloc'ed areas */
+       return (-1);
+    } else if (fsprobe_debug)
        fprintf(stderr, "[%s] fsprobe_Results.stats allocated (%d bytes)\n",
                rn, fsprobe_statsBytes);
 
     fsprobe_probeOKBytes = a_numServers * sizeof(int);
-    fsprobe_Results.probeOK = (int *) malloc(fsprobe_probeOKBytes);
+    fsprobe_Results.probeOK = malloc(fsprobe_probeOKBytes);
     if (fsprobe_Results.probeOK == (int *)0) {
-      fprintf(stderr,
-             "[%s] Can't allocate %d probeOK array entries (%d bytes)\n",
-             rn, a_numServers, fsprobe_probeOKBytes);
-      fsprobe_Cleanup(1); /*Delete already-malloc'ed areas*/
-      return(-1);
-    }
-    else
-      if (fsprobe_debug)
        fprintf(stderr,
-               "[%s] fsprobe_Results.probeOK allocated (%d bytes)\n",
+               "[%s] Can't allocate %d probeOK array entries (%d bytes)\n",
+               rn, a_numServers, fsprobe_probeOKBytes);
+       fsprobe_Cleanup(1);     /*Delete already-malloc'ed areas */
+       return (-1);
+    } else if (fsprobe_debug)
+       fprintf(stderr, "[%s] fsprobe_Results.probeOK allocated (%d bytes)\n",
                rn, fsprobe_probeOKBytes);
 
-    fsprobe_Results.probeNum  = 0;
+    fsprobe_Results.probeNum = 0;
     fsprobe_Results.probeTime = 0;
-    memset(fsprobe_Results.stats, 0, (a_numServers * sizeof(struct ProbeViceStatistics)));
+    memset(fsprobe_Results.stats, 0,
+          (a_numServers * sizeof(struct ProbeViceStatistics)));
 
     /*
      * Initialize the Rx subsystem, just in case nobody's done it.
      */
     if (fsprobe_debug)
-      fprintf(stderr, "[%s] Initializing Rx\n", rn);
-    PortToUse = FSPROBE_CBPORT;
-    do {
-      code = rx_Init(htons(PortToUse));
-      if (code) {
-       if (code == RX_ADDRINUSE) {
-         if (fsprobe_debug)
-           fprintf(stderr, "[%s] Callback port %d in use, advancing\n",
-                   rn, PortToUse);
-         PortToUse++;
-       }
-       else {
-        fprintf(stderr, "[%s] Fatal error in rx_Init()\n", rn);
-        return(-1);
-       }
-      }
-    } while (code);
+       fprintf(stderr, "[%s] Initializing Rx\n", rn);
+    code = rx_Init(0);
+    if (code) {
+       fprintf(stderr, "[%s] Fatal error in rx_Init()\n", rn);
+       return (-1);
+    }
     if (fsprobe_debug)
-      fprintf(stderr, "[%s] Rx initialized on port %d\n", rn, PortToUse);
+       fprintf(stderr, "[%s] Rx initialized.\n", rn);
 
     /*
      * Create a null Rx server security object, to be used by the
@@ -594,30 +593,30 @@ int fsprobe_Init(a_numServers, a_socketArray, a_ProbeFreqInSecs, a_ProbeHandler,
      */
     CBsecobj = rxnull_NewServerSecurityObject();
     if (CBsecobj == (struct rx_securityClass *)0) {
-      fprintf(stderr,
-             "[%s] Can't create null security object for the callback listener.\n",
-             rn);
-      fsprobe_Cleanup(1); /*Delete already-malloc'ed areas*/
-      return(-1);
+       fprintf(stderr,
+               "[%s] Can't create null security object for the callback listener.\n",
+               rn);
+       fsprobe_Cleanup(1);     /*Delete already-malloc'ed areas */
+       return (-1);
     }
     if (fsprobe_debug)
-      fprintf(stderr, "[%s] Callback server security object created\n", rn);
+       fprintf(stderr, "[%s] Callback server security object created\n", rn);
 
     /*
      * Create a null Rx client security object, to be used by the
-     * probe LWP.
+     * probe thread.
      */
     secobj = rxnull_NewClientSecurityObject();
     if (secobj == (struct rx_securityClass *)0) {
-      fprintf(stderr,
-             "[%s] Can't create client security object for probe LWP.\n",
-             rn);
-      fsprobe_Cleanup(1); /*Delete already-malloc'ed areas*/
-      return(-1);
+       fprintf(stderr,
+               "[%s] Can't create client security object for probe thread.\n",
+               rn);
+       fsprobe_Cleanup(1);     /*Delete already-malloc'ed areas */
+       return (-1);
     }
     if (fsprobe_debug)
-      fprintf(stderr, "[%s] Probe LWP client security object created\n",
-             rn);
+       fprintf(stderr, "[%s] Probe thread client security object created\n",
+               rn);
 
     curr_conn = fsprobe_ConnInfo;
     conn_err = 0;
@@ -626,166 +625,150 @@ int fsprobe_Init(a_numServers, a_socketArray, a_ProbeFreqInSecs, a_ProbeHandler,
         * Copy in the socket info for the current server, resolve its
         * printable name if possible.
         */
-      if (fsprobe_debug) {
-       fprintf(stderr, "[%s] Copying in the following socket info:\n", rn);
-       fprintf(stderr, "[%s] IP addr 0x%lx, port %d\n", rn,
-               (a_socketArray + curr_srv)->sin_addr.s_addr,
-               (a_socketArray + curr_srv)->sin_port);
-      }
-      memcpy(&(curr_conn->skt), a_socketArray + curr_srv, sizeof(struct sockaddr_in));
-
-      hostNameFound = hostutil_GetNameByINet(curr_conn->skt.sin_addr.s_addr);
-      if (hostNameFound == NULL) {
-       fprintf(stderr,
-               "[%s] Can't map Internet address %lu to a string name\n",
-               rn, curr_conn->skt.sin_addr.s_addr);
-       curr_conn->hostName[0] = '\0';
-      }
-      else {
-       strcpy(curr_conn->hostName, hostNameFound);
+       if (fsprobe_debug) {
+           fprintf(stderr, "[%s] Copying in the following socket info:\n",
+                   rn);
+           fprintf(stderr, "[%s] IP addr 0x%x, port %d\n", rn,
+                   (a_socketArray + curr_srv)->sin_addr.s_addr,
+                   (a_socketArray + curr_srv)->sin_port);
+       }
+       memcpy(&(curr_conn->skt), a_socketArray + curr_srv,
+              sizeof(struct sockaddr_in));
+
+       hostNameFound =
+           hostutil_GetNameByINet(curr_conn->skt.sin_addr.s_addr);
+       if (hostNameFound == NULL) {
+           fprintf(stderr,
+                   "[%s] Can't map Internet address %u to a string name\n",
+                   rn, curr_conn->skt.sin_addr.s_addr);
+           curr_conn->hostName[0] = '\0';
+       } else {
+           strcpy(curr_conn->hostName, hostNameFound);
+           if (fsprobe_debug)
+               fprintf(stderr, "[%s] Host name for server index %d is %s\n",
+                       rn, curr_srv, curr_conn->hostName);
+       }
+
+       /*
+        * Make an Rx connection to the current server.
+        */
        if (fsprobe_debug)
-         fprintf(stderr, "[%s] Host name for server index %d is %s\n",
-                 rn, curr_srv, curr_conn->hostName);
-      }
-
-      /*
-       * Make an Rx connection to the current server.
-       */
-      if (fsprobe_debug)
-       fprintf(stderr,
-               "[%s] Connecting to srv idx %d, IP addr 0x%lx, port %d, service 1\n",
-               rn, curr_srv, curr_conn->skt.sin_addr.s_addr,
-               curr_conn->skt.sin_port);
-      curr_conn->rxconn =
-       rx_NewConnection(curr_conn->skt.sin_addr.s_addr, /*Server addr*/
-                        curr_conn->skt.sin_port,        /*Server port*/
-                        1,                              /*AFS service num*/
-                        secobj,                         /*Security object*/
-                        0);                             /*Number of above*/
-      if (curr_conn->rxconn == (struct rx_connection *)0) {
-       fprintf(stderr,
-               "[%s] Can't create Rx connection to server %s (%lu)\n",
-               rn, curr_conn->hostName, curr_conn->skt.sin_addr.s_addr);
-       conn_err = 1;
-      }
-      if (fsprobe_debug)
-       fprintf(stderr, "[%s] New connection at 0x%lx\n",
-               rn, curr_conn->rxconn);
-
-      /*
-       * Make an Rx connection to the current volume server.
-       */
-      if (fsprobe_debug)
-       fprintf(stderr,
-               "[%s] Connecting to srv idx %d, IP addr 0x%lx, port %d, service 1\n",
-               rn, curr_srv, curr_conn->skt.sin_addr.s_addr, htons(7005));
-      curr_conn->rxVolconn =
-       rx_NewConnection(curr_conn->skt.sin_addr.s_addr, /*Server addr*/
-                        htons(AFSCONF_VOLUMEPORT),      /*Volume Server port*/
-                        VOLSERVICE_ID,                  /*AFS service num*/
-                        secobj,                         /*Security object*/
-                        0);                             /*Number of above*/
-      if (curr_conn->rxVolconn == (struct rx_connection *)0) {
-       fprintf(stderr,
-               "[%s] Can't create Rx connection to volume server %s (%lu)\n",
-               rn, curr_conn->hostName, curr_conn->skt.sin_addr.s_addr);
-       conn_err = 1;
-      } else {
-         int i, cnt;
-
-         memset(&curr_conn->partList, 0, sizeof(struct partList));
-         curr_conn->partCnt = 0;
-         i = XListPartitions(curr_conn->rxVolconn, &curr_conn->partList, &cnt);
-         if (!i) {
-             curr_conn->partCnt = cnt;
-         }
-      }
-      if (fsprobe_debug)
-       fprintf(stderr, "[%s] New connection at 0x%lx\n",
-               rn, curr_conn->rxVolconn);
-
-
-      /*
-       * Bump the current fsprobe connection to set up.
-       */
-      curr_conn++;
-
-    } /*for curr_srv*/
+           fprintf(stderr,
+                   "[%s] Connecting to srv idx %d, IP addr 0x%x, port %d, service 1\n",
+                   rn, curr_srv, curr_conn->skt.sin_addr.s_addr,
+                   curr_conn->skt.sin_port);
+       curr_conn->rxconn = rx_NewConnection(curr_conn->skt.sin_addr.s_addr,    /*Server addr */
+                                            curr_conn->skt.sin_port,   /*Server port */
+                                            1, /*AFS service num */
+                                            secobj,    /*Security object */
+                                            0);        /*Number of above */
+       if (curr_conn->rxconn == (struct rx_connection *)0) {
+           fprintf(stderr,
+                   "[%s] Can't create Rx connection to server %s (%u)\n",
+                   rn, curr_conn->hostName, curr_conn->skt.sin_addr.s_addr);
+           conn_err = 1;
+       }
+       if (fsprobe_debug)
+           fprintf(stderr, "[%s] New connection at %p\n", rn,
+                   curr_conn->rxconn);
+
+       /*
+        * Make an Rx connection to the current volume server.
+        */
+       if (fsprobe_debug)
+           fprintf(stderr,
+                   "[%s] Connecting to srv idx %d, IP addr 0x%x, port %d, service 1\n",
+                   rn, curr_srv, curr_conn->skt.sin_addr.s_addr,
+                   htons(7005));
+       curr_conn->rxVolconn = rx_NewConnection(curr_conn->skt.sin_addr.s_addr, /*Server addr */
+                                               htons(AFSCONF_VOLUMEPORT),      /*Volume Server port */
+                                               VOLSERVICE_ID,  /*AFS service num */
+                                               secobj, /*Security object */
+                                               0);     /*Number of above */
+       if (curr_conn->rxVolconn == (struct rx_connection *)0) {
+           fprintf(stderr,
+                   "[%s] Can't create Rx connection to volume server %s (%u)\n",
+                   rn, curr_conn->hostName, curr_conn->skt.sin_addr.s_addr);
+           conn_err = 1;
+       } else {
+           int i, cnt;
+
+           memset(&curr_conn->partList, 0, sizeof(struct partList));
+           curr_conn->partCnt = 0;
+           i = XListPartitions(curr_conn->rxVolconn, &curr_conn->partList,
+                               &cnt);
+           if (!i) {
+               curr_conn->partCnt = cnt;
+           }
+       }
+       if (fsprobe_debug)
+           fprintf(stderr, "[%s] New connection at %p\n", rn,
+                   curr_conn->rxVolconn);
+
+
+       /*
+        * Bump the current fsprobe connection to set up.
+        */
+       curr_conn++;
+
+    }                          /*for curr_srv */
 
     /*
      * Create the AFS callback service (listener).
      */
     if (fsprobe_debug)
-      fprintf(stderr, "[%s] Creating AFS callback listener\n", rn);
-    rxsrv_afsserver =
-      rx_NewService(0,                         /*Use default port*/
-                   1,                          /*Service ID*/
-                   "afs",                      /*Service name*/
-                   &CBsecobj,                  /*Ptr to security object(s)*/
-                   1,                          /*Number of security objects*/
-                   RXAFSCB_ExecuteRequest);    /*Dispatcher*/
+       fprintf(stderr, "[%s] Creating AFS callback listener\n", rn);
+    rxsrv_afsserver = rx_NewService(0, /*Use default port */
+                                   1,  /*Service ID */
+                                   "afs",      /*Service name */
+                                   &CBsecobj,  /*Ptr to security object(s) */
+                                   1,  /*Number of security objects */
+                                   RXAFSCB_ExecuteRequest);    /*Dispatcher */
     if (rxsrv_afsserver == (struct rx_service *)0) {
-      fprintf(stderr, "[%s] Can't create callback Rx service/listener\n", rn);
-      fsprobe_Cleanup(1); /*Delete already-malloc'ed areas*/
-      return(-1);
+       fprintf(stderr, "[%s] Can't create callback Rx service/listener\n",
+               rn);
+       fsprobe_Cleanup(1);     /*Delete already-malloc'ed areas */
+       return (-1);
     }
     if (fsprobe_debug)
-      fprintf(stderr, "[%s] Callback listener created\n", rn);
+       fprintf(stderr, "[%s] Callback listener created\n", rn);
 
     /*
      * Start up the AFS callback service.
      */
     if (fsprobe_debug)
-      fprintf(stderr, "[%s] Starting up callback listener.\n", rn);
-    rx_StartServer(0 /*Don't donate yourself to LWP pool*/);
+       fprintf(stderr, "[%s] Starting up callback listener.\n", rn);
+    rx_StartServer(0 /*Don't donate yourself to thread pool */ );
 
     /*
-     * Start up the probe LWP.
+     * Start up the probe thread.
      */
     if (fsprobe_debug)
-      fprintf(stderr, "[%s] Creating the probe LWP\n", rn);
-    code =
-      LWP_CreateProcess(fsprobe_LWP,           /*Function to start up*/
-                       LWP_STACK_SIZE,         /*Stack size in bytes*/
-                       1,                      /*Priority*/
-                       (void *) 0,             /*Parameters*/
-                       "fsprobe Worker",       /*Name to use*/
-                       &probeLWP_ID);          /*Returned LWP process ID*/
+       fprintf(stderr, "[%s] Creating the probe thread\n", rn);
+    code = pthread_create(&fsprobe_thread, NULL, fsprobe_LWP, NULL);
     if (code) {
-       fprintf(stderr, "[%s] Can't create fsprobe LWP!  Error is %d\n", rn, code);
-       fsprobe_Cleanup(1); /*Delete already-malloc'ed areas*/
-       return(code);
+       fprintf(stderr, "[%s] Can't create fsprobe thread!  Error is %d\n", rn,
+               code);
+       fsprobe_Cleanup(1);     /*Delete already-malloc'ed areas */
+       return (code);
     }
-    if (fsprobe_debug)
-      fprintf(stderr,
-             "[%s] Probe LWP process structure located at 0x%x\n",
-             rn, probeLWP_ID);
-
-#if 0
-    /*
-     * Do I need to do this?
-     */
-    if (fsprobe_debug)
-      fprintf(stderr, "[%s] Calling osi_Wakeup()\n", rn);
-    osi_Wakeup(&rxsrv_afsserver);      /*Wake up anyone waiting for it*/
-#endif /* 0 */
 
     /*
      * Return the final results.
      */
     if (conn_err)
-      return(-2);
+       return (-2);
     else
-      return(0);
+       return (0);
 
-} /*fsprobe_Init*/
+}                              /*fsprobe_Init */
 
 
 /*------------------------------------------------------------------------
  * [exported] fsprobe_ForceProbeNow
  *
  * Description:
- *     Wake up the probe LWP, forcing it to execute a probe immediately.
+ *     Wake up the probe thread, forcing it to execute a probe immediately.
  *
  * Arguments:
  *     None.
@@ -801,28 +784,71 @@ int fsprobe_Init(a_numServers, a_socketArray, a_ProbeFreqInSecs, a_ProbeHandler,
  *     As advertised.
  *------------------------------------------------------------------------*/
 
-int fsprobe_ForceProbeNow()
-
-{ /*fsprobe_ForceProbeNow*/
+int
+fsprobe_ForceProbeNow(void)
+{                              /*fsprobe_ForceProbeNow */
 
-    static char rn[] = "fsprobe_ForceProbeNow";        /*Routine name*/
+    static char rn[] = "fsprobe_ForceProbeNow";        /*Routine name */
 
     /*
      * There isn't a prayer unless we've been initialized.
      */
     if (!fsprobe_initflag) {
-      fprintf(stderr, "[%s] Must call fsprobe_Init first!\n", rn);
-      return(-1);
+       fprintf(stderr, "[%s] Must call fsprobe_Init first!\n", rn);
+       return (-1);
     }
 
     /*
      * Kick the sucker in the side.
      */
-    IOMGR_Cancel(probeLWP_ID);
+    opr_mutex_enter(&fsprobe_force_lock);
+    opr_cv_signal(&fsprobe_force_cv);
+    opr_mutex_exit(&fsprobe_force_lock);
 
     /*
      * We did it, so report the happy news.
      */
-    return(0);
+    return (0);
 
-} /*fsprobe_ForceProbeNow*/
+}                              /*fsprobe_ForceProbeNow */
+
+/*------------------------------------------------------------------------
+ * [exported] fsprobe_Wait
+ *
+ * Description:
+ *     Wait for the collection to complete.
+ *
+ * Arguments:
+ *    int sleep_secs : time to wait in seconds. 0 means sleep forever.
+ *
+ * Returns:
+ *     0 on success,
+ *     Error value otherwise.
+ *
+ * Environment:
+ *     The module must have been initialized.
+ *
+ * Side Effects:
+ *     As advertised.
+ *------------------------------------------------------------------------*/
+int
+fsprobe_Wait(int sleep_secs)
+{
+    int code;
+    struct timeval tv;
+
+    if (sleep_secs == 0) {
+       while (1) {
+           tv.tv_sec = 30;
+           tv.tv_usec = 0;
+           code = select(0, 0, 0, 0, &tv);
+           if (code < 0)
+               break;
+       }
+    } else {
+       tv.tv_sec = sleep_secs;
+       tv.tv_usec = 0;
+       code = select(0, 0, 0, 0, &tv);
+    }
+    return code;
+}