/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
* vim:expandtab:shiftwidth=8:tabstop=8:
*
- * Copyright (C) 2002 Cluster File Systems, Inc.
+ * GPL HEADER START
*
- * This file is part of Lustre, http://www.lustre.org.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
- * Lustre is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
+ * 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.
*
- * Lustre 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 for more details.
+ * 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
- * along with Lustre; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * 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.
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved
+ * Use is subject to license terms.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
*/
+ /* Interpret configuration llogs */
#include <stdio.h>
#include <time.h>
#include <liblustre.h>
-#include <linux/lustre_idl.h>
+#include <lustre/lustre_idl.h>
-int llog_pack_buffer(int fd, struct llog_log_hdr** llog_buf, struct llog_rec_hdr*** recs, int* recs_number);
+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);
-void llog_unpack_buffer(int fd,struct llog_log_hdr* llog_buf,struct llog_rec_hdr** recs_buf);
+void print_llog_header(struct llog_log_hdr *llog_buf);
+void print_records(struct llog_rec_hdr **recs_buf,int rec_number);
+void llog_unpack_buffer(int fd, struct llog_log_hdr *llog_buf,
+ struct llog_rec_hdr **recs_buf);
+
+#define CANCELLED 0x678
#define PTL_CMD_BASE 100
char* portals_command[17]=
"GET_INTERFACE",
""
};
-
+
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 fd, rec_number;
+ struct llog_log_hdr *llog_buf = NULL;
+ struct llog_rec_hdr **recs_buf = NULL;
setlinebuf(stdout);
-
+
if(argc != 2 ){
- printf("Usage: llog_reader filename \n");
+ printf("Usage: llog_reader filename\n");
return -1;
}
-
+
fd = open(argv[1],O_RDONLY);
if (fd < 0){
- printf("Could not open the file %s \n",argv[1]);
+ printf("Could not open the file %s\n", argv[1]);
goto out;
}
rc = llog_pack_buffer(fd, &llog_buf, &recs_buf, &rec_number);
-
- if(llog_buf == NULL )
- printf("error");
+ if (rc < 0) {
+ printf("Could not pack buffer; rc=%d\n", rc);
+ goto out_fd;
+ }
+
print_llog_header(llog_buf);
-
print_records(recs_buf,rec_number);
-
llog_unpack_buffer(fd,llog_buf,recs_buf);
+out_fd:
close(fd);
out:
return rc;
-int llog_pack_buffer(int fd, struct llog_log_hdr** llog,
- struct llog_rec_hdr*** recs,
- int* recs_number)
+int llog_pack_buffer(int fd, struct llog_log_hdr **llog,
+ struct llog_rec_hdr ***recs,
+ int *recs_number)
{
- int rc=0,recs_num,rd;
+ 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 cur_idx,i;
-
+ 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){
printf("Get file stat error.\n");
goto out;
- }
+ }
file_size = st.st_size;
-
+
file_buf = malloc(file_size);
if (file_buf == NULL){
printf("Memory Alloc for file_buf error.\n");
rc = -ENOMEM;
goto out;
- }
+ }
*llog = (struct llog_log_hdr*)file_buf;
rd = read(fd,file_buf,file_size);
printf("Read file error.\n");
rc = -EIO; /*FIXME*/
goto clear_file_buf;
- }
+ }
/* 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*));
+
+ recs_buf = malloc(recs_num * sizeof(struct llog_rec_hdr *));
if (recs_buf == NULL){
printf("Memory Alloc for recs_buf error.\n");
rc = -ENOMEM;
goto clear_file_buf;
- }
+ }
recs_pr = (struct llog_rec_hdr **)recs_buf;
-
+
ptr = file_buf + le32_to_cpu((*llog)->llh_hdr.lrh_len);
- cur_idx = 1;
i = 0;
- while (i < recs_num){
- struct llog_rec_hdr* cur_rec=(struct llog_rec_hdr*)ptr;
-
- while(!ext2_test_bit(cur_idx,(*llog)->llh_bitmap)){
- cur_idx++;
- ptr += cur_rec->lrh_len;
- if ((ptr-file_buf) > file_size){
- printf("The log is corrupted. \n");
- rc = -EINVAL;
- goto clear_recs_buf;
- }
- }
+
+ while (i < recs_num){
+ struct llog_rec_hdr *cur_rec = (struct llog_rec_hdr*)ptr;
+ int idx = le32_to_cpu(cur_rec->lrh_index);
recs_pr[i] = cur_rec;
- ptr+=cur_rec->lrh_len;
+
+ if (ext2_test_bit(idx, (*llog)->llh_bitmap)) {
+ 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);
+ } else {
+ printf("Bit %d of %d not set\n", idx, recs_num);
+ cur_rec->padding = CANCELLED;
+ /* The header counts only set records */
+ 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++;
- cur_idx++;
}
-
+
*recs = recs_pr;
- *recs_number=recs_num;
+ *recs_number = recs_num;
out:
return rc;
*llog=NULL;
goto out;
-
}
-
-void llog_unpack_buffer(int fd,struct llog_log_hdr* llog_buf,struct llog_rec_hdr **recs_buf)
+void llog_unpack_buffer(int fd, struct llog_log_hdr *llog_buf,
+ struct llog_rec_hdr **recs_buf)
{
free(llog_buf);
free(recs_buf);
return;
}
-
-void print_llog_header(struct llog_log_hdr* llog_buf)
+void print_llog_header(struct llog_log_hdr *llog_buf)
{
time_t t;
- printf("Header size : %d \n",
- // le32_to_cpu(llog_buf->llh_hdr.lrh_len));
- llog_buf->llh_hdr.lrh_len);
+ printf("Header size : %u\n",
+ le32_to_cpu(llog_buf->llh_hdr.lrh_len));
t = le64_to_cpu(llog_buf->llh_timestamp);
printf("Time : %s", ctime(&t));
- printf("Number of records: %d\n",
+ printf("Number of records: %u\n",
le32_to_cpu(llog_buf->llh_count)-1);
printf("Target uuid : %s \n",
(char *)(&llog_buf->llh_tgtuuid));
- /* Add the other infor you want to view here*/
+ /* Add the other info you want to view here */
printf("-----------------------\n");
return;
static void print_1_cfg(struct lustre_cfg *lcfg)
{
int i;
+
if (lcfg->lcfg_nid)
printf("nid=%s("LPX64") ", libcfs_nid2str(lcfg->lcfg_nid),
- lcfg->lcfg_nid);
+ (__u64)lcfg->lcfg_nid);
if (lcfg->lcfg_nal)
printf("nal=%d ", lcfg->lcfg_nal);
for (i = 0; i < lcfg->lcfg_bufcount; i++)
- printf("%d:%.*s ", i, lcfg->lcfg_buflens[i],
+ printf("%d:%.*s ", i, lcfg->lcfg_buflens[i],
(char*)lustre_cfg_buf(lcfg, i));
return;
}
static void print_setup_cfg(struct lustre_cfg *lcfg)
{
- char *name = lustre_cfg_string(lcfg, 0);
- char *type = name + strlen(name) - 3;
- if (!strcmp(type,"lov")){
- struct lov_desc *lovdesc;
+ struct lov_desc *desc;
+
+ if ((lcfg->lcfg_bufcount == 2) &&
+ (lcfg->lcfg_buflens[1] == sizeof(*desc))) {
printf("lov_setup ");
- printf("0:%s ", name);
+ printf("0:%s ", lustre_cfg_string(lcfg, 0));
printf("1:(struct lov_desc)\n");
- lovdesc = (struct lov_desc*)(lustre_cfg_string(lcfg, 1));
- printf("\t\tuuid=%s ", (char*)lovdesc->ld_uuid.uuid);
- printf("stripe:cnt=%d ", lovdesc->ld_default_stripe_count);
- printf("size=%lld ", lovdesc->ld_default_stripe_size);
- printf("offset=%lld ", lovdesc->ld_default_stripe_offset);
- printf("pattern=%d", lovdesc->ld_pattern);
- } else if (!strcmp(type,"lmv")){
- struct lmv_desc *lmvdesc;
- printf("lmv_setup ");
- printf("0:%s ", name);
- printf("1:(struct lmv_desc)\n");
- lmvdesc = (struct lmv_desc*)(lustre_cfg_string(lcfg, 1));
- printf("count=%d ", lmvdesc->ld_tgt_count);
- printf("atcive_count=%d", lmvdesc->ld_active_tgt_count);
- } else if (!strcmp(type,"cmm")){
- struct cmm_desc *cmmdesc;
- printf("cmm_setup ");
- printf("0:%s ", name);
- printf("1:(struct cmm_desc)\n");
- cmmdesc = (struct cmm_desc*)(lustre_cfg_string(lcfg, 1));
- printf("count=%d ", cmmdesc->ld_tgt_count);
- printf("atcive_count=%d", cmmdesc->ld_active_tgt_count);
+ desc = (struct lov_desc*)(lustre_cfg_string(lcfg, 1));
+ printf("\t\tuuid=%s ", (char*)desc->ld_uuid.uuid);
+ printf("stripe:cnt=%u ", desc->ld_default_stripe_count);
+ printf("size="LPU64" ", desc->ld_default_stripe_size);
+ printf("offset="LPU64" ", desc->ld_default_stripe_offset);
+ printf("pattern=%#x", desc->ld_pattern);
} else {
- printf("setup ");
+ printf("setup ");
print_1_cfg(lcfg);
}
-
return;
}
void print_lustre_cfg(struct lustre_cfg *lcfg, int *skip)
{
enum lcfg_command_type cmd = le32_to_cpu(lcfg->lcfg_command);
-
+
if (*skip > 0)
printf("SKIP ");
print_1_cfg(lcfg);
break;
}
- case(LCFG_LMV_ADD_MDC):{
- printf("lmv_modify_tgts add ");
- print_1_cfg(lcfg);
- break;
- }
- case(LCFG_LMV_DEL_MDC):{
- printf("lmv_modify_tgts del ");
- print_1_cfg(lcfg);
- break;
- }
- case(LCFG_CMM_ADD_MDC):{
- printf("cmm_modify_tgts add ");
- print_1_cfg(lcfg);
- break;
- }
- case(LCFG_CMM_DEL_MDC):{
- printf("cmm_modify_tgts del ");
- print_1_cfg(lcfg);
- break;
- }
case(LCFG_MOUNTOPT):{
printf("mount_option ");
print_1_cfg(lcfg);
}
case(LCFG_SET_TIMEOUT):{
printf("set_timeout=%d ", lcfg->lcfg_num);
- print_1_cfg(lcfg);
+ break;
+ }
+ case(LCFG_SET_LDLM_TIMEOUT):{
+ printf("set_ldlm_timeout=%d ", lcfg->lcfg_num);
break;
}
case(LCFG_SET_UPCALL):{
}
case(LCFG_MARKER):{
struct cfg_marker *marker = lustre_cfg_buf(lcfg, 1);
+ char createtime[26], canceltime[26] = "";
+ time_t time_tmp;
if (marker->cm_flags & CM_SKIP) {
- if (marker->cm_flags & CM_START)
+ if (marker->cm_flags & CM_START) {
+ printf("SKIP START ");
(*skip)++;
- if (marker->cm_flags & CM_END)
- (*skip)--;
+ } else {
+ printf( "END ");
+ *skip = 0;
+ }
+ }
+
+ if (marker->cm_flags & CM_EXCLUDE) {
+ if (marker->cm_flags & CM_START)
+ printf("EXCLUDE START ");
+ else
+ printf("EXCLUDE END ");
+ }
+
+ /* Handle overflow of 32-bit time_t gracefully.
+ * The copy to time_tmp is needed in any case to
+ * keep the pointer happy, even on 64-bit systems. */
+ time_tmp = marker->cm_createtime;
+ if (time_tmp == marker->cm_createtime) {
+ ctime_r(&time_tmp, createtime);
+ createtime[strlen(createtime) - 1] = 0;
+ } else {
+ strcpy(createtime, "in the distant future");
+ }
+
+ if (marker->cm_canceltime) {
+ /* Like cm_createtime, we try to handle overflow of
+ * 32-bit time_t gracefully. The copy to time_tmp
+ * is also needed on 64-bit systems to keep the
+ * pointer happy, see bug 16771 */
+ time_tmp = marker->cm_canceltime;
+ if (time_tmp == marker->cm_canceltime) {
+ ctime_r(&time_tmp, canceltime);
+ canceltime[strlen(canceltime) - 1] = 0;
+ } else {
+ strcpy(canceltime, "in the distant future");
+ }
}
- printf("marker %d (flags=%#x) %.16s '%s' %s:%s", marker->cm_step,
- marker->cm_flags, marker->cm_svname,
- marker->cm_comment, ctime(&marker->cm_createtime),
- marker->cm_canceltime ?
- ctime(&marker->cm_canceltime) : "");
+
+ printf("marker %3d (flags=%#04x, v%d.%d.%d.%d) %-15s '%s' %s-%s",
+ marker->cm_step, marker->cm_flags,
+ OBD_OCD_VERSION_MAJOR(marker->cm_vers),
+ OBD_OCD_VERSION_MINOR(marker->cm_vers),
+ OBD_OCD_VERSION_PATCH(marker->cm_vers),
+ OBD_OCD_VERSION_FIX(marker->cm_vers),
+ marker->cm_tgtname, marker->cm_comment,
+ createtime, canceltime);
+ break;
+ }
+ case(LCFG_POOL_NEW):{
+ printf("pool new ");
+ print_1_cfg(lcfg);
+ break;
+ }
+ case(LCFG_POOL_ADD):{
+ printf("pool add ");
+ print_1_cfg(lcfg);
+ break;
+ }
+ case(LCFG_POOL_REM):{
+ printf("pool remove ");
+ print_1_cfg(lcfg);
+ break;
+ }
+ case(LCFG_POOL_DEL):{
+ printf("pool destroy ");
+ print_1_cfg(lcfg);
break;
}
default:
return;
}
-void print_records(struct llog_rec_hdr** recs,int rec_number)
+void print_records(struct llog_rec_hdr **recs, int rec_number)
{
__u32 lopt;
int i, skip = 0;
-
- for(i = 0; i < rec_number; i++){
-
- printf("#%.2d ", le32_to_cpu(recs[i]->lrh_index));
+
+ for(i = 0; i < rec_number; i++) {
+ printf("#%.2d (%.3d)", le32_to_cpu(recs[i]->lrh_index),
+ le32_to_cpu(recs[i]->lrh_len));
lopt = le32_to_cpu(recs[i]->lrh_type);
- if (lopt == OBD_CFG_REC){
+ if (recs[i]->padding == CANCELLED)
+ printf("NOT SET ");
+
+ if (lopt == OBD_CFG_REC) {
struct lustre_cfg *lcfg;
- printf("L ");
- lcfg = (struct lustre_cfg *)
- ((char*)(recs[i]) + sizeof(struct llog_rec_hdr));
+ lcfg = (struct lustre_cfg *)((char*)(recs[i]) +
+ sizeof(struct llog_rec_hdr));
print_lustre_cfg(lcfg, &skip);
- }
+ } else if (lopt == LLOG_PAD_MAGIC) {
+ printf("padding\n");
+ } else
+ printf("unknown type %x\n", lopt);
- if (lopt == PTL_CFG_REC){
- printf("Portals - unknown type\n");
- }
}
}