Subject: Cloning Devices
To: None <tech-kern@netbsd.org>
From: Christos Zoulas <christos@zoulas.com>
List: tech-kern
Date: 12/01/2004 20:36:00
Many people have been asking about cloning devices, so here's a small
explanation on what they are and how they work. This is just a brief
overview and improvements are welcome.

christos

Cloning Devices in NetBSD

Cloning devices are devices that return a new device instance when they
are opened (a clone). Cloning is useful because:

1. An admininistrator does not need to create numbered devices a-priori
   in /dev and allocate a fixed number of device structures in the kernel.
   The number of devices is dynamic, so memory is not used and devices are
   created and destroyed as needed.
2. An application does not need to scan /dev to find an unused instance of
   a device.
3. The kernel code becomes simpler because locking is not necessary to access
   instances of the device, and races are eliminated during the creation and
   conditioning of the device for use.
4. It allows open to mutate to a specific file descriptor (used for /dev/fd
   and portalfs)

Devices that do cloning in the NetBSD kernel are as of this writing:
   - bpf 	The Berkeley Packet Filter
   - gif,tun,etc. Networking devices
   - ptm,ptmx	The Pseudo Tty Multiplexor
   - systrace	The system call access control device
   - dmoverio	The data mover pseudo-devide
   - crypto	The Cryprographic Pseudo device
   - ip,tcp,udp,rawip	Network access socket creation devices in compat/svr4

Devices that have fixed count of instances and could be converted to cloners:
   - fss	The File System Snapshot device
   - md 	Not a cloner, should really not need count.
   - tb         Tablet
   - loop       Network Loopback
   - ppp        Point to Point Protocol
   - sl         Serial IP Protocol
   - strip      Starmode Radio IP
   - ippp       ISDN device
   - irip       ISDN device
   - isdnbchan  ISDN device
   - isdntel    ISDN device
   - isdntrc    ISDN device
   - fwiso      ISDN device

All of those can be easily converted; in fact there are patches for ppp
and loop already written.

Of the cloner devices, there are two kinds:
   - Those which needs device node instances and need to be present in
     the filesystem, so that once they are created can be opened/accessed
     from other programs (/dev/pts/N)
   - Those which just kernel data structures and are accessible only by
     the creator application.

To create a cloner device, the device open routine, needs to construct
a new file descriptor, set l_dupfd to it and return either EDUPFD, or
EMOVEFD depending if it wants to close the original instance or not.
The fdclone(9) function handles the common case of an open that uses
falloc(9) and then specifies a set of fileops to be used for that file
descriptor. Most cloning devices that do not require filesystem access/
presence use this technique.

Networking cloning devices, use the if_clone structure to specify
the <dev>_clone_create() and the <dev>_clone_destroy() methods.

Devices that need to mutate file descriptors (portal /dev/fd), use
directly l_dupfd to set the file descriptor.

Finally ptys need to be accessed through the filesystem, and either
open an existing vnode (bsdpty /dev/[pt]tyXX) or a special ptyfs
filesystem that uses the vnode function switch to access the device
nodes.