openEuler24.03的/proc/version中,使用了gcc_old (GCC)这样的格式,而不是vmware能识别的格式。在启动vmwareworkstation时提示gcc找不到。
临时处理方法一
临时替换/proc/version,然后利用vmware自带工具vmware-modconfig处理。经AI生成的脚本如下:
注:需要管理员权限执行
#!/bin/bash
set -euo pipefail
# 前置依赖检查(核心必做)
if [ ! -d "/lib/modules/$(uname -r)/build" ]; then
echo "❌ 请先执行:sudo dnf install -y kernel-devel-$(uname -r)"
exit 1
fi
# 核心:替换/proc/version中的gcc_old,解决识别失败
PROC_BAK=$(mktemp /tmp/proc_version_bak.XXXXXX)
cat /proc/version > "$PROC_BAK"
sed 's/gcc_old (GCC)/gcc version/' "$PROC_BAK" > /tmp/proc_version_fixed
# 临时挂载修改后的文件
while mount | grep -q "/proc/version"; do umount /proc/version; done
mount --bind /tmp/proc_version_fixed /proc/version
# 仅使用官方工具编译VMware模块(移除手动编译兜底)
echo "✅ 使用官方工具编译VMware模块"
vmware-modconfig --console --install-all
# 恢复原生/proc/version,清理临时文件
umount /proc/version && rm -f "$PROC_BAK" /tmp/proc_version_fixed
# 重启VMware服务
sudo pkill -f vmware-authdlauncher || true
sudo systemctl restart vmware
# 验证结果
echo -e "\n===== 修复完成验证 ====="
sudo lsmod | grep -E "vmmon|vmnet" && echo "✅ 模块加载成功" || echo "⚠️ 模块加载失败,可尝试重新执行脚本"
sudo systemctl status vmware --no-pager | grep Active
临时处理方法二
手动编译受影响的模块vmmon和vmnet.经AI生成的脚本如下:
#!/bin/bash
set -euo pipefail
KERNEL_VERSION=$(uname -r)
MODULE_SRC="/usr/lib/vmware/modules/source"
MODULE_DEST="/lib/modules/${KERNEL_VERSION}/misc"
# 检查模块是否已存在且版本匹配
check_module() {
local mod_path="$1"
if [ ! -f "$mod_path" ]; then
return 1
fi
# 获取模块 vermagic
local vermagic
vermagic=$(modinfo -F vermagic "$mod_path" 2>/dev/null | head -1)
if [ -z "$vermagic" ]; then
return 1
fi
# 比较 vermagic 是否包含当前内核版本
if [[ "$vermagic" == *"$KERNEL_VERSION"* ]]; then
return 0
else
return 1
fi
}
if check_module "${MODULE_DEST}/vmmon.ko" && check_module "${MODULE_DEST}/vmnet.ko"; then
echo "当前内核的 VMware 模块已存在且版本匹配,跳过编译。"
exit 0
fi
# 检查内核头文件
if [ ! -d "/lib/modules/${KERNEL_VERSION}/build" ]; then
echo "❌ 未找到内核头文件,请执行:sudo dnf install kernel-devel-${KERNEL_VERSION}"
exit 1
fi
# 进入源码目录
cd "${MODULE_SRC}"
# 清理可能存在的旧解压目录
rm -rf vmmon-only vmnet-only
# 解压并编译 vmmon
echo "🔨 编译 vmmon..."
tar xf vmmon.tar
cd vmmon-only
make
cd ..
# 解压并编译 vmnet
echo "🔨 编译 vmnet..."
tar xf vmnet.tar
cd vmnet-only
make
cd ..
# 创建目标目录
mkdir -p "${MODULE_DEST}"
# 复制模块
cp vmmon-only/vmmon.ko "${MODULE_DEST}/vmmon.ko"
cp vmnet-only/vmnet.ko "${MODULE_DEST}/vmnet.ko"
# 更新模块依赖
depmod -a
# 清理临时解压目录
rm -rf vmmon-only vmnet-only
echo "✅ 编译完成,模块已安装至 ${MODULE_DEST}"
开机自动处理
建立systemd服务,开机自动启动手动编译脚本。由AI生成的一键安装测试脚本如下:
#!/bin/bash
# VMware 模块自动编译部署脚本(手动编译 + systemd)
# 适用于 openEuler / RHEL / CentOS 等使用 dnf 的发行版
set -euo pipefail
# 颜色输出
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
NC='\033[0m' # No Color
echo -e "${GREEN}========================================${NC}"
echo -e "${GREEN} VMware 模块自动编译部署脚本 ${NC}"
echo -e "${GREEN}========================================${NC}"
# 检查是否 root 权限
if [ "$EUID" -ne 0 ]; then
echo -e "${RED}请以 root 权限运行此脚本(使用 sudo)。${NC}"
exit 1
fi
# 检查 VMware 是否已安装(通过检测模块源码)
VMWARE_SRC="/usr/lib/vmware/modules/source"
if [ ! -f "$VMWARE_SRC/vmmon.tar" ] || [ ! -f "$VMWARE_SRC/vmnet.tar" ]; then
echo -e "${RED}错误:未找到 VMware 模块源码,请先安装 VMware Workstation。${NC}"
exit 1
fi
echo -e "${GREEN}✅ 检测到 VMware 模块源码。${NC}"
# 安装依赖
echo -e "${YELLOW}正在安装依赖(kernel-devel, make, gcc, elfutils-libelf-devel)...${NC}"
dnf install -y kernel-devel-$(uname -r) make gcc elfutils-libelf-devel
echo -e "${GREEN}✅ 依赖安装完成。${NC}"
# 创建手动编译脚本
echo -e "${YELLOW}创建编译脚本 /usr/local/bin/vmware-manual-build.sh ...${NC}"
cat > /usr/local/bin/vmware-manual-build.sh << 'EOF'
#!/bin/bash
set -euo pipefail
KERNEL_VERSION=$(uname -r)
MODULE_SRC="/usr/lib/vmware/modules/source"
MODULE_DEST="/lib/modules/${KERNEL_VERSION}/misc"
# 检查模块是否已存在且版本匹配
check_module() {
local mod_path="$1"
if [ ! -f "$mod_path" ]; then
return 1
fi
# 获取模块 vermagic
local vermagic
vermagic=$(modinfo -F vermagic "$mod_path" 2>/dev/null | head -1)
if [ -z "$vermagic" ]; then
return 1
fi
# 比较 vermagic 是否包含当前内核版本
if [[ "$vermagic" == *"$KERNEL_VERSION"* ]]; then
return 0
else
return 1
fi
}
if check_module "${MODULE_DEST}/vmmon.ko" && check_module "${MODULE_DEST}/vmnet.ko"; then
echo "当前内核的 VMware 模块已存在且版本匹配,跳过编译。"
exit 0
fi
# 检查内核头文件
if [ ! -d "/lib/modules/${KERNEL_VERSION}/build" ]; then
echo "❌ 未找到内核头文件,请执行:sudo dnf install kernel-devel-${KERNEL_VERSION}"
exit 1
fi
# 进入源码目录
cd "${MODULE_SRC}"
# 清理可能存在的旧解压目录
rm -rf vmmon-only vmnet-only
# 解压并编译 vmmon
echo "🔨 编译 vmmon..."
tar xf vmmon.tar
cd vmmon-only
make
cd ..
# 解压并编译 vmnet
echo "🔨 编译 vmnet..."
tar xf vmnet.tar
cd vmnet-only
make
cd ..
# 创建目标目录
mkdir -p "${MODULE_DEST}"
# 复制模块
cp vmmon-only/vmmon.ko "${MODULE_DEST}/vmmon.ko"
cp vmnet-only/vmnet.ko "${MODULE_DEST}/vmnet.ko"
# 更新模块依赖
depmod -a
# 清理临时解压目录
rm -rf vmmon-only vmnet-only
echo "✅ 编译完成,模块已安装至 ${MODULE_DEST}"
EOF
chmod +x /usr/local/bin/vmware-manual-build.sh
echo -e "${GREEN}✅ 编译脚本创建成功。${NC}"
# 创建 systemd 服务单元
echo -e "${YELLOW}创建 systemd 服务 /etc/systemd/system/vmware-manual-build.service ...${NC}"
cat > /etc/systemd/system/vmware-manual-build.service << 'EOF'
[Unit]
Description=VMware Manual Module Build
After=local-fs.target
Before=vmware.service
ConditionPathExists=/lib/modules/%v/build
ConditionPathExists=/usr/lib/vmware/modules/source/vmmon.tar
ConditionPathExists=/usr/lib/vmware/modules/source/vmnet.tar
[Service]
Type=oneshot
ExecStart=/usr/local/bin/vmware-manual-build.sh
RemainAfterExit=no
StandardOutput=journal
StandardError=journal
[Install]
WantedBy=multi-user.target
EOF
# 重新加载 systemd
systemctl daemon-reload
# 启用服务(开机自启)
systemctl enable vmware-manual-build.service
echo -e "${GREEN}✅ systemd 服务已启用。${NC}"
# 立即执行一次(测试)
echo -e "${YELLOW}立即执行编译脚本以测试...${NC}"
systemctl start vmware-manual-build.service
# 检查服务状态(使用 ExecMainStatus 判断)
EXIT_CODE=$(systemctl show -p ExecMainStatus --value vmware-manual-build.service)
if [ "$EXIT_CODE" = "0" ]; then
echo -e "${GREEN}✅ 编译服务执行成功。${NC}"
else
echo -e "${RED}⚠️ 编译服务执行可能失败,请查看日志:journalctl -u vmware-manual-build.service${NC}"
fi
# 重启 VMware 服务(如果已安装)
if systemctl list-unit-files | grep -q vmware.service; then
echo -e "${YELLOW}重启 VMware 服务...${NC}"
systemctl restart vmware.service || true
fi
# 最终提示
echo -e "${GREEN}========================================${NC}"
echo -e "${GREEN}部署完成!${NC}"
echo -e "编译脚本位置:${YELLOW}/usr/local/bin/vmware-manual-build.sh${NC}"
echo -e "systemd 服务:${YELLOW}vmware-manual-build.service${NC}"
echo -e ""
echo -e "每次系统启动时会自动检查并编译当前内核的 VMware 模块。"
echo -e "手动运行:${YELLOW}sudo systemctl start vmware-manual-build.service${NC}"
echo -e "查看日志:${YELLOW}sudo journalctl -u vmware-manual-build.service${NC}"
echo -e "${GREEN}========================================${NC}"
测试开机自动处理
开机自动处理脚本中有一次自启动完成编译。通过删除编译后的vmmon和vmnet,然后打开vmware报gcc找不到,然后重启后vmware能正常打开即可。
删除vmmon和vmnet模块脚本:
#!/bin/bash
# 查找所有内核版本下的 vmmon/vmnet 模块文件
sudo find /lib/modules -name "vmmon.ko*" -o -name "vmnet.ko*" 2>/dev/null
# 删除所有找到的文件(谨慎操作,确保不误删重要文件)
sudo find /lib/modules -name "vmmon.ko*" -o -name "vmnet.ko*" -exec rm -f {} \;
# 重新生成所有内核版本的模块依赖(可选,但建议执行)
sudo depmod -a
清除开机自动处理脚本留下的文件,进行还原
#!/bin/bash
# VMware 模块自动编译方案清理脚本
set -euo pipefail
# 颜色输出
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
NC='\033[0m' # No Color
echo -e "${GREEN}========================================${NC}"
echo -e "${GREEN} VMware 自动编译方案清理脚本 ${NC}"
echo -e "${GREEN}========================================${NC}"
# 检查是否 root 权限
if [ "$EUID" -ne 0 ]; then
echo -e "${RED}请以 root 权限运行此脚本(使用 sudo)。${NC}"
exit 1
fi
# 定义服务名和脚本路径
SERVICE_NAME="vmware-manual-build.service"
SCRIPT_PATH="/usr/local/bin/vmware-manual-build.sh"
# 1. 停止并禁用服务(如果存在)
if systemctl list-unit-files | grep -q "$SERVICE_NAME"; then
echo -e "${YELLOW}正在停止并禁用 $SERVICE_NAME ...${NC}"
systemctl stop "$SERVICE_NAME" 2>/dev/null || true
systemctl disable "$SERVICE_NAME" 2>/dev/null || true
echo -e "${GREEN}✅ 服务已停止并禁用。${NC}"
else
echo -e "${YELLOW}服务 $SERVICE_NAME 不存在,跳过。${NC}"
fi
# 2. 删除服务单元文件
if [ -f "/etc/systemd/system/$SERVICE_NAME" ]; then
echo -e "${YELLOW}正在删除服务单元文件...${NC}"
rm -f "/etc/systemd/system/$SERVICE_NAME"
echo -e "${GREEN}✅ 服务单元文件已删除。${NC}"
else
echo -e "${YELLOW}服务单元文件不存在,跳过。${NC}"
fi
# 3. 重新加载 systemd
systemctl daemon-reload
echo -e "${GREEN}✅ systemd 已重新加载。${NC}"
# 4. 删除编译脚本
if [ -f "$SCRIPT_PATH" ]; then
echo -e "${YELLOW}正在删除编译脚本 $SCRIPT_PATH ...${NC}"
rm -f "$SCRIPT_PATH"
echo -e "${GREEN}✅ 编译脚本已删除。${NC}"
else
echo -e "${YELLOW}编译脚本不存在,跳过。${NC}"
fi
# 5. 询问是否删除已安装的模块文件
echo -e "${YELLOW}是否要删除已安装的 VMware 模块文件(位于 /lib/modules/$(uname -r)/misc/ 下)?${NC}"
echo -e "${YELLOW}注意:删除后 VMware 将无法启动,除非重新编译模块。${NC}"
read -p "请输入 y/N: " -r choice
if [[ "$choice" =~ ^[Yy]$ ]]; then
MODULE_DEST="/lib/modules/$(uname -r)/misc"
if [ -d "$MODULE_DEST" ]; then
echo -e "${YELLOW}正在删除模块文件...${NC}"
rm -f "$MODULE_DEST"/vmmon.ko "$MODULE_DEST"/vmnet.ko
echo -e "${GREEN}✅ 模块文件已删除。${NC}"
# 更新模块依赖
depmod -a
echo -e "${GREEN}✅ 模块依赖已更新。${NC}"
else
echo -e "${YELLOW}模块目录不存在,跳过。${NC}"
fi
else
echo -e "${YELLOW}保留已安装的模块文件。${NC}"
fi
# 6. 提示完成
echo -e "${GREEN}========================================${NC}"
echo -e "${GREEN}清理完成!${NC}"
echo -e "如需重新部署,请再次运行安装脚本。"
echo -e "${GREEN}========================================${NC}"