• เป็นการทดลองบูต Arch Linux โดยใช้ Google Drive เป็นระบบไฟล์รูท แทนดิสก์โลคัลหรือ NFS
  • ในขั้นตอน initramfs มีการเมานต์ ระบบไฟล์ FUSE และสร้างอิมเมจ EFI แบบกำหนดเองด้วย Dracut ที่รวมเครือข่ายและไบนารีที่จำเป็นไว้
  • ตรวจพิสูจน์แนวคิดก่อนด้วย S3 และ s3fs จากนั้นเลี่ยงความล้มเหลวของ switch_root และ pivot_root ด้วยวิธีรัน chroot ในฐานะ PID 1
  • ระหว่างนำไปใช้กับ Google Drive ใช้ google-drive-ocamlfuse แต่ต้องปรับแก้ด้วยมือและปรับ timeout เพราะข้อจำกัดด้าน symbolic link, hard link, permission, attribute และความเร็ว
  • สุดท้ายสามารถบูตบนแล็ปท็อปที่ไม่มีอุปกรณ์จัดเก็บข้อมูลได้ด้วยไฟล์ EFI รวมบน USB และไดรเวอร์เครือข่ายแบบมีสาย แม้จะใช้งานจริงได้ไม่มาก แต่ก็แสดงความเป็นไปได้ของรูปแบบอื่น เช่น รูทบน SSHFS หรือ Git

ใช้ Google Drive เป็นระบบไฟล์รูท

  • หลังจากเห็นกรณีที่บูต Linux จาก NFS จึงลองทำเป้าหมายที่ยากกว่า นั่นคือ บูตรูทจาก Google Drive
  • เพราะต้องการโครงสร้างที่ทำงานได้ในตัวโดยไม่ต้องมีเครื่องผู้ช่วยแยกต่างหาก จึงเลือก FUSE ซึ่งทำงานเหมือนไดรเวอร์ระบบไฟล์ใน user space
  • เงื่อนไขหลักคือใส่โปรแกรม FUSE และการตั้งค่าเครือข่ายไว้ใน initramfs จากนั้นเมานต์ระบบไฟล์รูทระยะไกล แล้วให้บูตต่อไปตามปกติ

จุดที่จะแทรกในกระบวนการบูต Linux

  • ลำดับการบูต Linux แบ่งคร่าว ๆ ได้เป็นขั้นตอนต่อไปนี้
    • เฟิร์มแวร์ BIOS/UEFI เริ่ม bootloader
    • bootloader โหลดเคอร์เนล
    • เคอร์เนลคลาย initramfs ซึ่งเป็นระบบไฟล์ชั่วคราวใน RAM และใช้เครื่องมือสำหรับเมานต์ระบบไฟล์จริง
    • เคอร์เนลสลับไปยังระบบไฟล์จริงและรันระบบ init ของระบบไฟล์ใหม่
  • หากเมานต์ระบบไฟล์ FUSE ในขั้นตอนที่สาม ก็สามารถบูตต่อไปโดยใช้สตอเรจระยะไกลเสมือนเป็นรูทได้

พิสูจน์แนวคิดด้วย S3 ที่สร้างด้วย Dracut

  • ใช้ Dracut สำหรับสร้าง initramfs แบบกำหนดเอง
  • เลือก Arch Linux เป็นดิสโทรพื้นฐาน เพราะค่อนข้างเบาและคุ้นเคย
  • ในโมดูล Dracut รวมไบนารีที่เกี่ยวข้องกับ FUSE เช่น fusermount, fuseiso, mkisofs
  • สร้างอิมเมจ EFI ด้วย dracut.sh แล้วรันใน QEMU จากนั้นเข้าสู่ debug shell หลังมีคำเตือนว่าไม่มีอาร์กิวเมนต์ root=
  • ใน debug shell ทำงานที่จำเป็นต่อการบูตด้วยตัวเอง
    • โหลดไดรเวอร์ด้วย modprobe fuse, modprobe e1000
    • ตั้งค่าเครือข่ายด้วย dhclient eth0 และการตั้งค่า routing
    • เมานต์บัคเก็ต S3 ภายในไปที่ /sysroot ด้วย s3fs

switch_root ล้มเหลวและการเลี่ยงด้วย chroot

  • แม้จะเห็นรูทของ Arch Linux ที่ /sysroot แล้ว แต่ switch_root /sysroot /sbin/init ล้มเหลวด้วย Input/output error
  • pivot_root ก็ใช้กับ rootfs ของ initramfs ไม่ได้ จึงเกิด Invalid argument
  • ตามคำตอบใน Stack Exchange ที่อ้างอิงไว้ ใน initramfs rootfs ไม่สามารถใช้ pivot_root หรือ unmount ได้ ดังนั้นต้องเมานต์ทับรูทใหม่ แล้ว chroot ก่อนรัน init
  • หากรัน chroot /sysroot /sbin/init ตรง ๆ จาก shell systemd จะไม่ใช่ PID 1 จึงเริ่มทำงานตามปกติไม่ได้
  • แก้ init.sh ของ Dracut ให้ใส่การตั้งค่าเครือข่าย, การเมานต์ s3fs, การ bind mount /sys, /dev, /proc และตอนท้ายรัน exec chroot /sysroot /sbin/init จนบูตรูทจาก S3 สำเร็จ

ปัญหา DNS ที่พบในรูท S3

  • หลังบูตแล้ว ตรวจจากผลลัพธ์ mount พบว่า / ถูกเมานต์เป็นชนิด s3fs
  • เมื่อรัน pacman -Sy fastfetch ล้มเหลวเพราะ resolve โฮสต์ mirror ของแพ็กเกจ เช่น geo.mirror.pkgbuild.com ไม่ได้
  • เนื่องจากระบบไฟล์รูทอยู่บน S3 จึงสามารถเมานต์รูทนั้นจากเครื่องอื่นและเข้า chroot เพื่อติดตั้งเครื่องมือได้
  • systemd-resolved รันไม่ได้เพราะปัญหาสิทธิ์ในการเชื่อมต่อ stdout กับ journal socket จึงเลี่ยง DNS ด้วยการใส่ nameserver 1.1.1.1 ใน /etc/resolv.conf

ย้ายไป Google Drive

  • ใช้ google-drive-ocamlfuse เป็น FUSE implementation สำหรับ Google Drive
  • สร้าง OAuth2 secret ในบัญชี Google และเปิดใช้ API จากนั้นติดตั้งแพ็กเกจ AUR ใน Arch Linux VM
  • หลังเมานต์ Google Drive แล้ว ใช้งาน rsync ยาว ๆ เพื่อคัดลอกไฟล์ Arch Linux ไปยัง Drive
  • ในรูทที่ใช้ Google Drive ความแตกต่างของพฤติกรรมระบบไฟล์ยังคงเป็นปัญหา
    • symbolic link ที่ชี้ไปยัง symbolic link ไม่ทำงาน ทำให้รายการที่เกี่ยวข้องกับ /usr/lib มีปัญหา
    • hard link ไม่ทำงาน
    • relative symbolic link ไม่ทำงาน
    • ไม่อนุญาต symbolic link ที่ขาดปลายทาง
    • symbolic link ที่ชี้ออกไปนอก Google Drive ไม่ทำงาน
    • permission และ attribute ไม่ทำงาน
    • ความเร็วช้ามาก
  • เพื่อคงเงื่อนไขว่าไม่แก้ FUSE driver หรือเคอร์เนล จึงรับมือด้วยการสร้าง symbolic link ด้วยมือจาก log ของ rsync ที่ล้มเหลว

แก้ initramfs สำหรับ Google Drive

  • ใน initramfs ใส่ไฟล์ token ที่สร้างจากแล็ปท็อป, ไบนารี Google Drive FUSE และใบรับรอง SSL
  • ใส่ไฟล์ที่เกี่ยวข้องกับ /.gdfuse/default/config, /.gdfuse/default/state, /etc/ssl, /etc/ca-certificates ลงในอิมเมจ Dracut
  • เมื่อบูตด้วยรูท Google Drive เกิดข้อผิดพลาด chroot: /sbin/init: File not found
  • แม้ไฟล์จริงจะมีอยู่ แต่ถ้าไม่มีไลบรารีที่พึ่งพาหรือพาธของ dynamic linker Linux ก็อาจส่งกลับ File not found ได้
  • เพราะปัญหา relative symbolic link ทำให้เคอร์เนลไปหา /sysroot/sysroot อีกครั้งภายใน /sysroot จึงแก้โดยสร้าง /sysroot/sysroot แล้ว bind mount /sysroot เข้าไปในนั้น
  • หลังจากนั้นการบูตก็ยังช้ามาก
    • การสร้าง dynamic linker cache ใหม่ใช้เวลาประมาณ 5 นาที
    • แต่ละ systemd unit ใช้เวลาประมาณ 1 นาที
    • การบูตหยุดค้างเพราะ timeout ระหว่างรอ /dev/ttyS0
  • ตั้ง JobTimeoutSec=infinity ใน /etc/systemd/system/dev-ttyS0.device และเปลี่ยน LOGIN_TIMEOUT เป็น 0 ใน /etc/login.defs เพื่อหลีกเลี่ยง login timeout
  • หลัง cache สะสมแล้ว การอ่านไฟล์ก็ช้าน้อยกว่าตอนแรก

รันบนแล็ปท็อปที่ไม่มีอุปกรณ์จัดเก็บข้อมูล

  • ทดลองบูตบนฮาร์ดแวร์จริงด้วยแล็ปท็อปสำรองที่ไม่มีอุปกรณ์จัดเก็บข้อมูล
  • เปลี่ยนบางรายการจากการตั้งค่าสำหรับ QEMU ให้เหมาะกับฮาร์ดแวร์
    • ใช้ ไดรเวอร์ r8169 สำหรับพอร์ต Ethernet ของแล็ปท็อปแทน e1000 ที่เป็นค่าเริ่มต้น
    • ไม่ใช้ serial display
    • เปลี่ยนการตั้งค่าเครือข่ายให้ตรงกับ topology ของเครือข่ายที่บ้าน
  • ใช้ Powerline แทนสาย Ethernet ยาว ๆ
  • บิลด์ไฟล์ EFI แบบรวม ใส่ไว้ในพาธบูต EFI ของไดรฟ์ USB แล้วบูตจากแล็ปท็อป
  • หา directive modprobe สำหรับคีย์บอร์ดในตัวไม่เจอ จึงโหลด hid_usb และตั้งค่าเครือข่ายด้วยคีย์บอร์ดภายนอก
  • ผลลัพธ์สุดท้ายคือ “Cloud Native Computer” ที่ทำงานด้วยรูทบน Google Drive โดยไม่มีอุปกรณ์จัดเก็บข้อมูล

รูปแบบที่เป็นไปได้และข้อจำกัด

  • ตัวโปรเจกต์เองมีลักษณะกึ่งเล่นสนุกค่อนข้างมาก แต่สามารถใช้วิธีเดียวกันบูต Linux บน SSHFS ได้
  • หากใช้ gitfs ก็อาจบูต Linux จาก Git repository และติดตามการเปลี่ยนแปลงด้วย Git ได้
  • มีความเป็นไปได้มากมาย แต่ประโยชน์ใช้งานจริงมีจำกัด
  • นึกถึงการติดตั้ง Nix เป็นตัวเลือกสำหรับการทดลองถัดไป

ยังไม่มีความคิดเห็น

ยังไม่มีความคิดเห็น