[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