Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Accessing ext3 / ext4 journals

ext3 and ext4 file systems have journaling. Is there any chance there's some API to get details or events about files?

Some kind of API that will allow a user space program to access journal entries for files. Or even journal events, like "file x was deleted".

This seems to be some kind of documentation but I'm not sure if it's the right stuff.

like image 544
Gaurav Mahajan Avatar asked Jun 20 '12 07:06

Gaurav Mahajan


1 Answers

With debugfs

logdump

You can display information about the file system journal with the logdump command from debugfs.

For example, sudo debugfs -R 'logdump -S' /dev/sda3 yields

Journal features:         journal_incompat_revoke journal_checksum_v3
Total journal size:       512M
Total journal blocks:     131072
Max transaction length:   131072
Fast commit length:       0
Journal sequence:         0x004bd0ae
Journal start:            109412
Journal checksum type:    crc32c
Journal checksum:         0x157eebb7

Journal starts at block 109412, transaction 4968622
Found expected sequence 4968622, type 5 (revoke table) at block 109412
Found expected sequence 4968622, type 1 (descriptor block) at block 109413
Found expected sequence 4968622, type 2 (commit block) at block 109419
Found expected sequence 4968623, type 1 (descriptor block) at block 109420
Found expected sequence 4968623, type 2 (commit block) at block 109422
Found expected sequence 4968624, type 1 (descriptor block) at block 109423
Found expected sequence 4968624, type 2 (commit block) at block 109425
Found expected sequence 4968625, type 1 (descriptor block) at block 109426
// rest omitted

I realize that debugfs is not an API, but it accesses the journal.

Read the journal's bytes

To get at the raw bytes of the journal, you can use debugfs again. Its cat command accepts an inode number and prints the data of the address the inode's pointing to.

Assuming that the journal's inode number is 8:

sudo debugfs -R 'cat <8>' /dev/sda3 | hexdump -C

This prints the journal's bytes in hexadecimal. You should see the magic number of the journal's format, jbd2, at the beginning:

c0 3b 39 98

The journal uses big-endian byte order whereas ext4 uses little-endian.

With jls

jls from The Sleuth Kit also prints information about the journal.

For example, sudo jls /dev/sda3 yields

JBlk    Description
0:  Superblock (seq: 0)
sb version: 4
sb version: 4
sb feature_compat flags 0x00000000
sb feature_incompat flags 0x00000011
        JOURNAL_REVOKE
sb feature_ro_incompat flags 0x00000000
1:  Unallocated Commit Block (seq: 4936768, sec: 1613471034.3277057792)
2:  Unallocated Descriptor Block (seq: 4936769)
3:  Unallocated FS Block 42991838
4:  Unallocated FS Block 0
5:  Unallocated Commit Block (seq: 4949171, sec: 1613574032.1117509120)
6:  Unallocated Descriptor Block (seq: 4949172)
7:  Unallocated Commit Block (seq: 4960433, sec: 1613729975.4288594432)
8:  Unallocated Descriptor Block (seq: 4960434)
// rest omitted

The source code of jls is here.

DIY

Alternatively, you can consult the ext4 wiki to parse the journal using a program that you'll have to write yourself. The steps are roughly as follows:

  1. Read the ext4 superblock which starts 1024 bytes after the file system.
  2. Read the journal inode number from offset 0xE0 of the superblock. The journal's inode number is usually 8. This is documented here.
  3. Read the data you need from the journal, keep in mind that it's big-endian, as opposed to ext4 being little-endian. The journal's structure is described here.
like image 100
Matthias Braun Avatar answered Sep 23 '22 00:09

Matthias Braun