Function crate_swap::swap_crates

source ·
pub fn swap_crates(
    this_namespace: &Arc<CrateNamespace>,
    swap_requests: SwapRequestList,
    override_namespace_dir: Option<NamespaceDir>,
    state_transfer_functions: Vec<String>,
    kernel_mmi_ref: &MmiRef,
    verbose_log: bool,
    cache_old_crates: bool
) -> Result<(), &'static str>
Expand description

Swaps in new crates that can optionally replace existing crates in this CrateNamespace.

See the documentation of the SwapRequest struct for more details.

In general, the strategy for replacing an old crate C with a new crate C2 consists of three steps:

  1. Load the new replacement crate C2 from its object file.
  2. Copy the .data and .bss sections from old crate C to the new crate C2
  3. Set up new relocation entries that redirect all dependencies on the old crate C to the new crate C2.
  4. Remove crate C and clean it up, e.g., removing its entries from the symbol map. Save the removed crate (and its symbol subtrie) in a cache for later use to expedite future swapping operations.

The given CrateNamespace is used as the backup namespace for resolving unknown symbols, in adddition to any recursive namespaces on which this namespace depends.

Upon a successful return, this namespace (and/or its recursive namespace) will have the new crates in place of the old ones, and the old crates will be completely removed from this namespace. In this namespace there will be no remaining dependencies on the old crates, although crates in other namespaces may still include and depend upon those old crates.

Arguments

  • swap_requests: a list of several SwapRequests, in order to allow swapping multiple crates all at once as a single “atomic” procedure, which prevents weird linking/relocation errors, such as a new crate linking against an old crate that already exists in this namespace instead of linking against the new one that we want to replace that old crate with.
  • override_namespace_dir: the directories of object files from which missing crates should be loaded. If a crate cannot be found in this directory set, this namespace’s directory set will be searched for the crate. If None, only this CrateNamespace’s directory set (and its recursive namespace’s) will be used to find missing crates to be loaded.
  • state_transfer_functions: the fully-qualified symbol names of the state transfer functions, arbitrary functions that are invoked after all of the new crates are loaded but before the old crates are unloaded, in order to allow transfer of states from old crates to new crates or proper setup of states for the new crates. These function should exist in the new namespace (or its directory set) and should take the form of a StateTransferFunction. The given functions are invoked with the arguments (current_namespace, new_namespace), in which the current_namespace is the one currently running that contains the old crates, and the new_namespace contains only newly-loaded crates that are not yet being used. Both namespaces may (and likely will) contain more crates than just the old and new crates specified in the swap request list.
  • kernel_mmi_ref: a reference to the kernel’s MemoryManagementInfo.
  • verbose_log: enable verbose logging.

Warning: Correctness not guaranteed

This function currently makes no attempt to guarantee correct operation after a crate is swapped. For example, if the new crate changes a function or data structure, there is no guarantee that other crates will be swapped alongside that one. It will most likely error out, but this responsibility is currently left to the caller.

Crate swapping optimizations

When one or more crates is swapped out, they are not fully unloaded, but rather saved in a cache in order to accelerate future swapping commands.