newfs
OpenBSD 7.2
OpenBSD 7.2 が出た。今回で53回目のリリース。いよいよアプルのM2までもがサポートされ、ThinkPad x13s とかも仲間に加わったとか。ブルジョアの人もいるものだ。
オイラーは、そんな豪華な奴には目もくれず、ひたすら仮想PCで頑張るのさ。可弱い設備でも、動けばOK。
newfs
前回はfsckからnewfsに飛び火。両者共ユーザーランドのアプリ。観光するならqemuの窮屈な所ではなく、virtualBox上でもいいだろう。こちらならemacsとかも苦労なく動くからね。
vbox$ dd if=/dev/zero of=test.img bs=1M count=125 125+0 records in 125+0 records out 131072000 bytes transferred in 1.371 secs (95584145 bytes/sec) vbox$ doas vnconfig vnd0 /tmp/test.img vbox$ doas disklabel -E vnd0 Label editor (enter '?' for help at any prompt) vnd0> a a offset: [0] size: [256000] FS type: [4.2BSD] vnd0*> p OpenBSD area: 0-256000; size: 256000; free: 0 # size offset fstype [fsize bsize cpg] a: 256000 0 4.2BSD 2048 16384 1 c: 256000 0 unused vnd0*> w vnd0> q No label changes.
作成するDISKのサイズを前回の 1/4 にした。何せWindows 10には色々なOSを入れてて窮屈ですから。
vbox$ hexdump -C test.img 00000000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| * 00000200 57 45 56 82 0c 00 00 00 76 6e 64 20 64 65 76 69 |WEV.....vnd devi| 00000210 63 65 00 00 00 00 00 00 66 69 63 74 69 74 69 6f |ce......fictitio| 00000220 75 73 00 00 00 00 00 00 00 02 00 00 64 00 00 00 |us..........d...| 00000230 01 00 00 00 00 0a 00 00 64 00 00 00 00 e8 03 00 |........d.......| 00000240 a2 c2 fa c8 49 6d 90 c3 00 00 00 00 00 00 00 00 |....Im..........| 00000250 00 00 00 00 00 e8 03 00 00 00 00 00 00 00 00 00 |................| 00000260 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000270 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000280 00 00 00 00 57 45 56 82 89 ca 10 00 00 20 00 00 |....WEV...... ..| 00000290 00 00 01 00 00 e8 03 00 00 00 00 00 00 00 00 00 |................| 000002a0 07 14 01 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 000002b0 00 00 00 00 00 e8 03 00 00 00 00 00 00 00 00 00 |................| 000002c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| * 07d00000
出来上がったDISKのダンプ。これでdisklabelの所業が分るな。
super block
ちょっと寄り道して、要のスーパーブロックについて調べておく。簡単なものがいいだろう。 いきなり実用のOSじゃ眩暈発熱悪寒で、スーパー何とか薬のお世話になりそうだから。
at xv6
// Disk layout: // [ boot block | super block | log | inode blocks | // free bit map | data blocks] // // mkfs computes the super block and builds an initial file system. The // super block describes the disk layout: struct superblock { uint size; // Size of file system image (blocks) uint nblocks; // Number of data blocks uint ninodes; // Number of inodes. uint nlog; // Number of log blocks uint logstart; // Block number of first log block uint inodestart; // Block number of first inode block uint bmapstart; // Block number of first free map block };
案内のmkfs内は、こうなっていた。こんなものなのか。
sb.size = xint(FSSIZE); sb.nblocks = xint(nblocks); sb.ninodes = xint(NINODES); sb.nlog = xint(nlog); sb.logstart = xint(2); sb.inodestart = xint(2+nlog); sb.bmapstart = xint(2+nlog+ninodeblocks);
at minix
簡単なものの代表って事で、もう一種類。
fs/super.h
* Item # blocks * boot block 1 * super block 1 * inode map s_imap_blocks * zone map s_zmap_blocks * inodes (s_ninodes + 1 + INODES_PER_BLOCK - 1)/INODES_PER_BLOCK * unused whatever is needed to fill out the current zone * data zones (s_nzones - s_firstdatazone) << s_log_zone_size EXTERN struct super_block { inode_nr s_ninodes; /* # usable inodes on the minor device */ zone_nr s_nzones; /* total device size, including bit maps etc */ unshort s_imap_blocks; /* # of blocks used by inode bit map */ unshort s_zmap_blocks; /* # of blocks used by zone bit map */ zone_nr s_firstdatazone; /* number of first data zone */ short int s_log_zone_size; /* log2 of blocks/zone */ file_pos s_max_size; /* maximum file size on this device */ int s_magic; /* magic number to recognize super-blocks */ /* The following items are only used when the super_block is in memory. */ struct buf *s_imap[I_MAP_SLOTS]; /* pointers to the in-core inode bit map */ struct buf *s_zmap[ZMAP_SLOTS]; /* pointers to the in-core zone bit map */ dev_nr s_dev; /* whose super block is this? */ struct inode *s_isup; /* inode for root dir of mounted file sys */ struct inode *s_imount; /* inode mounted on */ real_time s_time; /* time of last update */ char s_rd_only; /* set to 1 iff file sys mounted read only */ char s_dirt; /* CLEAN or DIRTY */ } super_block[NR_SUPERS];
利便牲を考慮して、最終的にはメモリー上に展開し、関連部分を追加するとの事。そういう戦略も有りなんだな。
これを実際に作っているのは、tools/mkfs.c の中。
make newfs
次は、gdbにかけられるように特製のnewfsを作る。mount/ とか disklabel/ から一部のファイルを借りてきた。
vbox$ ls Makefile extern.h mkfs.c newfs.8 pathnames.h dkcksum.c getmntopts.c mntopts.h newfs.c vbox$ make cc -g -O0 -DMFS -I/tmp/newfs/../mount -MD -MP -c dkcksum.c cc -g -O0 -DMFS -I/tmp/newfs/../mount -MD -MP -c getmntopts.c cc -g -O0 -DMFS -I/tmp/newfs/../mount -MD -MP -c newfs.c cc -g -O0 -DMFS -I/tmp/newfs/../mount -MD -MP -c mkfs.c cc -o newfs dkcksum.o getmntopts.o newfs.o mkfs.o -lutil
vbox# ./newfs vnd0a /dev/rvnd0a: 125.0MB in 256000 sectors of 512 bytes 4 cylinder groups of 31.25MB, 2000 blocks, 4032 inodes each super-block backups (for fsck -b #) at: 160, 64160, 128160, 192160,
(gdb) b mkfs Breakpoint 1 at 0x7058: file mkfs.c, line 177. (gdb) r vnd0a Starting program: /tmp/newfs/newfs vnd0a Breakpoint 1, mkfs (pp=0x3411c888 <getdisklabel.lab+148>, fsys=0x2b7043c5 <open\ dev.namebuf> "/dev/rvnd0a", fi=4, fo=3, mfsmode=0, mfsuid=0, mfsgid=0) at mkfs.\ c:177 177 if ((fsun = calloc(1, sizeof (union fs_u))) == NULL ||
途中で、sblockってのが頻出するんで、どんな内容か確認。んが、そんなの無いと言われた。なして? 調べてみたら。
#define sblock fsun->fs
defineで定義した奴はgdbからは見えないのか。
(gdb) p/x fsun->fs $2 = { fs_firstfield = 0x0, fs_unused_1 = 0x0, fs_sblkno = 0x28, fs_cblkno = 0x30, fs_iblkno = 0x38, fs_dblkno = 0x230, fs_cgoffset = 0x0, fs_cgmask = 0x0, fs_ffs1_time = 0x0, fs_ffs1_size = 0x0, fs_ffs1_dsize = 0x0, fs_ncg = 0x4, fs_bsize = 0x4000, fs_fsize = 0x800, fs_frag = 0x8, : fs_maxsymlinklen = 0x78, fs_inodefmt = 0x2, fs_maxfilesize = 0x80100202ffff, fs_qbmask = 0x3fff, fs_qfmask = 0x7ff, fs_state = 0x0, fs_postblformat = 0x1, fs_nrpos = 0x1, fs_postbloff = 0x0, fs_rotbloff = 0x0, fs_magic = 0x19540119, fs_space = {0x0} }
大事なスーパーブロックを次のループの所で、DISK内に分散して格納してる(570行目あたり)。
for (cg = 0; cg < sblock.fs_ncg; cg++) { cur_cylno = (sig_atomic_t)cg; initcg(cg, utime); if (quiet) continue; j = snprintf(tmpbuf, sizeof tmpbuf, " %lld,", (long long)fsbtodb(&sblock, cgsblock(&sblock, cg))); if (j >= sizeof tmpbuf) j = sizeof tmpbuf - 1; => if (j < 0 || i+j >= width) { printf("\n"); i = 0; } i += j; printf("%s", tmpbuf); fflush(stdout); }
4箇所に分散してるはずなんだけど、forの終りを定義してる、 sblock.fs_ncg
が、ちょいといまいましい(上で出て来たdefine)。そんな時は、
(gdb) set $sblock=fsun->fs (gdb) p $sblock.fs_ncg $4 = 4
こんな風にgdbのコンビニエンス変数に、define値を写してしまおう。そして、変数の頭に$をつけて、変数を利用(参照)すれば良い。
で、スーパーブロックのサイズは、fs.hに定義されてて、SBLOCKSIZE 8192 てなってた。 ここまで、流れは分るんだけど、中身は解らず。なんとかしたいぞ。 fs.h
* For file system fs, the offsets of the various blocks of interest * are given in the super block as: * [fs->fs_sblkno] Super-block * [fs->fs_cblkno] Cylinder group block * [fs->fs_iblkno] Inode blocks * [fs->fs_dblkno] Data blocks * The beginning of cylinder group cg in fs, is given by * the ``cgbase(fs, cg)'' macro.
camcontrol or atactl
/sbinにDISK関連のアプリが集中して置いてある。どんなのがあるかと思ったら、もろにatactlなんてのがあった。じゃ、FreeBSDではどうよ? ataってのが発展解消してCAM(4)になったそうだ。
DESCRIPTION The CAM subsystem provides a uniform and modular system for the implementation of drivers to control various SCSI, ATA, NVMe, and MMC / SD devices, and to utilize different SCSI, ATA, NVMe, and MMC / SD host adapters through host adapter drivers. When the system probes buses, it attaches any devices it finds to the appropriate drivers. The pass(4) driver, if it is configured in the kernel, will attach to all devices.
今ならSDDが主流だけど、それはどうなってるの? まあ、取り敢えず使ってみる。
root@fb:/home/sakae # camcontrol identify /dev/ada0 pass0: <HITACHI HTS545025B9A300 PB2ZC61H> ATA8-ACS SATA 2.x device pass0: 300.000MB/s transfers (SATA 2.x, UDMA5, PIO 8192bytes) protocol ATA8-ACS SATA 2.x device model HITACHI HTS545025B9A300 firmware revision PB2ZC61H serial number 091026PB42041SGY80YB WWN 5000cca5e7cd4ce8 additional product id cylinders 16383 heads 16 sectors/track 63 sector size logical 512, physical 512, offset 0 LBA supported 268435455 sectors LBA48 supported 488397168 sectors PIO supported PIO4 DMA supported WDMA2 UDMA5 media RPM 5400 Zoned-Device Commands no Feature Support Enabled Value Vendor read ahead yes yes : Native Command Queuing (NCQ) yes 32 tags NCQ Priority Information yes NCQ Non-Data Command no NCQ Streaming no Receive & Send FPDMA Queued no NCQ Autosense no SMART yes yes :
dual boot してる 10年選手のThinkpadのシステムだ。で、SMARTなんてのをサポートしてるみたい。HDDの診断だな。
smartctl
ちょっくら入れてみるか。資料はこちら。 FreeBSDでハードディスクのヘルスチェックを行う方法
root@fb:/home/sakae # /usr/local/sbin/smartctl -a /dev/ada0 === START OF INFORMATION SECTION === Device Model: HITACHI HTS545025B9A300 Serial Number: 091026PB42041SGY80YB LU WWN Device Id: 5 000cca 5e7cd4ce8 Firmware Version: PB2ZC61H User Capacity: 250,059,350,016 bytes [250 GB] Sector Size: 512 bytes logical/physical Rotation Rate: 5400 rpm Form Factor: 2.5 inches Device is: Not in smartctl database 7.3/5319 ATA Version is: ATA8-ACS T13/1699-D revision 6 SATA Version is: SATA 2.6, 3.0 Gb/s (current: 3.0 Gb/s) Local Time is: Wed Oct 26 06:56:32 2022 JST SMART support is: Available - device has SMART capability. SMART support is: Enabled === START OF READ SMART DATA SECTION === SMART overall-health self-assessment test result: PASSED :
案外丈夫なものだな。
from USB
ポータブルって事で、USBからOpenBSD6.9を起動して、DISKがどう見えるか確認。 切り換えメニューは F12 キーの連打だった。すっかり忘れていたぞ。
obusb$ dmesg|grep sd sd0 at scsibus1 targ 0 lun 0: <ATA, HITACHI HTS54502, PB2Z> naa.5000cca5e7cd4ce8 sd0: 238475MB, 512 bytes/sector, 488397168 sectors sd1 at scsibus2 targ 1 lun 0: <BUFFALO, USB Flash Disk, 1.00> removable serial.04110239319600000407 sd1: 7626MB, 512 bytes/sector, 15618048 sectors
ちゃんと認識した。区画の確認で、知らないやつは、数字を事細かに並べて、煙に卷く作戦だんだな。まあ、dual boot なDISKだからなあ。
obusb$ fdisk sd0 Disk: sd0 Usable LBA: 40 to 488397134 [488397168 Sectors] #: type [ start: size ] ------------------------------------------------------------------------ 0: 83bd6b9d-7f41-11dc-be0b-001560b84f0f [ 40: 1024 ] 1: 516e7cb6-6ecf-11d6-8ff8-00022d09712b [ 1064: 100662272 ] 2: 516e7cb5-6ecf-11d6-8ff8-00022d09712b [ 100663336: 8388608 ] 3: 21686148-6449-6e6f-744e-656564454649 [ 109053952: 2048 ] 4: Linux files* [ 109056000: 377341952 ] 5: FAT12 [ 486397952: 1998848 ]
atactlで詳細を確認しようにも、そんなデバイスは知らないといわれた。 atactlコマンドでは、SMARTをコントロールする自前の機能を持っているんで、試してみたかったんだけど、残念至極であります。