Home | History | Annotate | Download | only in dservd
      1  6741  th199096 /*
      2  6741  th199096  * CDDL HEADER START
      3  6741  th199096  *
      4  6741  th199096  * The contents of this file are subject to the terms of the
      5  6741  th199096  * Common Development and Distribution License (the "License").
      6  6741  th199096  * You may not use this file except in compliance with the License.
      7  6741  th199096  *
      8  6741  th199096  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
      9  6741  th199096  * or http://www.opensolaris.org/os/licensing.
     10  6741  th199096  * See the License for the specific language governing permissions
     11  6741  th199096  * and limitations under the License.
     12  6741  th199096  *
     13  6741  th199096  * When distributing Covered Code, include this CDDL HEADER in each
     14  6741  th199096  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     15  6741  th199096  * If applicable, add the following below this CDDL HEADER, with the
     16  6741  th199096  * fields enclosed by brackets "[]" replaced with your own identifying
     17  6741  th199096  * information: Portions Copyright [yyyy] [name of copyright owner]
     18  6741  th199096  *
     19  6741  th199096  * CDDL HEADER END
     20  6741  th199096  */
     21  6741  th199096 /*
     22  9209      Jeff  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
     23  6741  th199096  * Use is subject to license terms.
     24  6741  th199096  */
     25  6741  th199096 
     26  6741  th199096 #include <nfs/nfs.h>
     27  6741  th199096 #include <nfs/nfs4.h>
     28  6741  th199096 #include <libintl.h>
     29  6741  th199096 #include <sys/param.h>
     30  6741  th199096 #include <sys/tiuser.h>
     31  6741  th199096 #include <rpc/svc.h>
     32  6741  th199096 #include "nfs_tbind.h"
     33  6741  th199096 #include <nfs/nfssys.h>
     34  9209      Jeff #include <libdserv.h>
     35  6741  th199096 #include <dservd.h>
     36  6741  th199096 
     37  6741  th199096 #define	PNFSCTLMDS	104000
     38  6741  th199096 #define	PNFSCTLMDS_V1	1
     39  6741  th199096 
     40  6741  th199096 #ifndef TEXT_DOMAIN
     41  6741  th199096 #define	TEXT_DOMAIN	"SUNW_OST_OSCMD"
     42  6741  th199096 #endif /* TEXT_DOMAIN */
     43  6741  th199096 
     44  6741  th199096 /*
     45  6741  th199096  * The following are all globals used by routines in nfs_tbind.c.
     46  6741  th199096  */
     47  6741  th199096 size_t	end_listen_fds;		/* used by conn_close_oldest() */
     48  6741  th199096 size_t	num_fds = 0;		/* used by multiple routines */
     49  6741  th199096 int	listen_backlog = 32;	/* used by bind_to_{provider,proto}() */
     50  6741  th199096 int	num_servers;		/* used by cots_listen_event() */
     51  6741  th199096 int	(*Mysvc)(int, struct netbuf, struct netconfig *) = NULL;
     52  6741  th199096 				/* used by cots_listen_event() */
     53  6741  th199096 int	max_conns_allowed = -1;	/* used by cots_listen_event() */
     54  6741  th199096 
     55  6741  th199096 #define	MAXHOSTNAMELEN 64
     56  6741  th199096 
     57  6741  th199096 static dserv_handle_t *do_all_handle;
     58  6741  th199096 
     59  6741  th199096 static char *
     60  6741  th199096 get_uaddr(struct netconfig *nconf, struct netbuf *nb)
     61  6741  th199096 {
     62  6741  th199096 	struct nfs_svc_args nsa;
     63  6741  th199096 	char *ua, *ua2, *mua = NULL;
     64  6741  th199096 	char me[MAXHOSTNAMELEN];
     65  6741  th199096 	struct nd_addrlist *nas;
     66  6741  th199096 	struct nd_hostserv hs;
     67  6741  th199096 	struct nd_mergearg ma;
     68  6741  th199096 
     69  6741  th199096 	ua = taddr2uaddr(nconf, nb);
     70  6741  th199096 
     71  6741  th199096 	if (ua == NULL) {
     72  6741  th199096 		return (NULL);
     73  6741  th199096 	}
     74  6741  th199096 
     75  6741  th199096 	gethostname(me, MAXHOSTNAMELEN);
     76  6741  th199096 
     77  6741  th199096 	hs.h_host = me;
     78  6741  th199096 	hs.h_serv = "nfs";
     79  6741  th199096 	if (netdir_getbyname(nconf, &hs, &nas)) {
     80  6741  th199096 		return (NULL);
     81  6741  th199096 	}
     82  6741  th199096 
     83  6741  th199096 	ua2 = taddr2uaddr(nconf, nas->n_addrs);
     84  6741  th199096 
     85  6741  th199096 	if (ua2 == NULL) {
     86  6741  th199096 		return (NULL);
     87  6741  th199096 	}
     88  6741  th199096 
     89  6741  th199096 	ma.s_uaddr = ua;
     90  6741  th199096 	ma.c_uaddr = ua2;
     91  6741  th199096 	ma.m_uaddr = NULL;
     92  6741  th199096 
     93  6741  th199096 	if (netdir_options(nconf, ND_MERGEADDR, 0, (char *)&ma)) {
     94  6741  th199096 		return (NULL);
     95  6741  th199096 	}
     96  6741  th199096 
     97  6741  th199096 	mua = ma.m_uaddr;
     98  6741  th199096 	return (mua);
     99  6741  th199096 }
    100  6741  th199096 
    101  6741  th199096 /*
    102  6741  th199096  * dserv_service is called either with a command of
    103  6741  th199096  * NFS4_KRPC_START or SETPORT. Any other value is
    104  6741  th199096  * invalid.
    105  6741  th199096  */
    106  6741  th199096 static int
    107  6741  th199096 dserv_service(int fd, struct netbuf *addrmask, struct netconfig *nconf,
    108  6741  th199096     int cmd, struct netbuf *addr)
    109  6741  th199096 {
    110  6741  th199096 	dserv_svc_args_t svcargs;
    111  6741  th199096 	dserv_setport_args_t setportargs;
    112  6741  th199096 	char *uaddr;
    113  6741  th199096 	int result;
    114  6741  th199096 
    115  6741  th199096 	switch (cmd) {
    116  6741  th199096 	case NFS4_KRPC_START:
    117  6741  th199096 		svcargs.fd = fd;
    118  6741  th199096 		bcopy(addr->buf, &svcargs.sin, addr->len);
    119  6741  th199096 		(void) strlcpy(svcargs.netid,
    120  6741  th199096 		    nconf->nc_netid, sizeof (svcargs.netid));
    121  6741  th199096 		uaddr = get_uaddr(nconf, addr);
    122  6741  th199096 		if (uaddr != NULL) {
    123  6741  th199096 			dserv_log(do_all_handle, LOG_INFO,
    124  6741  th199096 			    gettext("NFS4_KRPC_START: %s"), uaddr);
    125  6741  th199096 			free(uaddr);
    126  6741  th199096 		}
    127  6741  th199096 		result = dserv_kmod_svc(do_all_handle, &svcargs);
    128  6741  th199096 		break;
    129  6741  th199096 
    130  6741  th199096 	case NFS4_SETPORT:
    131  6741  th199096 		uaddr = get_uaddr(nconf, addr);
    132  6741  th199096 		if (uaddr == NULL) {
    133  6741  th199096 			dserv_log(do_all_handle, LOG_INFO,
    134  6741  th199096 			    gettext("NFS4_SETPORT: get_uaddr failed"));
    135  6741  th199096 			return (1);
    136  6741  th199096 		}
    137  6741  th199096 		(void) strlcpy(setportargs.dsa_uaddr, uaddr,
    138  6741  th199096 		    sizeof (setportargs.dsa_uaddr));
    139  6741  th199096 		(void) strlcpy(setportargs.dsa_proto, nconf->nc_proto,
    140  6741  th199096 		    sizeof (setportargs.dsa_proto));
    141  6741  th199096 		(void) strlcpy(setportargs.dsa_name, getenv("SMF_FMRI"),
    142  6741  th199096 		    sizeof (setportargs.dsa_name));
    143  6741  th199096 
    144  6741  th199096 		result = dserv_kmod_setport(do_all_handle, &setportargs);
    145  6741  th199096 
    146  6741  th199096 		if (result == 0)
    147  6741  th199096 			result = dserv_kmod_reportavail(do_all_handle);
    148  6741  th199096 		break;
    149  6741  th199096 
    150  6741  th199096 	default:
    151  6741  th199096 		dserv_log(do_all_handle, LOG_ERR,
    152  6741  th199096 		    gettext("bad cmd: %d"), cmd);
    153  6741  th199096 		return (1);
    154  6741  th199096 	}
    155  6741  th199096 
    156  6741  th199096 	if (result != 0) {
    157  6741  th199096 		dserv_log(do_all_handle, LOG_ERR, NULL);
    158  6741  th199096 		return (1); /* XXX errno? */
    159  6741  th199096 	}
    160  6741  th199096 
    161  6741  th199096 	return (0);
    162  6741  th199096 }
    163  6741  th199096 
    164  6741  th199096 void
    165  6741  th199096 dserv_daemon(dserv_handle_t *handle)
    166  6741  th199096 {
    167  6741  th199096 	struct svcpool_args dserv_svcpool;
    168  6741  th199096 	struct protob dservproto;
    169  6741  th199096 
    170  6741  th199096 	bzero(&dserv_svcpool, sizeof (dserv_svcpool));
    171  6741  th199096 
    172  6741  th199096 	dserv_svcpool.id = UNIQUE_SVCPOOL_ID;
    173  6741  th199096 
    174  6741  th199096 	if (_nfssys(SVCPOOL_CREATE, &dserv_svcpool)) {
    175  6741  th199096 		dserv_log(handle, LOG_ERR,
    176  6741  th199096 		    gettext("SVCPOOL_CREATE failed: %m"));
    177  6741  th199096 		exit(1);
    178  6741  th199096 	}
    179  6741  th199096 
    180  6741  th199096 	dserv_set_pool_id(handle, dserv_svcpool.id);
    181  6741  th199096 
    182  6741  th199096 	if (svcwait(dserv_svcpool.id)) {
    183  6741  th199096 		dserv_log(handle, LOG_ERR,
    184  6741  th199096 		    gettext("svcwait(DSERV_SVCPOOL_ID) failed: %m"));
    185  6741  th199096 		exit(1);
    186  6741  th199096 	}
    187  6741  th199096 
    188  6741  th199096 	dservproto.serv = "DSERV";
    189  6741  th199096 	dservproto.versmin = PNFSCTLMDS_V1;
    190  6741  th199096 	dservproto.versmax = PNFSCTLMDS_V1;
    191  6741  th199096 	dservproto.program = PNFSCTLMDS;
    192  6741  th199096 	dservproto.flags = PROTOB_NO_REGISTER;
    193  6741  th199096 	dservproto.next = NULL;
    194  6741  th199096 
    195  6741  th199096 	/*
    196  6741  th199096 	 * We love globals!
    197  6741  th199096 	 */
    198  6741  th199096 	Mysvc4 = dserv_service;
    199  6741  th199096 	do_all_handle = handle;
    200  6741  th199096 	if (do_all(&dservproto, NULL, 0) == -1) {
    201  6741  th199096 		dserv_log(handle, LOG_ERR,
    202  6741  th199096 		    gettext("do_all(): %m"));
    203  6741  th199096 		exit(1);
    204  6741  th199096 	}
    205  6741  th199096 	if (num_fds == 0) {
    206  6741  th199096 		dserv_log(handle, LOG_ERR,
    207  6741  th199096 		    gettext("Could not start DSERV service for any protocol"));
    208  6741  th199096 		exit(1);
    209  6741  th199096 	}
    210  6741  th199096 
    211  6741  th199096 	end_listen_fds = num_fds;
    212  6741  th199096 	poll_for_action();
    213  6741  th199096 
    214  6741  th199096 	dserv_log(handle, LOG_INFO,
    215  6741  th199096 	    gettext("I am shutting down now"));
    216  6741  th199096 
    217  6741  th199096 	exit(1);
    218  6741  th199096 }
    219