[OpenAFS-devel] Re: [OpenAFS] 2.6 kernel support anytime soon?
Workarounds?
Jeffrey Hutzelman
jhutz@cmu.edu
Mon, 10 May 2004 19:02:26 -0400
On Monday, May 10, 2004 18:01:17 -0400 Garrett Wollman
<wollman@khavrinen.lcs.mit.edu> wrote:
> Putting the PAG in the supplementary group list, though unavoidable,
> was and is no less broken.
True. But it's not terribly invasive and works pretty much everywhere.
> The semantics that AFS really wants (and
> probably kNFS/NFSv4 as well) are much closer to those of a process
> label.
Actually, the semantics that AFS really wants (and, I think, NFSv4 as well,
but I'll let those people speak for themselves) are closest to those of a
PAG. That's no surprise -- what we want matches the concept we invented to
do what we want. It's possible that what we want maps well onto your
favorite abstraction; it certainly maps reasonably well onto a variety of
others. It actually maps moderately well onto the supplementary group
list, except that nasty AFS-unaware programs tend to come along and call
setgroups() without regard to AFS. Still, something better would be, well,
better....
> What AFS wants are the following three functions:
>
> int afs_assign_process_label(afs_process_t p);
> int afs_get_label(afs_process_t p, afs_label_t *l);
> int afs_label_destruction_callback(afs_label_t l);
Not to be picky or anything, but those aren't functions; they're function
declarations. They tell me nothing whatsoever about what the functions
actually _do_, let alone things that happen elsewhere in the system.
What AFS wants are setpag(), PagInCred(), and an inheritance model that
matches our needs. If I make some inferences about what the functions
listed above do, and _if_ the inheritance model is correct, then yes, I can
_almost_ build what AFS needs out of them:
typedef struct proc *afs_process_t;
typedef afs_uint32 afs_label_t;
int setpag(afs_uint32 pagvalue, afs_uint32 *newpag, int change_parent)
{
int code;
*newpag = (pagvalue == -1 ? genpag() : pagvalue);
code = afs_assign_process_label(current, *newpag);
if (code) return code;
if (change_parent) {
code = afs_assign_process_label(current->parent, *newpag);
if (code) return code;
}
return 0;
}
// This is currently declared as follows:
// afs_int32 PagInCred(const struct AFS_UCRED *cred);
afs_uint32 PagInCred(const afs_process_t p)
{
int code;
afs_uint32 pagvalue;
code = afs_get_label(p, &pagvalue);
if (code) return NOPAG;
return pagvalue;
}
int afs_label_destruction_callback(afs_label_t l)
{
// whatever; it's just an integer
return 0;
}
But note that it's not exact. Your proposed afs_assign_process_label()
doesn't actually provide a means to control what label is assigned. And,
afs_get_label() expects to operate on a process, where what we currently
want is a struct ucred or whatever passes for it. But then, that's
platform-dependent code anyway, so it's not that big a deal.
The real difficulty is in the inheritance model. We have a specific model:
(1) Every process has at most one PAG
(2) Processes start out with no PAG
(3) A new process inherits its parent's PAG, if any
(4) A process can request a new PAG for itself
(5) There is a funny operation that lets a process request a new PAG for
itself _and its parent_. I think this is evil, but it's there.
(6) A process never gets a new PAG except by (4) or (5).
(7) There is no way to go back to the PAG-less state.
We currently can get this by using the supplementary group list, except
that we have to trap setgroups() in order to make (7) true. Any new
mechanism we use would have to have a very similar model.
-- Jeffrey T. Hutzelman (N3NHS) <jhutz+@cmu.edu>
Sr. Research Systems Programmer
School of Computer Science - Research Computing Facility
Carnegie Mellon University - Pittsburgh, PA