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>
@@ -23,10 +23,11 @@
* Copyright 2005 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
* Copyright 2013 Nexenta Systems, Inc. All rights reserved.
+ * Copyright (c) 2012 by Delphix. All rights reserved.
*/
/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
/* All Rights Reserved */
@@ -57,10 +58,12 @@
#include <arpa/inet.h>
#include <netdb.h>
#include <netdir.h>
#include <synch.h>
#include <thread.h>
+#include <ifaddrs.h>
+#include <errno.h>
#include <assert.h>
#include "sm_statd.h"
static int local_state; /* fake local sm state */
/* client name-to-address translation table */
@@ -87,13 +90,11 @@
extern int self_check(char *hostname);
extern struct lifconf *getmyaddrs(void);
/* ARGSUSED */
void
-sm_status(namep, resp)
- sm_name *namep;
- sm_stat_res *resp;
+sm_stat_svc(sm_name *namep, sm_stat_res *resp)
{
if (debug)
(void) printf("proc sm_stat: mon_name = %s\n",
namep->mon_name);
@@ -102,13 +103,11 @@
resp->state = LOCAL_STATE;
}
/* ARGSUSED */
void
-sm_mon(monp, resp)
- mon *monp;
- sm_stat_res *resp;
+sm_mon_svc(mon *monp, sm_stat_res *resp)
{
mon_id *monidp;
monidp = &monp->mon_id;
rw_rdlock(&thr_rwlock);
@@ -130,13 +129,11 @@
rw_unlock(&thr_rwlock);
}
/* ARGSUSED */
void
-sm_unmon(monidp, resp)
- mon_id *monidp;
- sm_stat *resp;
+sm_unmon_svc(mon_id *monidp, sm_stat *resp)
{
rw_rdlock(&thr_rwlock);
if (debug) {
(void) printf(
"proc sm_unmon: mon_name = %s, [%s, %d, %d, %d]\n",
@@ -152,13 +149,11 @@
rw_unlock(&thr_rwlock);
}
/* ARGSUSED */
void
-sm_unmon_all(myidp, resp)
- my_id *myidp;
- sm_stat *resp;
+sm_unmon_all_svc(my_id *myidp, sm_stat *resp)
{
rw_rdlock(&thr_rwlock);
if (debug)
(void) printf("proc sm_unmon_all: [%s, %d, %d, %d]\n",
myidp->my_name,
@@ -172,12 +167,11 @@
/*
* Notifies lockd specified by name that state has changed for this server.
*/
void
-sm_notify(ntfp)
- stat_chge *ntfp;
+sm_notify_svc(stat_chge *ntfp)
{
rw_rdlock(&thr_rwlock);
if (debug)
(void) printf("sm_notify: %s state =%d\n",
ntfp->mon_name, ntfp->state);
@@ -185,12 +179,11 @@
rw_unlock(&thr_rwlock);
}
/* ARGSUSED */
void
-sm_simu_crash(myidp)
- void *myidp;
+sm_simu_crash_svc(void *myidp)
{
int i;
struct mon_entry *monitor_q;
int found = 0;
@@ -725,11 +718,10 @@
thr_send_notice(void *arg)
{
moninfo_t *minfop;
minfop = (moninfo_t *)arg;
-
if (statd_call_lockd(&minfop->id, minfop->state) == -1) {
if (debug && minfop->id.mon_id.mon_name)
(void) printf("problem with notifying %s failure, "
"give up\n", minfop->id.mon_id.mon_name);
} else {
@@ -757,20 +749,20 @@
mon *monp;
int state;
{
enum clnt_stat clnt_stat;
struct timeval tottimeout;
- struct status stat;
+ struct sm_status stat;
my_id *my_idp;
char *mon_name;
int i;
int rc = 0;
CLIENT *clnt;
mon_name = monp->mon_id.mon_name;
my_idp = &monp->mon_id.my_id;
- (void) memset(&stat, 0, sizeof (struct status));
+ (void) memset(&stat, 0, sizeof (stat));
stat.mon_name = mon_name;
stat.state = state;
for (i = 0; i < 16; i++) {
stat.priv[i] = monp->priv[i];
}
@@ -779,16 +771,18 @@
stat.mon_name, stat.state);
tottimeout.tv_sec = SM_RPC_TIMEOUT;
tottimeout.tv_usec = 0;
- if ((clnt = create_client(my_idp->my_name, my_idp->my_prog,
- my_idp->my_vers, &tottimeout)) == (CLIENT *) NULL) {
+ clnt = create_client(my_idp->my_name, my_idp->my_prog, my_idp->my_vers,
+ "ticotsord", &tottimeout);
+ if (clnt == NULL) {
return (-1);
}
- clnt_stat = clnt_call(clnt, my_idp->my_proc, xdr_status, (char *)&stat,
+ clnt_stat = clnt_call(clnt, my_idp->my_proc,
+ xdr_sm_status, (char *)&stat,
xdr_void, NULL, tottimeout);
if (debug) {
(void) printf("clnt_stat=%s(%d)\n",
clnt_sperrno(clnt_stat), clnt_stat);
}
@@ -806,25 +800,39 @@
/*
* Client handle created.
*/
CLIENT *
-create_client(host, prognum, versnum, utimeout)
- char *host;
- int prognum;
- int versnum;
- struct timeval *utimeout;
+create_client(char *host, int prognum, int versnum, char *netid,
+ struct timeval *utimeout)
{
int fd;
struct timeval timeout;
CLIENT *client;
struct t_info tinfo;
- if ((client = clnt_create_timed(host, prognum, versnum,
- "netpath", utimeout)) == NULL) {
+ if (netid == NULL) {
+ client = clnt_create_timed(host, prognum, versnum,
+ "netpath", utimeout);
+ } else {
+ struct netconfig *nconf;
+
+ nconf = getnetconfigent(netid);
+ if (nconf == NULL) {
return (NULL);
}
+
+ client = clnt_tp_create_timed(host, prognum, versnum, nconf,
+ utimeout);
+
+ freenetconfigent(nconf);
+ }
+
+ if (client == NULL) {
+ return (NULL);
+ }
+
(void) CLNT_CONTROL(client, CLGET_FD, (caddr_t)&fd);
if (t_getinfo(fd, &tinfo) != -1) {
if (tinfo.servtype == T_CLTS) {
/*
* Set time outs for connectionless case
@@ -1298,6 +1306,75 @@
memcmp(dst1, dst2, len) == 0) {
return (0);
}
}
return (1);
+}
+
+/*
+ * Add IP address strings to the host_name list.
+ */
+void
+merge_ips(void)
+{
+ struct ifaddrs *ifap, *cifap;
+ int error;
+
+ error = getifaddrs(&ifap);
+ if (error) {
+ syslog(LOG_WARNING, "getifaddrs error: '%s'",
+ strerror(errno));
+ return;
+ }
+
+ for (cifap = ifap; cifap != NULL; cifap = cifap->ifa_next) {
+ struct sockaddr *sa = cifap->ifa_addr;
+ char addr_str[INET6_ADDRSTRLEN];
+ void *addr = NULL;
+
+ switch (sa->sa_family) {
+ case AF_INET: {
+ struct sockaddr_in *sin = (struct sockaddr_in *)sa;
+
+ /* Skip loopback addresses. */
+ if (sin->sin_addr.s_addr == htonl(INADDR_LOOPBACK)) {
+ continue;
+ }
+
+ addr = &sin->sin_addr;
+ break;
+ }
+
+ case AF_INET6: {
+ struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa;
+
+ /* Skip loopback addresses. */
+ if (IN6_IS_ADDR_LOOPBACK(&sin6->sin6_addr)) {
+ continue;
+ }
+
+ addr = &sin6->sin6_addr;
+ break;
+ }
+
+ default:
+ syslog(LOG_WARNING, "Unknown address family %d for "
+ "interface %s", sa->sa_family, cifap->ifa_name);
+ continue;
+ }
+
+ if (inet_ntop(sa->sa_family, addr, addr_str, sizeof (addr_str))
+ == NULL) {
+ syslog(LOG_WARNING, "Failed to convert address into "
+ "string representation for interface '%s' "
+ "address family %d", cifap->ifa_name,
+ sa->sa_family);
+ continue;
+ }
+
+ if (!in_host_array(addr_str)) {
+ add_to_host_array(addr_str);
+ }
+ }
+
+ freeifaddrs(ifap);
}