From bd61b6f1bb9848167d0cdecb22099856c3ad98ca Mon Sep 17 00:00:00 2001 From: Olaf Faaland Date: Sat, 7 Mar 2015 07:38:00 +0800 Subject: [PATCH] LU-6388 utils: make llog_reader parse changelogs Improve support for changelog_catalog records and changelog records. Extend llog_reader to handle records of type CHANGELOG_REC or CHANGELOG_USER_REC (present in lustre logs with changelog entries). Records in the changelog_catalog (type LLOG_LOGID_MAGIC) contain the ID of the object (file) containing actual changelog records. The new output provides the pathname to those files, as one would see them when mounting an ldiskfs or zfs target via the posix layer. This makes it easy to find those files to inspect them. Move some logid/fid manipulation functions, which are specific to llogs, out of lustre_log.h into a new header lustre_log_user.h. One of the functions is necessary for llog_reader to display useful information for certain lustre log record types. They are all related to logid/fid conversion or access, and are not dependent on dt_object like the rest of the material in lustre_log.h. Also, llog_test_9() is added to llog_test.c, used in sanity.sh test_60a to verify llog_reader. Change-Id: I7120c391702fd5b8e18031bbe6e109d9e079690f Signed-off-by: Olaf Faaland Signed-off-by: Emoly Liu Reviewed-on: http://review.whamcloud.com/14120 Tested-by: Jenkins Reviewed-by: Andreas Dilger Tested-by: Maloo Reviewed-by: Oleg Drokin --- lustre/include/Makefile.am | 1 + lustre/include/lustre_log.h | 39 +----- lustre/include/lustre_log_user.h | 77 ++++++++++++ lustre/obdclass/llog_test.c | 98 +++++++++++++++ lustre/tests/sanity.sh | 82 +++++++++++- lustre/utils/llog_reader.c | 264 ++++++++++++++++++++++++++------------- 6 files changed, 432 insertions(+), 129 deletions(-) create mode 100644 lustre/include/lustre_log_user.h diff --git a/lustre/include/Makefile.am b/lustre/include/Makefile.am index ed4e963..1271da6 100644 --- a/lustre/include/Makefile.am +++ b/lustre/include/Makefile.am @@ -69,6 +69,7 @@ EXTRA_DIST = \ lustre_linkea.h \ lustre_lmv.h \ lustre_log.h \ + lustre_log_user.h \ lustre_mdc.h \ lustre_mds.h \ lustre_net.h \ diff --git a/lustre/include/lustre_log.h b/lustre/include/lustre_log.h index 393ce28..c048739 100644 --- a/lustre/include/lustre_log.h +++ b/lustre/include/lustre_log.h @@ -15,11 +15,7 @@ * * You should have received a copy of the GNU General Public License * version 2 along with this program; If not, see - * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf - * - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. + * http://www.gnu.org/licenses/gpl-2.0.html * * GPL HEADER END */ @@ -31,7 +27,6 @@ */ /* * This file is part of Lustre, http://www.lustre.org/ - * Lustre is a trademark of Sun Microsystems, Inc. * * lustre/include/lustre_log.h * @@ -59,6 +54,7 @@ #include #include #include +#include #define LOG_NAME_LIMIT(logname, name) \ snprintf(logname, sizeof(logname), "LOGS/%s", name) @@ -82,37 +78,6 @@ struct cat_handle_data { struct llog_handle *chd_next_log; /* llog to be used next */ }; -static inline void logid_to_fid(struct llog_logid *id, struct lu_fid *fid) -{ - /* For compatibility purposes we identify pre-OSD (~< 2.3.51 MDS) - * logid's by non-zero ogen (inode generation) and convert them - * into IGIF */ - if (id->lgl_ogen == 0) { - fid->f_seq = id->lgl_oi.oi.oi_seq; - fid->f_oid = id->lgl_oi.oi.oi_id; - fid->f_ver = 0; - } else { - lu_igif_build(fid, id->lgl_oi.oi.oi_id, id->lgl_ogen); - } -} - -static inline void fid_to_logid(struct lu_fid *fid, struct llog_logid *id) -{ - id->lgl_oi.oi.oi_seq = fid->f_seq; - id->lgl_oi.oi.oi_id = fid->f_oid; - id->lgl_ogen = 0; -} - -static inline void logid_set_id(struct llog_logid *log_id, __u64 id) -{ - log_id->lgl_oi.oi.oi_id = id; -} - -static inline __u64 logid_id(struct llog_logid *log_id) -{ - return log_id->lgl_oi.oi.oi_id; -} - struct llog_handle; /* llog.c - general API */ diff --git a/lustre/include/lustre_log_user.h b/lustre/include/lustre_log_user.h new file mode 100644 index 0000000..68e51df --- /dev/null +++ b/lustre/include/lustre_log_user.h @@ -0,0 +1,77 @@ +/* + * GPL HEADER START + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 only, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License version 2 for more details (a copy is included + * in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU General Public License + * version 2 along with this program; If not, see + * http://www.gnu.org/licenses/gpl-2.0.html + * + * GPL HEADER END + */ +/* + * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. + * Use is subject to license terms. + * + * Copyright (c) 2012, 2014, Intel Corporation. + */ +/* + * This file is part of Lustre, http://www.lustre.org/ + * + * lustre/include/lustre_log_user.h + * + * Userspace-usable portion of Generic infrastructure for managing + * a collection of logs. + * See lustre_log.h for more details. + */ + +#ifndef _LUSTRE_LOG_USER_H +#define _LUSTRE_LOG_USER_H + +/* Lustre logs use FIDs constructed from oi_id and oi_seq directly, + * without attempting to use the IGIF and IDIF ranges as is done + * elsewhere, because of compatibility concerns (see lu-2888). + */ + +static inline void logid_to_fid(struct llog_logid *id, struct lu_fid *fid) +{ + /* For compatibility purposes we identify pre-OSD (~< 2.3.51 MDS) + * logid's by non-zero ogen (inode generation) and convert them + * into IGIF */ + if (id->lgl_ogen == 0) { + fid->f_seq = id->lgl_oi.oi.oi_seq; + fid->f_oid = id->lgl_oi.oi.oi_id; + fid->f_ver = 0; + } else { + lu_igif_build(fid, id->lgl_oi.oi.oi_id, id->lgl_ogen); + } +} + +static inline void fid_to_logid(struct lu_fid *fid, struct llog_logid *id) +{ + id->lgl_oi.oi.oi_seq = fid->f_seq; + id->lgl_oi.oi.oi_id = fid->f_oid; + id->lgl_ogen = 0; +} + +static inline void logid_set_id(struct llog_logid *log_id, __u64 id) +{ + log_id->lgl_oi.oi.oi_id = id; +} + +static inline __u64 logid_id(struct llog_logid *log_id) +{ + return log_id->lgl_oi.oi.oi_id; +} + +#endif /* ifndef _LUSTRE_LOG_USER_H */ diff --git a/lustre/obdclass/llog_test.c b/lustre/obdclass/llog_test.c index aff9204..61a5b44 100644 --- a/lustre/obdclass/llog_test.c +++ b/lustre/obdclass/llog_test.c @@ -1289,6 +1289,101 @@ out_put: RETURN(rc); } +static int llog_test_9_sub(const struct lu_env *env, struct llog_ctxt *ctxt) +{ + struct llog_handle *llh; + struct lu_fid fid; + int rc = 0; + + ENTRY; + + rc = llog_open_create(env, ctxt, &llh, NULL, NULL); + if (rc != 0) { + CERROR("9_sub: create log failed\n"); + RETURN(rc); + } + + rc = llog_init_handle(env, llh, + LLOG_F_IS_PLAIN | LLOG_F_ZAP_WHEN_EMPTY, + &uuid); + if (rc != 0) { + CERROR("9_sub: can't init llog handle: %d\n", rc); + GOTO(out_close, rc); + } + + logid_to_fid(&llh->lgh_id, &fid); + fid_to_logid(&fid, &llog_records.llr.lid_id); + rc = llog_write(env, llh, &llog_records.lrh, LLOG_NEXT_IDX); + if (rc < 0) { + CERROR("9_sub: write recs failed at #1: %d\n", rc); + GOTO(out_close, rc); + } + CWARN("9_sub: record type %x in log "DFID_NOBRACE"\n", + llog_records.lrh.lrh_type, PFID(&fid)); +out_close: + llog_close(env, llh); + RETURN(rc); +} + +/* Prepare different types of llog records for llog_reader test*/ +static int llog_test_9(const struct lu_env *env, struct obd_device *obd) +{ + struct llog_ctxt *ctxt; + int rc; + + ENTRY; + + ctxt = llog_get_context(obd, LLOG_TEST_ORIG_CTXT); + + CWARN("9a: test llog_logid_rec\n"); + llog_records.llr.lid_hdr.lrh_len = sizeof(llog_records.llr); + llog_records.llr.lid_tail.lrt_len = sizeof(llog_records.llr); + llog_records.llr.lid_hdr.lrh_type = LLOG_LOGID_MAGIC; + + rc = llog_test_9_sub(env, ctxt); + if (rc != 0) { + CERROR("9a: llog_logid_rec test failed\n"); + GOTO(out, rc); + } + + CWARN("9b: test llog_obd_cfg_rec\n"); + llog_records.lscr.lsc_hdr.lrh_len = sizeof(llog_records.lscr); + llog_records.lscr.lsc_tail.lrt_len = sizeof(llog_records.lscr); + llog_records.lscr.lsc_hdr.lrh_type = OBD_CFG_REC; + + rc = llog_test_9_sub(env, ctxt); + if (rc != 0) { + CERROR("9b: llog_obd_cfg_rec test failed\n"); + GOTO(out, rc); + } + + CWARN("9c: test llog_changelog_rec\n"); + /* Direct access to cr_do_not_use: peculiar case for this test */ + llog_records.lcr.cr_hdr.lrh_len = sizeof(llog_records.lcr); + llog_records.lcr.cr_do_not_use.lrt_len = sizeof(llog_records.lcr); + llog_records.lcr.cr_hdr.lrh_type = CHANGELOG_REC; + + rc = llog_test_9_sub(env, ctxt); + if (rc != 0) { + CERROR("9c: llog_changelog_rec test failed\n"); + GOTO(out, rc); + } + + CWARN("9d: test llog_changelog_user_rec\n"); + llog_records.lcur.cur_hdr.lrh_len = sizeof(llog_records.lcur); + llog_records.lcur.cur_tail.lrt_len = sizeof(llog_records.lcur); + llog_records.lcur.cur_hdr.lrh_type = CHANGELOG_USER_REC; + + rc = llog_test_9_sub(env, ctxt); + if (rc != 0) { + CERROR("9d: llog_changelog_user_rec test failed\n"); + GOTO(out, rc); + } + +out: + llog_ctxt_put(ctxt); + RETURN(rc); +} /* ------------------------------------------------------------------------- * Tests above, boring obd functions below * ------------------------------------------------------------------------- */ @@ -1337,6 +1432,9 @@ static int llog_run_tests(const struct lu_env *env, struct obd_device *obd) if (rc) GOTO(cleanup, rc); + rc = llog_test_9(env, obd); + if (rc != 0) + GOTO(cleanup, rc); cleanup: err = llog_destroy(env, llh); if (err) diff --git a/lustre/tests/sanity.sh b/lustre/tests/sanity.sh index 656df81..e5a0168 100644 --- a/lustre/tests/sanity.sh +++ b/lustre/tests/sanity.sh @@ -5126,11 +5126,89 @@ test_60a() { [ $PARALLEL == "yes" ] && skip "skip parallel run" && return remote_mgs_nodsh && skip "remote MGS with nodsh" && return do_facet mgs "! which run-llog.sh &> /dev/null" && - skip_env "missing subtest run-llog.sh" && return + do_facet mgs "! ls run-llog.sh &> /dev/null" && + skip_env "missing subtest run-llog.sh" && return + log "$TEST60_HEAD - from kernel mode" + do_facet mgs "$LCTL set_param debug=warning; $LCTL dk > /dev/null" do_facet mgs sh run-llog.sh + do_facet mgs $LCTL dk > $TMP/$tfile + + # LU-6388: test llog_reader + local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null") + llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader} + [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] && + skip_env "missing llog_reader" && return + local fstype=$(facet_fstype mgs) + [ $fstype != ldiskfs -a $fstype != zfs ] && + skip_env "Only for ldiskfs or zfs type mgs" && return + + local mntpt=$(facet_mntpt mgs) + local mgsdev=$(mgsdevname 1) + local fid_list + local fid + local rec_list + local rec + local rec_type + local obj_file + local path + local seq + local oid + local pass=true + + #get fid and record list + fid_list=($(awk '/9_sub.*record/ { print $NF }' /$TMP/$tfile | + tail -n 4)) + rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' /$TMP/$tfile | + tail -n 4)) + #remount mgs as ldiskfs or zfs type + stop mgs || error "stop mgs failed" + mount_fstype mgs || error "remount mgs failed" + for ((i = 0; i < ${#fid_list[@]}; i++)); do + fid=${fid_list[i]} + rec=${rec_list[i]} + seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g") + oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g") + oid=$((16#$oid)) + + case $fstype in + ldiskfs ) + obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;; + zfs ) + obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;; + esac + echo "obj_file is $obj_file" + do_facet mgs $llog_reader $obj_file + + rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" | + awk '{ print $3 }' | sed -e "s/^type=//g") + if [ $rec_type != $rec ]; then + echo "FAILED test_60a wrong record type $rec_type," \ + "should be $rec" + pass=false + break + fi + + #check obj path if record type is LLOG_LOGID_MAGIC + if [ "$rec" == "1064553b" ]; then + path=$(do_facet mgs $llog_reader $obj_file | + grep "path=" | awk '{ print $NF }' | + sed -e "s/^path=//g") + if [ $obj_file != $mntpt/$path ]; then + echo "FAILED test_60a wrong obj path" \ + "$montpt/$path, should be $obj_file" + pass=false + break + fi + fi + done + rm -f $TMP/$tfile + #restart mgs before "error", otherwise it will block the next test + stop mgs || error "stop mgs failed" + start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed" + $pass || error "test failed, see FAILED test_60a messages for specifics" } -run_test 60a "llog sanity tests run from kernel module ==========" +run_test 60a "llog_test run from kernel module and test llog_reader ==========" test_60b() { # bug 6411 [ $PARALLEL == "yes" ] && skip "skip parallel run" && return diff --git a/lustre/utils/llog_reader.c b/lustre/utils/llog_reader.c index e2d4183..5b2cb7c 100644 --- a/lustre/utils/llog_reader.c +++ b/lustre/utils/llog_reader.c @@ -33,8 +33,12 @@ * This file is part of Lustre, http://www.lustre.org/ * Lustre is a trademark of Sun Microsystems, Inc. */ - /* Interpret configuration llogs */ - +/** \defgroup llog_reader Lustre Log Reader + * + * Interpret llogs used for storing configuration and changelog data + * + * @{ + */ #include #include @@ -44,11 +48,14 @@ #endif #include #include +#include +#include #include #include #include #include +#include #include static inline int ext2_test_bit(int nr, const void *addr) @@ -67,7 +74,8 @@ int llog_pack_buffer(int fd, struct llog_log_hdr **llog_buf, struct llog_rec_hdr ***recs, int *recs_number); void print_llog_header(struct llog_log_hdr *llog_buf); -void print_records(struct llog_rec_hdr **recs_buf,int rec_number); +static void print_records(struct llog_rec_hdr **recs_buf, + int rec_number, int is_ext); void llog_unpack_buffer(int fd, struct llog_log_hdr *llog_buf, struct llog_rec_hdr **recs_buf); @@ -95,99 +103,162 @@ char* portals_command[17]= "" }; +int is_fstype_ext(int fd) +{ + struct statfs st; + int rc; + + rc = fstatfs(fd, &st); + if (rc < 0) { + llapi_error(LLAPI_MSG_ERROR, rc, "Got statfs error."); + return -errno; + } + + return (st.f_type == EXT4_SUPER_MAGIC); +} + + +/** + * Attempt to display a path to the object (file) containing changelog entries, + * referred to by this changelog_catalog record. + * + * This path depends on the implementation of the OSD device; zfs-osd and + * ldiskfs-osd are different. + * + * Assumes that if the file system containing the changelog_catalog is + * ext{2,3,4}, the backend is ldiskfs-osd; otherwise it is either zfs-osd or at + * least names objects based on FID and the zfs-osd path (which includes the + * FID) will be sufficient. + * + * The Object ID stored in the record is also displayed untranslated. + */ +#define OSD_OI_FID_NR (1UL << 7) +static void print_log_path(struct llog_logid_rec *lid, int is_ext) +{ + + char object_path[255]; + struct lu_fid fid_from_logid; + + logid_to_fid(&lid->lid_id, &fid_from_logid); + + if (is_ext) + snprintf(object_path, sizeof(object_path), + "O/"LPU64"/d%u/%u", fid_from_logid.f_seq, + fid_from_logid.f_oid % 32, fid_from_logid.f_oid); + else + snprintf(object_path, sizeof(object_path), + "oi."LPU64"/"DFID_NOBRACE, + fid_from_logid.f_seq & (OSD_OI_FID_NR - 1) , + PFID(&fid_from_logid)); + + printf("ogen=%X id="DOSTID" path=%s\n", + lid->lid_id.lgl_ogen, POSTID(&lid->lid_id.lgl_oi), + object_path); +} + int main(int argc, char **argv) { - int rc = 0; - int fd, rec_number; - struct llog_log_hdr *llog_buf = NULL; - struct llog_rec_hdr **recs_buf = NULL; + int rc = 0; + int is_ext; + int fd, rec_number; + struct llog_log_hdr *llog_buf = NULL; + struct llog_rec_hdr **recs_buf = NULL; - setlinebuf(stdout); + setlinebuf(stdout); - if(argc != 2 ){ - printf("Usage: llog_reader filename\n"); - return -1; - } + if (argc != 2) { + printf("Usage: llog_reader filename\n"); + return -1; + } - fd = open(argv[1],O_RDONLY); - if (fd < 0){ + fd = open(argv[1], O_RDONLY); + if (fd < 0) { rc = -errno; llapi_error(LLAPI_MSG_ERROR, rc, "Could not open the file %s.", argv[1]); - goto out; - } - rc = llog_pack_buffer(fd, &llog_buf, &recs_buf, &rec_number); - if (rc < 0) { + goto out; + } + + is_ext = is_fstype_ext(fd); + if (is_ext < 0) { + printf("Unable to determine type of filesystem containing %s\n", + argv[1]); + goto out; + } + + rc = llog_pack_buffer(fd, &llog_buf, &recs_buf, &rec_number); + if (rc < 0) { llapi_error(LLAPI_MSG_ERROR, rc, "Could not pack buffer."); - goto out_fd; - } + goto out_fd; + } + + print_llog_header(llog_buf); + print_records(recs_buf, rec_number, is_ext); + llog_unpack_buffer(fd, llog_buf, recs_buf); - print_llog_header(llog_buf); - print_records(recs_buf,rec_number); - llog_unpack_buffer(fd,llog_buf,recs_buf); out_fd: - close(fd); + close(fd); out: - return rc; + return rc; } int llog_pack_buffer(int fd, struct llog_log_hdr **llog, - struct llog_rec_hdr ***recs, - int *recs_number) + struct llog_rec_hdr ***recs, + int *recs_number) { - int rc = 0, recs_num,rd; - off_t file_size; - struct stat st; - char *file_buf=NULL, *recs_buf=NULL; - struct llog_rec_hdr **recs_pr=NULL; - char *ptr=NULL; - int i; - - rc = fstat(fd,&st); - if (rc < 0){ + int rc = 0, recs_num, rd; + off_t file_size; + struct stat st; + char *file_buf = NULL, *recs_buf = NULL; + struct llog_rec_hdr **recs_pr = NULL; + char *ptr = NULL; + int i; + + rc = fstat(fd, &st); + if (rc < 0) { rc = -errno; llapi_error(LLAPI_MSG_ERROR, rc, "Got file stat error."); - goto out; - } - file_size = st.st_size; + goto out; + } + file_size = st.st_size; if (file_size == 0) { rc = -1; llapi_error(LLAPI_MSG_ERROR, rc, "File is empty."); goto out; } - file_buf = malloc(file_size); - if (file_buf == NULL){ - rc = -ENOMEM; + file_buf = malloc(file_size); + if (file_buf == NULL) { + rc = -ENOMEM; llapi_error(LLAPI_MSG_ERROR, rc, "Memory Alloc for file_buf."); - goto out; - } - *llog = (struct llog_log_hdr*)file_buf; + goto out; + } + *llog = (struct llog_log_hdr *)file_buf; - rd = read(fd,file_buf,file_size); - if (rd < file_size){ - rc = -EIO; /*FIXME*/ + rd = read(fd, file_buf, file_size); + if (rd < file_size) { + rc = -EIO; /*FIXME*/ llapi_error(LLAPI_MSG_ERROR, rc, "Read file error."); - goto clear_file_buf; - } + goto clear_file_buf; + } - /* the llog header not countable here.*/ - recs_num = le32_to_cpu((*llog)->llh_count)-1; + /* the llog header not countable here.*/ + recs_num = le32_to_cpu((*llog)->llh_count) - 1; - recs_buf = malloc(recs_num * sizeof(struct llog_rec_hdr *)); - if (recs_buf == NULL){ - rc = -ENOMEM; + recs_buf = malloc(recs_num * sizeof(struct llog_rec_hdr *)); + if (recs_buf == NULL) { + rc = -ENOMEM; llapi_error(LLAPI_MSG_ERROR, rc, "Memory Alloc for recs_buf."); - goto clear_file_buf; - } - recs_pr = (struct llog_rec_hdr **)recs_buf; + goto clear_file_buf; + } + recs_pr = (struct llog_rec_hdr **)recs_buf; - ptr = file_buf + le32_to_cpu((*llog)->llh_hdr.lrh_len); - i = 0; + ptr = file_buf + le32_to_cpu((*llog)->llh_hdr.lrh_len); + i = 0; - while (i < recs_num){ + while (i < recs_num) { struct llog_rec_hdr *cur_rec; int idx; @@ -204,9 +275,8 @@ int llog_pack_buffer(int fd, struct llog_log_hdr **llog, recs_pr[i] = cur_rec; if (ext2_test_bit(idx, LLOG_HDR_BITMAP(*llog))) { - if (le32_to_cpu(cur_rec->lrh_type) != OBD_CFG_REC) - printf("rec #%d type=%x len=%u\n", idx, - cur_rec->lrh_type, cur_rec->lrh_len); + printf("rec #%d type=%x len=%u\n", idx, + cur_rec->lrh_type, cur_rec->lrh_len); } else { printf("Bit %d of %d not set\n", idx, recs_num); cur_rec->lrh_id = CANCELLED; @@ -214,29 +284,29 @@ int llog_pack_buffer(int fd, struct llog_log_hdr **llog, i--; } - ptr += le32_to_cpu(cur_rec->lrh_len); - if ((ptr - file_buf) > file_size) { - printf("The log is corrupt (too big at %d)\n", i); - rc = -EINVAL; - goto clear_recs_buf; - } - i++; - } + ptr += le32_to_cpu(cur_rec->lrh_len); + if ((ptr - file_buf) > file_size) { + printf("The log is corrupt (too big at %d)\n", i); + rc = -EINVAL; + goto clear_recs_buf; + } + i++; + } - *recs = recs_pr; - *recs_number = recs_num; + *recs = recs_pr; + *recs_number = recs_num; out: - return rc; + return rc; clear_recs_buf: - free(recs_buf); + free(recs_buf); clear_file_buf: - free(file_buf); + free(file_buf); - *llog=NULL; - goto out; + *llog = NULL; + goto out; } void llog_unpack_buffer(int fd, struct llog_log_hdr *llog_buf, @@ -304,7 +374,7 @@ static void print_setup_cfg(struct lustre_cfg *lcfg) printf("setup "); print_1_cfg(lcfg); } - + return; } @@ -497,13 +567,6 @@ void print_lustre_cfg(struct lustre_cfg *lcfg, int *skip) return; } -static void print_logid(struct llog_logid_rec *lid) -{ - printf("ogen=%X name="DOSTID"\n", - lid->lid_id.lgl_ogen, - POSTID(&lid->lid_id.lgl_oi)); -} - static void print_hsm_action(struct llog_agent_req_rec *larr) { char buf[12]; @@ -531,7 +594,17 @@ static void print_hsm_action(struct llog_agent_req_rec *larr) hai_dump_data_field(&larr->arr_hai, buf, sizeof(buf))); } -void print_records(struct llog_rec_hdr **recs, int rec_number) +void print_changelog_rec(struct llog_changelog_rec *rec) +{ + printf("changelog record id:0x%x cr_flags:0x%x cr_type:%s(0x%x)\n", + le32_to_cpu(rec->cr_hdr.lrh_id), + le32_to_cpu(rec->cr.cr_flags), + changelog_type2str(le32_to_cpu(rec->cr.cr_type)), + le32_to_cpu(rec->cr.cr_type)); +} + +static void print_records(struct llog_rec_hdr **recs, + int rec_number, int is_ext) { __u32 lopt; int i, skip = 0; @@ -555,14 +628,25 @@ void print_records(struct llog_rec_hdr **recs, int rec_number) printf("padding\n"); break; case LLOG_LOGID_MAGIC: - print_logid((struct llog_logid_rec *)recs[i]); + print_log_path((struct llog_logid_rec *)recs[i], + is_ext); break; case HSM_AGENT_REC: print_hsm_action((struct llog_agent_req_rec *)recs[i]); break; + case CHANGELOG_REC: + print_changelog_rec((struct llog_changelog_rec *) + recs[i]); + break; + case CHANGELOG_USER_REC: + printf("changelog_user record id:0x%x\n", + le32_to_cpu(recs[i]->lrh_id)); + break; default: printf("unknown type %x\n", lopt); break; } } } + +/** @} llog_reader */ -- 1.8.3.1