Whamcloud - gitweb
LU-16000 utils: align updatelog parameters in llog_reader
[fs/lustre-release.git] / lustre / utils / llog_reader.c
index 6b43408..dc2ef05 100644 (file)
@@ -27,7 +27,6 @@
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
- * Lustre is a trademark of Sun Microsystems, Inc.
  */
 /** \defgroup llog_reader Lustre Log Reader
  *
@@ -44,6 +43,7 @@
 #include <string.h>
 #include <sys/types.h>
 #include <sys/stat.h>
+#include <sys/param.h>
 #ifdef HAVE_ENDIAN_H
 # include <endian.h>
 #endif
@@ -220,7 +220,7 @@ int llog_pack_buffer(int fd, struct llog_log_hdr **llog,
        struct llog_rec_hdr **recs_pr = NULL;
        char *ptr = NULL;
        int count;
-       int i;
+       int i, last_idx;
 
        rc = fstat(fd, &st);
        if (rc < 0) {
@@ -289,6 +289,7 @@ int llog_pack_buffer(int fd, struct llog_log_hdr **llog,
        ptr = file_buf + __le32_to_cpu((*llog)->llh_hdr.lrh_len);
        i = 0;
 
+       last_idx = 0;
        while (ptr < (file_buf + file_size)) {
                struct llog_rec_hdr *cur_rec;
                int idx;
@@ -316,11 +317,20 @@ int llog_pack_buffer(int fd, struct llog_log_hdr **llog,
                        printf("rec #%d type=%x len=%u offset %lu\n", idx,
                               cur_rec->lrh_type, cur_rec->lrh_len, offset);
                } else {
-                       printf("Bit %d of %d not set\n", idx, recs_num);
                        cur_rec->lrh_id = CANCELLED;
+                       if (cur_rec->lrh_type == LLOG_PAD_MAGIC &&
+                          ((offset + cur_rec->lrh_len) & 0x7) != 0)
+                               printf("rec #%d wrong padding len=%u offset %lu to 0x%lx\n",
+                                      idx, cur_rec->lrh_len, offset,
+                                      offset + cur_rec->lrh_len);
                        /* The header counts only set records */
                        i--;
                }
+               if (last_idx + 1 != idx) {
+                       printf("Previous index is %d, current %d, offset %lu\n",
+                              last_idx, idx, offset);
+               }
+               last_idx = idx;
 
                ptr += __le32_to_cpu(cur_rec->lrh_len);
                if ((ptr - file_buf) > file_size) {
@@ -359,15 +369,20 @@ void llog_unpack_buffer(int fd, struct llog_log_hdr *llog_buf,
 void print_llog_header(struct llog_log_hdr *llog_buf)
 {
        time_t t;
+       unsigned int lrh_len = __le32_to_cpu(llog_buf->llh_hdr.lrh_len);
+       struct llog_rec_tail *tail = ((struct llog_rec_tail *)((char *)llog_buf+
+                                lrh_len - sizeof(llog_buf->llh_tail)));
 
-       printf("Header size : %u\n",
-              __le32_to_cpu(llog_buf->llh_hdr.lrh_len));
+       printf("Header size : %u\t llh_size : %u\n", lrh_len,
+              __le32_to_cpu(llog_buf->llh_size));
 
        t = __le64_to_cpu(llog_buf->llh_timestamp);
        printf("Time : %s", ctime(&t));
 
-       printf("Number of records: %u\n",
-              __le32_to_cpu(llog_buf->llh_count) - 1);
+       printf("Number of records: %u\tcat_idx: %u\tlast_idx: %u\n",
+              __le32_to_cpu(llog_buf->llh_count)-1,
+              __le32_to_cpu(llog_buf->llh_cat_idx),
+              __le32_to_cpu(tail->lrt_index));
 
        printf("Target uuid : %s\n",
               (char *)(&llog_buf->llh_tgtuuid));
@@ -762,6 +777,194 @@ void print_changelog_rec(struct llog_changelog_rec *rec)
        printf("\n");
 }
 
+static void lustre_swab_lu_fid(struct lu_fid *fid)
+{
+       fid->f_seq = __swab64(fid->f_seq);
+       fid->f_oid = __swab32(fid->f_oid);
+       fid->f_ver = __swab32(fid->f_ver);
+}
+
+static inline size_t
+update_op_size(unsigned int param_count)
+{
+       return offsetof(struct update_op, uop_params_off[param_count]);
+}
+
+
+static inline struct update_op *
+update_op_next_op(const struct update_op *uop)
+{
+       return (struct update_op *)((char *)uop +
+                               update_op_size(uop->uop_param_count));
+}
+
+static void lustre_swab_update_ops(struct update_ops *uops,
+                                  unsigned int op_count)
+{
+       unsigned int i;
+       unsigned int j;
+
+       struct update_op *op =
+              (struct update_op *)((char *)&uops->uops_op[0]);
+
+       for (i = 0; i < op_count; i++, op = update_op_next_op(op)) {
+               lustre_swab_lu_fid(&op->uop_fid);
+               op->uop_type = __swab16(op->uop_type);
+               op->uop_param_count = __swab16(op->uop_param_count);
+               for (j = 0; j < op->uop_param_count; j++)
+                       op->uop_params_off[j] = __swab16(op->uop_params_off[j]);
+       }
+}
+static const char *update_op_str(__u16 opc)
+{
+       static const char *opc_str[] = {
+               [OUT_START] = "start",
+               [OUT_CREATE] = "create",
+               [OUT_DESTROY] = "destroy",
+               [OUT_REF_ADD] = "ref_add",
+               [OUT_REF_DEL] = "ref_del",
+               [OUT_ATTR_SET] = "attr_set",
+               [OUT_ATTR_GET] = "attr_get",
+               [OUT_XATTR_SET] = "xattr_set",
+               [OUT_XATTR_GET] = "xattr_get",
+               [OUT_XATTR_LIST] = "xattr_list",
+               [OUT_INDEX_LOOKUP] = "lookup",
+               [OUT_INDEX_INSERT] = "insert",
+               [OUT_INDEX_DELETE] = "delete",
+               [OUT_WRITE] = "write",
+               [OUT_XATTR_DEL] = "xattr_del",
+               [OUT_PUNCH] = "punch",
+               [OUT_READ] = "read",
+               [OUT_NOOP] = "noop",
+       };
+
+       if (opc < (sizeof(opc_str) / sizeof((opc_str)[0])) &&
+           opc_str[opc] != NULL)
+               return opc_str[opc];
+       else
+               return "unknown";
+}
+
+char *buf2str(void *buf, unsigned int size)
+{
+       const char *hex = "0123456789ABCDEF";
+       char *buf_c = buf;
+       static char string[128];
+       int i, j = 0;
+       bool format_hex = false;
+
+       if (size > 0 && buf_c[size - 1] == 0)
+               size--;
+       for (i = 0; i < size; i++) {
+               if (buf_c[i] >= 0x20 && buf_c[i] <= 0x7E) {
+                       string[j++] = buf_c[i];
+                       format_hex = false;
+               } else if (j < sizeof(string) - 6) {
+                       if (!format_hex) {
+                               string[j++] = '\\';
+                               string[j++] = 'x';
+                               format_hex = true;
+                       }
+                       string[j++] = hex[(buf_c[i] >> 4) & 0xF];
+                       string[j++] = hex[buf_c[i] & 0xF];
+               } else {
+                       break;
+               }
+               if (j == sizeof(string) - 2)
+                       break;
+       }
+       string[j] = 0;
+       return string;
+}
+
+static inline size_t
+object_update_param_size(const struct object_update_param *param)
+{
+       return roundup(sizeof(*param) + param->oup_len, sizeof(__u64));
+}
+
+void print_update_rec(struct llog_update_record *lur)
+{
+       struct update_records *rec = &lur->lur_update_rec;
+       unsigned int i, j, up_count, pm_count;
+       struct update_op *op;
+       struct object_update_param *pm;
+
+       up_count = __le32_to_cpu(rec->ur_update_count);
+       pm_count = __le32_to_cpu(rec->ur_param_count);
+       printf("updatelog record master_transno:%llu batchid:%llu flags:0x%x u_index:%d u_count:%d p_count:%d\n",
+              (unsigned long long)__le64_to_cpu(rec->ur_master_transno),
+              (unsigned long long)__le64_to_cpu(rec->ur_batchid),
+              __le32_to_cpu(rec->ur_flags),
+              __le32_to_cpu(rec->ur_index),
+              up_count,
+              pm_count);
+
+       op = (struct update_op *)((char *)&rec->ur_ops.uops_op[0] + 0);
+       if (op->uop_type != __le16_to_cpu(op->uop_type))
+               lustre_swab_update_ops(&rec->ur_ops, up_count);
+
+       for (i = 0; i < up_count; i++, op = update_op_next_op(op)) {
+               printf("\t"DFID" type:%s/%d params:%d ",
+                      PFID(&op->uop_fid), update_op_str(op->uop_type),
+                      op->uop_type, op->uop_param_count);
+               for (j = 0; j < op->uop_param_count; j++)
+                       printf("p_%d:%d ", j, op->uop_params_off[j]);
+               printf("\n");
+       }
+       pm = (struct object_update_param *) op;
+       for (i = 0; i < pm_count; i++) {
+               printf("\tp_%d - %d/%s\n", i, pm->oup_len,
+                      buf2str(pm->oup_buf, pm->oup_len));
+               pm = (struct object_update_param *)((char *)pm +
+                    object_update_param_size(pm));
+       }
+       printf("\n");
+
+}
+
+static void print_unlink_rec(struct llog_unlink_rec *lur)
+{
+       printf("unlink record id:0x%x target %llx:%x:%x\n",
+               __le32_to_cpu(lur->lur_hdr.lrh_id),
+               (unsigned long long)__le64_to_cpu(lur->lur_oid),
+               __le32_to_cpu(lur->lur_oseq),
+               __le32_to_cpu(lur->lur_count));
+}
+
+static void print_unlink64_rec(struct llog_unlink64_rec *lur)
+{
+       printf("unlink64 record id:0x%x target "DFID"\n",
+               __le32_to_cpu(lur->lur_hdr.lrh_id),
+               PFID(&lur->lur_fid));
+}
+
+static void print_setattr64_rec(struct llog_setattr64_rec *lsr)
+{
+       printf("setattr64 record id:0x%x target "DFID" valid %llx uid %u:%u gid %u:%u\n",
+               __le32_to_cpu(lsr->lsr_hdr.lrh_id),
+               PFID(&lsr->lsr_oi.oi_fid),
+               (unsigned long long)__le64_to_cpu(lsr->lsr_valid),
+               __le32_to_cpu(lsr->lsr_uid_h),
+               __le32_to_cpu(lsr->lsr_uid),
+               __le32_to_cpu(lsr->lsr_gid_h),
+               __le32_to_cpu(lsr->lsr_gid));
+}
+
+static void print_setattr64_rec_v2(struct llog_setattr64_rec_v2 *lsr)
+{
+       printf("setattr64 v2 record id:0x%x target "DFID" valid %llx uid %u:%u gid %u:%u prj %u\n",
+               __le32_to_cpu(lsr->lsr_hdr.lrh_id),
+               PFID(&lsr->lsr_oi.oi_fid),
+               (unsigned long long)__le64_to_cpu(lsr->lsr_valid),
+               __le32_to_cpu(lsr->lsr_uid_h),
+               __le32_to_cpu(lsr->lsr_uid),
+               __le32_to_cpu(lsr->lsr_gid_h),
+               __le32_to_cpu(lsr->lsr_gid),
+               __le32_to_cpu(lsr->lsr_projid));
+}
+
+
 static void print_records(struct llog_rec_hdr **recs,
                          int rec_number, int is_ext)
 {
@@ -804,9 +1007,29 @@ static void print_records(struct llog_rec_hdr **recs,
                                            recs[i]);
                        break;
                case CHANGELOG_USER_REC:
+               case CHANGELOG_USER_REC2:
                        printf("changelog_user record id:0x%x\n",
                               __le32_to_cpu(recs[i]->lrh_id));
                        break;
+               case UPDATE_REC:
+                       print_update_rec((struct llog_update_record *)recs[i]);
+                       break;
+               case MDS_UNLINK_REC:
+                       print_unlink_rec((struct llog_unlink_rec *)recs[i]);
+                       break;
+               case MDS_UNLINK64_REC:
+                       print_unlink64_rec((struct llog_unlink64_rec *)recs[i]);
+                       break;
+               case MDS_SETATTR64_REC:
+                       if (__le32_to_cpu(recs[i]->lrh_len) >
+                               sizeof(struct llog_setattr64_rec)) {
+                               print_setattr64_rec_v2(
+                                 (struct llog_setattr64_rec_v2 *)recs[i]);
+                       } else {
+                               print_setattr64_rec(
+                                       (struct llog_setattr64_rec *)recs[i]);
+                       }
+                       break;
                default:
                        printf("unknown type %x\n", lopt);
                        break;