ntfs-3g (2)

KVMを使う(ネットワーク設定編)の冒頭が、minixで始まっていた。懐かしいねぇ。 筆者は、哲学者の食事に感銘を受けて、新版を買われたようだ。

オイラーもこの本(第一般)を持ってるぞ。オイラーが覚えているのは、エレベーター・アルゴリズムって奴。エレベーターに1階から乗った人達が、10階ボタンを押しました。5階も押されました。7階も押されました。押された順番に動くエレベーターなんて、誰も乗らんわな。

HDDはヘッドの移動に多大な時間が必要。要求通りにヘッドを移動してたんじゃ、時間がかかってしょうがない。そこで、エレベーターアルゴリズムを適用して、5階、7階、10階の順番に止まる階を調整する。それと同じ事をHDDのヘッドの制御にも適用しようって奴ね。 OSの開発には、世間を良く観察する必要が有るよって例。

今まで知ったかぶりしてOpenBSD観光なんてのをやってたけど、こういう基本的な解説書を読み直してみるかな。昔は難しくてスルーしてた部分が今ならスラスラと読める(かも知れない)。

MINIX 3

on qemu

前回ntfsをアクセス出来る事を知ってしまったので、やはり観光してみたくなる。 それには、伝家の宝刀であるqemuを使ってkernelに潜り込む必要が有る。

問題が一つある。qemuでUSBなステックを扱えるのか? 調べた限りでは、USBなやつはマウスぐらいしかサポートしてないみたい。

でも、USBな奴をddでファイルにダンプしておけば、そのファイルをdiskと見做してアクセス出来るのではなかろうか?

前回リナでバックアップしたファイルをOpenBSDに転送してきた(WiFi経由だから、空輸しましたってのが正解)。一応、ファイルコマンドで素性を調べてみた。

ob$ file disk
disk: QEMU QCOW Image (v3), 1073741824 bytes
ob$ file USB128M
USB128M: x86 boot sector; partition 1: ID=0x7, active, starthead 0, startsector 32, 255968 sectors

diskの中にはOpenBSDが入っている。USB128Mは、生意気にboot sectorなんて言ってるぞ。 そんな事は、どうでもよくて、qemuでどうやって複数のDiskを扱うか? それが疑問。

SAKURAな人が評価してた。複数のDiskを使ってね。

KVMを使う(ディスク性能編その2)

それをヒントに、下記のような起動スクリプトをでっちあげた。

ob$ cat withU
qemu-system-i386 -m 256 -s  -serial pty  \
  -net nic -net user,hostfwd=tcp::2022-:22 \
  -hda disk \
  -hdb USB128M

## -drive index=1,media=disk,cache=writethrough,file=USB128M

コメントしてる所が、細かい設定が可能な書き方らしい。簡略には、-hdcとかすれば良いとな。

ob$ ./withU &
[1] 9990
ob$ libGL error: No matching fbConfigs or visuals found
libGL error: failed to load driver: swrast
WARNING: Image format was not specified for 'USB128M' and probing guessed raw.
         Automatically detecting the format is dangerous for raw images, write operations on block 0 will be restricted.
         Specify the 'raw' format explicitly to remove the restrictions.
char device redirected to /dev/ttyp3 (label serial0)

早速、withUを使って起動します。警告が出てきたけど、実験ですから無視します。気にしてたら先に進みませんからね。

ob$ cu -l /dev/ttyp3
Connected to /dev/ttyp3 (speed 9600)

OpenBSD/i386 (vm.my.domain) (tty00)

login: sakae
Password:
  :
vm$ dmesg | grep wd
wd0 at pciide0 channel 0 drive 0: <QEMU HARDDISK>
wd0: 16-sector PIO, LBA48, 1024MB, 2097152 sectors
wd0(pciide0:0:0): using PIO mode 4, DMA mode 2
wd1 at pciide0 channel 1 drive 0: <QEMU HARDDISK>
wd1: 16-sector PIO, LBA48, 125MB, 256000 sectors
wd1(pciide0:1:0): using PIO mode 4, DMA mode 2
root on wd0a (c28637de21593793.a) swap on wd0b dump on wd0b

紐付きの回線を使ってlogin。すかさずどんな風にUSBを認識したか確認。wd1に表われたようです。

vm$ disklabel wd1
# /dev/rwd1c:
type: ESDI
disk: ESDI/IDE disk
label: QEMU HARDDISK
duid: 0000000000000000
flags:
bytes/sector: 512
sectors/track: 63
tracks/cylinder: 16
sectors/cylinder: 1008
cylinders: 253
total sectors: 256000
boundstart: 0
boundend: 256000
drivedata: 0

16 partitions:
#                size           offset  fstype [fsize bsize   cpg]
  c:           256000                0  unused
  i:           255968               32    NTFS

この内容何処かで見たような。そうリナではfdiskだったね。兎も角全体を表すのがcパーテションで、iパーテションがNTFSになってるんだな。

vm$ doas ntfs-3g /dev/wd1i /mnt
vm$ df
Filesystem  512-blocks      Used     Avail Capacity  Mounted on
/dev/wd0a      2028604   1536904    390272    80%    /
fusefs          255960     15952    240008     6%    /mnt
vm$ cd /mnt
vm$ touch aaaa
vm$ ls -l
total 8
drwxrwxrwx  1 root  wheel  0 Mar 14 06:13 System Volume Information
-rwxrwxrwx  1 root  wheel  0 Mar 23 06:10 aaaa
vm$ rm aaaa
vm$ echo Hello OpenBSD > zzzzz

上の情報を使ってntfs-3gでマウント。ファイルも作れているみたい。

vm$ doas umount /mnt
vm$ doas mount -t ntfs /dev/wd1i /mnt
vm$ cd /mnt
vm$ ls -ltr
total 272
-rwxr-xr-x  1 root  wheel       0 Jan  1  1601 $Volume
-rwxr-xr-x  1 root  wheel  131072 Jan  1  1601 $UpCase
-rwxr-xr-x  1 root  wheel       0 Jan  1  1601 $MFTMirr
-rwxr-xr-x  1 root  wheel       0 Jan  1  1601 $LogFile
-rwxr-xr-x  1 root  wheel       0 Jan  1  1601 $Boot
-rwxr-xr-x  1 root  wheel    4000 Jan  1  1601 $Bitmap
-rwxr-xr-x  1 root  wheel       0 Jan  1  1601 $BadClus
-rwxr-xr-x  1 root  wheel    2560 Jan  1  1601 $AttrDef
-rwxr-xr-x  1 root  wheel       0 Mar 14 06:12 $Secure
drwxr-xr-x  1 root  wheel       0 Mar 14 06:12 $Extend
drwxr-xr-x  1 root  wheel       0 Mar 14 06:13 System Volume Information
-rwxr-xr-x  1 root  wheel      14 Mar 23 06:12 zzzzz
vm$ cat zzzzz
Hello OpenBSD

今度は、OpenBSDに備え付けのmountコマンドでマウント。隠れファイルを暴き出しているな。手つかずのファイルは超過去の日付になってる。

zzzzzってファイルを作ったりaaaaを作って消したりしたんで、それなりに管理ファイル($Bitmap)が更新されてても良さそうだけど。

vm$ ntfsundelete -s /dev/wd1i
Inode    Flags  %age     Date    Time       Size  Filename
-----------------------------------------------------------------------
16       F..!     0%  1970-01-01 09:00         0  <none>
17       F..!     0%  1970-01-01 09:00         0  <none>
 :
64       FR..   100%  2020-03-23 06:10         0  aaaa
65       F..!     0%  1970-01-01 09:00         0  <none>
 :
255      F..!     0%  1970-01-01 09:00         0  <none>

Files with potentially recoverable content: 1

今度は注目の消してしまったファイルの復活プログラム。-sだとスキャンして、復活出来そうなファイルを列挙してくれるとな。zzzzzを消しておいて復活の実験。

vm$ ntfsundelete /dev/wd1i -m zzzzz -u -o xx
Inode    Flags  %age     Date    Time       Size  Filename
-----------------------------------------------------------------------
72       FR..   100%  2020-03-23 06:12        14  zzzzz
Undeleted 'zzzzz' successfully.


Files with potentially recoverable content: 1
vm$ cat xx
Hello OpenBSD

ちゃんと復活してntfsの外側(OpenBSDのエリア)に取り出せた。これを実施する時は、ntfsをumountしてから行う。

add disk

qemuベースでdiskを使う方法が分かったので、diskを増設してOpenBSDから使えるようにしてみる。まずはホストOS側でdiskの元になるファイルを作成する。大きいやつはいらないので、32Mと言う小ぶりなやつ。

ob$ dd if=/dev/zero of=RAW bs=1m count=32
32+0 records in
32+0 records out

出来上がったdiskを -hdc RAWとして、qemuに認識させる。ゲストOS側ではwd2に割り当てられた。パーテションを切って地均しする。-Eを付けると簡易的なeditorが立ち上がる。OSをインストールする時に出て来る、同じみのやつだ。

vm# disklabel -E wd2
Label editor (enter '?' for help at any prompt)
wd2> ?
Available commands:
 ? | h    - show help                 n [part] - set mount point
 A        - auto partition all space  p [unit] - print partitions
 a [part] - add partition             q        - quit & save changes
 b        - set OpenBSD boundaries    R [part] - resize auto allocated partition
 c [part] - change partition size     r        - display free space
 D        - reset label to default    s [path] - save label to file
 d [part] - delete partition          U        - undo all changes
 e        - edit drive parameters     u        - undo last change
 g [d|u]  - [d]isk or [u]ser geometry w        - write label to disk
 i        - modify disklabel UID      X        - toggle expert mode
 l [unit] - print disk label header   x        - exit & lose changes
 M        - disklabel(8) man page     z        - delete all partitions
 m [part] - modify partition

Suffixes can be used to indicate units other than sectors:
 'b' (bytes), 'k' (kilobytes), 'm' (megabytes), 'g' (gigabytes) 't' (terabytes)
 'c' (cylinders), '%' (% of total disk), '&' (% of free space).
Values in non-sector units are truncated to the nearest cylinder boundary.

地均しは下記のように、全面をaパーテションに割り当てた。

vm# disklabel wd2
# /dev/rwd2c:
type: ESDI
disk: ESDI/IDE disk
label: QEMU HARDDISK
 :
16 partitions:
#                size           offset  fstype [fsize bsize   cpg]
  a:            65536                0  4.2BSD   2048 16384     1
  c:            65536                0  unused

次はOSが使えるようにフォーマットする。色々なオプションを設定出来るけど、そこはそれ、お任せコースだ。

vm# newfs wd2a
/dev/rwd2a: 32.0MB in 65536 sectors of 512 bytes
4 cylinder groups of 8.00MB, 512 blocks, 1024 inodes each
super-block backups (for fsck -b #) at:
 32, 16416, 32800, 49184,
vm# mount /dev/wd2a /mnt
vm# df
Filesystem  512-blocks      Used     Avail Capacity  Mounted on
/dev/wd0a      2028604   1536924    390252    80%    /
/dev/wd2a        64220         4     61008     0%    /mnt

そしてマウントした。

ホストOS側から、このファイルを眺めてみる。

ob$ file RAW
RAW: Unix Fast File system [v1] (little-endian), last mounted on /mnt,
last written at Mon Mar 23 06:50:21 2020, clean flag 1, number of blocks 16384,
number of data blocks 16055, number of cylinder groups 4, block size 16384,
fragment size 2048, minimum percentage of free blocks 5, rotational delay 0ms,
disk rotational speed 60rps, TIME optimization

非常に、饒舌である。同族だから内情を良く知っているんだな。

同族以外の奴も扱えるぞ。mke2fsなんてコマンドを使えば

NAME
       mke2fs - create an ext2/ext3/ext4 filesystem

なんとリナのファイルシステムを作れてしまう(作れるって事は使えるって事だ)。なんと心の広い事か。何処かの誰かに爪の垢を煎じて飲ませたいぞ。ext4(5)なんてドキュメントもしっかり有るし、見習えよ!!!

sourceは、/sys/ufs/ext2fsに有るんで、後で見ておk。

mkntfs

そんな事より、折角の機会なんでntfsな奴の作成に挑戦してみろ。 ホストOS側で32MのZEROを埋めたファイルを作成。そして、ゲストOS側でそのdiskを地均し。

vm# disklabel -E wd1
Label editor (enter '?' for help at any prompt)
wd1> p
OpenBSD area: 0-65536; size: 65536; free: 65536
#                size           offset  fstype [fsize bsize   cpg]
  c:            65536                0  unused
wd1> a n
offset: [0] 32
size: [65504]
FS type: [4.2BSD] ntfs
wd1*> p
OpenBSD area: 0-65536; size: 65536; free: 32
#                size           offset  fstype [fsize bsize   cpg]
  c:            65536                0  unused
  n:            65504               32    NTFS
wd1*> w
wd1> q
No label changes.

今回はntfsのnにちなんで、パーテション名をnにしてみた(パーテション名はpまで可)。

vm$ fdisk wd1
Disk: wd1       geometry: 65/16/63 [65536 Sectors]
Offset: 0       Signature: 0x0
            Starting         Ending         LBA Info:
 #: id      C   H   S -      C   H   S [       start:        size ]
-------------------------------------------------------------------------------
 0: 00      0   0   0 -      0   0   0 [           0:           0 ] unused
 1: 00      0   0   0 -      0   0   0 [           0:           0 ] unused
 2: 00      0   0   0 -      0   0   0 [           0:           0 ] unused
 3: 00      0   0   0 -      0   0   0 [           0:           0 ] unused

IBM PC由来のいわゆるDOSパーテションは使っていない。ってか、何それって態度です。普通にOSをインストールする時には、ちゃんとこのコマンドを経由させられるんですけどね。

vm$ fdisk wd0
Disk: wd0       geometry: 520/64/63 [2097152 Sectors]
Offset: 0       Signature: 0xAA55
            Starting         Ending         LBA Info:
 #: id      C   H   S -      C   H   S [       start:        size ]
-------------------------------------------------------------------------------
 0: 00      0   0   0 -      0   0   0 [           0:           0 ] unused
 1: 00      0   0   0 -      0   0   0 [           0:           0 ] unused
 2: 00      0   0   0 -      0   0   0 [           0:           0 ] unused
*3: A6      0   1   2 -    519  63  63 [          64:     2096576 ] OpenBSD

先に進んで、早速ntfsしてみる。

vm# mkntfs /dev/wd1n
The sector size was not specified for /dev/wd1n and it could not be obtained automatically.  It has been set to 512 bytes.
The partition start sector was not specified for /dev/wd1n and it could not be obtained automatically.  It has been set to 0.
The number of sectors per track was not specified for /dev/wd1n and it could not be obtained automatically.  It has been set to 0.
The number of heads was not specified for /dev/wd1n and it could not be obtained automatically.  It has been set to 0.
Cluster size has been automatically set to 4096 bytes.
To boot from a device, Windows needs the 'partition start sector', the 'sectors per track' and the 'number of heads' to be set.
Windows will not be able to boot from this device.
Initializing device with zeroes: 100% - Done.
Creating NTFS volume structures.
mkntfs completed successfully. Have a nice day.

作成時に何もオプションを与えなかったので、色々な案内が出て来た。

vm# mkdir -p /mnt/ntfs
vm# mkdir -p /mnt/ffs
vm# ntfs-3g /dev/wd1n /mnt/ntfs
vm# mount -o rw /dev/wd2a /mnt/ffs
vm# df
Filesystem  512-blocks      Used     Avail Capacity  Mounted on
/dev/wd0a      2028604   1536944    390232    80%    /
fusefs           65496      5000     60496     8%    /mnt/ntfs
/dev/wd2a        64220         4     61008     0%    /mnt/ffs

マウントポイントを2つ用意してからマウントしてみた。ffsの方はマウント時にrwオプションを付けたんだけど、何かファイルを作ろうとすると権利が無いと言って来るなあ。dirのパーミッションを緩くしないと駄目なんかな。

ntfsの方は、その点は大丈夫で、無事にファイルを作成出来た。で、一度umountしてから、OpenBSD備え付けの(readonly)やつでマウント。中身を確認。

vm$ ls -ltra
total 4396
drwxr-xr-x  1 root  wheel        0 Jan  1  1601 .
-rwxr-xr-x  1 root  wheel   131072 Jan  1  1601 $UpCase
-rwxr-xr-x  1 root  wheel     1024 Jan  1  1601 $Bitmap
-rwxr-xr-x  1 root  wheel     2560 Jan  1  1601 $AttrDef
-rwxr-xr-x  1 root  wheel        0 Mar 24 07:44 $Volume
-rwxr-xr-x  1 root  wheel        0 Mar 24 07:44 $Secure
-rwxr-xr-x  1 root  wheel     4096 Mar 24 07:44 $MFTMirr
-rwxr-xr-x  1 root  wheel  2097152 Mar 24 07:44 $LogFile
drwxr-xr-x  1 root  wheel        0 Mar 24 07:44 $Extend
-rwxr-xr-x  1 root  wheel     8192 Mar 24 07:44 $Boot
-rwxr-xr-x  1 root  wheel        0 Mar 24 07:44 $BadClus
drwxr-xr-x  4 root  wheel      512 Mar 24 07:47 ..
-rwxr-xr-x  1 root  wheel       12 Mar 24 07:51 aa
vm$ cat aa
first write

fileコマンドに頼って、人定(あっ、察用語だった、人を特定する事ね)。

vm$ file \$UpCase
$UpCase: MS Windows icon resource - 2 icons, 3x, 4-colors
vm$ file \$AttrDef
$AttrDef: data
vm$ file \$MFTMirr
$MFTMirr: data
vm$ file \$LogFile
$LogFile: DOS executable (device driver) for DOS
vm$ file \$Boot
$Boot: x86 boot sector, mkdosfs boot message display

どうも、虚偽っぽいな。簡単に騙されていると思うぞ。信用ならん。まあ、無視しておいて、 ちょいといたずら心で、BPを置いてから、lsしてみたよ。

(gdb) bt 4
#0  ntfs_readdir (v=0xf362a6d8) at /usr/src/sys/ntfs/ntfs_vnops.c:412
#1  0xd057b84c in VOP_READDIR (vp=0xd1c08a00, uio=0xf362a750, cred=0xd1c45c60, eofflag=0xf362a744) at /usr/src/sys/kern/vfs_vops.c:519
#2  0xd0db14e9 in sys_getdents (p=0xd1ad218c, v=0xf362a864, retval=0xf362a85c) at /usr/src/sys/kern/vfs_syscalls.c:3053
#3  0xd06bae59 in mi_syscall (p=0xd1ad218c, code=99, callp=0xd10f934c <sysent+1188>, argp=0xf362a864, retval=0xf362a85c) at /usr/src/sys/sys/syscall_mi.h:92
(More stack frames follow...)

ふーん、ファイルシステムへのアクセスも、階層化されてて上位層は共通になってるのね。

vm# ls -l /dev/wd2a
brw-r-----  1 root  operator    0,  32 Feb 10 15:48 /dev/wd2a
vm# chmod g=rw /dev/wd2a
vm# ls -l /dev/wd2a
brw-rw----  1 root  operator    0,  32 Feb 10 15:48 /dev/wd2a

ffsへの書き込み出来ない件は、これも関係してるのね。まあ、そりゃそうだわな。

取り留めも無い事は更に続いて、書き込んだデータを探してみた。

ob$ file USB32M
USB32M: data
ob$ hexedit USB32M
 :
00018160   66 69 72 73  74 20 77 72  69 74 65 0A  00 00 00 00  first write.....
00018170   FF FF FF FF  00 00 00 00  00 00 00 00  00 00 00 00  ................

データがきちんと載っているのはいいんだけど、次の行にあるFFFFFFFFって何よ。普通に考えると、ファイルのコンテンツなんで、セクター単位で取られると思うんだけど、文字列の近傍にバイナリーデータが有るなんて、ちょっと信じられない。まあ、ntfsですから。

wd2として使っていた奴は、

0002C800   66 69 72 73  74 20 77 72  69 74 65 0A  00 00 00 00  first write.....
0002C810   00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  ................

vnconfig (pseudo disk devices)

下記はホストOS側にあるUSB128Mファイルをデバイスに見立てて、使ってしまう方法だ。

リナ方面だと、普通のファイルをデバイスに見立てて、えぃやとマウントしちゃう機能が提供されてるが、それはやり過ぎ感が強い。BSDでは、ひと手間置くようになってる。

vnconfigを使って、ファイルを仮想diskに対応させる。後は普通に使うだけ。仮想化を解除する場合は、vnconfig -u vnd0 のようにする。

ob# vnconfig vnd0 /home/sakae/i386/USB128M
ob# disklabel vnd0
# /dev/rvnd0c:
type: vnd
  :
16 partitions:
#                size           offset  fstype [fsize bsize   cpg]
  c:           256000                0  unused
  i:           255968               32    NTFS

同じ構造が見えている。

ob# ntfs-3g /dev/vnd0i /mnt
ob# df
Filesystem  512-blocks      Used     Avail Capacity  Mounted on
/dev/wd0a     23710364  18002224   4522624    80%    /
mfs:29713      2028910        10   1927456     0%    /tmp
fusefs          255960     15952    240008     6%    /mnt

ホストOS側でも使えた。

translate man

manには多彩な出力形式のオプションが有る。例えば、-T pdfだ。想像した通りmanの結果をpdfに落としてくれる。これを持って、コンビニへGoだ。

なんてのは、触りであって、オイラーの場合は、ぐぐるへGoだ。翻訳させちゃうのさ。ぐぐるのブラウザーで、右隅にある点が並んだ象形文字をクリック。そこから翻訳アプリを選ぶ。 それからドキュメントをクリック、パソコンを参照ボタンを押して、原文ファイルを選ぶ。 そして、翻訳。他の文書を翻訳したい場合、今選ばれているファイルの右側にある×印をクリックして、削除すれば良い。

翻訳の元ファイルを3種作ってみた。

ob$ man -T html ntfsundelete > aaa.html
ob$ man  ntfsundelete | col -b > bb.txt
ob$ man  ntfsundelete > cc.txt

aaa.htmlは翻訳を拒否された。

bb.txtは、重ね打ちで強調するためのBSを削除してからファイルに落としている。

警告
   奇跡
       ntfsundeleteは不可能を実行できません。

       ファイルが削除されると、MFTレコードは未使用としてマークされ、

cc.txtはその処理をしてないもの。見られたものじゃない。

C CA AV VE EA AT TS S
   M Mi ir ra ac cl le es s
       n nt tf fs su un nd de el le te eは不可能を実行できません。

       ファイルが削除されると、MFTレコードは未使用としてマークされ、

よって、bb.txtの形でぐぐると連携すれば幸せになれるよ。