-
Notifications
You must be signed in to change notification settings - Fork 4.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
FileStream.Lock(Int64, Int64) failure on Linux - always uses 'F_WRLCK'. #29173
Comments
What these operations do is based on how they work on Windows.
So using an exclusive lock to implement this seems appropriate.
You can make an API request. |
@tmds - perhaps I should clarify the problem. This simple program throws an exception when run on Linux - (again a file, 'testfile' must be present). using System;
using System.IO;
class Test
{
public static void Main()
{
using (FileStream fs = File.OpenRead("testfile"))
{
fs.Lock((long) 3, (long) 1);
}
}
} No exception is thrown on Windows.
... but is ultimately due to the attempt by .NET Core to set an exclusive lock on a read-only file - this gives the 'Bad file descriptor' error above. |
Yes, if you open with ReadWrite, no exception is thrown. It seems write permission is needed on Linux to be able to take the lock, while it is not required on Windows. |
So the behaviour documented by Microsoft...
.. is not actually possible for read only files on Linux because setting an exclusive lock on a read only file stream is going to throw an exception. But it is possible to create a shared lock on a read only file which when in place will block any attempt by another process to get an exclusive lock. This, of course will not prevent other processes from reading the locked region (or indeed getting another shared lock) - but that has got to be better than throwing an exception.
... just to avoid the exception on Linux. I don't see that as a good solution because now some other process (that has the file open for read/write) can wade in, get an exclusive lock and modify content in the file that the first process is using. Could .NET Core be changed to allow use of F_RDLCK (a shared lock) for read only files on Linux? This could either be implicit based on whether the file is opened read-only, or perhaps some other (API change?) mod could be made. |
@JeremyKuhne wdyt about changing Lock to be a shared lock on Linux for files opened without write access? That means others will be able to read it. I don't see issues with that. Currently the operation is throwing, because read access is not sufficient to take an exclusive lock. |
Sorry about the delayed response. I'm ok with moving to a shared lock. |
I am unable to create a shared lock (F_RDLCK) on a region within a file opened read-only on Linux.
FileStream.Lock always seems to use 'fcntl(fd, F_SETLK, {type=F_WRLCK...'.
For a file opened read-only, setting a 'F_WRLCK' (exclusive lock) is not a valid operation and triggers an EBADF (Bad file descriptor) error from fcntl, which triggers an Unhandled Exception from dotnet.
I can see this using 'strace', e.g. strace -o st_output.txt -f dotnet myprogram.
What is needed here is some way (property or method I guess) to specify the lock type, either F_RDLCK (a shared lock) or F_WRLCK (an exclusive lock).
To clarify those options and fcntl's behaviour - any number of concurrent shared locks can be made on the same part of a file unless there is an exclusive lock on it.
And ONE exclusive lock can be made on a specific region within a file unless there is already a lock - shared or exclusive - already present.
Note that the test program attached (a dotnet console app) expects a file 'testfile' to exist in its directory which can contain any random text.
This is my first issue, I do hope I have done this correctly! Regards.
Program_output.txt
Program.txt
The text was updated successfully, but these errors were encountered: