使用LFS

在这么冗长艰难的LFS构建之后,终于能够启动运行一个自己手搓的Linux,感觉确实良好。

接下来该怎么使用这个系统呢?

我有自己的计划,在 BLFS(Beyond Linux From Scratch)思考 中构想:

主要基于我的工作中心是后端。

LFS手册提供了一个很好的使用思路: 在Host主机中通过 chroot 来进行操作

准备工作

  • 之前在 LFS准备工作 配置了 root 用户的 ~/.bashrc ,但是需要注意,这个 ~/.bashrc 是需要通过 ~/.profile 引用才能自动生效的,所以这里补充一个 ~/.profile 配置(从 Debian 系统中复制):

增加 ~/.profile 来引用 ~/.bashrc
# ~/.profile: executed by the command interpreter for login shells.
# This file is not read by bash(1), if ~/.bash_profile or ~/.bash_login
# exists.
# see /usr/share/doc/bash/examples/startup-files for examples.
# the files are located in the bash-doc package.

# the default umask is set in /etc/profile; for setting the umask
# for ssh logins, install and configure the libpam-umask package.
#umask 022

# if running bash
if [ -n "$BASH_VERSION" ]; then
    # include .bashrc if it exists
    if [ -f "$HOME/.bashrc" ]; then
	. "$HOME/.bashrc"
    fi
fi

# set PATH so it includes user's private bin if it exists
if [ -d "$HOME/bin" ] ; then
    PATH="$HOME/bin:$PATH"
fi

# set PATH so it includes user's private bin if it exists
if [ -d "$HOME/.local/bin" ] ; then
    PATH="$HOME/.local/bin:$PATH"
fi
  • 我在 ~/.bashrc 中修改 $LFS 设置为 /chroot/lfs (这只是我的喜好,官方原文是 /mnt/lfs ):

调整 ~/.bashrc$LFS 设置为 /chroot/lfs
#LFS=/mnt/lfs
LFS=/chroot/lfs
  • 参考 FreeBSD Thick(厚) Jail 的思路,在物理主机上创建 /sketch 目录,将 /etc 目录下需要可以修订的配置文件复制到这个目录下并建立软链接,这样当 /etc 目录被 mountbind$LFS 中以后,这些文件对于jail内部是可以自由修订的

构建一个需要为每个jail定制的可修改目录 /sketch
mkdir /sketch
cd /etc/
mv hosts /sketch/
mv hostname /sketch/
mv resolve.conf /sketch/
ln -s /sketch/* ./
  • 创建设备目录:

创建虚拟内核文件系统挂载点
mkdir -pv $LFS/{dev,proc,sys,run,etc}

# var 空目录创建需要么?
mkdir -pv $LFS/var/{cache,local,log,mail,opt,spool}

# 需要mountbind的目录
mkdir -pv $LFS/root
mkdir -pv $LFS/home

# 为chroot之后的系统补全目录软链接
cd $LFS
ln -sv usr/lib .
ln -sv usr/sbin .
ln -sv usr/bin .

# 构建一个sketch目录存放需要定制的文件,这些文件在物理主机中会软链接到/sketch中文件
# mountbind物理主机/etc到chroot目录后,也能软链接到这些可定制文件
mkdir $LFS/sketch
cp /etc/hosts $LFS/sketch/
cp /etc/hostname $LFS/sketch/
cp /etc/resolv.conf $LFS/sketch/

# 补全 lib64 指向 lib 的库文件软链接,否则chroot会报错提示 /usr/bin/env 不存在
mkdir -pv lib64
cd $LFS/lib64
ln -s ../lib/ld-linux-x86-64.so.2 .
ln -s ../lib/ld-linux-x86-64.so.2 ld-lsb-x86-64.so.3

警告

这里必须 补全 lib64 指向 lib 的库文件软链接 ,否则 chroot 进入 $LFS 之后执行任何命令都会失败,但是会返回一个非常迷惑的提示:

执行 chroot 始终提示找不到文件
/usr/sbin/chroot: failed to run command '/usr/bin/env': No such file or directory
  • 准备 mount-virt.sh 脚本

挂载虚拟文件系统,为chroot准备
cat > ~/mount-virt.sh << "EOF"
#!/bin/bash

function mountbind
{
   if ! mountpoint $LFS/$1 >/dev/null; then
     $SUDO mount --bind /$1 $LFS/$1
     echo $LFS/$1 mounted
   else
     echo $LFS/$1 already mounted
   fi
}

function mounttype
{
   if ! mountpoint $LFS/$1 >/dev/null; then
     $SUDO mount -t $2 $3 $4 $5 $LFS/$1
     echo $LFS/$1 mounted
   else
     echo $LFS/$1 already mounted
   fi
}

if [ $EUID -ne 0 ]; then
  SUDO=sudo
else
  SUDO=""
fi

if [ x$LFS == x ]; then
  echo "LFS not set"
  exit 1
fi

mountbind dev
mounttype dev/pts devpts devpts -o gid=5,mode=620
mounttype proc    proc   proc
mounttype sys     sysfs  sysfs
mounttype run     tmpfs  run
if [ -h $LFS/dev/shm ]; then
  install -v -d -m 1777 $LFS$(realpath /dev/shm)
else
  mounttype dev/shm tmpfs tmpfs -o nosuid,nodev
fi 

mountbind usr
mountbind home

#mountbind usr/src
#mountbind boot
#mountbind home
EOF

备注

这里执行 mount --bind 将 Host 主机的 /usr 目录映射到 chroot 中,就不用完整复制 /usr 目录了(所有LFS的编译后 执行程序和库 都在这个目录下

  • 使用 root 身份执行:

执行挂载虚拟文件系统脚本
bash ~/mount-virt.sh

备注

这个脚本也可以用普通用户身份执行,但是需要安装 sudo (在后续 BLFS(Beyond Linux from scratch) 中完成,所以这里我还是用 root 身份执行)

完成后检查 df -h 输出类似如下:

挂载虚拟文件系统后检查
Filesystem      Size  Used Avail Use% Mounted on
/dev/root        14G  1.6G   12G  12% /
devtmpfs        189G     0  189G   0% /dev
tmpfs           189G  1.6M  189G   1% /run
tmpfs           189G     0  189G   0% /dev/shm
/dev/nvme0n1p1  365M  188K  365M   1% /boot/efi
/dev/sda2       117G   13G   98G  12% /sources
efivarfs        176K  119K   53K  70% /sys/firmware/efi/efivars
run             189G     0  189G   0% /chroot/lfs/run
tmpfs           189G     0  189G   0% /chroot/lfs/dev/shm

LFS建议不要将 BLFS(Beyond Linux from scratch) 使用的源代码包和LFS使用的源代码包混合存放在 /sources (chroot环境中的路径)中

  • 最后进入chroot环境 - 配置 ~/.bashrc 添加进入的命令别名:

配置 ~/.bashrc 添加进入的命令别名
alias lfs="sudo /usr/sbin/chroot --userspec=admin:admin $LFS /usr/bin/env -i \
	HOME=/root TERM=$TERM PS1='(lfs chroot) \u:\w\$ ' \
    PATH=/bin:/usr/bin:/sbin:/usr/sbin \
	/bin/bash --login"

普通用户 admin 设置

为了能够让admin用户也使用 chroot ,对 admin 用户账号也做了响应调整

备注

普通用户 chroot 需要使用 sudo 工具,所以必须先完成 BLFS(Beyond Linux from scratch)sudo 工具的安装

  • 同样配置 ~/.profile~/.bashrc ,但是在 ~/.bashrc 中配置 aliad chroot 稍作调整

#LFS=/mnt/lfs
LFS=/chroot/lfs

异常排查

chroot报错 No such file or directory

我在执行 chroot 时候遇到一个问题,始终提示:

执行 chroot 始终提示找不到文件
/usr/sbin/chroot: failed to run command '/usr/bin/env': No such file or directory

但是实际上 /chroot/lfs/usr/bin/env 程序是存在的(通过 mount --bind 从host中挂载

我以为是 mount --bind 问题,就完整把Host主机上 /usr 目录复制到chroot的 /chroot/lfs 下,但是报错依旧。似乎是host主机 chroot 无法正常工作?

LFS chroot cannot find /usr/bin/env 给了我启发(不过我的情况不一样),我对比了host主机的根目录和 $LFS ( /chroot/lfs )目录,发现 $LFS 缺少一个 /lib64

而执行 ldd /usr/bin/env 可以看到,这个程序依赖 /lib64/ld-linux-x86-64.so.2

所以补充执行

补全 $LFS 目录下的 lib64
mkdir $LFS/lib64
cd $LFS/lib64
ln -s ../lib/ld-linux-x86-64.so.2 .
ln -s ../lib/ld-linux-x86-64.so.2 ld-lsb-x86-64.so.3

果然,再次执行 chroot 这串指令就不再报错了

备注

我已经将这个补充命令添加到前面的执行脚本命令中,如果你按照我的步骤,应该不再报错

参考