KVM “qemu-ifup: could not configure /dev/net/tun: Operation not permitted”解决方案

今天帮一个同事解决在KVM Guest中使用虚拟网卡(桥接方式),我写了个qemu-ifup脚本拿来做guest启动之时使用。但是他使用时,遇到如下的问题。
/etc/qemu-ifup: could not launch network script
qemu-system-x86_64: -net tap,script=/etc/qemu-ifup: Device ‘tap’ could not be initialized

使用的命令为:
qemu-system-x86_64 -m 1024 -smp 2 -net nic,model=rtl8139 -net tap,scritp=/etc/qemu-ifup -hda /root/rhel6u2.img

我的qemu-ifup的小脚本如下:

你能看出其中的错误吗?

网上找了一下,先需要确认如下几个问题:
1. 是否加载tun模块?
lsmod | grep tun
如果没有加载,那么就请先load tun模块:modprobe tun
当然,如果你是把tun模块编译进内核了的,是不需要(也不能)modprobe加载tun的,你可以检查你的kernel config文件(通常在/boot/config-$VERSION),如果有如下的配置,则说明已经编译进kernel了的。
CONFIG_TUN=y

2. 检查/dev/net/tun的权限
ls -l /dev/net/tun
crw-rw-rw- 1 root root 10, 200 Mar 23 18:11 /dev/net/tun
这样的权限是没有问题的。

3. 检查/etc/qemu-ifup的权限
当前用户需要有可执行权限

4. 检查是否已经安装bridge-utils软件包
rpm -qa | grep bridge 来查询,如果没有就请安装bridge-utils包,主要是脚本中一般需要用到brctl这个命令的。

我检查了网上常见的4种说法后,依然没有发现问题。我后来仔细分析我的这个小小脚本,我将其单独执行,这时我发现它会报错说是找不到解释器。

我猛然想起来,这个脚本是我在Windows上写的,然后copy到同事的Linux机器上去执行的,所以它被加了一个“奇特的”符号”^M”,然后就找不到bash了。
解决方法当然是很简单,在linux上重新建立这个文件即可(内容不变),或者使用dos2unix工具转换为linux下的格式类型即可。

关于为什么有个神奇的符号“^M”,可以从参考我曾写过的一篇文章:回车与换行的区别
关于shebang指定脚本解释器,可以参考我前阵子写过的:Linux上的Shebang符号(#!)

master

Stay hungry, stay foolish.

17 Comments

  1. 我也碰到这个问题,如下:
    [root@host01 home]# kvm -m 1024 -smp 4 -boot order=d -hda /home/vm/kvm/centos64_64_01.qcow2 -nographic -net nic,model=e1000 -net tap,ifname=tap1
    /etc/qemu-ifup: could not launch network script
    kvm: -net tap,ifname=tap1: Device ‘tap’ could not be initialized

    我看了下我这没有/etc/qemu-ifup 这个脚本,这个脚本是不是默认不存在的?

    • 我按照书中写的操作
      brctl addbr br0
      brctr addif br0 eth0
      到这一步完成的时候宿主机网络断了,我继续把下面的操作走完又重启了下network服务service network restart后网络恢复,不知道为什么?
      brctl stm br0 on
      ifconfig eth0 0
      dhclient br0
      这个br0 跟那个tap0什么关系,以前用vmare的时候感觉没这么麻烦

  2. 总算把虚拟机用桥接方式连上网了,网上看了一堆乱七八糟的方法,最终还是加了个你书上p88页的qemu-ifup脚本后搞定了,那个脚本中没有你这篇博文中提到的/sbin/ifconfig $1 0.0.0.0 up这句,不加好像不行。虽然通了,但是原理还不太懂,为什么宿主机的eth0的ip设置成0了,还能ping同宿主机呢?宿主机中的eth0跟br0什么关系?
    另外是不是应该把书中p87页的btctl相关的几个命令也加到qemu-ifup脚本里面?

    • 书中p88的ip link set $1 up 已经本文中的 /sbin/ifconfig $1 0.0.0.0 up 类似了。
      另外,p87页中的命令不能加到qemu-ifup中去。 因为p87中的命令是配置宿主机的,一个宿主机只配置一个即可;而qemu-ifup脚本是针对每个客户机启动时都执行一遍(如果使用桥接的话),那个$1变量就是根据各个客户机都会有不同的值。

      • 书中p88的ip link set $1 up 已经本文中的 /sbin/ifconfig $1 0.0.0.0 up 类似了。
        原来如此,多谢指点。

  3. 又碰到个问题,qemu-kvm安装的虚拟机没法用virsh启动,virsh list找不到qemu命令安装的虚拟机,如果不用virt-install重装的话还有别的办法吗?
    virsh define xxx.xml貌似可以创建个虚拟机,感觉像是个clone的功能,问题是这个xml文件太复杂了,改改还可以,要手写一个太难用了。

    • qemu命令直接启动的一个客户机,不能用virsh管理~ 要用virsh管理必须用Virsh来启动。那个XML是很复杂,所以,我一般都是用virt-manager图形界面安装一个客户机,然后得到了一个xml文件,今后就根据这个复制、修改即可。。

      • 谢谢,经验之谈,很有价值,对于新手来说很多时候不知道自己的做法是不是合理,是不是有更好的方法可用而自己却一直用愚蠢的做法处理。有了您的指点心里踏实多了。

  4. 光看书还是行,按照上述脚本终于配置好了,但还是有个问题,还请不吝赐教。我的环境是服务3块网卡做了bond,然后创建网桥br0,现在开了2个虚拟机,虚拟机能够ping通外部,也能ping通宿主机,宿主机能够ping通2个虚拟机,但是外部网络无法ping通虚拟机,这是什么原因?

    • 你是使用Bridge方式吗?看你现象有点像使用NAT啊。。。 你看下书上的P90。另外,你看下你启动命令和虚拟机、宿主机IP是什么?

  5. 哈,回复速度还真快。多谢。
    ——————————
    宿主机br0的ip是192.168.10.15,虚拟机的IP是192.168.10.71,192.168.10.81,两个虚拟机互相也ping不通

    虚拟机启动命令是qemu-system-x86_64 rhel64.img -smp 2 -m 2048 -net nic -net tap,ifname=tap1,script=/etc/qemu-ifup,downscript=no

    脚本用此页面的脚本替换书上的脚本内容

    bridge name bridge id STP enabled interfaces
    br0 8000.02fdabf54f20 yes bond0
    tap1

  6. /usr/local/qemu-system//bin/qemu-system-x86_64 -m 1024 -smp 2 -boot order=cd -hda ubuntu-server-14.04-x64.qcow2 -cdrom ../System-cd/ubuntu-14.04-server-amd64.iso -net nic -net tap, ifname=tap1,script=bridge-up.sh,downscript=no -vnc :0 -daemonize
    /etc/qemu-ifup: could not launch network script
    qemu-system-x86_64: -net tap,: Device ‘tap’ could not be initialized
    ./bridge-up.sh tap1
    Cannot find device “tap1”
    interface tap1 does not exist!

    这个问题怎么解决

    • 既然都找到我这篇文章来了,你可以先把文章中提及的各种解决方法都先尝试一下。

发表评论

电子邮件地址不会被公开。 必填项已用*标注