Skip to content.

Personal tools
You are here: Home » 技術文書 » パターン » パターンMulti-Phase Startup(英語)

Document Actions

Multi-Phase Startup
Ver 2.1 - 1999,12/12
translated into English - 2001,8/28

Eiwa System Management, Inc.
Ver 1.0 1999,3/16
Ver 2.0 1999,6/16
Ver 2.1 1999,12/12
Ver 2.1-e 2001,8/28


Start up a system with subsystems which are dependent of one another.


bootstrap, run level, One Two Three!


Consider the startup procedure of realtime systems or operating systems. The system is composed of a number of subsystems and the subsystems are dependent of one another. Because of the dependency, it is impossible to sequentially start up one subsystem completely after another.

In this situation, you have to divide the subsystems' services into several phases(levels) and establish an arrangement over all the subsystems, so you can start up the whole system gradually in order.

But the procedure is usually complicated and the arrangement of the startup order requires detail information of all the subsystems. Besides, some startup order may lead the system into a deadlock.

The idea is, instead of dividing each subsystem's state into only two state(active/inactive), to introduce intermediate state(s). During the startup procedure, first, start up the subsystems into the intermediate state, and then, start up them into the final active state. Introducing sub levels for bootstrapping can avoid the problem of mutual-dependency and deadlock. If you introduce several intermediate levels and define the meaning of each level over the whole system, you can obtain an insight of the bootstrapping procedure.

In order to label the intermediate states, introduce an integer value, sometime called "run level", and make an arrangement over the whole system. This "Multi-Phase Startup Pattern" can make the design and implementation of startup procedure cleaner and safer.

Consider the following example.

An operating system has a subsystem called "File System(FS)" and another called "Network Interface(NI)".

When startup, it starts up FS first, reads a configuration file including its IP address and other information for NI, and then starts up NI to reach the final active state. Recently this operating system added a new FS feature of "Network File System(NFS)". This feature brought a mutual-dependency problem of FS and NI. That is;

  1. NI depends on FS for its configuration
  2. FS depends on NI for this new NFS feature

As this case shows, mutual dependency between subsystems prevents the whole system's startup in simple order(i.e. first FS, then NI). Therefore, the following method is adopted;

  1. FS first starts up only local file system service. In this state, the system does not have any network services. Label this state as "run level - 1".
  2. NI then connects to the network based on the configuration file using the local file system service of FS. In this state, the system is started up with the local file system and the simple network. Label this state as "run level - 2".
  3. Finally, FS build NFS service using NI's network service. In this state, the system is started up with the full feature. Label this state as "run level - 3", which is the final active state of the system.

The strategy here is to divide the subsystems' state into intermediate levels and to gradually achieve the final goal, in order to resolve the problem of the mutual dependency. "Multi-Phase Startup Pattern", provides a solution to the mutual dependency problem often occurs in the system's bootstrapping.


Use this pattern when;
  • starting up a system composed of several subsystems which are dependent of one another.
  • shutting down such a system gracefully.
  • starting up a distributed system with circular dependency.




  • System
    • represents the whole system responsible for starting up its subsystems.
    • comprises subsystems.
  • SubSystem
    • an abstract class for concrete subsystems.
    • provides an entry point(enterRunlevel) for 'System'.
    • provides an hot spot(doRunlevel) for 'ConcreteSubSystem's.
  • ConcreteSubSystem
    • represents concrete subsystems.
    • describes subsystem-specific behavior for each run level.


  • The System object requests its SubSystem objects to enter a certain run level.
  • Each SubSystem object enters the specified run level and takes action to get into the level.


In implementation, consider the following.

  • You need to define the meaning of each run level to obtain an arrangement over the whole system. An agreement that which subsystem depends on which services is needed among the subsystems in advance.
  • If one subsystem is not able to enter the specified run level, the System needs to recognize it as an error, and to decide whether to stop moving into the next level or to retry after a while.


The following variations are possible.

  • Degenerate the levels into three. they are often called "new, init, start".

    3 Phase Implementation

  • Making composite recursive hierarchy of System and SubSystem can be applied to multi-layer systems.

    Layered Implementation

  • Not only starting up, this pattern can be applied to graceful shutdown of the whole system.
  • There is a more flexible implementation in which the System object does not control the level of the system in a top-down basis and lets each Subsystem object resolve the dependency, retain its context, and elevate its run level. In this implementation, the System object repeats calling its subsystems' start() method until all the subsystems enters the final active state.

    Non-topdown Implementation

    This implementation makes the system more decentralized and more automonous. But, it gets more difficult to ensure that the system reach the final active state because each subsystem needs to observe the other subsystems one another, and its startup depends on the observed progress of the other subsystems. That is, during the startup process, it's possible for the system to get into a deadlock in which one subsystem waits for another's elevation and vice versa.

    Consider a n-space where one variable represents one subsystem's state. In this state space, The transition path from the initial state to the final active state is drawn as a movement of a point in the space. Non-topdown automonous implementation cannot avoid the point's passing deadlock areas laid in this space.

    Topdown management is viewed as putting 'check points' labeled with each run level within this state space. Introducing check points can deliberately avoid passing the deadlock areas. This approach is equivalent to that of "introducing a butler to the dining philosopher" in order to avoid deadlocks.

    Whether to adopt the topdown approach or the automonous approach is a trade off of the complexity of the system, requirements of error recovery, realtime constraint, flexibility of the system and so on.

    System's State Space and Deadlock Areas


In result,

  • The System can start up its mutually dependent subsystems reliably.
  • The Arrangement and process of the startup procedure gets clear.

   Knows Users

  • Run level and bootstrap of some UNIX systems.
  • A Complex realtime system I experienced.

   Related Patterns

  • Singleton[GoF] is often used for the implementation of the System class.
  • Composite[GoF] is used for the multi-layer implementation of the system.


I'd like to thank JPLoP members for a lot of advice in the course of refinement of this pattern. Especially, an automonous variation is from HIRASAWA Akira. The insight into the problem of the automonous variation and the essential heuristicness behind this pattern is from FUJINO 'Terry' Terunobu.

Kenji Hiranabe <>
Last modified: Sun Dec 12 12:55:07 1999