zhangguanzhang's Blog

e2fsck 太老报错 has unsupported feature(s): metadata_csum,从而尝试静态编译

字数统计: 1.2k阅读时长: 6 min
2021/01/24

e2fsck 静态编译和笔记

由来

写于 2022/05/13 ,有个老哥的 pve lvm not found,无法开机,然后他瞎搞一番后来找我,我让他 vgchange -a y 激活后挂载 /dev/mapper/pve-root 后进去修复 grub 。他当时用的是 debian 的 iso 进去整的,vgchange 的时候报错无法找到 dm-thin-pool 内核模块,然后还无法激活所有的 vg,我让他用 centos7.x 的 iso 进 rescue 试试后全部激活了。然后报错:

1
2
3
4
5
6
$ mount /dev/mapper/pve-root /mnt/sysimage
mount: wrong fs type, bad option, bad superblock on /dev/mapper/pve-root,
missing codepage or helper program, or other error

In some cases useful info is found in syslog - try
dmesg | tail or so.

看着是损坏了,pve 的 root 分区是 ext4 的,让他修复下:

1
2
3
4
$ fsck.ext4  /dev/mapper/pve-root
e2fsck 1.42.9 (28-Dec-2013)
/dev/mapper/pve-root has unsupported feature(s): metadata_csum
e2fsck: Get a newer version of e2fsck!

看样子 pve 的 mkfs.ext4 用了一些特性,而 centos 的 ISO 里的 e2fsck 实在太老了,后面让他用 pve 或者 debian 的 iso 进去修复了。然后我就有了静态编译 e2fsck 的想法。

e2fsck

静态编译

官方代码仓库

先找源码,github 上没找到,于是 man e2fsck 找到 This version of e2fsck was written by Theodore Ts'o <tytso@mit.edu> ,源码找的几个可下载的地址:

参考信息

官方的 INSTALL 里说:

1
2
3
If you wish to turn on ELF shared libraries, add the option
--enable-elf-shlibs. If you wish to build profiling libraries, add
the option --enable-profile.

我看了下默认编译出来的是只有基础的库连接:

1
2
3
4
$ ldd `which e2fsck `
linux-vdso.so.1 (0x00007ffd62457000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f3ae41b8000)
/lib64/ld-linux-x86-64.so.2 (0x00007f3ae44a6000)

在 pve 上看到链接信息:

1
2
3
4
5
6
7
8
9
10
11
$ ldd `which e2fsck`
linux-vdso.so.1 (0x00007ffe0cdac000)
libext2fs.so.2 => /lib/x86_64-linux-gnu/libext2fs.so.2 (0x00007fe5f95c5000)
libcom_err.so.2 => /lib/x86_64-linux-gnu/libcom_err.so.2 (0x00007fe5f95bf000)
libblkid.so.1 => /lib/x86_64-linux-gnu/libblkid.so.1 (0x00007fe5f956a000)
libuuid.so.1 => /lib/x86_64-linux-gnu/libuuid.so.1 (0x00007fe5f9561000)
libe2p.so.2 => /lib/x86_64-linux-gnu/libe2p.so.2 (0x00007fe5f9557000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007fe5f9552000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fe5f938f000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fe5f936e000)
/lib64/ld-linux-x86-64.so.2 (0x00007fe5f9678000)

centos 上看到的:

1
2
3
4
5
6
7
8
9
10
$ ldd `which e2fsck`
linux-vdso.so.1 => (0x00007fff6e0e7000)
libext2fs.so.2 => /lib64/libext2fs.so.2 (0x00007f297b006000)
libcom_err.so.2 => /lib64/libcom_err.so.2 (0x00007f297ae02000)
libblkid.so.1 => /lib64/libblkid.so.1 (0x00007f297abc2000)
libuuid.so.1 => /lib64/libuuid.so.1 (0x00007f297a9bd000)
libe2p.so.2 => /lib64/libe2p.so.2 (0x00007f297a7b5000)
libc.so.6 => /lib64/libc.so.6 (0x00007f297a3e7000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f297a1cb000)
/lib64/ld-linux-x86-64.so.2 (0x00007f297b24b000)

记得看 pve 的 /etc/mke2fs.conf 看有哪些特性:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
$ dpkg -S /etc/mke2fs.conf
e2fsprogs: /etc/mke2fs.conf
$ cat /etc/mke2fs.conf
[defaults]
base_features = sparse_super,large_file,filetype,resize_inode,dir_index,ext_attr
default_mntopts = acl,user_xattr
enable_periodic_fsck = 0
blocksize = 4096
inode_size = 256
inode_ratio = 16384
[fs_types]
...
ext4 = {
features = has_journal,extent,huge_file,flex_bg,metadata_csum,64bit,dir_nlink,extra_isize
inode_size = 256
}

...

自己编译出来的看了下是和上面的 base_features 是一样的,centos 7 的 e2fsprogs 我升级到 1.42.9 是:

1
2
3
4
5
6
7
8
9
10
11
[defaults]
base_features = sparse_super,filetype,resize_inode,dir_index,ext_attr
default_mntopts = acl,user_xattr
...
[fs_types]
...
ext4 = {
features = has_journal,extent,huge_file,flex_bg,uninit_bg,dir_nlink,extra_isize,64bit
inode_size = 256
}
...

ext4 的确实看到没有 metadata_csum 属性

ubuntu 静态编译

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
docker run --name t1 -tid -v $PWD/e2fsck:/opt --workdir  /opt ubuntu
docker exec -ti t1 sh -c 'sed -ri 's/(ports|deb|security|archive).(debian.org|ubuntu.com)/mirrors.aliyun.com/g' /etc/apt/sources.list && apt-get update'
docker exec -ti t1 bash

apt-get install -y \
gcc \
make \
pkg-config \
libcom-err2 \
libfuse-dev \
libattr1-dev \
libacl1-dev \
gawk texinfo texlive gettext

CFLAGS='-static -s' LDFLAGS='-static' ./configure \
--enable-verbose-makecmds \
--enable-libuuid \
--enable-libblkid \
--enable-fsck


make; echo $?
make install

$ e2fsck -V
e2fsck 1.46.5 (30-Dec-2021)
Using EXT2FS Library version 1.46.5, 30-Dec-2021
$ ldd `which e2fsck`
not a dynamic executable

buildx 一步到位:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
FROM docker.mirrors.ustc.edu.cn/library/ubuntu as build
ARG branch=1.46.5
ENV DEBIAN_FRONTEND noninteractive
RUN sed -ri 's/(ports|deb|security|archive).(debian.org|ubuntu.com)/mirrors.aliyun.com/g' /etc/apt/sources.list \
&& apt-get update
WORKDIR /opt

# COPY e2fsprogs . # 二选一
#RUN apt-get install -y git && git clone --branch v${branch} https://github.com/tytso/e2fsprogs.git
RUN apt-get install -y wget && wget https://mirrors.edge.kernel.org/pub/linux/kernel/people/tytso/e2fsprogs/v${branch}/e2fsprogs-${branch}.tar.gz \
&& tar zxf e2fsprogs-${branch}.tar.gz \
&& mv e2fsprogs-${branch} e2fsprogs \
&& rm -f e2fsprogs-${branch}.tar.gz

RUN apt-get install -y \
gcc make pkg-config \
libcom-err2 \
libfuse-dev \
libattr1-dev \
libacl1-dev \
gawk texinfo texlive gettext

RUN cd e2fsprogs; \
CFLAGS='-static -s' LDFLAGS='-static' \
./configure \
--enable-verbose-makecmds \
--enable-libuuid \
--enable-libblkid \
--enable-fsck \
&& make; echo $? \
&& make DESTDIR=/install_root install \
&& find /install_root

RUN rm -rf /install_root/usr/share \
/install_root/lib/systemd/ \
/install_root/usr/lib/ \
/install_root/usr/include \
&& mkdir -p /install_root/bin/ \
&& mv /install_root/sbin/* \
/install_root/usr/sbin/* \
/install_root/usr/bin/* \
/install_root/bin/ \
&& { rmdir /install_root/lib \
/install_root/usr/bin/ \
/install_root/usr/sbin/; \
rmdir /install_root/usr/; \
/install_root/sbin/; \
true; }

FROM scratch AS bin
COPY --from=build /install_root /

构建

1
2
3
4
5
docker buildx build  . --platform linux/amd64,linux/arm64      --target bin --output .

$ file linux_a*/bin/fsck.ext4
linux_amd64/bin/fsck.ext4: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), statically linked, BuildID[sha1]=a0f4bf08157fdc8132707af16f9fc103a411c05b, for GNU/Linux 3.2.0, with debug_info, not stripped
linux_arm64/bin/fsck.ext4: ELF 64-bit LSB executable, ARM aarch64, version 1 (GNU/Linux), statically linked, BuildID[sha1]=8b9c945c4a18bdaf6152b8445498fc5f436f5c3f, for GNU/Linux 3.7.0, with debug_info, not stripped

镜像推送到了:

1
2
zhangguanzhang/e2fsprogs:v1.46.5
registry.aliyuncs.com/zhangguanzhang/e2fsprogs:v1.46.5
CATALOG
  1. 1. 由来
  2. 2. e2fsck
    1. 2.1. 静态编译
      1. 2.1.1. 官方代码仓库
      2. 2.1.2. 参考信息
      3. 2.1.3. ubuntu 静态编译