tech-userlevel archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
MAKEDEV, pax, and mtree
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 "${pax}" -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 "${mtree}" -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 ${ch} in
@@ -431,6 +446,17 @@
s) do_specfile=true
opts="${opts} -s"
;;
+ t) TOOL_MTREE="${OPTARG}"
+ if check_mtree "${TOOL_MTREE}"; then
+ do_mtree=true
+ # do not add this to $opts; we will later
+ # add "-s" instead.
+ else
+ warn "Ignored -t option:" \
+ "${TOOL_MTREE} 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 "${TOOL_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 "${TOOL_MTREE}"; then
+ do_mtree=true
+ elif check_pax "${TOOL_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="${MKNOD} -R"
- else
+ else
MKNOD="${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="${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+"$@"} | ${TOOL_MTREE} -e -U
+ elif $do_pax ; then
wrap_makedev $makedev ${1+"$@"} | ${TOOL_PAX} -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
Home |
Main Index |
Thread Index |
Old Index