Difference between revisions of "Device API"

From The Open Source Backup Wiki (Amanda, MySQL Backup, BackupPC)
Jump to navigationJump to search
(Developer's documentation.)
Line 46: Line 46:
  
 
== Programmatic Interface ==
 
== Programmatic Interface ==
The Device API is implemented in the <tt>device-src/</tt> directory. It relies heavily on GLib's type system, so developers unfamiliar with the GObject system are encouraged to consult the relevant [documentation | file:///home/vectro/reference/gobject/index.html]
+
The Device API is implemented in the <tt>device-src/</tt> directory. It relies heavily on GLib's type system, so developers unfamiliar with the GObject system are encouraged to consult the relevant [http://developer.gnome.org/doc/API/2.0/gobject/index.html documentation]
  
 
Broadly speaking, the C interface revolves around a single glib virtual class -- Device -- which is actually implemented as one of many possible subclasses. The current class hierarchy of implemented devices looks like this:
 
Broadly speaking, the C interface revolves around a single glib virtual class -- Device -- which is actually implemented as one of many possible subclasses. The current class hierarchy of implemented devices looks like this:
Line 62: Line 62:
  
 
=== Properties Interface ===
 
=== Properties Interface ===
Most code related to device-independent properties is in <tt>property.h</tt> and <tt>property.c</tt>. Since property values are passed around as a [GValue | file:///home/vectro/reference/gobject/gobject-Generic-values.html], all value types must be registered in the GLib
+
Most code related to device-independent properties is in <tt>property.h</tt> and <tt>property.c</tt>. Since property values are passed around as a [http://developer.gnome.org/doc/API/2.0/gobject/gobject-Generic-values.html GValue], all value types must be registered in the GLib

Revision as of 00:43, 30 August 2006

The Device API is designed to replace the ancient tapeio subsystem (sometimes called the vtape API or Virtual Tape API), originally introduced to support virtual tapes. The Device API clears up a large number of limitations and device assumptions that the tapeio system made, allowing native support for new devices (such as CDs and DVDs) as well as new device-related functionality (such as parallel access, partial recycling, and appending).

The Device API does not change (or even address) media formats. It is not itself a user-visible change, though it enables many user-visible features.

History

The original design of the tapeio system (located in tape-src/) was to abstract tape-related functionality into a separate library. Thus, different devices (tape, vtape and RAIT) were all phrased in terms of tape operations: Rewind, fast-forward, read a block, etc. Operations were assumed to have the same semantics as a UNIX tape device. Furthermore, the API revealed a file descriptor, with the assumption that other parts of Amanda could perform operations such as stat() or dup2() on it.

Limitations of tapeio

Important limitations inherent in the design of tapeio include:

  • Exposes a UNIX file descriptor
  • Operates in terms of UNIX operations
  • Does not store information in a portable (yet device-specific) way.
  • Not reentrant: Access to the device is not permitted from multiple threads or processess.
  • Assumes devices can be opened and closed at will.
  • RAIT driver performs operations in series (rather than parallel).

Operations

Tapeio included the following operations:

  • tape_access(), tape_open(), tape_stat(), tapefd_close(), tapefd_read(), tapefd_write(): Act like their UNIX equivalents
  • tapefd_rewind(), tapefd_unload(): Do what you expect.
  • tapefd_fsf(): Seeks forward a certain number of filemarks.
  • tapefd_weof(): Writes a filemark.
  • tapefd_resetofs(): Workaround for some buggy kernels.
  • tapefd_status(): Prints status to stdout (!).

In addition, all tapefd_ commands have matching tape_ commands, which work on an unopened device.

Device API Features

In addition to relieving the limitations of the tapeio system discussed above, the Device API also adds a number of new features. These include:

  • Device properties allow drivers to describe themselves (and the devices and media they control), as well as allow arbitrary user settings to propagate down to the driver.
  • Smart locking means unrelated accesses can be performed without issue, while conflicting accesses wait for one another.
  • Appending to volumes is supported for able devices.
  • A device can describe its supported blocksize range to the Amanda core, instead of the other way around.
  • Deleting parts of volumes (without erasing the whole thing) is supported for able devices.
  • The amount of free disk space can be reported to the Amanda core.

Properties

The Device API includes a number of standard properties, and allows devices to declare and register other custom properties as may be appropriate. Standard properties include:

  • Concurrency: Does the device support concurrent readers and/or writers?
  • Streaming: Does the device require (or desire) streaming data?
  • Compression: Does the device support it, and what compression rate has been yielded.
  • Blocksize: What block size(s) are supported by the device? This property is settable for devices that support a variety of block sizes, or can be left unset for variable block size.
  • Device UUID: Returns a unique identifier for this piece of hardware.
  • Media access mode: What is the access paradigm for this volume? Can be Read-Only, Write-Once-Read-Many (WORM), Read-Write, or Write-Once-Read-Never.
  • Feature support: Does the device support partial deletion or appending to volumes?

Programmatic Interface

The Device API is implemented in the device-src/ directory. It relies heavily on GLib's type system, so developers unfamiliar with the GObject system are encouraged to consult the relevant documentation

Broadly speaking, the C interface revolves around a single glib virtual class -- Device -- which is actually implemented as one of many possible subclasses. The current class hierarchy of implemented devices looks like this:

GObject
+ Device
+ RaitDevice
  + NullDevice
  + FdDevice
    + TapeDevice
    + VfsDevice

One can obtain a Device by calling the factory function for the particular device manually, but the best way is just to call device_open() with a device name. It returns a device of the right type for the given name.

Properties Interface

Most code related to device-independent properties is in property.h and property.c. Since property values are passed around as a GValue, all value types must be registered in the GLib