NVRAM Module
Logo Image
Phase 1 Rewrite

2 Modularization

Modularizing NVRAM means that the code is cleanly divided into four hierarchical layers where functionality is not shared outside of the layers, where dependencies are forwarded from top to bottom, and where interactions with the layers are confined to well defined API's. Though this requires a certain amount of reorganization of the current implementation, the goal is to keep the same high level architecture while recoding data structures and reimplementing functions where necessary.

2.1 Module Layers

The NVRAM layer is the heart of the new implementation and it controls initialization and access to the non-volatile memory files, i.e. startup config, private config, persistent data, etc. It declares a new access-node structure list and passes list item pointers to the lower layers. It sits below the API layer which is divided into two sub-layers: the legacy API which are wrapper functions that allow access to NVRAM by the current code base without changes, and the NVRAM API which is a set of functions that implement the new features.
 
The Media layer sits below the NVRAM layer and is the reimplementation of the current "ifs" code that provides file services to the many types of storage media supported by the IOS.

 NVRAM is fundamentally different from other types of storage in that it is limited, local and non-removable memory used for specialized data. For this reason it will have it's own version of the drivers, and NVRAM will be modular enough to support different types of media drivers. Note that in all cases the functionality of a media type will include managing a pool of memory blocks. In some cases the pool can be used to distribute physical memory usage for devices that have a limited number of write cycles.

The Media layer is accessed, and makes accesses, through well defined API's, and all dependencies resolve to higher layers.

The Platform drivers are currently modularized and are accessed by the "ifs" code through a vector table. This code is commonly used throughout the IOS and will not be changed. 
NVRAM Layers

2.2 Implementation Phases

The reimlementation of NVRAM can be done in phases by coding, testing and committing the layers separately. Phase one will consist of the new NVRAM and API layers, with some small supporting changes to the media layer. Phase two will be a full Media layer implementation. As stated earlier, the Platform layer already exists as a clean module and so will not be reimplemented.

2.3 Managing Dependencies

The architecture of dependencies between layers is a uni-directional hierarchy that forwards dependencies from top to bottom. In practice this means that the lower layers "include" references from higher layers but never the other way around. If a higher layer needs something that's defined below, it must define a common structure and pass it to a "callback" function that was previously initialized, and which will pass the info back through the common data structure.

Structure pointers will appear opaque to lower layers where they are declared but not defined, and local elements can be hidden from the upper layers by passing void pointers which are cast to reveal only the elements that are relevant to the higher layer, i.e. overloading.

Using these simple techniques will keep dependencies from "pointing" in the wrong direction and help to enforce the boundaries defined by the API's. 

2.4 Backward Compatibility

Trying to implement a new architecture while maintaining current functionality greatly increases the archetecture's complexity and quickly overwhelms an attempt to move the code base forward. One solution is to abandon the need to be fully backwards compatible and instead provide a migration path between versions.

With respect to NVRAM, the compatibility issue is primarily one of moving the stored data between different memory maps. What this means is that NVRAM must be converted to the old memory map before the earlier IOS version can be loaded. The procedure is not difficult, but it's also not intended to be a feature. Normal migration is forward to a newer IOS, and backward migration should only be used if the need arises to revert to a version that uses the old memory map. 

Conversely, the new implementation should be able to read both versions of NVRAM, with the old memory map having it's currently limited functionality. This allows for a grace period after migration in which to establish confidence in the new IOS version before converting to the new memory map.

Note that memory mapping persists across IOS reloads, and that the versions of any default or secondary images should include the new NVRAM implementation to prevent the case where the old default image tries to read the new map. In such a case the startup config may be fine but the private config and persistent data would appear corrupted.
 
[ Prev Section : 1
[ Contents ]
[ Next Section : 3 ]