Whamcloud - gitweb
LU-9727 lustre: add uid/gid to Changelogs entries 14/28114/18
authorSebastien Buisson <sbuisson@ddn.com>
Wed, 19 Jul 2017 14:44:27 +0000 (23:44 +0900)
committerOleg Drokin <oleg.drokin@intel.com>
Mon, 11 Dec 2017 03:45:48 +0000 (03:45 +0000)
Add a new changelog extension named changelog_ext_uidgid to hold
uid/gid information.
uid/gid info is added to every Changelog entry type except MARK, in
the form 'u=<uid>:<gid>':
5 01CREAT 15:44:32.385864793 2017.07.18 0x0 t=[0x200000402:0x3:0x0]
ef=0x1 u=500:500 p=[0x200000402:0x2:0x0] file1

Signed-off-by: Sebastien Buisson <sbuisson@ddn.com>
Change-Id: Ie09e4cd146dea75985de00b1da58f75c2a5928f2
Reviewed-on: https://review.whamcloud.com/28114
Reviewed-by: Andreas Dilger <andreas.dilger@intel.com>
Tested-by: Jenkins
Tested-by: Maloo <hpdd-maloo@intel.com>
Reviewed-by: Henri Doreau <henri.doreau@cea.fr>
Reviewed-by: Olaf Weber <olaf.weber@hpe.com>
lustre/include/lustre/lustreapi.h
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 165e1fe..80ba7aa 100644 (file)
@@ -396,6 +396,8 @@ int llapi_changelog_get_fd(void *priv);
 /* Allow records up to endrec to be destroyed; requires registered id. */
 int llapi_changelog_clear(const char *mdtname, const char *idstr,
                          long long endrec);
+extern int llapi_changelog_set_xflags(void *priv,
+                                   enum changelog_send_extra_flag extra_flags);
 
 /* HSM copytool interface.
  * priv is private state, managed internally by these functions
index 52d0632..dfa345b 100644 (file)
@@ -2836,12 +2836,14 @@ enum llog_flag {
        LLOG_F_EXT_JOBID        = 0x8,
        LLOG_F_IS_FIXSIZE       = 0x10,
        LLOG_F_EXT_EXTRA_FLAGS  = 0x20,
+       LLOG_F_EXT_X_UIDGID     = 0x40,
 
        /* 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_MASK = LLOG_F_EXT_JOBID | LLOG_F_EXT_EXTRA_FLAGS |
+                         LLOG_F_EXT_X_UIDGID,
 };
 
 /* On-disk header structure of each log object, stored in little endian order */
index 111b732..6a2cacb 100644 (file)
@@ -1090,8 +1090,9 @@ static inline void hsm_set_cl_error(int *flags, int error)
 }
 
 enum changelog_rec_extra_flags {
-       CLFE_INVALID    = 0, /* No additional flags currently implemented */
-       CLFE_SUPPORTED  = CLFE_INVALID
+       CLFE_INVALID    = 0,
+       CLFE_UIDGID     = 0x0001,
+       CLFE_SUPPORTED  = CLFE_UIDGID
 };
 
 enum changelog_send_flag {
@@ -1107,6 +1108,11 @@ enum changelog_send_flag {
        CHANGELOG_FLAG_EXTRA_FLAGS = 0x08,
 };
 
+enum changelog_send_extra_flag {
+       /* Pack uid/gid into the changelog record */
+       CHANGELOG_EXTRA_FLAG_UIDGID = 0x01,
+};
+
 #define CR_MAXSIZE cfs_size_round(2 * NAME_MAX + 2 + \
                                  changelog_rec_offset(CLF_SUPPORTED, \
                                                        CLFE_SUPPORTED))
@@ -1151,6 +1157,12 @@ struct changelog_ext_extra_flags {
        __u64 cr_extra_flags; /* Additional CLFE_* flags */
 };
 
+/* Changelog extra extension to include UID/GID. */
+struct changelog_ext_uidgid {
+       __u64   cr_uid;
+       __u64   cr_gid;
+};
+
 static inline struct changelog_ext_extra_flags *changelog_rec_extra_flags(
        const struct changelog_rec *rec);
 
@@ -1167,6 +1179,8 @@ static inline size_t changelog_rec_offset(enum changelog_rec_flags crf,
 
        if (crf & CLF_EXTRA_FLAGS) {
                size += sizeof(struct changelog_ext_extra_flags);
+               if (cref & CLFE_UIDGID)
+                       size += sizeof(struct changelog_ext_uidgid);
        }
 
        return size;
@@ -1222,6 +1236,19 @@ struct changelog_ext_extra_flags *changelog_rec_extra_flags(
                                                                 CLFE_INVALID));
 }
 
+/* The uid/gid is the first extra extension */
+static inline
+struct changelog_ext_uidgid *changelog_rec_uidgid(
+       const struct changelog_rec *rec)
+{
+       enum changelog_rec_flags crf = rec->cr_flags &
+               (CLF_VERSION | CLF_RENAME | CLF_JOBID | CLF_EXTRA_FLAGS);
+
+       return (struct changelog_ext_uidgid *)((char *)rec +
+                                              changelog_rec_offset(crf,
+                                                                CLFE_INVALID));
+}
+
 /* The name follows the rename, jobid  and extra flags extns, if present */
 static inline char *changelog_rec_name(const struct changelog_rec *rec)
 {
@@ -1271,9 +1298,11 @@ static inline void changelog_remap_rec(struct changelog_rec *rec,
                                       enum changelog_rec_flags crf_wanted,
                                       enum changelog_rec_extra_flags cref_want)
 {
+       char *uidgid_mov = NULL;
        char *ef_mov;
        char *jid_mov;
        char *rnm_mov;
+       enum changelog_rec_extra_flags cref = CLFE_INVALID;
 
        crf_wanted &= CLF_SUPPORTED;
        cref_want &= CLFE_SUPPORTED;
@@ -1292,6 +1321,13 @@ static inline void changelog_remap_rec(struct changelog_rec *rec,
                changelog_rec_name(rec), rec->cr_namelen);
 
        /* Locations of extensions in the remapped record */
+       if (rec->cr_flags & CLF_EXTRA_FLAGS) {
+               uidgid_mov = (char *)rec +
+                       changelog_rec_offset(crf_wanted & CLF_SUPPORTED,
+                                            CLFE_INVALID);
+               cref = changelog_rec_extra_flags(rec)->cr_extra_flags;
+       }
+
        ef_mov  = (char *)rec +
                  changelog_rec_offset(crf_wanted & ~CLF_EXTRA_FLAGS,
                                       CLFE_INVALID);
@@ -1309,6 +1345,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_UIDGID) && (cref & CLFE_UIDGID))
+                       memmove(uidgid_mov, changelog_rec_uidgid(rec),
+                               sizeof(struct changelog_ext_uidgid));
+
                memmove(ef_mov, changelog_rec_extra_flags(rec),
                        sizeof(struct changelog_ext_extra_flags));
        }
@@ -1322,6 +1362,10 @@ static inline void changelog_remap_rec(struct changelog_rec *rec,
                        sizeof(struct changelog_ext_rename));
 
        /* Clear newly added fields */
+       if (uidgid_mov && (cref_want & CLFE_UIDGID) &&
+           !(cref & CLFE_UIDGID))
+               memset(uidgid_mov, 0, sizeof(struct changelog_ext_uidgid));
+
        if ((crf_wanted & CLF_EXTRA_FLAGS) &&
            !(rec->cr_flags & CLF_EXTRA_FLAGS))
                memset(ef_mov, 0, sizeof(struct changelog_ext_extra_flags));
index cd50853..483d24d 100644 (file)
@@ -217,7 +217,8 @@ static int chlg_load(void *args)
        rc = llog_init_handle(NULL, llh,
                              LLOG_F_IS_CAT |
                              LLOG_F_EXT_JOBID |
-                             LLOG_F_EXT_EXTRA_FLAGS,
+                             LLOG_F_EXT_EXTRA_FLAGS |
+                             LLOG_F_EXT_X_UIDGID,
                              NULL);
        if (rc) {
                CERROR("%s: fail to init llog handle: rc = %d\n",
index b5baf1e..7cf63ed 100644 (file)
@@ -736,7 +736,7 @@ static int mdd_llog_record_calc_size(const struct lu_env *env,
 {
        const struct lu_ucred   *uc = lu_ucred(env);
        enum changelog_rec_flags crf = CLF_EXTRA_FLAGS;
-       enum changelog_rec_extra_flags crfe = CLFE_INVALID;
+       enum changelog_rec_extra_flags crfe = CLFE_UIDGID;
 
        if (sname != NULL)
                crf |= CLF_RENAME;
@@ -845,8 +845,8 @@ static void mdd_changelog_rec_ext_rename(struct changelog_rec *rec,
                                         const struct lu_fid *spfid,
                                         const struct lu_name *sname)
 {
-       struct changelog_ext_rename     *rnm = changelog_rec_rename(rec);
-       size_t                           extsize = sname->ln_namelen + 1;
+       struct changelog_ext_rename *rnm = changelog_rec_rename(rec);
+       size_t extsize = sname->ln_namelen + 1;
 
        LASSERT(sfid != NULL);
        LASSERT(spfid != NULL);
@@ -862,7 +862,7 @@ static void mdd_changelog_rec_ext_rename(struct changelog_rec *rec,
 
 void mdd_changelog_rec_ext_jobid(struct changelog_rec *rec, const char *jobid)
 {
-       struct changelog_ext_jobid      *jid = changelog_rec_jobid(rec);
+       struct changelog_ext_jobid *jid = changelog_rec_jobid(rec);
 
        if (jobid == NULL || jobid[0] == '\0')
                return;
@@ -877,6 +877,15 @@ void mdd_changelog_rec_ext_extra_flags(struct changelog_rec *rec, __u64 eflags)
        ef->cr_extra_flags = eflags;
 }
 
+void mdd_changelog_rec_extra_uidgid(struct changelog_rec *rec,
+                                   __u64 uid, __u64 gid)
+{
+       struct changelog_ext_uidgid *uidgid = changelog_rec_uidgid(rec);
+
+       uidgid->cr_uid = uid;
+       uidgid->cr_gid = gid;
+}
+
 /** 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.
@@ -936,10 +945,15 @@ int mdd_changelog_ns_store(const struct lu_env *env,
        else
                crf |= CLF_VERSION;
 
+       xflags |= CLFE_UIDGID;
+
        rec->cr.cr_flags = crf;
 
        if (crf & CLF_EXTRA_FLAGS) {
                mdd_changelog_rec_ext_extra_flags(&rec->cr, xflags);
+               if (xflags & CLFE_UIDGID)
+                       mdd_changelog_rec_extra_uidgid(&rec->cr,
+                                                      uc->uc_uid, uc->uc_gid);
        }
 
        rec->cr.cr_type = (__u32)type;
index aeb0791..5a19769 100644 (file)
@@ -279,6 +279,8 @@ int mdd_declare_changelog_store(const struct lu_env *env,
                                       struct thandle *handle);
 void mdd_changelog_rec_ext_jobid(struct changelog_rec *rec, const char *jobid);
 void mdd_changelog_rec_ext_extra_flags(struct changelog_rec *rec, __u64 eflags);
+void mdd_changelog_rec_extra_uidgid(struct changelog_rec *rec,
+                                   __u64 uid, __u64 gid);
 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 15a761d..e15141e 100644 (file)
@@ -650,6 +650,8 @@ static int mdd_changelog_data_store_by_fid(const struct lu_env *env,
        if (uc != NULL && uc->uc_jobid[0] != '\0')
                flags |= CLF_JOBID;
 
+       xflags |= CLFE_UIDGID;
+
        reclen = llog_data_len(LLOG_CHANGELOG_HDR_SZ +
                               changelog_rec_offset(flags & CLF_SUPPORTED,
                                                    xflags & CLFE_SUPPORTED));
@@ -667,8 +669,12 @@ static int mdd_changelog_data_store_by_fid(const struct lu_env *env,
        if (flags & CLF_JOBID)
                mdd_changelog_rec_ext_jobid(&rec->cr, uc->uc_jobid);
 
-       if (flags & CLF_EXTRA_FLAGS)
+       if (flags & CLF_EXTRA_FLAGS) {
                mdd_changelog_rec_ext_extra_flags(&rec->cr, xflags);
+               if (xflags & CLFE_UIDGID)
+                       mdd_changelog_rec_extra_uidgid(&rec->cr,
+                                                      uc->uc_uid, uc->uc_gid);
+       }
 
        rc = mdd_changelog_store(env, mdd, rec, handle);
 
index 7ef7e9a..f1c4b22 100644 (file)
@@ -975,6 +975,8 @@ static int llog_osd_next_block(const struct lu_env *env,
                /* Trim unsupported extensions for compat w/ older clients */
                flags = CLF_SUPPORTED;
                xflags = CLFE_SUPPORTED;
+               if (!(loghandle->lgh_hdr->llh_flags & LLOG_F_EXT_X_UIDGID))
+                       xflags &= ~CLFE_UIDGID;
                if (!(loghandle->lgh_hdr->llh_flags & LLOG_F_EXT_EXTRA_FLAGS))
                        flags &= ~CLF_EXTRA_FLAGS;
                if (!(loghandle->lgh_hdr->llh_flags & LLOG_F_EXT_JOBID))
@@ -1119,6 +1121,8 @@ static int llog_osd_prev_block(const struct lu_env *env,
                /* Trim unsupported extensions for compat w/ older clients */
                flags = CLF_SUPPORTED;
                xflags = CLFE_SUPPORTED;
+               if (!(loghandle->lgh_hdr->llh_flags & LLOG_F_EXT_X_UIDGID))
+                       xflags &= ~CLFE_UIDGID;
                if (!(loghandle->lgh_hdr->llh_flags & LLOG_F_EXT_EXTRA_FLAGS))
                        flags &= ~CLF_EXTRA_FLAGS;
                if (!(loghandle->lgh_hdr->llh_flags & LLOG_F_EXT_JOBID))
index 3d278a0..9d3fd32 100644 (file)
@@ -5174,6 +5174,14 @@ static int lfs_changelog(int argc, char **argv)
                return rc;
        }
 
+       rc = llapi_changelog_set_xflags(changelog_priv,
+                                       CHANGELOG_EXTRA_FLAG_UIDGID);
+       if (rc < 0) {
+               fprintf(stderr, "Can't set xflags for changelog: %s\n",
+                       strerror(errno = -rc));
+               return rc;
+       }
+
        while ((rc = llapi_changelog_recv(changelog_priv, &rec)) == 0) {
                time_t secs;
                struct tm ts;
@@ -5210,6 +5218,14 @@ static int lfs_changelog(int argc, char **argv)
                                changelog_rec_extra_flags(rec);
 
                        printf(" ef=0x%llx", ef->cr_extra_flags);
+
+                       if (ef->cr_extra_flags & CLFE_UIDGID) {
+                               struct changelog_ext_uidgid *uidgid =
+                                       changelog_rec_uidgid(rec);
+
+                               printf(" u=%llu:%llu",
+                                      uidgid->cr_uid, uidgid->cr_gid);
+                       }
                }
 
                if (rec->cr_namelen)
index 15f334c..1389998 100644 (file)
@@ -68,6 +68,8 @@ struct changelog_private {
        int                              clp_fd;
        /* Changelog delivery mode */
        enum changelog_send_flag         clp_send_flags;
+       /* Changelog extra flags */
+       enum changelog_send_extra_flag   clp_send_extra_flags;
        /* Available bytes in buffer */
        size_t                           clp_buf_len;
        /* Current position in buffer */
@@ -243,6 +245,8 @@ int llapi_changelog_recv(void *priv, struct changelog_rec **rech)
 
        if (cp->clp_send_flags & CHANGELOG_FLAG_EXTRA_FLAGS) {
                rec_fmt |= CLF_EXTRA_FLAGS;
+               if (cp->clp_send_extra_flags & CHANGELOG_EXTRA_FLAG_UIDGID)
+                       rec_extra_fmt |= CLFE_UIDGID;
        }
 
        if (cp->clp_buf + cp->clp_buf_len <= cp->clp_buf_pos) {
@@ -328,3 +332,36 @@ out_close:
        close(fd);
        return rc;
 }
+
+/**
+ * Set extra flags for reading changelogs
+ *
+ * @param priv         Opaque private control structure
+ * @param extra_flags  Read extra flags (e.g. CHANGELOG_EXTRA_FLAG_UIDGID)
+ *
+ * Just call this function right after llapi_changelog_start().
+ */
+int llapi_changelog_set_xflags(void *priv,
+                              enum changelog_send_extra_flag extra_flags)
+{
+       struct changelog_private *cp = priv;
+       static bool warned_uidgid;
+
+       if (!cp || cp->clp_magic != CHANGELOG_PRIV_MAGIC)
+               return -EINVAL;
+
+       cp->clp_send_extra_flags = extra_flags;
+
+       /* CHANGELOG_EXTRA_FLAG_UIDGID will eventually become mandatory.
+        * If it wasn't specified, display a warning here.
+        * Code elsewhere will remove the corresponding extension.
+        */
+       if (!(extra_flags & CHANGELOG_EXTRA_FLAG_UIDGID) && !warned_uidgid) {
+               llapi_err_noerrno(LLAPI_MSG_WARN,
+                    "warning: %s() called without CHANGELOG_EXTRA_FLAG_UIDGID",
+                    __func__);
+               warned_uidgid = true;
+       }
+
+       return 0;
+}
index 3974a70..7e97137 100644 (file)
@@ -1551,6 +1551,14 @@ int lr_replicate()
                goto out;
         }
 
+       rc = llapi_changelog_set_xflags(changelog_priv,
+                                       CHANGELOG_EXTRA_FLAG_UIDGID);
+       if (rc < 0) {
+               fprintf(stderr, "Error setting xflag in changelog for fs %s.\n",
+                       status->ls_source_fs);
+               goto out;
+       }
+
         while (!quit && lr_parse_line(changelog_priv, info) == 0) {
                 rc = 0;
                if (info->type == CL_RENAME && !info->is_extended) {