- Do dự án hệ thống tệp dùng trong lớp học trùng thời điểm với việc chuẩn bị bài thuyết trình ChiPy, một hướng dẫn GitLab từng bước về cách xây dựng hệ thống tệp dựa trên FUSE bằng Python đã được khởi động
- FIUnamFS dùng trong lớp là một hệ thống tệp đồ chơi có cấp phát tệp liên tiếp, không hỗ trợ thư mục con và bị giới hạn ở kích thước đĩa mềm 1,44MB
- Trong sáu học kỳ, bài tập này đã được giao cho 30–40 sinh viên mỗi học kỳ, nhưng chỉ có một người nộp bài triển khai FUSE, nên nhu cầu về tài liệu Python FUSE dễ làm theo trở nên lớn hơn
- Hướng dẫn mới có dạng bài tập tăng dần, bắt đầu từ hệ thống tệp rỗng rồi thêm dần lời gọi hệ thống và chức năng; bao quát cả đọc/ghi dựa trên RAM và triển khai passthrough chỉ đọc
- Đi kèm là các ví dụ ngắn như DNS, biên dịch Markdown tức thời, unzip và hệ thống tệp loại bỏ chú thích, giúp sinh viên học FUSE qua ví dụ thực tiễn
Hướng dẫn Python FUSE bắt nguồn từ dự án lớp học
- Sau khi nhận được đề xuất thuyết trình tại Chicago Python User Group ở DebConf22, chủ đề này được nhắc lại ở DebConf24, dẫn đến việc tìm kiếm một chủ đề thuyết trình về Python
- Dù không xem Python là ngôn ngữ chính của mình, tác giả vẫn dùng Python trong lớp vì đây là ngôn ngữ sinh viên theo kịp tốt nhất
- Dự án lớp học FIUnamFS là viết tắt của “Facultad de Ingeniería, Universidad Nacional Autónoma de México”, một hệ thống tệp dùng trong môn học tại Khoa Kỹ thuật của Đại học Tự trị Quốc gia Mexico
- Dựa trên cấp phát tệp liên tiếp
- Không hỗ trợ thư mục con
- Thường bị giới hạn ở kích thước đĩa mềm 1,44MB
- Được dùng như một hệ thống tệp đồ chơi, dễ đặc tả và triển khai
- Tác giả đã yêu cầu sinh viên tạo giao diện được trau chuốt hơn một menu đơn giản, và cho rằng FUSE là lựa chọn phù hợp để người dùng sử dụng FIUnamFS mà không phải ý thức về nó
- Dự án này đã được giao trong sáu học kỳ cho 30–40 sinh viên mỗi kỳ, nhưng chỉ có một sinh viên thực sự nộp bản triển khai FUSE
Hạn chế của tài liệu hiện có và các lựa chọn
- Đã có các ví dụ và bài viết về Python FUSE, nhưng nhiều tài liệu không đủ để tự làm theo hoặc đã cũ
- Các giao diện FUSE có thể dùng trong Python cũng không được thống nhất thành một, khiến việc chọn điểm bắt đầu trở nên khó khăn
Cấu trúc của hướng dẫn trên GitLab
- Dự án GitLab mới a hand-holding guide to writing FUSE-based filesystems in Python trình bày theo từng bước nhiều bản triển khai hệ thống tệp FUSE có thể chạy được
- Một số hoạt động dựa trên RAM
- Một số được triển khai dựa trên passthrough
- Tác giả cũng có kế hoạch bổ sung hệ thống tệp dựa trên thiết bị khối giả để triển khai các hệ thống như FIUnamFS
- Hiện có năm tệp theo từng bước, bắt đầu từ hệ thống tệp rỗng đơn giản nhất rồi thêm từng lời gọi hệ thống và chức năng
- Cũng đi kèm các ví dụ ngắn và hữu ích có thể khiến sinh viên hứng thú
- Các ví dụ chỉ ở mức vài chục dòng nên dễ dùng trong lớp học, và
uncommentfstự động loại bỏ chú thích cùng khoảng trắng
Lịch thuyết trình và tài liệu công khai
- Bài thuyết trình ChiPy diễn ra trực tuyến lúc 18:30 GMT-6 ngày 10/10/2024
- Chủ đề tương tự cũng dự kiến được trình bày tại Jornadas Regionales de Software Libre và nerdear.la
- Video sau buổi thuyết trình cũng đã được công khai
- Video thuyết trình ChiPy: A hand-holding guide to writing FUSE-based filesystems in Python
- Video thuyết trình bằng tiếng Tây Ban Nha: Aprendiendo y enseñando a escribir sistemas de archivo en espacio de usuario con FUSE y Python
1 bình luận
Ý kiến trên Hacker News
Trên GitHub của libfuse [0] có các ví dụ cho C/C++ được sắp xếp rất tốt theo độ phức tạp
passthrough.c mirror một hệ thống tệp hiện có nhưng được ghi là “hiệu năng tệ khủng khiếp”, còn passthrough_fh.c thì “không tệ đến mức đó”
passthrough_ll.c được triển khai bằng API cấp thấp nên được mô tả là “ít tệ nhất trong ba cái”, còn passthrough_hp.cc là phiên bản hiệu năng cao viết bằng C++
Một số dự án FUSE thú vị tôi đã ghi chú gồm chia nhỏ tệp dung lượng lớn [1], hiển thị snapshot tăng dần của ZFS dưới dạng tệp [2], nén hệ thống tệp trong suốt [3], và các tùy chọn mount archive thành hệ thống tệp [4], [5]
[0] https://github.com/libfuse/libfuse/tree/master/example
[1] https://github.com/seiferma/splitviewfuse
[2] https://github.com/UNFmontreal/zfs_fuse_snapshot
[3] https://github.com/FS-make-simple/fusecompress
[4] https://github.com/google/fuse-archive
[5] https://github.com/mxmlnkn/ratarmount
Tại điểm mount của mọi dataset có một thư mục
.zfsẩn, thậm chí không hiện trongls -A; chỉ cần tin là nó tồn tại rồicdthẳng vàoBên dưới đó có thư mục
snapshot, trong đó có các thư mục tương ứng với từng snapshot của dataset đó, chứa các tệp của snapshotVí dụ,
/etc/hostscủa snapshot zrepl_20241011_010143_000 nằm ở/.zfs/snapshot/zrepl_20241011_010143_000/etc/hostsNếu không thích hành vi ẩn kiểu “ma thuật” này, cũng có thể đặt
zfs set snapdir=visibleđể nó hiện như một thư mục bình thườngRất vui khi thấy các liên kết liên quan, và vì cảm giác của tôi hơi mai một, nếu có tutorial hoặc hướng dẫn FUSE nào hữu ích thì tôi rất muốn nhận
Tôi thích FUSE, nhưng đó không phải lựa chọn duy nhất; cách đây không lâu tôi thử triển khai một hệ thống tệp ảo bằng giao thức 9p và thấy khá thú vị
Nếu nhớ không nhầm thì tôi dùng py9p, và trải nghiệm Python tốt hơn fuse-python rất nhiều
Nếu muốn, có thể dùng 9pfuse để mount dịch vụ 9p thông qua FUSE, nhưng tôi đã dùng client v9fs của kernel
Nếu mục tiêu chỉ là truyền hệ thống tệp qua mạng, tôi nghĩ mình đã dùng server 9p diod; nhìn chung đây là một hệ sinh thái nhỏ đáng xem qua
Ghi chú của tôi ở [1], nhưng phần lớn chỉ là tập hợp liên kết tới tài liệu gốc
FUSE cũng tốt, nhưng 9P tổng quát hơn, và có các implementation chất lượng ở nhiều nơi, kể cả Windows
Tuy nhiên tôi không chắc về đặc tính hiệu năng của 9p; tôi từng thấy người ta nói nó chậm, nhưng chưa thấy tài liệu nào mang tính kết luận
Tôi tò mò liệu có benchmark hay thông tin nào không
[0]: https://github.com/chaos/diod/blob/master/protocol.md
[1]: https://athenaeum.wiki/Zettelkasten/9p
Tôi muốn đọc ngẫu nhiên như tệp cục bộ mà không phải tải trước các tệp lớn
Một trong những nỗi khổ gặp phải là block size của FUSE quá nhỏ, khiến độ trễ và churn của các lời gọi HTTP tới backend tăng cao, và cần logic caching/đọc trước khá phức tạp
Logic đọc trước của kernel dường như hoàn toàn không hoạt động, và lúc đó tôi không điều tra sâu ngoài việc không tìm ra cách gợi ý cho nó
Có thể xem FAQ tại https://virtio-fs.gitlab.io
Dù vậy, đây vẫn là một dự án rất hay
Ước gì tôi biết điều này khi phải trải qua đúng quy trình y hệt cách đây một tháng
Trong nỗ lực tuyệt vọng nhằm làm Jira bớt khó chịu hơn, tôi đã nghĩ ra dự án jira-as-filesystem, dùng cách phân loại issue nội bộ để tạo thành cây
Thư mục biểu diễn issue, file biểu diễn các trường của issue, thư mục con biểu diễn các issue được liên kết, và cuối cùng tôi chọn fuse-python
Tôi đã không thể làm tiếp một thời gian, nhưng đã gặp vấn đề ở phần trừu tượng hóa
Nếu chỉ dùng ID issue làm tên thư mục thì dễ tự động hóa, nhưng khi
lssẽ chỉ thấy một đống ID khó nhận biết, khiến con người khó duyệt, nên tôi đã thêm một kiểu thư mục song song-with-summary, trong đó gắn thêm phần tóm tắt đã slug hóa sau ID issueTức là có một jira-as-filesystem cho các file gốc, còn để con người duyệt và tương tác thì có một cây symbolic link đặt nhiều liên kết tới cùng các file ở nhiều vị trí liên quan khác nhau
Có thể tôi đang thêm tầng phức tạp quá mức cần thiết vì hiểu chưa đủ, nhưng về mặt kỹ thuật có vẻ cách này có thể giải quyết vấn đề trừu tượng hóa vừa nói
Trên Linux hiện đại, đĩa được tham chiếu cả bằng block device lẫn UUID, nên tôi nghĩ cách tiếp cận này ổn và phù hợp với kỳ vọng
Tuy vậy, cá nhân tôi có lẽ sẽ không dùng, vì bản thân JIRA cũng đã đủ phức tạp rồi
Ví dụ: https://github.com/coddingtonbear/jirafs
1234-human-sensekhông được sao?Nó chứa cả hai loại thông tin và trông cũng dễ parse
Có rất nhiều tùy chọn mount FUSE, mỗi thứ có điểm đánh đổi, hiệu năng và tính năng khác nhau
Có cả s3fs, goofys, seaweed, minio, Google Drive, v.v.; JuiceFS cũng khá thú vị cho mục đích mount object storage rồi truy cập theo kiểu POSIX với metadata mà ta mong đợi ở một hệ thống file truyền thống
https://juicefs.com
Hay
Một câu hỏi liên quan: gần đây tôi thấy có những trường hợp triển khai hệ thống file dựa trên NFS vì đây là giao thức được hỗ trợ rộng rãi hơn
Có vẻ rclone làm vậy trên Mac; có hướng dẫn hoặc tài liệu so sánh nào về cách tiếp cận này không?
Nó hoạt động gần như một giải pháp thay thế, không cần kernel extension, mở một máy chủ NFS ở nền rồi mount bằng chức năng của macOS
Hiệu năng cũng khá tốt
Nếu muốn xem một sản phẩm hoàn chỉnh trông như thế nào, hãy xem trình quản lý nhạc azuline/rosé có hệ thống file ảo
Đây là một codebase rất tốt với nhiều chú thích, mô tả, kiểu và test, nên sẽ dễ học
https://github.com/azuline/rose
Nếu quan tâm đến FUSE, dự án kiểu song hành là CUSE cũng có thể thú vị
CUSE là mô phỏng driver thiết bị ký tự trong user space, cho phép giả lập phần cứng mà không cần biên dịch kernel module mới
Gần đây tôi đã dùng nó để viết một thiết bị phần cứng hỗ trợ IOCTL bằng Python
Tôi không tìm được thư viện Python tốt nào chạy dễ dàng, tài liệu cũng thiếu, nhưng cuối cùng chỉ với thư viện FFI ctypes là đã viết đủ được
Phần duy nhất không trực quan ngay với người chưa từng viết kernel driver như tôi là IOCTL sẽ có các lời gọi theo cặp, vì phải điều chỉnh lại kích thước buffer cho mỗi lần đọc/ghi
May là CUSE có chế độ debug hiển thị toàn bộ byte vào/ra
CUSE ban đầu được triển khai để tạo thiết bị âm thanh trong user space¹, nhưng cũng đã được dùng cho các mục đích như TTY tùy chỉnh, còn tôi dùng để tạo thiết bị SPI ảo
Hy vọng nó hữu ích với ai đó và dự án này được chú ý nhiều hơn
¹ https://lwn.net/Articles/308445/
Khá lâu trước đây, tôi đã tạo một hệ thống file FUSE bằng Python[1] để tương tác với hệ thống wiki tên là dokuwiki
Tôi xây nó trên hde llfuse[2], và đã phải triển khai khá nhiều API mức thấp không liên quan trực tiếp đến dokuwiki
Vì vậy tôi tạo easyfuse[3][4] như một wrapper bao bọc những phần không liên quan đến triển khai dokuwiki; nếu bạn định xây hệ thống FUSE thì đáng để xem qua
[1]: https://github.com/JelteF/dokuwikifuse
[2]: https://pypi.org/project/llfuse/
[3]: https://pypi.org/project/easyfuse/
[4]: https://github.com/JelteF/easyfuse
Về cơ bản dokuwiki là một tập hợp file văn bản, vậy mount bằng NFS hoặc chia sẻ qua Dropbox/Syncthing không đơn giản và hiệu quả hơn sao?
Có thể nghĩ FUSE như một cách để Makefile chỉ định đồ thị có hướng không chu trình trên các tài nguyên tùy ý
Ví dụ nếu có một hệ thống file FUSE phơi bày trạng thái cụm k8s, thì ngay cả người đầu óc đơn giản như tôi cũng có thể dễ viết các operator dễ tiếp cận hơn
Email cũng tương tự: nếu phơi bày IMAP như một hệ thống file, liệu các ứng dụng RAG (như gpt4all) có thể truy cập trực tiếp mọi thứ không?
Hơi lạc đề, nhưng mỗi khi thấy một blog mang không khí thập niên 90/2000, tôi luôn vào xem trang bài viết đầu tiên
Kể cả gwolf.org; nhìn vào những viên nang thời gian như thế luôn không bao giờ làm tôi thất vọng