Development/Docs/Modular Init

From Mandriva

Jump to: navigation, search
Modular rcS initscripts

An analysis of rc.sysinit and a plan to migrate to SysV-style rcS.d

Mandriva Linux currently uses the rc.sysinit script from Fedora/Red Hat to initialize runlevel S. This script poses many problems regarding maintainability, performance, consistency and robustness; here we summarize the tasks it performs and present an alternative set of modular runlevel S initialization scripts.

Contents


[edit]

Introduction

[edit]

System initialization

Initialization of a typical Linux system is similar to what happens in UNIX: prior to allowing users to log in, it is necessary to mount virtual, local and remote filesystems, set the system clock and hostname, prepare virtual memory swap areas, erase temporary files and initialize the network. Visual feedback in SuSE and Red Hat is similar to the initialization of HP-UX 10 (minus paging and spinner), while Debian uses an unformatted, Solaris-like startup. Runlevels are handled with individual scripts run by a sequencer. Fedora/Red Hat uses a single rc.sysinit reminiscent of the BSD rc.S script to handle initialization of runlevel S.

Mandriva Linux 2005 uses rc.sysinit like Red Hat. Conectiva Linux 10 splits initialization of runlevel S in individual scripts like SysV, SuSE and Debian.

[edit]

SysV runlevels

Mayank Sarup notes, in his A look at System V initialization article:

There are 7 runlevels that have been defined. Of these 7 runlevels 0, 1, 6 and S are reserved runlevels.

  • 0 - Halt
  • 1 - Single user mode for maintenance
  • 6 - Reboot
  • S - Single user mode but only the root partition is mounted. Use this one for filesystem check and repair.

The single user mode is handled differently by the various distributions. Under Red Hat, runlevel "S" and "1" are the same. Runlevel S under System V was for filesystem checks and repairs where only the root filesystem was mounted. No services are running. Runlevel 1 is single user but is used for system administration tasks like adding/removing packages or configuration changes. Some basic services are running but networking is disabled. SuSE works this way and makes the distinction between the two runlevels.

[edit]

Linux runlevels

Most Linux distributions use the System V initialization system, but with different runlevel specifications. There can be no distinction between runlevels S and 1, and no agreement whether networking should be started at single-user level or not:

  • Debian: All local filesystems mounted, device drivers initialized and network available after S40 of runlevel S. Regular multi-user runlevel is 2.
  • Red Hat: According to Sarup, runlevels S and 1 are the same. All local filesystems are mounted, but the network is not initialized. Runlevels 3 and 5 are used for multi-user.
  • Mandriva Linux 2005: like Red Hat.
  • Conectiva Linux 10: like Red Hat.
  • SuSE Linux: like SysV (confirm this).
[edit]

References

[edit]

rcS modularization

[edit]

Motivation

Having rc.sysinit handle runlevel S initialization results in a non-parallelizable, overly-complex script that contains code that shouldn't belong to a generic system. It's messy, it's slow and it's hard to maintain. Overhead introduced by executing separate scripts for each subsystem does exist, but the maintainability and code efficiency gain can result in a faster system initialization.

Among the benefits of a modular rcS initialization are:

  • Scripts handling initialization of specific, optional subsystems such as LVM, RAID or Braille terminal can be moved to the packages containing the implementation of such subsystems.
  • Improved maintainability.
  • More robust initialization routine.
  • Reduced overhead caused by execution of unnecessary code.
  • Execution can be paralellized if using an appropriate initialization system.
  • Scripts are easier to debug and profile.
[edit]

Modularization guidelines

[edit]

Kernel 2.2 support

Unless under risk of data loss, kernels 2.2 and earlier will no longer be supported.

[edit]

Keep current behavior

[edit]

Utility package layout

Essential components for initialization of runlevel S that are under the /usr hierarchy must be moved to local filesystems.

Rationale: Initialization of runlevel S can't rely on components installed under /usr until networking is started and remote filesystems are mounted. Part of the complexity and inefficiency of the Fedora/Red Hat script used in Mandriva Linux 2005 arises from the fact that it tries to use components whose availability is uncertain (such as console fonts and keymaps).

[edit]

Script ownership

If a script uses a component that is mandatory in all architectures (e.g. pam), it _may_ remain in the initscripts package. If it uses a component that will never exist in some architectures (e.g. console-tools on S/390, isapnp on PPC) then it must part with that package.

Rationale: Keeping the initialization of a package that is always present adds no initialization overhead. Conversely, we want to avoid always running a script for a package that will be never there.

[edit]

Optional services

If a script initializes an optional subsystem, it should belong to the package related to that subsystem.

Rationale: We don't want to always check and try to initialize a service that isn't installed.

[edit]

Current rc.sysinit

[edit]

rc.sysinit steps

Color key:

  • Optional steps to be moved to a different package.
  • To be removed unless we find a good reason to keep it.


  1. Run through initlog.
  2. Gather sysconfig data (network, usb, system)
  3. First try to set up the console font. [console-tools]
  4. Mount /proc.
  5. Mount /sys.
  6. Unmount the initrd, if necessary.
  7. Check SELinux status, but don't use it yet. [selinux]
  8. Do mysterious thing with two extra terminals, unless we have an S/390.
  9. Print the banner and interactive startup notice.
  10. Run devfsd if appropriate. [devfs]
  11. Mount /dev/pts.
  12. Mount /dev/shm.
  13. Start braille terminal. [brltty]
  14. Check interactive startup again.
  15. Fix console loglevel.
  16. Configure kernel parameters with sysctl.
  17. Set system clock (with extra black magic for alpha)
  18. Load keymap with loadkeys. [console-tools]
  19. Set the hostname.
  20. Set the NIS domain name. [nis]
  21. Initialize ACPI bits.
  22. Initialize USB.
  23. Read /etc/sysconfig/init.
  24. Initialize USB HID interface, keyboard and mouse.
  25. Check for fastboot mode.
  26. Check root filesystem, call rc.readonly to set up magic stuff needed for readonly root.
  27. Possibly update quotas if fsck was run on =/=. [quota]
  28. Deal with isapnp (using /sbin/isapnp). [isapnp]
  29. Remount the root filesystem read-write.
  30. Load extra SCSI modules if needed.
  31. Start udev. [udev]
  32. Initialize device mapper. [device-mapper]
  33. Initialize EVMS. [evms]
  34. Initialize LVM. [lvm]
  35. Clean up SELinux labels. [selinux]
  36. Load appropriate crypto modules for encrypted swap.
  37. Activate swap.
  38. Clear mtab and remove mtab backups.
  39. Update mtab with /proc, /sys, /proc/bus/usb, devfs, /initrd/loopfs if appropriate.
  40. Check for nomodules in the command line.
  41. Remove /lib/modules/preferred and /lib/modules/default.
  42. Run sndconfig for PNP cards. [sndconfig]
  43. Load sound modules if and only if they need persistent DMA buffers.
  44. Do some black magic involving modules, modprobe and hotplug. [hotplug?]
  45. Start RAID. [raidtools]
  46. Start LVM, part 2. [lvm]
  47. Restart devlabel.
  48. Check filesystems, except loopbacks.
  49. Mount local filesystems (includes black magic to detect kernel 2.2).
  50. Mount crypto filesystems.
  51. Check loopback filesystems.
  52. Mount loopback filesystems. All local non-USB filesystems mounted.
  53. Reset pam_console permissions.
  54. Try loading console font again.
  55. Start keytable. [console-tools]
  56. Check quotas on filesystems other than root. [quota]
  57. Initialize pseudo-random number generator.
  58. Configure machine if necessary, has rhgb stuff.
  59. Activate quotas for local filesystems. [quota]
  60. Remove junk from =/= (/fastboot, /forcefsck et al)
  61. Check if we have wtmpx, utmpx.
  62. Clean up /var.
  63. Reset pam_console permissions again.
  64. Clean up utmp, wtmp (and wtmpx, utmpx if they exist).
  65. Selective clean-up of /tmp.
  66. Detect and create/activate encrypted swap (wasn't it done before?)
  67. Activate swap in swapfiles.
  68. Initialize serial ports. [setserial]
  69. Load usb-storage and firewire if applicable.
  70. Always load ide-cd, and load ide-scsi if it's in the command line.
  71. Load st module for SCSI tapes if we have one.
  72. Run hdparm unless software RAID is resyncing. [hdparm]
  73. Adjust symlinks in /boot.
  74. Dump dmesg log. ( also done by mandrake_everytime).
  75. Create crash indicator /.autofsck.
  76. Kill getkey, check for confirmation mode.
  77. Touch /var/run/failsafe if failsafe set in command line.
  78. Run mandrake_firsttime if this is the first boot.
  79. Run mandrake_everytime.
    1. Disable supermount if not needed.
    2. Set up ethernet interfaces before hotplug, pcmcia
    3. Clean up /tmp (for real this time)
    4. Start Globetrotter stuff.
    5. Run netprofile.
    6. Create resolv.conf if not there.
    7. Dump dmesg (again, and overwrite the previous dump)
    8. Rewrite issue and issue.net if appropriate.
      1. Check if OEM, if so set name accordingly.
      2. Check system configuration and update system files and linux_logo files.
  80. Do some black magic with XF86Config.
[edit]

Notes

[edit]

Modular rcS.d

[edit]

Credits

[edit]

Initialization steps

[edit]

Full initialization

Initialization steps for a fully installed host are:

  1. Run through initlog.
  2. Mount virtual filesystems.
  3. Start devfsd, mount devfs.
  4. Set up braille terminal.
  5. Set console font.
  6. Initialize USB keyboard.
  7. Set keymap.
  8. Activate swap partition, check root filesystem, remount root filesystem read-write, update /etc/mtab.
  9. Run devfs if appropriate, mount virtual filesystems.
  10. Set system clock (with extra black magic for alpha).
  11. Set system hostname.
  12. Check and mount local filesystems.
  13. Check and mount loopback filesystems.
  14. Check and mount crypto filesystems.
  15. Configure kernel parameters, ACPI, /boot symlinks.
  16. ...
  17. Clean temporary files.
[edit]

Typical initialization

Initialization steps for the average desktop machine are:

  1. Run through initlog.
  2. Mount virtual filesystems.
  3. Set console font.
  4. Initialize USB keyboard.
  5. Set keymap.
  6. Activate swap partition, check root filesystem, remount root filesystem read-write, update /etc/mtab.
  7. Set system clock (with extra black magic for alpha).
  8. Set system hostname.
  9. Check and mount local filesystems.
  10. Configure kernel parameters, ACPI, /boot symlinks.
  11. ...
  12. Clean temporary files.
[edit]

Minimal initialization

Initialization steps for a minimalistic or headless host are:

  1. Run through initlog.
  2. Mount virtual filesystems.
  3. Activate swap partition, check root filesystem, remount root filesystem read-write, update /etc/mtab.
  4. Set system clock (with extra black magic for alpha).
  5. Set system hostname.
  6. Check and mount local filesystems.
  7. Configure kernel parameters, ACPI, /boot symlinks.
  8. ...
  9. Clean temporary files.
[edit]

Changes in other packages:

  • coreutils: /usr/bin/readlink to be moved to /bin/readlink
  • console-tools: add initscript, move /usr/lib/kbd to /lib/kbd
  • raidtools: add initscript
  • lvm(2): add initscript
  • ...

New versions of packages containing init scripts must require the new initscripts package. The initscripts package must conflict with older versions of these packages. Doing so we keep the system consistent and avoid circular dependencies.

[edit]

Further research

[edit]

Optimization issues

[edit]

Parallel initscripts

[edit]

Development

[edit]

References

[edit]

TODO

  • Check services which don't belong to standard startup and try to include them in packages which use it
  • Make an interface with chkconfig
Personal tools