Bài giảng Nguyên lý Hệ điều hành - Chương 6: Linux System Calls - Phạm Quang Dũng

Các nhóm hàm Các hàm liên quan đến hệ thống được chia thành 2 nhóm dựa vào cách chúng được thực thi:  Hàm thư viện: là hàm bình thường đặt trong thư viện bên ngoài chương trình. Các tham số được đặt trong các thanh ghi của CPU hoặc trên stack. Sự thực hiện được truyền đến đoạn mã đầu của hàm (thường trong thư viện chia sẻ được nạp)  System call: được thực thi trong Linux kernel. Các tham số được chuyển đến và xử lý trong kernel đến khi lời gọi kết thúc.  Linux cung cấp khoảng 200 system call. Một số được sử dụng cho chính hệ thống, số còn lại được sử dụng chỉ trong việc thực thi các hàm thư viện đặc biệt  Liệt kê trong /usr/include/asm/unistd.h  Hầu hết các system call được khai báo trong

pdf21 trang | Chia sẻ: candy98 | Lượt xem: 809 | Lượt tải: 0download
Bạn đang xem trước 20 trang tài liệu Bài giảng Nguyên lý Hệ điều hành - Chương 6: Linux System Calls - Phạm Quang Dũng, để xem tài liệu hoàn chỉnh bạn click vào nút DOWNLOAD ở trên
Chương 6. Linux System Calls Phạm Quang Dũng 2Các nhóm hàm Các hàm liên quan đến hệ thống được chia thành 2 nhóm dựa vào cách chúng được thực thi:  Hàm thư viện: là hàm bình thường đặt trong thư viện bên ngoài chương trình. Các tham số được đặt trong các thanh ghi của CPU hoặc trên stack. Sự thực hiện được truyền đến đoạn mã đầu của hàm (thường trong thư viện chia sẻ được nạp)  System call: được thực thi trong Linux kernel. Các tham số được chuyển đến và xử lý trong kernel đến khi lời gọi kết thúc. 3 Linux cung cấp khoảng 200 system call. Một số được sử dụng cho chính hệ thống, số còn lại được sử dụng chỉ trong việc thực thi các hàm thư viện đặc biệt  Liệt kê trong /usr/include/asm/unistd.h  Hầu hết các system call được khai báo trong 46.1. Sử dụng strace  Lệnh strace theo dõi sự thực hiện của một chương trình khác, liệt kê bất cứ system call nào chương trình gọi và bất kỳ signal nào nó nhận được.  % strace tên_CT [các_tham_số]  Vd: % strace hostname 56.2. access: kiểm tra quyền truy nhập file  system call access xác định xem tiến trình gọi có quyền truy nhập file hay không.  access(ts1, ts2)  ts1: đường dẫn tới file  ts2: chuỗi bit hoặc F_OK, R_OK, W_OK, X_OK  Giá trị trả về:  = 0 nếu tiến trình có các quyền trong ts2  = -1 nếu có lỗi, mã lỗi được thiết lập thích hợp là  ENOENT (file không tồn tại)  EACCES (không có quyền tới file hoặc thư mục chứa file)  EROFS (khi yêu cầu ghi lên file có thuộc tính chỉ đọc) 6Chương trình ví dụ  Listing 8.1 (check-access.c): kiểm tra sự tồn tại của file, xác định quyền đọc và ghi.  Cách chạy: % ./check-access /cpr/test.c 76.3. fsync, fdatasync: flushing disk buffer  Trên hầu hết HĐH, khi bạn ghi 1 file, dữ liệu không lập tức được ghi lên đĩa. HĐH lưu dữ liệu đó trong 1 buffer để:  giảm số lần ghi đĩa  cải thiện sự đáp ứng của chương trình  Khi buffer đầy hoặc trạng thái nào đó xuất hiện (vd: khi hết lượng thời gian ấn định), HĐH ghi các dữ liệu trong buffer lên đĩa luôn một lần.  Khi mất nguồn đột ngột, dữ liệu trong buffer bị mất  Với chương trình quan trọng, yêu cầu dữ liệu phải được ghi lên đĩa ngay lập tức.  Dùng fsync(writable_file_descriptor) 8fsync, fdatasync (tiếp)  Listing 8.3 (write_journal_entry.c): ghi từng mục đơn dòng lên 1 file nhật ký.  Có thể mở file để thực hiện vào-ra đồng bộ: tất cả các lần ghi được chuyển đến đĩa ngay lập tức:  xác định cờ O_SYNC khi mở file. 96.4. getrlimit, setrlimit: giới hạn tài nguyên  cho phép tiến trình đọc và thiết lập giới hạn tài nguyên hệ thống mà nó có thể sử dụng.  mỗi hàm có 2 tham số:  ts1: mã xác định loại giới hạn tài nguyên:  RLIMIT_CPU: lượng thời gian tối đa mà chương trình thực sự được sử dụng CPU (giây)  RLIMIT_DATA: dung lượng bộ nhớ tối đa cho CT  RMIT_NPROC: số tối đa tiến trình con được chạy  RMIT_NOFILE: số tối đa file descriptor mà tiến trình có thể mở tại một thời điểm.  ts2: con trỏ tới biến structrlimit. 10 Chương trình ví dụ  Listing 8.4 (limit-cpu.c): thiết lập giới hạn thời gian CPU là 1 giây rồi bước vào vòng lặp vô hạn. Linux sẽ giết tiến trình ngay khi nó dùng CPU vượt 1 giây.  Khi chạy CT: % ./limit-cpu CPU time limit exceeded 11 6.5. mprotect: thiết lập quyền bộ nhớ  Chương 5, phần “Mapped Memory” đã nói cách sử dụng system call mmap  Nhắc lại, tham số thứ ba của mmap là chuỗi bit hoặc cờ bảo vệ bộ nhớ (PROT_READ, PROT_WRITE, PROT_EXEC, PROT_NONE). Khi CT cố thực hiện hoạt động không được phép, nó bị chấm dứt bởi signal SIGSEGV.  Sau khi bộ nhớ được ánh xạ, các quyền trên có thể được sửa đổi bởi system call mprotect(ts1, ts2, ts3):  ts1: địa chỉ vùng nhớ  ts2: kích thước vùng nhớ  ts3: tập các cờ bảo vệ 12 Listing 8.7: mprotect.c 1. CT cài đặt hàm xử lý tín hiệu SIGSEGV 2. định vị 1 trang bộ nhớ bằng việc ánh xạ /dev/zero và ghi 1 giá trị lên đó để thu được một bản copy riêng 3. bảo vệ bộ nhớ bằng cách gọi mprotect với tham số PROT_NONE 4. sau đó CT ghi lên bộ nhớ, Linux gửi tín hiệu SIGSEGV, hàm xử lý tín hiệu gỡ bỏ bảo vệ, cho phép truy nhập bộ nhớ để ghi. 5. khi hàm xử lý hoàn thành, quyền điều khiển trở về main, CT dùng munmap để bỏ định vị bộ nhớ. 13 6.6. nanosleep: high-precision sleeping  Là phiên bản có độ chính xác cao (nano giây) của system call UNIX chuẩn sleep  Hữu dụng khi cần lập lịch cho các hoạt động thường xuyên có khoảng thời gian xen giữa rất nhỏ.  Cấu trúc struct timespec có 2 trường:  tv_sec: số giây nguyên  tv_nsec: số mili giây cộng thêm  nanosleep có tham số thứ hai là con trỏ tới 1 đối tượng struct timespec khi khác null sẽ bằng lượng thời gian còn lại, giúp việc tiếp tục lại hoạt động ngủ dễ dàng hơn. 14 Ví dụ  Listing 8.8 (better_sleep.c): hàm nhận một giá trị thực là số giây ngủ và khởi động lại hoạt động ngủ nếu nó được ngắt bởi 1 signal. 15 6.7. sendfile: truyền dữ liệu nhanh  Cung cấp cơ chế hiệu quả để copy dữ liệu từ một file descriptor này tới một file descriptor khác.  Không truyền qua buffer trung gian  File descriptor có thể là các tệp, socket, các thiết bị khác.  Các tham số:  file descriptor để ghi lên  file descriptor để đọc ra  con trỏ tới biến offset: bắt đầu đọc từ offset này của file  số byte cần truyền  Giá trị trả về là số byte đã được truyền 16 Chương trình ví dụ  Listing 8.10 (copy.c): Chương trình đơn giản nhưng thực thi copy file vô cùng hiệu quả.  gọi chương trình với 2 tên file trên dòng lệnh  sử dụng fstat để xác định kích thước của file nguồn (byte)  Có thể sử dụng sendfile trong nhiều nơi để giúp việc copy hiệu quả hơn.  Vd: Web server và các ứng dụng mạng khác.  Thông thường, một yêu cầu được nhận từ socket nối với máy client. Chương trình server mở file trên đĩa của mình để nhận dữ liệu cần thiết và ghi nội dung file lên socket mạng.  Sử dụng sendfile có thể tăng tốc đáng kể hoạt động trên. 17 6.8. setitimer: setting interval timers  Lập lịch việc phát đi một signal tại một số thời điểm trong tương lai sau khoảng thời gian ấn định trước.  Một chương trình có thể thiết lập 3 dạng timer khác nhau tùy theo truyền timer code:  ITIMER_REAL: tiến trình được gửi signal SIGALRM sau khoảng thời gian wall-clock xác định.  ITIMER_VIRTUAL: tiến trình được gửi signal SIGVTALRM sau khi tiến trình thực hiện được khoảng thời gian xác định. Thời gian tiến trình không thực hiện (khi kernel hoặc tiến trình khác chạy) không được tính.  ITIMER_PROF: tiến trình được gửi signal SIGPROF khi hết khoảng thời gian định trước, tính cả thời gian tiến trình thực hiện và thời gian thực hiện các system call gọi bởi tiến trình. 18 setitimer (tiếp)  Các tham số:  ts1: timer code  ts2: con trỏ tới đối tượng struct itimerval, xác định thiết lập mới cho timer đó.  ts3: nếu khác Null thì là con trỏ tới đối tượng struct itimerval khác để nhận các thiết lập timer cũ.  Biến struct itimerval có 2 trường:  it_value: chứa thời gian tính đến lần hết hạn tiếp theo của timer và 1 signal được gửi. nếu =0 thì timer là disable.  it_interval: chứa giá trị mà timer sẽ được thiết lập lại sau khi hết hạn. nếu =0 thì timer là disable sau khi hết hạn. 19 Chương trình ví dụ  Listing 8.11 (itimer.c): minh họa sử dụng setitimer để theo dõi thời gian thực hiện của 1 chương trình.  1 timer được cấu hình hết hạn sau mỗi 250 ms và gửi 1 signal SIGVTALRM. 20 6.9. sysinfo: lấy thống kê hệ thống  Tham số duy nhất là con trỏ tới biến struct sysinfo  Một số trường quan trọng của struct sysinfor:  uptime: thời gian tính từ khi hệ thống được khởi động (giây)  totalram: tổng dung lượng RAM khả dụng  freeram: dung lượng RAM còn trống  procs: số lượng tiến trình trong hệ thống  Để sử dụng sysinfo, bao gồm các thư viện: ,,  Listing 8.12 (sysinfo.c): in ra một số thống kê hệ thống ở thời điểm hiện tại. 21 6.10. uname  Dùng để lấy nhiều thông tin hệ thống như network name và domain name của máy tính, phiên bản HĐH  Tham số duy nhất: con trỏ tới đối tượng struct utsname, gồm các trường:  sysname: tên của HĐH (vd: Linux)  release, version: số hiệu phát hành và phiên bản của Linux kernel.  machine: một số thông tin về nền phần cứng chạy Linux. Với Linux x86, đó là i386 hoặc i686.  node:hostname tuyệt đối của máy tính  domain: domain name của máy tính  Listing 8.13 (print_uname.c): in một số thông tin của Linux