mirror of
https://github.com/lkl/linux.git
synced 2025-12-18 23:53:03 +09:00
lklfuse: add lock parameter to avoid duplicate mounts
This lock-while-mounted behaviour is similar to what QEMU does, and can help avoid duplicate mounts. Allowing for an explicit lock path that differs from the filesystem image / block device path was intentional, to ensure non-flock supporting filesystems can still be used. Also, there are cases where a block device and partition (e.g. sda and sda1) can both provide access to the same filesystem image, in which case an FS-ID based lock would make sense. Signed-off-by: David Disseldorp <ddiss@suse.de>
This commit is contained in:
@@ -39,7 +39,9 @@ OPTIONS
|
|||||||
|
|
||||||
-o part=parition mount <partition>.
|
-o part=parition mount <partition>.
|
||||||
|
|
||||||
-o ro open file read-only.
|
-o ro open block-device read-only.
|
||||||
|
|
||||||
|
-o lock=<file> only mount after taking an exclusive lock on <file>.
|
||||||
|
|
||||||
-o opts=options Linux kernel mount <options> (use \\ to escape , and =).
|
-o opts=options Linux kernel mount <options> (use \\ to escape , and =).
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <sys/file.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
@@ -24,6 +25,7 @@ struct lklfuse {
|
|||||||
const char *log;
|
const char *log;
|
||||||
const char *type;
|
const char *type;
|
||||||
const char *opts;
|
const char *opts;
|
||||||
|
const char *lock;
|
||||||
struct lkl_disk disk;
|
struct lkl_disk disk;
|
||||||
int disk_id;
|
int disk_id;
|
||||||
int part;
|
int part;
|
||||||
@@ -46,6 +48,7 @@ static struct fuse_opt lklfuse_opts[] = {
|
|||||||
LKLFUSE_OPT("mb=%d", mb, 0),
|
LKLFUSE_OPT("mb=%d", mb, 0),
|
||||||
LKLFUSE_OPT("opts=%s", opts, 0),
|
LKLFUSE_OPT("opts=%s", opts, 0),
|
||||||
LKLFUSE_OPT("part=%d", part, 0),
|
LKLFUSE_OPT("part=%d", part, 0),
|
||||||
|
LKLFUSE_OPT("lock=%s", lock, 0),
|
||||||
FUSE_OPT_KEY("-h", KEY_HELP),
|
FUSE_OPT_KEY("-h", KEY_HELP),
|
||||||
FUSE_OPT_KEY("--help", KEY_HELP),
|
FUSE_OPT_KEY("--help", KEY_HELP),
|
||||||
FUSE_OPT_KEY("-V", KEY_VERSION),
|
FUSE_OPT_KEY("-V", KEY_VERSION),
|
||||||
@@ -58,7 +61,7 @@ static struct fuse_opt lklfuse_opts[] = {
|
|||||||
static void usage(void)
|
static void usage(void)
|
||||||
{
|
{
|
||||||
printf(
|
printf(
|
||||||
"usage: lklfuse file mountpoint [options]\n"
|
"usage: lklfuse block-device mountpoint [options]\n"
|
||||||
"\n"
|
"\n"
|
||||||
"general options:\n"
|
"general options:\n"
|
||||||
" -o opt,[opt...] mount options\n"
|
" -o opt,[opt...] mount options\n"
|
||||||
@@ -70,7 +73,8 @@ static void usage(void)
|
|||||||
" -o type=fstype filesystem type\n"
|
" -o type=fstype filesystem type\n"
|
||||||
" -o mb=memory amount of memory to allocate in MB (default: 64)\n"
|
" -o mb=memory amount of memory to allocate in MB (default: 64)\n"
|
||||||
" -o part=parition partition to mount\n"
|
" -o part=parition partition to mount\n"
|
||||||
" -o ro open file read-only\n"
|
" -o ro open block-device read-only\n"
|
||||||
|
" -o lock=FILE only mount after taking an exclusive lock on FILE\n"
|
||||||
" -o opts=options mount options (use \\ to escape , and =)\n"
|
" -o opts=options mount options (use \\ to escape , and =)\n"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -791,7 +795,7 @@ int main(int argc, char **argv)
|
|||||||
struct fuse_cmdline_opts cli_opts;
|
struct fuse_cmdline_opts cli_opts;
|
||||||
struct fuse *fuse;
|
struct fuse *fuse;
|
||||||
struct stat st;
|
struct stat st;
|
||||||
int ret;
|
int ret, lockfd = -1;
|
||||||
|
|
||||||
if (fuse_opt_parse(&args, &lklfuse, lklfuse_opts, lklfuse_opt_proc))
|
if (fuse_opt_parse(&args, &lklfuse, lklfuse_opts, lklfuse_opt_proc))
|
||||||
return 1;
|
return 1;
|
||||||
@@ -801,6 +805,23 @@ int main(int argc, char **argv)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (lklfuse.lock) {
|
||||||
|
lockfd = open(lklfuse.lock, O_RDWR | O_CREAT, 0644);
|
||||||
|
if (lockfd < 0) {
|
||||||
|
fprintf(stderr, "failed to open %s: %s\n",
|
||||||
|
lklfuse.lock, strerror(errno));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = flock(lockfd, LOCK_EX | LOCK_NB);
|
||||||
|
if (ret < 0) {
|
||||||
|
fprintf(stderr, "unable to exclusively lock %s: %s\n",
|
||||||
|
lklfuse.lock, strerror(errno));
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
/* lock dropped when lockfd is closed on program exit */
|
||||||
|
}
|
||||||
|
|
||||||
if (fuse_parse_cmdline(&args, &cli_opts))
|
if (fuse_parse_cmdline(&args, &cli_opts))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user