Re: [PATCH] btrfs-progs: tests: Introduce expand_command() to inject aruguments more accurately

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Fri, Apr 03, 2020 at 07:20:16PM +0200, David Sterba wrote:
> On Mon, Mar 30, 2020 at 03:02:32PM +0800, Qu Wenruo wrote:
> > +# Temporary command array for building real command
> > +declare -a cmd_array
> 
> This gets declared only once when the script is sourced but there are
> numerous calls to 'unset cmd_array'. How does this interact?
> 
> The functions are called in the same shell level so this will unset and
> destroy the cmd_array, so it can't work after first use of eg.
> run_check. So there's some shell magic because this seems to work.

Adding some debugging prints before and after the cmd_array, the variable
exists at the beginning of expand_command and is destroyed after unset.

> > +expand_command()
> > +{
> > +	local command_index
> > +	local ins
> > +	local spec
> > +
> > +	ins=$(_get_spec_ins "$@")
> > +	spec=$(($ins-1))
> > +	spec=$(_cmd_spec "${@:$spec}")
> > +
> > +	if [ "$1" = 'root_helper' ] && _is_target_command "$2" ; then
> > +		command_index=2
> > +	elif _is_target_command "$1"  ; then
> > +		command_index=1
> > +	else
> > +		# Since we iterate from offset 1, this never get hit,
> > +		# thus we won't insert $INSTRUMENT
> > +		command_index=0
> > +	fi
> > +
> > +	for ((i = 1; i <= $#; i++ )); do
> > +		if [ $i -eq $command_index -a ! -z "$INSTRUMENT" ]; then
> > +			cmd_array+=("$INSTRUMENT")
> 
> This inserts the contents of INSTRUMENT as one value, that won't work
> eg. for INSTRUMENT='valgrind --tool=memcheck' or any extra parameters
> passed to valgrind or whatever other tool we'd like to use.

With unquoted $INSTRUMENT it does what I'd expect.

> > +		fi
> > +		if [ $i -eq $ins -a ! -z "$spec" ]; then
> > +			cmd_array+=("$spec")
> > +		fi
> > +		cmd_array+=("${!i}")
> > +
> > +	done
> > +}
> > +
> >  # Argument passing magic:
> >  # the command passed to run_* helpers is inspected, if there's 'btrfs command'
> >  # found and there are defined additional arguments, they're inserted just after
> > @@ -145,49 +202,28 @@ _cmd_spec()
> >  
> >  run_check()
> >  {
> > -	local spec
> > -	local ins
> > +	expand_command "$@"
> 
> The cmd_array should be reset before it's used to build a new command,
> not after.

unset cmd_array won't work here, but cmd_array=() resets the values and
does not destroy the variable.

> > +	echo "====== RUN CHECK ${cmd_array[@]}" >> "$RESULTS" 2>&1
> > +	if [[ $TEST_LOG =~ tty ]]; then echo "CMD: ${cmd_array[@]}" > /dev/tty; fi
> >  
> > -	ins=$(_get_spec_ins "$@")
> > -	spec=$(($ins-1))
> > -	spec=$(_cmd_spec "${@:$spec}")
> > -	set -- "${@:1:$(($ins-1))}" $spec "${@: $ins}"
> > -	echo "====== RUN CHECK $@" >> "$RESULTS" 2>&1
> > -	if [[ $TEST_LOG =~ tty ]]; then echo "CMD: $@" > /dev/tty; fi
> > -
> > -	# If the command is `root_helper` or mount/umount, don't call INSTRUMENT
> > -	# as most profiling tool like valgrind can't handle setuid/setgid/setcap
> > -	# which mount normally has.
> > -	# And since mount/umount is only called with run_check(), we don't need
> > -	# to do the same check on other run_*() functions.
> > -	if [ "$1" = 'root_helper' -o "$1" = 'mount' -o "$1" = 'umount' ]; then
> > -		"$@" >> "$RESULTS" 2>&1 || _fail "failed: $@"
> > -	else
> > -		$INSTRUMENT "$@" >> "$RESULTS" 2>&1 || _fail "failed: $@"
> > -	fi
> > +	"${cmd_array[@]}" >> "$RESULTS" 2>&1 || _fail "failed: ${cmd_array[@]}"
> > +	unset cmd_array 



[Index of Archives]     [Linux Filesystem Development]     [Linux NFS]     [Linux NILFS]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux