以下の手順は、CentOS 7で動作するように作成されていますが、systemdを実行するディストリビューションに簡単に十分に転送できるはずです。すべてのコマンドはルートとして実行されます。
システムが安定した状態であることを確認します
他の人がそれを使用していないこと、そして他に重要なことが何も起きていないことを確認してください。外部接続が途中で物事を混乱させないようにするために、httpdやftpdなどのサービス提供ユニットを停止することをお勧めします。
systemctl stop httpd
systemctl stop nfs-server
# and so on....
未使用のファイルシステムをすべてアンマウントします
umount -a
これにより、ルートボリューム自体およびさまざまな一時/システムFSに対して、多数の「ターゲットがビジーです」という警告が出力されます。現時点ではこれらは無視できます。重要なのは、ルートファイルシステム自体を除き、ディスク上のファイルシステムがマウントされていないことです。これを確認してください:
# mount alone provides the info, but column makes it possible to read
mount | column -t
ディスク上のファイルシステムがまだマウントされているのを見ると、そうでないはずの何かがまだ実行中です。使用しているものを確認しfuser
ます。
# if necessary:
yum install psmisc
# then:
fuser -vm <mountpoint>
systemctl stop <whatever>
umount -a
# repeat as required...
一時的なルートを作成する
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/
これにより、非常に最小限のルートシステムが作成され、(特に)マンページの表示(no /usr/share
)、ユーザーレベルのカスタマイズ(no /root
または/home
)などが中断されます。これは意図的なものであり、必要に応じてそのようなju審員が管理するルートシステムにとどまらないように奨励するものです。
この時点で、必要なソフトウェアがすべてインストールされていることも確認する必要があります。これにより、パッケージマネージャーも確実に破損します。すべての手順を一目見ながら、必要な実行可能ファイルがあることを確認してください。
ルートへのピボット
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により、マウントはデフォルトで(と同様にmount --make-shared
)サブツリーの共有を許可し、これによりpivot_root
失敗します。したがって、でグローバルにこれをオフにしmount --make-rprivate /
ます。システムおよび一時ファイルシステムは、新しいルートに大量に移動されます。これは、機能させるために必要です。systemdとの通信用のソケットは、特にに/run
存在するため、実行中のプロセスにそれを閉じる方法はありません。
リモートアクセスが切り替えを生き延びたことを確認する
systemctl restart sshd
systemctl status sshd
sshdを再起動した後、別のターミナルを開き、sshを介してマシンに再度接続することにより、取得できることを確認します。できない場合は、先に進む前に問題を修正してください。
再度接続できることを確認したら、現在使用しているシェルを終了して再接続します。これにより、残りの分岐sshd
が終了し、新しい分岐が保持されないことが保証されます/oldroot
。
まだ古いルートを使用してすべてを閉じます
fuser -vm /oldroot
これにより、古いルートディレクトリに保持されているプロセスのリストが出力されます。私のシステムでは、このように見えました:
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
アンマウントする前に、これらの各プロセスを処理する必要があります/oldroot
。ブルートフォースアプローチはkill $PID
それぞれに対してのみですが、これは物事を壊す可能性があります。よりソフトに行うには:
systemctl | grep running
これにより、実行中のサービスのリストが作成されます。これを保持しているプロセスのリストと相関させてから/oldroot
、systemctl restart
各プロセスに対して発行できるはずです。一部のサービスは一時的なルートでの起動を拒否し、障害状態になります。現時点ではこれらは重要ではありません。
サイズを変更するルートドライブがLVMドライブである場合は、で作成されたリストに表示されない場合でも、実行中の他のサービスを再起動する必要がありますfuser -vm /oldroot
。手順7でLVMドライブのサイズを変更できない場合は、を試してくださいsystemctl restart systemd-udevd
。
一部のプロセスは、simpleを介して処理できませんsystemctl restart
。私にとっては、これらが含まれていますauditd
(これはを介して殺されるのが好きではないsystemctl
ので、単に望んでいましたkill -15
)。これらは個別に処理できます。
通常、最後に見つかるプロセスはsystemd
それ自体です。これには、を実行しsystemctl daemon-reexec
ます。
完了すると、テーブルは次のようになります。
USER PID ACCESS COMMAND
/oldroot: root kernel mount /oldroot
古いルートをアンマウントします
umount /oldroot
この時点で、必要な操作を実行できます。元の質問には簡単なresize2fs
呼び出しが必要でしたが、ここでは何でもできます。もう1つのユースケースは、ルートファイルシステムを単純なパーティションからLVM / RAID / whateverに転送することです。
ルートをピボットバックする
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
これは、ステップ4の単純な反転です。
一時ルートを破棄します
の/tmp/tmproot
代わりに使用することを除いて、手順5と6を繰り返します/oldroot
。次に:
umount /tmp/tmproot
rmdir /tmp/tmproot
tmpfsであるため、この時点で一時的なルートはエーテルに溶解し、二度と見られなくなります。
場所に物を戻す
ファイルシステムを再度マウントします。
mount -a
この時点で、手順7で行った調整に従って更新する必要も/etc/fstab
ありgrub.cfg
ます。
失敗したサービスを再起動します。
systemctl | grep failed
systemctl restart <whatever>
共有サブツリーを再度許可します。
mount --make-rshared /
停止したサービスユニットを開始します。この単一のコマンドを使用できます。
systemctl isolate default.target