DeviceNamespace:Patches

Amir Goldstein edited this page Sep 8, 2013 · 3 revisions

Table of contents:


Overview of device namespace patches

The device namespace patches can be divided into 3 groups: framework, traditional virtualization, and context-aware virtualization.

[1] Device namespace - framework patches

  • device namespace framework and housekeeping
  • handling of active device namespace and switching
  • helpers and macros to help device driver authors make their code device namespace-aware
  • API for userspace to illustrate how to control device namespaces configuration and behavior
 dev_ns: introduce device namespace

[2] Device namespaces - traditional virtualization

  • add traditional virtualization to devices to make them namespace-aware
  • demonstrate how device driver authors can use the device namespace framework
 dev_ns: adopt the android binder driver
 dev_ns: adopt the android alarm-dev driver
 dev_ns: adopt the android logger driver

While all three sample devices are Android-specific, there are other Linux-generic devices that require namespace virtualization. Examples include logical devices such as the block loop device and the device mapper. Another example is the RTC device which, similar to the Android alarm-dev, should be virtualized to allow each device namespace to have a separate view of time.

Note: We chose to include Binder device here, rather than as part of IPC namespace, as we intend the device namespace to serve as a generic framework for this purpose. This choice can be revisited later.

[3] Device namespaces - context-aware virtualization

  • add context-aware virtualization to input/output devices to support active namespace
 dev_ns: adopt the input subsystem
 dev_ns: adopt the framebuffer subsystem
 dev_ns: adopt the LED subsystem
 dev_ns: adopt the backlight/lcd subsystem

With the foreground/background persona model, a user interacts only with active personas. Only processes in active (foreground) can send/receive updates to/from output/input devices. Processes in non-active (background) personas do not send updates to output devices and do not receive updates from input devices.

Some devices are relatively stateless, and primarily care about whether requests originate in an active persona (namespace) or not - and behave accordingly. For example, LED and backlight devices currently respect only state-change requests from processes in an active persona, but ignore such requests from non-active personas.

Conversely, some devices (or subsystems) need to maintain a device virtual state, in addition to the physical state, to reflect the state viewed by processes in non-active personas and accommodate their actions thereof. Examples include the input and the framebuffer subsystems.

Where possible, virtualization and multiplexing is implemented at the subsystem level, e.g. like the input and the framebuffer, so that it applies to a wide range of underlying devices.

How to apply and compile the patches

The device namespace patches are available in the devns-patches repository (managed using guilt/quilt).
The patches are based on Android emulator kernel android-goldfish-3.4 branch.
For convenience, the patches are already applied in the devns-goldfish-3.4 branch.

To download the kernel sources with the device namespace patches applied:

  git clone -b devns-goldfish-3.4 https://github.com/Cellrox/linux.git

Alternatively, you can download the base Android goldfish-3.4 kernel as well as the device namespace patches, and apply manually:

  # clone the repositories
  git clone -b android-goldfish-3.4 https://github.com/Cellrox/linux.git
  git clone https://github.com/Cellrox/devns-patches.git
  # create a branch and apply patches
  cd linux
  git checkout -b devns-goldfish-3.4
  git quiltimport ../devns-patches

Before compiling, you need to turn on the following kernel config options:

  # config options for device namespaces
  CONFIG_NAMESPACES=y
  CONFIG_PID_NS=y
  CONFIG_DEV_NS=y
  CONFIG_FB_DEV_NS=y
  CONFIG_FB_DEV_NS_PAN=y
  # CONFIG_FB_DEV_NS_DEBUG is not set

It is also recommended to turn on the remaining namespaces too:

  # config options for namespaces
  CONFIG_UTS_NS=y
  CONFIG_IPC_NS=y
  CONFIG_USER_NS=y
  CONFIG_NET_NS=y
  # and also
  CONFIG_DEVPTS_MULTIPLE_INSTANCES=y

Finally, compile the kernel, e.g.:

  make -j4

How to use device namespaces API

The device namespaces API currently includes two knobs in /proc/dev_ns:

  • /proc/dev_ns/active_ns_pid - get or set the active device namespaces, as identified by the pid of the init process in that namespaces. When setting the active namespace, a pid of any process from the target namespaces will suffice. (Note: said pids are interpreted in the root pid-namespace). Examples:
  $ echo `pidof prog` > /proc/dev_ns/active_ns_pid   # switch to namespace of prog
  $ echo 1 > /proc/dev_ns_active_ns_pid              # switch to root namespace
  • /proc/dev_ns/ns_tag - get or set the tag of a device namespace. The tag is at most 4 characters long, and is used in Android's logger device to denote the origin namespace of log messages. The write operation expects the string "pid:TAG", and sets the tag for pid. The get operation outputs information about the active namespaces: the pid of the init process, the timestamp of the last switch to it, and its tag". Examples:
  $ echo `pidof prog`:demo > /proc/dev_ns/ns_tag     # set the tag of the namespace of prog to "demo"
  $ echo 1:init > /proc/dev_ns/ns_tag                # set the tag of the root namespace to "init"
  $ cat /proc/dev_ns/ns_tag                          # show pid, timestamp, tag of the active namespace
  active: 1 timestamp: 0 tag: init
Note:
the proposed API is simple and easy for proof-of-concept purposes. We expect the API to be reviewed in light of different use-cases and future needs and change accordingly. At the very least it will be removed from /proc to /sys.

A demo of device namespaces on Android

We present an uber-simplified demo use case of device namespaces. The demo uses a secondary device namespace on an Android phone to place the phone "on hold" while the screen alternates among a delightful palette of colors. Visually it looks likes a mere screensaver, but unlike a screensaver, While this appears visually as a mere screensaver, in practice the phone itself is switched to a non-active namespace and does not have access to any physical device.

We provide this use case with the hope that it will serve as sample code for other uses of device name spaces. We will be glad to here about other exciting use cases and refer them from this site.

The demo works by creating a secondary device namespace to run a program that displays the palette. Upon request, it switches to the secondary namespace, and then listens to input events to perform a switch back to the primary namespace. The primary namespace, which runs Android, continue to operate even when the namespace is non-active, but does not generate physical output nor receives any input.

How to get the demo:
The demo git repository is available at: https://github.com/Cellrox/devns-demo.git. For detailed instructions, see the README file there.
(Note: this demo was made for AOSP 4.2.2 emulator, goldfish/goldfish-x86).

Enjoy exploring device namespaces!

Device namespaces TODO

We plan to work closely with the Linux kernel community to improve the device namespace patches and get them ready for submission to mainline kernel.

Cellrox developers Oren Laadan and Amir Goldstein will be attending the LPC 2013 Containers track to present the device namespaces work and discuss the best course to proceed.

A partial list of items to be discussed:

  • review the dev_ns framework in light of existing and future devices that need namespace-awareness.
  • review the dev_ns userspace ABI with respect to existing and future use-cases
  • device namespace case study for logical drivers (e.g. loop, dm) virtualization
  • device namespace case study for uevent virtualization
  • required device namespace changes to drivers core code (e.g. ns of virtual loop0?)
  • should there be more than a single active devns?
  • should there be a CLONE_NEWDEV flag?