[OpenAFS-devel] 1.2.8-rc3 on Itanium II
Joseph V Moss
jmoss@ichips.intel.com
Mon, 09 Dec 2002 15:31:30 -0800
In trying to build/run OpenAFS 1.2.8-rc3 on an Itanium II workstation running
RedHat Advanced Workstation 2.1, I ran into a couple of problems:
1) osi_vnodeops.c wouldn't build due to this recently added section
of code:
/* Safe because there are no large files, yet */
#if F_GETLK != F_GETLK64
if (cmd = F_GETLK64)
cmd = F_GETLK;
else if (cmd = F_SETLK64)
cmd = F_SETLK;
else if (cmd = F_SETLKW64)
cmd = F_SETLKW;
#endif /* F_GETLK != F_GETLK64 */
which failed due to F_GETLK64, F_SETLK64, and F_SETKLW64 being
undefined. Simply removing that section (essentially reverting
the file to the 1.2.7 version) worked for me. Making some changes
to the set of include files might be a better fix. What I'm
currently doing though, is changing the #if statement to:
#if defined(F_GETLK64) && (F_GETLK != F_GETLK64)
which also seems to work fine.
2) In osi_module.c, the attempt to determine the sys_call_table location
failed for multiple reasons: A) the scan starts in the wrong place,
B) the syscalls being looked for don't exist on ia64/linux, C) the
syscall table indexes are offset by 1024 and D) the ksyms don't point
at the function proper, but at a structure which has the function's
address as one of its members. The attached patch fixes all of
these issues. Note that since it is scanning a larger region of
memory, I decided to check for the addresses of three syscalls to
reduce the chance of a false match.
With these changes, 1.2.8-rc3 is working very well on Itanium II!
At least as a client - I haven't tested the server functionality at all.
I'll submit bug reports for these too.
--- src/afs/LINUX/osi_module.c.ksymsia64 Thu Nov 14 14:17:59 2002
+++ src/afs/LINUX/osi_module.c Mon Dec 9 00:24:47 2002
@@ -270,15 +270,32 @@
ptr=(unsigned long *)sec_start;
datalen=(sec_end-sec_start)/sizeof(unsigned long);
#else
+#if defined(AFS_IA64_LINUX20_ENV)
+ ptr = (unsigned long *) (&sys_close - 0x180000);
+ datalen=0x180000/sizeof(ptr);
+#else
ptr=(unsigned long *)&init_mm;
datalen=16384;
#endif
+#endif
for (offset=0;offset <datalen;ptr++,offset++) {
+#if defined(AFS_IA64_LINUX20_ENV)
+ unsigned long close_ip=(unsigned long) ((struct fptr *)&sys_close)->ip;
+ unsigned long chdir_ip=(unsigned long) ((struct fptr *)&sys_chdir)->ip;
+ unsigned long write_ip=(unsigned long) ((struct fptr *)&sys_write)->ip;
+ if (ptr[0] == close_ip &&
+ ptr[__NR_chdir - __NR_close] == chdir_ip &&
+ ptr[__NR_write - __NR_close] == write_ip) {
+ sys_call_table=(void *) &(ptr[ -1 * (__NR_close-1024)]);
+ break;
+ }
+#else
if (ptr[0] == (unsigned long)&sys_exit &&
ptr[__NR_open - __NR_exit] == (unsigned long)&sys_open) {
sys_call_table=ptr - __NR_exit;
break;
}
+#endif
}
#ifdef EXPORTED_KALLSYMS_ADDRESS
ret=kallsyms_address_to_symbol((unsigned long)sys_call_table, &mod_name,
@@ -292,10 +309,11 @@
printf("Failed to find address of sys_call_table\n");
return -EIO;
}
+ printf("Found sys_call_table @ %p\n", sys_call_table);
# ifdef AFS_SPARC64_LINUX20_ENV
error cant support this yet.
#endif
-#endif /* SYS_CALL_TABLE */
+#endif /* EXPORTED_SYS_CALL_TABLE */
/* Initialize pointers to kernel syscalls. */
#if defined(AFS_IA64_LINUX20_ENV)