0% found this document useful (0 votes)
483 views57 pages

Figure List

The document contains a table of contents listing 11 labs covering topics in operating systems including basic Linux, shell scripting, process management, memory management, file systems, C programming, pipes, signals, sockets, semaphores, deadlocks, and disk scheduling. It includes 31 figures illustrating concepts from each lab such as computer hardware layers, basic Linux commands, process states, memory management, file systems, threads, pipes, disk structure, and I/O systems. It also lists 4 questions related to OS types, memory access, OS concepts, and system calls from the introduction lab.

Uploaded by

Dien Cao
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
483 views57 pages

Figure List

The document contains a table of contents listing 11 labs covering topics in operating systems including basic Linux, shell scripting, process management, memory management, file systems, C programming, pipes, signals, sockets, semaphores, deadlocks, and disk scheduling. It includes 31 figures illustrating concepts from each lab such as computer hardware layers, basic Linux commands, process states, memory management, file systems, threads, pipes, disk structure, and I/O systems. It also lists 4 questions related to OS types, memory access, OS concepts, and system calls from the introduction lab.

Uploaded by

Dien Cao
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 57

Table of Contents

Lab 0 – Introduction ......................................................................................................... 2


Lab 1a – Basic Linux ........................................................................................................ 5
Lab 1b – Shell & Shell script ............................................................................................. 7
Lab 2 – Process management in Linux ............................................................................ 11
Lab 3 – Memory management in Linux ........................................................................... 16
Lab 4 – File system in Linux ........................................................................................... 20
Lab 5 – C basic in Linux ................................................................................................. 26
Lab 6a – Process management in C language ................................................................. 28
Lab 6b – Threads in C language...................................................................................... 33
Lab 7a – Pipe / Signal in C language .............................................................................. 36
Lab 7b – Socket / Shared Memory in C language ............................................................ 41
Lab 8 – Semaphore / mutex ............................................................................................. 44
Lab 9 - Deadlock & livelock ........................................................................................... 48
Lab 10 – Storage & Disk arm scheduling ........................................................................ 49
Lab 11 – I/O management ............................................................................................... 54

Figure list
Figure 1: Computer's layers ....................................................................................................... 2
Figure 2: Computer hardware's overview.................................................................................. 3
Figure 3: Switch mode ............................................................................................................... 4
Figure 4: Making a system call.................................................................................................. 5
Figure 5: OS structure................................................................................................................ 5
Figure 6: Some basic commands ............................................................................................... 6
Figure 7: Arithmetic Comparisons ............................................................................................ 9
Figure 8: String Comparisons .................................................................................................... 9
Figure 9: File check ................................................................................................................... 9
Figure 10: Stack ....................................................................................................................... 12
Figure 11: Fetch-Decode-Execute ........................................................................................... 12
Figure 12: Switching processes ............................................................................................... 13
Figure 13: Process states.......................................................................................................... 13
Figure 14: Sample of Memory location ................................................................................... 16
Figure 15: VM and physical memory ...................................................................................... 17
Figure 16: Page replacement ................................................................................................... 18
Figure 17: chmod ..................................................................................................................... 20
Figure 18: Hard link ................................................................................................................ 20
Figure 19: Soft link .................................................................................................................. 21
Figure 20: Implementing directories ....................................................................................... 22
Figure 21: I-node ..................................................................................................................... 23

1
Figure 22: Compile time .......................................................................................................... 26
Figure 23: fork() ...................................................................................................................... 29
Figure 24: Single thread and multithreads ............................................................................... 34
Figure 25: User & Kernel threads............................................................................................ 35
Figure 26: Pipe() ...................................................................................................................... 37
Figure 27: pipe between parent and child processes ............................................................... 38
Figure 28: Disk's structure ....................................................................................................... 50
Figure 29: Layers of the I/O software system ......................................................................... 54
Figure 30: Hardware communication ...................................................................................... 55
Figure 31: DMA ...................................................................................................................... 55

Question list
Question Lab
GQ0 – GQ4 Lab 0 - Introduction
Shell sample scripts Lab 1b – Shell & Shell scripts
Question L20-L23 Lab 2 - Process management
Question L30 – L34 Lab 3 - Memory management
C sample programs Lab 5 – C basic
C sample programs Lab 6a – Process management in C
C sample programs Lab 6b – Threads in C
C sample programs Lab 7a/7b – Signal, pipe, socket, shared memory
Question L80 – L81 Lab 8 – Semaphore
Producer – consumer problem Lab 8 - Semaphore
Question L90 Lab 9– Deadlock
Question L100 – L103 Lab 10 – Disk arm scheduling

Lab 0 – Introduction

Figure 1: Computer's layers

2
Figure 2: Computer hardware's overview

GQ0. OS zoo
- Mainframe
- PC
- Handheld
- Smartcard
- Server
- Embedded
- Sensor
- real-time

GQ1. Uniform memory access for accessing memory from any unit takes
a. same time b. different time

Uniform memory access: single memory controller à same time


Non- uniform memory access: multiple memory controller

GQ2.
- Multiprocessor: more than 1 CPU in single computer
- Multi-computer = interlinked more than 1 autonomous computers
- Multiprogramming: allow 1 or more processes running on single CPU - switch
(increase utilization of CPU)
- Time sharing: share facility for multiple users = multiprogramming to share CPU time
- Multitasking: allow multiple processes running
- Batch processing: Tasks are listed, at a time, only one task is performed, after this
task terminate, other in the list is automatically loaded. In this approach, similar jobs
were submitted to the CPU for processing and were run together.
- Spooling
o is a buffer that holds output for a device such as a printer, that cannot accept
interleaved data streams
o overlaps input of one job with the computation of other jobs
o Spooler may be reading the input of one job while printing the output of a
different job

GQ3. Concepts
- Instruction context: a task that hardware must carry out.

3
- Kernel mode/Supervisor mode (OS runs in this mode)
o Gains control of the computer to access all the hardware
o Can execute any machine instructions
o Supports security: Protects the OS from errant users
o Everything running in this mode is a part of the OS or closely associated
with it.
- User mode (The user software run in this mode)
o Can execute a subset of the machine instructions with the exception of
instructions to control of the machine or do I/O
- Mode switching
o If the user interacts with OS: user mode à kernel mode
o If the system passes control to a user program: kernel mode à user mode

Figure 3: Switch mode

System call
- 1) push parameters on stack
- 2) invoke the system call
- 3) put code for system call on register
- 4) trap to the kernel
- 5) since a number is associated with each system call, system call interface
invokes/dispatch intended system call in OS kernel and return status of the system call
and any return value
- 6) switch form kernel to user mode
- 7) increment stack pointer

4
Figure 4: Making a system call

GQ4. OS structure
• Monolithic Systems
• Layered Systems
• Micro Kernels
• Client-Server Model
• Virtual Machines
• Exokernels

Figure 5: OS structure

Lab 1a – Basic Linux


Output
- Capture all windows for showing that you installed successfully the virtual
machine, ubuntu Linux and openssh-server and using Linux basic commands
- Upload images in zip file to LMS

5
1. Install virtual machine
- VMware
- Or VirtualBox

Download ubuntu Linux iso file: https://releases.ubuntu.com/xenial/ubuntu-16.04.6-desktop-


amd64.iso

2. Install ubuntu Linux on virtual machine

3. Using terminal
- normal commands
o su, sudo, echo, man, date, time, lsb_release -a, uname
o Working with files: ls, cat, wc, cp, mv, rm, ...
o Working with directories: pwd, mkdir, cp –r, mv, rmdir, rm –f, cd, ...
- Install ssh: sudo apt-get install openssh-server & systemctl enable ssh
- Configure ssh server to connect from host machine

Figure 6: Some basic commands

4. Using vi <file_name>
- Press key a: insert or type the content (in the right)
- ESC key: exit to command mode
- The key arrow is used to move in the content
- Key x: delete a character
- Key dd: delete a row
- Command
• :w: write file
• :q: exit vi
• :wq: write file and exit vi

6
• :e!: delete all the content that typing after writing file
- Some other key function
• Ctrl G: show the current line
• G: end of file
• 1G: begin of file
• nG: go to n line
• dd: delete a line
- touch / more / tail / head / nano
5. kill a ssh session
- who or w to get session info
- pstree -p | grep sshd to get parent process ID of ssh session
- sudo kill -9 <PID>
- pstree – p to verify the result

Lab 1b – Shell & Shell script


Output:
- Capture all windows for showing that you used Linux basic commands
- Submit the source of the shell script (*.sh) and capture the screen that present the
result of shell script
- Compress the files and upload zip file to LMS

1. Shell & Shell script


- #!/bin/sh
- #!/bin/bash
- pipe | and &
o cat ./test.txt | sort | uniq -D : what is output?
- Variable
o Declaration:<variable_name>=<value>
o Access:variable1=$variable2
o Input value of variable: #read variable
o Some system variables
§ $#: number of parameters
§ $0: name of command
§ $*: list of parameters
§ $number: number>0 – the input argument
o Get input value to variable from the keyboard, file
§ Keyboard: read var1 var2 ...
§ File: read var1 var2 ... <data_file >
§ if the variable name is not existing, the value is assigned to $REPLY
variable
§ The “\” character allows the enter new line during the input value
§ The “-r” option is ineffective the “\”
- $#: stores the number of command-line arguments that were passed to the shell
program.
- $? : stores the exit value of the last command that was executed.
- $0 : stores the first word of the entered command (the name of the shell program).
- "$@" : stores all the arguments that were entered on the command line, individually
quoted ("$1" "$2" ...).
- expr op1 operator op2
o Not support floating point

7
o Operator: +, -, \*, /, = (equal), <=, <, >, >=, != (different), &, |
o Expr 1 + 2
- Let
o let "myvar=10" "myvar2=--myvar"; echo $myvar $myvar2
- $((...))
- Sleep()
- if ... then …fi / if … then …elif … then …else … fi
- case
- for … do … done
Numeric range for VARIABLE in 1 2 3 4 5 .. N
do
command1
command2
commandN
done
for VARIABLE in file1 file2 file3
do
command1 on $VARIABLE
command2
commandN
done
for OUTPUT in $(Linux-Command-Here)
do
command1 on $OUTPUT
command2 on $OUTPUT
commandN
done
Break for I in 1 2 3 4 5
do
statements1 #Executed for all values of ''I''
statements2
if (disaster-condition)
then
break #Abandon the loop.
fi
statements3 #While good and, no disaster-condition
done

- while
while [ condition ]
do
command1
command2
commandN
done

- until

8
Figure 7: Arithmetic Comparisons

Figure 8: String Comparisons

Figure 9: File check

2. Sample
Script Content
Print what is shell we on echo $SHELL
Sum n numbers keying in from #!bin/bash
keyboard echo "Enter Size(N)"

9
read N
i=1
sum=0
echo "Enter Numbers"
while [ $i -le $N ]
do
read num #get number
sum=$((sum + num)) #sum+=num
i=$((i + 1))
done
echo $sum
Sum of n number from 1 to n #!bin/bash
echo "key in n="
read n
i=0
s=0
while [ $i -le $n ]
do
s=$((s+i))
i=$((i+1))
done
echo "sum of $n numbers from 1 is " $s
Print weekday and days #!/bin/sh
i=1
weekdays="Mon Tue Wed Thu Fri"
for day in $weekdays
do
echo "Weekday $i : $day";
i=$((i+1));
done
#!/bin/sh
echo "Please talk to me ..."
while :
do
read INPUT_STRING
case $INPUT_STRING in
hello)
echo "Hello yourself!"
;;
bye)
echo "See you again!"
break
;;
*)
echo "Sorry, I don't understand"
;;
esac
done
echo "That's all!"
Check if file exist in current #!bin/bash
directory echo "File name: "
read FILE
if test -f "$FILE"; then
echo "$FILE exist"

10
else echo "$FILE does not exist"
fi
Make dir $1 in current directory dir=$1
and copy file $2 into dir $1 with basedir="./"
name $3 mkdir -p $basedir"/"$dir
cat $2 > $basedir"/"$dir"/"$3
List all file in directory (in ls | sort |
ascending order) while read file
do
echo $file
done
Write a shell script sum.sh that #!/bin/bash
takes an unspecified number of sum=0
command line arguments (up to 9) arg_no="$@"
of integers and finds their sum (to for var in $arg_no
add a number to the sum only if do
the number is greater than 10) if [ $var -gt 10 ]
then
sum=$((sum + var))
fi
done
echo $sum
Write a shell script takes the name ls –R $1 | wc –l
a path (eg:./), and counts all the
sub directories (recursively).
Count word in file wc -w ./nextcloud.txt

(wlcm-- word, line, character, and byte count)


Checking user in system who

who -b: time last system boot


Write a shell script that takes a ls $1 |
name of a folder as a command while read folder
line argument, and produce a file do
that contains the names of all sub if [ -d $1'/'$folder ]
folders with size 0 (that is empty then
sub folders) if [ -z $(ls -A $1'/'$folder) ]
then
echo $folder >> output.txt
fi
fi
done

Lab 2 – Process management in Linux


Output
- Capture all windows for showing that you used Linux commands
- Capture the terminal screen using the vi application to view the content of file that
are typed by you
- Upload images in zip file to LMS

Data structure & the basic fetch-decode-execute cycle

11
Figure 10: Stack

- The process Stack contains the temporary data such as method/function


parameters, return address and local variables.
- Heap is dynamically allocated memory to a process during its run time.
- Text includes the current activity represented by the value of Program Counter
and the contents of the processor's registers.
- Data contains the global and static variables.
- Processes that stay in the background to handle some activity such as e-mail, Web
pages, news, printing, and so on are called daemons.

Figure 11: Fetch-Decode-Execute

12
Process, thread, pthreads
- Process = program in execution
- PCB: process control block à process table
- Kinds of processes
o Compute Bound & I/O Bound Processes
o Independent Processes & Co-operating Processes
- Threads: lightweight processes

Figure 12: Switching processes

Figure 13: Process states

CPU scheduler
- Starvation / aging
- Scheduling: long-term, short-term
- Scheduling Mechanisms: Non-preemptive / Preemptive
- Scheduling algorithms: FCFS, SJF, SRTN, RR, Priority, Multilevel queues

Characteristics

13
- CPU Utilization − A scheduling algorithm should be designed so that CPU remains
busy as possible. It should make efficient use of CPU.
- Throughput − Throughput is the amount of work completed in a unit of time. In
other words, throughput is the processes executed to number of jobs completed in a
unit of time. The scheduling algorithm must look to maximize the number of jobs
processed per time unit.
- Response time − Response time is the time taken to start responding to the request. A
scheduler must aim to minimize response time for interactive users.
- Turnaround time − Turnaround time refers to the time between the moment of
submission of a job/ process and the time of its completion. Thus how long it takes to
execute a process is also an important factor.
- Waiting time − It is the time a job waits for resource allocation when several jobs are
competing in multiprogramming system. The aim is to minimize the waiting time.
- Fairness − A good scheduler should make sure that each process gets its fair share of
the CPU.

Question L20: Tính waiting time với turnaround time với thuật toán Round Robin
scheduling, biết quantum q=2 và
Process Arrival time Burst time
P1 0 5
P2 1 7
P3 2 1

0 1 2 3 4 5 6 7 8 9 10 11 12
P1 P1 P2 P2 P3 P1 P1 P2 P2 P1 P2 P2 P2

Waiting time = turnaround time – burst time = sum [start - arrival]


P1: (0) + (5-1) + (9-6) = 7
P2: (2 -1) + (7-3) +(10-8) = 7
P3: (4-2) = 2
Average waiting time = (7+7+2)/3 = 5.33

Turnaround = Exit time – arrival time


P1: 9 – 0 = 9
P2: 12 – 1 = 11
P3: 4 – 2 = 2

Question L21: Assume jobs A-D arrive in quick succession in the READY queue. Using
round robin scheduling, the turnaround time for job C is ____.
Arrival time: 0 1 2 3
Job: A B C D
CPU cycle: 8 4 9 5
A) 7 B) 20 C) 22 D) 24

Question L22: CPU sử dụng thuật toán scheduling SRTF, resource sử dụng thuật toán
scheduling FIFO
Process Time to Burst Resource Resource Burst Resource Resource
Read time 1 using name time 2 using name
list time 1 time 2
P1 0 6 5 R1 2 2 R1

14
P2 2 1 7 R2 3 4 R1
P3 8 4 3 R1 2 3 R2
P4 11 2 7 R2 1 4 R2

t 0 1 2 3 4 5 6 7 8 9 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9
C P P P P P P P P P P P P P P P P P P P P P
P 1 1 2 1 1 1 1 3 3 3 3 4 4 1 1 3 3 2 2 2 4
U
R P P P P P P P P P P P P P P
1 1 1 1 1 1 3 3 3 1 1 2 2 2 2
R P P P P P P P P P P P P P P P P P P P P P
2 2 2 2 2 2 2 2 4 4 4 4 4 4 4 3 3 3 4 4 4 4

1. Process management
- vmstat (view status of virtual memory) / top
- ps [-option]
- pstree–np
- pgrep
- kill [-signal]
- uptime / free
- processes' parameters: PID, PPID, UID, %CPU, %MEM, STAT, START, ADDR,
WCHAN, CMD, TIME, PRI, TTY, SZ, F
- F: flag - 1 forked but didn't exec ; - 4 used super-user privileges
- STAT: R, S, Z, W...
- /proc/sys/kernel/pid_max: process max ID
- top

2. Sample
Question L23. Kết qủa của lệnh này là gì? echo hello > ./my_info & cat < ./my_info

à echo hello > ./my_info


à cat < ./my_info

[1] 6402
hello
[1]+ Done echo hello > ./my_info

Command Description
cat /proc/cpuinfo View CPU info from /proc
ps -A or ps -e List all processes
ps -ef UID PID PPID C STIME TTY TIME CMD
(full format) root 1619 1 0 Apr30 tty1 00:00:00 /sbin/agetty --noclear tty1 linux
- C: processor utilization for scheduling. It shows the percentage of time in schedule spent
on certain process
- STIME: start time
- tty: the terminal from which the process was started
- Time: total time for which the process has utilized cpu
- cmd: the command and arguments executed
ipcs show information on IPC facilities
ipcs -s ------ Semaphore Arrays --------
key semid owner perms nsems
0x000000a7 65536 root 600 1
Executing a background job Job &

15
Lab 3 – Memory management in Linux
Output
- Capture all windows for showing that you used Linux commands
- Capture the terminal screen using the vi application to view the content of file that
are typed by you
- Upload images in zip file to LMS
Question L30: segmentation / paging
Lấy 1 vùng bộ nhớ cho process hoạt động?
- Paging à no external fragmentation , has internal fragmentation
- Segmentation -> no internal fragmentation
o Base register: starting address of allocated memory
o Limit register: length of allocated memory

Base Limit (words) Segmentation


100 256 0
400 1000 1
1450 360 2
1410 20 3

100 à 356: seg. 0


400 à 1400: seg 1
1410 à 1430: seg 3
1450 à 1810: seg 2

Physical address – logical address (seg. No. , offset )


Logical à physical ??
(0, 200) à 100+200 = 300
(3, 5) à 1410 + 5 = 1415
(2, 370) à 1450 + 370 = 1820 > 1810 à ko hợp lệ

Figure 14: Sample of Memory location

16
Paging:

Physical address <frame number, offset>


Frame 0
Frame 1

Virtual memory
Page

Điạ chỉ VM: <page number, offset>

Question L31:
1 hệ thống máy tính có:
- RAM 800M
- VM 32 bits
- Page size 16KB
Số bit dùng cho offset là bao nhiêu? 16KB= 2^4*2^10B = 2^14B à cần 14 bit để đánh số
được 16KB. Ví dụ: địa chỉ A nằm ở page số 3, offset 150: <3, 150> = địa chỉ A nằm ở page
số 3, byte 150 ; giả sử page số 3 có điạ chỉ đầu tiên là 2020. Điạ chỉ <3, 150> à physical
address = 2170
Frame size = page size = 16KB

Number of frames = size of RAM / size of frame = 800M/16K = 100*2^23 / 2^14 =


50*2^10=50*1024 = 51,200 frames
Number of pages = size of VM / page size = 2^32 / 2^14 = 2^18 pages

Logical address 23032 à <page, offset> 23032 mod 16384 (=16K) = 1 dư 6648 <1, 6648>

Figure 15: VM and physical memory

17
Page hit / page fault
- Thrashing: too many page faults

Figure 16: Page replacement

If do not have free frame in RAM à page replacement


- Optimal: latest one accessed in the future
- FIFO: loaded first
- LRU: least recently used
- NRU: not recently used
- Second change
- Working set clock
Question L32: Thuật toán thay trang LRU. Có bao nhiêu page fault?
2 5 7 2 3 1 4 6 4 5
2 2 2 2 2 2 4 4 4 4
5 5 5 3 3 3 6 6 6
7 7 7 1 1 1 1 5
* * * * * * * *

Question L33: Page hit ratio = 100% - (page fault ratio)


Process: 7 pages
Pages: 2,4,5,1,2,3,1,1,4,6
Scheduling: FIFO
Number of frames = 2

18
Hit ratio =10%
2 4 5 1 2 3 1 1 4 6
2 2 4 1 2 3 1 1 4 6
4 5 5 1 2 3 3 1 4
* * * * * * * * *

Average memory access time, known miss ratio = 2%


Average Memory access time = hit time (access mem) + miss ratio * (page fault penalty)
Page fault penalty = search in secondary memory + page replacement + update page table +
access mem

Assume that the page fault service time is 11ms, and average memory access time is 21ns. If
1-page fault is generated for every 10^6 memory accesses, what is the effective access time
for the memory?
Select one: a. 23ns b. 35ns c. 32ns d. 21ns

1-page fault (10^6 + 1) à page fault ratio = 1/(10^6 +1) = 10^-6 = 0.000001
Page hit = (1-10^-6) = 0.999999
Effective access time= page fault ratio * page fault service time + page hit ratio * average
memory access time

Question L34. A virtual memory system uses First In First Out (FIFO) page replacement
policy and allocates a fixed number of frames to a process. Consider the following
statements:
P: Increasing the number of page frames allocated to a process sometimes increases the page
fault rate. à Belady’ anomaly
Q: Some programs do not exhibit locality of reference

a. Both P and Q are false


b. Both P and Q are true, and Q is the reason for P
c. Both P and Q are true, but Q is not the reason for P
d. P is false, but Q is true

Command Description
free -m Report memory usage in MBs
total used free shared buff/cache available
Mem: 20015 686 17517 211 1811 18738
Swap: 20415 0 20415
cat /proc/meminfo The /proc contains virtual files that contain dynamic information about the kernel and the
system
vmstat -s the memory usage statistics much like the proc command
sudo dmidecode All about hardware information
sudo dmidecode -t 17 Memory device
(-t : type)
ipcs -m ------ Shared Memory Segments --------
key shmid owner perms bytes nattch status
0x00000000 0 root 644 80 2
0x00000000 32769 root 644 16384 2
0x00000000 65538 root 644 280 2
vmstat Report virtual memory statistics
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
0 0 0 17939416 364872 1490756 0 0 1 8 18 10 0 0 99 0 0

19
Lab 4 – File system in Linux
Output
- Capture all windows for showing that you used Linux commands
- Capture the terminal screen using the vi application to view the content of file that
are typed by you
- Upload images in zip file to LMS
1. File management
- Working with files attributes: chmod, chdir
o chmod u+x,g+x-r,o-r ./my_channel
o chmod a=wr ./my_channel
o chmod 777 ./my_channel

Figure 17: chmod

o useradd user1
o chown user1 ./test1.txt : change ownership
o chown –R user1 ./test : change ownership of directory
o groupadd group1
o chgrp group1 ./test1.txt
o chgrp -R group1 ./test
- Mount / unmount: in Linux, you don’t mount a hard drive or partition. You mount the
file system that’s on the partition, so it’s easy to have multiple file systems without
realizing it
o Create a mounting point by using mkdir (mkdir /mnt/sdi – i can be 1,2,3..)
o mount /dev/sdxi /mnt/sdi (mount /dev/sdb1 /mnt/sd1)
o unmount /mnt/sdi or unmount /dev/sdxi (where x is the drive letter and m is
the partition number identified)
- Soft link & hard link & dangling link

Figure 18: Hard link

20
Figure 19: Soft link

Command Description
ln -s until.sh until Create soft link
ls -ltr | grep until -rw-rw-r-- 1 sdev sdev 95 May 4 20:45 until.sh
lrwxrwxrwx 1 sdev sdev 8 May 5 10:04 until -> until.sh
rm until link will be removed, file until.sh remains
ls -il until.sh until 3419915 lrwxrwxrwx 1 sdev sdev 8 May 5 10:09 until -> until.sh
3420744 -rw-rw-r-- 1 sdev sdev 95 May 4 20:45 until.sh
ln until.sh until Create hard link
ls -il | grep until 3420744 -rw-rw-r-- 2 sdev sdev 95 May 4 20:45 until
3420744 -rw-rw-r-- 2 sdev sdev 95 May 4 20:45 until.sh
rm until.sh Link remains
stat until File: 'until'
Size: 95 Blocks: 8 IO Block: 4096 regular file
Device: fc00h/64512d Inode: 3420744 Links: 2
Access: (0664/-rw-rw-r--) Uid: ( 1000/ sdev) Gid: ( 1000/ sdev)
Access: 2020-05-05 10:14:50.862319663 +0700
Modify: 2020-05-04 20:45:46.107827313 +0700
Change: 2020-05-05 10:15:55.844279195 +0700

2. Linux file structures


- /bin: contains basic commands and programs
- /sbin: is much like the /bin directory in that it contains programs deemed essential for
using the operating system
- /boot: contains the actual files, images, and kernels necessary to boot the system
- /dev: Every hard drive, terminal device, input or output device available to the
system
- /etc: is basically a configuration directory for various system-wide services
- /home: contains the home directories of all of the users on the system (except for the
administrative user, root)
- /lib: is used for all of the shared system libraries that are required by the /bin and /sbin
directories
- /root: is the home directory of the administrative user (called "root").
- /proc: a pseudo-filesystem
- /mnt: is usually used to mount file systems like external hard drives, etc.
- /var: is supposed to contain variable data
- /tmp: is a directory that is used to store temporary files on the system

File types
• -: regular file.

21
• d : directory.
• c : character device file: Provides a serial stream of input or output. Terminals are
classic example for this type of files.
• b : block device file: are hardware files most of them are present in /dev.
• s : socket file: is used to pass information between applications for communication
purpose
• p : named pipe: One of the greatest features of UNIX is that you can redirect the
output of one program to the input of another program with very little work
• l : symbolic link: are linked files to other files. They are either Directory/Regular File.
The inode number for this file and its parent files is same. There are two types of link
files available in Linux/Unix - soft and hard link.

Directory implementation

Figure 20: Implementing directories

3. Inode
- is declared in the source code as a 32-bit
- the file system ID and inode number combine to make a unique identifier
- All inodes are held in one table. Using an inode number, the file system easily
calculates the offset into the inode table at which that inode is located

22
Figure 21: I-node

Command Description
df -i /dev/sda1 Filesystem Inodes IUsed IFree IUse% Mounted on
/dev/sda1 124928 298 124630 1% /boot

- File system: The file system being reported on.


- Inodes: The total number of inodes in this file system.
- IUsed: The number of inodes in use.
- IFree: The number of remaining inodes available for use.
- IUse%: The percentage of used inodes.
- Mounted on: The mount point for this file system.

Command Description
ls -lid ./ 3419898 drwxrwxr-x 2 sdev sdev 4096 May 4 22:21 ./
ls -lid ~ 2621442 drwxr-xr-x 16 sdev sdev 4096 May 4 22:21 /home/sdev
ls -lia ./ Report all files, includes . and ..
vi ./
stat -f /dev/sda1 File: "/dev/sda1"
(display file or file system ID: 0 Namelen: 255 Type: tmpfs
status) Block size: 4096 Fundamental block size: 4096
Blocks: Total: 2556973 Free: 2556973 Available: 2556973
Inodes: Total: 2556973 Free: 2556535
- -l (long format), -i (inode), and -d (directory)
- Because of -d, ls reports on the directory itself, not its contents
Sample
- ls -i until.sh: 3420744
- df /home/sdev: /dev/mapper/sdev--vg-root
- sudo debugfs -R "stat <3420744>" /dev/mapper/sdev--vg-root

Inode: 3420744 Type: regular Mode: 0664 Flags: 0x80000


Generation: 3641184708 Version: 0x00000000:00000001

23
User: 1000 Group: 1000 Size: 95
File ACL: 0 Directory ACL: 0
Links: 2 Blockcount: 8
Fragment: Address: 0 Number: 0 Size: 0
ctime: 0x5eb0da6b:c94ab66c -- Tue May 5 10:15:55 2020
atime: 0x5eb0da2a:cd97d0bc -- Tue May 5 10:14:50 2020
mtime: 0x5eb01c8a:19b541c4 -- Mon May 4 20:45:46 2020
crtime: 0x5eb01c8a:19b541c4 -- Mon May 4 20:45:46 2020
Size of extra inode fields: 32
EXTENTS:
(0):21571909

- Inode: The number of the inode we’re looking at.


- Type: This is a regular file, not a directory or symbolic link.
- Mode: The file permissions in octal
- Flags: Indicators that represent different features or functionality. The 0x80000 is the
“extents” flag
- Generation: A Network File System (NFS) uses this when someone accesses remote
file systems over a network connection as though they were mounted on the local
machine. The inode and generation numbers are used as a form of file handle.
- Version: The inode version.
- User: The owner of the file.
- Group: The group owner of the file.
- Project: Should always be zero.
- Size: The size of the file.
- File ACL: The file access control list. These were designed to allow you to give
controlled access to people who aren’t in the owner group.
- Links: The number of hard links to the file.
- Blockcount: The amount of hard drive space allocated to this file, given in 512-byte
chunks. Our file has been allocated eight of these, which is 4,096 bytes. So, our 98-
byte file sits within a single 4,096-byte disk block.
- Fragment: This file is not fragmented. (This is an obsolete flag.)
- Ctime: The time at which the file attribute was changed.
- Atime: The time at which this file was last accessed.
- Mtime: The time at which this file was last modified.
- Crtime: The time at which the file was created.
- Size of extra inode fields: The ext4 file system introduced the ability to allocate a
larger on-disk inode at format time. This value is the number of extra bytes the inode
is using. This extra space can also be used to accommodate future requirements for
new kernels or to store extended attributes.
- Inode checksum: A checksum for this inode, which makes it possible to detect if the
inode is corrupted.
- Extents: If extents are being used (on ext4, they are, by default), the metadata
regarding the disk block usage of files has two numbers that indicate the start and end
blocks of each portion of a fragmented file. This is more efficient than storing every
disk block taken up by each portion of a file. We have one extent because our small
file sits in one disk block at this block offset.

Command Description
dd copies a file, converting the format of the data in the process, according to
the operands specified
dd if=/dev/sda of=~/disk1.img Create a ISO disc image from the CD in the computer.

24
dd if=/dev/sda of=/dev/sdb Copy the contents from the if= drive /dev/sda to the of= drive /dev/sdb.
dd if=/dev/zero of=/file bs=1k count=100 Create file from device /dev/zero. Read and write 1k bytes at a time (size of
block = 1k) and copy only 100 input blocks
lsof list open files
lsof -p <PID> ps -af
UID PID PPID C STIME TTY TIME CMD
sdev 3699 3696 0 Apr30 pts/0 00:00:00 npm

lsof -p 3699
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
npm 3699 sdev cwd DIR 252,0 4096 2753956 /home/sdev/dfk/autodeploy/central/dfk-
admin-server
npm 3699 sdev rtd DIR 252,0 4096 2/
npm 3699 sdev txt REG 252,0 35028537 3677653 /usr/bin/node
npm 3699 sdev mem REG 252,0 1868984 5772234 /lib/x86_64-linux-gnu/libc-2.23.so
npm 3699 sdev mem REG 252,0 138696 5772221 /lib/x86_64-linux-gnu/libpthread-
2.23.so
npm 3699 sdev mem REG 252,0 89696 5767693 /lib/x86_64-linux-gnu/libgcc_s.so.1
npm 3699 sdev mem REG 252,0 1088952 5772237 /lib/x86_64-linux-gnu/libm-2.23.so
npm 3699 sdev mem REG 252,0 1566440 3672100 /usr/lib/x86_64-linux-
gnu/libstdc++.so.6.0.21
npm 3699 sdev mem REG 252,0 31712 5772217 /lib/x86_64-linux-gnu/librt-2.23.so
npm 3699 sdev mem REG 252,0 14608 5772219 /lib/x86_64-linux-gnu/libdl-2.23.so
npm 3699 sdev mem REG 252,0 162632 5772220 /lib/x86_64-linux-gnu/ld-2.23.so
npm 3699 sdev 0u CHR 136,0 0t0 3 /dev/pts/0
npm 3699 sdev 1u CHR 136,0 0t0 3 /dev/pts/0
npm 3699 sdev 2u CHR 136,0 0t0 3 /dev/pts/0
npm 3699 sdev 3u a_inode 0,11 0 8114 [eventpoll]
npm 3699 sdev 4r FIFO 0,10 0t0 22814 pipe
npm 3699 sdev 5w FIFO 0,10 0t0 22814 pipe
npm 3699 sdev 6r FIFO 0,10 0t0 22815 pipe
npm 3699 sdev 7w FIFO 0,10 0t0 22815 pipe
npm 3699 sdev 8u a_inode 0,11 0 8114 [eventfd]
npm 3699 sdev 9u CHR 136,0 0t0 3 /dev/pts/0
npm 3699 sdev 10r CHR 1,3 0t0 6 /dev/null
npm 3699 sdev 11u CHR 136,0 0t0 3 /dev/pts/0

FD: File descriptor


- cwd current working directory;
- Lnn library references (AIX);
- err FD information error (see NAME column);
- jld jail directory (FreeBSD);
- ltx shared library text (code and data);
- Mxx hex memory-mapped type number xx.
- m86 DOS Merge mapped file;
- mem memory-mapped file;
- mmap memory-mapped device;
- pd parent directory;
- rtd root directory;
- tr kernel trace file (OpenBSD);
- txt program text (code and data);
- v86 VP/ix mapped file;
Sample
- How many files are opening? lsof | wc -l
- Lists files that are open in the directory specified, but it does not descend into sub-
directories? lsof +d <dir path>

25
Lab 5 – C basic in Linux
Output:
- Capture all windows for showing how does your programs run and which
command did you use to run your programs
- Upload images in zip file to LMS
1. Basic c in Linux
- which gcc: /usr/bin/gcc
- nm: list symbols from object files
- exit(0): process terminates normally successfully
- exit(1): process terminates normally unsuccessfully
- static and dynamic link

Figure 22: Compile time

2. Sample
Program Content
Static link int sum( int a, int b ){return a + b;}

long multiply (int a, int b) {return a*b;}

gcc -c sum.c multiply.c

header file: lib.h

int sum(int a, int b);

long multiply (int a, int b);

bai1.c
#include <stdio.h>
#include "lib.h"
int main(){
int a, b;
printf ("Nhap a: ");
scanf ("%d", &a);
printf ("Nhap b: ");

26
scanf ("%d", &b);
printf ("Tong %d + %d = %d\n", a, b, sum(a,b));
printf ("Tich %d * %d = %ld\n", a, b, multiply(a,b));
return 0;
}
gcc -c bai1.c
gcc bai1.o sum.o multiply.o -o bai1

create static lib that support sum and multiply: ar cvr lib.a sum.o multiply.o
gcc -o bai1 bai1.o lib.a
Dynamic link Using fpic (PIC- Position Independence Code) to compile: gcc -c -fpic sum.c
multiply.c

create dynamic lib:gcc -shared sum.o multiply.o -o lib.so

Compile & link: gcc bai1.c -o bai1 -L. lib.so

Import current directory to path

LD_LIBRARY_PATH=.:

export LD_LIBRARY_PATH

Check libs: ldd bai1

linux-vdso.so.1 => (0x00007ffef0ffc000)


lib.so => ./lib.so (0x00007fcdf0517000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fcdf0144000)

/lib64/ld-linux-x86-64.so.2 (0x0000563ac0264000)

mkdir dleg

cp lib.so bai1.c lib.h ./dleg

gcc bai1.c -o bai1 -L. lib.so


Symbols a symbol table is a data structure used by a language translator such as a compiler
or interpreter, where each identifier (a.k.a. symbol) in a program's source code is
associated with information relating to its declaration or appearance in the source.

nm bai1
0000000000601048 B __bss_start
0000000000601048 b completed.7594
0000000000601038 D __data_start
0000000000601038 W data_start
0000000000400530 t deregister_tm_clones
00000000004005b0 t __do_global_dtors_aux
0000000000600e18 t __do_global_dtors_aux_fini_array_entry
0000000000601040 D __dso_handle
0000000000600e28 d _DYNAMIC
0000000000601048 D _edata
0000000000601050 B _end
0000000000400764 T _fini

27
00000000004005d0 t frame_dummy
0000000000600e10 t __frame_dummy_init_array_entry
0000000000400928 r __FRAME_END__
0000000000601000 d _GLOBAL_OFFSET_TABLE_
w __gmon_start__
00000000004007b0 r __GNU_EH_FRAME_HDR
0000000000400480 T _init
0000000000600e18 t __init_array_end
0000000000600e10 t __init_array_start
0000000000400770 R _IO_stdin_used
U __isoc99_scanf@@GLIBC_2.7
w _ITM_deregisterTMCloneTable
w _ITM_registerTMCloneTable
0000000000600e20 d __JCR_END__
0000000000600e20 d __JCR_LIST__
w _Jv_RegisterClasses
0000000000400760 T __libc_csu_fini
00000000004006f0 T __libc_csu_init
U __libc_start_main@@GLIBC_2.2.5
00000000004005f6 T main
00000000004006d7 T multiply
U printf@@GLIBC_2.2.5
0000000000400570 t register_tm_clones
U __stack_chk_fail@@GLIBC_2.4
0000000000400500 T _start
00000000004006c3 T sum

0000000000601048 D __TMC_END__

Address – Type - Name

A: The symbol's value is absolute, and will not be changed by further linking.

B: The symbol is in the uninitialized data section (known as BSS ).

D: The symbol is in the initialized data section.

R: The symbol is in a read only data section

T: The symbol is in the text (code) section.

U: The symbol is undefined.

u: The symbol is a unique global symbol


nm -f sysv sum.o
Name Value Class Type Size Line Section
sum |0000000000000000| T | FUNC|0000000000000014| |.text

Lab 6a – Process management in C language


Output:
- Capture all windows for showing how does your programs run and which
command did you use to run your programs

28
- Upload images in zip file to LMS
1. c in Linux
- System()
- Exec()
- Fork() and child process
- System calls: exit(), fork(), pipe()

Figure 23: fork()

2. Sample
Program Content
Using system #include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
int main (){
printf ("Practice with system\n");
// system (const char (cmdstr))
system ("ps -ax");
system ("mkdir bai2");
system ("cp bai2a ./bai2/");
sleep(10);
printf("Done\n");
exit (0);
}

29
We have some processes here
Using exec #include <unistd.h>
extern char **environ;
int execl( const char *path, const char *arg, ... );
int execlp( const char *file, const char *arg, ... );
int execle( const char *path, const char *arg, ..., char *const envp[] ); int
exect( const char *path, char *const argv[] );
int execv( const char *path, char *const argv[] );
int execvp( const char *file, char *const argv[] );

Process A is running, we start process B that uses A’s address space with same
PID (replace A) à using exec. What is output?

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
int main() {
printf ( "Replace this program with ps using exec\n" );
execlp ( "ps", "ps", "-aux", (char *) 0 );
printf ( "Done!!\n");
exit(0);}
Using fork What is output?

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main()
{
printf("Parent process - Hello world!\n");
fork();
sleep(10);
printf("Hello world!\n");
return 0;
}

ps -af | grep bai2c


sdev 32686 32234 0 11:56 pts/2 00:00:00 ./bai2c
sdev 32687 32686 0 11:56 pts/2 00:00:00 ./bai2c
Using fork What is output?

#include<unistd.h>
#include<stdio.h>
#include<sys/types.h>
#include <stdlib.h>
int main(){
pid_t pid;
char* msg;
int i;
pid =fork();
switch (pid){
case -1:
printf("Cannot create child process\n");
exit (1);

30
case 0:
msg="This is child process\n";
i=0;
for (;i<10;i++){printf("%s", msg); sleep(2);}
break;
default:
msg="This is parent process\n";
i=0;
for (;i<5;i++){printf("%s", msg); sleep(2);}
break;
}
exit(0);

ps -af | grep bai2d


sdev 2092 1673 0 13:59 pts/2 00:00:00 ./bai2d

sdev 2093 2092 0 13:59 pts/2 00:00:00 ./bai2d

ps -af | grep bai2d


sdev 2093 1 0 13:59 pts/2 00:00:00 ./bai2d
Wait() #include <sys/types.h>
#include <sys/wait.h>
pid_t wait(int &stat_loc);

#include<unistd.h>
#include<stdio.h>
#include<sys/types.h>
#include <stdlib.h>
#include<sys/wait.h>
int main(){
pid_t pid;
char* msg;
int i;
int child_status;
pid =fork();
switch (pid){
case -1:
printf("Cannot create child process\n");
exit (1);
case 0:
msg="This is child process\n";
i=0;
for (;i<10;i++){printf("%s", msg); sleep(2);}
break;
default:
msg="This is parent process\n";
i=0;
wait( &child_status );
for (;i<5;i++){printf("%s", msg); sleep(2);}
break;
}
exit(0);

31
}
What is output?

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
void forkeg ()
{
int x = 1;

if (fork() == 0)
printf ("Child has x = %d\n", ++x);
else
printf ("Parent has x = %d\n", --x);
}
int main()
{
forkeg ();
return 0;

}
Wait() 1. WIFEXITED(status): child exited normally
• WEXITSTATUS(status): return code when child exits

2. WIFSIGNALED(status): child exited because a signal was not caught


• WTERMSIG(status): gives the number of the terminating signal

3. WIFSTOPPED(status): child is stopped


• WSTOPSIG(status): gives the number of the stop signal

#include<unistd.h>
#include<stdio.h>
#include<sys/types.h>
#include <stdlib.h>
#include<sys/wait.h>
int main(){
pid_t pid;
char* msg;
int i;
int child_status;
pid =fork();
switch (pid){
case -1:
printf("Cannot create child process\n");
exit (1);
case 0:
msg="This is child process\n";
i=0;
for (;i<10;i++){printf("%s", msg); sleep(2);}
exit(10);
default:
msg="This is parent process\n";
i=0;

32
for (;i<5;i++){printf("%s", msg); sleep(2);}
wait( &child_status );
if ( WIFEXITED( child_status ))
printf( "Child process exited with code %d\n",WEXITSTATUS(
child_status ) );
else if (WIFSIGNALED(child_status))
psignal(WTERMSIG(child_status), "Exit signal");
break;
}
exit(0);

./bai2g
This is parent process
This is child process
This is parent process
This is child process
This is parent process
This is child process
This is parent process
This is child process
This is parent process
This is child process
This is child process
This is child process
Exit signal: Terminated

$ ps -af | grep bai2g


sdev 5189 3975 0 17:10 pts/2 00:00:00 ./bai2g
sdev 5190 5189 0 17:10 pts/2 00:00:00 ./bai2g

$ kill 5190

Lab 6b – Threads in C language


Output:
- Capture all windows for showing how does your programs run and which
command did you use to run your programs
- Upload images in zip file to LMS

- Thread = lightweight process


- Single thread & multithread

33
Figure 24: Single thread and multithreads

- User Level Threads & Kernel Level Threads


o User-level threads are implemented by users and the kernel is not aware of
the existence of these threads. It handles them as if they were single-threaded
processes. User-level threads are small and much faster than kernel level
threads. They are represented by a program counter(PC), stack, registers and a
small process control block. Also, there is no kernel involvement in
synchronization for user-level threads.
o Kernel-level threads are handled by the operating system directly and the
thread management is done by the kernel. The context information for the
process as well as the process threads is all managed by the kernel. Because of
this, kernel-level threads are slower than user-level threads.

34
Figure 25: User & Kernel threads

Sample
Program Content
#include <pthread.h>

int pthread_create ( pthread_t * thread, pthread_attr_t* attr,

void* (*start_routine) (void*), void* arg);

The pthread_create() function is used to create a new thread, with attributes


specified by attr, within a process. It is NULL if default value. The thread is
created executing start_routine with arg as its sole argument

int pthread_join (pthread_t th, void* thread_return);

The pthread_join() function waits for the thread specified by thread to terminate.
th is thread you want to wait. If thread_return is not NULL, then pthread_join()
copies the exit status of the target thread into the location pointed to by
thread_return. On success, pthread_join() returns 0; on error, it returns an error
number
thread #include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
void *myThread(void *vargp)
{
sleep(30);
printf("Printing Thread \n");
return NULL;
}

int main()
{

35
pthread_t thread_id;
printf("Before Thread\n");
pthread_create(&thread_id, NULL, myThread, NULL);
pthread_join(thread_id, NULL);
printf("After Thread\n");
exit(0);

gcc -pthread threadeg.c -o threadeg

ps -af | grep threadeg

9077 8627 0 22:38 pts/2 00:00:00 ./threadeg

ps -T -p 9077

PID SPID TTY TIME CMD


9077 9077 pts/2 00:00:00 threadeg

9077 9078 pts/2 00:00:00 threadeg

SPID: thread ID

top -H -p P 9152 ID
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+
COMMAND IME+ COMMAND
9152 sdev 20 0 14712 812 732 S 0.0 0.0 0:00.00 threadeg

9153 sdev 20 0 14712 812 732 S 0.0 0.0 0:00.00 threadeg

Lab 7a – Pipe / Signal in C language


Output:
- Capture all windows for showing how does your programs run and which
command did you use to run your programs
- Upload images in zip file to LMS

- IPC – inter process communication


o Message
o Signal
o Shared memory
o Pipe
o Socket
- Zombie / orphan
- Parent / children à only in Linux we have these terms

POSIX signals
- SIGINT: interrupt
- SIGTSTP: terminal stop.
- SIGSTOP: instructs the operating system to stop a process for later resumption

36
- SIGKILL: kill
- SIGTERM: termination. This allows the process to perform nice termination releasing
resources and saving state if appropriate
- SIGTRAP signal is sent to a process when an exception (or trap) occurs
- SIGSYS signal is sent to a process when it passes a bad argument to a system call
- SIGSEGV signal is sent to a process when it makes an invalid virtual memory
reference, or segmentation fault
- SIGILL signal is sent to a process when it attempts to execute an illegal, malformed,
unknown, or privileged instruction
- kill -INT 1234: send interrupt signal to process PID=1234
- kill -l

Pipe: Pipes behave FIFO(First in First out), Pipe behave like a queue data structure. Size of
read and write don’t have to match here. We can write 512 bytes at a time but we can read
only 1 byte at a time in a pipe
- anonymous pipe: is only used for communication between a child and its parent
process à pipe()
- named pipe: can be used for communication between two unnamed process à
mkfifo()

Figure 26: Pipe()

37
Figure 27: pipe between parent and child processes

Sample
Program Content
Catch signals Cannot catch KILL or STOP signals
using signal()
#include <signal.h>
void signal( int signum, void (*sighanldler)( int ) );

What happens if we do ctrl+c?

#include<stdio.h>
#include<unistd.h>
#include<signal.h>
void catch_sig(int sig_nr){
signal(SIGINT, catch_sig);
printf ("Do not press ctr+C. Signal number is %d\n", sig_nr);
}
int main(){
for(int i=0; i<10; i++){
printf("Do something number %d\n",i);
signal(SIGINT, catch_sig);
sleep(2);
}
}
Pipe() #include <unistd.h>

int pipe( int filedes[2] );

filedes[0]: to read / filedes[1]: to write

read (data pipe, phuf, PBUFSIZE ) / write (data pipe, phuf, PBUFSIZE )

38
Sample: Create a pipe. There are 2 processes: A and B (B is child process). A to
read data from user and write to pipe. B to read data from pipe and write to screen

#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>

void doA (int data_pipes[]){


int c;
close (data_pipes[0]);
while ( (c=getchar()) > 0){
if (write(data_pipes[1], &c, 1)==-1){
perror ("Process A cannot write to pipe");
close(data_pipes[1]);
exit(1);
}
}
close(data_pipes[1]);
exit(0);
}

void doB (int data_pipes[]){


int c;
close(data_pipes[1]);
while (read(data_pipes[0], &c, 1) > 0) putchar(c);
exit(0);
}

//process A
int main(){
int data_pipes[2];
int pid;
int rc = pipe (data_pipes);
if (rc==-1) {
perror("pipe cannot be created!");
exit(1);
}
pid=fork();//process B
switch (pid){
case -1: perror("child process cannot be created!"); exit(1);
case 0: doB(data_pipes);
default: doA(data_pipes);
}
return 0;
}
mkfifo() #include <sys/types.h>
#include <sys/stat.h>
mkfifo( const char *filename, mode_t mode );

mkfifo ./myfifo --mode=777

ls -ltr

39
prwxrwxrwx 1 sdev sdev 0 May 7 18:56 myfifo

echo hello world! > ./myfifo & cat < ./myfifo

[1] 6313
hello world!

[1]+ Done echo hello world! > ./myfifo

Same to working with file, but there are only O_WRONLY and O_RDONLY

Write first

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include<string.h>
#include<fcntl.h>
int main(){
char * myfifo="./my_channel";
mkfifo(myfifo,0666);
char readarr[256], writearr[256];
int fc;
while (1){
fc=open(myfifo, O_WRONLY);
fgets(writearr, sizeof(writearr), stdin);
write(fc, writearr, strlen(writearr)+1);
close(fc);
fc=open(myfifo, O_RDONLY);
read(fc, readarr, sizeof(readarr));
printf("Process 2 say: %s\n", readarr);
close(fc);
}
return 0;

Read first

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include<string.h>
#include<fcntl.h>
int main(){
char * myfifo="./my_channel";
mkfifo(myfifo,0666);
char readarr[256], writearr[256];
int fc;
while (1){

40
fc=open(myfifo, O_RDONLY);
read(fc, readarr, sizeof(readarr));
printf("Process 1 say: %s\n", readarr);
close(fc);
fc=open(myfifo, O_WRONLY);
fgets(writearr, sizeof(writearr), stdin);
write(fc, writearr, strlen(writearr)+1);
close(fc);
}
return 0;

Lab 7b – Socket / Shared Memory in C language


Output:
- Capture all windows for showing how does your programs run and which
command did you use to run your programs
- Upload images in zip file to LMS

Program Content
Socket Chat client – chat server

#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include<arpa/inet.h>
#include<unistd.h>
#define MAX 80
#define PORT 1234
#define SA struct sockaddr
void func(int sockfd)
{
char buff[MAX];
int n;
for (;;) {
bzero(buff, sizeof(buff));
printf("Enter the string : ");
n = 0;
while ((buff[n++] = getchar()) != '\n')
;
write(sockfd, buff, sizeof(buff));
bzero(buff, sizeof(buff));
read(sockfd, buff, sizeof(buff));
printf("From Server : %s", buff);
if ((strncmp(buff, "exit", 4)) == 0) {
printf("Client Exit...\n");
break;
}
}

41
}

int main()
{
int sockfd, connfd;
struct sockaddr_in servaddr, cli;

// socket create and varification


sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd == -1) {
printf("socket creation failed...\n");
exit(0);
}
else
printf("Socket successfully created..\n");
bzero(&servaddr, sizeof(servaddr));

// assign IP, PORT


servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");
servaddr.sin_port = htons(PORT);

// connect the client socket to server socket


if (connect(sockfd, (SA*)&servaddr, sizeof(servaddr)) != 0) {
printf("connection with the server failed...\n");
exit(0);
}
else
printf("connected to the server..\n");

// function for chat


func(sockfd);

// close the socket


close(sockfd);
}

#include<unistd.h>
#include <stdio.h>
#include <netdb.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#define MAX 80
#define PORT 1234
#define SA struct sockaddr

// Function designed for chat between client and server.


void func(int sockfd)
{
char buff[MAX];
int n;
// infinite loop for chat

42
for (;;) {
bzero(buff, MAX);
// read the message from client and copy it in buffer
read(sockfd, buff, sizeof(buff));
// print buffer which contains the client contents
printf("From client: %s\t To client : ", buff);
bzero(buff, MAX);
n = 0;
// copy server message in the buffer
while ((buff[n++] = getchar()) != '\n');
// and send that buffer to client
write(sockfd, buff, sizeof(buff));
// if msg contains "Exit" then server exit and chat ended.
if (strncmp("exit", buff, 4) == 0) {
printf("Server Exit...\n");
break;
}
}
}
int main()
{
int sockfd, connfd, len;
struct sockaddr_in servaddr, cli;

// socket create and verification


sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd == -1) {
printf("socket creation failed...\n");
exit(0);
}
else
printf("Socket successfully created..\n");
bzero(&servaddr, sizeof(servaddr));

// assign IP, PORT


servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(PORT);

// Binding newly created socket to given IP and verification


if ((bind(sockfd, (SA*)&servaddr, sizeof(servaddr))) != 0) {
printf("socket bind failed...\n");
exit(0);
}
else
printf("Socket successfully binded..\n");

// Now server is ready to listen and verification


if ((listen(sockfd, 5)) != 0) {
printf("Listen failed...\n");
exit(0);
}
else
printf("Server listening..\n");
len = sizeof(cli);

43
// Accept the data packet from client and verification
connfd = accept(sockfd, (SA*)&cli, &len);
if (connfd < 0) {
printf("server acccept failed...\n");
exit(0);
}
else printf("server acccept the client...\n");
// Function for chatting between client and server
func(connfd);
// After chatting close the socket
close(sockfd);
}

Shared Create shared memory 128 bytes for 2 processes


memory Process 1writes 2 integers into shared memory
Process 2 reads from shared memory and write sum of integers into shared
memory
Process 1 reads the sum and writes out

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include<stdio.h>
#include<unistd.h>
int main(){
int *shm, shmid, i;
shmid = shmget(IPC_PRIVATE, 128, IPC_CREAT | 0666);
shm=(int*) shmat (shmid, 0,0);
if(fork()==0) {
shm[0]=111;
shm[1]=999;
sleep(3);
printf("Process %d reads: Sum = %d", getpid(), shm[2]);
shmdt((void *)shm);
shmctl(shmid, IPC_RMID, (struct shmid_ds *) 0);
}
else {
sleep(1);
printf("Process %d writes to shared memory ...\n", getpid());
shm[2]=shm[0]+shm[1];
shmdt((void *)shm);
}
return(0);
}

Lab 8 – Semaphore / mutex


Output:
- Capture all windows for showing how does your programs run and which
command did you use to run your programs
- Upload images in zip file to LMS

- Shared resource: data, variable,…

44
- Race conditions: 2 or more processes are reading/writing some shared data and the
final result depends on who runs precisely when
- Critical section/critical region: the part of the program where the shared resource is
accessed

Making sure 2 or more processes do not get in each other’s way: 3 requirements
- Mutual Exclusion: if process Pi is executing in its critical section, no other process
can execute in its critical section
- Progress: if process pi wants to entering in its critical section then should be chosen to
enter
- Bounded waiting: no process should have wait forever to enter its critical section

Solution
- Semaphore (sleep & wake)
o Counter: 0/1 – binary semaphore (mutex) ; counting semaphore
o Atomic operations: all done as single operation (check values, changes,
sleep…)- down() / up()
§ Up(): free shared resource, check waiting queue, choose one process
from waiting queue and wake it up
§ Down(): request to enter shared resource. If no free resource, go to
waiting queue (sleep) à blocked
§ New
§ delete
- Busy waiting (Peterson algorithm)

Question L80: Nơi sản xuất rất nhỏ, chỉ có thể sản xuất 1 thứ hoặc lắp ráp, không thể làm
cùng lúc. Quy trình sản xuất xe đạp, bao gồm 3 tiến trình con như sau
- Sản xuất khung xe: Sanxuatkhungxe(){}
- Sản xuất bánh xe: Sanxuatbanhxe(){}
- Lắp ráp thành phẩm: Laprap(){}
Hãy đồng bộ hoạt động sản xuất này bằng cách sử dụng semaphore

Semaphore sKhungxe, sBanhxe, sLaprap; //mutex


sLaprap.Init = 0;
sKhungxe.Init = 0;
sBanhxe.Init = 1;
Sanxuatkhungxe(){
While(true){
Down(sKhungxe);
//San xuat
Up(sLaprap);
}
}
Sanxuatbanhxe(){
While(true){
Down(sBanhxe);
//San xuat
Up(sLaprap);
}
}

45
Laprap(){
While(true){
Down(sLaprap);
Down(sLaprap);
Down(sLaprap);
//Lap rap
Up(sKhungxe);
Up(sBanhxe);
Up(sBanhxe);
}
}

Question L81:

Mutex m=1; x=2;


P1: {
(1) m.down(); (2) x=x+5; (3) m.up()}
P2: {
(4) m.down(); (5) x=x*3; (6) m.up()}
P3: {
(7) m.down(); (8) x=x-2; (9) m.up()}

Xác định các trạng thái của các process trong trường hợp chạy như sau: 1, 4, 7, 2, 3, 5,
6, 8, 9

(1) m=0, P1: running, P2, P3: ready


(4) m=-1, P1: ready, P2: running à blocked, P3: ready
(7) m= -2, P1: ready, P2: blocked, P3: running à blocked
(2) x=7, P1: running
(3) m=-1, P1: running, P2: blocked à ready , P3: blocked
(5) x=21, P2: running, P3: blocked
(6) m=0, P2: running, P3: blocked à ready
(8) x=19, P3: running
(9) m=1, P3: running

Sample
Program Content
Producer- #include <stdio.h>
consumer #include <stdlib.h>
problem #include <unistd.h>
#include <malloc.h>
#include <pthread.h>

struct jobQueue {
struct jobQueue* nextJob;
int code;
};
pthread_mutex_t lock;
struct jobQueue *head = NULL;
struct jobQueue *tail = NULL;
int size = 0;

46
int capacity = 5;
int i=0;
void *threadEnqueue() {
while(1) {
if (size < capacity) {
i++;
size++;
printf("Enqueuing job %d. Size of queue is %d\n", i,size);
struct jobQueue *thisJob = (struct jobQueue*) malloc(sizeof(struct
jobQueue));
thisJob->code = i;
thisJob->nextJob = NULL;
if (tail != NULL)
tail->nextJob = thisJob;
if (head == NULL) {
head = thisJob;
}
tail = thisJob;
}
else printf("Full capacity\n");
sleep(2);
}

}
void *threadDequeue() {
while(1) {
pthread_mutex_lock(&lock);
if (size > 0 && head != NULL) {
printf("Dequeuing job %d. Size of queue is %d\n", head->code, --
size);
head = head->nextJob;
//size--;
}
else printf("Queue is empty\n");
sleep(7);
pthread_mutex_unlock(&lock);
}
}
int main(){
pthread_t thread1, thread2;

if (pthread_mutex_init(&lock, NULL) != 0)
{
printf("Mutex initialization is failed.\n");
return 1;
}

pthread_create(&thread2, NULL, threadDequeue, NULL);


pthread_create(&thread1, NULL, threadEnqueue, NULL);
pthread_join(thread1, NULL);
pthread_join(thread2, NULL);
while(1);
return 0;
}

47
Lab 9 - Deadlock & livelock
Livelock: no have deadlock, but functionally equivalent to deadlock

/* PROCESS 0 */
flag[0] = true; 1 9
while (flag[1]) { 3
flag[0] = false; 5
/*delay */;
flag[0] = true; 7
}
/*critical section*/;
flag[0] = false;

/* PROCESS 1 */
flag[1] = true; 2 10
while (flag[0]) { 4
flag[1] = false; 6
/*delay */;
flag[1] = true; 8
}
/* critical section*/;
flag[1] = false;

Deadlock’s conditions:
- Mutual exclusion
- Hold and wait
- Non-preemption
- Circular wait

Solution:
- Prevention: conditions
- Avoidance: safe & unsafe state (Banker’s algorithm)
- Detect and recovery: kill one by one / kill all
- Ignore

Question L90
Allocation Max Available
A B C A B C A B C
P1 2 1 0 7 5 3 3 3 2
P2 3 0 2 9 0 2
P3 0 0 2 4 3 3
P4 1 0 0 3 2 2
P5 1 1 1 2 2 2

Số lượng instance của resource: A = 10, B = 5, C=7


Giả sử lúc này P1 yêu cầu thêm tài nguyên là: (3, 4, 1) à có thể cấp tài nguyên cho P1 hay
không?(Banker)

Yêu cầu available hay ko? à ko à cancel

48
Giả sử lúc này P1 yêu cầu thêm tài nguyên là: (3, 1, 1) à có thể cấp tài nguyên cho P1 hay
không?(Banker)

Allocation Max Available


A B C A B C A B C
P1 2 1 0 7 5 3 3 3 2
P2 3 0 2 9 0 2
P3 0 0 2 4 3 3
P4 1 0 0 3 2 2
P5 1 1 1 2 2 2

Resource (10, 5, 7)
Yêu cầu available hay ko? à có
P1 (2,1,0) + (3,1,1) = (5,2,1) à available (0,2,1) à free à available (0, 2, 1) + (5,2,1) =
(5,4,2)
P2 à chạy? à
P3 à chạy? à free à available (5, 4, 4)
P4, p5, p2
P1, p3, p4, p5, p2 à safe state à có thể cấp tài nguyên vì có safe state

Giả sử lúc này P3 yêu cầu thêm tài nguyên là: (3, 1, 0) à có thể cấp tài nguyên cho P3 hay
không?(Banker)

Command Description
Sudo strace -p <PID> accept(3, {sa_family=AF_UNSPEC, sa_data="\0\0\0\0\0\0\0\0\0\0\0\0\0\0"}, [16]) = 5
(trace system calls mmap(NULL, 8392704, PROT_READ|PROT_WRITE,
and signals) à to MAP_PRIVATE|MAP_ANONYMOUS|MAP_STACK, -1, 0) = 0x7fd62f550000
check if program is mprotect(0x7fd62f550000, 4096, PROT_NONE) = 0
stuck clone(child_stack=0x7fd62fd4fff0,
flags=CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLO
NE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID
, parent_tidptr=0x7fd62fd509d0, tls=0x7fd62fd50700, child_tidptr=0x7fd62fd509d0) = 22340

accept(3, 0x6021a0, 0x6021b0) = ? ERESTARTSYS (To be restarted if SA_RESTART is


set)
--- SIGINT {si_signo=SIGINT, si_code=SI_KERNEL} ---
+++ killed by SIGINT +++
ps aux | grep sdev 22373 0.0 0.0 6556 756 pts/2 S+ 18:16 0:00 ./chatserver
<program name> if status is D à deadlock (stuck)

Lab 10 – Storage & Disk arm scheduling


Output:
- Capture all windows for showing how does your command run
- Upload images in zip file to LMS

Command Description
df File system disk space report
sudo blockdev --getbsz /dev/sda Size of block on file system
df -B 4096 /dev/sda1 Filesystem 4K-blocks Used Available Use% Mounted on
/dev/sda1 120731 14620 99877 13% /boot
df -h List all mounted device / partation
- File system: The file system on which we’re reporting.

49
- 4K-blocks: The total number of 4 KB blocks in this file system.
- Used: How many 4K blocks are in use.
- Available: The number of remaining 4 KB blocks that are available for use.
- Use%: The percentage of 4 KB blocks that have been used.
- Mounted on: The mount point for this file system.

Disk's structure:
- sector,
- track,
- spindle,
- cylinder,
- platter,
- read-write head,
- arm,
- arm assembly

Figure 28: Disk's structure

Formatting / Defragmenting Disks / error on disk (spare sector)

RAID: Redundant Arrays of Inexpensive Disks


- RAID 0
- RAID 1
- RAID 10
- RAID 5

50
Disk Space Management: Block Size / Track of Free Blocks (bitmaps, linked lists) / Disk
Quotas

Disk arm scheduling: Seek / rotational delay / transfer time / Advertised average seek time /
Disk spins / Controller overhead / Disk access time
- FCFS
- SSTF (Shortest seek time first)
- SCAN
- LOOK
- C-SCAN
- C-LOOK

Example
- Work Queue: 23, 89, 132, 42, 187
- there are 200 cylinders numbered from 0 - 199
- the disk head stars at number 100

FCFS

SSTF

51
SCAN (assume we are going inwards)

LOOK

C-SCAN

C-LOOK

52
Question L100: Suppose a disk has 201 cylinders, numbered from 0 to 200. At some time,
the disk arm is at cylinder 100, and there is a queue of disk access requests for cylinders 30,
85, 90, 100, 105, 110, 135 and 145. If Shortest-Seek Time First (SSTF) is being used for
scheduling the disk access, the request for cylinder 90 is serviced after servicing
____________ number of requests.
(A) 1
(B) 2
(C) 3
(D) 4

Question L101: Consider an operating system capable of loading and executing a single
sequential user process at a time. The disk head scheduling algorithm used is First Come First
Served (FCFS). If FCFS is replaced by Shortest Seek Time First (SSTF), claimed by the
vendor to give 50% better benchmark results, what is the expected improvement in the I/O
performance of user programs?
(A) 50%
(B) 40%
(C) 25%
(D) 0%

Question L102: Suppose the following disk request sequence (track numbers) for a disk with
100 tracks is given: 45, 20, 90, 10, 50, 60, 80, 25, 70. Assume that the initial position of the
R/W head is on track 50. The additional distance that will be traversed by the R/W head
when the Shortest Seek Time First (SSTF) algorithm is used compared to the SCAN
(Elevator) algorithm (assuming that SCAN algorithm moves towards 100 when it starts
execution) is _________ tracks
(A) 8
(B) 9
(C) 10
(D) 11

Questions L103: Consider a typical disk that rotates at 15000 rotations per minute (RPM)
and has a transfer rate of 50 × 10^6 bytes/sec. If the average seek time of the disk is twice the
average rotational delay and the controller’s transfer time is 10 times the disk transfer time,
the average time (in milliseconds) to read or write a 512-byte sector of the disk is
_____________

53
Disk latency = Seek Time + Rotation Time +Transfer Time + Controller Overhead
Average Rotational Time = (0.5)/(15000 / 60) = 2 miliseconds
It is given that average seek time is twice the average rotational delay à Avg. Seek Time =
2 * 2 = 4 miliseconds.
Transfer Time = 512 / (50 × 106 bytes/sec)= 10.24 microseconds
It is given that controller time is 10 times the average transfer timeController Overhead = 10
* 10.24 microseconds= 0.1 miliseconds

Lab 11 – I/O management


Output:
- Capture all windows for showing how does your command run
- Upload images in zip file to LMS

I/O software layers


- Interrupt Handlers
- Device controller & Device Drivers
- Device-Independent I/O Software
- User-Space I/O Software

Figure 29: Layers of the I/O software system

How to detect the arrival of I/O


- Polling
- Interrupt
CPU-Devices communication
- Special Instruction
- Memory-mapped
- Direct memory access (DMA)

54
Figure 30: Hardware communication

Figure 31: DMA

Device-Independent I/O Software


- Uniform interface

55
- Device naming
- Device protection
- Device-independent block size
- Buffering
- Allocation and releasing dedicated devices
- Error Reporting
Major & Minor number
- ls -ltr /dev
- brw-rw---- 1 root disk 7, 6 Apr 30 13:57 loop6
Buffering / double buffering
Daemon / spooling & spooling directory
Loop device / snap package
- a loop device, vnd (vnode disk), or lofi (loop file interface) is a pseudo-device that
makes a file accessible as a block device.
- Snap package: A snap bundles an application and all its dependents into one
compressed file. The dependents might be library files, web or database servers, or
anything else an application must have to launch and run. At run time that the snap
file is mounted on a block loop device. This allows the file’s internal SquashFS file
system to be accessed.

Command Description
df -t squashfs Filesystem 1K-blocks Used Available Use% Mounted on
/dev/loop0 96256 96256 0 100% /snap/core/9066
/dev/loop1 177536 177536 0 100% /snap/wekan-ondra/120
/dev/loop2 177536 177536 0 100% /snap/wekan-ondra/121
/dev/loop3 96128 96128 0 100% /snap/core/8935
lsblk list block devices
lsblk --nodeps /dev/sda5 NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda5 8:5 0 111.3G 0 part
- RO: read-only if 1 and 0 otherwise
- RM: 1 if the device is removable (Eg. Cdrom, USB) or 0 if the device is not removable
(Eg. Physical volume)
- TYPE: Displays whether the device is a loopback device, disk, partition or under LVM
control.
- MOUNTPOINT: The name of the file system on which the device is mounted.
lsblk -s -m NAME SIZE OWNER GROUP MODE
(-s: size, -m: permission) sda1 487M root disk brw-rw----
`-sda 111.8G root disk brw-rw----
sda2 1K root disk brw-rw----
`-sda 111.8G root disk brw-rw----
sdev--vg-root 91.4G root disk brw-rw----
`-sda5 111.3G root disk brw-rw----
`-sda 111.8G root disk brw-rw----
sdev--vg-swap_1 20G root disk brw-rw----
`-sda5 111.3G root disk brw-rw----
`-sda 111.8G root disk brw-rw----
loop0 93.9M root disk brw-rw----
loop1 173.3M root disk brw-rw----
loop2 173.4M root disk brw-rw----
loop3 93.8M root disk brw-rw----
losetup set up and control loop devices
losetup -l NAME SIZELIMIT OFFSET AUTOCLEAR RO BACK-FILE
/dev/loop0 0 0 1 1 /var/lib/snapd/snaps/core_9066.snap
/dev/loop1 0 0 1 1 /var/lib/snapd/snaps/wekan-ondra_120.snap
/dev/loop2 0 0 1 1 /var/lib/snapd/snaps/wekan-ondra_121.snap
/dev/loop3 0 0 1 1 /var/lib/snapd/snaps/core_8935.snap

mkfs Build a Linux file system, usually a hard disk partition


mkfs -t ext2 /dev/loop0 100 Build a ext2 file system on loop device in the first loop device (ID=0) with 100 blocks
and mount to /mnt

56
mount -t ext2 /dev/loop0
/mnt
fdisk Partition table editor
sudo fdisk -l Disk /dev/loop0: 93.9 MiB, 98484224 bytes, 192352 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk /dev/sda: 111.8 GiB, 120034123776 bytes, 234441648 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0xcf7a8a39

Device Boot Start End Sectors Size Id Type


/dev/sda1 * 2048 999423 997376 487M 83 Linux
/dev/sda2 1001470 234440703 233439234 111.3G 5 Extended
/dev/sda5 1001472 234440703 233439232 111.3G 8e Linux LVM
Disk /dev/mapper/sdev--vg-root: 91.4 GiB, 98087993344 bytes, 191578112 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes

Disk /dev/mapper/sdev--vg-swap_1: 20 GiB, 21407727616 bytes, 41811968 sectors


Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes

57

You might also like