1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 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 2004 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #include <stdio.h> 28 #include <sys/types.h> 29 #include <stdlib.h> 30 #include <unistd.h> 31 #include <sys/param.h> 32 #include <libintl.h> 33 #include <locale.h> 34 #include <rpc/rpc.h> 35 #include <rpcsvc/nlm_prot.h> 36 37 #include <sys/systeminfo.h> 38 #include <netdb.h> 39 #include <nss_dbdefs.h> 40 41 #include <nfs/nfs.h> 42 #include <nfs/export.h> 43 #include <nfs/nfssys.h> 44 45 extern char *optarg; 46 extern int optind; 47 extern int _nfssys(enum nfssys_op, void *); 48 49 static int share_zap(char *, char *); 50 51 /* 52 * Clear locks and v4 related state held by 53 * 'client'. 54 */ 55 static int 56 nfs4_clr_state(char *client) 57 { 58 int he_error; 59 char he_buf[NSS_BUFLEN_HOSTS]; 60 struct hostent host_ent, *he; 61 char **ap; 62 struct nfs4clrst_args arg; 63 64 if ((he = gethostbyname_r(client, &host_ent, he_buf, sizeof (he_buf), 65 &he_error)) == NULL) { 66 (void) fprintf(stderr, 67 gettext("client name '%s' can not be resolved\n"), 68 client); 69 return (1); 70 } 71 72 if (he_error) { 73 perror("gethostbyname"); 74 return (1); 75 } 76 77 /* 78 * The NFS4 clear state interface is 79 * versioned in case we need to pass 80 * more information in the future. 81 */ 82 arg.vers = NFS4_CLRST_VERSION; 83 arg.addr_type = he->h_addrtype; 84 85 /* 86 * Iterate over IP Addresses clear 87 * state for each. 88 */ 89 for (ap = he->h_addr_list; *ap; ap++) { 90 arg.ap = *ap; 91 _nfssys(NFS4_CLR_STATE, &arg); 92 } 93 return (0); 94 } 95 96 int 97 main(int argc, char *argv[]) 98 { 99 int i, c, ret; 100 int sflag = 0; 101 int errflg = 0; 102 char myhostname[MAXHOSTNAMELEN]; 103 104 if (geteuid() != (uid_t)0) { 105 (void) fprintf(stderr, gettext("clear_locks: must be root\n")); 106 exit(1); 107 } 108 109 (void) setlocale(LC_ALL, ""); 110 111 #if !defined(TEXT_DOMAIN) 112 #define TEXT_DOMAIN "SYS_TEST" 113 #endif 114 (void) textdomain(TEXT_DOMAIN); 115 116 /* 117 * Get the official hostname for this host 118 */ 119 sysinfo(SI_HOSTNAME, myhostname, sizeof (myhostname)); 120 121 while ((c = getopt(argc, argv, "s")) != EOF) { 122 switch (c) { 123 case 's': 124 sflag++; 125 break; 126 case '?': 127 errflg++; 128 } 129 } 130 131 i = argc - optind; 132 if (errflg || i != 1) { 133 (void) fprintf(stderr, 134 gettext("Usage: clear_locks [-s] hostname\n")); 135 exit(2); 136 } 137 138 if (sflag) { 139 (void) fprintf(stdout, 140 gettext("Clearing locks held for NFS client %s on server %s\n"), 141 myhostname, argv[optind]); 142 ret = share_zap(myhostname, argv[optind]); 143 } else { 144 (void) fprintf(stdout, 145 gettext("Clearing locks held for NFS client %s on server %s\n"), 146 argv[optind], myhostname); 147 ret = share_zap(argv[optind], myhostname); 148 ret += nfs4_clr_state(argv[optind]); 149 } 150 151 return (ret); 152 } 153 154 155 /* 156 * Request that host 'server' free all locks held by 157 * host 'client'. 158 */ 159 static int 160 share_zap(char *client, char *server) 161 { 162 struct nlm_notify notify; 163 enum clnt_stat rslt; 164 165 notify.state = 0; 166 notify.name = client; 167 rslt = rpc_call(server, NLM_PROG, NLM_VERSX, NLM_FREE_ALL, 168 xdr_nlm_notify, (char *)¬ify, xdr_void, 0, NULL); 169 if (rslt != RPC_SUCCESS) { 170 clnt_perrno(rslt); 171 return (3); 172 } 173 (void) fprintf(stderr, 174 gettext("clear of locks held for %s on %s returned success\n"), 175 client, server); 176 return (0); 177 } 178