操作系统似乎以任意方式应用 ext4 文件系统选项

Eri*_*eau 5 configuration ext4 options

我担心如果我无法解决这个问题,我可能不得不恢复为系统默认设置。

我正在尝试为单用户桌面环境设置各种系统配置,以获得更强大的 ext4 。尝试分配所需的配置设置,使其能够正确生效

我知道其中一些应该包含在文件中mke2fs.conf,以便最初使用这些正确的设置创建文件系统。但我稍后会解决这个问题,为以下内容保留发行版默认文件。

我知道我想要的 EXT4 选项可以在/etc/fstab. 以下条目显示了我通常想要的内容:

UUID=00000000-0000-0000-0000-000000000000       /DB001_F2       ext4    defaults,nofail,data=journal,journal_checksum,journal_async_commit,commit=15,errors=remount-ro,journal_ioprio=2,block_validity,nodelalloc,data_err=ignore,nodiscard   0       0
Run Code Online (Sandbox Code Playgroud)

其中每个DB001_F{p} 都是根磁盘上的一个分区( p = [2-8] )。

我在这里以与列表相同的顺序重复这些选项,以防更容易理解:

defaults
nofail
data=journal
journal_checksum
journal_async_commit
commit=15
errors=remount-ro
journal_ioprio=2
block_validity
nodelalloc
data_err=ignore
nodiscard
Run Code Online (Sandbox Code Playgroud)

在启动期间安装,下面的系统日志显示所有报告我认为被承认的可接受的设置:

64017 Sep  4 21:04:35 OasisMega1 kernel: [   21.622599] EXT4-fs (sda7): mounted filesystem with journalled data mode. Opts: data=journal,journal_checksum,journal_async_commit,commit=15,errors=remount-ro,journal_ioprio=2,block_validity,nodelalloc,data_err=ignore,nodiscard
64018 Sep  4 21:04:35 OasisMega1 kernel: [   21.720338] EXT4-fs (sda4): mounted filesystem with journalled data mode. Opts: data=journal,journal_checksum,journal_async_commit,commit=15,errors=remount-ro,journal_ioprio=2,block_validity,nodelalloc,data_err=ignore,nodiscard
64019 Sep  4 21:04:35 OasisMega1 kernel: [   21.785653] EXT4-fs (sda8): mounted filesystem with journalled data mode. Opts: data=journal,journal_checksum,journal_async_commit,commit=15,errors=remount-ro,journal_ioprio=2,block_validity,nodelalloc,data_err=ignore,nodiscard
64021 Sep  4 21:04:35 OasisMega1 kernel: [   22.890168] EXT4-fs (sda12): mounted filesystem with journalled data mode. Opts: data=journal,journal_checksum,journal_async_commit,commit=15,errors=remount-ro,journal_ioprio=2,block_validity,nodelalloc,data_err=ignore,nodiscard
64022 Sep  4 21:04:35 OasisMega1 kernel: [   23.214507] EXT4-fs (sda9): mounted filesystem with journalled data mode. Opts: data=journal,journal_checksum,journal_async_commit,commit=15,errors=remount-ro,journal_ioprio=2,block_validity,nodelalloc,data_err=ignore,nodiscard
64023 Sep  4 21:04:35 OasisMega1 kernel: [   23.308922] EXT4-fs (sda13): mounted filesystem with journalled data mode. Opts: data=journal,journal_checksum,journal_async_commit,commit=15,errors=remount-ro,journal_ioprio=2,block_validity,nodelalloc,data_err=ignore,nodiscard
64024 Sep  4 21:04:35 OasisMega1 kernel: [   23.513804] EXT4-fs (sda14): mounted filesystem with journalled data mode. Opts: data=journal,journal_checksum,journal_async_commit,commit=15,errors=remount-ro,journal_ioprio=2,block_validity,nodelalloc,data_err=ignore,nodiscard
Run Code Online (Sandbox Code Playgroud)

mount显示某些驱动器即使在重新启动后也未按预期报告,并且这是不一致的,如下所示:

/dev/sda7 on /DB001_F2 type ext4 (rw,relatime,nodelalloc,journal_checksum,journal_async_commit,errors=remount-ro,commit=15,data=journal)
/dev/sda8 on /DB001_F3 type ext4 (rw,relatime,nodelalloc,journal_checksum,journal_async_commit,errors=remount-ro,commit=15,data=journal)
/dev/sda9 on /DB001_F4 type ext4 (rw,relatime,nodelalloc,journal_checksum,journal_async_commit,errors=remount-ro,commit=15,data=journal)
/dev/sda12 on /DB001_F5 type ext4 (rw,relatime,nodelalloc,journal_async_commit,errors=remount-ro,commit=15,data=journal)
/dev/sda13 on /DB001_F6 type ext4 (rw,relatime,nodelalloc,journal_async_commit,errors=remount-ro,commit=15,data=journal)
/dev/sda14 on /DB001_F7 type ext4 (rw,relatime,nodelalloc,journal_async_commit,errors=remount-ro,commit=15,data=journal)
/dev/sda4 on /DB001_F8 type ext4 (rw,relatime,nodelalloc,journal_async_commit,errors=remount-ro,commit=15,data=journal)
Run Code Online (Sandbox Code Playgroud)

我在某处读到有关 中选项字符串长度的限制fstab,因此我过去常常tune2fs在较低级别预先设置一些参数。那些通过以下方式申请的tune2fs是:

journal_data,block_validity,nodelalloc
Run Code Online (Sandbox Code Playgroud)

使用时确认tune2fs -l

Default mount options:    journal_data user_xattr acl block_validity nodelalloc
Run Code Online (Sandbox Code Playgroud)

就位后,我修改了fstab条目以显示为

UUID=00000000-0000-0000-0000-000000000000       /DB001_F2       ext4    defaults,nofail,journal_checksum,journal_async_commit,commit=15,errors=remount-ro,journal_ioprio=2,data_err=ignore,nodiscard   0       0
Run Code Online (Sandbox Code Playgroud)

umount为我所有的DB001_F?( /dev/sda*) 做了 a ,然后我做了 a mount -av,报告了以下内容:

/                        : ignored
/DB001_F2                : successfully mounted
/DB001_F3                : successfully mounted
/DB001_F4                : successfully mounted
/DB001_F5                : successfully mounted
/DB001_F6                : successfully mounted
/DB001_F7                : successfully mounted
/DB001_F8                : successfully mounted
Run Code Online (Sandbox Code Playgroud)

每个驱动器的选项字符串均未报告错误。

我尝试使用journal_checksum_v3,但mount -av该设置全部失败。我使用该mount命令来查看报告的内容。

我还重新启动并mount针对这些减少的设置再次重复该操作,并mount再次显示驱动器未按预期报告,并且这仍然不一致,如下所示:

/dev/sda7 on /DB001_F2 type ext4 (rw,relatime,journal_checksum,journal_async_commit,commit=15)
/dev/sda8 on /DB001_F3 type ext4 (rw,relatime,journal_checksum,journal_async_commit,commit=15)
/dev/sda9 on /DB001_F4 type ext4 (rw,relatime,journal_checksum,journal_async_commit,commit=15)
/dev/sda12 on /DB001_F5 type ext4 (rw,relatime,journal_async_commit,commit=15)
/dev/sda13 on /DB001_F6 type ext4 (rw,relatime,journal_async_commit,commit=15)
/dev/sda14 on /DB001_F7 type ext4 (rw,relatime,journal_async_commit,commit=15)
/dev/sda4 on /DB001_F8 type ext4 (rw,relatime,journal_async_commit,commit=15)
Run Code Online (Sandbox Code Playgroud)

由于这些都是ext4类型文件系统,并且都位于同一物理驱动器上journal_checksum,因此我不明白不统一操作的行为!我也发现有趣的是,两类行为之间存在一条分界线,因为上面列出的顺序是fstab(根据/DB001_F?)中指定的顺序,这大概是安装顺序......所以什么“故障”导致剩余安装操作“降级”?

我的想法(可能毫无根据)是,某些属性可能在创建文件系统时设置得更好,这将使它们比其他方式更“持久/有效”。当我尝试通过在mke2fs.conf. mke2fs.ext4我怀疑再次失败,因为选项字符串的长度受到限制(64 个字符?)。 所以...我已经放弃对mke2fs.conf.

mke2fs.conf现在忽略这个问题,并专注于 fstab 和une2fs 功能,有人可以向我解释一下我做错了什么,导致安装无法正确报告当前有效的全部设置范围吗?

此时,我不知道我可以依靠什么来提供 ext4 行为的实际状态,并且正在考虑简单地恢复到发行版默认值,这让我很想要。

有没有可能一切都很好,只是系统没有正确报告?我不确定我是否可以轻松地接受这个观点。这是违反直觉的。

有人可以帮忙吗?

环境

UbuntuMATE 20.04 LTS
Linux OasisMega1 5.4.0-124-generic #140-Ubuntu SMP Thu Aug 4 02:23:37 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux 
RAM = 4GB
DSK = 2TB   (internal, 8 data partitions, 3 1GB swap partitions) [ROOT]
DSK = 500GB (internal,  2 data partitions, 1 1GB swap partitions)
DSK = 4TB   (external USB, 16 data partitions) [BACKUP drive]
Run Code Online (Sandbox Code Playgroud)

这是以下报道的内容debugfs

Filesystem features:
    has_journal
    ext_attr
    resize_inode
    dir_index
    filetype
    needs_recovery
    extent
    flex_bg
    sparse_super
    large_file
    huge_file
    dir_nlink
    extra_isize
    metadata_csum
Run Code Online (Sandbox Code Playgroud)

对于进一步了解问题不是很有用。

debugfs显示以下支持的功能:

debugfs 1.45.5 (07-Jan-2020)

Supported features: (...snip...) journal_checksum_v2 journal_checksum_v3
Run Code Online (Sandbox Code Playgroud)

值得注意的是,它debugfs显示了 或journal_checksum_v2available journal_checksum_v3,但没有journal_checksum显示手册页中引用的 。

这是否意味着我应该使用v2orv3代替journal_checksum

Eri*_*eau 0

鉴于对我的原始帖子的评论所进行的讨论,我准备得出这样的结论:自我最初安装 UbuntuMATE 20.04 LTS 发行版以来,两年多来对内核进行的许多更改是观察到的行为差异的根源。在不同时间创建的 8 个 集,尽管它们驻留在同一物理上。

因此,确保给定(即)的所有文件系统对安装选项、选项做出相同的反应以及通过命令进行相同的行为/报告的唯一方法是确保它们是使用相同的冻结版本创建的操作系统内核以及用于创建和调整这些文件系统的各种文件系统实用程序。

因此,为了回答我原来的问题,文件系统的报告不同是没有问题的,因为它们的报告是正确的,每个文件系统都有自己的历史背景,导致它们当前的状态

期待我即将升级到 UbuntuMATE 22.04 LTS(为什么我一开始就深入研究这一切),为了避免差异,因为安装磁盘不是内核或实用程序的最新版本,我定义的过程必须是:

  1. 升级到较新的操作系统,
  2. 重启,
  3. 应用所有更新,
  4. 创建现在驻留在根分区上的升级+更新的操作系统的备份映像,
  5. 使用最新的内核和实用程序重新创建根分区(使用驻留在辅助内部磁盘上的重复的完全更新的操作系统,这就是我的 500 GB 驱动器存在的原因,即测试、证明、确认最终所需的安装,然后再转入“生产”),
  6. 将完全更新的主操作系统从备份映像恢复到其正确的 ROOT 分区,
  7. 重新启动,然后
  8. 备份主磁盘上的所有其他分区,重新创建这些分区,然后恢复每个分区的数据。

只有这样,才能将所有分区创建为“等于”在一个快照中及时提供的最新和最好的分区。否则,根分区将与发行版安装后更新后创建的所有其他分区不一致。

此外,拥有一个与我创建的脚本类似的脚本可以确保统一应用所需的操作,从而避免在多次手动执行时可能出现的单调乏味的错误。

对于那些希望能够使用脚本以一致的方式管理和查看这些选项的人,这是我为自己创建的脚本:

#!/bin/sh

####################################################################################
###
### $Id: tuneFS.sh,v 1.2 2022/09/07 01:43:18 root Exp $
###
### Script to set consistent (local/site) preferences for filesystem treatment at boot-time or mounting
###
####################################################################################

TIMESTAMP=`date '+%Y%m%d-%H%M%S' `
BASE=`basename "$0" ".sh" `


###
### These variables will document hard-coded 'mount' preferences for filesystems
###
BOOT_MAX_INTERVAL="-c 10"   ### max number of boots before fsck [10 boots]
TIME_MAX_INTERVAL="-i 2w"   ### max calendar time between boots before fsck [2 weeks]
ERROR_ACTION="-e remount-ro"    ### what to do if error encountered
#-m reserved-blocks-percentage

###
### This OPTIONS string should be updated manually to document
### the preferred and expected settings to be applied to ext4 filesystems
###
OPTIONS="-o journal_data,block_validity,nodelalloc"

ASSIGN=0
REPORT=0
VERB=0
SINGLE=0
while [ $# -gt 0 ]
do
    case ${1} in
        --default ) REPORT=0 ; ASSIGN=0 ; shift ;;
        --report )  REPORT=1 ; ASSIGN=0 ; shift ;;
        --force )   REPORT=0 ; ASSIGN=1 ; shift ;;
        --verbose ) VERB=1 ; shift ;;
        --single )  SINGLE=1 ; shift ;;
        * ) echo "\n\t Invalid parameter used on the command line.  Valid options:  [ --default | --report | --force | --single | --verbose ] \n Bye!\n" ; exit 1 ;;
    esac
done


workhorse()
{
    case ${PARTITION} in
        1 )
            DEVICE="/dev/sda3"
            OPTIONS=""
            ;;
        2 )
            DEVICE="/dev/sda7"
            ;;
        3 )
            DEVICE="/dev/sda8"
            ;;
        4 )
            DEVICE="/dev/sda9"
            ;;
        5 )
            DEVICE="/dev/sda12"
            ;;
        6 )
            #UUID="0d416936-e091-49a7-9133-b8137d327ce0"
            #DEVICE="UUID=${UUID}"
            DEVICE="/dev/sda13"
            ;;
        7 )
            DEVICE="/dev/sda14"
            ;;
        8 )
            DEVICE="/dev/sda4"
            ;;
    esac
    PARTITION="DB001_F${PARTITION}"
    PREF="${BASE}.previous.${PARTITION}"

    reference=`ls -t1 "${PREF}."*".dumpe2fs" 2>/dev/null | grep -v 'ERR.dumpe2fs'| tail -1 `

    if [ ! -s "${PREF}.dumpe2fs.REFERENCE" ]
    then
        mv -v ${reference} ${PREF}.dumpe2fs.REFERENCE
    fi

    reference=`ls -t1 "${PREF}."*".verify" 2>/dev/null | grep -v 'ERR.verify'| tail -1 `

    if [ ! -s "${PREF}.verify.REFERENCE" ]
    then
        mv -v ${reference} ${PREF}.verify.REFERENCE
    fi

    BACKUP="${BASE}.previous.${PARTITION}.${TIMESTAMP}"
    BACKUP="${BASE}.previous.${PARTITION}.${TIMESTAMP}"

    rm -f ${PREF}.*.tune2fs
    rm -f ${PREF}.*.dumpe2fs

    ### reporting by 'tune2fs -l' is a subset of that from 'dumpe2fs -h'

    if [ ${REPORT} -eq 1 ]
    then
        ### No need to generate report from tune2fs for this mode.

        ( dumpe2fs -h ${DEVICE} 2>&1 ) | awk '{
                if( NR == 1 ){ print $0 } ;
                if( index($0,"revision") != 0 ){ print $0 } ;
                if( index($0,"mount options") != 0 ){ print $0 } ;
                if( index($0,"features") != 0 ){ print $0 } ;
                if( index($0,"Filesystem flags") != 0 ){ print $0 } ;
                if( index($0,"directory hash") != 0 ){ print $0 } ;
            }'>${BACKUP}.dumpe2fs
        echo "\n dumpe2fs REPORT [$PARTITION]:"
        cat ${BACKUP}.dumpe2fs
    else
        ### Generate report from tune2fs for this mode but only as sanity check.

        tune2fs -l ${DEVICE} 2>&1 >${BACKUP}.tune2fs

        ( dumpe2fs -h ${DEVICE} 2>&1 ) >${BACKUP}.dumpe2fs

        if [ ${VERB} -eq 1 ] ; then
            echo "\n tune2fs REPORT:"
            cat ${BACKUP}.tune2fs

            echo "\n dumpe2fs REPORT:"
            cat ${BACKUP}.dumpe2fs
        fi

        if [ ${ASSIGN} -eq 1 ]
        then
            tune2fs ${BOOT_MAX_INTERVAL}  ${TIME_MAX_INTERVAL}  ${ERROR_ACTION}  ${OPTIONS}  ${DEVICE}

            rm -f ${PREF}.*.verify
            ( dumpe2fs -h ${DEVICE} 2>&1 ) >${BACKUP}.verify

            if [ ${VERB} -eq 1 ] ; then  
                echo "\n Changes:"
                diff ${BACKUP}.dumpe2fs ${BACKUP}.verify
            fi
        else
            if [ ${VERB} -eq 1 ] ; then  
                echo "\n Differences:"
                diff ${BACKUP}.tune2fs ${BACKUP}.dumpe2fs
            fi

            rm -f ${BACKUP}.verify
        fi
    fi
}


if [ ${SINGLE} -eq 1 ]
then
    for PARTITION in 2 3 4 5 6 7 8
    do
        echo "\n\t Actions only for DB001_F${PARTITION} ? [y|N] => \c" ; read sel
        if [ -z "${sel}" ] ; then  sel="N" ; fi
        case ${sel} in
            y* | Y* ) DOIT=1 ; break ;;
            * ) DOIT=0 ;;
        esac
    done

    if [ ${DOIT} -eq 1 ]
    then
        workhorse
    fi
else
    for PARTITION in 2 3 4 5 6 7 8
    do
        workhorse
    done
fi


exit 0
exit 0
exit 0
Run Code Online (Sandbox Code Playgroud)

对于那些感兴趣的人,后续发布中有一个修改/扩展的脚本。

感谢大家的意见和反馈。