📄 usermodelinux-howto.txt
字号:
88..22.. AAssssiiggnn tthhee ffiillee ttoo aa UUMMLL ddeevviiccee Add an argument like the following to the UML command line: ubd4=new_filesystem making sure that you use an unassigned ubd device number. 88..33.. CCrreeaattiinngg aanndd mmoouunnttiinngg tthhee ffiilleessyysstteemm Make sure that the filesystem is available, either by being built into the kernel, or available as a module, then boot up UML and log in. If the root filesystem doesn't have the filesystem utilities (mkfs, fsck, etc), then get them into UML by way of the net or hostfs. Make the new filesystem on the device assigned to the new file: host# mkreiserfs /dev/ubd/4 <----------- MKREISERFSv2 -----------> ReiserFS version 3.6.25 Block size 4096 bytes Block count 25856 Used blocks 8212 Journal - 8192 blocks (18-8209), journal header is in block 8210 Bitmaps: 17 Root block 8211 Hash function "r5" ATTENTION: ALL DATA WILL BE LOST ON '/dev/ubd/4'! (y/n)y journal size 8192 (from 18) Initializing journal - 0%....20%....40%....60%....80%....100% Syncing..done. Now, mount it: UML# mount /dev/ubd/4 /mnt and you're in business. 99.. HHoosstt ffiillee aacccceessss If you want to access files on the host machine from inside UML, you can treat it as a separate machine and either nfs mount directories from the host or copy files into the virtual machine with scp or rcp. However, since UML is running on the host, it can access those files just like any other process and make them available inside the virtual machine without needing to use the network. This is now possible with the hostfs virtual filesystem. With it, you can mount a host directory into the UML filesystem and access the files contained in it just as you would on the host. 99..11.. UUssiinngg hhoossttffss To begin with, make sure that hostfs is available inside the virtual machine with UML# cat /proc/filesystems . hostfs should be listed. If it's not, either rebuild the kernel with hostfs configured into it or make sure that hostfs is built as a module and available inside the virtual machine, and insmod it. Now all you need to do is run mount: UML# mount none /mnt/host -t hostfs will mount the host's / on the virtual machine's /mnt/host. If you don't want to mount the host root directory, then you can specify a subdirectory to mount with the -o switch to mount: UML# mount none /mnt/home -t hostfs -o /home will mount the hosts's /home on the virtual machine's /mnt/home. 99..22.. hhoossttffss aass tthhee rroooott ffiilleessyysstteemm It's possible to boot from a directory hierarchy on the host using hostfs rather than using the standard filesystem in a file. To start, you need that hierarchy. The easiest way is to loop mount an existing root_fs file: host# mount root_fs uml_root_dir -o loop You need to change the filesystem type of / in etc/fstab to be 'hostfs', so that line looks like this: /dev/ubd/0 / hostfs defaults 1 1 Then you need to chown to yourself all the files in that directory that are owned by root. This worked for me: host# find . -uid 0 -exec chown jdike {} \; Next, make sure that your UML kernel has hostfs compiled in, not as a module. Then run UML with the boot device pointing at that directory: ubd0=/path/to/uml/root/directory UML should then boot as it does normally. 99..33.. BBuuiillddiinngg hhoossttffss If you need to build hostfs because it's not in your kernel, you have two choices: +o Compiling hostfs into the kernel: Reconfigure the kernel and set the 'Host filesystem' option under +o Compiling hostfs as a module: Reconfigure the kernel and set the 'Host filesystem' option under be in arch/um/fs/hostfs/hostfs.o. Install that in /lib/modules/`uname -r`/fs in the virtual machine, boot it up, and UML# insmod hostfs 1100.. TThhee MMaannaaggeemmeenntt CCoonnssoollee The UML management console is a low-level interface to the kernel, somewhat like the i386 SysRq interface. Since there is a full-blown operating system under UML, there is much greater flexibility possible than with the SysRq mechanism. There are a number of things you can do with the mconsole interface: +o get the kernel version +o add and remove devices +o halt or reboot the machine +o Send SysRq commands +o Pause and resume the UML You need the mconsole client (uml_mconsole) which is present in CVS (/tools/mconsole) in 2.4.5-9um and later, and will be in the RPM in 2.4.6. You also need CONFIG_MCONSOLE (under 'General Setup') enabled in UML. When you boot UML, you'll see a line like: mconsole initialized on /home/jdike/.uml/umlNJ32yL/mconsole If you specify a unique machine id one the UML command line, i.e. umid=debian you'll see this mconsole initialized on /home/jdike/.uml/debian/mconsole That file is the socket that uml_mconsole will use to communicate with UML. Run it with either the umid or the full path as its argument: host% uml_mconsole debian or host% uml_mconsole /home/jdike/.uml/debian/mconsole You'll get a prompt, at which you can run one of these commands: +o version +o halt +o reboot +o config +o remove +o sysrq +o help +o cad +o stop +o go 1100..11.. vveerrssiioonn This takes no arguments. It prints the UML version. (mconsole) version OK Linux usermode 2.4.5-9um #1 Wed Jun 20 22:47:08 EDT 2001 i686 There are a couple actual uses for this. It's a simple no-op which can be used to check that a UML is running. It's also a way of sending an interrupt to the UML. This is sometimes useful on SMP hosts, where there's a bug which causes signals to UML to be lost, often causing it to appear to hang. Sending such a UML the mconsole version command is a good way to 'wake it up' before networking has been enabled, as it does not do anything to the function of the UML. 1100..22.. hhaalltt aanndd rreebboooott These take no arguments. They shut the machine down immediately, with no syncing of disks and no clean shutdown of userspace. So, they are pretty close to crashing the machine. (mconsole) halt OK 1100..33.. ccoonnffiigg "config" adds a new device to the virtual machine. Currently the ubd and network drivers support this. It takes one argument, which is the device to add, with the same syntax as the kernel command line. (mconsole) config ubd3=/home/jdike/incoming/roots/root_fs_debian22 OK (mconsole) config eth1=mcast OK 1100..44.. rreemmoovvee "remove" deletes a device from the system. Its argument is just the name of the device to be removed. The device must be idle in whatever sense the driver considers necessary. In the case of the ubd driver, the removed block device must not be mounted, swapped on, or otherwise open, and in the case of the network driver, the device must be down. (mconsole) remove ubd3 OK (mconsole) remove eth1 OK 1100..55.. ssyyssrrqq This takes one argument, which is a single letter. It calls the generic kernel's SysRq driver, which does whatever is called for by that argument. See the SysRq documentation in Documentation/sysrq.txt in your favorite kernel tree to see what letters are valid and what they do. 1100..66.. hheellpp "help" returns a string listing the valid commands and what each one does. 1100..77.. ccaadd This invokes the Ctl-Alt-Del action on init. What exactly this ends up doing is up to /etc/inittab. Normally, it reboots the machine. With UML, this is usually not desired, so if a halt would be better, then find the section of inittab that looks like this # What to do when CTRL-ALT-DEL is pressed. ca:12345:ctrlaltdel:/sbin/shutdown -t1 -a -r now and change the command to halt. 1100..88.. ssttoopp This puts the UML in a loop reading mconsole requests until a 'go' mconsole command is received. This is very useful for making backups of UML filesystems, as the UML can be stopped, then synced via 'sysrq s', so that everything is written to the filesystem. You can then copy the filesystem and then send the UML 'go' via mconsole. Note that a UML running with more than one CPU will have problems after you send the 'stop' command, as only one CPU will be held in a mconsole loop and all others will continue as normal. This is a bug, and will be fixed. 1100..99.. ggoo This resumes a UML after being paused by a 'stop' command. Note that when the UML has resumed, TCP connections may have timed out and if the UML is paused for a long period of time, crond might go a little crazy, running all the jobs it didn't do earlier. 1111.. KKeerrnneell ddeebbuuggggiinngg NNoottee:: The interface that makes debugging, as described here, possible is present in 2.4.0-test6 kernels and later. Since the user-mode kernel runs as a normal Linux process, it is possible to debug it with gdb almost like any other process. It is slightly different because the kernel's threads are already being ptraced for system call interception, so gdb can't ptrace them. However, a mechanism has been added to work around that problem. In order to debug the kernel, you need build it from source. See ``Compiling the kernel and modules'' for information on doing that. Make sure that you enable CONFIG_DEBUGSYM and CONFIG_PT_PROXY during the config. These will compile the kernel with -g, and enable the ptrace proxy so that gdb works with UML, respectively. 1111..11.. SSttaarrttiinngg tthhee kkeerrnneell uunnddeerr ggddbb You can have the kernel running under the control of gdb from the beginning by putting 'debug' on the command line. You will get an xterm with gdb running inside it. The kernel will send some commands to gdb which will leave it stopped at the beginning of start_kernel. At this point, you can get things going with 'next', 'step', or 'cont'. There is a transcript of a debugging session here <debug- session.html> , with breakpoints being set in the scheduler and in an interrupt handler. 1111..22.. EExxaammiinniinngg sslleeeeppiinngg pprroocceesssseess Not every bug is evident in the currently running process. Sometimes, processes hang in the kernel when they shouldn't because they've deadlocked on a semaphore or something similar. In this case, when you ^C gdb and get a backtrace, you will see the idle thread, which isn't very relevant. What you want is the stack of whatever process is sleeping when it shouldn't be. You need to figure out which process that is, which is generally fairly easy. Then you need to get its host process id, which you can do either by looking at ps on the host or at task.thread.extern_pid in gdb. Now what you do is this: +o detach from the current thread (UML gdb) det +o attach to the thread you are interested in (UML gdb) att <host pid> +o look at its stack and anything else of interest (UML gdb) bt Note that you can't do anything at this point that requires that a process execute, e.g. calling a function +o when you're done looking at that process, reattach to the current thread and
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -