Bug 110068

Summary: [patch] rewrite of mdmfs(8) in shell
Product: Base System Reporter: Alex Kozlov <spam>
Component: binAssignee: Alex Kozlov <ak>
Status: Closed FIXED    
Severity: Affects Only Me    
Priority: Normal    
Version: Unspecified   
Hardware: Any   
OS: Any   
Attachments:
Description Flags
file.txt none

Description Alex Kozlov 2007-03-08 07:50:09 UTC
Drop-in replacement for a mdmfs written in shell

Fix: Patch attached with submission follows:
Comment 1 Alex Kozlov 2007-03-11 04:54:22 UTC
Updated patch. Fix handling of -n option(pr 110178), add user/group check


#!/bin/sh -f
#
# Copyright (c) 2006-7 Alex Kozlov
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
#    notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
#    notice, this list of conditions and the following disclaimer in the
#    documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#

. /etc/rc.subr

usage()
{
	echo "usage: ${0##*/} [-DLlMNnPSUX] [-a maxcontig] [-b block-size]"
	echo "		 [-c blocks-per-cylinder-group][-d max-extent-size] [-E path-mdconfig]"
	echo "		 [-e maxbpg] [-F file] [-f frag-size] [-i bytes] [-m percent-free]"
	echo "		 [-O optimization] [-o mount-options] [-p permissions] [-s size]"
	echo "		 [-v version] [-w user:group] tmd-device mount-point"
	exit 1
}

parse_options()
{
	local OPT OPTARG OPTIND

	while getopts a:b:Cc:Dd:E:e:F:f:hi:LlMm:NnO:o:Pp:Ss:t:Uv:w:X OPT; do
		case ${OPT} in
[abcdefilmn])	NEWFS_ARG="${NEWFS_ARG} -${OPT} ${OPTARG}" ;;
		C)	;;
		D)	opt_detach=NO ;;
		E)	MDCONFIG_PATH="${OPTARG}" ;;
		F)
			if checkyesno have_mdtype; then
				usage
			fi
			have_mdtype=YES
			opt_mdtype="vnode"
			MDCONFIG_ARG="${MDCONFIG_ARG} -f ${OPTARG}" ;;
		h)	usage ;;
		L)	redirect='' ;;
		M)
			if checkyesno have_mdtype; then
				usage
			fi
			have_mdtype=YES
			opt_mdtype="malloc" ;;
		N)	opt_norun=YES ;;
		o)	MOUNT_ARG="${MOUNT_ARG} -o ${OPTARG}" ;;
		O)	NEWFS_ARG="${NEWFS_ARG} -o ${OPTARG}" ;;
		P)	newfs=NO ;;
		p)	mp_mode="${OPTARG}" ;;
		S)	opt_softdep=NO ;;
		s)	MDCONFIG_ARG="${MDCONFIG_ARG} -s ${OPTARG}" ;;
		U)	opt_softdep=YES ;;
		v)	NEWFS_ARG="${NEWFS_ARG} -O ${OPTARG}" ;;
		w)
			case ${OPTARG} in
					*:*)	mp_user=${OPTARG%%:*}
							mp_group=${OPTARG#*:}
							run "${GETENT_PATH}" passwd "${mp_user}" 
							if [ ${run_errcode} -ne 0 ]; then
								err 1 "invalid user: ${mp_user}"
							fi
							run "${GETENT_PATH}" group "${mp_group}" 
							if [ ${run_errcode} -ne 0 ]; then
								err 1 "invalid group: ${mp_group}"
							fi ;;
					  *)	mp_user=${OPTARG} ;;
			esac ;;
		X)
			opt_debug=YES
			rc_debug=YES ;;
		*)	usage ;;
		esac
	done

	OPTC=$((${OPTIND} - 1))
}

do_mdconfig_detach()
{
	run "${MDCONFIG_PATH}" -d -u "${unit}"

	# This is allowed to fail.
	if checkyesno opt_debug && [ ${run_errcode} -ne 0 ];	then
		warn "mdconfig (detach) exited with error code ${run_errcode} (ignored)"
	fi
}

do_mdconfig_attach()
{
	if	checkyesno autounit; then
		run "${MDCONFIG_PATH}" -a -t "${opt_mdtype}" "${MDCONFIG_ARG}"
		if checkyesno opt_norun; then
			unit=0	# dummy unit
		else
			unit=${run_ret}
			unit=${unit#*md*}	# strip md
		fi
	else
		run "${MDCONFIG_PATH}" -a -t ${opt_mdtype} -u "${unit}" "${MDCONFIG_ARG}"
	fi

	if [ ${run_errcode} -ne 0 ]; then
		err 1 "mdconfig (attach) exited with error code ${run_errcode}"
	fi

	case ${unit} in
		[0-9]*) ;;
			 *) err 1 "unexpected output from mdconfig (attach): ${unit}" ;;
	esac
}

do_newfs()
{
	run "${NEWFS_PATH}" "${NEWFS_ARG}" "/dev/md${unit}"

	if [ ${run_errcode} -ne 0 ]; then
		err 1 "newfs exited with error code ${run_errcode}"
	fi
}

do_mount()
{
	run "${MOUNT_PATH}" "${MOUNT_ARG}" "/dev/md${unit}${suffix}" "${opt_mp}"

	if [ ${run_errcode} -ne 0 ]; then
		err 1 "mount exited with error code ${run_errcode}"
	fi
}

do_mpsetup()
{
	if [ -n "${mp_mode}" ]; then
		if checkyesno opt_debug; then
			debug "changing mode of ${opt_mp} to ${mp_mode}"
		fi

		run "${CHMOD_PATH}" "${mp_mode}" "${opt_mp}"

		if [ ${run_errcode} -ne 0 ]; then
			err 1 "chmod: ${opt_mp}"
		fi
	fi

	if [ -n "${mp_user}" ]; then
		if checkyesno opt_debug; then
			debug "changing owner (user) of ${opt_mp} to ${mp_user}"
		fi

		run "${CHOWN_PATH}" "${mp_user}" "${opt_mp}"

		if [ ${run_errcode} -ne 0 ]; then
			err 1 "chown ${opt_mp} to ${mp_user}"
		fi
	fi

	if [ -n "${mp_group}" ]; then
		if checkyesno opt_debug; then
			debug "changing owner (group) of ${opt_mp} to ${mp_group}"
		fi

		#run "${CHOWN_PATH}" :"${mp_group}" "${opt_mp}"
		run "${CHGRP_PATH}" "${mp_group}" "${opt_mp}"

		if [ ${run_errcode} -ne 0 ]; then
			err 1 "chgrp ${opt_mp} to ${mp_group}"
		fi
	fi
}

run()
{
	run_ret=''
	run_errcode=0

	if checkyesno opt_debug; then
		debug "running: $*"
	fi
	if checkyesno opt_norun; then
		return 0
	fi

	run_ret=`eval $* ${redirect}`
	run_errcode=$?
}

init_vars()
{
	CHMOD_PATH='/bin/chmod'
	CHOWN_PATH='/usr/sbin/chown'
	CHGRP_PATH='/usr/bin/chgrp'
	GETENT_PATH='/usr/bin/getent'
	NEWFS_PATH='/sbin/newfs'
	MDCONFIG_PATH='/sbin/mdconfig'
	MOUNT_PATH='/sbin/mount'
	NEWFS_ARG=''
	MDCONFIG_ARG=''
	MOUNT_ARG=''

	opt_detach=YES
	opt_softdep=YES
	opt_mdtype="swap"
	opt_norun=NO
	opt_debug=NO

	autounit=NO
	newfs=YES
	have_mdtype=NO
	suffix=''
	redirect='2>/dev/null'
}

main()
{
	init_vars
	parse_options ${1+"$@"}
	shift ${OPTC}

	if [ -z ${@+1} ]; then
		usage
	fi
	case $1 in
/dev/md[0-9]*|md[0-9]*)
						#unit=${1##*/}			# strip path
						unit=${1#*md*}			# strip md
						suffix=${unit##*[0-9]}	# get suffix (first non-digit)
						unit=${unit%%[^0-9]*} ;;# strip suffix
/dev/md|md|/dev/md[^0-9]*|md[^0-9]*)
						suffix=${1##*md}		# get suffix (first after md)
						unit=0
						autounit=YES ;;
					 *)	err 1 "bad device unit: $1" ;;
	esac

	shift

	if [ -z ${@+1} ]; then
		usage
	fi
	opt_mp=$1

	if checkyesno opt_softdep; then
		NEWFS_ARG="${NEWFS_ARG} -U"
	fi

	if ! checkyesno newfs && [ "${opt_mdtype}" != "vnode" ]; then
		err 1 "-P requires a vnode-backed disk"
	fi

	if checkyesno opt_detach && ! checkyesno autounit; then
		do_mdconfig_detach
	fi

	do_mdconfig_attach

	if checkyesno newfs; then
		do_newfs
	fi

	do_mount
	do_mpsetup
	exit 0
}

case ${0##*/} in
mount_mfs|mfs) mp_mode=01777 ;;
			*) ;;
esac
main ${1+"$@"}
Comment 2 Kris Kennaway 2007-03-11 09:25:34 UTC
On Thu, Mar 08, 2007 at 07:48:31AM +0000, Alex Kozlov wrote:

> >Description:
> Drop-in replacement for a mdmfs written in shell

Why?

Kris
Comment 3 Alex Kozlov freebsd_committer freebsd_triage 2012-08-24 06:54:33 UTC
Responsible Changed
From-To: freebsd-bugs->ak

I'll take it.
Comment 4 Alex Kozlov freebsd_committer freebsd_triage 2012-08-24 06:55:52 UTC
State Changed
From-To: open->closed

Unlikely to happen.