Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/netbsd-2-0]: src/etc/rc.d Pull up revisions 1.1-1.10 (requested by dbj i...
details: https://anonhg.NetBSD.org/src/rev/faaaea16c2c9
branches: netbsd-2-0
changeset: 560551:faaaea16c2c9
user: jdc <jdc%NetBSD.org@localhost>
date: Tue Apr 27 17:54:49 2004 +0000
description:
Pull up revisions 1.1-1.10 (requested by dbj in ticket #185)
Fix problems related to superblock upgrade issues which may be
experienced by -current users from 2003.
diffstat:
etc/rc.d/fixsb | 205 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 205 insertions(+), 0 deletions(-)
diffs (209 lines):
diff -r 4777a86ef4f7 -r faaaea16c2c9 etc/rc.d/fixsb
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/etc/rc.d/fixsb Tue Apr 27 17:54:49 2004 +0000
@@ -0,0 +1,205 @@
+#!/bin/sh
+#
+# $NetBSD: fixsb,v 1.10.2.2 2004/04/27 17:54:49 jdc Exp $
+#
+
+# PROVIDE: fixsb
+# REQUIRE: localswap
+# BEFORE: fsck
+
+. /etc/rc.subr
+
+name="fixsb"
+rcvar=$name
+start_cmd="fsck_start"
+stop_cmd=":"
+
+# This rc.d script attempts to correct problems with ffs1 filesystems
+# which may have been introduced by booting a netbsd-current kernel
+# from between April of 2003 and January 2004. For more information
+# see <http://mail-index.NetBSD.org/current-users/2004/01/11/0022.html>
+# This script was developed as a response to NetBSD pr install/25138
+# Additional prs regarding the original issue include:
+# bin/17910 kern/21283 kern/21404 port-macppc/23925 port-macppc/23926
+#
+
+fstab=/etc/fstab
+#verbose=1
+
+verbose()
+{
+ if [ -n "${verbose}" ]; then
+ echo "$@" 1>&2
+ fi
+}
+
+# This reads a field from the ffs superblock
+# at the specified offset and length in bytes
+# from the start of the superblock
+readsbfield()
+{
+ # The first dd command reads in the superblock using block aligned i/o
+ # sothat it works on a raw character device. The second dd extracts
+ # the exact field from the superblock that we wish to read.
+ (dd if="$1" bs=8192 count=1 skip=1 |
+ dd bs=1 skip="$2" count="$3" | cat -v) 2> /dev/null
+}
+
+# This shell function extracts the `ffs superblock' of the file
+# provided as its argument and tests for the following condition:
+# ((fs_magic == FS_UFS1_MAGIC) || fs_magic == FS_UFS1_MAGIC_SWAPPED) &&
+# (fs_sbsize == fs_maxbsize) && !(fs_old_flags & FS_FLAGS_UPDATED)
+#
+# return status is based on status of last filesystem checked:
+# 0 for botched superblock
+# 1 for filesystem does not appear to be ffs1 filesystem
+# 3 for ok fslevel 3 filesystem
+# 4 for ok fslevel 4 filesystem
+#
+# dbj%NetBSD.org@localhost 2004-04-12T18:15:06-0400
+check_part()
+{
+ verbose -n "Checking $1 ... "
+
+ # The following are 'cat -v' representations of the ffs1 magic number:
+ fsmagicn="^@^A^YT" # 0x00011954 FS_UFS1_MAGIC
+ fsmagics="T^Y^A^@" # 0x54190100 FS_UFS1_MAGIC_SWAPPED
+
+ # First we extract the superblock magic number field.
+ # We use cat -v to avoid having binary data in shell strings.
+ magic="$(readsbfield "$1" 1372 4)"
+
+ # Then we check if the magic number is valid (swapped or unswapped):
+ if [ "${magic}" != "${fsmagicn}" -a "${magic}" != "${fsmagics}" ]; then
+ verbose "does not appear to be an ffs1 filesystem."
+ return 1
+ fi
+
+ # Then we read fs_old_flags fields from disk
+ # And check the value of its high bit.
+ oldflags="$(readsbfield "$1" 211 1)"
+
+ case "${oldflags}" in
+ # Since the shell variable is the cat -v output, the
+ # high bit is indicated in the variable with the prefix M-
+ M-*)
+ verbose "file system looks ok at fslevel 4."
+ return 4
+ ;;
+ esac
+
+ # Then we read fs_bsize, fs_maxbsize fields from the disk:
+ bsize="$(readsbfield "$1" 48 4)"
+ maxbsize="$(readsbfield "$1" 860 4)"
+
+ # Compare the fs_bsize with fs_maxbsize to see if they are the same
+ if [ "${bsize}" != "${maxbsize}" ]; then
+ verbose "file system looks ok at fslevel 3."
+ return 3
+ fi
+
+ verbose "file system has botched superblock upgrade."
+ return 0
+}
+
+# This extracts raw ufs partitions to be fsck'ed from the file ${fstab}
+parse_fstab()
+{
+ for l in 1 2; do
+ cat "${fstab}" 2> /dev/null |
+ while read d m t o b f err; do
+ case "$d" in
+ \#*)
+ continue
+ ;;
+ /dev/*)
+ d="/dev/r${d#/dev/}"
+ ;;
+ esac
+ case "$t" in
+ ffs|ufs)
+ if [ "$f" = "$l" ]; then
+ echo "$d"
+ fi
+ ;;
+ esac
+ done
+ done
+}
+
+stop_boot()
+{
+ # Terminate the process (which may include the parent /etc/rc)
+ # if booting directly to multiuser mode.
+ if [ "$autoboot" = "yes" ]; then
+ kill -TERM $$
+ fi
+ exit 1
+}
+
+do_fsck()
+{
+ # During fsck ignore SIGQUIT
+
+ fsck_ffs "$@"
+ case $? in
+ 0)
+ ;;
+ 2)
+ stop_boot
+ ;;
+ 4)
+ echo "Rebooting..."
+ reboot
+ echo "Reboot failed; help!"
+ stop_boot
+ ;;
+ 8)
+ echo "Automatic file system check failed; help!"
+ stop_boot
+ ;;
+ 12)
+ echo "Boot interrupted."
+ stop_boot
+ ;;
+ 130)
+ stop_boot
+ ;;
+ *)
+ echo "Unknown error; help!"
+ stop_boot
+ ;;
+ esac
+}
+
+fsck_start()
+{
+ if [ -e /fastboot ]; then
+ echo "Fast boot: skipping disk checks."
+ else
+ # During fsck ignore SIGQUIT
+ trap : 3
+ okfs=true
+
+ echo -n "Checking for botched superblock upgrades:"
+ for p in $(parse_fstab); do
+ if check_part "$p"; then
+ if $okfs; then
+ echo
+ okfs=false
+ fi
+ echo "Repairing partition $p"
+ do_fsck -p -b 16 -c 4 "$p"
+ do_fsck -p -c 3 "$p"
+ fi
+ done
+ if $okfs; then
+ echo " done."
+ else
+ echo "Superblock(s) updated successfully."
+ fi
+ fi
+}
+
+load_rc_config $name
+run_rc_command "$1"
Home |
Main Index |
Thread Index |
Old Index