Questions about private file locks (Re: Proposed new krb5 FILE ccache protocol)

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

Questions about private file locks (Re: Proposed new krb5 FILE ccache protocol)

Nico Williams
On Tue, Jan 28, 2014 at 7:21 PM, Greg Hudson <[hidden email]> wrote:
> [1]
> http://jtlayton.wordpress.com/2014/01/07/file-private-posix-locks-aka-un-posix-locks/

That's very nice.  A few questions (I hope Simo or others can relay to
the relevant engineers):

 - Do private locks share the same namespace as POSIX file locks?
Surely they must, for many reasons, among others that otherwise NFS
will not support private locks for many, many years.

 - What is to be returned in the l_pid field of struct flock when
using F_GETLKP?

   My advice: put in a constant, say, (pid_t)-1.

 - The blog says that private locks "are owned by the open file".
Does this carry through to dup()/dup2()/...?

   Also, what if the same file is opened through several distinct
open()s in the same process?

   My guess: it doesn't matter, just explicitly drop locks rather than
close(2) to drop locks.  But this should be specified, even if to say
that this is undefined.

Nico
--
_______________________________________________
krbdev mailing list             [hidden email]
https://mailman.mit.edu/mailman/listinfo/krbdev
Reply | Threaded
Open this post in threaded view
|

Re: Questions about private file locks (Re: Proposed new krb5 FILE ccache protocol)

Jeff Layton

Simo forwarded these questions to me:

> On Tue, Jan 28, 2014 at 7:21 PM, Greg Hudson <[hidden email]> wrote:
> > [1]
> > http://jtlayton.wordpress.com/2014/01/07/file-private-posix-locks-aka-un-posix-locks/
>
> That's very nice.  A few questions (I hope Simo or others can relay to
> the relevant engineers):
>
>  - Do private locks share the same namespace as POSIX file locks?
> Surely they must, for many reasons, among others that otherwise NFS
> will not support private locks for many, many years.
>

Yes. The only real difference is their "ownership". Whereas classic
POSIX locks are "owned" by the process, file-private locks are "owned"
by the open file table entry (like flock() locks are).

>  - What is to be returned in the l_pid field of struct flock when
> using F_GETLKP?
>
>    My advice: put in a constant, say, (pid_t)-1.
>

That's exactly what it does. FWIW, the precedent comes from BSD where
flock and fcntl locks work in the same namespace.

>  - The blog says that private locks "are owned by the open file".
> Does this carry through to dup()/dup2()/...?
>

A dup'ed fd basically just takes a reference on the instance of an open
file and assigns that to a new "slot" in the fd table for the process.
The upshot is that locks taken on dup'ed fd's won't conflict with locks
on the "original" fd.

>    Also, what if the same file is opened through several distinct
> open()s in the same process?
>

Then those locks taken will conflict with one another since those are
distinct instances of an open file. Again, these are basically BSD
lock semantics which is what we're emulating here.

The basic idea is to have a flavor of POSIX locks that operates in the
same "lockspace" as them, but has the semantics of flock() locks on
inheritance and close.

>    My guess: it doesn't matter, just explicitly drop locks rather than
> close(2) to drop locks.  But this should be specified, even if to say
> that this is undefined.
>

Agreed. The semantics will be explicitly documented before I'm done. I
intend not to leave much in the way of undefined corners since those
tend to be painful over the long run.

Naturally, the documentation is turning out to be the hardest part ;)

--
Jeff Layton <[hidden email]>
_______________________________________________
krbdev mailing list             [hidden email]
https://mailman.mit.edu/mailman/listinfo/krbdev
Reply | Threaded
Open this post in threaded view
|

Re: Questions about private file locks (Re: Proposed new krb5 FILE ccache protocol)

Nico Williams
On Wed, Jan 29, 2014 at 6:35 PM, Jeff Layton <[hidden email]> wrote:

Thanks for your reply.

>>  - What is to be returned in the l_pid field of struct flock when
>> using F_GETLKP?
>>
>>    My advice: put in a constant, say, (pid_t)-1.
>
> That's exactly what it does. FWIW, the precedent comes from BSD where
> flock and fcntl locks work in the same namespace.

Have you considered whether you might have a different struct for
getting more information about who holds it?  My opinion is that "who
holds the lock" is not trivial or possible to determine or summarize
in enough cases (most) that it's not worth doing anything else about
it.  I surmise you agree.

>>  - The blog says that private locks "are owned by the open file".
>> Does this carry through to dup()/dup2()/...?
>
> A dup'ed fd basically just takes a reference on the instance of an open
> file and assigns that to a new "slot" in the fd table for the process.
> The upshot is that locks taken on dup'ed fd's won't conflict with locks
> on the "original" fd.

Because it's the same object.  That's what I expected, of course.

>>    Also, what if the same file is opened through several distinct
>> open()s in the same process?
>
> Then those locks taken will conflict with one another since those are
> distinct instances of an open file. Again, these are basically BSD
> lock semantics which is what we're emulating here.

And it'd have to be so, since "the same process" is meaningless when
it's the open file reference that owns the lock, not the process that
acquired it.

> The basic idea is to have a flavor of POSIX locks that operates in the
> same "lockspace" as them, but has the semantics of flock() locks on
> inheritance and close.

I'm a bit concerned about children processes inheriting locks by
accident then holding on to them forever.  I'm not sure what can be
done about that other than to remind people (perhaps in the fcntl(2)
man page text about private locks) to set O_CLOEXEC (or use system
calls that cause file descriptors to be born with O_CLOEXEC).

But that's a minor concern, and a price worth paying for file locking
that works.

lslk(1) might become a more useful tool though!

>>    My guess: it doesn't matter, just explicitly drop locks rather than
>> close(2) to drop locks.  But this should be specified, even if to say
>> that this is undefined.

Actually, it does matter, and it has to be that distinct opens are
distinct "lock owners".  Anything else would simply not work.

> Agreed. The semantics will be explicitly documented before I'm done. I
> intend not to leave much in the way of undefined corners since those
> tend to be painful over the long run.
>
> Naturally, the documentation is turning out to be the hardest part ;)

Naturally.  Thanks for the response.

Nico
--
_______________________________________________
krbdev mailing list             [hidden email]
https://mailman.mit.edu/mailman/listinfo/krbdev
Reply | Threaded
Open this post in threaded view
|

Re: Questions about private file locks (Re: Proposed new krb5 FILE ccache protocol)

Jeff Layton
On Wed, 29 Jan 2014 19:34:18 -0600
Nico Williams <[hidden email]> wrote:

> On Wed, Jan 29, 2014 at 6:35 PM, Jeff Layton <[hidden email]> wrote:
>
> Thanks for your reply.
>
> >>  - What is to be returned in the l_pid field of struct flock when
> >> using F_GETLKP?
> >>
> >>    My advice: put in a constant, say, (pid_t)-1.
> >
> > That's exactly what it does. FWIW, the precedent comes from BSD where
> > flock and fcntl locks work in the same namespace.
>
> Have you considered whether you might have a different struct for
> getting more information about who holds it?  My opinion is that "who
> holds the lock" is not trivial or possible to determine or summarize
> in enough cases (most) that it's not worth doing anything else about
> it.  I surmise you agree.
>

Yes, I considered it...

l_pid makes sense for "classic" POSIX locks since they are owned by the
process and that PID is guaranteed to be valid as long as that lock
sticks around.

These new locks OTOH are more "nebulous" since they can be inherited
across fork(). Certainly, we could do something like hash the pointer
to the open file and give that out as an opaque "owner" value, but I'm
not sure that that info is really that useful. You can't reasonable
take it and backtrack that to a thread of execution.

> >>  - The blog says that private locks "are owned by the open file".
> >> Does this carry through to dup()/dup2()/...?
> >
> > A dup'ed fd basically just takes a reference on the instance of an open
> > file and assigns that to a new "slot" in the fd table for the process.
> > The upshot is that locks taken on dup'ed fd's won't conflict with locks
> > on the "original" fd.
>
> Because it's the same object.  That's what I expected, of course.
>
> >>    Also, what if the same file is opened through several distinct
> >> open()s in the same process?
> >
> > Then those locks taken will conflict with one another since those are
> > distinct instances of an open file. Again, these are basically BSD
> > lock semantics which is what we're emulating here.
>
> And it'd have to be so, since "the same process" is meaningless when
> it's the open file reference that owns the lock, not the process that
> acquired it.
>

Exactly.

> > The basic idea is to have a flavor of POSIX locks that operates in the
> > same "lockspace" as them, but has the semantics of flock() locks on
> > inheritance and close.
>
> I'm a bit concerned about children processes inheriting locks by
> accident then holding on to them forever.  I'm not sure what can be
> done about that other than to remind people (perhaps in the fcntl(2)
> man page text about private locks) to set O_CLOEXEC (or use system
> calls that cause file descriptors to be born with O_CLOEXEC).
>
> But that's a minor concern, and a price worth paying for file locking
> that works.
>

Yeah, that's certainly a concern, but we have the same issue with
flock() today. It's more of a user-education problem. The semantics
with these are just *different* from classic POSIX locks even though
they operate in the same namespace. Converting code to use them means a
bit more care than just doing s/SETLK/SETLKP/.

> lslk(1) might become a more useful tool though!
>

Maybe. Since we don't have a clear PID that shows the owner, the info
that you can provide in lslk is limited. Still, you can probably show
that a lock exists, where it starts and ends, and that it's a
file-private lock, which can be helpful.

> >>    My guess: it doesn't matter, just explicitly drop locks rather than
> >> close(2) to drop locks.  But this should be specified, even if to say
> >> that this is undefined.
>
> Actually, it does matter, and it has to be that distinct opens are
> distinct "lock owners".  Anything else would simply not work.
>

Right, you have to be able to get rid of them somehow if the fd is
closed without explicitly dropping them. The semantics for flock() work
this way and people seem to think them reasonable enough.

> > Agreed. The semantics will be explicitly documented before I'm done. I
> > intend not to leave much in the way of undefined corners since those
> > tend to be painful over the long run.
> >
> > Naturally, the documentation is turning out to be the hardest part ;)
>
> Naturally.  Thanks for the response.
>

Glad to help!
--
Jeff Layton <[hidden email]>
_______________________________________________
krbdev mailing list             [hidden email]
https://mailman.mit.edu/mailman/listinfo/krbdev