Lab 6 - Processes and Services

Overview

At any given moment, there are anywhere from dozens to thousands of process running on a Unix system. The large majority of these processes, called daemons, run in the background. Daemons are crucial to having a usable system and provide much of a system’s core functionality, including the graphics server, sound server, and networking services to name a few.

Today we’ll explore these background processes and create some of our own! Make sure the following exercises are executed on your VM unless explicitly specified otherwise. Make sure to answer the questions on the google form as you work through the lab:

Google Form Exercises

Which processes are running on my system?

Open up a terminal and run the ps command. You should see something like this:

  PID TTY          TIME CMD
 3634 pts/2    00:00:00 ps
15015 pts/2    00:00:00 bash

Now open up another terminal and run sleep 1000 in the background, and then run ps. It should look like:

$ sleep 1000 &
[1] 29756
$ ps
  PID TTY          TIME CMD
29446 pts/2    00:00:00 bash
29756 pts/2    00:00:00 sleep
29757 pts/2    00:00:00 ps

In the first terminal run ps again. You should notice that the sleep process is not showing up, even though the thousand seconds haven’t expired. (Exercise 1) Why do you think this behavior occurs (hint: TTY column)?

We can get the process to display on the first terminal by running ps -u, which displays all the processes running as your user. Notice the PID column; each process has a unique ID assigned to it by the kernel. One thing we can do with this PID is send signals to the process. sleep 1000 is pretty useless, so go ahead and kill it – kill 29756 (substitute 29756 with whatever PID ps outputted for you).

The most common use of ps is to run ps -ef to see all the processes running on the system. Run ps -e and ps -f independently to see how the flags work together.

htop

Make sure htop is installed by running sudo apt install htop.

Now, open up a terminal and run the htop command. htop can be thought of as a more extensive version of ps -ef, whereby process stats are updated in real-time.

First press <F2>, scroll down to Display options, and check “Hide userland process threads.” We won’t be dealing with those in this lab.

Now open up another terminal and SSH into your VM. Run the command yes. It uses a lot of resources as it prints a continuous stream of y’s. (Exercise 2) What resource specifically does the yes command exhaust? If you are having trouble finding this, press < to choose which resource to order processes by. Make sure to quit out of yes (^C) once you are finished.

The process hierarchy

Run htop once more. This time click <F5> to enter Tree View. You should see a visual representation of the process hierarchy on your system, with everything stemming from /sbin/init (systemd).

For curious students that are interested in seeing a more extensive process hierarchy on a large system, you are encouraged to run htop on the OCF server tsunami. Let us know of any cool processes that you find!

Orphan processes

Open a second terminal and SSH to your VM. Now run sleep 1000 &. You should see this new process pop into your htop session on your first terminal. If not, press <F3> and search for “sleep.” (Exercise 3) What is its parent?

Select this parent and press <F9> to kill it. Send the SIGTERM signal. The sleep process now has init as its new parent, which is PID 1. What you just did is manually orphan a process; when that happens said process is subsequently re-parented by the init process.

Now go through the same steps again. This time, send the parent a SIGHUP (hangup) signal. Can you still find the sleep process? When SIGHUP is sent to a parent shell, the parent subsequently sends hangup signals to any child processes before terminating; all processes that receive SIGHUP from a parent shell will terminate – this is one way to avoid creating orphan processes.

If you are interested in learning about the different signals, run man 7 signal. Note that you can run man man for an explanation about the different manual section numbers.

Cron

So much infrastructure in the computing world relies on scheduled processes. This is the job of the cron daemon. For example, at the OCF, we use a cron job that runs every thirty minutes to keep our servers and desktops updated via puppet. To get a feel for the cron scheduler, we’re going to write a basic cron job.

(Exercise 4) Open the cron editor by running crontab -e (if the editor of your choice isn’t being launched, set the EDITOR environment variable), which will create a crontab for your user. Below is a sample task. Put this in your crontab:

* * * * * date +"\%T" >> $HOME/timestamps.txt

Right now this runs every minute. Modify it to run every five minutes and quit out of the editor. Make sure to leave this running while you complete the remainder of the lab as you will be turning this file in.

If you get stuck, visit crontab.guru!

Using systemd

What services are running right now?

Run systemctl. You’ll see a long table of every unit known to systemd.

Let’s narrow it down to services for now. Run systemctl --type=service. Now you can see a list of all services running on your computer. Each of these services is a daemon running in the background. Do you see any familiar services running?

Controlling Services

Now let’s use systemd to control a an nginx web server. Install nginx by issuing sudo apt install nginx. Once that is done we can tell systemd to start the service with the following: sudo systemctl start nginx. Run systemctl status nginx to ensure it is running and navigate to http://yourvm.decal.xcf.sh/ – you should be greeted by the nginx default landing page.

Now let’s make nginx listen for connections on the nonstandard port 420. In /etc/nginx/sites-available/default change the following lines:

listen 80 default_server;
listen [::]:80 default_server;

to:

listen 420 default_server;
listen [::]:420 default_server;

Tell systemd that nginx has changed configuration and needs reloading with: sudo systemctl reload nginx. Now, accessing http://yourvm.decal.xcf.sh/ should now give you a connection refused error and your webserver will only be accessible via http://yourvm.decal.xcf.sh:420/.

Note that not all services can be reloaded; systemd will notify you if this is the case and such services will have to be restarted instead with: sudo systemctl restart yourservice.

Finally go ahead and stop the nginx service with sudo systemctl stop nginx.

(Exercise 5) What is the difference between systemctl reload yourservice and systemctl reload restart yourservice?

Creating a service

Let’s set up a web server and create a systemd unit for it. Make sure git is installed; if it’s not, install it using apt.

To get the code run: git clone https://github.com/0xcf/decal-labs.git

If you have already cloned the repository, go to your decal-labs directory and run git pull. The materials for this part of the lab will be in the b6 directory.

We will also need to install some dependencies. Go ahead and execute the following commands: sudo apt update sudo apt install build-essential make python-virtualenv

Now run ./run. This should start up a simple web server at http://yourvm.decal.xcf.sh:5000

Your mission, should you choose to accept it, is to write a systemd service that manages this web server. To do this, make a new unit file in /etc/systemd/system/toy.service. Refer to the slides for an example; DigitalOcean also has a good guide on how to write systemd units. Here is a skeleton; all you need to do is fill in the values for each field.

[Unit]
Description=
Requires=
After=

[Install]
WantedBy=multi-user.target

[Service]
ExecStart=
User=

Some questions worth considering while writing this unit file are:

You are encouraged to experiment with other fields as suits your liking.

Once you have finished creating toy.service, let’s start the service and have the it start whenever our machine is booted.

# systemctl start toy.service
# systemctl enable toy.service

Debugging

You can check if the unit file succeeded by running systemctl status toy.service. If you are having issues with the unit file or the web server, check the logs for this unit by running journalctl -u toy.service. If you run into errors don’t get demoralized (it is, after all, only a decal); as a sysadmin you’ll have to become comfortable making sense of arcane error messages.

Crash the service!

(Exercise 6) One of the great benefits of using systemd to manage your services is that you don’t have to worry unnecessarily about bringing a process back up if it crashes. So let’s crash the service! You can do this by either sending a POST request with the json payload '{"crash":"true"}' to http://yourvm.decal.xcf.sh:5000/crash (Hint: use cURL) or by killing the webserver manually by sending a signal – both will cause the unit to crash. You can verify if you succeeded by running systemctl status toy.service, and the unit should either be in an inactive or failed state, depending on how you killed it.

Now add the following the /etc/systemd/system/toy.service under the Service directive:

Restart=always
RestartSec=10

To tell systemd that the unit file has changed run sudo systemctl daemon-reload. Now start your webserver and kill it again in any way you please, and you should see that it come back online after 10 seconds! Note that you can also run daemon-reload and change a unit file while a service is running.

(Exercise 7) Upload your fully featured toy.service file to the google form.

Exploration

Congratulations, you have completed the lab! This is just the tip of the iceberg when it comes to processes and services. If you want to learn more, here are some related topics you can look into.