OpenSuse: 왜 서브볼륨 마운트가 필요할까?

** 글을 쓰기 시작할 때만 해도 이 글에 대한 답을 구하지 못했었다. 그런데, 글을 쓰던 중, 답이 보였다.

  • tldr;
    var, home 등 서브볼륨이 초기 root 디렉토리인 @ 산하에 있음에도 서브볼륨 마운트가 필요한 이유는, Snapper 때문이다.
    Snapper 가 실행되면서 루트 디렉토리가 수시로 바뀌기 때문에, 최초엔 @ 산하에 있어서 서브볼륨 마운트를 하지 않더라도 같은 결과가 나오지만, 나중엔 반드시 마운트를 해줘야만 한다.

Leap 이든, Tumbleweed 든, OpenSuse 는 기본으로 다음과 같은 파일시스템 구조를 바탕으로 설치가 진행된다. (아래에 언급되어 있지만, 이런 구조를 Nested 라고 한다.)

FS_Root
   |
   └── @
       ├── var
       ├── usr/local
       ├── tmp
       ├── srv
       ├── root
       ├── opt
       ├── home
       ├── boot/grub2/x86_64-efi
       └── boot/grub2/i386-pc

FS_Root 는 파일시스템 루트, 즉 최상위 수준을 뜻한다.
바로 그 밑에 @ 라는 이름의 Subvolume 이 존재하고, 그 서브볼륨 아래에, 각각 var, usr/local 등등의 서브볼륨들이 존재한다.

다음 명령으로 저 파일시스템을 /mnt 에 마운트하고, ls 로 살펴보면 더 확실하게 보인다.

$ sudo mount /dev/sda2 /mnt -o subvolid=5
$ ll /mnt/@
drwxr-xr-x 1 root root 1.9K  1월 29 21:13 bin
drwxr-xr-x 1 root root  652  1월 29 17:07 boot
drwxr-xr-x 1 root root    0  1월 29 16:37 dev
drwxr-xr-x 1 root root 4.3K  1월 29 21:17 etc
drwxr-xr-x 1 root root   16  1월 29 17:04 home
drwxr-xr-x 1 root root   72  1월 29 17:03 lib
drwxr-xr-x 1 root root 3.2K  1월 29 16:53 lib64
drwxr-xr-x 1 root root    0  3월 12  2019 mnt
drwxr-xr-x 1 root root    8  1월 29 17:30 opt
drwxr-xr-x 1 root root    0  1월 29 16:37 proc
drwx------ 1 root root   88  1월 29 17:29 root
drwxr-xr-x 1 root root    0  1월 29 17:05 run
drwxr-xr-x 1 root root 4.3K  1월 29 16:56 sbin
drwxr-xr-x 1 root root    0  3월 12  2019 selinux
drwxr-xr-x 1 root root   12  1월 29 21:15 srv
drwxr-xr-x 1 root root    0  1월 29 16:37 sys
drwxrwxrwt 1 root root  258  1월 29 21:30 tmp
drwxr-xr-x 1 root root  104  3월 13  2019 usr
drwxr-xr-x 1 root root  114  1월 29 17:07 var

여기엔 서브볼륨과 일반 디렉토리가 섞여있지만, 아무튼 이런 형태로 디렉토리 구조가 형성이 된다.

이렇게 때문에, 그냥 @ 만 마운트 한다면, 나머지들을 굳이 따로 마운트할 필요는 없어 보인다.
예를 들자면,

# /etc/fstab
UUID=xxxx  /                       btrfs  defaults                      0  0

이렇게만 해줘도, 나중에 부팅한 후 / 를 살펴보면, var, home 등이 다 존재하기 때문에 굳이 따로 마운트를 해줄 필요는 없다. (당연하지 않은가?)

그/런/데!!
OpenSuse 는 굳이, 이걸 따로 마운트해주고 있다.

$ cat /etc/fstab
UUID=xxxx  /                       btrfs  defaults                      0  0
UUID=xxxx  /var                    btrfs  subvol=/@/var                 0  0
UUID=xxxx  /usr/local              btrfs  subvol=/@/usr/local           0  0
UUID=xxxx  /tmp                    btrfs  subvol=/@/tmp                 0  0
UUID=xxxx  /srv                    btrfs  subvol=/@/srv                 0  0
UUID=xxxx  /root                   btrfs  subvol=/@/root                0  0
UUID=xxxx  /opt                    btrfs  subvol=/@/opt                 0  0
UUID=xxxx  /home                   btrfs  subvol=/@/home                0  0

왜???
굳이 왜??


이 글을 쓰기 시작할 때, 전혀 답은 생각이 나지 않았다. 짜증도 났고. 도대체 내가 왜 이 문제를 고민해야 하는지?
검색을 해봐도 딱히 걸리는게 없었는데..

중간쯤 쓰다가, 갑자기 아!! 를 외칠 수 있었다.
그러고 나니, 예전에도 같은 고민을 했었고, 글도 쓰지 않았던가?? 하는 생각이 들었는데, 찾아봤으나 딱 이 문제에 대한 글은 못찾았다.

몇몇 관련된 들은 있는데, 정확하게 이 문제를 언급한 건 없다. (정말 없나..??)

아무튼, 답은 Btrfs snapshot, 그리고 그를 활용한 Snapper 때문이다.

Snapper 가 생성한 스냅샷을 보면, 이런 모습이다.

$ sudo snapper list
  # | Type   | Pre # | Date                            | User | Cleanup  | Description                      | Userdata
----+--------+-------+---------------------------------+------+----------+----------------------------------+---------
 0  | single |       |                                 | root |          | current                          |         
 1  | single |       | Mon 27 Jan 2020 05:31:03 PM KST | root |          |                                  |         
 2  | pre    |       | Mon 27 Jan 2020 05:32:56 PM KST | root | number   | apt                              |         
 3  | post   |     2 | Mon 27 Jan 2020 05:35:44 PM KST | root | number   | apt                              |         
 4  | pre    |       | Mon 27 Jan 2020 05:38:06 PM KST | root | number   | apt                              |         
 5  | post   |     4 | Mon 27 Jan 2020 05:39:16 PM KST | root | number   | apt                              |         
 6  | pre    |       | Mon 27 Jan 2020 05:39:54 PM KST | root | number   | apt                              |         
 7  | post   |     6 | Mon 27 Jan 2020 05:40:06 PM KST | root | number   | apt                              |         
 8  | pre    |       | Mon 27 Jan 2020 05:41:08 PM KST | root | number   | apt                              |         
 9  | post   |     8 | Mon 27 Jan 2020 05:41:17 PM KST | root | number   | apt                              |         
10  | pre    |       | Mon 27 Jan 2020 08:44:19 PM KST | root | number   | apt                              |         
11  | post   |    10 | Mon 27 Jan 2020 08:44:28 PM KST | root | number   | apt                              |         
12  | pre    |       | Mon 27 Jan 2020 08:48:58 PM KST | root | number   | apt                              |         
13  | post   |    12 | Mon 27 Jan 2020 08:49:10 PM KST | root | number   | apt                              |         
14  | pre    |       | Mon 27 Jan 2020 08:50:14 PM KST | root | number   | apt                              |         
15  | post   |    14 | Mon 27 Jan 2020 08:50:21 PM KST | root | number   | apt                              |         
16  | pre    |       | Mon 27 Jan 2020 08:50:35 PM KST | root | number   | apt                              |         
17  | post   |    16 | Mon 27 Jan 2020 08:50:41 PM KST | root | number   | apt                              |       

이 스냅샷은 /.snapshots/번호/snapshot/ 에 저장되어 있다. 만약, 특정 스냅샷을 루트로 설정하고 싶을 땐, fstab 에서 그 스냅샷(서브볼륨)으로 루트 디렉토리만 바꿔서 마운트하면 된다.

$ cat /etc/fstab
UUID=xxxx  /                       btrfs defaults,subvol=.snapshots/2/snapshot 0 0
UUID=xxxx  /var                    btrfs  subvol=/@/var                 0  0
UUID=xxxx  /usr/local              btrfs  subvol=/@/usr/local           0  0
UUID=xxxx  /tmp                    btrfs  subvol=/@/tmp                 0  0
UUID=xxxx  /srv                    btrfs  subvol=/@/srv                 0  0
UUID=xxxx  /root                   btrfs  subvol=/@/root                0  0
UUID=xxxx  /opt                    btrfs  subvol=/@/opt                 0  0
UUID=xxxx  /home                   btrfs  subvol=/@/home                0  0

그런데, 만약 이렇게 루트 디렉토리가 바뀌었을 경우, /var 등을 마운트해주지 않으면 ar 는 .snapshots/2/snapshot/var 가 되고, 서브볼륨(/@/var) 으로 마운트가 되어 있지 않으므로 그냥 텅 비어있는 디렉토리가 되고 만다.

(이 내용을 나중에 다시 봐도 이해할 수 있을런지.. 지금까지 이랬던 적이 많아서 걱정이 된다. 열심히 쓴다고 썼는데, 나중에 보면 이게 뭔 소리였는지 이해가 안되는 상황!)

하여, 최초 설치 시에는 굳이 마운트 할 필요가 없는 var 이하 서브볼륨들이 모두 저렇게 마운트가 돼 있다.

이런 파일/서브볼륨 배치(Layout)를, Nested(적절한 우리말이 없다.) 라고 한다.
아직 Btrfs Snapshot 에 익숙지 못해 평하기는 이르지만, Nested 보다는 Flat 쪽이 내가 받아들이기엔 좀 더 편해보인다. (현재 사용 중인 우분투 서버도 여기에 입각해서 만들었다.)

또, 이렇게 Nested 가 되면, 최초 @ 서브볼륨은 다소 붕 뜨는 듯한 느낌을 받게 된다. 바로 그 문제에 대해 정리한 글이 꽃삽질 : Snapper, Btrfs snapshot 의 문제점 돌아가기 이다.

안녕하세요. 글 남겨주셔서 고맙습니다.