บูตลินุกซ์จาก Google Drive
(ersei.net)- เป็นการทดลองบูต 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 ไม่ทำงาน
- ความเร็วช้ามาก
- symbolic link ที่ชี้ไปยัง symbolic link ไม่ทำงาน ทำให้รายการที่เกี่ยวข้องกับ
- เพื่อคงเงื่อนไขว่าไม่แก้ 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 โดยไม่มีอุปกรณ์จัดเก็บข้อมูล
ยังไม่มีความคิดเห็น