2 điểm bởi GN⁺ 2025-04-07 | 1 bình luận | Chia sẻ qua WhatsApp
  • Trong bối cảnh công cụ đồng bộ tệp tích hợp sẵn trên macOS vẫn dựa trên nền tảng từ năm 2006, Apple đã thay rsync 2.6.9 bằng openrsync
  • rsync cũ trên macOS vẫn nhận các bản sửa cần thiết cho vấn đề bảo mật và các vấn đề khác, nhưng không bao gồm các tính năng rsync 3.x sau phiên bản 2.6.9
  • Bối cảnh cốt lõi của việc chuyển đổi là khác biệt về giấy phép: rsync 2.x được phát hành theo GPLv2, còn rsync 3.x theo GPLv3
  • openrsync tương thích với rsync nhưng chỉ hỗ trợ một phần các tham số dòng lệnh, nên các script hiện có có thể không chạy nguyên trạng trên Sequoia
  • Tính đến macOS 15.4, /usr/bin/rsync được liên kết tới openrsync, vì vậy quản trị viên Mac cần kiểm tra các tùy chọn được hỗ trợ và khả năng tương thích của các tự động hóa hiện có

rsync 2.6.9 đã tồn tại lâu trên macOS

  • rsync là công cụ dòng lệnh dùng để truyền và đồng bộ tệp trên các hệ điều hành họ Unix
    • Có thể dùng giữa các thiết bị lưu trữ được kết nối trực tiếp với cùng một máy tính
    • Cũng có thể dùng để đồng bộ tệp với máy tính khác trên mạng
  • macOS đã tích hợp rsync trong thời gian dài, nhưng phiên bản Apple cung cấp là rsync 2.6.9, phiên bản cuối cùng của rsync 2.x
  • rsync 2.6.9 được phát hành vào tháng 11 năm 2006, và ngay cả sau khi rsync 3.x ra mắt, Apple vẫn không nâng rsync trong macOS lên các phiên bản sau đó
  • Apple vẫn cập nhật rsync 2.6.9 đi kèm macOS khi cần để xử lý vấn đề bảo mật và các vấn đề khác
  • Tuy nhiên, trước macOS Sequoia, rsync của Apple gần như dựa trên một nền tảng đã 20 năm tuổi và không bao gồm các tính năng mới được thêm vào những phiên bản rsync sau 2.6.9

Sự trì trệ phiên bản do GPLv2 và GPLv3

  • rsync 2.x và 3.x được phát hành theo các phiên bản giấy phép GPL khác nhau
  • Apple cho rằng họ có thể tuân thủ các điều khoản GPLv2 của rsync 2.x, nhưng không thể tuân thủ các điều khoản GPLv3 của rsync 3.x
  • Vì lý do này, macOS đã không cung cấp rsync 3.x

Việc chuyển sang openrsync trên macOS Sequoia

  • Trong macOS Sequoia, Apple đã thay rsync 2.6.9 bằng openrsync
  • openrsync là một triển khai rsync không sử dụng giấy phép GPL
  • openrsync được phát hành theo ISC license, một trong các giấy phép thuộc họ BSD
  • ISC license là giấy phép cho phép (permissive license), đặt ra rất ít hạn chế đối với việc sử dụng, sửa đổi và phân phối phần mềm được áp dụng
  • Apple cho rằng, khác với các điều khoản GPLv3 của rsync 3.x, họ có thể tuân thủ các điều khoản giấy phép của openrsync

Khác biệt tương thích quan trọng với quản trị viên Mac

  • Trong tương lai, Apple có thể cung cấp các phiên bản cập nhật của openrsync mà không phải lo về vấn đề tuân thủ GPL của rsync
  • Thay đổi thực tế lớn hơn là dù openrsync tương thích với rsync, nó chỉ cho phép một phần các tham số dòng lệnh của rsync
  • Các tính năng rsync từng hoạt động trên macOS cũ có thể thất bại trên macOS Sequoia
    • Vì tính năng đó có thể không có trong công cụ dòng lệnh openrsync đi kèm Sequoia
  • Có thể kiểm tra các tính năng được hỗ trợ trong openrsync của macOS Sequoia tại trang hướng dẫn openrsync

Cách kiểm tra trên macOS 15.4

  • Tính đến macOS 15.4, công cụ openrsync được liên kết tới /usr/bin/rsync
  • Người dùng có thể chạy openrsync giống như trước đây chạy công cụ dòng lệnh rsync
  • Kiểm tra thông tin phiên bản openrsync bằng lệnh sau
/usr/bin/rsync --version
  • Kết quả đầu ra sẽ tương tự như sau
username@computername ~ % /usr/bin/rsync --version
openrsync: protocol version 29
rsync version 2.6.9 compatible
username@computername ~ %
  • Kết quả hiển thị protocol version 29rsync version 2.6.9 compatible

1 bình luận

 
GN⁺ 2025-04-07
Ý kiến trên Hacker News
  • Tài liệu của openrsync quá sơ sài, nên không tạo được niềm tin rằng nó có thể thay thế rsync
    Với một chương trình sao chép tệp, nó phải có khả năng tạo ra bản sao hoàn chỉnh không làm mất dù chỉ một bit dữ liệu và metadata của bản gốc; nếu không thì xem như không dùng được
    Nhiều công cụ sao chép/lưu trữ thuộc họ Unix không tạo bản sao hoàn chỉnh với tùy chọn mặc định, và có công cụ dù dùng tùy chọn nào cũng không làm được
    Ít nhất cho đến vài năm trước, scp cũng khó tạo bản sao hoàn chỉnh khi hệ điều hành hoặc hệ thống tệp khác nhau, nên tôi không dùng, mà chỉ dùng rsync qua ssh
    rsync là một trong số ít công cụ, nếu truyền tùy chọn phù hợp, có thể bảo toàn cả extended attributes, ACL và timestamp độ chính xác cao ngay cả giữa các hệ điều hành/hệ thống tệp khác nhau như FreeBSD UFS và Linux XFS
    Tài liệu của openrsync không đảm bảo kiểu sao chép hoàn chỉnh như vậy, nên hiện tại tôi giả định là nó không làm được và đánh giá là vô dụng
    Về phía lưu trữ, trên Linux, khi bsdtar dùng định dạng pax thì có thể lưu gần như đầy đủ một bản sao tệp hoàn chỉnh, còn các định dạng tar/cpio cũ không chứa được metadata hiện đại
    Thường ngày tôi đặt alias cho rsync là /usr/bin/rsync --archive --xattrs --acls --hard-links --progress --rsh="ssh -p XXX -l YYYYYYY"
    cp của coreutils cũng có thể sao chép hoàn chỉnh nếu có đúng tùy chọn CLI và tùy chọn biên dịch, nhưng một số bản phân phối build mà không hỗ trợ extended attributes, nên chỉ sao chép một phần mà không có cảnh báo hay lỗi

    • Từng làm ở công ty backup, tôi thấy hầu hết khách hàng doanh nghiệp lớn không quá quan tâm liệu 99% metadata có được khôi phục chính xác hay không; miễn dữ liệu được khôi phục là họ thấy ổn
      Chúng tôi khôi phục mọi thứ rất cẩn thận, nhưng đôi khi có cảm giác chỉ có chúng tôi mới để tâm đến việc đó
    • Đây có thể chỉ là khác biệt về phong cách tài liệu
      Về cơ bản, tôi sẽ nghĩ openrsync là rsync với ít ràng buộc giấy phép hơn, chứ không cho rằng nó hoạt động khác
      README của openrsync nói nó tương thích với rsync và bảo xem tài liệu rsync
      Nếu extended attributes, ACL và timestamp độ phân giải cao không phải là tính năng tùy chọn ở cấp giao thức, thì để tuyên bố tương thích, chẳng phải nó phải hỗ trợ toàn bộ những gì rsync hiện đại hỗ trợ sao?
      Nếu không thì tôi thắc mắc liệu có phải nó chấp nhận toàn bộ giao thức nhưng cứ thế bỏ qua những thứ như ACL hay không
    • OpenRsync đến từ dự án OpenBSD, nên thường khiến người ta kỳ vọng về chất lượng và mức độ tập trung vào bảo mật
      Tuy nhiên, ngay cả website chính thức cũng ghi “We are still working on it... so please wait.”
    • Với Apple thì đây là vấn đề giấy phép, và sẽ có ít người dùng để tâm đến khác biệt này
      Những người dùng như vậy chỉ cần tự cài rsync là được
    • Có thể tìm thấy danh sách tham số mà openrsync chấp nhận trong mã nguồn
      --xattrs, --acls, --hard-links mà tôi dùng trong alias đều không có
      [0]https://github.com/kristapsdz/openrsync/blob/a257c0f495af2b5...
  • Là một người dùng Linux tương đối mới, mình thấy việc quản lý phiên bản của các tiện ích hệ thống đi kèm khá là lộn xộn
    Ví dụ tiêu biểu là unzip: unzip đi kèm trên máy chủ Debian và máy chủ Ubuntu cũ không xử lý được file ZIP mã hóa bằng AES-256, nhưng xem trên Stack Overflow thì có vẻ một số bản phân phối đã cập nhật để hỗ trợ việc này
    Vấn đề là rất khó tìm được bản unzip đã cập nhật; tất cả đều tự nhận là “version 6.00” nhưng hành vi thực tế lại khác nhau, và ngay cả khi tìm được thì cũng không biết thay thế bản đi kèm hệ thống có an toàn hay không
    Kết cục là dù ai đó đã thêm một tính năng hay vào một tiện ích được dùng rộng rãi, mình vẫn không dùng được; vì nó là tiện ích hệ thống cốt lõi nên cảm giác còn khó cập nhật hơn cả công cụ bên thứ ba
    Windows hay macOS có thể cũng tương tự hoặc tệ hơn về mặt tiện ích hệ thống, nhưng mình từng nghĩ Linux sẽ xử lý những chuyện này tốt hơn

    • Trong trường hợp này, nên dùng 7z thay cho unzip
      Mình gần như không nhớ đã từng dùng unzip trên Linux khi xử lý ZIP hay file nén nói chung
      Theo triết lý Unix, việc nối các công cụ đơn giản làm tốt một việc bằng pipe — như gói bằng tar, nén bằng gzip rồi mã hóa bằng pgp — cũng là một luồng tự nhiên
      Về chuyện phiên bản, mình không chắc vì sao cả Debian/Ubuntu đều ghi là 6.00, nhưng đây không phải điều phổ biến
      Nếu là máy cá nhân thì các bản phân phối rolling release như Arch hay Manjaro sẽ bám sát phiên bản upstream đều đặn hơn, nhưng đổi lại gánh nặng bảo trì và kỳ vọng phải tự quản lý sẽ lớn hơn
      Điều khó chịu hơn trong quản lý phiên bản Linux/mã nguồn mở là các thư viện trì hoãn việc tuyên bố v1.00 quá mức
      Dù đã được cắm sâu trong hệ sinh thái, ổn định và gần như hoàn thiện về tính năng, chúng vẫn ở v0.2 hay v0.68 suốt nhiều năm, gây bối rối cho người mới
    • Debian và Ubuntu có xu hướng buộc phiên bản công cụ hệ thống vào phiên bản phát hành của hệ điều hành
      Debian có chu kỳ phát hành dài nhưng rất ổn định, và trong stable thì mọi thứ khớp với nhau rất tốt
      Ubuntu về cơ bản giống như Debian cộng thêm ý tưởng “hay là phát hành thường xuyên hơn?”
      Nếu muốn công cụ mới nhất, bạn phải chấp nhận các lựa chọn có thể kém ổn định hơn như Nix hoặc Arch, mà cả hai đều không quá thân thiện
      Nếu muốn cả độ ổn định lẫn công cụ mới, Gentoo là một cách, nhưng còn nặng gánh hơn Arch
      Nếu muốn ổn định và đơn giản, có thể hy sinh dung lượng đĩa để dùng các cách như Docker/podman, flatpak, appcontainers, snap
      Windows và Mac cũng có vấn đề tương tự; Windows đã giải quyết bằng cách mang kèm các thư viện cũ và liên kết động tùy theo ứng dụng đang chạy
    • unzipmột trường hợp đặc biệt
      Phát triển upstream gần như đã dừng, và bản phát hành cuối cùng là 6.0 từ năm 2009
      Sau đó, nhiều vấn đề được phát hiện và tính năng cũng dần thiếu hụt, nên từng bản phân phối đã chất thêm rất nhiều bản vá lên bản phát hành đó; kết quả là xuất hiện các file thực thi rất khác nhau nhưng có cùng số phiên bản
      [0]: https://infozip.sourceforge.net/UnZip.html
      [1]: Nhìn vào công thức build của Arch có thể thấy số lượng bản vá được áp dụng: https://gitlab.archlinux.org/archlinux/packaging/packages/un...
    • Các bản phân phối là những dự án độc lập, nên những khác biệt như vậy là điều có thể dự đoán
      Một mức độ tương tác lẫn nhau nào đó là tốt, nhưng việc có nhiều lựa chọn đa dạng cũng là ưu điểm
      Hầu hết kho phần mềm của các bản phân phối đều có bsdtar, nên cũng đáng thử dùng thay thế; tùy bản phân phối, tên gói có thể là libarchive
      Chỉ cần bsdtar xf path/to/file là có thể giải nén gần như mọi định dạng, và cũng hỗ trợ AES của ZIP
      macOS có sẵn theo mặc định, và Windows có lẽ cũng có sẵn
    • Đúng là lộn xộn, và tốt nhất là ít phụ thuộc vào công cụ tích hợp sẵn nhất có thể
      Với mỗi việc cần làm, hãy tạo một kho git và flake.nix, rồi để direnv kích hoạt môi trường được khai báo trong flake khi vào thư mục đó
      Nếu viết script dùng grep, hãy đưa script vào kho và thêm cả pkgs.gnugrep vào flake.nix
      Như vậy phiên bản được dùng không phải phiên bản hệ thống mà là phiên bản đã khai báo; khi chuyển từ macOS sang Linux hay WSL, bạn vẫn gọi cùng một phiên bản grep
      Nix thường bị đánh giá là không thân thiện với người mới nên mình hơi dè dặt khi khuyến nghị nguyên xi, nhưng ý chính là phải khai báo phụ thuộc theo một cách nào đó và chỉ dùng các phụ thuộc đã khai báo
      Docker cũng làm được, và các hệ sinh thái ngôn ngữ như Python/Node.js/Go/Rust cũng cung cấp cách đóng gói và gọi phụ thuộc
      Làm vậy thì các lần cập nhật phụ thuộc sẽ được lưu thành commit, và khi có gì đó hỏng, bạn có thể quay lại commit trước
      Những kho như vậy không nhất thiết phải là dự án phần mềm; chúng cũng có thể chỉ là “bộ công cụ cần thiết khi làm XYZ”
  • Việc openrsync không hỗ trợ một số tính năng của rsync hơi phiền
    Dù vậy, việc giờ đây đã có nhiều triển khai độc lập của rsync là điều tốt
    Vì điều đó có nghĩa rsync đang được đối xử không chỉ như một phần mềm đơn thuần, mà như một giao thức thực sự

    • Điểm này rất đáng kỳ vọng
      Nếu tiến gần hơn tới một giao thức, có lẽ sẽ xuất hiện một điểm API diff nhị phân dựa trên thuật toán rsync
      Một sự thật thú vị là Dropbox từng dùng diff nhị phân rsync nội bộ để tải lên nhanh các thay đổi nhỏ trong những tệp lớn
      Tôi đoán hiện nay họ vẫn làm vậy, nhưng endpoint API công khai không có tính năng này, nên chỉ cần một thay đổi nhỏ trong tệp lớn cũng phải tải lại toàn bộ tệp
    • Xem http://github.com/stapelberg/rsync-over-grpc/ sẽ thấy một ví dụ dùng giao thức rsync, chính xác hơn là triển khai https://github.com/gokrazy/rsync trên gRPC
      Khá hữu ích trong môi trường doanh nghiệp khi SSH+rsync bị chặn nhưng việc dựng dịch vụ gRPC lại được cho phép
    • Trên website có ghi “We are still working on it... so please wait.”
      rsync có rất nhiều tính năng, nên chắc chắn sẽ mất khá nhiều thời gian
    • Cũng có librsync
    • Tôi thắc mắc tại sao điều này lại có nghĩa rsync là một giao thức
  • Trong bản vá mainline của rsync, hỗ trợ thuộc tính mở rộng đã được thêm vào để hỗ trợ metadata của macOS
    “Carbon Copy Cloner” của Bombich là một ứng dụng GUI bọc quanh nó
    https://support.bombich.com/hc/en-us/articles/20686446501143...
    Tôi biết đến Mike Bombich qua một bài đăng trên bảng tin dành cho quản trị viên hệ thống macOS Server, và cũng có tài liệu liên quan
    https://web.archive.org/web/20140707182312/http://static.afp...
    Nathaniel Gray đã tạo Backup Bouncer, công cụ kiểm chứng độ trung thực của bản sao lưu, bao gồm nhiều stream, thuộc tính mở rộng, ACL, v.v.
    https://github.com/n8gray/Backup-Bouncer
    Cũng có RsyncX, một ứng dụng SwiftUI bọc quanh rsync
    https://github.com/rsyncOSX/RsyncOSX
    Vào thời còn chạy phần mềm macOS “Classic” trên hệ UNIX mới, những thứ như vậy từng được coi là cực kỳ quan trọng
    https://web.archive.org/web/20161022012615/http://blog.plast...

    • Vấn đề của rsync là nó chậm đến phi lý
      IFileOperation (Windows) và FileManager (macOS) thực hiện kiểu sao chép có hiệu năng tốt nhất mà hệ thống tệp bên dưới hỗ trợ
      Với SMB và ReFS, kiểm tra CRC gần như chỉ là chuyện đánh dấu một ô, và trên các SMB share hiện đại của Windows Server hiện đại, bước khớp nội dung của rsync là công việc bị lặp lại
      Giữa các máy Windows, IFileOperation có thông lượng nhanh hơn rsync 1,5–8 lần, mức dùng CPU thấp hơn, và thậm chí có thể nhanh hơn sao chép tệp Go thông thường 1,2–3 lần
      Nếu chỉ nhìn vào Linux mà không quan tâm đến các hệ điều hành thực sự dùng metadata hệ thống tệp phức tạp, thì openrsync hoặc một chương trình đơn giản hơn là đủ
  • Tôi thắc mắc liệu có tài liệu nào giải thích rõ vì sao Apple lại sợ GPLv3 đến vậy không
    Tôi nghĩ nếu biên dịch tĩnh thành executable thì đáng lẽ không phải là vấn đề

    • GPLv3 đã bịt lỗ hổng cho phép công khai mã nguồn của sản phẩm phái sinh từ mã GPL nhưng lại không cho người dùng build và chạy mã nguồn đó trên thiết bị thực
      Khi đó TiVo đã làm như vậy, nên việc này được gọi là Tivoization
      Với iOS thì lý do không dùng GPLv3 rất rõ ràng, vì họ sẽ vi phạm các điều kiện
      macOS có thể phân phối mã GPLv3, nhưng Apple chia sẻ rất nhiều mã giữa iOS/macOS/watchOS/tvOS/visionOS, nên việc chỉ dựa vào GPLv3 trên một hệ điều hành còn các hệ khác thì không dùng không có nhiều ý nghĩa
      Đơn giản nhất là hoàn toàn không dùng
      Ngoài ra, nếu trong tương lai macOS bị khóa chặt hơn đối với việc chạy mã của người dùng, họ cũng không phải lo gỡ bỏ mã GPLv3 khi đó
    • Quan điểm của tôi về GPL và các giấy phép liên quan đã thay đổi rất nhiều sau khi làm việc với luật sư
      Ngay cả những điều tôi từng nghĩ là hoàn toàn an toàn cũng không được luật sư nhìn nhận chắc chắn như vậy
      Tôi không biết lý do của Apple, nhưng các luật sư doanh nghiệp ở những công ty khác đã đưa ra nguyên tắc là hãy chọn giấy phép không phải GPL nếu có thể
    • Có lẽ nhiều khả năng là họ muốn tránh hẳn tình huống phải tranh tụng GPLv3 trước tòa, và thậm chí có thể thua
      Nhìn vào lịch sử án lệ liên quan đến GPLv2, lợi ích thu được có vẻ ít so với công sức bỏ ra
      Từ góc nhìn của Apple, nếu chỉ thay thế phần bị coi là “vấn đề” thì có thể tránh toàn bộ nhóm vấn đề đó
    • Apple rõ ràng phản đối quyền của người dùng, còn GPL chính là giấy phép nhằm bảo vệ các quyền đó
      Các chi tiết kỹ thuật cụ thể có thể thú vị, nhưng tôi cho rằng chúng không phải là cốt lõi
    • Apple không nói lý do
      Tốt hơn là không nên tin các lời giải thích của người khác về ý định của Apple
  • Khi tự viết bản triển khai https://github.com/gokrazy/rsync bằng Go, tôi đã xem openrsync và thấy mã nguồn khá tốt
    Tuy nhiên, điều đáng tiếc là openrsync không tương thích 100% với rsync
    Khi các bài kiểm thử của tôi bị hỏng trên macOS 15, tôi biết được rằng Apple đã bắt đầu chuyển sang openrsync

  • Có nói rằng openrsync được viết như một phần của dự án rpki-client(1), trình xác thực RPKI cho OpenBSD, và được NetNod, IIS.SE, SUNET, 6connect tài trợ; tôi tò mò vì sao các tổ chức này lại tài trợ cho việc phát triển đó
    https://github.com/kristapsdz/openrsync?tab=readme-ov-file#p...

    • Lý do tồn tại được bình luận này giải thích khá rõ
      https://news.ycombinator.com/item?id=43605846
      Các công ty tài trợ cho những thứ hữu ích hoặc cần thiết
      Một số công ty trong danh sách có thể đang dùng BSD, và có khả năng họ muốn hoặc cần một bản triển khai rsync không phải GPLv3
      Hoặc đơn giản là họ có thể quan tâm đến việc tài trợ cho các dự án và hoạt động phát triển mã nguồn mở
  • Trong một thời gian, cho đến Sequoia 15.3, có thể dùng cả rsync_samba và rsync_openrsync thông qua /var/select/rsync hoặc biến môi trường CHOSEN_RSYNC
    Điểm đặc biệt gây khó chịu của openrsync là nó tuyên bố hỗ trợ phần tử đường dẫn “ma thuật” /./ cho --relative
    Tôi đã gửi báo cáo lỗi cho Apple về vấn đề này khoảng một tháng trước
    Từ Sequoia 15.4, rsync_samba đã biến mất, còn rsync thì tôi đã cài bằng Homebrew

  • Gần đây tôi gặp vấn đề này: khi tạo file .ipa iOS bằng xcodebuild từ dòng lệnh, có vẻ bên trong nó gọi rsync để sao chép file giữa các thư mục cục bộ
    Nhưng vì Homebrew rsync đứng trước trong $PATH, nó đã chạy bản đó, và xcodebuild truyền vào đối số chỉ dành cho openrsync là --extended-attributes
    Homebrew rsync không hiểu đối số đó nên thất bại và thoát

  • Tôi vẫn thấy mừng là Apple không dần loại bỏ khía cạnh POSIX để biến osx thành giống iOS, mà vẫn tiếp tục cải thiện và chấp nhận nó