#include <stdio.h>
#include <sys/types.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/param.h>
#include <libintl.h>
#include <locale.h>
#include <rpc/rpc.h>
#include <rpcsvc/nlm_prot.h>
#include <sys/systeminfo.h>
#include <netdb.h>
#include <nss_dbdefs.h>
#include <nfs/nfs.h>
#include <nfs/export.h>
#include <nfs/nfssys.h>
extern char *optarg;
extern int optind;
extern int _nfssys(enum nfssys_op, void *);
static int share_zap(char *, char *);
static int
nfs4_clr_state(char *client)
{
int he_error;
char he_buf[NSS_BUFLEN_HOSTS];
struct hostent host_ent, *he;
char **ap;
struct nfs4clrst_args arg;
if ((he = gethostbyname_r(client, &host_ent, he_buf, sizeof (he_buf),
&he_error)) == NULL) {
(void) fprintf(stderr,
gettext("client name '%s' can not be resolved\n"), client);
return (1);
}
if (he_error) {
perror("gethostbyname");
return (1);
}
arg.vers = NFS4_CLRST_VERSION;
arg.addr_type = he->h_addrtype;
for (ap = he->h_addr_list; *ap; ap++) {
arg.ap = *ap;
if (_nfssys(NFS4_CLR_STATE, &arg) != 0) {
perror("nfssys(NFS4_CLR_STATE)");
return (1);
}
}
return (0);
}
int
main(int argc, char *argv[])
{
int i, c, ret;
int sflag = 0;
int errflg = 0;
char myhostname[MAXHOSTNAMELEN];
if (geteuid() != (uid_t)0) {
(void) fprintf(stderr, gettext("clear_locks: must be root\n"));
exit(1);
}
(void) setlocale(LC_ALL, "");
#if !defined(TEXT_DOMAIN)
#define TEXT_DOMAIN "SYS_TEST"
#endif
(void) textdomain(TEXT_DOMAIN);
sysinfo(SI_HOSTNAME, myhostname, sizeof (myhostname));
while ((c = getopt(argc, argv, "s")) != EOF) {
switch (c) {
case 's':
sflag++;
break;
case '?':
errflg++;
}
}
i = argc - optind;
if (errflg || i != 1) {
(void) fprintf(stderr,
gettext("Usage: clear_locks [-s] hostname\n"));
exit(2);
}
if (sflag) {
(void) fprintf(stdout, gettext(
"Clearing locks held for NFS client %s on server %s\n"),
myhostname, argv[optind]);
ret = share_zap(myhostname, argv[optind]);
} else {
(void) fprintf(stdout, gettext(
"Clearing locks held for NFS client %s on server %s\n"),
argv[optind], myhostname);
ret = share_zap(argv[optind], myhostname);
ret += nfs4_clr_state(argv[optind]);
}
return (ret);
}
static int
share_zap(char *client, char *server)
{
struct nlm_notify notify;
enum clnt_stat rslt;
notify.state = 0;
notify.name = client;
rslt = rpc_call(server, NLM_PROG, NLM_VERSX, NLM_FREE_ALL,
xdr_nlm_notify, (char *)¬ify, xdr_void, 0, NULL);
if (rslt != RPC_SUCCESS) {
clnt_perrno(rslt);
return (3);
}
(void) fprintf(stderr,
gettext("clear of locks held for %s on %s returned success\n"),
client, server);
return (0);
}