List Info

Thread: MAKEDEV, pax, and mtree




MAKEDEV, pax, and mtree
country flaguser name
South Africa
2008-04-07 15:31:48
MAKEDEV(8) internally tries to use pax(8) to create device
nodes.
However, this doesn't work well if the device nodes already
exist; at
best, pax will complain "file would overwrite
itself", and at worst, pax
will not correct a file whose type or permissions are
incorrect.

Here's a patch to let MAKEDEV use mtree in preference to
pax.  In
normal use, it's expected that mtree will be available and
will work.
When MAKEDEV is invoked from init(8) to populate a
previously empty
/dev, it's expected that mtree will not be available, but
pax will be
available, and the problem that pax has with already
existing device
nodes will not be an issue.

I don't know what do do with the MAKEDEV "-f"
flag.  If MAKEDEV invokes
mknod(8), then MAKEDEV's "-f" flag selects between
mknod's "-r" and
"-R" flags.  If MAKEDEV invokes pax(1), I don't
think the "-f" flag
makes sense at all.  If MAKEDEV invokes mtree(8), would it
make sense
for MAKEDEV's "-f" flag to select between
"mtree -e -U -W" and "mtree -e
-U"?

--apb (Alan Barrett)

Index: src/etc/MAKEDEV.tmpl
============================================================
=======
--- MAKEDEV.tmpl	5 Mar 2008 02:29:51 -0000	1.102
+++ MAKEDEV.tmpl	7 Apr 2008 20:17:07 -0000
 -1,7
+1,7 
 #!/bin/sh -
 #	$NetBSD: MAKEDEV.tmpl,v 1.102 2008/03/05 02:29:51
christos Exp $
 #
-# Copyright (c) 2003,2007 The NetBSD Foundation, Inc.
+# Copyright (c) 2003,2007,2008 The NetBSD Foundation, Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with
or without
 -304,13
+304,14 
 usage()
 {
 	cat 1>&2 << _USAGE_
-Usage: ${0##*/} [-fMs] [-m mknod] [-p pax] special [...]
+Usage: ${0##*/} [-fMs] [-m mknod] [-p pax] [-t mtree]
special [...]
 	Create listed special devices.  Options:
 	-f		Force permissions to be updated on existing devices.
 	-M		Create memory file system.
 	-m mknod	Name of mknod(8) program.  [$TOOL_MKNOD or
mknod]
 	-p pax  	Name of pax(2) program.  [$TOOL_PAX or pax]
 	-s		Generate mtree(8) specfile instead of creating
devices.
+	-t mtree	Name of mtree(8) program.  [$TOOL_MTREE or
mtree]
 
 _USAGE_
 	exit 1
 -376,8
+377,8 
 }
 
 # check_pax path_to_pax
-#	Check whether pax supports the command line options we
-#	will want to use.
+#	Check whether pax exists and supports the command line
options
+#	and input format that we will want to use.
 #
 check_pax()
 {
 -385,6
+386,16 
 	echo ". type=dir optional" | nooutput -12
"$" -r -w -M -pe .
 }
 
+# check_mtree path_to_mtree
+#	Check whether mtree exists and supports the command line
options
+#	and input format that we will want to use.
+#
+check_mtree()
+{
+	local mtree="$1"
+	echo ". type=dir optional" | nooutput -12
"$" -e -U
+}
+
 # setup args...
 #	Parse command line arguments, exit on error.
 #	Callers should shift $((OPTIND - 1)) afterwards.
 -393,14
+404,18 
 {
 	PATH=/sbin:/usr/sbin:/bin:/usr/bin:/rescue
 
+	: ${TOOL_MKNOD:=mknod}
+	: ${TOOL_MTREE:=mtree}
+	: ${TOOL_PAX:=pax}
 	do_create_mfs=false
 	do_force=false
 	do_mknod=false
 	do_pax=false
+	do_mtree=false
 	do_redirect=false
 	do_specfile=false
-	opts=
-	while getopts Mfm:p:s ch; do
+	opts= # options passed to MAKEDEV.local child process
+	while getopts Mfm:p:st: ch; do
 		# Options that should not be passed through to
 		# MAKEDEV.local are not added to $opts.
 		case $ in
 -431,6
+446,17 
 		s)	do_specfile=true
 			opts="$ -s"
 			;;
+		t)	TOOL_MTREE="$"
+			if check_mtree "$"; then
+				do_mtree=true
+				# do not add this to $opts; we will later
+				# add "-s" instead.
+			else
+				warn "Ignored -t option:" 
+					"$ is missing or broken"
+				do_mknod=true
+			fi
+			;;
 		*)	usage ;;
 		esac
 	done
 -463,32
+489,42 
 
 	# do_force requires mknod
 	if $do_force; then
-		if $do_pax || $do_specfile; then
+		if $do_mtree || $do_pax || $do_specfile; then
 			warn "-f option works only with mknod"
 			exit 1
 		fi
 		do_mknod=true
 	fi
 
-	# If no other options take precedence, then default to
-	# using pax, if it appears to work.
-	if ! $do_mknod && ! $do_specfile && !
$do_pax; then
-		: ${TOOL_PAX:=pax}
-		if check_pax "$"; then
+	# If no explicit method was specified on the command line
+	# or forced above, then use one of mtree, pax, or mknod,
+	# in that order of preference.
+	#
+	# mtree is preferred over pax, because pax complains about
"file
+	# would overwrite itself" when trying to update a
file that
+	# already exists.  However, mtree is less likely than pax
to be
+	# available early in the boot sequence, when init(8) may
invoke
+	# MAKEDEV(8).  mknod is just very slow, because the shell
has to fork
+	# for each device node.
+	if ! ( $do_mtree || $do_pax || $do_mknod || $do_specfile
); then
+		if check_mtree "$"; then
+			do_mtree=true
+		elif check_pax "$"; then
 			do_pax=true
 		else
 			do_mknod=true
 		fi
 	fi
 
-	# Now we need exactly one of do_pax, do_mknod, or
do_specfile.
-	case $(( $($do_pax && echo 1 || echo 0) + 
+	# Now we need exactly one node-creation method.
+	case $(( $($do_mtree && echo 1 || echo 0) + 
+		$($do_pax && echo 1 || echo 0) + 
 		$($do_mknod && echo 1 || echo 0) + 
 		$($do_specfile && echo 1 || echo 0) ))
 	in
-	1)	: OK ;;
-	*)	
-		warn "-m, -p, and -s options are mutually
exclusive"
+	1)	: OK
+		;;
+	*)	warn "-m, -p, -s, and -t options are mutually
exclusive"
 		exit 1
 		;;
 	esac
 -496,16
+532,16 
 	# If we are using mknod, then decide what options to pass
it.
 	if $do_mknod; then
 		MKNOD="${TOOL_MKNOD:-mknod} -F netbsd"
-		if $do_force; then
+	if $do_force; then
 			MKNOD="$ -R"
-		else
+	else
 			MKNOD="$ -r"
 		fi
 	fi
 
-	# do_pax internally implies do_specfile.  This happens
after
-	# checking for mutually-exclusive options.
-	if $do_pax && ! $do_specfile; then
+	# do_mtree or do_pax internally implies do_specfile.
+	# This happens after checking for mutually-exclusive
options.
+	if ($do_mtree || $do_pax) && ! $do_specfile; then
 		do_specfile=true
 		opts="$ -s"
 	fi
 -518,7
+554,8 
 wrap_makedev()
 {
 	if $do_specfile; then
-		# "optional" tells pax(1) not to create the
directory itself.
+		# "." must appear as the first line of the
specfile.
+		# "optional" means do not create the directory
itself.
 		echo ". type=dir optional"
 	fi
 	"$"
 -547,9
+584,12 
 		unset count_nodes
 	fi
 
-	if $do_pax ; then
-		# wrap_makedev will print an mtree specification because
-		# do_pax implies do_specfile.  pax will create device
nodes.
+	# If using mtree or pax, then wrap_makedev should print an
mtree
+	# specification, which we postprocess to create the device
nodes.
+	# Otherwise, wrap_makedev should do all the work itself.
+	if $do_mtree ; then
+		wrap_makedev $makedev ${1+"$"} | $ -e
-U
+	elif $do_pax ; then
 		wrap_makedev $makedev ${1+"$"} | $ -r -w
-M -pe .
 	else
 		wrap_makedev $makedev ${1+"$"}
 -606,7
+646,7 
 		return
 	fi
 	if $do_specfile; then
-		echo "./$1 type=dir mode=$2 gid=$g_wheel uid=$u_root
optional"
+		echo "./$1 type=dir mode=$2 gid=$g_wheel
uid=$u_root"
 	else
 		nooutput -2 mkdir $1
 		chmod $2 $1

[1]

about | contact  Other archives ( Real Estate discussion Medical topics )