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-questions" 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>