1178476Sjb/*
2178476Sjb * CDDL HEADER START
3178476Sjb *
4178476Sjb * The contents of this file are subject to the terms of the
5178476Sjb * Common Development and Distribution License (the "License").
6178476Sjb * You may not use this file except in compliance with the License.
7178476Sjb *
8178476Sjb * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9178476Sjb * or http://www.opensolaris.org/os/licensing.
10178476Sjb * See the License for the specific language governing permissions
11178476Sjb * and limitations under the License.
12178476Sjb *
13178476Sjb * When distributing Covered Code, include this CDDL HEADER in each
14178476Sjb * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15178476Sjb * If applicable, add the following below this CDDL HEADER, with the
16178476Sjb * fields enclosed by brackets "[]" replaced with your own identifying
17178476Sjb * information: Portions Copyright [yyyy] [name of copyright owner]
18178476Sjb *
19178476Sjb * CDDL HEADER END
20178476Sjb */
21178476Sjb
22178476Sjb/*
23178476Sjb * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
24178476Sjb * Use is subject to license terms.
25178476Sjb */
26178476Sjb
27178476Sjb#pragma ident	"%Z%%M%	%I%	%E% SMI"
28178476Sjb
29178476Sjb#include <strings.h>
30178476Sjb#include <rpc/rpc.h>
31178476Sjb#include <stdlib.h>
32178476Sjb#include <sys/param.h>
33178476Sjb#include <rpcsvc/mount.h>
34178476Sjb
35178476Sjb#include "rpcsvc/nfs_prot.h"
36178476Sjb
37178476Sjbchar sharedpath[MAXPATHLEN];
38178476Sjbfhandle3 *rootfh;
39178476Sjb
40178476Sjb/*
41178476Sjb * The waiting() function returns the value passed in, until something
42178476Sjb * external modifies it.  In this case, the D script tst.call.d will
43178476Sjb * modify the value of *a, and thus break the while loop in dotest().
44178476Sjb *
45178476Sjb * This serves the purpose of not making the RPC calls until tst.call.d
46178476Sjb * is active.  Thus, the probes in tst.call.d can fire as a result of
47178476Sjb * the RPC call in dotest().
48178476Sjb */
49178476Sjb
50178476Sjbint
51178476Sjbwaiting(volatile int *a)
52178476Sjb{
53178476Sjb	return (*a);
54178476Sjb}
55178476Sjb
56178476Sjbstatic void
57178476Sjbgetattr_arginit(void *argp)
58178476Sjb{
59178476Sjb	GETATTR3args *args = argp;
60178476Sjb
61178476Sjb	args->object.data.data_len = rootfh->fhandle3_len;
62178476Sjb	args->object.data.data_val = rootfh->fhandle3_val;
63178476Sjb}
64178476Sjb
65178476Sjbstatic void
66178476Sjbsetattr_arginit(void *argp)
67178476Sjb{
68178476Sjb	SETATTR3args *args = argp;
69178476Sjb
70178476Sjb	bzero(args, sizeof (*args));
71178476Sjb	args->object.data.data_len = rootfh->fhandle3_len;
72178476Sjb	args->object.data.data_val = rootfh->fhandle3_val;
73178476Sjb}
74178476Sjb
75178476Sjbstatic void
76178476Sjblookup_arginit(void *argp)
77178476Sjb{
78178476Sjb	LOOKUP3args *args = argp;
79178476Sjb
80178476Sjb	args->what.name = "giant-skunk";
81178476Sjb	args->what.dir.data.data_len = rootfh->fhandle3_len;
82178476Sjb	args->what.dir.data.data_val = rootfh->fhandle3_val;
83178476Sjb}
84178476Sjb
85178476Sjbstatic void
86178476Sjbaccess_arginit(void *argp)
87178476Sjb{
88178476Sjb	ACCESS3args *args = argp;
89178476Sjb
90178476Sjb	args->object.data.data_len = rootfh->fhandle3_len;
91178476Sjb	args->object.data.data_val = rootfh->fhandle3_val;
92178476Sjb}
93178476Sjb
94178476Sjbstatic void
95178476Sjbcommit_arginit(void *argp)
96178476Sjb{
97178476Sjb	COMMIT3args *args = argp;
98178476Sjb
99178476Sjb	bzero(args, sizeof (*args));
100178476Sjb	args->file.data.data_len = rootfh->fhandle3_len;
101178476Sjb	args->file.data.data_val = rootfh->fhandle3_val;
102178476Sjb}
103178476Sjb
104178476Sjbstatic void
105178476Sjbcreate_arginit(void *argp)
106178476Sjb{
107178476Sjb	CREATE3args *args = argp;
108178476Sjb
109178476Sjb	bzero(args, sizeof (*args));
110178476Sjb	args->where.name = "pinky-blue";
111178476Sjb	args->where.dir.data.data_len = rootfh->fhandle3_len;
112178476Sjb	args->where.dir.data.data_val = rootfh->fhandle3_val;
113178476Sjb}
114178476Sjb
115178476Sjbstatic void
116178476Sjbfsinfo_arginit(void *argp)
117178476Sjb{
118178476Sjb	FSINFO3args *args = argp;
119178476Sjb
120178476Sjb	args->fsroot.data.data_len = rootfh->fhandle3_len;
121178476Sjb	args->fsroot.data.data_val = rootfh->fhandle3_val;
122178476Sjb}
123178476Sjb
124178476Sjbstatic void
125178476Sjbfsstat_arginit(void *argp)
126178476Sjb{
127178476Sjb	FSSTAT3args *args = argp;
128178476Sjb
129178476Sjb	args->fsroot.data.data_len = rootfh->fhandle3_len;
130178476Sjb	args->fsroot.data.data_val = rootfh->fhandle3_val;
131178476Sjb}
132178476Sjb
133178476Sjbstatic void
134178476Sjblink_arginit(void *argp)
135178476Sjb{
136178476Sjb	LINK3args *args = argp;
137178476Sjb
138178476Sjb	args->file.data.data_len = rootfh->fhandle3_len;
139178476Sjb	args->file.data.data_val = rootfh->fhandle3_val;
140178476Sjb	args->link.dir.data.data_len = rootfh->fhandle3_len;
141178476Sjb	args->link.dir.data.data_val = rootfh->fhandle3_val;
142178476Sjb	args->link.name = "samf";
143178476Sjb}
144178476Sjb
145178476Sjbstatic void
146178476Sjbmkdir_arginit(void *argp)
147178476Sjb{
148178476Sjb	MKDIR3args *args = argp;
149178476Sjb
150178476Sjb	bzero(args, sizeof (*args));
151178476Sjb	args->where.dir.data.data_len = rootfh->fhandle3_len;
152178476Sjb	args->where.dir.data.data_val = rootfh->fhandle3_val;
153178476Sjb	args->where.name = "cookie";
154178476Sjb}
155178476Sjb
156178476Sjbstatic void
157178476Sjbmknod_arginit(void *argp)
158178476Sjb{
159178476Sjb	MKNOD3args *args = argp;
160178476Sjb
161178476Sjb	bzero(args, sizeof (*args));
162178476Sjb	args->where.dir.data.data_len = rootfh->fhandle3_len;
163178476Sjb	args->where.dir.data.data_val = rootfh->fhandle3_val;
164178476Sjb	args->where.name = "pookie";
165178476Sjb}
166178476Sjb
167178476Sjbstatic void
168178476Sjbnull_arginit(void *argp)
169178476Sjb{
170178476Sjb}
171178476Sjb
172178476Sjbstatic void
173178476Sjbpathconf_arginit(void *argp)
174178476Sjb{
175178476Sjb	PATHCONF3args *args = argp;
176178476Sjb
177178476Sjb	args->object.data.data_len = rootfh->fhandle3_len;
178178476Sjb	args->object.data.data_val = rootfh->fhandle3_val;
179178476Sjb}
180178476Sjb
181178476Sjbstatic void
182178476Sjbread_arginit(void *argp)
183178476Sjb{
184178476Sjb	READ3args *args = argp;
185178476Sjb
186178476Sjb	bzero(args, sizeof (*args));
187178476Sjb	args->file.data.data_len = rootfh->fhandle3_len;
188178476Sjb	args->file.data.data_val = rootfh->fhandle3_val;
189178476Sjb}
190178476Sjb
191178476Sjbstatic void
192178476Sjbreaddir_arginit(void *argp)
193178476Sjb{
194178476Sjb	READDIR3args *args = argp;
195178476Sjb
196178476Sjb	bzero(args, sizeof (*args));
197178476Sjb	args->dir.data.data_len = rootfh->fhandle3_len;
198178476Sjb	args->dir.data.data_val = rootfh->fhandle3_val;
199178476Sjb	args->count = 1024;
200178476Sjb}
201178476Sjb
202178476Sjbstatic void
203178476Sjbreaddirplus_arginit(void *argp)
204178476Sjb{
205178476Sjb	READDIRPLUS3args *args = argp;
206178476Sjb
207178476Sjb	bzero(args, sizeof (*args));
208178476Sjb	args->dir.data.data_len = rootfh->fhandle3_len;
209178476Sjb	args->dir.data.data_val = rootfh->fhandle3_val;
210178476Sjb	args->dircount = 1024;
211178476Sjb	args->maxcount = 1024;
212178476Sjb}
213178476Sjb
214178476Sjbstatic void
215178476Sjbreadlink_arginit(void *argp)
216178476Sjb{
217178476Sjb	READLINK3args *args = argp;
218178476Sjb
219178476Sjb	args->symlink.data.data_len = rootfh->fhandle3_len;
220178476Sjb	args->symlink.data.data_val = rootfh->fhandle3_val;
221178476Sjb}
222178476Sjb
223178476Sjbstatic void
224178476Sjbremove_arginit(void *argp)
225178476Sjb{
226178476Sjb	REMOVE3args *args = argp;
227178476Sjb
228178476Sjb	args->object.dir.data.data_len = rootfh->fhandle3_len;
229178476Sjb	args->object.dir.data.data_val = rootfh->fhandle3_val;
230178476Sjb	args->object.name = "antelope";
231178476Sjb}
232178476Sjb
233178476Sjbstatic void
234178476Sjbrename_arginit(void *argp)
235178476Sjb{
236178476Sjb	RENAME3args *args = argp;
237178476Sjb
238178476Sjb	args->from.dir.data.data_len = rootfh->fhandle3_len;
239178476Sjb	args->from.dir.data.data_val = rootfh->fhandle3_val;
240178476Sjb	args->from.name = "walter";
241178476Sjb	args->to.dir.data.data_len = rootfh->fhandle3_len;
242178476Sjb	args->to.dir.data.data_val = rootfh->fhandle3_val;
243178476Sjb	args->to.name = "wendy";
244178476Sjb}
245178476Sjb
246178476Sjbstatic void
247178476Sjbrmdir_arginit(void *argp)
248178476Sjb{
249178476Sjb	RMDIR3args *args = argp;
250178476Sjb
251178476Sjb	args->object.dir.data.data_len = rootfh->fhandle3_len;
252178476Sjb	args->object.dir.data.data_val = rootfh->fhandle3_val;
253178476Sjb	args->object.name = "bunny";
254178476Sjb}
255178476Sjb
256178476Sjbstatic void
257178476Sjbsymlink_arginit(void *argp)
258178476Sjb{
259178476Sjb	SYMLINK3args *args = argp;
260178476Sjb
261178476Sjb	bzero(args, sizeof (*args));
262178476Sjb	args->where.dir.data.data_len = rootfh->fhandle3_len;
263178476Sjb	args->where.dir.data.data_val = rootfh->fhandle3_val;
264178476Sjb	args->where.name = "parlor";
265178476Sjb	args->symlink.symlink_data = "interior";
266178476Sjb}
267178476Sjb
268178476Sjbstatic void
269178476Sjbwrite_arginit(void *argp)
270178476Sjb{
271178476Sjb	WRITE3args *args = argp;
272178476Sjb
273178476Sjb	bzero(args, sizeof (*args));
274178476Sjb	args->file.data.data_len = rootfh->fhandle3_len;
275178476Sjb	args->file.data.data_val = rootfh->fhandle3_val;
276178476Sjb}
277178476Sjb
278178476Sjbtypedef void (*call3_arginit_t)(void *);
279178476Sjb
280178476Sjbtypedef struct {
281178476Sjb	call3_arginit_t arginit;
282178476Sjb	rpcproc_t proc;
283178476Sjb	xdrproc_t xdrargs;
284178476Sjb	size_t argsize;
285178476Sjb	xdrproc_t xdrres;
286178476Sjb	size_t ressize;
287178476Sjb} call3_test_t;
288178476Sjbcall3_test_t call3_tests[] = {
289178476Sjb	{getattr_arginit, NFSPROC3_GETATTR, xdr_GETATTR3args,
290178476Sjb	    sizeof (GETATTR3args), xdr_GETATTR3res, sizeof (GETATTR3res)},
291178476Sjb	{setattr_arginit, NFSPROC3_SETATTR, xdr_SETATTR3args,
292178476Sjb	    sizeof (SETATTR3args), xdr_SETATTR3res, sizeof (SETATTR3res)},
293178476Sjb	{lookup_arginit, NFSPROC3_LOOKUP, xdr_LOOKUP3args,
294178476Sjb	    sizeof (LOOKUP3args), xdr_LOOKUP3res, sizeof (LOOKUP3res)},
295178476Sjb	{access_arginit, NFSPROC3_ACCESS, xdr_ACCESS3args,
296178476Sjb	    sizeof (ACCESS3args), xdr_ACCESS3res, sizeof (ACCESS3res)},
297178476Sjb	{commit_arginit, NFSPROC3_COMMIT, xdr_COMMIT3args,
298178476Sjb	    sizeof (COMMIT3args), xdr_COMMIT3res, sizeof (COMMIT3res)},
299178476Sjb	{create_arginit, NFSPROC3_CREATE, xdr_CREATE3args,
300178476Sjb	    sizeof (CREATE3args), xdr_CREATE3res, sizeof (CREATE3res)},
301178476Sjb	{fsinfo_arginit, NFSPROC3_FSINFO, xdr_FSINFO3args,
302178476Sjb	    sizeof (FSINFO3args), xdr_FSINFO3res, sizeof (FSINFO3res)},
303178476Sjb	{fsstat_arginit, NFSPROC3_FSSTAT, xdr_FSSTAT3args,
304178476Sjb	    sizeof (FSSTAT3args), xdr_FSSTAT3res, sizeof (FSSTAT3res)},
305178476Sjb	{link_arginit, NFSPROC3_LINK, xdr_LINK3args,
306178476Sjb	    sizeof (LINK3args), xdr_LINK3res, sizeof (LINK3res)},
307178476Sjb	{mkdir_arginit, NFSPROC3_MKDIR, xdr_MKDIR3args,
308178476Sjb	    sizeof (MKDIR3args), xdr_MKDIR3res, sizeof (MKDIR3res)},
309178476Sjb	{mknod_arginit, NFSPROC3_MKNOD, xdr_MKNOD3args,
310178476Sjb	    sizeof (MKNOD3args), xdr_MKNOD3res, sizeof (MKNOD3res)},
311178476Sjb	/*
312178476Sjb	 * NULL proc is special.  Rather than special case its zero-sized
313178476Sjb	 * args/results, we give it a small nonzero size, so as to not
314178476Sjb	 * make realloc() do the wrong thing.
315178476Sjb	 */
316178476Sjb	{null_arginit, NFSPROC3_NULL, xdr_void, sizeof (int), xdr_void,
317178476Sjb	    sizeof (int)},
318178476Sjb	{pathconf_arginit, NFSPROC3_PATHCONF, xdr_PATHCONF3args,
319178476Sjb	    sizeof (PATHCONF3args), xdr_PATHCONF3res, sizeof (PATHCONF3res)},
320178476Sjb	{read_arginit, NFSPROC3_READ, xdr_READ3args,
321178476Sjb	    sizeof (READ3args), xdr_READ3res, sizeof (READ3res)},
322178476Sjb	{readdir_arginit, NFSPROC3_READDIR, xdr_READDIR3args,
323178476Sjb	    sizeof (READDIR3args), xdr_READDIR3res, sizeof (READDIR3res)},
324178476Sjb	{readdirplus_arginit, NFSPROC3_READDIRPLUS, xdr_READDIRPLUS3args,
325178476Sjb	    sizeof (READDIRPLUS3args), xdr_READDIRPLUS3res,
326178476Sjb	    sizeof (READDIRPLUS3res)},
327178476Sjb	{readlink_arginit, NFSPROC3_READLINK, xdr_READLINK3args,
328178476Sjb	    sizeof (READLINK3args), xdr_READLINK3res, sizeof (READLINK3res)},
329178476Sjb	{remove_arginit, NFSPROC3_REMOVE, xdr_REMOVE3args,
330178476Sjb	    sizeof (REMOVE3args), xdr_REMOVE3res, sizeof (REMOVE3res)},
331178476Sjb	{rename_arginit, NFSPROC3_RENAME, xdr_RENAME3args,
332178476Sjb	    sizeof (RENAME3args), xdr_RENAME3res, sizeof (RENAME3res)},
333178476Sjb	{rmdir_arginit, NFSPROC3_RMDIR, xdr_RMDIR3args,
334178476Sjb	    sizeof (RMDIR3args), xdr_RMDIR3res, sizeof (RMDIR3res)},
335178476Sjb	{symlink_arginit, NFSPROC3_SYMLINK, xdr_SYMLINK3args,
336178476Sjb	    sizeof (SYMLINK3args), xdr_SYMLINK3res, sizeof (SYMLINK3res)},
337178476Sjb	{write_arginit, NFSPROC3_WRITE, xdr_WRITE3args,
338178476Sjb	    sizeof (WRITE3args), xdr_WRITE3res, sizeof (WRITE3res)},
339178476Sjb	{NULL}
340178476Sjb};
341178476Sjb
342178476Sjbint
343178476Sjbdotest(void)
344178476Sjb{
345178476Sjb	CLIENT *client, *mountclient;
346178476Sjb	AUTH *auth;
347178476Sjb	struct timeval timeout;
348178476Sjb	caddr_t args, res;
349178476Sjb	enum clnt_stat status;
350178476Sjb	rpcproc_t proc;
351178476Sjb	call3_test_t *test;
352178476Sjb	void *argbuf = NULL;
353178476Sjb	void *resbuf = NULL;
354178476Sjb	struct mountres3 mountres3;
355178476Sjb	char *sp;
356178476Sjb	volatile int a = 0;
357178476Sjb
358178476Sjb	while (waiting(&a) == 0)
359178476Sjb		continue;
360178476Sjb
361178476Sjb	timeout.tv_sec = 30;
362178476Sjb	timeout.tv_usec = 0;
363178476Sjb
364178476Sjb	mountclient = clnt_create("localhost", MOUNTPROG, MOUNTVERS3, "tcp");
365178476Sjb	if (mountclient == NULL) {
366178476Sjb		clnt_pcreateerror("clnt_create mount");
367178476Sjb		return (1);
368178476Sjb	}
369178476Sjb	auth = authsys_create_default();
370178476Sjb	mountclient->cl_auth = auth;
371178476Sjb	sp = sharedpath;
372178476Sjb	bzero(&mountres3, sizeof (mountres3));
373178476Sjb	status = clnt_call(mountclient, MOUNTPROC_MNT,
374178476Sjb	    xdr_dirpath, (char *)&sp,
375178476Sjb	    xdr_mountres3, (char *)&mountres3,
376178476Sjb	    timeout);
377178476Sjb	if (status != RPC_SUCCESS) {
378178476Sjb		clnt_perror(mountclient, "mnt");
379178476Sjb		return (1);
380178476Sjb	}
381178476Sjb	if (mountres3.fhs_status != 0) {
382178476Sjb		fprintf(stderr, "MOUNTPROG/MOUNTVERS3 failed %d\n",
383178476Sjb		    mountres3.fhs_status);
384178476Sjb		return (1);
385178476Sjb	}
386178476Sjb	rootfh = &mountres3.mountres3_u.mountinfo.fhandle;
387178476Sjb
388178476Sjb	client = clnt_create("localhost", NFS3_PROGRAM, NFS_V3, "tcp");
389178476Sjb	if (client == NULL) {
390178476Sjb		clnt_pcreateerror("clnt_create");
391178476Sjb		return (1);
392178476Sjb	}
393178476Sjb	client->cl_auth = auth;
394178476Sjb
395178476Sjb	for (test = call3_tests; test->arginit; ++test) {
396178476Sjb		argbuf = realloc(argbuf, test->argsize);
397178476Sjb		resbuf = realloc(resbuf, test->ressize);
398178476Sjb		if ((argbuf == NULL) || (resbuf == NULL)) {
399178476Sjb			perror("realloc() failed");
400178476Sjb			return (1);
401178476Sjb		}
402178476Sjb		(test->arginit)(argbuf);
403178476Sjb		bzero(resbuf, test->ressize);
404178476Sjb		status = clnt_call(client, test->proc,
405178476Sjb		    test->xdrargs, argbuf,
406178476Sjb		    test->xdrres, resbuf,
407178476Sjb		    timeout);
408178476Sjb		if (status != RPC_SUCCESS)
409178476Sjb			clnt_perror(client, "call");
410178476Sjb	}
411178476Sjb
412178476Sjb	status = clnt_call(mountclient, MOUNTPROC_UMNT,
413178476Sjb	    xdr_dirpath, (char *)&sp,
414178476Sjb	    xdr_void, NULL,
415178476Sjb	    timeout);
416178476Sjb	if (status != RPC_SUCCESS)
417178476Sjb		clnt_perror(mountclient, "umnt");
418178476Sjb
419178476Sjb	return (0);
420178476Sjb}
421178476Sjb
422178476Sjb/*ARGSUSED*/
423178476Sjbint
424178476Sjbmain(int argc, char **argv)
425178476Sjb{
426178476Sjb	char shareline[BUFSIZ], unshareline[BUFSIZ];
427178476Sjb	int rc;
428178476Sjb
429178476Sjb	(void) snprintf(sharedpath, sizeof (sharedpath),
430178476Sjb	    "/tmp/nfsv3test.%d", getpid());
431178476Sjb	(void) snprintf(shareline, sizeof (shareline),
432178476Sjb	    "mkdir %s ; share %s", sharedpath, sharedpath);
433178476Sjb	(void) snprintf(unshareline, sizeof (unshareline),
434178476Sjb	    "unshare %s ; rmdir %s", sharedpath, sharedpath);
435178476Sjb
436178476Sjb	(void) system(shareline);
437178476Sjb	rc = dotest();
438178476Sjb	(void) system(unshareline);
439178476Sjb
440178476Sjb	return (rc);
441178476Sjb}
442