From: "Daniel P. Berrangé" <berrange@redhat.com>
To: Li Feng <fengli@smartx.com>
Cc: Kevin Wolf <kwolf@redhat.com>,
lifeng1519@gmail.com, "open list:raw" <qemu-block@nongnu.org>,
"open list:All patches CC here" <qemu-devel@nongnu.org>,
Max Reitz <mreitz@redhat.com>,
kyle@smartx.com
Subject: Re: [PATCH v2] file-posix: detect the lock using the real file
Date: Thu, 10 Dec 2020 15:59:10 +0000 [thread overview]
Message-ID: <20201210155910.GN24855@redhat.com> (raw)
In-Reply-To: <1607489688-37088-1-git-send-email-fengli@smartx.com>
On Wed, Dec 09, 2020 at 12:54:48PM +0800, Li Feng wrote:
> This patch addresses this issue:
> When accessing a volume on an NFS filesystem without supporting the file lock,
> tools, like qemu-img, will complain "Failed to lock byte 100".
>
> In the original code, the qemu_has_ofd_lock will test the lock on the
> "/dev/null" pseudo-file. Actually, the file.locking is per-drive property,
> which depends on the underlay filesystem.
>
> In this patch, make the 'qemu_has_ofd_lock' with a filename be more
> generic and reasonable.
>
> Signed-off-by: Li Feng <fengli@smartx.com>
> ---
> v2: remove the refactoring.
> ---
> block/file-posix.c | 32 ++++++++++++++++++--------------
> include/qemu/osdep.h | 2 +-
> tests/test-image-locking.c | 2 +-
> util/osdep.c | 19 ++++++++++++-------
> 4 files changed, 32 insertions(+), 23 deletions(-)
>
> diff --git a/block/file-posix.c b/block/file-posix.c
> index 806764f7e3..03be1b188c 100644
> --- a/block/file-posix.c
> +++ b/block/file-posix.c
> @@ -595,7 +595,7 @@ static int raw_open_common(BlockDriverState *bs, QDict *options,
> switch (locking) {
> case ON_OFF_AUTO_ON:
> s->use_lock = true;
> - if (!qemu_has_ofd_lock()) {
> + if (!qemu_has_ofd_lock(filename)) {
> warn_report("File lock requested but OFD locking syscall is "
> "unavailable, falling back to POSIX file locks");
> error_printf("Due to the implementation, locks can be lost "
> @@ -606,7 +606,7 @@ static int raw_open_common(BlockDriverState *bs, QDict *options,
> s->use_lock = false;
> break;
> case ON_OFF_AUTO_AUTO:
> - s->use_lock = qemu_has_ofd_lock();
> + s->use_lock = qemu_has_ofd_lock(filename);
> break;
> default:
> abort();
> @@ -2388,6 +2388,7 @@ raw_co_create(BlockdevCreateOptions *options, Error **errp)
> int fd;
> uint64_t perm, shared;
> int result = 0;
> + bool use_lock;
>
> /* Validate options and set default values */
> assert(options->driver == BLOCKDEV_DRIVER_FILE);
> @@ -2428,19 +2429,22 @@ raw_co_create(BlockdevCreateOptions *options, Error **errp)
> perm = BLK_PERM_WRITE | BLK_PERM_RESIZE;
> shared = BLK_PERM_ALL & ~BLK_PERM_RESIZE;
>
> - /* Step one: Take locks */
> - result = raw_apply_lock_bytes(NULL, fd, perm, ~shared, false, errp);
> - if (result < 0) {
> - goto out_close;
> - }
> + use_lock = qemu_has_ofd_lock(file_opts->filename);
> + if (use_lock) {
> + /* Step one: Take locks */
> + result = raw_apply_lock_bytes(NULL, fd, perm, ~shared, false, errp);
> + if (result < 0) {
> + goto out_close;
> + }
>
> - /* Step two: Check that nobody else has taken conflicting locks */
> - result = raw_check_lock_bytes(fd, perm, shared, errp);
> - if (result < 0) {
> - error_append_hint(errp,
> - "Is another process using the image [%s]?\n",
> - file_opts->filename);
> - goto out_unlock;
> + /* Step two: Check that nobody else has taken conflicting locks */
> + result = raw_check_lock_bytes(fd, perm, shared, errp);
> + if (result < 0) {
> + error_append_hint(errp,
> + "Is another process using the image [%s]?\n",
> + file_opts->filename);
> + goto out_unlock;
> + }
> }
>
> /* Clear the file by truncating it to 0 */
> diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h
> index f9ec8c84e9..349adad465 100644
> --- a/include/qemu/osdep.h
> +++ b/include/qemu/osdep.h
> @@ -512,7 +512,7 @@ int qemu_dup(int fd);
> int qemu_lock_fd(int fd, int64_t start, int64_t len, bool exclusive);
> int qemu_unlock_fd(int fd, int64_t start, int64_t len);
> int qemu_lock_fd_test(int fd, int64_t start, int64_t len, bool exclusive);
> -bool qemu_has_ofd_lock(void);
> +bool qemu_has_ofd_lock(const char *filename);
> #endif
>
> #if defined(__HAIKU__) && defined(__i386__)
> diff --git a/tests/test-image-locking.c b/tests/test-image-locking.c
> index ba057bd66c..3e80246081 100644
> --- a/tests/test-image-locking.c
> +++ b/tests/test-image-locking.c
> @@ -149,7 +149,7 @@ int main(int argc, char **argv)
>
> g_test_init(&argc, &argv, NULL);
>
> - if (qemu_has_ofd_lock()) {
> + if (qemu_has_ofd_lock(NULL)) {
> g_test_add_func("/image-locking/basic", test_image_locking_basic);
> g_test_add_func("/image-locking/set-perm-abort", test_set_perm_abort);
> }
> diff --git a/util/osdep.c b/util/osdep.c
> index 66d01b9160..20119aa9ae 100644
> --- a/util/osdep.c
> +++ b/util/osdep.c
> @@ -187,7 +187,7 @@ static int qemu_parse_fdset(const char *param)
> return qemu_parse_fd(param);
> }
>
> -static void qemu_probe_lock_ops(void)
> +static void qemu_probe_lock_ops(const char *filename)
> {
> if (fcntl_op_setlk == -1) {
> #ifdef F_OFD_SETLK
> @@ -200,10 +200,15 @@ static void qemu_probe_lock_ops(void)
> .l_type = F_WRLCK,
> };
>
> - fd = open("/dev/null", O_RDWR);
> + if (filename) {
> + fd = open(filename, O_RDWR);
> + } else {
> + fd = open("/dev/null", O_RDONLY);
> + }
> if (fd < 0) {
> fprintf(stderr,
> - "Failed to open /dev/null for OFD lock probing: %s\n",
> + "Failed to open %s for OFD lock probing: %s\n",
> + filename ? filename : "/dev/null",
> strerror(errno));
> fcntl_op_setlk = F_SETLK;
> fcntl_op_getlk = F_GETLK;
This is still just as broken as v1, because it is setting
a global variable fcntl_op_getlk, based on result of an
operation whose result will vary depending on the filename
parameter.
If you want to test whether a filesystem supports fcntl
locks in general, don't touch qemu_has_ofd_lock or
qemu_probe_lock_ops methods at all. Those are just for
probing regular fcntl vs OFD fcntl locks.
> @@ -225,9 +230,9 @@ static void qemu_probe_lock_ops(void)
> }
> }
>
> -bool qemu_has_ofd_lock(void)
> +bool qemu_has_ofd_lock(const char *filename)
> {
> - qemu_probe_lock_ops();
> + qemu_probe_lock_ops(filename);
> #ifdef F_OFD_SETLK
> return fcntl_op_setlk == F_OFD_SETLK;
> #else
> @@ -244,7 +249,7 @@ static int qemu_lock_fcntl(int fd, int64_t start, int64_t len, int fl_type)
> .l_len = len,
> .l_type = fl_type,
> };
> - qemu_probe_lock_ops();
> + qemu_probe_lock_ops(NULL);
> do {
> ret = fcntl(fd, fcntl_op_setlk, &fl);
> } while (ret == -1 && errno == EINTR);
> @@ -270,7 +275,7 @@ int qemu_lock_fd_test(int fd, int64_t start, int64_t len, bool exclusive)
> .l_len = len,
> .l_type = exclusive ? F_WRLCK : F_RDLCK,
> };
> - qemu_probe_lock_ops();
> + qemu_probe_lock_ops(NULL);
> ret = fcntl(fd, fcntl_op_getlk, &fl);
> if (ret == -1) {
> return -errno;
> --
> 2.24.3
>
>
Regards,
Daniel
--
|: https://berrange.com -o- https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org -o- https://fstop138.berrange.com :|
|: https://entangle-photo.org -o- https://www.instagram.com/dberrange :|
next prev parent reply other threads:[~2020-12-10 16:09 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-12-08 12:59 [PATCH] file-posix: detect the lock using the real file Li Feng
2020-12-08 13:45 ` Daniel P. Berrangé
2020-12-09 3:49 ` Li Feng
2020-12-08 14:38 ` Kevin Wolf
2020-12-09 4:09 ` Li Feng
2020-12-09 9:33 ` Daniel P. Berrangé
2020-12-09 17:43 ` Kevin Wolf
2020-12-10 14:56 ` Li Feng
2020-12-10 15:29 ` Daniel P. Berrangé
2020-12-10 15:53 ` Feng Li
2020-12-10 15:56 ` Daniel P. Berrangé
2020-12-09 4:54 ` [PATCH v2] " Li Feng
2020-12-10 15:59 ` Daniel P. Berrangé [this message]
2020-12-10 16:12 ` Feng Li
-- strict thread matches above, loose matches on Subject: below --
2020-12-10 15:54 Li Feng
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20201210155910.GN24855@redhat.com \
--to=berrange@redhat.com \
--cc=fengli@smartx.com \
--cc=kwolf@redhat.com \
--cc=kyle@smartx.com \
--cc=lifeng1519@gmail.com \
--cc=mreitz@redhat.com \
--cc=qemu-block@nongnu.org \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.