【问题标题】:QEMU Cannot Open Tap Device in Windows 10 HostQEMU 无法在 Windows 10 主机中打开 Tap 设备
【发布时间】:2020-01-19 03:45:02
【问题描述】:

我正在尝试将我的 QEMU VM 桥接到我的 Windows 10 主机中的本地适配器,但 QEMU 抱怨无法打开由 ifname 选项提供的接口名称 -netdev 参数。我已按照https://superuser.com/questions/1317652/how-to-set-up-nat-for-qemu-with-tap-backend-windows-10 中的答案进行操作,但没有运气。我已经从源代码交叉编译了 QEMU 来调试这种行为,是否可以检测到接口名称,显然 QEMU 可以找到适配器的名称,但不能找到 TAP 设备文件。为了进一步解释我的观点,这里是来自 QEMU 4.2.0 源代码(撰写本文时的最新版本)的net/tap-win32.c:595 的代码 sn-p,特别是 tap_win32_open 函数,我将强调它在此失败的地方函数(寻找// THIS IS WHERE IT WILL FAIL. cmets):

  1. 使用正确的现有网络接口进行测试:
static int tap_win32_open(tap_win32_overlapped_t **phandle,
                          const char *preferred_name)
{
    ...

    rc = get_device_guid(device_guid, sizeof(device_guid), name_buffer, sizeof(name_buffer));
    if (rc)
        return -1;

    snprintf (device_path, sizeof(device_path), "%s%s%s",
              USERMODEDEVICEDIR,
              device_guid,
              TAPSUFFIX);

    handle = CreateFile (
        device_path,
        GENERIC_READ | GENERIC_WRITE,
        0,
        0,
        OPEN_EXISTING,
        FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED,
        0 );

    if (handle == INVALID_HANDLE_VALUE) {
        return -1; // THIS IS WHERE IT WILL FAIL.
    }

    ...
  1. 使用不正确(不存在)的网络接口进行测试:
static int tap_win32_open(tap_win32_overlapped_t **phandle,
                          const char *preferred_name)
{
    ...

    rc = get_device_guid(device_guid, sizeof(device_guid), name_buffer, sizeof(name_buffer));
    if (rc)
        return -1; // THIS IS WHERE IT WILL FAIL.

    snprintf (device_path, sizeof(device_path), "%s%s%s",
              USERMODEDEVICEDIR,
              device_guid,
              TAPSUFFIX);

    handle = CreateFile (
        device_path,
        GENERIC_READ | GENERIC_WRITE,
        0,
        0,
        OPEN_EXISTING,
        FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED,
        0 );

    if (handle == INVALID_HANDLE_VALUE) {
        return -1;
    }

    ...

QEMU 使用前缀USERMODEDEVICEDIR,即\\.\Global\ 和设备GUID 的后缀.tap 在Windows 中创建设备路径。例如,我正在处理的网络适配器导致以下设备路径:\\.\Global\{990DA322-3986-4854-AE93-1D6FB0BFA137}.tap。知道为什么CreateFile 总是在设备路径上产生INVALID_HANDLE_VALUE 吗?顺便说一句,GetLastError() 返回2,从docs.microsoft.com 的含义如下:

...
ERROR_FILE_NOT_FOUND

2 (0x2)

The system cannot find the file specified.
...

【问题讨论】:

  • 尝试使用WinObjEx64查看设备是否真的存在
  • 如果您使用 ASCII 版本 API CreateFileA,请确保传递给 CreateFile 的路径为 "\\\\.\\Global\\{990DA322-3986-4854-AE93-1D6FB0BFA137}.tap"。如果您使用 unicode 版本 API CreateFileW,则传递 L"\\\\.\\Global\\{990DA322-3986-4854-AE93-1D6FB0BFA137}.tap"

标签: winapi cross-compiling device qemu file-not-found


【解决方案1】:

我很抱歉。我正在连接一个非 TAP 适配器,认为它会从中获取地址,就像 VirtualBox 一样。我之前在 QEMU 中并没有完全理解桥接的概念,但现在我应该连接到一个 TAP 适配器,然后将该适配器桥接到另一个首选适配器。

【讨论】:

  • 如果问题解决了,您可以分享您的解决方案并接受它。
  • 嗨@RitaHan-MSFT,我已经分享了我的问题的解决方案。我只是为-netdev 参数的ifname 子参数指定了一个非TAP 适配器。 QEMU 中的桥接比在 VirtualBox 中更复杂,我可以在其中指定要桥接的任何适配器。
猜你喜欢
  • 2018-08-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-06
  • 1970-01-01
  • 2020-11-08
  • 2014-08-04
相关资源
最近更新 更多