Print this page
XXX Remove nawk(1)
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/cmd/allocate/disk_clean.sh
+++ new/usr/src/cmd/allocate/disk_clean.sh
1 1 #! /usr/bin/sh
2 2 #
3 3 # CDDL HEADER START
4 4 #
5 5 # The contents of this file are subject to the terms of the
6 6 # Common Development and Distribution License (the "License").
7 7 # You may not use this file except in compliance with the License.
8 8 #
9 9 # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 10 # or http://www.opensolaris.org/os/licensing.
11 11 # See the License for the specific language governing permissions
12 12 # and limitations under the License.
13 13 #
14 14 # When distributing Covered Code, include this CDDL HEADER in each
15 15 # file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 16 # If applicable, add the following below this CDDL HEADER, with the
17 17 # fields enclosed by brackets "[]" replaced with your own identifying
18 18 # information: Portions Copyright [yyyy] [name of copyright owner]
19 19 #
20 20 # CDDL HEADER END
21 21 #
22 22 # Copyright 2010 Sun Microsystems, Inc. All rights reserved.
23 23 # Use is subject to license terms.
24 24 #
25 25 #
26 26 # This is a clean script for removable disks
27 27 #
28 28 # Following is the syntax for calling the script:
29 29 # scriptname [-s|-f|-i|-I] devicename [-A|-D] username zonename zonepath
30 30 #
31 31 # -s for standard cleanup by a user
32 32 # -f for forced cleanup by an administrator
33 33 # -i for boot-time initialization (when the system is booted with -r)
34 34 # -I to suppress error/warning messages; the script is run in the '-i'
35 35 # mode
36 36 #
37 37 # $1: devicename - device to be allocated/deallocated, e.g., sr0
38 38 #
39 39 # $2: -A if cleanup is for allocation, or -D if cleanup is for deallocation.
40 40 #
41 41 # $3: username - run the script as this user, rather than as the caller.
42 42 #
43 43 # $4: zonename - zone in which device to be allocated/deallocated
44 44 #
45 45 # $5: zonepath - root path of zonename
46 46 #
47 47 # A clean script for a removable media device should prompt the user to
48 48 # insert correctly labeled media at allocation time, and ensure that the
49 49 # media is ejected at deallocation time.
50 50 #
51 51 # Unless the clean script is being called for boot-time
52 52 # initialization, it may communicate with the user via stdin and
53 53 # stdout. To communicate with the user via CDE dialogs, create a
54 54 # script or link with the same name, but with ".windowing" appended.
55 55 # For example, if the clean script specified in device_allocate is
56 56 # /etc/security/xyz_clean, that script must use stdin/stdout. If a
57 57 # script named /etc/security/xyz_clean.windowing exists, it must use
58 58 # dialogs. To present dialogs to the user, the dtksh script
59 59 # /etc/security/lib/wdwmsg may be used.
60 60 #
61 61 # This particular script, disk_clean, will work using stdin/stdout, or
62 62 # using dialogs. A symbolic link disk_clean.windowing points to
63 63 # disk_clean.
64 64 #
65 65
66 66 # ####################################################
67 67 # ################ Local Functions #################
68 68 # ####################################################
69 69
70 70 #
71 71 # Set up for windowing and non-windowing messages
72 72 #
73 73 msg_init()
74 74 {
75 75 if [ `basename $0` != `basename $0 .windowing` ]; then
76 76 WINDOWING="yes"
77 77 case $VOLUME_MEDIATYPE in
78 78 cdrom) TITLE="CD-ROM";;
79 79 rmdisk) TITLE="Removable Disk";;
80 80 floppy) TITLE="Floppy";;
81 81 *) TITLE="Disk";;
82 82 esac
83 83
84 84 if [ "$MODE" = "allocate" ]; then
85 85 TITLE="$TITLE Allocation"
86 86 else
87 87 TITLE="$TITLE Deallocation"
88 88 fi
89 89 else
90 90 WINDOWING="no"
91 91 fi
92 92 }
93 93
94 94 #
95 95 # Display a message for the user. For windowing, user must press OK button
96 96 # to continue. For non-windowing, no response is required.
97 97 #
98 98 msg() {
99 99 if [ "$WINDOWING" = "yes" ]; then
100 100 $WDWMSG "$*" "$TITLE" OK
101 101 elif [ "$silent" != "y" ]; then
102 102 echo "$*" > /dev/${MSGDEV}
103 103 fi
104 104 }
105 105
106 106 ok_msg() {
107 107 if [ "$WINDOWING" = "yes" ]; then
108 108 $WDWMSG "$*" "$TITLE" READY
109 109 else
110 110 form=`gettext "Media in %s is ready. Please store safely."`
111 111 printf "${form}\n" $PROG $DEVICE > /dev/{MSGDEV}
112 112 fi
113 113 }
114 114
115 115 error_msg() {
116 116 if [ "$WINDOWING" = "yes" ]; then
117 117 $WDWMSG "$*" "$TITLE" ERROR
118 118 else
119 119 form=`gettext "%s: Error cleaning up device %s."`
120 120 printf "${form}\n" $PROG $DEVICE > /dev/${MSGDEV}
121 121 fi
122 122 }
123 123
124 124 #
125 125 # Ask the user an OK/Cancel question. Return 0 for OK, 1 for Cancel.
126 126 #
127 127 okcancel() {
128 128 if [ "$WINDOWING" = "yes" ]; then
129 129 $WDWMSG "$*" "$TITLE" OK Cancel
130 130 elif [ "$silent" != "y" ]; then
131 131 get_reply "$* (y to continue, n to cancel) \c" y n
132 132 fi
133 133 }
134 134
135 135 #
136 136 # Ask the user an Yes/No question. Return 0 for Yes, 1 for No
137 137 #
138 138 yesno() {
139 139 if [ "$WINDOWING" = "yes" ]; then
140 140 $WDWMSG "$*" "$TITLE" Yes No
141 141 elif [ "$silent" != "y" ]; then
142 142 get_reply "$* (y/n) \c" y n
143 143 fi
144 144 }
145 145
146 146 #
147 147 # Display an error message, put the device in the error state, and exit.
148 148 #
149 149 error_exit() {
150 150 if [ "$silent" != "y" ]; then
151 151 msg "$2" "$3" \
152 152 "\n\nDevice has been placed in allocation error state." \
153 153 "\nPlease inform system administrator."
154 154 fi
155 155 exit 1
156 156 }
157 157
158 158 #
159 159 # get_reply prompt choice ...
160 160 #
161 161 get_reply() {
162 162 prompt=$1; shift
163 163 while true
164 164 do
165 165 echo $prompt > /dev/tty
166 166 read reply
167 167 i=0
168 168 for choice in $*
169 169 do
170 170 if [ "$choice" = "$reply" ]
171 171 then
172 172 return $i
173 173 else
174 174 i=`expr $i + 1`
175 175 fi
176 176 done
177 177 done
178 178 }
179 179
180 180 #
181 181 # Find the first disk slice containing a file system
182 182 #
183 183 find_fs()
184 184 {
185 185 # The list of files in device_maps(4) is in an unspecified order.
186 186 # To speed up the fstyp(1M) scanning below in most cases, perform
187 187 # the search for filesystems as follows:
188 188 # 1) Select only block device files of the form "/dev/dsk/*".
189 189 # 2) Sort the list of files in an order more likely to yield
190 190 # matches: first the fdisk(1M) partitions ("/dev/dsk/cNtNdNpN")
191 191 # then the format(1M) slices ("/dev/dsk/cNtNdNsN"), in ascending
192 192 # numeric order within each group.
193 193 DEVall="`echo $FILES | \
194 194 /usr/bin/tr ' ' '\n' | \
195 195 /usr/bin/sed '/^\/dev\/dsk\//!d; s/\([sp]\)\([0-9]*\)$/ \1 \2/;' | \
196 196 /usr/bin/sort -t ' ' -k 2,2d -k 3,3n | \
197 197 /usr/bin/tr -d ' '`"
198 198 for DEVn in $DEVall ; do
199 199 fstyp_output="`/usr/sbin/fstyp -a $DEVn 2>&1`"
200 200 if [ $? = 0 ]; then
201 201 FSPATH=$DEVn
202 202 gen_volume_label="`echo "$fstyp_output" | \
203 203 sed -n '/^gen_volume_label: .\(.*\).$/s//\1/p'`"
204 204 if [ "$gen_volume_label" != "" ]; then
205 205 FSNAME="`echo $gen_volume_label | \
206 206 /usr/xpg4/bin/tr '[:upper:] ' '[:lower:]_'`"
207 207 fi
208 208 # For consistency, hsfs filesystems detected at
209 209 # /dev/dsk/*p0 are mounted as /dev/dsk/*s2
210 210 FSTYPE=`echo "$fstyp_output" | /usr/bin/head -1`
211 211 if [ "$FSTYPE" = hsfs -a \
212 212 `/usr/bin/expr $FSPATH : '.*p0'` -gt 0 ]; then
213 213 FSPATH=`echo $FSPATH | /usr/bin/sed 's/p0$/s2/'`
214 214 fi
215 215 return
↓ open down ↓ |
215 lines elided |
↑ open up ↑ |
216 216 fi
217 217 done
218 218 }
219 219
220 220 #
221 221 # Find all mountpoints in use for a set of device special files.
222 222 # Usage: findmounts devpath ...
223 223 #
224 224
225 225 findmounts() {
226 - nawk -f - -v vold_root="$VOLD_ROOT" -v devs="$*" /etc/mnttab <<\
226 + /usr/xpg4/bin/awk -f - -v vold_root="$VOLD_ROOT" -v devs="$*" /etc/mnttab <<\
227 227 "ENDOFAWKPGM"
228 228 BEGIN {
229 229 split(devs, devlist, " ");
230 230 for (devN in devlist) {
231 231 dev = devlist[devN];
232 232 realdevlist[dev] = 1;
233 233 sub(/.*\//, "", dev);
234 234 sub(/s[0-9]$/, "", dev);
235 235 if (vold_root != "") {
236 236 vold_dir[vold_root "/dev/dsk/" dev] = 1;
237 237 vold_dir[vold_root "/dev/rdsk/" dev] = 1;
238 238 }
239 239 }
240 240 }
241 241
242 242 {
243 243 for (dev in realdevlist) {
244 244 if ($1 == dev) {
245 245 mountpoint = $2;
246 246 print mountpoint;
247 247 }
248 248 }
249 249 for (dev in vold_dir) {
250 250 if (substr($1, 1, length(dev)) == dev) {
251 251 mountpoint = $2;
252 252 print mountpoint;
253 253 }
254 254 }
255 255 }
256 256 ENDOFAWKPGM
257 257 }
258 258
259 259 #
260 260 # Allocate a device.
261 261 # Ask the user to make sure the disk is properly labeled.
262 262 # Ask if the disk should be mounted.
263 263 #
264 264 do_allocate()
265 265 {
266 266 if [ $VOLUME_MEDIATYPE = floppy ]; then
267 267 # Determine if media is in drive
268 268 eject_msg="`eject -q $DEVFILE 2>&1`"
269 269 eject_status="$?"
270 270 case $eject_status in
271 271 1) # Media is not in drive
272 272 okcancel "Insert disk in $DEVICE."
273 273 if [ $? != 0 ]; then
274 274 exit 0
275 275 fi;;
276 276 3) # Error
277 277 error_exit $DEVICE \
278 278 "Error checking for media in drive.";;
279 279 esac
280 280 else
281 281 okcancel "Insert disk in $DEVICE."
282 282 if [ $? != 0 ]; then
283 283 exit 0
284 284 fi
285 285 fi
286 286
287 287 yesno "Do you want $DEVICE mounted?"
288 288 if [ $? != 0 ]; then
289 289 exit 0
290 290 fi
291 291
292 292 if [ $VOLUME_MEDIATYPE = cdrom -o $VOLUME_MEDIATYPE = rmdisk ]; then
293 293 # Get the device path and volume name of a partition
294 294 find_fs
295 295 if [ "$FSPATH" != "" ]; then
296 296 VOLUME_PATH=$FSPATH
297 297 fi
298 298 if [ "$FSNAME" != "" ]; then
299 299 VOLUME_NAME=$FSNAME
300 300 fi
301 301 fi
302 302 VOLUME_ACTION=insert
303 303
304 304 # Give ourself write permission on device file so file system gets
305 305 # mounted read/write if possible.
306 306 # rmmount only cares about permissions not user...
307 307 chown $VOLUME_USER $VOLUME_PATH
308 308 chmod 700 $VOLUME_PATH
309 309
310 310 # Do the actual mount. VOLUME_* environment variables are inputs to
311 311 # rmmount.
312 312 rmmount_msg="`/usr/sbin/rmmount 2>&1`"
313 313 rmmount_status="$?"
314 314 if [ $rmmount_status -eq 0 ]; then
315 315 EXIT_STATUS=$CLEAN_MOUNT
316 316 elif [ $rmmount_status -gt 0 -a $VOLUME_MEDIATYPE != cdrom ]; then
317 317 # Try again in readonly mode. cdrom is always mounted ro, so
318 318 # no need to try again.
319 319 echo "Read-write mount of $DEVICE failed. Mounting read-only."
320 320 VOLUME_ACTION=remount; export VOLUME_ACTION
321 321 VOLUME_MOUNT_MODE=ro; export VOLUME_MOUNT_MODE
322 322 `/usr/sbin/rmmount`
323 323 if [ $? -eq 0 ]; then
324 324 EXIT_STATUS=$CLEAN_MOUNT
325 325 fi
326 326 fi
327 327
328 328 # Set permissions on directory used by vold, sdtvolcheck, etc.
329 329 if [ -d /tmp/.removable ]; then
330 330 chown root /tmp/.removable
331 331 chmod 777 /tmp/.removable
332 332 fi
333 333 }
334 334
335 335
336 336 do_deallocate()
337 337 {
338 338 if [ $VOLUME_MEDIATYPE = cdrom -o $VOLUME_MEDIATYPE = rmdisk ]; then
339 339 if [ -h /$VOLUME_MEDIATYPE/$DEVICE ]; then
340 340 # Get the device path and volume name of a partition
341 341 VOLUME_PATH=`ls -l /$VOLUME_MEDIATYPE/$DEVICE|\
342 342 cut -d '>' -f2`
343 343 VOLUME_DEVICE=`mount -p|grep $VOLUME_PATH|\
344 344 cut -d ' ' -f1`
345 345 fi
346 346 fi
347 347
348 348 if [ -d "$VOLUME_PATH" ]; then
349 349 VOLUME_ACTION=eject
350 350 # Do the actual unmount.
351 351 # VOLUME_* environment variables are inputs to rmmount.
352 352 rmmount_msg="`/usr/sbin/rmmount 2>&1`"
353 353 rmmount_status="$?"
354 354
355 355 # Remove symbolic links to mount point
356 356 for name in /$VOLUME_MEDIATYPE/*; do
357 357 if [ -h $name ]; then
358 358 target=`ls -l $name | awk '{ print $NF; }'`
359 359 target_dir=`dirname $target`
360 360 target_device=`echo $target_dir | \
361 361 sed -e 's/^.*-\(.*\)$/\1/'`
362 362 if [ "$target_device" = "$DEVICE" ]; then
363 363 rm -f $name
364 364 fi
365 365 fi
366 366 done
367 367 else
368 368 rmmount_status=0
369 369 fi
370 370
371 371 case $rmmount_status in
372 372 1) # still mounted
373 373 error_exit $DEVICE "Error unmounting $DEVICE" "$rmmount_msg";;
374 374 0) # not mounted
375 375 # Eject the media
376 376 if [ "$FLAG" = "f" ] ; then
377 377 eject_msg="`eject -f $DEVICE 2>&1`"
378 378 else
379 379 eject_msg="`eject $DEVICE 2>&1`"
380 380 fi
381 381 eject_status="$?"
382 382 case $eject_status in
383 383 0|1|4) # Media has been ejected
384 384 case $VOLUME_MEDIATYPE in
385 385 floppy|cdrom|rmdisk)
386 386 msg "Please remove the disk from $DEVICE.";;
387 387 esac;;
388 388 3) # Media didn't eject
389 389 msg $DEVICE "Error ejecting disk from $DEVICE" \
390 390 "$eject_msg";;
391 391 esac
392 392 esac
393 393 }
394 394
395 395 #
396 396 # Reclaim a device
397 397 #
398 398 do_init()
399 399 {
400 400 eject_msg="`eject -f $DEVICE 2>&1`"
401 401 eject_status="$?"
402 402
403 403 case $eject_status in
404 404 0) # Media has been ejected
405 405 if [ "$silent" != "y" ]; then
406 406 ok_msg
407 407 fi
408 408 exit 0;;
409 409 1) # Media not ejected
410 410 if [ "$silent" != "y" ]; then
411 411 error_msg
412 412 fi
413 413 exit 0;;
414 414 3) # Error
415 415 if [ "$silent" != "y" ]; then
416 416 error_msg
417 417 fi
418 418 msg $DEVICE "Error ejecting disk from $DEVICE" \
419 419 "$eject_msg"
420 420 exit 2;;
421 421 esac
422 422 }
423 423
424 424
425 425 # ####################################################
426 426 # ################ Begin main program ################
427 427 # ####################################################
428 428
429 429 trap "" INT TERM QUIT TSTP ABRT
430 430
431 431 PATH="/usr/bin:/usr/sbin"
432 432 MODE="allocate"
433 433 SILENT=n
434 434 WDWMSG="/etc/security/lib/wdwmsg"
435 435 VOLUME_ZONE_PATH="/"
436 436 USAGE="Usage: disk_clean [-s|-f|-i|-I] devicename -[A|D] [username] [zonename] [zonepath]"
437 437 EXIT_STATUS=0
438 438 CLEAN_MOUNT=4
439 439 MACH=`uname -p`
440 440 FLAG=i
441 441 #
442 442 # Parse the command line arguments
443 443 #
444 444 while getopts ifsI c
445 445 do
446 446 case $c in
447 447 i)
448 448 FLAG=$c;;
449 449 f)
450 450 FLAG=$c;;
451 451 s)
452 452 FLAG=$c;;
453 453 I)
454 454 FLAG=i
455 455 silent=y;;
456 456 \?)
457 457 echo $USAGE
458 458 exit 1;;
459 459 esac
460 460 done
461 461
462 462 shift `expr $OPTIND - 1`
463 463
464 464 DEVICE=$1
465 465 MODE="deallocate"
466 466 if [ "$2" = "-A" ]; then
467 467 MODE="allocate"
468 468 elif [ "$2" = "-D" ]; then
469 469 MODE="deallocate"
470 470 fi
471 471
472 472 #get the device_maps information
473 473 MAP=`/usr/sbin/list_devices -s -l $DEVICE`
474 474 FILES=`echo $MAP | cut -f4 -d:` # e.g., /dev/dsk/c0t6d0s0 /dev/dsk/c0t6d0s1 ...
475 475 DEVFILE=`echo $FILES | cut -f1 -d" "` # e.g., "/dev/dsk/c0t6d0s0"
476 476
477 477 # Set VOLUME_ variables that are inputs to rmmount
478 478
479 479 VOLUME_DEVICE=`echo $FILES | cut -f2 -d" "` # e.g., "/dev/dsk/c0t6d0s1"
480 480 MEDIATYPE=`echo $MAP | cut -f3 -d: | cut -f2 -d" "`
481 481 # e.g., "cdrom" or "floppy"
482 482 if [ "$MEDIATYPE" = "sr" ]; then
483 483 VOLUME_MEDIATYPE="cdrom"
484 484 elif [ "$MEDIATYPE" = "fd" ]; then
485 485 VOLUME_MEDIATYPE="floppy"
486 486 elif [ "$MEDIATYPE" = "rmdisk" ]; then
487 487 VOLUME_MEDIATYPE="rmdisk"
488 488 fi
489 489
490 490 VOLUME_PATH=$DEVFILE # e.g., "/dev/dsk/c0t6d0s0"
491 491 if [ "$MACH" = "i386" ] && [ "$MEDIATYPE" = "rmdisk" ]; then
492 492 VOLUME_PATH=`echo $DEVFILE | sed -e 's/s0/p0/'`
493 493 fi
494 494
495 495 SYMDEV=`echo $DEVICE | sed -e 's/_//'` # e.g., "cdrom" or "floppy"
496 496 SYMNUM=`echo $SYMDEV | sed -e 's/[a-z]*//g'`
497 497 SYMDEV=`echo $SYMDEV | sed -e 's/[0-9]*//g'`
498 498 if [ "$SYMDEV" = "sr" ]; then
499 499 VOLUME_SYMDEV="cdrom"$SYMNUM
500 500 elif [ "$SYMDEV" = "fd" ]; then
501 501 VOLUME_SYMDEV="floppy"$SYMNUM
502 502 elif [ "$SYMDEV" = "rmdisk" ]; then
503 503 VOLUME_SYMDEV="rmdisk"$SYMNUM
504 504 else
505 505 VOLUME_SYMDEV=$SYMDEV$SYMNUM
506 506 fi
507 507
508 508 VOLUME_ZONE_NAME=$4
509 509
510 510 VOLUME_ZONE_PATH=$5
511 511
512 512 if [ "$MODE" = "allocate" ]; then
513 513 if [ -n "$3" ]; then # e.g., "joeuser"
514 514 VOLUME_USER=$3
515 515 else
516 516 VOLUME_USER=`/usr/xpg4/bin/id -u -nr`
517 517 fi
518 518 else
519 519 # If there's a directory for the device under /<mediatype>, get the
520 520 # user name from there, to use in cleaning up that directory. Otherwise,
521 521 # the user name isn't actually used in deallocation.
522 522 if [ -d ${VOLUME_ZONE_PATH}/${VOLUME_MEDIATYPE}/*-${DEVICE} ]; then
523 523 VOLUME_USER=`ls -ld ${VOLUME_ZONE_PATH}/${VOLUME_MEDIATYPE}/*-${DEVICE} | awk '/^d/{print $3}'`
524 524 else
525 525 if [ -n "$3" ]; then
526 526 VOLUME_USER=$3
527 527 else
528 528 VOLUME_USER=`/usr/xpg4/bin/id -u -nr`
529 529 fi
530 530 fi
531 531 fi
532 532
533 533 VOLUME_NAME=unnamed_${VOLUME_MEDIATYPE}
534 534 # e.g., "joeuser-cdrom0/unnamed_cdrom"
535 535
536 536 if [ "$VOLUME_MEDIATYPE" = "rmdisk" ]; then
537 537 VOLUME_PCFS_ID=1
538 538 else
539 539 VOLUME_PCFS_ID=
540 540 fi
541 541
542 542 export VOLUME_ACTION VOLUME_DEVICE VOLUME_MEDIATYPE VOLUME_NAME VOLUME_PCFS_ID
543 543 export VOLUME_PATH VOLUME_SYMDEV VOLUME_USER VOLUME_ZONE_NAME VOLUME_ZONE_PATH
544 544
545 545 USERDIR=${VOLUME_USER}-${DEVICE} # e.g., "joeusr-cdrom0"
546 546
547 547 msg_init
548 548
549 549 if [ "$MODE" = "allocate" ]; then
550 550 MSGDEV=tty
551 551 do_allocate
552 552 else
553 553 if [ "$FLAG" = "i" ] ; then
554 554 MSGDEV=console
555 555 do_init
556 556 else
557 557 MSGDEV=tty
558 558 do_deallocate
559 559 fi
560 560 fi
561 561
562 562 exit $EXIT_STATUS
↓ open down ↓ |
326 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX