Course outline

Linux / Advanced: boundaries, security, and recovery / Lesson 18

Build reliable services and diagnose incidents

Connect readiness, restart policy, sandboxing, evidence preservation, and controlled recovery into a practical service lifecycle.

About 4 min readContent reviewed
On this page

Lesson goals

  • Choose a service type that matches the process model.
  • Distinguish readiness, liveness, retries, and rate limits.
  • Investigate incidents through a testable causal timeline.

Startup is not the same as readiness

A process can exist before it has opened its socket or loaded required state. Type=exec confirms that the service executable was successfully invoked, but not that application initialization finished. Type=notify allows a supporting application to report readiness explicitly. Type=oneshot fits finite work, while legacy forking behavior requires an appropriate model and reliable main-process identification. ExecStart is not automatically an interactive shell command: shell operators need an explicitly invoked shell if they are truly required. Prefer a direct executable and explicit arguments so the manager can identify and supervise the intended workload.

Retries require a bounded policy

Restart=on-failure can recover from some unexpected exits, but it does not repair a bad configuration or unavailable credential. RestartSec= spaces attempts, while start-rate limits can stop repeated activation. A deliberate stop is different from an application crash. Define acceptable retry behavior and ensure startup is idempotent so repeated execution does not duplicate durable work. If the service consumes jobs, coordinate acknowledgement and checkpoint semantics with the application. Restart supervision improves availability only when the application’s state transitions remain correct across interruption and re-entry.

ini Read a study-only worker unit
[Unit]
Description=Synthetic report worker for review
StartLimitIntervalSec=60
StartLimitBurst=3

[Service]
Type=exec
ExecStart=/usr/local/libexec/example-worker --foreground
User=example-worker
Restart=on-failure
RestartSec=5
NoNewPrivileges=yes
PrivateTmp=yes

The executable and account are fictional and must not be installed by copying this fragment. The unit illustrates bounded retries and two sandbox settings; it is not a complete application deployment.

Reduce access without breaking required state

Service sandboxing can separate temporary directories, prevent new privilege gains, restrict writable paths, and reduce capabilities. Each setting changes the execution contract and must be tested with the actual application. PrivateTmp does not mean every application file is private, and NoNewPrivileges does not remove privileges already held. Read-only filesystem protection needs explicit writable locations for legitimate state. User and group identity still matter. Use the installed systemd manual because options and their implementation depend on version, kernel support, and whether the service runs under a user or system manager.

Preserve the first failure and build a timeline

Start an incident record with impact, first observed time, affected scope, and recent changes. Capture unit result, invocation evidence, journal entries, relevant cgroup events, and dependency state before restarting. Correlate timestamps carefully because clocks and time zones can differ across machines. Separate observations from hypotheses: permission denied is evidence, while a suspected deployment mistake is a hypothesis. Choose one low-risk discriminating check, update the hypothesis, and avoid a sequence of unrecorded changes. Repeated restarts can destroy the original evidence and create an additional rate-limit symptom.

bash Capture bounded incident evidence
systemctl show example-worker.service -p Result -p ExecMainCode -p ExecMainStatus -p NRestarts
journalctl -u example-worker.service -b -n 80 --no-pager
systemctl cat example-worker.service

These read-only commands inspect a prepared fictional lab unit. Compare the first failure with later retry messages. No restart, reset-failed, or configuration mutation is included.

Recovery and prevention need different evidence

Recovery proves that useful service returned; root-cause analysis explains the mechanism that produced the incident and why existing controls missed it. A rollback can restore availability without fully explaining the defect, so record that uncertainty explicitly. Verify an application request, data consistency, and expected dependency behavior after an authorized recovery. Then reproduce the causal mechanism in a disposable environment and add the smallest meaningful protection, such as input validation or configuration checking. Document a concise timeline, contributing conditions, tested fix, and an operational check that would detect recurrence.

Common errors and fixes

Active is treated as ready

Why it happens
Process startup was confused with application initialization.
How to fix it
Use a supported readiness model and functional check.
Prevent it next time
Define readiness before dependency ordering.

A restart loop becomes the repair

Why it happens
Retries concealed a persistent configuration or state failure.
How to fix it
Capture the first cause and bound recovery attempts.
Prevent it next time
Pair restart policy with failure classification.

Sandbox settings are copied without testing

Why it happens
Required application paths and privileges were unknown.
How to fix it
Test the access contract on a matching disposable image.
Prevent it next time
Review each restriction against required behavior.

Check your understanding

1. A unit reaches the start limit after several identical missing-file errors. What should the next diagnosis address?

Show worked solution

Treat the start-limit message as a consequence of retries. Investigate the first missing-file error, effective working directory, executable arguments, mount availability, and deployment contents. Only after fixing the cause should the authorized lab recovery plan consider clearing the limit and starting again.

2. A rollback restores requests. Is the incident analysis complete?

Show worked solution

No. Recovery is established, but the failed change’s causal mechanism and prevention remain open. Preserve the before/after versions, correlate evidence, reproduce the failure safely, and verify a targeted fix. State any remaining uncertainty instead of presenting correlation as proof.

Key takeaways

  • Choose a process model and test application readiness.
  • Preserve evidence, bound retries, and verify recovery functionally.

Official references