1 of 55

Services and Processes

Lecture 4

owent, zoey

(slide credits kmo, rrchan, cooperc, keur)

2 of 55

Course Resources

  • Your facilitators!
  • Ed, Gradescope
  • OCF Slack (ocf.io/slack) or Discord (ocf.io/discord) #decal-general
  • All materials available at decal.ocf.io
  • Ask questions / work on lab with us during lab sessions! (Tues 8-9pm in OCF Lab)

3 of 55

Outline

  • Processes
  • Services
  • Intro to systemd

4 of 55

Disclaimer

  • This is not cs162
  • This topic gets very deeply technical and we will only scratch the surface here
  • Main goal: become a more productive Linux user, not a kernel hacker

5 of 55

Processes

6 of 55

What is a process?

A process is a single instance of a program.

Processes are isolated from one another and have their own memory, threads, etc. (Additional isolation, such as filesystem or network isolation, is also possible.)

7 of 55

What is a process?

  • PID: Process ID
  • PPID: Parent’s PID
  • UID: User running the process
  • The program (executable) that the process is running
  • The args (command line) of the process

(and more…)

8 of 55

Init

  • First process started at boot, given PID 1
    • Manages all other services and processes
  • Run htop, open tree view (f5). What is the root of the tree?

9 of 55

10 of 55

Process Hierarchy

Each process is created by a parent

(Except PID 1)

Processes can have many children

11 of 55

Processes vs Threads

A process has one or more threads.

  • Processes have their own data and code, must use pipes, files, etc. to communicate with one another
  • Threads share the same process but have different system states (“multithreaded process”)

12 of 55

Aside: Why does Chrome spawn so many processes?

13 of 55

How are processes created?

A process will fork(2) into a two new processes, which continue from the same place

The parent keeps the original PID and the child gets a new PID

Optionally, the new process (the child) exec(3) and begin running a new program

14 of 55

How many “henlo”s get printed?

int main( void ) {� fork();printf( "henlo: %d\n", getpid() );}

15 of 55

How many “henlo”s get printed?

int main( void ) {� fork();printf( "henlo: %d\n", getpid() );}

int main( void ) {� fork();printf( "henlo: %d\n", getpid() );}

int main( void ) {� fork();printf( "henlo: %d\n", getpid() );}

PID 1000

PID 1000

PID 2000

16 of 55

How many “henlo”s get printed?

int main( void ) {� fork();

fork();

fork();printf( "henlo: %d\n", getpid() );}

2^1

2^2

2^3

17 of 55

Have you seen this code before?

:(){ :|:& };:

bomb() {

bomb | bomb &

} bomb

18 of 55

Making the child do something

int main( void ) {

if ( fork() > 0 ) {

/* parent process */

wait( NULL );

} else {

/* child process */

execv( “/bin/bash”, NULL );

}}

19 of 55

htop exploration

  • htop(1): interactive terminal process manager
  • https://peteris.rocks/blog/htop/
  • PID/User/Command/CPU%/MEM%/TIME: self-explanatory
  • PRI/NI: Priority and Niceness (take cs162, or google scheduling policy/SCHED_OTHER)
  • VIRT/RES/SHR: virtual image, resident size, shared memory usage
  • S: Status (S = sleep, R = running, T = terminated, Z = zombie)

20 of 55

What does this code do?

int main( void ) {

if ( fork() > 0 ) {

/* parent process */

sleep( 1 );

} else {

/* child process */

exit( 1 );

}}

21 of 55

What does this code do?

\_ /usr/bin/zsh

\_ ./zombie-creator

\_ [zombie-creator] <defunct>

Parent

Child

22 of 55

Zombie Process

When a child has died but has not been “reaped”

Child metadata stays in process table so parent can collect exit status

Totally normal, all children that exit are zombies!

23 of 55

24 of 55

What happens when a process dies

if ( fork() > 0 ) {/* parent process */� sleep( 1 );

} else {/* child process */exit( 1 );

}

When a process exits, returns int (exit code 0-255)

0 is success and anything else indicates an error

25 of 55

What happens when a process dies

if ( fork() > 0 ) {/* parent process */� sleep( 1 );

} else {/* child process */exit( 123 );

}

When a process exits, returns int (exit code 0-255)

0 is success and anything else indicates an error

26 of 55

Parents need to wait() on children

int main( void ) {

if ( fork() > 0 ) {

int status;

sleep( 1 );

wait( &status );

printf( "%d\n", WEXITSTATUS ( status ) );

} else {

exit( 123 );

}

27 of 55

What happens if the parent exits first?

If parent exits first, orphan processes are re-parented by the init process

init reaps all orphans that are zombies

28 of 55

Orphans

int main( void ) {

if ( fork() > 0 ) {

/* parent process */

sleep ( 1 );

exit( 0 );

} else {

/* child process */

sleep( 100 );

exit( 123 );

}

Process tree after start

Process tree after 1 second

Parent

Child

Parent

Child

29 of 55

When can zombies become a problem?

Parent doesn’t wait() on children

Parent is long running process

Zombie child processes never become orphans

Resource leakage!

30 of 55

Zombie leakage in the wild

31 of 55

Inter-process Communication

Various ways in which processes can communicate

  • Exit codes
  • Signals (e.g. SIGTERM, SIGKILL, SIGINT)
  • Pipes (STDIN, STDOUT, STDERR)
  • Sockets (UNIX socket, IP socket)
  • Message Bus (e.g. dbus on Linux)
  • … and many many more...

32 of 55

Process Signals

  • SIGTERM: tell a process to exit now
  • SIGKILL: terminate process immediately
  • SIGINT: interrupt, when you press Ctrl+C
  • SIGHUP: the user closes the terminal window
  • SIGWINCH: terminal window resized
  • SIGSTOP / SIGCONT: stop/resume

SIGKILL and SIGSTOP cannot be handled

33 of 55

Services

34 of 55

What is a service?

  • A service is a type of process known as a Daemon
    • A daemon is a noninteractive background process
    • Typically names end with a ‘d’, but not always the case
  • Services are controlled by an init system
  • Examples: sshd, httpd, rsyslogd, nginx, postfix, ...
  • Not a strict definition

35 of 55

Services - What’s the point?

  • Can run for long periods of time
    • Useful in many cases, such as web servers
  • Can be publicly accessible or shared between multiple users
    • Can be networked.
  • Ex. sshd allows for incoming ssh connections - very important
  • Can write your own services!

36 of 55

Systemd

  • Systemd is an init system that manages processes and services
    • Most commonly used init system on modern Linux systems
  • Provides tools for users to manage services
    • systemctl - start, stop, check status, and more
    • journalctl - check systemd journal
  • Some debate in the free software community about systemd
    • systemd bad use runit

37 of 55

Systemd Unit Files

  • Service behavior defined by systemd unit files
    • How should this service start up? How should it respond to various systemctl management commands?

38 of 55

A (simplified) Unit File: helloworld.service

[Unit]�Description=A simple unit file

[Service]�ExecStart=/usr/bin/helloworld�User=ocfstaff Restart=always

[Install]�WantedBy=multi-user.target

Description - what the service does

Commands

When this unit should get started

39 of 55

Example Unit file - Nginx

40 of 55

systemctl (no args) - Info about systemd units

41 of 55

systemctl status [name] - Gets info about a service’s status

42 of 55

More systemctl!

  • systemctl start [name] - starts a service
  • systemctl stop [name] - stops a service
  • systemctl restart [name] - restarts a service
  • systemctl reload [name] - reload a service’s configuration
  • systemctl enable [name] - sets a service to start on boot
  • systemctl disable [name] - opposite of enable

Behavior for these commands depends on the service, as defined in the unit file, but typically will do the things listed above.

43 of 55

Example - sshd

  • Handles ssh connections

  • Notice that bash and htop are children of sshd, since I am ssh’d into this machine.

44 of 55

Example - nginx and httpd

  • nginx - http webserver daemon named ‘Nginx’
  • httpd - http webserver daemon named ‘Apache’

Both examples of services which listen on port 80 and serve content.

45 of 55

Problem: systemd sucks

  • Extremely complicated especially on large systems
  • This can and has led to security issues
  • Also doesn’t abide by the “UNIX Philosophy”
    • This is another way of saying that Linux nerds don’t agree about how it has assumed its role in most systems

46 of 55

Problem: systemd sucks, and people care

  • The rest of this is redacted because it devolved into name-calling

47 of 55

Bonus: Runit

  • A better init system that systemd (bc I said so)
  • Minimal
  • Understand your services
  • Average Runit User:

48 of 55

About Runit

  • Created for the Void Linux distribution
    • Artix, Parabola
  • Uses file, symbolic link, and folder management to start, stop, enable, disable, etc
  • Everything is executable!

49 of 55

Hierarchy

  • runsvdir: /etc/runit/runsvdir/current OR /run/runit/service #symlink
  • Service Directory: /etc/runit/sv/myservice
    • ../myservice/run #executable
    • ../myservice/log/run #executable
    • And more!

50 of 55

Example: dbus

51 of 55

Example: udevd

52 of 55

Service Management

  • Enabling:�ln -s /etc/runit/sv/dbus /run/runit/service/
  • Disabling:�rm /run/runit/service
  • Stop on boot:�touch /etc/runit/sv/dbus/down
  • Start on boot:�rm /etc/runit/sv/dbus/down

53 of 55

Service Management

  • Start: sv up dbus
  • Stop: sv down dbus
  • Run Once: sv once dbus
  • Restart: sv status dbus
  • Status: sv status dbus
  • Etc…!

54 of 55

Minimal Philosophy

  • Always prefer minimal, simple software
    • Readable
    • Bug Free
    • Simple
    • Unix Philosophy: �Good at one thing and one thing only
  • Also systemd is bad
  • Like really bad

55 of 55

Like Really Bad (not OCF endorsed msg)