OSDN Git Service

tests: add double quotes around a use of $VERBOSE
[android-x86/external-parted.git] / tests / t-local.sh
1 # Put test-related bits that are parted-specific here.
2 # This file is sourced from the testing framework.
3 sector_size_=${PARTED_SECTOR_SIZE:-512}
4
5 scsi_debug_lock_dir_="$abs_srcdir/scsi_debug.lock"
6
7 require_scsi_debug_module_()
8 {
9   # check for scsi_debug module
10   modprobe -n scsi_debug ||
11     skip_ "you lack the scsi_debug kernel module"
12 }
13
14 scsi_debug_modprobe_succeeded_=
15
16 # Always run this cleanup function.
17 cleanup_final_() { scsi_debug_cleanup_; }
18
19 scsi_debug_cleanup_()
20 {
21   # This function must always release the lock.
22   # If modprobe succeeded, it must be sure to run rmmod.
23   if test -n "$scsi_debug_modprobe_succeeded_"; then
24     # We have to insist.  Otherwise, a single rmmod usually fails to remove it,
25     # due either to "Resource temporarily unavailable" or to
26     # "Module scsi_debug is in use".
27     for i in 1 2 3; do
28       rmmod scsi_debug \
29         && { test "$VERBOSE" = yes && warn_ $ME_ rmmod scsi_debug...; break; }
30       sleep .2 || sleep 1
31     done
32   fi
33   rm -fr $scsi_debug_lock_dir_
34 }
35
36 # Helper function: wait 2s (via .1s increments) for FILE to appear.
37 # Usage: wait_for_dev_to_appear_ /dev/sdg
38 # Return 0 upon success, 1 upon failure.
39 wait_for_dev_to_appear_()
40 {
41   local file=$1
42   local i=0
43   local incr=1
44   while :; do
45     ls "$file" > /dev/null 2>&1 && return 0
46     sleep .1 2>/dev/null || { sleep 1; incr=10; }
47     i=$(expr $i + $incr); test $i = 20 && break
48   done
49   return 1
50 }
51
52 # Tests that uses "modprobe scsi_debug ..." must not be run in parallel.
53 scsi_debug_acquire_lock_()
54 {
55   local retries=20
56   local lock_timeout_stale_seconds=120
57
58   # If it was created more than $lock_timeout_stale_seconds ago, remove it.
59   # FIXME: implement this
60
61   local i=0
62   local incr=1
63   while :; do
64     mkdir "$scsi_debug_lock_dir_" && return 0
65     sleep .1 2>/dev/null || { sleep 1; incr=10; }
66     i=$(expr $i + $incr); test $i = $(expr $retries \* 10) && break
67   done
68
69   warn_ "$ME_: failed to acquire lock: $scsi_debug_lock_dir_"
70   return 1
71 }
72
73 # If there is a scsi_debug device, print the corresponding "sdN" and return 0.
74 # Otherwise, return 1.
75 new_sdX_()
76 {
77   local m; m=$(grep -lw scsi_debug /sys/block/sd*/device/model) || return 1
78
79   # Remove the /sys/block/ prefix, and then the /device/model suffix.
80   m=${m#/sys/block/}
81   m=${m%/device/model}
82   echo "$m"
83   return 0
84 }
85
86 # Create a device using the scsi_debug module with the options passed to
87 # this function as arguments.  Upon success, print the name of the new device.
88 scsi_debug_setup_()
89 {
90   scsi_debug_acquire_lock_
91
92   # It is not trivial to determine the name of the device we're creating.
93   # Record the names of all /sys/block/sd* devices *before* probing:
94   touch stamp
95   modprobe scsi_debug "$@" || { rm -f stamp; return 1; }
96   scsi_debug_modprobe_succeeded_=1
97   test $VERBOSE = yes \
98     && warn_ $ME_ modprobe scsi_debug succeeded
99
100   # Wait up to 2s (via .1s increments) for the list of devices to change.
101   # Sleeping for a fraction of a second requires GNU sleep, so fall
102   # back on sleeping 2x1s if that fails.
103   # FIXME-portability: using "cmp - ..." probably requires GNU cmp.
104   local incr=1
105   local i=0
106   local new_dev
107   while :; do
108     new_dev=$(new_sdX_) && break
109     sleep .1 2>/dev/null || { sleep 1; incr=10; }
110     i=$(expr $i + $incr); test $i = 20 && break
111   done
112
113   case $new_dev in
114     sd[a-z]) ;;
115     sd[a-z][a-z]) ;;
116     *) warn_ $ME_ unexpected device name: $new_dev; return 1 ;;
117   esac
118   local t=/dev/$new_dev
119   wait_for_dev_to_appear_ $t
120   echo $t
121   return 0
122 }
123
124 require_512_byte_sector_size_()
125 {
126   test $sector_size_ = 512 \
127       || skip_ FS test with sector size != 512
128 }
129
130 peek_()
131 {
132   case $# in 2) ;; *) echo "usage: peek_ FILE 0_BASED_OFFSET" >&2; exit 1;; esac
133   case $2 in *[^0-9]*) echo "peek_: invalid offset: $2" >&2; exit 1 ;; esac
134   dd if="$1" bs=1 skip="$2" count=1
135 }
136
137 poke_()
138 {
139   case $# in 3) ;; *) echo "usage: poke_ FILE 0_BASED_OFFSET BYTE" >&2; exit 1;;
140     esac
141   case $2 in *[^0-9]*) echo "poke_: invalid offset: $2" >&2; exit 1 ;; esac
142   case $3 in ?) ;; *) echo "poke_: invalid byte: '$3'" >&2; exit 1 ;; esac
143   printf %s "$3" | dd of="$1" bs=1 seek="$2" count=1 conv=notrunc
144 }
145
146 # byte 56 of the partition entry is the first byte of its 72-byte name field
147 gpt1_pte_name_offset_()
148 {
149   local ss=$1
150   case $ss in *[^0-9]*) echo "$0: invalid sector size: $ss">&2; return 1;; esac
151   expr $ss \* 2 + 56
152   return 0
153 }
154
155 # Change the name of the first partition in the primary GPT table,
156 # thus invalidating the PartitionEntryArrayCRC32 checksum.
157 gpt_corrupt_primary_table_()
158 {
159   case $# in 2) ;; *) echo "$0: expected 2 args, got $#" >&2; return 1;; esac
160   local dev=$1
161   local ss=$2
162   case $ss in *[^0-9]*) echo "$0: invalid sector size: $ss">&2; return 1;; esac
163
164   # get the first byte of the name
165   local orig_pte_name_byte
166   orig_pte_name_byte=$(peek_ $dev $(gpt1_pte_name_offset_ $ss)) || return 1
167
168   local new_byte
169   test x"$orig_pte_name_byte" = xA && new_byte=B || new_byte=A
170
171   # Replace with a different byte
172   poke_ $dev $(gpt1_pte_name_offset_ $ss) "$new_byte" || return 1
173
174   printf %s "$orig_pte_name_byte"
175   return 0
176 }
177
178 gpt_restore_primary_table_()
179 {
180   case $# in 3) ;; *) echo "$0: expected 2 args, got $#" >&2; return 1;; esac
181   local dev=$1
182   local ss=$2
183   case $ss in *[^0-9]*) echo "$0: invalid sector size: $ss">&2; return 1;; esac
184   local orig_byte=$3
185   poke_ $dev $(gpt1_pte_name_offset_ $ss) "$orig_byte" || return 1
186 }
187
188 . "$abs_top_srcdir/tests/t-lvm.sh"