[OpenAFS] Re: openafs does not put a [correct] value in fsinfo.f_type?
Russ Allbery
rra@stanford.edu
Wed, 27 Dec 2006 16:44:26 -0800
Adam Megacz <megacz@cs.berkeley.edu> writes:
> Are you referring to this?
> http://www.pdc.kth.se/kth-krb/
> The code in lib/kafs/afssys.c appears to catch the SIGSYS signal while
> doing some scary syscall()-guessing.
> This is the closest thing to an answer so far. But that's a pretty
> huge amount of code just to figure out what filesystem a file sits on.
If you only care about Linux, the code to do an AFS system call is much
simpler. See pam-afs-session for how this code is used. You only need
the signal handling on platforms where you're actually doing a syscall,
and you only need the *really* scary stuff on AIX.
/*
* sys-linux.c
*
* AFS system call for Linux systems.
*
* This is an AFS system call implementation for Linux systems only (and new
* enough implementations of OpenAFS on Linux that /proc/fs/openafs/afs_ioctl
* exists). It is for use on systems that don't have libkafs or libkopenafs,
* or where a dependency on those libraries is not desirable for some reason.
*/
#include "config.h"
#include <errno.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <unistd.h>
/*
* The struct passed to ioctl to do an AFS system call. Definition taken from
* the afs/afs_args.h OpenAFS header.
*/
struct afsprocdata {
long param4;
long param3;
long param2;
long param1;
long syscall;
};
/*
* The workhorse function that does the actual system call. All the values
* are passed as longs to match the internal OpenAFS interface, which means
* that there's all sorts of ugly type conversion happening here.
*
* The first path we attempt is the OpenAFS path; the second is the one used
* by Arla (at least some versions).
*/
int
pamafs_syscall(long call, long param1, long param2, long param3, long param4,
int *rval)
{
struct afsprocdata syscall_data;
int fd, oerrno;
fd = open("/proc/fs/openafs/afs_ioctl", O_RDWR);
if (fd < 0)
fd = open("/proc/fs/nnpfs/afs_ioctl", O_RDWR);
if (fd < 0)
return -1;
syscall_data.syscall = call;
syscall_data.param1 = param1;
syscall_data.param2 = param2;
syscall_data.param3 = param3;
syscall_data.param4 = param4;
*rval = ioctl(fd, _IOW('C', 1, void *), &syscall_data);
oerrno = errno;
close(fd);
errno = oerrno;
return 0;
}
--
Russ Allbery (rra@stanford.edu) <http://www.eyrie.org/~eagle/>