Thứ Bảy, 13 tháng 1, 2018

[Vụn vặt Linux] Processess - Tiến trình trong Linux

Process ( Tiến trình)
Trước hết, ta cần tìm hiểu khái niệm tiến trình là gì?

Tiến trình, theo ta hiểu, là một đoạn chương trình thực hiện một công việc cụ thể nào đó. Cũng như khi ta viết một chương trình đơn giản (hello world chẳng hạn), thì công việc của chúng ta đó là in ra dòng chữ Hello World. Nhưng khi đó, dĩ nhiên ta sẽ chỉ có một hàm main chạy chính và hệ thống của ta cũng sẽ chỉ quản lý hàm main đó.

Vậy sự khác nhau giữa tiến trình và một chương trình thông thường là gì?

Trước hết ta cần biết, hệ thống Linux quản lý rất nhiều tác vụ trong cùng một thời điểm,các tác vụ đó có thể là:
- truyền nhận file
- đọc ghi từ ổ cứng
- giao tiếp với ngoại vi (bàn phím, chuột v.v...)
Tương ứng với mỗi tác vụ là mỗi chương trình mà ta thường viết (giống hello world), hệ thống Linux sẽ cung cấp và tài nguyên để các chương trình này hoạt động một cách gần như song song và độc lập với nhau.

Khi một process chạy, Linux kernel sẽ cung cấp một không gian địa chỉ vùng nhớ như sau cho nó.

Chức năng của từng phần các bạn có thể tra google nhé.
Phần quan trọng nhất đó là text segment, data segment và bss segment. Text segment chưa các mã thực thi và là vùng nhớ chỉ đọc, ví dụ như các giá trị hằng số. Data segment chứa các biến toàn cục đã được khởi tạo, vùng nhớ này có thể được ghi. Vùng bss chứa các giá trị toàn cục chưa được khởi tạo, mặc định, C compiler sẽ gán cho các giá trị này giá trị là 0, do đó các giá trị này không cần lưu giá trị 0 của chúng nhằm tiết kiệm bộ nhớ, mỗi khi chương trình được chạy, các giá trị này sẽ đồng thời được gán giá trị 0 bằng cách map với một bảng 0 (zero page) bởi kernel sau đó load vào bộ nhớ. Đó là lí do tại sao ta không để chung bộ nhớ bss và data chung. BSS - Block Started by Symbol.

Process thường đi kèm với rất nhiều tài nguyên được quản lý bởi kernel.

Thread (Luồng)
Một process có thể bao gồm ít nhất 1 hoặc nhiều thread.
- 1 thread - single-threaded
- nhiều thread - multi-threaded
Các thread trong cùng một process chia sẻ cùng tài nguyên trừ stack segment (bao gồm biến local, thanh ghi lệnh - instruction pointer).
Linux xây dựng các thread theo chuẩn POSIX, do đó thường được gọi là Pthread.

Process hierarchy (Phân tầng của tiến trình)
Mỗi process đều có một định danh là ID của chúng, process ID là duy nhất và là số dương.
Khi hệ thống khởi động lên, ta có một process chạy đầu tiên đó là init process  có PID = 1. Process này sẽ là process cha của các process khác thông qua hàm fork() để tạo ra một process mới. Bất cứ một process nào được sinh ra sau đó cũng có thể sinh ra các process con kế tiếp, khi một process cha bị kill, các process con của nó sẽ nhận process init là process cha.





[Review Sách] Phía Nam biên giới, phía Tây mặt trời (south of the border west of the sun - Murakami) - Khi tôi thấy tôi trong trang sách














Tôi thấy tôi trong cuốn sách, chứ không phải trong gương hay trong một bề mặt nước tĩnh lặng nào cả.
Đó chính là những lời mà tôi muốn nói về cuốn sách này, và nó đúng, tôi nghĩ, cho tất cả chúng ta. Những mối tình vụng dại, những sai lầm lớn và nhỏ, những vết thương không-bao-giờ-khép-miệng, những nuối tiếc của thanh xuân mà ai cũng có, ai cũng trải qua.

Cuốn sách xoay quanh 3 người con gái và cũng là cuộc đời của Hajime.
Shimamoto: Người tình cả đời Hajime theo đuổi
Yukiko: Vợ Hajime
Izumi; Bạn gái thời trung học

Phía nam biên giới: Mexico hay tên bài hát theo suốt cả câu chuyện
Phía Tây mặt trời: người ta đi mãi hướng tới mặt trời và rồi chết gục bởi đói và khát
Star-crossed lovers: Những cặp tình nhân trong chòm sao xấu cũng như Hajime và Shimamoto

Đoạn khiến tối ám ảnh nhất đó là khi H và S quan hệ trước khi S ra đi mãi mãi, nó để lại trong tôi 1 sự trống vắng và tự thấy đồng cảm vì cái gì đó đã mãi mãi mất đi, và đã thực sự chết đi, đôi khi có gì đó còn lại là sự trống rỗng.


[Vụn vặt Linux] File và FileSystem trong Linux (P2)

Trong phần 1, ta đã tìm hiểu các khái niệm về file và links trong hệ thống Linux. Ta cũng đã được biết qua nguyên lý thiết kế:
Everything is a file
Trong phần này, những dạng file đặc biệt sẽ chỉ rõ việc triển khai nguyên lý này trên thực tế bên trong hệ thống Linux.

Special files
Các file đặc biệt bao gồm 4 loại:
- block device files
- character device files
- named pipes
- và Unix domain sockets

User-space giao tiếp với các thiết bị bên dưới thông qua device files, nghĩa là thiết bị có thể mở file, đọc và ghi file này, các file như lớp trung gian giữa user-space và kernel. Devices files lại được chia thành 2 loại là character device và block devices, chúng có cùng cách sử dụng nhưng sở dĩ có tên khác nhau là do cách ta tiếp cận dữ liệu của file.

Character device files
Với loại file này, việc đọc ghi dữ liệu sẽ được thực hiện trên từng byte của 1 queue. Một ví dụ điển hình đó là keyboard. Khi ta dùng bàn phím (physical) gõ chữ hello, trên user-space sẽ đọc từng chữ h-e-l-l-o từ file và hiển thị lên màn hình, khi không còn kí tự nào nữa, thiết bị sẽ trả về kí tự EOL. Do đó các thiết bị như bàn phím nói ở trên được gọi là character device.

Block device files
Với loại file này, việc đọc và ghi dữ liệu sẽ được thực hiện tùy ý. Device driver sẽ map dữ liệu vật lý vào 1 file mà user có thể tùy ý truy cập (thường đồng nghĩa với quá trình mount). Ví dụ điển hình là hard disks, flash hoặc CD Drives.

Named pipes
Pipe là 1 phương thức truyền thông liên tiến trình (IPC) hoạt động bằng cơ chế đầu ra của một chương trình là đầu vào của 1 chương trình khác.
http://www.linfo.org/pipes.html
Cụ thể hơn các bạn có thể xem ở đây:
http://man7.org/linux/man-pages/man2/pipe.2.html

Socket files
Socket cũng là một phương thức IPC, nhưng hơn pipes đó là socket cho phép chúng ta không những có thể giao tiếp giữa hai process trong cùng một máy tính, còn có thể giao tiếp giữa các thiết bị khác nhau trên mạng Internet (sử dụng host name và port). Một socket được đặc trưng bởi 1 socket file.
http://man7.org/linux/man-pages/man2/socket.2.html

Filesystem
Tất cả các thư mục chúng ta thấy trong hệ thống Linux như root/ home/ etc/ v.v... đều được gọi là filesystem. Vậy filesystem là gì?
Filesystem thực ra là các vùng nhớ trên đĩa cứng hoặc Floppy Disk, Flash v.v... và được mount vào hệ thống để ta có thể thao tác với chúng được. Trường hợp đặc biệt là root filesystem hay còn gọi là rfs, là filesystem đầu tiên được mount khi hệ thống bắt đầu khởi động, từ root fs, ta có thể thực hiện các thao tác như mount các ngoại vi khác như floppydisk sẽ ở /media/cdrom/.
Dù vậy, filesystem cũng có thể là các file ảo (virtual filesystem - vfs) chỉ tồn tại trên RAM (ví dụ như proc file) hoặc network filesystem - nfs.
File system lại được chia ra thành các loại như sau:
- media specific fs (ISO9660)
- network fs
- native fs (ext4)
- fs from other Unix systesm (XFS)
- fs from non-Unix systesm (FAT).

Thứ Bảy, 6 tháng 1, 2018

[Vụn vặt Linux] File và FileSystem trong Linux (P1)

Linux tuân theo nguyên lí:
Everything is a file
Trong hệ thống Linux, mỗi file sẽ được đặc trưng bởi một đặc tả tệp (file descriptor), đây là một số nguyên được quản lý và cung cấp bởi Linux kernel và được share với user-space. Khi ta đã có file descriptor, ta có thể thực hiện các thao tác trên file như đọc, ghi v.v...

Regular files
Hay còn gọi là tệp thông thường, các file này chính là các file mà ta thường thao tác nhất như các file có dạng text, file object v.v... Trong các file này chứa các dữ liệu được sắp xếp theo byte-stream, nghĩa là chúng ta có thể truy cập với đơn vị nhỏ nhất cho việc đọc và ghi trên 1 file.

Việc ta trỏ đến byte nào của 1 file sẽ phụ thuộc vào vị trí hiện tại của ta ở trên file đó.
Ví dụ, khi ta mở 1 file lên, ta sẽ ở vị trí đầu tiên của nó với offset là 0. Tiếp theo, mỗi khi ta thao tác, vị trí offset sẽ được tăng tuyến tính với byte mà ta đã thao tác cùng.
Ngoài ra ta cũng có thể thay đổi vị trí offset này bằng 1 số hàm. Vậy bạn cnó thể đặt câu hỏi là giá trị offset này giá trị nằm trong dải bao nhiêu. Tôi xin trả lời luôn đó là 0 - 2^64-1.
Ta cũng có thể nhận thấy giá trị offset hợp lệ của 1 file sẽ quyết định kích thước của file đó, tôi tạm gọi là length.

Vậy ta có thể cắt 1 file hoặc nối vào 1 file không?
Câu trả lời là CÓ!
Thư viện POSIX có hỗ trợ các hàm:
#include <unistd.h>
int ftruncate(int fildes, off_t length);
int truncate(const char *path, off_t length);
Việc giảm size của 1 file sẽ đồng nghĩa với việc ta cắt phần cuối của file.
Việc tăng size 1 file sẽ đồng nghĩa ta chèn các giá trị zero vào khoảng được thêm mới của file.
Một file có thể rỗng nghĩa là length của file đó là 0 đồng nghĩa với việc bất cứ việc truy nhập vào byte nào của file này sẽ vô nghĩa (sẽ ra vùng nhớ khác).

Một file có thể được đồng thời mở ở nhiều chương trình, do đó việc đọc ghi tới file đó sẽ được cho phép đối với tất cả các chương trình mở nó.
Một chương trình có thể mở file nhiều lần, mỗi lần mở file, 1 file descriptor sẽ được trả về tương ứng cho phép truy nhập vào file đó.
Vậy các chương trình chia sẻ 1 file descriptor thì sao? Câu trả lời là được. Bạn có thể tự hỏi rằng việc đọc và ghi tùy tiện vào 1 file bởi nhiều chương trình khác nhau có thể gây ra lỗi, việc này xử lý bằng cơ chế đồng bộ (sẽ được trình bày sau).

Mặc dù ta thường truy nhập file dựa trên filename, nhưng thực tế các file là các đối tượng gọi là i-node trong hệ thống Linux (information node), i-node là một số nguyên được gán với vùng dữ liệu vật lý trong bộ nhớ. Một i-node sẽ chứa các thông tin như:
+ Thời gian sửa đổi
+ Owner
+ Loại file
+ Kích thước
+ Ví trí dữ liệu.

Directories and Links
Tạm gọi la thư mục và liên kết
Thông thường, khi ta truy nhập đến một file, ta sẽ sử dụng bằng tên của file chứ không phải là inode-number mặc dù chính số này mới thể hiện một cách vật lý dữ liệu ta muốn truy nhập. Tất nhiên, để truy cập đến một file ta cần biết đường dẫn của nó, và đối tượng gần với file đó nhất chính là thư mục (directory). Một thư mực hoạt động giống như một ánh xạ các inode-number với tên của các file tương ứng. Một cặp tên và số inode sẽ cho ta một liên kết (link).

Một thư mục cũng là một file thông thường ta đã đề cập ở trên, chỉ khác là file này chỉ bao gồm thông tin ánh xạ (mapping) giữa inode và tên file chứ không chứa thông tin giống như file thông thường. Việc ánh xạ giữa inode và tên file được thực hiện bởi 1 bảng băm (hash table) dưới kernel, khi ta sử dụng một đường dẫn, kernel cần sử dụng bảng này để phân giải ra giá trị node cho phép ta truy cập file.

Vậy flow khi ta mở 1 file thông thường sẽ là như sau:
File name -> inode_number -> inode -> metadata (data).

Vậy thư mục cũng là một file thông thường, do đó nó phải có một inode tương ứng. Các link ở trong inode mà thư mục trỏ tới cũng có thể trỏ đến các thư mục khác, điều này tạo ra directory hierarchy (phân tầng thư mục) như hình dưới đây:

Ban đầu, ta chỉ có 1 thư mục root, được kí hiệu bởi /, nhưng có rất nhiều thư mục trong một hệ thống như ta biết. Vậy việc truy cập chúng sẽ có hai trường hợp.
1. Path name bắt đầu từ root (gọi là đường dẫn tuyệt đối).
2. Path name bắt đầu từ một thư mục khác root (đường dẫn tương đối).

Trong trường hợp 1, ta thấy kernel có thể rõ ràng truy vấn đến đường dẫn đó vì inode của root là đã biết trước.

Nhưng trong trường hợp 2, việc phân giải đường dẫn được bắt đầu từ current working directory - PWD (thư mục hiện tại) , việc truy vấn cũng tương tự đến file nhưng lúc này đường dẫn sẽ là việc ghép giữa PWD và đường dẫn tương đối.
Ví dụ:
1. root/usr/dexter/hobbies/luring.txt (đường dẫn tuyệt đối).
2. pwd = root/user/dexter
    hobbies/luring

Mặc dù thư mục cũng giống 1 file nhưng kernel không cho phép ta thực hiện các hành động giống như một file thông thường, mà ta chỉ có thể thêm link hoặc xóa link của 1 thư mục(tương ứng với việc thêm file hoặc xóa file) trong thư mục đó.

Hard Links
Là khi ta có nhiều link trỏ tới cùng 1 inode.
Hard-link cho phép nhiều pathname khác nhau trỏ tới cùng 1 inode. Ví dụ:
 /home/bluebeard/treasure.txt và /home/blackbeard/to_steal.txt.
Ví dụ trong 1 thư mục ta gõ:
ls -la
Mỗi file sẽ có 1 biến count, với mỗi link trỏ tới inode của file, biến count sẽ tăng lên 1, tương tự khi ta sử dụng unlinking, biến count sẽ giảm đi 1. Do đó, khi ta thực hiện thao tác xóa bỏ 1 file, dữ liệu thực tế (inode) sẽ chỉ thực sự biến mất trên filesystem khi mà biến count của inode đó là 0.

Symbolic Links
Khác với hard-link, symlink là một file (nghĩa là có inode) và dữ liệu của nó chính là đường dẫn đến inode mà nó thực sự trỏ tới. Một symlink có thể trỏ tới bất kỳ đâu, hoặc đến một file không tồn tại, khi này sẽ gọi là broken link.
Một ví dụ rõ ràng của Symlink đó là short-cut. Khi ta xóa bỏ dữ liệu gốc của short-cut, short-cut sẽ không thể thực thi do dữ liệu thực tế đã bị xóa bỏ hoàn toàn trên filesystem.


[Vụn vặt Linux] iptables và ip6tables - Cách tạo một firewall trên Linux

https://upload.wikimedia.org/wikipedia/commons/3/37/Netfilter-packet-flow.svg

Trong bài viết này, mình sẽ giới thiệu về iptables và ip6tables (thực ra hai thằng này giống nhau thôi, chỉ là một thằng cho ipv4 và thằng con lại cho ipv6).


Thứ Sáu, 5 tháng 1, 2018

[Vụn vặt Linux] Standards - Where we are?

Don't sell your soul to the devil
Như chúng ta đã biết, để thao tác với Linux kernel, ta phải thông qua các lớp API (hay thư viện có sẵn).
Đã có rất nhiều các chuẩn cho các API này được ra đời nhưng Linux kernel hầu như tuân theo hai chuẩn: POSIX (Portable Operating System Interface) và SUS (Single Unix Specification).

POSIX: ra đời giữa thập kỉ 1980 bởi Richard Stallman, các chuẩn về POSIX được ra đời liên tiếp sau đó và hiện giờ chúng ta đang sử dụng 1 phiên bản POSIX ổn định là POSIX 2008 hay POSIX.1.

SUS: ra đời cuối thập kỉ 1980 và đầu 1990 bởi The Open Group và được đón nhận rộng rãi nhờ giá thành miễn phí. Bản ổn định, SUS4

- Ngày này, Linux kernel cùng đồng thời sử dụng SUS và POSIX.

As stated earlier, Linux aims toward POSIX and SUS compliance. It provides the inter‐ faces documented in SUSv4 and POSIX 2008, including real-time (POSIX.1b) and threading (POSIX.1c) support. More importantly, Linux strives to behave in accordance with POSIX and SUS requirements. In general, failing to agree with the standards is considered a bug.

Thứ Năm, 4 tháng 1, 2018

[Review sách] Bắt trẻ đồng xanh (Catcher in the Rye của Salinger) - Một cái nhìn mới về con người quanh ta

























Mở đầu câu truyện là việc chàng thanh niên 16 tuổi nước Mỹ bỏ học và đứng từ ngọn đồi cao nhìn xuống trường Spencer và hồi tưởng lại những "thứ rác rưởie" những ngày qua cậu gặp phải.

Nỗi cô đơn có thể nói là thứ xuyên suốt cuốn sách khi mà chàng trai có một cách nhìn đời rất trần trụi, nhìn đâu cũng thấy sự bộ tịch và chướng mắt.
Tất nhiên là tôi cũng đã đọc review cuốn sách này trước khi cầm nó lên lần đầu tiên, nhưng quả thực tôi sẽ không bày tỏ quan điểm là tôi ủng hộ cách sống, cách nhìn nhận mọi việc của nhân vật chính hay không.

Và vì lẽ đó nên tôi mới nói chàng thanh niên có một cái nhìn mới, anh ta nhìn mọi thứ với ánh mắt tiêu cực của tuổi mới lớn khi đều bất bình với mọi sự xung quanh. Cậu chán trường học, chán lũ bạn bộ tịch, những con người bộ tịch và xã hội xung quanh nhưng lại có tình yêu to lớn với gia đình khi mà hai cô em gái được nhắc đến hầu như xuyên suốt cuốn truyện: Allie và Phoebe.

Bên cạnh đó, còn một người con gái mà cậu có tình cảm, thứ làm tôi luôn mong chờ khi chưa đọc xong cuốn sách là một cuộc trò truyện qua điện thoại giữa cậu và Jane, tôi muốn biết về Jane hơn khi mà cậu đã giới thiệu tự thuật về một cô gái hay ho đến thế. Nhưng chắc chắn không dưới 3 lần trong cuốn sách, cậu đã nhấc ống nghe lên nhưng lại không gọi cho Jane, mà lại gọi cho cô người tình nhạt nhẽo và chán nhách.
Một số người đọc trước đã thất vọng về cái kết của "Bắt trẻ đồng xanh", khi mà chàng trai có ý định bỏ đi và sống một cuộc sống du mục và cô độc (trong một cái chòi nhỏ), nhưng riêng tôi thì không.

Khi chàng trai gặp Phoebe và nói về ý định bỏ đi của mình, cậu đã được cảm động bởi người em và từ bỏ quyết định ra đi, đó là quyết định đúng đắn ở cái tuổi 16 của cậu, khi mà tôi chắc chắn rồi cậu cũng sẽ quay trở về thôi khi mà trong túi chẳng còn xu nào và chẳng ai nhận cậu và cậu có thể sống sót được khi mới ở tuổi đó, và với một công tử như cậu.

Và cũng sẽ là quá phi thực tế khi mà cậu ra đi, lúc đó cuốn truyện sẽ như một cuốn sách đọc để giải trí khi mà cái kết cuối cùng lại chính là điều con người ta mong muốn nhất.

Kết lại, mình đánh giá truyện này không sâu sắc lắm, dù nó được đánh giá khá cao trên goodread và qua các review trên mạng, có thể một phần do dịch giả, và mình rất ghét cái bọn review sách mà suốt ngày thấy khen, khen dù mình thấy cuốn đó chả có gì đặc sắc.

Đánh giá:
Hành văn: 6
Nội dung: 6

P/S: Nếu hiện tại bạn chưa tìm được cuốn nào hay, xin hãy đọc Suối Nguồn - Ayn Rand

[Vụn vặt Linux] System Call

System Calls hay còn được gọi là syscall, là những lời gọi hàm từ user space tới kernel space để yêu cầu kernel thực hiện một công việc nào nó (như giao tiếp với ngoại vi, đọc ghi file v.v). Có rất nhiều System Calls nó thể kể đến một vào syscall cơ bản như:
- read()
- write()
hay một số syscall rất ít gặp như:
- get_thread_area()
- set_tid_address()
Danh sách đầy đủ hơn có thể tìm ở đây: http://asm.sourceforge.net/syscall.html
Vậy chung quy lại: System Calls (lời gọi hệ thống) là một việc chúng ta gọi một hàm mà kernel cung cấp (glibc) từ user-space để yêu cầu kernel thực hiện một nhiệm vụ nhất định.

Tại sao chúng ta cần System Calls?
Trong kiến trúc của Linux kernel, user-space không thể gọi trực tiếp các tác vụ bên dưới kernel (các hàm dưới kernel) để đảm bảo tính bảo mật và độ tin cậy (vì kernel làm việc trực tiếp với hardware).
Do đó, system calls được sinh ra để thực hiện việc làm cầu nối giữa kernel và user.

Cơ chế hoạt động của System Calls:
User-space thông báo cho Kernel space phải thực hiện tác vụ nào thông qua machine registers (thanh ghi máy). Như danh sách system calls mình đưa ở trên, số 5 chính là sys_open (tương ứng với hàm open trên user-space). Khi trên user-space gọi hàm open(), con số đại diện cho system call sys_open() là 5 sẽ được điền vào thanh ghi EAX, sau đó thực hiện softwa interrupt instruction (lệnh ngắt phần mềm) int 0x80. "Mình sẽ giới thiệu về SII trong bài viết sau đó".

Cám ơn và chúc tốt lành.

[Vụn vặt Linux] A new way - Tự học Linux

Giới thiệu:
Chuỗi bài viết về Linux không phải là một tutorial hay guideline mà chỉ là một cách để tôi lưu lại những kiến thức vụn vặt về Linux trong quá trình tự học.
Mọi kiến thức đều được lấy từ cuốn: Linux System Programming - Robert Love