Home | History | Annotate | Download | only in nfs
      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 (the "License").
      6  * You may not use this file except in compliance with the License.
      7  *
      8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
      9  * or http://www.opensolaris.org/os/licensing.
     10  * See the License for the specific language governing permissions
     11  * and limitations under the License.
     12  *
     13  * When distributing Covered Code, include this CDDL HEADER in each
     14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     15  * If applicable, add the following below this CDDL HEADER, with the
     16  * fields enclosed by brackets "[]" replaced with your own identifying
     17  * information: Portions Copyright [yyyy] [name of copyright owner]
     18  *
     19  * CDDL HEADER END
     20  */
     21 
     22 /*
     23  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
     24  * Use is subject to license terms.
     25  */
     26 
     27 #pragma ident	"%Z%%M%	%I%	%E% SMI"
     28 
     29 #include <strings.h>
     30 #include <rpc/rpc.h>
     31 #include <stdlib.h>
     32 #include <sys/param.h>
     33 #include <rpcsvc/mount.h>
     34 
     35 #include "rpcsvc/nfs_prot.h"
     36 
     37 char sharedpath[MAXPATHLEN];
     38 fhandle3 *rootfh;
     39 
     40 /*
     41  * The waiting() function returns the value passed in, until something
     42  * external modifies it.  In this case, the D script tst.call.d will
     43  * modify the value of *a, and thus break the while loop in dotest().
     44  *
     45  * This serves the purpose of not making the RPC calls until tst.call.d
     46  * is active.  Thus, the probes in tst.call.d can fire as a result of
     47  * the RPC call in dotest().
     48  */
     49 
     50 int
     51 waiting(volatile int *a)
     52 {
     53 	return (*a);
     54 }
     55 
     56 static void
     57 getattr_arginit(void *argp)
     58 {
     59 	GETATTR3args *args = argp;
     60 
     61 	args->object.data.data_len = rootfh->fhandle3_len;
     62 	args->object.data.data_val = rootfh->fhandle3_val;
     63 }
     64 
     65 static void
     66 setattr_arginit(void *argp)
     67 {
     68 	SETATTR3args *args = argp;
     69 
     70 	bzero(args, sizeof (*args));
     71 	args->object.data.data_len = rootfh->fhandle3_len;
     72 	args->object.data.data_val = rootfh->fhandle3_val;
     73 }
     74 
     75 static void
     76 lookup_arginit(void *argp)
     77 {
     78 	LOOKUP3args *args = argp;
     79 
     80 	args->what.name = "giant-skunk";
     81 	args->what.dir.data.data_len = rootfh->fhandle3_len;
     82 	args->what.dir.data.data_val = rootfh->fhandle3_val;
     83 }
     84 
     85 static void
     86 access_arginit(void *argp)
     87 {
     88 	ACCESS3args *args = argp;
     89 
     90 	args->object.data.data_len = rootfh->fhandle3_len;
     91 	args->object.data.data_val = rootfh->fhandle3_val;
     92 }
     93 
     94 static void
     95 commit_arginit(void *argp)
     96 {
     97 	COMMIT3args *args = argp;
     98 
     99 	bzero(args, sizeof (*args));
    100 	args->file.data.data_len = rootfh->fhandle3_len;
    101 	args->file.data.data_val = rootfh->fhandle3_val;
    102 }
    103 
    104 static void
    105 create_arginit(void *argp)
    106 {
    107 	CREATE3args *args = argp;
    108 
    109 	bzero(args, sizeof (*args));
    110 	args->where.name = "pinky-blue";
    111 	args->where.dir.data.data_len = rootfh->fhandle3_len;
    112 	args->where.dir.data.data_val = rootfh->fhandle3_val;
    113 }
    114 
    115 static void
    116 fsinfo_arginit(void *argp)
    117 {
    118 	FSINFO3args *args = argp;
    119 
    120 	args->fsroot.data.data_len = rootfh->fhandle3_len;
    121 	args->fsroot.data.data_val = rootfh->fhandle3_val;
    122 }
    123 
    124 static void
    125 fsstat_arginit(void *argp)
    126 {
    127 	FSSTAT3args *args = argp;
    128 
    129 	args->fsroot.data.data_len = rootfh->fhandle3_len;
    130 	args->fsroot.data.data_val = rootfh->fhandle3_val;
    131 }
    132 
    133 static void
    134 link_arginit(void *argp)
    135 {
    136 	LINK3args *args = argp;
    137 
    138 	args->file.data.data_len = rootfh->fhandle3_len;
    139 	args->file.data.data_val = rootfh->fhandle3_val;
    140 	args->link.dir.data.data_len = rootfh->fhandle3_len;
    141 	args->link.dir.data.data_val = rootfh->fhandle3_val;
    142 	args->link.name = "samf";
    143 }
    144 
    145 static void
    146 mkdir_arginit(void *argp)
    147 {
    148 	MKDIR3args *args = argp;
    149 
    150 	bzero(args, sizeof (*args));
    151 	args->where.dir.data.data_len = rootfh->fhandle3_len;
    152 	args->where.dir.data.data_val = rootfh->fhandle3_val;
    153 	args->where.name = "cookie";
    154 }
    155 
    156 static void
    157 mknod_arginit(void *argp)
    158 {
    159 	MKNOD3args *args = argp;
    160 
    161 	bzero(args, sizeof (*args));
    162 	args->where.dir.data.data_len = rootfh->fhandle3_len;
    163 	args->where.dir.data.data_val = rootfh->fhandle3_val;
    164 	args->where.name = "pookie";
    165 }
    166 
    167 static void
    168 null_arginit(void *argp)
    169 {
    170 }
    171 
    172 static void
    173 pathconf_arginit(void *argp)
    174 {
    175 	PATHCONF3args *args = argp;
    176 
    177 	args->object.data.data_len = rootfh->fhandle3_len;
    178 	args->object.data.data_val = rootfh->fhandle3_val;
    179 }
    180 
    181 static void
    182 read_arginit(void *argp)
    183 {
    184 	READ3args *args = argp;
    185 
    186 	bzero(args, sizeof (*args));
    187 	args->file.data.data_len = rootfh->fhandle3_len;
    188 	args->file.data.data_val = rootfh->fhandle3_val;
    189 }
    190 
    191 static void
    192 readdir_arginit(void *argp)
    193 {
    194 	READDIR3args *args = argp;
    195 
    196 	bzero(args, sizeof (*args));
    197 	args->dir.data.data_len = rootfh->fhandle3_len;
    198 	args->dir.data.data_val = rootfh->fhandle3_val;
    199 	args->count = 1024;
    200 }
    201 
    202 static void
    203 readdirplus_arginit(void *argp)
    204 {
    205 	READDIRPLUS3args *args = argp;
    206 
    207 	bzero(args, sizeof (*args));
    208 	args->dir.data.data_len = rootfh->fhandle3_len;
    209 	args->dir.data.data_val = rootfh->fhandle3_val;
    210 	args->dircount = 1024;
    211 	args->maxcount = 1024;
    212 }
    213 
    214 static void
    215 readlink_arginit(void *argp)
    216 {
    217 	READLINK3args *args = argp;
    218 
    219 	args->symlink.data.data_len = rootfh->fhandle3_len;
    220 	args->symlink.data.data_val = rootfh->fhandle3_val;
    221 }
    222 
    223 static void
    224 remove_arginit(void *argp)
    225 {
    226 	REMOVE3args *args = argp;
    227 
    228 	args->object.dir.data.data_len = rootfh->fhandle3_len;
    229 	args->object.dir.data.data_val = rootfh->fhandle3_val;
    230 	args->object.name = "antelope";
    231 }
    232 
    233 static void
    234 rename_arginit(void *argp)
    235 {
    236 	RENAME3args *args = argp;
    237 
    238 	args->from.dir.data.data_len = rootfh->fhandle3_len;
    239 	args->from.dir.data.data_val = rootfh->fhandle3_val;
    240 	args->from.name = "walter";
    241 	args->to.dir.data.data_len = rootfh->fhandle3_len;
    242 	args->to.dir.data.data_val = rootfh->fhandle3_val;
    243 	args->to.name = "wendy";
    244 }
    245 
    246 static void
    247 rmdir_arginit(void *argp)
    248 {
    249 	RMDIR3args *args = argp;
    250 
    251 	args->object.dir.data.data_len = rootfh->fhandle3_len;
    252 	args->object.dir.data.data_val = rootfh->fhandle3_val;
    253 	args->object.name = "bunny";
    254 }
    255 
    256 static void
    257 symlink_arginit(void *argp)
    258 {
    259 	SYMLINK3args *args = argp;
    260 
    261 	bzero(args, sizeof (*args));
    262 	args->where.dir.data.data_len = rootfh->fhandle3_len;
    263 	args->where.dir.data.data_val = rootfh->fhandle3_val;
    264 	args->where.name = "parlor";
    265 	args->symlink.symlink_data = "interior";
    266 }
    267 
    268 static void
    269 write_arginit(void *argp)
    270 {
    271 	WRITE3args *args = argp;
    272 
    273 	bzero(args, sizeof (*args));
    274 	args->file.data.data_len = rootfh->fhandle3_len;
    275 	args->file.data.data_val = rootfh->fhandle3_val;
    276 }
    277 
    278 typedef void (*call3_arginit_t)(void *);
    279 
    280 typedef struct {
    281 	call3_arginit_t arginit;
    282 	rpcproc_t proc;
    283 	xdrproc_t xdrargs;
    284 	size_t argsize;
    285 	xdrproc_t xdrres;
    286 	size_t ressize;
    287 } call3_test_t;
    288 call3_test_t call3_tests[] = {
    289 	{getattr_arginit, NFSPROC3_GETATTR, xdr_GETATTR3args,
    290 	    sizeof (GETATTR3args), xdr_GETATTR3res, sizeof (GETATTR3res)},
    291 	{setattr_arginit, NFSPROC3_SETATTR, xdr_SETATTR3args,
    292 	    sizeof (SETATTR3args), xdr_SETATTR3res, sizeof (SETATTR3res)},
    293 	{lookup_arginit, NFSPROC3_LOOKUP, xdr_LOOKUP3args,
    294 	    sizeof (LOOKUP3args), xdr_LOOKUP3res, sizeof (LOOKUP3res)},
    295 	{access_arginit, NFSPROC3_ACCESS, xdr_ACCESS3args,
    296 	    sizeof (ACCESS3args), xdr_ACCESS3res, sizeof (ACCESS3res)},
    297 	{commit_arginit, NFSPROC3_COMMIT, xdr_COMMIT3args,
    298 	    sizeof (COMMIT3args), xdr_COMMIT3res, sizeof (COMMIT3res)},
    299 	{create_arginit, NFSPROC3_CREATE, xdr_CREATE3args,
    300 	    sizeof (CREATE3args), xdr_CREATE3res, sizeof (CREATE3res)},
    301 	{fsinfo_arginit, NFSPROC3_FSINFO, xdr_FSINFO3args,
    302 	    sizeof (FSINFO3args), xdr_FSINFO3res, sizeof (FSINFO3res)},
    303 	{fsstat_arginit, NFSPROC3_FSSTAT, xdr_FSSTAT3args,
    304 	    sizeof (FSSTAT3args), xdr_FSSTAT3res, sizeof (FSSTAT3res)},
    305 	{link_arginit, NFSPROC3_LINK, xdr_LINK3args,
    306 	    sizeof (LINK3args), xdr_LINK3res, sizeof (LINK3res)},
    307 	{mkdir_arginit, NFSPROC3_MKDIR, xdr_MKDIR3args,
    308 	    sizeof (MKDIR3args), xdr_MKDIR3res, sizeof (MKDIR3res)},
    309 	{mknod_arginit, NFSPROC3_MKNOD, xdr_MKNOD3args,
    310 	    sizeof (MKNOD3args), xdr_MKNOD3res, sizeof (MKNOD3res)},
    311 	/*
    312 	 * NULL proc is special.  Rather than special case its zero-sized
    313 	 * args/results, we give it a small nonzero size, so as to not
    314 	 * make realloc() do the wrong thing.
    315 	 */
    316 	{null_arginit, NFSPROC3_NULL, xdr_void, sizeof (int), xdr_void,
    317 	    sizeof (int)},
    318 	{pathconf_arginit, NFSPROC3_PATHCONF, xdr_PATHCONF3args,
    319 	    sizeof (PATHCONF3args), xdr_PATHCONF3res, sizeof (PATHCONF3res)},
    320 	{read_arginit, NFSPROC3_READ, xdr_READ3args,
    321 	    sizeof (READ3args), xdr_READ3res, sizeof (READ3res)},
    322 	{readdir_arginit, NFSPROC3_READDIR, xdr_READDIR3args,
    323 	    sizeof (READDIR3args), xdr_READDIR3res, sizeof (READDIR3res)},
    324 	{readdirplus_arginit, NFSPROC3_READDIRPLUS, xdr_READDIRPLUS3args,
    325 	    sizeof (READDIRPLUS3args), xdr_READDIRPLUS3res,
    326 	    sizeof (READDIRPLUS3res)},
    327 	{readlink_arginit, NFSPROC3_READLINK, xdr_READLINK3args,
    328 	    sizeof (READLINK3args), xdr_READLINK3res, sizeof (READLINK3res)},
    329 	{remove_arginit, NFSPROC3_REMOVE, xdr_REMOVE3args,
    330 	    sizeof (REMOVE3args), xdr_REMOVE3res, sizeof (REMOVE3res)},
    331 	{rename_arginit, NFSPROC3_RENAME, xdr_RENAME3args,
    332 	    sizeof (RENAME3args), xdr_RENAME3res, sizeof (RENAME3res)},
    333 	{rmdir_arginit, NFSPROC3_RMDIR, xdr_RMDIR3args,
    334 	    sizeof (RMDIR3args), xdr_RMDIR3res, sizeof (RMDIR3res)},
    335 	{symlink_arginit, NFSPROC3_SYMLINK, xdr_SYMLINK3args,
    336 	    sizeof (SYMLINK3args), xdr_SYMLINK3res, sizeof (SYMLINK3res)},
    337 	{write_arginit, NFSPROC3_WRITE, xdr_WRITE3args,
    338 	    sizeof (WRITE3args), xdr_WRITE3res, sizeof (WRITE3res)},
    339 	{NULL}
    340 };
    341 
    342 int
    343 dotest(void)
    344 {
    345 	CLIENT *client, *mountclient;
    346 	AUTH *auth;
    347 	struct timeval timeout;
    348 	caddr_t args, res;
    349 	enum clnt_stat status;
    350 	rpcproc_t proc;
    351 	call3_test_t *test;
    352 	void *argbuf = NULL;
    353 	void *resbuf = NULL;
    354 	struct mountres3 mountres3;
    355 	char *sp;
    356 	volatile int a = 0;
    357 
    358 	while (waiting(&a) == 0)
    359 		continue;
    360 
    361 	timeout.tv_sec = 30;
    362 	timeout.tv_usec = 0;
    363 
    364 	mountclient = clnt_create("localhost", MOUNTPROG, MOUNTVERS3, "tcp");
    365 	if (mountclient == NULL) {
    366 		clnt_pcreateerror("clnt_create mount");
    367 		return (1);
    368 	}
    369 	auth = authsys_create_default();
    370 	mountclient->cl_auth = auth;
    371 	sp = sharedpath;
    372 	bzero(&mountres3, sizeof (mountres3));
    373 	status = clnt_call(mountclient, MOUNTPROC_MNT,
    374 	    xdr_dirpath, (char *)&sp,
    375 	    xdr_mountres3, (char *)&mountres3,
    376 	    timeout);
    377 	if (status != RPC_SUCCESS) {
    378 		clnt_perror(mountclient, "mnt");
    379 		return (1);
    380 	}
    381 	if (mountres3.fhs_status != 0) {
    382 		fprintf(stderr, "MOUNTPROG/MOUNTVERS3 failed %d\n",
    383 		    mountres3.fhs_status);
    384 		return (1);
    385 	}
    386 	rootfh = &mountres3.mountres3_u.mountinfo.fhandle;
    387 
    388 	client = clnt_create("localhost", NFS3_PROGRAM, NFS_V3, "tcp");
    389 	if (client == NULL) {
    390 		clnt_pcreateerror("clnt_create");
    391 		return (1);
    392 	}
    393 	client->cl_auth = auth;
    394 
    395 	for (test = call3_tests; test->arginit; ++test) {
    396 		argbuf = realloc(argbuf, test->argsize);
    397 		resbuf = realloc(resbuf, test->ressize);
    398 		if ((argbuf == NULL) || (resbuf == NULL)) {
    399 			perror("realloc() failed");
    400 			return (1);
    401 		}
    402 		(test->arginit)(argbuf);
    403 		bzero(resbuf, test->ressize);
    404 		status = clnt_call(client, test->proc,
    405 		    test->xdrargs, argbuf,
    406 		    test->xdrres, resbuf,
    407 		    timeout);
    408 		if (status != RPC_SUCCESS)
    409 			clnt_perror(client, "call");
    410 	}
    411 
    412 	status = clnt_call(mountclient, MOUNTPROC_UMNT,
    413 	    xdr_dirpath, (char *)&sp,
    414 	    xdr_void, NULL,
    415 	    timeout);
    416 	if (status != RPC_SUCCESS)
    417 		clnt_perror(mountclient, "umnt");
    418 
    419 	return (0);
    420 }
    421 
    422 /*ARGSUSED*/
    423 int
    424 main(int argc, char **argv)
    425 {
    426 	char shareline[BUFSIZ], unshareline[BUFSIZ];
    427 	int rc;
    428 
    429 	(void) snprintf(sharedpath, sizeof (sharedpath),
    430 	    "/tmp/nfsv3test.%d", getpid());
    431 	(void) snprintf(shareline, sizeof (shareline),
    432 	    "mkdir %s ; share %s", sharedpath, sharedpath);
    433 	(void) snprintf(unshareline, sizeof (unshareline),
    434 	    "unshare %s ; rmdir %s", sharedpath, sharedpath);
    435 
    436 	(void) system(shareline);
    437 	rc = dotest();
    438 	(void) system(unshareline);
    439 
    440 	return (rc);
    441 }
    442