Wednesday, 10 December 2014

sysctl - cấu hình các tham số kernel khi đang chạy

sysctl là một công cụ đơn giản (vâng, đơn giản hơn cả ls), công việc của nó chỉ có hiển thị hoặc thay đổi một tham số nào đó của kernel. Vấn đề biết phải thay đổi tham số nào, để làm gì mới là phần ... phức tạp.

Hỏi theo phong cách CCGU:
# whatis sysctl
sysctl (8)           - configure kernel parameters at runtime
# whereis sysctl
sysctl: /sbin/sysctl /etc/sysctl.d /etc/sysctl.conf /usr/share/man/man8/sysctl.8.gz
Hiển thị 1 parameter có tên là net.ipv4.ip_forward (để cho phép forward gói tin) :
# sysctl net.ipv4.ip_forward
net.ipv4.ip_forward = 0
Thay đổi giá trị của parameter nói trên:
# sysctl -w net.ipv4.ip_forward=1
net.ipv4.ip_forward = 1
Các settings của sysctl nằm ở /etc/sysctl.conf và có thể trong thư mục /etc/sysctl.d, để thay đổi có hiệu lực cả sau khi reboot, cần sửa các file này thay vì set trực tiếp bằng sysctl.

Các parameter mà sysctl thao tác được liệt kê ở dạng file tại thư mục /proc/sys.
 Option: -a hiển thị tất cả các tham số hiện tại sẵn sàng
# find /proc/sys -type f | wc -l # đếm số file trong /proc/sys
693
# sysctl -a | wc -l 
error: permission denied on key 'net.ipv4.route.flush'
error: permission denied on key 'net.ipv6.route.flush'
error: permission denied on key 'vm.compact_memory'
713
Có một chút chênh lệch về số lượng ở đây, lý do có sự chênh lệch này là do output của sysctl có nhiều giá trị khác nhau cho cùng 1 parameter:
Option: -N chỉ hiển thị phần tên của key, không hiển thị giá trị
# sysctl -N -a 2>/dev/null | uniq -c | sort -nr | head -n3
     24 dev.cdrom.info
      1 vm.vfs_cache_pressure
      1 vm.vdso_enabled
 loại đi những giá trị bị trùng lặp, ta có:
root@integration-ubuntu:~# sysctl -N -a | uniq | wc -l
error: permission denied on key 'net.ipv4.route.flush'
error: permission denied on key 'net.ipv6.route.flush'
error: permission denied on key 'vm.compact_memory'
690 # +3 = 693
Lý do 3 key bị permission denied vì các file tương ứng không cho phép đọc, chỉ được ghi :
# ls -l /proc/sys/net/ipv4/route/flush
--w------- 1 root root 0 Dec 10 12:22 /proc/sys/net/ipv4/route/flush
Chú ý, sysctl có option -A nhưng có vẻ như tác dụng của nó giống hệt -a:
# diff <(sysctl -a 2>/dev/null) <(sysctl -A 2>/dev/null)
145c145
< kernel.random.uuid = 0385f986-31fe-436f-91cb-6174e8ea362b
---
> kernel.random.uuid = b2621216-76bb-4ade-bb3b-daa28ea8af52
Phân nhóm các parameter:
# sysctl -N -a 2>/dev/null | cut -d'.' -f1 | uniq -c
      2 debug
     38 dev
     34 fs
    110 kernel
    492 net
     37 vm
Vậy như kết quả trên cho thấy, có 492 key có thể thay đổi cho net (liên quan đến network), 110 thay đổi các tính năng chung của kernel và phần còn lại cho vm (virtual memory subsystem), dev, fs, debug.

Giải thích nhanh về các subdir của /proc/sys (số lượng subdir này phụ thuộc vào platform phần cứng mà OS của bạn đang chạy) :

abi/  execution domains & personalities
debug/  <empty>
dev/  device specific information (eg dev/cdrom/info)
fs/  specific filesystems
  filehandle, inode, dentry and quota tuning
  binfmt_misc <Documentation/binfmt_misc.txt>
kernel/  global kernel info / tuning
  miscellaneous stuff
net/  networking stuff, for documentation look in:
  <Documentation/networking/>
proc/  <empty>
sunrpc/  SUN Remote Procedure Call (NFS)
vm/  memory management tuning
  buffer and cache management

Bài viết thực hiện trên:
# uname -r; lsb_release -d
3.13.0-30-generic
Description:    Ubuntu 12.04.4 LTS
# dpkg-query -s `dpkg -S $(which sysctl) | cut -d: -f1` | grep Desc -A5
Description: /proc file system utilities
 This package provides command line and full screen utilities for browsing
 procfs, a "pseudo" file system dynamically generated by the kernel to
 provide information about the status of entries in its process table
 (such as whether the process is running, stopped, or a "zombie").

Tham khảo: https://www.kernel.org/doc/Documentation/sysctl/

Theo man 1 sysctl, khi thay đổi một giá trị cần dùng thêm -w nhưng theo code của sysctl, -w hay "X=Y" có giá trị như nhau:

  • for ( ; *argv; argv++) {
  • if (WriteMode || index(*argv, '='))
  • ReturnCode += WriteSetting(*argv);
  • else
  • ReturnCode += ReadSetting(*argv);
  • }

  • https://gitorious.org/procps/procps/source/2ec9f5c22e3eeaf4da514e0e6ec9374cfdbb9a99%3asysctl.c#L804

    Nhưng vì doc là tiêu chuẩn với người dùng nên để cho an toàn, tốt nhất hãy sử dụng
     sysctl -w X=Y
     khi muốn thay đổi một parameter.

    Chú ý, trên các hệ thống không phải Linux (vd: BSDs ...) vẫn có sysctl và tác dụng tương tự.