1#!/bin/sh 2### BEGIN INIT INFO 3# Provides: volatile 4# Required-Start: $local_fs 5# Required-Stop: $local_fs 6# Default-Start: S 7# Default-Stop: 8# Short-Description: Populate the volatile filesystem 9### END INIT INFO 10 11# Get ROOT_DIR 12DIRNAME="$(dirname "$0")" 13ROOT_DIR="$(echo "$DIRNAME" | sed -ne 's:/etc/.*::p')" 14 15[ -e "${ROOT_DIR}/etc/default/rcS" ] && . "${ROOT_DIR}/etc/default/rcS" 16# When running populate-volatile.sh at rootfs time, disable cache. 17[ -n "$ROOT_DIR" ] && VOLATILE_ENABLE_CACHE=no 18# If rootfs is read-only, disable cache. 19[ "$ROOTFS_READ_ONLY" = "yes" ] && VOLATILE_ENABLE_CACHE=no 20 21CFGDIR="${ROOT_DIR}/etc/default/volatiles" 22TMPROOT="${ROOT_DIR}/var/volatile/tmp" 23COREDEF="00_core" 24 25[ "${VERBOSE}" != "no" ] && echo "Populating volatile Filesystems." 26 27create_file() { 28 EXEC="" 29 if [ -z "$2" ]; then 30 EXEC=" 31 touch \"$1\"; 32 " 33 else 34 EXEC=" 35 cp \"$2\" \"$1\"; 36 " 37 fi 38 EXEC=" 39 ${EXEC} 40 chown ${TUSER}:${TGROUP} $1 || echo \"Failed to set owner -${TUSER}- for -$1-.\"; 41 chmod ${TMODE} $1 || echo \"Failed to set mode -${TMODE}- for -$1-.\" " 42 43 test "$VOLATILE_ENABLE_CACHE" = yes && echo "$EXEC" >> /etc/volatile.cache.build 44 45 if [ -e "$1" ]; then 46 [ "${VERBOSE}" != "no" ] && echo "Target already exists. Skipping." 47 else 48 if [ -z "$ROOT_DIR" ]; then 49 eval "$EXEC" 50 else 51 # Creating some files at rootfs time may fail and should fail, 52 # but these failures should not be logged to make sure the do_rootfs 53 # process doesn't fail. This does no harm, as this script will 54 # run on target to set up the correct files and directories. 55 eval "$EXEC" > /dev/null 2>&1 56 fi 57 fi 58} 59 60mk_dir() { 61 EXEC=" 62 mkdir -p \"$1\"; 63 chown ${TUSER}:${TGROUP} $1 || echo \"Failed to set owner -${TUSER}- for -$1-.\"; 64 chmod ${TMODE} $1 || echo \"Failed to set mode -${TMODE}- for -$1-.\" " 65 66 test "$VOLATILE_ENABLE_CACHE" = yes && echo "$EXEC" >> /etc/volatile.cache.build 67 if [ -e "$1" ]; then 68 [ "${VERBOSE}" != "no" ] && echo "Target already exists. Skipping." 69 else 70 if [ -z "$ROOT_DIR" ]; then 71 eval "$EXEC" 72 else 73 # For the same reason with create_file(), failures should 74 # not be logged. 75 eval "$EXEC" > /dev/null 2>&1 76 fi 77 fi 78} 79 80link_file() { 81 EXEC=" 82 if [ -L \"$2\" ]; then 83 [ \"\$(readlink \"$2\")\" != \"$1\" ] && { rm -f \"$2\"; ln -sf \"$1\" \"$2\"; }; 84 elif [ -d \"$2\" ]; then 85 if awk '\$2 == \"$2\" {exit 1}' /proc/mounts; then 86 cp -a $2/* $1 2>/dev/null; 87 cp -a $2/.[!.]* $1 2>/dev/null; 88 rm -rf \"$2\"; 89 ln -sf \"$1\" \"$2\"; 90 fi 91 else 92 ln -sf \"$1\" \"$2\"; 93 fi 94 " 95 96 test "$VOLATILE_ENABLE_CACHE" = yes && echo " $EXEC" >> /etc/volatile.cache.build 97 98 if [ -z "$ROOT_DIR" ]; then 99 eval "$EXEC" 100 else 101 # For the same reason with create_file(), failures should 102 # not be logged. 103 eval "$EXEC" > /dev/null 2>&1 104 fi 105} 106 107check_requirements() { 108 cleanup() { 109 rm "${TMP_INTERMED}" 110 rm "${TMP_DEFINED}" 111 rm "${TMP_COMBINED}" 112 } 113 114 CFGFILE="$1" 115 116 TMP_INTERMED="${TMPROOT}/tmp.$$" 117 TMP_DEFINED="${TMPROOT}/tmpdefined.$$" 118 TMP_COMBINED="${TMPROOT}/tmpcombined.$$" 119 120 sed 's@\(^:\)*:.*@\1@' "${ROOT_DIR}/etc/passwd" | sort | uniq > "${TMP_DEFINED}" 121 grep -v "^#" "${CFGFILE}" | cut -s -d " " -f 2 > "${TMP_INTERMED}" 122 cat "${TMP_DEFINED}" "${TMP_INTERMED}" | sort | uniq > "${TMP_COMBINED}" 123 NR_DEFINED_USERS="$(wc -l < "${TMP_DEFINED}")" 124 NR_COMBINED_USERS="$(wc -l < "${TMP_COMBINED}")" 125 126 [ "${NR_DEFINED_USERS}" -ne "${NR_COMBINED_USERS}" ] && { 127 echo "Undefined users:" 128 diff "${TMP_DEFINED}" "${TMP_COMBINED}" | grep "^>" 129 cleanup 130 return 1 131 } 132 133 134 sed 's@\(^:\)*:.*@\1@' "${ROOT_DIR}/etc/group" | sort | uniq > "${TMP_DEFINED}" 135 grep -v "^#" "${CFGFILE}" | cut -s -d " " -f 3 > "${TMP_INTERMED}" 136 cat "${TMP_DEFINED}" "${TMP_INTERMED}" | sort | uniq > "${TMP_COMBINED}" 137 138 NR_DEFINED_GROUPS="$(wc -l < "${TMP_DEFINED}")" 139 NR_COMBINED_GROUPS="$(wc -l < "${TMP_COMBINED}")" 140 141 [ "${NR_DEFINED_GROUPS}" -ne "${NR_COMBINED_GROUPS}" ] && { 142 echo "Undefined groups:" 143 diff "${TMP_DEFINED}" "${TMP_COMBINED}" | grep "^>" 144 cleanup 145 return 1 146 } 147 148 # Add checks for required directories here 149 150 cleanup 151 return 0 152} 153 154apply_cfgfile() { 155 CFGFILE="$1" 156 SKIP_REQUIREMENTS="$2" 157 158 [ "${VERBOSE}" != "no" ] && echo "Applying ${CFGFILE}" 159 160 [ "${SKIP_REQUIREMENTS}" = "yes" ] || check_requirements "${CFGFILE}" || { 161 echo "Skipping ${CFGFILE}" 162 return 1 163 } 164 165 sed 's/#.*//' "${CFGFILE}" | \ 166 while read -r TTYPE TUSER TGROUP TMODE TNAME TLTARGET; do 167 test -z "${TLTARGET}" && continue 168 TNAME=${ROOT_DIR}${TNAME} 169 [ "${VERBOSE}" != "no" ] && echo "Checking for -${TNAME}-." 170 171 [ "${TTYPE}" = "l" ] && { 172 TSOURCE="$TLTARGET" 173 [ "${VERBOSE}" != "no" ] && echo "Creating link -${TNAME}- pointing to -${TSOURCE}-." 174 link_file "${TSOURCE}" "${TNAME}" 175 continue 176 } 177 178 [ "${TTYPE}" = "b" ] && { 179 TSOURCE="$TLTARGET" 180 [ "${VERBOSE}" != "no" ] && echo "Creating mount-bind -${TNAME}- from -${TSOURCE}-." 181 mount --bind "${TSOURCE}" "${TNAME}" 182 EXEC=" 183 mount --bind \"${TSOURCE}\" \"${TNAME}\"" 184 test "$VOLATILE_ENABLE_CACHE" = yes && echo "$EXEC" >> /etc/volatile.cache.build 185 continue 186 } 187 188 [ -L "${TNAME}" ] && { 189 [ "${VERBOSE}" != "no" ] && echo "Found link." 190 NEWNAME=$(ls -l "${TNAME}" | sed -e 's/^.*-> \(.*\)$/\1/') 191 if echo "${NEWNAME}" | grep -v "^/" >/dev/null; then 192 TNAME="$(echo "${TNAME}" | sed -e 's@\(.*\)/.*@\1@')/${NEWNAME}" 193 [ "${VERBOSE}" != "no" ] && echo "Converted relative linktarget to absolute path -${TNAME}-." 194 else 195 TNAME="${NEWNAME}" 196 [ "${VERBOSE}" != "no" ] && echo "Using absolute link target -${TNAME}-." 197 fi 198 } 199 200 case "${TTYPE}" in 201 "f") [ "${VERBOSE}" != "no" ] && echo "Creating file -${TNAME}-." 202 TSOURCE="$TLTARGET" 203 [ "${TSOURCE}" = "none" ] && TSOURCE="" 204 create_file "${TNAME}" "${TSOURCE}" 205 ;; 206 "d") [ "${VERBOSE}" != "no" ] && echo "Creating directory -${TNAME}-." 207 mk_dir "${TNAME}" 208 # Add check to see if there's an entry in fstab to mount. 209 ;; 210 *) [ "${VERBOSE}" != "no" ] && echo "Invalid type -${TTYPE}-." 211 continue 212 ;; 213 esac 214 done 215 return 0 216} 217 218clearcache=0 219exec 9</proc/cmdline 220while read -r line <&9 221do 222 case "$line" in 223 *clearcache*) clearcache=1 224 ;; 225 *) continue 226 ;; 227 esac 228done 229exec 9>&- 230 231if test -e "${ROOT_DIR}/etc/volatile.cache" -a "$VOLATILE_ENABLE_CACHE" = "yes" -a "x$1" != "xupdate" -a "x$clearcache" = "x0" 232then 233 sh "${ROOT_DIR}/etc/volatile.cache" 234else 235 rm -f "${ROOT_DIR}/etc/volatile.cache" "${ROOT_DIR}/etc/volatile.cache.build" 236 237 # Apply the core file with out checking requirements. ${TMPROOT} is 238 # needed by check_requirements but is setup by this file, so it must be 239 # processed first and without being checked. 240 [ -e "${CFGDIR}/${COREDEF}" ] && apply_cfgfile "${CFGDIR}/${COREDEF}" "yes" 241 242 # Fast path: check_requirements is slow and most of the time doesn't 243 # find any problems. If there are a lot of config files, it is much 244 # faster to to concatenate them all together and process them once to 245 # avoid the overhead of calling check_requirements repeatedly 246 TMP_FILE="${TMPROOT}/tmp_volatile.$$" 247 rm -f "$TMP_FILE" 248 249 CFGFILES="$(ls -1 "${CFGDIR}" | grep -v "^${COREDEF}\$" | sort)" 250 for file in ${CFGFILES}; do 251 cat "${CFGDIR}/${file}" >> "$TMP_FILE" 252 done 253 254 if check_requirements "$TMP_FILE" 255 then 256 apply_cfgfile "$TMP_FILE" "yes" 257 else 258 # Slow path: One or more config files failed requirements. 259 # Process each one individually so the offending one can be 260 # skipped 261 for file in ${CFGFILES}; do 262 apply_cfgfile "${CFGDIR}/${file}" 263 done 264 fi 265 rm "$TMP_FILE" 266 267 [ -e "${ROOT_DIR}/etc/volatile.cache.build" ] && sync && mv "${ROOT_DIR}/etc/volatile.cache.build" "${ROOT_DIR}/etc/volatile.cache" 268fi 269 270if [ -z "${ROOT_DIR}" ] && [ -f /etc/ld.so.cache ] && [ ! -f /var/run/ld.so.cache ] 271then 272 ln -s /etc/ld.so.cache /var/run/ld.so.cache 273fi 274