This document is meant to help both packagers and individuals wishing to install vdev from source do so as painlessly as possible. However, the reader is expected to have basic command-line proficiency, familiarity with their bootloader of choice, and familiarity with installing and removing system services.
The steps in this document are lightly tested, and are **specific to Debian and Devuan**. Please report bugs to the Devuan mailing list, or to `firstname.lastname@example.org`.
Step 1: Compile and Install vdev
The steps to check out, compile and install vdev, libudev-compat, and host-specific configuration files to your root partition are as follows. These steps will disable udevd and libudev, and make it so vdevd and its libraries are used in place of it.
**WARNING:** These steps will disable udev. If vdev does not work correctly for you, you are expected to know how to restore udev.
**BEFORE RUNNING THESE COMMANDS:** You will need to back up your copies of `libudev.so.*` from udev. They are often found in the **multiarch /lib** (such as `/lib/x86_64-linux-gnu/`). You should move them out of your linker's search path, so libudev-linked software will use libudev-compat's `libudev.so.*` files (moving them to a directory on your root partition, like `/lib/libudev.bak/`, should be fine). The instructions below install libudev-compat's `libudev.so.*` files to `/lib` to avoid accidentally overwriting udev's `libudev.so.*` in the multiarch `/lib` directory.
$ git clone https://github.com/jcnelson/vdev
$ cd vdev
$ make -C vdevd PREFIX=
$ sudo make -C vdevd install PREFIX=
$ make -C libudev-compat PREFIX= INCLUDE_PREFIX=/usr
$ sudo make -C libudev-compat install PREFIX= INCLUDE_PREFIX=/usr
$ sudo update-rc.d udev disable
$ sudo update-rc.d udev-finish disable
$ make -C example PREFIX=
$ sudo make -C example install PREFIX=
As a result of these commands, you will have installed `vdevd` to `/sbin/vdevd`, vdev's helpers to `/lib/vdev/`, vdev's host-specific configuration to `/etc/vdev/`, vdev's System V init script to `/etc/init.d/`, and libudev-compat to `/lib/libudev.so.1.5.2`.
**AFTER RUNNING THESE COMMANDS:** You will need to restart any software that was using `libudev.so.1*`. This includes the X server in most cases. Use `lsof(8)` to find a full listing. You can ignore any software that uses `libudev.so.0*` (such as Chrome and Chromium).
Step 2: Generate an Initramfs
To boot with vdev in an initramfs, you must additionally generate an initramfs image that contains it. This can only be done after vdev has been installed to your root partition.
$ make -C example initramfs
The initramfs image file will be generated under `example/initrd.img-$KERNEL_VERSION`, where `$KERNEL_VERSION` is the build host's running kernel version (i.e. from `uname -r`).
Step 3: Install the Initramfs
**BEFORE YOU DO ANYTHING:** You should ensure that you will be able to recover if this initramfs does not boot for you. This usually involves ensuring that your bootloader always has a valid entry to a vanilla initramfs image. With GRUB2, you can test the vdev initramfs without installing it. Simply copy it to `/initrd.img.vdev`, reboot, edit your boot script, and replace the path to the given initrd with `/initrd.img.vdev`.
Once the initramfs image has been generated and you're comfortable with it, you must configure your bootloader to use it. The steps to do so are bootloader-specific. For GRUB2, this can be achieved simply by copying the image file into `/boot` and running `sudo update-grub2`.
**WARNING:** Be sure to back up your old initramfs image first!
**WARNING:** Be sure you know how to boot from the backed-up initramfs image if this one does not work!
Copyright (c) 2014, Jude Nelson (email@example.com) et al.
Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
**This system is mothballed. It's usable if you know what you're doing--I've been using it for years on my laptop without issues--but it's not for typical users. Expect to get your hands dirty.**
**I do not have time to work on it in the foreseeable future, nor do I have time to answer support requests.**
Vdev is a portable userspace device-file manager for UNIX-like operating systems. It differs from existing device-file managers in that it provides an optional filesystem interface that implements a *per-process view of /dev*, thereby giving the host administrator the means to control device node access based on arbitrary criteria (such as process session ID, process seat assignment, etc.).
The Linux port of vdev aims to be a drop-in replacement for udev.
More information is available in the [design document](http://judecnelson.blogspot.com/2015/01/introducing-vdev.html).
* **Portable Architecture**. Vdev is designed to be portable across (modern) *nix. It can interface with both the kernel and synthetic device event sources, including another vdev instance, or an existing `/dev` tree. It can also be statically linked and can compile with multiple libc's.
* **Event-driven**. Vdev's core logic is built around reacting to events from its back-end event source. It creates and removes device files and metadata in response to devices being plugged in or unplugged.
* **Scriptable**. Vdev aims to keep device management policy and mechanisms as separate as possible. It offers an easy-to-understand programming model for matching a device event to a sequence of administrator-defined programs to handle it.
* **Advanced Access Control**. Vdev comes with an optional userspace filesystem that lets the administrator control how individual processes see the files under `/dev`. The criteria are programmatically selected and thus arbitrary--*any* process information can be used to control access.
* **Container Friendly**. Vdev can run in containers and chroots, and offers the administrator an easy-to-understand way to restrict, filter, and modify the device events the contained vdevd will observe. Importantly, the Linux port of vdev does *not* rely on netlink sockets to propagate events to client programs.
* **Sensible, Backwards-Compatible Defaults**. Vdev comes with a reference configuration and set of helper programs that make it usable out-of-the-box, with no subsequent tweaking required. The Linux port is a drop-in replacement for udev: it generates an equivalent `/dev` tree, as well as an equivalent `/run/udev` tree. It also ships with a "libudev-compat" library that is ABI-compatible with libudev 219. Libudev-linked software such as the X.org X server can use vdev and libudev-compat without recompilation. In addition, the Linux port interoperates with but does not depend on the `devtmpfs` filesystem.
* **Init system integration**. Vdev is meant to run with full functionality regardless of which init system, daemon manager, service manager, plumbing layer, etc. the user runs, since they address orthogonal concerns. It will coexist with and complement them, but neither forcibly replace them nor require them to be present.
* **New client libraries, language bindings, or Dbus APIs**. Vdev will exprose all of the necessary state and device metadata via the /dev filesystem directly. Any wrappers that present this information via higher-level APIs (such as libudev) will be supported only to provide backwards compatibility.
There are two binaries in vdev: the hotplug daemon vdevd, and the userspace filesystem vdevfs. You can use one without the other. **If you only intend to replace udevd, you can ignore vdevfs.**
Vdevd comes with a set of scripts that provide udev compatibility for the Linux port, and these scripts make use of the following packages. Vdevd's scripts can work without them, but some functionality will be missing:
Vdev's libudev-compat library removes the netlink connection to udev in favor of creating and watching a process- and `udev_monitor`-specific directory, which vdevd's helper scripts discover and use to send serialized device events by writing them as files. It is highly recommended that users install [eventfs](https://github.com/jcnelson/eventfs) and use it to host libudev-compat's event directories. Eventfs is optimized for this use-case--it will ensure that libudev-compat's directories are backed by RAM, easily accessed in FIFO order, and automatically removed once the libudev-compat process that created them exits.
By default, everything installs under `/usr/local`. To build and install everything with default options, run:
$ sudo make install
To build and install vdevd (with no configuration) to `/usr/local/sbin`, type:
$ make -C vdevd OS=$OS_TYPE
$ sudo make -C vdevd install
Substitute `$OS_TYPE` with:
* "LINUX" to build for Linux (the default value)
* "OPENBSD" to build for OpenBSD (coming soon)
`$OS_TYPE` defaults to "LINUX".
To build and install vdevd's default recommended configuration to `/usr/local/etc`, type:
$ make -C example
$ sudo make -C example install
To build and install vdevd's hardware database to `/usr/local/lib`, type:
$ make -C hwdb
$ sudo make -C hwdb install
To build and install libudev-compat to `/usr/local/lib/` and its headers to `/usr/local/include`, type:
$ make -C libudev-compat
$ sudo make -C libudev-compat install
To build and install vdevfs to `/usr/local/sbin/`, type:
$ make -C fs
$ sudo make -C fs install
You can override the installation directories at build-time by setting the `PREFIX` variable on the command-line (e.g. `make -C vdevd PREFIX=/`), and you can specify an alternative installation root by setting `DESTDIR` at install-time (e.g. `sudo make -C vdevd install DESTDIR=/opt`). You can also control where header files are installed by setting the `INCLUDE_PREFIX` variable (e.g. `make -C libudev-compat install PREFIX=/ INCLUDE_PREFIX=/usr`).
Replacing udev on Linux
If you want to replace udev with vdev, it is recommended that you install the binaries to your root partition and the libudev-compat headers to `/usr`. This is done by setting `DESTDIR= PREFIX= INCLUDE_PREFIX=/usr` when installing.
If you have an initramfs and rely on udevd during early boot, you will need to rebuild your initramfs so it will start vdevd instead. If you are installing on Debian or Devuan, please first read Appendix B of the [how-to-test.md](https://github.com/jcnelson/vdev/blob/master/how-to-test.md) document, since it contains instructions on how to install vdevd's init script and rebuild your initramfs via the Debian/Devuan initramfs tools.
**If you are replacing udev and libudev, you should back up their init scripts, header files, and libraries before installing vdev. You may need to revert to them if vdev does not work for you.**
* **Why another device manager?** I want to control which processes have access to which device nodes based on criteria other than their user and group IDs. For example, I want to filter access based on which login session the process belongs to, and I want to filter based on which container a process runs in. Also, I want to have this functionality available on each of the *nix OSs I use on a (semi-)regular basis. To the best of my knowledge, no device manager lets me do this (except perhaps Plan 9's per-process namespaces), so I wrote my own.
* **What is the license for vdev?** Vdev code is available for use under the terms of either the [GPLv3+](https://github.com/jcnelson/vdev/blob/master/LICENSE.GPLv3%2B) or [ISC license](https://github.com/jcnelson/vdev/blob/master/LICENSE.ISC). However, the Linux port of vdev ships with some optional Linux-specific [helper programs](https://github.com/jcnelson/vdev/tree/master/vdevd/helpers/LINUX) that were derived from udev. They are available under the terms of the GPLv2 where noted in the source files.
* **Which Linux distributions are you targeting?** Vdev is distro-agnostic, but I'm developing and testing primarily for [Debian](http://www.debian.org) and [Devuan](http://devuan.org).
* **Which BSDs/other UNIXes are you planning to support?** OpenBSD for now. Well-written, suitably-licensed pull requests that port vdev to these or other UNIX-like OSs will be gratefully accepted.
* **Does this project have anything to do with systemd and udev merging?** It's not strictly related, but the pending merger definitely motivated me to start this project sooner rather than later. I hope vdev's existence will help alleviate the tension between the pro- and anti-systemd crowds:
* Linux users who don't want to use systemd can run vdev in place of udev.
* Linux Users who prefer some other device manager besides udev or vdev but need to run software that depends on libudev can use libudev-compat (vdev's udev-compatibility helper programs are easily portable to other device managers).
* Linux developers who need fine-grained device access controls but don't want to couple their software to systemd will have vdevfs as a portable, easy-to-use alternative.
* Linux users do not need to choose between systemd and vdevfs, since they can coexist.
* The systemd developers can tightly couple udev to systemd-PID-1 if they want, since non-systemd users will have an alternative.