viced: Move host quota calculation
[openafs.git] / src / viced / host.c
index 695abc9..c24841c 100644 (file)
 
 #include <roken.h>
 #include <afs/opr.h>
+#include <opr/lock.h>
 
 #ifdef HAVE_SYS_FILE_H
 #include <sys/file.h>
 #endif
 
-#include <rx/xdr.h>
-#include <lwp.h>
-#include <lock.h>
 #include <afs/afsint.h>
 #define FSINT_COMMON_XG
 #include <afs/afscbint.h>
@@ -71,10 +69,11 @@ int rxcon_ident_key;
 int rxcon_client_key;
 
 static struct rx_securityClass *sc = NULL;
+static int h_quota_limit;
 
 /* arguments for PerHost_EnumerateClient enumeration */
 struct enumclient_args {
-    afs_int32 vid;
+    VolumeId vid;
     int (*proc)(struct client *client, void *rock);
     void *rock;
 };
@@ -211,7 +210,7 @@ GetHTBlock(void)
        ShutDownAndCore(PANIC);
     }
     for (i = 0; i < (h_HTSPERBLOCK); i++)
-       CV_INIT(&block->entry[i].cond, "block entry", CV_DEFAULT, 0);
+       opr_cv_init(&block->entry[i].cond);
     for (i = 0; i < (h_HTSPERBLOCK); i++)
        Lock_Init(&block->entry[i].lock);
     for (i = 0; i < (h_HTSPERBLOCK - 1); i++)
@@ -564,7 +563,7 @@ h_gethostcps_r(struct host *host, afs_int32 now)
     while (host->hostFlags & HCPS_INPROGRESS) {
        slept = 1;              /* I did sleep */
        host->hostFlags |= HCPS_WAITING;        /* I am sleeping now */
-       CV_WAIT(&host->cond, &host_glock_mutex);
+       opr_cv_wait(&host->cond, &host_glock_mutex);
     }
 
 
@@ -620,7 +619,7 @@ h_gethostcps_r(struct host *host, afs_int32 now)
     /* signal all who are waiting */
     if (host->hostFlags & HCPS_WAITING) {      /* somebody is waiting */
        host->hostFlags &= ~HCPS_WAITING;
-       CV_BROADCAST(&host->cond);
+       opr_cv_broadcast(&host->cond);
     }
 }
 
@@ -1608,18 +1607,8 @@ removeInterfaceAddr_r(struct host *host, afs_uint32 addr, afs_uint16 port)
 static int
 h_threadquota(int waiting)
 {
-    if (lwps > 64) {
-       if (waiting > 5)
-           return 1;
-    } else if (lwps > 32) {
-       if (waiting > 4)
-           return 1;
-    } else if (lwps > 16) {
-       if (waiting > 3)
-           return 1;
-    } else {
-       if (waiting > 2)
-           return 1;
+    if (waiting > h_quota_limit) {
+       return 1;
     }
     return 0;
 }
@@ -2129,7 +2118,9 @@ h_GetHost_r(struct rx_connection *tcon)
                    /* the new host is held and locked */
                } else {
                    /* This really is a new host */
-                   h_AddHostToUuidHashTable_r(&identP->uuid, host);
+                   opr_Assert(interfValid == 1);
+                   initInterfaceAddr_r(host, &interf);
+
                    cb_conn = host->callback_rxcon;
                    rx_GetConnection(cb_conn);
                    H_UNLOCK;
@@ -2144,8 +2135,6 @@ h_GetHost_r(struct rx_connection *tcon)
                                ("InitCallBackState3 success on host %" AFS_PTR_FMT " (%s:%d)\n",
                                 host, afs_inet_ntoa_r(host->host, hoststr),
                                 ntohs(host->port)));
-                       opr_Assert(interfValid == 1);
-                       initInterfaceAddr_r(host, &interf);
                    }
                }
            }
@@ -2187,12 +2176,15 @@ h_GetHost_r(struct rx_connection *tcon)
 
 /* not reentrant */
 void
-h_InitHostPackage(void)
+h_InitHostPackage(int hquota)
 {
+    opr_Assert(hquota > 0);
+    h_quota_limit = hquota;
+
     memset(&nulluuid, 0, sizeof(afsUUID));
     rxcon_ident_key = rx_KeyCreate((rx_destructor_t) free);
     rxcon_client_key = rx_KeyCreate((rx_destructor_t) 0);
-    MUTEX_INIT(&host_glock_mutex, "host glock", MUTEX_DEFAULT, 0);
+    opr_mutex_init(&host_glock_mutex);
 }
 
 static int
@@ -2260,7 +2252,7 @@ PerHost_EnumerateClient(struct host *host, void *arock)
 }
 
 void
-h_EnumerateClients(afs_int32 vid,
+h_EnumerateClients(VolumeId vid,
                    int (*proc)(struct client *client, void *rock),
                    void *rock)
 {
@@ -2379,9 +2371,12 @@ getPeerDetails(struct rx_connection *conn,
  *
  * The refCount on client->host is returned incremented.  h_ReleaseClient_r
  * does not decrement the refCount on client->host.
+ *
+ * *a_viceid is set to the user's ViceId, even if we don't return a client
+ * struct.
  */
 struct client *
-h_FindClient_r(struct rx_connection *tcon)
+h_FindClient_r(struct rx_connection *tcon, afs_int32 *a_viceid)
 {
     struct client *client;
     struct host *host = NULL;
@@ -2400,6 +2395,9 @@ h_FindClient_r(struct rx_connection *tcon)
        && !(client->host->hostFlags & HOSTDELETED)
        && !client->deleted) {
 
+       if (a_viceid) {
+           *a_viceid = client->ViceId;
+       }
        client->refCount++;
        h_Hold_r(client->host);
        if (client->prfail != 2) {
@@ -2424,6 +2422,10 @@ h_FindClient_r(struct rx_connection *tcon)
     if (code)
        fail = 1;
 
+    if (a_viceid) {
+       *a_viceid = viceid;
+    }
+
     if (!client) { /* loop */
        host = h_GetHost_r(tcon);       /* Returns with incremented refCount  */
 
@@ -3164,7 +3166,7 @@ h_stateVerifyAddrHash(struct fs_dump_state * state, struct host * h,
 static int
 h_stateVerifyUuidHash(struct fs_dump_state * state, struct host * h)
 {
-    int ret = 0, found = 0;
+    int ret = 0;
     struct host *host = NULL;
     struct h_UuidHashChain *chain;
     afsUUID * uuidp = &h->interface->uuid;
@@ -3187,7 +3189,6 @@ h_stateVerifyUuidHash(struct fs_dump_state * state, struct host * h)
                            h->index, host->index));
                state->flags.warnings_generated = 1;
            }
-           found = 1;
            goto done;
        }
        if (chain_len > FS_STATE_H_MAX_UUID_HASH_CHAIN_LEN) {
@@ -3199,16 +3200,16 @@ h_stateVerifyUuidHash(struct fs_dump_state * state, struct host * h)
        chain_len++;
     }
 
-    if (!found) {
-       afsUUID_to_string(uuidp, tmp, sizeof(tmp));
-       if (state->mode == FS_STATE_LOAD_MODE) {
-           ViceLog(0, ("h_stateVerifyUuidHash: error: uuid %s not found in hash\n", tmp));
-           ret = 1;
-           goto done;
-       } else {
-           ViceLog(0, ("h_stateVerifyUuidHash: warning: uuid %s not found in hash\n", tmp));
-           state->flags.warnings_generated = 1;
-       }
+    /* Fall through, so host not found */
+
+    afsUUID_to_string(uuidp, tmp, sizeof(tmp));
+    if (state->mode == FS_STATE_LOAD_MODE) {
+       ViceLog(0, ("h_stateVerifyUuidHash: error: uuid %s not found in hash\n", tmp));
+       ret = 1;
+       goto done;
+    } else {
+       ViceLog(0, ("h_stateVerifyUuidHash: warning: uuid %s not found in hash\n", tmp));
+       state->flags.warnings_generated = 1;
     }
 
  done:
@@ -3757,112 +3758,6 @@ static struct AFSFid zerofid;
  * Since it can serialize them, and pile up, it should be a separate LWP
  * from other events.
  */
-#if 0
-static int
-CheckHost(struct host *host, int flags, void *rock)
-{
-    struct client *client;
-    struct rx_connection *cb_conn = NULL;
-    int code;
-
-#ifdef AFS_DEMAND_ATTACH_FS
-    /* kill the checkhost lwp ASAP during shutdown */
-    FS_STATE_RDLOCK;
-    if (fs_state.mode == FS_MODE_SHUTDOWN) {
-       FS_STATE_UNLOCK;
-       return H_ENUMERATE_BAIL(flags);
-    }
-    FS_STATE_UNLOCK;
-#endif
-
-    /* Host is held by h_Enumerate */
-    H_LOCK;
-    for (client = host->FirstClient; client; client = client->next) {
-       if (client->refCount == 0 && client->LastCall < clientdeletetime) {
-           client->deleted = 1;
-           host->hostFlags |= CLIENTDELETED;
-       }
-    }
-    if (host->LastCall < checktime) {
-       h_Lock_r(host);
-       if (!(host->hostFlags & HOSTDELETED)) {
-            host->hostFlags |= HWHO_INPROGRESS;
-           cb_conn = host->callback_rxcon;
-           rx_GetConnection(cb_conn);
-           if (host->LastCall < clientdeletetime) {
-               host->hostFlags |= HOSTDELETED;
-               if (!(host->hostFlags & VENUSDOWN)) {
-                   host->hostFlags &= ~ALTADDR;        /* alternate address invalid */
-                   if (host->interface) {
-                       H_UNLOCK;
-                       code =
-                           RXAFSCB_InitCallBackState3(cb_conn,
-                                                      &FS_HostUUID);
-                       H_LOCK;
-                   } else {
-                       H_UNLOCK;
-                       code =
-                           RXAFSCB_InitCallBackState(cb_conn);
-                       H_LOCK;
-                   }
-                   host->hostFlags |= ALTADDR; /* alternate addresses valid */
-                   if (code) {
-                       char hoststr[16];
-                       (void)afs_inet_ntoa_r(host->host, hoststr);
-                       ViceLog(0,
-                               ("CB: RCallBackConnectBack (host.c) failed for host %s:%d\n",
-                                hoststr, ntohs(host->port)));
-                       host->hostFlags |= VENUSDOWN;
-                   }
-                   /* Note:  it's safe to delete hosts even if they have call
-                    * back state, because break delayed callbacks (called when a
-                    * message is received from the workstation) will always send a
-                    * break all call backs to the workstation if there is no
-                    * callback.
-                    */
-               }
-           } else {
-               if (!(host->hostFlags & VENUSDOWN) && host->cblist) {
-                   char hoststr[16];
-                   (void)afs_inet_ntoa_r(host->host, hoststr);
-                   if (host->interface) {
-                       afsUUID uuid = host->interface->uuid;
-                       H_UNLOCK;
-                       code = RXAFSCB_ProbeUuid(cb_conn, &uuid);
-                       H_LOCK;
-                       if (code) {
-                           if (MultiProbeAlternateAddress_r(host)) {
-                               ViceLog(0,("CheckHost: Probing all interfaces of host %s:%d failed, code %d\n",
-                                           hoststr, ntohs(host->port), code));
-                               host->hostFlags |= VENUSDOWN;
-                           }
-                       }
-                   } else {
-                       H_UNLOCK;
-                       code = RXAFSCB_Probe(cb_conn);
-                       H_LOCK;
-                       if (code) {
-                           ViceLog(0,
-                                   ("CheckHost: Probe failed for host %s:%d, code %d\n",
-                                    hoststr, ntohs(host->port), code));
-                           host->hostFlags |= VENUSDOWN;
-                       }
-                   }
-               }
-           }
-           H_UNLOCK;
-           rx_PutConnection(cb_conn);
-           cb_conn=NULL;
-           H_LOCK;
-            host->hostFlags &= ~HWHO_INPROGRESS;
-       }
-       h_Unlock_r(host);
-    }
-    H_UNLOCK;
-    return held;
-
-}                              /*CheckHost */
-#endif
 
 int
 CheckHost_r(struct host *host, void *dummy)
@@ -4125,6 +4020,8 @@ initInterfaceAddr_r(struct host *host, struct interfaceAddr *interf)
     opr_Assert(!host->interface);
     host->interface = interface;
 
+    h_AddHostToUuidHashTable_r(&interface->uuid, host);
+
     if (LogLevel >= 125) {
        afsUUID_to_string(&interface->uuid, uuidstr, 127);