The rootfs package provides the root filesystem layout, essential files and symlinks, and base configuration files used in an LFS system.
While most of these directories and links were installed to the main LFS partition in Section 7.5, “Creating Directories” and Section 7.6, “Creating Essential Files and Symlinks”, they also need to be packaged and reinstalled. Additionally, other configuration files from Chapter 9 and parts of BLFS are included. Prepare the PKGBUILD for the rootfs package with the following commands:
mkdir /sources/rootfs
cd /sources/rootfs
cat > PKGBUILD << "REALEOF"
# Maintainer: Linux From Scratch <lfs-dev@lists.linuxfromscratch.org>
pkgname="rootfs"
pkgver="12.3"
pkgrel="1"
pkgdesc="Skeleton directory layout and core /etc and /var/log files for initial install"
arch=('any')
url="https://www.linuxfromscartch.org/"
license=('Creative Commons Attribution-NonCommercial-ShareAlike 4.0')
groups=('core')
options=('emptydirs')
backup=('etc/bashrc'
'etc/dircolors'
'etc/fstab'
'etc/group'
'etc/hosts'
'etc/inputrc'
'etc/ld.so.conf'
'etc/locale.conf'
'etc/passwd'
'etc/profile'
'etc/profile.d/bash_completion.sh'
'etc/profile.d/dircolors.sh'
'etc/profile.d/extrapaths.sh'
'etc/profile.d/readline.sh'
'etc/profile.d/umask.sh'
'etc/profile.d/i18n.sh'
'etc/skel/.bash_logout'
'etc/skel/.bash_profile'
'etc/skel/.bashrc'
'etc/skel/.profile'
'etc/shells'
'root/.bash_logout'
'root/.bash_profile'
'root/.bashrc'
'root/.profile'
'var/log/btmp'
'var/log/faillog'
'var/log/lastlog'
'var/log/wtmp')
package(){
# 4.2
install -vdm755 "${pkgdir}"/{etc,usr/{bin,lib,sbin},var}
ln -sfv usr/bin "${pkgdir}/bin"
ln -sfv usr/lib "${pkgdir}/lib"
ln -sfv usr/sbin "${pkgdir}/sbin"
install -vdm755 "${pkgdir}/lib64"
# 7.3
install -vdm755 "${pkgdir}"/{dev,proc,run,sys}
# 7.5
install -vdm755 "${pkgdir}"/{boot,home,mnt,opt,srv}
install -vdm755 "${pkgdir}"/etc/{opt,sysconfig}
install -vdm755 "${pkgdir}"/lib/firmware
install -vdm755 "${pkgdir}"/media/{floppy,cdrom}
install -vdm755 "${pkgdir}"/usr/{,local/}{include,src}
install -vdm755 "${pkgdir}"/usr/lib/locale
install -vdm755 "${pkgdir}"/usr/local/{bin,lib,sbin}
install -vdm755 "${pkgdir}"/usr/{,local/}share/{color,dict,doc,info,locale,man}
install -vdm755 "${pkgdir}"/usr/{,local/}share/{misc,terminfo,zoneinfo}
install -vdm755 "${pkgdir}"/usr/{,local/}share/man/man{1..8}
install -vdm755 "${pkgdir}"/var/{cache,local,log,mail,opt,spool}
install -vdm755 "${pkgdir}"/var/lib/{color,misc,locate}
install -vdm750 "${pkgdir}"/root
install -vdm1777 "${pkgdir}"{,/var}/tmp
ln -sfv /run "${pkgdir}/var/run"
ln -sfv /run/lock "${pkgdir}/var/lock"
# 7.6
ln -sv /proc/self/mounts "${pkgdir}/etc/mtab"
REALEOF
Need to break up for SysV and systemd:
cat >> PKGBUILD << "REALEOF"
cat > "${pkgdir}/etc/passwd" << "EOF"
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/dev/null:/usr/bin/false
daemon:x:6:6:Daemon User:/dev/null:/usr/bin/false
messagebus:x:18:18:D-Bus Message Daemon User:/run/dbus:/usr/bin/false
uuidd:x:80:80:UUID Generation Daemon User:/dev/null:/usr/bin/false
pacman:x:102:102:Pacman Packaging User:/home/pacman:/bin/bash
nobody:x:65534:65534:Unprivileged User:/dev/null:/usr/bin/false
EOF
cat > "${pkgdir}/etc/group" << "EOF"
root:x:0:
bin:x:1:daemon
sys:x:2:
kmem:x:3:
tape:x:4:
tty:x:5:
daemon:x:6:
floppy:x:7:
disk:x:8:
lp:x:9:
dialout:x:10:
audio:x:11:
video:x:12:
utmp:x:13:
cdrom:x:15:
adm:x:16:
messagebus:x:18:
input:x:24:
mail:x:34:
kvm:x:61:
uuidd:x:80:
wheel:x:97:
pacman:x:102:
users:x:999:
nogroup:x:65534:
EOF
REALEOF
Continue with the rest of the common configuraiton:
cat >> PKGBUILD << "REALEOF"
touch "${pkgdir}"/var/log/{btmp,lastlog,faillog,wtmp}
chgrp -v 13 "${pkgdir}/var/log/lastlog"
chmod -v 664 "${pkgdir}/var/log/lastlog"
chmod -v 600 "${pkgdir}/var/log/btmp"
# 7.6 and 9.5.4
cat > "${pkgdir}/etc/hosts" << "EOF"
# Begin /etc/hosts
# IPv4
127.0.0.1 localhost.localdomain localhost
# Populate the follwoing lines after installation
#127.0.1.1 <FQDN> <HOSTNAME>
#<192.168.1.1> <FQDN> <HOSTNAME> [alias1] [alias2 ...]
# IPv6
::1 localhost ip6-localhost ip6-loopback
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
# End /etc/hosts
EOF
#8.5.2.3
install -vdm755 "${pkgdir}/etc/ld.so.conf.d/"
cat > "${pkgdir}/etc/ld.so.conf" << "EOF"
# Begin /etc/ld.so.conf
/usr/local/lib
/opt/lib
# Add an include directory
include /etc/ld.so.conf.d/*.conf
# End /etc/ld.so.conf
EOF
#9.8
cat > "${pkgdir}/etc/inputrc" << "EOF"
# Begin /etc/inputrc
# Modified by Chris Lynn <roryo@roryo.dynup.net>
# Allow the command prompt to wrap to the next line
set horizontal-scroll-mode Off
# Enable 8bit input
set meta-flag On
set input-meta On
# Turns off 8th bit stripping
set convert-meta Off
# Keep the 8th bit for display
set output-meta On
# none, visible or audible
set bell-style none
# All of the following map the escape sequence of the value
# contained in the 1st argument to the readline specific functions
"\eOd": backward-word
"\eOc": forward-word
# for linux console
"\e[1~": beginning-of-line
"\e[4~": end-of-line
"\e[5~": beginning-of-history
"\e[6~": end-of-history
"\e[3~": delete-char
"\e[2~": quoted-insert
# for xterm
"\eOH": beginning-of-line
"\eOF": end-of-line
# for Konsole
"\e[H": beginning-of-line
"\e[F": end-of-line
# End /etc/inputrc
EOF
#9.9
cat > "${pkgdir}/etc/shells" << "EOF"
# Begin /etc/shells
/bin/sh
/bin/bash
# End /etc/shells
EOF
#10.2
cat > "${pkgdir}/etc/fstab" << "EOF"
# Begin /etc/fstab
# file system mount-point type options dump fsck
# order
/dev/<xxx> / <fff> defaults 1 1
/dev/<yyy> swap swap pri=1 0 0
proc /proc proc nosuid,noexec,nodev 0 0
sysfs /sys sysfs nosuid,noexec,nodev 0 0
devpts /dev/pts devpts gid=5,mode=620 0 0
tmpfs /run tmpfs defaults 0 0
devtmpfs /dev devtmpfs mode=0755,nosuid 0 0
# End /etc/fstab
EOF
#BLFS postlfs/skel.html
install -vdm0700 "${pkgdir}/etc/skel"
#BLFS postlfs/profile.html
cat > "${pkgdir}/etc/profile" << "EOF"
# Begin /etc/profile
# Written for Beyond Linux From Scratch
# by James Robertson <jameswrobertson@earthlink.net>
# modifications by Dagmar d'Surreal <rivyqntzne@pbzpnfg.arg>
# System wide environment variables and startup programs.
# System wide aliases and functions should go in /etc/bashrc. Personal
# environment variables and startup programs should go into
# ~/.bash_profile. Personal aliases and functions should go into
# ~/.bashrc.
# Functions to help us manage paths. Second argument is the name of the
# path variable to be modified (default: PATH)
pathremove () {
local IFS=':'
local NEWPATH
local DIR
local PATHVARIABLE=${2:-PATH}
for DIR in ${!PATHVARIABLE} ; do
if [ "$DIR" != "$1" ] ; then
NEWPATH=${NEWPATH:+$NEWPATH:}$DIR
fi
done
export $PATHVARIABLE="$NEWPATH"
}
pathprepend () {
pathremove $1 $2
local PATHVARIABLE=${2:-PATH}
export $PATHVARIABLE="$1${!PATHVARIABLE:+:${!PATHVARIABLE}}"
}
pathappend () {
pathremove $1 $2
local PATHVARIABLE=${2:-PATH}
export $PATHVARIABLE="${!PATHVARIABLE:+${!PATHVARIABLE}:}$1"
}
export -f pathremove pathprepend pathappend
# Set the initial path
export PATH=/usr/bin
# Attempt to provide backward compatibility with LFS earlier than 11
if [ ! -L /bin ]; then
pathappend /bin
fi
if [ $EUID -eq 0 ] ; then
pathappend /usr/sbin
if [ ! -L /sbin ]; then
pathappend /sbin
fi
unset HISTFILE
fi
# Set up some environment variables.
export HISTSIZE=1000
export HISTIGNORE="&:[bf]g:exit"
# Set some defaults for graphical systems
export XDG_DATA_DIRS=${XDG_DATA_DIRS:-/usr/share}
export XDG_CONFIG_DIRS=${XDG_CONFIG_DIRS:-/etc/xdg}
export XDG_RUNTIME_DIR=${XDG_RUNTIME_DIR:-/tmp/xdg-$USER}
for script in /etc/profile.d/*.sh ; do
if [ -r $script ] ; then
. $script
fi
done
unset script
# End /etc/profile
EOF
install -vdm755 "${pkgdir}/etc/profile.d"
cat > "${pkgdir}/etc/profile.d/bash_completion.sh" << "EOF"
# Begin /etc/profile.d/bash_completion.sh
# Import bash completion scripts
# If the bash-completion package is installed, use its configuration instead
if [ -f /usr/share/bash-completion/bash_completion ]; then
# Check for interactive bash and that we haven't already been sourced.
if [ -n "${BASH_VERSION-}" -a -n "${PS1-}" -a -z "${BASH_COMPLETION_VERSINFO-}" ]; then
# Check for recent enough version of bash.
if [ ${BASH_VERSINFO[0]} -gt 4 ] || \
[ ${BASH_VERSINFO[0]} -eq 4 -a ${BASH_VERSINFO[1]} -ge 1 ]; then
[ -r "${XDG_CONFIG_HOME:-$HOME/.config}/bash_completion" ] && \
. "${XDG_CONFIG_HOME:-$HOME/.config}/bash_completion"
if shopt -q progcomp && [ -r /usr/share/bash-completion/bash_completion ]; then
# Source completion code.
. /usr/share/bash-completion/bash_completion
fi
fi
fi
else
# bash-completions are not installed, use only bash completion directory
if shopt -q progcomp; then
for script in /etc/bash_completion.d/* ; do
if [ -r $script ] ; then
. $script
fi
done
fi
fi
# End /etc/profile.d/bash_completion.sh
EOF
install -vdm755 "${pkgdir}/etc/bash_completion.d"
cat > "${pkgdir}/etc/profile.d/dircolors.sh" << "EOF"
# Setup for /bin/ls and /bin/grep to support color, the alias is in /etc/bashrc.
if [ -f "/etc/dircolors" ] ; then
eval $(dircolors -b /etc/dircolors)
fi
if [ -f "$HOME/.dircolors" ] ; then
eval $(dircolors -b $HOME/.dircolors)
fi
EOF
cat > "${pkgdir}/etc/profile.d/extrapaths.sh" << "EOF"
if [ -d /usr/local/lib/pkgconfig ] ; then
pathappend /usr/local/lib/pkgconfig PKG_CONFIG_PATH
fi
if [ -d /usr/local/bin ]; then
pathprepend /usr/local/bin
fi
if [ -d /usr/local/sbin -a $EUID -eq 0 ]; then
pathprepend /usr/local/sbin
fi
if [ -d /usr/local/share ]; then
pathprepend /usr/local/share XDG_DATA_DIRS
fi
# Set some defaults before other applications add to these paths.
pathappend /usr/share/info INFOPATH
EOF
cat > "${pkgdir}/etc/profile.d/readline.sh" << "EOF"
# Set up the INPUTRC environment variable.
if [ -z "$INPUTRC" -a ! -f "$HOME/.inputrc" ] ; then
INPUTRC=/etc/inputrc
fi
export INPUTRC
EOF
cat > "${pkgdir}/etc/profile.d/umask.sh" << "EOF"
# By default, the umask should be set.
if [ "$(id -gn)" = "$(id -un)" -a $EUID -gt 99 ] ; then
umask 002
else
umask 022
fi
EOF
# Use blocaled configuration for /etc/locale.conf and /etc/profile.d/i18n.sh
cat > "${pkgdir}/etc/locale.conf" << EOF
# Begin /etc/locale.conf
LANG=en_US.UTF-8
# End /etc/locale.conf
EOF
cat > "${pkgdir}/etc/profile.d/i18n.sh" << "EOF"
# Begin /etc/profile.d/i18n.sh
if [ -r /etc/locale.conf ]; then source /etc/locale.conf; fi
if [ -n "$LANG" ]; then export LANG; fi
if [ -n "$LC_TYPE" ]; then export LC_TYPE; fi
if [ -n "$LC_NUMERIC" ]; then export LC_NUMERIC; fi
if [ -n "$LC_TIME" ]; then export LC_TIME; fi
if [ -n "$LC_COLLATE" ]; then export LC_COLLATE; fi
if [ -n "$LC_MONETARY" ]; then export LC_MONETARY; fi
if [ -n "$LC_MESSAGES" ]; then export LC_MESSAGES; fi
if [ -n "$LC_PAPER" ]; then export LC_PAPER; fi
if [ -n "$LC_NAME" ]; then export LC_NAME; fi
if [ -n "$LC_ADDRESS" ]; then export LC_ADDRESS; fi
if [ -n "$LC_TELEPHONE" ]; then export LC_TELEPHONE; fi
if [ -n "$LC_MEASUREMENT" ]; then export LC_MEASUREMENT; fi
if [ -n "$LC_IDENTIFICATION" ]; then export LC_IDENTIFICATION; fi
# End /etc/profile.d/i18n.sh
EOF
cat > "${pkgdir}/etc/bashrc" << "EOF"
# Begin /etc/bashrc
# Written for Beyond Linux From Scratch
# by James Robertson <jameswrobertson@earthlink.net>
# updated by Bruce Dubbs <bdubbs@linuxfromscratch.org>
# System wide aliases and functions.
# System wide environment variables and startup programs should go into
# /etc/profile. Personal environment variables and startup programs
# should go into ~/.bash_profile. Personal aliases and functions should
# go into ~/.bashrc
# Provides colored /bin/ls and /bin/grep commands. Used in conjunction
# with code in /etc/profile.
alias ls='ls --color=auto'
alias grep='grep --color=auto'
# Provides prompt for interactive shells, specifically shells started
# in the X environment. [Review the LFS archive thread titled
# PS1 Environment Variable for a great case study behind this script
# addendum.]
# Setup different prompt colors for local/remote and root/non-root users
NORMAL="\[\e[0m\]"
RED="\[\e[1;31m\]"
GREEN="\[\e[1;32m\]"
YELLOW="\[\e[1;33m\]"
MAGENTA="\[\e[1;35m\]"
CYAN="\[\e[1;36m\]"
# Set local prompt color
if [[ $EUID == 0 ]] ; then
if [[ $TERM == "screen" ]] ; then
PS1="$RED\u [ $NORMAL\w$RED ] (screen)# $NORMAL"
else
PS1="$RED\u [ $NORMAL\w$RED ]# $NORMAL"
fi
else
if [[ $TERM == "screen" ]] ; then
PS1="$YELLOW\w [ $NORMAL\w$YELLOW] (screen)\$ $NORMAL"
else
PS1="$GREEN\u [ $NORMAL\w$GREEN ]\$ $NORMAL"
fi
fi
# Set remote prompt
if [[ "$SSH_CLIENT" != "" ]] ; then
if [[ $EUID == 0 ]] ; then
if [[ $TERM == "screen" ]] ; then
PS1="$MAGENTA\u\h [ $NORMAL\w$MAGENTA ] (screen)# $NORMAL"
else
PS1="$MAGENTA\u@\h [ $NORMAL\w$MAGENTA ]# $NORMAL"
fi
else
if [[ $TERM == "screen" ]] ; then
PS1="$CYAN\u@\h [ $NORMAL\w$CYAN ] (screen)\$ $NORMAL"
else
PS1="$CYAN\u@\h [ $NORMAL\w$CYAN ]\$ $NORMAL"
fi
fi
fi
unset RED GREEN MAGENTA YELLOW CYAN NORMAL
# GnuPG wants this or it'll fail with pinentry-curses under some
# circumstances# Begin ~/.bashrc
# Written for Beyond Linux From Scratch
# by James Robertson <jameswrobertson@earthlink.net>
# Personal aliases and functions.
# Personal environment variables and startup programs should go in
# ~/.bash_profile. System wide environment variables and startup
# programs are in /etc/profile. System wide aliases and functions are
# in /etc/bashrc.
if [ -f "/etc/bashrc" ] ; then
source /etc/bashrc
fi
# Set up user specific i18n variables
#export LANG=en_US.UTF-8
# End ~/.bashrc (for example signing a Git commit)
tty -s && export GPG_TTY=$(tty)
# End /etc/bashrc
EOF
cat > "${pkgdir}/etc/skel/.bash_profile" << "EOF"
# Begin ~/.bash_profile
# Written for Beyond Linux From Scratch
# by James Robertson <jameswrobertson@earthlink.net>
# updated by Bruce Dubbs <bdubbs@linuxfromscratch.org>
# Personal environment variables and startup programs.
# Personal aliases and functions should go in ~/.bashrc. System wide
# environment variables and startup programs are in /etc/profile.
# System wide aliases and functions are in /etc/bashrc.
if [ -f "$HOME/.bashrc" ] ; then
source $HOME/.bashrc
fi
if [ -d "$HOME/bin" ] ; then
pathprepend $HOME/bin
fi
# Having . in the PATH is dangerous
#if [ $EUID -gt 99 ]; then
# pathappend .
#fi
# End ~/.bash_profile
EOF
cat > "${pkgdir}/etc/skel/.profile" << "EOF"
# Begin ~/.profile
# Personal environment variables and startup programs.
if [ -d "$HOME/bin" ] ; then
pathprepend $HOME/bin
fi
# Set up user specific i18n variables
#export LANG=<ll>_<CC>.<charmap><@modifiers>
# End ~/.profile
EOF
cat > "${pkgdir}/etc/skel/.bashrc" << "EOF"
# Begin ~/.bashrc
# Written for Beyond Linux From Scratch
# by James Robertson <jameswrobertson@earthlink.net>
# Personal aliases and functions.
# Personal environment variables and startup programs should go in
# ~/.bash_profile. System wide environment variables and startup
# programs are in /etc/profile. System wide aliases and functions are
# in /etc/bashrc.
if [ -f "/etc/bashrc" ] ; then
source /etc/bashrc
fi
# Set up user specific i18n variables
#export LANG=en_US.UTF-8
# End ~/.bashrc
EOF
cat > "${pkgdir}/etc/skel/.bash_logout" << "EOF"
# Begin ~/.bash_logout
# Written for Beyond Linux From Scratch
# by James Robertson <jameswrobertson@earthlink.net>
# Personal items to perform on logout.
# End ~/.bash_logout
EOF
dircolors -p > "${pkgdir}/etc/dircolors"
cp "${pkgdir}/etc/skel/.bash_profile" "${pkgdir}/root"
cp "${pkgdir}/etc/skel/.profile" "${pkgdir}/root"
cp "${pkgdir}/etc/skel/.bashrc" "${pkgdir}/root"
cp "${pkgdir}/etc/skel/.bash_logout" "${pkgdir}/root"
# Post LFS fixes:
chmod 0555 "${pkgdir}/proc"
chmod 1777 "${pkgdir}/run"
chmod 0555 "${pkgdir}/sys"
}
REALEOF
Produce the rootfs package using the following commands:
chown -R root:pacman . chmod 2775 . chmod 664 PKGBUILD su pacman -c 'makepkg -L --nodeps'
Add the newly created package to the central package repository:
cp rootfs-12.3-1-any.pkg.tar.xz \
/srv/pacman/repos/LFS
repo-add /srv/pacman/repos/LFS/LFS.db.tar.xz \
/srv/pacman/repos/LFS/rootfs-12.3-1-any.pkg.tar.xz
Update the local cache and install the rootfs package:
pacman -Syu pacman -S rootfs --overwrite \* -dd --noconfirm
Despite the overwrite flag above, configuration files are a special case and are added to the filesystem with a ".pacnew" file extension. Overwrite the original files with the ones from this package using the following command:
for file in `find / -name "*.pacnew"`
do
cp -vf "${file}" "${file%.*}"
done
Finally, copy the source files into the source repository and clean up the build directory:
mkdir /srv/pacman/source/LFS/rootfs cp PKGBUILD /srv/pacman/source/LFS/rootfs cd /sources rm -rf rootfs