Information Technology: An Introduction for Today’s Digital World
.)
132
◾
Linux with Operating System Concepts
between threads is often handled faster than context switching between processes. For
one reason, switching between processes may involve loading program code from virtual
memory into main memory. This should not happen when switching between threads.
Threads are a newer idea in programming but are available in most operating systems.
However, to take advantage of threads, the program must be written using threads and
you must be running multiple threads of the same program. A multitasking system that is
switching off between threads is known as a multithreaded system. Thus, a multitasking
system can also be multithreading.
Another form of process management occurs when the computer has multiple pro-
cessors. This is known as multiprocessing. In this case, the operating system selects the
processor to run a given process. In this way, multiple processors can execute their own
processes. Typically, once launched onto a processor, the process remains there. However,
load balancing allows the operating system to move processes between processors if neces-
sary. In addition, some programs are set up to themselves be distributed to multiple pro-
cessors in which case one process might execute in parallel on more than one processor,
each processor in charge of some portion of the overall process. Today’s multicore proces-
sors permit multiprocessing.
Linux by default uses cooperative and preemptive multitasking and multithreading.
Programmers who wish to take advantage of multiprocessing must include instructions
in the program that specify how to distribute the process. Linux can also perform batch
processing on request using the batch instruction (covered in Chapter 14).
4.2.3 Interrupt Handling
We mentioned above that the timer interrupts the CPU. What does this mean? Left to itself,
the CPU performs the fetch–execute cycle repeatedly until it finishes executing the current
program. But there are occasions where we want to interrupt the CPU so that it can focus
its attention elsewhere. The timer reaching 0 is just one example.
We refer to the situation where something needs attention by the CPU as an
interrupt
request
(IRQ). The IRQ may originate from hardware or software. For hardware, the IRQ
is carried over a reserved line on the bus connecting the hardware device to the CPU (or
to an interrupt controller device). For software, an IRQ is submitted as an interrupt signal
(this is explained in Section 4.6.2 later in this chapter).
Upon receiving an interrupt, the CPU finishes its current fetch–execute cycle and
then decides how to respond to the interrupt. The CPU must determine who raised the
interrupt (which device or if it was raised by software). IRQs are prioritized so that if the
CPU is handling a low-priority IRQ, it can be interrupted to handle a higher priority
IRQ. The CPU acknowledges the IRQ to the interrupting device. Now, it must handle
the interrupt.
To handle the interrupt, the CPU switches to the operating system. For every type of
interrupt, the operating system contains an
interrupt handler
. Each interrupt handler is
a piece of code written to handle a specific type of interrupting situation. The CPU per-
forms a context switch from the current process to the proper interrupt handler. The CPU
Managing Processes
◾
133
must save what it was doing with respect to the current process as explained in the last
subsection.
In Linux, interrupt handlers are part of the kernel. As the interrupt handler executes,
information about the interrupt is recorded under /
proc/interrupts
. This file stores
the number of interrupts per I/O device as well as the IRQ number for that device. If you
have multiple CPUs or multiple cores, you receive a listing for each of the CPUs/cores.
We see an example of the /
proc/interrupts
file below for a computer with two
CPUs (or two cores). The first column lists the IRQ associated with the given device. The
second column is the number of interrupts from the device for each of the two CPUs. The
third column is the device’s driver and the last column is the device’s name. Notice that the
timer has the most number of interrupts by far, which is reasonable as the timer interrupts
the CPU many times per second.
CPU0 CPU1
0:
20342577 20342119 IO-APIC-edge
timer
12: 3139
381
IO-APIC-edge i8042
59: 22159 6873
IO-APIC-edge eth0
64: 3
0
IO-SAPIC-EDGE ide0
80: 4
12
IO-SAPIC-edge keyboard
The file /
proc/stat
also contains interrupt information. It stores for each IRQ the
number of interrupts received. The first entry is the sum total of interrupts followed by
each IRQ’s number of interrupts. For instance, on the processor above, we would see an
entry of
intr
where the second number would be 40684696 (the sum of the interrupts
from the timer, IRQ 0). The entire
intr
listing will be a lengthy sequence of integer num-
bers. Most likely, many of these values will be zero indicating that no interrupt requests
have been received from that particular device.
4.3 STARTING, PAUSING, AND RESUMING PROCESSES
Starting a Linux process from the GUI is accomplished through the menus. The GUI is
launched at OS initialization time and is spawned by the init process. As the user runs
programs, those are spawned by the GUI (e.g., Gnome). Some application processes will
spawn additional processes as well. For instance, the user may be running the Firefox web
browser. Opening a new tab requires spawning a child process (actually a thread). Sending
a web page’s content to the printer spawns another process/thread.
4.3.1 Ownership of Running Processes
Many running processes require access to files (as well as other resources). For instance, if
you are running the vi text editor, you may want to open a file in your home directory or
save a file to your home directory. How then does the vi process obtain access rights (espe-
cially since you probably do not permit others to write to your directory)? When a process
is launched by the user, the process takes on the user’s UID and the user’s private group’s
134
◾
Linux with Operating System Concepts
GID. That is, the process is running as an extension of you. Therefore, the process has the
same access rights that you have. This is perfectly suitable in many cases.
However, some applications require access to their own file space and their own files. For
instance, the lp command (print files) copies the output to a printer spool file, located
in /var/spool. This space is not accessible to the user. So how does lp write the data there?
When some software is installed, a special account is created for that software. Thus, lp has
its own user account. You might examine the /etc/passwd file for other software accounts
(you will find, among others, accounts for mail, halt, ftp, and the apache web server). For lp,
it has a home directory of /var/spool/lpd and a login shell of /sbin/nologin. There is no login
shell because we do not want people to attempt to log in using lp’s account and gain access to
system files. You will see that the various software accounts have home directories in the top
level directories of /sbin, /proc, or /var. In running lp, the operating system switches from
you the user to lp the software account. Now lp has access to its own file space.
In other situations, the process does not need its own account but it still has to
gain access to system files. Consider the passwd command. This program is owned
by root. When a user runs passwd, the program accesses the password file (which is
stored in/ etc/shadow, not/etc/passwd) first to ensure that the user has entered the correct
current password. Then the program accesses the file again to modify the password. When
a user runs passwd, it should run under the user’s account. But the shadow file is only
accessible to root. The way Linux gets around this problem is to provide a special bit in the
permissions that indicate that the process should be owned not by the user who launched
the process, but by the owner of the file containing the program’s executable code. In the
case of passwd, this is root. Therefore, because this special bit is set, when running passwd,
it takes on root’s ownership. Now it can access the /etc/shadow file that is only accessible
to root.
To set up a program to execute under the ownership of the file’s owner, you need to
alter the permissions (using chmod as described below). To determine if a process will run
under the user’s ownership or the file’s ownership, inspect the file’s permissions through
a long listing. You will find that the owner’s executable bit is not set to ‘x’ but to ‘s.’ If you
alter the owner’s execution status, the permission changes from ‘x’ to ‘s.’ Similarly, you can
change the group execution. If the executable bit is set to s, this is known as setting user
permission ID or setting group permission ID (SUID, GUID). By altering the executable
bit, the program, when running, switches it’s owner or group ID. The programs passwd,
mount, and su, among others, are set up in this way.
Let us take passwd as a specific example. If you look at the program, stored in /usr/bin,
you find that it has permissions of
-r-s--x--x
and its owner and group are both root.
Thus, root is able to read it and for execute, it has the letter ‘s.’ The world has execute access.
So, any user can run passwd. But when running passwd, the program is granted not the
user’s permissions but the file owner’s permissions. That is, passwd runs under root and
not the user. If you look at the /etc/passwd file, which the passwd program may manipulate,
it has permissions of
-rw-r--r--
and also has root for its owner and group. So passwd,
running under your user account would not be able to write to the /etc/passwd file. But
passwd running under root can. Thus, the executable bit for passwd is ‘s’ for the owner.
Managing Processes
◾
135
When the execution permission for owner is changed to ‘s,’ this changes the effective user
of the program. The real user is still the user who issued the command. The effective user is
now the program’s owner (root in this case). This is also known as the EUID (effective user
ID). Similarly, setting the group ID on execution changes the effective group (EGID).
To change the execution bit use chmod. Recall from Chapter 3 that there were three
ways to use chmod, ugo
+
/-, ugo
=
, and the three-digit permission. You can change the
execution bit from x to s (or from nothing to s) and from s to x (or from s to nothing) using
the
+
/- approach and the three-digit approach. The ugo
=
approach cannot be used. With
the ugo
+
/- approach, merely substitute ‘s’ for ‘x’ as in
u
+
s
or
g
+
s
. You can also reset the
value back to ‘x’ using
u
-
s
+
x
(or
g
-
s
+
x
), and you can remove execute access entirely with
u
-
s
or
g
-
s
.
The three-digit approach is different in that you use a four-digit number. If you want to
establish the ‘s’ for the user, prepend a 4 to the 3-digit number. For instance, if you want a
file to have permission of -
rwsr
-
xr
-
x
, you would normally use 755 to indicate that every-
one should have execute access. Now, however, you would prepend a 4, or 4755, to state that
the file should be rwxr-xr-x but with an ‘s’ for the user’s execution bit. Similarly, you would
prepend a 2 to change the group’s execution from ‘x’ to ‘s.’ You would use 6 to change both
user and group execution status. Below are several examples.
4744 _ rwsr--r--
4754 _ rwsr-xr--
4755 _ rwsr-xr-x
6755 _ rwsr-sr-x
2750 _ rwxr-sr--
2755 _ rwxr-sr-x
To reset the execution bit from ‘s’ to ‘x,’ prepend a 0, as in 0755 to reset
rwsr
-
xr
-
x
to
rwxr
-
xr
-
x
. Recall from Chapter 3 that prepending a 1 to the three-digit number, as in
1777, adds the sticky bit to the executable permission for world. With SUID and GUID,
we used 4xxx and 2xxx to change the executable permission for owner and group, respec-
tively. The sticky bit though is used on directories to control write access to already existing
files within the directory.
4.3.2 Launching Processes from a Shell
Launching processes from within a shell is accomplished by specifying the process name.
You have already seen this in Chapters 2 and 3. If the file storing the program is not in a
directory stored in the PATH variable, then the command must include the directory path.
This can be specified either with an absolute or relative path. As an example, /sbin may not
be in the user’s PATH variable because it contains system administration programs. To
execute the
ifconfig
program (which displays information about network connectivity
and IP addresses), you might have to enter /
sbin/ifconfig
.
Launching your own programs is slightly different from launching system programs.
These programs will include any that you have written and compiled into executable pro-
grams as well as shell scripts. The notation to run such a program is .
/filename
if the
program is in the current directory. If the file is in another directory, you do not need to
use the .
/
notation.
136
◾
Linux with Operating System Concepts
To this point, most of the programs you have executed from the command line have run
quickly. The result of the program is some output sent to the terminal window and then the
command line prompt is made available to you again. What happens if you have a lengthy
process to run and yet you want to continue to work through the command line? If the
program you are going to run can run in a batch mode, then you can launch it and regain
the command line prompt while the program is still executing. Batch mode means that the
process will run independently of the user, or without interaction. Consider, for instance,
that you want to use find. Recall that find, when run on the entire file system, can take a lot
of time. The command you want to execute is
find / -perm 000
>
results.txt
Because this instruction needs no input from the user, and because its output is being
sent to a file and so will not interfere with the user running other programs, we should
be able to launch it as a batch process. In order to do so, when issuing the command, end
the command with the character &. This denotes that the process should run in the
Do'stlaringiz bilan baham: |