我想以非 root 用户身份创建一个文件系统映像,我面临的问题是我目前的做法是,它需要安装,而非 root 用户无法安装。
这就是我现在正在做的事情:
#!/bin/sh
IMG="app.ext4"
LBL="PIHU_APP"
MNT="/mnt/PIHU_APP"
APP="/home/buildroot/board/arctura/PIHU_APP/application"
#64MB:
dd if=/dev/zero of=$IMG bs=4096 count=16384
mkfs.ext4 $IMG
e2label $IMG $LBL
mkdir -p $MNT
mount -o loop $IMG $MNT
cp -r $APP $MNT
sync
umount $MNT
我拥有完全的 root 访问权限,因此我可以设置/准备任何内容,但脚本将从非 root 帐户执行。
然而,我有一种感觉可能有更好的方法,甚至可能不需要安装,但我不确定..
答案1
mke2fs -d
最小的可运行示例,无需sudo
mke2fs
是 e2fsprogs 包的一部分。它由 2018 年在 Google 工作的著名 Linux 内核文件系统开发人员 Theodore Ts'o 编写,上游源代码位于 kernel.org 下:https://git.kernel.org/pub/scm/fs/ext2/e2fsprogs因此,该存储库可以被视为 ext 文件系统操作的参考用户态实现:
#!/usr/bin/env bash
set -eu
root_dir=root
img_file=img.ext2
# Create a test directory to convert to ext2.
mkdir -p "$root_dir"
echo asdf > "${root_dir}/qwer"
# Create a 32M ext2 without sudo.
# If 32M is not enough for the contents of the directory,
# it will fail.
rm -f "$img_file"
mke2fs \
-L '' \
-N 0 \
-O ^64bit \
-d "$root_dir" \
-m 5 \
-r 1 \
-t ext2 \
"$img_file" \
32M \
;
# Test the ext2 by mounting it with sudo.
# sudo is only used for testing.
mountpoint=mnt
mkdir -p "$mountpoint"
sudo mount "$img_file" "$mountpoint"
sudo ls -l "$mountpoint"
sudo cmp "${mountpoint}/qwer" "${root_dir}/qwer"
sudo umount "$mountpoint"
关键选项是-d
, 它选择用于镜像的目录,它是 commit 中 v1.43 的一个相对较新的补充。0d4deba22e2aa95ad958b44972dc933fd0ebbc59
因此,它可以在 Ubuntu 18.04 上直接运行,其中 e2fsprogs 1.44.1-1,但不能在 Ubuntu 16.04 上运行,后者的版本为 1.42.13。
然而,我们可以像 Buildroot 一样,在 Ubuntu 16.04 上轻松地从源代码编译它:
git clone git://git.kernel.org/pub/scm/fs/ext2/e2fsprogs.git
cd e2fsprogs
git checkout v1.44.4
./configure
make -j`nproc`
./misc/mke2fs -h
如果mke2fs
失败:
__populate_fs: Operation not supported while setting xattrs for "qwer"
mke2fs: Operation not supported while populating file system
添加选项时:
-E no_copy_xattrs
例如,当根目录位于 NFS 中或而tmpfs
不是 extX 作为这些文件系统时,这是必需的似乎没有扩展属性。
mke2fs
通常符号链接到mkfs.extX
,并man mke2fs
表示如果您将 call if 与此类符号链接一起使用,则-t
隐含了 then 。
我是如何发现这一点以及如何解决未来的问题的:构建根无需 sudo 即可生成 ext2 映像如图所示,所以我只是运行构建V=1
并从最后的图像生成部分提取命令。好的旧复制粘贴从来没有让我失望过。
TODO:描述如何解决以下问题:
- 在映像中创建 sudo 拥有的文件。 Buildroot 就可以做到。
- 自动计算所需的最小尺寸。最初估计
du
文件大小和find . | wc
目录结构,最小为 32Mb(较小的失败),然后加倍直到命令起作用,这可能是一个非常不错的方法。 Buildroot曾经这样做过,但由于某种原因停止了,但我们自己实现起来很容易。 - 方便地从分区中提取所有文件:
一个镜像文件中的多个分区
答案2
必须是ext4吗?
如果有其他选择,您可以试试运气
- mksquashfs,从用户空间生成只读压缩文件系统
- mkisofs,生成常用于光学介质的只读文件系统
- cpio, tar, ...需要先解压的档案
否则,要使ext4
用户空间成为现实,您必须
- 疯狂地
debugfs
- 在用户空间虚拟机中启动内核
- 找到另一个知道处理 ext4 图像的纯用户空间实用程序
关于debugfs
,大多数文件系统甚至没有这样的实用程序,你很幸运。
用户会话:
$ truncate -s 64M app.ext4
$ /sbin/mkfs.ext4 app.ext4
Creating filesystem with 65536 1k blocks and 16384 inodes
$ /sbin/debugfs -w app.ext4
debugfs: mkdir this_is_crazy
debugfs: cd this_is_crazy
debugfs: write /proc/config.gz config.gz
Allocated inode: 13
根会话:(只是为了检查它是否有效)
# mount -o loop app.ext4 loop/
# cd loop/
# ls
lost+found this_is_crazy
# md5sum this_is_crazy/config.gz /proc/config.gz
7b414ad844272a9e3c31931037fe0495 this_is_crazy/config.gz
7b414ad844272a9e3c31931037fe0495 /proc/config.gz
所以,这是可能的并且有效。
然而,最实用的选择仍然应该是以某种方式使用 root。
答案3
sudo
正是针对此类问题,您需要授予用户在 /etc/sudoers 文件中运行 mount 命令的权限
然后在您的脚本中您可以在 mount 命令前面加上 sudo:
sudo mount -o loop $IMG $MNT
您可以配置规则,使其不需要密码
答案4
virt-make-fs命令可以满足您的所有要求
sudo yum install -y /usr/bin/virt-make-fs
virt-make-fs -s 64M -t ext4 $APP $IMG --label=$LBL