sshfsでマウントしたディレクトリの中でファイルをマウントしてLVMを構築して連結した話

# 注意
あくまでも理論上できそうな事を実際にやってみただけなので、再現性の保証はありません。ご注意下さい。

# はじめに
"sshfsでマウントしたディレクトリの中でファイルをマウントしてLVMを構築して連結"するというのは結構前から考えていたのですが、実際にやってみないと始まらないという訳でやってみました。

# 準備するもの
- 安定した通信回線
  - 不安定なWi-Fiはやめたほうがいい
- sshする(マウントする)Linuxマシン
  - Ubuntu 18.04
  - sshfsを入れておくこと
  - 以降`Z`と呼ぶ
  - `/etc/fuse.conf`で`user_allow_other`を有効にしておく
- sshされる(ファイルを置く)Linuxマシン
  - 今回2台用意した
  - 2台ともUbuntu 18.04
  - それぞれの区別のため、一つのホスト名(と名前)を`A`、もう一つのホスト名は`B`とする

# やるよ
## AとBで下準備 (デバイスになるファイルの用意)
先にAとBで以下のようにファイルを作成します。(コマンドは例)

```
$ mkdir lvm_test
$ cd lvm_test
$ dd if=/dev/zero of=./lvmfile bs=1M count=1536
1536+0 records in
1536+0 records out
1610612736 bytes (1.6 GB, 1.5 GiB) copied, 4.25904 s, 378 MB/s
```

## sshfsしてZにマウントする
次に、上記で作成した`lvm_test`をZにマウントします。

```
$ sshfs lesmi@A:/home/lesmi/lvm_test a/ -o allow_other
$ sshfs lesmi@B:/home/lesmi/lvm_test b/ -o allow_other
```

## デバイスにするファイルをloopbackとしてマウント
ファイルのままだとこの後の`pvcreate`が出来ないので、loopbackデバイスに変換します。(snapがあるとloop0やloop1は使用済みだと思われます)

```
# losetup /dev/loop0 ./a/lvmfile
# losetup /dev/loop1 ./b/lvmfile
```

## LVMにデバイスを登録する
上記で作成したloopbackデバイスに登録し、グループを作成します

```
# pvcreate /dev/loop0
  Physical volume "/dev/loop0" successfully created.
# pvcreate /dev/loop1
  Physical volume "/dev/loop1" successfully created.

# vgcreate overssh /dev/loop0
  Volume group "overssh" successfully created
# vgextend overssh /dev/loop1
  Volume group "overssh" successfully extended
```

## 作成したグループからvolumeを作成する
ここまで全く同じようにやると、多分766 extents、つまり3064MB使えると思いますので、フルサイズでvolumeを作成します。

```
# lvcreate -L3064 -n overssh_lv overssh
  Logical volume "overssh_lv" created.
```

## ext4でフォーマット、ついでにマウント
ここまで来るともうすでにvolumeとして使用できるので、ext4としてフォーマットします。(実際には何でもいい)
ついでにマウントしてしまいます。

```
# mkfs.ext4 /dev/overssh/overssh_lv
mke2fs 1.44.1 (24-Mar-2018)
Creating filesystem with 784384 4k blocks and 196224 inodes
Filesystem UUID: 149068ec-d9f2-46d0-a5f1-9f626bd4327c
Superblock backups stored on blocks:
        32768, 98304, 163840, 229376, 294912

Allocating group tables: done
Writing inode tables: done
Creating journal (16384 blocks): done
Writing superblocks and filesystem accounting information: done
# mount /dev/overssh/overssh_lv $PWD/combined
```

# 試してみる
`df -h`してみるとこんな感じ(元々あったデバイスは除外)

```
$ df -h
Filesystem                                     Size  Used Avail Use% Mounted on
lesmi@A:/home/lesmi/lvm_test                    55G   25G   27G  48% /home/lesmi/lvm_test/a
lesmi@B:/home/lesmi/lvm_test                    29G   13G   15G  46% /home/lesmi/lvm_test/b
/dev/mapper/overssh-overssh_lv                 2.9G  2.0G  797M  72% /home/lesmi/lvm_test/combined
```

できてますね

`dd`で容量一杯まで書き込むとこんな感じ

```
$ dd if=/dev/zero of=./test status=progress
2873205248 bytes (2.9 GB, 2.7 GiB) copied, 127 s, 22.6 MB/s
dd: writing to './test': No space left on device
5680497+0 records in
5680496+0 records out
2908413952 bytes (2.9 GB, 2.7 GiB) copied, 127.524 s, 22.8 MB/s
$ rm test
```

全部書き込めるみたいですね。 ~~Seagateじゃないんだから~~

# やりっぱなしはダメだよね
という訳で後片づけの時間です。使わないからね。
なおA、Bでやる作業は(ファイルの削除を除いて)特にありません。

## Z上からvolumeをアンマウントする
まずは普通に`./combined`をアンマウントします。

```
# umount -l ./combined
```

## LVMからvolumeを削除する
sshfsを早速アンマウントするとおかしくなるので、LVMをなんとかします。

```
# lvchange -an /dev/overssh/overssh_lv
# lvremove /dev/overssh/overssh_lv
Do you really want to remove and DISCARD logical volume overssh/overssh_lv? [y/n]: y
  /dev/loop0: BLKDISCARD ioctl at offset 1048576 size 1606418432 failed: Input/output error.
  /dev/loop1: BLKDISCARD ioctl at offset 1048576 size 1606418432 failed: Input/output error.
  Logical volume "overssh_lv" successfully removed
```

エラーっぽいのが出ていますが、これはloopbackデバイスが特定のioctlに対応してないだけなので気にしなくても問題なさそうです。

## `vgchange -an overssh`をする
よく分かりませんがやっておきます。

```
# vgchange -an overssh
  0 logical volume(s) in volume group "overssh" now active
```

## Volume groupを削除する
Volume groupを削除し、関連付けられているデバイスを解放(?)します。

```
# vgremove overssh
  Volume group "overssh" successfully removed
```

## LVMにさようならを告げる
最初に作ったloopbackデバイスを、LVMから完全に削除します。

```
# pvremove /dev/loop0 /dev/loop1
  Labels on physical volume "/dev/loop0" successfully wiped.
  Labels on physical volume "/dev/loop1" successfully wiped.
```

## loopbackを解除する
loopbackデバイスを削除し、sshfs上のファイルを解放します。

```
# losetup -d /dev/loop0
# losetup -d /dev/loop1
```

## sshfsをアンマウントしておしまい
最後に、sshfsをアンマウントして切断します。

```
# umount -l ./a ./b
```

お疲れさまでした。後片付けはこれで終わりです。

# 感想
実際にやってみたらすんなりできてしまったので面白かったです。
実用性は皆無ですが。