From 21fb4d93a94ef3876051fed31c5ef0c33f484f9d Mon Sep 17 00:00:00 2001 From: Sebastien Buisson Date: Tue, 25 Jul 2017 09:45:58 -0400 Subject: [PATCH] LU-9727 lustre: implement CL_OPEN for Changelogs 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 Change-Id: I72c479938ab4782523f1b16aef19fbbc96f43c7f Reviewed-on: https://review.whamcloud.com/28214 Tested-by: Jenkins Reviewed-by: Andreas Dilger Tested-by: Maloo Reviewed-by: Li Xi Reviewed-by: Oleg Drokin --- lustre/include/uapi/linux/lustre/lustre_idl.h | 63 ++-------------- lustre/include/uapi/linux/lustre/lustre_user.h | 100 ++++++++++++++++++++++++- lustre/mdc/mdc_changelog.c | 3 +- lustre/mdd/mdd_dir.c | 7 ++ lustre/mdd/mdd_internal.h | 1 + lustre/mdd/mdd_object.c | 9 ++- lustre/obdclass/llog_osd.c | 2 + lustre/utils/lfs.c | 26 ++++++- lustre/utils/liblustreapi_chlg.c | 2 + lustre/utils/lustre_rsync.c | 3 +- 10 files changed, 154 insertions(+), 62 deletions(-) diff --git a/lustre/include/uapi/linux/lustre/lustre_idl.h b/lustre/include/uapi/linux/lustre/lustre_idl.h index c3ec65b..3a65228 100644 --- a/lustre/include/uapi/linux/lustre/lustre_idl.h +++ b/lustre/include/uapi/linux/lustre/lustre_idl.h @@ -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 */ diff --git a/lustre/include/uapi/linux/lustre/lustre_user.h b/lustre/include/uapi/linux/lustre/lustre_user.h index 0fdc9d1..d62a908 100644 --- a/lustre/include/uapi/linux/lustre/lustre_user.h +++ b/lustre/include/uapi/linux/lustre/lustre_user.h @@ -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)); diff --git a/lustre/mdc/mdc_changelog.c b/lustre/mdc/mdc_changelog.c index 252592c..96b9dee 100644 --- a/lustre/mdc/mdc_changelog.c +++ b/lustre/mdc/mdc_changelog.c @@ -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", diff --git a/lustre/mdd/mdd_dir.c b/lustre/mdd/mdd_dir.c index 09d41d6..88ee6a0 100644 --- a/lustre/mdd/mdd_dir.c +++ b/lustre/mdd/mdd_dir.c @@ -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. diff --git a/lustre/mdd/mdd_internal.h b/lustre/mdd/mdd_internal.h index bc27a30..d704d2f 100644 --- a/lustre/mdd/mdd_internal.h +++ b/lustre/mdd/mdd_internal.h @@ -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, diff --git a/lustre/mdd/mdd_object.c b/lustre/mdd/mdd_object.c index 05b67e4..fc31d01 100644 --- a/lustre/mdd/mdd_object.c +++ b/lustre/mdd/mdd_object.c @@ -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); diff --git a/lustre/obdclass/llog_osd.c b/lustre/obdclass/llog_osd.c index c853433..a374221 100644 --- a/lustre/obdclass/llog_osd.c +++ b/lustre/obdclass/llog_osd.c @@ -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)) diff --git a/lustre/utils/lfs.c b/lustre/utils/lfs.c index 98d78e4..7290411 100644 --- a/lustre/utils/lfs.c +++ b/lustre/utils/lfs.c @@ -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) diff --git a/lustre/utils/liblustreapi_chlg.c b/lustre/utils/liblustreapi_chlg.c index 32a31c2..9ff2c8b 100644 --- a/lustre/utils/liblustreapi_chlg.c +++ b/lustre/utils/liblustreapi_chlg.c @@ -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) { diff --git a/lustre/utils/lustre_rsync.c b/lustre/utils/lustre_rsync.c index 20a1c14..109a389 100644 --- a/lustre/utils/lustre_rsync.c +++ b/lustre/utils/lustre_rsync.c @@ -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); -- 1.8.3.1