Linux lsvpd design and implementation notes

Martin Schwenke

$Id: design.xml,v 1.5 2004/06/16 04:15:59 martins Exp $


Table of Contents

1. Introduction
2. Overall architecture
2.1. Data collection
2.2. Querying
3. Database structure
4. Implementation languages
4.1. bash
4.2. C
5. Modular design
5.1. Multiplexed functions
6. Legal Statement

1. Introduction

The Linux lsvpd package is a partial reimplementation, for Linux®, of some AIX® hardware inventory and configuration commands. The focus is on providing the same level of serviceability on IBM® pSeries® hardware as is provided by AIX. The main function is to list Vital Product Data (VPD) about hardware components, including systems, adapters and devices, in a variety of ways.

This documentation contains design and implementation notes for the Linux lsvpd package. This documentation is aimed at developers who are attempting to update the package. Installation notes are in a different document.

2. Overall architecture

Commands in the package belong to one of two categories: data collection (or scanning) and querying.

2.1. Data collection

Information about hardware is collected and stored in a database under /var/lib/lsvpd/db (formerly /var/lib/lsvpd/device-tree, with some supplementary information stored in other subdirectories of /var/lib/lsvpd). Currently there is only a single data collection command called update-lsvpd-db, which is invoked at boot time and can also be run manually at any time. update-lsvpd-db's main job is to construct linux,vpd files, containing VPD, for use by the querying commands.

It is assumed that under Linux 2.4 there will be no hotplug events that the lsvpd package needs to know about. Under Linux 2.6 this will change, so finer grain data collection will need to be implemented. Changes in the 0.9 and 0.10 releases should allow relevant commands to be implemented relatively easily.

2.2. Querying

The query commands find VPD and other information in the database and present it in a variety of formats. These commands include the following:

lsvpd
Lists VPD. The textual output format is both machine and human readable. This command is used by higher-level system management tools.
lscfg
Lists (hardware) configuration. The textual output format is designed for human consumption. The simplest type of output simply lists a subset of hardware components, and this output can be augmented with VPD. There is also a facility for outputting a platform-specific section.
lsmcode
Lists microcode and firmware levels. Can produce either a tabular, machine-readable format, or a human-oriented format. Doesn't have interactive menus like the AIX version.

3. Database structure

The database under /var/lib/lsvpd/db has two subdirectories: bus andlinux. The bus directory contains a bus view of the system's hardware, while the linux directory contains the operating system's view of adapters, devices and miscellaneous useful information. Devices and adapters are cross linked between the two directories. Supplementary information that used to be stored in (other) subdirectories of /var/lib/lsvpd is now stored in relevant directories of the adapters and devices.

On machines with an Open Firmware device-tree, such as pSeries, the bus directory contains the device-tree, augmented with linux,vpd properties (and cross-links).

On other machines with sysfs, the bus directory is populated with information from sysfs and then augmented as above.

4. Implementation languages

4.1. bash

The following observations and requirements influenced the choice of bash as the primary implementation language:

  • A lot of the work done by the lsvpd package is text processing. The shell, along with external commands, is very good at processing text.
  • lsvpd's hardware inventory database might be useful early in the boot sequence as part of a persistent device naming system or similar. The only scripting language that is generally available on a Linux root filesystem is the shell.
  • /bin/bash is the usual Linux shell, and contains useful features, such as built-in arithmetic operations and a certain amount of string handling. It also has many commonly used commands built-in.

4.2. C

Helper utilities that can't be implemented in bash, and are not otherwise available, are implemented in C. This allows small, efficient executables to be produced, which is appropriate for certain early-boot environments, such as in an initramfs.

5. Modular design

The main commands in the lsvpd package, written in bash, are written in a modular manner. This allows their complexity to be more easily managed and allows features to be added depending on (possibly architecture-dependent) operating system features and availability of other commands or packages.

There are several subdirectories of modules:

common.d
Contains modules available to all commands.
scan.d
Contains modules used during data collection, currently just the update-lsvpd-db command.
query.d
Contains modules used by all of the query commands.
lsvpd.d, lscfg.d, lsmcode.d
Each of these directories contains modules used by the associated query command.

At the simplest level, modules work by redefining shell functions that are defined in previously loaded modules. Default modules contain stubs or versions of functions with minimal functionality. Modules that are loaded later may then define more sophisticated versions of those functions, depending on the available functionality.

5.1. Multiplexed functions

To avoid a plethora of case statements, a function multiplexing scheme has been implemented. A multiplexed function is declared like this:

	  make_multiplexed do_device
	

Initially, this causes any calls to this function, such as

	  do_device scsi /dev/sg0
	

to fail silently, since the do_device function has been declared but not defined.

Subsequent modules can then define individual implementation functions that are called according to the first argument that is passed to do_device. For example, if an implementation called do_device_scsi is defined, it will be called when the first argument is scsi, as in the above example. If the first argument does not coincide with a defined implementation, then the implementation do_device_DEFAULT will be called, if it is defined. Otherwise silent failure occurs. This allows modules to incrementally introduce functionality for different device types.

Note that if a module wishes to replace a number of implementations with a ..._DEFAULT implementation, it will also need to use set -f to remove unwanted implementations. Alternatively, if a module is able to provide all implementations using a single function, then it can simply define a new do_device function and completely override the multiplexing.

6. Legal Statement

  • This work represents the view of the author and does not necessarily represent the view of IBM.
  • Linux is a registered trademark of Linus Torvalds.
  • IBM, AIX and pSeries are trademarks or registered trademarks of International Business Machines Corporation in the United States and/or other countries.
  • Other company, product, and service names may be trademarks or service marks of others.