以前にルートファイルシステムの下にあったデータを専用のマウントポイントに移動するには、システムのパーティションを再配置する必要があることに気付きました。ボリュームはすべてLVMにあるため、これは比較的簡単です。新しいボリュームを作成し、データをそれらに移動し、ルートファイルシステムを縮小してから、適切なポイントに新しいボリュームをマウントします。
問題はステップ3で、ルートファイルシステムを縮小します。関連するファイルシステムはext4であるため、オンラインでのサイズ変更がサポートされています。ただし、マウントされている間は、ファイルシステムを拡張することしかできません。パーティションを縮小するには、パーティションをアンマウントする必要があります。もちろん、通常の操作ではルートパーティションではマウントを解除できません。
Webに関する回答は、LiveCDまたはその他のレスキューメディアの起動、縮小操作の実行、インストールされたシステムへの再起動を中心に展開しているようです。ただし、問題のシステムはリモートであり、SSH経由でのみアクセスできます。再起動はできますが、レスキューディスクを起動してコンソールから操作することはできません。
リモートシェルアクセスを維持しながら、ルートファイルシステムをアンマウントするにはどうすればよいですか?
承認された回答:
この問題を解決する上で、http://www.ivarch.com/blogs/oss/2007/01/resize-a-live-root-fs-a-howto.shtmlで提供される情報は極めて重要でした。ただし、そのガイドは非常に古いバージョンのRHELを対象としており、さまざまな情報が廃止されました。
以下の手順は、CentOS 7で動作するように作成されていますが、systemdを実行するすべてのディストリビューションに簡単に転送できるはずです。すべてのコマンドはrootとして実行されます。
-
システムが安定した状態にあることを確認します
他の誰もそれを使用しておらず、他に重要なことが起こっていないことを確認してください。外部接続によって途中で問題が発生しないようにするために、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/
これにより、非常に最小限のルートシステムが作成され、(とりわけ)マンページの表示が中断されます(
/usr/share
はありません)。 )、ユーザーレベルのカスタマイズ(/root
なし または/home
)など。これは意図的なものであり、必要以上にそのような仮帆装の根系に留まらないように促すものです。この時点で、必要なすべてのソフトウェアがインストールされていることも確認する必要があります。これにより、パッケージマネージャーも確実に機能しなくなります。すべての手順を確認し、必要な実行可能ファイルがあることを確認してください。
-
ルートにピボット
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
を試してください。 。一部のプロセスは、単純な
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/その他に転送することです。 -
ルートを元に戻します
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
この時点で、
/etc/fstab
も更新する必要があります およびgrub.cfg
手順7で行った調整に従って。失敗したサービスを再起動します:
systemctl | grep failed systemctl restart <whatever>
共有サブツリーを再度許可する:
mount --make-rshared /
停止したサービスユニットを開始します–次の1つのコマンドを使用できます:
systemctl isolate default.target
これで完了です。
関連:Kaliにソフトウェアセンターをインストールできませんか?RHEL4でこの進化を実現してくれたAndrewWoodと、前者へのリンクを提供してくれたsteveに感謝します。