From 5c607b86332914dc7a2cdaf9cca3028a5f299d85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Love=20H=C3=B6rnquist=20=C3=85strand?= Date: Mon, 10 Apr 2006 16:38:22 +0000 Subject: [PATCH] Try harder to get the pioctl to work via the /proc or /dev interface, OpenAFS choose to reuse the same ioctl number, while Arla didn't. Also, try new ioctl before the the old syscalls. git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@17044 ec53bebd-3082-4978-b11e-865c3cabbd6b --- lib/kafs/afssys.c | 110 +++++++++++++++++++++++++--------------------- 1 file changed, 59 insertions(+), 51 deletions(-) diff --git a/lib/kafs/afssys.c b/lib/kafs/afssys.c index 49ac973ea..7fa8f3502 100644 --- a/lib/kafs/afssys.c +++ b/lib/kafs/afssys.c @@ -55,6 +55,7 @@ struct devdata { unsigned long retval; }; #define VIOC_SYSCALL_DEV _IOWR('C', 2, struct devdata) +#define VIOC_SYSCALL_DEV_OPENAFS _IOWR('C', 1, struct devdata) int _kafs_debug; /* this should be done in a better way */ @@ -72,6 +73,7 @@ int _kafs_debug; /* this should be done in a better way */ static int afs_entry_point = UNKNOWN_ENTRY_POINT; static int afs_syscalls[2]; static char *afs_ioctlpath; +static unsigned long afs_ioctlnum; /* Magic to get AIX syscalls to work */ #ifdef _AIX @@ -162,14 +164,42 @@ map_syscall_name_to_number (const char *str, int *res) #endif static int -try_ioctlpath(const char *path, int entrypoint) +try_ioctlpath(const char *path, unsigned long ioctlnum, int entrypoint) { - int fd; + int fd, ret, saved_errno; + fd = open(path, O_RDWR); if (fd < 0) return 1; + switch (entrypoint) { + case LINUX_PROC_POINT: { + struct procdata data = { 0, 0, 0, 0, AFSCALL_PIOCTL }; + data.param2 = (unsigned long)VIOCGETTOK; + ret = ioctl(fd, ioctlnum, &data); + break; + } + case MACOS_DEV_POINT: { + struct devdata data = { AFSCALL_PIOCTL, 0, 0, 0, 0, 0, 0, 0 }; + data.param2 = (unsigned long)VIOCGETTOK; + ret = ioctl(fd, ioctlnum, &data); + break; + } + default: + abort(); + } + saved_errno = errno; close(fd); + /* + * Be quite liberal in what error are ok, the first is the one + * that should trigger given that params is NULL. + */ + if (ret && + (saved_errno != EFAULT && + saved_errno != EDOM && + saved_errno != ENOTCONN)) + return 1; afs_ioctlpath = strdup(path); + afs_ioctlnum = ioctlnum; if (afs_ioctlpath == NULL) return 1; afs_entry_point = entrypoint; @@ -378,7 +408,7 @@ k_hasafs(void) #if !defined(NO_AFS) && defined(SIGSYS) RETSIGTYPE (*saved_func)(int); #endif - int saved_errno; + int saved_errno, ret; char *env = NULL; if (!issuid()) @@ -402,45 +432,36 @@ k_hasafs(void) #ifdef SIGSYS saved_func = signal(SIGSYS, SIGSYS_handler); #endif + if (env && strstr(env, "..") == NULL) { - if (env && (strncmp("/dev/", env, 5) == 0 || strncmp("/proc/", env, 6) == 0)) { - if (try_ioctlpath(env, LINUX_PROC_POINT) == 0) - goto done; - if (try_ioctlpath(env, MACOS_DEV_POINT) == 0) - goto done; + if (strncmp("/proc/", env, 6) == 0) { + if (try_ioctlpath(env, VIOC_SYSCALL_PROC, LINUX_PROC_POINT) == 0) + goto done; + } + if (strncmp("/dev/", env, 5) == 0) { + if (try_ioctlpath(env, VIOC_SYSCALL_DEV, MACOS_DEV_POINT) == 0) + goto done; + if (try_ioctlpath(env,VIOC_SYSCALL_DEV_OPENAFS,MACOS_DEV_POINT) ==0) + goto done; + } } -#ifdef __APPLE__ - /* - * Darwin needs runtime check if we want to use the syscall - */ - do { - int version; - int mib[2]; - size_t len; - char *kernelVersion; - - mib[0] = CTL_KERN; - mib[1] = KERN_OSRELEASE; - - if (sysctl(mib, 2, NULL, &len, NULL, 0)) - break; - kernelVersion = malloc(len); - if (kernelVersion == NULL) - break; - if (sysctl(mib, 2, kernelVersion, &len, NULL, 0)) { - free(kernelVersion); - break; - } - - version = atoi(kernelVersion); - free(kernelVersion); - if (version >= 8) - goto skip_syscall; - - } while(0); -#endif + ret = try_ioctlpath("/proc/fs/openafs/afs_ioctl", + VIOC_SYSCALL_PROC, LINUX_PROC_POINT); + if (ret == 0) + goto done; + ret = try_ioctlpath("/proc/fs/nnpfs/afs_ioctl", + VIOC_SYSCALL_PROC, LINUX_PROC_POINT); + if (ret == 0) + goto done; + ret = try_ioctlpath("/dev/openafs_ioctl", + VIOC_SYSCALL_DEV_OPENAFS, MACOS_DEV_POINT); + if (ret == 0) + goto done; + ret = try_ioctlpath("/dev/nnpfs_ioctl", VIOC_SYSCALL_DEV, MACOS_DEV_POINT); + if (ret == 0) + goto done; #if defined(AFS_SYSCALL) || defined(AFS_SYSCALL2) || defined(AFS_SYSCALL3) { @@ -523,19 +544,6 @@ k_hasafs(void) goto done; #endif -#ifdef __APPLE__ - skip_syscall: -#endif - - if (try_ioctlpath("/proc/fs/openafs/afs_ioctl", LINUX_PROC_POINT) == 0) - goto done; - if (try_ioctlpath("/proc/fs/nnpfs/afs_ioctl", LINUX_PROC_POINT) == 0) - goto done; - - if (try_ioctlpath("/dev/openafs_ioctl", MACOS_DEV_POINT) == 0) - goto done; - if (try_ioctlpath("/dev/nnpfs_ioctl", MACOS_DEV_POINT) == 0) - goto done; done: #ifdef SIGSYS