Tôi đang sử dụng chức năng C sau để tạo nhiều không gian tên mạng từ một quá trình trường hợp duy nhất :Làm thế nào để tạo ra nhiều không gian tên mạng từ một trường hợp quá trình duy nhất
void create_namespace(const char *ns_name)
{
char ns_path[100];
snprintf(ns_path, 100, "%s/%s", "/var/run/netns", ns_name);
close(open(ns_path, O_RDONLY|O_CREAT|O_EXCL, 0));
unshare(CLONE_NEWNET);
mount("/proc/self/ns/net", ns_path, "none", MS_BIND , NULL);
}
Sau khi quá trình của tôi tạo ra tất cả các namspaces và Tôi thêm một giao diện vào bất kỳ không gian tên mạng nào (với lệnh ip link set tap1 netns ns1
), sau đó tôi thực sự thấy giao diện này trong tất cả các không gian tên (có lẽ, đây thực sự là một không gian tên duy nhất nằm dưới các tên khác nhau).
Nhưng, nếu tôi tạo nhiều không gian tên bằng cách sử dụng nhiều quy trình thì mọi thứ đều hoạt động tốt.
Điều gì có thể xảy ra ở đây? Tôi có phải chuyển bất kỳ cờ bổ sung nào cho unshare()
để làm việc này từ một cá thể quá trình không? Có một hạn chế rằng một cá thể quá trình đơn lẻ không thể tạo ra nhiều không gian tên mạng? Hoặc có vấn đề với cuộc gọi mount()
, bởi vì /proc/self/ns/net
thực sự được gắn nhiều lần?
Cập nhật: Dường như unshare()
chức năng tạo ra nhiều không gian tên mạng một cách chính xác, nhưng tất cả các điểm gắn kết trong /var/run/netns/
thực sự tham khảo để không gian tên mạng đầu tiên được gắn trong direcotry đó.
Update2: Dường như cách tốt nhất là dùng fork() một quy trình khác và thực hiện hàm create_namespace() từ đó. Dù sao, tôi sẽ vui mừng khi nghe một giải pháp tốt hơn mà không liên quan đến fork() gọi hoặc ít nhất có được một xác nhận rằng sẽ chứng minh rằng nó là không thể tạo và quản lý nhiều không gian tên mạng từ một quá trình duy nhất.
UPDATE3: tôi có thể tạo ra nhiều không gian tên với không chia sẻ() bằng cách sử dụng đoạn mã sau:
int main() {
create_namespace("a");
system("ip tuntap add mode tap tapa");
system("ifconfig -a");//shows lo and tapA interface
create_namespace("b");
system("ip tuntap add mode tap tapb");
system("ifconfig -a");//show lo and tapB interface, but does not show tapA. So this is second namespace created.
}
Nhưng sau khi quá trình này kết thúc và tôi thực hiện ip netns exec a ifconfig -a
và ip netns exec b ifconfig -a
có vẻ như rằng cả hai lệnh là đột nhiên được thực hiện trong không gian tên a. Vì vậy, vấn đề thực tế là lưu trữ các tham chiếu đến các không gian tên (hoặc gọi mount() đúng cách. Nhưng tôi không chắc chắn, nếu điều này là có thể).
+1, nhưng bạn có thể giải thích ý của mình với "Lưu ý rằng bạn không tạo không gian tên mạng mới với chia sẻ không"? Xem cập nhật # 3, bởi vì sự hiểu biết của tôi là unshare() vẫn có thể tạo không gian tên mạng.Bản sao (CLONE_NEWNET) giống như "Tôi sẽ tạo một tiến trình con mới với một không gian tên mạng mới", trong khi unshare (CLONE_NEWNET) giống như "Tôi không muốn chia sẻ không gian tên mạng với tiến trình cha mẹ của tôi nữa. cái mới. " lxc sử dụng clone(), trong khi iproute2 sử dụng unshare(). –
Tôi sẽ cố gắng giải thích. Bạn tạo một không gian tên mạng cho quá trình _current_ của bạn với * unshare *, nhưng vì không gian tên mạng cần có PID để sống, bạn sẽ không thể tạo một vùng tên mới chỉ với * unshare * cho quá trình _same_. – Coren
Tôi thấy bạn điểm, nhưng unshare() vẫn có thể tạo một không gian tên mạng mới (điều này cần cập nhật cho câu trả lời của bạn). Ngoài ra, tôi đoán, không gian tên không nhất thiết cần một PID thực tế để sống (ví dụ: sau khi thực hiện lệnh "ip netns add nsX", quá trình ip kết thúc, nhưng không gian tên nsX vẫn còn). Tôi đoán giới hạn này "tại sao nó không thể tạo ra nhiều không gian tên mạng từ quá trình duy nhất" đã làm điều gì đó với cách mount() hoạt động. –