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