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