uml使用详细

来源:互联网 发布:淘宝里的评价怎么删除 编辑:程序博客网 时间:2024/05/17 02:57

1,内核编译:
先说下环境如下,操作系统为CentOS 6.0 64位,除内核被升级为2.6.38.8外,其它基本环境无改变:
[root@localhost uml]# cat /etc/issue
CentOS Linux release 6.0 (Final)
Kernel \r on an \m

[root@localhost uml]# uname -a
Linux localhost.localdomain 2.6.38.8 #5 SMP Sun Aug 19 21:23:53 CST 2012 x86_64 x86_64 x86_64 GNU/Linux

解压配置,就以linux-2.6.38.8为例,因为刚好有这个内核源码压缩包:
[root@localhost uml]# tar xjf linux-2.6.38.8.tar.bz2
[root@localhost uml]# cd linux-2.6.38.8
[root@localhost linux-2.6.38.8]# make ARCH=um menuconfig

选下如下几项:
将以虚拟块设备作为根文件系统,并且我这里提供的根文件系统是ext4的:
Device Drivers —>
[*] Block devices —>
[*] Virtual block device
[*] Always do synchronous disk IO for UBD
File systems —>
<*> The Extended 4 (ext4) filesystem

将以虚拟设备作为网络设备,可根据需要选择,比如如下:
[*] Networking support —>
UML Network Devices —>
[*] Virtual network device
[*] Ethertap transport
[*] TUN/TAP transport
[*] SLIP transport
[*] Daemon transport
[ ] VDE transport
[*] Multicast transport
[ ] pcap transport
[*] SLiRP transport

既然是调内核,这两个选项必不可少:
Kernel hacking —>
[*] Compile the kernel with debug info
[*] Compile the kernel with frame pointers

执行编译:
[root@localhost linux-2.6.38.8]# make ARCH=um
或者只要linux执行文件:
[root@localhost linux-2.6.38.8]# make ARCH=um linux

如果没有错误,那么就算初步成功,否则请参考前面的文章做错误修复:
[root@localhost linux-2.6.38.8]# ls linux -lFh
-rwxr-xr-x. 2 root root 35M Aug 24 14:36 linux*

2,UML执行:
首先需要一个根文件系统,从这个网址:http://fs.devloop.org.uk/下载即可:
[root@localhost linux-2.6.38.8]# cp linux ../
[root@localhost linux-2.6.38.8]# cd ..
[root@localhost uml]# ls
linux linux-2.6.38.8 linux-2.6.38.8.tar.bz2 rootfs
[root@localhost uml]# ./linux ubda=./rootfs mem=256m

正常进入到UML系统,退出输入halt或init 0即可。

3,初次调试内核:
首先找到uml对应的进程,一般会有多个:
[root@localhost uml]# ps uf | grep linux | grep -v grep
root 26897 4.3 5.6 270320 57112 pts/0 S+ 14:48 0:12 \_ ./linux ubda=./rootfs mem=256m
root 26904 0.0 5.6 270320 57112 pts/0 S+ 14:48 0:00 \_ ./linux ubda=./rootfs mem=256m
root 26905 0.4 5.6 270320 57112 pts/0 S+ 14:48 0:01 \_ ./linux ubda=./rootfs mem=256m
root 26906 0.0 5.6 270320 57112 pts/0 S+ 14:48 0:00 \_ ./linux ubda=./rootfs mem=256m
root 26907 0.0 0.1 3776 1516 pts/0 t+ 14:48 0:00 \_ ./linux ubda=./rootfs mem=256m
root 27058 0.2 0.0 3120 772 pts/0 t+ 14:48 0:00 \_ ./linux ubda=./rootfs mem=256m
root 27342 0.0 0.0 3152 644 pts/0 t+ 14:48 0:00 \_ ./linux ubda=./rootfs mem=256m
root 27636 0.0 0.0 3400 664 pts/0 t+ 14:48 0:00 \_ ./linux ubda=./rootfs mem=256m
root 27663 0.0 0.1 4036 1376 pts/0 t+ 14:48 0:00 \_ ./linux ubda=./rootfs mem=256m
root 27672 0.0 0.1 4056 1768 pts/0 t+ 14:48 0:00 \_ ./linux ubda=./rootfs mem=256m
一般情况下,用gdb attach到主进程即可:
[root@localhost uml]# gdb -p 26897
进入gdb后立即设置:(gdb) set follow-fork-mode parent
因为UML在运行的过程中可能会fork新的子进程(比如UML启动了新的系统服务),如果不做这个设置,会导致gdb跟丢UML。
试试在schedule()函数处下个断点,按c继续后马上被中断(这是当然的):
(gdb) b schedule
Breakpoint 1 at 0x601ca50f: file kernel/sched.c, line 4017.
(gdb) c
Continuing.

Breakpoint 1, schedule () at kernel/sched.c:4017
4017 if (need_resched())
(gdb) up
#1 0×0000000060012424 in default_idle () at arch/um/kernel/process.c:246
246 schedule();
(gdb) list
241 /*
242 * although we are an idle CPU, we do not want to
243 * get into the scheduler unnecessarily.
244 */
245 if (need_resched())
246 schedule();
247
248 tick_nohz_stop_sched_tick(1);
249 nsecs = disable_timer();
250 idle_sleep(nsecs);
(gdb)

4,网络支持:
以TUN/TAP为例。关于更多的信息可以参考:
http://user-mode-linux.sourceforge.net/old/networking.html
UML可以利用host机器的TUN/TAP虚拟网络设备来创建虚拟网卡与外界通信。这里先在host机器上创建tap设备,创建tap设备需要的应用层工具tunctl可从此处下载:http://sourceforge.net/projects/tunctl/files/

[root@localhost uml]# tar xzf tunctl-1.5.tar.gz
[root@localhost uml]# cd tunctl-1.5
[root@localhost tunctl-1.5]# make
[root@localhost tunctl-1.5]# make install
[root@localhost tunctl-1.5]# tunctl -t tap1
[root@localhost tunctl-1.5]# ifconfig tap1 10.0.0.1

这就在host机器里创建了tap类型的虚拟网络设备,再以如下命令执行UML,从而在UML里创建一个可与该虚拟网络设备通信的网卡eth0:
[root@localhost uml]# ./linux ubda=./rootfs mem=256m eth0=tuntap,tap1,,

在UML里ping host机的tap1的操作:
[root@localhost ~]# ifconfig eth1 10.0.0.2
[root@localhost ~]# ping 10.0.0.1
PING 10.0.0.1 (10.0.0.1) 56(84) bytes of data.
64 bytes from 10.0.0.1: icmp_seq=1 ttl=64 time=67.2 ms
64 bytes from 10.0.0.1: icmp_seq=2 ttl=64 time=0.338 ms
^C
— 10.0.0.1 ping statistics —
2 packets transmitted, 2 received, 0% packet loss, time 1569ms
rtt min/avg/max/mdev = 0.338/33.814/67.290/33.476 ms
[root@localhost ~]#

在host机里ping UML的eth0:
[root@localhost tunctl-1.5]# ping 10.0.0.2
PING 10.0.0.2 (10.0.0.2) 56(84) bytes of data.
64 bytes from 10.0.0.2: icmp_seq=1 ttl=64 time=0.411 ms
64 bytes from 10.0.0.2: icmp_seq=2 ttl=64 time=0.177 ms
^C
— 10.0.0.2 ping statistics —
2 packets transmitted, 2 received, 0% packet loss, time 1312ms
rtt min/avg/max/mdev = 0.177/0.294/0.411/0.117 ms
[root@localhost tunctl-1.5]#

可以创建多个tap虚拟网络设备,让UML创建更多的虚拟网卡:
[root@localhost tunctl-1.5]# tunctl -t tap2
[root@localhost tunctl-1.5]# ifconfig tap2 20.0.0.1
再以“./linux ubda=./rootfs mem=256m eth0=tuntap,tap1,, eth1=tuntap,tap2,,”执行UML即可。其它虚拟网络设备,比如ethertap、Multicast、switch daemon、slip、slirp等也都可以利用,这里有一套官方工具:http://user-mode-linux.sourceforge.net/uml_utilities_20070815.tar.bz2。

5,利用uml_switch对UML虚拟机进行组网:
首先,使用uml_switch命令创建三台虚拟交换机:switch1、switchA和switchB,其中:
switch1的网络为10.0.0.0/24,并且其对应的tap1的host ip地址为10.0.0.1,启动和配置方式为:
[root@localhost af]# nohup uml_switch -tap tap1 -unix /tmp/switch1 &
[root@localhost af]# ifconfig tap1 10.0.0.1
switchA的网络为192.168.11.0/24,启动方式为:
[root@localhost af]# nohup uml_switch -tap tapA -unix /tmp/switchA &
switchB的网络为192.168.22.0/24,启动方式为:
[root@localhost af]# nohup uml_switch -tap tapB -unix /tmp/switchB &

接着,启用serverA,使其有两个网卡,一个连接switch1(eth0),一个连接switchA(eth1),启动serverA的命令为:
[root@localhost net_simu]# ./serverA/linux ubda=./serverA/rootfs mem=128m eth0=daemon,,unix,/tmp/switch1 eth1=daemon,,unix,/tmp/switchA
执行成功登陆UML系统后,可看到有两个网卡表示正常。

启动serverB,使其也有两个网卡,一个连接switch1(eth0),一个连接switchA(eth1),启动serverB的命令为:
[root@localhost net_simu]# ./serverB/linux ubda=./serverB/rootfs mem=128m eth0=daemon,,unix,/tmp/switch1 eth1=daemon,,unix,/tmp/switchB

启动clientA1,使其有一个网卡,连接switchA(eth0),启动命令为:
[root@localhost net_simu]# ./clientA1/linux ubda=./clientA1/rootfs mem=128m eth0=daemon,,unix,/tmp/switchA

启动clientB1,使其有一个网卡,连接switchB (eth0),启动命令为:
[root@localhost net_simu]# ./clientB1/linux ubda=./clientB1/rootfs mem=128m eth0=daemon,,unix,/tmp/switchB

启动clientB2,使其有一个网卡,连接switchB (eth0),启动命令为:
[root@localhost net_simu]# ./clientB2/linux ubda=./clientB2/rootfs mem=128m eth0=daemon,,unix,/tmp/switchB

做网络测试:
在clientB2上ping clientB1和serverB没问题,其它几个switch域内互ping也没问题;
在serverA上ping host机器OK,ping google的DNS服务器不行,那是当然的,需要我们再在host机器上加上NAT才能当UML的数据发送出去,先对host机器做如下设置:

1
2
3
4
5
6
7
[root@www ~]# echo 1 > /proc/sys/net/ipv4/ip_forward
[root@www ~]# iptables -F INPUT
[root@www ~]# iptables -F OUTPUT
[root@www ~]# iptables -F FORWARD
[root@www ~]# iptables -t nat -F POSTROUTING
[root@www ~]# iptables -t nat -F PREROUTING
[root@www ~]# iptables -t nat -A POSTROUTING -o eth3 -s 10.0.0.0/24 -j MASQUERADE

再试试ping google DNS服务器,就已经可以了。

6,试用总结
在2.6内核下(UML自2.6.9开始合入到kernel主线里),UML的使用非常的简单,它能做和不能做的总结如下:
1 调试内核代码流程 √
2 调试业务内核模块逻辑功能 √
3 抓取非硬件导致的oops和宕机 √
4 非法内存或空指针访问 √
5 进程请求资源死锁 √
6 非硬件因素导致的文件/文件系统损坏 √ 文件访问处断点
7 一台实体机器上运行多个UML实例 √
8 模拟复杂的网络环境 √
9 调试UML内普通进程 × 已被UML监控
10 调试intel网卡驱动 × 硬件相关皆无视
11 模拟高性能网络环境 × 网络性能很差
12 捕获SMP条件下才可能出现的问题 × X86_64 SMP待研究

转载请保留地址:http://lenky.info/2012/08/26/uml%e4%bd%bf%e7%94%a8%e8%af%a6%e7%bb%86/ 或http://lenky.info/?p=1890





之前提到过KML,这里描述一下UML,但关于UML的编译和使用不想做过多的介绍,因为官网等都有很多这方面的资料,不过我乐意提供另外一些汇总信息,也是我在编译使用UML过程中遇到的问题,当然限于环境关系,这些问题在另外的环境里不一定就出现,另外的环境里出现的问题我这里可能没有遇到。
一,不错的相关站点:http://user-mode-linux.sourceforge.net/、http://uml.devloop.org.uk/index.html
二,文件系统:http://fs.devloop.org.uk/
三,邮件列表:http://dir.gmane.org/gmane.linux.uml.devel、http://dir.gmane.org/gmane.linux.uml.user
四,UML项目并没有废弃,一直在更新维护,这从邮件列表的活动情况可以看出来,Linux 3.0还有UML的更新:http://kernelnewbies.org/Linux_3.0#head-64b1d7b9dd5fdd57ce0350987108ac475634e5e7
五,在编译和使用UML过程中,可能遇到的问题:
1,找不到文件系统
[ 0.230000] VFS: Cannot open root device “98:0″ or unknown-block(98,0)
[ 0.230000] Please append a correct “root=” boot option; here are the available partitions:
[ 0.230000] Kernel panic – not syncing: VFS: Unable to mount root fs on unknown-block(98,0)
解决:首先请确保UML内核编译时已经选上这么几项:
— Block devices
[*] Virtual block device
[*] Always do synchronous disk IO for UBD
其次,如果你的根文件系统是ext4的,请确保选中:
File systems —>
<*> The Extended 4 (ext4) filesystem
其它文件系统类似。
最后,请确保运行uml时带上了ubda或udba这样的选项。
另外几个选项也建议选上:将以虚拟设备作为网络设备:
[*] Networking support —>
UML Network Devices —>
[*] Virtual network device
[*] Ethertap transport
[*] TUN/TAP transport
使用UML大部分是为了调内核,这两个选项必不可少:
Kernel hacking —>
[*] Compile the kernel with debug info
[*] Compile the kernel with frame pointers
2,编译警告:
LD vmlinux.o
MODPOST vmlinux.o
WARNING: vmlinux.o (.__syscall_stub.2): unexpected non-allocatable section.
Did you forget to use “ax”/”aw” in a .S file?
Note that for example contains
section definitions for use in .S files.
GEN .version
解决:http://comments.gmane.org/gmane.linux.uml.devel/12200

diff –git a/arch/um/sys-x86_64/stub.S b/arch/um/sys-x86_64/stub.S
index 6d9edf9..20e4a96 100644
— a/arch/um/sys-x86_64/stub.S
+++ b/arch/um/sys-x86_64/stub.S
@@ -1,7 +1,7 @@
#include “as-layout.h”
.globl syscall_stub
-.section .__syscall_stub, “x”
+.section .__syscall_stub, “ax”
syscall_stub:
syscall
/* We don’t have 64-bit constants, so this constructs the address
3,模块插入错误:
[root@localhost ~]# insmod test.ko
[ 3120.390000] test: Unknown symbol memcpy
[ 3120.390000] test: Unknown symbol _GLOBAL_OFFSET_TABLE_
insmod: error inserting ‘test.ko’: -1 Unknown symbol in module
[root@localhost ~]#
解决:https://dev.openwrt.org/browser/branches/backfire/target/linux/uml/patches-2.6.30/003-fix_memcpy_export_on_x86_64.patch?rev=21295
arch/um/os-Linux/user_syms.c
a b
23 23 EXPORT_SYMBOL(strstr);
24 24 #endif
25 25
26 – #ifndef __x86_64__
++ 26 #if !defined(__x86_64) || (__GNUC__ == 4 && __GNUC_MINOR__ < 3) || (__GNUC__ < 4)
27 27 extern void *memcpy(void *, const void *, size_t);
28 28 EXPORT_SYMBOL(memcpy);
29 29 #endif
_GLOBAL_OFFSET_TABLE_的问题解决:
不要有-fPIC编译选项或者直接设置-fno-pic
https://github.com/LeeDroid-/Flyer-2.6.35/commit/778422912da1042b9febb59a8786718628e93487
-CFLAGS_MODULE = $(MODFLAGS)
+CFLAGS_MODULE = $(MODFLAGS) -fno-pic
4,模块插入错误:
出现另外的错误(如果设置的内存大于等于504M):
[root@localhost tmp]# insmod test.ko
[ 605.820000] overflow in relocation type 11 val 1a0b93b40
[ 605.820000] `test’ likely not compiled with -mcmodel=kernel
insmod: error inserting ‘test.ko’: -1 Invalid module format
[root@localhost tmp]#
解决:貌似这是UML本身bug,把内核设置为小于504M吧。
5,运行警告:
IRQ 5/eth1: IRQF_DISABLED is not guaranteed on shared IRQs
解决:
http://comments.gmane.org/gmane.linux.uml.devel/12098
—–
— arch/um/drivers/net_kern.c.orig 2009-03-11 21:16:36.000000000 +0100
+++ arch/um/drivers/net_kern.c 2009-03-11 21:16:46.000000000 +0100
-165,7 +165,7 
}
err = um_request_irq(dev->irq, lp->fd, IRQ_READ, uml_net_interrupt,
- IRQF_DISABLED | IRQF_SHARED, dev->name, dev);
+ IRQF_SHARED, dev->name, dev);
if (err != 0) {
printk(KERN_ERR “uml_net_open: failed to get irq(%d)\n”, err);
err = -ENETUNREACH;
6,编译错误:
[root@localhost ~]$ make linux ARCH=um
make[1]: `arch/um/sys-x86_64/user-offsets.s’ is up to date.
CHK include/linux/version.h
CHK include/linux/utsrelease.h
SYMLINK include/asm -> include/asm-um
CALL scripts/checksyscalls.sh
CHK include/linux/compile.h
CC arch/um/os-Linux/mem.o
arch/um/os-Linux/mem.c: In function ‘create_tmp_file’:
arch/um/os-Linux/mem.c:216: error: implicit declaration of function ‘fchmod’
make[1]: *** [arch/um/os-Linux/mem.o] Error 1
make: *** [arch/um/os-Linux] Error 2
[root@localhost ~]$
解决:http://moodlearchive.epfl.ch/2010-2011/mod/forum/discuss.php?d=108781
在对应的源文件里包含即可。
六,UML的网络支持:这个还是比较多的,这在内核选项里可以看到:make menuconfig ARCH=um
[*] Networking support —>
UML Network Devices —>
[*] Virtual network device
[*] Ethertap transport
[*] TUN/TAP transport
[*] SLIP transport
[*] Daemon transport
[ ] VDE transport
[*] Multicast transport
[*] pcap transport
[*] SLiRP transport
但需要如下两个工具:
http://sourceforge.net/projects/tunctl/files/
http://user-mode-linux.sourceforge.net/uml_utilities_20070815.tar.bz2
七,UML对SMP支持:
这个从UML的邮件列表来看,x86 估计是直接支持的:
http://thread.gmane.org/gmane.linux.kernel/326919/focus=327289
http://thread.gmane.org/gmane.linux.uml.devel/9298/focus=9301
而x86-64下估计有问题:
http://thread.gmane.org/gmane.linux.kernel/326919
http://thread.gmane.org/gmane.linux.uml.devel/12206/focus=12209
http://article.gmane.org/gmane.linux.kernel/235089/match=smp
http://thread.gmane.org/gmane.linux.kernel/600015
但我并未做实际验证,所以对此尚且不太清楚。分类:


原创粉丝点击