파일 시스템이 마운트 해제되었지만 여전히 사용 중인 이유는 무엇입니까?

파일 시스템이 마운트 해제되었지만 여전히 사용 중인 이유는 무엇입니까?

나는 오랫동안 ext4 파일 시스템을 사용해 왔지만 ext4 파일 시스템에서 이상한 동작을 본 것은 이번이 처음입니다. 기본 장치에서 I/O 오류가 발생했으며
ext4 파일 시스템이 존재하는 곳에 파일 시스템이 읽기 전용으로 다시 마운트되었습니다 . 이것은 괜찮으며 구성에 대해 예상된 대로입니다. 그러나 알 수 없는 이유로 인해 이제 파일 시스템을 완전히 마운트 해제하는 것이 불가능합니다. 명령이 성공적으로 반환됩니다. 추가로 명령을 실행하면 "설치되지 않음"이 표시됩니다. 명령 출력에서 ​​설치 항목이 사라졌습니다. 파일 시스템은 다른 곳에 마운트되지 않습니다. 하지만. 첫째: dmesg에 일반적인 텍스트가 표시되지 않습니다. 사실 dmesg에는 아무것도 없습니다. 두 번째 사항(그 자체로 뭔가 잘못되었음을 나타냄):/dev/dm-2



umount /the/mount/point
mount

EXT4-fs: unmounting filesystem

root# cat /proc/meminfo | grep dirty
Dirty:           9457728 kB
root# time sync

real    0m0.012s                                                                                
user    0m0.000s                                                                                
sys     0m0.002s
root# cat /proc/meminfo | grep dirty
Dirty:           9453632 kB

세 번째 사항: 디버그 디렉터리가 /sys/fs/ext4/dm-2여전히 존재합니다. /sys/fs/ext4/dm-2/simulate_fail파일 시스템이 닫히기를 바라면서 "1"을 써 보십시오 . 하지만 아무것도 하지 않고 dmesg에 아무것도 표시하지 않습니다.
마지막으로 네 번째는 장치를 사용할 수 없게 만듭니다.

root# e2fsck -fy /dev/dm-2
e2fsck 1.46.5 (30-Dec-2021)
/dev/dm-2 is in use.
e2fsck: Cannot continue, aborting.

재부팅 등이 가능하다는 것을 알고 있습니다. 이 질문은 간단한 초보자 문제를 해결하기 위한 것이 아닙니다. ext4 파일 시스템에 대한 경험이 있는 누군가가 이 동작의 원인을 이해하는 데 도움을 줄 수 있기를 바랍니다.
장치 dm-2는 다른 곳에 설치되지도 않고, 번들로 마운트되지도 않으며, 다른 용도로 사용되지도 않습니다.
으로 측정했을 때 더티 캐시를 사용하는 다른 항목은 없었습니다 cat /proc/meminfo | grep dirty.
성공적인 제거 호출은 MNT_DETACH(unused -l플래그)가 아닙니다. 그럼에도 불구하고 거의 즉시 성공했습니다(이상하네요). 마운트 지점은 더 이상 마운트되지 않습니다. 하지만 위에서 설명한 것처럼 파일 시스템이 마운트 해제되지 않은 것을 쉽게 알 수 있습니다.

업데이트: AB가 지적했듯이 파일 시스템이 여전히 다른 네임스페이스에 마운트되어 있는지 확인해 보았습니다. 다른 네임스페이스에 설치하지 않았으므로 아무 것도 표시되지 않을 것으로 예상했습니다. 그런데 놀랍게도 다른 네임스페이스에 설치되었고 놀랍게도 (사용자 이름이 변경되었습니다):

4026533177 mnt       1 3411291 an-unrelated-nonroot-user       xdg-dbus-proxy --args=43

해당 네임스페이스로 이동하여 이를 사용하여 제거하려고 시도했는데, nsenter -t 3411291 -m -- umount /the/mount/point
그 결과 dmesg에서 분할 오류(코어 덤프)가 발생했습니다.

[970130.866738] Buffer I/O error on dev dm-2, logical block 0, lost sync page write
[970130.867925] EXT4-fs error (device dm-2): ext4_mb_release_inode_pa:4846: group 9239, free 2048, pa_free 4
[970130.870291] Buffer I/O error on dev dm-2, logical block 0, lost sync page write
[970130.949466] divide error: 0000 [#1] PREEMPT SMP PTI
[970130.950677] CPU: 49 PID: 4118804 Comm: umount Tainted: P        W  OE      6.1.68-missmika #1
[970130.953056] Hardware name: OEM X79G/X79G, BIOS 4.6.5 08/02/2022
[970130.953121] RIP: 0010:mb_update_avg_fragment_size+0x35/0x120
[970130.953121] Code: 41 54 53 4c 8b a7 98 03 00 00 41 f6 44 24 7c 80 0f 84 9a 00 00 00 8b 46 14 48 89 f3 85 c0 0f 84 8c 00 00 00 99 b9 ff ff ff ff <f7> 7e 18 0f bd c8 41 89 cd 41 83 ed 01 0f 88 ce 00 00 00 0f b6 47
[970130.957139] RSP: 0018:ffffb909e3123a28 EFLAGS: 00010202
[970130.957139] RAX: 000000000000082a RBX: ffff91140ac554d8 RCX: 00000000ffffffff
[970130.957139] RDX: 0000000000000000 RSI: ffff91140ac554d8 RDI: ffff910ead74f800
[970130.957139] RBP: ffffb909e3123a40 R08: 0000000000000000 R09: 0000000000004800
[970130.957139] R10: ffff910ead74f800 R11: ffff9114b7126000 R12: ffff910eb31d2000
[970130.957139] R13: 0000000000000007 R14: ffffb909e3123b80 R15: ffff911d732beffc
[970130.957139] FS:  00007f6d94ab4800(0000) GS:ffff911d7fcc0000(0000) knlGS:0000000000000000
[970130.957139] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[970130.957139] CR2: 00003d140602f000 CR3: 0000000365690002 CR4: 00000000001706e0
[970130.957139] Call Trace:
[970130.957139]  <TASK>
[970130.957139]  ? show_regs.cold+0x1a/0x1f
[970130.957139]  ? __die_body+0x24/0x70
[970130.957139]  ? __die+0x2f/0x3b
[970130.957139]  ? die+0x34/0x60
[970130.957139]  ? do_trap+0xdf/0x100
[970130.957139]  ? do_error_trap+0x73/0xa0
[970130.957139]  ? mb_update_avg_fragment_size+0x35/0x120
[970130.957139]  ? exc_divide_error+0x3f/0x60
[970130.957139]  ? mb_update_avg_fragment_size+0x35/0x120
[970130.957139]  ? asm_exc_divide_error+0x1f/0x30
[970130.957139]  ? mb_update_avg_fragment_size+0x35/0x120
[970130.957139]  ? mb_set_largest_free_order+0x11c/0x130
[970130.957139]  mb_free_blocks+0x24d/0x5e0
[970130.957139]  ? ext4_validate_block_bitmap.part.0+0x29/0x3e0
[970130.957139]  ? __getblk_gfp+0x33/0x3b0
[970130.957139]  ext4_mb_release_inode_pa.isra.0+0x12e/0x350
[970130.957139]  ext4_discard_preallocations+0x22e/0x490
[970130.957139]  ext4_clear_inode+0x31/0xb0
[970130.957139]  ext4_evict_inode+0xba/0x750
[970130.989137]  evict+0xd0/0x180
[970130.989137]  dispose_list+0x39/0x60
[970130.989137]  evict_inodes+0x18e/0x1a0
[970130.989137]  generic_shutdown_super+0x46/0x1b0
[970130.989137]  kill_block_super+0x2b/0x60
[970130.989137]  deactivate_locked_super+0x39/0x80
[970130.989137]  deactivate_super+0x46/0x50
[970130.989137]  cleanup_mnt+0x109/0x170
[970130.989137]  __cleanup_mnt+0x16/0x20
[970130.989137]  task_work_run+0x65/0xa0
[970130.989137]  exit_to_user_mode_prepare+0x152/0x170
[970130.989137]  syscall_exit_to_user_mode+0x2a/0x50
[970130.989137]  ? __x64_sys_umount+0x1a/0x30
[970130.989137]  do_syscall_64+0x6d/0x90
[970130.989137]  ? syscall_exit_to_user_mode+0x38/0x50
[970130.989137]  ? __x64_sys_newfstatat+0x22/0x30
[970130.989137]  ? do_syscall_64+0x6d/0x90
[970130.989137]  ? exit_to_user_mode_prepare+0x3d/0x170
[970130.989137]  ? syscall_exit_to_user_mode+0x38/0x50
[970130.989137]  ? __x64_sys_close+0x16/0x50
[970130.989137]  ? do_syscall_64+0x6d/0x90
[970130.989137]  ? exc_page_fault+0x8b/0x180
[970130.989137]  entry_SYSCALL_64_after_hwframe+0x64/0xce
[970130.989137] RIP: 0033:0x7f6d94925a3b
[970130.989137] Code: fb 43 0f 00 f7 d8 64 89 01 48 83 c8 ff c3 90 f3 0f 1e fa 31 f6 e9 05 00 00 00 0f 1f 44 00 00 f3 0f 1e fa b8 a6 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 05 c3 0f 1f 40 00 48 8b 15 c1 43 0f 00 f7 d8
[970130.989137] RSP: 002b:00007ffdd60f7d08 EFLAGS: 00000246 ORIG_RAX: 00000000000000a6
[970130.989137] RAX: 0000000000000000 RBX: 0000000000000000 RCX: 00007f6d94925a3b
[970130.989137] RDX: 0000000000000000 RSI: 0000000000000000 RDI: 000055ca1c6f7d60
[970130.989137] RBP: 000055ca1c6f7b30 R08: 0000000000000000 R09: 00007ffdd60f6a90
[970130.989137] R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000
[970130.989137] R13: 000055ca1c6f7d60 R14: 000055ca1c6f7c40 R15: 000055ca1c6f7b30
[970130.989137]  </TASK>
[970130.989137] Modules linked in: 88x2bu(OE) erofs dm_zero zram ext2 hfs hfsplus xfs kvdo(OE) dm_bufio mikasecfs(OE) simplefsplus(OE) melon(OE) mikatest(OE) iloveaki(OE) tls vboxnetadp(OE) vboxnetflt(OE) vboxdrv(OE) ip6t_REJECT nf_reject_ipv6 ip6t_rt ipt_REJECT nf_reject_ipv4 xt_recent xt_tcpudp nft_limit xt_limit xt_addrtype xt_pkttype nft_chain_nat xt_MASQUERADE xt_nat nf_nat xt_conntrack nf_conntrack nf_defrag_ipv6 nf_defrag_ipv4 nft_compat nf_tables binfmt_misc nfnetlink nvidia_uvm(POE) nvidia_drm(POE) intel_rapl_msr intel_rapl_common nvidia_modeset(POE) sb_edac nls_iso8859_1 x86_pkg_temp_thermal intel_powerclamp coretemp nvidia(POE) snd_hda_codec_realtek snd_hda_codec_generic ledtrig_audio snd_hda_codec_hdmi cfg80211 joydev snd_hda_intel input_leds snd_intel_dspcfg snd_intel_sdw_acpi snd_hda_codec kvm_intel snd_hda_core snd_hwdep kvm snd_pcm snd_seq_midi rapl snd_seq_midi_event snd_rawmidi intel_cstate serio_raw pcspkr snd_seq video wmi snd_seq_device snd_timer drm_kms_helper fb_sys_fops snd syscopyarea sysfillrect sysimgblt soundcore
[970130.989137]  ioatdma dca mac_hid sch_fq_codel dm_multipath scsi_dh_rdac scsi_dh_emc scsi_dh_alua msr parport_pc ppdev lp parport drm efi_pstore ip_tables x_tables autofs4 raid10 raid456 async_raid6_recov async_memcpy async_pq async_xor async_tx raid1 raid0 multipath linear crct10dif_pclmul hid_generic crc32_pclmul ghash_clmulni_intel sha512_ssse3 sha256_ssse3 sha1_ssse3 usbhid cdc_ether aesni_intel usbnet uas hid crypto_simd r8152 cryptd usb_storage mii psmouse ahci i2c_i801 r8169 lpc_ich libahci i2c_smbus realtek [last unloaded: 88x2bu(OE)]
[970131.024615] ---[ end trace 0000000000000000 ]---
[970131.203209] RIP: 0010:mb_update_avg_fragment_size+0x35/0x120
[970131.204344] Code: 41 54 53 4c 8b a7 98 03 00 00 41 f6 44 24 7c 80 0f 84 9a 00 00 00 8b 46 14 48 89 f3 85 c0 0f 84 8c 00 00 00 99 b9 ff ff ff ff <f7> 7e 18 0f bd c8 41 89 cd 41 83 ed 01 0f 88 ce 00 00 00 0f b6 47
[970131.207841] RSP: 0018:ffffb909e3123a28 EFLAGS: 00010202
[970131.209048] RAX: 000000000000082a RBX: ffff91140ac554d8 RCX: 00000000ffffffff
[970131.210284] RDX: 0000000000000000 RSI: ffff91140ac554d8 RDI: ffff910ead74f800
[970131.211512] RBP: ffffb909e3123a40 R08: 0000000000000000 R09: 0000000000004800
[970131.212749] R10: ffff910ead74f800 R11: ffff9114b7126000 R12: ffff910eb31d2000
[970131.213977] R13: 0000000000000007 R14: ffffb909e3123b80 R15: ffff911d732beffc
[970131.215181] FS:  00007f6d94ab4800(0000) GS:ffff911d7fcc0000(0000) knlGS:0000000000000000
[970131.216370] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[970131.217553] CR2: 00003d140602f000 CR3: 0000000365690002 CR4: 00000000001706e0
[970131.218740] note: umount[4118804] exited with preempt_count 1

머신은 여전히 ​​작동하며 다른 파일 시스템은 동기화될 수 있습니다.

root# sync -f /
root#

하지만 전역 동기화는 아닙니다.

root# sync
(goes D state forever)

이 Ghost 파일 시스템과 관련된 더티 캐시가 사라지지 않고 파일 시스템이 여전히 "마운트"되어 있는
이러한 문제의 이유는 무엇입니까 ?

답변1

면책조항: 부분적인 커널 오류가 발생하는 이유를 이 답변에서 설명할 수 없으며 설명하지 않겠습니다. 이는 커널 버그처럼 보이며 I/O 오류 조건으로 인해 발생할 수 있습니다.

긴 이야기 짧게

새 마운트 네임스페이스가 원래 마운트 네임스페이스에서 마운트된 파일 시스템을 상속하는 경우 파일 시스템이 여전히 사용 중일 수 있지만 둘 사이의 전파 설정으로 인해 원래 네임스페이스에서 마운트 해제가 활성화되지 않습니다. 새로운 네임스페이스. 이 명령은 findmnt -A -o +PROPAGATION출력에 표시되는 각 마운트 지점의 전파 상태도 표시합니다.

일반적으로 이런 일이 발생해서는 안 됩니다.체계환경 때문에체계/공유 마운트는 커널 기본값이 아닌 초기에 이루어지므로 private마운트 해제가 공유 그룹 내에서 전파될 수 있습니다. 따라서 시스템화되지 않은 환경이나 도구가 --make-private일부 설치에서 명시적으로 사용되는 경우에는 이런 일이 더 쉽게 발생할 것으로 예상됩니다 . --make-private특히 가상 의사 파일 시스템에 대한 용도는 여전히 있습니다.

이러한 일이 발생하는 것을 방지하는 한 가지 방법은 다음과 같습니다.새 마운트 네임스페이스를 생성하기 전공유로 마운트 지점을 변경하십시오 mount --make-shared ....

공유 마운트와 비공유 마운트에서 어떤 일이 발생하는지 설명하기 위해 실험을 수행했습니다. 나는 시스템화된 환경이나 비시스템화된 환경에서 실험이 동일하게 잘 작동하는지 확인하려고 노력하고 있습니다.

실험

이는 아래와 같이 복제할 수 있습니다(일부 값을 /dev/loop0조정해야 함).

# truncate -s $((2**20)) /tmp/test.raw
# mkfs.ext4 -Elazy_itable_init=0,lazy_journal_init=0 -L test /tmp/test.raw
mke2fs 1.47.0 (5-Feb-2023)

Filesystem too small for a journal
Discarding device blocks: done                            
Creating filesystem with 1024 1k blocks and 128 inodes

Allocating group tables: done                            
Writing inode tables: done                            
Writing superblocks and filesystem accounting information: done

# losetup -f --show /tmp/test.raw 
/dev/loop0
# mkdir -p /mnt/propagation/test

이렇게 하면 디렉터리를 마운트 지점으로 전환하여 전체 시스템을 변경하지 않고도 나중에 변경 실험을 전파할 수 있습니다.

# mount --bind /mnt/propagation /mnt/propagation

이제 실험에 따라 다른 결과가 나올 수 있습니다.

unshare(1)말하다:

unshareprivateutil-linux 버전 2.27은 새 네임스페이스가 실제로 공유되지 않도록 자동으로 새 마운트 네임스페이스로 전파를 설정하기 때문입니다 . 이 기능은 옵션을 사용하여 비활성화할 수 있습니다 --propagation unchanged. 이것이 private커널 기본값이라는 점에 유의하십시오.

다른 도구도 이 작업을 수행할 수 있습니다. 여기서는 기본 마운트 지점 을 변경 /mnt/propagation하고 항상 .--propagation unchanged//

  1. 그리고shared

    # mount --make-shared /mnt/propagation
    # mount /dev/loop0 /mnt/propagation/test
    # ls /mnt/propagation/test
    lost+found
    # cat /proc/self/mountinfo | grep /mnt/propagation/test
    862 854 7:0 / /mnt/propagation/test rw,relatime shared:500 - ext4 /dev/loop0 rw
    

    두 번째(루트) 셸을 만들고 새 설치 네임스페이스에 대한 공유를 해제합니다(구분하기 위해 프롬프트를 NMNS#으로 변경했습니다).

    # unshare -m --propagation unchanged --
    NMNS# cat /proc/self/mountinfo | grep /mnt/propagation/test
    1454 1453 7:0 / /mnt/propagation/test rw,relatime shared:500 - ext4 /dev/loop0 rw
    NMNS# cd /mnt/propagation/test
    

    또한 shared:500링크는 두 네임스페이스 모두에 마운트됩니다. 한 네임스페이스에서 마운트를 해제하면 다른 네임스페이스에서도 마운트가 해제됩니다.

    원래 셸(원래 마운트 네임스페이스)에서 마운트 해제합니다.

    # umount /mnt/propagation/test
    umount: /mnt/propagation/test: target is busy.
    

    리소스 사용량 해제:

    NMNS# cd /
    
    # umount /mnt/propagation/test
    # 
    

    이번에는 효과가 있었습니다.

    새 마운트 네임스페이스에서도 사라지는 것을 확인하세요.

    NMNS# cat /proc/self/mountinfo | grep /mnt/propagation/test
    NMNS# 
    

    커널은 dmesg파일 시스템이 (모든 곳에서) 마운트 해제되었음을 기록합니다. 예를 들면 다음과 같습니다.

    EXT4-fs (loop0): unmounting filesystem e74e0353-ace0-4eff-86ae-30e288db853e.
    

    정리하려면 새로 설치된 네임스페이스에서 셸을 종료하세요.

  2. 그리고private

    # mount --make-private /mnt/propagation
    # mount /dev/loop0 /mnt/propagation/test
    # cat /proc/self/mountinfo | grep /mnt/propagation/test
    857 854 7:0 / /mnt/propagation/test rw,relatime - ext4 /dev/loop0 rw
    

    더 이상 공유하지 마세요.

    다른 곳:

    # unshare -m --propagation unchanged --
    NMNS# cat /proc/self/mountinfo | grep /mnt/propagation/test
    1454 1453 7:0 / /mnt/propagation/test rw,relatime - ext4 /dev/loop0 rw
    NMNS# echo $$
    232529
    
    # umount /mnt/propagation/test
    # e2fsck /dev/loop0
    e2fsck 1.47.0 (5-Feb-2023)
    /dev/loop0 is in use.
    e2fsck: Cannot continue, aborting.
    
    
    
    # 
    

    파일 시스템은 새 설치 네임스페이스에 마운트된 상태로 유지됩니다.

    원래 네임스페이스에서 이 악성 네임스페이스를 찾으려면 다음 명령을 실행할 수 있습니다.

    # for pid in $(lsns --noheadings -t mnt -o PID); do nsenter -t "$pid" -m -- findmnt /mnt/propagation/test && echo $pid; done
    nsenter: failed to execute findmnt: No such file or directory
    TARGET                SOURCE     FSTYPE OPTIONS
    /mnt/propagation/test /dev/loop0 ext4   rw,relatime
    232529
    # 
    

    참고: nsenter: failed to execute findmnt: No such file or directory실행 중인 LXC 컨테이너의 마운트 네임스페이스를 findmnt사용할 수 없게 됩니다. 루프는 마운트 지점을 사용하여 새 네임스페이스에서 프로세스의 PID를 찾습니다(참고: 실제 상황에서는 동일한 마운트 네임스페이스에서 다른 PID일 수 있으므로 중요하지 않습니다.). 극단적인 경우에는 마운트 네임스페이스 변경, 마운트 확인, (u)마운트를 모두 한번에 수행할 수 있는 전용 명령이 필요합니다.

    이 마운트는 프로세스가 마운트된 파일 시스템을 적극적으로 사용하는 경우(성공 방지) 필요할 수 있는 나머지 보유 리소스(PID 232529)를 제거하거나 umount이 네임스페이스에서 마운트 해제하여 제거할 수 있습니다.

    # nsenter -t 232529 -m -- umount /mnt/propagation/test
    # e2fsck /dev/loop0
    e2fsck 1.47.0 (5-Feb-2023)
    test: clean, 11/128 files, 58/1024 blocks
    

유용한 참고자료:

관련 정보