The views expressed on this blog are my own and do not necessarily reflect the views of Oracle

April 26, 2010

kfed - ASM metadata editor


The kfed is an undocumented ASM utility that can be used to read and modify ASM metadata blocks. It is a standalone utility, independent of ASM instance, so it can be used with either mounted or dismounted disk groups. The most powerful kfed feature is its ability to fix corrupt ASM metadata.

The kfed binary is present in the recent ASM versions, but if you don't see it in your $ORACLE_HOME/bin directory (e.g. it may not be present in version 10.1), it can be built as follows:

$ cd $ORACLE_HOME/rdbms/lib
$ make -f ins* ikfed

kfed read

With the kfed read command we can read a single ASM metadata block. The syntax is:

$ kfed read [aun=ii aus=jj blkn=kk dev=]asm_disk_name

Where the command line parameters are
  • aun - Allocation Unit (AU) number to read from. Default is AU0, or the very beginning of the ASM disk.
  • aus - AU size. Default is 1048576 (1MB). Specify the aus when reading from a disk group with non-default AU size.
  • blkn - block number to read. Default is block 0, or the very first block of the AU.
  • dev - ASM disk or device name. Note that the keyword dev can be omitted, but the ASM disk name is mandatory.
Use kfed to read ASM disk header block

The following is an example of using the kfed utility to read the ASM disk header from ASM disk /dev/sda1.

$ kfed read /dev/sda1 | more
kfbh.endian:                          1 ; 0x000: 0x01
kfbh.hard:                          130 ; 0x001: 0x82
kfbh.type:                            1 ; 0x002: KFBTYP_DISKHEAD
kfbh.datfmt:                          1 ; 0x003: 0x01
kfbh.block.blk:                       0 ; 0x004: blk=0
kfbh.block.obj:              2147483648 ; 0x008: disk=0
kfbh.check:                  3102721733 ; 0x00c: 0xb8efc6c5
kfbh.fcn.base:                        0 ; 0x010: 0x00000000
kfbh.fcn.wrap:                        0 ; 0x014: 0x00000000
...
kfdhdb.dsknum:                        0 ; 0x024: 0x0000
kfdhdb.grptyp:                        2 ; 0x026: KFDGTP_NORMAL
kfdhdb.hdrsts:                        3 ; 0x027: KFDHDR_MEMBER
kfdhdb.dskname:               DATA_0000 ; 0x028: length=9
kfdhdb.grpname:                    DATA ; 0x048: length=4
kfdhdb.fgname:                DATA_0000 ; 0x068: length=9
kfdhdb.ausize:                  1048576 ; 0x0bc: 0x00100000
kfdhdb.dsksize:                   12284 ; 0x0c4: 0x00002ffc
...

Note that the above kfed command is equivalent to this one (with all parameters explicitly set to their default values):

$ kfed read aun=0 aus=1048576 blkn=0 dev=/dev/sda1

We see that the above kfed output is nicely formatted and human readable (sort of). The fields are grouped based on the actual content of the ASM metadata block.

In this example, the kfbh fields show the block header data, and the most important one is kfbh.type, which says KFBTYP_DISKHEAD, meaning the ASM disk header. This is the expected block type for an ASM disk header.

We then see the actual content of the ASM disk header metadata block - the kfdhdb fields. Some of those are the disk number (kfdhdb.dsknum), 0 in this case, the group redundancy type (kfdhdb.grptyp), normal redundancy in this case, the disk header status (kfdhdb.hdrsts), member in this case, the disk name (kfdhdb.dskname) - DATA_0000, etc.

Please see ASM disk header for the complete explanation of kfdhdb fields.

Use kfed to read any ASM metadata block

The next example shows how to read an ASM File Directory block. To do that we would use the following kfed command:

$ kfed read aun=10 blkn=1 dev=/dev/sda1 | more
kfbh.endian:                          1 ; 0x000: 0x01
kfbh.hard:                          130 ; 0x001: 0x82
kfbh.type:                            4 ; 0x002: KFBTYP_FILEDIR
...

Note that I had to specify AU10 and block 1 to read a File Directory block. Have a look at the ASM File Directory post to learn how to locate a File Directory block.

Is my ASM metadata block corrupt

If you see kfbh.type=KFBTYP_INVALID, in the disk header on a disk you believe belongs to an ASM disk group, that indicates that the ASM disk header is corrupt. But don't jump to conclusions! Are you looking at the right disk? Is this the right disk partition? Can you access that disk via some other name - in a multipath setup? If you are not sure, or if the disk header is in fact damaged, contact Oracle Support for assistance.

Note that this applies to any ASM metadata block. If ASM expects to find a metadata block and instead finds a block that is zeroed out or contains rubbish, it will report the block as KFBTYP_INVALID, and an error (usually ORA-15196) will be reported in the ASM and/or database alert log (depends on which instance discovers the problem).

kfed write

With the kfed write command we can write to a single ASM metadata block. The syntax is:

$ kfed write [aun=ii aus=jj blkn=kk dev=]asm_disk_name text=new_contents chksum=yes

Where the new command line parameters are
  • text - a text file with the new block contents
  • checksum=yes - calculate and write the correct checksum. Note that the checksum in the text file with the new content does not have to be correct.
Use kfed to write the correct checksum to ASM metadata block

An ASM metadata may look fine, but in fact be corrupt. For example the block checksum (kfbh.check) could be wrong, in which case that would need to be corrected. Indeed, if the only problem is an incorrect checksum, that can be easily corrected by simply reading the block and then writing it back! The kfed will calculate the new checksum and write the block back with the correct checksum.

Here are the complete steps to correct the bad checksum for block 2 in AU0 on disk /dev/sda1:

$ kfed read aun=0 blkn=2 dev=/dev/sda1 > /tmp/aun0_blkn2_sda1.kfed
$ kfed write aun=0 blkn=2 dev=/dev/sda1 text=/tmp/aun0_blkn2_sda1.kfed chksum=yes

NOTE: Please seek Oracle Support assistance with any suspected ASM metadata block corruption.

kfed find

The kfed find will examine all blocks in an allocation unit and report back on the block types found. The syntax is:

$ kfed find [aun=ii aus=jj dev=]asm_disk_name

We see that the find command parameters are the same as for the read command, but the difference is that the find operates on all blocks in an allocation unit.

Use kfed find command to verify blocks in AU0

This is an example of using the kfed find to verify that all blocks in AU0 have the expected ASM metadata.

$ kfed find /dev/sda1

The expected result is type 1 for block 0, type 2 for block 1 and type 3 for all other blocks, i.e.:

$ kfed find /dev/sda1
Block 0 has type 1
Block 1 has type 2
Block 2 has type 3
Block 3 has type 3
Block 4 has type 3
...
Block 255 has type 3


If you see anything else in the output, that indicates a corrupted ASM metadata block. In that case please seek assistance from Oracle Support.

Note that my allocation unit size is 1MB, so there are only 255 blocks in the AU. If your allocation unit size is 4MB, the same command should return block type information for 1024 blocks.

I should also point out that with the above find command we only looked at the expected ASM metadata block types. We did not look at the actual metadata block contents. Some ASM metadata block corruptions are indeed with the block contents, i.e the block type is correct, but the contents is wrong. Such corruptions are only detected when ASM reads the corrupt block, in which case an ORA-15196 error will be reported. Please seek assistance from Oracle Support if you are unfortunate enough to encounter that error.

Conclusion

The kfed if an unassuming but very powerful utility. While I have shown only few commands, the kfed can also format an empty ASM file, perform a sanity check on an ASM metadata block, display data structure sizes and perform few other more obscure operations.