[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/>