FreeBSD Shutdown Operations: Schedule, Cancel, and Verify a Clean Stop
Plan FreeBSD halts and reboots with shutdown(8), understand rc.shutdown ordering, coordinate users and services, and verify power state safely.
A FreeBSD reboot is not just a power-button action. The operator must distinguish a halt from a reboot or power-off request, notify logged-in users, allow services to stop, understand which shutdown scripts run, and verify that the machine reached the requested state. A graceful request reduces avoidable risk, but it cannot guarantee that a failed daemon exits cleanly, that hardware honors a power command, or that application data were committed before shutdown began.
This is an operations runbook for the system-level shutdown(8) command. It does not replace service-specific quiesce procedures, database backup instructions, or hypervisor and cloud-provider controls. For a host that carries state, coordinate the application layer before scheduling an operating-system action.
Decide what “down” means
FreeBSD distinguishes several actions. shutdown -r requests a reboot. shutdown -h halts the system. shutdown -p requests power-off; the poweroff command is documented as equivalent to shutdown -p now. A halt does not necessarily mean the physical machine loses power, and software power-off depends on platform support. A remote management controller or virtualization platform may report a separate power state, so verify the outcome through the appropriate control plane.
Avoid describing all three as “restart” in a change plan. Specify whether services should return automatically, whether the machine should remain halted for hands-on maintenance, or whether the physical or virtual instance should be powered off. Check that the boot path and console access are available before a reboot, especially after kernel, firmware, storage, or network changes.
Schedule with warnings and a cancellation path
The shutdown utility accepts a time and an optional warning message. A relative time such as +30 schedules the action thirty minutes ahead; an absolute time can be written in the formats accepted by the installed manual. For example:
shutdown -r +15 "Approved maintenance: host reboot in 15 minutes"
Use a message that identifies the host, reason, and expected service impact without exposing sensitive details to every logged-in user. shutdown places a time and warning in /var/run/nologin, preventing new logins before the action. Check the exact behavior and syntax on the target system before using it in automation.
To cancel a scheduled shutdown, send SIGTERM to the shutdown process as described in the manual; the utility removes the nologin file it created. On a managed host, also notify the people who received the original warning and confirm that the cancellation took effect. Do not delete /var/run/nologin blindly: it may have another operational reason to exist.
The -k option sends a warning without actually shutting down. It is useful to rehearse message delivery, but it is not a dry-run of service shutdown, disk synchronization, or platform power behavior. A successful warning rehearsal validates only that part of the procedure.
Before the maintenance window, capture the current system identity, uptime, release, and critical service state:
hostname
freebsd-version -kru
uptime
service -e
who
Save outputs in the approved change record. Identify application owners, long-running jobs, mounted remote filesystems, replication roles, and any maintenance lock that should prevent an unexpected restart. For clusters, disable or drain the node through the cluster’s supported control plane before stopping the host. A local shutdown command cannot ensure quorum, migration, leader transfer, or safe failover for the services running above it.
Understand the rc shutdown phase
FreeBSD’s rc.shutdown procedure reads configuration, uses rcorder to order scripts in /etc/rc.d and local startup directories that have the shutdown keyword, reverses that order, and runs each through the rc framework with faststop. The order is therefore based on declared script dependencies, not on an operator’s assumption about alphabetical names.
This mechanism gives services an orderly stop path, but it is not an application transaction protocol. A custom rc script should not be the only place where critical business data are committed. It may not run after power loss, kernel panic, forced hypervisor reset, or hardware failure. Treat shutdown hooks as best-effort lifecycle integration and keep service-level checkpointing and recovery procedures independent.
The system’s init path eventually transitions processes as part of shutdown. Do not use kill -9 as a routine pre-step; it bypasses normal service stop behavior and can leave application-specific work incomplete. If a service refuses to stop, diagnose its supervisor, dependencies, logs, and escalation policy before forcing the host down. Capture the process and service state rather than hiding the issue with a broad kill command.
For a local service, use its rc.d interface to assess status and stop behavior in a controlled window:
service example_service status
service example_service stop
service example_service status
Replace example_service with an actual installed rc script. Test this sequence in staging before relying on it. Some services have application-native drain or checkpoint commands that must run before service stop; consult that product’s documentation. A service reporting stopped does not prove that an external peer has observed a completed failover.
Use distinct options deliberately
The most common invocations should be explicit:
# Reboot after notifying users immediately
shutdown -r now "Rebooting for approved maintenance"
# Halt without requesting a physical power-off
shutdown -h now "System halt requested"
# Request system power-off now
shutdown -p now "System power-off requested"
These commands change live system state and should not be run as casual tests. shutdown requires root privileges or membership in the documented operator group. Confirm the chosen action, target host, maintenance approval, and console path before execution. In a shell session connected to a remote machine, copy the command into the ticket first and verify the hostname in a separate line; confusing a bastion with the target can turn a sound plan into an outage.
Avoid using sync as a ritual substitute for shutdown. FreeBSD’s sync(8) manual says it is generally preferable to use reboot(8) or halt(8), which can perform additional actions such as resynchronizing the hardware clock and flushing internal caches before a final sync. The kernel’s sync(2) may return before all buffers are flushed. If an application requires a durable transaction, use its documented synchronization mechanism before requesting system shutdown.
Observe completion and recover safely
After issuing the action, keep a console or management session available. For a reboot, confirm that the host disappears and returns, that the boot completes, and that the expected release, network interfaces, mounts, and services are healthy. For a halt, verify console state. For power-off, check the platform power state rather than assuming that the SSH disconnect proves the machine powered down.
If the host does not return, distinguish a failed boot from a request that never reached the target. Check out-of-band console output, hypervisor events, storage visibility, and boot environment selection. Avoid repeatedly cycling power while a filesystem or storage array is recovering. Preserve console output and timestamps for incident review.
After boot, validate the actual application outcome:
uptime
service example_service status
mount -p
df -h
tail -n 80 /var/log/messages
These are starting points, not universal checks. Use application-native health endpoints and replication or queue metrics where appropriate. Compare them with the pre-change baseline and confirm that any node rejoined its cluster under the expected identity and role. Do not declare success merely because the host answers ping or SSH.
Failure cases to plan for
A shutdown can be blocked by /var/run/noshutdown; the manual says the file prevents the action unless the documented force option is used. Do not override it automatically. Find who created the sentinel and why. A timed shutdown can be canceled, but users still need an updated communication. A scheduled machine power-off can complete as a halt if hardware does not support power cycling or power-off behavior. A local service script can stop while a remote dependency remains active. A failed disk sync or application flush can surface only in logs or in the next startup’s recovery.
Document the expected behavior for service stop timeouts, local filesystems, network mounts, virtualization, and high-availability membership. In particular, remote filesystems can complicate shutdown if a client has blocked operations; resolve or explicitly account for that state rather than assuming the normal sequence will be instantaneous. Keep a tested rollback: cancel a scheduled action before its start time, or use the console recovery path if a reboot fails.
Acceptance criteria
Before execution, the correct host and action are confirmed, users and dependent service owners are notified, stateful applications have been quiesced through their documented procedures, and a console path is available. After execution, the intended halt, reboot, or power-off state is observed, boot and service checks pass where applicable, and application health is confirmed at its own layer. Record any stop timeout, failed sync, unexpected reboot, or manual intervention as a real deviation.
An orderly operating-system shutdown is a useful lifecycle boundary, not proof of application consistency. Pair it with explicit service-level preparation and a post-start acceptance test.
Related:
- FreeBSD’s rc.d Init System: Scripts, Dependencies, and Service Ordering
- FreeBSD daemon(8) Operations: Supervise Foreground Programs Predictably
Sources: