Whamcloud - gitweb
b=20030
authornathan <nathan>
Thu, 30 Jul 2009 19:29:04 +0000 (19:29 +0000)
committernathan <nathan>
Thu, 30 Jul 2009 19:29:04 +0000 (19:29 +0000)
i=thomas.leibovici@cea.fr
i=adilger
return changelog entries as a struct from llapi

16 files changed:
lustre/include/lustre/liblustreapi.h
lustre/include/lustre/lustre_idl.h
lustre/include/lustre/lustre_user.h
lustre/mdd/mdd_device.c
lustre/mdd/mdd_dir.c
lustre/mdd/mdd_lproc.c
lustre/mdd/mdd_object.c
lustre/mds/mds_log.c
lustre/obdclass/llog_swab.c
lustre/obdclass/lprocfs_status.c
lustre/ptlrpc/wiretest.c
lustre/utils/lfs.c
lustre/utils/liblustreapi.c
lustre/utils/lreplicate.c
lustre/utils/wirecheck.c
lustre/utils/wiretest.c

index cde0b68..59fc25d 100644 (file)
@@ -182,14 +182,23 @@ extern int llapi_rsetfacl(int argc, char *argv[]);
 extern int llapi_rgetfacl(int argc, char *argv[]);
 extern int llapi_cp(int argc, char *argv[]);
 extern int llapi_ls(int argc, char *argv[]);
-extern int llapi_changelog_open(const char *mdtname, long long startrec);
-extern int llapi_changelog_clear(const char *mdtname, const char *idstr,
-                                 long long endrec);
-extern int llapi_changelog_register(const char *mdtname);
-extern int llapi_changelog_unregister(const char *mdtname, int id);
 extern int llapi_fid2path(const char *device, const char *fidstr, char *path,
                           int pathlen, long long *recno, int *linkno);
-/* HSM copytool interface.  priv is private copytool state, managed internally
+extern int llapi_path2fid(const char *path, lustre_fid *fid);
+
+/* Changelog interface.  priv is private state, managed internally
+   by these functions */
+#define CHANGELOG_FLAG_FOLLOW 0x01
+extern int llapi_changelog_start(void **priv, int flags, const char *mdtname,
+                                 long long startrec);
+extern int llapi_changelog_fini(void **priv);
+extern int llapi_changelog_recv(void *priv, struct changelog_rec **rech);
+extern int llapi_changelog_free(struct changelog_rec **rech);
+/* Allow records up to endrec to be destroyed; requires registered id. */
+extern int llapi_changelog_clear(const char *mdtname, const char *idstr,
+                                 long long endrec);
+
+/* HSM copytool interface.  priv is private state, managed internally
    by these functions */
 extern int llapi_copytool_start(void **priv, int flags, int archive_num_count,
                                 int *archive_nums);
index e2e43c2..e29996f 100644 (file)
@@ -2319,48 +2319,14 @@ struct llog_size_change_rec {
 } __attribute__((packed));
 
 #define CHANGELOG_MAGIC 0xca103000
-/** Changelog record types
- * When adding record types, update mdd_lproc.c's changelog_str
- */
-enum changelog_rec_type {
-        CL_MARK     = 0,
-        CL_CREATE   = 1,  /* namespace */
-        CL_MKDIR    = 2,  /* namespace */
-        CL_HARDLINK = 3,  /* namespace */
-        CL_SOFTLINK = 4,  /* namespace */
-        CL_MKNOD    = 5,  /* namespace */
-        CL_UNLINK   = 6,  /* namespace */
-        CL_RMDIR    = 7,  /* namespace */
-        CL_RENAME   = 8,  /* namespace */
-        CL_EXT      = 9,  /* namespace extended record (2nd half of rename) */
-        CL_OPEN     = 10, /* not currently used */
-        CL_CLOSE    = 11, /* may be written to log only with mtime change */
-        CL_IOCTL    = 12,
-        CL_TRUNC    = 13,
-        CL_SETATTR  = 14,
-        CL_XATTR    = 15,
-        CL_LAST
-};
-
-/** Changelog entry type names. Must be defined in the same order as the
- * \a changelog_rec_type enum.
- */
-#define DECLARE_CHANGELOG_NAMES static const char *changelog_str[] =         \
-       {"MARK","CREAT","MKDIR","HLINK","SLINK","MKNOD","UNLNK","RMDIR",      \
-        "RNMFM","RNMTO","OPEN","CLOSE","IOCTL","TRUNC","SATTR","XATTR"}
 
 /** \a changelog_rec_type's that can't be masked */
 #define CHANGELOG_MINMASK (1 << CL_MARK)
 /** bits covering all \a changelog_rec_type's */
-#define CHANGELOG_ALLMASK 0XFFFF
+#define CHANGELOG_ALLMASK 0XFFFFFFFF
 /** default \a changelog_rec_type mask */
 #define CHANGELOG_DEFMASK CHANGELOG_ALLMASK
 
-/* per-record flags */
-#define CLF_VERSION  0x1000
-#define CLF_FLAGMASK 0x0FFF
-#define CLF_HSM      0x0001
-
 /* changelog llog name, needed by client replicators */
 #define CHANGELOG_CATALOG "changelog_catalog"
 
@@ -2371,22 +2337,9 @@ struct changelog_setinfo {
 
 /** changelog record */
 struct llog_changelog_rec {
-        struct llog_rec_hdr   cr_hdr;
-        __u16                 cr_flags; /**< (flags&CLF_FLAGMASK)|CLF_VERSION */
-        __u16                 cr_namelen;
-        __u32                 cr_type;  /**< \a changelog_rec_type */
-        __u64                 cr_index;
-        __u64                 cr_prev;  /**< last index for this target fid */
-        __u64                 cr_time;
-        union {
-                struct lu_fid cr_tfid;        /**< target fid */
-                __u32         cr_markerflags; /**< CL_MARK flags */
-        };
-        struct lu_fid         cr_pfid;        /**< parent fid */
-        union {
-                char          cr_name[0];     /**< last element */
-                struct llog_rec_tail cr_tail; /**< for_sizezof_only */
-        };
+        struct llog_rec_hdr  cr_hdr;
+        struct changelog_rec cr;
+        struct llog_rec_tail cr_tail; /**< for_sizezof_only */
 } __attribute__((packed));
 
 #define CHANGELOG_USER_PREFIX "cl"
index 87643f8..eb58cd8 100644 (file)
@@ -417,7 +417,58 @@ struct if_quotactl {
 };
 
 
-/********* Misc **********/
+/********* Changelogs **********/
+/** Changelog record types */
+enum changelog_rec_type {
+        CL_MARK     = 0,
+        CL_CREATE   = 1,  /* namespace */
+        CL_MKDIR    = 2,  /* namespace */
+        CL_HARDLINK = 3,  /* namespace */
+        CL_SOFTLINK = 4,  /* namespace */
+        CL_MKNOD    = 5,  /* namespace */
+        CL_UNLINK   = 6,  /* namespace */
+        CL_RMDIR    = 7,  /* namespace */
+        CL_RENAME   = 8,  /* namespace */
+        CL_EXT      = 9,  /* namespace extended record (2nd half of rename) */
+        CL_OPEN     = 10, /* not currently used */
+        CL_CLOSE    = 11, /* may be written to log only with mtime change */
+        CL_IOCTL    = 12,
+        CL_TRUNC    = 13,
+        CL_SETATTR  = 14,
+        CL_XATTR    = 15,
+        CL_HSM      = 16, /* HSM specific events, see flags */
+        CL_LAST
+};
+
+static inline const char *changelog_type2str(int type) {
+        static const char *changelog_str[] = {
+                "MARK",  "CREAT", "MKDIR", "HLINK", "SLINK", "MKNOD", "UNLNK",
+                "RMDIR", "RNMFM", "RNMTO", "OPEN",  "CLOSE", "IOCTL", "TRUNC",
+                "SATTR", "XATTR", "HSM"   };
+        if (type >= 0 && type < CL_LAST)
+                return changelog_str[type];
+        return NULL;
+}
+
+/* per-record flags */
+#define CLF_VERSION  0x1000
+#define CLF_FLAGMASK 0x0FFF
+/* Anything under the flagmask may be per-type (if desired) */
+
+struct changelog_rec {
+        __u16                 cr_namelen;
+        __u16                 cr_flags; /**< (flags&CLF_FLAGMASK)|CLF_VERSION */
+        __u32                 cr_type;  /**< \a changelog_rec_type */
+        __u64                 cr_index; /**< changelog record number */
+        __u64                 cr_prev;  /**< last index for this target fid */
+        __u64                 cr_time;
+        union {
+                lustre_fid    cr_tfid;        /**< target fid */
+                __u32         cr_markerflags; /**< CL_MARK flags */
+        };
+        lustre_fid            cr_pfid;        /**< parent fid */
+        char                  cr_name[0];     /**< last element */
+} __attribute__((packed));
 
 struct ioc_changelog_clear {
         __u32 icc_mdtindex;
@@ -425,6 +476,9 @@ struct ioc_changelog_clear {
         __u64 icc_recno;
 };
 
+
+/********* Misc **********/
+
 #ifndef offsetof
 # define offsetof(typ,memb)     ((unsigned long)((char *)&(((typ *)0)->memb)))
 #endif
index 302b1d5..16fefbd 100644 (file)
@@ -148,11 +148,11 @@ static int changelog_init_cb(struct llog_handle *llh, struct llog_rec_hdr *hdr,
 
         CDEBUG(D_INFO,
                "seeing record at index %d/%d/"LPU64" t=%x %.*s in log "LPX64"\n",
-               hdr->lrh_index, rec->cr_hdr.lrh_index, rec->cr_index,
-               rec->cr_type, rec->cr_namelen, rec->cr_name,
+               hdr->lrh_index, rec->cr_hdr.lrh_index, rec->cr.cr_index,
+               rec->cr.cr_type, rec->cr.cr_namelen, rec->cr.cr_name,
                llh->lgh_id.lgl_oid);
 
-        mdd->mdd_cl.mc_index = rec->cr_index;
+        mdd->mdd_cl.mc_index = rec->cr.cr_index;
         RETURN(LLOG_PROC_BREAK);
 }
 
@@ -303,18 +303,18 @@ int mdd_changelog_llog_write(struct mdd_device         *mdd,
         struct llog_ctxt *ctxt;
         int rc;
 
-        if ((mdd->mdd_cl.mc_mask & (1 << rec->cr_type)) == 0)
+        if ((mdd->mdd_cl.mc_mask & (1 << rec->cr.cr_type)) == 0)
                 return 0;
 
-        rec->cr_hdr.lrh_len = llog_data_len(sizeof(*rec) + rec->cr_namelen);
+        rec->cr_hdr.lrh_len = llog_data_len(sizeof(*rec) + rec->cr.cr_namelen);
         /* llog_lvfs_write_rec sets the llog tail len */
         rec->cr_hdr.lrh_type = CHANGELOG_REC;
-        rec->cr_time = cfs_time_current_64();
+        rec->cr.cr_time = cfs_time_current_64();
         spin_lock(&mdd->mdd_cl.mc_lock);
         /* NB: I suppose it's possible llog_add adds out of order wrt cr_index,
            but as long as the MDD transactions are ordered correctly for e.g.
            rename conflicts, I don't think this should matter. */
-        rec->cr_index = ++mdd->mdd_cl.mc_index;
+        rec->cr.cr_index = ++mdd->mdd_cl.mc_index;
         spin_unlock(&mdd->mdd_cl.mc_lock);
         ctxt = llog_get_context(obd, LLOG_CHANGELOG_ORIG_CTXT);
         if (ctxt == NULL)
@@ -396,17 +396,17 @@ int mdd_changelog_write_header(struct mdd_device *mdd, int markerflags)
         if (rec == NULL)
                 RETURN(-ENOMEM);
 
-        rec->cr_flags = CLF_VERSION;
-        rec->cr_type = CL_MARK;
-        rec->cr_namelen = len;
-        memcpy(rec->cr_name, obd->obd_name, rec->cr_namelen);
+        rec->cr.cr_flags = CLF_VERSION;
+        rec->cr.cr_type = CL_MARK;
+        rec->cr.cr_namelen = len;
+        memcpy(rec->cr.cr_name, obd->obd_name, rec->cr.cr_namelen);
         /* Status and action flags */
-        rec->cr_markerflags = mdd->mdd_cl.mc_flags | markerflags;
+        rec->cr.cr_markerflags = mdd->mdd_cl.mc_flags | markerflags;
 
         rc = mdd_changelog_llog_write(mdd, rec, NULL);
 
         /* assume on or off event; reset repeat-access time */
-        mdd->mdd_cl.mc_starttime = rec->cr_time;
+        mdd->mdd_cl.mc_starttime = rec->cr.cr_time;
 
         OBD_FREE(rec, reclen);
         RETURN(rc);
index d1cf1f4..06561d9 100644 (file)
@@ -647,13 +647,13 @@ static int mdd_changelog_ns_store(const struct lu_env  *env,
                 RETURN(-ENOMEM);
         rec = (struct llog_changelog_rec *)buf->lb_buf;
 
-        rec->cr_flags = CLF_VERSION;
-        rec->cr_type = (__u32)type;
+        rec->cr.cr_flags = CLF_VERSION;
+        rec->cr.cr_type = (__u32)type;
         tfid = tf ? tf : mdo2fid(target);
-        rec->cr_tfid = *tfid;
-        rec->cr_pfid = *tpfid;
-        rec->cr_namelen = tname->ln_namelen;
-        memcpy(rec->cr_name, tname->ln_name, rec->cr_namelen);
+        rec->cr.cr_tfid = *tfid;
+        rec->cr.cr_pfid = *tpfid;
+        rec->cr.cr_namelen = tname->ln_namelen;
+        memcpy(rec->cr.cr_name, tname->ln_name, rec->cr.cr_namelen);
         if (likely(target))
                 target->mod_cltime = cfs_time_current_64();
 
index 903a675..3784927 100644 (file)
@@ -155,15 +155,6 @@ static int lprocfs_rd_atime_diff(char *page, char **start, off_t off,
 
 
 /**** changelogs ****/
-DECLARE_CHANGELOG_NAMES;
-
-const char *changelog_bit2str(int bit)
-{
-        if (bit < CL_LAST)
-                return changelog_str[bit];
-        return NULL;
-}
-
 static int lprocfs_rd_changelog_mask(char *page, char **start, off_t off,
                                      int count, int *eof, void *data)
 {
@@ -174,7 +165,7 @@ static int lprocfs_rd_changelog_mask(char *page, char **start, off_t off,
         while (i < CL_LAST) {
                 if (mdd->mdd_cl.mc_mask & (1 << i))
                         rc += snprintf(page + rc, count - rc, "%s ",
-                                       changelog_str[i]);
+                                       changelog_type2str(i));
                 i++;
         }
         return rc;
@@ -197,7 +188,7 @@ static int lprocfs_wr_changelog_mask(struct file *file, const char *buffer,
                 GOTO(out, rc = -EFAULT);
         kernbuf[count] = 0;
 
-        rc = libcfs_str2mask(kernbuf, changelog_bit2str, &mdd->mdd_cl.mc_mask,
+        rc = libcfs_str2mask(kernbuf, changelog_type2str, &mdd->mdd_cl.mc_mask,
                              CHANGELOG_MINMASK, CHANGELOG_ALLMASK);
         if (rc == 0)
                 rc = count;
index e04f1c8..070847e 100644 (file)
@@ -1200,10 +1200,10 @@ static int mdd_changelog_data_store(const struct lu_env     *env,
                 RETURN(-ENOMEM);
         rec = (struct llog_changelog_rec *)buf->lb_buf;
 
-        rec->cr_flags = CLF_VERSION;
-        rec->cr_type = (__u32)type;
-        rec->cr_tfid = *tfid;
-        rec->cr_namelen = 0;
+        rec->cr.cr_flags = CLF_VERSION;
+        rec->cr.cr_type = (__u32)type;
+        rec->cr.cr_tfid = *tfid;
+        rec->cr.cr_namelen = 0;
         mdd_obj->mod_cltime = cfs_time_current_64();
 
         rc = mdd_changelog_llog_write(mdd, rec, handle);
index 17393d2..0108623 100644 (file)
@@ -127,7 +127,7 @@ static int llog_changelog_cancel_cb(struct llog_handle *llh,
         /* This is always a (sub)log, not the catalog */
         LASSERT(llh->lgh_hdr->llh_flags & LLOG_F_IS_PLAIN);
 
-        if (rec->cr_index > endrec)
+        if (rec->cr.cr_index > endrec)
                 /* records are in order, so we're done */
                 RETURN(LLOG_PROC_BREAK);
 
index 1602044..8c49fc7 100644 (file)
@@ -156,14 +156,14 @@ void lustre_swab_llog_rec(struct llog_rec_hdr *rec, struct llog_rec_tail *tail)
         case CHANGELOG_REC: {
                 struct llog_changelog_rec *cr = (struct llog_changelog_rec*)rec;
 
-                __swab16s(&cr->cr_flags);
-                __swab16s(&cr->cr_namelen);
-                __swab32s(&cr->cr_type);
-                __swab64s(&cr->cr_index);
-                __swab64s(&cr->cr_prev);
-                __swab64s(&cr->cr_time);
-                lustre_swab_lu_fid(&cr->cr_tfid);
-                lustre_swab_lu_fid(&cr->cr_pfid);
+                __swab16s(&cr->cr.cr_namelen);
+                __swab16s(&cr->cr.cr_flags);
+                __swab32s(&cr->cr.cr_type);
+                __swab64s(&cr->cr.cr_index);
+                __swab64s(&cr->cr.cr_prev);
+                __swab64s(&cr->cr.cr_time);
+                lustre_swab_lu_fid(&cr->cr.cr_tfid);
+                lustre_swab_lu_fid(&cr->cr.cr_pfid);
                 break;
         }
 
index 6c5e052..b1224aa 100644 (file)
@@ -2233,8 +2233,6 @@ EXPORT_SYMBOL(lprocfs_obd_wr_recovery_maxtime);
 /**** Changelogs *****/
 #define D_CHANGELOG 0
 
-DECLARE_CHANGELOG_NAMES;
-
 /* How many records per seq_show.  Too small, we spawn llog_process threads
    too often; too large, we run out of buffer space */
 #define CHANGELOG_CHUNK_SIZE 100
@@ -2245,25 +2243,26 @@ static int changelog_show_cb(struct llog_handle *llh, struct llog_rec_hdr *hdr,
         struct seq_file *seq = (struct seq_file *)data;
         struct changelog_seq_iter *csi = seq->private;
         struct llog_changelog_rec *rec = (struct llog_changelog_rec *)hdr;
-        int rc;
+        char *ptr;
+        int cnt, rc;
         ENTRY;
 
         if ((rec->cr_hdr.lrh_type != CHANGELOG_REC) ||
-            (rec->cr_type >= CL_LAST)) {
+            (rec->cr.cr_type >= CL_LAST)) {
                 CERROR("Not a changelog rec %d/%d\n", rec->cr_hdr.lrh_type,
-                       rec->cr_type);
+                       rec->cr.cr_type);
                 RETURN(-EINVAL);
         }
 
         CDEBUG(D_CHANGELOG, "rec="LPU64" start="LPU64" cat=%d:%d start=%d:%d\n",
-               rec->cr_index, csi->csi_startrec,
+               rec->cr.cr_index, csi->csi_startrec,
                llh->lgh_hdr->llh_cat_idx, llh->lgh_cur_idx,
                csi->csi_startcat, csi->csi_startidx);
 
-        if (rec->cr_index < csi->csi_startrec)
+        if (rec->cr.cr_index < csi->csi_startrec)
                 /* Skip entries earlier than what we are interested in */
                 RETURN(0);
-        if (rec->cr_index == csi->csi_startrec) {
+        if (rec->cr.cr_index == csi->csi_startrec) {
                 /* Remember where we started, since seq_read will re-read
                  * the data when it reallocs space.  Sigh, if only there was
                  * a way to tell seq_file how big the buf should be in the
@@ -2276,38 +2275,42 @@ static int changelog_show_cb(struct llog_handle *llh, struct llog_rec_hdr *hdr,
                 /* Stop at some point with a reasonable seq_file buffer size.
                  * Start from here the next time.
                  */
-                csi->csi_endrec = rec->cr_index - 1;
+                csi->csi_endrec = rec->cr.cr_index - 1;
                 csi->csi_startcat = llh->lgh_hdr->llh_cat_idx;
                 csi->csi_startidx = rec->cr_hdr.lrh_index - 1;
                 csi->csi_wrote = 0;
                 RETURN(LLOG_PROC_BREAK);
         }
 
-        rc = seq_printf(seq, LPU64" %02d%-5s "LPU64" 0x%x t="DFID,
-                        rec->cr_index, rec->cr_type,
-                        changelog_str[rec->cr_type], rec->cr_time,
-                        rec->cr_flags & CLF_FLAGMASK, PFID(&rec->cr_tfid));
-
-        if (rec->cr_namelen)
-                /* namespace rec includes parent and filename */
-                rc += seq_printf(seq, " p="DFID" %.*s\n", PFID(&rec->cr_pfid),
-                                 rec->cr_namelen, rec->cr_name);
-        else
-                rc += seq_puts(seq, "\n");
+        CDEBUG(D_CHANGELOG, LPU64" %02d%-5s "LPU64" 0x%x t="DFID" p="DFID
+               " %.*s\n", rec->cr.cr_index, rec->cr.cr_type,
+               changelog_type2str(rec->cr.cr_type), rec->cr.cr_time,
+               rec->cr.cr_flags & CLF_FLAGMASK,
+               PFID(&rec->cr.cr_tfid), PFID(&rec->cr.cr_pfid),
+               rec->cr.cr_namelen, rec->cr.cr_name);
+
+        cnt = sizeof(rec->cr) + rec->cr.cr_namelen;
+        ptr = (char *)(&rec->cr);
+        CDEBUG(D_CHANGELOG, "packed rec %d starting at %p\n", cnt, ptr);
+        rc = 0;
+        while ((cnt-- > 0) && (rc == 0)) {
+                rc = seq_putc(seq, *ptr);
+                ptr++;
+        }
 
         if (rc < 0) {
                 /* Ran out of room in the seq buffer. seq_read will dump
                  * the whole buffer and re-seq_start with a larger one;
                  * no point in continuing the llog_process */
                 CDEBUG(D_CHANGELOG, "rec="LPU64" overflow "LPU64"<-"LPU64"\n",
-                       rec->cr_index, csi->csi_startrec, csi->csi_endrec);
+                       rec->cr.cr_index, csi->csi_startrec, csi->csi_endrec);
                 csi->csi_endrec = csi->csi_startrec - 1;
                 csi->csi_wrote = 0;
                 RETURN(LLOG_PROC_BREAK);
         }
 
         csi->csi_wrote++;
-        csi->csi_endrec = rec->cr_index;
+        csi->csi_endrec = rec->cr.cr_index;
 
         RETURN(0);
 }
index 4bd0158..790f861 100644 (file)
@@ -1978,6 +1978,42 @@ void lustre_assert_wire_constants(void)
         LASSERTF((int)sizeof(((struct llog_size_change_rec *)0)->lsc_tail) == 8, " found %lld\n",
                  (long long)(int)sizeof(((struct llog_size_change_rec *)0)->lsc_tail));
 
+        /* Checks for struct changelog_rec */
+        LASSERTF((int)sizeof(struct changelog_rec) == 64, " found %lld\n",
+                 (long long)(int)sizeof(struct changelog_rec));
+        LASSERTF((int)offsetof(struct changelog_rec, cr_namelen) == 0, " found %lld\n",
+                 (long long)(int)offsetof(struct changelog_rec, cr_namelen));
+        LASSERTF((int)sizeof(((struct changelog_rec *)0)->cr_namelen) == 2, " found %lld\n",
+                 (long long)(int)sizeof(((struct changelog_rec *)0)->cr_namelen));
+        LASSERTF((int)offsetof(struct changelog_rec, cr_flags) == 2, " found %lld\n",
+                 (long long)(int)offsetof(struct changelog_rec, cr_flags));
+        LASSERTF((int)sizeof(((struct changelog_rec *)0)->cr_flags) == 2, " found %lld\n",
+                 (long long)(int)sizeof(((struct changelog_rec *)0)->cr_flags));
+        LASSERTF((int)offsetof(struct changelog_rec, cr_type) == 4, " found %lld\n",
+                 (long long)(int)offsetof(struct changelog_rec, cr_type));
+        LASSERTF((int)sizeof(((struct changelog_rec *)0)->cr_type) == 4, " found %lld\n",
+                 (long long)(int)sizeof(((struct changelog_rec *)0)->cr_type));
+        LASSERTF((int)offsetof(struct changelog_rec, cr_index) == 8, " found %lld\n",
+                 (long long)(int)offsetof(struct changelog_rec, cr_index));
+        LASSERTF((int)sizeof(((struct changelog_rec *)0)->cr_index) == 8, " found %lld\n",
+                 (long long)(int)sizeof(((struct changelog_rec *)0)->cr_index));
+        LASSERTF((int)offsetof(struct changelog_rec, cr_prev) == 16, " found %lld\n",
+                 (long long)(int)offsetof(struct changelog_rec, cr_prev));
+        LASSERTF((int)sizeof(((struct changelog_rec *)0)->cr_prev) == 8, " found %lld\n",
+                 (long long)(int)sizeof(((struct changelog_rec *)0)->cr_prev));
+        LASSERTF((int)offsetof(struct changelog_rec, cr_time) == 24, " found %lld\n",
+                 (long long)(int)offsetof(struct changelog_rec, cr_time));
+        LASSERTF((int)sizeof(((struct changelog_rec *)0)->cr_time) == 8, " found %lld\n",
+                 (long long)(int)sizeof(((struct changelog_rec *)0)->cr_time));
+        LASSERTF((int)offsetof(struct changelog_rec, cr_tfid) == 32, " found %lld\n",
+                 (long long)(int)offsetof(struct changelog_rec, cr_tfid));
+        LASSERTF((int)sizeof(((struct changelog_rec *)0)->cr_tfid) == 16, " found %lld\n",
+                 (long long)(int)sizeof(((struct changelog_rec *)0)->cr_tfid));
+        LASSERTF((int)offsetof(struct changelog_rec, cr_pfid) == 48, " found %lld\n",
+                 (long long)(int)offsetof(struct changelog_rec, cr_pfid));
+        LASSERTF((int)sizeof(((struct changelog_rec *)0)->cr_pfid) == 16, " found %lld\n",
+                 (long long)(int)sizeof(((struct changelog_rec *)0)->cr_pfid));
+
         /* Checks for struct llog_changelog_rec */
         LASSERTF((int)sizeof(struct llog_changelog_rec) == 88, " found %lld\n",
                  (long long)(int)sizeof(struct llog_changelog_rec));
@@ -1985,38 +2021,10 @@ void lustre_assert_wire_constants(void)
                  (long long)(int)offsetof(struct llog_changelog_rec, cr_hdr));
         LASSERTF((int)sizeof(((struct llog_changelog_rec *)0)->cr_hdr) == 16, " found %lld\n",
                  (long long)(int)sizeof(((struct llog_changelog_rec *)0)->cr_hdr));
-        LASSERTF((int)offsetof(struct llog_changelog_rec, cr_flags) == 16, " found %lld\n",
-                 (long long)(int)offsetof(struct llog_changelog_rec, cr_flags));
-        LASSERTF((int)sizeof(((struct llog_changelog_rec *)0)->cr_flags) == 2, " found %lld\n",
-                 (long long)(int)sizeof(((struct llog_changelog_rec *)0)->cr_flags));
-        LASSERTF((int)offsetof(struct llog_changelog_rec, cr_namelen) == 18, " found %lld\n",
-                 (long long)(int)offsetof(struct llog_changelog_rec, cr_namelen));
-        LASSERTF((int)sizeof(((struct llog_changelog_rec *)0)->cr_namelen) == 2, " found %lld\n",
-                 (long long)(int)sizeof(((struct llog_changelog_rec *)0)->cr_namelen));
-        LASSERTF((int)offsetof(struct llog_changelog_rec, cr_type) == 20, " found %lld\n",
-                 (long long)(int)offsetof(struct llog_changelog_rec, cr_type));
-        LASSERTF((int)sizeof(((struct llog_changelog_rec *)0)->cr_type) == 4, " found %lld\n",
-                 (long long)(int)sizeof(((struct llog_changelog_rec *)0)->cr_type));
-        LASSERTF((int)offsetof(struct llog_changelog_rec, cr_index) == 24, " found %lld\n",
-                 (long long)(int)offsetof(struct llog_changelog_rec, cr_index));
-        LASSERTF((int)sizeof(((struct llog_changelog_rec *)0)->cr_index) == 8, " found %lld\n",
-                 (long long)(int)sizeof(((struct llog_changelog_rec *)0)->cr_index));
-        LASSERTF((int)offsetof(struct llog_changelog_rec, cr_prev) == 32, " found %lld\n",
-                 (long long)(int)offsetof(struct llog_changelog_rec, cr_prev));
-        LASSERTF((int)sizeof(((struct llog_changelog_rec *)0)->cr_prev) == 8, " found %lld\n",
-                 (long long)(int)sizeof(((struct llog_changelog_rec *)0)->cr_prev));
-        LASSERTF((int)offsetof(struct llog_changelog_rec, cr_time) == 40, " found %lld\n",
-                 (long long)(int)offsetof(struct llog_changelog_rec, cr_time));
-        LASSERTF((int)sizeof(((struct llog_changelog_rec *)0)->cr_time) == 8, " found %lld\n",
-                 (long long)(int)sizeof(((struct llog_changelog_rec *)0)->cr_time));
-        LASSERTF((int)offsetof(struct llog_changelog_rec, cr_tfid) == 48, " found %lld\n",
-                 (long long)(int)offsetof(struct llog_changelog_rec, cr_tfid));
-        LASSERTF((int)sizeof(((struct llog_changelog_rec *)0)->cr_tfid) == 16, " found %lld\n",
-                 (long long)(int)sizeof(((struct llog_changelog_rec *)0)->cr_tfid));
-        LASSERTF((int)offsetof(struct llog_changelog_rec, cr_pfid) == 64, " found %lld\n",
-                 (long long)(int)offsetof(struct llog_changelog_rec, cr_pfid));
-        LASSERTF((int)sizeof(((struct llog_changelog_rec *)0)->cr_pfid) == 16, " found %lld\n",
-                 (long long)(int)sizeof(((struct llog_changelog_rec *)0)->cr_pfid));
+        LASSERTF((int)offsetof(struct llog_changelog_rec, cr) == 16, " found %lld\n",
+                 (long long)(int)offsetof(struct llog_changelog_rec, cr));
+        LASSERTF((int)sizeof(((struct llog_changelog_rec *)0)->cr) == 64, " found %lld\n",
+                 (long long)(int)sizeof(((struct llog_changelog_rec *)0)->cr));
         LASSERTF((int)offsetof(struct llog_changelog_rec, cr_tail) == 80, " found %lld\n",
                  (long long)(int)offsetof(struct llog_changelog_rec, cr_tail));
         LASSERTF((int)sizeof(((struct llog_changelog_rec *)0)->cr_tail) == 8, " found %lld\n",
index 38d074a..ba1306e 100644 (file)
@@ -65,7 +65,6 @@
 
 /* For dirname() */
 #include <libgen.h>
-#include <poll.h>
 
 #include <lnet/api-support.h>
 #include <lnet/lnetctl.h>
@@ -2359,58 +2358,18 @@ static int lfs_ls(int argc, char **argv)
         return(llapi_ls(argc, argv));
 }
 
-/* A helper function to return single, whole lines delimited by newline.
-   Returns length of line.  Not reentrant! */
-static int get_next_full_line(int fd, char **ptr)
-{
-        static char buf[8192]; /* bigger than MAX_PATH_LENGTH */
-        static char *sptr = buf, *eptr = buf;
-        static int len, rem;
-
-        if ((*ptr == NULL) /* first time */
-            || (eptr >= buf + len) /* buffer empty */) {
-                sptr = eptr = buf;
-                len = read(fd, buf, sizeof(buf));
-                if (len <= 0)
-                        return len;
-        } else {
-                sptr = eptr + 1;
-        }
-
-full_line:
-        while (eptr < buf + len) {
-                eptr++;
-                /* parse full lines */
-                if (*eptr == '\n') {
-                        *eptr = '\0';
-                        *ptr = sptr;
-                        return (eptr - sptr);
-                }
-        }
-
-        /* partial line; move to front of buf */
-        rem = buf + len - sptr;
-        memcpy(buf, sptr, rem);
-        sptr = buf;
-        eptr = buf + rem;
-        len = read(fd, eptr, sizeof(buf) - rem);
-        if (len <= 0)
-                return len;
-        len += rem;
-        goto full_line;
-}
-
 static int lfs_changelog(int argc, char **argv)
 {
-        long long startrec = 0, endrec = 0, recnum;
-        int fd, len;
-        char c, *mdd, *ptr = NULL;
+        void *changelog_priv;
+        struct changelog_rec *rec;
+        long long startrec = 0, endrec = 0;
+        char c, *mdd;
         struct option long_opts[] = {
                 {"follow", no_argument, 0, 'f'},
                 {0, 0, 0, 0}
         };
         char short_opts[] = "f";
-        int follow = 0;
+        int rc, follow = 0;
 
         optind = 0;
         while ((c = getopt_long(argc, argv, short_opts,
@@ -2436,44 +2395,37 @@ static int lfs_changelog(int argc, char **argv)
         if (argc > optind)
                 endrec = strtoll(argv[optind++], NULL, 10);
 
-        fd = llapi_changelog_open(mdd, startrec);
-        if (fd < 0) {
-                fprintf(stderr, "%s Can't open changelog: %s\n", argv[0],
-                        strerror(errno = -fd));
-                return fd;
+        rc = llapi_changelog_start(&changelog_priv,
+                                   follow ? CHANGELOG_FLAG_FOLLOW : 0,
+                                   mdd, startrec);
+        if (rc < 0) {
+                fprintf(stderr, "Can't start changelog: %s\n",
+                        strerror(errno = -rc));
+                return rc;
         }
 
-        while ((len = get_next_full_line(fd, &ptr)) >= 0) {
-                if (len == 0) {
-                        struct pollfd pfds[1];
-                        int rc;
-
-                        if (!follow)
-                                break;
-                        pfds[0].fd = fd;
-                        pfds[0].events = POLLIN;
-                        rc = poll(pfds, 1, -1);
-                        if (rc < 0)
-                                break;
-                        continue;
-                }
-     /* eg. 2 02MKDIR 4405821890 t=[0x100000400/0x5] p=[0x100000400/0x4] pics */
-                sscanf(ptr, "%lld *", &recnum);
-                if (endrec && recnum > endrec)
+        while ((rc = llapi_changelog_recv(changelog_priv, &rec)) == 0) {
+                if (endrec && rec->cr_index > endrec)
                         break;
-                if (recnum < startrec)
+                if (rec->cr_index < startrec)
                         continue;
-                printf("%.*s\n", len, ptr);
-        }
 
-        close(fd);
-
-        if (len < 0) {
-                fprintf(stderr, "read err %d\n", errno);
-                return -errno;
+                printf(LPU64" %02d%-5s "LPU64" 0x%x t="DFID,
+                       rec->cr_index, rec->cr_type,
+                       changelog_type2str(rec->cr_type), rec->cr_time,
+                       rec->cr_flags & CLF_FLAGMASK, PFID(&rec->cr_tfid));
+                if (rec->cr_namelen)
+                        /* namespace rec includes parent and filename */
+                        printf(" p="DFID" %.*s\n", PFID(&rec->cr_pfid),
+                               rec->cr_namelen, rec->cr_name);
+                else
+                        printf("\n");
+                llapi_changelog_free(&rec);
         }
 
-        return 0;
+        llapi_changelog_fini(&changelog_priv);
+
+        return (rc == 1 ? 0 : rc);
 }
 
 static int lfs_changelog_clear(int argc, char **argv)
index c029546..0164cd7 100644 (file)
@@ -65,6 +65,7 @@
 #else
 #include <unistd.h>
 #endif
+#include <poll.h>
 
 #include <liblustre.h>
 #include <lnet/lnetctl.h>
@@ -2441,18 +2442,23 @@ int llapi_ls(int argc, char *argv[])
 /* Print mdtname 'name' into 'buf' using 'format'.  Add -MDT0000 if needed.
  * format must have %s%s, buf must be > 16
  */
-static int get_mdtname(const char *name, char *format, char *buf)
+static int get_mdtname(char *name, char *format, char *buf)
 {
         char suffix[]="-MDT0000";
         int len = strlen(name);
 
+        if ((len > 5) && (strncmp(name + len - 5, "_UUID", 5) == 0)) {
+                name[len - 5] = '\0';
+                len -= 5;
+        }
+
         if (len > 8) {
                 if ((len <= 16) && strncmp(name + len - 8, "-MDT", 4) == 0) {
                         suffix[0] = '\0';
                 } else {
                         /* Not enough room to add suffix */
-                        llapi_err(LLAPI_MSG_ERROR, "MDT name too long |%s|\n",
-                                  name);
+                        llapi_err(LLAPI_MSG_ERROR | LLAPI_MSG_NO_ERRNO,
+                                  "MDT name too long |%s|", name);
                         return -EINVAL;
                 }
         }
@@ -2460,12 +2466,26 @@ static int get_mdtname(const char *name, char *format, char *buf)
         return sprintf(buf, format, name, suffix);
 }
 
+/****** Changelog API ********/
+#define CHANGELOG_PRIV_MAGIC 0xCA8E1080
+struct changelog_private {
+        int magic;
+        int fd;
+        int flags;
+};
 
-/* Return a file descriptor to a readable changelog */
-int llapi_changelog_open(const char *device, long long startrec)
+/** Start reading from a changelog
+ * @param priv Opaque private control structure
+ * @param flags Start flags (e.g. follow)
+ * @param device Report changes recorded on this MDT
+ * @param startrec Report changes beginning with this record number
+ */
+int llapi_changelog_start(void **priv, int flags, const char *device,
+                          long long startrec)
 {
+        struct changelog_private *cp;
         char path[256];
-        char mdtname[17];
+        char mdtname[20];
         int rc, fd;
 
         if (device[0] == '/')
@@ -2493,7 +2513,99 @@ int llapi_changelog_open(const char *device, long long startrec)
                 return -errno;
         }
 
-        return fd;
+        cp = malloc(sizeof(*cp));
+        if (cp == NULL) {
+                close(fd);
+                return -ENOMEM;
+        }
+
+        cp->magic = CHANGELOG_PRIV_MAGIC;
+        cp->fd = fd;
+        cp->flags = flags;
+        *priv = cp;
+
+        return 0;
+}
+
+/** Finish reading from a changelog */
+int llapi_changelog_fini(void **priv)
+{
+        struct changelog_private *cp = (struct changelog_private *)*priv;
+
+        if (!cp || (cp->magic != CHANGELOG_PRIV_MAGIC))
+                return -EINVAL;
+
+        close(cp->fd);
+        free(cp);
+        *priv = NULL;
+        return 0;
+}
+
+static int pollwait(int fd) {
+        struct pollfd pfds[1];
+        int rc;
+
+        pfds[0].fd = fd;
+        pfds[0].events = POLLIN;
+        rc = poll(pfds, 1, -1);
+        return rc < 0 ? -errno : rc;
+}
+
+/** Read the next changelog entry
+ * @param priv Opaque private control structure
+ * @param rech Changelog record handle; record will be allocated here
+ * @return 0 valid message received; rec is set
+ *         <0 error code
+ *         1 EOF
+ */
+int llapi_changelog_recv(void *priv, struct changelog_rec **rech)
+{
+        struct changelog_private *cp = (struct changelog_private *)priv;
+        struct changelog_rec rec, *recp;
+        int rc = 0;
+
+        if (!cp || (cp->magic != CHANGELOG_PRIV_MAGIC))
+                return -EINVAL;
+        if (rech == NULL)
+                return -EINVAL;
+
+readrec:
+        /* Read in the rec to get the namelen */
+        rc = read(cp->fd, &rec, sizeof(rec));
+        if (rc < 0)
+                return -errno;
+        if (rc == 0) {
+                if (cp->flags && CHANGELOG_FLAG_FOLLOW) {
+                        rc = pollwait(cp->fd);
+                        if (rc < 0)
+                                return rc;
+                        goto readrec;
+                }
+                return 1;
+        }
+
+        recp = malloc(sizeof(rec) + rec.cr_namelen);
+        if (recp == NULL)
+                return -ENOMEM;
+        memcpy(recp, &rec, sizeof(rec));
+        rc = read(cp->fd, recp->cr_name, rec.cr_namelen);
+        if (rc < 0) {
+                free(recp);
+                llapi_err(LLAPI_MSG_ERROR, "Can't read entire filename");
+                return -errno;
+        }
+
+        *rech = recp;
+        return 0;
+}
+
+/** Release the changelog record when done with it. */
+int llapi_changelog_free(struct changelog_rec **rech)
+{
+        if (*rech)
+                free(*rech);
+        *rech = NULL;
+        return 0;
 }
 
 int llapi_changelog_clear(const char *mdtname, const char *idstr,
@@ -2525,7 +2637,7 @@ int llapi_changelog_clear(const char *mdtname, const char *idstr,
                 fd = open(mdtname, O_RDONLY | O_DIRECTORY | O_NONBLOCK);
                 rc = fd < 0 ? -errno : 0;
         } else {
-                if (get_mdtname(mdtname, "%s%s", fsname) < 0)
+                if (get_mdtname((char *)mdtname, "%s%s", fsname) < 0)
                         return -EINVAL;
                 ptr = fsname + strlen(fsname) - 8;
                 *ptr = '\0';
index b1b64e4..c4ee8f8 100644 (file)
@@ -518,7 +518,7 @@ void lr_get_FID_PATH(char *mntpt, char *fidstr, char *buf, int bufsize)
 {
         /* Open-by-FID path is <mntpt>/.lustre/fid/[SEQ:OID:VER] */
         snprintf(buf, bufsize, "%s/%s/fid/%s", mntpt, dot_lustre_name,
-                 fidstr + 2);
+                 fidstr);
         return;
 }
 
@@ -610,8 +610,8 @@ int lr_add_pc(const char *pfid, const char *tfid, const char *name)
         p = calloc(1, sizeof(*p));
         if (!p)
                 return -ENOMEM;
-        strcpy(p->pc_log.pcl_pfid, pfid + 2);
-        strcpy(p->pc_log.pcl_tfid, tfid + 2);
+        strcpy(p->pc_log.pcl_pfid, pfid);
+        strcpy(p->pc_log.pcl_tfid, tfid);
         strcpy(p->pc_log.pcl_name, name);
 
         p->pc_next = parents;
@@ -664,8 +664,8 @@ int lr_remove_pc(const char *pfid, const char *tfid)
         struct lr_parent_child_list *curr, *prev;
 
         for (prev = curr = parents; curr; prev = curr, curr = curr->pc_next) {
-                if (strcmp(curr->pc_log.pcl_pfid, pfid + 2) == 0 &&
-                    strcmp(curr->pc_log.pcl_tfid, tfid + 2) == 0) {
+                if (strcmp(curr->pc_log.pcl_pfid, pfid) == 0 &&
+                    strcmp(curr->pc_log.pcl_tfid, tfid) == 0) {
                         if (curr == parents)
                                 parents = curr->pc_next;
                         else
@@ -684,7 +684,7 @@ int lr_mk_special(struct lr_info *info)
 
         snprintf(info->dest, PATH_MAX, "%s/%s/%s",
                 status->ls_targets[info->target_no], SPECIAL_DIR,
-                info->tfid + 2);
+                info->tfid);
 
         rc = lr_mkfile(info);
         if (rc)
@@ -715,7 +715,7 @@ int lr_rm_special(struct lr_info *info)
 
         snprintf(info->dest, PATH_MAX, "%s/%s/%s",
                  status->ls_targets[info->target_no], SPECIAL_DIR,
-                 info->tfid + 2);
+                 info->tfid);
         rc = lr_rmfile(info);
 
         if (rc)
@@ -733,7 +733,7 @@ int lr_create(struct lr_info *info)
         int mkspecial = 0;
 
         /* Is target FID present on the source? */
-        rc = lr_get_path(info, info->tfid + 3);
+        rc = lr_get_path(info, info->tfid);
         if (rc == -ENOENT) {
                 /* Source file has disappeared. Not an error. */
                 lr_debug(DINFO, "create: tfid %s not found on"
@@ -745,7 +745,7 @@ int lr_create(struct lr_info *info)
         strcpy(info->savedpath, info->path);
 
         /* Is parent FID present on the source */
-        rc = lr_get_path(info, info->pfid + 3);
+        rc = lr_get_path(info, info->pfid);
         if (rc == -ENOENT) {
                 lr_debug(DINFO, "create: pfid %s not found on source-fs\n",
                          info->tfid);
@@ -808,7 +808,7 @@ int lr_remove(struct lr_info *info)
                 if (!rc1)
                         continue;
 
-                rc1 = lr_get_path(info, info->pfid + 3);
+                rc1 = lr_get_path(info, info->pfid);
                 if (rc1 == -ENOENT) {
                         lr_debug(DINFO, "remove: pfid %s not found\n",
                                  info->pfid);
@@ -843,11 +843,11 @@ int lr_move(struct lr_info *info, struct lr_info *ext)
         int special_src = 0;
         int special_dest = 0;
 
-        rc_dest = lr_get_path(ext, ext->pfid + 3);
+        rc_dest = lr_get_path(ext, ext->pfid);
         if (rc_dest < 0 && rc_dest != -ENOENT)
                 return rc_dest;
 
-        rc_src = lr_get_path(info, info->pfid + 3);
+        rc_src = lr_get_path(info, info->pfid);
         if (rc_src < 0 && rc_src != -ENOENT)
                 return rc_src;
 
@@ -869,7 +869,7 @@ int lr_move(struct lr_info *info, struct lr_info *ext)
                 if (rc_dest == -ENOENT) {
                         snprintf(info->dest, PATH_MAX, "%s/%s/%s",
                                 status->ls_targets[info->target_no],
-                                SPECIAL_DIR, info->tfid + 2);
+                                SPECIAL_DIR, info->tfid);
                         special_dest = 1;
                 }
 
@@ -881,7 +881,7 @@ int lr_move(struct lr_info *info, struct lr_info *ext)
                                           errno == ENOENT)) {
                         snprintf(info->src, PATH_MAX, "%s/%s/%s",
                                 status->ls_targets[info->target_no],
-                                SPECIAL_DIR, info->tfid + 2);
+                                SPECIAL_DIR, info->tfid);
                         special_src = 1;
                 }
 
@@ -895,7 +895,7 @@ int lr_move(struct lr_info *info, struct lr_info *ext)
                 if (special_src) {
                         lr_remove_pc(info->pfid, info->tfid);
                         if (!special_dest)
-                                lr_cascade_move(info->tfid + 2, info->dest, info);
+                                lr_cascade_move(info->tfid, info->dest, info);
                 }
                 if (special_dest)
                         lr_add_pc(ext->pfid, info->tfid, ext->name);
@@ -932,7 +932,7 @@ int lr_link(struct lr_info *info)
                 /* Search through the hardlinks to get the src and dest */
                 for (i = 0; i < st.st_nlink && (info->src[0] == 0 ||
                                                 info->dest[0] == 0); i++) {
-                        rc1 = lr_get_path_ln(info, info->tfid + 3, i);
+                        rc1 = lr_get_path_ln(info, info->tfid, i);
                         lr_debug(rc1 ? 0:DTRACE, "\tfid2path %s, %s, %d rc=%d\n",
                                  info->path, info->name, i, rc1);
                         if (rc1)
@@ -964,11 +964,11 @@ int lr_link(struct lr_info *info)
                 if (info->src[0] == 0)
                         snprintf(info->src, PATH_MAX, "%s/%s/%s",
                                 status->ls_targets[info->target_no],
-                                SPECIAL_DIR, info->tfid + 2);
+                                SPECIAL_DIR, info->tfid);
                 else if (info->dest[0] == 0)
                         snprintf(info->dest, PATH_MAX, "%s/%s/%s",
                                 status->ls_targets[info->target_no],
-                                SPECIAL_DIR, info->tfid + 2);
+                                SPECIAL_DIR, info->tfid);
 
                 rc1 = link(info->src, info->dest);
                 lr_debug(rc1?0:DINFO, "link: %s [to] %s; rc1=%d %s\n",
@@ -988,7 +988,7 @@ int lr_setattr(struct lr_info *info)
 
         lr_get_FID_PATH(status->ls_source, info->tfid, info->src, PATH_MAX);
 
-        rc = lr_get_path(info, info->tfid + 3);
+        rc = lr_get_path(info, info->tfid);
         if (rc == -ENOENT)
                 lr_debug(DINFO, "setattr: %s not present on source-fs\n",
                          info->src);
@@ -1019,7 +1019,7 @@ int lr_setxattr(struct lr_info *info)
 
         lr_get_FID_PATH(status->ls_source, info->tfid, info->src, PATH_MAX);
 
-        rc = lr_get_path(info, info->tfid + 3);
+        rc = lr_get_path(info, info->tfid);
         if (rc == -ENOENT)
                 lr_debug(DINFO, "setxattr: %s not present on source-fs\n",
                          info->src);
@@ -1043,51 +1043,23 @@ int lr_setxattr(struct lr_info *info)
 }
 
 /* Parse a line of changelog entry */
-int lr_parse_line(struct lr_info *info, FILE *fp)
+int lr_parse_line(void *priv, struct lr_info *info)
 {
-        unsigned long long time;
-        unsigned int flags;
-        char typestr[TYPE_STR_LEN];
-        char line[PATH_MAX];
-        char *str;
-        int i;
+        struct changelog_rec *rec;
 
-        if (fgets(line, sizeof(line), fp) != NULL) {
-                if (sscanf(line, "%llu %s %llu %x %s %s",
-                           &info->recno, typestr, &time,
-                           &flags, info->tfid, info->pfid) < 4) {
-                        fprintf(stderr, "error: unexpected changelog record "
-                                "format - %s\n", line);
-                        return -1;
-                }
-                typestr[2] = '\0';
-                info->type = atoi(typestr);
-
-                /* The filename could have spaces in it. scanf would
-                   have ignored it. Parse for the complete
-                   filename. */
-                if (info->type != CL_SETATTR &&
-                    info->type != CL_XATTR &&
-                    info->type != CL_MARK) {
-                        for (i = 0, str = line; str != NULL && i <= 5;
-                             i++, str++){
-                                str = strchr(str, ' ');
-                        }
-                        if (str) {
-                                strncpy(info->name, str, PATH_MAX);
-                                str = strchr(info->name, '\n');
-                                if (str)
-                                        str[0] = '\0';
-                        } else {
-                                fprintf(stderr, "error: unexpected changelog "
-                                        "record format - %s\n", line);
-                                return -1;
-                        }
-                }
-                rec_count++;
-        } else {
+        if (llapi_changelog_recv(priv, &rec) != 0)
                 return -1;
-        }
+
+        info->recno = rec->cr_index;
+        info->type = rec->cr_type;
+        sprintf(info->tfid, DFID, PFID(&rec->cr_tfid));
+        sprintf(info->pfid, DFID, PFID(&rec->cr_pfid));
+        strncpy(info->name, rec->cr_name, rec->cr_namelen);
+        info->name[rec->cr_namelen] = '\0';
+
+        llapi_changelog_free(&rec);
+
+        rec_count++;
         return 0;
 }
 
@@ -1352,22 +1324,18 @@ void lr_print_status(struct lr_info *info)
                 printf("Using rsync: %s (%s)\n", rsync, rsync_ver);
 }
 
-DECLARE_CHANGELOG_NAMES;
-
 void lr_print_failure(struct lr_info *info, int rc)
 {
         fprintf(stderr, "Replication of operation failed(%d):"
-                " %lld %s (%d) %s %s %s\n", rc, info->recno, 
-                changelog_str[info->type], info->type, info->tfid,
+                " %lld %s (%d) %s %s %s\n", rc, info->recno,
+                changelog_type2str(info->type), info->type, info->tfid,
                 info->pfid, info->name);
 }
 
 /* Replicate filesystem operations from src_path to target_path */
 int lr_replicate()
 {
-        int fd;
-        FILE *fp;
-        long long startrec;
+        void *changelog_priv;
         struct lr_info *info;
         struct lr_info *ext;
         time_t start;
@@ -1419,25 +1387,20 @@ int lr_replicate()
         lr_print_status(info);
 
         /* Open changelogs for consumption*/
-        startrec = status->ls_last_recno;
-        fd = llapi_changelog_open(status->ls_source_fs, startrec);
-        if (fd < 0) {
+        rc = llapi_changelog_start(&changelog_priv, 0, status->ls_source_fs,
+                                   status->ls_last_recno);
+        if (rc < 0) {
                 fprintf(stderr, "Error opening changelog file for fs %s.\n",
                         status->ls_source_fs);
-                return fd;
-        }
-        if ((fp = fdopen(fd, "r")) == NULL) {
-                fprintf(stderr, "Error: fdopen failed.");
-                close(fd);
-                return -errno;
+                return rc;
         }
 
-        while (!quit && lr_parse_line(info, fp) == 0) {
+        while (!quit && lr_parse_line(changelog_priv, info) == 0) {
                 rc = 0;
                 if (info->type == CL_RENAME)
                         /* Rename operations have an additional changelog
                            record of information. */
-                        lr_parse_line(ext, fp);
+                        lr_parse_line(changelog_priv, ext);
 
                 if (dryrun)
                         continue;
@@ -1488,6 +1451,8 @@ int lr_replicate()
                 }
         }
 
+        llapi_changelog_fini(&changelog_priv);
+
         if (errors || verbose)
                 printf("Errors: %d\n", errors);
 
@@ -1499,9 +1464,6 @@ int lr_replicate()
                 printf("Changelog records consumed: %lld\n", rec_count);
         }
 
-        close(fd);
-        fclose(fp);
-
         return 0;
 }
 
index c68650c..99543bd 100644 (file)
@@ -956,19 +956,27 @@ check_llog_size_change_rec(void)
 }
 
 static void
+check_changelog_rec(void)
+{
+        BLANK_LINE();
+        CHECK_STRUCT(changelog_rec);
+        CHECK_MEMBER(changelog_rec, cr_namelen);
+        CHECK_MEMBER(changelog_rec, cr_flags);
+        CHECK_MEMBER(changelog_rec, cr_type);
+        CHECK_MEMBER(changelog_rec, cr_index);
+        CHECK_MEMBER(changelog_rec, cr_prev);
+        CHECK_MEMBER(changelog_rec, cr_time);
+        CHECK_MEMBER(changelog_rec, cr_tfid);
+        CHECK_MEMBER(changelog_rec, cr_pfid);
+}
+
+static void
 check_llog_changelog_rec(void)
 {
         BLANK_LINE();
         CHECK_STRUCT(llog_changelog_rec);
         CHECK_MEMBER(llog_changelog_rec, cr_hdr);
-        CHECK_MEMBER(llog_changelog_rec, cr_flags);
-        CHECK_MEMBER(llog_changelog_rec, cr_namelen);
-        CHECK_MEMBER(llog_changelog_rec, cr_type);
-        CHECK_MEMBER(llog_changelog_rec, cr_index);
-        CHECK_MEMBER(llog_changelog_rec, cr_prev);
-        CHECK_MEMBER(llog_changelog_rec, cr_time);
-        CHECK_MEMBER(llog_changelog_rec, cr_tfid);
-        CHECK_MEMBER(llog_changelog_rec, cr_pfid);
+        CHECK_MEMBER(llog_changelog_rec, cr);
         CHECK_MEMBER(llog_changelog_rec, cr_tail);
 }
 
@@ -1465,6 +1473,7 @@ main(int argc, char **argv)
         check_llog_setattr_rec();
         check_llog_setattr64_rec();
         check_llog_size_change_rec();
+        check_changelog_rec();
         check_llog_changelog_rec();
         check_llog_gen();
         check_llog_gen_rec();
index 697f917..bebd1f4 100644 (file)
@@ -1975,6 +1975,42 @@ void lustre_assert_wire_constants(void)
         LASSERTF((int)sizeof(((struct llog_size_change_rec *)0)->lsc_tail) == 8, " found %lld\n",
                  (long long)(int)sizeof(((struct llog_size_change_rec *)0)->lsc_tail));
 
+        /* Checks for struct changelog_rec */
+        LASSERTF((int)sizeof(struct changelog_rec) == 64, " found %lld\n",
+                 (long long)(int)sizeof(struct changelog_rec));
+        LASSERTF((int)offsetof(struct changelog_rec, cr_namelen) == 0, " found %lld\n",
+                 (long long)(int)offsetof(struct changelog_rec, cr_namelen));
+        LASSERTF((int)sizeof(((struct changelog_rec *)0)->cr_namelen) == 2, " found %lld\n",
+                 (long long)(int)sizeof(((struct changelog_rec *)0)->cr_namelen));
+        LASSERTF((int)offsetof(struct changelog_rec, cr_flags) == 2, " found %lld\n",
+                 (long long)(int)offsetof(struct changelog_rec, cr_flags));
+        LASSERTF((int)sizeof(((struct changelog_rec *)0)->cr_flags) == 2, " found %lld\n",
+                 (long long)(int)sizeof(((struct changelog_rec *)0)->cr_flags));
+        LASSERTF((int)offsetof(struct changelog_rec, cr_type) == 4, " found %lld\n",
+                 (long long)(int)offsetof(struct changelog_rec, cr_type));
+        LASSERTF((int)sizeof(((struct changelog_rec *)0)->cr_type) == 4, " found %lld\n",
+                 (long long)(int)sizeof(((struct changelog_rec *)0)->cr_type));
+        LASSERTF((int)offsetof(struct changelog_rec, cr_index) == 8, " found %lld\n",
+                 (long long)(int)offsetof(struct changelog_rec, cr_index));
+        LASSERTF((int)sizeof(((struct changelog_rec *)0)->cr_index) == 8, " found %lld\n",
+                 (long long)(int)sizeof(((struct changelog_rec *)0)->cr_index));
+        LASSERTF((int)offsetof(struct changelog_rec, cr_prev) == 16, " found %lld\n",
+                 (long long)(int)offsetof(struct changelog_rec, cr_prev));
+        LASSERTF((int)sizeof(((struct changelog_rec *)0)->cr_prev) == 8, " found %lld\n",
+                 (long long)(int)sizeof(((struct changelog_rec *)0)->cr_prev));
+        LASSERTF((int)offsetof(struct changelog_rec, cr_time) == 24, " found %lld\n",
+                 (long long)(int)offsetof(struct changelog_rec, cr_time));
+        LASSERTF((int)sizeof(((struct changelog_rec *)0)->cr_time) == 8, " found %lld\n",
+                 (long long)(int)sizeof(((struct changelog_rec *)0)->cr_time));
+        LASSERTF((int)offsetof(struct changelog_rec, cr_tfid) == 32, " found %lld\n",
+                 (long long)(int)offsetof(struct changelog_rec, cr_tfid));
+        LASSERTF((int)sizeof(((struct changelog_rec *)0)->cr_tfid) == 16, " found %lld\n",
+                 (long long)(int)sizeof(((struct changelog_rec *)0)->cr_tfid));
+        LASSERTF((int)offsetof(struct changelog_rec, cr_pfid) == 48, " found %lld\n",
+                 (long long)(int)offsetof(struct changelog_rec, cr_pfid));
+        LASSERTF((int)sizeof(((struct changelog_rec *)0)->cr_pfid) == 16, " found %lld\n",
+                 (long long)(int)sizeof(((struct changelog_rec *)0)->cr_pfid));
+
         /* Checks for struct llog_changelog_rec */
         LASSERTF((int)sizeof(struct llog_changelog_rec) == 88, " found %lld\n",
                  (long long)(int)sizeof(struct llog_changelog_rec));
@@ -1982,38 +2018,10 @@ void lustre_assert_wire_constants(void)
                  (long long)(int)offsetof(struct llog_changelog_rec, cr_hdr));
         LASSERTF((int)sizeof(((struct llog_changelog_rec *)0)->cr_hdr) == 16, " found %lld\n",
                  (long long)(int)sizeof(((struct llog_changelog_rec *)0)->cr_hdr));
-        LASSERTF((int)offsetof(struct llog_changelog_rec, cr_flags) == 16, " found %lld\n",
-                 (long long)(int)offsetof(struct llog_changelog_rec, cr_flags));
-        LASSERTF((int)sizeof(((struct llog_changelog_rec *)0)->cr_flags) == 2, " found %lld\n",
-                 (long long)(int)sizeof(((struct llog_changelog_rec *)0)->cr_flags));
-        LASSERTF((int)offsetof(struct llog_changelog_rec, cr_namelen) == 18, " found %lld\n",
-                 (long long)(int)offsetof(struct llog_changelog_rec, cr_namelen));
-        LASSERTF((int)sizeof(((struct llog_changelog_rec *)0)->cr_namelen) == 2, " found %lld\n",
-                 (long long)(int)sizeof(((struct llog_changelog_rec *)0)->cr_namelen));
-        LASSERTF((int)offsetof(struct llog_changelog_rec, cr_type) == 20, " found %lld\n",
-                 (long long)(int)offsetof(struct llog_changelog_rec, cr_type));
-        LASSERTF((int)sizeof(((struct llog_changelog_rec *)0)->cr_type) == 4, " found %lld\n",
-                 (long long)(int)sizeof(((struct llog_changelog_rec *)0)->cr_type));
-        LASSERTF((int)offsetof(struct llog_changelog_rec, cr_index) == 24, " found %lld\n",
-                 (long long)(int)offsetof(struct llog_changelog_rec, cr_index));
-        LASSERTF((int)sizeof(((struct llog_changelog_rec *)0)->cr_index) == 8, " found %lld\n",
-                 (long long)(int)sizeof(((struct llog_changelog_rec *)0)->cr_index));
-        LASSERTF((int)offsetof(struct llog_changelog_rec, cr_prev) == 32, " found %lld\n",
-                 (long long)(int)offsetof(struct llog_changelog_rec, cr_prev));
-        LASSERTF((int)sizeof(((struct llog_changelog_rec *)0)->cr_prev) == 8, " found %lld\n",
-                 (long long)(int)sizeof(((struct llog_changelog_rec *)0)->cr_prev));
-        LASSERTF((int)offsetof(struct llog_changelog_rec, cr_time) == 40, " found %lld\n",
-                 (long long)(int)offsetof(struct llog_changelog_rec, cr_time));
-        LASSERTF((int)sizeof(((struct llog_changelog_rec *)0)->cr_time) == 8, " found %lld\n",
-                 (long long)(int)sizeof(((struct llog_changelog_rec *)0)->cr_time));
-        LASSERTF((int)offsetof(struct llog_changelog_rec, cr_tfid) == 48, " found %lld\n",
-                 (long long)(int)offsetof(struct llog_changelog_rec, cr_tfid));
-        LASSERTF((int)sizeof(((struct llog_changelog_rec *)0)->cr_tfid) == 16, " found %lld\n",
-                 (long long)(int)sizeof(((struct llog_changelog_rec *)0)->cr_tfid));
-        LASSERTF((int)offsetof(struct llog_changelog_rec, cr_pfid) == 64, " found %lld\n",
-                 (long long)(int)offsetof(struct llog_changelog_rec, cr_pfid));
-        LASSERTF((int)sizeof(((struct llog_changelog_rec *)0)->cr_pfid) == 16, " found %lld\n",
-                 (long long)(int)sizeof(((struct llog_changelog_rec *)0)->cr_pfid));
+        LASSERTF((int)offsetof(struct llog_changelog_rec, cr) == 16, " found %lld\n",
+                 (long long)(int)offsetof(struct llog_changelog_rec, cr));
+        LASSERTF((int)sizeof(((struct llog_changelog_rec *)0)->cr) == 64, " found %lld\n",
+                 (long long)(int)sizeof(((struct llog_changelog_rec *)0)->cr));
         LASSERTF((int)offsetof(struct llog_changelog_rec, cr_tail) == 80, " found %lld\n",
                  (long long)(int)offsetof(struct llog_changelog_rec, cr_tail));
         LASSERTF((int)sizeof(((struct llog_changelog_rec *)0)->cr_tail) == 8, " found %lld\n",