Skip to content

Instantly share code, notes, and snippets.

@hieunt79
Last active May 21, 2024 07:20
Show Gist options
  • Save hieunt79/0fba98c39d3f3db52958dc31a0620b92 to your computer and use it in GitHub Desktop.
Save hieunt79/0fba98c39d3f3db52958dc31a0620b92 to your computer and use it in GitHub Desktop.
TIL

AppArmor

  1. AppArmor là gì?
  2. Có các chức năng gì?
  3. Cấu hình như thế nào?

AppArmor

  1. AppArmor là một công cụ cho phép quản lý các chương trình, cho phép giới hạn quyền truy cập vào các file trên hệ thống với một program.

Khác với window's UAC, trao quyền cho user, AppArmor giới hạn khả năng truy cập cho các program

Usage

AppArmor

  • Chạy dưới kernel

  • Quản lý program theo Profile. có 2 mode với Profile

    • Enforcement: giới hạn file truy cập và thông báo nếu có sự vi phạm
    • Complain: chỉ thông báo vi phạm, nhưng vẫn cho truy cập
  • Ngoài các cái chạy mặc định lúc khởi động, có những cái bị disable (trong /etc/apparmor.d/disable). VD với firefox:

    • Để enable: sudo aa-enforce /etc/apparmor.d/usr.bin.firefox
    • Disable again:
    sudo ln -s /etc/apparmor.d/usr.bin.firefox /etc/apparmor.d/disable/
    sudo apparmor_parser -R /etc/apparmor.d/usr.bin.firefox
    

Create AppArmor Profile

Install AppArmor utils

apt-get install apparmor-utils

Tạo Profile:

aa-genprof /path/to/application

Edit Profile

sudo aa-logprof /path/to/application

Stop & restart

sysstemctl stop apparmor
sysstemctl restart apparmor

Kết luận

AppArmor giới hạn quyền truy cập của program vào các file. Cung cấp công cụ kiểm tra các file ứng dụng truy cập, log vi phạm.

Nếu có lỗi về quyền thì nên check cái này.

How to SSH to Ubuntu 20 from Xshell 5

Error in Xshell "no matching key exchange algorithm found"

Add these lines to the end of /etc/ssh/sshd_config, then restart process:

Ciphers [email protected],aes128-ctr,aes192-ctr,aes256-ctr,[email protected],[email protected]
MACs [email protected],[email protected],[email protected],[email protected],[email protected],[email protected],[email protected],hmac-sha2-256,hmac-sha2-512,hmac-sha1

KexAlgorithms diffie-hellman-group1-sha1,diffie-hellman-group14-sha1,diffie-hellman-group-exchange-sha1,diffie-hellman-group-exchange-sha256,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group1-sha1,[email protected]

2. System Performance: Methodologies

2.1 Terminology

  • IOPS: Input/output operations per second is a measure of the rate of data transfer operations. For disk I/O, IOPS refers to reads and writes per second.
  • Throughput: The rate of work performed. Especially in communications, the term is used to refer to the data rate (bytes per second or bits per second). In some contexts (e.g., databases) throughput can refer to the operation rate (operations per second or transactions per second).
  • Response time: The time for an operation to complete. This includes any time spent waiting and time spent being serviced (service time), including the time to transfer the result.
  • latency: A measure of time an operation waiting to be serviced. In some contexts, it can refers to the entire time for an operation, equivalent to response time.
  • Utilization: với các resource cung cấp theo kiểu request, đây là cách đo lường cho mức độ resource đc sử dụng (how busy a resource is), dựa trên thời gian sử dụng chia cho thời gian lấy mẫu. Còn với resource cung cấp storage, utilization là lượng capacity đã dùng.
  • Saturation: Mức độ mà resource phải đưa các request vào queue vì ko xử lý kịp
  • Bottleneck: Trong system performance (SP), cái này là resource mà làm giới hạn SP của cả hệ thống. Phát hiện và xử lý bottleneck là hoạt động chính của SP.
  • Workload: Đầu vào của system, cái mà system xử lý.
  • Cache: Một khu vực lưu trữ tốc độ cao, lưu trữ data để tránh việc phải gọi tới những tầng chậm hơn, để tăng hiệu năng

2.3 Concepts

2.3.1 latency

The latency is the tiem spent waiting before an operation is performed.

Performance issues can be quantified using latency and then ranked because they are expressed using the same units (times). Từ đó đánh giá xem việc tối ưu có ok không, bằng cách xem xét latency tăng lên hay giảm xuống. Việc đánh giá này khó mà làm đc với các thông số khác, vd như IOPS metrics.

Khi có thể, hay convert các metric types khác về latency để cho phép so sánh. Ví dụ: nếu phải chọn giữa 100 network I/O hay 50 disk I/O, ta nên chọn cái nào? Nhưng nếu so sánh giữa 100ms network I/O và 50ms disk I/O, sự khác biệt là rõ.

2.3.2 Time scales

Vì thời gian đo đc, so sánh đc, nó giúp ta cảm nhận đc thời gian (dịch hơi ngu từ "to have an instinct about time"), và có kì vọng phù hợp cho latency cho các jobs khác nhau của hệ thống

2.3.3 Trade-offs

Ta cần biết một vài trade-offs phổ biến (các tập tiêu chí mà ta chỉ chọn đc 2/3):

  • Good / fast / cheap
  • High performance/ On-time / Inexpensive

Có những tiêu chí mà khi sửa, ta sẽ được cái này mà mất cái kia, khó mà vẹn cả đôi đường. Một vài ví dụ:

  • File system record size (or block size): Small record sizes, close to the application I/O, giúp random I/O workloads ngon hơn, file system cache đc dùng hiệu quả hơn (ứng dụng chạy ngon hơn). Large record will improve streaming workload, including file system backups.
  • Network buffer size: Small buffer will reduce the the memory overhead per connection, helping the system scale. Large sizes will improve network throughput

2.3.4 Tuning Efforts

Việc tuning hiệu quả nhất khi được thực hiện càng gần chỗ "the work is performed". Nghĩa là sao, lấy một vài ví dụ cho dễ hiểu:

Layer Example Tuning Targets
Application Application logic, request queue sizes, database queries performed
Database Database table layout, indexes, buffering
System calls Memory-mapped or read/write, sync or async I/O flags
File system Record size, cache size, file system tunables, journaling
Storage RAID level, number and type of disks, storage tunables

Vì hệ thống thường là để cho application chạy trên đó, tập trung phần này thường mang lại big wins. Ngoài việc tối ưu db query, queue, thì việc phát triển nhanh chỉ chú ý tới sự chính xác, khi nào có problem performance thì mới quay qua fix.

Một chú ý nhỏ, việc quan sát ở OS-level cũng giúp nhìn ra vấn đề ở tầng application.

2.3.5 Level of Appropriateness

Cài này là sự phù hợp, mỗi tổ chức hay môi trường có một yêu cầu riêng về performance. Tiêu chí cần phải có ở tổ chức này có thể không cần ở tổ chức khác, nó không phải đúng hoặc sai mà phụ thuộc vào ROI (return on investment).

Tuy nhiên, system performance không phải chỉ mỗi liên quan tới cost, nó còn có end-user experience. Nếu trải nghiệm khách hàng tệ quá thì ko hay, nó cũng sẽ ảnh hưởng doanh thu.

Khi thực hiện phân tích performance, cái gọi là level of appropriateness comes in to play in deciding when to stop analysis.

2.3.6 When to Stop Analysis

When doing performance analysis, ta cần biết đâu nên là điểm dừng. Có một vài vd:

  • Khi ta đã giải thích đc khá nhiều, phần lớn vấn đề về performance
  • Khi potential ROI nhỏ hơn nhiều so với cost for analysis
  • Khi biết một cái khác có thể mang lại nhiều giá trị hơn

Khi là performance engineer, đánh giá ưu tiên cho các vấn đề khác nhau để thực hiện là một nhiệm vụ quan trọng

2.3.7 Point-in-Time Recommendations

Các tính chất của hệ thống thay đổi theo thời gian (thêm user / phần cứng mới / updated software). Vì vậy các thông số có thể oke tại một thời điểm nhưng có thể trở thành nghẽn tại một thời điểm khác.

Khi thay đổi một thứ gì đó, nên lưu lại để xem xét sau này. Khá là ổn khi lưu lại trên version control system với chú thích rõ ràng. Ngoài ra có thể dùng các configuration management tools (vd Puppet, Salt, Chef ...)

2.3.8 Load vs. Architecture

Ứng dụng chạy ngon hay không có thể do architecture hoặc implementation. Hoặc cũng có thể do lượng tải chạy vào hệ thống.

Túm lại, cần phải test tải cho hệ thống, để xem hệ thống hành xử ntn.

2.3.9 Scalability

Biểu đồ hiệu năng của hệ thống khi tăng dần tải gọi là scalability. Đoạn đầu thì là linear nhưng khi knee point is reached, khả năng xử lý giảm xuống (thoughput)

Điểm knee point này xảy ra khi một thành phần nào đó đạt tới 100% utilization: the saturation point. Thành phần đó đạt 100% utilization và queue của thành phần này bắt đầu xuất hiện thường xuyên và dài hơn.

Có những thành phần mà khi hết utilization sẽ làm hệ thống "chậm" nhanh hơn, vd memory hoặc disk I/O, cũng có những cái mà khi nó hết thì hệ thống "chậm" chậm hơn xíu, vd CPU utilization.

Hệ thống cũng có thể tránh việc chậm đi bằng cách từ chối phục vụ khi hết khả năng xử lý. VD: return 503 Service Unavailable.

2.3.10 Performance metrics

Là những thông số được nghiên cứu và thu thập cho việc performance analysis và monitor. Một vài thông số cơ bản:

  • Throughput: Either operations or data volume per second. Là operation nếu để đo database throughput, là volume per second nếu là network.
  • IOPS: I/O operations per second
  • Utilization: How busy a resource is, as a percentage
  • Latency: Operation time, as an average or percentile

Overhead

Metrics are not free, cũng phải dành tài nguyên để thu thập tính toán.

Issues

Nên nhớ, metrics đc cung cấp có thể đúng, có thể sai, thường là phức tạp và thiếu tài liệu mô tả, thậm chí có bug.

2.3.11 Utilization

Time-based

Time-based Utilization: thời gian mà thiết bị được sử dụng, đc tính theo công thức U=B/T với U là utilization, B tổng thời gian mà thiết bị đc sử dụng, T là thời gian quan sát.

Thường thì khi đạt 100% utilization thì hiệu năng sẽ giảm đáng kể. Tuy nhiên cũng có những thiết bị mà ko bị degrade như thế vì nó có thể xử lý song song.

Capacity-based

Một cách khác hiểu khác cho utilization là ám chỉ capacity thay vì time. Nếu đầy 100% thì coi như không tiếp nhận xử lý đc thêm nữa. Ví dụ cho trường hợp này là memory hoặc storage capacity.

2.3.12 Saturation

Mức độ mà resource không xử lý thêm được nữa được gọi là saturation. Với capacity based, 100% utilization sẽ là bắt đầu saturation, còn với time-based thì chưa chắc, vì còn tùy thuộc vào khả năng xử lý song song của nó.

Mọi cái saturation là một cái performance issue, là một cái tăng latency, cần phải đc xử lý

2.3.13 Profiling

Profiling cho ta một góc nhìn tổng quát về hệ thống, cho phép nghiên cứu, phân tích tương quan giữa các thành phần?

2.3.14 Caching

Caching được dùng để cải thiện performance. Cache là lưu trữ kết quả từ một tầng storage chậm ở tầng storage nhanh hơn, vd cache disk blocks in RAM.

Nhiều tầng cache có thể đc dùng cùng lúc, vd CPU có nhiều cache layer.

Một thông số cũng khá quan trọng là cache's hit ratio: hit ratio = hits / (hits + misses)

Hit ratio này càng cao càng tốt và sự tăng của 98% lên 99% có ý nghĩa về performance nhiều hơn là từ 10% lên 11%. Tuy nhiên, việc so sánh cache hits rate của hai service chưa chắc là oke, vì có thể service A có hits rate lớn (vd 90%) lại có số lượng miss rate nhiều (200/s)

Algorithms

Cache management algorithms và policies là cách để xác định xem cache lại thông tin ntn.

Hot, cold, warm caches

Các từ trên là để miêu tả trạng thái của cache:

  • Cold: là khi cache trống, toàn các thông tin rác. Hit ratio của cold cache là 0. Đây là khi cache mới chạy, gần warm up.
  • Warm: đã có useful data nhưng hit rate chưa đủ cao để được coi là hot
  • Hot: có tỉ lệ hit rate cao, vd: hơn 99%
  • Warmth: cache warmth miêu tả mức độ hot warm của cache. Việc improve cache warmth là tăng hit ratio.

Khi cache mới chạy nó sẽ cần thời gian để warm up. Khi mà cache có kích thước lớn, hoặc storage có tốc độ đọc chậm, thì sẽ cần nhiều thời gian để warm up hơn.

2.3.15 Known-Unknowns

Việc biết cái gì mình biết - biết, biết - không biết, không biết - không biết là khá quan trọng trong SP.

Trong SP có rất nhiều thành phần, việc học thêm, học sâu về system, sẽ giúp ta biến những cái không biết - không biết thành những cái biết - không biết, cuối cùng là biết - biết. Từ đấy giúp giải quyết nhiều vấn đề hơn.

Có thể đọc thêm về cái này: Năm mức dốt & Hành trình truy cầu tri thức

Perspective

Có hai góc nhìn về SP và sẽ đi kèm với các thông số khác nhau của hệ thống:

  • workload analysis (top-down)
  • resource analysis (bottom-up)

Operating system

Table of contents

Hiểu về OS và kernel là rất cần thiết cho việc phân tích SP. Nhiều lúc ta cần phải phát triển và test các giả thuyết về hành xử của hệ thống, vd như system call được thực hiện như nào, kernel schedule thread trên CPU như nào... Nói chung là cần phải hiểu về OP và kernel.

Mục tiêu của chapter này:

  • Learn kernel terinology: context switching, swapping, paging, preemption, etc.
  • Hiểu vai trò của kernel và system call.
  • Kiến thức về bên trong của kernel: interrupts, schedulers, virtual memory, I/O stack.
  • See how kernel performance features have been added from Unix to Linux.
  • Develop a basic understanding of extended BPF.

Chương này có 3 phần:

  • Terminology liệt kê các thuật ngữ quan trọng
  • Background tổng hợp định nghĩa quan trọng
  • Kernel tổng hợp các cách triển khai riêng của Linux và các kernel khác

3.1 Terminology

Operating system: là software và files được cài trên hệ thống để nó boot và execute programs. Bao gồm kernel, admin tools, system libraries.

Kernel: là chương trình quản lý hệ thống, bao gồm: hardware devices, memory, CPU scheduling. Nó chạy priviledged CPU mode, đc phép access trực tiếp vào hardware, called kernel mode

Process: OS abstraction and environment for executing a program. Program chạy trong user mode và access to kernel mode (vd thực hiện device I/O) thông qua system calls or trap into the kernel.

Thread: An exceutable context that can be scheduled to run on a CPU. Kernel có nhiều threads và mỗi process chưa một hoặc nhiều thread.

Task: A Linux runable entity, which can refer to a process (with a single thread), a thread from a multithreaded process, or kernel threads.

BPF program: A kernel-mode program running in the BPF execution environment (?????)

Main memory: The physical memory of the system (e.g., RAM).

Virtual memory: An abstraction of main memory that supports multitasking and oversubscription. It is, practically, an infinite resource.

Kernel space: The virtual memory address space for the kernel

User space: The virtual memory address space for processes.

User land: User-level programs and libraries (/usr/bin, /usr/lib)

Context switch: A switch from running one thread or process to another. This is a normal function of the kernel CPU scheduler, and involves switching the set of running CPU registers (the thread context) to a new set.

Mode switch: A switch between kernel and user modes

System call (syscall): A well-defined protocol for user programs to request the kernel to perform privileged operations, including device I/O.

Processor: Not to be confused with process, a processor is a physical chip containing one or more CPU

Trap: A signal sent to the kernel to request a system routine (privileged action). Trap types include system calls, processor exceptions, and interrupts

Hardware interrupt: A signal sent by physical devices to the kernel, usually to request servicing of I/O. An interrupt is a type of trap

3.2 Background

Miêu tả chung về OS và kernel

3.2.1 Kernel

Kernel là core software của OS. What it does depends on the kernel model: Unix-like OS (Linux and BSD) have a monolithic kernel. Nó quả lý CPU scheduling, memory, file systems, network protocols, and system devices (disk, network interfaces, etc)

(Application (System Libraries (System call (Kernel (Hardware))))

System libraries cung cấp interface dễ dàng hơn cho application tương tác với kernel, thay vì phải dùng trực tiếp system call.

Thực ra có thể không cần phải dùng System libraries, ví dụ Golang runtime có syscall layer riêng mà ko cần system library, libc.

Kernel Excetion

Kernel thường chỉ chạy theo yêu cầu (app call system call), cũng có những tác vụ không phải là system call cần tiêu tốn CPU nhưng không đáng kể. Workload cần thực hiện I/O thường xuyên (vd web server), execute mostly in kernel context. Workload that are compute-intensive run in user mode, uninterrupted by the kernel.

Kernel cũng có thể ảnh hưởng tới performance của compute-intensive workload. Vd: chọn những core có warmer cache thì tốc độ xử lý cao hơn.

3.2.2 Kernel and User modes

Kernel runs in a special CPU mode called kernel mode, full access tới tất cả thiết bị, thực hiện privileged instuctions.

User programs (processes) run in user mode, và request các privileged operations thông qua kernel via system calls, such as I/O.

Vì mode và context switches tốn một chút tài nguyên, một vài cách tối ưu:

  • User-mode syscalls: implement some syscalls in a user-mode library alone.
  • Memory mapping: Used for demand paging, it can also be used for data stores and other I/O, avoiding syscall overhead.
  • Kernel bypass: Cho phép user-mode programs to access hardware directly, vd DPDK
  • Kernel-mode applications: vd TUX web server

Kernel and user mode have their own software execution contexts, including a stack and registers. Some processor architectures use a separate address space for the kernel, which mean the mode switch must also change the virtual memory context.

3.2.3 System Calls

Như đã biết ở trên, system call để yêu cầu kernel thực thi tác vụ. Có khoảng vài trăm cái system call, được docs hóa ngon lành và ship cùng với OS. System call thường ít thay đổi interface và sử dụng error code để miêu tả lỗi gặp phải.

Một vài syscall quan trọng cần biết:

  • read(2) Read bytes
  • write(2) Write bytes
  • open(2) Open a file
  • close(2) Close a file
  • fork(2) Create a new process
  • clone(2) Create a new process or thread
  • exec(2) Execute a new program
  • connect(2) Connect to a network host
  • accept(2) Accept a network connection
  • stat(2) Fetch file statistics
  • ioctl(2) Set I/O properties, or other miscellaneous functions
  • mmap(2) Map a file to the memory address space
  • brk(2) Extend the heap pointer
  • futex(2) Fast user-space mutex

Nếu không rõ về cái syscall nào thì refer man syscalls

3.2.4 Interrupts

Interrupt là tín hiệu (signal) bắn vào processor để cho nó biết có một cái gì đó xảy ra cần phải được xử lý. Khi nhận interrupt, processor sẽ bắt đầu enter kernel mode, lưu lại trạng thái của thread hiện tại, rồi chạy một cái interrupt service routinne (ISR) để xử lý cái interrupt này.

Có hai loại interrupt:

  • Asynchronous interrupt by external hardware
  • Synchronous interrupt by software instructions

Asynchronous interrupt

Như đã nói ở trên hardware devices gửi IRQs (interrupt service requests) đến processor, which arrive asynchronously tới current running software. VD một vài cái hardware interrupts:

  • Disk devices gửi signal là đã finish một disk I/O
  • Hardware indicating a failure condition
  • Network interface signal the arrival of a packet
  • Input devices: keyboard and mouse input

Synchronous interrupt

Synchronous interrupt đc sinh bởi software instructions. Có 3 loại software interrupt: traps, exceptions, faults; tuy nhiên những khái niệm này lại có thể hoán đổi cho nhau:

  • Traps:
  • Exception: một ngoại lệ xảy ra (exception), vd: divide by zero.
  • Fault: A term often used for memory events, such as page faults

Với những cái interrupt này, the responsible software và instructions vẫn nằm trên CPU.

Interrupt threads

ISRs đc thiết kế để xử lý nhanh nhất có thể, giảm thiểu tác động của việc interrupt tới threads đang chạy. Nếu một interrupt cần phải đc xử lý nhiều hơn, nó có thể được xử lý bằng interrupt thread và scheduled để chạy bởi kernel.

Trong Linux, device drivers chia làm 2 nửa, nửa trên (top half) xử lý interrupt thật nhanh, và scheduling work xuống nửa dưới (bottom half) để xử lý sau. Top half thường chạy ở chế độ interrupt-disable mode để trì hoãn các interrupt khác. Bottom half can either be tasklet or work queues; the latter are threads that can be scheduled by the kernel and can sleep when necessary.

E.g: Linux network drivers. Top half dùng để handle IRQs for inbound packet, which call the bottom half to push the packet up the network stack. The bottom half is implemented as a softirq (software interrupt).

Interrupt masking

Some code paths in the kernel cannot be interrupted safely. Để tránh những trường hợp này, kernel có thể tạm thời mask interrupt bằng cách set CPU's interrupt mask register. Thời gian interrupt disable time nên nhở nhất có thể.

3.2.5 Clock and Idle

Một thành phần quan trọng của Linux kernel là clock() routine, đc chạy bởi timer interrupt. Thường đc chạy mỗi 60, 100, 1000 lần mỗi giây, mỗi excecution của clock gọi là một tick Cái này dùng để update system time, expiring timers và time slices for thread scheduling, maintaining CPU statistics...

Một vài problem với cái clock này (đã đc improved trong những bản kernel hiện tại)

  • Tick latency: với 100Hz clock, tương đương độ trễ 10ms. Cái này đc fix bằng high-resolution real-time interrupts
  • Tick overhead: Ticks dùng nhiều CPU cycle và làm ứng dụng hơi đơ một chút

Modern kernels have moved much functionality out of the clock routine to on-demand interrupt, in an effort to create a tickless kernel. Nhằm giảm thiểu overhead và cải thiện power efficiency by allowing processor to remain sleep state longer.

When there is no work to perform, kernel schedules a placeholder thread that wait for work, called the idle thread.

3.2.6 Processes

A process is an environment for executing a user-level program. It consists of a memory address space, file descriptors, thread stacks, and registers.

Processes are multitasked by kernel. They are individually identified by their unique process ID (PID).

A process contains one or more threads, which operate in the process address space and share the same file descriptors. A thread is an executable context consisting of a stack, registers, and an instruction pointer (also called a program counter). Multiple threads allow a single process to execute in parallel across multiple CPUs. On Linux, threads and processes are both tasks.

The first process launched by the kernel is called "init" and have PID 1.

Process Creation

Processes are normally created using the fork(2) system call on Unix systems.

The fork(2) or clone(2) syscall may use a copy-on-write (COW) strategy to improve performance. This strategy either defers or eliminates the need to copy memory, reducing memory and CPU usage.

Process Life Cycle

Hình bên dưới show một life cycle of a process.

Figure 3.8 Process life cycle

On-Proc là trạng thái mà process đang đc chạy trên processor. Trạng thái ready-to-run là đã sẵn sàng nhưng mà đang chờ ở queue để đc processor xử lý. Hầu hết I/O will block, đặt process và trạng thái sleep, cho tới khi I/O xong. Zombie state là process đã xong và chờ parent process hoặc kernel remove nó đi.

Process environment

Process environment bao gồm data trên user address space của process và metadata (context) trên kernel.

Figure 3.9 Process environment

Mỗi kernel context của process gồm: PID, UID, PPID ... Cũng như file descriptors (refer về file mà process đang sử dụng)

3.2.7 Stacks

Stack là vùng nhớ trên memory dùng cho các dữ liệu tạm thời, tổ chức kiểu LIFO (vào sau ra trước). Nó được dùng để chứa các dữ liệu ít quan trọng ...... Khi một function được gọi, địa chỉ để trả về giá trị được lưu vào stack (the return address is saved to the stack). Một vài registers (thanh ghi) cũng đc lưu vào stack nếu giá trị của nó được dùng ngay sau khi gọi (?)... Tập data trên stack liên quan tới một function được thực thi gọi là stack frame.

Chúng ta có thể xuất ra được các fucntion đã được excute (stack walking). Action này gọi là stack back trace hoặc stack trace. Đây là một công cụ rất hiệu quả trong system performance.

How to read the stack

Stack thường đc print theo kiểu leaf-to-root, nghĩa là fucntion mới nhất quay ngược về các fucntion trước nó (hay gọi ra nó).

Vì stack này là các hàm trong source code nên thường sẽ không có document nào ngoài code, trừ một số trường hợp là các hàm là API hoặc được document riêng.

User and Kernel stacks

Khi thực thi một system call, process's thread có hai stack: user-level stack và kernel level stack.

Figure 3.10 User and Kernel stacks

...

3.2.8 Virtual memory

Virtual memory là một trừu tượng hóa của main memory, cung cấp một góc nhìn riêng biệt, ko chung chạ và gần như không giới hạn cho các tiến trình và kernel. Việc này cũng giúp cho phép mapping nhiều vùng nhớ bên dưới (main memory và secondary storage (disks) nếu cần).

Figure 3.11 Virtual memory

Memory management

Vì virtual memory cho phép dùng cả hai vùng storage làm mem (cả main memory và disks), kernel sẽ cố gắng giữ những cái tiến trình hay dùng ở main memory cho hiệu quả. Có hai cách kernel dùng:

  • Process swapping move cả cục process giữa secondary và main luôn
  • Paging move từng phần nhỏ của memory (called pages) (v.d 4 KBytes)

Process swapping làm hiệu năng tụt, còn Paging thì hiệu quả hơn. Cả hai cách đều dùng thuật toán least recently used. Trong Linux từ swapping thường được dùng để chỉ tới paging.

3.2.9 Schedulers

Unix và derivative của nó thường chia một khoảng thời gian thành nhiều phần nhỏ và phân bố cho các process khác nhau để chạy nhiều process cùng lúc. Việc chia thời gian sử dụng processor cho các process được thực hiện bởi scheduler, key component của OS kernel.

Việc phân bổ CPU time giữa các process còn phải cân nhắc yếu tố priority sao cho important work được thực thi sớm hơn. Scheduler track tất cả các thread trong trạng thái ready-to-run, các thread đặt trọng các queue chia theo priority, gọi là run queues.

Khi có nhiều threads cùng muốn được thực thi, priority cao hơn sẽ đc thực thi trước. Kernel threads có priority cao hơn so với user-level process.

Priority có thể đc edit để cải thiện hiệu năng của workload. Workload đc chia làm hai loại:

  • CPU-bound: Application cần nhiều tải tính toán, vd scientific and mathematical analysis, những cái cần dùng nhiều CPU time. Những ứng dụng này bị giới hạn bởi tài nguyên CPU
  • I/O-bound: Application thường thực hiện I/O, dùng ít compute, v.d web servers, file servers... những cái mà mong muốn độ trễ thấp. Khi tải tăng thì I/O storage hoặc network resource là những cái được sử dụng nhiều hơn.

Policy thường được sử dụng trong UNIX là xác định các CPU-bound workload và giảm priority tụi này xuống, cho phép I/O-bound chạy trước.

3.2.10 File systems

File systems là cách tổ chức dữ liệu dưới dạng file và thư mục. File systems cung cấp file-based interface để truy cập dữ liệu, thường dựa trên chuẩn POSIX. The operating system provides a global file namespace, tổ chức theo kiểu top-down tree topology bắt đầu với root level ("/"). Các file system khác join tree bằng cách mount vào các mount point.

Đa số file systems lưu data dưới disks, một số file systems được gen ra bởi kernel, such as /proc and /dev

Kernel cung cấp nhiều phương pháp để isolate process khỏi file namespace, chroot(8) và trên Linux là mount namespaces (cái này thường dùng cho containers).

VFS

Virtual file system là một kernel interface dùng để trừu tượng các loại file system, để cho nhiều loại file system cùng hoạt động song song, vd Sun Microsystem vừa có UFS và NFS (network file system)

VFS interface cho phép thêm mới file system type vào kernel dễ dàng hơn. Và cũng cho phép user program và application truy cập file system dễ dàng hơn.

I/O stack

Với các storage-device-based file system, the path từ user-level software tới storage device gọi là I/O stack.

Hình bên dưới mô tả I/O stack. Có một đường bên trái cho phép thẳng xuống block device, bypassing file system. Path này thi thoảng đc dùng bởi administrative tools và databases.

+---------------------------+
|       Application         |
+------------------+--------+
                   |
                   |
+------------------v--------+
|      System Calls         |
+----+-------------+--------+
     |             |
     |    +--------v--------+
     |    |      VFS        |
     |    +--------+--------+
     |             |
     |    +--------v--------+
     |    |    File system  |
     |    +--------+--------+
     |             |
+----v-------------v--------+
| Block Device Interface    |
+------------+--------------+
             |
+------------v--------------+
|  Volume manager           |
+------------+--------------+
             |
             |
+------------v--------------+
| Host Bus Adapter Driver   |
+------------+--------------+
             |
+------------v--------------+
|     Disk devices          |
+---------------------------+

Figure 3.15 Generic I/O stacks

3.2.11 Caching

Disk I/O thường có latency cao nên các software stack thường cố gắng để cache lại read and write để tránh latency này.

Cache Examples
Client cache Web browser cache
Application cache
Web server cache Apache cache
Database cache memcached
Caching server MySQL buffer cache
Directory cache dcache
File metadata cache inode cache
Operating system buffer cache Buffer cache
File system primary cache Page cache, ZFS ARC
File system secondary cache ZFS L2ARC
Device cache ZFS vdev
Block cache Buffer cache
Disk controller cache RAID card cache
Storage array cache
On-disk cache

V.d, buffer cache là một khu vực trên main memory tạm thời store recently used disk block. Disk read được phục vụ ngay từ chỗ cache này thay vì phải gọi xuống disk.

3.2.12 Networking

Modern kernel cung cấp một stack các giao thức network, đã đc tích hợp sẵn. Giao thức thường được sử dụng là TCP/IP. User-level program truy cập network bằng endpoint mà kernel cấp, endpoint này gọi là socket.

3.2.13 Device drivers

Device drivers là các kernel software cho việc quản lý device và I/O, thường đc cung cấp bởi device vendors. Some kernel hỗ trợ pluggable device drivers, cho phép loaded or unloaded driver mà ko cần phải restart lại.

Device drivers chia hai loại:

  • Character device hay raw device, cũng cấp phương pháp truy cập tuần tự sequential và không có buffer, vd: keyboard, mouse
  • Block devices: thực hiện I/O theo units of blocks, thường thì là 512b mỗi block. Truy cập randomly dựa theo block offset. Trong original Unix, block device cung cấp caching (cache trên main memory, gọi là buffer cache).

3.2.14 Multiprocessor

3.2.15 Preemption

Kernel preemption cho phép thread ở user-level có priority cao hơn kernel và đc thực thi trước. Kernel support preemption gọi là fully preemption, mặc dù có một vài code path vẫn ko thể bị interrupt.

Một cách tiếp cận khác đc hỗ trợ là voluntary kernel preemption, where logical stopping points in the kernel code can check and perform preemption (don't understand this :D).

3.2.16 Resource management

Linux cung cấp nhiều công cụ để cấu hình tunning access tới các resource. Linux có control groups (cgroups) và nhiều cái khác được phát triển để cung cấp việc xử lý.

3.2.17 Observability

3.3 Kernel

Phần này mô tả chi tiết Unix-like kernel implementation và focus vào performance.

3.4 Linux

Linux được tạo bởi Linus Torvards vào năm 1991 với mục tiêu là một free OS cho Intel personal computers.

Linux kế thừa với nhiều ý tưởng từ các OS trước đó: Unix, BSD, Solaris, Plan 9

3.4.1 Linux Kernel Developments

3.4.2 systemd

suser@desktop:~$ systemd-analyze
Startup finished in 2.531s (kernel) + 23.513s (userspace) = 26.044s 
graphical.target reached after 23.503s in userspace
suser@desktop:~$ systemd-analyze critical-chain
The time when unit became active or started is printed after the "@" character.
The time the unit took to start is printed after the "+" character.

graphical.target @23.503s
└─multi-user.target @23.503s
  └─telegraf.service @6.998s +144ms
    └─network.target @2.322s
      └─NetworkManager.service @1.856s +466ms
        └─dbus.service @1.853s
          └─basic.target @1.843s
            └─sockets.target @1.842s
              └─snapd.socket @1.842s +850us
                └─sysinit.target @1.835s
                  └─snapd.apparmor.service @1.787s +47ms
                    └─apparmor.service @1.641s +144ms
                      └─local-fs.target @1.640s
                        └─run-snapd-ns-snap\x2dstore.mnt.mount @11.531s
                          └─run-snapd-ns.mount @10.989s
                            └─local-fs-pre.target @620ms
                              └─keyboard-setup.service @467ms +153ms
                                └─systemd-journald.socket @456ms
                                  └─-.mount @452ms
                                    └─system.slice @452ms
                                      └─-.slice @452ms
suser@desktop:~$ systemd-analyze blame
21.111s plymouth-quit-wait.service                           
 3.496s apt-daily-upgrade.service                            
 2.084s docker.service                                       
 1.305s snapd.service

3.4.4 Extended BPF

BPF stand for Berkerly Packet Filter, ban đầu là để cải thiện hiệu năng của packet capture tools. Năm 2013 được viết lại và trở thành engine đa mục đích, dùng cho networking, Observability, và security.

BPF khá là quan trọng trong SP analysis. Nó cung cấp khả năng lập trình với các event resource của kernel: tracepoints, kprobes, uprobes, và perf_events. Vd: BPF program có thể ghi lại timestamp khi start và end khi I/O để tính I/O duration.

3.7 Exercises

  1. Answer the following questions about OS terminology:
  • What is the difference between a process, a thread, and a task?

    • Vẫn chưa phân biệt được sự khác biệt. Process thì là chương trình của người dùng chạy trên user-mode
  • What is a mode switch and a context switch?

    • Mode switch là việc CPU chuyển việc xử lý từ user-mode sang kernel mode hoặc ngược lại.
    • Context switch là CPU chuyển từ xử lý process (hoặc thread) này sang process (thread) khác
  • What is the difference between paging and process swapping?

    • Paging là chia virtual memory cho các process
    • Process swapping là chuyển memory của process sang phần swap vì ít sử dụng.
  • What is the difference between I/O-bound and CPU-bound workloads?

    • I/O bound là các ứng dụng cần nhiều towng tác đọc ghi với các thiết bị bên ngoài, giới hạn bởi tốc độ I/O
    • CPU bound là ứng dụng cần thực hiện tính toán nhiều, giới hạn bởi số lượng tài nguyên compute
    • Thường ta sẽ tunning cho I/O đc CPU thực hiện trước để tăng tốc độ xử lý của I/O bound
  1. Answer the following conceptual questions:
  • Describe the role of the kernel.

    • Thực hiện quản các tài nguyên bên dưới
    • Cung cấp giao diện tương tác thông qua system call
  • Describe the role of system calls.

    • Cho phép ứng dụng tương tác với các thiết bị mà kernel quản lý thông qua system call
  • Describe the role of VFS and its location in the I/O stack

    • VFS nằm trên các file system khác để cung cấp một interface thống nhất cho các ứng dụng dễ giao tiếp với nhiều loại interface bên dưới, cho phép nhiều fs cùng tồn tại như một thể thống nhất với góc nhìn từ app.
    • VFS > FSs > syscall > kernel > device controller > device
  1. Answer the following deeper questions:
  • List the reasons why a thread would leave the current CPU.

    • Thread cần đọc một số thông tin từ disk, hoặc chờ từ I/O tương tác từ bên ngoài
    • Có thread có độ ưu tiên cao hơn thread hiện tại
  • Describe the advantages of virtual memory and demand paging.

    • Virtual memory tương tự như VFS ở trên, tạo thành một mức trừu tượng giữa main memory, secondary memory với memory cung cấp cho các process, thread bên trên
    • Cho phép ứng dụng chạy với lượng memory ảo gần như vô hạn
    • Swap các process ko thường được sử dụng để cho phép chạy nhiều ứng dụng hơn.
    • Với demand paging, thì mình chưa biết
=========
Transfer file between Linux machines
=========
1. Server listen with command
nc -l -p 80 -q 30 > file.xxx < /dev/null
with: -q: number of seconds that server wait for connection
TIP: choose value of "-q" wisely =))
2. Client send file
cat file.xx | nc server.ip.address 80
@eveningcafe
Copy link

thank thay

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment