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