From nobody@FreeBSD.org  Thu Mar  8 07:48:31 2007
Return-Path: <nobody@FreeBSD.org>
Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52])
	by hub.freebsd.org (Postfix) with ESMTP id 7D76216A401
	for <freebsd-gnats-submit@FreeBSD.org>; Thu,  8 Mar 2007 07:48:31 +0000 (UTC)
	(envelope-from nobody@FreeBSD.org)
Received: from www.freebsd.org (www.freebsd.org [69.147.83.33])
	by mx1.freebsd.org (Postfix) with ESMTP id 6D7C113C48D
	for <freebsd-gnats-submit@FreeBSD.org>; Thu,  8 Mar 2007 07:48:31 +0000 (UTC)
	(envelope-from nobody@FreeBSD.org)
Received: from www.freebsd.org (localhost [127.0.0.1])
	by www.freebsd.org (8.13.1/8.13.1) with ESMTP id l287mVLv023241
	for <freebsd-gnats-submit@FreeBSD.org>; Thu, 8 Mar 2007 07:48:31 GMT
	(envelope-from nobody@www.freebsd.org)
Received: (from nobody@localhost)
	by www.freebsd.org (8.13.1/8.13.1/Submit) id l287mVP7023239;
	Thu, 8 Mar 2007 07:48:31 GMT
	(envelope-from nobody)
Message-Id: <200703080748.l287mVP7023239@www.freebsd.org>
Date: Thu, 8 Mar 2007 07:48:31 GMT
From: Alex Kozlov<spam@rm-rf.kiev.ua>
To: freebsd-gnats-submit@FreeBSD.org
Subject: [patch] rewrite of mdmfs in shell
X-Send-Pr-Version: www-3.0

>Number:         110068
>Category:       bin
>Synopsis:       [patch] rewrite of mdmfs(8) in shell
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    ak
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Thu Mar 08 07:50:09 GMT 2007
>Closed-Date:    Fri Aug 24 05:55:52 UTC 2012
>Last-Modified:  Fri Aug 24 05:55:52 UTC 2012
>Originator:     Alex Kozlov
>Release:        FreeBSD 6.2
>Organization:
private
>Environment:
>Description:
Drop-in replacement for a mdmfs written in shell
>How-To-Repeat:

>Fix:


Patch attached with submission follows:

#!/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##*/} [-DLlMNPSUX] [-a maxcontig] [-b block-size]"
	echo "		 [-d rotdelay] [-e maxbpg] [-F file] [-f frag-size] [-i bytes]"
	echo "		 [-e maxbpg] [-F file] [-f frag-size] [-i bytes] [-m percent-free]"
	echo "		 [-p permissions] [-s size] [-v version] [-w user:group]"
	echo "		 tmd-device mount-point"
	exit 1
}

parse_options()
{
	local OPT OPTARG OPTIND

	while getopts a:b:Cc:Dd:E:e:F:f:hi:LlMm:Nn:O: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#*:} ;;
					  *)	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'
	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+"$@"}

>Release-Note:
>Audit-Trail:

From: Alex Kozlov <spam@rm-rf.kiev.ua>
To: bug-followup@FreeBSD.org, spam@rm-rf.kiev.ua
Cc:  
Subject: Re: bin/110068: [patch] rewrite of mdmfs in shell
Date: Sun, 11 Mar 2007 06:54:22 +0200

 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+"$@"}

From: Kris Kennaway <kris@obsecurity.org>
To: Alex Kozlov <spam@rm-rf.kiev.ua>
Cc: freebsd-gnats-submit@FreeBSD.org
Subject: Re: bin/110068: [patch] rewrite of mdmfs in shell
Date: Sun, 11 Mar 2007 05:25:34 -0400

 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
Responsible-Changed-From-To: freebsd-bugs->ak 
Responsible-Changed-By: ak 
Responsible-Changed-When: Fri Aug 24 05:54:33 UTC 2012 
Responsible-Changed-Why:  
I'll take it. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=110068 
State-Changed-From-To: open->closed 
State-Changed-By: ak 
State-Changed-When: Fri Aug 24 05:55:52 UTC 2012 
State-Changed-Why:  
Unlikely to happen. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=110068 
>Unformatted:
