それマグで!

知識はカップより、マグでゆっくり頂きます。 takuya_1stのブログ

習慣に早くから配慮した者は、 おそらく人生の実りも大きい。

pi zero でUSB-OTG でUSBシリアルを使う。

USB-OTG でUSBシリアルを使う。

USB OTB 経由で、シリアルコンソールが動けば勝ち。今回はUSB-OTGデバイスに、orage pi zero を使う。

USB-OTGとはスマホを接続時にUSBテザリングバイスやフォトストレージのように機能を選べるアレである。

パソコンとPi zeroをUSB-OTGで接続し、シリアル通信を有効にすると、パソコンからはUSBシリアルデバイスに見える。

シリアルコンソール設定する。

https://oshlab.com/enable-g_serial-usb-otg-console-orange-pi-armbian/

echo "g_serial" >> /etc/modules
mkdir -p /etc/systemd/system/serial-getty@ttyGS0.service.d

cat - > /etc/systemd/system/serial-getty@ttyGS0.service.d/10-switch-role.conf
[Service]
ExecStartPre=-/bin/sh -c "echo 2 > /sys/bus/platform/devices/sunxi_usb_udc/otg_role"


systemctl --no-reload enable serial-getty@ttyGS0.service
echo "ttyGS0" >> /etc/securetty
reboot

Orange Pi をUSBでRaspiにつなぐ。

Raspiにつないだ。見えるぞ。見えるぞ。

takuya@raspi-ubuntu:~$ lsusb
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 001 Device 003: ID 0525:a4a7 Netchip Technology, Inc. Linux-USB Serial Gadget (CDC ACM mode)

raspi から USBのOrange Pi へつなぐ

sudo screen /dev/ttyACM0 115200

f:id:takuya_1st:20211130235717p:plain

これで、よくあるSSHを経由しない pi zero の管理ってやつができる。でも今回の目標はこれじゃない。

Orange Pi につながるのはいいけど、逆に、Raspiをリモートから読みたいよね。

単純に通信する。

agetty を使わずに、単純に通信する。

Orange Piの agetty を止める。

systemctl enable  serial-getty@ttyGS0.service
systemctl stop    serial-getty@ttyGS0.service
systemctl status  serial-getty@ttyGS0.service

シリアルコンソールを許可する。

root@OrangePi:~# chmod 666 /dev/tty*S0

Raspi側に見えているシリアルコンソールを許可する。

takuya@raspi-ubuntu:~$ sudo chmod 666 /dev/ttyA*

単純に通信をする。 Raspi 側

takuya@raspi-ubuntu:~$ sudo screen /dev/ttyACM0 115200

Orange Pi Zero側

root@OrangePi:~# screen /dev/ttyGS0 11520

これで、両方から通信で、単純に文字列が送信できることがわかります。

youtu.be

raspi(USB) からはOTGどう見えているのか。

単純にUSBデバイスで見えているとわかります。

takuya@raspi-ubuntu:~$ lsusb
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 001 Device 004: ID 0525:a4a7 Netchip Technology, Inc. Linux-USB Serial Gadget (CDC ACM mode)

ttyACM0ができています。

takuya@raspi-ubuntu:~$ ls /dev/ttyA*
/dev/ttyACM0  /dev/ttyAMA0

シリアルデバイスであることを確認します。

takuya@raspi-ubuntu:~$ ls -l /dev/serial/by-id/
total 0
lrwxrwxrwx 1 root root 13 11月 29 23:52 usb-Armbian_Linux_5.3.5+_with_musb-hdrc_Gadget_Serial_v2.4-if00 -> ../../ttyACM0

f:id:takuya_1st:20211201004318p:plain:w300

最初の逆をやろう。

シリアルコンソールを使ってRaspi側へログインしよう

raspi( login - agetty - usb)  ----<OTG/serial>--- ( usb/otg -- screen ) orange pi zero

Orange Pi から、Raspiにログインする。

Raspi側で、agetty で待ち受ける。

getty を起動する。

takuya@raspi-ubuntu:~$ sudo systemctl start getty@ttyACM0.service

状態の確認

takuya@raspi-ubuntu:~$ sudo systemctl start getty@ttyACM0.service
[sudo] password for takuya:
takuya@raspi-ubuntu:~$ sudo systemctl status getty@ttyACM0.service
● getty@ttyACM0.service - Getty on ttyACM0
     Loaded: loaded (/lib/systemd/system/getty@.service; disabled; vendor preset: enabled)
     Active: active (running) since Tue 2021-11-30 12:00:00 JST; 3s ago
       Docs: man:agetty(8)
             man:systemd-getty-generator(8)
             http://0pointer.de/blog/projects/serial-console.html
   Main PID: 6546 (login)
      Tasks: 1 (limit: 9257)
     CGroup: /system.slice/system-getty.slice/getty@ttyACM0.service
             └─6546 /bin/login -p --

11月 30 12:00:00 raspi-ubuntu systemd[1]: Started Getty on ttyACM0.
11月 30 12:00:01 raspi-ubuntu login[6546]: pam_unix(login:auth): check pass; user unknown
11月 30 12:00:01 raspi-ubuntu login[6546]: pam_unix(login:auth): authentication failure; logname=LOGIN uid=0 euid=0 tty>
11月 30 12:00:03 raspi-ubuntu login[6546]: FAILED LOGIN (1) on '/dev/ttyACM0' FOR 'UNKNOWN', Authentication failure
lines 1-15/15 (END)

orange pi zero 側の設定。

agetty が USBで起動したら、Orange Piの gettyを止める。

systemctl disable serial-getty@ttyGS0.service
systemctl stop    serial-getty@ttyGS0.service
systemctl status  serial-getty@ttyGS0.service

停止した。

root@OrangePi:~# systemctl status serial-getty@ttyGS0.service
● serial-getty@ttyGS0.service - Serial Getty on ttyGS0
   Loaded: loaded (/lib/systemd/system/serial-getty@.service; enabled; vendor preset: enabled)
  Drop-In: /etc/systemd/system/serial-getty@ttyGS0.service.d
           └─10-switch-role.conf
   Active: inactive (dead) since 火 2021-11-30 03:10:14 UTC; 1s ago
     Docs: man:agetty(8)
           man:systemd-getty-generator(8)
           http://0pointer.de/blog/projects/serial-console.html
 Main PID: 11293 (code=killed, signal=TERM)

11月 30 03:05:10 OrangePi systemd[1]: Started Serial Getty on ttyGS0.
11月 30 03:05:10 OrangePi sh[11290]: /bin/sh: 1: cannot create /sys/bus/platform/devices/sunxi_usb_udc/otg_role: Directory nonexistent
11月 30 03:10:14 OrangePi systemd[1]: Stopping Serial Getty on ttyGS0...
11月 30 03:10:14 OrangePi systemd[1]: Stopped Serial Getty on ttyGS0.

Orange PiZero から Raspiのagetty へ USB経由で接続する。

screen /dev/ttyGS0 115200

つながった!

f:id:takuya_1st:20211130235739p:plain

USB-OTG でシリアルコンソール。

USBシリアルコンソールなので、OTGを使うと、USB接続側のどちらかで待ち受ける事ができる。agetty を起動させた側がログインされる側。になる。

Pi zero があると

Pizeroで、シリアルコンソールがついてない機器にUSBでシリアルコンソールを追加できる。

Pi Zero にSSHログインすることにより、リモート・シリアルコンソールを作ることができる。それもUSB1本の接続で電源・シリアルコンソールの両方ができる。USB接続だけで完結するので強い。

USBが接続されたタイミングで起動する。

どうやるのか。

sudo systemctl enable getty@ttyACM0.service

とりあえず,enable しておけば大丈夫だと思う。

厳密にやるには、usb デバイスをudev でみて、systemdで units に wantedby を書けばいいのだろうが・・・・

[Unit]
Description=Getty on ttyACM0
After=systemd-user-sessions.service plymouth-quit-wait.service getty-pre.target
After=rc-local.service
Before=getty.target
IgnoreOnIsolate=yes

Conflicts=rescue.service
Before=rescue.service

ConditionPathExists=/dev/tty0

[Service]
ExecStart=-/sbin/agetty -o '-p -- \\u' --noclear ttyACM0 $TERM
Type=idle
Restart=always
RestartSec=0
UtmpIdentifier=ttyACM0
TTYPath=/dev/ttyACM0
TTYReset=yes
TTYVHangup=yes
TTYVTDisallocate=yes
KillMode=process
IgnoreSIGPIPE=no
SendSIGHUP=yes
UnsetEnvironment=LANG LANGUAGE LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT LC_IDENTIFICATION

[Install]
WantedBy=sys-devices-platform-scb-fd500000.pcie-pci0000:00-0000:00:00.0-0000:01:00.0-usb1-1\x2d1-1\x2d1.4-1\x2d1.4:2.0-tty-ttyACM0.device

wanted by で使うデバイスは、systemctl list-units -t device | grep -i serial でなんとかできる。

systemdでは「デバイスが存在する」状態をunit として管理してて、それを一覧するのが次のコマンド。

systemctl list-units -t device

実際の例。

takuya@raspi-ubuntu:~$ systemctl list-units -t device | grep -i serial
  sys-devices-platform-scb-fd500000.pcie-pci0000:00-0000:00:00.0-0000:01:00.0-usb1-1\x2d1-1\x2d1.4-1\x2d1.4:2.0-tty-ttyACM0.device              loaded active plugged Linux-USB Serial Gadget (CDC ACM mode)
  sys-devices-platform-soc-fe201000.serial-tty-ttyAMA0.device                                                                                   loaded active plugged /sys/devices/platform/soc/fe201000.serial/tty/ttyAMA0
  sys-devices-platform-soc-fe215040.serial-tty-ttyS0.device                                                                                     loaded active plugged /sys/devices/platform/soc/fe215040.serial/tty/ttyS0

いろいろ試したけど、ここまでする必要はないと思う。

まとめ

USB-OTGで、手軽にリモートアクセスできるシリアル通信を追加することができる。

今回、実験に使ったのはOrange Pi Zero ですが、USB-OTGでシリアルコンソールが可能です。Raspi Zero でも可能です。

f:id:takuya_1st:20211201004339p:plain:w300

Pi Zeroへログインする記事が多いですが、リッスンさせる agetty を起動する側次第で、Pi zero経由でログインもできるようになる事がわかりました。USBケーブル一本で、任意のPCにリモートコンソールが追加できてとても便利です。intel vPro のようにBIOSアクセスはできませんが、市販マザーボードではGRUB/initramfsへアクセスできるだけでも有益です。ネットワーク実験でいちいち設置場所に行かなくてもいいですしね。

RaspberryPi zero は SSH接続しなくても、USB接続でログインすることができます。

rPiで検索するとSSHばかりですが、pi zero に限りOTGが使えるので、USBではシリアル通信ができます。

世の中の記事は、pi zero へ ログインする話ばかりですが、'pi zero から'ログインする事もできます。「なんの意味があるのそれ」と思うかもしれませんが、リモートからSSH経由でpi zero にログインし、その先に接続したPCへログインし、テレワークのリモート管理に役立てることができるのです。

今回使った機器 / Orange Pi Zero

raspi -- raspi zero だと記事がわかりづらくなるので、あえて Orange Pi Zero を使っています。

Orange Pi Zero は日本のAmazonでも変えますがAliexpressなど中華サイトの通販のほうがいいかもしれませんね。

ちなみに、なんちゃらPiのなかでも特にOrange Piは、発熱がすごいので長時間運用するには向きません。

参考資料

systemd-networkdでVLANを作る

networkd で VLAN インターフェースを作ろう

eth0 の設定に書いた。タグVLANをリッスンするインターフェースを作ろう。networkd の設定で。

networkd の設定は、3つファイルを使った。

systemd-networkd は設定がバラけるので管理が面倒です。そのうちnetplanに書き直そうと思う。

/etc/systemd/network/01-eth0.network

今回は、mavlan のひとつで vlan をリッスンする。

[Match]
Name=eth0

[Network]
MACVLAN=macvlan0
MACVLAN=macvlan1
VLAN=vlan11 # vlanインターフェース名称
LinkLocalAddressing=no

/etc/systemd/network/03-vlan11.network

[Match]
Name=vlan11 # インターフェース名称を指定

[Network]
DHCP=yes

/etc/systemd/network/03-vlan11.netdev

VLAN IDを設定する。

[NetDev]
Name=vlan11 # インターフェース名称
Kind=vlan

[VLAN]
Id=11 # tag の番号

再起動

ubuntu なので、この他にも netplanに設定があるので念の為。

sudo netplan --debug generate
sudo netplan --debug apply

再起動

sudo systemctl restart networkd-dispatcher.service

VLANで通信を確認

tcpdump -e で パケットとVLAN ID を確認。

f:id:takuya_1st:20211129183859p:plain

出来上がった。ネットワーク設定

だんだんカオスになってきた。。。raspi4 はよく働きますね。

f:id:takuya_1st:20211129184109p:plain

図のCPUってのは、IPアドレスを振ってるインターフェースを明確にするために、便宜的に書いてる感じです。

CPU接続してる=IPアドレス割当してる。なので、CPUと接続してる=フィルタリングかかってるであり、CPU接続してる=フォワード設定に従う=ルーティングテーブルを使う でもあります。レイヤが上の機能をCPUと解釈して、CPUを便宜的に書くと図がスッキリするので好きです。

systemd/networkdでmacvlanを複数作り、1つのLANポート(NIC)を複数の別物として扱う

以前の資料

macvtap でできた仮想マシンとホストと通信してみる。macvlan/macvtap - それマグで!

macvlan を複数作りたい。

macvlan を複数作りたい。デバイスを区別して別物として扱って便利に使いたいのです。

/etc/systemd/network の中身を弄くります。

ファイルを増やして対応しました

total 28
drwxr-xr-x 2 root root 4096 11月 29 16:28 ./
drwxr-xr-x 5 root root 4096 10月 29 17:48 ../
-rw-r--r-- 1 root root   87 11月 29 16:20 01-eth0.network
-rw-r--r-- 1 root root   60  5月 30  2021 01-macvlan0.netdev
-rw-r--r-- 1 root root  143  5月 30  2021 01-macvlan0.network
-rw-r--r-- 1 root root   60 11月 29 16:22 02-macvlan1.netdev
-rw-r--r-- 1 root root  143 11月 29 16:23 02-macvlan1.network

/etc/systemd/network/01-eth0.network

[Match]
Name=eth0

[Network]
MACVLAN=macvlan0
MACVLAN=macvlan1 # 2つ目を追加
LinkLocalAddressing=no

1つ目のmacvlan の設定

/etc/systemd/network/01-macvlan0.network

[Match]
Name=macvlan0

[Network]
DHCP=no
Address=192.168.1.240/24
Gateway=192.168.1.1
DNS=1.1.1.1
LinkLocalAddressing=no

/etc/systemd/network/01-macvlan0.netdev

[NetDev]
Name=macvlan0
Kind=macvlan

[MACVLAN]
Mode=bridge

2つ目のmacvlan の設定

/etc/systemd/network/02-macvlan1.network

[Match]
Name=macvlan1

[Network]
DHCP=no
Address=192.168.1.241/24
Gateway=192.168.1.1
DNS=1.1.1.1
LinkLocalAddressing=no

/etc/systemd/network/02-macvlan1.netdev

[NetDev]
Name=macvlan1
Kind=macvlan

[MACVLAN]
Mode=bridge

反映

ubuntu なので netplan もまとめて更新しておきます。

sudo netplan --debung generate
sudo netplan --debung apply
## 再起動
sudo systemctl restart systemd-networkd.service

結果の確認

無事に macvlan が作成されました。これで、1つのLANポートを全く違う別デバイスとして扱うことができます。

仮想マシンに割り当てたりすると、完璧に「別マシン」ですね。

ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue (略
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 (略
3: wlan0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop 
(略
4: macvlan0@eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 32:b7:9f:1a:67:d4 brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.240/24 brd 192.168.1.255 scope global macvlan0
       valid_lft forever preferred_lft forever
5: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 
(略
6: macvlan1@eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 52:76:71:6e:4f:80 brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.241/24 brd 192.168.1.255 scope global macvlan1
       valid_lft forever preferred_lft forever

関連資料

takuya-1st.hatenablog.jp

参考資料

http://manpages.ubuntu.com/manpages/bionic/man5/systemd.network.5.html

起動時にfsck 実行でを設定する/check ext4 disk on boot

起動時に fsck を実施する。

長期間起動しっぱなしのマシンだと、fsck 機会がなかなか無いので、ext4 をチェックし忘れないようにしたい。 fsck をしておけば、hdd/ssdの故障に早く気づけるはずだ。また故障し不良セクタが増えても代替セクタをうまく使ってくれるんじゃないかなと思う。

たまには、実施しておこう fsck

起動にやる

マウントしてるとめんどくさいので、起動時にやることにする。

カネール・パラメタに次を追加

/etc/default/grub

GRUB_CMDLINE_LINUX_DEFAULT=......  fsck.mode=force  "

grub を更新

sudo update-grub

再起動して試してみた。

f:id:takuya_1st:20211127181930p:plain

lvm on luks のディスクでも動く。安心した。

参考資料

https://unix.stackexchange.com/questions/123963/how-to-force-fsck-at-every-boot-all-relevant-filesystems

php の pecl のインストール

古いphpのアプリを動かす。

https://packages.sury.org/php/ を使って php7.0 をインストール

サンプルとして、pecl から rarパッケージを持ってくる

php8.1/php8.0/php7.4 でも同様です。

php7.0 で pecl パッケージ をインストールする。

sudo apt install php7.0-dev

パッケージの取得とビルド

パッケージ取得して、phpize7.0して、ビルドする。

mkdir working
cd working
wget https://pecl.php.net/get/rar-4.2.0.tgz
tar zxvf rar-4.2.0.tgz
cd rar-4.2.0
## ビルド
phpize7.0
./configure
make 
## インストール
make install 

インストールのチェック

ls -l /usr/lib/php/*/rar.so

有効化

インストールしただけでは、モジュールがあるだけなので、php設定でロードする必要がある。

設定を作る

## 適当なモジュールのロードファイルをテンプレートに使う。
cp /etc/php/7.0/mods-available/zip.ini cp /etc/php/7.0/mods-available/rar.ini
sed -i 's/zip/rar/g' cp /etc/php/7.0/mods-available/rar.ini

設定を有効にする( Debianではこうする)

sudo phpenmod -v 7.0 rar

再起動

モジュールが有効になるように再起動する。

sudo systemctl restart php7.0-fpm.service
sudo systemctl restart apache2.service

動作チェック

クライアント側

php -i | grep rar

WEB サーバー

curl localhost/phpinfo.php | grep rar

インストール完了

PECLもいまだにちゃんと動くから安心した。

昔作ったpthread つかうアプリとか動かせそう。

unetbootin がUSBドライブを認識しない。

unetbootin がUSBドライブを認識しない。

debian / ubuntu のインストールディスクを作ろうとしてハマった。

ISOディスクから手軽にインストール・ディスクを作れるので前から使っていたが、Windowsだと思ったように動かなかった。

なぜか、USBフラッシュドライブが見えないんですね。

unetbootin のインストール

choco install unetbootin

USBドライブが見えない。

f:id:takuya_1st:20211126172659p:plain

起動時に引数を与える。

windowsの場合、次のようにcmd.exeで引数を与えてやると動く

unetbootin installtype=USB targetdrive=D:\

f:id:takuya_1st:20211126172712p:plain

ドライブ・レターが割り当てられないとき

NTFS / FAT32 などでフォーマットする。

参考資料

https://superuser.com/questions/839523/windows-usb-tool-and-unetbootin-never-detects-external-hard-drive

debian 11 が勝手にスリープする問題。

debian 11 が勝手にスリープする。

デスクトップをインストールすると・・・

スリープも自動設定されます。

debianGnome 無しで入れればよかった。

20分でスリープしちゃいます。

スリープを無効にする。

sudo systemctl mask sleep.target suspend.target hibernate.target hybrid-sleep.target

GNOMEのいらないアプリを消す。

使わないと思うし、プロセスとして起動してくるので、ps aux 見るときに邪魔なので消しちゃえ。

sudo apt purge gnome-bluetooth \
    gnome-weather \
    gnome-music \
    gnome-maps \
    gnome-games\
    modemmanager \
    thunderbird \
    network-manager\
    wpasupplicant
sudo apt autoremove

多分使わない、ゲームとかいらんねん。

いらないものを消しておかないと、バージョンアップや、バックアップで無駄な時間を浪費することになる。

とくに libre officeは正直使わないので、taskselでデスクトップをインストールするときにインストールしてほしくない。

WiFi/Bluetooth関連デバイスの状況見て判断してほしい。

Evolutionは多分使わない。

sudo apt purge evolution

https://askubuntu.com/questions/315640/how-do-i-completely-remove-evolution

gvfs が邪魔で umount アンマウントできない。

gvfs が邪魔で umount アンマウントできない。

takuya@server:~$ sudo lsof +D /mnt
lsof: WARNING: can't stat() fuse.gvfsd-fuse file system /run/user/116/gvfs
      Output information may be incomplete.
lsof: WARNING: can't stat() fuse.gvfsd-fuse file system /run/user/1000/gvfs
      Output information may be incomplete.

gvfs をアンマウントすると解決した。

takuya@server:~$ sudo umount /run/user/1000/gvfs
takuya@server:~$ sudo umount /run/user/116/gvfs

意外と単純ですね。

gvfs の親をたどって gdm や systemd-initを 再起動しなくちゃいけないのかとか思った。

gvfs でマウントさせない。

fstab から gvfs を排除する。

# before 
ro,noatime,nodiratime,nofail,nosuid,nodev,nofail,x-gvfs-show
# after
ro,noatime,nodiratime,nofail,nosuid,nodev,nofail

参考資料

https://askubuntu.com/questions/790273/lsof-warning-cant-stat-fuse-gvfsd-fuse-file-system-run-user-1000-gvfs-outp

SSDが死んだときの症状です。SSDが死んだときのメモ

SSDが死んだときの症状です。

立て続けに死ぬなんてついてない。この前は、HDDとSDカードがお亡くなりになったのですが、SSDも死にました。私の使い方は荒っぽいですかねえ。dd とか rsync とかガンガンやってるしnginxのキャッシュに使ってたしphpのキャッシュに使ってたし、lvm キャッシュに使ってたし。書き込み量は半端なかったとおもう。

f:id:takuya_1st:20211126161817p:plain

ELFヘッダが無い、つまりファイルが崩壊しています。 f:id:takuya_1st:20211126161828p:plain

resolve.conf もこのザマ。

f:id:takuya_1st:20211126161839p:plain

ファイルが壊れたんです。データが書き込めてないんです。

cat したらnull しか出てこないんです。

f:id:takuya_1st:20211126161854p:plain

まじで書き込めてない。

f:id:takuya_1st:20211126162003p:plain

ELFエラーになってるので /libを全部上書きすれば読めるんだろうけど。

Debianが最新バージョンになっていれば、いま新規で最新バージョンを入れても、ファイルが一致するので、インストールはできると思うんだよね。上書きインストールをすることもできるけど、まずはサルベージして別のHDD/SSD上でやらないとね。

読み込み専用でサルベージ(救出)

一部ファイルが読めるうちに、読み出す。

慌てずに、READ ONLY。

ただし、慌てない。 READ ONLYでマウント する。

noatime 未設定ならなおさらです。読む前に、読み込み専用にするべき。

もしくは、取り外した上で、完全にシステムから切り離して、全くアクセスが起きないようにする。

dd/ddrescue/で取り出しておきます。 dump / tar で読むときは、必ずリードオンリー。

故障前の具体的な症状。

大量ファイルの書き込みがやたら遅い。

apt upgrade / apt install などでめっちゃ時間がかかる。

今回は、gitlabc-ce をアップグレードが1時間とか掛かってた。気づけば終わらずに半日過ぎてました。 最初は、なんかプロセスのロック競合かと思ってたんだ。でもよく考えたら、SSDの寿命だったんです。

いつ起きたか。

apt dist-uprrade で判明した。が、 /etc/resolv.conf が壊れてDNSが引けなくなって気づきました。

dist-upgrade などで 一気に大量にファイルの更新が入ったので。書き込み上限に達したと思われる。

こう考えると、npm / yarn はSSDを殺しに来てますね。npm はSSDでは使わないことにする。npm するときは結果をキャッシュするかビルド済みをpush することにする。

mysql は返ってきませんでした。

一部破損くらいなら、ジャーナルでなんとかなるかと思ったけどだめですね。データベースのファイルごと飛んでいました。

smartのエラーメッセージ

完全に死んだあとにS.M.A.R.Tのメッセージが飛んできました。遅かった。

This message was generated by the smartd daemon running on:

   host name:  server
   DNS domain: [Empty]

The following warning/error was logged by the smartd daemon:

Device: /dev/nvme0, number of Error Log entries increased from 0 to 2

Device info:
CT500P1SSD8, S/N:18XXXXX, FW:P3CR010

For details see host's SYSLOG.

You can also use the smartctl utility for further investigation.
Another message will be sent in 24 hours if the problem persists.

メッセージをみると、 , number of Error Log entries increased from 0 to 2 とエラーが出てるのがはっきりわかるのでsmartmontoolsはあてになるようです。死んだあとでメール来たので遅かったけど。

死んだSSDについて

購入日 2019/2/5 でした。わずか2年半の短い命でした。

Crucial SSD M.2 500GB P1シリーズ Type2280 PCIe3.0x4 NVMe 5年保証 CT500P1SSD8

f:id:takuya_1st:20211126162348p:plain:w120

保証は効かない

f:id:takuya_1st:20211126163502p:plain

商品には5年保証と書いてあるが、CrucialのSSDは、販売店を経由した保証しか申請できない模様です。Amazonで購入したつもりが、マケプレでした。当然ですが、ショップに連絡は付きませんし、保証申請は絶望的な状況です。

保証付きでも申請できないという事実に心が折れたので、もう二度とcrucial は買いません。

SSD購入時の反省点

マケプレは絶対避ける。まともな正規代理店から買う。

保証申請してもデータは帰ってきませんが、金銭的に余裕ができます。保証申請ができるものを買うとき、保証が効く商品を購入する。海外輸入品とかそういうのは使い捨てです。保証はありません。

容量に余裕を持って購入する。

カツカツな容量で回すと、速度低下と寿命縮小を招くので少し余裕を持って買う。SSDは容量が大きいほど書き込みが高速になるのですこし容量に余裕を持って買う必要があると実感した。

SSD使用時の注意点

速いからと安易にキャッシュに使わない。

SSDは書き込み時にいい感じにローテーションしてくれるが、容量を半分以上使い切ると、ローテーションがうまく回らないらしい。つねに空き容量を持っておく必要がある。

discard / trim の実行を気にかける。

いい感じに trim する。trim するときは、全体がちゃんと trim されているか注意する 。Systemdで有効化されているはずなので動作チェックしておく。

fstrim --verbose --all

バックアップを取る。

常識ですが、バックアップやスナップショットを常に持っておく必要があります。

式年遷宮する。

ストレージには寿命があります。式年遷宮しましょう。

debian multimedia を有効にする

debian multimedia を有効にする

最近は公式レポジトリが追いついてきてるので、よほどの理由がない限り入れずに済むのですが。念の為に入れていくことにする

apt/sources.list.d/multimedia.list

deb https://www.deb-multimedia.org bullseye main non-free
deb https://www.deb-multimedia.org bullseye stable non-free

有効化

apt-get update
apt-get update -oAcquire::AllowInsecureRepositories=true
apt-get install deb-multimedia-keyring
apt-get update -oAcquire::AllowInsecureRepositories=false

automysqlbackupに救われた。新サーバにも導入する。

automysqlbackupに救われた。

SSDが寿命により崩壊し、データが消えたと嘆いていたのですが。mysql のデータは残っていた。

入れたことを忘れていた。

存在を忘れていたautomysqlbackupがバックアップを取ってくれていた。助かる。 まじ救われた。5年前の自分に感謝。

バックアップの保存先。

/var/lib/automysqlbackup

automysqlbackup インストール

debian 11 では。パスワードの設定が必要。以前は debian-sys-adm というユーザーが存在してそれをそのまま使うことができていたが、セキュリティ上の理由の懸念により現在は使えない。

MariaDB [(none)]> SELECT Host, User, Password FROM mysql.user;
+-----------+------------------+-------------------------------------------+
| Host      | User             | Password                                  |
+-----------+------------------+-------------------------------------------+
| localhost | root             | *ABCDEFGHIJKLMNOP123456787890|
+-----------+------------------+-------------------------------------------+

面倒なので、既存のパスワードを消してやる

このため、デフォルトはrootなので、sshでログインしない限り使えない。

set password for root@localhost=password('')

root@localhsot のパスワードを無効にしても大丈夫なのは、ssh でログインしない限り使えないから。リモート( mysql 接続) では使えません。ただしnginxのプロキシでmysql.sock を公開されちゃうとかされたら危険。そのときは知らない。

バックアップが取得されることを確認。

sudo  /usr/sbin/automysqlbackup
sudo find  /var/lib/automysqlbackup/

パスワードを設定する場合

automysqlbackup は単なるスクリプトなので設定は環境変数を使うだけになっている。

/etc/default/automysqlbackup

USERNAME=debian-sys-maint
PASSWORD=my_root_password
DBNAMES="`mysql --user=$USERNAME --password=$PASSWORD --host=$DBHOST --batch --skip-column-names -e "show databases"| sed 's/ /%/g'`"

これで、auto mysql dump backup が稼働する。

debian11 での注意

debian-sys-maint と /etc/mysql/debian.cnf が使えなくなっている。

以前は、/etc/mysql/debian.cnf にメンテナンス用のパスワードを記載していたが使えなくなっているので注意が必要。

debian 11 での利用の場合

debian-sys-maint を有効にする。

ALTER USER 'debian-sys-maint'@'localhost' IDENTIFIED BY  'P@assword123456' WITH GRANT OPTION;

sys-maint を使うように設定する。

USERNAME=debian-sys-maint
PASSWORD=P@assword123456

performance_schema を除外する。

DBNAMES="`mysql --user=$USERNAME --password=$PASSWORD --host=$DBHOST  \
--batch --skip-column-names -e "show databases"|  \
grep -v performance_schema | sed 's/ /%/g'`"

perfomance_schema.account テーブルがロックできなくて落ちる。

次のようにロックのエラーが出てくる。

mysqldump: Got error: 1142: "SELECT, LOCK TABLES command denied to user 'debian-sys-maint'@'localhost' for table 'accounts'" when using LOCK TABLES

perfomance_schemaは、バックアップになくても影響ないテーブルなので、除外する。

そのために、/etc/cron.daily/automysqlbackup を書き換えて、grep -v を追加した。

参考資料

nextcloud のdataディレクトリの移動をする。

データ・ディレクトリを変更する。

データの場所だけの変更なら割と楽

occ 初期チェックが不安定なのでちょっと壊れたりするけど概ね問題なく移動できる。

nextcloud のデータ・ディレクトリを別空間にすることで、phpソースコードときれいに分離するので管理が楽になる。nextcloudの動作チェック時にphpソースコードgrep で検索しやすくなる。

手順

  1. メンテナンス・モードをON
  2. データベースのバックアップ
  3. ディレクトリを移動(またはコピー)
  4. 設定の書き換え
  5. メンテナンス・モードOFF

最初にメンテナンス・モードをONにしておく

php nextcloud/occ  maintenance:mode --on

バージョン。私の現在のバージョンは次の通り。

php nextcloud/occ -V
Nextcloud is in maintenance mode - no apps have been loaded

Nextcloud 22.2.3

念の為にデータベースをバックアップ

## mysql の場合
mysqldump nextcloud
## sqlite3 の場合
cp nextcloud.sqlite3{,back}

ディレクトリを移動 わたしは、マウントしてるだけなので変更は楽ちん。

sudo umount nextcloud/data
sudo mount /dev/sdx /opt/nextcloud/data
sudo chown -R www-data. /opt/nextcloud
sudo -u www-data /opt/nextcloud/data/.ocdata

occの起動時のディレクトリ・チェックのプログラムが不安定で、上位ディレクトリへのパーミッション・チェックが走るので、nextcloud/data のように階層構造を作ってあげないと、うまくいかないとおもう。

設定の変更

nextcloud/occ  config:system:set  datadirectory --value="/opt/nextcloud/data/"

最後にメンテナンスモードをオフにする。

php nextcloud/occ  maintenance:mode --off

コレで終わり

うまくいかないとき

初期チェックが走って、データベースがぶっ壊れてる可能性がある。

ちいとばかり、初期チェック動作が不安定だったので注意する。

ディレクトリを消すと初期チェックが走るのだが、設定を替えてるのが反映されないので、データベースにゴミデータが書かれて困った。

データベースの修正。

ストレージ指定が、local::/ だとか local::/var/www/nextcloud/dataとかやばい感じなることがあったので修正した。

select * from oc_storages;
alter table oc_storages auto_increment = 0 ;
delete from oc_storages where numeric_id = 1 limit 1;
update oc_storages set numeric_id = 1 where numeric_id=12;

階層を1段深くしなかったとき。

takuya@:nextcloud$ sudo sudo -u www-data php /opt/nextcloud-data
データディレクトリは、絶対パスにする必要があります
設定ファイル内の "datadirectory" の値を確認してください。

データディレクトリが無効です
データディレクトリの直下に ".ocdata" ファイルがあるのを確認してください。

"data" ディレクトリを作成できません
多くの場合、Webサーバーのルートディレクトリに書き込み権限を与えることで直ります。https://docs.nextcloud.com/server/22/go.php?to=admin-dir_permissions を見てください。

参考資料

https://matoken.org/blog/2019/12/03/move-nextcloud-data-directory/

luksRemoveKey で最後のカギを消去する。(kill slot や remove key )

最後の一個を消すとどうなるんだろう。

cryptsetup luksRemoveKey /dev/sdg 

luksRemoveKey でHDDを安全に消去するに等しいですね。luksの暗号化ストレージは、鍵がないとアクセスできません。鍵を消せば全てアクセス不能になり、アクセス不能とは消したに等しい。

takuya@:~$ sudo cryptsetup luksRemoveKey /dev/sdg
削除するキーのパスフレーズを入力してください:

WARNING!
========
これは最後のキースロットです。このキーがなくなるとデバイスは使用不能になります。

Are you sure? (Type 'yes' in capital letters):
操作は中止されました。キースロットは消去されていません。

luksKillSlot の場合

1つしか無い鍵を、luksKillSlotで、killslot してやる。

sudo cryptsetup luksKillSlot  /dev/nvme1n1  0

同じように鍵データを消すことができる。

最後のカギを消去=HDDの消去。

鍵を消せばもう二度とアクセスできません。

HDDを物理的に消去せずともデータを誰かに読まれる可能性はなくなります。

うっかり消した場合。

luksHeaderBackupしていれば、復旧が可能です。

キースロットが空っぽ

takuya@:~$ sudo cryptsetup luksDump /dev/sdg
LUKS header information
(略

Data segments:
  0: crypt
        offset: 16777216 [bytes]
        length: (whole device)
        cipher: aes-xts-plain64
        sector: 512 [bytes]

Keyslots:
Tokens:
Digests:
(略

header をリストアする

takuya@:~$ sudo cryptsetup luksHeaderRestore /dev/sdg --header-backup-file=sdg.header.dump

WARNING!
========
デバイス /dev/sdg 既に LUKS2 ヘッダがあります。ヘッダを置き換えると既にあるキースロットを破壊します。

Are you sure? (Type 'yes' in capital letters): YES

ヘッダが戻る。

ヘッダが戻ると使える。

takuya@:~$ sudo cryptsetup luksDump /dev/sdg
LUKS header information
(略
Data segments:
  0: crypt
        offset: 16777216 [bytes]
        length: (whole device)
        cipher: aes-xts-plain64
        sector: 512 [bytes]

Keyslots:
  0: luks2
        Key:        512 bits
        Priority:   normal
        Cipher:     aes-xts-plain64
        Cipher key: 512 bits
        PBKDF:      argon2i
        Time cost:  5
        Memory:     1048576
        Threads:    4
        Salt:       14 08 04 8e 97 f3 64 7b cb eb 6c 3e 33 e2 ed 0c
                    73 9f 4b 60 92 e7 5a 3e 89 d9 44 5b 7b 3b ee 11
        AF stripes: 4000
        AF hash:    sha256
        Area offset:32768 [bytes]
        Area length:258048 [bytes]
        Digest ID:  0
Tokens:
Digests:
(略

最後のカギを消去する前に

鍵を替えておく。

どうしても心配なら

鍵を変更だけでも不安なら、re-encrypt で鍵を替えて再暗号化。マスターキーが変更される。

takuya@:~$ sudo cryptsetup-reencrypt /dev/sdg
キースロット 0 のパスフレーズを入力してください:
Progress:   0.0%, ETA 782:17, 1264 MiB written, speed  81.3 MiB/s

ちゃんと仕様を見てないけど、マスターキーがあって、そのキーを複製し、暗号化してキースロットにおいてるんだと思う。

2023-11-30

killslot で検索にかからないのでキーワードを追加

このHDD・SSDはUSBで接続しているのか

このHDD・SSDはUSBで接続しているのか

USB/SSD がUSB接続なのかeSATAなのか、どっちかわからなくなった。

同じ型番(モデル)のディスクで区別がつなかいのでまいったので、区別して、違いを見つける方法を探した。

sdXが USB 接続か調べる。

find /dev/disk/by-id/ -lname '*sdX'

やってみた。

takuya@:~$ find /dev/disk/by-id/ -lname '*sde'
/dev/disk/by-id/wwn-0x50014ee2642edf63
/dev/disk/by-id/ata-WDC_WD40EZRZ-22GXCB0_WD-WCC7XXXX
takuya@:~$ find /dev/disk/by-id/ -lname '*sdg'
/dev/disk/by-id/usb-JMicron_Generic_0123456789ABCDEF-0:0

/dev/disk/by-id/ はシンボリック・リンク

シンボリックリンクになっているので、その先をみてみよう

takuya@:~$ ll /dev/disk/by-id/usb-JMicron_Generic_0123456789ABCDEF-0:0
lrwxrwxrwx 1 root root 9 11月 23 23:43 /dev/disk/by-id/usb-JMicron_Generic_0123456789ABCDEF-0:0 -> ../../sdg

なるほど、シンボリックリンクで管理されてるんですね。

takuya@:~$ ll /dev/disk/by-id/ata-WDC_WD40EZRZ-22GXCB0_WD-WCC7XXXXXXXXXX
lrwxrwxrwx 1 root root 9 11月 23 23:43 /dev/disk/by-id/ata-WDC_WD40EZRZ-22GXCB0_WD-WCC7KXXXX-> ../../sde

SSD でも大丈夫

takuya@:~$ find /dev/disk/by-id/ -lname '*sda'
/dev/disk/by-id/usb-NV-2242A_NV-2242A_00A20XXXX

わかりますね。助かる。