Những gì bạn yêu cầu làm được thực hiện ít nhất một lần trên mọi hệ thống Linux được cấu hình phổ biến ngoài kia. Hầu hết sử dụng công cụ có sẵn bằng cách busybox
gọi switch_root
:
Điều gì switch_root
làm là xóa tất cả các tệp ra khỏi rootfs (để giải phóng bộ nhớ) và sau đó chroot
vào một hệ thống tệp mới và thực hiện một quá trình init mới ra khỏi hệ thống tệp mới.
Điều này xảy ra trong quá trình khởi tạo hệ thống. Khi một hệ thống linux được khởi động, kernel sẽ đưa hệ thống lên theo từng giai đoạn. Lúc đầu, hạt nhân được thực thi trong bộ nhớ bởi một số hệ thống khác - chẳng hạn như bộ tải khởi động hoặc phần sụn - và tại thời điểm này, hạt nhân chỉ còn lại để tự bảo vệ - không có tham chiếu khung thực cho hệ thống mà trên đó nó vừa được thực hiện.
Đây là những gì initramfs
hình ảnh thường được thêm vào không gian bộ nhớ của nó (nhưng cũng có thể được biên dịch trực tiếp vào kernel) được thiết kế để xử lý. Các initramfs là một hình ảnh hệ thống tập tin gốc thực sự (hoàn thành w / /dev
và /proc
what-have-you) - đó là hệ thống tập tin gốc đầu tiên được gắn bởi một nhân linux. Nó bao gồm một kho lưu trữ hệ thống tập tin gốc có chứa bất kỳ / tất cả các mô-đun / tệp cấu hình dành riêng cho hệ thống cần thiết để lấy kernel trên chân của nó - để khởi động nó.
Dù sao, kernel gắn kết lưu trữ dưới dạng rootfs (về cơ bản là một tmpfs ) và sau đó làm bất cứ điều gì cần thiết để tìm một số khác/
và gắn cái đó lên trên nó. Nó làm điều này mỗi khi bạn khởi động hệ thống của bạn. Nó có thể làm điều đó một lần nữa và không cần dùng đến các hack không cần thiết như unionfs hay aufs - cả hai đều có khả năng gây ra tất cả các loại biến chứng cụ thể và chi tiết cấu hình cụ thể (không đề cập đến sự không ổn định) .
Trong phần switch_root
mô tả được trích dẫn ở trên, có lẽ bạn sẽ nhận thấy cụm từ xóa tất cả các tệp khỏi rootfs . Rõ ràng đây không phải là một hành vi mong muốn khi chuyển ra khỏi rootfs dựa trên đĩa. Nhưng nó chỉ xảy ra theo cách đó switch_root
để giải phóng bộ nhớ cho hệ thống tập tin dựa trên ram - và hoàn toàn không cần thiết. Đây là một số chi tiết từ bài viết được trích dẫn trước đó:
Đoạn mã shell sau đây trình bày cách sử dụng switch_root:
# First, find and mount the new filesystem.
mkdir /newroot
mount /dev/whatever /newroot
# Unmount everything else you've attached to rootfs. (Moving the filesystems
# into newroot is something useful to do with them.)
mount --move /sys /newroot/sys
mount --move /proc /newroot/proc
mount --move /dev /newroot/dev
# Now switch to the new filesystem, and run /sbin/init out of it. Don't
# forget the "exec" here, because you want the new init program to inherit
# PID 1.
exec switch_root /newroot /sbin/init
Như bạn thấy ở trên, xử lý /dev
, /proc
và /sys
các vấn đề liên quan có thể được rất đơn giản thực hiện. Nhân tiện, nếu bạn định lớp bất kỳ thú mount --move
cưỡi nào, bạn sẽ phải đối phó không chỉ với mtab
và mount
bất kỳ biến chứng nào khác được giới thiệu bởi hệ thống phân lớp của bạn. Nó đơn giản hơn để làm giống như bạn mô tả trong câu hỏi - mount root từ một nơi khác.
Bạn sẽ cần phải làm về cơ bản tất cả những thứ đó xảy ra trong một cấu hình initramfs điển hình và rất ít khác - (mà không nhằm mục đích bao gồm Debian hoặc Redhat initramfs hình ảnh 's - cả hai đều được cách qua chế) . Vấn đề thực sự duy nhất bạn có thể gặp phải là làm thế nào để khiến cho PID1 tuân theo - nếu bạn để init hệ thống của mình bị mắc kẹt trên một số rootfs mồ côi, những thứ rất kỳ lạ có thể sớm bắt đầu xảy ra trên hệ thống của bạn. Cách rõ ràng để xử lý việc này là chuẩn bị từ initramfs trên. Chỉ cần đảm bảo rằng init
quy trình của đĩa cứng của bạn được chuẩn bị cho exec
một quá trình khác sau này khi bạn muốn chuyển đổi rễ. Nếu bạn đang sử dụng systemd
init
thì biến chứng này đã được xử lý cho bạn:
systemctl --help
...
switch-root ROOT [INIT] Change to a different root file system
...
Nếu bạn đang sử dụng systemd
dựa trên cơ sở, init
bạn nên nghiên cứu các tệp đơn vị /usr/lib/systemd/system/initrd*
để có ý tưởng về systemd
tình huống chuyển đổi gốc theo kiểu kịch bản thường xảy ra như thế nào.
Một cách khác để đi về nó có thể là để bắt chước busybox
's switch_root
trong initramfs - nhưng để bỏ qua những phần mà bạn xóa tất cả các tập tin gốc ban đầu của. Arch Linux hệ thống được cấu hình với systemd
trong initramfs làm điều này. Trên những trang, gắn kết initramfs gốc mình thành /newroot
's /run/initramfs
trước khi thực hiện chuyển đổi sở và là những gì hệ thống rơi trở lại lúc tắt máy để xử lý sạch ngủ / đình chỉ và tương tự. Đó có thể là cách tốt nhất để xử lý trường hợp của bạn, thực sự - chỉ là một hệ thống gốc nhỏ bé, bền bỉ mà bạn sử dụng cho các ứng dụng đã được root riêng lẻ.