On Fri, 3 Aug 2018 13:22:05 +0200 Stephan Wiesand <[email protected]> wrote:
> > > On 3. Aug 2018, at 13:08, Christian <[email protected]> wrote: > > > is there an easy way to check in C (under linux) whether a directory > > entry is a mount point for an afs volume and maybe also obtain the name > > of the volume mounted? > > popen("fs lsm /the/path", "r") ? Hi Christian, Since you asked for a way to check in C, looking at the fs lsmount implementation, you can see the OpenAFS fs program issues an ioctl (under linux) to do a "mount point stat". The ioctl returns EINVAL if the path is not an openafs "mount point". Here's a working example (for linux only): #include <stdio.h> #include <stdlib.h> #include <string.h> #include <errno.h> #include <fcntl.h> #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <sys/ioctl.h> #define AFSCALL_PIOCTL 20 #define AFS_PIOCTL_MAXSIZE 2048 #define _VICEIOCTL(id) ((unsigned int) _IOW('V', id, struct ViceIoctl)) #define VIOC_AFS_STAT_MT_PT _VICEIOCTL(29) #define VIOC_SYSCALL_TYPE 'C' #define VIOC_SYSCALL _IOW(VIOC_SYSCALL_TYPE,1,void *) #define PROC_SYSCALL_FNAME "/proc/fs/openafs/afs_ioctl" struct ViceIoctl { caddr_t in; caddr_t out; short in_size; short out_size; }; struct afsprocdata { long param4; long param3; long param2; long param1; long syscall; }; char buffer[AFS_PIOCTL_MAXSIZE]; int pioctl(char *path, int command, struct ViceIoctl *arg, int follow) { int code; int fd; struct afsprocdata syscall_data; fd = open(PROC_SYSCALL_FNAME, O_RDONLY); if (fd < 0) { fprintf(stderr, "failed to open %s; errno=%d\n", PROC_SYSCALL_FNAME, errno); return -1; } syscall_data.syscall = (long)AFSCALL_PIOCTL; syscall_data.param1 = (long)path; syscall_data.param2 = (long)command; syscall_data.param3 = (long)arg; syscall_data.param4 = (long)follow; code = ioctl(fd, VIOC_SYSCALL, &syscall_data); close(fd); return code; } int main(int argc, char *argv) { int code; struct ViceIoctl blob; char *parent = "/afs/example.com/test"; char *last = "xyzzy"; memset(buffer, 0, AFS_PIOCTL_MAXSIZE); blob.in = last; blob.in_size = strlen(last) + 1; blob.out_size = AFS_PIOCTL_MAXSIZE; blob.out = buffer; code = pioctl(parent, VIOC_AFS_STAT_MT_PT, &blob, 1); if (code == 0) { printf("%s/%s is a mount point for volume %s\n", parent, last, buffer); } else if (errno == EINVAL) { printf("%s/%s is not a mount point\n", parent, last); } else { fprintf(stderr, "pioctl failed: code=%d; errno=%d\n", code, errno); } return 0; } /* * Example usage: * * $ make lsm * cc lsm.c -o lsm * $ ./lsm * /afs/example.com/test/xyzzy is a mount point for volume #xyzzy * */ Hope this helps, Mike -- Michael Meffie <[email protected]> _______________________________________________ OpenAFS-info mailing list [email protected] https://lists.openafs.org/mailman/listinfo/openafs-info
