1 คะแนน โดย GN⁺ 2024-10-13 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • โปรเจ็กต์ระบบไฟล์สำหรับการสอนกับการเตรียมบรรยายที่ ChiPy มาบรรจบกัน จนเริ่มมีคู่มือบน GitLab สำหรับสร้าง ระบบไฟล์แบบ FUSE ด้วย Python ทีละขั้นตอน
  • FIUnamFS ที่ใช้ในชั้นเรียนเป็นระบบไฟล์ตัวอย่างแบบง่าย มีการจัดสรรไฟล์แบบต่อเนื่อง ไม่รองรับไดเรกทอรีย่อย และจำกัดขนาดไว้ที่ฟลอปปีดิสก์ 1.44MB
  • ตลอดหกภาคการศึกษา มีการมอบหมายงานให้นักศึกษาภาคการศึกษาละ 30~40 คน แต่มีผู้ส่งงาน การทำ FUSE จริงเพียงคนเดียว จึงยิ่งเห็นความจำเป็นของสื่อ Python FUSE ที่ทำตามได้ง่าย
  • คู่มือใหม่นี้อยู่ในรูปแบบ แบบฝึกหัดแบบค่อยเป็นค่อยไป โดยเริ่มจากระบบไฟล์ว่างเปล่าแล้วค่อยเพิ่ม system call และฟังก์ชันต่าง ๆ รวมถึงการทำงานอ่าน/เขียนบน RAM และการทำ passthrough แบบอ่านอย่างเดียว
  • ยังมีตัวอย่างสั้น ๆ อย่าง DNS, การคอมไพล์ Markdown แบบทันที, unzip และระบบไฟล์ลบคอมเมนต์ เพื่อให้นักศึกษาได้เรียนรู้ FUSE ผ่าน ตัวอย่างที่ใช้งานได้จริง

คู่มือ Python FUSE ที่เริ่มต้นจากโปรเจ็กต์ในชั้นเรียน

  • หลังได้รับข้อเสนอให้บรรยายกับ Chicago Python User Group ที่ DebConf22 และมีการพูดถึงเรื่องนี้อีกครั้งที่ DebConf24 จึงเริ่มมองหาหัวข้อบรรยายเกี่ยวกับ Python
  • แม้จะไม่ได้มองว่า Python เป็นภาษาหลักของตัวเอง แต่มันเป็นภาษาที่นักศึกษาตามได้ดีที่สุด จึงใช้ Python ในการสอน
  • โปรเจ็กต์ประจำวิชา FIUnamFS เป็นตัวย่อของ “Facultad de Ingeniería, Universidad Nacional Autónoma de México” และเป็นระบบไฟล์ที่ใช้ในชั้นเรียนของคณะวิศวกรรมศาสตร์ มหาวิทยาลัยอิสระแห่งชาติเม็กซิโก
    • ทำงานบนพื้นฐานของ การจัดสรรไฟล์แบบต่อเนื่อง
    • ไม่รองรับไดเรกทอรีย่อย
    • โดยทั่วไปจำกัดขนาดเท่าฟลอปปีดิสก์ 1.44MB
    • ใช้เป็นระบบไฟล์ตัวอย่างแบบง่ายที่เขียนสเปกและอิมพลีเมนต์ได้ไม่ยาก
  • ผู้สอนได้ขอให้นักศึกษาสร้างอินเทอร์เฟซที่ประณีตกว่าเมนูธรรมดา และมองว่า FUSE เหมาะสำหรับทำให้ผู้ใช้ใช้งาน FIUnamFS ได้โดยไม่ต้องรับรู้เบื้องหลัง
  • โปรเจ็กต์นี้ถูกมอบหมายมาแล้วหกภาคการศึกษา ภาคการศึกษาละ 30~40 คน แต่มีนักศึกษาเพียงคนเดียวที่ส่งงานอิมพลีเมนต์ FUSE จริง

ข้อจำกัดของสื่อเดิมและตัวเลือกต่าง ๆ

  • แม้จะมีตัวอย่างและบทความเกี่ยวกับ Python FUSE อยู่แล้ว แต่หลายชิ้นยังไม่พอสำหรับการทำตามด้วยตัวเอง หรือเป็นข้อมูลที่เก่าแล้ว
  • อินเทอร์เฟซ FUSE ที่ใช้ได้จาก Python ก็ยังไม่ได้ถูกรวมเป็นมาตรฐานเดียว ทำให้เลือกยากว่าจะเริ่มจากที่ไหน

โครงสร้างของคู่มือบน GitLab

  • โปรเจ็กต์ GitLab ใหม่ a hand-holding guide to writing FUSE-based filesystems in Python แสดงการอิมพลีเมนต์ระบบไฟล์ FUSE ที่ทำงานได้จริงหลายแบบแบบทีละขั้น
    • บางส่วนทำงานบนพื้นฐานของ RAM
    • บางส่วนอิมพลีเมนต์แบบ passthrough
    • มีแผนจะเพิ่มระบบไฟล์ที่อิงกับอุปกรณ์บล็อกเสมือนสำหรับการอิมพลีเมนต์แบบ FIUnamFS
  • ปัจจุบันมีไฟล์แบบค่อยเป็นค่อยไปอยู่ห้าไฟล์ เริ่มจากระบบไฟล์ว่างเปล่าที่ง่ายที่สุด แล้วเพิ่ม system call และความสามารถต่าง ๆ ทีละอย่าง
  • ยังมีตัวอย่างสั้นและมีประโยชน์ที่น่าจะทำให้นักศึกษาสนใจรวมอยู่ด้วย
  • ตัวอย่างเหล่านี้มีขนาดเพียงไม่กี่สิบบรรทัด จึงเหมาะกับการใช้สอนในชั้นเรียน และ uncommentfs จะลบคอมเมนต์กับช่องว่างออกโดยอัตโนมัติ

กำหนดการบรรยายและสื่อที่เผยแพร่

1 ความคิดเห็น

 
GN⁺ 2024-10-13
ความคิดเห็นบน Hacker News
  • ใน [0] บน GitHub ของ libfuse มีตัวอย่างสำหรับ C/C++ จัดเรียงตามระดับความซับซ้อนไว้อย่างดี
    passthrough.c มิเรอร์ไฟล์ซิสเต็มที่มีอยู่ แต่ระบุไว้ว่า “ประสิทธิภาพแย่มาก” ส่วน passthrough_fh.c ระบุว่า “ไม่ได้แย่ขนาดนั้น”
    passthrough_ll.c เขียนด้วย API ระดับต่ำ และบอกว่า “แย่น้อยที่สุดในสามตัว” ส่วน passthrough_hp.cc เป็นเวอร์ชันประสิทธิภาพสูงที่เขียนด้วย C++
    โปรเจกต์ FUSE ที่น่าสนใจที่จดไว้มี การแบ่งไฟล์ขนาดใหญ่ [1], แสดงสแนปช็อตแบบ incremental ของ ZFS เป็นไฟล์ [2], การบีบอัดไฟล์ซิสเต็มแบบโปร่งใส [3], และตัวเลือกสำหรับเมานต์ archive เป็นไฟล์ซิสเต็ม [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

    • [2] อาจเป็นตัวอย่างโค้ดที่ดี แต่ฟีเจอร์นี้ มีอยู่ใน ZFS อยู่แล้ว
      ที่จุดเมานต์ของทุก dataset จะมีโฟลเดอร์ .zfs ที่ซ่อนอยู่ซึ่งแม้แต่ ls -A ก็ไม่แสดง และถ้าเชื่อว่ามีอยู่ก็ cd เข้าไปตรง ๆ ได้เลย
      ข้างใต้นั้นมีโฟลเดอร์ snapshot และภายในมีโฟลเดอร์ของแต่ละสแนปช็อตของ dataset นั้น พร้อมไฟล์ของสแนปช็อตอยู่ข้างใน
      ตัวอย่างเช่น /etc/hosts ของสแนปช็อต zrepl_20241011_010143_000 จะอยู่ที่ /.zfs/snapshot/zrepl_20241011_010143_000/etc/hosts
      หากไม่ชอบพฤติกรรมซ่อนแบบมายากลนี้ ก็สามารถตั้งค่าให้มองเห็นเหมือนโฟลเดอร์ทั่วไปได้ด้วย zfs set snapdir=visible
    • เมื่อไม่นานมานี้กำลังนึกถึง FUSE เพื่อใช้เลี่ยงเรื่อง การแยกแยะตัวพิมพ์เล็ก-ใหญ่ บน Linux
      ดีใจที่ได้เห็นลิงก์ที่เกี่ยวข้อง และถ้ามี tutorial หรือ guide เกี่ยวกับ FUSE ที่ช่วยได้ เพราะความคุ้นมือเริ่มฝืดไปบ้าง ก็อยากได้เช่นกัน
  • ชอบ FUSE แต่ก็ไม่ใช่ตัวเลือกเดียว และเมื่อไม่นานมานี้ลองทำไฟล์ซิสเต็มเสมือนด้วย โปรโตคอล 9p แล้วค่อนข้างสนุก
    เท่าที่จำได้ใช้ py9p และประสบการณ์กับ Python ดีกว่า fuse-python มาก
    ถ้าต้องการก็สามารถใช้ 9pfuse เพื่อเมานต์บริการ 9p ผ่าน FUSE ได้ แต่ฉันใช้ไคลเอนต์ v9fs ของเคอร์เนล
    ถ้าเป้าหมายคือแค่ส่งต่อไฟล์ซิสเต็มข้ามเครือข่าย คิดว่าเคยใช้เซิร์ฟเวอร์ 9p อย่าง diod และโดยรวมเป็น ecosystem เล็ก ๆ ที่น่าลองสำรวจ

    • 9p เป็นโปรโตคอลเล็ก ๆ ที่ยอดเยี่ยมจริง ๆ และใน diod[0] ก็มีเอกสารของตัวโปรโตคอลเองอยู่พอสมควร แถมเนื้อหาก็เรียบง่าย
      โน้ตของฉันอยู่ที่ [1] แต่ส่วนใหญ่เป็นชุดลิงก์ไปยังเอกสารต้นทาง
      FUSE ก็ดี แต่ 9P ใช้งานได้ทั่วไปมากกว่า และมี implementation คุณภาพดีในหลายที่ รวมถึง Windows
      อย่างไรก็ตามยังไม่มั่นใจเรื่องลักษณะด้านประสิทธิภาพของ 9p เคยเห็นคนบอกว่าช้า แต่ยังไม่เห็นข้อมูลที่ฟันธงได้
      อยากรู้ว่ามี benchmark หรือข้อมูลอะไรไหม
      [0]: https://github.com/chaos/diod/blob/master/protocol.md
      [1]: https://athenaeum.wiki/Zettelkasten/9p
    • ประมาณ 18 เดือนก่อน เคยทดลองเอา FUSE ไปวางหน้า URL แบบ HTTPS
      ต้องการอ่านแบบสุ่มเหมือนไฟล์ในเครื่อง โดยไม่ต้องดาวน์โหลดไฟล์ใหญ่ทั้งหมดก่อน
      หนึ่งในความเจ็บปวดที่เจอคือ block size ของ FUSE เล็กเกินไป ทำให้การเรียก HTTP ไปยัง backend มี latency และ churn สูง และต้องมีลอจิก caching/read-ahead ที่ค่อนข้างซับซ้อน
      ลอจิก read-ahead ของเคอร์เนลดูเหมือนไม่ทำงานเลย และตอนนั้นไม่ได้ขุดลึก นอกจากยังหาวิธีกระตุ้นมันไม่เจอ
    • ใน qemu การใช้ fuse(virtiofs) อาจให้ประสิทธิภาพดีกว่า 9p(virtio-9p)
      ดู FAQ ได้ที่ https://virtio-fs.gitlab.io
    • py9p มีรีลีสล่าสุดเมื่อปี 2013 และดูเหมือนยังถูกระบุว่าเป็น “beta”
      ถึงอย่างนั้นก็ยังเป็นโปรเจกต์ที่เจ๋ง
  • ถ้ารู้เรื่องนี้ตอนที่ต้องทำขั้นตอนเดียวกันเป๊ะเมื่อเดือนก่อนก็คงดี
    ด้วยความพยายามอย่างสิ้นหวังที่จะทำให้การใช้งาน Jira น่าหงุดหงิดน้อยลง ผมนึกถึงโปรเจกต์ jira-as-filesystem ที่สร้างทรีโดยใช้การจัดหมวดหมู่ issue ภายใน
    ผมให้ไดเรกทอรีแทน issue, ไฟล์แทนฟิลด์ของ issue และไดเรกทอรีย่อยแทน issue ที่เชื่อมโยงกัน แล้วสุดท้ายก็เลือกใช้ fuse-python
    พักงานไปช่วงหนึ่ง แต่เริ่มเจอปัญหาตั้งแต่ระดับ abstraction แล้ว
    ถ้าใช้ชื่อไดเรกทอรีเป็นแค่ ID ของ issue ระบบอัตโนมัติจะทำได้ง่าย แต่พอ ls แล้วเห็นแต่ ID ที่อ่านไม่รู้เรื่องเต็มไปหมด ทำให้คนค้นดูได้ยาก เลยเพิ่มชนิดไดเรกทอรีคู่ขนานแบบ -with-summary ที่ต่อท้าย ID ของ issue ด้วยสรุปแบบ slug

    • ไม่ได้หมายความว่านี่เป็นไอเดียที่ดีนะ แต่ผมคิดว่าทำ daemon ที่คอยอัปเดต เวอร์ชัน symbolic link ของสภาพแวดล้อม Jira ทั้งหมดให้เป็นปัจจุบันดีไหม
      คือมี jira-as-filesystem หนึ่งชุดสำหรับไฟล์ต้นฉบับ แล้วมีทรี symbolic link สำหรับให้มนุษย์สำรวจและโต้ตอบ โดยวางลิงก์หลายอันไปยังไฟล์เดียวกันในหลายตำแหน่งที่เกี่ยวข้อง
      อาจเป็นการเพิ่มชั้นมากเกินจำเป็นเพราะผมยังเข้าใจไม่พอ แต่ในเชิงเทคนิคดูเหมือนจะแก้ปัญหา abstraction ที่พูดถึงตอนนี้ได้
    • ในระบบไฟล์ Unix การอ้างถึงสิ่งเดียวกันสองวิธีเป็นเรื่องปกติ
      ใน Linux สมัยใหม่ ดิสก์ถูกอ้างถึงได้ทั้งในฐานะ block device และ UUID ดังนั้นผมคิดว่าแนวทางนี้ใช้ได้และสอดคล้องกับสิ่งที่คาดหวัง
      แต่ส่วนตัวคงไม่ใช้ เพราะ JIRA เองก็ซับซ้อนพออยู่แล้ว
    • บน GitHub มีตระกูล jirafs อยู่พอสมควร
      ตัวอย่าง: https://github.com/coddingtonbear/jirafs
    • ทำเป็นแบบ 1234-human-sense เฉย ๆ ไม่ได้เหรอ?
      มันมีข้อมูลทั้งสองแบบ และดูเหมือน parse ง่ายด้วย
    • มีโอกาสจะเปิดเผยโซลูชันที่ทำไว้เป็น โอเพนซอร์ส ไหม?
  • มีตัวเลือกการเมานต์ FUSE เยอะมากจริง ๆ โดยแต่ละตัวมีจุดประนีประนอม ประสิทธิภาพ และฟีเจอร์แตกต่างกัน
    มีทั้ง s3fs, goofys, seaweed, minio, Google Drive ฯลฯ และ JuiceFS ก็น่าสนใจมากสำหรับการเมานต์ object storage แล้วเข้าถึงในแบบ POSIX พร้อม metadata ที่คาดหวังจากระบบไฟล์แบบดั้งเดิม
    https://juicefs.com

  • ดีเลย
    คำถามใกล้เคียงคือ ช่วงหลังผมเห็นบางกรณีที่นำ ระบบไฟล์บนพื้นฐาน NFS มาใช้ เพราะเป็นโปรโตคอลที่รองรับกว้างกว่า
    ดูเหมือน rclone จะทำแบบนี้บน Mac มีไกด์หรือบทความเปรียบเทียบแนวทางนี้ไหม?

    • ข้อเท็จจริงที่น่าสนใจ: ใน macOS เวอร์ชันล่าสุด ถ้าจะติดตั้ง macFUSE ต้องปิดฟีเจอร์ความปลอดภัย แต่มี fuse-t ที่ยอดเยี่ยมอยู่
      มันทำงานได้แทบเหมือนตัวทดแทน ไม่ต้องใช้ kernel extension และเปิด NFS server ในเบื้องหลังแล้วเมานต์ด้วยฟังก์ชันของ macOS
      ประสิทธิภาพก็ค่อนข้างดี
    • ตัวอย่าง Rust: https://github.com/xetdata/nfsserve
  • ถ้าอยากเห็นว่าผลิตภัณฑ์ที่ทำเสร็จแล้วหน้าตาเป็นอย่างไร ลองดูตัวจัดการเพลง azuline/rosé ที่มี virtual filesystem
    เป็น codebase ที่ยอดเยี่ยม มีคอมเมนต์ คำอธิบาย type และเทสต์จำนวนมาก น่าจะเรียนรู้ได้ง่าย
    https://github.com/azuline/rose

  • ถ้าสนใจ FUSE โปรเจกต์คู่กันอย่าง CUSE ก็น่าสนใจเช่นกัน
    CUSE คือการจำลองไดรเวอร์ character device ใน userspace ทำให้เลียนแบบฮาร์ดแวร์ได้โดยไม่ต้องคอมไพล์ kernel module ใหม่
    ช่วงหลังผมใช้มันเขียนอุปกรณ์ฮาร์ดแวร์ที่รองรับ IOCTL ด้วย Python
    ผมหาไลบรารี Python ดี ๆ ที่ใช้งานง่ายไม่เจอ และเอกสารก็มีน้อย แต่สุดท้ายก็เขียนได้ด้วยไลบรารี ctypes FFI เพียงอย่างเดียว
    ส่วนเดียวที่ไม่ค่อยเป็นธรรมชาติทันทีสำหรับคนที่ไม่เคยเขียน kernel driver คือ IOCTL จะมีการเรียกมาเป็นคู่ เพราะต้องปรับขนาดบัฟเฟอร์ใหม่สำหรับการอ่าน/เขียนแต่ละครั้ง
    โชคดีที่ CUSE มีโหมด debug ที่แสดงไบต์อินพุตและเอาต์พุตทั้งหมด
    เดิมที CUSE ถูกทำขึ้นเพื่อสร้างอุปกรณ์เสียงใน userspace¹ แต่ก็ถูกใช้กับกรณีอย่าง TTY แบบกำหนดเองด้วย และผมใช้มันสร้างอุปกรณ์ SPI เสมือน
    หวังว่าจะเป็นประโยชน์กับใครสักคน และอยากให้โปรเจกต์นี้ได้รับความสนใจมากขึ้น
    ¹ https://lwn.net/Articles/308445/

  • นานมาแล้วผมเคยสร้าง ระบบไฟล์ FUSE ด้วย Python[1] เพื่อโต้ตอบกับระบบวิกิชื่อ dokuwiki
    สร้างอยู่บน hde llfuse[2] ซึ่งต้อง implement API ระดับต่ำจำนวนมากที่ไม่ได้เกี่ยวข้องโดยตรงกับ dokuwiki
    ดังนั้นผมจึงสร้าง easyfuse[3][4] เป็น wrapper สำหรับห่อส่วนที่ไม่เกี่ยวกับการ implement dokuwiki และถ้าคิดจะสร้างระบบ FUSE ก็น่าลองดู
    [1]: https://github.com/JelteF/dokuwikifuse
    [2]: https://pypi.org/project/llfuse/
    [3]: https://pypi.org/project/easyfuse/
    [4]: https://github.com/JelteF/easyfuse

    • อยากรู้ว่า use case ที่ทำ FUSE สำหรับ dokuwiki คืออะไร
      โดยพื้นฐานแล้ว dokuwiki เป็นชุดของไฟล์ข้อความ ดังนั้นการเมานต์ผ่าน NFS หรือแชร์ผ่าน Dropbox/Syncthing จะง่ายและมีประสิทธิภาพกว่าหรือเปล่า?
  • คิดว่า FUSE เป็นวิธีที่ทำให้ Makefile ระบุ directed acyclic graph บน resource ใด ๆ ก็ได้
    ตัวอย่างเช่น ถ้ามีระบบไฟล์ FUSE ที่เปิดเผยสถานะของคลัสเตอร์ k8s ก็อาจทำให้เขียน operator ที่คนหัวเรียบง่ายอย่างผมเข้าถึงได้ง่ายขึ้น
    อีเมลก็เช่นกัน ถ้าเปิด IMAP เป็นระบบไฟล์ แอป RAG (อย่าง gpt4all) ก็น่าจะเข้าถึงทุกอย่างได้โดยตรงไม่ใช่หรือ?

  • นอกเรื่องนิดหน่อย แต่เวลาเห็นบล็อกบรรยากาศยุค 90/2000 ผมมักจะเข้าไปดูหน้าโพสต์แรกเสมอ
    รวมถึง gwolf.org ด้วย การได้ส่องดู ไทม์แคปซูล แบบนั้นไม่เคยทำให้ผิดหวังเลย