Whamcloud - gitweb
LU-9727 lustre: implement CL_OPEN for Changelogs 14/28214/23
authorSebastien Buisson <sbuisson@ddn.com>
Tue, 25 Jul 2017 13:45:58 +0000 (09:45 -0400)
committerOleg Drokin <oleg.drokin@intel.com>
Tue, 6 Feb 2018 04:26:33 +0000 (04:26 +0000)
Record OPEN events in Changelogs, and add a new changelog
extension named changelog_ext_openmode to hold open mode.
An OPEN changlog entry is in the form:
7 10OPEN  13:38:51.510728296 2017.07.25 0x242
t=[0x200000401:0x2:0x0] ef=0x7 u=500:500 nid=10.128.11.159@tcp m=-w-
By default, disable recording of OPEN events in Changelogs.
Note that CREAT are still recorded even if OPEN are disabled.

Signed-off-by: Sebastien Buisson <sbuisson@ddn.com>
Change-Id: I72c479938ab4782523f1b16aef19fbbc96f43c7f
Reviewed-on: https://review.whamcloud.com/28214
Tested-by: Jenkins
Reviewed-by: Andreas Dilger <andreas.dilger@intel.com>
Tested-by: Maloo <hpdd-maloo@intel.com>
Reviewed-by: Li Xi <lixi@ddn.com>
Reviewed-by: Oleg Drokin <oleg.drokin@intel.com>
lustre/include/uapi/linux/lustre/lustre_idl.h
lustre/include/uapi/linux/lustre/lustre_user.h
lustre/mdc/mdc_changelog.c
lustre/mdd/mdd_dir.c
lustre/mdd/mdd_internal.h
lustre/mdd/mdd_object.c
lustre/obdclass/llog_osd.c
lustre/utils/lfs.c
lustre/utils/liblustreapi_chlg.c
lustre/utils/lustre_rsync.c

index c3ec65b..3a65228 100644 (file)
@@ -1824,58 +1824,6 @@ struct mdt_rec_setattr {
 #define MDS_ATTR_BLOCKS     0x8000ULL /* = 32768 */
 #define MDS_ATTR_PROJID            0x10000ULL  /* = 65536 */
 
-#ifndef FMODE_READ
-#define FMODE_READ               00000001
-#define FMODE_WRITE              00000002
-#endif
-
-#define MDS_FMODE_CLOSED         00000000
-#define MDS_FMODE_EXEC           00000004
-/*     MDS_FMODE_EPOCH          01000000 obsolete since 2.8.0 */
-/*     MDS_FMODE_TRUNC          02000000 obsolete since 2.8.0 */
-/*     MDS_FMODE_SOM            04000000 obsolete since 2.8.0 */
-
-#define MDS_OPEN_CREATED         00000010
-#define MDS_OPEN_CROSS           00000020
-
-#define MDS_OPEN_CREAT           00000100
-#define MDS_OPEN_EXCL            00000200
-#define MDS_OPEN_TRUNC           00001000
-#define MDS_OPEN_APPEND          00002000
-#define MDS_OPEN_SYNC            00010000
-#define MDS_OPEN_DIRECTORY       00200000
-
-#define MDS_OPEN_BY_FID        040000000 /* open_by_fid for known object */
-#define MDS_OPEN_DELAY_CREATE  0100000000 /* delay initial object create */
-#define MDS_OPEN_OWNEROVERRIDE 0200000000 /* NFSD rw-reopen ro file for owner */
-#define MDS_OPEN_JOIN_FILE     0400000000 /* open for join file.
-                                           * We do not support JOIN FILE
-                                           * anymore, reserve this flags
-                                           * just for preventing such bit
-                                           * to be reused. */
-
-#define MDS_OPEN_LOCK         04000000000 /* This open requires open lock */
-#define MDS_OPEN_HAS_EA      010000000000 /* specify object create pattern */
-#define MDS_OPEN_HAS_OBJS    020000000000 /* Just set the EA the obj exist */
-#define MDS_OPEN_NORESTORE  0100000000000ULL /* Do not restore file at open */
-#define MDS_OPEN_NEWSTRIPE  0200000000000ULL /* New stripe needed (restripe or
-                                              * hsm restore) */
-#define MDS_OPEN_VOLATILE   0400000000000ULL /* File is volatile = created
-                                               unlinked */
-#define MDS_OPEN_LEASE    01000000000000ULL /* Open the file and grant lease
-                                             * delegation, succeed if it's not
-                                             * being opened with conflict mode.
-                                             */
-#define MDS_OPEN_RELEASE   02000000000000ULL /* Open the file for HSM release */
-
-#define MDS_OPEN_RESYNC    04000000000000ULL /* FLR: file resync */
-
-/* lustre internal open flags, which should not be set from user space */
-#define MDS_OPEN_FL_INTERNAL (MDS_OPEN_HAS_EA | MDS_OPEN_HAS_OBJS |    \
-                             MDS_OPEN_OWNEROVERRIDE | MDS_OPEN_LOCK |  \
-                             MDS_OPEN_BY_FID | MDS_OPEN_LEASE |        \
-                             MDS_OPEN_RELEASE | MDS_OPEN_RESYNC)
-
 enum mds_op_bias {
        MDS_CHECK_SPLIT         = 1 << 0,
        MDS_CROSS_REF           = 1 << 1,
@@ -2749,8 +2697,11 @@ struct llog_size_change_rec {
 #define CHANGELOG_ALLMASK 0XFFFFFFFF
 /** default \a changelog_rec_type mask. Allow all of them, except
  * CL_ATIME since it can really be time consuming, and not necessary
- * under normal use. */
-#define CHANGELOG_DEFMASK (CHANGELOG_ALLMASK & ~(1 << CL_ATIME))
+ * under normal use.
+ * Remove also CL_OPEN from default list as it can be costly and only necessary
+ * for audit purpose.
+ */
+#define CHANGELOG_DEFMASK (CHANGELOG_ALLMASK & ~(1 << CL_ATIME | 1 << CL_OPEN))
 
 /* changelog llog name, needed by client replicators */
 #define CHANGELOG_CATALOG "changelog_catalog"
@@ -2844,13 +2795,15 @@ enum llog_flag {
        LLOG_F_EXT_EXTRA_FLAGS  = 0x20,
        LLOG_F_EXT_X_UIDGID     = 0x40,
        LLOG_F_EXT_X_NID        = 0x80,
+       LLOG_F_EXT_X_OMODE      = 0x100,
 
        /* Note: Flags covered by LLOG_F_EXT_MASK will be inherited from
         * catlog to plain log, so do not add LLOG_F_IS_FIXSIZE here,
         * because the catlog record is usually fixed size, but its plain
         * log record can be variable */
        LLOG_F_EXT_MASK = LLOG_F_EXT_JOBID | LLOG_F_EXT_EXTRA_FLAGS |
-                         LLOG_F_EXT_X_UIDGID | LLOG_F_EXT_X_NID,
+                         LLOG_F_EXT_X_UIDGID | LLOG_F_EXT_X_NID |
+                         LLOG_F_EXT_X_OMODE,
 };
 
 /* On-disk header structure of each log object, stored in little endian order */
index 0fdc9d1..d62a908 100644 (file)
@@ -982,6 +982,59 @@ enum la_valid {
        LA_REMOTE_ATTR_SET = (LA_UID | LA_GID | LA_PROJID | LA_LAYOUT_VERSION)
 };
 
+#ifndef FMODE_READ
+#define FMODE_READ               00000001
+#define FMODE_WRITE              00000002
+#endif
+
+#define MDS_FMODE_CLOSED         00000000
+#define MDS_FMODE_EXEC           00000004
+/*     MDS_FMODE_EPOCH          01000000 obsolete since 2.8.0 */
+/*     MDS_FMODE_TRUNC          02000000 obsolete since 2.8.0 */
+/*     MDS_FMODE_SOM            04000000 obsolete since 2.8.0 */
+
+#define MDS_OPEN_CREATED         00000010
+#define MDS_OPEN_CROSS           00000020
+
+#define MDS_OPEN_CREAT           00000100
+#define MDS_OPEN_EXCL            00000200
+#define MDS_OPEN_TRUNC           00001000
+#define MDS_OPEN_APPEND          00002000
+#define MDS_OPEN_SYNC            00010000
+#define MDS_OPEN_DIRECTORY       00200000
+
+#define MDS_OPEN_BY_FID                040000000 /* open_by_fid for known object */
+#define MDS_OPEN_DELAY_CREATE  0100000000 /* delay initial object create */
+#define MDS_OPEN_OWNEROVERRIDE 0200000000 /* NFSD rw-reopen ro file for owner */
+#define MDS_OPEN_JOIN_FILE     0400000000 /* open for join file.
+                                          * We do not support JOIN FILE
+                                          * anymore, reserve this flags
+                                          * just for preventing such bit
+                                          * to be reused. */
+
+#define MDS_OPEN_LOCK         04000000000 /* This open requires open lock */
+#define MDS_OPEN_HAS_EA      010000000000 /* specify object create pattern */
+#define MDS_OPEN_HAS_OBJS    020000000000 /* Just set the EA the obj exist */
+#define MDS_OPEN_NORESTORE  0100000000000ULL /* Do not restore file at open */
+#define MDS_OPEN_NEWSTRIPE  0200000000000ULL /* New stripe needed (restripe or
+                                             * hsm restore) */
+#define MDS_OPEN_VOLATILE   0400000000000ULL /* File is volatile = created
+                                               unlinked */
+#define MDS_OPEN_LEASE    01000000000000ULL /* Open the file and grant lease
+                                             * delegation, succeed if it's not
+                                             * being opened with conflict mode.
+                                             */
+#define MDS_OPEN_RELEASE   02000000000000ULL /* Open the file for HSM release */
+
+#define MDS_OPEN_RESYNC    04000000000000ULL /* FLR: file resync */
+
+/* lustre internal open flags, which should not be set from user space */
+#define MDS_OPEN_FL_INTERNAL (MDS_OPEN_HAS_EA | MDS_OPEN_HAS_OBJS |    \
+                             MDS_OPEN_OWNEROVERRIDE | MDS_OPEN_LOCK |  \
+                             MDS_OPEN_BY_FID | MDS_OPEN_LEASE |        \
+                             MDS_OPEN_RELEASE | MDS_OPEN_RESYNC)
+
+
 /********* Changelogs **********/
 /** Changelog record types */
 enum changelog_rec_type {
@@ -1122,7 +1175,8 @@ enum changelog_rec_extra_flags {
        CLFE_INVALID    = 0,
        CLFE_UIDGID     = 0x0001,
        CLFE_NID        = 0x0002,
-       CLFE_SUPPORTED  = CLFE_UIDGID | CLFE_NID
+       CLFE_OPEN       = 0x0004,
+       CLFE_SUPPORTED  = CLFE_UIDGID | CLFE_NID | CLFE_OPEN
 };
 
 enum changelog_send_flag {
@@ -1143,6 +1197,8 @@ enum changelog_send_extra_flag {
        CHANGELOG_EXTRA_FLAG_UIDGID = 0x01,
        /* Pack nid into the changelog record */
        CHANGELOG_EXTRA_FLAG_NID    = 0x02,
+       /* Pack open mode into the changelog record */
+       CHANGELOG_EXTRA_FLAG_OMODE  = 0x04,
 };
 
 #define CR_MAXSIZE cfs_size_round(2 * NAME_MAX + 2 + \
@@ -1204,6 +1260,11 @@ struct changelog_ext_nid {
        __u32 padding;
 };
 
+/* Changelog extra extension to include OPEN mode. */
+struct changelog_ext_openmode {
+       __u32 cr_openflags;
+};
+
 static inline struct changelog_ext_extra_flags *changelog_rec_extra_flags(
        const struct changelog_rec *rec);
 
@@ -1224,6 +1285,8 @@ static inline size_t changelog_rec_offset(enum changelog_rec_flags crf,
                        size += sizeof(struct changelog_ext_uidgid);
                if (cref & CLFE_NID)
                        size += sizeof(struct changelog_ext_nid);
+               if (cref & CLFE_OPEN)
+                       size += sizeof(struct changelog_ext_openmode);
        }
 
        return size;
@@ -1308,6 +1371,23 @@ struct changelog_ext_nid *changelog_rec_nid(const struct changelog_rec *rec)
                                            changelog_rec_offset(crf, cref));
 }
 
+/* The OPEN mode is the third extra extension */
+static inline
+struct changelog_ext_openmode *changelog_rec_openmode(
+       const struct changelog_rec *rec)
+{
+       enum changelog_rec_flags crf = rec->cr_flags &
+               (CLF_VERSION | CLF_RENAME | CLF_JOBID | CLF_EXTRA_FLAGS);
+       enum changelog_rec_extra_flags cref = CLFE_INVALID;
+
+       if (rec->cr_flags & CLF_EXTRA_FLAGS)
+               cref = changelog_rec_extra_flags(rec)->cr_extra_flags &
+                      (CLFE_UIDGID | CLFE_NID);
+
+       return (struct changelog_ext_openmode *)((char *)rec +
+                                              changelog_rec_offset(crf, cref));
+}
+
 /* The name follows the rename, jobid  and extra flags extns, if present */
 static inline char *changelog_rec_name(const struct changelog_rec *rec)
 {
@@ -1357,6 +1437,7 @@ static inline void changelog_remap_rec(struct changelog_rec *rec,
                                       enum changelog_rec_flags crf_wanted,
                                       enum changelog_rec_extra_flags cref_want)
 {
+       char *omd_mov = NULL;
        char *nid_mov = NULL;
        char *uidgid_mov = NULL;
        char *ef_mov;
@@ -1382,13 +1463,18 @@ static inline void changelog_remap_rec(struct changelog_rec *rec,
 
        /* Locations of extensions in the remapped record */
        if (rec->cr_flags & CLF_EXTRA_FLAGS) {
+               omd_mov = (char *)rec +
+                       changelog_rec_offset(crf_wanted & CLF_SUPPORTED,
+                                            cref_want & ~CLFE_OPEN);
                nid_mov = (char *)rec +
                        changelog_rec_offset(crf_wanted & CLF_SUPPORTED,
-                                            cref_want & ~CLFE_NID);
+                                            cref_want & ~(CLFE_NID |
+                                                          CLFE_OPEN));
                uidgid_mov = (char *)rec +
                        changelog_rec_offset(crf_wanted & CLF_SUPPORTED,
                                             cref_want & ~(CLFE_UIDGID |
-                                                          CLFE_NID));
+                                                          CLFE_NID |
+                                                          CLFE_OPEN));
                cref = changelog_rec_extra_flags(rec)->cr_extra_flags;
        }
 
@@ -1409,6 +1495,10 @@ static inline void changelog_remap_rec(struct changelog_rec *rec,
        /* Move the extension fields to the desired positions */
        if ((crf_wanted & CLF_EXTRA_FLAGS) &&
            (rec->cr_flags & CLF_EXTRA_FLAGS)) {
+               if ((cref_want & CLFE_OPEN) && (cref & CLFE_OPEN))
+                       memmove(omd_mov, changelog_rec_openmode(rec),
+                               sizeof(struct changelog_ext_openmode));
+
                if ((cref_want & CLFE_NID) && (cref & CLFE_NID))
                        memmove(nid_mov, changelog_rec_nid(rec),
                                sizeof(struct changelog_ext_nid));
@@ -1430,6 +1520,10 @@ static inline void changelog_remap_rec(struct changelog_rec *rec,
                        sizeof(struct changelog_ext_rename));
 
        /* Clear newly added fields */
+       if (omd_mov && (cref_want & CLFE_OPEN) &&
+           !(cref & CLFE_OPEN))
+               memset(omd_mov, 0, sizeof(struct changelog_ext_openmode));
+
        if (nid_mov && (cref_want & CLFE_NID) &&
            !(cref & CLFE_NID))
                memset(nid_mov, 0, sizeof(struct changelog_ext_nid));
index 252592c..96b9dee 100644 (file)
@@ -221,7 +221,8 @@ static int chlg_load(void *args)
                              LLOG_F_EXT_JOBID |
                              LLOG_F_EXT_EXTRA_FLAGS |
                              LLOG_F_EXT_X_UIDGID |
-                             LLOG_F_EXT_X_NID,
+                             LLOG_F_EXT_X_NID |
+                             LLOG_F_EXT_X_OMODE,
                              NULL);
        if (rc) {
                CERROR("%s: fail to init llog handle: rc = %d\n",
index 09d41d6..88ee6a0 100644 (file)
@@ -1062,6 +1062,13 @@ void mdd_changelog_rec_extra_nid(struct changelog_rec *rec,
        clnid->cr_nid = nid;
 }
 
+void mdd_changelog_rec_extra_omode(struct changelog_rec *rec, int flags)
+{
+       struct changelog_ext_openmode *omd = changelog_rec_openmode(rec);
+
+       omd->cr_openflags = (__u32)flags;
+}
+
 /** Store a namespace change changelog record
  * If this fails, we must fail the whole transaction; we don't
  * want the change to commit without the log entry.
index bc27a30..d704d2f 100644 (file)
@@ -310,6 +310,7 @@ void mdd_changelog_rec_extra_uidgid(struct changelog_rec *rec,
                                    __u64 uid, __u64 gid);
 void mdd_changelog_rec_extra_nid(struct changelog_rec *rec,
                                 lnet_nid_t nid);
+void mdd_changelog_rec_extra_omode(struct changelog_rec *rec, int flags);
 int mdd_changelog_store(const struct lu_env *env, struct mdd_device *mdd,
                        struct llog_changelog_rec *rec, struct thandle *th);
 int mdd_changelog_data_store(const struct lu_env *env, struct mdd_device *mdd,
index 05b67e4..fc31d01 100644 (file)
@@ -654,6 +654,8 @@ static int mdd_changelog_data_store_by_fid(const struct lu_env *env,
                xflags |= CLFE_UIDGID;
                xflags |= CLFE_NID;
        }
+       if (type == CL_OPEN)
+               xflags |= CLFE_OPEN;
 
        reclen = llog_data_len(LLOG_CHANGELOG_HDR_SZ +
                               changelog_rec_offset(flags & CLF_SUPPORTED,
@@ -679,10 +681,11 @@ static int mdd_changelog_data_store_by_fid(const struct lu_env *env,
                                                       uc->uc_uid, uc->uc_gid);
                if (xflags & CLFE_NID)
                        mdd_changelog_rec_extra_nid(&rec->cr, uc->uc_nid);
+               if (xflags & CLFE_OPEN)
+                       mdd_changelog_rec_extra_omode(&rec->cr, flags);
        }
 
        rc = mdd_changelog_store(env, mdd, rec, handle);
-
        RETURN(rc);
 }
 
@@ -2352,6 +2355,7 @@ static int mdd_open(const struct lu_env *env, struct md_object *obj,
                    int flags)
 {
        struct mdd_object *mdd_obj = md2mdd_obj(obj);
+       struct md_device *md_dev = lu2md_dev(mdd2lu_dev(mdo2mdd(obj)));
        struct lu_attr *attr = MDD_ENV_VAR(env, cattr);
        int rc = 0;
 
@@ -2366,6 +2370,9 @@ static int mdd_open(const struct lu_env *env, struct md_object *obj,
                GOTO(out, rc);
 
        mdd_obj->mod_count++;
+
+       mdd_changelog(env, CL_OPEN, flags, md_dev, mdo2fid(mdd_obj));
+
        EXIT;
 out:
        mdd_write_unlock(env, mdd_obj);
index c853433..a374221 100644 (file)
@@ -793,6 +793,8 @@ static void changelog_block_trim_ext(struct llog_rec_hdr *hdr,
        enum changelog_rec_flags flags = CLF_SUPPORTED;
        enum changelog_rec_extra_flags extra_flags = CLFE_SUPPORTED;
 
+       if (!(loghandle->lgh_hdr->llh_flags & LLOG_F_EXT_X_OMODE))
+               extra_flags &= ~CLFE_OPEN;
        if (!(loghandle->lgh_hdr->llh_flags & LLOG_F_EXT_X_NID))
                extra_flags &= ~CLFE_NID;
        if (!(loghandle->lgh_hdr->llh_flags & LLOG_F_EXT_X_UIDGID))
index 98d78e4..7290411 100644 (file)
@@ -5603,7 +5603,8 @@ static int lfs_changelog(int argc, char **argv)
 
        rc = llapi_changelog_set_xflags(changelog_priv,
                                        CHANGELOG_EXTRA_FLAG_UIDGID |
-                                       CHANGELOG_EXTRA_FLAG_NID);
+                                       CHANGELOG_EXTRA_FLAG_NID |
+                                       CHANGELOG_EXTRA_FLAG_OMODE);
        if (rc < 0) {
                fprintf(stderr, "Can't set xflags for changelog: %s\n",
                        strerror(errno = -rc));
@@ -5661,6 +5662,29 @@ static int lfs_changelog(int argc, char **argv)
                                printf(" nid=%s",
                                       libcfs_nid2str(nid->cr_nid));
                        }
+
+                       if (ef->cr_extra_flags & CLFE_OPEN) {
+                               struct changelog_ext_openmode *omd =
+                                       changelog_rec_openmode(rec);
+                               char mode[] = "---";
+
+                               /* exec mode must be exclusive */
+                               if (omd->cr_openflags & MDS_FMODE_EXEC) {
+                                       mode[2] = 'x';
+                               } else {
+                                       if (omd->cr_openflags & FMODE_READ)
+                                               mode[0] = 'r';
+                                       if (omd->cr_openflags &
+                                           (FMODE_WRITE |
+                                            MDS_OPEN_TRUNC |
+                                            MDS_OPEN_APPEND))
+                                               mode[1] = 'w';
+                               }
+
+                               if (strcmp(mode, "---") != 0)
+                                       printf(" m=%s", mode);
+
+                       }
                }
 
                if (rec->cr_namelen)
index 32a31c2..9ff2c8b 100644 (file)
@@ -249,6 +249,8 @@ int llapi_changelog_recv(void *priv, struct changelog_rec **rech)
                        rec_extra_fmt |= CLFE_UIDGID;
                if (cp->clp_send_extra_flags & CHANGELOG_EXTRA_FLAG_NID)
                        rec_extra_fmt |= CLFE_NID;
+               if (cp->clp_send_extra_flags & CHANGELOG_EXTRA_FLAG_OMODE)
+                       rec_extra_fmt |= CLFE_OPEN;
        }
 
        if (cp->clp_buf + cp->clp_buf_len <= cp->clp_buf_pos) {
index 20a1c14..109a389 100644 (file)
@@ -1558,7 +1558,8 @@ int lr_replicate()
 
        rc = llapi_changelog_set_xflags(changelog_priv,
                                        CHANGELOG_EXTRA_FLAG_UIDGID |
-                                       CHANGELOG_EXTRA_FLAG_NID);
+                                       CHANGELOG_EXTRA_FLAG_NID |
+                                       CHANGELOG_EXTRA_FLAG_OMODE);
        if (rc < 0) {
                fprintf(stderr, "Error setting xflag in changelog for fs %s.\n",
                        status->ls_source_fs);