โคลนโน้ตบุ๊กผ่าน NVMe TCP
(copyninja.in)- แทนที่จะตั้งค่าโน้ตบุ๊กเครื่องใหม่ตั้งแต่ต้น ผู้เขียนเลือก เปิดเผยทั้งดิสก์ของโน้ตบุ๊กเครื่องเดิมผ่าน NVMe over TCP แล้วโคลนผ่านเครือข่ายแบบเดิมทั้งหมด
- สภาพแวดล้อมเดิมใช้ การเข้ารหัสดิสก์ทั้งลูก และดิสก์ขนาด 512GB ส่วนโน้ตบุ๊กใหม่ใช้ NVMe 1TB จึงต้องขยายพาร์ทิชัน, LUKS และ BTRFS หลังโคลนเสร็จ
- แทนการใช้
systemd-storagetm.serviceผู้เขียนบูตโน้ตบุ๊กทั้งสองเครื่องด้วย GRML rescue CD แล้วตั้งค่าnvmet-tcpและ/sys/kernel/config/nvmet - การคัดลอกจริงทำด้วย
ddและเนื่องจากโน้ตบุ๊กใหม่ไม่มีพอร์ตอีเธอร์เน็ตจึง ใช้ได้แค่ WiFi ทำให้การโคลน 512GB ใช้เวลาราว 7 ชั่วโมง 30 นาที ที่ความเร็วประมาณ 18~20MB/s - หลังโคลน ผู้เขียนใช้
parted,growpart,cryptsetup resizeและ BTRFS resize เพื่อปรับให้ใช้พื้นที่ 1TB ได้ทั้งหมด และสภาพแวดล้อมเดิมก็ถูกย้ายมาต่อได้แทบทั้งหมด
ส่งออกดิสก์เดิมผ่าน NVMe over TCP
-
เพื่อไม่ต้องทำขั้นตอนตั้งค่าโน้ตบุ๊กใหม่ซ้ำทั้งหมด ผู้เขียนจึงเลือกวิธี คัดลอกทั้งดิสก์ของโน้ตบุ๊กเครื่องเดิม ตามคำแนะนำของเพื่อนร่วมงาน
-
ก่อนเริ่มมีอุปสรรคอยู่สองอย่าง
- ไม่มีเครื่องมือสำหรับเปิดโน้ตบุ๊กเครื่องเดิมแล้วต่อดิสก์ใหม่ผ่าน USB
- โน้ตบุ๊กเดิมใช้ การเข้ารหัสดิสก์ทั้งลูก และดิสก์ 512GB ส่วนเครื่องใหม่เป็น NVMe 1TB จึงต้องปรับขนาด LUKS
-
ลำดับงานแบ่งเป็นสามขั้น: เปิดเผยดิสก์, คัดลอก, และขยายความจุ
- ส่งออกดิสก์จากโน้ตบุ๊กเดิมด้วย
nvmet-tcp - คัดลอกดิสก์นั้นบนโน้ตบุ๊กใหม่
- ขยายพาร์ทิชันให้เต็ม 1TB
- ปรับขนาด LUKS
- สุดท้ายปรับขนาดดิสก์รากของ BTRFS
- ส่งออกดิสก์จากโน้ตบุ๊กเดิมด้วย
-
ใช้ GRML แทน systemd-storagetm.service
- วิธีที่ง่ายที่สุดคือใช้ systemd-storagetm.service
- สามารถเรียกใช้ได้โดยกำหนด
rd.systemd.unit=storage-target-mode.targetเพื่อบูตเข้าstorage-target-mode.target - แต่แนวทางนี้ต้องใส่บริการเครือข่ายไว้ในอิมเมจ dracut initrd และในโหมดนั้น การตั้งค่า WiFi ยุ่งยาก จึงไม่ได้เลือกใช้
- ผู้เขียนจึงบูตโน้ตบุ๊กทั้งสองเครื่องด้วย GRML rescue CD แล้วใช้โมดูล
nvmet-tcpของ Linux เพื่อส่งออกดิสก์ NVMe จากเครื่องเดิม
modprobe nvmet-tcp cd /sys/kernel/config/nvmet mkdir ports/0 cd ports/0 echo "ipv4" > addr_adrfam echo 0.0.0.0 > addr_traaddr echo 4420 > addr_trsvcid echo tcp > addr_trtype cd /sys/kernel/config/nvmet/subsystems mkdir testnqn echo 1 >testnqn/allow_any_host mkdir testnqn/namespaces/1 cd testnqn # replace the device name with the disk you want to export echo "/dev/nvme0n1" > namespaces/1/device_path echo 1 > namespaces/1/enable ln -s "../../subsystems/testnqn" /sys/kernel/config/nvmet/ports/0/subsystems/testnqn- ด้วยการตั้งค่านี้ อุปกรณ์เป้าหมายจะถูกเปิดเผยผ่าน NVMe over TCP
- บนโน้ตบุ๊กใหม่ ให้ค้นหาและเชื่อมต่ออุปกรณ์ที่ถูกส่งออกมา
nvme discover -t tcp -a <ip> -s 4420 nvme connectl-all -t tcp -a <> -s 4420- จากนั้นตรวจสอบอุปกรณ์ที่เชื่อมต่อบนโน้ตบุ๊กใหม่ได้ด้วย
nvme listแล้วจึงเริ่มคัดลอกดิสก์
คัดลอกดิสก์และปรับขนาด
-
คัดลอก 512GB ด้วย
dd- การคัดลอกดิสก์รากทำด้วยคำสั่ง
dd - เนื่องจากโน้ตบุ๊กใหม่ ไม่มีพอร์ตอีเธอร์เน็ตและใช้ได้แค่ WiFi การคัดลอก 512GB ทั้งหมดจึงใช้เวลาประมาณ 7 ชั่วโมง 30 นาที
- ความเร็วในการส่งข้อมูลอยู่ที่ราว 18~20MB/s
- ทางเลือกอื่นคือสร้างพาร์ทิชันและไฟล์ระบบเบื้องต้นก่อนแล้วคัดลอกดิสก์รากด้วย
rsyncหรือใช้การส่งไฟล์ระบบของ BTRFS โดยตรง
dd if=/dev/nvme2n1 of=/dev/nvme0n1 status=progress bs=40M - การคัดลอกดิสก์รากทำด้วยคำสั่ง
-
ขยายพาร์ทิชัน, LUKS และ BTRFS
partedตรวจพบว่าตารางพาร์ทิชันไม่ตรงกับขนาดดิสก์ และหลังถามยืนยันก็แก้ไขให้อัตโนมัติ- เพื่อขยายพาร์ทิชันที่สอง ผู้เขียนติดตั้ง
cloud-guest-utilsและใช้growpart
growpart /dev/nvem0n1 p2- ขั้นถัดไปคือขยายขนาด คอนเทนเนอร์ LUKS ด้วย
cryptsetup
cryptsetup luksOpen /dev/nvme0n1p2 ENC cryptsetup resize ENC- หลังจากนั้นผู้เขียนรีบูตเข้าดิสก์และยืนยันว่าระบบทำงานปกติ แล้วจึงล็อกอินเพื่อปรับขนาดไฟล์ระบบ BTRFS
- BTRFS ต้องเมานต์ระบบอยู่จึงจะปรับขนาดได้ ดังนั้นจึง ไม่สามารถทำในสถานะบูตแบบไลฟ์ได้
btfs fielsystem resize max /- ผลลัพธ์คือบนโน้ตบุ๊กใหม่ก็ได้สภาพแวดล้อมที่เหมือนยังใช้งานเครื่องเดิมอยู่
- โดยปกติการปรับตัวกับโน้ตบุ๊กเครื่องใหม่อย่างสมบูรณ์มักใช้เวลาประมาณ 1~2 สัปดาห์ แต่วิธีนี้ช่วยลดเวลานั้นลง
- อีกสิ่งที่ได้เพิ่มเติมคือได้เรียนรู้ วิธีส่งออกดิสก์ผ่าน NVMe over TCP
1 ความคิดเห็น
ความคิดเห็นจาก Hacker News
ในสถานการณ์ของผู้เขียน สุดท้ายก็เป็นแค่การ คัดลอกบล็อกแบบลำดับด้วย
dd(1)เท่านั้น ดังนั้นแทบไม่มีข้อได้เปรียบอะไรจากการใช้ NVMe/TCP เลย คำสั่งที่ซับซ้อนสามารถแทนได้ด้วยnetcatแบบง่าย ๆโน้ตบุ๊กปลายทาง:
$ nc -l -p 1234 | dd of=/dev/nvme0nX bs=1Mโน้ตบุ๊กต้นทาง:
$ nc x.x.x.x 1234ddฝั่งปลายทางมีไว้เพื่อบัฟเฟอร์การเขียนให้เร็วและมีประสิทธิภาพขึ้น ถ้าเพิ่มgzip/gunzipเข้าไปทั้งฝั่งต้นทางและปลายทาง จะเร็วขึ้นมากเมื่อดิสก์ไม่ได้ถูกใช้งานเต็มและมีบล็อก 0 อยู่มาก ส่วนตัวนี่เป็นวิธีที่ชอบที่สุดเวลาอิมเมจเครื่องพีซีผ่านเครือข่าย และเคยทำแบบนี้มาหลายครั้งแล้วบน GigE การบีบอัดมักกลายเป็นคอขวด จึงควรส่ง
--fastให้gzipหรือดีกว่านั้นคือใช้ lz4/unlz4 แทนgzip/gunzipเพื่อความเร็วที่มากกว่า เมื่อก่อนเคยทำอิมเมจโน้ตบุ๊ก Windows เครื่องใหม่ที่มี NVMe 1TB ผ่าน GigE ใช้เวลาราว 20 นาที และเพราะพื้นที่ว่างถูกบีบอัดจนเกือบเป็น 0 ผลลัพธ์จึงได้อิมเมจขนาด 20GB ปกติจะเก็บอิมเมจ lz4 นั้นไว้เป็นแบ็กอัป แล้วอีกหลายปีค่อยกู้คืนด้วยunlz4 | ddตอนจะบริจาคโน้ตบุ๊ก ซึ่งสะดวกมากแต่ก็ไม่เคยรู้มาก่อนว่ามี Linux kernel module
nvme-tcpเรียนรู้อะไรใหม่ทุกวัน ดูเหมือนว่านี่จะมีประโยชน์กับการเมานต์ไฟล์ซิสเต็มบน NVMe ระยะไกลมากกว่าการเข้าถึงแบบดิบด้วยddเพิ่มเติมคือขนาดบัฟเฟอร์ของ pipe สูงสุดใน Linux คือ 64kB ดังนั้นในทางเทคนิคอาร์กิวเมนต์
dd bs=Xไม่จำเป็นต้องใหญ่กว่านั้น ถึงอย่างนั้นbs=1Mก็ไม่ได้มีโทษอะไร และจะช่วยรวบรวมการอ่านขนาด 64kB จนได้ 1MB รวมถึงรองรับในอนาคตหากขนาด pipe ใหญ่ขึ้นด้วยnetcatบางเวอร์ชันมีตัวเลือกขนาดบล็อก I/O จึงไม่ต้องใช้dd bs=Xแต่netcatบนดิสก์กู้คืนมักเป็นเวอร์ชันที่ไม่มีตัวเลือกนี้pvแทนddทั้งสองฝั่ง ก็ไม่ต้องกังวลเรื่องกำหนดขนาดบล็อกให้เหมาะสม และยังได้กราฟความคืบหน้าที่ดูสวยด้วยtestdiskสร้างตารางพาร์ทิชันกลับขึ้นมาใหม่ แต่ก่อนหน้านั้นไม่อยากแตะต้องดิสก์ที่เสียหาย จึงคัดลอกข้อมูลประมาณ 40TB ด้วยแฟลชดิสก์กู้คืน,netcatและไดรฟ์เซิร์ฟเวอร์บางเครื่องมีสล็อต RAID แบบกายภาพเต็มหมด จึงใส่ดิสก์สำรองเพิ่มไม่ได้ และใช้คำสั่งประมาณ
dd if=/dev/sdc bs=xxx | gzip | nc -l -p 8888กับคำสั่งย้อนกลับอีกฝั่งหนึ่ง ซึ่งทำงานได้ดีเกินคาด สิ่งหนึ่งที่ต้องระวังคือทดลองจับคู่dd bsให้เข้ากับขนาดเซกเตอร์ เพราะขนาดที่เหมาะสมส่งผลต่อ throughput ของddอย่างมากddแบบนี้อาจทำให้เกิด ความเสียหาย ได้ ต้องมีiflag=fullblockเพื่อไม่ให้บล็อกถูกตัด และแม้จะเสี่ยงเป็นธรรมเนียมที่ทำตาม ๆ กันโดยไม่คิด แต่conv=syncก็ไม่ได้มีโทษอะไร ส่วนตัวแล้วชอบใช้nc -l -p 1234 > /dev/nvme0nXตรง ๆ มากกว่าถ้าใส่
pvเข้าไปใน pipeline จะเห็นเวลาที่คาดว่าจะเสร็จได้ แต่ก็อาจมีผลกับประสิทธิภาพเล็กน้อยขอขอบคุณ AWS/Annapurna/Nitro/Lightbits ที่นำ NVMe-over-TCP มาสู่ Linux
https://www.techtarget.com/searchstorage/news/252459311/Ligh...
“สมาคม NVM Express ให้สัตยาบัน NVMe/TCP เป็น binding transport layer ในเดือนพฤศจิกายน 2018 มาตรฐานนี้พัฒนาต่อยอดมาจากโค้ดเบสที่ทีมวิศวกรรมของ Lightbits ส่งให้ NVM Express ในตอนแรก”
https://www.lightbitslabs.com/blog/linux-distributions-nvme-...
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/lin...
เมื่อเทียบกับด้านล่างนี้แล้ว วิธีนั้นดูยุ่งยากกว่ามาก:
nbdkit file /dev/nvme0n1,nbdcopy nbd://otherlaptop localfilenbdcopyจัดการ ไฟล์ sparse ได้ และสามารถปรับจำนวนการเชื่อมต่อกับจำนวนเธรดให้เหมาะกับจำนวนคอร์ได้ รวมถึงบังคับ flush ก่อนจบงานได้ และยังเปิดแถบความคืบหน้าได้ด้วย ถ้าไดรฟ์ไม่ได้เข้ารหัสก็รองรับ TLS เช่นกันเมื่อเร็ว ๆ นี้ต้องติดตั้ง xubuntu ลงบนโน้ตบุ๊กเครื่องใหม่ แต่ครั้งนี้อยากจัดระเบียบการตั้งค่าบางส่วนใหม่แทนที่จะโคลนทั้งหมดเหมือนก่อน
การโอนข้อมูลผ่านสาย USB-C ที่ความเร็ว 10Gb/s มีประโยชน์มาก เพราะอีกทางเลือกมีแค่ WiFi
แค่เสียบคอมพิวเตอร์เข้าหากันก็จะเกิดเครือข่ายชั่วคราว แล้วก็ย้ายข้อมูลด้วย
rsyncได้เลย จากที่เห็นลิงก์ก็วิ่งเต็มอยู่แล้ว เลยดูเหมือนการใช้โปรโตคอลอื่นจะไม่ได้มีประโยชน์มากนัก แน่นอนว่าการเรียนรู้อะไรใหม่ ๆ เป็นเรื่องดี แต่บางทีอาจไม่ใช่ตอนที่กำลังโคลนโน้ตบุ๊กตัวการโอนเร็วมาก ย้าย 1TB เสร็จในไม่กี่นาที ครั้งนี้ไม่ได้ใช้การเข้ารหัสด้วยเลยง่ายขึ้นมาก
ไม่ค่อยเข้าใจว่าทำไมไม่ pipe btrfs ผ่านเครือข่าย ก่อนอื่นสร้าง btrfs snapshot แล้วใช้
btrfs send => nc => network => nc => btrfs receiveก็จะส่งเฉพาะบล็อกที่ใช้งานอยู่btrfs send/receiveผ่าน SSH ตลอดและมันทำงานได้ดีมาก น่าจะเปิด SSH server จากไลฟ์เซสชันของ GRML ได้ไม่ยากด้วยแต่มีข้อควรระวังอย่างหนึ่งคือใน btrfs ไม่สามารถส่ง snapshot แบบ recursive ได้ ดังนั้นถ้ามี recursive snapshot เยอะ การ mirror โครงสร้างเดียวกันไปยังดิสก์ใหม่จะค่อนข้างยาก เรื่องนี้อาจเกิดกับ Docker/LXD/Incus ได้ ฉันชอบ btrfs นะ แต่เรื่อง recursive send/receive นี่ ZFS ทำได้ดีกว่า
เมื่อเร็ว ๆ นี้ต้องคัดลอกไฟล์ขนาดประมาณ 200GB ผ่าน WiFi อยากให้ถ้าการเชื่อมต่อล้มเหลวจะได้ไม่ต้องเริ่มใหม่ตั้งแต่ต้น และไม่ให้ข้อมูลสูญหาย เลยใช้
rsyncแต่ใช้เวลาอย่างน้อย 6 ชั่วโมง เลยสงสัยว่ามีวิธีที่ดีกว่านี้ไหมแล้ววิธีแบบ
ddให้การรับประกันอะไรบ้าง ต้องเอา md5 ของ block device ปลายทางมาเทียบหรือเปล่า?WiFi มีปัจจัยคอขวดด้านประสิทธิภาพได้เยอะกว่ามาก แค่ต่ออุปกรณ์สักตัวเข้ากับเราเตอร์ด้วยสาย แล้วให้อีกตัวใช้งานไร้สาย ก็ช่วยได้พอสมควรแล้ว
rsyncส่งได้ทีละไฟล์เท่านั้น คุณอาจแบ่งรายชื่อไฟล์ด้วยxargs/parallelแล้วรันrsyncหลายอินสแตนซ์ หรือใช้ตัวอย่างrcloneที่รองรับ การส่งแบบขนาน ในตัว-zเพื่อบีบอัดหรือไม่ ถ้าใช้อีเธอร์เน็ตได้ บนอุปกรณ์ส่วนใหญ่น่าจะเข้าใกล้ 100MB/s และใช้เวลาราว 35 นาทีrsyncคือ SSH นั่นก็มักเป็นคอขวดได้ OpenSSH เคยมีข้อจำกัดด้านประสิทธิภาพแปลก ๆ มาตามประวัติศาสตร์ และบางครั้งต้องใช้แพตช์ที่ไม่ค่อยมีคนรู้จักเพื่อหลีกเลี่ยงมัน ถ้า CPU ไม่ใช่คอขวด การเปิดการบีบอัดก็ช่วยได้“ในระบบเครือข่ายคอมพิวเตอร์ Carrier-sense multiple access with collision avoidance (CSMA/CA) เป็นวิธีการเข้าถึงสื่อร่วมกันของเครือข่ายที่ใช้การตรวจจับพาหะ แต่จะเริ่มส่งข้อมูลก็ต่อเมื่อพบว่าช่องสัญญาณ ‘ว่าง’ เท่านั้น เพื่อหลีกเลี่ยงการชนกัน เมื่อส่งข้อมูล โหนดจะส่งข้อมูลแพ็กเก็ตทั้งก้อน
เรื่องนี้สำคัญเป็นพิเศษในเครือข่ายไร้สาย เพราะตัวส่งไร้สายจะทำให้ตัวรับของตัวเองไวต่อสัญญาณลดลงจนใช้งานไม่ได้ระหว่างการส่งแพ็กเก็ต จึงไม่สามารถใช้ CSMA/CD ซึ่งเป็นวิธีตรวจจับการชนกันได้
CSMA/CA มีความเชื่อถือได้ต่ำเพราะปัญหา hidden node
CSMA/CA เป็นโปรโตคอลที่ทำงานในชั้น data link”
https://en.wikipedia.org/wiki/Carrier-sense_multiple_access_...
วิธีนี้อาจมีข้อดีของมัน แต่ตอนที่ฉันย้ายโน้ตบุ๊กในอดีต ฉันจะเปิดตัวติดตั้งบนทั้งสองฝั่งแล้วใช้
ddร่วมกับncจำได้ว่าเพิ่ม gzip เข้าไปด้วยเพื่อให้ส่งช่วงที่เป็นศูนย์ยาว ๆ ได้เร็วขึ้นถ้าโน้ตบุ๊กเครื่องใหม่ไม่มีพอร์ตอีเธอร์เน็ต วิธีแบบแฮ็ก ๆ ของฉันอาจเร็วกว่านิดหน่อยเพราะมีการบีบอัด เพราะข้อจำกัดที่การบีบอัดเพิ่มเข้ามาคงยังไม่ถึงจุดที่เป็นคอขวดบนลิงก์เครือข่ายที่เร็วขนาดนั้น
ใช้ Clonezilla ไปเลยไม่ได้หรือ? มันคัดลอกเฉพาะบล็อกข้อมูลจริงและยังปรับขนาดพาร์ทิชันอัตโนมัติได้ด้วย ฉันทำแบบนั้นตลอด
แน่นอนว่าโดยปกติฉันจะถอดดิสก์ NVMe ออกจากโน้ตบุ๊กแล้วเอาไปเสียบกับ dock ความเร็วสูง
ฉันยังไม่ไว้ใจมันถึงขั้นปล่อยทิ้งไว้เฉย ๆ ได้ทั้งหมด การสำรองข้อมูลไม่เหมือนกับการรวมการสำรองและการกู้คืนเข้าด้วยกัน ดังนั้นควรทดลองไว้ก่อน และ Clonezilla ก็อาจมีปัญหาได้เวลาสร้างพาร์ทิชันใหม่บนดิสก์ที่แตกต่างจากต้นทางมาก
น่าจะหลายสิบปีแล้วที่ฉันไม่ได้ “ติดตั้ง” ระบบปฏิบัติการลงเดสก์ท็อปหรือโน้ตบุ๊กแบบจริงจัง ฉันมักคัดลอกไฟล์แล้วค่อยปรับเฉพาะส่วนที่จำเป็น โดยปกติจะถือโอกาสนี้อัปเดตพารามิเตอร์อย่างชนิดของไฟล์ซิสเต็ม ขนาดบล็อก การเข้ารหัส ฯลฯ ด้วยการสร้างไฟล์ซิสเต็มใหม่แล้วใช้
rsyncย้ายไฟล์ถึงอย่างนั้น ถ้าเป็นคนที่วางแผนล่วงหน้า การใช้แนวทางเชิงประกาศมากกว่าอย่าง NixOS ที่คัดลอกแค่การตั้งค่าแล้วติดตั้งส่วนที่เหลือใหม่อัตโนมัติ ก็น่าจะดีกว่า
ถ้าเชื่อมต่ออุปกรณ์กันโดยตรงผ่าน WiFi โดยไม่มี AP คั่นกลาง น่าจะเพิ่ม ความเร็วในการรับส่ง ได้เป็นสองเท่า ในสถานการณ์นี้ก็น่าลองทำอยู่