summaryrefslogtreecommitdiffstats
path: root/sys-utils/losetup.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys-utils/losetup.c')
-rw-r--r--sys-utils/losetup.c68
1 files changed, 51 insertions, 17 deletions
diff --git a/sys-utils/losetup.c b/sys-utils/losetup.c
index d862fd8e7..f455b49c3 100644
--- a/sys-utils/losetup.c
+++ b/sys-utils/losetup.c
@@ -43,6 +43,7 @@ enum {
COL_NAME = 0,
COL_AUTOCLR,
COL_BACK_FILE,
+ COL_FILE_FMT_TYPE,
COL_BACK_INO,
COL_BACK_MAJMIN,
COL_MAJMIN,
@@ -69,18 +70,19 @@ struct colinfo {
};
static struct colinfo infos[] = {
- [COL_AUTOCLR] = { "AUTOCLEAR", 1, SCOLS_FL_RIGHT, N_("autoclear flag set"), SCOLS_JSON_BOOLEAN},
- [COL_BACK_FILE] = { "BACK-FILE", 0.3, 0, N_("device backing file")},
- [COL_BACK_INO] = { "BACK-INO", 4, SCOLS_FL_RIGHT, N_("backing file inode number"), SCOLS_JSON_NUMBER},
- [COL_BACK_MAJMIN] = { "BACK-MAJ:MIN", 6, 0, N_("backing file major:minor device number")},
- [COL_NAME] = { "NAME", 0.25, 0, N_("loop device name")},
- [COL_OFFSET] = { "OFFSET", 5, SCOLS_FL_RIGHT, N_("offset from the beginning"), SCOLS_JSON_NUMBER},
- [COL_PARTSCAN] = { "PARTSCAN", 1, SCOLS_FL_RIGHT, N_("partscan flag set"), SCOLS_JSON_BOOLEAN},
- [COL_RO] = { "RO", 1, SCOLS_FL_RIGHT, N_("read-only device"), SCOLS_JSON_BOOLEAN},
- [COL_SIZELIMIT] = { "SIZELIMIT", 5, SCOLS_FL_RIGHT, N_("size limit of the file in bytes"), SCOLS_JSON_NUMBER},
- [COL_MAJMIN] = { "MAJ:MIN", 3, 0, N_("loop device major:minor number")},
- [COL_DIO] = { "DIO", 1, SCOLS_FL_RIGHT, N_("access backing file with direct-io"), SCOLS_JSON_BOOLEAN},
- [COL_LOGSEC] = { "LOG-SEC", 4, SCOLS_FL_RIGHT, N_("logical sector size in bytes"), SCOLS_JSON_NUMBER},
+ [COL_AUTOCLR] = { "AUTOCLEAR", 1, SCOLS_FL_RIGHT, N_("autoclear flag set"), SCOLS_JSON_BOOLEAN},
+ [COL_BACK_FILE] = { "BACK-FILE", 0.3, 0, N_("device backing file")},
+ [COL_FILE_FMT_TYPE] = { "FILE-FORMAT", 1, 0, N_("backing file format")},
+ [COL_BACK_INO] = { "BACK-INO", 4, SCOLS_FL_RIGHT, N_("backing file inode number"), SCOLS_JSON_NUMBER},
+ [COL_BACK_MAJMIN] = { "BACK-MAJ:MIN", 6, 0, N_("backing file major:minor device number")},
+ [COL_NAME] = { "NAME", 0.25, 0, N_("loop device name")},
+ [COL_OFFSET] = { "OFFSET", 5, SCOLS_FL_RIGHT, N_("offset from the beginning"), SCOLS_JSON_NUMBER},
+ [COL_PARTSCAN] = { "PARTSCAN", 1, SCOLS_FL_RIGHT, N_("partscan flag set"), SCOLS_JSON_BOOLEAN},
+ [COL_RO] = { "RO", 1, SCOLS_FL_RIGHT, N_("read-only device"), SCOLS_JSON_BOOLEAN},
+ [COL_SIZELIMIT] = { "SIZELIMIT", 5, SCOLS_FL_RIGHT, N_("size limit of the file in bytes"), SCOLS_JSON_NUMBER},
+ [COL_MAJMIN] = { "MAJ:MIN", 3, 0, N_("loop device major:minor number")},
+ [COL_DIO] = { "DIO", 1, SCOLS_FL_RIGHT, N_("access backing file with direct-io"), SCOLS_JSON_BOOLEAN},
+ [COL_LOGSEC] = { "LOG-SEC", 4, SCOLS_FL_RIGHT, N_("logical sector size in bytes"), SCOLS_JSON_NUMBER},
};
static int columns[ARRAY_SIZE(infos) * 2] = {-1};
@@ -120,11 +122,16 @@ static int printf_loopdev(struct loopdev_cxt *lc)
ino_t ino = 0;
char *fname;
uint32_t type;
+ char *file_fmt_str;
fname = loopcxt_get_backing_file(lc);
if (!fname)
return -EINVAL;
+ file_fmt_str = loopcxt_get_file_fmt_type_string(lc);
+ if (!file_fmt_str)
+ return -EINVAL;
+
if (loopcxt_get_backing_devno(lc, &dev) == 0)
loopcxt_get_backing_inode(lc, &ino);
@@ -141,6 +148,9 @@ static int printf_loopdev(struct loopdev_cxt *lc)
if (loopcxt_get_sizelimit(lc, &x) == 0 && x)
printf(_(", sizelimit %ju"), x);
+
+ printf(_(", file-format %s"), file_fmt_str);
+
goto done;
}
@@ -162,6 +172,8 @@ static int printf_loopdev(struct loopdev_cxt *lc)
printf(_(", encryption %s (type %u)"), e, type);
}
+ printf(_(", file-format %s"), file_fmt_str);
+
done:
free(fname);
printf("\n");
@@ -241,6 +253,9 @@ static int set_scols_data(struct loopdev_cxt *lc, struct libscols_line *ln)
case COL_BACK_FILE:
p = loopcxt_get_backing_file(lc);
break;
+ case COL_FILE_FMT_TYPE:
+ p = loopcxt_get_file_fmt_type_string(lc);
+ break;
case COL_OFFSET:
if (loopcxt_get_offset(lc, &x) == 0)
xasprintf(&np, "%jd", x);
@@ -424,6 +439,7 @@ static void __attribute__((__noreturn__)) usage(void)
fputs(_(" -r, --read-only set up a read-only loop device\n"), out);
fputs(_(" --direct-io[=<on|off>] open backing file with O_DIRECT\n"), out);
fputs(_(" --show print device name after setup (with -f)\n"), out);
+ fputs(_(" -t, --type set file format type of the loop device\n"), out);
fputs(_(" -v, --verbose verbose mode\n"), out);
/* output options */
@@ -473,7 +489,7 @@ static void warn_size(const char *filename, uint64_t size, uint64_t offset, int
static int create_loop(struct loopdev_cxt *lc,
int nooverlap, int lo_flags, int flags,
const char *file, uint64_t offset, uint64_t sizelimit,
- uint64_t blocksize)
+ uint64_t blocksize, uint32_t file_fmt_type)
{
int hasdev = loopcxt_has_device(lc);
int rc = 0;
@@ -568,6 +584,12 @@ static int create_loop(struct loopdev_cxt *lc,
warn(_("%s: failed to use backing file"), file);
break;
}
+
+ if ((rc = loopcxt_set_file_fmt_type(lc, file_fmt_type))) {
+ warn(_("failed to use backing file format type"));
+ break;
+ }
+
errno = 0;
rc = loopcxt_setup_device(lc);
if (rc == 0)
@@ -595,6 +617,8 @@ int main(int argc, char **argv)
char *outarg = NULL;
int list = 0;
unsigned long use_dio = 0, set_dio = 0, set_blocksize = 0;
+ int use_file_fmt_type = 0;
+ uint32_t file_fmt_type = 0;
enum {
OPT_SIZELIMIT = CHAR_MAX + 1,
@@ -625,6 +649,7 @@ int main(int argc, char **argv)
{ "direct-io", optional_argument, NULL, OPT_DIO },
{ "raw", no_argument, NULL, OPT_RAW },
{ "show", no_argument, NULL, OPT_SHOW },
+ { "type", required_argument, NULL, 't' },
{ "verbose", no_argument, NULL, 'v' },
{ "version", no_argument, NULL, 'V' },
{ NULL, 0, NULL, 0 }
@@ -647,7 +672,7 @@ int main(int argc, char **argv)
if (loopcxt_init(&lc, 0))
err(EXIT_FAILURE, _("failed to initialize loopcxt"));
- while ((c = getopt_long(argc, argv, "ab:c:d:Dfhj:JlLno:O:PrvV",
+ while ((c = getopt_long(argc, argv, "ab:c:d:Dfhj:JlLno:O:Prt:vV",
longopts, NULL)) != -1) {
err_exclusive_options(c, longopts, excl, excl_st);
@@ -725,6 +750,14 @@ int main(int argc, char **argv)
if (optarg)
use_dio = parse_switch(optarg, _("argument error"), "on", "off", NULL);
break;
+ case 't':
+ if (optarg) {
+ if (parse_file_fmt_type(optarg, &file_fmt_type) == 0)
+ use_file_fmt_type = 1;
+ else
+ errx(EXIT_FAILURE, _("failed to parse file format type"));
+ }
+ break;
case 'v':
break;
case OPT_SIZELIMIT: /* --sizelimit */
@@ -763,6 +796,7 @@ int main(int argc, char **argv)
columns[ncolumns++] = COL_AUTOCLR;
columns[ncolumns++] = COL_RO;
columns[ncolumns++] = COL_BACK_FILE;
+ columns[ncolumns++] = COL_FILE_FMT_TYPE;
columns[ncolumns++] = COL_DIO;
columns[ncolumns++] = COL_LOGSEC;
}
@@ -822,10 +856,10 @@ int main(int argc, char **argv)
}
if (act != A_CREATE &&
- (sizelimit || lo_flags || showdev))
+ (sizelimit || lo_flags || showdev || use_file_fmt_type))
errx(EXIT_FAILURE,
_("the options %s are allowed during loop device setup only"),
- "--{sizelimit,partscan,read-only,show}");
+ "--{sizelimit,partscan,read-only,show,type}");
if ((flags & LOOPDEV_FL_OFFSET) &&
act != A_CREATE && (act != A_SHOW || !file))
@@ -838,7 +872,7 @@ int main(int argc, char **argv)
switch (act) {
case A_CREATE:
res = create_loop(&lc, no_overlap, lo_flags, flags, file,
- offset, sizelimit, blocksize);
+ offset, sizelimit, blocksize, file_fmt_type);
if (res == 0) {
if (showdev)
printf("%s\n", loopcxt_get_device(&lc));