Date: Thu, 15 Nov 2001 20:54:24 +0000 From: Ian Dowse <iedowse@maths.tcd.ie> To: "Richard E. Hawkins" <dochawk@psu.edu> Cc: freebsd-questions@FreeBSD.ORG, freebsd-emulation@FreeBSD.ORG, marcel@FreeBSD.ORG, "Vladimir N. Silyaev" <vsilyaev@mindspring.com> Subject: Could not get address for /dev/vmnet1: Invalid argument Message-ID: <200111152054.aa71745@salmon.maths.tcd.ie> In-Reply-To: Your message of "Wed, 14 Nov 2001 20:32:28 GMT." <200111142032.aa79929@salmon.maths.tcd.ie>
next in thread | previous in thread | raw e-mail | index | archive | help
In message <200111142032.aa79929@salmon.maths.tcd.ie>, Ian Dowse writes:
>A ktrace of vmware as it fails shows that it opens /compat/linux/dev/vmnet1
>and attempts to do a SIOCGIFADDR ioctl on that descriptor (i.e a
>socket ioctl on a character device descriptor) but gets an EINVAL
>return. I haven't figured out for sure if it uses the linux (0x8915)
>or freebsd number for the ioctl.
Ok, I looked into this some more and I have some patches that work
around the issue. The real problem is that it is utterly bogus on
FreeBSD for if_tap/vmnet to use SIOCGIFADDR and SIOCGIFFLAGS the
way it does. These ioctls are supposed to take `struct ifreq'
arguments (as encoded in the length bits) but if_tap/vmnet uses
them for something completely different. I think it's ok for this
reuse to occur on Linux though, so these ioctls on /dev/vmnetX
should really be translated into some if_tap-specific ioctls by
the linux emulation code.
The workaround patch is in two bits: one bit limits the linux
emulator to only touching socket ioctls if the descriptor is
a socket; the other adds an ioctl translator for vmnet ioctls
to the vmmon module. Note that this doesn't do things the right
way (which would be to fix if_tap), but it does seem to work.
VMware also performs ioctls 0x89f2 and 0x89f6 on /dev/vmnet1;
I don't know what these are supposed to do.
Ian
Patch 1, apply in src/sys/compat/linux/, then rebuild kernel or
just linux module.
Index: linux_ioctl.c
===================================================================
RCS file: /home/iedowse/CVS/src/sys/compat/linux/linux_ioctl.c,v
retrieving revision 1.55.2.5
diff -u -r1.55.2.5 linux_ioctl.c
--- linux_ioctl.c 2001/11/05 19:08:22 1.55.2.5
+++ linux_ioctl.c 2001/11/15 18:27:31
@@ -1508,8 +1508,14 @@
{
char lifname[LINUX_IFNAMSIZ], ifname[IFNAMSIZ];
struct ifnet *ifp;
+ struct file *fp;
int error;
+ if (args->fd < p->p_fd->fd_nfiles &&
+ (fp = p->p_fd->fd_ofiles[args->fd]) != NULL &&
+ fp->f_type != DTYPE_SOCKET)
+ return (ENOIOCTL);
+
KASSERT(LINUX_IFNAMSIZ == IFNAMSIZ,
(__FUNCTION__ "(): LINUX_IFNAMSIZ != IFNAMSIZ"));
@@ -1700,7 +1706,7 @@
}
if (type == DTYPE_SOCKET)
return (linux_ioctl_socket(p, args));
- return (ioctl(p, (struct ioctl_args *)args));
+ return (ENOIOCTL);
}
/*
Patch 2, apply in vmware2/work/vmware-distrib/vmmon-only/freebsd, then
from vmware2/work/vmware-distrib run "make" then "make install".
--- linux_emu.c.orig Thu Nov 15 20:16:07 2001
+++ linux_emu.c Thu Nov 15 20:15:27 2001
@@ -37,6 +37,11 @@
#include <sys/cdio.h>
#include <sys/file.h>
#include <sys/select.h>
+#include <sys/socket.h>
+#include <sys/sockio.h>
+#include <sys/stat.h>
+
+#include <net/if.h>
#include <machine/ioctl_fd.h>
@@ -541,3 +546,41 @@
#undef DEB
}
+/* vmnet ioctls */
+LINUX_IOCTL_SET(vmnet, 0x8900, 0x89ff);
+
+#define LINUX_SIOCGIFFLAGS 0x8913
+#define LINUX_SIOCGIFADDR 0x8915
+
+#define VMNET_MAJOR 149
+
+static int
+linux_ioctl_vmnet(struct proc *p, struct linux_ioctl_args *args)
+{
+ struct stat sb;
+ struct filedesc *fdp;
+ struct file *fp;
+ int error;
+ short flags;
+
+ /* Check if this looks like a vmnet device. */
+ if (args->fd >= p->p_fd->fd_nfiles ||
+ (fp = p->p_fd->fd_ofiles[args->fd]) == NULL ||
+ fp->f_type != DTYPE_VNODE || fo_stat(fp, &sb, p) != 0 ||
+ (sb.st_mode & S_IFMT) != S_IFCHR ||
+ ((sb.st_rdev >> 8) & 0xff) != VMNET_MAJOR)
+ return (ENOIOCTL);
+
+ switch (args->cmd & 0xffff) {
+ case LINUX_SIOCGIFADDR:
+ args->cmd = SIOCGIFADDR;
+ return ioctl(p, (struct ioctl_args *)args);
+ case LINUX_SIOCGIFFLAGS:
+ args->cmd = SIOCGIFFLAGS;
+ /* XXX, should translate flags. */
+ return ioctl(p, (struct ioctl_args *)args);
+ default:
+ printf("linux_ioctl_vmnet unknown ioctl %08x\n", args->cmd);
+ }
+ return (ENOIOCTL);
+}
To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-emulation" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200111152054.aa71745>
