Các hướng dẫn bên dưới được tạo để hoạt động với CentOS 7, nhưng chúng có thể dễ dàng đủ chuyển sang bất kỳ bản phân phối nào chạy systemd. Tất cả các lệnh được chạy như root.
Đảm bảo hệ thống ở trạng thái ổn định
Hãy chắc chắn rằng không có ai khác đang sử dụng nó và không có gì quan trọng khác đang diễn ra. Có lẽ nên dừng các đơn vị cung cấp dịch vụ như httpd hoặc ftpd, chỉ để đảm bảo các kết nối bên ngoài không phá vỡ mọi thứ ở giữa.
systemctl stop httpd
systemctl stop nfs-server
# and so on....
Ngắt kết nối tất cả các hệ thống tập tin không sử dụng
umount -a
Điều này sẽ in một số cảnh báo 'Target đang bận', cho chính khối lượng gốc và cho các FS tạm thời / hệ thống khác nhau. Đây có thể được bỏ qua cho thời điểm này. Điều quan trọng là không có hệ thống tập tin trên đĩa nào được gắn kết, ngoại trừ chính hệ thống tập tin gốc. Xác nhận điều này:
# mount alone provides the info, but column makes it possible to read
mount | column -t
Nếu bạn thấy bất kỳ hệ thống tập tin trên đĩa nào vẫn được gắn kết, thì cái gì đó vẫn đang chạy mà không nên. Kiểm tra xem nó đang sử dụng cái gì fuser
:
# if necessary:
yum install psmisc
# then:
fuser -vm <mountpoint>
systemctl stop <whatever>
umount -a
# repeat as required...
Làm gốc tạm thời
mkdir /tmp/tmproot
mount -t tmpfs none /tmp/tmproot
mkdir /tmp/tmproot/{proc,sys,dev,run,usr,var,tmp,oldroot}
cp -ax /{bin,etc,mnt,sbin,lib,lib64} /tmp/tmproot/
cp -ax /usr/{bin,sbin,lib,lib64} /tmp/tmproot/usr/
cp -ax /var/{account,empty,lib,local,lock,nis,opt,preserve,run,spool,tmp,yp} /tmp/tmproot/var/
Điều này tạo ra một hệ thống gốc rất tối thiểu, phá vỡ (trong số những thứ khác) xem manpage (không /usr/share
), tùy chỉnh ở cấp độ người dùng (không /root
hoặc /home
), v.v. Điều này là có chủ ý, vì nó cấu thành sự khuyến khích không ở trong một hệ thống gốc được bồi thẩm đoàn như vậy lâu hơn cần thiết.
Tại thời điểm này, bạn cũng nên đảm bảo rằng tất cả các phần mềm cần thiết đã được cài đặt, vì nó cũng sẽ chắc chắn phá vỡ trình quản lý gói. Lướt qua tất cả các bước và đảm bảo bạn có các tệp thực thi cần thiết.
Xoay vào gốc
mount --make-rprivate / # necessary for pivot_root to work
pivot_root /tmp/tmproot /tmp/tmproot/oldroot
for i in dev proc sys run; do mount --move /oldroot/$i /$i; done
systemd gây ra các mount để cho phép chia sẻ cây con theo mặc định (như với mount --make-shared
) và điều này gây ra pivot_root
lỗi. Do đó, chúng tôi tắt nó trên toàn cầu với mount --make-rprivate /
. Hệ thống và hệ thống tập tin tạm thời được chuyển bán buôn vào root mới. Điều này là cần thiết để làm cho nó hoạt động ở tất cả; các ổ cắm để liên lạc với systemd, trong số những thứ khác, sống trong đó /run
, và vì vậy không có cách nào để làm cho các tiến trình chạy đóng nó.
Đảm bảo truy cập từ xa sống sót sau khi chuyển đổi
systemctl restart sshd
systemctl status sshd
Sau khi khởi động lại sshd, đảm bảo rằng bạn có thể vào, bằng cách mở một thiết bị đầu cuối khác và kết nối lại với máy thông qua ssh. Nếu bạn không thể, hãy khắc phục sự cố trước khi tiếp tục.
Khi bạn đã xác minh, bạn có thể kết nối lại, thoát khỏi trình bao bạn đang sử dụng và kết nối lại. Điều này cho phép các ngã ba còn lại sshd
thoát ra và đảm bảo cái mới không giữ /oldroot
.
Đóng mọi thứ vẫn sử dụng root cũ
fuser -vm /oldroot
Điều này sẽ in một danh sách các quy trình vẫn đang giữ trên thư mục gốc cũ. Trên hệ thống của tôi, nó trông như thế này:
USER PID ACCESS COMMAND
/oldroot: root kernel mount /oldroot
root 1 ...e. systemd
root 549 ...e. systemd-journal
root 563 ...e. lvmetad
root 581 f..e. systemd-udevd
root 700 F..e. auditd
root 723 ...e. NetworkManager
root 727 ...e. irqbalance
root 730 F..e. tuned
root 736 ...e. smartd
root 737 F..e. rsyslogd
root 741 ...e. abrtd
chrony 742 ...e. chronyd
root 743 ...e. abrt-watch-log
libstoragemgmt 745 ...e. lsmd
root 746 ...e. systemd-logind
dbus 747 ...e. dbus-daemon
root 753 ..ce. atd
root 754 ...e. crond
root 770 ...e. agetty
polkitd 782 ...e. polkitd
root 1682 F.ce. master
postfix 1714 ..ce. qmgr
postfix 12658 ..ce. pickup
Bạn cần phải đối phó với từng quy trình trước khi bạn có thể ngắt kết nối /oldroot
. Cách tiếp cận vũ phu chỉ đơn giản là kill $PID
cho mỗi người, nhưng điều này có thể phá vỡ mọi thứ. Để làm điều đó nhẹ nhàng hơn:
systemctl | grep running
Điều này tạo ra một danh sách các dịch vụ đang chạy. Bạn sẽ có thể tương quan điều này với danh sách các quy trình đang nắm giữ /oldroot
, sau đó phát hành systemctl restart
cho từng quy trình . Một số dịch vụ sẽ từ chối đưa ra trong thư mục gốc tạm thời và vào trạng thái không thành công; những điều này không thực sự quan trọng vào lúc này.
Nếu ổ đĩa gốc bạn muốn thay đổi kích thước là ổ LVM, bạn cũng có thể cần phải khởi động lại một số dịch vụ đang chạy khác, ngay cả khi chúng không hiển thị trong danh sách được tạo bởi fuser -vm /oldroot
. Nếu bạn thấy bạn không thể thay đổi kích thước ổ LVM trong Bước 7, hãy thử systemctl restart systemd-udevd
.
Một số quy trình không thể được xử lý thông qua đơn giản systemctl restart
. Đối với tôi những thứ này bao gồm auditd
(không muốn bị giết qua systemctl
, và vì vậy chỉ muốn a kill -15
). Đây có thể được giải quyết với cá nhân.
Quá trình cuối cùng bạn sẽ tìm thấy, thường là systemd
chính nó. Đối với điều này, chạy systemctl daemon-reexec
.
Khi bạn đã hoàn tất, bảng sẽ trông như thế này:
USER PID ACCESS COMMAND
/oldroot: root kernel mount /oldroot
Tháo gốc
umount /oldroot
Tại thời điểm này, bạn có thể thực hiện bất kỳ thao tác nào bạn yêu cầu. Câu hỏi ban đầu cần một resize2fs
lời mời đơn giản , nhưng bạn có thể làm bất cứ điều gì bạn muốn ở đây; một trường hợp sử dụng khác là chuyển hệ thống tập tin gốc từ một phân vùng đơn giản sang LVM / RAID / bất cứ điều gì.
Xoay gốc trở lại
mount <blockdev> /oldroot
mount --make-rprivate / # again
pivot_root /oldroot /oldroot/tmp/tmproot
for i in dev proc sys run; do mount --move /tmp/tmproot/$i /$i; done
Đây là một sự đảo ngược đơn giản của bước 4.
Vứt bỏ gốc tạm thời
Lặp lại các bước 5 và 6, ngoại trừ sử dụng /tmp/tmproot
thay thế /oldroot
. Sau đó:
umount /tmp/tmproot
rmdir /tmp/tmproot
Vì nó là một tmpfs, tại thời điểm này, gốc tạm thời tan vào ether, không bao giờ được nhìn thấy nữa.
Đặt mọi thứ trở lại vị trí của họ
Mount hệ thống tập tin một lần nữa:
mount -a
Tại thời điểm này, bạn cũng nên cập nhật /etc/fstab
và grub.cfg
phù hợp với bất kỳ điều chỉnh nào bạn đã thực hiện trong bước 7.
Khởi động lại bất kỳ dịch vụ thất bại:
systemctl | grep failed
systemctl restart <whatever>
Cho phép chia sẻ lại một lần nữa:
mount --make-rshared /
Bắt đầu các đơn vị dịch vụ đã dừng - bạn có thể sử dụng lệnh đơn này:
systemctl isolate default.target
Và bạn đã hoàn thành.
Rất cám ơn Andrew Wood, người đã thực hiện quá trình tiến hóa này trên RHEL4 và steve, người đã cung cấp cho tôi liên kết đến cái trước.