Skip to content

Commit 0b1d6bb

Browse files
committed
Add comprehensive troubleshooting guide and shortcuts reference for Linux systems
- Created a new markdown file for "OS in Practice" detailing real-world troubleshooting workflows for common server issues, including CPU, memory, disk, network, and application problems. - Added a new markdown file for "Linux Shortcuts" that serves as a complete reference for terminal shortcuts across various tools like bash, vim, less/man, top, htop, tmux, and nano.
1 parent d3aa651 commit 0b1d6bb

8 files changed

Lines changed: 3487 additions & 0 deletions

COMMANDS-AND-Guides/operating-systems/05-users-and-permissions.md

Lines changed: 421 additions & 0 deletions
Large diffs are not rendered by default.

COMMANDS-AND-Guides/operating-systems/06-networking-from-os.md

Lines changed: 400 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 367 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,367 @@
1+
# Operating Systems — 07: Storage and Disks
2+
3+
> **Last updated:** July 6, 2026
4+
> **Block devices, partitions, mount, and how AWS EBS volumes actually appear in Linux.**
5+
6+
---
7+
8+
## The Storage Stack
9+
10+
From physical disk to a file you can open, there are several layers:
11+
12+
```
13+
Your App
14+
15+
File (open("/data/db.sqlite"))
16+
17+
Filesystem (ext4, xfs — manages files, directories, permissions)
18+
19+
Block Device (/dev/nvme0n1p1 — a partition)
20+
21+
Block Device (/dev/nvme0n1 — the whole disk)
22+
23+
Storage driver (NVMe driver in the kernel)
24+
25+
Physical or virtual disk (EBS volume, NVMe SSD, HDD)
26+
```
27+
28+
Each layer provides an abstraction. You can swap them out (different filesystems, different disks) without changing your app.
29+
30+
---
31+
32+
## Block Devices
33+
34+
A block device is a file in `/dev/` that represents a storage device. It exposes a fixed-size, random-access byte array.
35+
36+
```bash
37+
# List all block devices:
38+
lsblk
39+
40+
# Output on a typical EC2 instance:
41+
# NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
42+
# nvme0n1 259:0 0 20G 0 disk
43+
# └─nvme0n1p1 259:1 0 20G 0 part / ← root partition, mounted at /
44+
# nvme1n1 259:2 0 100G 0 disk ← attached EBS, not partitioned yet
45+
# xvda 8:0 0 20G 0 disk ← older EC2 uses this naming
46+
47+
# With filesystem type:
48+
lsblk -f
49+
50+
# NAME FSTYPE FSVER LABEL UUID MOUNTPOINTS
51+
# nvme0n1
52+
# └─nvme0n1p1 xfs / abc-123-... /
53+
# nvme1n1 (no filesystem yet)
54+
```
55+
56+
### Device Naming
57+
58+
```
59+
NVMe (modern EC2, m5, c5, r5, etc.):
60+
nvme0n1 → first NVMe device
61+
nvme0n1p1 → first partition of nvme0n1
62+
nvme1n1 → second NVMe device (second EBS volume)
63+
64+
Xen virtual disk (older EC2 instance types like m3):
65+
xvda → first virtual disk
66+
xvda1 → first partition
67+
xvdb, xvdc → additional EBS volumes
68+
69+
SATA/SCSI (physical servers, not EC2):
70+
sda → first disk
71+
sda1 → first partition
72+
sdb → second disk
73+
```
74+
75+
---
76+
77+
## Partitions
78+
79+
A **partition** divides a disk into independent regions. Each partition can have its own filesystem.
80+
81+
```bash
82+
# View partition table:
83+
sudo fdisk -l /dev/nvme1n1
84+
# Disk /dev/nvme1n1: 100 GiB, 107374182400 bytes, 209715200 sectors
85+
# Disk model: Amazon Elastic Block Store
86+
# Disklabel type: gpt
87+
# ... (no partitions if brand new)
88+
89+
# Create a partition (interactive):
90+
sudo fdisk /dev/nvme1n1
91+
# Commands:
92+
# n → new partition
93+
# p → primary
94+
# 1 → partition number 1
95+
# (accept defaults for start/end to use whole disk)
96+
# w → write and exit
97+
98+
# Or non-interactive with parted:
99+
sudo parted /dev/nvme1n1 --script mklabel gpt mkpart primary xfs 0% 100%
100+
```
101+
102+
**For a single-purpose EBS volume, skip partitioning.** Create the filesystem directly on `/dev/nvme1n1` (not on a partition). It's simpler:
103+
104+
```bash
105+
# Format the whole disk directly (no partition):
106+
sudo mkfs.xfs /dev/nvme1n1
107+
108+
# Mount it:
109+
sudo mkdir /data
110+
sudo mount /dev/nvme1n1 /data
111+
```
112+
113+
---
114+
115+
## Formatting and Mounting a New EBS Volume
116+
117+
This is the complete workflow for adding an EBS volume to EC2:
118+
119+
```bash
120+
# Step 1: Attach the EBS volume in AWS Console
121+
# (or via CLI: aws ec2 attach-volume --volume-id vol-xxx --instance-id i-xxx --device /dev/sdf)
122+
123+
# Step 2: Find the device name (may differ from what AWS shows):
124+
lsblk
125+
# Look for the new device — usually nvme1n1 for the second volume
126+
127+
# Step 3: Check if it has a filesystem already:
128+
sudo file -s /dev/nvme1n1
129+
# If output is just "data" → no filesystem, proceed to format
130+
# If output shows "XFS filesystem" → already formatted, just mount
131+
132+
# Step 4: Format (ONLY if new/empty — this DESTROYS existing data):
133+
sudo mkfs.xfs /dev/nvme1n1 # use xfs for Amazon Linux (default)
134+
sudo mkfs.ext4 /dev/nvme1n1 # use ext4 for Ubuntu
135+
136+
# Step 5: Create mount point:
137+
sudo mkdir -p /data
138+
139+
# Step 6: Get the UUID (stable identifier, better than /dev/nvme1n1):
140+
sudo blkid /dev/nvme1n1
141+
# /dev/nvme1n1: UUID="a1b2c3d4-e5f6-..." TYPE="xfs"
142+
143+
# Step 7: Mount:
144+
sudo mount /dev/nvme1n1 /data
145+
# Or by UUID:
146+
sudo mount UUID="a1b2c3d4-e5f6-..." /data
147+
148+
# Step 8: Make it survive reboots — add to /etc/fstab:
149+
sudo nano /etc/fstab
150+
# Add:
151+
UUID=a1b2c3d4-e5f6-... /data xfs defaults,nofail 0 2
152+
153+
# Step 9: Verify:
154+
df -h /data
155+
# /dev/nvme1n1 100G 1.5G 99G 2% /data
156+
157+
# Step 10: Set ownership (if needed):
158+
sudo chown -R ubuntu:ubuntu /data
159+
```
160+
161+
---
162+
163+
## Checking Disk Space
164+
165+
```bash
166+
# Disk space by filesystem:
167+
df -h
168+
# Filesystem Size Used Avail Use% Mounted on
169+
# /dev/nvme0n1p1 20G 12G 7.7G 61% /
170+
# /dev/nvme1n1 100G 1.2G 99G 2% /data
171+
# tmpfs 7.7G 0 7.7G 0% /dev/shm
172+
173+
# Disk space usage by directory:
174+
du -sh /var/log/ # total size of /var/log
175+
du -sh /var/log/* # size of each item in /var/log
176+
du -sh /* 2>/dev/null # size of each top-level dir
177+
178+
# Find the largest directories (top 10):
179+
du -h / 2>/dev/null | sort -rh | head -10
180+
181+
# Find large files:
182+
find / -type f -size +100M 2>/dev/null -exec ls -lh {} \;
183+
# Or:
184+
find / -type f -size +100M -printf '%s %p\n' 2>/dev/null | sort -rn | head -20
185+
```
186+
187+
---
188+
189+
## LVM — Logical Volume Manager
190+
191+
LVM adds a layer of abstraction between physical disks and filesystems, enabling resizing, snapshots, and combining multiple disks.
192+
193+
```
194+
Physical disks (PV): /dev/nvme1n1 /dev/nvme2n1
195+
196+
Volume Group (VG): my-vg (pool of all physical storage)
197+
198+
Logical Volumes (LV): /dev/my-vg/data (flexible partitions)
199+
/dev/my-vg/logs
200+
201+
Filesystems: ext4 on /data, xfs on /logs
202+
```
203+
204+
```bash
205+
# Is LVM in use?
206+
sudo pvdisplay # physical volumes
207+
sudo vgdisplay # volume groups
208+
sudo lvdisplay # logical volumes
209+
210+
# Create an LVM setup:
211+
sudo pvcreate /dev/nvme1n1 # mark as PV
212+
sudo vgcreate my-vg /dev/nvme1n1 # create VG
213+
sudo lvcreate -L 80G -n data my-vg # create 80GB LV
214+
sudo mkfs.xfs /dev/my-vg/data # format
215+
sudo mount /dev/my-vg/data /data # mount
216+
217+
# Extend an LV when you add more disks:
218+
sudo pvcreate /dev/nvme2n1 # add new disk as PV
219+
sudo vgextend my-vg /dev/nvme2n1 # add to VG
220+
sudo lvextend -L +50G /dev/my-vg/data # extend LV by 50GB
221+
sudo xfs_growfs /data # expand filesystem to fill LV
222+
# (for ext4: sudo resize2fs /dev/my-vg/data)
223+
```
224+
225+
**When LVM is worth it:**
226+
- You have multiple physical disks to combine
227+
- You need online resize (expanding without unmounting)
228+
- You want filesystem snapshots for backups
229+
230+
**When it's not worth it:**
231+
- Single EBS volume on EC2 — you can just resize the EBS volume and grow the filesystem directly (simpler)
232+
233+
---
234+
235+
## Resizing an EBS Volume (Without LVM)
236+
237+
AWS lets you resize an EBS volume while the instance is running.
238+
239+
```bash
240+
# Step 1: Resize the EBS volume in AWS Console (or CLI)
241+
# aws ec2 modify-volume --volume-id vol-xxx --size 200
242+
243+
# Step 2: After AWS reports resize complete, check in the OS:
244+
lsblk
245+
# nvme0n1: shows new size (200GB)
246+
# nvme0n1p1: still shows old size (20GB) — partition hasn't grown yet
247+
248+
# Step 3: Grow the partition (if using partition + filesystem):
249+
sudo growpart /dev/nvme0n1 1 # grow partition 1 to fill the disk
250+
251+
# Step 4: Grow the filesystem to fill the partition:
252+
sudo xfs_growfs / # for XFS (can be done while mounted!)
253+
# or for ext4:
254+
sudo resize2fs /dev/nvme0n1p1 # for ext4
255+
256+
# If the filesystem is directly on the disk (no partition):
257+
sudo xfs_growfs /data # just grow the filesystem
258+
```
259+
260+
This is live, zero-downtime — no unmounting required (for XFS and ext4 online resize).
261+
262+
---
263+
264+
## RAID (Brief Overview)
265+
266+
**RAID** (Redundant Array of Independent Disks) combines multiple disks for redundancy or performance.
267+
268+
```
269+
RAID 0: Striping — data spread across disks for speed. No redundancy.
270+
2× 500GB → 1TB usable, 2× read/write speed
271+
One disk fails → all data lost
272+
273+
RAID 1: Mirroring — identical copies on all disks.
274+
2× 500GB → 500GB usable, writes to both
275+
One disk fails → still works
276+
277+
RAID 5: Striping + parity — N disks, N-1 usable, 1 can fail.
278+
4× 500GB → 1.5TB usable, survives 1 disk failure
279+
280+
RAID 10: Mirroring + Striping. Performance + redundancy.
281+
4× 500GB → 1TB usable, survives 1+ disk failure
282+
```
283+
284+
**On AWS:** EBS already handles redundancy internally — you don't need RAID for data safety. RAID 0 is sometimes used on EC2 with multiple EBS volumes for maximum IOPS.
285+
286+
---
287+
288+
## Performance Monitoring for Disk
289+
290+
```bash
291+
# Live I/O stats (1 second interval):
292+
iostat -xz 1
293+
294+
# Output:
295+
# Device r/s w/s rMB/s wMB/s await r_await w_await util
296+
# nvme0n1 5.00 20.00 0.04 0.31 0.60 0.50 0.63 2.0%
297+
298+
# Key columns:
299+
# r/s, w/s = reads/writes per second
300+
# rMB/s, wMB/s = throughput in MB/s
301+
# await = average I/O time (ms) — should be < 10ms for SSD
302+
# r_await/w_await = separate read/write latency
303+
# util% = how busy the device is (100% = saturated → bottleneck)
304+
305+
# Check EBS volume type limits:
306+
# gp3: 125 MB/s base, 3000 IOPS base (can configure higher)
307+
# io2: up to 64,000 IOPS (for high-performance databases)
308+
309+
# Watch disk I/O in real time:
310+
iotop -o # only show processes doing I/O
311+
# (sudo apt install iotop or sudo dnf install iotop)
312+
```
313+
314+
---
315+
316+
## /proc/mounts and /proc/diskstats
317+
318+
```bash
319+
# All current mounts (kernel view, more accurate than /etc/fstab):
320+
cat /proc/mounts
321+
322+
# Disk I/O statistics (what iostat reads from):
323+
cat /proc/diskstats
324+
# 259 0 nvme0n1 12345 678 1234567 45678 ...
325+
# Fields: major minor name reads_completed reads_merged sectors_read time_reading ...
326+
```
327+
328+
---
329+
330+
## tmpfs — RAM as a Filesystem
331+
332+
`tmpfs` is a filesystem stored in RAM. Reading/writing it is as fast as RAM (not disk).
333+
334+
```bash
335+
# /tmp and /run are usually tmpfs:
336+
mount | grep tmpfs
337+
# tmpfs on /tmp type tmpfs (rw,nosuid,nodev,size=7901740k)
338+
# tmpfs on /run type tmpfs (rw,nosuid,nodev,size=1580348k,mode=755)
339+
340+
# Create your own tmpfs (useful for temp data in high-performance scenarios):
341+
sudo mount -t tmpfs -o size=2G tmpfs /mnt/fast-scratch
342+
df -h /mnt/fast-scratch
343+
# tmpfs 2.0G 0 2.0G 0% /mnt/fast-scratch
344+
345+
# WARNING: All data in tmpfs is lost on reboot or unmount.
346+
# Use for: build artifacts, temporary processing files, test databases
347+
```
348+
349+
---
350+
351+
## Disk I/O Scheduler
352+
353+
The I/O scheduler decides the order in which I/O requests are sent to the disk.
354+
355+
```bash
356+
# See current scheduler:
357+
cat /sys/block/nvme0n1/queue/scheduler
358+
# [none] mq-deadline kyber bfq
359+
360+
# For NVMe SSDs on EC2: "none" is usually optimal
361+
# (NVMe SSDs have their own internal queue management)
362+
363+
# For HDDs: "mq-deadline" or "bfq" can improve performance
364+
echo "mq-deadline" | sudo tee /sys/block/sda/queue/scheduler
365+
```
366+
367+
→ Continue to: `08-package-management.md`

0 commit comments

Comments
 (0)