Add ioctl-based AFS calls for Solaris 11
authorAndrew Deason <adeason@sinenomine.net>
Thu, 9 Dec 2010 00:16:14 +0000 (18:16 -0600)
committerDerrick Brashear <shadow@dementia.org>
Mon, 13 Dec 2010 19:12:58 +0000 (11:12 -0800)
Switch from using syscall-based AFS calls to ioctl-based AFS calls,
since syscall 65 was repurposed in some kernels in Solaris 11 and
OpenSolaris. Update the provided afs init script to accomodate the
additional steps needing for starting the AFS client.

Partially based off of some work by Derrick Brashear.

Change-Id: If694af8ac576856fed113851f1be4154b4d970d3
Reviewed-on: http://gerrit.openafs.org/3498
Reviewed-by: Derrick Brashear <shadow@dementia.org>
Tested-by: Derrick Brashear <shadow@dementia.org>

15 files changed:
src/afs/SOLARIS/osi_ioctl.c [new file with mode: 0644]
src/afs/SOLARIS/osi_vfsops.c
src/afs/afs.h
src/afs/afs_syscall.c
src/afsd/afs.rc.solaris.2.11
src/afsd/afsd_kernel.c
src/config/afs_args.h
src/config/param.sun4x_511.h
src/config/param.sunx86_511.h
src/libafs/MakefileProto.SOLARIS.in
src/sys/glue.c
src/sys/pioctl.c
src/sys/setpag.c
src/sys/sys_prototypes.h
src/volser/volmain.c

diff --git a/src/afs/SOLARIS/osi_ioctl.c b/src/afs/SOLARIS/osi_ioctl.c
new file mode 100644 (file)
index 0000000..4208d5c
--- /dev/null
@@ -0,0 +1,220 @@
+/*
+ * Copyright 2010, Sine Nomine Associates and others.
+ * All Rights Reserved.
+ *
+ * This software has been released under the terms of the IBM Public
+ * License.  For details, see the LICENSE file in the top-level source
+ * directory or online at http://www.openafs.org/dl/license10.html
+ */
+
+#include <afsconfig.h>
+#include "afs/param.h"
+
+/* ioctl-based emulation for the AFS syscall, for Solaris 11 and onwards. */
+
+#ifdef AFS_SUN511_ENV
+
+#include "afs/sysincludes.h"   /* Standard vendor system headers */
+#include "afsincludes.h"       /* Afs-based standard headers */
+
+#include <sys/types.h>
+#include <sys/file.h>
+#include <sys/errno.h>
+#include <sys/open.h>
+#include <sys/cred.h>
+#include <sys/ddi.h>
+#include <sys/sunddi.h>
+
+#define DEVAFS_MINOR 0
+
+static int
+devafs_open(dev_t *devp, int flag, int otyp, cred_t *cred_p)
+{
+    if (getminor(*devp) != DEVAFS_MINOR) {
+       return EINVAL;
+    }
+    if (otyp != OTYP_CHR) {
+       return EINVAL;
+    }
+    return 0;
+}
+
+static int
+devafs_close(dev_t dev, int flag, int otyp, cred_t *cred_p)
+{
+    if (getminor(dev) != DEVAFS_MINOR) {
+       return EINVAL;
+    }
+    if (otyp != OTYP_CHR) {
+       return EINVAL;
+    }
+    return 0;
+}
+
+static int
+devafs_ioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *cred_p,
+             int *rval_p)
+{
+    int error;
+    struct afssysa ua;
+    rval_t rv;
+
+    if (getminor(dev) != DEVAFS_MINOR) {
+       return EINVAL;
+    }
+
+    switch (cmd) {
+    case VIOC_SYSCALL: {
+       struct afssysargs sargs;
+       error = ddi_copyin((const void *)arg, &sargs, sizeof(sargs), mode);
+       if (error) {
+           return EFAULT;
+       }
+       ua.syscall = sargs.syscall;
+       ua.parm1 = sargs.param1;
+       ua.parm2 = sargs.param2;
+       ua.parm3 = sargs.param3;
+       ua.parm4 = sargs.param4;
+       ua.parm5 = sargs.param5;
+       ua.parm6 = sargs.param6;
+
+       break;
+    }
+    case VIOC_SYSCALL32: {
+       struct afssysargs32 sargs32;
+       error = ddi_copyin((const void *)arg, &sargs32, sizeof(sargs32), mode);
+       if (error) {
+           return EFAULT;
+       }
+       ua.syscall = sargs32.syscall;
+       ua.parm1 = sargs32.param1;
+       ua.parm2 = sargs32.param2;
+       ua.parm3 = sargs32.param3;
+       ua.parm4 = sargs32.param4;
+       ua.parm5 = sargs32.param5;
+       ua.parm6 = sargs32.param6;
+
+       break;
+    }
+    default:
+       return EINVAL;
+    }
+
+    rv.r_val1 = 0;
+    error = Afs_syscall(&ua, &rv);
+
+    if (!error) {
+       error = rv.r_val1;
+    }
+
+    return error;
+}
+
+static struct cb_ops devafs_cb_ops = {
+    /* .cb_open =     */ devafs_open,
+    /* .cb_close =    */ devafs_close,
+    /* .cb_strategy = */ nodev,
+    /* .cb_print =    */ nodev,
+    /* .cb_dump =     */ nodev,
+    /* .cb_read =     */ nodev,
+    /* .cb_write =    */ nodev,
+    /* .cb_ioctl =    */ devafs_ioctl,
+    /* .cb_devmap =   */ nodev,
+    /* .cb_mmap =     */ nodev,
+    /* .cb_segmap =   */ nodev,
+    /* .cb_chpoll =   */ nochpoll,
+    /* .cb_prop_op =  */ ddi_prop_op,
+    /* .cb_str =      */ NULL,
+    /* .cb_flag =     */ D_NEW | D_MP | D_64BIT,
+    /* .cb_rev =      */ CB_REV,
+    /* .cb_aread =    */ nodev,
+    /* .cb_awrite =   */ nodev,
+};
+
+static dev_info_t *devafs_dip = NULL;
+
+static int
+devafs_getinfo(dev_info_t *dip, ddi_info_cmd_t cmd, void *arg, void **resultp)
+{
+    switch (cmd) {
+    case DDI_INFO_DEVT2DEVINFO:
+       *resultp = devafs_dip;
+       return DDI_SUCCESS;
+    case DDI_INFO_DEVT2INSTANCE:
+       *resultp = 0; /* we only have one instance */
+       return DDI_SUCCESS;
+    default:
+       return DDI_FAILURE;
+    }
+}
+
+static int
+devafs_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
+{
+    int error;
+    switch (cmd) {
+    case DDI_ATTACH:
+       osi_Assert(devafs_dip == NULL);
+
+       error = ddi_create_minor_node(dip, "afs", S_IFCHR, DEVAFS_MINOR,
+                                     DDI_PSEUDO, 0);
+       if (error != DDI_SUCCESS) {
+           return DDI_FAILURE;
+       }
+
+       devafs_dip = dip;
+
+       ddi_report_dev(dip);
+
+       return DDI_SUCCESS;
+    case DDI_RESUME:
+       return DDI_FAILURE;
+    default:
+       return DDI_FAILURE;
+    }
+}
+
+static int
+devafs_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
+{
+    switch (cmd) {
+    case DDI_DETACH:
+       osi_Assert(devafs_dip != NULL);
+
+       devafs_dip = NULL;
+
+       ddi_prop_remove_all(dip);
+       ddi_remove_minor_node(dip, NULL);
+
+       return DDI_SUCCESS;
+    case DDI_SUSPEND:
+       return DDI_FAILURE;
+    default:
+       return DDI_FAILURE;
+    }
+}
+
+static struct dev_ops afs_devops = {
+    /* .devo_rev =      */ DEVO_REV,
+    /* .devo_refcnt =   */ 0,
+    /* .devo_getinfo =  */ devafs_getinfo,
+    /* .devo_identify = */ nulldev,
+    /* .devo_probe =    */ nulldev,
+    /* .devo_attach =   */ devafs_attach,
+    /* .devo_detach =   */ devafs_detach,
+    /* .devo_reset =    */ nodev,
+    /* .devo_cb_ops =   */ &devafs_cb_ops,
+    /* .devo_bus_ops =  */ NULL,
+    /* .devo_power =    */ NULL,
+    /* .devo_quiesce =  */ ddi_quiesce_not_needed,
+};
+
+extern struct mod_ops mod_driverops;
+
+struct modldrv afs_modldrv = {
+    &mod_driverops,
+    "/dev/afs driver",
+    &afs_devops,
+};
+
+#endif /* AFS_SUN511_ENV */
index 369d35b..f923e4e 100644 (file)
@@ -512,11 +512,13 @@ static struct vfssw afs_vfw = {
 };
 #endif
 
+#ifndef AFS_SUN511_ENV
 static struct sysent afssysent = {
     6,
     0,
     Afs_syscall
 };
+#endif /* AFS_SUN511_ENV */
 
 /* inter-module dependencies */
 char _depends_on[] = "drv/ip drv/udp strmod/rpcmod";
@@ -525,7 +527,6 @@ char _depends_on[] = "drv/ip drv/udp strmod/rpcmod";
  * Info/Structs to link the afs module into the kernel
  */
 extern struct mod_ops mod_fsops;
-extern struct mod_ops mod_syscallops;
 
 static struct modlfs afsmodlfs = {
     &mod_fsops,
@@ -537,6 +538,13 @@ static struct modlfs afsmodlfs = {
 #endif
 };
 
+#ifdef AFS_SUN511_ENV
+
+extern struct modldrv afs_modldrv;
+
+#else /* AFS_SUN511_ENV */
+
+extern struct mod_ops mod_syscallops;
 static struct modlsys afsmodlsys = {
     &mod_syscallops,
     "afs syscall interface",
@@ -552,7 +560,7 @@ static struct modlsys afsmodlsys = {
   * land here from sysent or sysent32
   */
 
-#if defined(AFS_SUN57_64BIT_ENV)
+# if defined(AFS_SUN57_64BIT_ENV)
 extern struct mod_ops mod_syscallops32;
 
 static struct modlsys afsmodlsys32 = {
@@ -560,16 +568,21 @@ static struct modlsys afsmodlsys32 = {
     "afs syscall interface(32 bit)",
     &afssysent
 };
-#endif
+# endif
+#endif /* !AFS_SUN511_ENV */
 
 
 static struct modlinkage afs_modlinkage = {
     MODREV_1,
+    (void *)&afsmodlfs,
+#ifdef AFS_SUN511_ENV
+    (void *)&afs_modldrv,
+#else
     (void *)&afsmodlsys,
-#ifdef AFS_SUN57_64BIT_ENV
+# ifdef AFS_SUN57_64BIT_ENV
     (void *)&afsmodlsys32,
-#endif
-    (void *)&afsmodlfs,
+# endif
+#endif /* !AFS_SUN511_ENV */
     NULL
 };
 
@@ -627,7 +640,11 @@ _init()
 #endif /* AFS_SUN52_ENV */
 #endif /* AFS_SUN55_ENV */
 #endif /* !AFS_NONFSTRANS */
-#if !defined(AFS_SUN58_ENV)
+
+#ifndef AFS_SUN511_ENV
+    /* syscall initialization stff */
+
+# if !defined(AFS_SUN58_ENV)
     /* 
      * Re-read the /etc/name_to_sysnum file to make sure afs isn't added after
      * reboot.  Ideally we would like to call modctl_read_sysbinding_file() but
@@ -637,14 +654,14 @@ _init()
      * proper slot entry and we also actually have to properly initialize the
      * global sysent[AFS_SYSCALL] entry!
      */
-#ifdef AFS_SUN53_ENV
-#ifndef        SYSBINDFILE
-#define        SYSBINDFILE     "/etc/name_to_sysnum"
-#endif /* SYSBINDFILE */
+#  ifdef       AFS_SUN53_ENV
+#   ifndef     SYSBINDFILE
+#    define    SYSBINDFILE     "/etc/name_to_sysnum"
+#   endif /* SYSBINDFILE */
     read_binding_file(SYSBINDFILE, sb_hashtab);
-#else /* !AFS_SUN53_ENV */
+#  else /* !AFS_SUN53_ENV */
     read_binding_file(sysbind, sb_hashtab);
-#endif /* AFS_SUN53_ENV */
+#  endif /* AFS_SUN53_ENV */
     make_syscallname("afs", AFS_SYSCALL);
 
     if (sysent[AFS_SYSCALL].sy_call == nosys) {
@@ -652,14 +669,15 @@ _init()
            sysent[AFS_SYSCALL].sy_lock =
                (krwlock_t *) kobj_zalloc(sizeof(krwlock_t), KM_SLEEP);
            rw_init(sysent[AFS_SYSCALL].sy_lock, "afs_syscall",
-#ifdef AFS_SUN57_ENV
+#  ifdef AFS_SUN57_ENV
                    RW_DEFAULT, NULL);
-#else /* !AFS_SUN57_ENV */
+#  else /* !AFS_SUN57_ENV */
                    RW_DEFAULT, DEFAULT_WT);
-#endif /* AFS_SUN57_ENV */
+#  endif /* AFS_SUN57_ENV */
        }
     }
-#endif /* !AFS_SUN58_ENV */
+# endif /* !AFS_SUN58_ENV */
+#endif /* !AFS_SUN511_ENV */
 
     osi_Init();                        /* initialize global lock, etc */
 
index 85064b7..13c68ca 100644 (file)
@@ -1488,4 +1488,36 @@ afs_set_cr_rgid(afs_ucred_t *cred, gid_t gid) {
     cred->cr_rgid = gid;
 }
 #endif
+
+#ifdef AFS_SUN5_ENV
+
+/** The 32 bit OS expects the members of this structure to be 32 bit
+ * quantities and the 64 bit OS expects them as 64 bit quanties. Hence
+ * to accomodate both, *long* is used instead of afs_int32
+ */
+
+# ifdef AFS_SUN57_ENV
+struct afssysa {
+    long syscall;
+    long parm1;
+    long parm2;
+    long parm3;
+    long parm4;
+    long parm5;
+    long parm6;
+};
+# else
+struct afssysa {
+    afs_int32 syscall;
+    afs_int32 parm1;
+    afs_int32 parm2;
+    afs_int32 parm3;
+    afs_int32 parm4;
+    afs_int32 parm5;
+    afs_int32 parm6;
+};
+# endif
+extern int Afs_syscall(struct afssysa *uap, rval_t *rvp);
+#endif /* AFS_SUN5_ENV */
+
 #endif /* _AFS_H_ */
index 9eb70f7..18d6d6e 100644 (file)
@@ -439,33 +439,6 @@ copyin_iparam(caddr_t cmarg, struct iparam *dst)
 #ifdef AFS_SUN5_ENV
 extern int afs_sinited;
 
-/** The 32 bit OS expects the members of this structure to be 32 bit
- * quantities and the 64 bit OS expects them as 64 bit quanties. Hence
- * to accomodate both, *long* is used instead of afs_int32
- */
-
-# ifdef AFS_SUN57_ENV
-struct afssysa {
-    long syscall;
-    long parm1;
-    long parm2;
-    long parm3;
-    long parm4;
-    long parm5;
-    long parm6;
-};
-# else
-struct afssysa {
-    afs_int32 syscall;
-    afs_int32 parm1;
-    afs_int32 parm2;
-    afs_int32 parm3;
-    afs_int32 parm4;
-    afs_int32 parm5;
-    afs_int32 parm6;
-};
-# endif
-
 Afs_syscall(struct afssysa *uap, rval_t * rvp)
 {
     int *retval = &rvp->r_val1;
index a7ac81e..9f53b96 100644 (file)
@@ -37,21 +37,6 @@ killproc() {            # kill the named process(es)
 case $1 in
 'start')
 
-#
-# Make sure afs exists in /etc/name_to_sysnum
-#
-if grep -s "afs" /etc/name_to_sysnum > /dev/null; then
-    echo "Entry for afs already exists in /etc/name_to_sysnum"
-else
-    echo "Creating entry for afs in /etc/name_to_sysnum"
-    cp /etc/name_to_sysnum /etc/name_to_sysnum.orig
-    sed '/nfs/i\
-afs                    65' /etc/name_to_sysnum > /tmp/name_to_sysnum
-    mv /tmp/name_to_sysnum /etc/name_to_sysnum
-    echo "Rebooting now for new /etc/name_to_sysnum to take effect"
-    reboot
-fi
-
 ## Check to see that /bin/isalist exists and is executable
 if [ ! -x /bin/isalist ] ;then
       echo "/bin/isalist not executable"
@@ -64,13 +49,13 @@ fi
 case `/bin/isalist` in
     *amd64* )
               nfssrv=/kernel/misc/amd64/nfssrv
-              afs=/kernel/fs/amd64/afs ;;
+              afs=/kernel/drv/amd64/afs ;;
     *sparcv9* )
               nfssrv=/kernel/misc/sparcv9/nfssrv
-              afs=/kernel/fs/sparcv9/afs ;;
+              afs=/kernel/drv/sparcv9/afs ;;
           * )
               nfssrv=/kernel/misc/nfssrv
-              afs=/kernel/fs/afs ;;
+              afs=/kernel/drv/afs ;;
 esac
 
 
@@ -91,8 +76,33 @@ fi
 ## Load AFS kernel extensions
 
 if [ -f $afs ]; then
-      echo "Loading AFS kernel extensions"
-      modload $afs
+      if [ -f /kernel/drv/afs.conf ] ; then
+          echo "Kernel afs.conf already exists"
+      else
+          echo "Creating kernel afs.conf"
+          echo 'name="afs" parent="pseudo";' > /kernel/drv/afs.conf
+      fi
+
+      # load the module
+      if grep '^afs ' /etc/name_to_major >/dev/null ; then
+          echo "Loading AFS kernel extensions"
+          modload $afs
+         # this can sometimes be necessary to get the /devices afs device to
+         # attach
+         update_drv afs
+      else
+          echo "Installing AFS driver and loading kernel extensions"
+          add_drv -m '* 0666 root root' afs
+      fi
+
+      # Create the /dev/afs link
+      if grep name=afs /etc/devlink.tab >/dev/null ; then
+          echo "Entry for afs already exists in /etc/devlink.tab"
+      else
+          echo "Adding entry for afs in /etc/devlink.tab"
+          echo "type=ddi_pseudo;name=afs;addr=0;minor=afs      \D" >> /dev/devlink.tab
+         devfsadm
+      fi
 else
       echo "$afs does not exist. Skipping AFS startup."
       exit 1
@@ -174,7 +184,9 @@ echo ;;
 
 #
 # Stop the AFS inetd and server processes
-# Note that the afsd processes cannot be killed
+# We do not kill the afsd process here. It should be possible to do now, but we
+# don't do it yet. Note that you need to parse 'modinfo | grep afs' output and
+# give the id to modunload, in order to unload the kernel module.
 #
 
 echo "Killing inetd.afs"
index 76e28b5..7f1c874 100644 (file)
@@ -225,6 +225,15 @@ afsd_call_syscall(long param1, long param2, long param3, long param4, long param
 #endif
             error=syscall_data.retval;
     }
+# elif defined(AFS_SUN511_ENV)
+       {
+           int rval;
+           rval = ioctl_sun_afs_syscall(AFSCALL_CALL, param1, param2, param3,
+                                        param4, param5, param6, &error);
+           if (rval) {
+               error = rval;
+           }
+       }
 # else /* AFS_DARWIN80_ENV */
        error =
        syscall(AFS_SYSCALL, AFSCALL_CALL, param1, param2, param3, param4,
index fb9be1d..54445ed 100644 (file)
@@ -278,6 +278,33 @@ struct afssysargs64 {
 #define SYSCALL_DEV_FNAME "/dev/openafs_ioctl"
 #endif
 
+#ifdef AFS_SUN511_ENV
+# define VIOC_SYSCALL_TYPE 'C'
+# define VIOC_SYSCALL _IOW(VIOC_SYSCALL_TYPE, 1, struct afssysargs)
+# define VIOC_SYSCALL32 _IOW(VIOC_SYSCALL_TYPE, 2, struct afssysargs32)
+# define SYSCALL_DEV_FNAME "/dev/afs"
+
+struct afssysargs {
+    afs_uint64 param6;
+    afs_uint64 param5;
+    afs_uint64 param4;
+    afs_uint64 param3;
+    afs_uint64 param2;
+    afs_uint64 param1;
+    afs_uint32 syscall;
+};
+
+struct afssysargs32 {
+    afs_uint32 param6;
+    afs_uint32 param5;
+    afs_uint32 param4;
+    afs_uint32 param3;
+    afs_uint32 param2;
+    afs_uint32 param1;
+    afs_uint32 syscall;
+};
+#endif /* AFS_SUN511_ENV */
+
 #ifdef AFS_CACHE_VNODE_PATH
 #define AFS_CACHE_CELLS_INODE -2
 #define AFS_CACHE_ITEMS_INODE -3
index 5b999c9..0a98289 100644 (file)
@@ -42,8 +42,6 @@
 #define RXK_LISTENER_ENV       1
 #define AFS_GCPAGS             1       /* if nonzero, garbage collect PAGs */
 
-#define        AFS_SYSCALL             65
-
 /* File system entry (used if mount.h doesn't define MOUNT_AFS */
 #define AFS_MOUNT_AFS   "afs"
 
 #define AFS_USERSPACE_IP_ADDR  1
 #define AFS_GCPAGS             0       /* if nonzero, garbage collect PAGs */
 
+/* so we get _IOW() when we include sys/ioctl.h */
+#define BSD_COMP
+
 #define UKERNEL                        1       /* user space kernel */
 #define AFS_GREEDY43_ENV       1       /* Used only in rx/rx_user.c */
 #define AFS_ENV                        1
 #endif
 
 #define        AFS_3DISPARES           1       /* Utilize the 3 available disk inode 'spares' */
-#define        AFS_SYSCALL             65
+
+/* so we get _IOW() when we include sys/ioctl.h */
+#define BSD_COMP
 
 /* File system entry (used if mount.h doesn't define MOUNT_AFS */
 #define AFS_MOUNT_AFS          1
index fef6672..9454109 100644 (file)
@@ -52,7 +52,8 @@
 #define        AFS_3DISPARES           1       /* Utilize the 3 available disk inode 'spares' */
 #endif /* AFS_NAMEI_ENV */
 
-#define        AFS_SYSCALL             65
+/* so we get _IOW() when we include sys/ioctl.h */
+#define BSD_COMP
 
 /* File system entry (used if mount.h doesn't define MOUNT_AFS */
 #define AFS_MOUNT_AFS          "afs"
 #endif
 
 #define        AFS_3DISPARES           1       /* Utilize the 3 available disk inode 'spares' */
-#define        AFS_SYSCALL             65
+
+/* so we get _IOW() when we include sys/ioctl.h */
+#define BSD_COMP
 
 /* File system entry (used if mount.h doesn't define MOUNT_AFS */
 #define AFS_MOUNT_AFS          1
index ef349e3..4d96272 100644 (file)
@@ -18,6 +18,9 @@ AFS_OS_OBJS = \
        osi_gcpags.o \
        osi_groups.o \
        osi_inode.o \
+<sunx86_511 sun4x_511>
+       osi_ioctl.o \
+<all>
        osi_file.o \
        osi_sleep.o \
        osi_vcache.o \
index 8a2985b..80330de 100644 (file)
@@ -106,3 +106,58 @@ int ioctl_afs_syscall(long syscall, long param1, long param2, long param3,
     return 0;
 }
 #endif
+
+#ifdef AFS_SUN511_ENV
+int
+ioctl_sun_afs_syscall(long syscall, uintptr_t param1, uintptr_t param2,
+                      uintptr_t param3, uintptr_t param4, uintptr_t param5,
+                      uintptr_t param6, int *error)
+{
+    void *ioctldata;
+    long callnum;
+    int fd, code;
+
+# ifdef _ILP32
+    struct afssysargs32 sargs32;
+    sargs32.syscall = syscall;
+    sargs32.param1 = param1;
+    sargs32.param2 = param2;
+    sargs32.param3 = param3;
+    sargs32.param4 = param4;
+    sargs32.param5 = param5;
+    sargs32.param6 = param6;
+
+    ioctldata = &sargs32;
+    callnum = VIOC_SYSCALL32;
+# else /* _ILP32 */
+    struct afssysargs sargs;
+    sargs.syscall = syscall;
+    sargs.param1 = param1;
+    sargs.param2 = param2;
+    sargs.param3 = param3;
+    sargs.param4 = param4;
+    sargs.param5 = param5;
+    sargs.param6 = param6;
+
+    ioctldata = &sargs;
+    callnum = VIOC_SYSCALL;
+# endif /* !_ILP32 */
+
+    fd = open(SYSCALL_DEV_FNAME, O_RDWR);
+    if (fd < 0) {
+       return -1;
+    }
+
+    *error = 0;
+
+    code = ioctl(fd, callnum, ioctldata);
+    close(fd);
+
+    if (code) {
+       errno = code;
+       *error = code;
+    }
+
+    return 0;
+}
+#endif /* AFS_SUN511_ENV */
index 60f0fa5..3c0d8af 100644 (file)
@@ -71,6 +71,12 @@ lpioctl(char *path, int cmd, void *cmarg, int follow)
                             follow, 0, 0, &errcode);
     if (rval)
        errcode = rval;
+#elif defined(AFS_SUN511_ENV)
+    rval = ioctl_sun_afs_syscall(AFSCALL_PIOCTL, (uintptr_t)path, cmd,
+                                 (uintptr_t)cmarg, follow, 0, 0, &errcode);
+    if (rval) {
+       errcode = rval;
+    }
 #else
     errcode = syscall(AFS_SYSCALL, AFSCALL_PIOCTL, path, cmd, cmarg, follow);
 #endif
index 8a36af5..3b3c572 100644 (file)
@@ -63,6 +63,13 @@ lsetpag(void)
     if (rval) {
        errorcode = rval;
     }
+#elif defined(AFS_SUN511_ENV)
+    int rval;
+
+    rval = ioctl_sun_afs_syscall(AFSCALL_SETPAG,0,0,0,0,0,0,&errcode);
+    if (rval) {
+       errcode = rval;
+    }
 #else
     errcode = syscall(AFS_SYSCALL, AFSCALL_SETPAG);
 #endif
index cb62c77..1296132 100644 (file)
@@ -17,6 +17,10 @@ extern int proc_afs_syscall(long, long, long, long, long, int *);
 #ifdef AFS_DARWIN80_ENV
 extern int ioctl_afs_syscall(long, long, long, long, long, long, long, int *);
 #endif
+#ifdef AFS_SUN511_ENV
+extern int ioctl_sun_afs_syscall(long, uintptr_t, uintptr_t, uintptr_t,
+                                 uintptr_t, uintptr_t, uintptr_t, int*);
+#endif
 
 /* pioctl.c */
 extern int lpioctl(char *, int, void *, int);
index cc0b84b..993a58d 100644 (file)
@@ -206,7 +206,21 @@ BKGSleep(void *unused)
 }
 #endif
 
-#ifndef AFS_NT40_ENV
+#ifdef AFS_NT40_ENV
+/* no volser_syscall */
+#elif defined(AFS_SUN511_ENV)
+int
+volser_syscall(afs_uint32 a3, afs_uint32 a4, void *a5)
+{
+    int err, code;
+    code = ioctl_sun_afs_syscall(28 /* AFSCALL_CALL */, a3, a4, a5, 0, 0, 0,
+                                 &err);
+    if (code) {
+       err = code;
+    }
+    return err;
+}
+#else
 int
 volser_syscall(afs_uint32 a3, afs_uint32 a4, void *a5)
 {