Lưu ý
Mục đích của file này là để độc giả tiếng Việt có thể đọc và hiểu tài liệu nhân kernel dễ dàng hơn, không phải để tạo ra một nhánh tài liệu riêng. Nếu bạn có bất kỳ nhận xét hoặc cập nhật nào cho file này, vui lòng thử cập nhật file tiếng Anh gốc trước. Nếu bạn thấy có sự khác biệt giữa bản dịch và bản gốc, hoặc có vấn đề về bản dịch, vui lòng gửi góp ý hoặc patch cho người dịch của file này, hoặc nhờ người bảo trì và người review tài liệu tiếng Việt giúp đỡ.
- Bản gốc:
- Người dịch:
Google Translate (machine translation)
- Phiên bản gốc:
8541d8f725c6
Cảnh báo
Tài liệu này được dịch tự động bằng máy và chưa được review bởi người dịch. Nội dung có thể không chính xác hoặc khó hiểu ở một số chỗ. Khi có sự khác biệt với bản gốc, bản gốc luôn là chuẩn. Bản dịch chất lượng cao (được review) được đặt trong thư mục vi_VN/.
hủy chia sẻ cuộc gọi hệ thống¶
Tài liệu này mô tả lệnh gọi hệ thống mới, unshare(). Tài liệu
cung cấp cái nhìn tổng quan về tính năng, tại sao nó cần thiết, làm thế nào nó có thể
được sử dụng, đặc tả giao diện, thiết kế, triển khai và
làm thế nào nó có thể được kiểm tra.
Nhật ký thay đổi¶
phiên bản 0.1 Tài liệu ban đầu, Janak Desai (janak@us.ibm.com), 11 tháng 1 năm 2006
Nội dung¶
- Tổng quan
Lợi ích
Chi phí
Yêu cầu
Đặc tả chức năng
Thiết kế cấp cao
Thiết kế cấp thấp
Đặc điểm kỹ thuật kiểm tra
Công việc tương lai
1) Tổng quan¶
Hầu hết các nhân của hệ điều hành cũ đều hỗ trợ tính năng trừu tượng hóa các luồng dưới dạng nhiều bối cảnh thực thi trong một quy trình. Những hạt nhân này cung cấp các nguồn lực và cơ chế đặc biệt để duy trì các “sợi dây” này. Linux kernel, một cách thông minh và đơn giản, không tạo ra sự khác biệt giữa các tiến trình và “luồng”. Kernel cho phép các tiến trình chia sẻ tài nguyên và do đó họ có thể đạt được hành vi “luồng” kế thừa mà không cần yêu cầu các cấu trúc và cơ chế dữ liệu bổ sung trong kernel. các sức mạnh của việc triển khai các luồng theo cách này không chỉ đến từ sự đơn giản của nó mà còn cho phép các lập trình viên ứng dụng làm việc bên ngoài giới hạn của các tài nguyên được chia sẻ tất cả hoặc không có gì của di sản chủ đề. Trên Linux, tại thời điểm tạo luồng bằng hệ thống nhân bản gọi, các ứng dụng có thể chọn lọc các tài nguyên để chia sẻ giữa các chủ đề.
lệnh gọi hệ thống unshare() thêm một nguyên thủy vào mô hình luồng Linux
cho phép các luồng ‘hủy chia sẻ’ một cách có chọn lọc bất kỳ tài nguyên nào đang được
được chia sẻ tại thời điểm tạo ra chúng. unshare() được khái niệm hóa bởi
Al Viro vào tháng 8 năm 2000, trên danh sách gửi thư Linux-Kernel, như một phần
cuộc thảo luận về các chủ đề POSIX trên Linux. unshare() tăng cường
tính hữu ích của các luồng Linux đối với các ứng dụng muốn kiểm soát
tài nguyên được chia sẻ mà không cần tạo ra một tiến trình mới. unshare() là điều đương nhiên
ngoài tập hợp các nguyên thủy có sẵn trên Linux để triển khai
khái niệm tiến trình/luồng như một máy ảo.
2) Lợi ích¶
unshare() sẽ hữu ích cho các khung ứng dụng lớn như PAM
nơi tạo một quy trình mới để kiểm soát việc chia sẻ/hủy chia sẻ quy trình
tài nguyên là không thể. Vì không gian tên được chia sẻ theo mặc định
khi tạo một quy trình mới bằng cách sử dụng fork hoặc clone, unshare() có thể có lợi
ngay cả các ứng dụng không theo luồng nếu chúng có nhu cầu tách liên kết
từ không gian tên được chia sẻ mặc định. Sau đây liệt kê hai trường hợp sử dụng
nơi có thể sử dụng unshare().
2.1 Không gian tên ngữ cảnh cho mỗi bảo mật¶
unshare() có thể được sử dụng để triển khai các thư mục đa tức thời bằng cách sử dụng
cơ chế không gian tên cho mỗi tiến trình của kernel. Thư mục đa nghĩa,
chẳng hạn như phiên bản ngữ cảnh theo từng người dùng và/hoặc theo từng bảo mật của/tmp,/var/tmp hoặc
phiên bản ngữ cảnh theo từng bảo mật của thư mục chính của người dùng, cách ly người dùng
xử lý khi làm việc với các thư mục này. Sử dụng tính năng hủy chia sẻ(), PAM
module có thể dễ dàng thiết lập một không gian tên riêng cho người dùng khi đăng nhập.
Cần có các thư mục được thể hiện bằng nhiều cách để chứng nhận Tiêu chí chung
Tuy nhiên, với Hồ sơ bảo vệ hệ thống được gắn nhãn, với tính khả dụng
về tính năng cây chia sẻ trong nhân Linux, ngay cả các hệ thống Linux thông thường
có thể hưởng lợi từ việc thiết lập không gian tên riêng khi đăng nhập và
polyinstantiating/tmp,/var/tmp và các thư mục khác được coi là
phù hợp bởi người quản trị hệ thống.
2.2 ngừng chia sẻ bộ nhớ ảo và/hoặc mở tệp¶
Hãy xem xét một ứng dụng máy khách/máy chủ nơi máy chủ đang xử lý
yêu cầu của khách hàng bằng cách tạo ra các quy trình chia sẻ tài nguyên như
bộ nhớ ảo và mở tập tin. Nếu không có tính năng hủy chia sẻ(), máy chủ phải
quyết định những gì cần được chia sẻ tại thời điểm tạo quy trình
dịch vụ nào theo yêu cầu. unshare() cho phép máy chủ có khả năng
tách rời các phần của bối cảnh trong quá trình phục vụ của
yêu cầu. Đối với các khung ứng dụng phần mềm trung gian lớn và phức tạp, điều này
khả năng hủy chia sẻ() sau khi quá trình được tạo có thể rất
hữu ích.
3) Chi phí¶
Để không trùng lặp mã và xử lý thực tế là unshare()
hoạt động trên một tác vụ đang hoạt động (ngược lại với việc sao chép/phân nhánh làm việc trên một tác vụ mới
nhiệm vụ không hoạt động được phân bổ) unshare() đã phải thực hiện một cuộc tổ chức lại nhỏ
các thay đổi đối với các hàm copy_* được sử dụng bởi lệnh gọi hệ thống sao chép/ngã ba.
Có một chi phí liên quan đến việc thay đổi hiện có, được thử nghiệm tốt và
mã ổn định để triển khai một tính năng mới có thể không được thực hiện
rộng rãi vào thời gian đầu. Tuy nhiên, với thiết kế và mã phù hợp
xem xét các thay đổi và tạo thử nghiệm không chia sẻ() cho LTP
lợi ích của tính năng mới này có thể vượt quá chi phí của nó.
4) Yêu cầu¶
unshare() đảo ngược việc chia sẻ đã được thực hiện bằng lệnh gọi hệ thống clone(2),
vì vậy unshare() sẽ có giao diện tương tự như clone(2). Đó là,
vì các cờ trong clone(int flags, void *stack) chỉ định những gì nên
được chia sẻ, các cờ tương tự trong unshare(int flags) phải chỉ định
những gì không nên chia sẻ. Thật không may, điều này có thể đảo ngược
ý nghĩa của các cờ theo cách chúng được sử dụng trong bản sao (2).
Tuy nhiên, không có giải pháp dễ dàng nào mà ít gây nhầm lẫn hơn và
cho phép không chia sẻ bối cảnh gia tăng trong tương lai mà không cần thay đổi ABI.
Giao diện unshare() sẽ phù hợp với khả năng bổ sung trong tương lai của
cờ ngữ cảnh mới mà không yêu cầu xây dựng lại các ứng dụng cũ.
Nếu và khi các cờ ngữ cảnh mới được thêm vào, thiết kế unshare() sẽ cho phép
tăng dần việc ngừng chia sẻ các tài nguyên đó trên cơ sở cần thiết.
5) Đặc tả chức năng¶
- NAME
hủy chia sẻ - tách các phần của bối cảnh thực thi quy trình
- SYNOPSIS
#include <lịch trình.h>
int không chia sẻ(int flag);
- DESCRIPTION
unshare()cho phép một tiến trình tách rời các phần thực thi của nó bối cảnh hiện đang được chia sẻ với các quy trình khác. phần bối cảnh thực thi, chẳng hạn như không gian tên, được chia sẻ theo mặc định khi một quy trình mới được tạo bằng fork(2), trong khi các phần khác, chẳng hạn như bộ nhớ ảo, bộ mô tả tệp đang mở, v.v., có thể được chia sẻ theo yêu cầu rõ ràng để chia sẻ chúng khi tạo một quy trình sử dụng bản sao (2).- Công dụng chính của unshare() là cho phép một tiến trình kiểm soát nó
bối cảnh thực thi được chia sẻ mà không tạo ra một quy trình mới.
- Đối số flags chỉ định một hoặc bitwise-or’ed của một số
các hằng số sau.
- CLONE_FS
Nếu CLONE_FS được đặt, thông tin hệ thống tệp của người gọi được tách khỏi thông tin hệ thống tệp được chia sẻ.
- CLONE_FILES
Nếu CLONE_FILES được đặt, bảng mô tả tệp của người gọi bị tách khỏi bộ mô tả tệp được chia sẻ cái bàn.
- CLONE_NEWNS
Nếu CLONE_NEWNS được đặt, không gian tên của người gọi là tách khỏi không gian tên được chia sẻ.
- CLONE_VM
Nếu CLONE_VM được đặt, bộ nhớ ảo của người gọi sẽ tách khỏi bộ nhớ ảo được chia sẻ.
- RETURN VALUE
Khi thành công, số không trở lại. Khi thất bại, -1 được trả về và errno là
- ERRORS
- EPERM CLONE_NEWNS được chỉ định bởi một quy trình không phải root (quy trình
không có CAP_SYS_ADMIN).
- ENOMEM Không thể phân bổ đủ bộ nhớ để sao chép các phần của người gọi
bối cảnh cần được chia sẻ.
EINVAL Cờ không hợp lệ được chỉ định làm đối số.
- CONFORMING ĐẾN
Lệnh gọi
unshare()dành riêng cho Linux và không nên được sử dụng trong các chương trình có thể mang theo được.- SEE ALSO
bản sao(2), ngã ba(2)
6) Thiết kế cấp cao¶
Tùy thuộc vào đối số flags, lệnh gọi hệ thống unshare() sẽ phân bổ
cấu trúc bối cảnh quy trình thích hợp, điền vào đó các giá trị từ
phiên bản chia sẻ hiện tại, liên kết các cấu trúc mới được sao chép
với cấu trúc tác vụ hiện tại và các bản phát hành được chia sẻ tương ứng
các phiên bản. Không thể sử dụng các chức năng trợ giúp của bản sao (copy_*)
trực tiếp bằng unshare() vì hai lý do sau.
- bản sao hoạt động trên một nhiệm vụ mới được phân bổ chưa hoạt động
cấu trúc, trong đó
unshare()hoạt động trên hoạt động hiện tại nhiệm vụ. Do đó,unshare()phải thực hiệntask_lock()thích hợp trước khi liên kết các cấu trúc ngữ cảnh mới được sao chép
- unshare() phải phân bổ và sao chép tất cả cấu trúc ngữ cảnh
đang không được chia sẻ, trước khi liên kết chúng với nhiệm vụ hiện tại và giải phóng các cấu trúc chia sẻ cũ hơn. Thất bại làm như vậy sẽ tạo ra các điều kiện cạnh tranh và/hoặc rất tiếc khi cố gắng để quay trở lại do một lỗi. Hãy xem xét trường hợp không chia sẻ cả bộ nhớ ảo và không gian tên. Sau khi hủy chia sẻ thành công vm, nếu lệnh gọi hệ thống gặp lỗi khi cấp phát cấu trúc không gian tên mới, mã trả về lỗi sẽ phải đảo ngược việc không chia sẻ của vm. Là một phần của sự đảo ngược cuộc gọi hệ thống sẽ phải quay lại phiên bản cũ hơn, chia sẻ, vm cấu trúc có thể không còn tồn tại nữa.
Do đó, mã từ các hàm copy_* được phân bổ và sao chép
cấu trúc ngữ cảnh hiện tại đã được chuyển sang các hàm dup_* mới. Bây giờ,
Hàm copy_* gọi hàm dup_* để phân bổ và sao chép
cấu trúc ngữ cảnh thích hợp và sau đó liên kết chúng với
cấu trúc nhiệm vụ đang được xây dựng. cuộc gọi hệ thống unshare() được bật
mặt khác thực hiện như sau:
Kiểm tra các cờ để buộc các cờ bị thiếu, nhưng ngụ ý
- Đối với mỗi cấu trúc ngữ cảnh, hãy gọi hàm unshare() tương ứng
chức năng trợ giúp để phân bổ và sao chép một bối cảnh mới cấu trúc, nếu bit thích hợp được đặt trong đối số cờ.
- Nếu không có lỗi trong việc phân bổ và sao chép và có
là các cấu trúc ngữ cảnh mới sau đó khóa cấu trúc tác vụ hiện tại, liên kết cấu trúc ngữ cảnh mới với cấu trúc nhiệm vụ hiện tại, và giải phóng khóa trên cấu trúc nhiệm vụ hiện tại.
Phát hành một cách thích hợp các cấu trúc ngữ cảnh, chia sẻ, cũ hơn.
7) Thiết kế cấp thấp¶
Việc thực hiện unshare() có thể được nhóm lại thành 4 nhóm khác nhau sau đây:
các mục:
Tổ chức lại các hàm copy_* hiện có
chức năng dịch vụ cuộc gọi hệ thống
unshare()các hàm trợ giúp
unshare()cho từng bối cảnh quy trình khác nhauĐăng ký số cuộc gọi hệ thống cho các kiến trúc khác nhau
7.1) Tổ chức lại hàm copy_*¶
Mỗi chức năng sao chép như copy_mm, copy_namespace, copy_files, v.v., có khoảng hai thành phần. Thành phần đầu tiên được phân bổ và nhân đôi cấu trúc thích hợp và thành phần thứ hai liên kết nó với cấu trúc tác vụ được truyền vào dưới dạng đối số cho bản sao chức năng. Thành phần đầu tiên được chia thành chức năng riêng của nó. Các hàm dup_* này được phân bổ và nhân đôi cấu trúc ngữ cảnh. Các hàm copy_* được sắp xếp lại được gọi các hàm dup_* tương ứng của chúng và sau đó liên kết các hàm mới cấu trúc trùng lặp với cấu trúc nhiệm vụ mà chức năng sao chép đã được gọi.
7.4) Cuối cùng¶
Sửa đổi mã cụ thể của kiến trúc một cách thích hợp để đăng ký cuộc gọi hệ thống mới.
8) Đặc điểm kỹ thuật kiểm tra¶
Việc kiểm tra unshare() sẽ kiểm tra những điều sau:
- Cờ hợp lệ: Kiểm tra để kiểm tra các cờ sao chép tín hiệu và
trình xử lý tín hiệu không được triển khai chưa, trả về -EINVAL.
- Cờ bị thiếu/ngụ ý: Kiểm tra để đảm bảo rằng nếu không chia sẻ
không gian tên mà không chỉ định chính xác việc hủy chia sẻ hệ thống tập tin hủy chia sẻ cả không gian tên và thông tin hệ thống tập tin.
- Đối với mỗi trong số bốn (không gian tên, hệ thống tệp, tệp và vm)
được hỗ trợ hủy chia sẻ, xác minh rằng hệ thống gọi chính xác không chia sẻ cấu trúc thích hợp. Xác minh rằng việc hủy chia sẻ chúng một cách riêng lẻ cũng như kết hợp với từng các công việc khác như mong đợi.
- Thực thi đồng thời: Sử dụng các phân đoạn bộ nhớ dùng chung và futex trên
một địa chỉ trong phân đoạn shm để đồng bộ hóa việc thực thi khoảng 10 thread. Có một vài chủ đề thực thi execve, một vài _exit và phần còn lại không chia sẻ với sự kết hợp khác nhau của những lá cờ. Xác minh rằng việc hủy chia sẻ được thực hiện như mong đợi và rằng không có lỗi hoặc bị treo.
9) Công việc tương lai¶
Việc triển khai unshare() hiện tại không cho phép hủy chia sẻ
tín hiệu và bộ xử lý tín hiệu. Tín hiệu ban đầu rất phức tạp và
để hủy chia sẻ tín hiệu và/hoặc bộ xử lý tín hiệu của một hệ thống hiện đang chạy
quá trình thậm chí còn phức tạp hơn. Nếu trong tương lai có một quyết định cụ thể
cần cho phép không chia sẻ tín hiệu và/hoặc bộ xử lý tín hiệu, nó có thể
được thêm dần vào unshare() mà không ảnh hưởng đến di sản
các ứng dụng sử dụng chức năng unshare().