Skip Menu | Preferences | Logout
Logged in as guest
RT for grand.central.org
 
 
#4462: Linux 2.6 proc interface patch
X  Ticket metadata  
X  The Basics  
Id: 4462
Status: resolved
Left: 0 min
Priority: 0/0
Queue: openafs-bugs

X  People  
Owner: shadow
Requestors: jcurley@cmu.edu
Cc: de0u@andrew.cmu.edu
jhutz <jhutz@cmu.edu>
AdminCc:

X  Dates  
Created: Fri May 07 16:05:14 2004
Starts: Not set
Started: Sat May 08 00:11:18 2004
Last Contact: Not set
Due: Not set
Closed: Thu Jul 08 01:55:56 2004
Updated: Thu Jul 08 01:55:56 2004 by shadow

X  Links  
Depends on:
Depended on by:
Parents:
Children:
Refers to:
Referred to by:

X  Attachments  
proc_syscall_interface.patch
x.diff

X  More about Jonathan Curley  
Comments about this user:
No comment entered about this user
This user's 10 highest priority tickets:

X  History Display mode:[Brief headers] [Full headers]
#     Fri May 07 16:05:14 2004  jcurley@cmu.edu - Ticket created    
Subject: Linux 2.6 proc interface patch
From: Jonathan Curley <jcurley@cmu.edu>
To: openafs-bugs@openafs.org
Date: Fri, 07 May 2004 16:05:03 -0400
Download(untitled)
text/plain 140b

Attached is a patch that replaces the afs syscall interface with a magic
proc file, as required for linux 2.6 compatibility.

- Jon Curley
Index: acinclude.m4
===================================================================
RCS file: /cvs/openafs/acinclude.m4,v
retrieving revision 1.107
diff -u -w -r1.107 acinclude.m4
--- acinclude.m4 27 Apr 2004 19:43:04 -0000 1.107
+++ acinclude.m4 7 May 2004 19:29:08 -0000
@@ -192,8 +192,8 @@
LINUX_SCHED_STRUCT_TASK_STRUCT_HAS_SIGMASK_LOCK
LINUX_WHICH_MODULES
if test "x$ac_cv_linux_config_modversions" = "xno"; then
- AC_MSG_WARN([Cannot determine sys_call_table status. assuming it's exported])
- ac_cv_linux_exports_sys_call_table=yes
+ AC_MSG_WARN([Cannot determine sys_call_table status. assuming it isn't exported])
+ ac_cv_linux_exports_sys_call_table=no
if test -f "$LINUX_KERNEL_PATH/include/asm/ia32_unistd.h"; then
ac_cv_linux_exports_ia32_sys_call_table=yes
fi
Index: src/afs/LINUX/osi_misc.c
===================================================================
RCS file: /cvs/openafs/src/afs/LINUX/osi_misc.c,v
retrieving revision 1.32
diff -u -w -r1.32 osi_misc.c
--- src/afs/LINUX/osi_misc.c 4 May 2004 21:38:15 -0000 1.32
+++ src/afs/LINUX/osi_misc.c 7 May 2004 19:29:18 -0000
@@ -312,6 +312,12 @@
{
extern int (*sys_settimeofdayp) (struct timeval * tv,
struct timezone * tz);
+
+ // If pointer invalid, time setting doesn't work.
+ if(!sys_settimeofdayp) {
+ printf("Warning: SetTime failed because syscall table is not exported.\n");
+ return;
+ }
#ifdef AFS_LINUX_64BIT_KERNEL
struct timeval tv;
AFS_STATCNT(osi_SetTime);
Index: src/afs/LINUX/osi_module.c
===================================================================
RCS file: /cvs/openafs/src/afs/LINUX/osi_module.c,v
retrieving revision 1.44
diff -u -w -r1.44 osi_module.c
--- src/afs/LINUX/osi_module.c 12 Apr 2004 16:04:32 -0000 1.44
+++ src/afs/LINUX/osi_module.c 7 May 2004 19:29:20 -0000
@@ -27,6 +27,7 @@
#endif

#include <linux/module.h>
+#include <linux/proc_fs.h>
#include <linux/slab.h>
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
#include <linux/init.h>
@@ -51,7 +52,6 @@
asmlinkage int (*sys_settimeofdayp) (struct timeval * tv,
struct timezone * tz);
asmlinkage long (*sys_setgroupsp) (int gidsetsize, gid_t * grouplist);
-
#ifdef EXPORTED_SYS_CALL_TABLE
#ifdef AFS_SPARC64_LINUX20_ENV
extern unsigned int sys_call_table[]; /* changed to uint because SPARC64 has syscaltable of 32bit items */
@@ -130,6 +130,52 @@
}
#endif /* AFS_SPARC64_LINUX20_ENV */

+static int afs_ioctl(struct inode *, struct file *, unsigned int,
+ unsigned long);
+
+static struct file_operations afs_syscall_fops = {
+ .ioctl = afs_ioctl,
+};
+
+static struct proc_dir_entry *openafs_procfs;
+
+static int
+afsproc_init()
+{
+ struct proc_dir_entry *entry1;
+
+ openafs_procfs = proc_mkdir(PROC_FSDIRNAME, proc_root_fs);
+ entry1 = create_proc_entry(PROC_SYSCALL_NAME, 0, openafs_procfs);
+
+ entry1->proc_fops = &afs_syscall_fops;
+
+ entry1->owner = THIS_MODULE;
+
+ return 0;
+}
+
+static void
+afsproc_exit()
+{
+ remove_proc_entry(PROC_SYSCALL_NAME, openafs_procfs);
+ remove_proc_entry(PROC_FSDIRNAME, proc_root_fs);
+}
+
+static int
+afs_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
+ unsigned long arg)
+{
+
+ struct afsprocdata sysargs;
+
+
+ if (copy_from_user(&sysargs, (void *)arg, sizeof(struct afsprocdata)))
+ return -1;
+
+ return afs_syscall(sysargs.syscall, sysargs.param1,
+ sysargs.param2, sysargs.param3, sysargs.param4);
+}
+
#ifdef AFS_IA64_LINUX20_ENV

asmlinkage long
@@ -306,11 +352,15 @@
break;
}
#else
+#ifdef EXPORTED_SYS_OPEN
if (ptr[0] == (unsigned long)&sys_exit
&& ptr[__NR_open - __NR_exit] == (unsigned long)&sys_open) {
sys_call_table = ptr - __NR_exit;
break;
}
+#else
+ break;
+#endif
#endif
#endif
#endif
@@ -327,8 +377,8 @@
#endif
if (!sys_call_table) {
printf("Failed to find address of sys_call_table\n");
- return -EIO;
- }
+ sys_settimeofdayp = 0;
+ } else {
printf("Found sys_call_table at %x\n", sys_call_table);
# ifdef AFS_SPARC64_LINUX20_ENV
error cant support this yet.
@@ -357,9 +407,9 @@
#ifdef EXPORTED_KALLSYMS_ADDRESS
ret =
kallsyms_address_to_symbol((unsigned long)&interruptible_sleep_on,
- &mod_name, &mod_start, &mod_end, &sec_name,
- &sec_start, &sec_end, &sym_name,
- &sym_start, &sym_end);
+ &mod_name, &mod_start, &mod_end,
+ &sec_name, &sec_start, &sec_end,
+ &sym_name, &sym_start, &sym_end);
ptr = (unsigned long *)sec_start;
datalen = (sec_end - sec_start) / sizeof(unsigned long);
#else /* EXPORTED_KALLSYMS_ADDRESS */
@@ -382,15 +432,16 @@
#ifdef EXPORTED_KALLSYMS_ADDRESS
ret =
kallsyms_address_to_symbol((unsigned long)ia32_sys_call_table,
- &mod_name, &mod_start, &mod_end, &sec_name,
- &sec_start, &sec_end, &sym_name,
- &sym_start, &sym_end);
+ &mod_name, &mod_start, &mod_end,
+ &sec_name, &sec_start, &sec_end,
+ &sym_name, &sym_start, &sym_end);
if (ret && strcmp(sym_name, "ia32_sys_call_table"))
ia32_sys_call_table = 0;
#endif /* EXPORTED_KALLSYMS_ADDRESS */
#endif /* EXPORTED_KALLSYMS_SYMBOL */
if (!ia32_sys_call_table) {
- printf("Warning: Failed to find address of ia32_sys_call_table\n");
+ printf
+ ("Warning: Failed to find address of ia32_sys_call_table\n");
} else {
printf("Found ia32_sys_call_table at %x\n", ia32_sys_call_table);
}
@@ -443,11 +494,12 @@
POINTER2SYSCALL afs_syscall;
}
#endif /* AFS_S390_LINUX22_ENV */
-
+ }
osi_Init();
register_filesystem(&afs_fs_type);

/* Intercept setgroups calls */
+ if (sys_call_table) {
#if defined(AFS_IA64_LINUX20_ENV)
sys_setgroupsp = (void *)&sys_setgroups;

@@ -468,8 +520,10 @@
sys_setgroups32p = SYSCALL2POINTER sys_call_table[__NR_setgroups32];
sys_call_table[__NR_setgroups32] = POINTER2SYSCALL afs_xsetgroups32;
#ifdef AFS_SPARC64_LINUX20_ENV
- sys32_setgroups32p = SYSCALL2POINTER sys_call_table32[__NR_setgroups32];
- sys_call_table32[__NR_setgroups32] = POINTER2SYSCALL afs32_xsetgroups32;
+ sys32_setgroups32p =
+ SYSCALL2POINTER sys_call_table32[__NR_setgroups32];
+ sys_call_table32[__NR_setgroups32] =
+ POINTER2SYSCALL afs32_xsetgroups32;
#endif /* AFS_SPARC64_LINUX20_ENV */
#endif /* __NR_setgroups32 */
#ifdef AFS_AMD64_LINUX20_ENV
@@ -493,8 +547,10 @@
sys_setgroupsp = set_afs_xsetgroups_syscall(afs_xsetgroups);
sys32_setgroupsp = set_afs_xsetgroups_syscall32(afs32_xsetgroups);
#endif
+ }

osi_sysctl_init();
+ afsproc_init();

return 0;
}
@@ -510,7 +566,7 @@
struct task_struct *t;

osi_sysctl_clean();
-
+ if (sys_call_table) {
#if defined(AFS_IA64_LINUX20_ENV)
sys_call_table[__NR_setgroups - 1024] =
POINTER2SYSCALL((struct fptr *)sys_setgroupsp)->ip;
@@ -525,7 +581,8 @@
# if defined(__NR_setgroups32)
sys_call_table[__NR_setgroups32] = POINTER2SYSCALL sys_setgroups32p;
# ifdef AFS_SPARC64_LINUX20_ENV
- sys_call_table32[__NR_setgroups32] = POINTER2SYSCALL sys32_setgroups32p;
+ sys_call_table32[__NR_setgroups32] =
+ POINTER2SYSCALL sys32_setgroups32p;
# endif
# endif
#endif /* AFS_IA64_LINUX20_ENV */
@@ -541,6 +598,7 @@
#endif
}
#endif
+ }
#ifdef AFS_PPC64_LINUX20_ENV
set_afs_syscall(afs_ni_syscall);
set_afs_xsetgroups_syscall(sys_setgroupsp);
@@ -551,6 +609,7 @@
osi_linux_free_inode_pages(); /* Invalidate all pages using AFS inodes. */
osi_linux_free_afs_memory();

+ afsproc_exit();
return;
}

Index: src/afsd/afsd.c
===================================================================
RCS file: /cvs/openafs/src/afsd/afsd.c,v
retrieving revision 1.40
diff -u -w -r1.40 afsd.c
--- src/afsd/afsd.c 4 Dec 2003 16:10:46 -0000 1.40
+++ src/afsd/afsd.c 7 May 2004 19:29:26 -0000
@@ -2260,12 +2260,15 @@
}

#if !defined(AFS_SGI_ENV) && !defined(AFS_AIX32_ENV)
+
call_syscall(param1, param2, param3, param4, param5, param6, param7)
long param1, param2, param3, param4, param5, param6, param7;
{
int error;
#ifdef AFS_LINUX20_ENV
long eparm[4];
+ struct afsprocdata syscall_data;
+ int fd = open(PROC_SYSCALL_FNAME,O_RDWR);

eparm[0] = param4;
eparm[1] = param5;
@@ -2273,11 +2276,22 @@
eparm[3] = param7;

param4 = (long)eparm;
-#endif

+ syscall_data.syscall = AFSCALL_CALL;
+ syscall_data.param1 = param1;
+ syscall_data.param2 = param2;
+ syscall_data.param3 = param3;
+ syscall_data.param4 = param4;
+ if(fd > 0) {
+ error = ioctl(fd, VIOC_SYSCALL, &syscall_data);
+ close(fd);
+ }
+ else
+#endif
error =
syscall(AFS_SYSCALL, AFSCALL_CALL, param1, param2, param3, param4,
param5, param6, param7);
+
if (afsd_verbose)
printf("SScall(%d, %d, %d)=%d ", AFS_SYSCALL, AFSCALL_CALL, param1,
error);
Index: src/config/afs_args.h
===================================================================
RCS file: /cvs/openafs/src/config/afs_args.h,v
retrieving revision 1.10
diff -u -w -r1.10 afs_args.h
--- src/config/afs_args.h 8 Aug 2003 19:55:11 -0000 1.10
+++ src/config/afs_args.h 7 May 2004 19:29:28 -0000
@@ -172,4 +172,25 @@
#define AFS_CLIENT_RETRIEVAL_VERSION 1 /* latest version */
#define AFS_CLIENT_RETRIEVAL_FIRST_EDITION 1 /* first version */

+/* Defines and structures for the AFS proc replacement layer for the original syscall (AFS_SYSCALL) strategy */
+
+#ifdef AFS_LINUX20_ENV
+
+#define PROC_FSDIRNAME "openafs"
+#define PROC_SYSCALL_NAME "afs_ioctl"
+#define PROC_SYSCALL_FNAME "/proc/fs/openafs/afs_ioctl"
+#define VIOC_SYSCALL_TYPE 'C'
+#define VIOC_SYSCALL _IOW(VIOC_SYSCALL_TYPE,1,void *)
+
+struct afsprocdata {
+ int param4;
+ int param3;
+ int param2;
+ int param1;
+ int syscall;
+};
+
+#endif
+
+
#endif /* _AFS_ARGS_H_ */
Index: src/sys/afssyscalls.c
===================================================================
RCS file: /cvs/openafs/src/sys/afssyscalls.c,v
retrieving revision 1.7
diff -u -w -r1.7 afssyscalls.c
--- src/sys/afssyscalls.c 15 Jul 2003 23:16:54 -0000 1.7
+++ src/sys/afssyscalls.c 7 May 2004 19:29:33 -0000
@@ -17,6 +17,7 @@
#include <sys/errno.h>
#include <afs/afs_args.h>
#include <sys/file.h>
+#include <sys/ioctl.h>
#if defined(AFS_SUN_ENV) && !defined(AFS_SUN5_ENV)
#include <unistd.h>
#else
@@ -313,21 +314,60 @@

#endif /* AFS_NAMEI_ENV */

+#ifdef AFS_LINUX20_ENV
+int proc_afs_syscall(int syscall, int param1, int param2, int param3,
+ int param4, int *rval) {
+ struct afsprocdata syscall_data;
+ int fd = open(PROC_SYSCALL_FNAME, O_RDWR);
+
+ if(fd < 0)
+ return -1;
+
+ syscall_data.syscall = syscall;
+ syscall_data.param1 = param1;
+ syscall_data.param2 = param2;
+ syscall_data.param3 = param3;
+ syscall_data.param4 = param4;
+
+ *rval = ioctl(fd, VIOC_SYSCALL, &syscall_data);
+
+ close(fd);
+
+ return 0;
+}
+#endif
+
int
lsetpag(void)
{
- int errcode;
+ int errcode, rval;

+#ifdef AFS_LINUX20_ENV
+ rval = proc_afs_syscall(AFSCALL_SETPAG,0,0,0,0,&errcode);
+
+ if(rval)
+ errcode = syscall(AFS_SYSCALL, AFSCALL_SETPAG);
+#else
errcode = syscall(AFS_SYSCALL, AFSCALL_SETPAG);
+#endif
+
return (errcode);
}

int
lpioctl(char *path, int cmd, char *cmarg, int follow)
{
- int errcode;
+ int errcode, rval;
+
+#ifdef AFS_LINUX20_ENV
+ rval = proc_afs_syscall(AFSCALL_PIOCTL, (unsigned int)path, cmd, (unsigned int)cmarg, follow, &errcode);

+ if(rval)
errcode = syscall(AFS_SYSCALL, AFSCALL_PIOCTL, path, cmd, cmarg, follow);
+#else
+ errcode = syscall(AFS_SYSCALL, AFSCALL_PIOCTL, path, cmd, cmarg, follow);
+#endif
+
return (errcode);
}

#     Fri May 07 16:31:54 2004  root - Cc jhutz added    
#     Fri May 07 16:31:54 2004  root - Cc de0u@andrew.cmu.edu added    
#     Sat May 08 00:11:16 2004  shadow - Correspondence added    
Subject: Re: Linux 2.6 proc interface patch
Download(untitled)
text/plain 257b
[Non-text message not quoted]

Applied as linux-26-provide-proc-interface-instead-of-syscall-20040507


except for the small bit which became pointless between when you submitted
and when I applied: sys_settimeofday is strictly unneeded in 2.6.

#     Sat May 08 00:11:18 2004  shadow - Given to shadow    
#     Sat May 08 00:11:18 2004  shadow - Status changed from new to open    
#     Mon May 10 00:40:47 2004  shadow - Correspondence added    
Subject: Re: Linux 2.6 proc interface patch
Download(untitled)
text/plain 385b
[shadow - Sat May 8 00:11:16 2004]:

> [Non-text message not quoted]
>
> Applied as linux-26-provide-proc-interface-instead-of-syscall-20040507
>
>
> except for the small bit which became pointless between when you submitted
> and when I applied: sys_settimeofday is strictly unneeded in 2.6.
>
Mismatched {} pair when sys_call_table is exported, I fixed it in CVS.
#     Tue May 11 16:12:21 2004  jhutz - Correspondence added    
Date: Tue, 11 May 2004 16:11:43 -0400
From: Jeffrey Hutzelman <jhutz@cmu.edu>
To: openafs-bugs@openafs.org
Subject: Re: [grand.central.org #4462] Re: Linux 2.6 proc interface patch
Download(untitled)
text/plain 316b
A few minor patches related to details of the ioctl interface:

- The arguments to afs_syscall are long, not int
- The ioctl vnode op should return a negative error code, not -1.
- We should return -EINVAL if the ioctl command is not the one we know,
so that it is possible to extend this interface later.

-- Jeff
Downloadx.diff
text/plain 2.2k
Index: src/afs/LINUX/osi_module.c
===================================================================
RCS file: /cvs/openafs/src/afs/LINUX/osi_module.c,v
retrieving revision 1.47
diff -u -r1.47 osi_module.c
--- src/afs/LINUX/osi_module.c 10 May 2004 04:39:21 -0000 1.47
+++ src/afs/LINUX/osi_module.c 11 May 2004 20:08:28 -0000
@@ -170,9 +170,10 @@

struct afsprocdata sysargs;

+ if (cmd != VIOC_SYSCALL) return -EINVAL;

if (copy_from_user(&sysargs, (void *)arg, sizeof(struct afsprocdata)))
- return -1;
+ return -EFAULT;

return afs_syscall(sysargs.syscall, sysargs.param1,
sysargs.param2, sysargs.param3, sysargs.param4);
Index: src/config/afs_args.h
===================================================================
RCS file: /cvs/openafs/src/config/afs_args.h,v
retrieving revision 1.11
diff -u -r1.11 afs_args.h
--- src/config/afs_args.h 8 May 2004 04:12:28 -0000 1.11
+++ src/config/afs_args.h 11 May 2004 20:08:28 -0000
@@ -183,11 +183,11 @@
#define VIOC_SYSCALL _IOW(VIOC_SYSCALL_TYPE,1,void *)

struct afsprocdata {
- int param4;
- int param3;
- int param2;
- int param1;
- int syscall;
+ long param4;
+ long param3;
+ long param2;
+ long param1;
+ long syscall;
};

#endif
Index: src/sys/afssyscalls.c
===================================================================
RCS file: /cvs/openafs/src/sys/afssyscalls.c,v
retrieving revision 1.8
diff -u -r1.8 afssyscalls.c
--- src/sys/afssyscalls.c 8 May 2004 04:12:29 -0000 1.8
+++ src/sys/afssyscalls.c 11 May 2004 20:08:30 -0000
@@ -315,8 +315,8 @@
#endif /* AFS_NAMEI_ENV */

#ifdef AFS_LINUX20_ENV
-int proc_afs_syscall(int syscall, int param1, int param2, int param3,
- int param4, int *rval) {
+int proc_afs_syscall(long syscall, long param1, long param2, long param3,
+ long param4, int *rval) {
struct afsprocdata syscall_data;
int fd = open(PROC_SYSCALL_FNAME, O_RDWR);

@@ -360,7 +360,7 @@
int errcode, rval;

#ifdef AFS_LINUX20_ENV
- rval = proc_afs_syscall(AFSCALL_PIOCTL, (unsigned int)path, cmd, (unsigned int)cmarg, follow, &errcode);
+ rval = proc_afs_syscall(AFSCALL_PIOCTL, (long)path, cmd, (long)cmarg, follow, &errcode);

if(rval)
errcode = syscall(AFS_SYSCALL, AFSCALL_PIOCTL, path, cmd, cmarg, follow);
#     Tue May 11 16:48:13 2004  shadow - Correspondence added    
Subject: Re: Linux 2.6 proc interface patch
Download(untitled)
text/plain 85b
[Non-text message not quoted]


linux26-proc-interface-use-long-not-int-20040511
#     Tue May 11 16:49:28 2004  shadow - Correspondence added    
Subject: Re: Linux 2.6 proc interface patch
Download(untitled)
text/plain 85b
[Non-text message not quoted]


linux26-proc-interface-use-long-not-int-20040511
#     Tue May 11 16:52:38 2004  shadow - Correspondence added    
Subject: Re: Linux 2.6 proc interface patch
Download(untitled)
text/plain 85b
[Non-text message not quoted]


linux26-proc-interface-use-long-not-int-20040511
#     Tue May 11 16:54:36 2004  shadow - Correspondence added    
Subject: Re: Linux 2.6 proc interface patch
Download(untitled)
text/plain 85b
[Non-text message not quoted]


linux26-proc-interface-use-long-not-int-20040511
#     Tue May 11 16:57:08 2004  shadow - Correspondence added    
Subject: Re: Linux 2.6 proc interface patch
Download(untitled)
text/plain 85b
[Non-text message not quoted]


linux26-proc-interface-use-long-not-int-20040511
#     Tue May 11 16:59:26 2004  shadow - Correspondence added    
Subject: Re: Linux 2.6 proc interface patch
Download(untitled)
text/plain 85b
[Non-text message not quoted]


linux26-proc-interface-use-long-not-int-20040511
#     Thu Jul 08 01:55:56 2004  shadow - Status changed from open to resolved    
»|« RT 3.2.2 Copyright 1996-2004 Best Practical Solutions, LLC.