Control Services in Red Hat Enterprise Linux

Red Hat Enterprise LinuxBeginner
Practice Now

Introduction

In this lab, you will gain hands-on experience managing system services on RHEL using the systemctl command. You will learn to view all loaded and active services, check the status of specific services, and control their runtime behavior by starting, stopping, and restarting them. Furthermore, you will explore how to reload service configurations, enable or disable services for automatic startup at boot, and understand the advanced concepts of masking and unmasking services to prevent their activation.

This practical guide will equip you with essential skills for system administration, enabling you to effectively monitor and manage the lifecycle of services crucial for the operation of your RHEL system.

View All Loaded and Active Services with systemctl

In this step, you will learn how to identify automatically started system processes using the systemctl command. systemctl is the primary tool for managing systemd services in Red Hat Enterprise Linux.

First, let's explore how to list all currently loaded and active service units. The systemctl list-units --type=service command is used for this purpose. This command displays service units that the systemd daemon has successfully parsed and loaded into memory, and which are currently active.

Open your terminal in the RHEL environment. You are already logged in as the labex user, and your current directory is ~/project.

Execute the following command to list all loaded and active service units:

systemctl list-units --type=service

You will see output similar to this, showing various services and their states:

UNIT                  LOAD    ACTIVE  SUB      DESCRIPTION
atd.service           loaded  active  running  Job spooling tools
auditd.service        loaded  active  running  Security Auditing Service
chronyd.service       loaded  active  running  NTP client/server
crond.service         loaded  active  running  Command Scheduler
dbus-broker.service   loaded  active  running  D-Bus System Message Bus
...output omitted...

Let's break down the columns in the output:

  • UNIT: This is the name of the service unit, typically ending with .service.
  • LOAD: Indicates whether the systemd daemon successfully parsed the unit's configuration and loaded it into memory. loaded means it was successful.
  • ACTIVE: This is the high-level activation state of the unit. active generally means the unit started successfully.
  • SUB: This is the low-level activation state, providing more detailed information. For running services, running is common.
  • DESCRIPTION: A brief description of what the service does.

Press q to exit the command.

Next, you can use the --all option with systemctl list-units --type=service to list all service units regardless of their activation states (active, inactive, failed, etc.). This can be useful for seeing services that are installed but not currently running.

Execute the following command:

systemctl list-units --type=service --all

The output will include services that are inactive or in other states, providing a more comprehensive view:

UNIT                          LOAD      ACTIVE   SUB     DESCRIPTION
  atd.service                 loaded    active   running Job spooling tools
  auditd.service              loaded    active   running Security Auditing ...
  auth-rpcgss-module.service  loaded    inactive dead    Kernel Module ...
  chronyd.service             loaded    active   running NTP client/server
  cpupower.service            loaded    inactive dead    Configure CPU power ...
  crond.service               loaded    active   running Command Scheduler
  dbus-broker.service         loaded    active   running  D-Bus System Message Bus
● display-manager.service     not-found inactive dead    display-manager.service
...output omitted...

Finally, to see the state of all installed unit files, including those that are not loaded or active, you can use systemctl list-unit-files --type=service. This command shows whether a service is enabled (starts at boot), disabled (does not start at boot), static (cannot be enabled directly but might be started by another unit), or masked (prevented from starting).

Execute the following command:

systemctl list-unit-files --type=service

You will see output similar to this, indicating the STATE and VENDOR PRESET for each service unit file:

UNIT FILE                         STATE       VENDOR PRESET
arp-ethers.service                disabled    disabled
atd.service                       enabled     enabled
auditd.service                    enabled     enabled
auth-rpcgss-module.service        static      -
autovt@.service                   alias       -
blk-availability.service          disabled    disabled
...output omitted...

This command is particularly useful for understanding which services are configured to start automatically when the system boots up.

Check Status of a Specific Service with systemctl status

In this step, you will learn how to check the detailed status of a specific service using the systemctl status command. This command provides comprehensive information about a service, including whether it's running, its process ID, memory usage, and recent log entries.

We will use the crond.service (cron daemon) as an example. The cron daemon is a common service that handles scheduled tasks.

Open your terminal in the RHEL environment. Ensure you are in your ~/project directory.

Execute the following command to check the status of the crond.service:

systemctl status crond.service

You will see detailed output similar to this:

● crond.service - Command Scheduler
     Loaded: loaded (/usr/lib/systemd/system/crond.service; enabled; preset: enabled)
     Active: active (running) since Mon 2022-03-14 05:38:10 EDT; 25min ago
   Main PID: 1089 (crond)
      Tasks: 1 (limit: 35578)
     Memory: 1.2M
        CPU: 12ms
     CGroup: /system.slice/crond.service
             └─1089 /usr/sbin/crond -n

Mar 14 05:38:10 workstation systemd[1]: Started Command Scheduler.
Warning: some journal files were not opened due to insufficient permissions.

Let's examine the key fields in the output:

  • Loaded: This line tells you if the service unit's configuration file has been processed. It also shows the path to the unit file (/usr/lib/systemd/system/crond.service) and its enablement status (enabled means it's configured to start at boot).
  • Active: This is crucial. It indicates the current state of the service. active (running) means the service is currently active and its processes are running. It also shows how long it has been active. Other states could be inactive (not running), active (exited) (completed a one-time task), or failed (encountered an error).
  • Main PID: The Process ID (PID) of the main process associated with the service, along with the command name.
  • Tasks: The number of tasks (threads) the service is currently using.
  • Memory: The amount of memory the service is consuming.
  • CPU: The CPU time consumed by the service.
  • CGroup: Information about the control group the service belongs to, which is used for resource management.
  • The lines below CGroup show recent log entries related to the service, providing insights into its startup and ongoing activities.

In addition to systemctl status, there are simpler commands to quickly check specific aspects of a service's state:

  • To check if a service is active:

    systemctl is-active crond.service

    Expected output:

    active
  • To check if a service is enabled (configured to start at boot):

    systemctl is-enabled crond.service

    Expected output:

    enabled
  • To check if a service has failed:

    systemctl is-failed crond.service

    Expected output (if running correctly):

    active

    If a service had issues starting or running, this command would return failed.

These commands are useful for scripting or quick checks when you don't need the full detailed output of systemctl status.

Start, Stop, and Restart a Service with systemctl

In this step, you will learn how to manage the lifecycle of system services using systemctl commands. You will practice starting, stopping, and restarting a service. For this exercise, we will use a dummy service that we will create. This approach ensures that we can safely manipulate a service without affecting critical system functions.

First, let's create a simple service unit file. This file will define a service that simply writes a timestamp to a log file every few seconds.

Create a new service unit file named mytest.service directly in the systemd system directory using nano:

sudo nano /etc/systemd/system/mytest.service

Paste the following content into the nano editor:

[Unit]
Description=My Test Service
After=network.target

[Service]
Type=simple
ExecStart=/bin/bash -c 'while true; do echo "$(date): My Test Service is running." >> /tmp/mytest.log; sleep 5; done'
ExecStop=/bin/bash -c 'echo "$(date): My Test Service stopped." >> /tmp/mytest.log'
Restart=on-failure

[Install]
WantedBy=multi-user.target
  • [Unit]: Contains generic information about the unit. Description provides a human-readable name, and After=network.target specifies that this service should start after the network is up.
  • [Service]: Defines the behavior of the service.
    • Type=simple: Indicates a simple service type where the ExecStart command is the main process.
    • ExecStart: The command to execute when the service starts. Here, it's a bash loop that writes a timestamped message to /tmp/mytest.log every 5 seconds.
    • ExecStop: The command to execute when the service stops. It writes a stop message to the log.
    • Restart=on-failure: Configures the service to restart if it exits with a non-zero status.
  • [Install]: Contains information about how the service should be installed. WantedBy=multi-user.target means this service should be started when the system reaches the multi-user runlevel.

Save the file by pressing Ctrl+X, then Y to confirm, and Enter to save the file.

Now, reload the systemd daemon to recognize the new service file:

sudo systemctl daemon-reload

Starting a Service

To start a service, use the systemctl start command.

Execute the following command to start mytest.service. Note that we need to use sudo because systemctl operations typically require root privileges.

sudo systemctl start mytest.service

There will be no immediate output if the command is successful.

Now, verify that the service is running by checking its status:

systemctl status mytest.service

You should see output indicating that the service is active (running):

● mytest.service - My Test Service
     Loaded: loaded (/etc/systemd/system/mytest.service; disabled; preset: disabled)
     Active: active (running) since ...
   Main PID: ... (bash)
      Tasks: 2 (limit: ...)
     Memory: ...
        CPU: ...
     CGroup: /system.slice/mytest.service
             ├─... /bin/bash -c "while true; do echo \"\$(date): My Test Service is running.\" >> /tmp/mytest.log; sleep 5; done"
             └─... sleep 5

...output omitted...

You can also check the log file to see if the service is writing messages:

tail -f /tmp/mytest.log

You should see new lines appearing every 5 seconds, similar to this:

Tue Jul 22 09:15:09 AM CST 2025: My Test Service is running.
Tue Jul 22 09:15:14 AM CST 2025: My Test Service is running.

Press Ctrl+C to exit tail.

Stopping a Service

To stop a running service, use the systemctl stop command.

Execute the following command to stop mytest.service:

sudo systemctl stop mytest.service

Again, there will be no immediate output.

Verify that the service has stopped:

systemctl status mytest.service

The output should now show Active: inactive (dead):

○ mytest.service - My Test Service
     Loaded: loaded (/etc/systemd/system/mytest.service; disabled; preset: disabled)
     Active: inactive (dead) since ...
...output omitted...

Check the log file /tmp/mytest.log again. You should see the "My Test Service stopped." message and no new "running" messages appearing.

tail /tmp/mytest.log

The output will look similar to this:

Tue Jul 22 09:15:24 AM CST 2025: My Test Service is running.
Tue Jul 22 09:15:28 AM CST 2025: My Test Service stopped.

Restarting a Service

To restart a service, use the systemctl restart command. This command first stops the service and then starts it again. This is useful when you've made changes to a service's configuration and need them to take effect.

Execute the following command to restart mytest.service:

sudo systemctl restart mytest.service

Verify that the service is running again:

systemctl status mytest.service

You should see Active: active (running) again, and the Main PID will likely be a new number, indicating a new process has started.

● mytest.service - My Test Service
     Loaded: loaded (/etc/systemd/system/mytest.service; disabled; preset: disabled)
     Active: active (running) since ...
   Main PID: ... (bash)
      Tasks: 2 (limit: ...)
     Memory: ...
        CPU: ...
     CGroup: /system.slice/mytest.service
             ├─... /bin/bash -c "while true; do echo \"\$(date): My Test Service is running.\" >> /tmp/mytest.log; sleep 5; done"
             └─... sleep 5
...output omitted...

Check the log file /tmp/mytest.log to confirm that the service has resumed writing "running" messages.

tail -f /tmp/mytest.log

You should see a "stopped" message followed by new "running" messages:

Tue Jul 22 09:15:28 AM CST 2025: My Test Service stopped.
Tue Jul 22 09:15:40 AM CST 2025: My Test Service is running.

Press Ctrl+C to exit tail.

Applying Configuration Changes to a Service

In this step, you will learn about reloading service configurations. Some services can apply changes to their configuration files without needing a full restart. This is known as "reloading" the service. Reloading is generally preferred over restarting because it avoids service downtime and preserves existing connections or states. When a service is reloaded, its Process ID (PID) typically remains the same, unlike a full restart where the PID changes.

We will continue to use our mytest.service from the previous step. We will modify its behavior and then attempt to reload it to see what happens.

First, ensure mytest.service is running. If it's not, start it:

sudo systemctl start mytest.service

Verify its status and take note of its Main PID:

systemctl status mytest.service

Now, let's modify the mytest.service file to change the message it logs and the interval. We will change the log message and the sleep duration.

Open /etc/systemd/system/mytest.service with nano:

sudo nano /etc/systemd/system/mytest.service

Change the ExecStart line to the following, modifying the message and the sleep time from 5 to 2 seconds:

[Unit]
Description=My Test Service
After=network.target

[Service]
Type=simple
ExecStart=/bin/bash -c 'while true; do echo "$(date): My Test Service (reloaded) is running." >> /tmp/mytest.log; sleep 2; done'
ExecStop=/bin/bash -c 'echo "$(date): My Test Service stopped." >> /tmp/mytest.log'
Restart=on-failure

[Install]
WantedBy=multi-user.target

Save the file by pressing Ctrl+X, then Y, and Enter.

After saving the changes, you need to inform systemd that the service's configuration has changed.

sudo systemctl daemon-reload

Now, let's try to reload the service to apply the changes:

sudo systemctl reload mytest.service

You will likely encounter an error:

Failed to reload mytest.service: Job type reload is not applicable for unit mytest.service.

This error occurs because our simple service is not configured to handle a reload request. For a service to be reloadable, its unit file must include an ExecReload directive, which specifies the command to run to reload the configuration. Since our mytest.service lacks this, systemd doesn't know how to reload it.

In situations like this, systemd provides a convenient command: reload-or-restart. This command will attempt to reload the service, but if reloading is not supported, it will fall back to restarting the service. This is often a safer and more effective way to apply configuration changes.

Let's use reload-or-restart now:

sudo systemctl reload-or-restart mytest.service

This command should succeed. Now, check the status of the service again:

systemctl status mytest.service

Observe the Main PID. Since our service was restarted (because it couldn't be reloaded), you will notice that the Main PID is a new number. This confirms that the old process was stopped and a new one was started with the updated configuration.

Finally, let's check the /tmp/mytest.log file to see if the changes have taken effect.

tail -f /tmp/mytest.log

You should see the new log message "My Test Service (reloaded) is running." appearing every 2 seconds. Press Ctrl+C to exit tail.

Enable and Disable Services at Boot with systemctl

In this step, you will learn how to configure services to start automatically at boot time (enable) or prevent them from starting at boot (disable). This is crucial for managing system resources and ensuring that necessary services are available when the system starts.

In a typical systemd environment, enabling a service creates symbolic links in the appropriate systemd configuration directories (e.g., /etc/systemd/system/multi-user.target.wants/) that point to the service's unit file. Disabling a service removes these links.

Since we are in a containerized environment where systemd might not be fully operational in the traditional sense, the enable and disable commands might not create actual symlinks in the /etc/systemd/system directory that persist across container restarts. However, systemctl still processes these commands and updates its internal state, which is what we will observe.

We will continue to use our mytest.service for this demonstration.

First, ensure mytest.service is stopped from the previous step:

sudo systemctl stop mytest.service

Enabling a Service

To enable a service, use the systemctl enable command. This command configures the service to start automatically when the system boots.

Execute the following command to enable mytest.service:

sudo systemctl enable mytest.service

You might see output similar to this, indicating that a symbolic link would be created in a full systemd environment:

Created symlink /etc/systemd/system/multi-user.target.wants/mytest.service → /etc/systemd/system/mytest.service.

Now, verify that the service is enabled using systemctl is-enabled:

systemctl is-enabled mytest.service

Expected output:

enabled

This confirms that systemctl now considers mytest.service to be enabled for boot.

You can also combine enabling and starting a service in one command using the --now option. This is a convenient way to ensure a service is both running immediately and configured to start on future boots.

First, let's disable it to prepare for the --now demonstration:

sudo systemctl disable mytest.service

Now, enable and start it simultaneously:

sudo systemctl enable --now mytest.service

Verify its status and enablement:

systemctl status mytest.service
systemctl is-enabled mytest.service

You should see Active: active (running) from the status command and enabled from the is-enabled command.

Disabling a Service

To disable a service, use the systemctl disable command. This command removes the configuration that causes the service to start at boot time.

Execute the following command to disable mytest.service:

sudo systemctl disable mytest.service

You might see output indicating the removal of the symbolic link:

Removed /etc/systemd/system/multi-user.target.wants/mytest.service.

Now, verify that the service is disabled:

systemctl is-enabled mytest.service

Expected output:

disabled

Similar to enabling, you can combine disabling and stopping a service using the --now option. This will stop the service immediately and prevent it from starting on future boots.

sudo systemctl disable --now mytest.service

Verify its status and enablement:

systemctl status mytest.service
systemctl is-enabled mytest.service

You should see Active: inactive (dead) from the status command and disabled from the is-enabled command.

This concludes the demonstration of enabling and disabling services. Remember that in a real systemd environment, these commands directly manipulate the boot configuration.

Mask and Unmask Services with systemctl

In this final step, you will learn about masking and unmasking services. Masking a service is a powerful way to prevent it from being started, either manually or automatically at boot.

When you mask a service, systemd creates a symbolic link from /etc/systemd/system/<service-name>.service to /dev/null, effectively making the service unit file unavailable to systemd. This is a stronger alternative to disable.

This mechanism works best for services that are defined in /usr/lib/systemd/system, which is where packages install their service files. The mask command creates an overriding "empty" file in /etc/systemd/system. However, as you have discovered, if you try to mask a service that you created directly in /etc/systemd/system (like our mytest.service), the command can fail because it is designed to not overwrite an existing configuration file, which would cause data loss.

To demonstrate masking correctly, we will use a pre-existing service, atd.service.

First, let's check the current status of atd.service. It should be active and enabled.

systemctl status atd.service

The output will be similar to this, showing the service is active and running:

● atd.service - Deferred execution scheduler
     Loaded: loaded (/usr/lib/systemd/system/atd.service; enabled; preset: enabled)
     Active: active (running) since Tue 2025-07-22 09:13:06 CST; 22min ago
       Docs: man:atd(8)
   Main PID: 1222 (atd)
      Tasks: 1 (limit: 22509)
     Memory: 900.0K
        CPU: 5ms
     CGroup: /system.slice/atd.service
             └─1222 /usr/sbin/atd -f

Masking a Service

It's good practice to stop a service before masking it.

sudo systemctl stop atd.service

Now, execute the following command to mask atd.service:

sudo systemctl mask atd.service

You will see output indicating the creation of a symbolic link to /dev/null:

Created symlink /etc/systemd/system/atd.service → /dev/null.

Now, try to start the masked service:

sudo systemctl start atd.service

You will receive an error message, indicating that the service is masked:

Failed to start atd.service: Unit atd.service is masked.

You can also check the state of the service using systemctl list-unit-files:

systemctl list-unit-files --type=service | grep atd.service

The output should show masked for atd.service:

atd.service                            masked      enabled

This confirms that the service is now masked and cannot be started.

Unmasking a Service

To unmask a service, use the systemctl unmask command. This command removes the symbolic link to /dev/null, restoring the original service file from /usr/lib/systemd/system.

Execute the following command to unmask atd.service:

sudo systemctl unmask atd.service

You will see output indicating the removal of the symbolic link:

Removed "/etc/systemd/system/atd.service".

Now, check the state of the service using systemctl list-unit-files again:

systemctl status atd.service

You should see Active: active (running), similar to this:

● atd.service - Deferred execution scheduler
     Loaded: loaded (/usr/lib/systemd/system/atd.service; enabled; preset: enabled)
     Active: active (running) since Tue 2025-07-22 09:36:10 CST; 2s ago
       Docs: man:atd(8)
   Main PID: 7372 (atd)
      Tasks: 1 (limit: 22509)
     Memory: 868.0K
        CPU: 6ms
     CGroup: /system.slice/atd.service
             └─7372 /usr/sbin/atd -f

This concludes the lab on controlling services and daemons. You have learned how to view, start, stop, restart, reload, enable, disable, mask, and unmask services using systemctl.

Summary

In this lab, we gained hands-on experience managing control system services using the systemctl command, even within a containerized environment where systemd might not be the primary init system. We learned how to list all loaded and active service units using systemctl list-units --type=service, understanding the UNIT, LOAD, ACTIVE, and SUB columns to interpret service states.

Furthermore, we explored essential service management operations: checking the status of a specific service with systemctl status, and controlling service lifecycle by starting, stopping, and restarting services. We also covered how to reload service configurations, enable and disable services to control their behavior at boot time, and the advanced concepts of masking and unmasking services to prevent them from being started. This comprehensive set of skills provides a solid foundation for managing services on RHEL systems.