[OpenAFS] Notes on building AFS for S/390 Linux (and a question)

Michael Durket durket@100acrewood.stanford.edu
Thu, 29 Mar 2001 14:42:10 -0800

I have some notes I kept while building OpenAFS 1.0.3 for
Linux on S/390. I hope that they assist people trying to
build it.

I have not tried to run a server. I am only interested in
running the client. I can get the client up, but there's
still problems (with liblwp) that I'm trying to work out.

I'm building on the RedHat beta, the kernel version is
2.2.18, and the kernel is an SMP kernel.

To build OpenAFS I needed to do the following:

   1) Make my target s390_linux22

   2) In src/libafs/MakefileProto.LINUX, make the following

      In the CCFLAGS definition for the <s390_linux22 s390_linux24>
      section, change the -O2 flag to -O, unless you're sure you
      have a fixed gcc that supports -O2 correctly.

      This prevents the kernel loadable module from hanging when you
      start up AFS.

      In the COMPDIRS section, right after the <i386_linux22 i386_linux24>
      section, add the following section:

      <s390_linux22 s390_linux24>
                      ln -s ${LINUX_SRCDIR}$$v/include/asm-s390 asm ; \

      This prevents compile errors on MUTEX in rx_kmutex.h

   3) I had to temporarily symlink /usr/src/linux/include/linux/rhconfig.h
      over to /usr/include/linux/rhconfig.h to correct an error message
      that indicated that UTSNAME wasn't defined. This appears to be a
      RedHat problem - you may not experience this on other S/390 Linux

   4) There's an incorrect assumption made in the src/afs/LINUX/osi_module.c
      module. In general it's assumed that the value of PAGE_OFFSET can
      never be 0. If I understand it correctly, it's assumed the kernel
      is always mapped starting at a high virtual address (greater than the
      highest physical address on the machine?). In any case, on the S/390
      the kernel is mapped starting at 0, and thus PAGE_OFFSET is 0.

      The computation used in get_page_offset (in osi_module.c) returns
      the highest address value (0x7FFFFFFF) which is incorrect.

      I changed osi_module.c as follows (this might not be the best way
      to do it):

      static int get_page_offset(long *offset)
      #if defined(AFS_PPC_LINUX22_ENV) || defined(AFS_SPARC64_LINUX20_ENV) || defined(AFS_SPARC_LINUX20_ENV) || defined(AFS_S390_LINUX22_ENV)
          *offset = PAGE_OFFSET;
          return 1;
         struct task_struct *p;

         /* search backward thru the circular list */
         for(p = current; p; p = p->prev_task)
         if (p->pid == 1)
            *offset = p->addr_limit.seg;
            return 1;

      return 0;

      You also need to change the code in the init_module routine where it
      gets the page offset to the following:

      /* obtain PAGE_OFFSET value */
      if (get_page_offset(&afs_linux_page_offset) == 0) {
        /* couldn't obtain page offset so can't continue */
        printf("afs: Unable to obtain PAGE_OFFSET. Exiting..");
        return -EIO;

      And, change the declaration of the get_page_offset routine
      (at line 32 in osi_module.c) to:

      static int get_page_offset(long *offset);

      Failure to make these mods causes lots of error messages on AFS
      shutdown from osi_linux_verify_alloced_memory.

   After making the above changes and building OpenAFS you need to make the
 following changes before starting it:

   5) A minor change to the /usr/vice/etc/afs.rc file: when starting up
      afsd, the ${OPTIONS} needs to be ${AFSD_OPTIONS}.

   6) I also had to make a symlink in /usr/vice/etc/modload to the correct
      kernel module because of the way that RedHat (at least) specifies the
      module version - the code in afs.rc comes up with the wrong module
      name. The symlink (in my case) is:

           libafs-2.2.18-0.16vrdr.mp.o -> libafs-2.2.18.mp.o

 You should then be able to start OpenAFS successfully (after defining client
directories, etc as specified in the Quick Beginnings guide).

However, you won't be able to use klog or anything else which depends on
liblwp. If you try, you'll get the following error:

***LWP: PRE_Block not 1
***LWP: Abort --- dumping PCBs ...
Aborted (core dumped)

This leads to my questions:

   1) What is the purpose of PRE_Block (to block pre-emptions)?

   2) Are the routines that set and clear this flag going to work
      properly in an SMP kernel?

   3) Is there some #define that's missing in the config/param... files
      for s390 linux that will fix this?

Mike Durket