2003-05-09 10:04:24

by David Howells

[permalink] [raw]
Subject: Adding an "acceptable" interface to the Linux kernel for AFS


Hi,

I'm trying to write an AFS syscall framework for the Linux kernel that can do
two things:

(1) Handle PAGs without the need to subvert the groups list and override the
set/getgroups syscalls.

(2) Cache authentication data per PAG, doing garbage collection automatically
when a PAG no longer has any attached processes.

(3) Pass other AFS syscall operations to interfaces in whatever AFS
filesystem module is currently loaded (OpenAFS, Arla, etc.).

However, (3) is somewhat tricky as the interface isn't very consistent. For
instance, it would appear that all PIOCTL commands should require a path, but
some of them don't:-/ I don't know why these commands were made PIOCTLs rather
than using the CALL interface, but it makes multiplexing in the core kernel
more difficult.

I'm wondering how attached OpenAFS is to this interface? Can OpenAFS be
altered to use the following access points instead:

(1) setpag(pag_t pag)

(2) getpag()

(3) settok(const char *fs, const char *domain, size_t size, const void *data)

(4) gettok(const char *fs, const char *domain, size_t size, void *data)

(5) deltok(const char *fs, const char *domain)

(6) cleartoks(const char *fs)

(7) pioctl(const char *path, int cmd, void *arg, int followsymlinks)

(Where path is mandatory.)

It may be possible to replace this entirely with calls to setxattr and
co. from userspace... apart from VIOC_AFS_STAT_MT_PT that is, and that
could be done with open/ioctl/close on the directory.

(8) fsctl(const char *fs, const char *cmd, struct fsctl_buf)

Using:

struct fsctl_buf { size_t in_size, out_size; void *in, *out; };

All miscellaneous ops would be done through this. It would work
internally as nfsservctl does in 2.5.

David


2003-05-09 16:28:29

by Derrick J Brashear

[permalink] [raw]
Subject: Re: Adding an "acceptable" interface to the Linux kernel for AFS

On Fri, 9 May 2003, David Howells wrote:

> I'm trying to write an AFS syscall framework for the Linux kernel that can do
> two things:

Pick any 2? ;-)

> (1) Handle PAGs without the need to subvert the groups list and override the
> set/getgroups syscalls.
>
> (2) Cache authentication data per PAG, doing garbage collection automatically
> when a PAG no longer has any attached processes.
>
> (3) Pass other AFS syscall operations to interfaces in whatever AFS
> filesystem module is currently loaded (OpenAFS, Arla, etc.).
>
> However, (3) is somewhat tricky as the interface isn't very consistent. For
> instance, it would appear that all PIOCTL commands should require a path, but
> some of them don't:-/ I don't know why these commands were made PIOCTLs rather
> than using the CALL interface, but it makes multiplexing in the core kernel
> more difficult.

History. Realistically I'd only worry about pioctls that do take a path,
and assume the others will be handled some other way. In fact:

> I'm wondering how attached OpenAFS is to this interface? Can OpenAFS be
> altered to use the following access points instead:

Generally I think this interface will work. I have a few questions:

> (1) setpag(pag_t pag)

If you don't specify a pag it should allocate you one, and for non-priviledged
users this should be the only allowed mode.

> (2) getpag()

I assume:
fs is a text representation of whose filesystem you're doing this for?
("openafs", "arla", etc)
domain is what's typically referred to as an afs cell

I'd also like to see a priviledged "unsetpag()", e.g. I no longer wish to be
in a pag.

> (3) settok(const char *fs, const char *domain, size_t size, const void *data)
>
> (4) gettok(const char *fs, const char *domain, size_t size, void *data)
>
> (5) deltok(const char *fs, const char *domain)
>
> (6) cleartoks(const char *fs)

Currently it's possible to set a token when you have no pag, and these
become associated with the uid that set them. (The pag number is not the uid;
Instead any process without a pag but with a uid that has tokens associated
with it gets those tokens.) As long as the above don't bind tightly to a pag,
sure.

As to pioctl, will it be able to handle things where path cannot be stat'd
in advance? For instance, the prefetching hint (VIOCPREFETCH), if you
could stat it, it wouldn't be a prefetch. Another concern there would be
dangling mount points (a mount point you still have to a volume that's
been deleted) when calling VIOC_AFS_DELETE_MT_PT or VIOC_AFS_STAT_MT_PT.

As long as this is doable, we will conform.

> (7) pioctl(const char *path, int cmd, void *arg, int followsymlinks)
>
> (Where path is mandatory.)
>
> It may be possible to replace this entirely with calls to setxattr and
> co. from userspace... apart from VIOC_AFS_STAT_MT_PT that is, and that
> could be done with open/ioctl/close on the directory.

To the extent we can we'd avoid relying on this (8), but I think we'll need it
for now.

> (8) fsctl(const char *fs, const char *cmd, struct fsctl_buf)
>
> Using:
>
> struct fsctl_buf { size_t in_size, out_size; void *in, *out; };
>
> All miscellaneous ops would be done through this. It would work
> internally as nfsservctl does in 2.5.

The only other concern is transition for existing sites, and that need not
be done in the kernel. All we ask is the current "afs syscall" number be
left vacant, and sites that care can patch their kernel. Nothing need be
distributed.

2003-05-09 17:28:13

by David Howells

[permalink] [raw]
Subject: Re: Adding an "acceptable" interface to the Linux kernel for AFS


> > I'm wondering how attached OpenAFS is to this interface? Can OpenAFS be
> > altered to use the following access points instead:
>
> Generally I think this interface will work.

It would be nice, though, not to have to worry about differentiating between
pioctls that take a path and those that don't inside of the core kernel.

> > (1) setpag(pag_t pag)
>
> If you don't specify a pag it should allocate you one, and for
> non-priviledged users this should be the only allowed mode.

Thinking about it, this shouldn't take an argument at all, and should just put
its caller into a completely new PAG with a unique ID.

> I assume:
> fs is a text representation of whose filesystem you're doing this for?
> ("openafs", "arla", etc)
> domain is what's typically referred to as an afs cell

Yes. After all, you might need the key to be available before you can mount.

This may be useful for samba too... The mount command for samba typically
requires authentication data to be passed as options (workgroup, username,
password).

> I'd also like to see a priviledged "unsetpag()", e.g. I no longer wish to be
> in a pag.

"I" being the calling process? That can be done. I could just define that it
is permissible for the PAG pointer to be NULL. This makes support for the init
process easier, as I don't have to compile in a PAG for it.

> Currently it's possible to set a token when you have no pag, and these
> become associated with the uid that set them. (The pag number is not the uid;
> Instead any process without a pag but with a uid that has tokens associated
> with it gets those tokens.) As long as the above don't bind tightly to a pag,
> sure.

So you'd have a list of tokens associated with the user too?

I suppose I could give both the PAG and the user lists, and search the PAG
first, then the user, but what detemines the user? The PAG, the opener of a
file or the current process?

> As to pioctl, will it be able to handle things where path cannot be stat'd
> in advance? For instance, the prefetching hint (VIOCPREFETCH), if you
> could stat it, it wouldn't be a prefetch. Another concern there would be
> dangling mount points (a mount point you still have to a volume that's
> been deleted) when calling VIOC_AFS_DELETE_MT_PT or VIOC_AFS_STAT_MT_PT.

The latter pair of pioctls you've mentioned both require the directory holding
the mount point to be locally available as a kernel inode, and both of them
require the path to that directory to be supplied as the path argument to
pioctl rather than the path of the mountpoint, so I don't see that there'd be
a problem there.

I don't have documentation on VIOCPREFETCH, but if it's anything like the
other two, then it shouldn't be a problem either.

> To the extent we can we'd avoid relying on this (8), but I think we'll need
> it for now.
>
> > (8) fsctl(const char *fs, const char *cmd, struct fsctl_buf)
> >

It may be possible to do this through the sysfs filesystem in 2.5 instead.

David

2003-05-09 18:57:21

by Derrick J Brashear

[permalink] [raw]
Subject: Re: Adding an "acceptable" interface to the Linux kernel for AFS

On Fri, 9 May 2003, David Howells wrote:

>
> > > I'm wondering how attached OpenAFS is to this interface? Can OpenAFS be
> > > altered to use the following access points instead:
> >
> > Generally I think this interface will work.
>
> It would be nice, though, not to have to worry about differentiating between
> pioctls that take a path and those that don't inside of the core kernel.

I think it may be safe to not deal with them and assume some other
interface (sysctl or something appropriate) will be used.

> > > (1) setpag(pag_t pag)
> >
> > If you don't specify a pag it should allocate you one, and for
> > non-priviledged users this should be the only allowed mode.
>
> Thinking about it, this shouldn't take an argument at all, and should just put
> its caller into a completely new PAG with a unique ID.

There are valid reasons to allow a PAG to be specified, but only with
priviledge. e.g. user mode protocol translator (afs to nfs)

> "I" being the calling process? That can be done. I could just define that it
> is permissible for the PAG pointer to be NULL. This makes support for the init
> process easier, as I don't have to compile in a PAG for it.

Yes, I as the caller.

> > Currently it's possible to set a token when you have no pag, and these
> > become associated with the uid that set them. (The pag number is not the uid;
> > Instead any process without a pag but with a uid that has tokens associated
> > with it gets those tokens.) As long as the above don't bind tightly to a pag,
> > sure.
>
> So you'd have a list of tokens associated with the user too?

A uid could have tokens associated with it. They'd get used only for
PAGless processes running as that uid. Join a PAG and they stop being
visible to you (the caller)


> I suppose I could give both the PAG and the user lists, and search the PAG
> first, then the user, but what detemines the user? The PAG, the opener of a
> file or the current process?

The uid of the current process. Again, if you're in a PAG you don't get
uid tokens. You could create 2 PAG number spaces, 1 using uid
and one sequential alloc, but then you need more management I guess (or to
assume kernel code will be able to provide hooks for accepting tokens
regardless of PAG and just let people who care deal in their code)


> > As to pioctl, will it be able to handle things where path cannot be stat'd
> > in advance? For instance, the prefetching hint (VIOCPREFETCH), if you
> > could stat it, it wouldn't be a prefetch. Another concern there would be
> > dangling mount points (a mount point you still have to a volume that's
> > been deleted) when calling VIOC_AFS_DELETE_MT_PT or VIOC_AFS_STAT_MT_PT.
>
> The latter pair of pioctls you've mentioned both require the directory holding
> the mount point to be locally available as a kernel inode, and both of them
> require the path to that directory to be supplied as the path argument to
> pioctl rather than the path of the mountpoint, so I don't see that there'd be
> a problem there.
>
> I don't have documentation on VIOCPREFETCH, but if it's anything like the
> other two, then it shouldn't be a problem either.

Takes a path to attempt to prefetch as a text string.


2003-05-09 20:07:19

by David Howells

[permalink] [raw]
Subject: Re: Adding an "acceptable" interface to the Linux kernel for AFS


Hi Derrick,

> There are valid reasons to allow a PAG to be specified, but only with
> priviledge. e.g. user mode protocol translator (afs to nfs)

I suppose I can do that... I can add a hook to the security framework or add a
an extra capability to allow a finer degree of control.

Perhaps:

newpag() <--- new PAG
setpag(0) <--- no PAG
setpag(>0) <--- join PAG if permitted

> > I suppose I could give both the PAG and the user lists, and search the PAG
> > first, then the user, but what detemines the user? The PAG, the opener of a
> > file or the current process?
>
> The uid of the current process. Again, if you're in a PAG you don't get
> uid tokens. You could create 2 PAG number spaces, 1 using uid
> and one sequential alloc, but then you need more management I guess (or to
> assume kernel code will be able to provide hooks for accepting tokens
> regardless of PAG and just let people who care deal in their code)

Getting the per-user PAG data from the current process becomes a little
trickier when worker kernel threads become involved:-/

Maybe each user_struct should _also_ have a normal PAG associated with
it. Asking for "no PAG" joins the calling process into its owner user's
PAG. Then you only need one number space...

However, doing this would affect authentication tokens for every FS that
stored them in this way, not just AFS (Samba for instance).

> > I don't have documentation on VIOCPREFETCH, but if it's anything like the
> > other two, then it shouldn't be a problem either.
>
> Takes a path to attempt to prefetch as a text string.

I take it that "prefetch" means try and fetch the entire file into the cache?

David

2003-05-09 20:18:03

by Derrick J Brashear

[permalink] [raw]
Subject: Re: Adding an "acceptable" interface to the Linux kernel for AFS

On Fri, 9 May 2003, David Howells wrote:

> > There are valid reasons to allow a PAG to be specified, but only with
> > priviledge. e.g. user mode protocol translator (afs to nfs)
>
> I suppose I can do that... I can add a hook to the security framework or add a
> an extra capability to allow a finer degree of control.
>
> Perhaps:
>
> newpag() <--- new PAG
> setpag(0) <--- no PAG
> setpag(>0) <--- join PAG if permitted

Sure.

> > The uid of the current process. Again, if you're in a PAG you don't get
> > uid tokens. You could create 2 PAG number spaces, 1 using uid
> > and one sequential alloc, but then you need more management I guess (or to
> > assume kernel code will be able to provide hooks for accepting tokens
> > regardless of PAG and just let people who care deal in their code)
>
> Getting the per-user PAG data from the current process becomes a little
> trickier when worker kernel threads become involved:-/
>
> Maybe each user_struct should _also_ have a normal PAG associated with
> it. Asking for "no PAG" joins the calling process into its owner user's
> PAG. Then you only need one number space...

As long as the PAG number itself is tied to and not directly the uid, that
should work.

> However, doing this would affect authentication tokens for every FS that
> stored them in this way, not just AFS (Samba for instance).

If each FS has its own tokens, I assume there's no problem if you don't
allow setting of any for those that don't support non-PAG tokens?

> > > I don't have documentation on VIOCPREFETCH, but if it's anything like the
> > > other two, then it shouldn't be a problem either.
> >
> > Takes a path to attempt to prefetch as a text string.
>
> I take it that "prefetch" means try and fetch the entire file into the cache?

Yes.

2003-05-09 21:11:36

by Chuck Ebbert

[permalink] [raw]
Subject: Re: Adding an "acceptable" interface to the Linux kernel for AFS

David Howells wrote:

>> I assume:
>> fs is a text representation of whose filesystem you're doing this for?
>> ("openafs", "arla", etc)
>> domain is what's typically referred to as an afs cell
>
> Yes. After all, you might need the key to be available before you can mount.
>
> This may be useful for samba too... The mount command for samba typically
> requires authentication data to be passed as options (workgroup, username,
> password).

ncpmount, too?

Petr Vandrovec is listed as maintainer...