Print this page
195 Need replacement for nfs/lockd+klm
Reviewed by: Gordon Ross <gordon.ross@nexenta.com>
Reviewed by: Jeremy Jones <jeremy@delphix.com>
Reviewed by: Jeff Biseda <jbiseda@delphix.com>

Split Close
Expand all
Collapse all
          --- old/usr/src/cmd/fs.d/nfs/statd/sm_proc.c
          +++ new/usr/src/cmd/fs.d/nfs/statd/sm_proc.c
↓ open down ↓ 17 lines elided ↑ open up ↑
  18   18   * information: Portions Copyright [yyyy] [name of copyright owner]
  19   19   *
  20   20   * CDDL HEADER END
  21   21   */
  22   22  /*
  23   23   * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
  24   24   * Use is subject to license terms.
  25   25   */
  26   26  /*
  27   27   * Copyright 2013 Nexenta Systems, Inc.  All rights reserved.
       28 + * Copyright (c) 2012 by Delphix. All rights reserved.
  28   29   */
  29   30  
  30   31  /*      Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
  31   32  /*        All Rights Reserved   */
  32   33  
  33   34  /*
  34   35   * University Copyright- Copyright (c) 1982, 1986, 1988
  35   36   * The Regents of the University of California
  36   37   * All Rights Reserved
  37   38   *
↓ open down ↓ 14 lines elided ↑ open up ↑
  52   53  #include <memory.h>
  53   54  #include <net/if.h>
  54   55  #include <sys/sockio.h>
  55   56  #include <sys/socket.h>
  56   57  #include <netinet/in.h>
  57   58  #include <arpa/inet.h>
  58   59  #include <netdb.h>
  59   60  #include <netdir.h>
  60   61  #include <synch.h>
  61   62  #include <thread.h>
       63 +#include <ifaddrs.h>
       64 +#include <errno.h>
  62   65  #include <assert.h>
  63   66  #include "sm_statd.h"
  64   67  
  65   68  static int local_state;         /* fake local sm state */
  66   69                                  /* client name-to-address translation table */
  67   70  static name_addr_entry_t *name_addr = NULL;
  68   71  
  69   72  
  70   73  #define LOGHOST "loghost"
  71   74  
↓ open down ↓ 10 lines elided ↑ open up ↑
  82   85  static void send_notice(char *mon_name, int state);
  83   86  static void add_to_host_array(char *host);
  84   87  static int in_host_array(char *host);
  85   88  static void pr_name_addr(name_addr_entry_t *name_addr);
  86   89  
  87   90  extern int self_check(char *hostname);
  88   91  extern struct lifconf *getmyaddrs(void);
  89   92  
  90   93  /* ARGSUSED */
  91   94  void
  92      -sm_status(namep, resp)
  93      -        sm_name *namep;
  94      -        sm_stat_res *resp;
       95 +sm_stat_svc(sm_name *namep, sm_stat_res *resp)
  95   96  {
  96   97  
  97   98          if (debug)
  98   99                  (void) printf("proc sm_stat: mon_name = %s\n",
  99      -                                namep->mon_name);
      100 +                    namep->mon_name);
 100  101  
 101  102          resp->res_stat = stat_succ;
 102  103          resp->state = LOCAL_STATE;
 103  104  }
 104  105  
 105  106  /* ARGSUSED */
 106  107  void
 107      -sm_mon(monp, resp)
 108      -        mon *monp;
 109      -        sm_stat_res *resp;
      108 +sm_mon_svc(mon *monp, sm_stat_res *resp)
 110  109  {
 111  110          mon_id *monidp;
 112  111          monidp = &monp->mon_id;
 113  112  
 114  113          rw_rdlock(&thr_rwlock);
 115  114          if (debug) {
 116  115                  (void) printf("proc sm_mon: mon_name = %s, id = %d\n",
 117      -                monidp->mon_name, * ((int *)monp->priv));
      116 +                    monidp->mon_name, * ((int *)monp->priv));
 118  117                  pr_mon(monp->mon_id.mon_name);
 119  118          }
 120  119  
 121  120          /* only monitor other hosts */
 122  121          if (self_check(monp->mon_id.mon_name) == 0) {
 123  122                  /* store monitor request into monitor_q */
 124  123                  insert_mon(monp);
 125  124          }
 126  125  
 127  126          pr_mon(monp->mon_id.mon_name);
 128  127          resp->res_stat = stat_succ;
 129  128          resp->state = local_state;
 130  129          rw_unlock(&thr_rwlock);
 131  130  }
 132  131  
 133  132  /* ARGSUSED */
 134  133  void
 135      -sm_unmon(monidp, resp)
 136      -        mon_id *monidp;
 137      -        sm_stat *resp;
      134 +sm_unmon_svc(mon_id *monidp, sm_stat *resp)
 138  135  {
 139  136          rw_rdlock(&thr_rwlock);
 140  137          if (debug) {
 141  138                  (void) printf(
 142      -                        "proc sm_unmon: mon_name = %s, [%s, %d, %d, %d]\n",
 143      -                        monidp->mon_name, monidp->my_id.my_name,
 144      -                        monidp->my_id.my_prog, monidp->my_id.my_vers,
 145      -                        monidp->my_id.my_proc);
      139 +                    "proc sm_unmon: mon_name = %s, [%s, %d, %d, %d]\n",
      140 +                    monidp->mon_name, monidp->my_id.my_name,
      141 +                    monidp->my_id.my_prog, monidp->my_id.my_vers,
      142 +                    monidp->my_id.my_proc);
 146  143                  pr_mon(monidp->mon_name);
 147  144          }
 148  145  
 149  146          delete_mon(monidp->mon_name, &monidp->my_id);
 150  147          pr_mon(monidp->mon_name);
 151  148          resp->state = local_state;
 152  149          rw_unlock(&thr_rwlock);
 153  150  }
 154  151  
 155  152  /* ARGSUSED */
 156  153  void
 157      -sm_unmon_all(myidp, resp)
 158      -        my_id *myidp;
 159      -        sm_stat *resp;
      154 +sm_unmon_all_svc(my_id *myidp, sm_stat *resp)
 160  155  {
 161  156          rw_rdlock(&thr_rwlock);
 162  157          if (debug)
 163  158                  (void) printf("proc sm_unmon_all: [%s, %d, %d, %d]\n",
 164      -                myidp->my_name,
 165      -                myidp->my_prog, myidp->my_vers,
 166      -                myidp->my_proc);
      159 +                    myidp->my_name,
      160 +                    myidp->my_prog, myidp->my_vers,
      161 +                    myidp->my_proc);
 167  162          delete_mon((char *)NULL, myidp);
 168  163          pr_mon(NULL);
 169  164          resp->state = local_state;
 170  165          rw_unlock(&thr_rwlock);
 171  166  }
 172  167  
 173  168  /*
 174  169   * Notifies lockd specified by name that state has changed for this server.
 175  170   */
 176  171  void
 177      -sm_notify(ntfp)
 178      -        stat_chge *ntfp;
      172 +sm_notify_svc(stat_chge *ntfp)
 179  173  {
 180  174          rw_rdlock(&thr_rwlock);
 181  175          if (debug)
 182  176                  (void) printf("sm_notify: %s state =%d\n",
 183      -                        ntfp->mon_name, ntfp->state);
      177 +                    ntfp->mon_name, ntfp->state);
 184  178          send_notice(ntfp->mon_name, ntfp->state);
 185  179          rw_unlock(&thr_rwlock);
 186  180  }
 187  181  
 188  182  /* ARGSUSED */
 189  183  void
 190      -sm_simu_crash(myidp)
 191      -        void *myidp;
      184 +sm_simu_crash_svc(void *myidp)
 192  185  {
 193  186          int i;
 194  187          struct mon_entry *monitor_q;
 195  188          int found = 0;
 196  189  
 197  190          /* Only one crash should be running at a time. */
 198  191          mutex_lock(&crash_lock);
 199  192          if (debug)
 200  193                  (void) printf("proc sm_simu_crash\n");
 201  194          if (in_crash) {
↓ open down ↓ 518 lines elided ↑ open up ↑
 720  713  
 721  714  /*
 722  715   * Work thread created to do the actual statd_call_lockd
 723  716   */
 724  717  static void *
 725  718  thr_send_notice(void *arg)
 726  719  {
 727  720          moninfo_t *minfop;
 728  721  
 729  722          minfop = (moninfo_t *)arg;
 730      -
 731  723          if (statd_call_lockd(&minfop->id, minfop->state) == -1) {
 732  724                  if (debug && minfop->id.mon_id.mon_name)
 733  725                          (void) printf("problem with notifying %s failure, "
 734  726                              "give up\n", minfop->id.mon_id.mon_name);
 735  727          } else {
 736  728                  if (debug)
 737  729                          (void) printf("send_notice: %s, %d notified.\n",
 738  730                              minfop->id.mon_id.mon_name, minfop->state);
 739  731          }
 740  732  
↓ open down ↓ 11 lines elided ↑ open up ↑
 752  744  /*
 753  745   * Contact lockd specified by monp.
 754  746   */
 755  747  static int
 756  748  statd_call_lockd(monp, state)
 757  749          mon *monp;
 758  750          int state;
 759  751  {
 760  752          enum clnt_stat clnt_stat;
 761  753          struct timeval tottimeout;
 762      -        struct status stat;
      754 +        struct sm_status stat;
 763  755          my_id *my_idp;
 764  756          char *mon_name;
 765  757          int i;
 766  758          int rc = 0;
 767  759          CLIENT *clnt;
 768  760  
 769  761          mon_name = monp->mon_id.mon_name;
 770  762          my_idp = &monp->mon_id.my_id;
 771      -        (void) memset(&stat, 0, sizeof (struct status));
      763 +        (void) memset(&stat, 0, sizeof (stat));
 772  764          stat.mon_name = mon_name;
 773  765          stat.state = state;
 774  766          for (i = 0; i < 16; i++) {
 775  767                  stat.priv[i] = monp->priv[i];
 776  768          }
 777  769          if (debug)
 778  770                  (void) printf("statd_call_lockd: %s state = %d\n",
 779  771                          stat.mon_name, stat.state);
 780  772  
 781  773          tottimeout.tv_sec = SM_RPC_TIMEOUT;
 782  774          tottimeout.tv_usec = 0;
 783  775  
 784      -        if ((clnt = create_client(my_idp->my_name, my_idp->my_prog,
 785      -                my_idp->my_vers, &tottimeout)) == (CLIENT *) NULL) {
 786      -                        return (-1);
      776 +        clnt = create_client(my_idp->my_name, my_idp->my_prog, my_idp->my_vers,
      777 +            "ticotsord", &tottimeout);
      778 +        if (clnt == NULL) {
      779 +                return (-1);
 787  780          }
 788  781  
 789      -        clnt_stat = clnt_call(clnt, my_idp->my_proc, xdr_status, (char *)&stat,
      782 +        clnt_stat = clnt_call(clnt, my_idp->my_proc,
      783 +                                xdr_sm_status, (char *)&stat,
 790  784                                  xdr_void, NULL, tottimeout);
 791  785          if (debug) {
 792  786                  (void) printf("clnt_stat=%s(%d)\n",
 793  787                          clnt_sperrno(clnt_stat), clnt_stat);
 794  788          }
 795  789          if (clnt_stat != (int)RPC_SUCCESS) {
 796  790                  syslog(LOG_WARNING,
 797  791                          "statd: cannot talk to lockd at %s, %s(%d)\n",
 798  792                          my_idp->my_name, clnt_sperrno(clnt_stat), clnt_stat);
 799  793                  rc = -1;
↓ open down ↓ 1 lines elided ↑ open up ↑
 801  795  
 802  796          clnt_destroy(clnt);
 803  797          return (rc);
 804  798  
 805  799  }
 806  800  
 807  801  /*
 808  802   * Client handle created.
 809  803   */
 810  804  CLIENT *
 811      -create_client(host, prognum, versnum, utimeout)
 812      -        char    *host;
 813      -        int     prognum;
 814      -        int     versnum;
 815      -        struct timeval  *utimeout;
      805 +create_client(char *host, int prognum, int versnum, char *netid,
      806 +    struct timeval *utimeout)
 816  807  {
 817  808          int             fd;
 818  809          struct timeval  timeout;
 819  810          CLIENT          *client;
 820  811          struct t_info   tinfo;
 821  812  
 822      -        if ((client = clnt_create_timed(host, prognum, versnum,
 823      -                        "netpath", utimeout)) == NULL) {
      813 +        if (netid == NULL) {
      814 +                client = clnt_create_timed(host, prognum, versnum,
      815 +                    "netpath", utimeout);
      816 +        } else {
      817 +                struct netconfig *nconf;
      818 +
      819 +                nconf = getnetconfigent(netid);
      820 +                if (nconf == NULL) {
      821 +                        return (NULL);
      822 +                }
      823 +
      824 +                client = clnt_tp_create_timed(host, prognum, versnum, nconf,
      825 +                    utimeout);
      826 +
      827 +                freenetconfigent(nconf);
      828 +        }
      829 +
      830 +        if (client == NULL) {
 824  831                  return (NULL);
 825  832          }
      833 +
 826  834          (void) CLNT_CONTROL(client, CLGET_FD, (caddr_t)&fd);
 827  835          if (t_getinfo(fd, &tinfo) != -1) {
 828  836                  if (tinfo.servtype == T_CLTS) {
 829  837                          /*
 830  838                           * Set time outs for connectionless case
 831  839                           */
 832  840                          timeout.tv_usec = 0;
 833  841                          timeout.tv_sec = SM_CLTS_TIMEOUT;
 834  842                          (void) CLNT_CONTROL(client,
 835      -                                CLSET_RETRY_TIMEOUT, (caddr_t)&timeout);
      843 +                            CLSET_RETRY_TIMEOUT, (caddr_t)&timeout);
 836  844                  }
 837  845          } else
 838  846                  return (NULL);
 839  847  
 840  848          return (client);
 841  849  }
 842  850  
 843  851  /*
 844  852   * ONLY for debugging.
 845  853   * Debug messages which prints out the monitor table information.
↓ open down ↓ 447 lines elided ↑ open up ↑
1293 1301                  ++rawaddr1;
1294 1302                  ++rawaddr2;
1295 1303  
1296 1304                  if (inet_pton(af1, rawaddr1, dst1) == 1 &&
1297 1305                      inet_pton(af2, rawaddr1, dst2) == 1 &&
1298 1306                      memcmp(dst1, dst2, len) == 0) {
1299 1307                          return (0);
1300 1308                  }
1301 1309          }
1302 1310          return (1);
     1311 +}
     1312 +
     1313 +/*
     1314 + * Add IP address strings to the host_name list.
     1315 + */
     1316 +void
     1317 +merge_ips(void)
     1318 +{
     1319 +        struct ifaddrs *ifap, *cifap;
     1320 +        int error;
     1321 +
     1322 +        error = getifaddrs(&ifap);
     1323 +        if (error) {
     1324 +                syslog(LOG_WARNING, "getifaddrs error: '%s'",
     1325 +                    strerror(errno));
     1326 +                return;
     1327 +        }
     1328 +
     1329 +        for (cifap = ifap; cifap != NULL; cifap = cifap->ifa_next) {
     1330 +                struct sockaddr *sa = cifap->ifa_addr;
     1331 +                char addr_str[INET6_ADDRSTRLEN];
     1332 +                void *addr = NULL;
     1333 +
     1334 +                switch (sa->sa_family) {
     1335 +                case AF_INET: {
     1336 +                        struct sockaddr_in *sin = (struct sockaddr_in *)sa;
     1337 +
     1338 +                        /* Skip loopback addresses. */
     1339 +                        if (sin->sin_addr.s_addr == htonl(INADDR_LOOPBACK)) {
     1340 +                                continue;
     1341 +                        }
     1342 +
     1343 +                        addr = &sin->sin_addr;
     1344 +                        break;
     1345 +                }
     1346 +
     1347 +                case AF_INET6: {
     1348 +                        struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa;
     1349 +
     1350 +                        /* Skip loopback addresses. */
     1351 +                        if (IN6_IS_ADDR_LOOPBACK(&sin6->sin6_addr)) {
     1352 +                                continue;
     1353 +                        }
     1354 +
     1355 +                        addr = &sin6->sin6_addr;
     1356 +                        break;
     1357 +                }
     1358 +
     1359 +                default:
     1360 +                        syslog(LOG_WARNING, "Unknown address family %d for "
     1361 +                            "interface %s", sa->sa_family, cifap->ifa_name);
     1362 +                        continue;
     1363 +                }
     1364 +
     1365 +                if (inet_ntop(sa->sa_family, addr, addr_str, sizeof (addr_str))
     1366 +                    == NULL) {
     1367 +                        syslog(LOG_WARNING, "Failed to convert address into "
     1368 +                            "string representation for interface '%s' "
     1369 +                            "address family %d", cifap->ifa_name,
     1370 +                            sa->sa_family);
     1371 +                        continue;
     1372 +                }
     1373 +
     1374 +                if (!in_host_array(addr_str)) {
     1375 +                        add_to_host_array(addr_str);
     1376 +                }
     1377 +        }
     1378 +
     1379 +        freeifaddrs(ifap);
1303 1380  }
    
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX