1 điểm bởi GN⁺ 2025-04-03 | 1 bình luận | Chia sẻ qua WhatsApp
  • Hỗ trợ Plan 9, khởi đầu như một thông báo Cá tháng Tư, đã dẫn tới các PR thực tế cùng các sửa đổi kernel và Go; tính đến ngày 2/4/2025, Tailscale đã chạy được trên Plan 9
  • Đây không chỉ là vấn đề build đơn giản với GOOS=plan9 GOARCH=386; trước hết, port Plan 9 của Go đã lộ ra các vấn đề crash runtime và xử lý đặc biệt trong compiler
  • Nhờ các sửa đổi của Russ Cox đối với kernel Plan 9 cũng như runtime/compiler của Go, các vấn đề về SSE, ngữ cảnh dấu phẩy động, thời gian đơn điệu, DNS và môi trường phát triển đã được xử lý cùng lúc
  • Tailscale tận dụng giao diện file /net của Plan 9 để gắn thêm triển khai giống TUN, routing, Tailscale SSH, MagicDNS và thu thập dịch vụ, nhưng một số phần vẫn là triển khai tạm hoặc chưa hoàn thiện
  • Phạm vi kiểm chứng hiện chủ yếu là 9legacyGOARCH=386; 9front, amd64, exit node và hỗ trợ net/netns của Go cần được kiểm chứng thêm hoặc thiết kế lại

Trò đùa Cá tháng Tư trở thành một bản port thực sự

  • Tailscale công bố hỗ trợ Plan 9 vào ngày 1/4/2025, và ngày hôm sau đã tiết lộ bối cảnh rằng thông báo này dựa trên một công việc port thực sự đang chạy được
  • Công việc này dẫn tới Tailscale PR cùng nhiều sửa đổi cho Plan 9 và Go
  • Cách tiếp cận ban đầu xuất phát từ kỳ vọng rằng chỉ cần build hai binary Go của Tailscale bằng GOOS=plan9 GOARCH=386 go install ./cmd/tailscale{,d} là được
  • Trong lần thử đầu tiên vào tháng 8/2023, một phần quá trình build đã chạy, nhưng khi thực thi thì xảy ra crash bất thường
    • Port Plan 9 của Go không phải là first-class port, nên các regression bị bỏ mặc
    • Cũng có khả năng Tailscale đã đẩy Go trên Plan 9 đi xa hơn trước đây
  • Việc port bị dừng trong suốt năm 2024, rồi được tiếp tục vào tháng 3/2025 cùng với ý tưởng Cá tháng Tư

SSE và việc hoàn thiện hỗ trợ Plan 9 của Go

  • Tập lệnh SSE, được giới thiệu trên Intel Pentium III năm 1999, là một trong những điểm khởi đầu chính của công việc lần này
  • Compiler Go từng cố tránh dùng SSE khi target Plan 9
    • Lý do là kernel Plan 9 không lưu và khôi phục các thanh ghi SSE trong note handler
    • Compiler Go không thể biết đoạn mã nào sẽ chạy bên trong note handler, nên đã cố vô hiệu hóa SSE trên toàn cục
    • Cách xử lý đặc biệt này thường xuyên bị hỏng, khiến các ngoại lệ plan9 xuất hiện ở nhiều nơi trong compiler
  • Russ Cox đã sửa kernel Plan 9 để xử lý ngữ cảnh dấu phẩy động và SIMD trong note handler
    • Với phía 386, đã có sửa đổi sys/src/9: allow floating point in note handlers
    • Trên kernel amd64 9k, các vấn đề bổ sung được phát hiện như aliasing trạng thái FP sau fork, SIMD trong note handler, và mất thanh ghi khi noted(NCONT)
  • Ở phía Go, việc loại bỏ xử lý đặc biệt khi sinh mã cho Plan 9 đã giúp tailscaled có thể chạy lâu hơn

IPC và môi trường phát triển

  • Sau đó, tailscaled bắt đầu crash vì thiếu bộ nhớ thay vì hỏng stack
  • Trong lần thử port Plan 9 trước đó, gói IPC safesocket của Tailscale có lỗi tạo goroutine vô hạn
  • Vấn đề được giải quyết tạm thời bằng cách chuyển sang dùng localhost TCP
    • Cách này ít phù hợp hơn với mô hình “mọi thứ đều là file” của Plan 9, nhưng đã xác nhận rằng các dịch vụ Plan 9 khác cũng dùng localhost TCP
    • Trong tương lai, có thể tốt hơn nếu đặt LocalAPI lên trên gói srv9p mà Russ đã port sang Go
    • Triển khai hiện tại không thể gắn xác thực localhost như trên các nền tảng khác, nên có ghi rõ là không nên dùng trên máy Plan 9 dùng chung
  • Giai đoạn phát triển ban đầu diễn ra trên VM dựa trên image CD 9legacy, và vòng lặp tải binary qua HTTP rồi chạy khá chậm
  • rsc/plan9 do Russ Cox tạo bao gồm mã nguồn Plan 9, binary biên dịch sẵn và script ./boot/qemu
    • VM qemu boot không cần disk, và dùng repository Git do localhost 9P server cung cấp làm root filesystem
    • Bằng cách chia sẻ filesystem giữa máy phát triển và Plan 9, thời gian lặp giảm từ đơn vị phút xuống đơn vị giây
    • qemu cũng dùng virtio nên nhanh hơn

Tích hợp mạng: TUN, routing, MagicDNS

  • Phiên bản Tailscale chạy được đầu tiên hoạt động ở chế độ networking trong user space, không dùng network stack của kernel
    • TCP, UDP, ICMP, v.v. được xử lý thông qua netstack của gVisor
    • Muốn truy cập tailnet từ máy Plan 9 thì phải dùng proxy HTTP/SOCKS5 của tailscaled
    • Điều này không lý tưởng vì rất ít chương trình Plan 9 nhận biết biến môi trường HTTP_PROXY hoặc ALL_PROXY
  • Triển khai giống TUN của Plan 9 rất đơn giản
    • Mở /net/ipifc/clone và đọc số interface mới
    • Ghi "bind pkt\n" vào control fd sẽ tạo một interface mới như /net/ipifc/2/*
    • Mở /net/ipifc/2/data để đọc và ghi trực tiếp các gói IP
    • Không cần ioctl riêng hay framing độ dài
  • Việc thao tác routing table cũng được thực hiện qua file /net/iproute
    • Ghi "tag tail\n" để gắn tag tail cho các route được thêm sau đó
    • Thêm route bằng các thông điệp như "add 100.64.0.0 /106 100.102.103.104"
    • Vì nội bộ Plan 9 lấy IPv6 làm trung tâm và xử lý IPv4 như địa chỉ IPv4-mapped IPv6, nên CGNAT 100.64.0.0/10 được biểu diễn như /106
  • MagicDNS là công việc cho phép truy cập peer trên Plan 9 bằng các tên như foo hoặc foo.tailnet-name.ts.net
    • Cũng đã có thảo luận về phương án chặn các truy vấn /net/dns hoặc /net/cs
    • Cuối cùng, Russ đã sửa Plan 9 để có thể chỉ định DNS server thay thế cho một DNS suffix cụ thể
    • Vấn đề truy vấn DNS bị negative cache sai cũng đã được sửa

Tailscale SSH và thu thập dịch vụ

  • Tailscale SSH là SSH server tích hợp trong tailscaled, xác thực bằng Tailscale identity đã biết thông qua khóa WireGuard gắn với gói tin
  • Ban đầu, shell /bin/rc của Plan 9 được chạy bằng os/exec.Command và nối stdin/stdout
    • Shell đã chạy, nhưng echo, điều hướng và interrupt tiến trình không hoạt động đúng
  • Russ đã thêm ví dụ netshell vào 9fans/go
    • Ví dụ này gần giống một telnet server rất không an toàn, nhưng đủ để gắn phía sau Tailscale SSH
    • Sau đó, việc lấy nội dung /dev/snarf của Plan 9 qua SSH, hoặc cross-compile test Go trên laptop rồi chạy qua SSH trở nên dễ dàng hơn
  • Tính năng tùy chọn thu thập dịch vụ của Tailscale cũng được xem xét để phù hợp với Plan 9
    • Duyệt /proc/NNN/fd để tìm tiến trình đã mở /net/tcp/clone
    • Khớp QID của fd với /net/tcp/NNN/{status,local} để xác nhận trạng thái listening và port
    • Cách tính số TCP từ QID dễ bị ảnh hưởng khi implementation kernel thay đổi, nên vẫn là điểm chưa thỏa đáng

Thời gian, demo web, v86

  • Có trường hợp tailscaled bị crash do gVisor netstack báo rằng thời gian đơn điệu (monotonic time) đã đi lùi
    • Implementation thời gian của Go trên Plan 9 đang dùng wall time làm thời gian đơn điệu
    • Khi ntpd chỉnh đồng hồ lùi lại, giả định về thời gian đơn điệu của netstack bị phá vỡ
  • Russ đã thêm thời gian đơn điệu vào /dev/bintime của Plan 9 và sửa để Go sử dụng nó
  • Để chạy Plan 9 trên web, v86 được sử dụng
    • v86 chạy hệ điều hành 32-bit bằng WASM và cung cấp nhiều phương thức mạng
    • Đây cũng là một trong những lý do tập trung vào GOARCH=386
  • Ban đầu, để gửi frame Ethernet qua websocket relay, hỗ trợ giao thức wsproxy đã được thêm vào môi trường mô phỏng mạng của Tailscale
    • Nó chạy trong môi trường test tích hợp mô phỏng ARP, DHCP, DNS, NAT, control plane, DERP, v.v. bằng gVisor netstack
    • Tuy nhiên, do các lượt đi-về của DHCP, nếu relay ở xa thì quá trình khởi động rio, GUI của Plan 9, bị chậm
  • Sau đó, WISP server cũng được triển khai, nhưng do thiếu thời gian trước khi đưa vào production nên bản phát hành dùng cấu hình network relay mặc định của copy.sh/v86
  • Disk image chứa Tailscale và Plan 9 có dung lượng 16MB, còn binary Tailscale sau khi giải nén là 23MB
    • Đây là lý do khi boot có thể thấy bước “gunzip…”
    • Image ví dụ được đưa vào profile 9legacy của copy.sh/v86

Việc còn lại và kết quả thực tế

1 bình luận

 
GN⁺ 2025-04-03
Các ý kiến trên Hacker News
  • Nếu có gì thắc mắc thì tôi có thể trả lời
    Hiện có vài người đang bàn về chuyện này tại https://meet.google.com/qre-gydb-mkv
    Chỉnh sửa: sau một giờ thì mọi người đã rời đi
    Bài blog ngày 1 tháng 4 trước đó là https://tailscale.com/blog/tailscale-enterprise-plan-9-suppo...

    • Tôi chưa từng thiết lập hệ thống Plan 9 lần nào; dùng cái này có cho phép giao tiếp hệ thống phân tán đi qua Tailnet của tôi không?
  • Việc Russ Cox theo đuổi trò đùa này đến cùng đúng là huyền thoại

    • Ước gì ai đó thuyết phục Russ rằng đưa một trình duyệt web đầy đủ vào Plan 9 sẽ cực kỳ buồn cười
  • Trên danh sách 9fans có một bài như thế này cho ngày Cá tháng Tư
    Nội dung nói rằng chi phí bảo trì các kiến trúc máy tính chưa trưởng thành như mips, 386, arm, arm64, amd64 là quá lớn, nên họ quyết định tập trung vào các kiến trúc trưởng thành và ổn định hơn
    Các kiến trúc đó là power64 và itanium, vì vậy mọi kiến trúc ngoài power64 và itanium sẽ bị đóng băng, lưu giữ và được thăng cấp lên trạng thái hết vòng đời

  • Không đùa đâu, tôi thật sự ước có một phiên bản Plan 9 cho doanh nghiệp
    Dạo này phần lớn script tôi viết bằng rc; vì chúng tôi dùng nix và có thể tự động kéo vào bằng dirnev nên đồng nghiệp vẫn bỏ qua cho, và nó khá tốt

    • Tôi nghĩ họ sẽ lo về việc người khác có thể đọc và sửa các script rc đó hơn là việc có chạy được chúng hay không
    • Một ưu điểm của rc là thế này[1]:
      “Nguyên tắc quan trọng nhất trong thiết kế rc là nó không phải là bộ xử lý macro. Đầu vào không bao giờ bị quét quá một lần bởi mã phân tích từ vựng và cú pháp”
      Ở một công ty Unix trước đây tôi từng làm, một shell script đang chạy bị sửa, khiến phần lớn đĩa làm việc bị xóa. May là chúng tôi có bản sao lưu hằng ngày trên băng từ; chuyện đó khoảng 17 năm trước
      [1] https://www.scs.stanford.edu/nyu/04fa/sched/readings/rc.pdf
    • Bạn có thể giải thích cụ thể hơn bạn kỳ vọng gì ở “Plan 9 cho doanh nghiệp” không?
  • Nếu bạn bỏ lỡ bài đầu tiên và chỉ muốn tự thử, nó chạy được trong ảnh v86 này:
    https://copy.sh/v86/?profile=custom&m=768&vram=16&hda.url=ht...
    Trong VM, bạn có thể khởi động tailscaledtailscale. Do khả năng proxy khá hạn chế nên có thể mất một lúc mới vào trạng thái online
    Chỉnh sửa: alt đóng vai trò nút thứ ba. Để mở terminal, giữ alt rồi nhấp chuột phải, chọn new, thả alt rồi kéo bằng nhấp chuột phải để chỉnh kích thước cửa sổ terminal

  • Webinar đang diễn ra (Google Meet) https://ftp.plan9.ts.net/webinar

    • Cho những ai có thể quan tâm: vừa kết thúc rồi
  • Tôi thích tiền đề của trò đùa, nhưng càng giải thích dài thì bỗng thấy chán nản
    Có quá nhiều thứ hỏng và độ phức tạp cũng quá lớn. Rốt cuộc để làm gì, chỉ để tạo một đường hầm mạng? Nếu chính phần việc bổ sung này là trò đùa thì chắc đã buồn cười hơn

    • Để làm phần mới thì cần một chút việc ở phía Plan 9, nhưng phần triển khai Tailscale thực tế lại ít việc hơn nhiều so với các Unix khác
    • Nghe như nhờ việc này mà trình biên dịch Go cũng tốt hơn. Vì phần xử lý đặc thù cho Plan 9 trong mã đã giảm đi
  • Tôi nghĩ mình có thể giữ rsc, rob pike và bradfitz lại nói chuyện hàng giờ, đặc biệt là về Plan 9. Tất nhiên như vậy sẽ hoàn toàn làm lãng phí thời gian của họ
    Hệ điều hành đó thật sự mê hoặc
    Tôi nhớ hồi đầu sự nghiệp, một chuyên gia làm cùng ngồi cạnh, kiên nhẫn chỉ cho tôi cách làm và trả lời câu hỏi cho đến khi tôi hiểu đủ. Kiểu như giúp bạn có thể bơi được dù bị ném xuống nước sâu; chỉ trong ba giờ, đó là một trong những lần tôi trưởng thành nhanh nhất trong sự nghiệp, như thể nhận được cả một bằng cử nhân về một mảng kiến thức cụ thể
    Tôi không biết C, cũng không hiểu Plan 9 đủ để dùng hiệu quả, nhưng có những tính năng tuyệt vời và hữu ích mà tôi muốn biết và học thêm, dù chỉ để tiếc rằng ba hệ điều hành chính hiện nay không có chúng
    Nếu có tiền, tôi muốn mua thời gian nói chuyện trực tiếp với cả ba người để mở rộng kiến thức về Go, và cũng muốn mua thời gian của rsc và rob pike để có được sự hiểu biết về Plan 9 mà tôi luôn muốn nhưng chưa tự đạt được

  • Tôi thật sự thích Plan 9. Lấy nhiều nguyên tắc của nó để làm hệ điều hành của riêng mình là dự án khi nghỉ hưu và mục tiêu đời tôi
    Chỉnh sửa: tôi đã giữ sẵn tên “chaos10” cho dự án này. Vì nó sẽ chẳng có kế hoạch gì, giống SerenityOS

  • Tôi hoàn toàn không ngờ họ lại vá cả kernel Plan 9 để làm cho thứ này chạy được

    • Sao lại không? Rõ ràng chưa ai từng nghiêm túc làm chuyện như thế này, nên khối lượng phần còn thiếu có vẻ tương đối ít :)