Subject: kern/3711: ibcs2 emulation lacks sysfs()
To: None <gnats-bugs@gnats.netbsd.org>
From: None <arnej@math.ntnu.no>
List: netbsd-bugs
Date: 06/05/1997 15:53:08
>Number: 3711
>Category: kern
>Synopsis: ibcs2 emulation lacks sysfs()
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: kern-bug-people (Kernel Bug People)
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Thu Jun 5 07:05:01 1997
>Last-Modified:
>Originator: Arne H. Juul
>Organization:
Norwegian University of Technology and Science
>Release: NetBSD-current as of Jun 5, 1997
>Environment:
System: NetBSD leon.math.ntnu.no 1.2E NetBSD 1.2E (NIKITA) #14: Thu Jun 5 14:39:16 CEST 1997 arnej@leon.math.ntnu.no:/usr/src/sys/arch/i386/compile/NIKITA i386
>Description:
The IBCS2 emulation environment in NetBSD has stubbed out
the sysfs() call. This causes problems for some types of
programs, in my case AXXiON-NetBackup.
To implement sysfs() one needs to establish a mapping
between filesystem-type name and number. I noticed that
the FreeBSD emulation already has such a mapping, so I
extended that emulation a bit and made it common instead
of making another version. The mapping should in theory
be dynamic, but in practice it suffices to add new
filesystem types as (or preferrably a bit before) they
are implemented for Net/FreeBSD.
>How-To-Repeat:
Try to run a SCO (or other ibcs2) program that uses sysfs().
>Fix:
Apply following patch:
diff -ruN compat.orig/common/Makefile compat/common/Makefile
--- compat.orig/common/Makefile Sun Jun 1 07:16:22 1997
+++ compat/common/Makefile Thu Jun 5 14:19:39 1997
@@ -7,7 +7,8 @@
SRCS= compat_exec.c compat_util.c kern_exit_43.c kern_info_09.c \
kern_info_43.c kern_resource_43.c kern_sig_43.c kern_xxx_12.c \
- tty_43.c uipc_syscalls_43.c vfs_syscalls_43.c vm_43.c
+ tty_43.c uipc_syscalls_43.c vfs_syscalls_43.c vm_43.c \
+ compat_mnttype.c
# really, all machines where sizeof(int) != sizeof(long)
.if (${MACHINE_ARCH} != "alpha")
diff -ruN compat.orig/common/compat_mnttype.c compat/common/compat_mnttype.c
--- compat.orig/common/compat_mnttype.c Thu Jan 1 01:00:00 1970
+++ compat/common/compat_mnttype.c Thu Jun 5 14:08:01 1997
@@ -0,0 +1,66 @@
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/mount.h>
+#include <compat/common/compat_mnttype.h>
+
+/*
+ * List of filesystem types. This needs to be updated whenever
+ * a) somebody adds a filesystem to NetBSD
+ * b) somebody adds a filesystem to FreeBSD
+ * Used for binary compatibility modes, primarily with FreeBSD,
+ * but also for SysV, see ibcs2_sys_sysfs().
+ *
+ * LKM filesystems are not supported.
+ */
+static char *netbsd_mount_type[] = {
+ "(none)", /* 0 = MOUNT_NONE */
+ "ffs", /* 1 = "Fast" Filesystem */
+ "nfs", /* 2 = Network Filesystem */
+ "mfs", /* 3 = Memory Filesystem */
+ "msdos", /* 4 = MSDOS Filesystem */
+ "lfs", /* 5 = Log-based Filesystem */
+ "lofs", /* 6 = Loopback filesystem */
+ "fdesc", /* 7 = File Descriptor Filesystem */
+ "portal", /* 8 = Portal Filesystem */
+ "null", /* 9 = Minimal Filesystem Layer */
+ "umap", /* 10 = User/Group Identifier Remapping Filesystem */
+ "kernfs", /* 11 = Kernel Information Filesystem */
+ "procfs", /* 12 = /proc Filesystem */
+ "afs", /* 13 = Andrew Filesystem */
+ "cd9660", /* 14 = ISO9660 (aka CDROM) Filesystem */
+ "union", /* 15 = Union (translucent) Filesystem */
+ /* These filesystems don't exist in NetBSD yet */
+ NULL, /* 16 = "devfs" - existing device Filesystem */
+ "ext2fs", /* 17 = Linux EXT2FS */
+ "netcon", /* 18 = Netcon Novell filesystem */
+ /* These filesystems don't exist in FreeBSD */
+ "adosfs", /* 19 = AmigaDOS Filesystem */
+};
+#define NUMFSTYPES 20
+
+int
+convert_mount_type_to_num(const char *name, int *num)
+{
+ int i;
+ for (i=0; i<NUMFSTYPES; i++) {
+ if (!strcmp(name, netbsd_mount_type[i])) {
+ *num = i;
+ return 0;
+ }
+ }
+ return EINVAL;
+}
+
+char *
+convert_mount_type_to_name(int num)
+{
+ if (num>=0 && num<NUMFSTYPES) {
+ return (netbsd_mount_type[num]);
+ }
+ return (NULL);
+}
+
+int get_num_mount_types(void)
+{
+ return NUMFSTYPES;
+}
diff -ruN compat.orig/common/compat_mnttype.h compat/common/compat_mnttype.h
--- compat.orig/common/compat_mnttype.h Thu Jan 1 01:00:00 1970
+++ compat/common/compat_mnttype.h Thu Jun 5 10:33:06 1997
@@ -0,0 +1,3 @@
+extern int convert_mount_type_to_num(const char *name, int *num);
+extern char *convert_mount_type_to_name(int num);
+extern int get_num_mount_types(void);
diff -ruN compat.orig/freebsd/freebsd_file.c compat/freebsd/freebsd_file.c
--- compat.orig/freebsd/freebsd_file.c Fri Jan 31 13:21:23 1997
+++ compat/freebsd/freebsd_file.c Thu Jun 5 14:19:10 1997
@@ -49,45 +49,12 @@
#include <compat/freebsd/freebsd_syscallargs.h>
#include <compat/freebsd/freebsd_util.h>
+#include <compat/common/compat_mnttype.h>
#define ARRAY_LENGTH(array) (sizeof(array)/sizeof(array[0]))
const char freebsd_emul_path[] = "/emul/freebsd";
-static char * convert_from_freebsd_mount_type __P((int));
-
-static char *
-convert_from_freebsd_mount_type(type)
- int type;
-{
- static char *netbsd_mount_type[] = {
- NULL, /* 0 = MOUNT_NONE */
- "ffs", /* 1 = "Fast" Filesystem */
- "nfs", /* 2 = Network Filesystem */
- "mfs", /* 3 = Memory Filesystem */
- "msdos", /* 4 = MSDOS Filesystem */
- "lfs", /* 5 = Log-based Filesystem */
- "lofs", /* 6 = Loopback filesystem */
- "fdesc", /* 7 = File Descriptor Filesystem */
- "portal", /* 8 = Portal Filesystem */
- "null", /* 9 = Minimal Filesystem Layer */
- "umap", /* 10 = User/Group Identifier Remapping Filesystem */
- "kernfs", /* 11 = Kernel Information Filesystem */
- "procfs", /* 12 = /proc Filesystem */
- "afs", /* 13 = Andrew Filesystem */
- "cd9660", /* 14 = ISO9660 (aka CDROM) Filesystem */
- "union", /* 15 = Union (translucent) Filesystem */
- NULL, /* 16 = "devfs" - existing device Filesystem */
-#if 0 /* These filesystems don't exist in FreeBSD */
- "adosfs", /* ?? = AmigaDOS Filesystem */
-#endif
- };
-
- if (type < 0 || type >= ARRAY_LENGTH(netbsd_mount_type))
- return (NULL);
- return (netbsd_mount_type[type]);
-}
-
int
freebsd_sys_mount(p, v, retval)
struct proc *p;
@@ -105,7 +72,7 @@
caddr_t sg = stackgap_init(p->p_emul);
struct sys_mount_args bma;
- if ((type = convert_from_freebsd_mount_type(SCARG(uap, type))) == NULL)
+ if ((type = convert_mount_type_to_name(SCARG(uap, type))) == NULL)
return ENODEV;
s = stackgap_alloc(&sg, MFSNAMELEN + 1);
if ((error = copyout(type, s, strlen(type) + 1)) != 0)
diff -ruN compat.orig/ibcs2/ibcs2_misc.c compat/ibcs2/ibcs2_misc.c
--- compat.orig/ibcs2/ibcs2_misc.c Thu Mar 27 13:20:43 1997
+++ compat/ibcs2/ibcs2_misc.c Thu Jun 5 14:17:15 1997
@@ -103,6 +103,8 @@
#include <compat/ibcs2/ibcs2_syscallargs.h>
#include <compat/ibcs2/ibcs2_sysi86.h>
+#include <compat/common/compat_mnttype.h>
+
int
ibcs2_sys_ulimit(p, v, retval)
@@ -1173,6 +1175,10 @@
return EINVAL;
}
+/*
+ * This call takes one, two, or three parameters,
+ * and the types differ. Yeuch.
+ */
int
ibcs2_sys_sysfs(p, v, retval)
struct proc *p;
@@ -1184,17 +1190,47 @@
syscallarg(caddr_t) d1;
syscallarg(char *) buf;
} */ *uap = v;
+ int error, i;
+ char fstype[MFSNAMELEN];
+ char *fst;
#define IBCS2_GETFSIND 1
#define IBCS2_GETFSTYP 2
#define IBCS2_GETNFSTYP 3
+extern int convert_mount_type_to_num(const char *name, int *num);
+extern char *convert_mount_type_to_name(int num);
+
switch(SCARG(uap, cmd)) {
case IBCS2_GETFSIND:
+ if ((error = copyinstr(SCARG(uap, d1), fstype,
+ sizeof fstype, (u_int *)0)))
+ return (error);
+ /* special case nfs. */
+ if (!strcmp(fstype, "NFS")) strcpy(fstype, "nfs");
+ error = convert_mount_type_to_num(fstype, retval);
+ return (error);
case IBCS2_GETFSTYP:
+ i = (int)SCARG(uap, d1);
+ fst = convert_mount_type_to_name(i);
+ if (fst) {
+ /* special case nfs AGAIN. */
+ if (!strcmp(fst, "nfs"))
+ strcpy(fstype, "NFS");
+ else
+ strcpy(fstype, fst);
+ if ((error = copyout(fstype, SCARG(uap, buf),
+ strlen(fstype)+1)))
+ return (error);
+ *retval = 0;
+ return 0;
+ }
+ return EINVAL;
case IBCS2_GETNFSTYP:
+ *retval = get_num_mount_types();
+ return 0;
}
- return EINVAL; /* XXX - TODO */
+ return EINVAL;
}
int
diff -ruN compat.orig/ibcs2/ibcs2_stat.c compat/ibcs2/ibcs2_stat.c
--- compat.orig/ibcs2/ibcs2_stat.c Sat May 4 13:50:20 1996
+++ compat/ibcs2/ibcs2_stat.c Thu Jun 5 14:17:29 1997
@@ -39,6 +39,7 @@
#include <sys/malloc.h>
#include <sys/vnode.h>
#include <sys/syscallargs.h>
+#include <sys/syslog.h>
#include <vm/vm.h>
@@ -52,6 +53,8 @@
#include <compat/ibcs2/ibcs2_util.h>
#include <compat/ibcs2/ibcs2_utsname.h>
+#include <compat/common/compat_mnttype.h>
+
static void bsd_stat2ibcs_stat __P((struct ostat *, struct ibcs2_stat *));
static int cvt_statfs __P((struct statfs *, caddr_t, int));
@@ -81,9 +84,16 @@
int len;
{
struct ibcs2_statfs ssfs;
+ int fstyp;
bzero(&ssfs, sizeof ssfs);
- ssfs.f_fstyp = 0;
+ if (convert_mount_type_to_num(sp->f_fstypename, &fstyp)) {
+ log(LOG_WARNING, "Unknown fstypename %s in ibcs2 cvt_statfs\n",
+ sp->f_fstypename);
+ ssfs.f_fstyp = 0;
+ } else {
+ ssfs.f_fstyp = fstyp;
+ }
ssfs.f_bsize = sp->f_bsize;
ssfs.f_frsize = 0;
ssfs.f_blocks = sp->f_blocks;
>Audit-Trail:
>Unformatted: