LLOG Log Header ^^^^^^^^^^^^^^^ [[struct-llog-log-hdr]] [source,c] ---- struct llog_log_hdr { struct llog_rec_hdr llh_hdr; obd_time llh_timestamp; __u32 llh_count; __u32 llh_bitmap_offset; __u32 llh_size; __u32 llh_flags; __u32 llh_cat_idx; /* for a catalog the first plain slot is next to it */ struct obd_uuid llh_tgtuuid; __u32 llh_reserved[LLOG_HEADER_SIZE/sizeof(__u32) - 23]; __u32 llh_bitmap[LLOG_BITMAP_BYTES/sizeof(__u32)]; struct llog_rec_tail llh_tail; }; ---- The llog records start and end on a record size boundary, typically 8192 bytes, or as stored in 'llh_size', which allows some degree of random access within the llog file, even with variable record sizes. It is possible to interpolate the offset of an arbitrary record within the file by estimating the byte offset of a particular record index using 'llh_count' and the llog file size and aligning it to the chunk boundary 'llh_size'. The record index in the 'llog_rec_hdr' of the first record in that chunk can be used to further refine the estimate of the offset of the desired index down to a single chunk, and then sequential access can be used to find the actual record. Each llog file begins with an 'llog_log_hdr' that describes the llog file itself, followed by a series of log records that are appended sequentially to the file. Each record, including the header itself, begins with an 'llog_rec_hdr' and ends with an 'llog_rec_tail'. The lgd_llh_flags are: .LLog Flags **** [source,c] ---- enum llog_flag { LLOG_F_ZAP_WHEN_EMPTY = 0x1, LLOG_F_IS_CAT = 0x2, LLOG_F_IS_PLAIN = 0x4, }; ---- **** .LLog Record Header [[struct-llog-rec-hdr]] **** [source,c] ---- struct llog_rec_hdr { __u32 lrh_len; __u32 lrh_index; __u32 lrh_type; __u32 lrh_id; }; ---- **** The 'llog_rec_hdr' is at the start of each llog record and describes the log record. 'lrh_len' holds the record size in bytes, including the header and tail. 'lrh_index' is the record index within the llog file and is sequentially increasing for each subsequent record. It can be used to determine the offset within the llog file when searching for an arbitrary record within the file. 'lrh_type' describes the type of data stored in this record. .LLog Operation Type **** [source,c] ---- enum llog_op_type { LLOG_PAD_MAGIC = LLOG_OP_MAGIC | 0x00000, OST_SZ_REC = LLOG_OP_MAGIC | 0x00f00, MDS_UNLINK64_REC = LLOG_OP_MAGIC | 0x90000 | (MDS_REINT << 8) | REINT_UNLINK, MDS_SETATTR64_REC = LLOG_OP_MAGIC | 0x90000 | (MDS_REINT << 8) | REINT_SETATTR, OBD_CFG_REC = LLOG_OP_MAGIC | 0x20000, LLOG_GEN_REC = LLOG_OP_MAGIC | 0x40000, CHANGELOG_REC = LLOG_OP_MAGIC | 0x60000, CHANGELOG_USER_REC = LLOG_OP_MAGIC | 0x70000, HSM_AGENT_REC = LLOG_OP_MAGIC | 0x80000, UPDATE_REC = LLOG_OP_MAGIC | 0xa0000, LLOG_HDR_MAGIC = LLOG_OP_MAGIC | 0x45539, LLOG_LOGID_MAGIC = LLOG_OP_MAGIC | 0x4553b, }; ---- **** .LLog Record Tail [[struct-llog-rec-tail]] **** [source,c] ---- struct llog_rec_tail { __u32 lrt_len; __u32 lrt_index; }; ---- **** The 'llog_rec_tail' is at the end of each llog record. The 'lrt_len' and 'lrt_index' fields must be the same as 'lrh_len' and 'lrh_index' in the header. They can be used to verify record integrity, as well as allowing processing the llog records in reverse order.