Skip to main content

6.3. Storage: Giám sát hiệu năng storage và ACL

Mục lục​


1. Vì sao cần giám sát hiệu năng storage?​

Giống như CPU và RAM, thiết bị lưu trữ cũng có giới hạn của nó. Một process dùng CPU quá mức, giữ nó ở 100%, thì hệ thống chậm đi đáng kể. Chuyện tương tự xảy ra khi một thiết bị lưu trữ bị dùng quá mức.

Với CPU và RAM đã có top và htop để xem process nào đang dùng bao nhiêu, phần đó nằm ở Part 3.2: Process và giám sát tài nguyên. Nhưng với thiết bị lưu trữ thì xem bằng gì, làm sao thấy được cái gì đang đọc và ghi vào chúng?

Có nhiều công cụ giám sát được thao tác đọc ghi. Tài liệu này đi qua vài công cụ đơn giản hơn trong số đó. Package sysstat chứa một số công cụ như vậy, cài bằng lệnh thường gặp:

sudo apt install sysstat

Package này chứa vài utility thống kê hệ thống khác, nhưng hai cái quan tâm ở đây là iostat và pidstat. Tên iostat đến từ I O statistics, và I O viết tắt của input và output: dữ liệu được input vào thiết bị lưu trữ khi ghi, và thiết bị lưu trữ output dữ liệu ra khi đọc. pidstat viết tắt của Process ID Statistics. Mỗi process trên Linux có một identifier duy nhất, nên công cụ này cho thấy thống kê của từng process trên hệ thống, kèm số ID của chúng.

Một thiết bị lưu trữ bị dùng quá mức hoặc bị ép tới giới hạn theo hai cách khác nhau. Cách thứ nhất là có thứ gì đó đọc hoặc ghi vào nó quá thường xuyên. Cách thứ hai là có thứ gì đó đọc và ghi vào nó ở tốc độ rất cao, tức khối lượng dữ liệu được truyền rất lớn. Nếu có thứ dùng thiết bị quá thường xuyên thì số tps sẽ cao. Còn với khối lượng dữ liệu lớn thì các field kilobyte đọc và ghi sẽ mang số lớn.

Kể cả khi một thứ gì đó ghi rất ít dữ liệu vào thiết bị, chẳng hạn một kilobyte mỗi lần, nhưng nó làm vậy hàng trăm lần mỗi giây, thì vẫn tạo áp lực lên thiết bị và có thể đẩy thiết bị tới giới hạn. Nguyên nhân là mỗi thiết bị lưu trữ chỉ xử lý được một số lượng request tối đa nhất định mỗi giây. Một process thực hiện số lượng transfer mỗi giây cao thì các process khác chẳng còn lại bao nhiêu, nên một process làm nhiều process khác bị bỏ đói chỉ bằng cách dùng thiết bị lưu trữ quá mức.

Chuyện tương tự xảy ra với các transfer lớn. Nếu thiết bị chỉ ghi được hai GB dữ liệu mỗi giây và một process đã ghi ở mức 1,98 GB, thì phần còn lại cho các process khác rất ít. Chúng phải chờ rất lâu mới ghi xong dữ liệu của mình, và kết quả là một hệ thống chậm, không phản hồi.

Two ways to overload a diskMany small requestshigh tps1 kB written hundreds of timesEach device accepts only somany requests per secondFew huge transfershigh kB_wrtn/s1.98 GB/s out of a 2 GB/s limitAlmost no bandwidth is leftfor any other processOne greedy process starves every other process on the same device.

2. iostat và cách đọc các field​

Cách đơn giản nhất để xem tổng quan thiết bị lưu trữ đang được dùng ra sao là gọi iostat không kèm đối số:

iostat

# Output (minh họa):
Linux 5.15.0-91-generic (lfcs) 10/24/26 _x86_64_ (2 CPU)

avg-cpu: %user %nice %system %iowait %steal %idle
1.24 0.01 0.62 0.15 0.00 97.98

Device tps kB_read/s kB_wrtn/s kB_dscd/s kB_read kB_wrtn kB_dscd
sda 2.41 48.12 19.33 0.00 412556 165780 0
dm-0 1.87 44.90 18.02 0.00 385012 154492 0

Trước hết phải hiểu output này cho biết điều gì. Nó hiển thị mức sử dụng trong quá khứ của các thiết bị lưu trữ, tức cho biết các thiết bị đã được dùng ra sao kể từ lúc hệ thống boot lên, không hẳn là chúng đang được dùng ra sao ngay lúc này. Các field tính theo mỗi giây hơi khó hiểu ở điểm này, nên lấy một ví dụ cho gọn: các field đó hiện mức sử dụng trung bình chia cho tổng thời gian kể từ khi hệ thống khởi động.

Giả sử hệ thống boot lên cách đây ba giây. Trong giây thứ nhất, có thứ gì đó đọc từ đĩa ở mức 100 kilobyte mỗi giây. Trong giây kế tiếp, có thứ đọc từ đĩa ở mức 200 kilobyte mỗi giây. Trong giây thứ ba, không còn gì đọc từ đĩa nữa, nên mức sử dụng là 0 kilobyte mỗi giây. Cộng 100 với 200 rồi với 0, chia cho tổng số giây kể từ lúc boot là ba giây, ra mức sử dụng trung bình 300 chia 3, tức 100 kilobyte mỗi giây. Nên iostat có thể hiện số 100 ở field kilobyte đọc.

Nếu một giây nữa trôi qua mà không có gì đọc từ đĩa, iostat sẽ hiện số khác ở lần chạy tiếp theo. Lúc đó là 100 cộng 200 cộng 0 cộng 0, chia cho bốn giây tổng thời gian hệ thống đã lên, nên có thể thấy số 75 ở field kilobyte đọc.

Các field được tính theo cách đó là tps, kB_read/s, kB_wrtn/s và kB_dscd/s. Khi đi tìm cái gì đang dùng thiết bị lưu trữ, ba field đầu là những field cần quan tâm.

  • tps viết tắt của transfers per second. Có thể hình dung nó là số lần hệ thống bảo thiết bị này đọc hoặc ghi một thứ gì đó.
  • kB_read/s là số kilobyte đọc được mỗi giây.
  • kB_wrtn/s là số kilobyte được ghi mỗi giây.
  • kB_read và kB_wrtn thì rõ ràng hơn nhiều: chúng hiện tổng số kilobyte đã đọc hoặc đã ghi kể từ lúc hệ thống boot. Chúng không phụ thuộc thời gian nên không có trung bình nào phải tính.

Một điểm cần biết về độ chính xác: những gì iostat hiện ra không luôn phản ánh đúng lượng dữ liệu mỗi giây mà một process đọc hoặc ghi. Chẳng hạn một process yêu cầu ghi một kilobyte mỗi giây, nhưng iostat có thể không hiện ra rằng thiết bị đang được dùng ở mức hàng nghìn kilobyte mỗi giây. Lý do là iostat suy ra các con số này từ những gì thiết bị báo cáo, không phải từ process, và thiết bị có thể làm việc với các block dữ liệu lớn hơn. Dù một process chỉ gửi một kilobyte, thiết bị vẫn có thể báo rằng nó đã cập nhật một block lớn hơn nhiều. Các con số ước lượng vì vậy bị thổi lên, nhất là với các transfer nhỏ, nhưng chúng chính xác hơn với các transfer lớn.

Chế độ refresh theo chu kỳ​

Cách dùng thứ hai của iostat là truyền vào một con số:

iostat 1

Cách này làm iostat in ra mức sử dụng thiết bị lưu trữ mỗi 1 giây, tức nó refresh mỗi giây. Muốn refresh mỗi năm giây thì ghi 5 ở cuối, hay bất cứ con số nào phù hợp nhu cầu. Ở chế độ này, iostat không còn hiện mức sử dụng trung bình kể từ lúc hệ thống boot: kB_wrtn/s ở đây không cho biết tốc độ ghi trung bình kể từ lúc boot, mà cho biết tốc độ ghi trung bình trong một giây vừa qua.

Vài option hữu dụng của iostat​

  • -d làm nó chỉ hiện báo cáo mức sử dụng thiết bị. Bình thường iostat cũng hiện một phần thông tin về mức dùng CPU ở đầu output, và -d bỏ các chi tiết đó đi.
  • -h làm nó hiển thị thống kê I O ở dạng người đọc được. Bình thường iostat hiện số liệu theo kilobyte, và nhìn một giá trị kilobyte đã ghi là 11311196 thì rất khó nhẩm ra bao nhiêu megabyte hay gigabyte. Option này tự động đổi các giá trị sang kilobyte, megabyte hoặc gigabyte, tùy cái nào hợp lý với output. Thay vì một dãy số dài, nó hiện ra một thứ như 12,7 gig, dễ đọc hơn nhiều.
  • -p ALL và -p sda cho xem từng partition. iostat mặc định hiện hoạt động của toàn bộ thiết bị lưu trữ chứ không hiện của từng partition trên đó. Chẳng hạn nó cho thấy /dev/sda đã được dùng ra sao, nhưng không cho thấy /dev/sda1 hay /dev/sda2 được dùng ra sao. Dùng iostat -p ALL để xem mọi partition và thiết bị, hoặc iostat -p sda để xem các partition trên thiết bị sda.
iostat -d
iostat -h
iostat -p ALL
iostat -p sda
man iostat

3. pidstat và thủ phạm ở mức process​

iostat chỉ ra thiết bị nào đang chịu tải, nhưng nó không cho biết process nào gây ra tải đó. Đó là việc của pidstat:

pidstat -d

# Output (minh họa):
Linux 5.15.0-91-generic (lfcs) 10/24/26 _x86_64_ (2 CPU)

14:21:07 UID PID kB_rd/s kB_wr/s kB_ccwr/s iodelay Command
14:21:07 0 1411 0.00 988.42 0.00 12 dd
14:21:07 101 702 0.00 0.21 0.00 0 rsyslogd

Để nhớ option -d, cứ nghĩ tới devices. Quên thêm option này thì pidstat không cho thấy các process đang dùng thiết bị lưu trữ ra sao.

Đọc output cũng dễ: cột kB_rd/s là số kilobyte đọc mỗi giây, cột kB_wr/s là số kilobyte ghi mỗi giây. Chú ý cột ghi: process có giá trị lớn nhất ở cột đó là process đang ghi nhiều kilobyte mỗi giây nhất. Nên ghi lại và nhớ process ID của nó bằng cách nhìn cột PID. Ở ví dụ trên, PID cần nhớ là 1411.

pidstat cũng hỗ trợ in thống kê mỗi X giây, giống iostat. Dùng không kèm option dòng lệnh thì nó in ra mức transfer đọc ghi trung bình mỗi giây, tức các giá trị trung bình trong quá khứ. Muốn kết quả theo thời gian thực thì dùng một lệnh như sau để nó liên tục refresh dữ liệu mỗi giây:

pidstat -d 1

Thoát khỏi pidstat bằng Control-C, giống như với iostat.

Phiên bản option human-readable tương đương của pidstat là --human, nên lệnh để xem thống kê ở dạng dễ đọc là:

pidstat -d --human
man pidstat

Đừng dùng -h với pidstat, vì trong công cụ này -h được gán cho một chức năng khác.


4. Lần theo dấu vết một process ghi đĩa​

Lý thuyết đủ rồi, giờ dựng một tình huống thật. Trước tiên mở một process ghi liên tục vào thiết bị lưu trữ:

dd if=/dev/zero of=deleteme bs=1 count=1000000 oflag=dsync &

Từng tham số có lý do riêng. if là input file, ở đây chọn /dev/zero, một file sinh ra vô hạn số 0. of là output file, dữ liệu được ghi vào một file tên deleteme. bs=1 bảo dd ghi dữ liệu một byte mỗi lần. count=1000000 làm dd ghi một byte đó một triệu lần. Cặp bs và count này khiến dd ghi trong thời gian dài, đủ để thử nghiệm tình huống. oflag=dsync làm dd tránh dùng cache: với write caching, thao tác ghi có thể kết thúc quá sớm, còn với đối số này thao tác ghi kéo dài. Dấu & ở cuối làm lệnh chạy ở background, nên dòng lệnh vẫn dùng được tiếp mà không phải chờ dd xong.

Tracking down a storage hog1. iostat 1Which device is busy?Clue: dm-0 and sda2. pidstat -dWhich process writes most?Clue: dd with PID 14113. dmsetup infoWhat hides behind dm-0?An LV sitting on sda34. ps and killInspect then stop the processkill 1411, then kill -9 1411One tool names the device, another names the process, a third resolves the mapping.

Giờ giả vờ không biết cái gì đang ghi vào thiết bị lưu trữ và cần tìm ra. Bước đầu dùng iostat, nhưng theo cách mới ở mục trước:

iostat 1

# Output (minh họa):
Device tps kB_read/s kB_wrtn/s kB_dscd/s kB_read kB_wrtn kB_dscd
sda 982.00 0.00 982.00 0.00 0 982 0
dm-0 982.00 0.00 982.00 0.00 0 982 0

Để iostat chạy liên tục sẽ thấy output lặp lại như trên, và nó cho manh mối đầu tiên: dm-0 và sda đang bị ghi vào. Tới lúc này chỉ biết có thứ gì đó đang ghi vào dm-0 và /dev/sda, nhưng chưa biết process nào làm việc đó.

Nhấn Control-C để thoát iostat, rồi tới lượt pidstat giúp điều tra:

pidstat -d

Output của pidstat cho manh mối thứ hai: lệnh dd là process có giá trị lớn nhất ở cột kilobyte ghi mỗi giây. Ghi lại PID của nó, ở ví dụ này là 1411.

Hai manh mối đã có: dm-0 cùng /dev/sda đang bị ghi vào, và PID ghi nhiều nhất là 1411. Còn bước cuối: dm-0 là thiết bị gì? dm viết tắt của device mapper, và nó được tạo ra bởi Logical Volume Manager, phần đã học ở Part 6.2: LVM. Lệnh dmsetup cho biết nó map tới cái gì:

sudo dmsetup info /dev/dm-0

# Output (minh họa):
Name: ubuntu--vg-ubuntu--lv
State: ACTIVE
Read Ahead: 256
Tables present: LIVE
Open count: 1
Event number: 0
Major, minor: 252, 0
Number of targets: 1

Theo sau đó là lsblk:

lsblk

# Output (minh họa):
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
sda 8:0 0 50G 0 disk
├─sda1 8:1 0 1M 0 part
├─sda2 8:2 0 1.8G 0 part /boot
└─sda3 8:3 0 48.2G 0 part
└─ubuntu--vg-ubuntu--lv 252:0 0 23.5G 0 lvm /

Lệnh thứ nhất cho thấy dm-0 map tới một thứ tên ubuntu-vg-ubuntu-lv. Đó là một LV, tức logical volume, được tạo ra lúc cài hệ điều hành. Và trong lsblk, logical volume này nằm dưới /dev/sda3, tức nó là một logical volume tạo trên ổ đĩa /dev/sda. Tới đây đã rõ vì sao cả dm-0 lẫn sda đều hiện ra như đang bị dùng tích cực trong iostat: sda là thiết bị thật đang được dùng, còn dm-0 chỉ là một lớp trừu tượng dùng sda bên dưới.

Câu chuyện điều tra kết thúc với hai kết luận: dd là process đang ghi vào /dev/sda, thiết bị lưu trữ đầu tiên trên hệ thống, và PID của dd là 1411 trong ví dụ này.

Trong tình huống thật có thể thấy những thứ khác. Chẳng hạn process ghi dồn dập lại là một chương trình database như MariaDB. Khi đó bước tiếp theo là xem log của nó để biết chuyện gì đang diễn ra, rồi restart nó bằng một lệnh như:

sudo systemctl restart mariadb

Với tình huống đang xét, xem chính xác lệnh nào đã khởi động process này bằng:

ps 1411

Và nếu muốn dừng process một cách êm thấm:

kill 1411

Nếu lệnh đó không có tác dụng thì ép tắt:

kill -9 1411

Lệnh này gửi signal SIGKILL, thứ chấm dứt process một cách đột ngột, nghĩa là process không có cơ hội kết thúc êm thấm, không lưu được dữ liệu của nó. Nên chỉ dùng cách này như phương án cuối cùng, khi lệnh đầu đã bất lực.

Cách làm việc ở mục này là ví dụ tốt cho lối điều tra thường dùng trên hệ thống Linux: nhiều khi phải dùng nhiều hơn một công cụ và thu manh mối từ tất cả chúng để đi tới kết luận.


5. Giới hạn của permission bit truyền thống​

Chạy ls -l trong một directory nào đó và thấy danh sách file như sau:

ls -l

# Output (minh họa):
-rw-rw-r-- 1 alex staff 0 Oct 24 14:02 file1
-rw-rw-r-- 1 alex staff 0 Oct 24 14:02 file2
-rw-rw-r--+ 1 alex staff 31 Oct 24 14:05 file3

Các file này thuộc user alex và group staff. Ba permission bit đầu, rw-, cho biết alex đọc và ghi được vào các file này. Ba bit kế tiếp, rw-, cho biết mọi user thuộc group staff cũng đọc và ghi được. Ba bit cuối, r--, cho biết tất cả các user còn lại chỉ đọc được các file này, không ghi được. Chi tiết về các permission bit này cùng chmod, SUID, SGID và sticky bit nằm ở Part 2.2: Phân quyền file.

Chỉ bộ permission đầu tiên là dành riêng cho một user cụ thể. Hai bộ còn lại rất rộng: một bộ áp cho mọi người trong một group, bộ kia áp cho tất cả các user khác trên hệ thống. Phần lớn thời gian điều đó không gây trở ngại gì.

Nhưng xét tình huống này. Đang đăng nhập bằng một user tên jeremy. Anh ta rõ ràng không phải alex, và cũng không thuộc group staff, nên bộ permission thứ ba được áp cho anh ta: r--. Vậy nếu muốn jeremy sửa được file3 thì sao?

Ý đầu tiên nảy ra thường là thêm jeremy vào group staff, và khi đó anh ta sửa được file đó. Nhưng thêm vào group thì anh ta cũng có quyền sửa luôn file1 và file2, và đó là điều không muốn. Mong muốn là tạo một ngoại lệ cho jeremy chỉ với file3. Cho jeremy làm owner của file đó cũng gây đổ vỡ không kém: khi đó user alex lại mất quyền ghi.

Lời giải cho vấn đề này là ACL, tức Access Control List.

ACL extends the three permission setsTraditional permission bitsuser alexrw-group staffrw-all other usersr--jeremy is not alex and not in staff, so he only gets r--setfacl adds exceptionsACL entries added with setfacluser jeremyrwgroup sudorwuser johnno permission bitsmask caps every ACL entry: with mask r, rw becomes effective rA plus sign after the permission bits in ls -l marks a file that carries an ACL.

Permission chuẩn khá chung chung: chúng chỉ áp cho một user cụ thể, một group, và tất cả các user còn lại trên hệ thống, nên khá hạn chế. ACL cho phép làm thứ mà permission bit không làm được: định nghĩa permission riêng cho hai hay nhiều user. Chẳng hạn một ACL cho jeremy đọc và ghi, cho jane chỉ đọc, và từ chối mọi quyền của john. Định nghĩa permission cho nhiều group cũng khả thi.


6. setfacl và getfacl​

Giống như chmod dùng để đổi permission file chuẩn, setfacl dùng để đổi các permission nâng cao được định nghĩa trong một ACL. Tên lệnh đến từ Set File Access Control List.

Trên các bản Ubuntu mới, ACL không được cài sẵn, nên có thể cần cài trước:

sudo apt install acl

Quay lại vấn đề ở mục trước. Tất cả các user khác bị từ chối quyền ghi vào file, nhưng cần một ngoại lệ cho riêng user tên jeremy. Thêm một ACL entry cho phép jeremy đọc và ghi file đó:

sudo setfacl --modify user:jeremy:rw file3

Với user:, câu lệnh nói rằng muốn sửa ACL cho một user. Kế tiếp chỉ rõ user đó là jeremy. Cuối cùng, với :rw, các permission đọc và ghi được thêm cho user này. Nếu muốn thêm toàn bộ permission thì ghi :rwx ở đoạn đó. Cho đọc và thực thi thì là :rx. Cho chỉ đọc thì là :r. sudo là cần thiết vì jeremy không phải owner của file, alex mới là owner. Nhưng nếu user thao tác chính là owner của file thì không cần sudo.

Từ lúc jeremy có quyền ghi, lệnh ghi đè nội dung file đó thành công. Nhưng với file2 thì không, kết quả là permission denied, dù nhìn permission của hai file thì chúng gần như giống nhau. Nhìn kỹ hơn mới thấy một khác biệt nhỏ.

ACL là tùy chọn nên phần lớn file không có ACL, và cách nhanh nhất để nhận ra file nào có là dấu cộng nhỏ. Trong output ls -l ở mục trước có một dấu cộng ngay sau các permission bit của file3, và đó là dấu hiệu cho biết tồn tại một ACL.

Để xem ACL của file này, dùng getfacl:

getfacl file3

# Output (minh họa):
# file: file3
# owner: alex
# group: staff
user::rw-
user:jeremy:rw-
group::rw-
mask::rw-
other::r--

Các dòng user, group và other không cần quan tâm, chúng chỉ là permission thông thường của file. Dòng đáng xem là ACL entry vừa thêm cho jeremy.

Để xóa ACL của một user hoặc một group cụ thể, dùng option --remove:

sudo setfacl --remove user:jeremy file3
sudo setfacl --remove group:sudo file3

Và để xóa toàn bộ ACL entry:

sudo setfacl --remove-all file3

Để cho phép mọi user trong group sudo đọc và ghi vào file này, lệnh dùng group thay cho user:

sudo setfacl --modify group:sudo:rw file3

Để từ chối toàn bộ permission của một user cụ thể, ghi username rồi một danh sách permission bit rỗng, hoặc ba dấu gạch ngang:

sudo setfacl --modify user:john:--- file3

7. Mask và ACL trên directory​

Trong output của getfacl còn một dòng nữa: mask. Mask định nghĩa permission tối đa mà file hoặc directory này có thể có. Khi thêm ACL thì không cần lo về nó, vì mask tự động được điều chỉnh cho vừa với nhu cầu: cấp quyền rwx cho jeremy thì mask tự nở ra thành rwx.

Nhưng mask hữu dụng khi cần giới hạn các permission đang có. Giả sử một ACL liệt kê bốn user, một số trong đó đọc, ghi và thực thi được. Rồi quyết định rằng như vậy là quá nhiều: permission tối đa muốn cho phép chỉ là đọc file, không ghi và không thực thi. Sửa tay ACL cho từng user thì mất thời gian, nên thay vào đó định nghĩa mask:

sudo setfacl --modify mask::r file3
getfacl file3

# Output (minh họa):
# file: file3
# owner: alex
# group: staff
user::rw-
user:jeremy:rw- #effective:r--
group::rw- #effective:r--
mask::r--
other::r--

Trong output xuất hiện một trường mới thú vị: effective: r. Nó cho biết dù ACL ghi rằng user jeremy đọc và ghi được, permission có hiệu lực chỉ là read-only, vì mask giới hạn permission ở đây.

Áp ACL lên cả một directory​

Đôi khi cần áp một ACL cho nguyên một directory cùng mọi subdirectory và file bên trong nó. Thuật ngữ kỹ thuật cho việc này là áp dụng thay đổi recursively, và setfacl có option làm việc đó: --recursive.

mkdir mydir
sudo setfacl --recursive --modify user:jeremy:rw mydir

Option --recursive cũng thêm được vào các lệnh xóa ACL entry, nên các lệnh sau xóa jeremy khỏi directory đó, hoặc xóa group sudo khỏi directory đó, theo kiểu đệ quy:

sudo setfacl --recursive --remove user:jeremy mydir
sudo setfacl --recursive --remove group:sudo mydir

8. File attribute với chattr và lsattr​

Bật một attribute cho một file sẽ làm file đó hành xử khác với bình thường. Hai ví dụ dễ hiểu nhất là attribute append-only và attribute immutable. Mỗi attribute có một chữ cái tương ứng.

Append-only​

Với append-only, chữ cái dùng là a. Chỉ user root bật hoặc tắt được attribute này. Tạo một file mới rồi bật append-only trên nó bằng lệnh chattr, với dấu cộng rồi chữ a:

sudo chattr +a newfile

Thay đổi này có tác dụng gì? Khi attribute này bật, chỉ việc append được phép, tức chỉ thêm dữ liệu mới lên trên dữ liệu cũ. Dữ liệu cứ được thêm vào file, nhưng dữ liệu cũ không ghi đè hay sửa được.

Chẳng hạn file đang chứa dòng chữ cho biết đây là nội dung cũ. Thử ghi đè nó bằng nội dung mới thì không được, kết quả là operation not permitted. Nhưng thử thêm nội dung mới vào mà không ghi đè nội dung cũ thì thành công, và file giờ chứa cả nội dung cũ lẫn nội dung mới.

Để bỏ attribute append khỏi một file, gõ dấu trừ rồi chữ a thay cho dấu cộng:

sudo chattr -a newfile

Immutable​

Attribute immutable được biểu diễn bằng chữ i. Để đặt nó lên một file, chỉ cần đổi a thành i:

sudo chattr +i newfile

Đúng như tên gọi, attribute này làm file trở thành immutable, nghĩa là nó không thể bị thay đổi theo bất cứ cách nào. Nó không đổi tên được, không xóa được, không sửa được, coi như bị đóng băng. Kể cả user root cũng không xóa hay sửa được file này.

Gặp một file mà ngay cả root cũng không xóa hay sửa được, nên kiểm tra attribute của nó. Lệnh làm việc đó là lsattr:

lsattr newfile

# Output (minh họa):
----i---------e------- newfile

Giống lệnh ls, lsattr dùng được cho cả một directory. Trong output trên, chữ i chính là attribute immutable. Để bỏ attribute này:

sudo chattr -i newfile

chattr khá dễ dùng: cứ dấu cộng để thêm và dấu trừ để bỏ một attribute, theo sau là chữ cái đại diện cho attribute đó. Các attribute khác xem được trong man page.

Một điểm phải cẩn thận khi vận hành: tuy có nhiều attribute tồn tại, một số trong chúng không có hiệu lực gì trong vài tình huống. Chẳng hạn có attribute c để bật nén cho một file, nhưng một số file system như ext4 không hỗ trợ nén trực tiếp, nên bật attribute này cho một file nằm trên file system ext4 sẽ không có tác dụng nào. Trước khi tin rằng một attribute đã có hiệu lực, nên kiểm tra lại bằng lsattr và thử đúng hành vi mà nó hứa hẹn.


Nguồn tham khảo​

Nguồn gốc: Khóa "Prep Course - Linux Foundation Certified System Administrator (LFCS) Certification" — phần "6. Storage" (giám sát hiệu năng storage với iostat và pidstat, quản lý và cấu hình ACL cùng file attribute), nền tảng KodeKloud. Giảng viên: Jeremy Morgan và Alexandru Andrei.