# Chapter 10 Exercises
## Daniil Gubajdullin BS19-01
### +Task 1
Suppose a system contains two device files that have the same major and minor number and are both character devices. ff two processes wish to open the physical device simultaneously, show that it makes no difference whether they open the same device file or different device files. What happens when they close the device?
#### Solution:
The kernel uses the major number at open time to dispatch execution to the appropriate driver.
The minor number is used only by the driver specified by the major number; other parts of the kernel don’t use it, and merely pass it along to the driver. It is common for a driver to control several devices. The minor number provides a way for the driver to differentiate among them.
This is why it doesn't matter which file to open.
When one of the process close one of the file, the second file will close too.
### +Task 2
Recall from Chapter 5 that the mknod system call requires superuser permission to create a device special file. Given that device access is governed by the permission modes of a file, why must mknod require superuser permission?
#### Solution:
With $\textbf{mknod}$, you create device-special files that allow raw access to the hardware. That is, the kernel looks at the device-special file's permissions to decide whether a given user is allowed raw acess to hardware, not to anything in configuration or some such.
Thus, if regular users would be able to create device-special files, then they would be able to bypass all kernel security and access all hardware directly by simply creating a device-special file (in their home directory, say), and using that to nuke the hard disk.
As such, creating device-special files can only be done by $\textbf{root}$.
### Task 3
Write a program that verifies that the file systems on a disk do not overlap. The program should take two arguments: a device file that represents a disk volume and a descriptor file that gives section numbers and section lengths for the disk type. The program should read the super blocks to make sure that file systems do not overlap. Will such a program always be correct?
#### Solution:
### Task 4
The program mkfs initializes a file system on a disk by creating the super block, leaving space for the Mode list, putting all the data blocks on a linked list, and making the root Mode directory. How would you program mkfs? How does the program change if there is a volume table of contents? How should it initialize the volume table of contents?
#### Solution:
### +Task 5
The programs mkfs and .fsck (Chapter 5) are user-level programs instead of part of the kernel. Comment.
#### Solution:
These two programs are part of the user-level because they work with file systems and so that the operating system can prevent them from making changes that can harm it, they put them in the user-level instead of the kernel
### +Task 6
Suppose a programmer wants to write a data base system to run on the UNIX system.
The data base programs run at user level, not as part of the kernel. How should the
system interact with the disk? Consider the following issues:
* Use of the regular file system interface versus the raw disk,
я думаю регулярку, тк проще будеет управлять данными в отличии от прямого доступа к дискам. Плюс у нас запускается в юзер левел, надо помнить об абстракции и расмтраивать бд как обычную программу
* Need for speed,
храним файлы в раме и записываем на диск временами, ну тип как ОС и делает
* Need to know when data actually resides on disk,
они всегда находятся на диске, при записе они сразу записываются на диск, скорость чтения важнее чем запись, имхо.
* Size of the data base: Does it fit into one file system, an entire disk volume, or several disk volumes?
для консистенса бд должна быть умещена в parttion of disk. можно опрделеить entire disk volume как один partion
#### Solution:
1. Need to use regular file system, because it is easier to control the data than having direct access to the disk. As well, because we run DB in user-level, must not forget about abstraction.
2. Just as the OS does now, need to save data in RAM and sometimes save to the disk.
3.
4.
### +Task 7
The UNIX kernel tacitly assumes that the file system is contained on perfect disks. However, disks could contain faults that incapacitate certain sectors although the remainder of the disk is still "good." How could a disk driver (or intelligent disk controller) make allowances for small numbers of bad sectors. How would this affect performance?
#### Solution:
There are two types of bad sectors on disk - $\textbf{physical}$ and $\textbf{logical}$.
$\textbf{Physical}$(hard) - bad sector on the hard drive that’s physically damaged.
$\textbf{Logical}$(soft) - bad sector is a cluster of storage on the hard drive that appears to not be working properly.
Bad sectors may be detected by the operating system or the disk controller. Most file systems contain provisions for sectors to be marked as bad, so that the operating system avoids them in the future.
Of course, the operation of marking sectors as bad slows down both the disk, programs, and the operating system as a whole.
### Task 8
When mounting a file system, the kernel invokes the driver open procedure but later releases the Mode for the device special file at the end of the mount call. When umounting a file system, the kernel accesses the mode of the device special file, invokes the driver close procedure, and releases the mode. Compare the sequence of Mode operations and driver open and close calls to the sequence when opening and closing a block device. Comment.
почитать [сайт](https://www.oreilly.com/library/view/linux-device-drivers/0596000081/ch12s05.html) !!! а так не ебу
#### Solution:
### +Task 9
Run the program in Figure 10.14 but direct the output to a file. Compare the
contents of the file to the output when output goes to the terminal. You will have to interrupt the processes to stop them; let them run long enough to get a sufficient amount of output. What happens if the write call in the program is replaced with
```c
printf(output);
```
$\textbf{Figure 10.14}$
```c
char form[] = "this is a sample output string from child ";
main()
{
char output[128];
int i;
for (i = 0; i < 18; i++)
{
switch(fork())
{
case -1: /* error — hit max procs */
exit();
default: /* parent process */
break;
case 0: /* child process */
/* format output string in variable output */
sprintf(output, "%s%d\n%s%d\n", form, i, form, i);
for (;;)
write(1, output, sizeof(output));
}
}
}
```
#### Solution:
There are two outputs for $\textbf{write()}$ and $\textbf{printf()}$:
* For $\textbf{write()}$ - it first ouput all blocks for one child
* For $\textbf{printf()}$ - it prints randomly for each child
```
��U@"Ӛ�U� Ӛ�Uthis is a sample output string from child 6
this is a sample output string from child 6
"Ӛ�U@"Ӛ�U� Ӛ�Uthis is a sample output string from child 6
this is a sample output string from child 6
"Ӛ�U@"Ӛ�U� Ӛ�Uthis is a sample output string from child 6
this is a sample output string from child 6
"Ӛ�U@"Ӛ�U� Ӛ�Uthis is a sample output string from child 6
this is a sample output string from child 6
"Ӛ�U@"Ӛ�U� Ӛ�Uthis is a sample output string from child 6
this is a sample output string from child 6
"Ӛ�U@"Ӛ�U� Ӛ�Uthis is a sample output string from child 6
this is a sample output string from child 6
"Ӛ�U@"Ӛ�U� Ӛ�Uthis is a sample output string from child 6
this is a sample output string from child 6
"Ӛ�U@"Ӛ�U� Ӛ�Uthis is a sample output string from child 6
this is a sample output string from child 6
"Ӛ�U@"Ӛ�U� Ӛ�Uthis is a sample output string from child 6
this is a sample output string from child 6
"Ӛ�U@"Ӛ�U� Ӛ�Uthis is a sample output string from child 6
this is a sample output string from child 6
"Ӛ�U@"Ӛ�U� Ӛ�Uthis is a sample output string from child 6
this is a sample output string from child 6
"Ӛ�U@"Ӛ�U� Ӛ�Uthis is a sample output string from child 6
this is a sample output string from child 6
"Ӛ�U@"Ӛ�U� Ӛ�Uthis is a sample output string from child 6
this is a sample output string from child 6
"Ӛ�U@"Ӛ�U� Ӛ�Uthis is a sample output string from child 6
this is a sample output string from child 6
"Ӛ�U@"Ӛ�U� Ӛ�Uthis is a sample output string from child 6
this is a sample output string from child 6
"Ӛ�U@"Ӛ�U� Ӛ�Uthis is a sample output string from child 6
this is a sample output string from child 6
"Ӛ�U@"Ӛ�U� Ӛ�Uthis is a sample output string from child 6
this is a sample output string from child 6
"Ӛ�U@"Ӛ�U� Ӛ�Uthis is a sample output string from child 6
this is a sample output string from child 6
"Ӛ�U@"Ӛ�U� Ӛ�Uthis is a sample output string from child 6
this is a sample output string from child 6
"Ӛ�U@"Ӛ�U� Ӛ�Uthis is a sample output string from child 6
this is a sample output string from child 6
"Ӛ�U@"Ӛ�U� Ӛ�Uthis is a sample output string from child 6
this is a sample output string from child 6
"Ӛ�U@"Ӛ�U� Ӛ�Uthis is a sample output string from child 6
this is a sample output string from child 6
"Ӛ�U@"Ӛ�U� Ӛ�Uthis is a sample output string from child 6
this is a sample output string from child 6
"Ӛ�U@"Ӛ�U� Ӛ�Uthis is a sample output string from child 6
this is a sample output string from child 6
"Ӛ�U@"Ӛ�U� Ӛ�Uthis is a sample output string from child 6
this is a sample output string from child 6
"Ӛ�U@"Ӛ�U� Ӛ�Uthis is a sample output string from child 6
this is a sample output string from child 6
"Ӛ�U@"Ӛ�U� Ӛ�Uthis is a sample output string from child 6
this is a sample output string from child 6
"Ӛ�U@"Ӛ�U� Ӛ�Uthis is a sample output string from child 6
this is a sample output string from child 6
"Ӛ�U@"Ӛ�U� Ӛ�Uthis is a sample output string from child 6
```
```
this is a sample output string from child 16
this is a sample output string from child 17
this is a sample output string from child 17
this is a sample output string from child 16
this is a sample output string from child 16
this is a sample output string from child 16
this is a sample output string from child 16
this is a sample output string from child 17
this is a sample output string from child 17
this is a sample output string from child 15
this is a sample output string from child 15
this is a sample output string from child 17
this is a sample output string from child 17
this is a sample output string from child 16
this is a sample output string from child 16
this is a sample output string from child 16
this is a sample output string from child 16
this is a sample output string from child 16
this is a sample output string from child 16
this is a sample output string from child 17
this is a sample output string from child 17
this is a sample output string from child 17
this is a sample output string from child 17
this is a sample output string from child 16
this is a sample output string from child 16
this is a sample output string from child 17
this is a sample output string from child 17
this is a sample output string from child 17
this is a sample output string from child 17
this is a sample output string from child 17
this is a sample output string from child 17
this is a sample output string from child 16
this is a sample output string from child 16
this is a sample output string from child 16
this is a sample output string from child 16
this is a sample output string from child 17
this is a sample output string from child 17
this is a sample output string from child 14
this is a sample output string from child 14
this is a sample output string from child 17
this is a sample output string from child 17
this is a sample output string from child 17
this is a sample output string from child 17
this is a sample output string from child 17
this is a sample output string from child 17
this is a sample output string from child 17
this is a sample output string from child 17
this is a sample output string from child 17
this is a sample output string from child 17
this is a sample output string from child 17
this is a sample output string from child 17
this is a sample output string from child 15
this is a sample output string from child 15
this is a sample output string from child 16
this is a sample output string from child 16
this is a sample output string from child 14
this is a sample output string from child 14
```
### +Task 10
What happens when a user attempts to do text editing in the background:
```
ed file &
```
#### Solution:
When a user attempts to do text editing in the background, system creates a process, write it $\textbf{PID}$ in terminal. We can later connect to this process and edit text.
### +Task 11
Terminal files typically have access permissions set as in
```
crw--w--w— 2 mjb lus 33, 11 Oct 25 20:27 tty6l
```
when a user is logged on. That is, read/write permission is permitted for user "mjb," but only write permission is allowed other users. Why?
крч я тут почитал, обычно похожие разрешения бывают у дескрипторов драйверов, что я думаю: у терминала подобные разрешения по 2 причинам:
1) mjb может читать и писать тк он открыл этот процесс, следовательно оутпут он поулчает лично, а не кто-то другой.
2) другие юзеры могут писать в терминал (хз почему), но не могут видеть оутпут тк процесс создан тобой.
#### Solution:
For terminal files similar permissions for 2 reasons:
1. mjb user can read/write because he open the process, therefore he get the output, not other users.
2. Other users can write to terminal, because process opens in user level, but can not read an output, because mjb opens the process.
### +Task 12
Assuming you know the terminal device file name of a friend, write a program that allows you to write messages to your friend's terminal. What other information do you need to encode a reasonable facsimile of the usual $\textbf{write}$ command?
#### Solution:
```c
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#define STR_SIZE 10000
int main(int argc, char const *argv[])
{
char dev_file_name[] = "/dev/pts/17";
char send_msg[] = ">";
char cmd[] = "sudo echo";
char result[STR_SIZE] = {0};
snprintf(result, sizeof(result), "%s %s %s %s", cmd, argv[1], send_msg, dev_file_name);
system(result);
return (0);
}
```
### Task 13
Implement the $\textbf{stty}$ command: with no parameters, it retrieves the values of terminal settings and reports them to the user. Otherwise, the user can set various settings interactively.
#### Solution:
### +Task 14
Encode a line discipline that writes the machine name at the beginning of each line of output.
#### Solution:
To change the output to the terminal you need to add special line to ```.bashrc``` file:
```bash
PS1='${HOSTNAME%%.*}: '
```
### +Task 15
In canonical mode, a user can temporarily stop output to a terminal by typing "control s" at the terminal and resume output by typing "control q." How should the standard line discipline implement this feature?
#### Solution:
This functionality appeared quite a long time ago in teleprinters. If the printer couldn't print as fast as the teletype was receiving data, for instance, the teletype could send an XOFF flow control command (Ctrl+S) to the remote side saying "Stop transmitting for now", and then could send the XON flow control command (Ctrl+Q) to the remote side saying "I've caught up, please continue".
And this usage survives in Unix because modern terminal emulators are emulating physical terminals (like the vt100) which themselves were (in some ways) emulating teletypes.
Ref: https://unix.stackexchange.com/
### Task 16
The $\textbf{init}$ process spawns a $\textbf{getty}$ process for each terminal line in the system. What would happen if two getty processes were to exist simultaneously for one terminal, waiting for a user to log in? Can the kernel prevent this?
#### Solution:
### +Task 17
Suppose the shell were coded so that it "ignored" the end of file and continued to $\textbf{read}$ its standard input. What would happen when a user (in the login shell) hits end of file and continues typing?
#### Solution:
Since the shell ignores the end of the file, after it reaches the end of the file, it will simply read from standard input, but will not write anything.
### +Task 18
Suppose a process $\textbf{reads}$ its control terminal but ignores or catches hangup signals. What happens when the process continues to $\textbf{read}$ the control terminal after a hangup?
я думаю он просто будет висеть в бэкграунде и ждать, хотя у него же хранится родительский pid надо почитать
почитай [site](https://unix.stackexchange.com/questions/479/keep-processes-running-after-ssh-session-disconnects)
#### Solution:
There is a command $\textbf{nohup}$ - NO Hang UP. It makes your process ignore the hangup signal. So, if you type ```nohup long-running-process &``` and then log out from terminal, process continue working and save the output to ```nohup.out``` by default.
### +Task 19
The $\textbf{getty}$ program is responsible for opening a terminal line, and $\textbf{login}$ is responsible for checking login and password information. What advantages are there for doing the two functions in separate programs?
#### Solution:
There is good two have getty and login separetly, because instead of the login program, getty may also be set up by the system administrator to run any other program, for example pppd (point-to-point protocol daemon) to provide a dial-up Internet connection.
Ref: https://en.wikipedia.org/
### Task 20
Consider the two methods for implementing the indirect terminal driver ("/dev/tty"), described in Section 10.3.6. What differences would a user perceive? (Hint: Think about the system calls $\textbf{stat}$ and $\textbf{fstat}$.)
#### Solution:
### Task 21
Design a method for scheduling streams modules, where the kernel contains a special process that executes module service procedures when they are scheduled to execute.
#### Solution:
### Task 22
Design a scheme for virtual terminals (windows) using conventional (nonstreams) drivers.
#### Solution:
### Task 23
Design a method for implementing virtual terminals using streams such that a kernel module, rather than a user process, multiplexes I/O between the virtual and physical terminals. Describe a mechanism for connecting the streams to allow fan-in and fan-out. Is it better to put a multiplexing module inside the kernel or construct it as a user process?
#### Solution:
### Task 24
The command ps reports interesting information on process activity in a running system. In traditional implementations, ps reads the information in the process table directly from kernel memory. Such a method is unstable in a development environment where the size of process table entries changes and ps cannot easily find the correct fields in the process table. Encode a driver that is impervious to a changing environment.
#### Solution:
```c=
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
char form[] = "this is a sample output string from child ";
void main()
{
char output[128];
int i;
for (i = 0; i < 18; i++)
{
switch(fork())
{
case -1: /* error — hit max procs */
exit(0);
default: /* parent process */
break;
case 0: /* child process */
/* format output string in variable output */
sprintf(output, "%s%d\n%s%d\n", form, i, form, i);
printf(output);
}
}
}
```