erofs-utils: mkfs: improvement for unprivileged container support
When developers want to use erofs as guest container rootfs, it
requires to uid/gid offsetting for each files.
This patch adds uid/gid offsetting feature to mkfs.erofs.
Example of how to use uid/gid offset:
In case of lxc guest image.
Image creation:
mkafs.erofs --uid-offset=100000 --gid-offset=100000 file dir
Set lxc config:
lxc.idmap = u 0 100000 65536
lxc.idmap = g 0 100000 65536
Signed-off-by: Naoto Yamaguchi <naoto.yamaguchi@aisin.co.jp>
Link: https://lore.kernel.org/r/20220814022915.7964-1-naoto.yamaguchi@aisin.co.jp
Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
diff --git a/include/erofs/config.h b/include/erofs/config.h
index 6c6d71f..539d813 100644
--- a/include/erofs/config.h
+++ b/include/erofs/config.h
@@ -68,6 +68,7 @@
u64 c_unix_timestamp;
u32 c_uid, c_gid;
const char *mount_point;
+ long long c_uid_offset, c_gid_offset;
#ifdef WITH_ANDROID
char *target_out_path;
char *fs_config_file;
diff --git a/lib/inode.c b/lib/inode.c
index ce75014..4da28b3 100644
--- a/lib/inode.c
+++ b/lib/inode.c
@@ -855,6 +855,15 @@
inode->i_mode = st->st_mode;
inode->i_uid = cfg.c_uid == -1 ? st->st_uid : cfg.c_uid;
inode->i_gid = cfg.c_gid == -1 ? st->st_gid : cfg.c_gid;
+
+ if (inode->i_uid + cfg.c_uid_offset < 0)
+ erofs_err("uid overflow @ %s", path);
+ inode->i_uid += cfg.c_uid_offset;
+
+ if (inode->i_gid + cfg.c_gid_offset < 0)
+ erofs_err("gid overflow @ %s", path);
+ inode->i_gid += cfg.c_gid_offset;
+
inode->i_mtime = st->st_mtime;
inode->i_mtime_nsec = ST_MTIM_NSEC(st);
diff --git a/mkfs/main.c b/mkfs/main.c
index deb8e1f..b969b35 100644
--- a/mkfs/main.c
+++ b/mkfs/main.c
@@ -51,6 +51,8 @@
{"blobdev", required_argument, NULL, 13},
{"ignore-mtime", no_argument, NULL, 14},
{"preserve-mtime", no_argument, NULL, 15},
+ {"uid-offset", required_argument, NULL, 16},
+ {"gid-offset", required_argument, NULL, 17},
{"mount-point", required_argument, NULL, 512},
#ifdef WITH_ANDROID
{"product-out", required_argument, NULL, 513},
@@ -97,6 +99,8 @@
#endif
" --force-uid=# set all file uids to # (# = UID)\n"
" --force-gid=# set all file gids to # (# = GID)\n"
+ " --uid-offset=# add offset # to all file uids (# = id offset)\n"
+ " --gid-offset=# add offset # to all file gids (# = id offset)\n"
" --help display this help and exit\n"
" --ignore-mtime use build time instead of strict per-file modification time\n"
" --max-extent-bytes=# set maximum decompressed extent size # in bytes\n"
@@ -383,6 +387,22 @@
case 15:
cfg.c_ignore_mtime = false;
break;
+ case 16:
+ errno = 0;
+ cfg.c_uid_offset = strtoll(optarg, &endptr, 0);
+ if (errno || *endptr != '\0') {
+ erofs_err("invalid uid offset %s", optarg);
+ return -EINVAL;
+ }
+ break;
+ case 17:
+ errno = 0;
+ cfg.c_gid_offset = strtoll(optarg, &endptr, 0);
+ if (errno || *endptr != '\0') {
+ erofs_err("invalid gid offset %s", optarg);
+ return -EINVAL;
+ }
+ break;
case 1:
usage();
exit(0);