Arch Linux

Please read this before reporting a bug:
https://wiki.archlinux.org/title/Bug_reporting_guidelines

Do NOT report bugs when a package is just outdated, or it is in the AUR. Use the 'flag out of date' link on the package page, or the Mailing List.

REPEAT: Do NOT report bugs for outdated packages!
Tasklist

FS#79979 - RFE: python - consider adding support for open file descriptor locking

Attached to Project: Arch Linux
Opened by Gene (GeneC) - Sunday, 15 October 2023, 23:35 GMT
Last edited by Toolybird (Toolybird) - Monday, 16 October 2023, 19:24 GMT
Task Type Feature Request
Category Packages: Core
Status Closed
Assigned To No-one
Architecture All
Severity Low
Priority Normal
Reported Version
Due in Version Undecided
Due Date Undecided
Percent Complete 100%
Votes 0
Private No

Details

Description:
For your consideration:

Linux has supported (non-posix) open file descriptor locks for several years.
Python supports them as of 3.9 per the docs [1].
They do offer some advantages over Posix locks. see e.g. [3]

They are: fcntl.F_OFD_SETLK and fcntl.F_OFD_GETLK

However they dont work in our python 3.11.5.

I confirmed they work fine in C-code but to compile they need [2] :
_GNU_SOURCE to be defined at compile time.

Maybe that is helpful in changing the python build to get them working.

Thanks!

gene

[1] https://docs.python.org/3/library/fcntl.html
[2] https://www.gnu.org/software/libc/manual/html_node/Open-File-Description-Locks.html
[3] https://lwn.net/Articles/586904/
This task depends upon

Closed by  Toolybird (Toolybird)
Monday, 16 October 2023, 19:24 GMT
Reason for closing:  Not a bug
Additional comments about closing:  "Not a bug - just my own coding bug."
Comment by Toolybird (Toolybird) - Monday, 16 October 2023, 03:56 GMT
> they dont work in our python 3.11.5

??? Surely it's a bug then, and not a feature request? Please provide "Steps to reproduce".
Comment by loqs (loqs) - Monday, 16 October 2023, 12:19 GMT
$ python
Python 3.11.5 (main, Sep 2 2023, 14:16:33) [GCC 13.2.1 20230801] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import fcntl
>>> import struct
>>> fcntl.F_OFD_GETLK
36
>>> fcntl.F_OFD_SETLK
37
>>> lockdata = struct.pack('hhllhh', fcntl.F_WRLCK, 0, 0, 10, 0, 0)
>>> f1 = open("testfile", 'w')
>>> try:
... fcntl.fcntl(f1, fcntl.F_OFD_SETLK, lockdata)
... except IOError as e:
... if e.errno != errno.EINVAL:
... raise
... else:
... print('kernel does not support fcntl.F_OFD_SETLK')
... raise
...
b'\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
Edit:
Test use of constant as well as presence.
Comment by Gene (GeneC) - Monday, 16 October 2023, 12:30 GMT
Right the constants are indeed defined - and its entirely possible my code is not right of course.

Code and tests attached.

Notes:
C-code implemtation
-------------------
flock_sizes.c = print size of struct flock
c_lock_test.c = c-code locking with and without OFD

build :
make

- to see size of struct flock elements:
./flock_sizes

Tests
-------------------
Test 1) Using F_SETLK

locking use 2 terminals. run c_lock_test in both.
First will acquire lock second will fail (until first exits)

./c_lock_test

Test 2) Using F_OFD_SETLK

repeat test but with argument to turn on OFD

./c_lock_test ofd

Test (1) and (2) both work.

Python:
-------------------

run test in 2 terminals as above:

Test 3) Using F_SETLK

./lock_test.py

Test 4) Using F_OFD_SETLK

./lock_test.py ofd


Test (3) works, but (4) fails to acquire lock.

Comment by loqs (loqs) - Monday, 16 October 2023, 12:35 GMT
Please see my edit. This would seem to be either an issue in your code or an upstream issue.
Edit:
If you adjust the tests from [1] to be standalone, do they pass for you?

[1] https://github.com/ceph/ceph/blob/main/qa/workunits/fs/misc/filelock_interrupt.py
Comment by Gene (GeneC) - Monday, 16 October 2023, 12:42 GMT
Bah @loqs you're right - very much my bug.

When using OFD the lockdata cannot contain pid - it has to be 0.
Changing line 73 of my python to:
l_pid = 0

Makes it work - very sorry for noise - and thanks for helping me fix my stuff :-

Comment by Gene (GeneC) - Monday, 16 October 2023, 12:47 GMT
@loqs - glanced at link and it has struct sizes which look possibly wrong to me at least on x86 they should be 8 byte offsets ('q') not 4 byte ('l')

The struct table is here: https://docs.python.org/3/library/struct.html

I used flock_sizes to get the correct values.
Comment by Gene (GeneC) - Monday, 16 October 2023, 12:51 GMT
In hindsight would have been better to post to our forum not here - my apologies.

Loading...