summaryrefslogtreecommitdiffstats
path: root/tools/nlmtest
diff options
context:
space:
mode:
authorhjl <hjl>1999-10-18 23:21:12 +0000
committerhjl <hjl>1999-10-18 23:21:12 +0000
commit8b7ad01b14df1e7529b9ba8a1ea17df0d6004ef9 (patch)
tree0904ef8554ed680fe3244fa618685e1fb7ea148b /tools/nlmtest
downloadnfs-utils-8b7ad01b14df1e7529b9ba8a1ea17df0d6004ef9.tar.gz
nfs-utils-8b7ad01b14df1e7529b9ba8a1ea17df0d6004ef9.tar.xz
nfs-utils-8b7ad01b14df1e7529b9ba8a1ea17df0d6004ef9.zip
Initial revision
Diffstat (limited to 'tools/nlmtest')
-rw-r--r--tools/nlmtest/Makefile26
-rw-r--r--tools/nlmtest/README5
-rw-r--r--tools/nlmtest/host.h28
-rw-r--r--tools/nlmtest/nlm_prot.x183
-rw-r--r--tools/nlmtest/nlmtest.c264
5 files changed, 506 insertions, 0 deletions
diff --git a/tools/nlmtest/Makefile b/tools/nlmtest/Makefile
new file mode 100644
index 0000000..6f29afb
--- /dev/null
+++ b/tools/nlmtest/Makefile
@@ -0,0 +1,26 @@
+#
+# nlmtest Exercise some NLM calls to test the lockd server.
+#
+
+TOOL = nlmtest
+SRCS = $(RPCSRCS) nlmtest.c
+OBJS = $(SRCS:.c=.o)
+
+RPCSRCS = nlm_prot_clnt.c nlm_prot_xdr.c
+RPCHDRS = nlm_prot.h
+
+#LIBS = -lnfs
+
+include $(TOP)rules.mk
+
+install::
+ @:
+
+$(RPCHDRS) $(RPCSRCS): nlm_prot.x
+ $(RM) $(RPCHDRS) $(RPCSRCS)
+ $(RPCGEN) -h -o nlm_prot.h $<
+ $(RPCGEN) -l -o nlm_prot_clnt.c $<
+ $(RPCGEN) -c -o nlm_prot_xdr.c $<
+
+clean distclean::
+ $(RM) $(RPCHDRS) $(RPCSRCS)
diff --git a/tools/nlmtest/README b/tools/nlmtest/README
new file mode 100644
index 0000000..b54cb43
--- /dev/null
+++ b/tools/nlmtest/README
@@ -0,0 +1,5 @@
+
+This is a simple tool to test your lockd server. This is a very
+primitive program. To use it on your system, you have to edit
+host.h and adjust the inode and device numbers in nltest.c to
+suit your nfs server.
diff --git a/tools/nlmtest/host.h b/tools/nlmtest/host.h
new file mode 100644
index 0000000..b4f30df
--- /dev/null
+++ b/tools/nlmtest/host.h
@@ -0,0 +1,28 @@
+/*
+ * host.h
+ *
+ * Defaults for nlmtest
+ */
+
+#ifndef NLMTEST_HOST_H
+#define NLMTEST_HOST_H
+
+/*
+ * The host on which lockd runs
+ */
+#define NLMTEST_HOST "crutch"
+
+/*
+ * NFS mount point
+ */
+#define NLMTEST_DIR "../../mount/"
+
+/*
+ * The default file name and its inode version number.
+ * There's no way the test program can find out the version number,
+ * so you have to add it here.
+ */
+#define NLMTEST_FILE NLMTEST_DIR "COPYING"
+#define NLMTEST_VERSION 1
+
+#endif /* NLMTEST_HOST_H */
diff --git a/tools/nlmtest/nlm_prot.x b/tools/nlmtest/nlm_prot.x
new file mode 100644
index 0000000..a425912
--- /dev/null
+++ b/tools/nlmtest/nlm_prot.x
@@ -0,0 +1,183 @@
+/* @(#)nlm_prot.x 2.1 88/08/01 4.0 RPCSRC */
+/* @(#)nlm_prot.x 1.8 87/09/21 Copyr 1987 Sun Micro */
+
+/*
+ * Network lock manager protocol definition
+ * Copyright (C) 1986 Sun Microsystems, Inc.
+ *
+ * protocol used between local lock manager and remote lock manager
+ */
+
+#ifdef RPC_CLNT
+%#include <string.h>
+#endif
+
+#ifdef RPC_HDR
+%#define LM_MAXSTRLEN 1024
+%#define MAXNAMELEN LM_MAXSTRLEN+1
+#endif
+
+/*
+ * status of a call to the lock manager
+ */
+enum nlm_stats {
+ nlm_granted = 0,
+ nlm_denied = 1,
+ nlm_denied_nolocks = 2,
+ nlm_blocked = 3,
+ nlm_denied_grace_period = 4
+};
+
+struct nlm_holder {
+ bool exclusive;
+ int svid;
+ netobj oh;
+ unsigned l_offset;
+ unsigned l_len;
+};
+
+union nlm_testrply switch (nlm_stats stat) {
+ case nlm_denied:
+ struct nlm_holder holder;
+ default:
+ void;
+};
+
+struct nlm_stat {
+ nlm_stats stat;
+};
+
+struct nlm_res {
+ netobj cookie;
+ nlm_stat stat;
+};
+
+struct nlm_testres {
+ netobj cookie;
+ nlm_testrply stat;
+};
+
+struct nlm_lock {
+ string caller_name<LM_MAXSTRLEN>;
+ netobj fh; /* identify a file */
+ netobj oh; /* identify owner of a lock */
+ int svid; /* generated from pid for svid */
+ unsigned l_offset;
+ unsigned l_len;
+};
+
+struct nlm_lockargs {
+ netobj cookie;
+ bool block;
+ bool exclusive;
+ struct nlm_lock alock;
+ bool reclaim; /* used for recovering locks */
+ int state; /* specify local status monitor state */
+};
+
+struct nlm_cancargs {
+ netobj cookie;
+ bool block;
+ bool exclusive;
+ struct nlm_lock alock;
+};
+
+struct nlm_testargs {
+ netobj cookie;
+ bool exclusive;
+ struct nlm_lock alock;
+};
+
+struct nlm_unlockargs {
+ netobj cookie;
+ struct nlm_lock alock;
+};
+
+
+#ifdef RPC_HDR
+%/*
+% * The following enums are actually bit encoded for efficient
+% * boolean algebra.... DON'T change them.....
+% */
+#endif
+enum fsh_mode {
+ fsm_DN = 0, /* deny none */
+ fsm_DR = 1, /* deny read */
+ fsm_DW = 2, /* deny write */
+ fsm_DRW = 3 /* deny read/write */
+};
+
+enum fsh_access {
+ fsa_NONE = 0, /* for completeness */
+ fsa_R = 1, /* read only */
+ fsa_W = 2, /* write only */
+ fsa_RW = 3 /* read/write */
+};
+
+struct nlm_share {
+ string caller_name<LM_MAXSTRLEN>;
+ netobj fh;
+ netobj oh;
+ fsh_mode mode;
+ fsh_access access;
+};
+
+struct nlm_shareargs {
+ netobj cookie;
+ nlm_share share;
+ bool reclaim;
+};
+
+struct nlm_shareres {
+ netobj cookie;
+ nlm_stats stat;
+ int sequence;
+};
+
+struct nlm_notify {
+ string name<MAXNAMELEN>;
+ long state;
+};
+
+/*
+ * Over-the-wire protocol used between the network lock managers
+ */
+
+program NLM_PROG {
+ version NLM_VERS {
+
+ nlm_testres NLM_TEST(struct nlm_testargs) = 1;
+
+ nlm_res NLM_LOCK(struct nlm_lockargs) = 2;
+
+ nlm_res NLM_CANCEL(struct nlm_cancargs) = 3;
+ nlm_res NLM_UNLOCK(struct nlm_unlockargs) = 4;
+
+ /*
+ * remote lock manager call-back to grant lock
+ */
+ nlm_res NLM_GRANTED(struct nlm_testargs)= 5;
+ /*
+ * message passing style of requesting lock
+ */
+ void NLM_TEST_MSG(struct nlm_testargs) = 6;
+ void NLM_LOCK_MSG(struct nlm_lockargs) = 7;
+ void NLM_CANCEL_MSG(struct nlm_cancargs) =8;
+ void NLM_UNLOCK_MSG(struct nlm_unlockargs) = 9;
+ void NLM_GRANTED_MSG(struct nlm_testargs) = 10;
+ void NLM_TEST_RES(nlm_testres) = 11;
+ void NLM_LOCK_RES(nlm_res) = 12;
+ void NLM_CANCEL_RES(nlm_res) = 13;
+ void NLM_UNLOCK_RES(nlm_res) = 14;
+ void NLM_GRANTED_RES(nlm_res) = 15;
+ } = 1;
+
+ version NLM_VERSX {
+ nlm_shareres NLM_SHARE(nlm_shareargs) = 20;
+ nlm_shareres NLM_UNSHARE(nlm_shareargs) = 21;
+ nlm_res NLM_NM_LOCK(nlm_lockargs) = 22;
+ void NLM_FREE_ALL(nlm_notify) = 23;
+ } = 3;
+
+} = 100021;
+
diff --git a/tools/nlmtest/nlmtest.c b/tools/nlmtest/nlmtest.c
new file mode 100644
index 0000000..77dd889
--- /dev/null
+++ b/tools/nlmtest/nlmtest.c
@@ -0,0 +1,264 @@
+/*
+ * nlmtest
+ *
+ * Simple tool for NLM testing. You will have to adjust the values in
+ * host.h to your test system.
+ *
+ * Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de>
+ */
+
+#include "config.h"
+
+#include <sys/stat.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <nfs/nfs.h>
+#include <getopt.h>
+#include "nlm_prot.h"
+#include "host.h"
+
+static char myhostname[256];
+static int hostnamelen;
+
+static void makelock(struct nlm_lock *, u_int32_t, off_t, off_t);
+static void makeowner(struct netobj *, u_int32_t);
+static void makefileh(struct netobj *);
+static char * nlm_stat_name(int status);
+static char * holderstr(struct netobj *oh);
+
+int
+main(int argc, char **argv)
+{
+ CLIENT *client;
+ nlm_testargs testargs;
+ nlm_lockargs lockargs;
+ nlm_unlockargs unlockargs;
+ nlm_lock alock;
+ nlm_testres *testres;
+ nlm_res *lockres;
+ char *filename = NLMTEST_FILE;
+ char *svchost = NLMTEST_HOST;
+ unsigned long offset = 0, length = 0;
+ int exclusive = 0;
+ int blocking = 0;
+ int unlock = 0;
+ u_int32_t cookie = 4321;
+ u_int32_t mypid = 1234;
+ int c;
+
+ while ((c = getopt(argc, argv, "bf:h:l:o:p:ux")) != EOF) {
+ switch(c) {
+ case 'b':
+ blocking = 1;
+ break;
+ case 'f':
+ filename = optarg;
+ break;
+ case 'h':
+ svchost = optarg;
+ break;
+ case 'l':
+ length = atoi(optarg);
+ break;
+ case 'o':
+ offset = atoi(optarg);
+ break;
+ case 'p':
+ mypid = atoi(optarg);
+ break;
+ case 'u':
+ unlock = 1;
+ break;
+ case 'x':
+ exclusive = 1;
+ break;
+ default:
+ fprintf(stderr, "nlmtest: bad option %c\n", c);
+ exit (2);
+ }
+ }
+
+ client = clnt_create(svchost, NLM_PROG, NLM_VERS, "udp");
+ if (client == NULL) {
+ clnt_pcreateerror("localhost");
+ exit(1);
+ }
+
+ /* Get local host name */
+ if (gethostname(myhostname, sizeof(myhostname)) < 0)
+ strcpy(myhostname, "unknown");
+ hostnamelen = strlen(myhostname);
+
+ makelock(&alock, mypid, offset, length);
+
+ testargs.cookie.n_bytes = (void*)&cookie;
+ testargs.cookie.n_len = 4;
+ testargs.exclusive = exclusive;
+ testargs.alock = alock;
+
+ if ((testres = nlm_test_1(&testargs, client)) == NULL) {
+ clnt_perror(client, "nlm_test call failed:");
+ exit (1);
+ }
+ printf ("nlm_test reply:\n"
+ "\tcookie: %d\n"
+ "\tstatus: %s\n",
+ *(int*)(testres->cookie.n_bytes),
+ nlm_stat_name(testres->stat.stat)
+ );
+
+ if (testres->stat.stat == nlm_denied) {
+ nlm_holder *holder = &(testres->stat.nlm_testrply_u.holder);
+ printf ("\tconflicting lock:\n"
+ "\t oh: %s\n"
+ "\t pid: %d\n"
+ "\t offset: %d\n"
+ "\t length: %d\n"
+ "\t exclusive: %d\n",
+ holderstr(&holder->oh),
+ holder->svid,
+ holder->l_offset,
+ holder->l_len,
+ holder->exclusive);
+ }
+
+ if (testres->stat.stat != nlm_granted && !unlock && !blocking)
+ return 1;
+
+ if (unlock) {
+ unlockargs.cookie.n_bytes = (void*)&cookie;
+ unlockargs.cookie.n_len = sizeof(cookie);
+ unlockargs.alock = alock;
+
+ if ((lockres = nlm_unlock_1(&unlockargs, client)) == NULL) {
+ clnt_perror(client, "nlm_unlock call failed:");
+ exit (1);
+ }
+ printf ("nlm_unlock reply:\n"
+ "\tcookie: %d\n"
+ "\tstatus: %s\n",
+ *(int*)(lockres->cookie.n_bytes),
+ nlm_stat_name(lockres->stat.stat)
+ );
+ } else {
+ lockargs.cookie.n_bytes = (void*)&cookie;
+ lockargs.cookie.n_len = sizeof(cookie);
+ lockargs.exclusive = exclusive;
+ lockargs.alock = alock;
+ lockargs.reclaim = 0;
+ lockargs.state = 0;
+
+ if ((lockres = nlm_lock_1(&lockargs, client)) == NULL) {
+ clnt_perror(client, "nlm_lock call failed:");
+ exit (1);
+ }
+ printf ("nlm_lock reply:\n"
+ "\tcookie: %d\n"
+ "\tstatus: %s\n",
+ *(int*)(lockres->cookie.n_bytes),
+ nlm_stat_name(lockres->stat.stat)
+ );
+ }
+
+ return 0;
+}
+
+static char *
+nlm_stat_name(int status)
+{
+ static char buf[12];
+
+ switch (status) {
+ case nlm_granted:
+ return "nlm_granted";
+ case nlm_denied:
+ return "nlm_denied";
+ case nlm_denied_nolocks:
+ return "nlm_denied_nolocks";
+ case nlm_blocked:
+ return "nlm_blocked";
+ case nlm_denied_grace_period:
+ return "nlm_denied_grace_period";
+ }
+ sprintf(buf, "%d", status);
+ return buf;
+}
+
+static char *
+holderstr(struct netobj *oh)
+{
+ static char buffer[4096];
+ unsigned char c, *sp;
+ int i;
+
+ for (i = 0, sp = buffer; i < oh->n_len; i++) {
+ c = (unsigned char) oh->n_bytes[i];
+ if (c < 0x20 || c > 0x7f)
+ sp += sprintf(sp, "\\%03o", c);
+ else
+ *sp++ = c;
+ }
+ *sp++ = '\0';
+
+ return buffer;
+}
+
+static void
+makelock(struct nlm_lock *alock, u_int32_t mypid, off_t offset, off_t length)
+{
+ makeowner(&alock->oh, mypid); /* Create owner handle */
+ makefileh(&alock->fh); /* Create file handle */
+
+ alock->caller_name = myhostname;
+ alock->svid = mypid;
+ alock->l_offset = offset;
+ alock->l_len = length;
+}
+
+static void
+makeowner(struct netobj *oh, u_int32_t mypid)
+{
+ static char ohdata[1024];
+
+ oh->n_bytes = ohdata;
+ oh->n_len = hostnamelen + 1 + 4;
+
+ strcpy(ohdata, myhostname);
+ memcpy(ohdata + hostnamelen + 1, &mypid, 4);
+}
+
+static void
+makefileh(struct netobj *fh)
+{
+ static struct knfs_fh f;
+ struct stat stb;
+
+ memset(&f, 0, sizeof(f));
+#if 0
+ if (stat(NLMTEST_DIR, &stb) < 0) {
+ perror("couldn't stat mount point " NLMTEST_DIR);
+ exit(1);
+ }
+ f.fh_xdev = stb.st_dev;
+ f.fh_xino = stb.st_ino;
+
+ if (stat(NLMTEST_DIR, &stb) < 0) {
+ perror("couldn't stat mount point " NLMTEST_DIR);
+ exit(1);
+ }
+ f.fh_dev = stb.st_dev;
+ f.fh_ino = stb.st_ino;
+
+ f.fh_version = NLMTEST_VERSION;
+#else
+ f.fh_xdev = 0x801;
+ f.fh_xino = 37596;
+ f.fh_dev = 0x801;
+ f.fh_ino = 37732;
+#endif
+
+ fh->n_len = 32;
+ fh->n_bytes = (void *) &f;
+}