Make cmdebug -addrs work on platforms other than Solaris.
[openafs.git] / src / venus / cmdebug.c
index e6c55d7..d1bf4a5 100644 (file)
@@ -1,10 +1,30 @@
+/*
+ * 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 <sys/types.h>
 #include <netinet/in.h>
 #include <sys/socket.h>
 #include <netdb.h>
 #include <stdio.h>
+#ifdef HAVE_STRING_H
+#include <string.h>
+#else
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif
+#endif
 #ifdef AFS_AIX32_ENV
 #include <signal.h>
 #endif
 #include <afs/cmd.h>
 #include <rx/rx.h>
 #include <lock.h>
+#include <afs/afs_args.h>
 
-extern struct rx_securityClass *rxnull_NewServerSecurityObject();
 extern struct hostent *hostutil_GetHostByName();
 
+static PrintCacheConfig(aconn)
+    struct rx_connection *aconn;
+{
+    struct cacheConfig c;
+    afs_uint32 srv_ver, conflen;
+    int code;
+
+    c.cacheConfig_len = 0;
+    c.cacheConfig_val = NULL;
+    code = RXAFSCB_GetCacheConfig(aconn, 1, &srv_ver, &conflen, &c);
+    if (code) {
+       printf("cmdebug: error checking cache config: %s\n",
+              error_message(code));
+       return 0;
+    }
+
+    if (srv_ver == AFS_CLIENT_RETRIEVAL_FIRST_EDITION) {
+       struct cm_initparams_v1 *c1;
+
+       if (c.cacheConfig_len != sizeof(*c1) / sizeof(afs_uint32)) {
+           printf("cmdebug: configuration data size mismatch (%d != %d)\n",
+                  c.cacheConfig_len, sizeof(*c1) / sizeof(afs_uint32));
+           return 0;
+       }
+
+       c1 = (struct cm_initparams_v1 *) c.cacheConfig_val;
+       printf("Chunk files:   %d\n", c1->nChunkFiles);
+       printf("Stat caches:   %d\n", c1->nStatCaches);
+       printf("Data caches:   %d\n", c1->nDataCaches);
+       printf("Volume caches: %d\n", c1->nVolumeCaches);
+       printf("Chunk size:    %d", c1->otherChunkSize);
+       if (c1->firstChunkSize != c1->otherChunkSize)
+           printf(" (first: %d)", c1->firstChunkSize);
+       printf("\n");
+       printf("Cache size:    %d kB\n", c1->cacheSize);
+       printf("Set time:      %s\n", c1->setTime ? "yes" : "no");
+       printf("Cache type:    %s\n", c1->memCache ? "memory" : "disk");
+    } else {
+       printf("cmdebug: unsupported server version %d\n", srv_ver);
+    }
+}
+
+static PrintInterfaces(aconn)
+    struct rx_connection *aconn;
+{
+    struct interfaceAddr addr;
+    int i, code;
+
+    code = RXAFSCB_WhoAreYou(aconn, &addr);
+    if (code) {
+       printf("cmdebug: error checking interfaces: %s\n", error_message(code));
+       return 0;
+    }
+
+    printf("Host interfaces:\n");
+    for (i=0; i<addr.numberOfInterfaces; i++) {
+       printf("%s", afs_inet_ntoa(htonl(addr.addr_in[i])));
+       if (addr.subnetmask[i])
+           printf(", netmask %s", afs_inet_ntoa(htonl(addr.subnetmask[i])));
+       if (addr.mtu[i])
+           printf(", MTU %d", addr.mtu[i]);
+       printf("\n");
+    }
+
+    return 0;
+}
+
 static IsLocked(alock)
 register struct AFSDBLockDesc *alock; {
     if (alock->waitStates || alock->exclLocked
@@ -76,12 +163,55 @@ register struct rx_connection *aconn; {
     return 0;
 }
 
-static PrintCacheEntries(aconn, aint32)
-int aint32;
-register struct rx_connection *aconn; {
+struct cell_cache {
+    afs_int32 cellnum;
+    char *cellname;
+    struct cell_cache *next;
+};
+
+static char *GetCellName(struct rx_connection *aconn, afs_int32 cellnum)
+{
+    static int no_getcellbynum;
+    static struct cell_cache *cache;
+    struct cell_cache *tcp;
+    int code;
+    char *cellname;
+    serverList sl;
+
+    if (no_getcellbynum)
+       return NULL;
+
+    for (tcp = cache; tcp; tcp = tcp->next)
+       if (tcp->cellnum == cellnum)
+           return tcp->cellname;
+
+    cellname = NULL;
+    sl.serverList_len = 0;
+    sl.serverList_val = NULL;
+    code = RXAFSCB_GetCellByNum(aconn, cellnum, &cellname, &sl);
+    if (code) {
+       if (code == RXGEN_OPCODE)
+           no_getcellbynum = 1;
+       return NULL;
+    }
+
+    if (sl.serverList_val)
+       free (sl.serverList_val);
+    tcp = malloc(sizeof(struct cell_cache));
+    tcp->next = cache;
+    tcp->cellnum = cellnum;
+    tcp->cellname = cellname;
+    cache = tcp;
+
+    return cellname;
+}
+
+static PrintCacheEntries(struct rx_connection *aconn, int aint32)
+{
     register int i;
     register afs_int32 code;
     struct AFSDBCacheEntry centry;
+    char *cellname;
 
     for(i=0;i<10000;i++) {
        code = RXAFSCB_GetCE(aconn, i, &centry);
@@ -102,8 +232,16 @@ register struct rx_connection *aconn; {
        if (!aint32 && !IsLocked(&centry.lock)) continue;
 
        /* otherwise print this entry */
-       printf("** Cache entry @ 0x%08x for %d.%d.%d.%d\n", centry.addr, centry.cell,
-              centry.netFid.Volume, centry.netFid.Vnode, centry.netFid.Unique);
+       printf("** Cache entry @ 0x%08x for %d.%d.%d.%d", centry.addr,
+              centry.cell, centry.netFid.Volume, centry.netFid.Vnode,
+              centry.netFid.Unique);
+
+       cellname = GetCellName(aconn, centry.cell);
+       if (cellname)
+           printf(" [%s]\n", cellname);
+       else
+           printf("\n");
+
        if (IsLocked(&centry.lock)) {
            printf("    locks: ");
            PrintLock(&centry.lock);
@@ -152,13 +290,23 @@ struct cmd_syndesc *as; {
        printf("cmdebug: can't resolve address for host %s.\n", hostName);
        exit(1);
     }
-    bcopy(thp->h_addr, &addr, sizeof(afs_int32));
+    memcpy(&addr, thp->h_addr, sizeof(afs_int32));
     secobj = rxnull_NewServerSecurityObject();
     conn = rx_NewConnection(addr, htons(port), 1, secobj, 0);
     if (!conn) {
        printf("cmdebug: failed to create connection for host %s\n", hostName);
        exit(1);
     }
+    if (as->parms[3].items) {
+       /* -addrs */
+       PrintInterfaces(conn);
+       return 0;
+    }
+    if (as->parms[4].items) {
+       /* -cache */
+       PrintCacheConfig(conn);
+       return 0;
+    }
     if (as->parms[2].items) int32p = 1;
     else int32p = 0;
     PrintLocks(conn, int32p);
@@ -189,10 +337,12 @@ char **argv; {
 #endif
     rx_Init(0);
 
-    ts = cmd_CreateSyntax((char *) 0, CommandProc, 0, "probe unik server");
+    ts = cmd_CreateSyntax(NULL, CommandProc, 0, "probe unik server");
     cmd_AddParm(ts, "-servers", CMD_SINGLE, CMD_REQUIRED, "server machine");
     cmd_AddParm(ts, "-port", CMD_SINGLE, CMD_OPTIONAL, "IP port");
     cmd_AddParm(ts, "-long", CMD_FLAG, CMD_OPTIONAL, "print all info");
+    cmd_AddParm(ts, "-addrs", CMD_FLAG, CMD_OPTIONAL, "print only host interfaces");
+    cmd_AddParm(ts, "-cache", CMD_FLAG, CMD_OPTIONAL, "print only cache configuration");
 
     cmd_Dispatch(argc, argv);
     exit(0);