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