今天看到一个类似的问题:VBoxManage:不会启动虚拟机 NS_ERROR_FAILURE (0x80004005)但我可以在这里描述一个完全不同的令人费解的背景。
在基于 Ubuntu 20.04 的发行版中,我能够从普通用户发出以下命令:
$ whoami
my-user-name
$ VBoxManage startvm --type headless my.app-name
但我是不是能够从 Java(特别是 Tomcat9)从同一用户执行相同的命令:
ProcessBuilder pb = new ProcessBuilder("bash", "-c", "whoami"); // my-user-name
Process p = pb.start();
ProcessBuilder pb = new ProcessBuilder("bash", "-c", "VBoxManage ...");
Process p = pb.start();
在最后一种情况下,我收到此错误:
VBoxManage: error: Details: code NS_ERROR_FAILURE (0x80004005), component MachineWrap, interface IMachine
请注意,我还能够从紧急tty
控制台或任何其他非交互式 shell 成功发出该命令,但是不是来自 Tomcat 进程执行的 Java。
互联网上的每个人都只是建议重新安装 VirtualBox,但这对于这种情况来说是完全不相关的解决方案(也是因为我多次尝试重新安装 Tomcat 或 VirtualHost 而不更改任何内容)。他们还建议采用,--type headless
但我已经这样做了。
我也尝试过这些,但没有成功:
- 重新安装Tomcat
- 重新安装 VirtualBox(两次)
- 将内核更新到奇怪的不稳定版本
- 刷新较新的 BIOS
有什么故障排除提示吗?
答案1
我也有同样的问题。我受到了systemd
限制的影响。
检查您的 systemd Tomcat 服务(使用您的确切版本):
sudo systemctl cat tomcat9.service
#
# Systemd unit file for Apache Tomcat
#
...
# Security
User=my-user-name
Group=my-user-name
PrivateTmp=yes
AmbientCapabilities=CAP_NET_BIND_SERVICE
NoNewPrivileges=true
...
您可能有上述设置,特别是NoNewPrivileges
。这对于某些用例来说是有问题的,因为:1
如果为 true,则确保服务进程及其所有子进程永远无法通过 execve() 获得新权限(例如,通过 setuid 或 setgid 位,或文件系统功能)。这是确保进程及其子进程永远无法再次提升权限的最简单、最有效的方法。
如果这是您的问题,请禁用该配置(我已对其进行了评论):
sudo systemctl edit --full tomcat9.service
...
# NoNewPrivileges=true
...
然后重启Tomcat:
sudo systemctl restart tomcat9.service
一切都会恢复正常。
我希望这能帮助其他人避免由于发行版采用的默认 systemd 服务单元中的这一特定限制而花费数小时进行故障排除。如果您有更多注释,请添加评论。