[PATCH 2/3] erofs-utils: improve the usage and version text of non-fuse commands
Luke T. Shumaker
lukeshu at lukeshu.com
Fri Nov 3 06:31:21 AEDT 2023
From: "Luke T. Shumaker" <lukeshu at umorpha.io>
For each command:
- Change the format of --help to be closer to the usual GNU format
- Have the --version text mention that it is part of erofs-utils
- Include compile-time feature flags in -V
- Have --help and --version print on stdout not stderr
- Exit with 0 from --help and --version
- Have flag errors print a message saying to use --help instead of
printing the full help text
For fsck.erofs:
- Consolidate the descriptions of --[no-]preserve[-<owner|perms>
- Clarify the range that -d accepts
For mkfs.erofs:
- Print supported algorithms and their level ranges+defaults
- Clarify the range that -d accepts
For mkfs.erofs to have access to the algorithms' level ranges and
defaults, it is necessary to modify
z_erofs_list_available_compressors() to return the full `struct
erofs_algorithm` instead of just the `->name`.
Signed-off-by: Luke T. Shumaker <lukeshu at umorpha.io>
---
dump/main.c | 40 +++++++-----
fsck/main.c | 68 ++++++++++++--------
include/erofs/compress.h | 2 +-
lib/compressor.c | 13 +---
lib/compressor.h | 9 ++-
man/mkfs.erofs.1 | 10 +--
mkfs/main.c | 132 ++++++++++++++++++++++++---------------
7 files changed, 163 insertions(+), 111 deletions(-)
diff --git a/dump/main.c b/dump/main.c
index a952f32..293093d 100644
--- a/dump/main.c
+++ b/dump/main.c
@@ -106,25 +106,31 @@ static struct erofsdump_feature feature_lists[] = {
static int erofsdump_readdir(struct erofs_dir_context *ctx);
-static void usage(void)
+static void usage(int argc, char **argv)
{
- fputs("usage: [options] IMAGE\n\n"
- "Dump erofs layout from IMAGE, and [options] are:\n"
- " -S show statistic information of the image\n"
- " -V, --version print the version number of dump.erofs and exit.\n"
- " -e show extent info (INODE required)\n"
- " -s show information about superblock\n"
- " --device=X specify an extra device to be used together\n"
- " --ls show directory contents (INODE required)\n"
- " --nid=# show the target inode info of nid #\n"
- " --path=X show the target inode info of path X\n"
- " -h, --help display this help and exit.\n",
- stderr);
+ // " 1 2 3 4 5 6 7 8 "
+ // "12345678901234567890123456789012345678901234567890123456789012345678901234567890\n"
+ printf(
+ "Usage: %s [OPTIONS] IMAGE\n"
+ "Dump erofs layout from IMAGE.\n"
+ "\n"
+ "General options:\n"
+ " -V, --version print the version number of dump.erofs and exit\n"
+ " -h, --help display this help and exit\n"
+ "\n"
+ " -S show statistic information of the image\n"
+ " -e show extent info (INODE required)\n"
+ " -s show information about superblock\n"
+ " --device=X specify an extra device to be used together\n"
+ " --ls show directory contents (INODE required)\n"
+ " --nid=# show the target inode info of nid #\n"
+ " --path=X show the target inode info of path X\n",
+ argv[0]);
}
static void erofsdump_print_version(void)
{
- printf("dump.erofs %s\n", cfg.c_version);
+ printf("dump.erofs (erofs-utils) %s\n", cfg.c_version);
}
static int erofsdump_parse_options_cfg(int argc, char **argv)
@@ -155,7 +161,7 @@ static int erofsdump_parse_options_cfg(int argc, char **argv)
++dumpcfg.totalshow;
break;
case 'h':
- usage();
+ usage(argc, argv);
exit(0);
case 3:
err = blob_open_ro(&sbi, optarg);
@@ -663,7 +669,7 @@ int main(int argc, char **argv)
err = erofsdump_parse_options_cfg(argc, argv);
if (err) {
if (err == -EINVAL)
- usage();
+ fprintf(stderr, "Try '%s --help' for more information.\n", argv[0]);
goto exit;
}
@@ -690,7 +696,7 @@ int main(int argc, char **argv)
erofsdump_print_statistic();
if (dumpcfg.show_extent && !dumpcfg.show_inode) {
- usage();
+ fprintf(stderr, "Try '%s --help' for more information.\n", argv[0]);
goto exit_put_super;
}
diff --git a/fsck/main.c b/fsck/main.c
index 2ac3547..aeea892 100644
--- a/fsck/main.c
+++ b/fsck/main.c
@@ -14,6 +14,7 @@
#include "erofs/compress.h"
#include "erofs/decompress.h"
#include "erofs/dir.h"
+#include "../lib/compressor.h"
static int erofsfsck_check_inode(erofs_nid_t pnid, erofs_nid_t nid);
@@ -64,45 +65,58 @@ static void print_available_decompressors(FILE *f, const char *delim)
{
int i = 0;
bool comma = false;
- const char *s;
+ const struct erofs_algorithm *s;
while ((s = z_erofs_list_available_compressors(&i)) != NULL) {
if (comma)
fputs(delim, f);
- fputs(s, f);
+ fputs(s->name, f);
comma = true;
}
fputc('\n', f);
}
-static void usage(void)
+static void usage(int argc, char **argv)
{
- fputs("usage: [options] IMAGE\n\n"
- "Check erofs filesystem compatibility and integrity of IMAGE, and [options] are:\n"
- " -V, --version print the version number of fsck.erofs and exit\n"
- " -d# set output message level to # (maximum 9)\n"
- " -p print total compression ratio of all files\n"
- " --device=X specify an extra device to be used together\n"
- " --extract[=X] check if all files are well encoded, optionally extract to X\n"
- " -h, --help display this help and exit\n"
- "\nExtraction options (--extract=X is required):\n"
- " --force allow extracting to root\n"
- " --overwrite overwrite files that already exist\n"
- " --preserve extract with the same ownership and permissions as on the filesystem\n"
- " (default for superuser)\n"
- " --preserve-owner extract with the same ownership as on the filesystem\n"
- " --preserve-perms extract with the same permissions as on the filesystem\n"
- " --no-preserve extract as yourself and apply user's umask on permissions\n"
- " (default for ordinary users)\n"
- " --no-preserve-owner extract as yourself\n"
- " --no-preserve-perms apply user's umask when extracting permissions\n"
- "\nSupported algorithms are: ", stderr);
- print_available_decompressors(stderr, ", ");
+ // " 1 2 3 4 5 6 7 8 "
+ // "12345678901234567890123456789012345678901234567890123456789012345678901234567890\n"
+ printf(
+ "Usage: %s [OPTIONS] IMAGE\n"
+ "Check erofs filesystem compatibility and integrity of IMAGE.\n"
+ "\n"
+ "This version of fsck.erofs is capable of checking images that use any of the\n"
+ "following algorithms: ", argv[0]);
+ print_available_decompressors(stdout, ", ");
+ printf("\n"
+ "General options:\n"
+ " -V, --version print the version number of fsck.erofs and exit\n"
+ " -h, --help display this help and exit\n"
+ "\n"
+ " -d<0-9> set output verbosity; 0=quiet, 9=verbose (default=%i)\n"
+ " -p print total compression ratio of all files\n"
+ " --device=X specify an extra device to be used together\n"
+ " --extract[=X] check if all files are well encoded, optionally\n"
+ " extract to X\n"
+ "\n"
+ "Extraction options (--extract=X is required):\n"
+ " --force allow extracting to root\n"
+ " --overwrite overwrite files that already exist\n"
+ " --[no-]preserve same as --[no-]preserve-owner --[no-]preserve-perms\n"
+ " --[no-]preserve-owner whether to preserve the ownership from the\n"
+ " filesystem (default for superuser), or to extract as\n"
+ " yourself (default for ordinary users)\n"
+ " --[no-]preserve-perms whether to preserve the exact permissions from the\n"
+ " filesystem without applying umask (default for\n"
+ " superuser), or to modify the permissions by applying\n"
+ " umask (default for ordinary users)\n",
+ EROFS_WARN);
}
static void erofsfsck_print_version(void)
{
- printf("fsck.erofs %s\n", cfg.c_version);
+ printf("fsck.erofs (erofs-utils) %s\navailable decompressors: ",
+ cfg.c_version);
+ print_available_decompressors(stdout, ", ");
}
static int erofsfsck_parse_options_cfg(int argc, char **argv)
@@ -128,7 +142,7 @@ static int erofsfsck_parse_options_cfg(int argc, char **argv)
fsckcfg.print_comp_ratio = true;
break;
case 'h':
- usage();
+ usage(argc, argv);
exit(0);
case 2:
fsckcfg.check_decomp = true;
@@ -919,7 +933,7 @@ int main(int argc, char *argv[])
err = erofsfsck_parse_options_cfg(argc, argv);
if (err) {
if (err == -EINVAL)
- usage();
+ fprintf(stderr, "Try '%s --help' for more information.\n", argv[0]);
goto exit;
}
diff --git a/include/erofs/compress.h b/include/erofs/compress.h
index 46cff03..046640b 100644
--- a/include/erofs/compress.h
+++ b/include/erofs/compress.h
@@ -24,7 +24,7 @@ int z_erofs_compress_init(struct erofs_sb_info *sbi,
int z_erofs_compress_exit(void);
const char *z_erofs_list_supported_algorithms(int i, unsigned int *mask);
-const char *z_erofs_list_available_compressors(int *i);
+const struct erofs_algorithm *z_erofs_list_available_compressors(int *i);
static inline bool erofs_is_packed_inode(struct erofs_inode *inode)
{
diff --git a/lib/compressor.c b/lib/compressor.c
index 93f5617..47079d4 100644
--- a/lib/compressor.c
+++ b/lib/compressor.c
@@ -10,14 +10,7 @@
#define EROFS_CONFIG_COMPR_DEF_BOUNDARY (128)
-static const struct erofs_algorithm {
- char *name;
- const struct erofs_compressor *c;
- unsigned int id;
-
- /* its name won't be shown as a supported algorithm */
- bool optimisor;
-} erofs_algs[] = {
+static const struct erofs_algorithm erofs_algs[] = {
{ "lz4",
#if LZ4_ENABLED
&erofs_compressor_lz4,
@@ -65,12 +58,12 @@ const char *z_erofs_list_supported_algorithms(int i, unsigned int *mask)
return "";
}
-const char *z_erofs_list_available_compressors(int *i)
+const struct erofs_algorithm *z_erofs_list_available_compressors(int *i)
{
for (;*i < ARRAY_SIZE(erofs_algs); ++*i) {
if (!erofs_algs[*i].c)
continue;
- return erofs_algs[(*i)++].name;
+ return &erofs_algs[(*i)++];
}
return NULL;
}
diff --git a/lib/compressor.h b/lib/compressor.h
index 9fa01d1..db848f1 100644
--- a/lib/compressor.h
+++ b/lib/compressor.h
@@ -24,7 +24,14 @@ struct erofs_compressor {
void *dst, unsigned int dstsize);
};
-struct erofs_algorithm;
+struct erofs_algorithm {
+ char *name;
+ const struct erofs_compressor *c;
+ unsigned int id;
+
+ /* its name won't be shown as a supported algorithm */
+ bool optimisor;
+};
struct erofs_compress {
struct erofs_sb_info *sbi;
diff --git a/man/mkfs.erofs.1 b/man/mkfs.erofs.1
index 970ff28..45be11a 100644
--- a/man/mkfs.erofs.1
+++ b/man/mkfs.erofs.1
@@ -21,10 +21,12 @@ from \fISOURCE\fR directory.
.SH OPTIONS
.TP
.BI "\-z " compression-algorithm \fR[\fP, # \fR][\fP: ... \fR]\fP
-Set a primary algorithm for data compression, which can be set with an optional
-compression level (1 to 12 for LZ4HC, 0 to 9 for LZMA and 100 to 109 for LZMA
-extreme compression) separated by a comma. Alternative algorithms could be
-specified and separated by colons.
+Set a primary algorithm for data compression, which can be set with an
+optional compression level. Alternative algorithms could be specified
+and separated by colons. See the output of
+.B mkfs.erofs \-\-help
+for a listing of the algorithms that \fBmkfs.erofs\fR is compiled with
+and what their respective level ranges are.
.TP
.BI "\-b " block-size
Set the fundamental block size of the filesystem in bytes. In other words,
diff --git a/mkfs/main.c b/mkfs/main.c
index d86a548..f024026 100644
--- a/mkfs/main.c
+++ b/mkfs/main.c
@@ -30,6 +30,7 @@
#include "erofs/rebuild.h"
#include "../lib/liberofs_private.h"
#include "../lib/liberofs_uuid.h"
+#include "../lib/compressor.h"
#define EROFS_SUPER_END (EROFS_SUPER_OFFSET + sizeof(struct erofs_super_block))
@@ -77,75 +78,104 @@ static void print_available_compressors(FILE *f, const char *delim)
{
int i = 0;
bool comma = false;
- const char *s;
+ const struct erofs_algorithm *s;
while ((s = z_erofs_list_available_compressors(&i)) != NULL) {
if (comma)
fputs(delim, f);
- fputs(s, f);
+ fputs(s->name, f);
comma = true;
}
fputc('\n', f);
}
-static void usage(void)
+static void usage(int argc, char **argv)
{
- fputs("usage: [options] FILE SOURCE(s)\n"
- "Generate EROFS image (FILE) from DIRECTORY, TARBALL and/or EROFS images. And [options] are:\n"
- " -V, --version print the version number of mkfs.erofs and exit\n"
- " -b# set block size to # (# = page size by default)\n"
- " -d# set output message level to # (maximum 9)\n"
- " -x# set xattr tolerance to # (< 0, disable xattrs; default 2)\n"
- " -zX[,Y][:..] X=compressor (Y=compression level, optional)\n"
- " alternative algorithms can be separated by colons(:)\n"
- " -C# specify the size of compress physical cluster in bytes\n"
- " -EX[,...] X=extended options\n"
- " -L volume-label set the volume label (maximum 16)\n"
- " -T# set a fixed UNIX timestamp # to all files\n"
- " -UX use a given filesystem UUID\n"
- " --all-root make all files owned by root\n"
- " --blobdev=X specify an extra device X to store chunked data\n"
- " --chunksize=# generate chunk-based files with #-byte chunks\n"
- " --compress-hints=X specify a file to configure per-file compression strategy\n"
- " --exclude-path=X avoid including file X (X = exact literal path)\n"
- " --exclude-regex=X avoid including files that match X (X = regular expression)\n"
+ int i = 0;
+ const struct erofs_algorithm *s;
+
+ // " 1 2 3 4 5 6 7 8 "
+ // "12345678901234567890123456789012345678901234567890123456789012345678901234567890\n"
+ printf(
+ "Usage: %s [OPTIONS] FILE SOURCE(s)\n"
+ "Generate EROFS image (FILE) from SOURCE(s).\n"
+ "\n"
+ "General options:\n"
+ " -V, --version print the version number of mkfs.erofs and exit\n"
+ " -h, --help display this help and exit\n"
+ "\n"
+ " -b# set block size to # (# = page size by default)\n"
+ " -d<0-9> set output verbosity; 0=quiet, 9=verbose (default=%i)\n"
+ " -x# set xattr tolerance to # (< 0, disable xattrs; default 2)\n"
+ " -zX[,Y][:...] X=compressor (Y=compression level, optional)\n"
+ " alternative compressors can be separated by colons(:)\n"
+ " supported compressors and their level ranges are:\n",
+ argv[0], EROFS_WARN);
+ while ((s = z_erofs_list_available_compressors(&i)) != NULL) {
+ printf(" %s", s->name);
+ if (s->c->setlevel) {
+ if (!strcmp(s->name, "lzma"))
+ /* A little kludge to show the range as disjointed
+ * "0-9,100-109" instead of a continuous "0-109", and to
+ * state what those two subranges respectively mean. */
+ printf("[<0-9,100-109>]\t0-9=normal, 100-109=extreme (default=%i)",
+ s->c->default_level);
+ else
+ printf("[,<0-%i>]\t(default=%i)",
+ s->c->best_level, s->c->default_level);
+ }
+ putchar('\n');
+ }
+ printf(
+ " -C# specify the size of compress physical cluster in bytes\n"
+ " -EX[,...] X=extended options\n"
+ " -L volume-label set the volume label (maximum 16)\n"
+ " -T# set a fixed UNIX timestamp # to all files\n"
+ " -UX use a given filesystem UUID\n"
+ " --all-root make all files owned by root\n"
+ " --blobdev=X specify an extra device X to store chunked data\n"
+ " --chunksize=# generate chunk-based files with #-byte chunks\n"
+ " --compress-hints=X specify a file to configure per-file compression strategy\n"
+ " --exclude-path=X avoid including file X (X = exact literal path)\n"
+ " --exclude-regex=X avoid including files that match X (X = regular expression)\n"
#ifdef HAVE_LIBSELINUX
- " --file-contexts=X specify a file contexts file to setup selinux labels\n"
+ " --file-contexts=X specify a file contexts file to setup selinux labels\n"
#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"
+ " --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"
#ifdef HAVE_ZLIB
- " --gzip try to filter the tarball stream through gzip\n"
+ " --gzip try to filter the tarball stream through gzip\n"
#endif
- " -h, --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"
- " --preserve-mtime keep per-file modification time strictly\n"
- " --aufs replace aufs special files with overlayfs metadata\n"
- " --tar=[fi] generate an image from tarball(s)\n"
- " --ovlfs-strip=[01] strip overlayfs metadata in the target image (e.g. whiteouts)\n"
- " --quiet quiet execution (do not write anything to standard output.)\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"
+ " --preserve-mtime keep per-file modification time strictly\n"
+ " --aufs replace aufs special files with overlayfs metadata\n"
+ " --tar=[fi] generate an image from tarball(s)\n"
+ " --ovlfs-strip=<0,1> strip overlayfs metadata in the target image (e.g. whiteouts)\n"
+ " --quiet quiet execution (do not write anything to standard output.)\n"
#ifndef NDEBUG
- " --random-pclusterblks randomize pclusterblks for big pcluster (debugging only)\n"
- " --random-algorithms randomize per-file algorithms (debugging only)\n"
+ " --random-pclusterblks randomize pclusterblks for big pcluster (debugging only)\n"
+ " --random-algorithms randomize per-file algorithms (debugging only)\n"
#endif
- " --xattr-prefix=X X=extra xattr name prefix\n"
- " --mount-point=X X=prefix of target fs path (default: /)\n"
+ " --xattr-prefix=X X=extra xattr name prefix\n"
+ " --mount-point=X X=prefix of target fs path (default: /)\n"
#ifdef WITH_ANDROID
- "\nwith following android-specific options:\n"
- " --product-out=X X=product_out directory\n"
- " --fs-config-file=X X=fs_config file\n"
- " --block-list-file=X X=block_list file\n"
+ "\n"
+ "Android-specific options:\n"
+ " --product-out=X X=product_out directory\n"
+ " --fs-config-file=X X=fs_config file\n"
+ " --block-list-file=X X=block_list file\n"
#endif
- "\nAvailable compressors are: ", stderr);
- print_available_compressors(stderr, ", ");
+ );
}
static void version(void)
{
- printf("mkfs.erofs %s\n", cfg.c_version);
+ printf("mkfs.erofs (eorfs-utils) %s\navailable compressors: ",
+ cfg.c_version);
+ print_available_compressors(stdout, ", ");
}
static unsigned int pclustersize_packed, pclustersize_max;
@@ -545,7 +575,7 @@ static int mkfs_parse_options_cfg(int argc, char *argv[])
version();
exit(0);
case 'h':
- usage();
+ usage(argc, argv);
exit(0);
default: /* '?' */
@@ -947,13 +977,13 @@ int main(int argc, char **argv)
erofs_show_progs(argc, argv);
if (err) {
if (err == -EINVAL)
- usage();
+ fprintf(stderr, "Try '%s --help' for more information.\n", argv[0]);
return 1;
}
err = parse_source_date_epoch();
if (err) {
- usage();
+ fprintf(stderr, "Try '%s --help' for more information.\n", argv[0]);
return 1;
}
@@ -967,7 +997,7 @@ int main(int argc, char **argv)
err = dev_open(&sbi, cfg.c_img_path);
if (err) {
- usage();
+ fprintf(stderr, "Try '%s --help' for more information.\n", argv[0]);
return 1;
}
--
2.42.0
More information about the Linux-erofs
mailing list