2 static char sfs_c_vldSid[] = "@(#)sfs_2_vld.c 2.1 97/10/23";
6 * Copyright (c) 1992-1997,2001 by Standard Performance Evaluation Corporation
8 * Standard Performance Evaluation Corporation (SPEC)
9 * 6585 Merchant Place, Suite 100
12 * This product contains benchmarks acquired from several sources who
13 * understand and agree with SPEC's goal of creating fair and objective
14 * benchmarks to measure computer performance.
16 * This copyright notice is placed here only to protect SPEC in the
17 * event the source is misused in any manner that is contrary to the
18 * spirit, the goals and the intent of SPEC.
20 * The source code is provided to the user or company under the license
21 * agreement for the SPEC Benchmark Suite for this product.
24 /*****************************************************************
26 * Copyright 1991,1992 Legato Systems, Inc. *
27 * Copyright 1991,1992 Auspex Systems, Inc. *
28 * Copyright 1991,1992 Data General Corporation *
29 * Copyright 1991,1992 Digital Equipment Corporation *
30 * Copyright 1991,1992 Interphase Corporation *
31 * Copyright 1991,1992 Sun Microsystems, Inc. *
33 *****************************************************************/
36 * ------------------------------ sfs_c_vld.c ---------------------------
38 * Validation suite for sfs.
41 * void Validate_ops(int, char **)
44 * void validate_init_rpc()
45 * void validate_creation(void)
46 * void validate_attributes(void)
47 * void validate_read_write(void)
48 * void validate_rename(void)
49 * int compare_sattr(char *, char *, sattr *, fattr *)
50 * int compare_fattr(char *, char *, fattr *, fattr *)
51 * uint16_t sum(unsigned char *, uint_t)
52 * void validate_remove(void)
53 * void validate_cleanup(void)
54 * void validate_exit(void)
55 * void verror(int, ValMsgType, char *, ...)
58 * 04-Dec-91 Keith Define string.h for SYSV/SVR4.
59 * 25-Jun-91 Wiryaman Created
64 * ------------------------- Include Files -------------------------
76 #include <sys/types.h>
81 #include "sfs_c_def.h"
83 extern struct hostent *Server_hostent;
86 * ----------------------- External Definitions -----------------------
89 /* forward definitions for local routines */
92 * BATCH - do complete pass of validation, reporting errors if any
93 * VERBOSE - prints step-by-step validation actions being performed
94 * INTERACTIVE - VERBOSE and if any errors encountered, ask to continue
99 #define VAL_INTERACTIVE 3
107 #define NUMREGFILES 7
110 #define NUMSYMLINKS 5
111 #define NUMFILES NUMREGFILES + NUMDIRS + NUMLINKS + NUMSYMLINKS
114 static void validate_init_rpc(void);
115 static void validate_exit(void);
116 static void validate_creation(void);
117 static void validate_attributes(void);
118 static void validate_read_write(void);
119 static void validate_rename(void);
120 static void validate_remove(void);
121 static void validate_cleanup(void);
122 static int compare_sattr(char *, char *, sattr *, fattr *);
123 static int compare_fattr(char *, char *, fattr *, fattr *);
124 static uint16_t sum(unsigned char *, uint_t);
125 static void verror(int, ValMsgType, char *, ...);
127 static void val_op_null(void);
128 static void val_op_getattr(fhandle_t *, attrstat *);
129 static void val_op_setattr(sattrargs *, attrstat *);
130 static void val_op_lookup(diropargs *, diropres *);
131 static void val_op_readlink(fhandle_t *, readlinkres *);
132 static void val_op_read(readargs *, readres *);
133 static void val_op_write(writeargs *, attrstat *);
134 static void val_op_create(createargs *, diropres *);
135 static void val_op_remove(diropargs *, nfsstat *);
136 static void val_op_rename(renameargs *, nfsstat *);
137 static void val_op_link(linkargs *, nfsstat *);
138 static void val_op_symlink(symlinkargs *, nfsstat *);
139 static void val_op_mkdir(mkdirargs *, diropres *);
140 static void val_op_rmdir(diropargs *, nfsstat *);
141 static void val_op_readdir(readdirargs *, readdirres *);
142 static void val_op_statfs(fhandle_t *, statfsres *);
143 static void create_tmp_handles(void);
144 static void delete_tmp_handles(void);
147 * ---------------------- Static Declarations ----------------------
152 static int Validate_errors = 0;
153 static char Testdirname[SFS_MAXPATHLEN]; /* test dir component name */
156 * ---------------------- SFS Validation Suite ----------------------
165 CLIENT * mount_client_ptr;
168 verror(VAL_BATCH, E, "Can only validate one directory at a time.\n");
172 Num_io_files = NUMFILES;
174 nfs_version = NFS_VERSION;
181 (void) sprintf(Testdirname, "%s/validatedir", valdir);
184 verror(VAL_BATCH, I, "validating sfs on \"%s\" directory ...\n",
188 create_tmp_handles();
191 * need priv port to do following
193 mount_client_ptr = lad_getmnt_hand(valdir);
194 if (mount_client_ptr == NULL) {
200 * should be all done doing priv port stuff
202 if (setuid(Real_uid) != 0) {
203 (void) fprintf(stderr,"%s: %s%s\n",
204 sfs_Myname, "cannot perform setuid operation.\n",
205 "Do `make install` as root.\n");
208 init_mount_point(0, valdir, mount_client_ptr);
209 verror(VAL_VERBOSE, I, "validating null operation ...\n");
213 validate_attributes();
214 validate_read_write();
221 * Cleanup mount client handle
223 clnt_destroy(mount_client_ptr);
225 delete_tmp_handles();
236 * allocate and initialize client handles
239 validate_init_rpc(void)
241 NFS_client = lad_clnt_create(Tcp? 1: 0, Server_hostent,
242 (uint32_t) NFS_PROGRAM,
243 (uint32_t) NFS_VERSION,
244 RPC_ANYSOCK, &Nfs_timers[0]);
246 if (NFS_client == ((CLIENT *) NULL)) {
247 verror(VAL_BATCH, E, "portmap/nfsd server not responding\n");
251 NFS_client->cl_auth = authunix_create(lad_hostname, Real_uid,
253 } /* validate_init_rpc */
257 validate_creation(void)
266 char sl_target_path[NFS_MAXPATHLEN];
269 char sym_data[NFS_MAXPATHLEN];
271 for (filenum=0; filenum < NUMFILES ; filenum++) {
273 Cur_file_ptr = &Io_files[filenum];
274 sfs_gettime(&Cur_time);
276 if (filenum < NUMREGFILES) {
278 (void) sprintf(Cur_filename, Filespec, filenum);
280 /* regular file creation */
281 argcr.attributes.mode= (NFSMODE_REG | 0666);
282 argcr.attributes.uid = Cur_uid;
283 argcr.attributes.gid = Cur_gid;
284 argcr.attributes.atime.seconds = (unsigned int) Cur_time.esec;
285 argcr.attributes.atime.useconds = (unsigned int) Cur_time.usec;
286 argcr.attributes.mtime.seconds = (unsigned int) Cur_time.esec;
287 argcr.attributes.mtime.useconds = (unsigned int) Cur_time.usec;
288 argcr.attributes.size = 0;
289 (void) memmove((char *) &argcr.where.dir, (char *) &Export_dir.fh2,
291 argcr.where.name = Cur_filename;
293 verror(VAL_VERBOSE, I, "validating create file %s ...\n",
295 val_op_create(&argcr, &reply);
297 if (reply.status == NFS_OK) {
298 Cur_file_ptr->state = Exists;
299 (void) memmove((char *) &Cur_file_ptr->fh2,
300 (char *) &reply.diropres_u.diropres.file, NFS_FHSIZE);
301 (void) strcpy(Cur_file_ptr->file_name, Cur_filename);
302 (void) memmove((char *) &Cur_file_ptr->attributes2,
303 (char *) &reply.diropres_u.diropres.attributes,
304 sizeof(Cur_file_ptr->attributes2));
305 (void) compare_sattr(Ops[CREATE].name, Io_files[filenum].file_name,
306 &argcr.attributes, &Cur_file_ptr->attributes2);
308 Cur_file_ptr->state = Nonexistent;
309 errno = (int)reply.status;
310 verror(VAL_BATCH, E, "create %s failed: %m\n", Cur_filename);
312 * An error in file creation is fatal, because we use the
313 * created files to validate the other operations.
318 } else if (filenum < NUMREGFILES + NUMDIRS) {
320 (void) sprintf(Cur_filename, Dirspec, filenum);
322 /* directory creation */
323 argmk.attributes.mode= (NFSMODE_DIR | 0777);
324 argmk.attributes.uid = Cur_uid;
325 argmk.attributes.gid = Cur_gid;
326 argmk.attributes.size = 0xFFFFFFFF;
327 argmk.attributes.atime.seconds = (unsigned int) Cur_time.esec;
328 argmk.attributes.atime.useconds = (unsigned int) Cur_time.usec;
329 argmk.attributes.mtime.seconds = (unsigned int) Cur_time.esec;
330 argmk.attributes.mtime.useconds = (unsigned int) Cur_time.usec;
331 (void) memmove((char *) &argmk.where.dir, (char *) &Export_dir.fh2,
333 argmk.where.name = Cur_filename;
335 verror(VAL_VERBOSE, I, "validating mkdir %s ...\n", Cur_filename);
336 val_op_mkdir(&argmk, &reply);
338 if (reply.status == NFS_OK) {
339 Cur_file_ptr->state = Exists;
340 (void) memmove((char *) &Cur_file_ptr->fh2,
341 (char *) &reply.diropres_u.diropres.file,
343 (void) strcpy(Cur_file_ptr->file_name, Cur_filename);
344 (void) memmove((char *) &Cur_file_ptr->attributes2,
345 (char *) &reply.diropres_u.diropres.attributes,
346 sizeof(Cur_file_ptr->attributes2));
347 (void) compare_sattr(Ops[MKDIR].name, Io_files[filenum].file_name,
348 &argmk.attributes, &Cur_file_ptr->attributes2);
350 Cur_file_ptr->state = Nonexistent;
351 verror(VAL_BATCH, W, "mkdir %s failed:%m\n", Cur_filename);
354 } else if(filenum < NUMREGFILES + NUMDIRS + NUMLINKS ) {
356 (void) sprintf(Cur_filename, Filespec, filenum);
358 /* hard link creation */
359 target_filenum = NUMFILES-NUMSYMLINKS-1-filenum;
360 (void) memmove((char *) &argln.from,
361 (char *) &Io_files[target_filenum].fh2, NFS_FHSIZE);
362 (void) memmove((char *) &argln.to.dir, (char *) &Export_dir.fh2,
364 argln.to.name = Cur_filename;
366 verror(VAL_VERBOSE, I, "validating link %s %s ...\n",
367 Io_files[target_filenum].file_name, Cur_filename);
368 val_op_link(&argln, &reply.status);
370 if (reply.status == NFS_OK) {
371 Cur_file_ptr->state = Exists;
372 (void) memmove((char *) &Cur_file_ptr->fh2,
373 (char *) &Io_files[target_filenum].fh2,
375 (void) strcpy(Cur_file_ptr->file_name, Cur_filename);
376 Cur_file_ptr->attributes2 = Io_files[target_filenum].attributes2;
377 Io_files[target_filenum].attributes2.nlink++;
378 Cur_file_ptr->attributes2.nlink++;
380 Cur_file_ptr->state = Nonexistent;
381 verror(VAL_BATCH, W, "link %s failed: %m\n", Cur_filename);
386 (void) sprintf(Cur_filename, Symspec, filenum);
388 /* symbolic link creation */
389 target_filenum = NUMFILES-1-filenum;
390 (void) memmove((char *) &argsl.from.dir, (char *) &Export_dir.fh2,
392 argsl.from.name = Cur_filename;
393 (void) sprintf(sl_target_path,
394 "./%s", Io_files[target_filenum].file_name);
395 argsl.attributes.size = strlen(sl_target_path);
396 argsl.to = sl_target_path;
397 argsl.attributes.mode = (NFSMODE_LNK | 0777);
398 argsl.attributes.uid = Cur_uid;
399 argsl.attributes.gid = Cur_gid;
400 argsl.attributes.atime.seconds = (unsigned int)Cur_time.esec;
401 argsl.attributes.atime.useconds = (unsigned int)Cur_time.usec;
402 argsl.attributes.mtime.seconds = (unsigned int)Cur_time.esec;
403 argsl.attributes.mtime.useconds = (unsigned int)Cur_time.usec;
405 verror(VAL_VERBOSE, I, "validating symlink %s %s ...\n",
406 sl_target_path, Cur_filename);
407 val_op_symlink(&argsl, &reply.status);
409 if (reply.status == NFS_OK) {
410 Cur_file_ptr->state = Exists;
412 /* do a lookup to get file handle and attributes */
413 (void) memmove((char *) &arglp.dir, (char *) &Export_dir.fh2,
415 arglp.name = Cur_filename;
417 val_op_lookup(&arglp, &reply);
419 if (reply.status == NFS_OK) {
420 (void) memmove((char *) &Cur_file_ptr->fh2,
421 (char *) &reply.diropres_u.diropres.file, NFS_FHSIZE);
422 (void) strcpy(Cur_file_ptr->file_name, Cur_filename);
423 Cur_file_ptr->attributes2 =
424 reply.diropres_u.diropres.attributes;
425 (void) compare_sattr(Ops[SYMLINK].name,
426 Io_files[filenum].file_name,
428 &Cur_file_ptr->attributes2);
430 verror(VAL_BATCH, W, "lookup %s failed: %m\n",
435 /* validate readlink */
436 rlreply.readlinkres_u.data = sym_data;
438 verror(VAL_VERBOSE, I, "validating readlink %s ...\n",
440 val_op_readlink(&Cur_file_ptr->fh2, &rlreply);
442 if (rlreply.status == NFS_OK) {
443 sym_data[rlreply.readlinkres_u.len] = '\0';
444 if (strcmp(sl_target_path, sym_data)) {
446 "readlink %s error, result = %s, should be %s\n",
447 Cur_filename, rlreply.readlinkres_u.data,
451 verror(VAL_BATCH, W, "readlink %s failed:%m\n",
456 Cur_file_ptr->state = Nonexistent;
457 verror(VAL_BATCH, W, "symlink %s failed: %m\n",
461 } /* end for each file */
463 } /* validate_creation */
467 validate_attributes(void)
476 /* validate fsstat */
478 /* validate lookup */
479 for (filenum = 0; filenum < NUMFILES; filenum++) {
480 (void) memmove((char *) &arglp.dir, (char *) &Export_dir.fh2,
482 arglp.name = Io_files[filenum].file_name;
484 verror(VAL_VERBOSE, I, "validating lookup %s ...\n",
485 Io_files[filenum].file_name);
486 val_op_lookup(&arglp, &lreply);
488 if (lreply.status == NFS_OK) {
489 if (memcmp((char *) &(Io_files[filenum].fh2),
490 (char *) &(lreply.diropres_u.diropres.file),
492 verror(VAL_BATCH, W, "lookup %s: file handle mismatch\n",
493 Io_files[filenum].file_name);
495 (void) compare_fattr(Ops[LOOKUP].name, Io_files[filenum].file_name,
496 &Io_files[filenum].attributes2,
497 &lreply.diropres_u.diropres.attributes);
499 verror(VAL_BATCH, W, "lookup %s failed:%m\n",
500 Io_files[filenum].file_name);
504 /* validate getattr */
505 for (filenum = 0; filenum < NUMFILES; filenum++) {
506 (void) memmove((char *) &fh, (char *) &Io_files[filenum].fh2,
509 verror(VAL_VERBOSE, I, "validating getattr %s ...\n",
510 Io_files[filenum].file_name);
511 val_op_getattr(&fh, &areply);
513 if (areply.status == NFS_OK) {
514 (void) compare_fattr(Ops[GETATTR].name, Io_files[filenum].file_name,
515 &Io_files[filenum].attributes2,
516 &areply.attrstat_u.attributes);
518 verror(VAL_BATCH, W, "getattr %s failed: %m\n",
519 Io_files[filenum].file_name);
523 /*validate setattr */
524 for (filenum = 0; filenum < NUMFILES; filenum++) {
525 sfs_gettime(&Cur_time);
526 if (filenum >= NUMREGFILES && filenum < NUMREGFILES + NUMDIRS)
527 argsa.attributes.mode= 0777;
529 argsa.attributes.mode= 0666;
530 argsa.attributes.uid = 0xFFFFFFFF;
531 argsa.attributes.gid = 0xFFFFFFFF;
532 argsa.attributes.size = 0xFFFFFFFF;
533 argsa.attributes.atime.seconds = (unsigned int)Cur_time.esec;
534 argsa.attributes.atime.useconds = (unsigned int)Cur_time.usec;
535 argsa.attributes.mtime.seconds = (unsigned int)Cur_time.esec;
536 argsa.attributes.mtime.useconds = (unsigned int)Cur_time.usec;
537 (void) memmove((char *) &argsa.file, (char *) &Io_files[filenum].fh2,
540 verror(VAL_VERBOSE, I, "validating setattr %s ...\n",
541 Io_files[filenum].file_name);
542 val_op_setattr(&argsa, &areply);
544 if (areply.status == NFS_OK) {
545 if (argsa.attributes.mode != areply.attrstat_u.attributes.mode){
546 argsa.attributes.mode |=
547 (Io_files[filenum].attributes2.mode & NFSMODE_FMT);
548 argsa.attributes.mode &= Io_files[filenum].attributes2.mode;
550 Io_files[filenum].attributes2 = areply.attrstat_u.attributes;
551 (void) compare_sattr(Ops[SETATTR].name, Io_files[filenum].file_name,
552 &argsa.attributes, &areply.attrstat_u.attributes);
554 val_op_getattr(&argsa.file, &areply);
556 if (areply.status == NFS_OK) {
557 (void) compare_fattr(Ops[GETATTR].name, Io_files[filenum].file_name,
558 &Io_files[filenum].attributes2,
559 &areply.attrstat_u.attributes);
561 verror(VAL_BATCH, W, "getattr %s failed: %m\n",
562 Io_files[filenum].file_name);
565 verror(VAL_BATCH, W, "setattr %s failed: %m\n",
566 Io_files[filenum].file_name);
570 } /* validate_attributes */
574 validate_read_write(void)
577 uint16_t sum; /* checksum of data */
578 uint16_t len; /* length of len and data */
579 char data[DEFAULT_MAX_BUFSIZE - 2 * sizeof(uint16_t)];
592 readdirres rdirreply;
594 entry entry_stream[9];
595 char name_stream[9 * SFS_MAXNAMLEN];
599 /* get the maximum number of blocks sfs will write */
600 maxblks = Io_dist_ptr->max_bufs;
601 maxfiles = maxblks > NUMREGFILES ? NUMREGFILES : maxblks;
603 /* write maxblks - filenum + 1 blocks to each regular file */
605 argwr.beginoffset = 0; /* unused */
606 argwr.totalcount = 0; /* unused */
607 argwr.data.data_val = (char *)█
609 for (blocknum = 0; blocknum <= maxblks ; blocknum++) {
611 for (i=0; i < sizeof(block.data); i++)
612 block.data[i] = (char)blocknum;
614 for (filenum=0; filenum < maxfiles; filenum++) {
616 /* Write fewer blocks to files with higher numbers. */
617 if (blocknum > (maxblks - filenum))
620 /* set the length field */
621 if (blocknum == (maxblks - filenum)) {
622 block.len = ((maxfiles - filenum) *
623 (Bytes_per_block/Kb_per_block)) - (sizeof(block.len)
624 + sizeof(block.sum));
626 block.len = Bytes_per_block - (sizeof(block.len)
627 + sizeof(block.sum));
629 block.sum = sum((unsigned char *) &block.len,
630 block.len + sizeof(block.len));
632 (void) memmove((char *) &argwr.file,
633 (char *) &Io_files[filenum].fh2, NFS_FHSIZE);
634 argwr.data.data_len = block.len +
635 sizeof(block.len) + sizeof(block.sum);
637 verror(VAL_VERBOSE, I,
638 "validating write %d bytes @ offset %d to %s ...\n",
639 argwr.data.data_len, argwr.offset,
640 Io_files[filenum].file_name);
642 val_op_write(&argwr, &wrreply);
644 if (wrreply.status == NFS_OK) {
645 (void) compare_fattr(Ops[WRITE].name, Io_files[filenum].file_name,
646 &Io_files[filenum].attributes2,
647 &wrreply.attrstat_u.attributes);
648 Io_files[filenum].attributes2 = wrreply.attrstat_u.attributes;
650 verror(VAL_BATCH, W, "write %s failed: %m\n",
651 Io_files[filenum].file_name);
654 argwr.offset += Bytes_per_block;
659 for (filenum = 0; filenum < maxfiles; filenum++) {
660 (void) memmove((char *) &argrd.file, (char *) &Io_files[filenum].fh2,
664 rdreply.readres_u.reply.data.data_len = 0;
665 maxblks = Io_files[filenum].attributes2.size / Bytes_per_block;
666 for (blocknum = 0; blocknum <= maxblks; blocknum ++) {
668 if (argrd.count != rdreply.readres_u.reply.data.data_len) {
669 argrd.count -= rdreply.readres_u.reply.data.data_len;
670 rdreply.readres_u.reply.data.data_val = (char *)&block +
671 rdreply.readres_u.reply.data.data_len;
674 if (blocknum < maxblks)
675 argrd.count = Bytes_per_block;
677 argrd.count = (maxfiles - filenum)
678 * (Bytes_per_block/Kb_per_block);
679 rdreply.readres_u.reply.data.data_val = (char *)█
681 argrd.totalcount = argrd.count; /* unused */
683 verror(VAL_VERBOSE, I,
684 "validating read %d bytes @ offset %d from %s ...\n",
685 argrd.count, argrd.offset,
686 Io_files[filenum].file_name);
688 val_op_read(&argrd, &rdreply);
690 if (rdreply.status == NFS_OK) {
691 (void) compare_fattr(Ops[READ].name, Io_files[filenum].file_name,
692 &Io_files[filenum].attributes2,
693 &rdreply.readres_u.reply.attributes);
694 Io_files[filenum].attributes2 =
695 rdreply.readres_u.reply.attributes;
696 argrd.offset += rdreply.readres_u.reply.data.data_len;
698 verror(VAL_BATCH, W, "read %s failed: %m\n",
699 Io_files[filenum].file_name);
703 (block.sum != sum((unsigned char *) &block.len,
704 block.len + sizeof(block.len)))) {
705 verror(VAL_BATCH, W, "read %s checksum mismatch\n",
706 Io_files[filenum].file_name);
711 /* validate readdir */
714 (void) memmove((char *) &argrdir.dir, (char *) &Export_dir.fh2, NFS_FHSIZE);
715 (void) memset((char *) argrdir.cookie, '\0', NFS_COOKIESIZE);
716 argrdir.count = DEFAULT_MAX_BUFSIZE;
718 (void) memset((char *) &rdirreply, '\0', sizeof(rdirreply));
719 rdirreply.readdirres_u.reply.max_entries = entry_cnt;
720 rdirreply.readdirres_u.reply.entries = entry_stream;
721 for (i = 0; i < entry_cnt; i++) {
722 entry_stream[i].name = &name_stream[i * SFS_MAXNAMLEN];
726 verror(VAL_VERBOSE, I, "validating readdir %d entries of %s ...\n",
727 rdirreply.readdirres_u.reply.max_entries, Testdirname);
728 val_op_readdir(&argrdir, &rdirreply);
730 if (rdirreply.status == NFS_OK) {
731 for (i = 0; i < rdirreply.readdirres_u.reply.max_entries; i++) {
733 entry_stream[i].name[entry_stream[i].name_len] = '\0';
734 if (!entry_stream[i].valid) {
736 "readdir %s error: entry %d (%s) is marked invalid\n",
737 Testdirname, i, entry_stream[i].name);
739 if ((!strcmp(entry_stream[i].name, ".")) ||
740 (!strcmp(entry_stream[i].name, "..")) ) {
744 for (filenum = 0; filenum < NUMFILES; filenum++) {
745 if (!strcmp(entry_stream[i].name, Io_files[filenum].file_name)) {
746 if (entry_stream[i].fileid !=
747 Io_files[filenum].attributes2.fileid) {
749 "readdir %s error: file %s fileid mismatch\n",
750 Testdirname, entry_stream[i].name);
753 " fileid: got = %d, original = %d\n",
754 entry_stream[i].fileid,
755 Io_files[filenum].attributes2.fileid);
760 if (filenum == NUMFILES) {
762 "readdir %s error: file \"%s\" was not created within sfs\n",
763 Testdirname, entry_stream[i].name);
767 if (i < entry_cnt && entry_stream[i].valid) {
769 "readdir %s error: valid entries exceeded maximum\n",
774 verror(VAL_BATCH, W, "readdir %s failed: %m\n", Testdirname);
777 (void) memmove((char *)argrdir.cookie,
778 (char *)entry_stream[rdirreply.readdirres_u.reply.max_entries-1].cookie,
781 } while (rdirreply.readdirres_u.reply.eof == 0);
783 if (numfiles != NUMFILES) {
785 "readdir %s error: the number of files found\n\
786 does not match with the number of files created within sfs\n", Testdirname);
789 } /* validate_read_write */
793 validate_rename(void)
798 char newname[SFS_MAXNAMLEN];
801 (void) memmove((char *) &argrn.from.dir, (char *) &Export_dir.fh2, NFS_FHSIZE);
802 (void) memmove((char *) &argrn.to.dir, (char *) &Export_dir.fh2, NFS_FHSIZE);
804 for (filenum=0; filenum < NUMFILES; filenum++) {
805 if (Io_files[filenum].state != Exists)
809 (void) sprintf(newname, "n%s", Io_files[filenum].file_name);
810 argrn.from.name = Io_files[filenum].file_name;
811 argrn.to.name = newname;
813 verror(VAL_VERBOSE, I, "validating rename %s %s ...\n",
814 argrn.from.name, argrn.to.name);
816 val_op_rename(&argrn, &rnreply);
818 if (rnreply == NFS_OK) {
819 (void) strcpy(Io_files[filenum].file_name, newname);
821 verror(VAL_BATCH, W, "rename %s to %s failed: %m\n",
822 Io_files[filenum].file_name, newname);
828 verror(VAL_BATCH, E, "validate_rename: no files renamed\n");
829 verror(VAL_BATCH, W, " due to previous operation error\n");
832 } /* validate_rename */
843 int prev_warn = FALSE; /* -1 info warning */
844 int flag_error = FALSE;
846 if (attr1->type != attr2->type) {
847 if (attr1->type == 0xFFFFFFFF) {
850 verror(VAL_BATCH, I, "%s: %s attribute mismatch\n",
853 verror(VAL_BATCH, I, " type: current = %d, previous = %d\n",
854 attr2->type, attr1->type);
855 attr1->type = attr2->type;
860 verror(VAL_BATCH, E, "%s: %s attribute mismatch\n",
863 verror(VAL_BATCH, E, " type: current = %d, previous = %d\n",
864 attr2->type, attr1->type);
870 if ((attr1->mode & NFSMODE_MASK) != (attr2->mode & NFSMODE_MASK)) {
871 if (attr1->mode == (unsigned int)0xFFFFFFFF) {
874 verror(VAL_BATCH, I, "%s: %s attribute mismatch\n",
877 verror(VAL_BATCH, I, " mode: current = %7o, previous = %7o\n",
878 attr2->mode, attr1->mode);
879 attr1->mode = attr2->mode;
884 verror(VAL_BATCH, E, "%s: %s attribute mismatch\n",
887 verror(VAL_BATCH, E, " mode: current = %d, previous = %d\n",
888 attr2->mode, attr1->mode);
894 if (attr1->nlink != attr2->nlink) {
895 if (attr1->nlink == (unsigned int)0xFFFFFFFF) {
898 verror(VAL_BATCH, I, "%s: %s attribute mismatch\n",
901 verror(VAL_BATCH, I, " nlink: current = %d, previous = %d\n",
902 attr2->nlink, attr1->nlink);
903 attr1->nlink = attr2->nlink;
908 verror(VAL_BATCH, E, "%s: %s attribute mismatch\n",
911 verror(VAL_BATCH, E, " nlink: current = %d, previous = %d\n",
912 attr2->nlink, attr1->nlink);
920 * Check for user "nobody", UID -2, which may be untranslated from
921 * sixteen-bit two's complement.
923 if (attr1->uid != attr2->uid && !((attr2->uid == (unsigned int)0xFFFFFFFE ||
924 attr2->uid == 65534) && attr1->uid ==0)) {
925 if (attr1->uid == (unsigned int)0xFFFFFFFF) {
928 verror(VAL_BATCH, I, "%s: %s attribute mismatch\n",
931 verror(VAL_BATCH, I, " uid: current = %d, previous = %d\n",
932 attr2->uid, attr1->uid);
933 attr1->uid = attr2->uid;
938 verror(VAL_BATCH, E, "%s: %s attribute mismatch\n",
941 verror(VAL_BATCH, E, " uid: current = %d, previous = %d\n",
942 attr2->uid, attr1->uid);
948 if (attr1->gid != attr2->gid && attr2->gid != 0) {
950 if (attr1->gid != attr2->gid) {
952 if (attr1->gid == (unsigned int)0xFFFFFFFF) {
955 verror(VAL_BATCH, I, "%s: %s attribute mismatch\n",
958 verror(VAL_BATCH, I, " gid: current = %d, previous = %d\n",
959 attr2->gid, attr1->gid);
960 attr1->gid = attr2->gid;
965 verror(VAL_BATCH, E, "%s: %s attribute mismatch\n",
968 verror(VAL_BATCH, E, " gid: current = %d, previous = %d\n",
969 attr2->gid, attr1->gid);
975 if (attr1->size != attr2->size) {
976 if (strcmp(op, Ops[WRITE].name)) {
977 if (attr1->size == (unsigned int)0xFFFFFFFF) {
980 verror(VAL_BATCH, I, "%s: %s attribute mismatch\n",
983 verror(VAL_BATCH, I, " size: current = %d, previous = %d\n",
984 attr2->size, attr1->size);
985 attr1->size = attr2->size;
990 verror(VAL_BATCH, E, "%s: %s attribute mismatch\n",
993 verror(VAL_BATCH, E, " size: current = %d, previous = %d\n",
994 attr2->size, attr1->size);
1001 if (attr1->blocksize != attr2->blocksize) {
1002 if (attr1->blocksize == (unsigned int)0xFFFFFFFF) {
1005 verror(VAL_BATCH, I, "%s: %s attribute mismatch\n",
1008 verror(VAL_BATCH, I, " blocksize: current = %d, previous = %d\n",
1009 attr2->blocksize, attr1->blocksize);
1010 attr1->blocksize = attr2->blocksize;
1015 verror(VAL_BATCH, E, "%s: %s attribute mismatch\n",
1018 verror(VAL_BATCH, E, " blocksize: current = %d, previous = %d\n",
1019 attr2->blocksize, attr1->blocksize);
1026 /* compare rdev only if type == NFCHR or NFBLK */
1027 if ((attr1->type == NFCHR || attr1->type == NFBLK) &&
1028 attr1->rdev != attr2->rdev) {
1029 if (attr1->rdev == (unsigned int)0xFFFFFFFF) {
1032 verror(VAL_BATCH, I, "%s: %s attribute mismatch\n",
1035 verror(VAL_BATCH, I, " rdev: current = %d, previous = %d\n",
1036 attr2->rdev, attr1->rdev);
1037 attr1->rdev = attr2->rdev;
1042 verror(VAL_BATCH, E, "%s: %s attribute mismatch\n",
1045 verror(VAL_BATCH, E, " rdev: current = %d, previous = %d\n",
1046 attr2->rdev, attr1->rdev);
1054 * The NFS specification does not require that the number of blocks
1055 * associated with a file remain constant. Certain file systems
1056 * may pre-allocate more blocks than necessary then trim them
1057 * back ("garbage collect") or even blow holes in files that have
1059 * We must check that we never get back -1.
1061 if (attr1->blocks != attr2->blocks) {
1062 if (strcmp(op, Ops[WRITE].name)) {
1063 if (attr1->blocks == (unsigned int)0xFFFFFFFF) {
1066 verror(VAL_BATCH, I, "%s: %s attribute mismatch\n",
1069 verror(VAL_BATCH, I, " blocks: current = %d, previous = %d\n",
1070 attr2->blocks, attr1->blocks);
1071 attr1->blocks = attr2->blocks;
1078 if (attr1->fsid != attr2->fsid) {
1079 if (attr1->fsid == (unsigned int)0xFFFFFFFF) {
1082 verror(VAL_BATCH, I, "%s: %s attribute mismatch\n",
1085 verror(VAL_BATCH, I, " fsid: current = %d, previous = %d\n",
1086 attr2->fsid, attr1->fsid);
1087 attr1->fsid = attr2->fsid;
1092 verror(VAL_BATCH, E, "%s: %s attribute mismatch\n",
1095 verror(VAL_BATCH, E, " fsid: current = %d, previous = %d\n",
1096 attr2->fsid, attr1->fsid);
1102 if (attr1->fileid != attr2->fileid) {
1103 if (attr1->fileid == (unsigned int)0xFFFFFFFF) {
1106 verror(VAL_BATCH, I, "%s: %s attribute mismatch\n",
1109 verror(VAL_BATCH, I, " fileid: current = %d, previous = %d\n",
1110 attr2->fileid, attr1->fileid);
1111 attr1->fileid = attr2->fileid;
1116 verror(VAL_BATCH, E, "%s: %s attribute mismatch\n",
1119 verror(VAL_BATCH, E, " fileid: current = %d, previous = %d\n",
1120 attr2->fileid, attr1->fileid);
1127 verror(VAL_BATCH, I,
1128 "\n Warning: the previous value of a field is -1,\n");
1129 verror(VAL_BATCH, I,
1130 " this resulted from an unused field returned by\n");
1131 verror(VAL_BATCH, I,
1132 " the previous operation on this file/directory.\n");
1133 verror(VAL_BATCH, I,
1134 " The current value is now stored for future comparison\n\n");
1138 verror(VAL_BATCH, W,"\n");
1142 } /* ckompare_fattr */
1157 if (attr1->mode != (unsigned int)0xFFFFFFFF &&
1158 (attr1->mode & NFSMODE_MASK) != (attr2->mode & NFSMODE_MASK)) {
1160 verror(VAL_BATCH, E, "%s: %s attribute mismatch\n",
1164 verror(VAL_BATCH, E, " mode: returned = %7o, specified = %7o\n",
1165 attr2->mode, attr1->mode);
1170 * Check for user "nobody", UID -2, which may be untranslated from
1171 * sixteen-bit two's complement.
1173 if (attr1->uid != (unsigned int)0xFFFFFFFF && attr1->uid != attr2->uid &&
1174 !((attr2->uid == (unsigned int)0xFFFFFFFE ||
1175 attr2->uid == 65534) &&
1178 verror(VAL_BATCH, E, "%s: %s attribute mismatch\n",
1181 if (attr1->uid == 0)
1182 (void) strcat(msg," (is root UID mapped to other UID?)");
1183 verror(VAL_BATCH, E, " uid: returned = %d, specified = %d %s\n",
1184 attr2->uid, attr1->uid, msg);
1187 if (attr1->gid != (unsigned int)0xFFFFFFFF &&
1188 attr1->gid != attr2->gid &&
1191 if (attr1->gid != 0xFFFFFFFF && attr1->gid != attr2->gid) {
1194 verror(VAL_BATCH, E, "%s: %s attribute mismatch\n",
1197 verror(VAL_BATCH, E, " gid: returned = %d, specified = %d\n",
1198 attr2->gid, attr1->gid);
1202 if (attr1->size != (unsigned int)0xFFFFFFFF &&
1203 attr1->size != attr2->size) {
1205 verror(VAL_BATCH, E, "%s: %s attribute mismatch\n",
1208 verror(VAL_BATCH, E, " size: returned = %d, specified = %d\n",
1209 attr2->size, attr1->size);
1214 verror(VAL_BATCH, W,"\n");
1218 } /* compare_sattr */
1222 * Return the BSD checksum of buf[0..len-1]
1226 unsigned char * buf,
1232 for (; len--; buf++) {
1234 cksum = (cksum >> 1) + 0x8000;
1237 cksum += (uint16_t) *buf;
1245 validate_remove(void)
1253 (void) memmove((char *) &args.dir, (char *) &Export_dir.fh2, NFS_FHSIZE);
1255 for (filenum = 0; filenum < NUMFILES; filenum++) {
1257 if (Io_files[filenum].state != Exists)
1260 args.name = Io_files[filenum].file_name;
1262 if (Io_files[filenum].attributes2.type == NFDIR) {
1263 op = Ops[RMDIR].name;
1264 verror(VAL_VERBOSE, I, "validating rmdir %s ...\n",
1266 val_op_rmdir(&args, &reply);
1268 op = Ops[REMOVE].name;
1269 verror(VAL_VERBOSE, I, "validating remove %s ...\n",
1271 val_op_remove(&args, &reply);
1274 if (reply == NFS_OK) {
1275 /* make sure the file is removed from the directory */
1276 val_op_lookup(&args, &lreply);
1278 if (lreply.status == NFSERR_NOENT) {
1279 Io_files[filenum].state = Nonexistent;
1280 } else if (lreply.status == NFS_OK) {
1281 verror(VAL_BATCH, W, "%s %s: file not removed\n",
1282 op, Io_files[filenum].file_name);
1284 verror(VAL_BATCH, W, "lookup %s failed: %m\n",
1285 Io_files[filenum].file_name);
1289 verror(VAL_BATCH, W, "%s %s failed: %m\n", op,
1290 Io_files[filenum].file_name);
1295 } /* validate_remove */
1299 validate_cleanup(void)
1305 clnt_destroy(NFS_client);
1307 } /* validate_cleanup */
1313 if (!Validate_errors) {
1314 verror(VAL_BATCH, I, "validation completed successfully.\n");
1317 verror(VAL_BATCH, I, "validation terminated with errors\n");
1321 } /* validate_exit */
1342 * Expand the "%m" format character into the descriptive string
1343 * for the current value of errno. Printf handles the other "%"
1344 * formatting characters.
1346 if (Validate >= opt) {
1347 for (fp = fmt; *fp; fp++) {
1348 if (*fp == '%' && fp[1] == 'm') {
1349 if ((sp = strerror(errno)) == NULL) {
1350 (void) sprintf(bp, "unknown error %d", errno);
1352 (void) strcpy(bp, sp);
1354 bp = buf + strlen(buf);
1361 (void) vprintf(buf, ap);
1368 if (msgtype == W && Validate == VAL_INTERACTIVE) {
1373 (void) fprintf(stderr, "continue? (y or n) ");
1374 if (!fgets(ans,80,stdin)) {
1375 (void) fprintf(stderr, "\n");
1378 if (ans[0] == 'n' || ans[0] == 'N') {
1381 } else if (ans[0] == 'y' || ans[0] == 'Y') {
1398 rpc_stat = clnt_call(NFS_client, NFSPROC_NULL,
1399 xdr_void, (char *)0, xdr_void, (char *)0,
1400 Nfs_timers[Ops[NULLCALL].call_class]);
1401 if (rpc_stat == RPC_SUCCESS)
1403 if (rpc_stat != RPC_TIMEDOUT) {
1404 clnt_perror(NFS_client, "null");
1412 val_op_getattr(fhandle_t *args, attrstat *reply)
1418 rpc_stat = clnt_call(NFS_client, NFSPROC_GETATTR,
1419 xdr_getattr, (char *)args, xdr_getattr, (char *)reply,
1420 Nfs_timers[Ops[GETATTR].call_class]);
1421 if (rpc_stat == RPC_SUCCESS)
1423 if (rpc_stat != RPC_TIMEDOUT) {
1424 clnt_perror(NFS_client, "getattr");
1432 val_op_setattr(sattrargs *args, attrstat *reply)
1438 rpc_stat = clnt_call(NFS_client, NFSPROC_SETATTR,
1439 xdr_setattr, (char *)args, xdr_setattr, (char *)reply,
1440 Nfs_timers[Ops[SETATTR].call_class]);
1441 if (rpc_stat == RPC_SUCCESS)
1443 if (rpc_stat != RPC_TIMEDOUT) {
1444 clnt_perror(NFS_client, "setattr");
1452 val_op_lookup(diropargs *args, diropres *reply)
1458 rpc_stat = clnt_call(NFS_client, NFSPROC_LOOKUP,
1459 xdr_lookup, (char *)args, xdr_lookup, (char *)reply,
1460 Nfs_timers[Ops[LOOKUP].call_class]);
1461 if (rpc_stat == RPC_SUCCESS)
1463 if (rpc_stat != RPC_TIMEDOUT) {
1464 clnt_perror(NFS_client, "lookup");
1472 val_op_readlink(fhandle_t *args, readlinkres *reply)
1478 rpc_stat = clnt_call(NFS_client, NFSPROC_READLINK,
1479 xdr_readlink, (char *)args, xdr_readlink, (char *)reply,
1480 Nfs_timers[Ops[READLINK].call_class]);
1481 if (rpc_stat == RPC_SUCCESS)
1483 if (rpc_stat != RPC_TIMEDOUT) {
1484 clnt_perror(NFS_client, "readlink");
1492 val_op_read(readargs *args, readres *reply)
1498 rpc_stat = clnt_call(NFS_client, NFSPROC_READ,
1499 xdr_read, (char *)args, xdr_read, (char *)reply,
1500 Nfs_timers[Ops[READ].call_class]);
1501 if (rpc_stat == RPC_SUCCESS)
1503 if (rpc_stat != RPC_TIMEDOUT) {
1504 clnt_perror(NFS_client, "read");
1512 val_op_write(writeargs *args, attrstat *reply)
1518 rpc_stat = clnt_call(NFS_client,
1519 NFSPROC_WRITE, xdr_write, (char *)args, xdr_write, (char *)reply,
1520 Nfs_timers[Ops[WRITE].call_class]);
1522 if (rpc_stat == RPC_SUCCESS)
1524 if (rpc_stat != RPC_TIMEDOUT) {
1525 clnt_perror(NFS_client, "write");
1533 val_op_create(createargs *args, diropres *reply)
1539 rpc_stat = clnt_call(NFS_client,
1540 NFSPROC_CREATE, xdr_create, (char *)args, xdr_create, (char *)reply,
1541 Nfs_timers[Ops[CREATE].call_class]);
1542 if (rpc_stat == RPC_SUCCESS)
1544 if (rpc_stat != RPC_TIMEDOUT) {
1545 clnt_perror(NFS_client, "create");
1553 val_op_remove(diropargs *args, nfsstat *reply)
1559 rpc_stat = clnt_call(NFS_client,
1560 NFSPROC_REMOVE, xdr_remove, (char *)args, xdr_remove, (char *)reply,
1561 Nfs_timers[Ops[REMOVE].call_class]);
1562 if (rpc_stat == RPC_SUCCESS)
1564 if (rpc_stat != RPC_TIMEDOUT) {
1565 clnt_perror(NFS_client, "remove");
1573 val_op_rename(renameargs *args, nfsstat *reply)
1579 rpc_stat = clnt_call(NFS_client, NFSPROC_RENAME,
1580 xdr_rename, (char *)args, xdr_rename, (char *)reply,
1581 Nfs_timers[Ops[RENAME].call_class]);
1582 if (rpc_stat == RPC_SUCCESS)
1584 if (rpc_stat != RPC_TIMEDOUT) {
1585 clnt_perror(NFS_client, "rename");
1593 val_op_link(linkargs *args, nfsstat *reply)
1599 rpc_stat = clnt_call(NFS_client, NFSPROC_LINK,
1600 xdr_link, (char *)args, xdr_link, (char *)reply,
1601 Nfs_timers[Ops[LINK].call_class]);
1602 if (rpc_stat == RPC_SUCCESS)
1604 if (rpc_stat != RPC_TIMEDOUT) {
1605 clnt_perror(NFS_client, "link");
1613 val_op_symlink(symlinkargs *args, nfsstat *reply)
1619 rpc_stat = clnt_call(NFS_client, NFSPROC_SYMLINK,
1620 xdr_symlink, (char *)args, xdr_symlink, (char *)reply,
1621 Nfs_timers[Ops[SYMLINK].call_class]);
1622 if (rpc_stat == RPC_SUCCESS)
1624 if (rpc_stat != RPC_TIMEDOUT) {
1625 clnt_perror(NFS_client, "symlink");
1633 val_op_mkdir(mkdirargs *args, diropres *reply)
1639 rpc_stat = clnt_call(NFS_client, NFSPROC_MKDIR,
1640 xdr_mkdir, (char *)args, xdr_mkdir, (char *)reply,
1641 Nfs_timers[Ops[MKDIR].call_class]);
1642 if (rpc_stat == RPC_SUCCESS)
1644 if (rpc_stat != RPC_TIMEDOUT) {
1645 clnt_perror(NFS_client, "mkdir");
1653 val_op_rmdir(diropargs *args, nfsstat *reply)
1659 rpc_stat = clnt_call(NFS_client, NFSPROC_RMDIR,
1660 xdr_rmdir, (char *)args, xdr_rmdir, (char *)reply,
1661 Nfs_timers[Ops[RMDIR].call_class]);
1662 if (rpc_stat == RPC_SUCCESS)
1664 if (rpc_stat != RPC_TIMEDOUT) {
1665 clnt_perror(NFS_client, "rmdir");
1673 val_op_readdir(readdirargs *args, readdirres *reply)
1679 rpc_stat = clnt_call(NFS_client, NFSPROC_READDIR,
1680 xdr_readdir, (char *)args, xdr_readdir, (char *)reply,
1681 Nfs_timers[Ops[READDIR].call_class]);
1682 if (rpc_stat == RPC_SUCCESS)
1684 if (rpc_stat != RPC_TIMEDOUT) {
1685 clnt_perror(NFS_client, "readdir");
1693 val_op_statfs(fhandle_t *args, statfsres *reply)
1699 rpc_stat = clnt_call(NFS_client, NFSPROC_STATFS,
1700 xdr_statfs, (char *)args, xdr_statfs, (char *)reply,
1701 Nfs_timers[Ops[FSSTAT].call_class]);
1702 if (rpc_stat == RPC_SUCCESS)
1704 if (rpc_stat != RPC_TIMEDOUT) {
1705 clnt_perror(NFS_client, "statfs");
1712 create_tmp_handles(void)
1715 for (filenum = 0; filenum < NUMFILES; filenum++) {
1717 if(Io_files[filenum].fh_data == (sfs_fh_data *)0)
1719 Io_files[filenum].fh_data =
1720 calloc(1,sizeof(sfs_fh_data));
1721 Io_files[filenum].attributes2.type = NFNON;
1722 Io_files[filenum].attributes3.type = NF3NON;
1728 delete_tmp_handles()
1731 for (filenum = 0; filenum < NUMFILES; filenum++) {
1733 if(Io_files[filenum].fh_data != (sfs_fh_data *)0)
1735 free(Io_files[filenum].fh_data);
1736 Io_files[filenum].fh_data=(sfs_fh_data *)0;