Home / Alt manpages / systemd-sysv-generator(8)

  • systemd-sysv-generator(8)
  • Admin command
  • linux

Track Down Wrapped Init Scripts with systemd-sysv-generator

Reload systemd and a service you swore was hand-configured turns out to be a wrapper: systemd-sysv-generator just imported it from /etc/init.d/. This guide shows you how to find that script, read the generated unit it produced, and check the ordering and boot targets it was given. Allow about 10 minutes.

You need a shell account that can read the service files; reach for sudo only where a step needs privileged access.

What the generator actually does

  • It is a compatibility shim, not a converter. In systemd 255, it reads executable-looking scripts from /etc/init.d/ and builds temporary .service wrappers when the system manager starts or reloads. The wrapper just calls the original script.
  • It is on its way out. The component is deprecated upstream. Treat any imported service as migration work waiting to happen, not a reason to add more SysV scripts. A native unit gives you clearer dependencies, logging and lifecycle behaviour.
  • It has no options worth touching. systemd calls it itself; its documented synopsis is just its own path:
/usr/lib/systemd/system-generators/systemd-sysv-generator

Do not run that path to start or stop a service. Use systemctl for service operations and let systemd invoke its generators in the background.

1. Find the legacy script

List the script named by the service you are investigating. Replace the placeholder with a real service name; this is a read-only command and does not need elevated privileges.

SERVICE_NAME=example-daemon
ls -l "/etc/init.d/$SERVICE_NAME"
sed -n '1,100p' "/etc/init.d/$SERVICE_NAME"

Look for an LSB header between ### BEGIN INIT INFO and ### END INIT INFO. Fields such as Required-Start, Required-Stop, Should-Start, Default-Start and Default-Stop describe ordering and runlevel intent. A script without useful headers can still be wrapped, but systemd has less to go on when ordering it.

Checkpoint

You should have a real file below /etc/init.d/. If it is missing, you are probably looking at a native unit, or a service name from a different package entirely.

2. Ask systemd which unit is active

Use the service name with a .service suffix. Neither command changes service state:

systemctl status "$SERVICE_NAME.service" --no-pager
systemctl cat "$SERVICE_NAME.service"
  • For an imported script, systemctl cat commonly shows a comment saying the unit was automatically generated, a SourcePath=/etc/init.d/... line, and something like ExecStart=/etc/init.d/example-daemon start. The exact Type, timeout and stop command depend on the script and its headers.
  • If systemd cannot find the unit, check the script name and package installation first. The generator only ever looks in /etc/init.d/; a script anywhere else is not its problem.

3. Inspect dependencies and boot placement

Ask systemd to show the unit's effective ordering and relationships:

systemctl show "$SERVICE_NAME.service" \
  -p FragmentPath -p SourcePath -p Type -p Before -p After \
  -p WantedBy --no-pager

Generated units live under /run/systemd/, which is runtime state, not a file you should ever edit directly. The SourcePath points back to the SysV script. If you need to change behaviour, change the package configuration or replace the script with a native unit; edits to the generated file are lost on the next reload or boot.

  • LSB facilities get translated. In systemd 255, $remote_fs, $network, $named, $portmap and $time are recognised and become dependencies on native systemd targets. The generated unit is also ordered after basic.target, because systemd does not support SysV scripts as part of early boot.
  • Runlevels become targets. Enablement shows up as targets such as runlevel2.target and runlevel5.target. The wrapper is wanted by the targets that match the runlevels the original script was enabled for, which is why a script can exist on disk but never start during a normal boot.

4. Reload after a script or package change

Generators run when the system manager reloads, so after a package changes an init script, tell systemd to catch up. This is an administrative operation and may need elevated privileges:

sudo systemctl daemon-reload
systemctl cat "$SERVICE_NAME.service"

The second command is your verification step. Compare SourcePath, the ExecStart and ExecStop lines, and the ordering from systemctl show. A reload does not, by itself, start, stop or restart the service.

Common traps

  • Do not stop or disable a production service just to see how it was generated. systemctl stop, disable and mask all change availability or boot behaviour. If you have made a reversible change, restore it with the matching systemctl enable or systemctl unmask command once you have confirmed the unit name.
  • Do not assume a wrapper that starts cleanly matches the old init system exactly. SysV compatibility is broad but not complete.

Safety boundary

When replacing a script, record its current start order, stop order, environment and dependencies first. Write a native unit with explicit After=, Wants= or Requires= relationships, test it in a maintenance window, and only remove the old script once you have a verified rollback path.

Done means

  • Identified the source script below /etc/init.d/.
  • Confirmed the wrapper with systemctl cat, including its source path.
  • Checked type and ordering with systemctl show.
  • Know the generated files are disposable, living under /run/systemd/.
  • Have a test and rollback plan for any future replacement.