それマグで!

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

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

gzip ファイルの圧縮率を変える。

圧縮率をbestに変えたい

圧縮率を変えるには、再圧縮が必要

gzip -cd old.gz | gzip > new.gz

伸長(展開)してからやるとストレージが無駄になる。

gzip -cd dump.gz 
gzip -best dump

そこで、直接パイプしてあげればいい

gzip -cd dump.gz  | gzip > dump.gz.2

巨大ファイルで時間のかかるとき

pv と組み合わせて、進捗を表示しつつ

pigz で CPUパワーをフルパワーで使ってやる。

pv -cN read dump.gz | pigz -d -p4 | pigz --best -p 4 | pv -cN compress >  dump.gz.2

インストール

sudo apt install pv pigz 

圧縮アルゴリズムを変更するときも同様

gzipからxz に変えたいときも同様にできる。

gzip -cd old.gz | xz > new.gz

圧縮アルゴリズムの選定基準

圧縮アルゴリズムを「圧縮時間」「圧縮率」だけで比較するのは、だめ。

xz は圧縮には時間が掛かるが、展開は速い。そのため。「XZは、誰か一人がCPU時間を提供して、多くの利用者が展開で使う」ようなときに大変メリットがある。だからリナックスカーネルとかに使われてたりする。

gzip は圧縮時間も圧縮率もそこそこで、使いやすい。「gzipはどこでも使えるオールラウンダ」ってことだし。

圧縮は、繰り返しデータの出現に対し行われるので、ディスクイメージに空き容量があればとても圧縮が効く。

だけど、CD-ROMやUbuntuのインストールUSBのような重複コンテンツは殆どなく容量いっぱいまで使われているストレージには、圧縮は殆ど効果を発揮しない。時間を掛けてXZで圧縮してもGzipでサクッと圧縮してもgzip/xzの結果で数MBも変わらない。

圧縮がどれくらい効くファイルなのか、ちゃんと予想くらいは立てて圧縮作業の展望を持っておかないと、圧縮率を変えても、圧縮アルゴリズムを変更しても電気の無駄遣いになるだけなので注意です。

「完全なランダムデータ」は圧縮が効かないってことをちゃんとわかった上で、ランダムデータに近いものほど圧縮効果が無いことを忘れないでほしいのです。

snap lxd のbtrfsストレージの中に入る

snap lxd の中に入りたい。

BTRFSの場合単純にマウントしてもいいんだけど。

lxc storage list | grep default
losetup -l | grep default.img
/dev/loop10         0      0         1  0 /var/snap/lxd/common/lxd/disks/default.img   1     512
mount /dev/loop10   /mnt

マウントもちょっと怖い。とかZFSの場合どうするんだろうか考えた。

本来lxd のストレージはそのままアクセスできるはずなんだけど、snap の場合はlxdはsnap内部に閉じ込められているんで外部からアクセスで規範い。

snap の中へ chroot してみる

snap の環境の中にlxd

root@#  chroot /var/snap/lxd/common/mntns  /bin/bash

これでsnapでもlxdで使ってるストレージを直接見ることができたわ

各種コマンドをPATH通す

sudo chroot /var/snap/lxd/common/mntns /bin/bash
export PATH=$PATH:/snap/lxd/current/bin
### インスタンスのなかを直接もみる。
cd /var/snap/lxd/common/lxd/containers/nginx/

btrfs を修正したり。

btrfs property set -ts /var/snap/lxd/common/mntns/var/snap/lxd/common/lxd/storage-pools/bt01/containers/nginx ro false

snap のlxdの問題

snap環境にセパレートされていて、管理も楽だし最新版が提供されるので便利だけど、トラブル時に通常LXD違うのでちょっとめんどくさかった。

lxc delete 時間かかりすぎるのでストレージまるごと消したい。

lxc delete 時間かかりすぎる

lxc ストレージのbtrfsのrestore(load)に失敗したので。強制的に消す方法を模索する

うっかり、コンテナに200GBも入れてしまったので、時間がかかって仕方ない。

いっそのこと先にストレージをけしたらどうなるのか。1Gのコンテナで試してみることにした。

ストレージとインスタンスを作成する

lxc storage create bt02 btrfs
lxc launch images:debian/11 d11 --storage=bt02

ストレージを消してやる

sudo rm   /var/snap/lxd/common/lxd/disks/bt02.img

ファイルはもうない

sudo ls -alt  /var/snap/lxd/common/lxd/disks/bt02.img
ls: cannot access '/var/snap/lxd/common/lxd/disks/bt02.img': No such file or directory

参照は残ってる。

losetup
NAME        SIZELIMIT OFFSET AUTOCLEAR RO BACK-FILE                                         DIO LOG-SEC
/dev/loop10         0      0         1  0 /var/snap/lxd/common/lxd/disks/bt02.img (deleted)   1     512
lxc storage list
+---------+--------+--------------------------------------------+-------------+---------+---------+
|  NAME   | DRIVER |                   SOURCE                   | DESCRIPTION | USED BY |  STATE  |
+---------+--------+--------------------------------------------+-------------+---------+---------+
| bt02    | btrfs  | /var/snap/lxd/common/lxd/disks/bt02.img    |             | 2       | CREATED |
+---------+--------+--------------------------------------------+-------------+---------+---------+

ストレージは消したけど、新規起動できてしまう。

ある意味正しいけどある意味怖い。

lxc launch images:debian/11 d12 --storage=bt02
Creating d12
Starting d12

ストレージが消えたのを反映させる。

ストレージの存在と状態はSQLiteで管理しているらしく、起動にチェックするらしい。 SQLiteを操作して消す以外に方法が見当たらない、

lxd を再起動して、エラーにしてやる。

sudo snap restart lxd

再起動すると UNAVAILABLE にななる。.

 lxc storage list
+---------+--------+--------------------------------------------+-------------+---------+-------------+
|  NAME   | DRIVER |                   SOURCE                   | DESCRIPTION | USED BY |    STATE    |
+---------+--------+--------------------------------------------+-------------+---------+-------------+
| bt02    | btrfs  | /var/snap/lxd/common/lxd/disks/bt02.img    |             | 3       | UNAVAILABLE |
+---------+--------+--------------------------------------------+-------------+---------+-------------+

インスタンスはストレージがないので起動していない。

lxc list
+------+---------+------+------+-----------+-----------+
| NAME |  STATE  | IPV4 | IPV6 |   TYPE    | SNAPSHOTS |
+------+---------+------+------+-----------+-----------+
| d11  | STOPPED |      |      | CONTAINER | 0         |
+------+---------+------+------+-----------+-----------+
| d12  | STOPPED |      |      | CONTAINER | 0         |
+------+---------+------+------+-----------+-----------+

インスタンスを消してみる

lxc delete d12
lxc delete d11

特にエラーなく消せる。

ストレージを一覧から削除する

lxc storage delete bt02

無事消えました。

結論

ストレージ・ファイルを消しても、起動中なら参照は残ってるので、そのまま使える。

再起動すると、ストレージがが見つからいためUNAVAILABLEになる。インスタンスも起動しない。

その状態でインスタンスを消すことはできる。

この方法でbtrfsエラーが出て、消せなくなったコンテナを消すことができるようになった。

インスタンスを直接消す事ができるので、エラーがでたストレージは切り離せませすね。

複数のインスタンスでストレージを使ってる場合は、インスタンスlxc move で移動させておけば、影響なく消せますね。やったね。

btrfs 怖すぎるだろほんと。

lxc のインスタンスにコンソールを接続する

lxc で起動したらコンソールにつなぎたい

console は完全に virsh っぽい。

lxc stop vps
lxc start --console  vps

ちゃんと起動ログを確認できる、

takuya@raspi-ubuntu:~$ lxc start d12 --console
To detach from the console, press: <ctrl>+a q
Queued start job for default target Graphical Interface.
[  OK  ] Created slice system-getty.slice.
[  OK  ] Created slice system-modprobe.slice.
[  OK  ] Created slice User and Session Slice.
[  OK  ] Started Dispatch Password Requests to Console Directory Watch.
[  OK  ] Started Forward Password Requests to Wall Directory Watch.
[UNSUPP] Starting of Arbitrary Executable Fi…tem Automount Point not supported.
[  OK  ] Reached target Local Encrypted Volumes.
[  OK  ] Reached target Paths.
[  OK  ] Reached target Remote File Systems.
[  OK  ] Reached target Slices.
[  OK  ] Reached target Swap.
[  OK  ] Listening on initctl Compatibility Named Pipe.
[  OK  ] Listening on Journal Socket (/dev/log).
[  OK  ] Listening on Journal Socket.
[  OK  ] Listening on Network Service Netlink Socket.
[  OK  ] Listening on udev Control Socket.
[  OK  ] Listening on udev Kernel Socket.

Debian GNU/Linux 11 d12 console

d12 login: takuya
Password:

切断

切断は、 ctrl a q です。

ctrl a は gnu screen とかぶるので注意が必要

コンソールにだけ接続する

コンソールにだけ接続する

lxc console d12 

注意。

私の環境ではmconsole 付きで起動した場合 lxc shell が壊れることがあったので注意

lxc のインスタンスのIPアドレスを固定する

staic に割り当てたい

lxbr0 でDHCPから割り当てられるが、固定したい時がある。 デバイスを割り当ててればい

lxbr0 の割当をして、固定する。

lxc config device remove eth1 nginx
lxc network attach lxdbr0 nginx eth1 eth1
lxc config device set nginx eth1 ipv4.address 10.185.93.4

内部だけどデバイスで割り当てるのは、完全な内部というより外部のブリッジにつなぐだけですね。

lxdbr0 以外にも接続できるなら、libvirt ネットワークやdocker ネットワークにも接続できたりできそうですね。

docker のボリュームのサーバー間移動

docker ボリュームをサーバ間で移動する

ただrsyncすれば問題なく動く。dockerコマンドは使いません。直接取り出せば大丈夫です。

ホスト側にログインする。docker の内部には一切ログインしない。

コマンド例

takuya$ ssh takuya@docker-host
takuya@docker-host$ sudo rsync -av /var/lib/docker/volumes server:/var/lib/docker/volumes

/var/lib/docker/volumes のバックアップ

繰り返しになるが、docker コマンドは使いません。

/var/lib/docker/volumes をホスト側でtgz で固めて移動させてもいい。

tar cvzf  volumes.tgz /var/lib/docker/volumes 
rsync -av volumes.tgz  server:~

コンテナごとに取り出したり、execしてもいいけど、ホスト側から読み出して、まとめて持っていけるんですよね。

コンテナは停止が無難。

コンテナを停止してファイルを書き出しさせてからバックアップを取る。

データベースなどは、稼働中の移動は少しだけリスキー。コンテナ起動中に exec で取り出したり、docker cp で取り出したりだと危険がある。execしてもダイレクトにボリュームをrsyncしても同じことだともう。

単なるファイルしかおいてないのであれば、稼働中に取り出しても大丈夫だと思う。

ただし、docker が起動してたら書き込みタイミングでファイルが変わるかもしれないですけど。ディスクIOはきれいに制御されているはずなので、「ファイル」に対するアクセスだけなら問題ないと思う。ファイルをループバックでマウントしてたり常時開いて書き込んでいる状態の場合は万が一のことはあると思うが。docker プロセス停止してたら問題ない。

LXCのbtfsストレージの中身を見る

LXCのbtfsストレージの中身を見る

LXCのストレージをマウントしてアクセスする。

btrfs は losetup 経由になっている。zfs の場合は違う。

lxc のストレージ情報を見る

lxc storage list 
LXCストレージをマウントしてデータを取り出す。
lxc storage list | grep default 
mount /dev/loopX /mnt

lxd が未起動の場合には、losetup

lxdが起動中なら loseup されているのですが。lxdが未起動の場合は自分でlosetup してあげる必要がある。

lxc storage list | grep default 
losetup -f --show /var/snap/lxd/common/lxd/disks/default.img
mount /dev/loopX /mnt

btrfs の場合は、特に問題なくマウントができる。

サクッと調べたい
function lxc_show_storage(){
  name=$1
    losetup | grep $1
    loop_dev=$( losetup | grep $name | cut -d ' ' -f 1 )
    echo $loop_dev
    img_path=$(losetup | grep $name | awk '{print $6}')
    echo $img_path
}

マウントしたりメンテしたり

btrfs の場合は、scrub や resize max を実行しメンテナンスする必要がありlosetup 経由はめっちゃ使う。

自宅サバのpostfix のメール送信を外部サーバーに任せる(SSHでvpsから送信)

postfix via ssh でメール送信を安全にする

VPN経由でメール送信をすると大変。VPNの管理がめんどくさい。

だったらHTTPS/SSHで配送すればいい。

SSHpostfix配送する。

単純に、SSH起動して、SSH経由でsendmail を起動すればいい。

/etc/postfix/master.cf

master cf で sshを起動する設定を掛けばいい

master.cf にssh設定を書く

## ssh でVPSから送信する。
ssh-relay-hateml unix    -       n       n       -       -     pipe
  user=mail argv=/usr/bin/ssh -i /etc/mail/ssh-sendmail-key root@ssh.server.local -p 2222  /usr/sbin/sendmail -i $recipient

これは、次のコマンドをpostfixで呼び出すだけである。

cat sample-mail.txt | sudo -u mail  ssh -i /etc/mail/ssh-sendmail-key root@ssh.server.local -p 2222  /usr/sbin/sendmail 

master.cf に curl/phpスクリプトを指定する。

## https で送信する。
php-relay unix    -       n       n       -       -     pipe
  user=www-data argv=/usr/bin/php -f /takuya/stdin.php $recipient

これは、次のphpコマンドをpostfixで呼び出すだけである。

cat sample-mail.txt | sudo -u www-data  /usr/bin/php -f /home/takuya/https_sendmail.php takuya@example.com

https_sendmail.php の中で curlHTTPS経由でメールを送る。 サーバー側にphpファイルを設置しておく

https_sendmail.php は簡単にcurl を使えばいいだけですね。

<?php 
// 処理の概要
$ch = curl_init("https://www.example.com/index.php?key=$KEY");
curl_exec($ch);
curl_close($ch);

サーバー側で、受け取ってあげればいい。 /var/www/virtualhosts/sendmail.example.com/www-data/index.php

<?php 
## 処理の概要を抜粋
// 認証
if ( $key != $_POST['key] ){
   exit;
}
// メール送信
mail(
    $_POST['mail']['to'],
    $_POST['mail']['subject'],
    $_POST['mail']['message'],
    $_POST['mail']['additional_headers '],
    $_POST['mail']['additional_params'],
):

どの配送を使うか決める

master.cf に複数記述した配送方式から外部向けのデフォルト送信先を変えておけばいいわけである。

/etc/postfix/main.cf

main.cf で選ぶ

default_transport = ssh-relay-hateml

transport map で決めてあげればメアド毎に配送を決められる。

HTTPS/SSHで転送すれば確実。もう、ポートスキャンやセキュリティに悩まなくて済む。

まとめ

別サーバーにSMTPの配送を任せるが、OP25B で配送ができないので、困る。

だったらレンサバ・VPSAmazon AWS経由で送信すればいい。それだけ。

OB25Bがある?だったらレイヤを変えて送信すればいい。25を使わず、SSHHTTPSでメールを配送すればいいだけである。

VPN接続してレイヤを合わせるのは、維持管理がめんどくさいので、単純にコマンドをパイプで繋いだらUNIXらしくていいじゃないか。

GoogleGMAILがxoauth 対応しないとめんどくさいので、1台だけXOAUTHサーバーを作っておいて、そこへSSHでメール送信すればいいわけである。

関連資料

時間のかかる巨大ファイルコピーで進捗の状況を見ながら操作したい

長時間コピーがいつ終わるかわからない。

100GB を超えるストレージ・ダンプのコピーがいつ終わるか予想がつかない。

cp hdd.img /mnt/hdd.img

100GBとかいつ終わるの・・・ってなる

手軽な手段 rsync

rsync -av --progress source hdd.img /mnt/hdd.img

rsync が一番手軽な手段。ただし rsync-z をつけると圧縮転送だから注意。あとrsync は理由がわからないが遅い。

進捗を見ながらコピーしたい → dd

dd / ddrescue を使えばコピーの進捗を見ながらできるじゃん

ddrescue hdd.img /mnt/hdd.img
dd  if=hdd.img of=/mnt/hdd.img status=progress

pv で進捗をバー表示

sudo apt install pv で pv をインストールしてあげれば、コピー状況がわかるじゃん

pv hdd.img | cat - > /mnt/hdd.img

プログレスバーが出てくる

59.3GiB 0:23:16 [38.1MiB/s] [=======>                 ] 32% ETA 0:47:23

pv なら圧縮転送できる

pv はファイルを読み込んで、流すだけなのでパイプ使えるじゃん

pv hdd.img | gzip - >  /mnt/hdd.img

これなら進捗わかるじゃん。

gzip 圧縮が遅いのでpigz に変える

gzip を挟むと遅いので pigzに変えてあげる。準備はsudo apt install pigz で。

pv hdd.img | pigz - >  /mnt/hdd.img.gz

圧縮をとにかく速く

圧縮率を調整してもうちょっと時間を稼げる。

pv hdd.img | pigz --fast - >  /mnt/hdd.img.gz

圧縮と読込の両方の状況を表示

pv は cat として動作するので、書き込み速度の状況を表示できた

pv -c hdd.img | pigz --fast | pv -c >  /mnt/hdd.img.gz

ただ、2つ表示すると、区別がつかないので名前をつけてあげる

pv -cN src-read hdd.img | pigz --fast | pv -cN gz-out - >  /mnt/hdd.img.gz

-c はそれぞれの進捗を見るためのオプション
-N は名前を付けるオプション

オプションをつけたら進捗が手にとるようにわかって楽しい。

参考資料

https://wonderwall.hatenablog.com/entry/2017/08/03/072500

持ち運べるUSB-nvmeを作ってWindows・Ubuntu環境をいつでもどこでも

USB起動する Windows を作る

通称Windows to Go と呼ばれる、USBドライブで起動するWindowsを作ることができる。

意義

  • 小型のSSDWindowsを入れて持ち運べる
  • SSDで250GBがポケットサイズになったのでとても楽
  • HDDのように耐衝撃性を考えなくて済む
  • いつもの環境を使えるようになる。

SSD をどうするか

この商品が手にはいったので持ち運べるOSが作れるようになった。

nvme 2230 をUSBメモリに化けさせることができる。

そしてその容量で250GBでデュアルブートLinux/Windows/Mac)が作れるので楽ちん*1

持ち運べるSSD/nvme

コンパクトな最強の商品があります。

リモートワークに最適

ノートPC持参するより楽じゃん?

小学校に、OSの入ってないPCとモニタを用意しておき、USBメモリで起動すればいい。備品管理が格段に楽ちん

リモートワーク(在宅)とオフィス出社するときに、ブートするUSBメモリを持ち運べばいい。

そして、それはポケットに入ってじゃまにならないサイズで高速起動しておけばいい。ストレージは暗号化かけておけばいい。

VDI/RDPより快適なのでは

USBメモリを持ち運べば、いつでもどこでも同じ環境で仕事ができると考えれば、VDI環境作るまでもないんじゃないの。

めちゃくちゃいい

USBメモリのように低速に悩むこともないし、中身を取り替えて使える。めっちゃおすすめ。

NVME 2230/2242 なので本当に持ち運びしやすい。2280は22mm x 88mm ですが、2242は 22mm x 42 mm です。そう考えるとめっちゃ小さいでしょ?

*1:macbook にパスワードを設定しているとUSBブートにパスワードが必要になったので、macbookから別OSを起動するの面倒だけど

ubuntu Live CDでWindowsのバックアップを取得する

ubuntu Live CDでWindowsのバックアップを取得する

UbuntuのLiveUSBを作成してバックアップを作る

UbuntuのLiveUSBを使って、HDDをクローン作成出来ます。

自分のPCにUSBフラッシュドライブを差し込んでUbuntuで起動します。Ubuntuが起動したら「ターミナル」を起動します。

ddrescue をインストールします。

ターミナルに次の命令(コマンド)を打ち込みます。

sudo add-apt-repository universe
sudo apt install gddrescue 

ddrescue でバックアップを取ります。

インストールした ddrescueを使って「バックアップ」を作ります。

ddrescue /dev/sdd /dev/sde

/dev/sddって何?

/dev/sda /dev/sdb /dev/sdc はHDD・SSDUSBメモリなどストレージを接続したら、そのストレージ(ブロックデバイス)を識別し利用するために、自動的につけられる名前です。/dev/sda /dev/sdb /dev/sdc と接続した順に使われます。

/dev/sdd の名前は、起動したパソコンへのUSB接続状態で変わります。

どのディスクがどの名前になってるかを調べるには、ターミナルに次のコマンドを打ち込めばわかります。

lsblk 

USBドライブを抜き差しししながら、lsblkの結果を眺めて名前を特定しましょう。

WindowsのDドライブと何が違うの?

Dドライブの名前は、WindowsでSDカード接続したときに自動的につけられる名前で、これもC/D/E/Fと順番に使われます。/dev/sda と似ていますね

でも、/dev/sdeE:\ は全く違います。

windowsでは「ファイルが読み書きができる状態」のストレージにアルファベットを割り当てています。ファイルの読み書きができない状態のドライブを、Windowsでは Disk0/Disk1 のように連番を割り当てています。(通常は見えません。)この連番が linuxでは /dev/sda,sdbのようなアルファベットになっています。

読み書きできないって?

「ファイルが読み書きできない」状態とは、空っぽのストレージです。

空っぽとは未フォーマットことです。「未フォーマット状態」も馴染みがなくて、わかりにくいとおもいます。データ消去ソフトで0を書き込み抹消した状態です。

未フォーマット状態でも書き込める。

ストレージは、未フォーマット状態でも、書き込みが可能です。未フォーマットのドライブをフォーマットすれば、書き込めるようになります。フォーマットするとは、ディスクに「パーティション情報を書き込んでいるのです」

未フォーマットのドライブに書き込みができないとフォーマットができないですよね。だから、未フォーマット状態のドライブでも読み書きは出来ているわけです。この直接アクセス機能でHDDクローンを作るのがバックアップ・イメージ作成の基本的な戦略です。

ストレージを直接扱う /dev/sda

未フォーマット状態の生ストレージをLinuxではブロックデバイスと呼びます。このブロックデバイスを扱うのが /dev/sda のデバイス名になります。

Windowsでは、生のディスクを「Disk」、フォーマット済でファイルが書き込める状態のディスクを「Volume」と呼んで区別していますね。

UbuntuLinuxなのでHDD/SSDをダイレクトに扱うときは /dev/sdXのような名前でアクセスします。

生のデバイスを使ってクローン

ddrescue では、ファイルを読み出すのではなく、生のデバイスとして、0/1の信号まま直接読み出すことが出来ます。0/1の信号を直接読み出してハードディスクからハードディスクへコピーしてクローンを作ることが出来ます。

CD/DVDも生のデバイスとして扱えます。このクローンの機能で、CD/DVDをそのまま複製するときも使われます。

ddrescue のコマンドの詳細

冒頭の ddrescue コマンドは、/dev/sdd のディスクから /dev/sde のディスクにデータを丸コピーしているのです。

ddrescue /dev/sdd /dev/sde

ddrescue のコマンド書式は次のようになっています。

ddrescue SOURCE DESTINATION

source は転送元、destination は転送先を表します。省略してsrc/dstと書くこともあります。

ddrescue src dstではは、HDDに限らずコピーできるものなら何でもコピーします。ddrescueはデータを左から右へ流すだけのソフトウェアです。もちろんファイルコピーも出来ます。

バックアップをファイル保存

ddrescueが使えるからと行ってディスク → ディスク ( disk to disk ) で保存していると、HDDが何台在って足りません。そこで大容量ディスクに「ファイル」として保存しておけば、HDDの台数を節約できますし、USB再接続の手間が省けます。

ddrescue /dev/sdd my-backup.img

コピー先はコピー元より大容量が必要です。ファイルを保存するときも同様です。ファイルがあるフォルダがHDDより大容量でなくてはいけません。

容量が足りない

しかし実際にはコピーしようとすると、コピー先容量が足りないことがあります。どうしたらいいでしょうか。データを圧縮すれば解決です。データ圧縮で容量を節約できます。

このときddrescueの代わりにddを使います。 dd は ddrescue の祖先です。

コマンドは次になります。

dd if=/dev/sdd | gzip - > my-backup.img.gz

ddrescueの代わりに上記コマンドを使います。 dd は ddrescue の祖先です。dd もデータを流すだけのソフトウェアです。

  • dd if=/dev/sdd は。データを抜き出して別プログラムに転送します。
  • | は、左から右へデータを流します。左と右にプログラムを指定します。
  • gzip - > my-backup.img.gzは、受け取ったデータを圧縮して、右のファイルへ書き出します。

これらを合わせたら上記のコマンドは「転送と転送」と「圧縮と転送」を組み合わせていたとわかります。dd で抜き出したデータを |で転送して、gzipで圧縮し、> my-backup.img.gzに書き出す命令ということです。

データを書き戻す。

バックアップデータは元HDDに書出したいと考えるでしょう。

先程の ddrescue の転送先と転送元の順番を逆にすればいいのです。

ddrescue /dev/sde /dev/sdd

圧縮ファイルの場合は逆(展開)が入ります。

gzip -d my-backup.img.gz -c | dd of=/dev/sdd

圧縮されたデータでも転送の順番を逆にすればいいのですが、圧縮と展開という逆の処理が必要になります。

  • gzip -d ファイル名で指定したファイルを展開します。
  • gzip -cで展開したデータを別プログラムに流します。
  • | でプログラムからプログラムにデータを転送します。
  • dd of=/dev/sdd でプログラムから転送されたデータをHDDへ転送します。

コピーのときはdd if=/dev/sdd ではHDDからデータを読取って次へ転送していました。今度は逆なので受け取ったデータをHDDへ転送する必要があります。それがif=/of= の違いです。dd of=/dev/sddは受け取ったデータをHDDへ転送しています。if=input FILEの略です。of= output FILE の省略です。

フリーソフトウェア

ddrescue コマンドを使えば、HDDからHDDへのコピーができる。

そのためのddrescueコマンドは ubuntu で使える。そしてubuntu は無料で使える。だからddrescueも無料で使える。よってHDDのコピーしてクローンを作成しても無料である。無料ソフトウェアで自由に使える。Linuxは無料でソースコードも公開されていて、誰もが自由に使えます。誰もが知的欲求のままに自由にソースコードを閲覧し自由にコンピュータを扱えるようにするためGPLという約束があります。「ソフトウェア公共財は未来永劫に公共財である」と言う約束です。

最後に

ubuntuusbメモリを作っておけば、SSDからデータを吸い出してコピーすることが出来ます。SSDが寿命を迎える前に、一度バックアップをとっておきましょう。

コンピュータのバックアップを取るために、少しの知識と少しの手間、そして少しの時間がアレば、自由なソフトウェアをつかって、自由にコンピュータのデータをコピーできるのです。バックアップを取るのも自由なら消すのも自由。そしてそれは誰でもが扱えるソフトウェアによって成立しています。

クローン専用ソフトウェアは ddrescueという自由に使えるソフトウェアです。ddrecueを動かすUbuntuも自由ソフトウェア(OS)です。自由に使えるので、無料でデータのバックアップの専用ソフトウェア使えます。データのバックアップくらいは自分でできるよう練習してみてはいかがでしょうか。

まぁ売るのも自由なのですが。無料のソフトを買う人はいないよね。

WindowsのGPT+UEFIのBCDブートを修正してしてブートマネージャを何とかする

ブートをぶっ飛ばしたWindowsを修正する

ある日電源をいれたらWindowsが起動しなくなってて、泣きそうになったけど、Cドライブは生きていたのでブートが死んだとわかったのでEFIブートを必死で直した。

回復コンソール(コマンドプロンプト)を実行する

Windowsのインストールディスクから起動する、WinReから起動する、USBに作成した回復ドライブで起動するなどをして、修復する→トラブルシューティング→オプション→コマンドプロンプトで回復用のコマンドプロンプトを起動します。

diskpart でドライブの様子を確認する。

diskpart

Cドライブの割り当てを確認します。

DISKPART > list vol 

もし、c:ドライブが意図したディスクと違うディスクに割り当てらているときはc:ドライブの割り当てを削除して別のボリュームにC:を割り当てます。

list vol 
select vol 0
remove letter=c
select vol 3
assgin letter=c

EFIブートパーティションにドライブ文字割り当て

list vol 
select vol 1 
assign letter=s
list vol

これは、EFIパーティションにS:を割り当てている例です

bcdboot で起動の修正

bcdboot /l ja-JP /s S: /f UEFI

S:ドライブはDISKPART、EFIブートパーティションAssign Letter=sしてあります。

/l ja-JPは省略してもいいみたいですが、合わせた方がすんなり起動する様です。

DISKPARTで確認したC:ドライブを起動ドライブとしてUEFIを再構成する例です。

だいたいの場合はこれで治ります。

EFIパーティションがない場合

DISKPARTで作成します。

DISKPARTでFAT32パーティションを100M-300M程度作ります。

私はgdiskで作っちゃうし diskpartでのやり方は知らない。

sgdisk -n '1::+100M' /dev/loopX
sgdisk -t 1::ef00 /dev/loopX

DISKPARTの使い方はこの記事の本題でないので割愛。

ブートオーダーを修正する。

bcdeditでEFIの登録を修正

bcdeditを確認すると、なんか大量にIDが含まれているとき、bdceditでブートドライブのUUID登録を修正するとブートが治りました。

ディスクを交換した、ddした、gdiskでリサイズしたとかディスクのIDが変化した時にこのようなエラーが起きます。BDCbootで修正可能ならいいんですが、バックアップのUSBドライブ複数接続していて、複数のC:ドライブがあったりデュアルブートだと、EFIブート順がグチャる可能性がある。

EFIブートローダーを確認する

bcdedit /enum
bcdedit /enum {firmware}

次の例は私のWindowsで確認したEFIブート順です。

次の例は、ブート破損したWindowsで確認できたブート順序です。

余計なものを消してスッキリさせる。

次の様に、ファームウェアのbootmgrのオーダーから余計なのをサクサク消していき bootmgrだけにしておきました。

bcdedit /set {fwbootmgr} displayorder {bootmgr} /remove
bcdedit /set {fwbootmgr} displayorder {e05xxxx-11-xxxx} /remove

最後に先頭にEFIブートマネージャーを登録します。

bcdedit /set {fwbootmgr} displayorder {bootmgr} /addfirst

スッキリ

bcdbootを修正

bcdeditでIdentifierを修正した後に、再びbcdboodでブート登録する

bcdboot /l ja-JP /s S: /f UEFI

S:ドライブはDISKPART、EFIブートパーティションAssign Letter=sしてあります。

/l ja-JPは省略してもいいみたいですが、合わせた方がすんなり起動する様です。

enum を見てみると

enum を見ていると、多分こういうことなんだろうなと思います。

個人的に設定を見て解釈しただけで、公式マニュアルを読んでないので間違ってるかもしれません。

よく見かける次のコマンド

このコマンドだとEFIブートになるかならないか、運です。

bcdboot C:\Windows /l ja-jp
bootrec /rebuildbcd

リカバリUSBメモリ起動する際にUEFIブートしていればこれでいいとおもうけど、うっかりCSMでMBRからブートしていたらUEFIブートにはならないよね。bcdbootはEFIだし、rebuilbcdの前にEFIパーティションの状態がわからないことには辛い。

次のfixboot関連のコマンドも見かけるけど、EFIパーティションの有無で変わるよね。

bootrec /Rebuildbcd
bootrec /fixboot

BCDが壊れていたばあい。RebuidBCDでマイクロソフトEFIパーティションを修復できていいけど、/fixbootはどれくらい効果があるかはわからないCドライブどこだよって思う。

いまどきUEFI必須でGPTでTPM必須なWindowsMBRの記事を使うこともないと思うんだけどさ。リカバリに課金するのも癪だよね。

ブートセクタの記述

EFIパーティションいれたブートマネージャから起動します。

ブートセクタで番号指定して起動していたMBRはGPT+UEFIでは使いません。

GPT関連でブートセクタと書いてたらその人の記事は怪しいと思う

参考資料

NTFS のボリューム(HDD/SSD)をLinuxでメンテナンスする・練習する

ntfs のストレージをLinuxから操作したい

Linuxに接続してNTFSのHDD/SSDをメンテナンスしたときのメモ

使うツール

  • ntfsresize
  • ntfsfix
  • gdisk
  • losetup
  • ddrescue
  • kpartx

NTFSのディスクイメージを作る

ddrescue で取り出せばおっけ

ddrescue /dev/sda2 ntfs.img

ディスクイメージを接続する

losetup で ディスクイメージファイルを接続して通常HDD同等に扱えるようにする。

losetup -f ntfs.img
losetup -l | grep ntfs.img

空っぽのディスクイメージを使って操作する

NTFSの操作の練習のために、空っぽのディスクイメージを作って練習する

次のようにして実験用の環境を作ることができた。

truncate -s 5G ntfs.img
sudo sgdisk -Z ntfs.img
sudo sgdisk -n "0::+1G" ntfs.img
sudo sgdisk -p  ntfs.img
sudo sgdisk -t 1:0700  ntfs.img
sudo sgdisk -p  ntfs.img
sudo losetup -f --show ntfs.img
sudo kpartx -a  /dev/loopX
sudo ls /dev/mapper/loop
sudo mkfs.ntfs /dev/mapper/loopXp1

/dev/loopX は毎回変わるので注意

後片付け

sudo kpartx -d /dev/loop0
sudo losetpup -d /dev/loop0

マウントする

マウントする。 /dev/loopX は losetup している場合

# シンプルボリュームにした場合
mount -t  ntfs /dev/loopX  /mnt
# partitionを作った場合
mount -t  ntfs /dev/mapper/loopXpN  /mnt

losetup をmount と同時にやる

mount -t ntfs -o loop ntfs.img /mnt

NTFSのチェック

ntfsresize のコマンドにチェック機能があるので、NTFSのディスクチェックに使える。

sudo ntfsresize -c /dev/loopX
# または 
sudo ntfsresize -c /dev/mapper/loopXp1

info の表示でもチェックは走るみたい

sudo ntfsresize -i /dev/loop10

NTFS リサイズ

sudo ntfsresize -n -v -x  /dev/loop10

やった結果(正常終了)

takuya@:~$ sudo ntfsresize -f /dev/loop10
ntfsresize v2017.3.23AR.3 (libntfs-3g)
Device name        : /dev/loop10
NTFS volume version: 3.1
Cluster size       : 4096 bytes
Current volume size: 511411470848 bytes (511412 MB)
Current device size: 511411471360 bytes (511412 MB)
New volume size    : 511411470848 bytes (511412 MB)
Nothing to do: NTFS volume size is already OK.

やった結果(エラー時)

実際にやってみた結果。CHKDSKで修正が必須らしいです。CHKDSKWindowsのコマンドなのでLinuxでは修復ができないのかもしれない。

takuya@:~$ sudo ntfsresize -n -i /dev/loop10
ntfsresize v2017.3.23AR.3 (libntfs-3g)
Device name        : /dev/loop10
NTFS volume version: 3.1
Cluster size       : 4096 bytes
Current volume size: 511411470848 bytes (511412 MB)
Current device size: 511411471360 bytes (511412 MB)
Checking filesystem consistency ...
Cluster 16521360 is referenced multiple times!
Cluster 16521361 is referenced multiple times!
100.00 percent completed
ERROR: Filesystem check failed!
ERROR: 2452 clusters are referenced multiple times.
NTFS is inconsistent. Run chkdsk /f on Windows then reboot it TWICE!
The usage of the /f parameter is very IMPORTANT! No modification was
and will be made to NTFS by this software until it gets repaired.

NTFS の修正

-n をつけて調査だけしたあとにオプションを外して書き込みをする

sudo ntfsfix -n -b -d /dev/loopX
sudo ntfsfix -b -d /dev/loopX
takuya@:~$ sudo ntfsfix -b -d /dev/loop0
Mounting volume... OK
Processing of $MFT and $MFTMirr completed successfully.
Checking the alternate boot sector... OK
NTFS volume version is 3.1.
Going to un-mark the bad clusters ($BadClus)... No bad clusters...OK
NTFS partition /dev/loop0 was processed successfully.

NTFSのリサイズ(縮小・拡大)

sudo ntfsresize -s 1G /dev/loop0

CHKDSK が要求される場合

ntfsfix を試す

sudo ntfsfix /dev/loop0
sudo ntfsresize -s 1G /dev/loop0

データ破損を覚悟して forcesする

sudo ntfsresize -s 1G --force /dev/loop0

パーティションサイズとNTFSのサイズが合わない場合

NTFSは、パーティションサイズとNTFSのサイズが一致している必要がありWindowsで認識できない。Cドライブで不一致を起こすと起動失敗してBSoDになる。

Successfully resized NTFS on device '/dev/mapper/loop0p1'.
You can go on to shrink the device for example with Linux fdisk.
IMPORTANT: When recreating the partition, make sure that you
  1)  create it at the same disk sector (use sector as the unit!)
  2)  create it with the same partition type (usually 7, HPFS/NTFS)
  3)  do not make it smaller than the new NTFS filesystem size
  4)  set the bootable flag for the partition if it existed before
Otherwise you won't be able to access NTFS or can't boot from the disk!
If you make a mistake and don't have a partition table backup then you

ext4 ならresize2fs を実行すればいいが、NTFSには適切なコマンドが無いので、gdisk を使ってセクタサイズとボリュームサイズを計算しパーティション修正を頑張る。根性で。

partedでも可能だが自動にやってくれるわけじゃない。基本的に経験と勘と気合と根性の4K作業です。(計算方法さえ知ってれば大丈夫)tune2fsやresize2fs のようなものはない。

gdisk で修正すると、パーティションのUUIDが変わってしまうのでNTFSがCドライブのならWindowsのライセンス認証が無効になる。

かんたんな修正方法

パーティションサイズの修正には、すごく簡単な方法がある。

GPartedを起動してOKを押す。

GPatedの起動時のパーティションチェックで修正すれば簡単です。

GPartedをつかえば、ddイメージのGPT自体がおかしくなったときにも対応可能ですし、GPartedが楽だと思う。

CHKDSK がない

chkdsk /f を掛けろとメッセージが出てくるのだが、それに相当するコマンドがどれかわからなかったので、最悪の場合ではWindowsを持ち出してきてCHKDSKをまわすしか無いと思う。

NTFSの利点

Linuxext4NTFSを比較したとき、最大のメリットは「ファイル名の最大文字数」です。

巷にはファイルシステムを比較したとかでパフォーマンスの記事が溢れていますが、ファイル名の最大長に触れた記事は殆どありませんね。記事を見てもメンテナンスをしたりとかディスク交換したりとか、そういう記事は見当たりませんよね。誰も使い込んでないんですよ。なので今回は、NTFSのメンテナンスをLinuxからする場合に着目してまとめてみた。NASのデータをNTFSmにしておけば、最悪の場合Windowsでマウントできるので、便利だと思うんですよね。

LinuxのカーネルにNTFSが取り込まれたので、そろそろ常用していいんじゃないかと思ったんですが。LinuxNTFSを常用するのはまだ茨の道なので少し覚悟が必要ですね。

Windowsの回復パーティションを作る。 WinREの領域の再生

回復パーティションの作成

Windowsの回復パーティションをつくってみる。

自分でインストールしたWindowsには回復パーティションにある WinRe.wim がなく、なんか不安。

ブート失敗したときは、C:\Windows\System32\Recovery\WinRe.wim から起動するはずだけど、Cがブートだとわからなくなったらどうすりゃと不安になったので作り方を調べてみた

Windowsの回復パーティションの設置場所

SSD/HDDの先頭・末尾に1GBほどの小さい領域をつくって、そこにWinRe.wimを設置する

作ってみた

メーカ製PCではなく自作やHDD交換カスタムインストールされたWindowsではWinREはつくられてない。またWindowsアップデートのタイミングでWindows REが消されてたりする。

いままでEFIブートをぶっ壊したPCを何台か修復したのですが、USBのインストールメディア作成が面倒だった。もしブートがぶっ飛んでも安心なようなWinREを作成しておけばUSBのインストールメディアの手間を飛ばすことができる。もし自分のPCにトラブルが起きたときにリカバリの詳細オプションからスタートアップ修復やコマンド・プロンプトで修復ができれば便利だと思う。

winreの状態チェック

reagentc /info コマンドでWinREの現在状態がわかる。

現在はDisabledなのでWinREを作成しEnabledを目指そうと思う。

WinRe の準備

ともかくWinRe.wimが無いと始まらない。

方法1:既存のWindowsから持ってくる

C:\Windows\System32\Recovery

Win ProにはRecoveryにWinRe.wimがありHomeにはなかった。
インストールしているWin10のバージョンの問題かもしれない。
もしかしたらWinRe.wimはHomeにはなくPro以上限定かもしれない。

方法2:インストールメディアから取り出す

インストール・メディアから持ってくる

  • WindowsのインストールUSBを挿入する
  • 7zip でUSBを開く
  • install.esd を探して7zip で開く
  • 更にたどると、WinRe.wim がある。
  • E:\sources\install.esd\1\Windows\System32\Recovery\

ESD(インストールイメージ)が7z で開いてさらに中身が見れることを知っておく必要がありますね。

ESD自体はマイクロソフト公式サイトからメディア作成ツールで作ることができる。

取り出したWinRe.wimを設置

取り出したWinRe.wimを、Recoveryに設置する

C:\Windows\System32\Recovery\Winre.wim

ちなみに、この設置で、回復ドライブ作成が動くようになる。

わたしのWindows Homeでは回復パーティションどころか回復ドライブ作成すらできなかったので、回復ドライブ作成が動くだけでも助かった。

設置で回復ドライブを作れるようになった例

winre.wimC:\Windows\System32\Recovery\Winre.wimに設置すると、回復メディア作成ツールが動くようになった。

WindowsHomeのインストールの一部ではC:\Windows\System32\Recovery\Winre.wimが作られてない事があるようだ。回復ドライブ作成機能が動かないWindows10を、何度か見かけた。

末尾にパーティションを作成

次の図のように、パーティションを配置したい。

未割り当てを消せばいいが、Cドライブが500GBにもなるとバックアップが不便だしSSDの寿命も考えて未使用領域を残しておきたい。*1

Windowsのディスク管理ツールだと不便がある。未割当て領域を跨ぎ末尾にパーティションを作るのができない。Windowsだと末尾にパーティションつくる計算が面倒。

gidsk で 2700 を指定すれば Windows REになる

使い慣れたgdisk で作った

$ gdisk /dev/sdX
Command (? for help): l
Type search string, or <Enter> to show all codes:
0700 Microsoft basic data                0c01 Microsoft reserved
2700 Windows RE                          3000 ONIE boot
3001 ONIE config                         3900 Plan 9

gidks で末尾から1GiBは。セクタ数から計算した

start セクタ : `末尾 -  1024*1024*1024/512`
end セクタ : 末尾

gidskなら差分サイズ指定できたので楽ができたはず

パーティションを作ったら初期化

NTFSパーティションを初期化した。

windowsのdiskpart で確認

作ったパーティションWindowsDISKPART で確認した

回復パーティションが認識された

パーティションをマウントする

WinRe.wimをコピーすればいいのだが、そのためにはドライブにアサイン(マウント)してエクスプローラーで見られるようにする必要がある。

diskpartでコマンドをサクサク叩く

ドライブレターのアサインとIDの割当

list vol
select vol 5 
assign letter=r
set id="de94bba4-06d1-4d40-a16a-bfd50179d6ac"
gpt attributes=0x8000000000000001

パーティションにアクセスしファイルを書き込みたいので、ドライブレターを割り当てた。

gpt attribute と gpt のid が大事らしい。参考資料に従ってやった

リカバリパーティション(WinRE)なのでRにした

あとは、R:\を、開いて WinReをコピーした

winreをコピーする

参考資料はcmd.exe で次のようにやっていた

mkdir R:\Recovery\WindowsRE
xcopy /h C:\Windows\System32\Recovery\Winre.wim R:\Recovery\WindowsRE

わたしはWSLから操作したので、次のように実行した。

mkdir  -p /mnt/r
sudo mount -t drvfs R: /mnt/r
mkdir -p /mnt/r/Recovery/WindowsRE
cp  /mnt/c/windows/system32/recovery/winre.wim  /mnt/r/Recovery/WindowsRE

windows REの状態を確認する

最初はDisabledで絶望したのだが。

> reagentc /info
Windows 回復環境 (Windows RE) およびシステム リセット構成
情報:

    Windows RE の状態:         Disabled

有効にする事ができた。

> reagentc /enable
REAGENTC.EXE: 操作は成功しました。

Windows RE 環境を作れた

reagentc /enable をすることで、回復パーティションを作ることができた。

回復ドライブの指定

参考資料によると、回復ドライブを指定して、そのドライブを使って回復ができるらしい

/pathオプションに登録する回復環境のパス、/targetに登録先のWindowsフォルダを指定する。

> reagentc /setreimage /path R:\Recovery\WindowsRE /target C:\Windows
ディレクトリは次に設定されています: \\?\GLOBALROOT\device\harddisk0\partition4\Recovery\WindowsRE

回復起動する

Windowsの設定で「再起動時のブート方法」を選んで、トラブルシューティングで起動して、コマンド・プロンプトなど色々と増えていることを確認にする。 [設定] > [PC 設定の変更] > [全般] とか

おまけ diskpart の使い方

起動

diskpart

ディスクを扱う場合

list disk
select disk 0
list part 
select part 0 

ボリューム(Windowsが認識可能なフォーマットされたドライブ・パーティション)を扱う

list vol
select vol 2
list vol 
select vol 1 
remove letter=c
select vol 2 
assgin letter=c

C:の割当の解除は、回復から起動したコマンドであればできる。

bitlocker の制限

bitlocker 環境化はWinREにアクセスできたとしてもディスクのマウントができないので、暗号化ボリュームの復号化キーをつかうことになるだろう

reagentc /enable の実行時に何も指定してない場合、C:\Windowsを使うので、WinREだけではBitlockerにアクセスできないので有効化できなくて当然である。

PS C:\Users\takuya\Desktop> reagentc /enable
REAGENTC.EXE: Windows RE cannot be enabled on a volume with BitLocker Drive Encryption enabled.

もし必要なら、システムイメージが入ったデータ・パーティションを作ればいいのだが。

Bitlockerはノートパソコンが主流であろうし、回復用USBフラッシュを作るだけで事足りそうな気がしますね。

TPMのセキュアブートなどがうまく組み合わされるWin11だとまた事情は変わってくるかもしれません。

WinREが使えたほうが良い理由

UEFI+GPTに変わって、MBRのフラグで管理しなくなった。

そのためスタートアップ修復の登場機会が増えていいる。

UEFIの修正にとても重要。

とくにEFIブートのパーティションFAT32で作られるので、「自称詳しい」ひとたちが、「何だこれ?Windowsはいらんことを」と消してしまうことが多発して、我が家にEFIのぶっ壊れたWindowsが持ち込まれる要件が増えている。

MBRオジサンはEFIを知らないままEFI環境に移行しているので、HDD増設で先頭のEFIパーティションFAT32を、あれこれ弄っちゃうようです。

起動しなくなったーって電話があるときは、回復パーティションがないから電話かかってくるんですよね。古くからのPC達人たちよ、まじ学んでくれ、君たちがエロゲをやってたアオハル時代のMBRじゃないんだよ。もう。

参考資料

*1:SSDが寿命を迎え大変苦労した。もう二度とSSDを容量上限まで使いたくない。その際にSSDのバックアップに苦労した。だからドライブはディスクイメージバックアップで扱いやすいサイズにすることにした。

Windowsでローカルドメイン名を使いたい

ホスト名の指定だけでIPがわかるようにしたい

DHCPサーバーとDNSサーバーに、ローカルドメイン名は設定済み

windowsでも名前解決をしたい

ホスト名だけで行けそう

ping ホスト名で、検索されてIPアドレスが分かるようになった。