UMview is essentially a System Call Virtual Machine. To accomplish its job to start a process within system call virtualization something like a Virtual Machine Monitor have to be between process looking for a new view of the underlying system and the operating system itself.
UMview is made of several tools that will be explained below.
It is used to start a new command (passed as argument with it own additional optional arguments). Once started if there's not any module loaded it behaves like executing outside umview. When starting a non-interactive shell program within umview it may be useful to preload modules.
$ umview bash
- module preloading
- preloaded modules can be specified with command line argument
umview -p modulename[,param1,...,paramN]
$ umview -p lwipv6.so,vd0=/var/run/vde.ctl bash
- kernel optimization and additional features
- Features like kernel optimization or module nesting are autodetected and enabled by default when available. It may be useful for debugging reasons to disable one or more of this options with flag parameters passed to umview.
- disable modules nesting
$ umview -x bash
- disable all kernel extensions
$ umview -n bash
$ umview --nokmulti bash
$ umview --nokvm bash
- If umview was compiled with debugging symbols enabled it is possible to redirect all the debugging output to a file specified in the command line.
$ umview -o debugging_file.txt bash
Adds the specified service module to the umview chain. It must be run from the process launched within umview, so it permits to load a service module during execution inside umview.
$ um_add_service umnnet
Removes the specified service module from umview.
$ um_ls_service umdev: virtual devices umfuse: virtual file systems (user level FUSE) $ um_del_service umdev
This command gives a list of the currently loaded umview service modules.
$ um_ls_service umdev: virtual devices umfuse: virtual file systems (user level FUSE) umnet: virtual (multi-stack) networking
Modules are like shared objects so needs to be loaded by umview like any other dynamic library. The path where umview modules reside should be added to ld.so cache or declared as shell environment variable
umnet is the View-OS module for multi-networking. In fact it supports the multi stack extension to the Berkeley Socket API named msockets.
From the user's point of view, umnet can be loaded in this way
Like many other View-OS modules umnet enables the mount operation for sub-modules prefixed by umnet
mount -t umnetnull none /dev/net/null mount -t umnetcurrent none /dev/net/current
The former example define /dev/net/null to be a null network (socket/msocket calls fail, no networking is possible using /dev/net/null). The latter is a gateway to the current stack of the calling process.
umnet provides also the msocket backward compatibility tool named mstack.
mstack /dev/net/native ip link
gives the same output of ip link (there is a subtle but important difference: the mstack command causes the View-OS hypervisor -- i.e. umview or kmview -- to give the answer, using ip addr the answer comes directly from the kernel to the process bypassing View-OS).
mstack is a backward compatibility tool, not a protection tool. When several stacks are available it is possible to use mstack to switch from one stack to another.
If a stack gets mounted on /dev/net/default, View-OS uses this stack as default.
mount -t umnetnative none /dev/net/default
defines the native network as the default network. The effect of this command is subtle: all the programs seem to access the network in the same way after this command as they did before it.
- Before the command the processes use the kernel stack directly: default networking has not been virtualized.
- After the command the networking calls get virtualized and View-OS (umview or kmview) uses the kernel stack to execute the calls.
mount -t umnetnull -o perm none /dev/net/default
disables networking. The perm option denies the umount operation (the mountpoint will always be busy), thus the operation is not undoable.
Linux kernel provides an extension module that allows to define new executable file formats without the need of recompile the whole kernel. This task is accomplished by an interface in
What this UMview service module aims is to allow registration of new executable file formats at user-level.
The module works by overlaying a virtual
/proc interface onto the same place where the real binfmt_misc
/proc interface resides.
First of all the
umbinfmt module must be loaded into the UMview chain of services. Then umbinfmt virtual filesystem have to be mounted in
$ um_add_service umbinfmt umbinfmt init $ mount -t umbinfmt none /proc/sys/fs/binfmt_misc $ ls -l /proc/sys/fs/binfmt_misc --w------- 1 root root 0 Jan 1 1970 register -rw-r--r-- 1 root root 0 Jan 1 1970 status
Once the interface have been mounted it is possible to register new executable file format by writing a special string like
$ echo ':foo:E::foo::/usr/bin/bar:' > /proc/sys/fs/binfmt_misc
Further details about binfmt_misc linux kernel extension at 
Devices are seen by processes as special files that are able to process specific I/O control calls as well as normal I/O transfers operations. UMdev is the service module that adds to UMview virtual device support.
Each virtual device is provided by UMdev submodules designed to provide the appropriate set of
ioctl. To load new virtual devices UMdev uses
mount system call and command. In this way UMdev gives to submodules the ability to define and attach to filesystem special files.
This submodule provides the ability to create virtual devices able to manage Master Boot Record (MBR) partition tables. Thus it is possible to mount real hard disk images to be seen as virtual devices accessible for read and write operations at user-level. Withing UMview, with umdev service module loaded it is possible to map a regular file to a special file to get it acting as a block device.
$ hexdump -C test.img 0000000 0000 0000 0000 0000 0000 0000 0000 0000 * 1388000 $ mount -t umdevmbr test.img test_hd
Now it is possible to manage partition table of
test_hd with tools like
fdisk and others. Once done it is possible to access device and partitions, create new filesystems or do any i/o control operation on them.
$ sfdisk -l test_hd Disk test_hd: 2 cylinders, 255 heads, 63 sectors/track Units = cylinders of 8225280 bytes, blocks of 1024 bytes, counting from 0 Device Boot Start End #cyls #blocks Id System test_hd1 0+ 1 2- 16033+ 83 Linux test_hd2 0 - 0 0 0 Empty test_hd3 0 - 0 0 0 Empty test_hd4 0 - 0 0 0 Empty
One primary partition have been created on test_hd. It is possible to make a new filesystem by accessing it as
$ mkfs.ext3 test_hd1 mke2fs 1.40-WIP (14-Nov-2006) Filesystem label= OS type: Linux Block size=1024 (log=0) Fragment size=1024 (log=0) 4016 inodes, 16032 blocks 801 blocks (5.00%) reserved for the super user First data block=1 Maximum filesystem blocks=16515072 2 block groups 8192 blocks per group, 8192 fragments per group 2008 inodes per group Superblock backups stored on blocks: 8193 Writing inode tables: done Creating journal (1400 blocks): done Writing superblocks and filesystem accounting information: done
This submodule of UMdev is used to create virtual ramdisk devices. As ramdisk devices provided optionally by linux this submodule takes a segment of the active system memory and makes it available as a virtual block devices, with the difference that withing umview it is possible to create new virtual ramdisks at user level.
$ um_add_service umdev $ mount -t umdevramdisk -o size=100M,mbr none test_rd $ /sbin/mkfs.ext2 test_rd [...] $ um_add_service umfuse $ mount -t umfuseext2 -o rw+ test_rd /tmp/mnt renzo@rd235:~$ ls /tmp/mnt lost+found $
Notice that in the mount options it is possible to specify ramdisk size and if the virtual device has to be able to manage a master boot record. In this case partitions creating will be allowed.
This module provides virtual tun/tap device interface. Currently under development.
UMdev test submodules
The virtual null device similar to linux
/dev/null is also available when
umdev service module is loaded. As usual a new virtual null device can be attached to filesystem via mount command. Notice that a debug message is emitted for each I/O request to the virtual null device.
$ mount -t umdevnull none null $ ls -l null crw------- 0 render render 0, 0 Jan 1 1970 null $ cat /dev/urandom > null null_open c 0 0 flag 8001 null_write c 0 0 len 4096 null_write c 0 0 len 4096 [...] null_write c 0 0 len 4096 null_write c 0 0 len 4096 null_release c 0 0 flag 0
This submodule is a simple example of ramdisk implemented as a character device. Once mounted a new special file representing the virutal device it is possible to make usual I/O operations like it was a real character device, up to 64 kilobytes.
$ mount -t umdevtrivhd none chardev $ dd if=/dev/urandom of=chardev 129+0 records in 128+0 records out 65536 bytes (66 kB) copied, 0.165209 seconds, 397 kB/s $ cat chardev | md5sum fe09c11f6a9d9e8d55fc7623ef026798 $ dd if=chardev of=chardev_content 128+0 records in 128+0 records out 65536 bytes (66 kB) copied, 0.17301 seconds, 379 kB/s $ md5sum chardev_content fe09c11f6a9d9e8d55fc7623ef026798
Adds to UMview virtual filesystems support. The name UMfuse comes from FUSE (Filesystem in userspace). The idea behind FUSE is the implementation of filesystem support in userspace. A filesystem implementation for FUSE is just a program that uses a specific interface provided by the FUSE library. When a filesystem implemented via FUSE is mounted every action to that filesystem is captured by a kernel module (developed for FUSE) and forwarded to the user level filesystem implementation.
UMfuse keeps the same interface of FUSE. Moreover, FUSE modules are source level compatible with UMfuse ones, with the only difference that UMfuse modules are dynamic libraries instead of a program which uses the FUSE library. Thus it is possible to compile a shared object from the same source code and obtain both FUSE and UMfuse modules with minor changes that enable UMfuse modules to manage several mounted filesystem at a time.
As usual the appropriate service module must be loaded into the UMview chain of services.
$ um_add_service umfuse
From now on every mount request starting with a umfuse prefix is forwarded to UMfuse that loads the appropriate library. The little example below shows how it is possible to mount an ext2 filesystem within a disk image mounted as a virtual block device.
$ mount -t umdevmbr hd_image.img /dev/disk $ sfdisk -l /dev/disk Disk /dev/disk: 2 cylinders, 255 heads, 63 sectors/track Units = cylinders of 8225280 bytes, blocks of 1024 bytes, counting from 0 Device Boot Start End #cyls #blocks Id System /dev/disk1 0+ 1 2- 16033+ 83 Linux $ mount -t umfuseext2 -o rw+ /dev/disk1 /mnt $ ls /mnt drwx------ 2 render render 12288 Jan 28 19:42 lost+found
- UMfuse supports two access control methods to the mounted filesystems. Default method known as Omnipotent Mode gives no restrictions to filesystem access: everything that is permitted by the UMfuse filesystem implementation is permitted to the user.
- The other access method is called Human Mode. When working in this mode (enabled via mount options) a permission check is done before proceeding with system calls on the filesystem. Default user and group IDs are those of the user running UMview but they can be overridden using
gidat mount time.
$ mount -t umfuseext2 -o human,rw+ /dev/disk1 mnt/ UmFUSE Human mode
ViewFS is a module that supports filesystem reorganization. Its main features are:
- Possibility to hide files, directories and hierarchies.
- Moving files and directory without affecting the real underlying filesystem
- Permissions redefinition
- Copy-on-write access to files, and directories to allow write access to read-only entities.
- Merging of real and virtual directories.
With ViewFS allow the user to give to processes a new view of the filesystem that is made of some kind of patchwork of tiles taken from existing filesystems. Possible applications are unlimited since almost everyting in linux operating system can be represented via filesystem interface.