[arch-projects] [initscripts][PATCH] arch-tmpfiles: add new script to handle volatile file control

Kurt J. Bosch kjb-temp-2009 at alpenjodel.de
Sun Jul 24 08:17:18 EDT 2011


Dave Reisner, 2011-07-24 05:10:
> This is the same concept as systemd's tmpfiles handling, slightly
> simplified to avoid timed re-triggering of file cleaning. Most of our
> current file cleaning that takes place in rc.single and rc.sysinit is
> replaced by this, with the exception that we hold onto the /var/lock and
> /var/run for finer control, since we still check for the possibility of
> these directories being symlinks and adjust accordingly.
>
> Signed-off-by: Dave Reisner<dreisner at archlinux.org>
> ---
> Tom and I talked about this tonight and I volunteered to hack it up. It's a
> simple but fairly substantial framework for handling temporary files and
> directories which is compatible with systemd. For more detail, see the man
> page[1], but I've taken most of the relevant bits and added them to the main
> tmpfiles script as documentation. It should be fairly self explanatory.
>
> [1] http://0pointer.de/public/systemd-man/tmpfiles.d.html
>
>   Makefile      |   13 ++++-
>   arch-tmpfiles |  156 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>   functions     |    6 +--
>   tmpfiles.conf |   20 +++++++
>   4 files changed, 190 insertions(+), 5 deletions(-)
>   create mode 100755 arch-tmpfiles
>   create mode 100644 tmpfiles.conf
>
> diff --git a/Makefile b/Makefile
> index c568b13..9fd2347 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -1,5 +1,14 @@
>   VER  := $(shell git describe)
> -DIRS := /etc/rc.d /etc/conf.d /etc/rc.d/functions.d /etc/logrotate.d /sbin /etc/bash_completion.d /usr/share/zsh/site-functions
> +DIRS := \
> +	/etc/rc.d \
> +	/etc/conf.d \
> +	/etc/rc.d/functions.d \
> +	/etc/logrotate.d \
> +	/sbin \
> +	/usr/lib/tmpfiles.d \
> +	/usr/lib/initscripts \
> +	/etc/bash_completion.d \
> +	/usr/share/zsh/site-functions
>
>   minilogd: minilogd.o
>
> @@ -13,6 +22,8 @@ install: minilogd installdirs
>   	install -m644 -t $(DESTDIR)/etc/rc.d functions
>   	install -m755 -t $(DESTDIR)/etc/rc.d hwclock network netfs
>   	install -m755 -t $(DESTDIR)/sbin minilogd rc.d
> +	install -m755 -t $(DESTDIR)/usr/lib/initscripts arch-tmpfiles
> +	install -m644 tmpfiles.conf $(DESTDIR)/usr/lib/tmpfiles.d/arch.conf
>   	install -m644 -T bash-completion $(DESTDIR)/etc/bash_completion.d/rc.d
>   	install -m644 -T zsh-completion $(DESTDIR)/usr/share/zsh/site-functions/_rc.d
>
> diff --git a/arch-tmpfiles b/arch-tmpfiles
> new file mode 100755
> index 0000000..194a44b
> --- /dev/null
> +++ b/arch-tmpfiles
> @@ -0,0 +1,156 @@
> +#!/bin/bash
> +#
> +# /usr/lib/initscripts/tmpfiles
> +#
> +# Control of creation, deletion, and cleaning of volatile and temporary files
> +#
> +
> +_f() {
> +	# Create a file if it doesn't exist yet
> +	local path=$1 mode=$2 uid=$3 gid=$4
> +
> +	if [[ ! -e $path ]]; then
> +		install -m"$mode" -o"$uid" -g"$gid"<(:) "$path"
> +	fi
> +}
> +
> +_F() {
> +	# Create or truncate a file
> +	local path=$1 mode=$2 uid=$3 gid=$4
> +
> +	install -m"$mode" -o"$uid" -g"$gid"<(:) "$path"
> +}
> +
> +_d() {
> +	# Create a directory if it doesn't exist yet
> +	local path=$1 mode=$2 uid=$3 gid=$4
> +
> +	if [[ ! -d "$path" ]]; then
> +		install -d -m"$mode" -o"$uid" -g"$gid" "$path"
> +	fi
> +}
> +
> +_D() {
> +	# Create or empty a directory
> +	local path=$1 mode=$2 uid=$3 gid=$4
> +
> +	if [[ -d $path ]]; then
> +		(
> +			shopt -s dotglob
> +			rm --one-file-system -rf "$path"/*
> +		)
> +	fi
> +	install -d -m"$mode" -o"$uid" -g"$gid" "$path"
> +}
> +
> +_p() {
> +	# Create a named pipe (FIFO) if it doesn't exist yet
> +	local path=$1 mode=$2 uid=$3 gid=$4
> +
> +	if [[ ! -p "$path" ]]; then
> +		mkfifo -m$mode "$path"
> +		chown "$uid:$gid" "$path"
> +	fi
> +}
> +
> +_x() {
> +	# Ignore a path during cleaning. Use this type to exclude paths from clean-up as
> +	# controlled with the Age parameter. Note that lines of this type do not
> +	# influence the effect of r or R lines. Lines of this type accept shell-style
> +	# globs in place of of normal path names.
> +	:
> +	# XXX: we don't implement this
> +}
> +
> +_r() {
> +	# Remove a file or directory if it exists. This may not be used to remove
> +	# non-empty directories, use R for that. Lines of this type accept shell-style
> +	# globs in place of normal path names.
> +	local -a paths=($1)
> +
> +	for path in "${paths[@]}"; do
> +		if [[ -f $path ]]; then
> +			rm -f "$path"
> +		elif [[ -d $path ]]; then
> +			rmdir "$path"
> +		fi
> +	done
> +}
> +
> +_R() {
> +	# Recursively remove a path and all its subdirectories (if it is a directory).
> +	# Lines of this type accept shell-style globs in place of normal path names.
> +	local -a paths=($1)
> +
> +	for path in "${paths[@]}"; do
> +		[[ -d $path ]]&&  rm -rf --one-file-system "$path"
> +	done
> +}
> +
> +shopt -s nullglob
> +
> +# catch errors in functions so we can exit with something meaningfully
> +set -E
> +trap '(( ++error ))' ERR
> +
> +declare -i error=0
> +declare -A fragments
> +declare -a tmpfiles_d=(
> +	/usr/lib/tmpfiles.d/*.conf
> +	/etc/tmpfiles.d/*.conf
> +	/run/tmpfiles.d/*.conf
> +)
> +
> +# directories declared later in the tmpfiles_d array will override earlier
> +# directories, on a per file basis.
> +# Example: `/etc/tmpfiles.d/foo.conf' supersedes `/usr/lib/tmpfiles.d/foo.conf'.
> +for path in "${tmpfiles_d[@]}"; do
> +	fragments[${path##*/}]=${path%/*}
> +done
> +
> +# loop through the gathered fragments, sorted globally by filename
> +while read -d '' fragment; do
> +	declare -i i=0
> +
> +	printf -v file '%s/%s' "${fragments[$fragment]}" "$fragment"
> +
> +	### FILE FORMAT ###
> +	# XXX: We ignore the final 'Age' parameter
> +	# 0    1              2    3    4    5
> +	# Type Path           Mode UID  GID  Age
> +	# d    /run/user      0755 root root 10d
> +
> +	# omit read's -r flag to honor escapes here, so that whitespace can be
> +	# escaped for paths. We will _not_ honor quoted paths.
> +	while read -a line; do
> +		(( ++i ))
> +
> +		# skip over comments and empty lines
> +		if (( ! ${#line[*]} )) || [[ ${line[0]:0:1} = '#' ]]; then
> +			continue
> +		fi
> +
> +		# whine about invalid entries
> +		if ! type -t _${line[0]}>/dev/null; then
> +			printf "arch-tmpfiles: skipping malformed entry on line %d of \`%s'\n" "$i" "$file"
> +			(( ++error ))
> +			continue
> +		fi
> +
> +		# fall back on defaults when parameters are passed as '-'
> +		if [[ ${line[2]} = '-' ]]; then
> +			case ${line[0]} in
> +				p|f|F) line[2]=0644 ;;
> +				d|D) line[2]=0755 ;;
> +			esac
> +		fi
> +		[[ ${line[3]} = '-' ]]&&  line[3]=0
> +		[[ ${line[4]} = '-' ]]&&  line[4]=0
> +
> +		_${line[0]} "${line[@]:1}"
> +	done<"$file"
> +done<  <(printf '%s\0' "${!fragments[@]}" | sort -z)
> +
> +exit $error
> +
> +# vim: set ts=2 sw=2 noet:

There is no KISS any more in this world - nowhere. [whining]

> diff --git a/functions b/functions
> index 1cfcf28..a894a46 100644
> --- a/functions
> +++ b/functions
> @@ -420,15 +420,13 @@ mount_all() {
>
>   remove_leftover() {
>   	stat_busy "Removing Leftover Files"
> -		rm -rf /etc/{nologin,shutdownpid} /forcefsck /tmp/* /tmp/.[^.]* /tmp/..?* /var/run/daemons
> +		# handle this separately until we declare the non-symlinks obsoleted
>   		[[ ! -L /var/lock ]]&&  rm -rf /var/lock/*
>   		if [[ ! -L /var/run&&  -d /var/run ]]; then
>   			find /var/run/ \! -type d -delete
>   			ln -s /run/daemons /var/run/daemons
>   		fi
> -		install -Tm 0664 -o root -g utmp<(:) /var/run/utmp
> -		# Keep {x,k,g}dm happy with xorg
> -		mkdir -m 1777 /tmp/.{X11,ICE}-unix
> +		/usr/lib/initscripts/arch-tmpfiles || stat_fail
>   	stat_done

Might spit out [FAIL] *and* [DONE].

>   }
>
> diff --git a/tmpfiles.conf b/tmpfiles.conf
> new file mode 100644
> index 0000000..d47a028
> --- /dev/null
> +++ b/tmpfiles.conf
> @@ -0,0 +1,20 @@
> +#
> +# /usr/lib/tmpfiles.d/arch.conf
> +#
> +
> +d /tmp/.X11-unix 1777 root root 10d
> +d /tmp/.ICE-unix 1777 root root 10d
> +d /tmp/.XIM-unix 1777 root root 10d
> +d /tmp/.font-unix 1777 root root 10d
> +d /tmp/.Test-unix 1777 root root 10d
> +
> +f /var/run/tmp 0664 - utmp
> +
> +r /tmp/.X[0-9]-lock
> +r /etc/nologin
> +r /etc/shutdownpid
> +r /forcefsck
> +
> +D /tmp/
> +D /var/run/daemons
> +

-- 
Kurt


More information about the arch-projects mailing list