1 #
2 #
3 # CDDL HEADER START
4 #
5 # The contents of this file are subject to the terms of the
6 # Common Development and Distribution License (the "License").
7 # You may not use this file except in compliance with the License.
8 #
9 # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 # or http://www.opensolaris.org/os/licensing.
11 # See the License for the specific language governing permissions
12 # and limitations under the License.
13 #
14 # When distributing Covered Code, include this CDDL HEADER in each
15 # file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 # If applicable, add the following below this CDDL HEADER, with the
17 # fields enclosed by brackets "[]" replaced with your own identifying
18 # information: Portions Copyright [yyyy] [name of copyright owner]
19 #
20 # CDDL HEADER END
21 #
22
23 #
24 # Copyright 2009 Sun Microsystems, Inc. All rights reserved.
25 # Use is subject to license terms.
26 #
27 # ident "@(#)fs_common.ksh 1.4 09/03/09 SMI"
28 #
29
30 . ${TET_SUITE_ROOT}/lofi-tests/lib/util_common
31
32 LOFIADM="/usr/sbin/lofiadm"
33 LS=/usr/bin/ls
34 MKFILE=/usr/sbin/mkfile
35 MKISOFS=/usr/bin/mkisofs
36 RM=/usr/bin/rm
37 TMPDIR=/tmp
38 NEWFS=/usr/sbin/newfs
39 FSTYP=/usr/sbin/fstyp
40 ZPOOL=/usr/sbin/zpool
41
42 #
43 # Minimum and maximum sizes of files that will be created to populate
44 # reference tree.
45 #
46 MIN_ADJ_FILE_SIZE=0
47 MAX_ADJ_FILE_SIZE=65536
48
49 DEFAULT_FILE_SIZE="10M"
50 LOFI_DEV_NUM_LIMIT=128
51
52 #
53 # NAME
54 # make_and_verify_file
55 #
56 # SYNOPSIS
57 # make_and_verify_file <file size> <full pathname>
58 #
59 # DESCRIPTION
60 # Use mkfile(1M) to create a file with the specified size and name.
61 # If the mkfile returns good status, use ls to verify the existence
62 # of the file.
63 #
64 # RETURN VALUES
65 # 0 File created and verified
66 # 1 File creation or verification failed
67 #
68 function make_and_verify_file {
69 typeset size="$1"
70 typeset filename="$2"
71 typeset cmd
72
73 # If the specified file already exists, delete it.
74 if [[ -f "$filename" ]]; then
75 $RM -f $filename
76 if (( $? != 0 )); then
77 cti_unresolved "Error: File '$filename' already" \
78 "exists and this process can't delete it."
79 return 1
80 fi
81 fi
82
83 # Build the command to create the file. Any size parameter that
84 # starts with a zero (excluding leading whitespace) we interpret as
85 # being zero (this is so that we'll catch 0, 0k, 0m, 0G, etc.).
86 echo $size | sed 's/^[ \t]*//' | grep "^0" >/dev/null
87 if (( $? == 0 )); then
88 # Use 'touch' to create zero-length file.
89 cmd="/usr/bin/touch $filename"
90 else
91 # Use 'mkfile' to create file.
92 cmd="$MKFILE $size $filename"
93 fi
94
95 # Create the file
96 record_cmd_execution "$cmd"
97 cti_execute "UNRESOLVED" "$cmd"
98 if (( $? != 0 )); then
99 cti_report "Error: Unable to create file via '$cmd'"
100 return 1
101 fi
102
103 # Verify that the file exists
104 cmd="ls $filename"
105 record_cmd_execution "$cmd"
106 cti_execute "UNRESOLVED" "$cmd"
107 if (( $? != 0 )); then
108 cti_report "Error: '$cmd' returned good status but an 'ls'" \
109 "of the file fails"
110 return 1
111 fi
112
113 if [[ -n "$VERBOSE" ]]; then
114 cti_report "File $filename of size $size successfully created"
115 fi
116
117 return 0
118 }
119
120
121 #
122 # NAME
123 # cleanup_lofi_files
124 #
125 # SYNOPSIS
126 # cleanup_lofi_files
127 #
128 # DESCRIPTION
129 # Find all lofi files (assuming they were created using the predefined
130 # lofi files names) and delete them.
131 #
132 # RETURN VALUES
133 # 0 All lofi files delete or no lofi files found.
134 # 1 Unable to delete one or more lofi files.
135 #
136 function cleanup_lofi_files {
137 typeset lofi_file_list=`$LS $SCRATCH_DIR | grep lofi_file_`
138 typeset retval=0
139 typeset cmd lofi_file
140
141 if [[ -z "$lofi_file_list" ]]; then
142 # No files to delete
143 return 0
144 fi
145
146 for lofi_file in $lofi_file_list
147 do
148 cmd="$RM $SCRATCH_DIR/$lofi_file"
149 record_cmd_execution "$cmd"
150 cti_execute "UNRESOLVED" "$cmd"
151 if (( $? != 0 )); then
152 retval=1
153 fi
154 done
155
156 return $retval
157 }
158
159
160 #
161 # NAME
162 # associate_lofidev_and_file
163 #
164 # SYNOPSIS
165 # associate_lofidev_and_file <type> <name>
166 #
167 # DESCRIPTION
168 # For a given file name determine the associated lofi device, or
169 # vice versa. The calling function identifies the type of name it's
170 # passing in and the name itself. This function determines the name
171 # of the associated item and prints it to standard out so it can be
172 # captured by the caller.
173 #
174 # RETURN VALUES
175 # 0 Found a 1-to-1 match between the lofi device and a file
176 # 1 lofiadm command failed or produced no output
177 # 2 lofi device listed more than once, associated with multiple
178 # files (shouldn't happen)
179 # 3 lofi device not listed, associated with no files
180 function associate_lofidev_and_file {
181 typeset type="$1"
182 typeset name="$2"
183 typeset retval=0
184 typeset cmd match_list line
185
186 # Execute 'lofiadm' command without any arguments, which should
187 # output the current lofi setup. Not knowing if we're being called
188 # for a positive or negative test case, we'll pass a status value
189 # of "PASS" to cti_execute() to prevent it from setting the tet status
190 # to something negative on failure. The calling function will be the
191 # one to set the tet status.
192 cmd="$LOFIADM"
193 record_cmd_execution "$cmd"
194 cti_execute "PASS" "$cmd"
195 if (( $? != 0 )); then
196 return 1
197 fi
198
199 # Make sure the output isn't null (shouldn't ever be, as lofiadm
200 # should still print out column headers even when no lofiadm
201 # devices are configured).
202 if [[ ! -s cti_stdout ]]; then
203 cti_report "'lofiadm' command returned good status but" \
204 "printed nothing to stdout"
205 return 1
206 fi
207
208 # Walk through every line in the file, looking for ones in which
209 # the lofi block device name (first column) matches the device name
210 # provided to us by the calling function.
211 { while read line; do
212 if [[ -n "$line" ]]; then
213 set $line
214 if [[ "$type" = "lofi_dev" ]]; then
215 # Match on lofi device name (first column)
216 if [[ "$1" = "$name" ]]; then
217 # Capture matching file
218 match_list="$match_list $2"
219 fi
220 else
221 # Match on file name (second column)
222 if [[ "$2" = "$name" ]]; then
223 # Capture matching lofi dev
224 match_list="$match_list $1"
225 fi
226 fi
227 fi
228 done } < cti_stdout
229
230 # Did we find a match?
231 if [[ -n "$match_list" ]]; then
232 set $match_list
233 if (( $# > 1 )); then
234 if [[ "$type" = "lofi_dev" ]]; then
235 cti_report "Error: 'lofiadm' command showed" \
236 "more than one file associated with" \
237 "device ${name}: $match_list"
238 else
239 cti_report "Error: 'lofiadm' command showed" \
240 "more than one lofi dev associated with" \
241 "file ${name}: $match_list"
242 fi
243 retval=2
244 fi
245 else
246 # Didn't find an entry for the specified lofi device. Don't
247 # print a failure as this might have been expected.
248 retval=3
249 fi
250
251 # Output the list of files we generated so it can be captured by
252 # the calling function, stripping off any leading whitespace.
253 echo $match_list | sed 's/^ //'
254
255 return $retval
256 }
257
258
259 #
260 # NAME
261 # add_lofi_device
262 #
263 # SYNOPSIS
264 # add_lofi_device <file> <optional lofi dev>
265 #
266 # DESCRIPTION
267 # Execute the 'lofiadm -a' command to create a lofi device based on
268 # the specified file (the file must already exist). In addition to
269 # checking the return code from 'lofiadm -a', the function performs
270 # additional checks to be sure the command behaved as expected.
271 #
272 # RETURN VALUES
273 # 0 lofi device successfully created and verified.
274 # 1 creation of lofi device failed.
275 # 2 creation of lofi device returned good status but additional
276 # verification failed.
277 # In addition to return codes, if no lofi device name was specified,
278 # the name of the lofi device chosen by 'lofiadm -a' will be echoed
279 # so that it can be captured by the calling function.
280 #
281 function add_lofi_device {
282 typeset file="$1"
283 typeset desired_lofi_dev="$2"
284 typeset desired_lofi_dev lofi_dev cmd_retval line dev_match_count
285 typeset file_match_count dev_match cmd
286 typeset retval=0
287
288 # Build the lofiadm command
289 typeset cmd="$LOFIADM -a $file $desired_lofi_dev"
290
291 # Execute lofiadm command. Note: We don't know if the lofiadm -a
292 # command is expected to pass or fail as we could be called by a
293 # negative test case. For that reason, we pass in a "PASS" status to
294 # cti_execute so that it won't set a failing TET status if the
295 # command doesn't succeed.
296 record_cmd_execution "$cmd"
297 cti_execute "PASS" "$cmd"
298 cmd_retval=$?
299
300 # 'lofiadm -a' failed. Nothing else for us to do.
301 if (( $cmd_retval != 0 )); then
302 cti_reportfile cti_stderr
303 return 1
304 fi
305
306 # Retrieve whatever lofiadm printed to stdout
307 typeset lofi_dev_returned="`cat cti_stdout`"
308
309 if [[ -n "$desired_lofi_dev" ]]; then
310 lofi_dev="$desired_lofi_dev"
311 # We specified a particular lofi device, in which case
312 # lofiadm should not have printed anything to stdout.
313 if [[ -n "$lofi_dev_returned" ]]; then
314 cti_report "Err: 'lofiadm -a' cmd should not print" \
315 "to stdout when the lofi dev is specified"
316 cti_report "The following was printed to stdout:" \
317 "$lofi_returned_dev"
318 retval=2
319 fi
320 else
321 lofi_dev="$lofi_dev_returned"
322 # We did not specify a particular lofi device, so lofiadm
323 # should have printed the name of the lofi device it created
324 # to stdout.
325 if [[ -n "$lofi_dev_returned" ]]; then
326 set $lofi_dev_returned
327 if (( $# > 1 )); then
328 retval=2
329 fi
330 else
331 cti_report "Error: $LOFIADM -a succeeded but did" \
332 "not provide a lofi device name"
333 retval=2
334 fi
335 fi
336
337 # Verify that 'lofiadm' shows the correct block device and file
338 # for the just created lofi dev.
339 lofi_dev_reported_back=`associate_lofidev_and_file file $file`
340 if (( $? != 0 )); then
341 cti_report "'lofiadm -a' command returned good status but" \
342 "'lofiadm' output shows irregularities."
343 retval=2
344 else
345 if [[ "$lofi_dev_reported_back" = "$lofi_dev" ]]; then
346 if [[ -n "$VERBOSE" ]]; then
347 cti_report "'lofiadm' shows file '$file'" \
348 "associated with device $lofi_dev as" \
349 "expected"
350 fi
351 else
352 cti_report "Error: File $file should be associated" \
353 "with lofi device $desired_lofi_dev but 'lofiadm'" \
354 "shows it associated with $lofi_dev_reported_back"
355 retval=2
356 fi
357 fi
358
359 if (( $retval != 0 )); then
360 cti_report "Output of 'lofiadm -a' follows:"
361 cti_reportfile cti_stdout
362 fi
363
364 # If a lofi devname was output by the lofiadm command, echo it so
365 # it can be captured by the function that called us.
366 if [[ -n "$lofi_dev_returned" ]]; then
367 echo $lofi_dev_returned
368 fi
369
370 return $retval
371 }
372
373
374 #
375 # NAME
376 # del_lofi_device
377 #
378 # SYNOPSIS
379 # del_lofi_device <lofi dev or filename>
380 #
381 # DESCRIPTION
382 # Delete a lofiadm device based on the provided lofi device name or
383 # file name.
384 #
385 # RETURN VALUES
386 # 0 Delete completed successfully
387 # 1 Delete or verification of delete was unsuccessful
388 #
389 function del_lofi_device {
390 typeset lofi_dev_or_file="$1"
391 typeset cmd
392
393 cmd="$LOFIADM -d $lofi_dev_or_file"
394 record_cmd_execution "$cmd"
395
396 cti_execute "FAIL" "$cmd"
397 if (( $? != 0 )); then
398 return 1
399 fi
400
401 return 0
402 }
403
404
405 #
406 # NAME
407 # del_lofi_dev_and_file
408 #
409 # SYNOPSIS
410 # del_lofi_dev_and_file <filename>
411 #
412 # DESCRIPTION
413 # Since most test cases will have to delete both the lofi device they
414 # created and the file associated with that device, this function
415 # exists to allow them to do both with a single function call.
416 #
417 # RETURN VALUES
418 # 0 Deletion of both lofi device and file was successful
419 # 1 Deletion of lofi device and/or file was unsuccessful
420 #
421 function del_lofi_dev_and_file {
422 typeset filename=$1
423 typeset retval=0
424 typeset cmd
425
426 # Delete the lofi device
427 del_lofi_device $filename
428 if (( $? != 0 )); then
429 retval=1
430 fi
431
432 # Delete the file
433 cmd="$RM $filename"
434 record_cmd_execution "$cmd"
435 cti_execute "FAIL" "$cmd"
436 if (( $? != 0 )); then
437 retval=1
438 fi
439
440 return $retval
441 }
442
443
444 #
445 # NAME
446 # get_supported_compression_types
447 #
448 # SYNOPSIS
449 # get_supported_compression_types
450 #
451 # DESCRIPTION:
452 # Determine which compression types are supported by lofi on the
453 # system the test suite is being run on.
454 #
455 # RETURN VALUES
456 # No value is returned. The names of the supported compression
457 # algorithms (if any) are printed to stdout do they can be captured
458 # by the calling function.
459 #
460 function get_supported_compression_types {
461
462 #
463 # Get usage message for lofiadm and extract the line containing
464 # compression info, if it's there. If no compression info is found,
465 # we're running on an OS version that doesn't support lofi compression.
466 #
467 typeset compression_info=`$LOFIADM -h 2>&1 | grep "lofiadm -C"`
468 if [[ -n $compression_info ]]; then
469 #
470 # Found line containing compression info. Parse it to extract
471 # the supported compression types.
472 #
473 comp_list=`print $compression_info | \
474 sed -e 's/^lofiadm -C *//' | sed -e 's/\] .*//' | \
475 sed -e 's/\[//' | sed -e 's/|/ /g'`
476
477 #
478 # Depending on the OS version, the usage message will contain
479 # one of the following descriptions of compression algorithms:
480 # -C [algorithm]
481 # or
482 # -C [<algorithm1>|<algorithm2>|...|<algorithmN>]
483 # The former is the style used by the initial compression
484 # support putback into Solaris and you just have to know that
485 # the supported types are 'gzip', 'gzip6', and 'gzip9'. The
486 # latter is the style for subsequent additions of compression
487 # algorithms and specifically identifies which algorithms are
488 # supported.
489 #
490 if [[ $comp_list == 'algorithm' ]]; then
491 print "gzip gzip-6 gzip-9"
492 else
493 print $comp_list
494 fi
495 fi
496 }
497
498
499 #
500 # NAME
501 # is_compression_type_supported
502 #
503 # DESCRIPTION
504 # Determine if the desired compression type is supported by lofi on the
505 # system the test suite is running on.
506 #
507 # SYNOPSIS
508 # is_compression_type_supported <desired compression type>
509 #
510 # RETURN VALUES
511 # 0 Desired compression type is supported
512 # 1 Desired compression type is not supported
513 # 2 No lofi compression supported on system
514 #
515 function is_compression_type_supported {
516 typeset desired_compression_type="$1"
517 typeset supported_compression_types=`get_supported_compression_types`
518
519 if [[ ! -n $supported_compression_types ]]; then
520 # lofi compression not supported at all on this system
521 return 2
522 fi
523
524 #
525 # Compression is supported, so check if the desired compression type
526 # is one of the supported ones.
527 #
528 for comp_type in $supported_compression_types
529 do
530 if [[ $desired_compression_type = $comp_type ]]; then
531 # Desired compression type is supported
532 return 0
533 fi
534 done
535
536 # Desired compression type is not supported
537 return 1
538 }
539
540
541 #
542 # NAME
543 # create_ufs
544 #
545 # SYNOPSIS
546 # create_ufs -f <file> -l <lofi device>
547 #
548 # DESCRIPTION:
549 #
550 # Create a ufs filesystem. The <file> argument passed in is
551 # first lofi mounted and then a ufs is created on the lofi
552 # mounted device. The <lofi_device> specifies a particular
553 # lofi device name to use.
554 #
555 # RETURN VALUES
556 # 0 ufs filesystem successfully created
557 # 1 ufs filesystem not successfully created
558 #
559 function create_ufs {
560
561 typeset file_name_arg lofi_dev option
562
563 while getopts f:l:z: option
564 do
565 case $option in
566 f) file_name_arg="$OPTARG";;
567 l) lofi_dev="$OPTARG";;
568 esac
569 done
570
571 # Build 'raw' lofi device name based on block name
572 raw_lofi_dev=`echo $lofi_dev | sed 's/\/lofi/\/rlofi/'`
573
574 # Create ufs filesystem on the specified device
575 cmd="$NEWFS $raw_lofi_dev"
576 record_cmd_execution "$cmd"
577 cti_execute "UNRESOLVED" "$cmd"
578 if (( $? != 0 )); then
579 cti_report "unable to create ufs on lofi device" \
580 "$lofi_device_arg."
581 return 1
582 fi
583
584 if [[ -n "$VERBOSE" ]]; then
585 cti_report "Creation of ufs on lofi device $lofi_device_arg" \
586 "succeeded."
587 fi
588
589 # The newfs command returned successfully, so check to make
590 # sure that a ufs filesystem has been created on the lofi
591 # device.
592 cmd="$FSTYP $raw_lofi_dev"
593 record_cmd_execution "$cmd"
594 fstype=`$cmd`
595 if (( $? != 0 )); then
596 cti_report "ufs does not appear to be correctly associated" \
597 "with lofi device lofi device $lofi_device_arg."
598 cti_unresolved
599 return 1
600 fi
601
602 return 0
603
604 }
605
606
607 #
608 # NAME
609 # create_zfs <file>
610 #
611 # SYNOPSIS
612 # create_zfs -f <file> -z <zpool name> -l <lofi device>
613 #
614 # DESCRIPTION:
615 #
616 # Create a lofi device using the specified file and then place a
617 # zfs filesystem on it.
618 #
619 # RETURN VALUES
620 # 0 zfs filesystem successfully created
621 # 1 zfs filesystem not successfully created
622 #
623 function create_zfs {
624
625 typeset file_name_arg lofi_dev zpool_name option
626
627 while getopts f:l:z: option
628 do
629 case $option in
630 f) file_name_arg="$OPTARG";;
631 l) lofi_dev="$OPTARG";;
632 z) zpool_name="$OPTARG";;
633 esac
634 done
635
636 typeset lofi_device_returned fstype
637 typeset retval=0
638 typeset add_status=0
639
640 # Now that a file has been successfully mounted as a lofi device,
641 # create a zfs filesystem on it.
642 cmd="$ZPOOL create $zpool_name $lofi_dev"
643 record_cmd_execution "$cmd"
644 cti_execute "UNRESOLVED" "$cmd"
645 if (( $? != 0 )); then
646 cti_report "Unable to create a zpool using lofi device" \
647 "$lofi_dev."
648 return 1
649 fi
650
651 if [[ -n "$VERBOSE" ]]; then
652 cti_report "Creation of zpool using lofi device" \
653 "$lofi_device_arg succeeded."
654 fi
655
656 # The following checks to see if zpool status is returned.
657 cmd="$ZPOOL status"
658 record_cmd_execution "$cmd"
659 cti_execute "UNRESOLVED" "$cmd"
660 if (( $? != 0 )); then
661 cti_report "Check of zpool $zpool_name failed."
662 cleanup_lofi_zfs -z $zpool_name -l $file_name_arg
663 return 1
664 fi
665
666
667 # The zpool command returned successfully, so check to make
668 # sure that a zfs filesystem has been created on the lofi
669 # device.
670 cmd="$FSTYP $lofi_dev"
671 record_cmd_execution "$cmd"
672 fstype=`$cmd`
673 if (( $? != 0 )) || [[ $fstype != "zfs" ]]; then
674 cti_report "zfs does not appear to be correctly associated"\
675 "lofi device $lofi_device_arg."
676 cti_unresolved
677 cleanup_lofi_zfs -z $zpool_name -l $file_name_arg
678 return 1
679 fi
680
681 return 0
682 }
683
684
685 #
686 # NAME
687 # cleanup_lofi_zfs
688 #
689 # SYNOPSIS
690 # cleanup_lofi_zfs -z <zpool name> -l <lofi device or file name>
691 #
692 # RETURN VALUES
693 # 0 zfs filesystem and lofi device successfully deleted
694 # 1 zfs filesystem or lofi device could not be deleted
695 #
696 function cleanup_lofi_zfs {
697
698 typeset lofi_dev_or_file zpool_name
699
700 while getopts l:z: option
701 do
702 case $option in
703 l) lofi_dev_or_file="$OPTARG";;
704 z) zpool_name="$OPTARG";;
705 esac
706 done
707
708 cmd="$ZPOOL destroy $zpool_name"
709 record_cmd_execution "$cmd"
710 cti_execute "UNRESOLVED" "$cmd"
711 if (( $? != 0 )); then
712 cti_report "Unable to remove zpool '$zpool_arg'"
713 return 1
714 fi
715
716 if [[ -n "$VERBOSE" ]]; then
717 cti_report "zpool '$zpool_arg' removed"
718 fi
719
720 del_lofi_device $lofi_dev_or_file
721 if (( $? != 0 )); then
722 cti_report "Deleting the lofi device associated with" \
723 "$lofi_dev_or_file failed."
724 return 2
725 fi
726
727 if [[ -n "$VERBOSE" ]]; then
728 cti_report "lofi device associated with '$lofi_dev_or_file'" \
729 "deleted"
730 fi
731
732 return 0
733 }
734
735
736 #
737 # NAME
738 # import_zfs
739 #
740 # SYNOPSIS
741 # import_zfs <path to device> <zpool name>
742 #
743 # DESCRIPTION
744 # Import the specified zpool.
745 #
746 # RETURN VALUE
747 # 0 ZFS filesystem successfully imported
748 # 1 Unable to import ZFS filesystem
749 #
750 function import_zfs {
751 typeset path_to_dev="$1"
752 typeset zpool_name="$2"
753
754 typeset dir=`dirname $1`
755 typeset cmd="zpool import -d $dir $zpool_name"
756 record_cmd_execution "$cmd"
757
758 cti_execute "FAIL" "$cmd"
759 if (( $? != 0 )); then
760 return 1
761 fi
762
763 if [[ -n "$VERBOSE" ]]; then
764 cti_report "zpool '$zpool_name' associated with" \
765 "'$path_to_dev' imported"
766 fi
767
768 return 0
769 }
770
771
772 #
773 # NAME
774 # build_reference_tree
775 #
776 # SYNOPSIS
777 # build_reference_tree <directory>
778 #
779 # DESCRIPTION
780 # Build a hierarchy of directories and files, covering a variety of
781 # permission values and sizes. The expectation is that the resulting
782 # tree will copied to a filesystem, and that the contents of that
783 # filesystem can be compared back against this tree for validation.
784 #
785 # RETURN VALUES
786 # 0 - reference tree built successfully
787 # 1 - errors encountered, reference tree not created or not complete
788 function build_reference_tree {
789 typeset ref_dir="$1"
790 typeset owner=0;
791 typeset group=0;
792 typeset other=0;
793
794 typeset def_other=4
795 typeset def_group=4
796 typeset def_owner=4
797 typeset def_misc=0
798
799 # Delete previous version if one exists
800 if [[ -d "$ref_dir" ]]; then
801 cti_report "$ref_dir exists; deleting to create fresh version"
802 $RM -rf $ref_dir
803 if (( $? != 0 )); then
804 cti_report "Unable to delete existing $ref_dir"
805 return 1
806 fi
807 fi
808
809 # Create top-level directory
810 cti_execute "FAIL" "mkdir -p $ref_dir"
811 if (( $? != 0 )); then
812 cti_report "Unable to make directory $ref_dir"
813 return 1
814 fi
815
816 typeset counter=0
817 typeset size=$MIN_ADJ_FILE_SIZE
818 typeset size_inc
819 let size_inc=$MAX_ADJ_FILE_SIZE/10
820 typeset perm_type bits cur_dir
821
822 # The 'for' and nested 'while' loop create a subdirectory for each
823 # type of file permissions ('other', 'group', 'owner', and 'misc'),
824 # then for each combination of permissions bits for that type (0-7)
825 # creates a file and sets the permissions. The sizes of the files
826 # created is varied.
827 for perm_type in other group owner misc
828 do
829 # Create subdirectory for the permissions type
830 cur_dir=$ref_dir/$perm_type
831 cti_execute "FAIL" "mkdir $cur_dir"
832 if (( $? != 0 )); then
833 cti_report "Error: Unable to make directory $cur_dir"
834 return 1
835 fi
836
837 # For each set of permissions bits for this type, create the
838 # file and set the permissions.
839 bits=0
840 while (( $bits <= 7 )); do
841 # Build the set of permissions that the file to be
842 # created will have.
843 if [[ $perm_type = "other" ]]; then
844 perms=$def_misc$def_owner$def_group$bits
845 elif [[ $perm_type = "group" ]]; then
846 perms=$def_misc$def_owner$bits$def_other
847 elif [[ $perm_type = "owner" ]]; then
848 perms=$def_misc$bits$def_group$def_other
849 else
850 perms=$bits$def_owner$def_group$def_other
851 fi
852
853 # 'mkfile' won't create files with a size of zero, so
854 # depending on the size of this file we'll use 'touch'
855 # (zero length file) or 'mkfile' (non zero length) to
856 # perform the file creation.
857 if (( $size == 0 )); then
858 cti_execute "FAIL" "touch $cur_dir/f$perms"
859 else
860 cti_execute "FAIL" \
861 "mkfile $size $cur_dir/f$perms"
862 fi
863
864 if (( $? != 0 )); then
865 cti_report "Error: Unable to create file" \
866 "$cur_dir/f$perms"
867 return 1
868 fi
869
870 # Set permissions on the file.
871 cti_execute "FAIL" "chmod $perms $cur_dir/f$perms"
872 if (( $? != 0 )); then
873 cti_report "Error: Unable to set permissions" \
874 "for file $cur_dir/f$perms"
875 return 1
876 fi
877
878 # Increment the 'bits' used to set the permissions
879 # so that the next file will have a different value
880 # than this one.
881 let bits=$bits+1
882
883 # Increase the size for the next file, wrapping around
884 # back to zero if the size exceeds the maximum allowed.
885 let size=$size+$size_inc
886 if (( $size > $MAX_ADJ_FILE_SIZE )); then
887 size=$MIN_ADJ_FILE_SIZE
888 fi
889 done
890 done
891
892 if [[ -n "$VERBOSE" ]]; then
893 cti_report "Reference tree created at '$ref_dir'"
894 fi
895
896 return 0
897 }
898
899
900 #
901 # NAME
902 # create_isofs
903 #
904 # SYNOPSIS
905 # create_isofs <filename> <source directory>
906 #
907 # DESCRIPTION
908 # Create file <filename> as an iso image of <directory> using
909 # mkisofs(8) and then do some basic santity testing of the
910 # command output.
911 #
912 # RETURN VALUE
913 # 0 - Creation returned good status and output to stderr seems sane
914 # 1 - Creation returned non-zero status
915 # 2 - Creation returned good status but output to stderr doesn't seem
916 # right
917 #
918 function create_isofs {
919 typeset file="$1"
920 typeset src_dir="$2"
921
922 # Build and execute mkisofs command
923 typeset cmd="$MKISOFS -o $file $src_dir"
924 record_cmd_execution "$cmd"
925 cti_execute FAIL "$cmd"
926 if (( $? != 0 )); then
927 cti_report "Creation of iso image unsuccessful"
928
929 # Delete iso image file if it was created.
930 if [[ -f "$file" ]]; then
931 $RM -rf $file 2>/dev/null
932 fi
933 return 1
934 fi
935
936 # mkisofs should print various bits of information to stderr when
937 # it succeeds. First make sure output was written to stderr...
938 if [[ ! -s cti_stderr ]]; then
939 cti_report "Cmd '$cmd' returned good status but did not" \
940 "print anything to stderr (which it's expected to)"
941 return 2
942 fi
943
944 # ...then make sure the output looks sane by looking for the string
945 # 'extents written' which should have been printed on the last line.
946 grep "extents written" cti_stderr >/dev/null
947 if (( $? != 0 )); then
948 cti_report "Cmd 'cmd' returned good status but did not find" \
949 "information about extents written in stderr as expected"
950 return 2
951 fi
952
953 if [[ -n "$VERBOSE" ]]; then
954 cti_report "Creation of iso fs ($cmd) succeeded"
955 fi
956
957 return 0
958 }
959
960
961 #
962 # NAME
963 # validate_file
964 #
965 # SYNOPSIS
966 # validate_file <src_path> <dest_path> <file_basename> <fs_type>
967 #
968 # DESCRIPTION
969 # Arguments:
970 # src_path - Path to the directory in the original set of dirs/files
971 # containing the dir/file that was copied to the destination.
972 # dest_path - Path to the directory in the destination/copy that
973 # contains the dir/file.
974 # file_basename - 'basename' of the file/dir being validated.
975 # fs_type - The filesystem type of the destination/copy (e.g.
976 # ufs, zfs, iso.
977 #
978 # RETURN VALUES
979 # 0 - All validation checks of the dir/file passed
980 # 1 - One or more validation checks of the dir/file failed
981 #
982 function validate_file {
983 typeset src_path="$1"
984 typeset dest_path="$2"
985 typeset file_basename="$3"
986 typeset fs_type="$4"
987
988 typeset retval=0
989
990 src_listing=`ls -l $src_path | grep "$file_basename\$"`
991 dest_listing=`ls -l $dest_path | grep "$file_basename\$"`
992
993 if [[ -z "$src_listing" ]]; then
994 cti_report "Error: 'ls' doesn't show $file_basename in" \
995 "$src_path"
996 return 1
997 fi
998
999 if [[ -n "$dest_listing" ]]; then
1000 dest_file=$dest_path/$file_basename
1001 else
1002 # Didn't find a matching file in the destination. If the
1003 # destination is an hsfs filesystem, this could be because a
1004 # '.' was appended to the filename when the iso image was
1005 # created.
1006 if [[ $fs_type = "hsfs" ]]; then
1007 typeset alt_dest_basename="${file_basename}."
1008 dest_listing=`ls -l $dest_path | grep "$alt_dest_basename\$"`
1009 if [[ -z "$dest_listing" ]]; then
1010 cti_report "Error: 'ls' doesn't show" \
1011 "$file_basename $alt_dest_basename in" \
1012 "$dest_path"
1013 retval=1
1014 fi
1015 dest_file=$dest_path/$alt_dest_basename
1016 else
1017 cti_report "Error: 'ls' doesn't show $file_basename" \
1018 "in $dest_path"
1019 retval=1
1020 fi
1021 fi
1022
1023 # Make sure we found a corresponding file in the destination.
1024 if (( $retval != 0 )); then
1025 cti_report "Error: Unable to find file corresponding to" \
1026 "$src_path in $dest_path"
1027 return 1
1028 fi
1029
1030 # Determine the expected permissions for the file and what the
1031 # actual permissions are.
1032 if [[ $fs_type = "hsfs" ]]; then
1033 # HSFS filesystems are read only, with permissions set to
1034 # '-r-xr-xr-x' for all files and 'dr-xr-xr-x' for all
1035 # directories.
1036 if [[ -d $dest_file ]]; then
1037 exp_perms="dr-xr-xr-x"
1038 else
1039 exp_perms="-r-xr-xr-x"
1040 fi
1041 else
1042 # For other filesystem types, we expect the file permissions
1043 # to be the same as they were in the source.
1044 typeset exp_perms=`echo $src_listing | awk ' { print $1 } ' `
1045 fi
1046 typeset dest_perms=`echo $dest_listing | awk ' { print $1 } ' `
1047
1048 if [[ "$exp_perms" != "$dest_perms" ]]; then
1049 cti_report "Error: Expected $dest_file to have permissions" \
1050 "'$exp_perms' but found '$dest_perms' instead"
1051 retval=1
1052 fi
1053
1054 # Verify file size is correct (n/a for directories)
1055 if [[ ! -d $dest_file ]]; then
1056 typeset src_size=`echo $src_listing | awk ' { print $5 } ' `
1057 typeset dest_size=`echo $dest_listing | awk ' { print $5 } ' `
1058
1059 if [[ "$src_size" != "$dest_size" ]]; then
1060 cti_report "Error: Sizes of files" \
1061 "$src_path/$file_basename ($src_size) and" \
1062 "$dest_file ($dest_size) do not match"
1063 cti_report "$src_listing"
1064 cti_report "$dest_listing"
1065 retval=1
1066 fi
1067 fi
1068
1069 return $retval
1070 }
1071
1072
1073 #
1074 # NAME
1075 # validate_test_fs
1076 #
1077 # SYNOPSIS
1078 # validate_test_fs <mount point> <src dir> <fs type>
1079 #
1080 # DESCRIPTION
1081 #
1082 # RETURN CODES
1083 # 0 Comparison of FS against source dir found no problems
1084 # 1 Contents of FS and source dir don't match or trouble accessing
1085 # FS.
1086 #
1087 function validate_test_fs {
1088 typeset fs_mnt_point="$1"
1089 typeset src_dir="$2"
1090 typeset fs_type="$3"
1091 typeset start_dir=`pwd`
1092 typeset status=0
1093
1094 # Make sure the fs is mounted
1095 cti_execute "PASS" "df -k $fs_mnt_point"
1096 if (( $? != 0 )); then
1097 cti_report "Specified $fs_type fs '$fs_mnt_point' does not" \
1098 "appear to be mounted"
1099 return 1
1100 fi
1101
1102 cd $src_dir
1103 typeset src_file_list=$TMPDIR/src_file_list_$$
1104 find . -print > $src_file_list
1105 cd $start_dir
1106
1107 typeset mod_src src_path dest_path file_basename
1108 { while read src_filename; do
1109 # Strip the leading "./" off the filename
1110 mod_src_filename=`echo $src_filename | sed 's/^\.\///'`
1111 src_path=`dirname $src_dir/$mod_src_filename`
1112 dest_path=`dirname $fs_mnt_point/$mod_src_filename`
1113 file_basename=`basename $src_dir/$mod_src_filename`
1114 if [[ "$file_basename" = "." ]]; then
1115 continue
1116 fi
1117 validate_file $src_path $dest_path $file_basename $fs_type
1118 if (( $? != 0 )); then
1119 status=1
1120 fi
1121 done } < $src_file_list
1122
1123 if [[ -n "$VERBOSE" ]] && (( $status == 0 )); then
1124 cti_report "Comparision of '$fs_mnt_point' against" \
1125 "'$src_dir' shows no errors (fs type '$fs_type')"
1126 fi
1127
1128 # Clean up
1129 $RM -f $src_file_list 2>/dev/null
1130
1131 return 0
1132 }
1133
1134
1135 #
1136 # NAME
1137 # lofi_and_fs_tidy_up
1138 #
1139 # SYNOPSIS
1140 # lofi_and_fs_tidy_up [ -f lofi file ] \
1141 # [ -m hsfs or ufs mnt point ] [ -s status ] [ -z zfs pool name ]
1142 #
1143 # DESCRIPTION
1144 # Tidy up after execution of a typical lofi test purpose, where there
1145 # is a single filesystem associated with a single lofi device and a
1146 # single file. The caller tells this function about the filesystem and
1147 # lofi device that were configured. This function tears down that
1148 # configuration.
1149 #
1150 # RETURN VALUE
1151 # 0 Tidying-up was successful.
1152 # 1 Problems encountered while tidying-up.
1153 #
1154 function lofi_and_fs_tidy_up {
1155 typeset lofi_file hufs_mnt_point zpool_name delete_file
1156
1157 # Process arguments
1158 typeset option
1159 while getopts df:m:z: option
1160 do
1161 case $option in
1162 d) delete_file="yes";;
1163 f) lofi_file="$OPTARG";;
1164 m) hufs_mnt_point="$OPTARG";;
1165 z) zpool_name="$OPTARG";;
1166 esac
1167 done
1168
1169 # Clean up ZFS config
1170 if [[ -n "$zpool_name" ]]; then
1171 status=1
1172 errmsg='device is busy'
1173 until [ $status == 0 ]; do
1174 cmd="zpool export $zpool_name"
1175 record_cmd_execution "$cmd"
1176 $cmd 2>/tmp/err
1177 if (( $? != 0)); then
1178 # if this is busy signal then we want to retry
1179 if [ "`grep "$errmsg" /tmp/err`" != "" ]; then
1180 cti_report "zpool '$zpool_name' not cleaned up;" \
1181 "can't delete lofi device based on file" \
1182 "'$lofi_file'"
1183 else # return here if error is something else
1184 return 1
1185 fi
1186 else
1187 status=0
1188 fi
1189 done
1190 fi
1191
1192 # Clean up UFS config
1193 if [[ -n "$hufs_mnt_point" ]]; then
1194 cmd="umount $hufs_mnt_point"
1195 record_cmd_execution "$cmd"
1196 cti_execute "FAIL" "$cmd"
1197 if (( $? != 0 )); then
1198 cti_report "ufs fs mounted at '$ufs_mount_point" \
1199 "would not unmount; can't delete lofi device" \
1200 "based on file '$lofi_file'"
1201 return 1
1202 fi
1203 fi
1204
1205 # Clean up lofi device
1206 if [[ -n "$lofi_file" ]]; then
1207 lofi_dev=`associate_lofidev_and_file file $lofi_file`
1208 if [[ -n "$lofi_dev" ]]; then
1209 # There appears to be a lofi device based on the file
1210 del_lofi_device $lofi_dev
1211 if (( $? != 0 )); then
1212 cti_report "Can't delete lofi device" \
1213 "'$lofi_dev' and so can't delete file" \
1214 "'$lofi_file'"
1215 return 1
1216 fi
1217 fi
1218
1219 if [[ -n "$delete_file" ]]; then
1220 cmd="$RM -f $lofi_file"
1221 record_cmd_execution "$cmd"
1222 $cmd
1223 if (( $? != 0 )); then
1224 cti_report "Could not remove file '$lofi_file'"
1225 return 1
1226 fi
1227 fi
1228 fi
1229
1230 return 0
1231 }
1232
1233
1234 #
1235 # NAME
1236 # create_populated_fs_in_file
1237 #
1238 # SYNOPSIS
1239 # create_populated_fs_in_file -f <fs type> -l <file> -s <source dir> \
1240 # -r <file size> [-c compression type] [-d desired lofi device] \
1241 # [-z zpool_name]
1242 #
1243 # DESCRIPTION:
1244 # Create and populate a filesystem of the specified type in the
1245 # specified file. When this function is complete, the specified
1246 # file will contain a filesystem image that can be accessed by
1247 # associating the file with a lofi device. The filesystem is
1248 # populated by copying (via cpio) the contents of the source dir
1249 # specified by the -s flag.
1250 #
1251 # RETURN CODES:
1252 # 0 File system created and populated
1253 # 1 Problem with file system creation or populating
1254 #
1255 function create_populated_fs_in_file {
1256 typeset compression_type desired_lofi_dev file_system_param
1257 typeset lofi_file file_size_param src_dir zpool_name
1258 typeset status=0
1259
1260 # Process arguments
1261 typeset option
1262 while getopts c:f:l:r:s:z: option
1263 do
1264 case $option in
1265 c) compression_type="$OPTARG";;
1266 d) desired_lofi_dev="$OPTARG";;
1267 f) file_system_param="$OPTARG";;
1268 l) lofi_file="$OPTARG";;
1269 r) file_size_param="$OPTARG";;
1270 s) src_dir="$OPTARG";;
1271 z) zpool_name="$OPTARG";;
1272 esac
1273 done
1274
1275 # Verify that the source directory exists
1276 if [[ ! -d $src_dir ]]; then
1277 cti_uninitiated "Error: Specified source dir to copy from" \
1278 "($src_dir) does not exist or is not a directory."
1279 return 1
1280 fi
1281
1282 typeset status=0 fs_creation_status=0 fs_population_status=0
1283 typeset lofi_dev_name mount_point
1284 typeset lofi_dev
1285 typeset ufs_finish_arg zfs_finish_arg
1286 typeset cmd
1287
1288 if [[ $file_system_param == "ufs" || $file_system_param = "hsfs" ]]
1289 then
1290 mount_point="/mnt"
1291 fi
1292
1293 # For ufs and zfs filesystems creating the lofi file, creating the
1294 # filesystem, and populating it are all separate steps.
1295 if [[ $file_system_param == "ufs" || $file_system_param = "zfs" ]]
1296 then
1297 # Create the file
1298 make_and_verify_file $file_size_param $lofi_file
1299 if (( $? != 0 )); then
1300 # File creation failed.
1301 return 1
1302 fi
1303
1304 # Add lofi device based on just-created file.
1305 # $desired_lofi_dev may or may not be set, so
1306 # add_lofi_device() may return a lofi dev name to us.
1307 lofi_dev=`add_lofi_device $lofi_file $desired_lofi_dev`
1308 if (( $? != 0 )); then
1309 # Addition of lofi device failed
1310 lofi_and_fs_tidy_up -f $lofi_file
1311 return 1
1312 fi
1313
1314 # If we specified a desired lofi dev name, then
1315 # add_lofi_device() will not have output a lofi dev name.
1316 if [[ -n "$desired_lofi_dev" ]]; then
1317 lofi_dev="$desired_lofi_dev"
1318 fi
1319
1320 # Create filesystem
1321 if [[ $file_system_param == "ufs" ]]; then
1322 create_ufs -f $lofi_file -l $lofi_dev
1323 fs_creation_status=$?
1324 else
1325 create_zfs -f $lofi_file -z $zpool_name -l $lofi_dev
1326 fs_creation_status=$?
1327 fi
1328
1329 if (( $fs_creation_status != 0 )); then
1330 # Filesystem creation failed
1331 lofi_and_fs_tidy_up -f $lofi_file
1332 return 1
1333 fi
1334
1335 # Take care of filesystem mounting
1336 typeset mount_status=0
1337 if [[ $file_system_param = "ufs" ]]; then
1338 # ufs filesystem must be mounted after
1339 # creation.
1340 cmd="mount -F $file_system_param $lofi_dev"
1341 cmd="$cmd $mount_point"
1342 record_cmd_execution "$cmd"
1343 cti_execute "FAIL" "$cmd"
1344 if (( $? != 0 )); then
1345 lofi_and_fs_tidy_up \
1346 -f $lofi_file -m $mount_point
1347 return 1
1348 fi
1349 ufs_finish_arg="-m $mount_point"
1350 else
1351 # ZFS filesystem should have been mounted at
1352 # creation time.
1353 zfs_finish_arg="-z $zpool_name"
1354 mount_point="/${zpool_name}"
1355 grep "$mount_point" /etc/mnttab >/dev/null
1356 if (( $? != 0 )); then
1357 cti_fail "ZFS file system $zpool_name not" \
1358 "mounted at creation time"
1359 lofi_and_fs_tidy_up \
1360 -f $lofi_file $zfs_finish_arg
1361 return 1
1362 fi
1363 fi
1364
1365 # 'cd' to the top directory of the reference tree
1366 typeset mypwd=`pwd`
1367 cmd="cd $src_dir"
1368 record_cmd_execution "$cmd"
1369 $cmd
1370
1371 # Use cpio to copy the reference tree to the target
1372 # filesystem. We won't use cti_execute to execute this as
1373 # is will create cti_stdout and cti_stderr files in the
1374 # reference tree as that is our current working directory.
1375 # This means we'll have to manage command output ourselves.
1376 #
1377 # Command with a pipe ("|") in it won't execute correctly
1378 # if we try to execute it out of a variable, so have to
1379 # explicitly write out the command twice (once to log it
1380 # in the execution record, once to execute it).
1381 record_cmd_execution "find . -print | cpio -pdm $mount_point"
1382 find . -print | cpio -pdm $mount_point >/dev/null \
1383 2>${TMPDIR}/$$_cpio_stderr
1384 typeset populate_status=$?
1385
1386 # 'cd' back to our original location before doing anything
1387 # else.
1388 cmd="cd $mypwd"
1389 record_cmd_execution "$cmd"
1390 $cmd
1391
1392 # Abort if populating the filesystem failed
1393 if (( $populate_status != 0 )); then
1394 cti_report "Populating $file_system_param file" \
1395 "system failed. stderr for find/cpio:"
1396 cti_reportfile ${TMPDIR}/$$_cpio_stderr
1397 $RM -f ${TMPDIR}/$$_cpio_stderr 2>/dev/null
1398 lofi_and_fs_tidy_up -f $lofi_file \
1399 $ufs_finish_arg $zfs_finish_arg
1400 return 1
1401 fi
1402 $RM -f ${TMPDIR}/$$_cpio_stderr 2>/dev/null
1403
1404 if [[ -n "$VERBOSE" ]]; then
1405 cti_report "Populating of $file_system_param file" \
1406 "system completed"
1407 fi
1408
1409 lofi_and_fs_tidy_up -f $lofi_file $ufs_finish_arg \
1410 $zfs_finish_arg
1411 if (( $? != 0 )); then
1412 return 1
1413 fi
1414
1415 if [[ -n "$VERBOSE" ]]; then
1416 cti_report "Unmounted the $file_system_param" \
1417 "filesystem and deleted lofi device"
1418 fi
1419
1420 elif [[ $file_system_param == "hsfs" ]]; then
1421 # For an hsfs filesystem, creation of the file and population
1422 # by the file system all happen at once.
1423 create_isofs $lofi_file $src_dir
1424 if (( $? != 0 )); then
1425 lofi_and_fs_tidy_up -f $lofi_file
1426 return 1
1427 fi
1428 fi
1429
1430 return 0
1431 }
1432
1433
1434 #
1435 # NAME:
1436 # verify_populated_fs_in_file
1437 #
1438 # SYNOPSIS:
1439 # verify_populated_fs_in_file -f <fs type> -l <lofi file> -s <src dir> \
1440 # [-c] [-z <zpool name>]
1441 #
1442 # DESCRIPTION:
1443 # Verify the filesystem contents of the specified lofi file against
1444 # the original source. At this time the verification is restricted
1445 # to file/directory names and permissions, as the files were created
1446 # via 'mkfile' [by build_reference_tree()] and so don't actually
1447 # have contents for us to verify.
1448 #
1449 # RETURN CODES:
1450 # 0 Contents of filesystem on lofi device verified
1451 # 1 Filesystem on lofi device inaccessible or doesn't match source
1452 #
1453 function verify_populated_fs_in_file {
1454 typeset lofi_file file_system_param compression zpool_name
1455 typeset status=0
1456
1457 # Process function arguments
1458 typeset option
1459 while getopts cf:l:s:z: option
1460 do
1461 case $option in
1462 c) compression="yes";;
1463 f) file_system_param="$OPTARG";;
1464 l) lofi_file="$OPTARG";;
1465 s) src_dir="$OPTARG";;
1466 z) zpool_name="$OPTARG";;
1467 esac
1468 done
1469
1470 # Add lofi device based on the file.
1471 lofi_dev=`add_lofi_device $lofi_file`
1472 if (( $? != 0 )); then
1473 # Addition of lofi device failed
1474 lofi_and_fs_tidy_up -f $lofi_file
1475 return 1
1476 fi
1477
1478 # Verify that the correct file system type is reported.
1479 cmd="$FSTYP $lofi_dev"
1480 record_cmd_execution "$cmd"
1481 cti_execute "FAIL" "$cmd"
1482 typeset fs_type=`cat cti_stdout`
1483 if [[ "$fs_type" != "$file_system_param" ]]; then
1484 cti_fail "$FSTYP for $lofi_dev returns type '$fs_type';" \
1485 "expected '$file_system_param'"
1486 lofi_and_fs_tidy_up -f $lofi_file
1487 return 1
1488 fi
1489
1490 if [[ -n "$compression" && $file_system_param = "zfs" ]]; then
1491 # With a compressed zfs zpool, the only check we can make is
1492 # executing fstyp above to verify that the on-the-fly
1493 # decompression allows the file system type to be determined.
1494 # We can't import or otherwise use the zpool so we'll return
1495 # now.
1496 lofi_and_fs_tidy_up -f $lofi_file
1497 return 0
1498 fi
1499
1500 # Need to specify mount point for ufs or hsfs; zfs fs has mount
1501 # point defined in itself.
1502 if [[ $file_system_param == "ufs" || $file_system_param = "hsfs" ]]
1503 then
1504 mount_point="/mnt"
1505 fi
1506
1507 # If the file is compressed and contains a UFS filesystem, first try
1508 # mounting it read/write. This should fail.
1509 if [[ -n "$compression" && "$file_system_param" = "ufs" ]]; then
1510 cti_report "Attempt mounting compressed UFS filesystem" \
1511 "read/write. This is expected to fail."
1512 cmd="mount -F ufs $lofi_dev $mount_point"
1513 record_cmd_execution "$cmd"
1514 cti_execute "PASS" "$cmd"
1515 if (( $? == 0 )); then
1516 cti_fail "Mounting of compressed ufs filesystem at" \
1517 "$lofi/dev/ with read/write permissions" \
1518 "succeeded when it was expected to fail."
1519 lofi_and_fs_tidy_up -f $lofi_file \
1520 -m $mount_point
1521 cmd="mount -F ufs $lofi_dev $mount_point"
1522 record_cmd_execution "$cmd"
1523 cti_execute "PASS" "$cmd"
1524 if (( $? == 0 )); then
1525 return 1
1526 fi
1527 status=1
1528 fi
1529
1530 if [[ -n "$VERBOSE" ]]; then
1531 cti_report "Attempted mounting of compressed ufs" \
1532 "filesystem with read/write permissions failed" \
1533 "as expected."
1534 fi
1535 fi
1536
1537 typeset hufs_finish_arg zfs_finish_arg
1538 if [[ "$file_system_param" = "ufs" || "$file_system_param" = "hsfs" ]]
1539 then
1540 # Set mount options to read-only if file is compressed.
1541 typeset mopts
1542 if [[ -n "$compression" ]]; then
1543 mopts="-o ro"
1544 fi
1545
1546 # Mount the FS.
1547 cmd="mount -F $file_system_param $mopts $lofi_dev $mount_point"
1548 record_cmd_execution "$cmd"
1549 cti_execute "PASS" "$cmd"
1550 if (( $? != 0 )); then
1551 if [[ -n "$compression" ]]; then
1552 cti_fail "Mounting of compressed" \
1553 "$file_system_param filesystem at" \
1554 "$lofi_dev with read-only option failed" \
1555 "when it was expected to pass"
1556 else
1557 cti_fail "Mounting of $file_system_param" \
1558 "filesystem with default options failed" \
1559 "when it was expected to pass"
1560 fi
1561 lofi_and_fs_tidy_up -f $lofi_file \
1562 -m $mount_point
1563 return 1
1564 fi
1565 hufs_finish_arg="-m $mount_point"
1566 elif [[ "$file_system_param" = "zfs" ]]; then
1567 mount_point="/${zpool_name}"
1568 import_zfs $lofi_dev $zpool_name
1569 if (( $? != 0 )); then
1570 lofi_and_fs_tidy_up -f $lofi_file
1571 return
1572 fi
1573
1574 zfs_finish_arg="-z $zpool_name"
1575 fi
1576
1577 # Validate the contents of the file system on the lofi device
1578 # associated with the decompressed file.
1579 validate_test_fs $mount_point $src_dir $file_system_param
1580 if (( $? == 0 )); then
1581 if [[ -n "$VERBOSE" ]]; then
1582 cti_report "Validation of $file_system_param" \
1583 "filesystem succeeded"
1584 fi
1585 else
1586 if [[ -n "$VERBOSE" ]]; then
1587 cti_report "Validation of $file_system_param" \
1588 "filesystem failed"
1589 fi
1590 status=1
1591 fi
1592
1593 # Unmount the filesystem and dissasociate the lofi device from it.
1594 lofi_and_fs_tidy_up -f $lofi_file $hufs_finish_arg $zfs_finish_arg
1595 if (( $? != 0 )); then
1596 return 1
1597 fi
1598
1599 return $status
1600 }