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
Quoted 2 lines · David Howells
I'm trying to write an AFS syscall framework for the Linux kernel that can do two things:
Pick any 2? ;-)
Quoted 6 lines
(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.
Quoted 8 lines
(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:
Quoted 2 lines
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:
Quoted 1 line
(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.
Quoted 1 line
(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.
Quoted 7 lines
(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.
Quoted 7 lines
(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_PTthat 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.
Quoted 8 lines
(8)
fsctl(const char *fs, const char *cmd, struct fsctl_buf)Using:
struct
fsctl_buf{size_tin_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.
Quoted 5 lines
Quoted 3 lines
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.
Quoted 4 lines
Quoted 1 line
(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.
Quoted 4 lines
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).
Quoted 2 lines
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.
Quoted 5 lines
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?
Quoted 5 lines
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_PTorVIOC_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.
Quoted 5 lines
To the extent we can we'd avoid relying on this (8), but I think we'll need it for now.
Quoted 2 lines
(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
Quoted 8 lines · David Howells
Quoted 5 lines
Quoted 3 lines
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.
Quoted 7 lines
Quoted 4 lines
Quoted 1 line
(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)
Quoted 3 lines
"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.
Quoted 7 lines
Quoted 5 lines
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)
Quoted 3 lines
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)
Quoted 6 lines
Quoted 5 lines
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_PTorVIOC_AFS_STAT_MT_PT.
Quoted 8 lines
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.
Hi Derrick,
Quoted 2 lines
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
Quoted 9 lines
Quoted 3 lines
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).
Quoted 4 lines
Quoted 2 lines
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
Quoted 11 lines · David Howells
Quoted 2 lines
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.
Quoted 6 lines
Quoted 5 lines
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)
Quoted 6 lines
Getting the per-user PAG data from the current process becomes a little trickier when worker kernel threads become involved:-/
Maybe each
user_structshould _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.
Quoted 2 lines
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?
Quoted 6 lines
Quoted 4 lines
Quoted 2 lines
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.