losetup: implement -r option. Closes 4033.

function                                             old     new   delta
packed_usage                                       28595   28633     +38
losetup_main                                         285     290      +5
singlemount                                          906     908      +2
set_loop                                             674     672      -2

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
Denys Vlasenko 2011-09-12 02:13:47 +02:00
parent dd1061b6a7
commit 13e709c53f
4 changed files with 17 additions and 13 deletions

View File

@ -1164,7 +1164,7 @@ extern int del_loop(const char *device) FAST_FUNC;
/* If *devname is not NULL, use that name, otherwise try to find free one, /* If *devname is not NULL, use that name, otherwise try to find free one,
* malloc and return it in *devname. * malloc and return it in *devname.
* return value: 1: read-only loopdev was setup, 0: rw, < 0: error */ * return value: 1: read-only loopdev was setup, 0: rw, < 0: error */
extern int set_loop(char **devname, const char *file, unsigned long long offset) FAST_FUNC; extern int set_loop(char **devname, const char *file, unsigned long long offset, int ro) FAST_FUNC;
/* Like bb_ask below, but asks on stdin with no timeout. */ /* Like bb_ask below, but asks on stdin with no timeout. */
char *bb_ask_stdin(const char * prompt) FAST_FUNC; char *bb_ask_stdin(const char * prompt) FAST_FUNC;

View File

@ -84,7 +84,7 @@ int FAST_FUNC del_loop(const char *device)
search will re-use an existing loop device already bound to that search will re-use an existing loop device already bound to that
file/offset if it finds one. file/offset if it finds one.
*/ */
int FAST_FUNC set_loop(char **device, const char *file, unsigned long long offset) int FAST_FUNC set_loop(char **device, const char *file, unsigned long long offset, int ro)
{ {
char dev[LOOP_NAMESIZE]; char dev[LOOP_NAMESIZE];
char *try; char *try;
@ -93,11 +93,13 @@ int FAST_FUNC set_loop(char **device, const char *file, unsigned long long offse
int i, dfd, ffd, mode, rc = -1; int i, dfd, ffd, mode, rc = -1;
/* Open the file. Barf if this doesn't work. */ /* Open the file. Barf if this doesn't work. */
mode = O_RDWR; mode = ro ? O_RDONLY : O_RDWR;
ffd = open(file, mode); ffd = open(file, mode);
if (ffd < 0) { if (ffd < 0) {
mode = O_RDONLY; if (mode != O_RDONLY) {
ffd = open(file, mode); mode = O_RDONLY;
ffd = open(file, mode);
}
if (ffd < 0) if (ffd < 0)
return -errno; return -errno;
} }

View File

@ -8,11 +8,12 @@
*/ */
//usage:#define losetup_trivial_usage //usage:#define losetup_trivial_usage
//usage: "[-o OFS] LOOPDEV FILE - associate loop devices\n" //usage: "[-r] [-o OFS] LOOPDEV FILE - associate loop devices\n"
//usage: " losetup -d LOOPDEV - disassociate\n" //usage: " losetup -d LOOPDEV - disassociate\n"
//usage: " losetup [-f] - show" //usage: " losetup [-f] - show"
//usage:#define losetup_full_usage "\n\n" //usage:#define losetup_full_usage "\n\n"
//usage: " -o OFS Start OFS bytes into FILE" //usage: " -o OFS Start OFS bytes into FILE"
//usage: "\n -r Read-only"
//usage: "\n -f Show first free loop device" //usage: "\n -f Show first free loop device"
//usage: //usage:
//usage:#define losetup_notes_usage //usage:#define losetup_notes_usage
@ -37,11 +38,12 @@ int losetup_main(int argc UNUSED_PARAM, char **argv)
OPT_d = (1 << 0), OPT_d = (1 << 0),
OPT_o = (1 << 1), OPT_o = (1 << 1),
OPT_f = (1 << 2), OPT_f = (1 << 2),
OPT_r = (1 << 3), /* must be last */
}; };
/* max 2 args, all opts are mutually exclusive */ /* max 2 args, -d,-o,-f opts are mutually exclusive */
opt_complementary = "?2:d--of:o--df:f--do"; opt_complementary = "?2:d--of:o--df:f--do";
opt = getopt32(argv, "do:f", &opt_o); opt = getopt32(argv, "do:fr", &opt_o);
argv += optind; argv += optind;
if (opt == OPT_o) if (opt == OPT_o)
@ -63,12 +65,12 @@ int losetup_main(int argc UNUSED_PARAM, char **argv)
bb_show_usage(); bb_show_usage();
if (argv[1]) { if (argv[1]) {
/* [-o OFS] BLOCKDEV FILE */ /* [-r] [-o OFS] BLOCKDEV FILE */
if (set_loop(&argv[0], argv[1], offset) < 0) if (set_loop(&argv[0], argv[1], offset, (opt / OPT_r)) < 0)
bb_simple_perror_msg_and_die(argv[0]); bb_simple_perror_msg_and_die(argv[0]);
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
/* [-o OFS] BLOCKDEV */ /* [-r] [-o OFS] BLOCKDEV */
s = query_loop(argv[0]); s = query_loop(argv[0]);
if (!s) if (!s)
bb_simple_perror_msg_and_die(argv[0]); bb_simple_perror_msg_and_die(argv[0]);
@ -78,7 +80,7 @@ int losetup_main(int argc UNUSED_PARAM, char **argv)
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
/* [-o OFS|-f] with no params */ /* [-r] [-o OFS|-f] with no params */
n = 0; n = 0;
while (1) { while (1) {
char *s; char *s;

View File

@ -1809,7 +1809,7 @@ static int singlemount(struct mntent *mp, int ignore_busy)
if (ENABLE_FEATURE_MOUNT_LOOP && S_ISREG(st.st_mode)) { if (ENABLE_FEATURE_MOUNT_LOOP && S_ISREG(st.st_mode)) {
loopFile = bb_simplify_path(mp->mnt_fsname); loopFile = bb_simplify_path(mp->mnt_fsname);
mp->mnt_fsname = NULL; // will receive malloced loop dev name mp->mnt_fsname = NULL; // will receive malloced loop dev name
if (set_loop(&mp->mnt_fsname, loopFile, 0) < 0) { if (set_loop(&mp->mnt_fsname, loopFile, 0, /*ro:*/ 0) < 0) {
if (errno == EPERM || errno == EACCES) if (errno == EPERM || errno == EACCES)
bb_error_msg(bb_msg_perm_denied_are_you_root); bb_error_msg(bb_msg_perm_denied_are_you_root);
else else