summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Reisner <dreisner@archlinux.org>2011-07-23 22:21:35 -0400
committerDave Reisner <dreisner@archlinux.org>2011-07-24 10:24:50 -0400
commite6c21e612838581c53c7742eb6071697f2d9e5a3 (patch)
treed5dee48319db29f6578cbef21adc763f28607856
parent1f358f911a0237f4224169c4d225a9ae306e0853 (diff)
arch-tmpfiles: add new script to handle volatile file control
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@archlinux.org>
-rw-r--r--Makefile13
-rwxr-xr-xarch-tmpfiles156
-rw-r--r--functions7
-rw-r--r--tmpfiles.conf20
4 files changed, 190 insertions, 6 deletions
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..b80aafa
--- /dev/null
+++ b/arch-tmpfiles
@@ -0,0 +1,156 @@
+#!/bin/bash
+#
+# /usr/lib/initscripts/arch-tmpfiles
+#
+# Control 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
+ find "$path" -mindepth 1 -maxdepth 1 -xdev -print0 | xargs -r0 rm -rf
+ 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 path
+ 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 path
+ 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 meaningful
+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.
+# `/run/tmpfiles/foo.conf' will always be read after `/etc/tmpfiles.d/bar.conf'
+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:
diff --git a/functions b/functions
index 1cfcf28..16cf898 100644
--- a/functions
+++ b/functions
@@ -420,16 +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
- stat_done
+ /usr/lib/initscripts/arch-tmpfiles && stat_done || stat_fail
}
bootlogd_stop() {
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
+