| #!/bin/sh |
| ### BEGIN INIT INFO |
| # Provides: volatile |
| # Required-Start: $local_fs |
| # Required-Stop: $local_fs |
| # Default-Start: S |
| # Default-Stop: |
| # Short-Description: Populate the volatile filesystem |
| ### END INIT INFO |
| |
| # Get ROOT_DIR |
| DIRNAME="$(dirname "$0")" |
| ROOT_DIR="$(echo "$DIRNAME" | sed -ne 's:/etc/.*::p')" |
| |
| [ -e "${ROOT_DIR}/etc/default/rcS" ] && . "${ROOT_DIR}/etc/default/rcS" |
| # When running populate-volatile.sh at rootfs time, disable cache. |
| [ -n "$ROOT_DIR" ] && VOLATILE_ENABLE_CACHE=no |
| # If rootfs is read-only, disable cache. |
| [ "$ROOTFS_READ_ONLY" = "yes" ] && VOLATILE_ENABLE_CACHE=no |
| |
| CFGDIR="${ROOT_DIR}/etc/default/volatiles" |
| TMPROOT="${ROOT_DIR}/var/volatile/tmp" |
| COREDEF="00_core" |
| |
| [ "${VERBOSE}" != "no" ] && echo "Populating volatile Filesystems." |
| |
| create_file() { |
| EXEC="" |
| if [ -z "$2" ]; then |
| EXEC=" |
| touch \"$1\"; |
| " |
| else |
| EXEC=" |
| cp \"$2\" \"$1\"; |
| " |
| fi |
| EXEC=" |
| ${EXEC} |
| chown ${TUSER}:${TGROUP} $1 || echo \"Failed to set owner -${TUSER}- for -$1-.\"; |
| chmod ${TMODE} $1 || echo \"Failed to set mode -${TMODE}- for -$1-.\" " |
| |
| test "$VOLATILE_ENABLE_CACHE" = yes && echo "$EXEC" >> /etc/volatile.cache.build |
| |
| if [ -e "$1" ]; then |
| [ "${VERBOSE}" != "no" ] && echo "Target already exists. Skipping." |
| else |
| if [ -z "$ROOT_DIR" ]; then |
| eval "$EXEC" |
| else |
| # Creating some files at rootfs time may fail and should fail, |
| # but these failures should not be logged to make sure the do_rootfs |
| # process doesn't fail. This does no harm, as this script will |
| # run on target to set up the correct files and directories. |
| eval "$EXEC" > /dev/null 2>&1 |
| fi |
| fi |
| } |
| |
| mk_dir() { |
| EXEC=" |
| mkdir -p \"$1\"; |
| chown ${TUSER}:${TGROUP} $1 || echo \"Failed to set owner -${TUSER}- for -$1-.\"; |
| chmod ${TMODE} $1 || echo \"Failed to set mode -${TMODE}- for -$1-.\" " |
| |
| test "$VOLATILE_ENABLE_CACHE" = yes && echo "$EXEC" >> /etc/volatile.cache.build |
| if [ -e "$1" ]; then |
| [ "${VERBOSE}" != "no" ] && echo "Target already exists. Skipping." |
| else |
| if [ -z "$ROOT_DIR" ]; then |
| eval "$EXEC" |
| else |
| # For the same reason with create_file(), failures should |
| # not be logged. |
| eval "$EXEC" > /dev/null 2>&1 |
| fi |
| fi |
| } |
| |
| link_file() { |
| EXEC=" |
| if [ -L \"$2\" ]; then |
| [ \"\$(readlink \"$2\")\" != \"$1\" ] && { rm -f \"$2\"; ln -sf \"$1\" \"$2\"; }; |
| elif [ -d \"$2\" ]; then |
| if awk '\$2 == \"$2\" {exit 1}' /proc/mounts; then |
| cp -a $2/* $1 2>/dev/null; |
| cp -a $2/.[!.]* $1 2>/dev/null; |
| rm -rf \"$2\"; |
| ln -sf \"$1\" \"$2\"; |
| fi |
| else |
| ln -sf \"$1\" \"$2\"; |
| fi |
| " |
| |
| test "$VOLATILE_ENABLE_CACHE" = yes && echo " $EXEC" >> /etc/volatile.cache.build |
| |
| if [ -z "$ROOT_DIR" ]; then |
| eval "$EXEC" |
| else |
| # For the same reason with create_file(), failures should |
| # not be logged. |
| eval "$EXEC" > /dev/null 2>&1 |
| fi |
| } |
| |
| check_requirements() { |
| cleanup() { |
| rm "${TMP_INTERMED}" |
| rm "${TMP_DEFINED}" |
| rm "${TMP_COMBINED}" |
| } |
| |
| CFGFILE="$1" |
| |
| TMP_INTERMED="${TMPROOT}/tmp.$$" |
| TMP_DEFINED="${TMPROOT}/tmpdefined.$$" |
| TMP_COMBINED="${TMPROOT}/tmpcombined.$$" |
| |
| sed 's@\(^:\)*:.*@\1@' "${ROOT_DIR}/etc/passwd" | sort | uniq > "${TMP_DEFINED}" |
| grep -v "^#" "${CFGFILE}" | cut -s -d " " -f 2 > "${TMP_INTERMED}" |
| cat "${TMP_DEFINED}" "${TMP_INTERMED}" | sort | uniq > "${TMP_COMBINED}" |
| NR_DEFINED_USERS="$(wc -l < "${TMP_DEFINED}")" |
| NR_COMBINED_USERS="$(wc -l < "${TMP_COMBINED}")" |
| |
| [ "${NR_DEFINED_USERS}" -ne "${NR_COMBINED_USERS}" ] && { |
| echo "Undefined users:" |
| diff "${TMP_DEFINED}" "${TMP_COMBINED}" | grep "^>" |
| cleanup |
| return 1 |
| } |
| |
| |
| sed 's@\(^:\)*:.*@\1@' "${ROOT_DIR}/etc/group" | sort | uniq > "${TMP_DEFINED}" |
| grep -v "^#" "${CFGFILE}" | cut -s -d " " -f 3 > "${TMP_INTERMED}" |
| cat "${TMP_DEFINED}" "${TMP_INTERMED}" | sort | uniq > "${TMP_COMBINED}" |
| |
| NR_DEFINED_GROUPS="$(wc -l < "${TMP_DEFINED}")" |
| NR_COMBINED_GROUPS="$(wc -l < "${TMP_COMBINED}")" |
| |
| [ "${NR_DEFINED_GROUPS}" -ne "${NR_COMBINED_GROUPS}" ] && { |
| echo "Undefined groups:" |
| diff "${TMP_DEFINED}" "${TMP_COMBINED}" | grep "^>" |
| cleanup |
| return 1 |
| } |
| |
| # Add checks for required directories here |
| |
| cleanup |
| return 0 |
| } |
| |
| apply_cfgfile() { |
| CFGFILE="$1" |
| SKIP_REQUIREMENTS="$2" |
| |
| [ "${VERBOSE}" != "no" ] && echo "Applying ${CFGFILE}" |
| |
| [ "${SKIP_REQUIREMENTS}" = "yes" ] || check_requirements "${CFGFILE}" || { |
| echo "Skipping ${CFGFILE}" |
| return 1 |
| } |
| |
| sed 's/#.*//' "${CFGFILE}" | \ |
| while read -r TTYPE TUSER TGROUP TMODE TNAME TLTARGET; do |
| test -z "${TLTARGET}" && continue |
| TNAME=${ROOT_DIR}${TNAME} |
| [ "${VERBOSE}" != "no" ] && echo "Checking for -${TNAME}-." |
| |
| [ "${TTYPE}" = "l" ] && { |
| TSOURCE="$TLTARGET" |
| [ "${VERBOSE}" != "no" ] && echo "Creating link -${TNAME}- pointing to -${TSOURCE}-." |
| link_file "${TSOURCE}" "${TNAME}" |
| continue |
| } |
| |
| [ "${TTYPE}" = "b" ] && { |
| TSOURCE="$TLTARGET" |
| [ "${VERBOSE}" != "no" ] && echo "Creating mount-bind -${TNAME}- from -${TSOURCE}-." |
| mount --bind "${TSOURCE}" "${TNAME}" |
| EXEC=" |
| mount --bind \"${TSOURCE}\" \"${TNAME}\"" |
| test "$VOLATILE_ENABLE_CACHE" = yes && echo "$EXEC" >> /etc/volatile.cache.build |
| continue |
| } |
| |
| [ -L "${TNAME}" ] && { |
| [ "${VERBOSE}" != "no" ] && echo "Found link." |
| NEWNAME=$(ls -l "${TNAME}" | sed -e 's/^.*-> \(.*\)$/\1/') |
| if echo "${NEWNAME}" | grep -v "^/" >/dev/null; then |
| TNAME="$(echo "${TNAME}" | sed -e 's@\(.*\)/.*@\1@')/${NEWNAME}" |
| [ "${VERBOSE}" != "no" ] && echo "Converted relative linktarget to absolute path -${TNAME}-." |
| else |
| TNAME="${NEWNAME}" |
| [ "${VERBOSE}" != "no" ] && echo "Using absolute link target -${TNAME}-." |
| fi |
| } |
| |
| case "${TTYPE}" in |
| "f") [ "${VERBOSE}" != "no" ] && echo "Creating file -${TNAME}-." |
| TSOURCE="$TLTARGET" |
| [ "${TSOURCE}" = "none" ] && TSOURCE="" |
| create_file "${TNAME}" "${TSOURCE}" |
| ;; |
| "d") [ "${VERBOSE}" != "no" ] && echo "Creating directory -${TNAME}-." |
| mk_dir "${TNAME}" |
| # Add check to see if there's an entry in fstab to mount. |
| ;; |
| *) [ "${VERBOSE}" != "no" ] && echo "Invalid type -${TTYPE}-." |
| continue |
| ;; |
| esac |
| done |
| return 0 |
| } |
| |
| clearcache=0 |
| exec 9</proc/cmdline |
| while read -r line <&9 |
| do |
| case "$line" in |
| *clearcache*) clearcache=1 |
| ;; |
| *) continue |
| ;; |
| esac |
| done |
| exec 9>&- |
| |
| if test -e "${ROOT_DIR}/etc/volatile.cache" -a "$VOLATILE_ENABLE_CACHE" = "yes" -a "x$1" != "xupdate" -a "x$clearcache" = "x0" |
| then |
| sh "${ROOT_DIR}/etc/volatile.cache" |
| else |
| rm -f "${ROOT_DIR}/etc/volatile.cache" "${ROOT_DIR}/etc/volatile.cache.build" |
| |
| # Apply the core file with out checking requirements. ${TMPROOT} is |
| # needed by check_requirements but is setup by this file, so it must be |
| # processed first and without being checked. |
| [ -e "${CFGDIR}/${COREDEF}" ] && apply_cfgfile "${CFGDIR}/${COREDEF}" "yes" |
| |
| # Fast path: check_requirements is slow and most of the time doesn't |
| # find any problems. If there are a lot of config files, it is much |
| # faster to to concatenate them all together and process them once to |
| # avoid the overhead of calling check_requirements repeatedly |
| TMP_FILE="${TMPROOT}/tmp_volatile.$$" |
| rm -f "$TMP_FILE" |
| |
| CFGFILES="$(ls -1 "${CFGDIR}" | grep -v "^${COREDEF}\$" | sort)" |
| for file in ${CFGFILES}; do |
| cat "${CFGDIR}/${file}" >> "$TMP_FILE" |
| done |
| |
| if check_requirements "$TMP_FILE" |
| then |
| apply_cfgfile "$TMP_FILE" "yes" |
| else |
| # Slow path: One or more config files failed requirements. |
| # Process each one individually so the offending one can be |
| # skipped |
| for file in ${CFGFILES}; do |
| apply_cfgfile "${CFGDIR}/${file}" |
| done |
| fi |
| rm "$TMP_FILE" |
| |
| [ -e "${ROOT_DIR}/etc/volatile.cache.build" ] && sync && mv "${ROOT_DIR}/etc/volatile.cache.build" "${ROOT_DIR}/etc/volatile.cache" |
| fi |
| |
| if [ -z "${ROOT_DIR}" ] && [ -f /etc/ld.so.cache ] && [ ! -f /var/run/ld.so.cache ] |
| then |
| ln -s /etc/ld.so.cache /var/run/ld.so.cache |
| fi |