首页 > 代码库 > Linux 更新后异常(kernel 版本 3.17) VMware player
Linux 更新后异常(kernel 版本 3.17) VMware player
前几天手欠把linux的内和从3.16 升级到 3.17,结果就悲剧了,VMware不能正常启动了,一直报一个错误。
我这里的linux版本为:fedora20,其他发行版本也一样;
VMware player版本: VMware-Player-6.0.4-2249910.x86_64.bundle
错误信息大概为:
before you can run vmware several modules must be compiled and loaded into the running kernel;
大概的意思就是说,运行vmware虚拟机前需要编译linux的内核;
我天朝大百度搜不出来什么结果..希望提醒后来者低碳生活,远离百度;
好了,不说废话,放上解决方案:
第一步、cd到这个目录下找到文件:vmnet.tar
cd /usr/lib/vmware/modules/source/
第二步、修改这个文件前最好先备份一下,重新建立个文件夹:
mkdir vmnet_bak
第三步、将vmnet.tar 拷贝到 vmnet_bak下
cp vmnet.tar vmnet_bak/
第四步、用tar命令解压 vmnet.tar 并修改文件 netif.c 找到行号130:
文件内容:
/********************************************************* * Copyright (C) 1998-2013 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation version 2 and no later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *********************************************************/ #include "driver-config.h" #define EXPORT_SYMTAB #include <linux/kernel.h> #include <linux/version.h> #include <linux/sched.h> #include <linux/slab.h> #include <linux/poll.h> #include <linux/netdevice.h> #include <linux/etherdevice.h> #include <linux/mm.h> #include "compat_skbuff.h" #include <linux/sockios.h> #include "compat_sock.h" #define __KERNEL_SYSCALLS__ #include <asm/io.h> #include <linux/proc_fs.h> #include <linux/file.h> #include "vnetInt.h" #include "compat_netdevice.h" #include "vmnetInt.h" typedef struct VNetNetIF { VNetPort port; struct net_device *dev; struct net_device_stats stats; } VNetNetIF; static void VNetNetIfFree(VNetJack *this); static void VNetNetIfReceive(VNetJack *this, struct sk_buff *skb); static Bool VNetNetIfCycleDetect(VNetJack *this, int generation); static int VNetNetifOpen(struct net_device *dev); static int VNetNetifProbe(struct net_device *dev); static int VNetNetifClose(struct net_device *dev); static int VNetNetifStartXmit(struct sk_buff *skb, struct net_device *dev); static struct net_device_stats *VNetNetifGetStats(struct net_device *dev); static int VNetNetifSetMAC(struct net_device *dev, void *addr); static void VNetNetifSetMulticast(struct net_device *dev); static int VNetNetIfProcRead(char *page, char **start, off_t off, int count, int *eof, void *data); /* *---------------------------------------------------------------------- * * VNetNetIfSetup -- * * Sets initial netdevice state. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ static void VNetNetIfSetup(struct net_device *dev) // IN: { #if !COMPAT_LINUX_VERSION_CHECK_LT(3, 1, 0) || defined(HAVE_NET_DEVICE_OPS) static const struct net_device_ops vnetNetifOps = { .ndo_init = VNetNetifProbe, .ndo_open = VNetNetifOpen, .ndo_start_xmit = VNetNetifStartXmit, .ndo_stop = VNetNetifClose, .ndo_get_stats = VNetNetifGetStats, .ndo_set_mac_address = VNetNetifSetMAC, #if COMPAT_LINUX_VERSION_CHECK_LT(3, 2, 0) .ndo_set_multicast_list = VNetNetifSetMulticast, #else .ndo_set_rx_mode = VNetNetifSetMulticast, #endif }; #endif ether_setup(dev); // turns on IFF_BROADCAST, IFF_MULTICAST #if COMPAT_LINUX_VERSION_CHECK_LT(3, 1, 0) && !defined(HAVE_NET_DEVICE_OPS) dev->init = VNetNetifProbe; dev->open = VNetNetifOpen; dev->hard_start_xmit = VNetNetifStartXmit; dev->stop = VNetNetifClose; dev->get_stats = VNetNetifGetStats; dev->set_mac_address = VNetNetifSetMAC; dev->set_multicast_list = VNetNetifSetMulticast; #else dev->netdev_ops = &vnetNetifOps; #endif /* HAVE_NET_DEVICE_OPS */ } /* *---------------------------------------------------------------------- * * VNetNetIf_Create -- * * Create a net level port to the wonderful world of virtual * networking. * * Results: * Errno. Also returns an allocated port to connect to, * NULL on error. * * Side effects: * None. * *---------------------------------------------------------------------- */ int VNetNetIf_Create(char *devName, // IN: VNetPort **ret, // OUT: int hubNum) // IN: { VNetNetIF *netIf; struct net_device *dev; int retval; static unsigned id = 0; char deviceName[VNET_NAME_LEN]; memcpy(deviceName, devName, sizeof deviceName); NULL_TERMINATE_STRING(deviceName); dev = alloc_netdev(sizeof *netIf, deviceName, VNetNetIfSetup); if (!dev) { retval = -ENOMEM; goto out; } netIf = netdev_priv(dev); netIf->dev = dev; netIf->port.id = id++; netIf->port.next = NULL; netIf->port.jack.peer = NULL; netIf->port.jack.numPorts = 1; VNetSnprintf(netIf->port.jack.name, sizeof netIf->port.jack.name, "netif%u", netIf->port.id); netIf->port.jack.private = netIf; netIf->port.jack.index = 0; netIf->port.jack.procEntry = NULL; netIf->port.jack.free = VNetNetIfFree; netIf->port.jack.rcv = VNetNetIfReceive; netIf->port.jack.cycleDetect = VNetNetIfCycleDetect; netIf->port.jack.portsChanged = NULL; netIf->port.jack.isBridged = NULL; netIf->port.exactFilterLen = 0; /* * Make proc entry for this jack. */ retval = VNetProc_MakeEntry(netIf->port.jack.name, S_IFREG, netIf, VNetNetIfProcRead, &netIf->port.jack.procEntry); if (retval) { netIf->port.jack.procEntry = NULL; if (retval != -ENXIO) { goto outFreeDev; } } /* * Rest of fields. */ netIf->port.flags = IFF_RUNNING; memset(netIf->port.paddr, 0, sizeof netIf->port.paddr); memset(netIf->port.ladrf, 0, sizeof netIf->port.ladrf); memset(netIf->port.exactFilter, 0, sizeof netIf->port.exactFilter); /* This will generate the reserved MAC address c0:00:?? where ?? == hubNum. */ VMX86_BUILD_MAC(netIf->port.paddr, hubNum); /* Make sure the MAC is unique. */ retval = VNetSetMACUnique(&netIf->port, netIf->port.paddr); if (retval) { goto outRemoveProc; } netIf->port.fileOpRead = NULL; netIf->port.fileOpWrite = NULL; netIf->port.fileOpIoctl = NULL; netIf->port.fileOpPoll = NULL; memset(&netIf->stats, 0, sizeof netIf->stats); memcpy(dev->dev_addr, netIf->port.paddr, sizeof netIf->port.paddr); if (register_netdev(dev) != 0) { LOG(0, (KERN_NOTICE "%s: could not register network device\n", dev->name)); retval = -ENODEV; goto outRemoveProc; } *ret = &netIf->port; return 0; outRemoveProc: if (netIf->port.jack.procEntry) { VNetProc_RemoveEntry(netIf->port.jack.procEntry); } outFreeDev: free_netdev(dev); out: return retval; } /* *---------------------------------------------------------------------- * * VNetNetIfFree -- * * Free the net interface port. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ void VNetNetIfFree(VNetJack *this) // IN: jack { VNetNetIF *netIf = container_of(this, VNetNetIF, port.jack); if (this->procEntry) { VNetProc_RemoveEntry(this->procEntry); } unregister_netdev(netIf->dev); free_netdev(netIf->dev); } /* *---------------------------------------------------------------------- * * VNetNetIfReceive -- * * This jack is receiving a packet. Take appropriate action. * * Results: * None. * * Side effects: * Frees skb. * *---------------------------------------------------------------------- */ void VNetNetIfReceive(VNetJack *this, // IN: jack struct sk_buff *skb) // IN: packet { VNetNetIF *netIf = this->private; uint8 *dest = SKB_2_DESTMAC(skb); if (!NETDEV_UP_AND_RUNNING(netIf->dev)) { goto drop_packet; } if (!VNetPacketMatch(dest, netIf->dev->dev_addr, NULL, 0, allMultiFilter, netIf->dev->flags)) { goto drop_packet; } /* send to the host interface */ skb->dev = netIf->dev; skb->protocol = eth_type_trans(skb, netIf->dev); netif_rx_ni(skb); netIf->stats.rx_packets++; return; drop_packet: dev_kfree_skb(skb); } /* *---------------------------------------------------------------------- * * VNetNetIfCycleDetect -- * * Cycle detection algorithm. * * Results: * TRUE if a cycle was detected, FALSE otherwise. * * Side effects: * None. * *---------------------------------------------------------------------- */ Bool VNetNetIfCycleDetect(VNetJack *this, // IN: jack int generation) // IN: { VNetNetIF *netIf = this->private; return VNetCycleDetectIf(netIf->dev->name, generation); } /* *---------------------------------------------------------------------- * * VNetNetifOpen -- * * The virtual network‘s open dev operation. * * Results: * errno. * * Side effects: * None. * *---------------------------------------------------------------------- */ int VNetNetifOpen(struct net_device *dev) // IN: { /* * The host interface is not available if the hub is bridged. * * It‘s actually okay to support both. We just need * to tag packets when VNetXmitPacket gives them to the interface * so they can be dropped by VNetBridgeReceive(). * * if so return -EBUSY; */ netif_start_queue(dev); // xxx need to change flags return 0; } /* *---------------------------------------------------------------------- * * VNetNetifProbe -- * * ??? * * Results: * 0. * * Side effects: * None. * *---------------------------------------------------------------------- */ int VNetNetifProbe(struct net_device *dev) // IN: unused { return 0; } /* *---------------------------------------------------------------------- * * VNetNetifClose -- * * The virtual network‘s close dev operation. * * Results: * errno. * * Side effects: * None. * *---------------------------------------------------------------------- */ int VNetNetifClose(struct net_device *dev) // IN: { netif_stop_queue(dev); // xxx need to change flags return 0; } /* *---------------------------------------------------------------------- * * VNetNetifStartXmit -- * * The virtual network‘s start xmit dev operation. * * Results: * ???, 0. * * Side effects: * None. * *---------------------------------------------------------------------- */ int VNetNetifStartXmit(struct sk_buff *skb, // IN: struct net_device *dev) // IN: { VNetNetIF *netIf = netdev_priv(dev); if(skb == NULL) { return 0; } /* * Block a timer-based transmit from overlapping. This could better be * done with atomic_swap(1, dev->tbusy), but set_bit() works as well. * If this ever occurs the queue layer is doing something evil! */ VNetSend(&netIf->port.jack, skb); netIf->stats.tx_packets++; dev->trans_start = jiffies; return 0; } /* *---------------------------------------------------------------------- * * VNetNetifSetMAC -- * * Sets MAC address (i.e. via ifconfig) of netif device. * * Results: * Errno. * * Side effects: * The MAC address may be changed. * *---------------------------------------------------------------------- */ int VNetNetifSetMAC(struct net_device *dev, // IN: void *p) // IN: { VNetNetIF *netIf = netdev_priv(dev); struct sockaddr const *addr = p; if (!VMX86_IS_STATIC_MAC(addr->sa_data)) { return -EINVAL; } memcpy(netIf->port.paddr, addr->sa_data, dev->addr_len); memcpy(dev->dev_addr, addr->sa_data, dev->addr_len); return 0; } /* *---------------------------------------------------------------------- * * VNetNetifSetMulticast -- * * Sets or clears the multicast address list. This information * comes from an array in dev->mc_list, and with a counter in * dev->mc_count. * * Since host-only network ifaces can‘t be bridged, it‘s debatable * whether this is at all useful, but at least now you can turn it * on from ifconfig without getting an ioctl error. * Results: * Void. * * Side effects: * Multicast address list might get changed. * *---------------------------------------------------------------------- */ void VNetNetifSetMulticast(struct net_device *dev) // IN: unused { } /* *---------------------------------------------------------------------- * * VNetNetifGetStats -- * * The virtual network‘s get stats dev operation. * * Results: * A struct full of stats. * * Side effects: * None. * *---------------------------------------------------------------------- */ static struct net_device_stats * VNetNetifGetStats(struct net_device *dev) // IN: { VNetNetIF *netIf = netdev_priv(dev); return &netIf->stats; } /* *---------------------------------------------------------------------- * * VNetNetIfProcRead -- * * Callback for read operation on this netif entry in vnets proc fs. * * Results: * Length of read operation. * * Side effects: * None. * *---------------------------------------------------------------------- */ int VNetNetIfProcRead(char *page, // IN/OUT: buffer to write into char **start, // OUT: 0 if file < 4k, else offset into page off_t off, // IN: (unused) offset of read into the file int count, // IN: (unused) maximum number of bytes to read int *eof, // OUT: TRUE if there is nothing more to read void *data) // IN: client data { VNetNetIF *netIf = data; int len = 0; if (!netIf) { return len; } len += VNetPrintPort(&netIf->port, page+len); len += sprintf(page+len, "dev %s ", netIf->dev->name); len += sprintf(page+len, "\n"); *start = 0; *eof = 1; return len; }
dev = alloc_netdev(sizeof *netIf, deviceName, VNetNetIfSetup);
将上面这个函数添加一个型参 :NET_NAME_UNKNOWN
dev = alloc_netdev(sizeof *netIf, deviceName, NET_NAME_UNKNOWN, VNetNetIfSetup);
这样就ok了。将文件保存。退出vim就可以了。
第五步、将解压前的文件夹重新打包,并将VMware原始的文件重命名为:vmnet_bak.tar
tar czvf vmnet.tar vmnet-only/
mv vmnet.tar vmnet_bak.tar
第六步、将修改后的vmnet.tar 复制到 原文件的路径下,直接覆盖原始文件(因为前面已经被分vmware的vmnet.tar)
cp /usr/lib/vmware/modules/source/vmnet_bak/vmnet.tar /usr/lib/vmware/modules/source/
到这里就ok了,重新启动vmware player 虚拟机启动成功,你会看到你所熟悉熟悉的界面。
以上经历告诉我们,linux的内核不要随便升级,特别是服务器的操作系统,否则后果不堪设想....
Linux 更新后异常(kernel 版本 3.17) VMware player