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>


   8  *
   9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  10  * or http://www.opensolaris.org/os/licensing.
  11  * See the License for the specific language governing permissions
  12  * and limitations under the License.
  13  *
  14  * When distributing Covered Code, include this CDDL HEADER in each
  15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  16  * If applicable, add the following below this CDDL HEADER, with the
  17  * fields enclosed by brackets "[]" replaced with your own identifying
  18  * information: Portions Copyright [yyyy] [name of copyright owner]
  19  *
  20  * CDDL HEADER END
  21  */
  22 /*
  23  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
  24  * Use is subject to license terms.
  25  */
  26 /*
  27  * Copyright 2013 Nexenta Systems, Inc.  All rights reserved.

  28  */
  29 
  30 /*      Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T     */
  31 /*        All Rights Reserved   */
  32 
  33 /*
  34  * University Copyright- Copyright (c) 1982, 1986, 1988
  35  * The Regents of the University of California
  36  * All Rights Reserved
  37  *
  38  * University Acknowledgment- Portions of this document are derived from
  39  * software developed by the University of California, Berkeley, and its
  40  * contributors.
  41  */
  42 
  43 #include <stdio.h>
  44 #include <sys/types.h>
  45 #include <stdlib.h>
  46 #include <unistd.h>
  47 #include <string.h>
  48 #include <syslog.h>
  49 #include <rpc/rpc.h>
  50 #include <rpcsvc/sm_inter.h>
  51 #include <rpcsvc/nsm_addr.h>
  52 #include <memory.h>
  53 #include <net/if.h>
  54 #include <sys/sockio.h>
  55 #include <sys/socket.h>
  56 #include <netinet/in.h>
  57 #include <arpa/inet.h>
  58 #include <netdb.h>
  59 #include <netdir.h>
  60 #include <synch.h>
  61 #include <thread.h>


  62 #include <assert.h>
  63 #include "sm_statd.h"
  64 
  65 static int local_state;         /* fake local sm state */
  66                                 /* client name-to-address translation table */
  67 static name_addr_entry_t *name_addr = NULL;
  68 
  69 
  70 #define LOGHOST "loghost"
  71 
  72 static void delete_mon(char *mon_name, my_id *my_idp);
  73 static void insert_mon(mon *monp);
  74 static void pr_mon(char *);
  75 static int statd_call_lockd(mon *monp, int state);
  76 static int hostname_eq(char *host1, char *host2);
  77 static char *get_system_id(char *hostname);
  78 static void add_aliases(struct hostent *phost);
  79 static void *thr_send_notice(void *);
  80 static void delete_onemon(char *mon_name, my_id *my_idp,
  81                                 mon_entry **monitor_q);
  82 static void send_notice(char *mon_name, int state);
  83 static void add_to_host_array(char *host);
  84 static int in_host_array(char *host);
  85 static void pr_name_addr(name_addr_entry_t *name_addr);
  86 
  87 extern int self_check(char *hostname);
  88 extern struct lifconf *getmyaddrs(void);
  89 
  90 /* ARGSUSED */
  91 void
  92 sm_status(namep, resp)
  93         sm_name *namep;
  94         sm_stat_res *resp;
  95 {
  96 
  97         if (debug)
  98                 (void) printf("proc sm_stat: mon_name = %s\n",
  99                                 namep->mon_name);
 100 
 101         resp->res_stat = stat_succ;
 102         resp->state = LOCAL_STATE;
 103 }
 104 
 105 /* ARGSUSED */
 106 void
 107 sm_mon(monp, resp)
 108         mon *monp;
 109         sm_stat_res *resp;
 110 {
 111         mon_id *monidp;
 112         monidp = &monp->mon_id;
 113 
 114         rw_rdlock(&thr_rwlock);
 115         if (debug) {
 116                 (void) printf("proc sm_mon: mon_name = %s, id = %d\n",
 117                 monidp->mon_name, * ((int *)monp->priv));
 118                 pr_mon(monp->mon_id.mon_name);
 119         }
 120 
 121         /* only monitor other hosts */
 122         if (self_check(monp->mon_id.mon_name) == 0) {
 123                 /* store monitor request into monitor_q */
 124                 insert_mon(monp);
 125         }
 126 
 127         pr_mon(monp->mon_id.mon_name);
 128         resp->res_stat = stat_succ;
 129         resp->state = local_state;
 130         rw_unlock(&thr_rwlock);
 131 }
 132 
 133 /* ARGSUSED */
 134 void
 135 sm_unmon(monidp, resp)
 136         mon_id *monidp;
 137         sm_stat *resp;
 138 {
 139         rw_rdlock(&thr_rwlock);
 140         if (debug) {
 141                 (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);
 146                 pr_mon(monidp->mon_name);
 147         }
 148 
 149         delete_mon(monidp->mon_name, &monidp->my_id);
 150         pr_mon(monidp->mon_name);
 151         resp->state = local_state;
 152         rw_unlock(&thr_rwlock);
 153 }
 154 
 155 /* ARGSUSED */
 156 void
 157 sm_unmon_all(myidp, resp)
 158         my_id *myidp;
 159         sm_stat *resp;
 160 {
 161         rw_rdlock(&thr_rwlock);
 162         if (debug)
 163                 (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);
 167         delete_mon((char *)NULL, myidp);
 168         pr_mon(NULL);
 169         resp->state = local_state;
 170         rw_unlock(&thr_rwlock);
 171 }
 172 
 173 /*
 174  * Notifies lockd specified by name that state has changed for this server.
 175  */
 176 void
 177 sm_notify(ntfp)
 178         stat_chge *ntfp;
 179 {
 180         rw_rdlock(&thr_rwlock);
 181         if (debug)
 182                 (void) printf("sm_notify: %s state =%d\n",
 183                         ntfp->mon_name, ntfp->state);
 184         send_notice(ntfp->mon_name, ntfp->state);
 185         rw_unlock(&thr_rwlock);
 186 }
 187 
 188 /* ARGSUSED */
 189 void
 190 sm_simu_crash(myidp)
 191         void *myidp;
 192 {
 193         int i;
 194         struct mon_entry *monitor_q;
 195         int found = 0;
 196 
 197         /* Only one crash should be running at a time. */
 198         mutex_lock(&crash_lock);
 199         if (debug)
 200                 (void) printf("proc sm_simu_crash\n");
 201         if (in_crash) {
 202                 cond_wait(&crash_finish, &crash_lock);
 203                 mutex_unlock(&crash_lock);
 204                 return;
 205         } else {
 206                 in_crash = 1;
 207         }
 208         mutex_unlock(&crash_lock);
 209 
 210         for (i = 0; i < MAX_HASHSIZE; i++) {
 211                 mutex_lock(&mon_table[i].lock);


 710                                     free(minfop->id.mon_id.my_id.my_name);
 711                                     free(minfop);
 712                                     continue;
 713                                 }
 714                         }
 715                 }
 716                 next = next->nxt;
 717         }
 718         mutex_unlock(&mon_table[hash].lock);
 719 }
 720 
 721 /*
 722  * Work thread created to do the actual statd_call_lockd
 723  */
 724 static void *
 725 thr_send_notice(void *arg)
 726 {
 727         moninfo_t *minfop;
 728 
 729         minfop = (moninfo_t *)arg;
 730 
 731         if (statd_call_lockd(&minfop->id, minfop->state) == -1) {
 732                 if (debug && minfop->id.mon_id.mon_name)
 733                         (void) printf("problem with notifying %s failure, "
 734                             "give up\n", minfop->id.mon_id.mon_name);
 735         } else {
 736                 if (debug)
 737                         (void) printf("send_notice: %s, %d notified.\n",
 738                             minfop->id.mon_id.mon_name, minfop->state);
 739         }
 740 
 741         free(minfop->id.mon_id.mon_name);
 742         free(minfop->id.mon_id.my_id.my_name);
 743         free(minfop);
 744 
 745         thr_exit((void *) 0);
 746 #ifdef lint
 747         /*NOTREACHED*/
 748         return ((void *)0);
 749 #endif
 750 }
 751 
 752 /*
 753  * Contact lockd specified by monp.
 754  */
 755 static int
 756 statd_call_lockd(monp, state)
 757         mon *monp;
 758         int state;
 759 {
 760         enum clnt_stat clnt_stat;
 761         struct timeval tottimeout;
 762         struct status stat;
 763         my_id *my_idp;
 764         char *mon_name;
 765         int i;
 766         int rc = 0;
 767         CLIENT *clnt;
 768 
 769         mon_name = monp->mon_id.mon_name;
 770         my_idp = &monp->mon_id.my_id;
 771         (void) memset(&stat, 0, sizeof (struct status));
 772         stat.mon_name = mon_name;
 773         stat.state = state;
 774         for (i = 0; i < 16; i++) {
 775                 stat.priv[i] = monp->priv[i];
 776         }
 777         if (debug)
 778                 (void) printf("statd_call_lockd: %s state = %d\n",
 779                         stat.mon_name, stat.state);
 780 
 781         tottimeout.tv_sec = SM_RPC_TIMEOUT;
 782         tottimeout.tv_usec = 0;
 783 
 784         if ((clnt = create_client(my_idp->my_name, my_idp->my_prog,
 785                 my_idp->my_vers, &tottimeout)) == (CLIENT *) NULL) {

 786                         return (-1);
 787         }
 788 
 789         clnt_stat = clnt_call(clnt, my_idp->my_proc, xdr_status, (char *)&stat,

 790                                 xdr_void, NULL, tottimeout);
 791         if (debug) {
 792                 (void) printf("clnt_stat=%s(%d)\n",
 793                         clnt_sperrno(clnt_stat), clnt_stat);
 794         }
 795         if (clnt_stat != (int)RPC_SUCCESS) {
 796                 syslog(LOG_WARNING,
 797                         "statd: cannot talk to lockd at %s, %s(%d)\n",
 798                         my_idp->my_name, clnt_sperrno(clnt_stat), clnt_stat);
 799                 rc = -1;
 800         }
 801 
 802         clnt_destroy(clnt);
 803         return (rc);
 804 
 805 }
 806 
 807 /*
 808  * Client handle created.
 809  */
 810 CLIENT *
 811 create_client(host, prognum, versnum, utimeout)
 812         char    *host;
 813         int     prognum;
 814         int     versnum;
 815         struct timeval  *utimeout;
 816 {
 817         int             fd;
 818         struct timeval  timeout;
 819         CLIENT          *client;
 820         struct t_info   tinfo;
 821 
 822         if ((client = clnt_create_timed(host, prognum, versnum,
 823                         "netpath", utimeout)) == NULL) {






 824                 return (NULL);
 825         }











 826         (void) CLNT_CONTROL(client, CLGET_FD, (caddr_t)&fd);
 827         if (t_getinfo(fd, &tinfo) != -1) {
 828                 if (tinfo.servtype == T_CLTS) {
 829                         /*
 830                          * Set time outs for connectionless case
 831                          */
 832                         timeout.tv_usec = 0;
 833                         timeout.tv_sec = SM_CLTS_TIMEOUT;
 834                         (void) CLNT_CONTROL(client,
 835                                 CLSET_RETRY_TIMEOUT, (caddr_t)&timeout);
 836                 }
 837         } else
 838                 return (NULL);
 839 
 840         return (client);
 841 }
 842 
 843 /*
 844  * ONLY for debugging.
 845  * Debug messages which prints out the monitor table information.


1283                 af2 = AF_INET6;
1284         else
1285                 return (1);
1286 
1287         if (af1 != af2)
1288                 return (1);
1289 
1290         if (rawaddr1 != NULL && rawaddr2 != NULL) {
1291                 char dst1[16];
1292                 char dst2[16];
1293                 ++rawaddr1;
1294                 ++rawaddr2;
1295 
1296                 if (inet_pton(af1, rawaddr1, dst1) == 1 &&
1297                     inet_pton(af2, rawaddr1, dst2) == 1 &&
1298                     memcmp(dst1, dst2, len) == 0) {
1299                         return (0);
1300                 }
1301         }
1302         return (1);





































































1303 }


   8  *
   9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  10  * or http://www.opensolaris.org/os/licensing.
  11  * See the License for the specific language governing permissions
  12  * and limitations under the License.
  13  *
  14  * When distributing Covered Code, include this CDDL HEADER in each
  15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  16  * If applicable, add the following below this CDDL HEADER, with the
  17  * fields enclosed by brackets "[]" replaced with your own identifying
  18  * information: Portions Copyright [yyyy] [name of copyright owner]
  19  *
  20  * CDDL HEADER END
  21  */
  22 /*
  23  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
  24  * Use is subject to license terms.
  25  */
  26 /*
  27  * Copyright 2013 Nexenta Systems, Inc.  All rights reserved.
  28  * Copyright (c) 2012 by Delphix. All rights reserved.
  29  */
  30 
  31 /*      Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T     */
  32 /*        All Rights Reserved   */
  33 
  34 /*
  35  * University Copyright- Copyright (c) 1982, 1986, 1988
  36  * The Regents of the University of California
  37  * All Rights Reserved
  38  *
  39  * University Acknowledgment- Portions of this document are derived from
  40  * software developed by the University of California, Berkeley, and its
  41  * contributors.
  42  */
  43 
  44 #include <stdio.h>
  45 #include <sys/types.h>
  46 #include <stdlib.h>
  47 #include <unistd.h>
  48 #include <string.h>
  49 #include <syslog.h>
  50 #include <rpc/rpc.h>
  51 #include <rpcsvc/sm_inter.h>
  52 #include <rpcsvc/nsm_addr.h>
  53 #include <memory.h>
  54 #include <net/if.h>
  55 #include <sys/sockio.h>
  56 #include <sys/socket.h>
  57 #include <netinet/in.h>
  58 #include <arpa/inet.h>
  59 #include <netdb.h>
  60 #include <netdir.h>
  61 #include <synch.h>
  62 #include <thread.h>
  63 #include <ifaddrs.h>
  64 #include <errno.h>
  65 #include <assert.h>
  66 #include "sm_statd.h"
  67 
  68 static int local_state;         /* fake local sm state */
  69                                 /* client name-to-address translation table */
  70 static name_addr_entry_t *name_addr = NULL;
  71 
  72 
  73 #define LOGHOST "loghost"
  74 
  75 static void delete_mon(char *mon_name, my_id *my_idp);
  76 static void insert_mon(mon *monp);
  77 static void pr_mon(char *);
  78 static int statd_call_lockd(mon *monp, int state);
  79 static int hostname_eq(char *host1, char *host2);
  80 static char *get_system_id(char *hostname);
  81 static void add_aliases(struct hostent *phost);
  82 static void *thr_send_notice(void *);
  83 static void delete_onemon(char *mon_name, my_id *my_idp,
  84                                 mon_entry **monitor_q);
  85 static void send_notice(char *mon_name, int state);
  86 static void add_to_host_array(char *host);
  87 static int in_host_array(char *host);
  88 static void pr_name_addr(name_addr_entry_t *name_addr);
  89 
  90 extern int self_check(char *hostname);
  91 extern struct lifconf *getmyaddrs(void);
  92 
  93 /* ARGSUSED */
  94 void
  95 sm_stat_svc(sm_name *namep, sm_stat_res *resp)


  96 {
  97 
  98         if (debug)
  99                 (void) printf("proc sm_stat: mon_name = %s\n",
 100                     namep->mon_name);
 101 
 102         resp->res_stat = stat_succ;
 103         resp->state = LOCAL_STATE;
 104 }
 105 
 106 /* ARGSUSED */
 107 void
 108 sm_mon_svc(mon *monp, sm_stat_res *resp)


 109 {
 110         mon_id *monidp;
 111         monidp = &monp->mon_id;
 112 
 113         rw_rdlock(&thr_rwlock);
 114         if (debug) {
 115                 (void) printf("proc sm_mon: mon_name = %s, id = %d\n",
 116                     monidp->mon_name, * ((int *)monp->priv));
 117                 pr_mon(monp->mon_id.mon_name);
 118         }
 119 
 120         /* only monitor other hosts */
 121         if (self_check(monp->mon_id.mon_name) == 0) {
 122                 /* store monitor request into monitor_q */
 123                 insert_mon(monp);
 124         }
 125 
 126         pr_mon(monp->mon_id.mon_name);
 127         resp->res_stat = stat_succ;
 128         resp->state = local_state;
 129         rw_unlock(&thr_rwlock);
 130 }
 131 
 132 /* ARGSUSED */
 133 void
 134 sm_unmon_svc(mon_id *monidp, sm_stat *resp)


 135 {
 136         rw_rdlock(&thr_rwlock);
 137         if (debug) {
 138                 (void) printf(
 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);
 143                 pr_mon(monidp->mon_name);
 144         }
 145 
 146         delete_mon(monidp->mon_name, &monidp->my_id);
 147         pr_mon(monidp->mon_name);
 148         resp->state = local_state;
 149         rw_unlock(&thr_rwlock);
 150 }
 151 
 152 /* ARGSUSED */
 153 void
 154 sm_unmon_all_svc(my_id *myidp, sm_stat *resp)


 155 {
 156         rw_rdlock(&thr_rwlock);
 157         if (debug)
 158                 (void) printf("proc sm_unmon_all: [%s, %d, %d, %d]\n",
 159                     myidp->my_name,
 160                     myidp->my_prog, myidp->my_vers,
 161                     myidp->my_proc);
 162         delete_mon((char *)NULL, myidp);
 163         pr_mon(NULL);
 164         resp->state = local_state;
 165         rw_unlock(&thr_rwlock);
 166 }
 167 
 168 /*
 169  * Notifies lockd specified by name that state has changed for this server.
 170  */
 171 void
 172 sm_notify_svc(stat_chge *ntfp)

 173 {
 174         rw_rdlock(&thr_rwlock);
 175         if (debug)
 176                 (void) printf("sm_notify: %s state =%d\n",
 177                     ntfp->mon_name, ntfp->state);
 178         send_notice(ntfp->mon_name, ntfp->state);
 179         rw_unlock(&thr_rwlock);
 180 }
 181 
 182 /* ARGSUSED */
 183 void
 184 sm_simu_crash_svc(void *myidp)

 185 {
 186         int i;
 187         struct mon_entry *monitor_q;
 188         int found = 0;
 189 
 190         /* Only one crash should be running at a time. */
 191         mutex_lock(&crash_lock);
 192         if (debug)
 193                 (void) printf("proc sm_simu_crash\n");
 194         if (in_crash) {
 195                 cond_wait(&crash_finish, &crash_lock);
 196                 mutex_unlock(&crash_lock);
 197                 return;
 198         } else {
 199                 in_crash = 1;
 200         }
 201         mutex_unlock(&crash_lock);
 202 
 203         for (i = 0; i < MAX_HASHSIZE; i++) {
 204                 mutex_lock(&mon_table[i].lock);


 703                                     free(minfop->id.mon_id.my_id.my_name);
 704                                     free(minfop);
 705                                     continue;
 706                                 }
 707                         }
 708                 }
 709                 next = next->nxt;
 710         }
 711         mutex_unlock(&mon_table[hash].lock);
 712 }
 713 
 714 /*
 715  * Work thread created to do the actual statd_call_lockd
 716  */
 717 static void *
 718 thr_send_notice(void *arg)
 719 {
 720         moninfo_t *minfop;
 721 
 722         minfop = (moninfo_t *)arg;

 723         if (statd_call_lockd(&minfop->id, minfop->state) == -1) {
 724                 if (debug && minfop->id.mon_id.mon_name)
 725                         (void) printf("problem with notifying %s failure, "
 726                             "give up\n", minfop->id.mon_id.mon_name);
 727         } else {
 728                 if (debug)
 729                         (void) printf("send_notice: %s, %d notified.\n",
 730                             minfop->id.mon_id.mon_name, minfop->state);
 731         }
 732 
 733         free(minfop->id.mon_id.mon_name);
 734         free(minfop->id.mon_id.my_id.my_name);
 735         free(minfop);
 736 
 737         thr_exit((void *) 0);
 738 #ifdef lint
 739         /*NOTREACHED*/
 740         return ((void *)0);
 741 #endif
 742 }
 743 
 744 /*
 745  * Contact lockd specified by monp.
 746  */
 747 static int
 748 statd_call_lockd(monp, state)
 749         mon *monp;
 750         int state;
 751 {
 752         enum clnt_stat clnt_stat;
 753         struct timeval tottimeout;
 754         struct sm_status stat;
 755         my_id *my_idp;
 756         char *mon_name;
 757         int i;
 758         int rc = 0;
 759         CLIENT *clnt;
 760 
 761         mon_name = monp->mon_id.mon_name;
 762         my_idp = &monp->mon_id.my_id;
 763         (void) memset(&stat, 0, sizeof (stat));
 764         stat.mon_name = mon_name;
 765         stat.state = state;
 766         for (i = 0; i < 16; i++) {
 767                 stat.priv[i] = monp->priv[i];
 768         }
 769         if (debug)
 770                 (void) printf("statd_call_lockd: %s state = %d\n",
 771                         stat.mon_name, stat.state);
 772 
 773         tottimeout.tv_sec = SM_RPC_TIMEOUT;
 774         tottimeout.tv_usec = 0;
 775 
 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);
 780         }
 781 
 782         clnt_stat = clnt_call(clnt, my_idp->my_proc,
 783                                 xdr_sm_status, (char *)&stat,
 784                                 xdr_void, NULL, tottimeout);
 785         if (debug) {
 786                 (void) printf("clnt_stat=%s(%d)\n",
 787                         clnt_sperrno(clnt_stat), clnt_stat);
 788         }
 789         if (clnt_stat != (int)RPC_SUCCESS) {
 790                 syslog(LOG_WARNING,
 791                         "statd: cannot talk to lockd at %s, %s(%d)\n",
 792                         my_idp->my_name, clnt_sperrno(clnt_stat), clnt_stat);
 793                 rc = -1;
 794         }
 795 
 796         clnt_destroy(clnt);
 797         return (rc);
 798 
 799 }
 800 
 801 /*
 802  * Client handle created.
 803  */
 804 CLIENT *
 805 create_client(char *host, int prognum, int versnum, char *netid,
 806     struct timeval *utimeout)



 807 {
 808         int             fd;
 809         struct timeval  timeout;
 810         CLIENT          *client;
 811         struct t_info   tinfo;
 812 
 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) {
 831                 return (NULL);
 832         }
 833 
 834         (void) CLNT_CONTROL(client, CLGET_FD, (caddr_t)&fd);
 835         if (t_getinfo(fd, &tinfo) != -1) {
 836                 if (tinfo.servtype == T_CLTS) {
 837                         /*
 838                          * Set time outs for connectionless case
 839                          */
 840                         timeout.tv_usec = 0;
 841                         timeout.tv_sec = SM_CLTS_TIMEOUT;
 842                         (void) CLNT_CONTROL(client,
 843                             CLSET_RETRY_TIMEOUT, (caddr_t)&timeout);
 844                 }
 845         } else
 846                 return (NULL);
 847 
 848         return (client);
 849 }
 850 
 851 /*
 852  * ONLY for debugging.
 853  * Debug messages which prints out the monitor table information.


1291                 af2 = AF_INET6;
1292         else
1293                 return (1);
1294 
1295         if (af1 != af2)
1296                 return (1);
1297 
1298         if (rawaddr1 != NULL && rawaddr2 != NULL) {
1299                 char dst1[16];
1300                 char dst2[16];
1301                 ++rawaddr1;
1302                 ++rawaddr2;
1303 
1304                 if (inet_pton(af1, rawaddr1, dst1) == 1 &&
1305                     inet_pton(af2, rawaddr1, dst2) == 1 &&
1306                     memcmp(dst1, dst2, len) == 0) {
1307                         return (0);
1308                 }
1309         }
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);
1380 }