Whamcloud - gitweb
LU-5054 llite: enforce pool name length limit 06/10306/11
authorLi Xi <lixi@ddn.com>
Thu, 2 Oct 2014 23:43:02 +0000 (07:43 +0800)
committerAndreas Dilger <andreas.dilger@intel.com>
Sat, 25 Oct 2014 00:03:10 +0000 (00:03 +0000)
The pool related codes have some inconsistency about the length
of pool name. Creating and setting a pool name of lenght 16
to a directory will succeed. However, creating a file under
that directory will fail.

This patch disables any pool name which is longer or equal to
16. And it changes LOV_MAXPOOLNAME from 16 to 15 which might
cause some invalid LLOG records of OST pools with 16 byte names.
It is not a problem since invalid LLOG records are just ignored.
And OST pools with 16 byte names won't work well anyway on the
old versions. There will be problem of inconsistency if part of
the servers have this patch and part of the servers don't. But
it would be safe to assume that this is not a normal
configuration.

Signed-off-by: Li Xi <lixi@ddn.com>
Change-Id: I3672fb5414662120c3e6b8641002a6b76994cc77
Reviewed-on: http://review.whamcloud.com/10306
Reviewed-by: Andreas Dilger <andreas.dilger@intel.com>
Tested-by: Jenkins
Reviewed-by: Fan Yong <fan.yong@intel.com>
Tested-by: Maloo <hpdd-maloo@intel.com>
12 files changed:
lustre/doc/llapi_file_get_stripe.3
lustre/include/lustre/lustre_idl.h
lustre/include/lustre/lustre_user.h
lustre/include/lustre_lmv.h
lustre/include/obd.h
lustre/lod/lod_lov.c
lustre/ptlrpc/wiretest.c
lustre/tests/llapi_layout_test.c
lustre/tests/ost-pools.sh
lustre/utils/liblustreapi.c
lustre/utils/wirecheck.c
lustre/utils/wiretest.c

index 24d172f..d3232fb 100644 (file)
@@ -40,7 +40,7 @@ struct lov_user_md_v3 {
         __u32 lmm_stripe_size;
         __u16 lmm_stripe_count;
         __u16 lmm_stripe_offset;
-        char  lmm_pool_name[LOV_MAXPOOLNAME];
+        char  lmm_pool_name[LOV_MAXPOOLNAME + 1];
         struct lov_user_ost_data_v1 lmm_objects[0];
 } __attribute__((packed));
 .fi
index d3dc0b0..6359780 100644 (file)
@@ -1722,7 +1722,7 @@ struct lov_mds_md_v3 {            /* LOV EA mds/wire data (little-endian) */
        /* lmm_stripe_count used to be __u32 */
        __u16 lmm_stripe_count;   /* num stripes in use for this object */
        __u16 lmm_layout_gen;     /* layout generation number */
-       char  lmm_pool_name[LOV_MAXPOOLNAME]; /* must be 32bit aligned */
+       char  lmm_pool_name[LOV_MAXPOOLNAME + 1]; /* must be 32bit aligned */
        struct lov_ost_data_v1 lmm_objects[0]; /* per-stripe data */
 };
 
@@ -2738,7 +2738,7 @@ struct lmv_mds_md_v1 {
        __u32 lmv_padding1;
        __u64 lmv_padding2;
        __u64 lmv_padding3;
-       char lmv_pool_name[LOV_MAXPOOLNAME];    /* pool name */
+       char lmv_pool_name[LOV_MAXPOOLNAME + 1];        /* pool name */
        struct lu_fid lmv_stripe_fids[0];       /* FIDs for each stripe */
 };
 
index f4d1f8b..6fdc747 100644 (file)
@@ -314,8 +314,8 @@ enum ll_lease_type {
 #define LOV_PATTERN_F_HOLE     0x40000000 /* there is hole in LOV EA */
 #define LOV_PATTERN_F_RELEASED 0x80000000 /* HSM released file */
 
-#define LOV_MAXPOOLNAME 16
-#define LOV_POOLNAMEF "%.16s"
+#define LOV_MAXPOOLNAME 15
+#define LOV_POOLNAMEF "%.15s"
 
 #define LOV_MIN_STRIPE_BITS 16   /* maximum PAGE_SIZE (ia64), power of 2 */
 #define LOV_MIN_STRIPE_SIZE (1 << LOV_MIN_STRIPE_BITS)
@@ -371,7 +371,7 @@ struct lov_user_md_v3 {           /* LOV EA user data (host-endian) */
                __u16 lmm_layout_gen;     /* layout generation number
                                           * used when reading */
        };
-       char  lmm_pool_name[LOV_MAXPOOLNAME]; /* pool name */
+       char  lmm_pool_name[LOV_MAXPOOLNAME + 1]; /* pool name */
        struct lov_user_ost_data_v1 lmm_objects[0]; /* per-stripe data */
 } __attribute__((packed));
 
@@ -429,7 +429,7 @@ struct lmv_user_md_v1 {
        __u32   lum_padding1;
        __u32   lum_padding2;
        __u32   lum_padding3;
-       char    lum_pool_name[LOV_MAXPOOLNAME];
+       char    lum_pool_name[LOV_MAXPOOLNAME + 1];
        struct  lmv_user_mds_data  lum_objects[0];
 } __attribute__((packed));
 
index 9dced71..acd4e4e 100644 (file)
@@ -48,7 +48,7 @@ struct lmv_stripe_md {
        __u32   lsm_md_layout_version;
        __u32   lsm_md_default_count;
        __u32   lsm_md_default_index;
-       char    lsm_md_pool_name[LOV_MAXPOOLNAME];
+       char    lsm_md_pool_name[LOV_MAXPOOLNAME + 1];
        struct lmv_oinfo lsm_md_oinfo[0];
 };
 
index 1aaeff4..60acd33 100644 (file)
@@ -107,7 +107,7 @@ struct lov_stripe_md {
                 __u32 lw_pattern;          /* striping pattern (RAID0, RAID1) */
                 __u16 lw_stripe_count;  /* number of objects being striped over */
                 __u16 lw_layout_gen;       /* generation of the layout */
-                char  lw_pool_name[LOV_MAXPOOLNAME]; /* pool name */
+               char  lw_pool_name[LOV_MAXPOOLNAME + 1]; /* pool name */
         } lsm_wire;
 
         struct lov_oinfo *lsm_oinfo[0];
index 08fbeda..a65eec6 100644 (file)
@@ -791,9 +791,11 @@ int lod_store_def_striping(const struct lu_env *env, struct dt_object *dt,
        v3->lmm_stripe_count = cpu_to_le16(lo->ldo_def_stripenr);
        v3->lmm_stripe_offset = cpu_to_le16(lo->ldo_def_stripe_offset);
        v3->lmm_stripe_size = cpu_to_le32(lo->ldo_def_stripe_size);
-       if (lo->ldo_pool != NULL)
+       if (lo->ldo_pool != NULL) {
                strlcpy(v3->lmm_pool_name, lo->ldo_pool,
                        sizeof(v3->lmm_pool_name));
+               v3->lmm_pool_name[sizeof(v3->lmm_pool_name) - 1] = '\0';
+       }
        info->lti_buf.lb_buf = v3;
        info->lti_buf.lb_len = sizeof(*v3);
        rc = dt_xattr_set(env, next, &info->lti_buf, XATTR_NAME_LOV, 0, th,
index 4bf3158..64ed09d 100644 (file)
@@ -1494,7 +1494,7 @@ void lustre_assert_wire_constants(void)
                 (long long)(int)offsetof(struct lov_mds_md_v3, lmm_layout_gen));
        LASSERTF((int)sizeof(((struct lov_mds_md_v3 *)0)->lmm_layout_gen) == 2, "found %lld\n",
                 (long long)(int)sizeof(((struct lov_mds_md_v3 *)0)->lmm_layout_gen));
-       CLASSERT(LOV_MAXPOOLNAME == 16);
+       CLASSERT(LOV_MAXPOOLNAME == 15);
        LASSERTF((int)offsetof(struct lov_mds_md_v3, lmm_pool_name[16]) == 48, "found %lld\n",
                 (long long)(int)offsetof(struct lov_mds_md_v3, lmm_pool_name[16]));
        LASSERTF((int)sizeof(((struct lov_mds_md_v3 *)0)->lmm_pool_name[16]) == 1, "found %lld\n",
index 98a812a..12109f1 100644 (file)
@@ -523,7 +523,7 @@ void test12(void)
 
        /* Pool name too long*/
        errno = 0;
-       rc = llapi_layout_pool_name_set(layout, "0123456789abcdef0");
+       rc = llapi_layout_pool_name_set(layout, "0123456789abcdef");
        ASSERTF(rc == -1 && errno == EINVAL, "rc = %d, errno = %d", rc, errno);
 
        llapi_layout_free(layout);
@@ -824,7 +824,7 @@ void test18(void)
 void test19(void)
 {
        struct llapi_layout *layout;
-       char *name = "0123456789abcdef";
+       char *name = "0123456789abcde";
        char mypool[LOV_MAXPOOLNAME + 1] = { '\0' };
        int rc;
 
index ad56980..865f62f 100644 (file)
@@ -237,20 +237,20 @@ test_1b() {
     create_pool_nofail ${POOL}12
     destroy_pool ${POOL}12
 }
-run_test 1b "Create a pool with a 10 character pool name"
+run_test 1b "Create a pool with a 10 char pool name"
 
 test_1c() {
     set_cleanup_trap
-    create_pool_nofail ${POOL}12345678
-    destroy_pool ${POOL}12345678
+    create_pool_nofail ${POOL}1234567
+    destroy_pool ${POOL}1234567
 }
-run_test 1c "Create a pool with a 16 character pool name"
+run_test 1c "Create a pool with a 15 char pool name"
 
 test_1d() {
     set_cleanup_trap
-    create_pool_fail ${POOL}123456789
+    create_pool_fail ${POOL}12345678
 }
-run_test 1d "Create a pool with a 17 char pool name; should fail"
+run_test 1d "Create a pool with a 16 char pool name; should fail"
 
 test_1e() {
     set_cleanup_trap
@@ -318,6 +318,23 @@ test_1m() {
 }
 run_test 1m "pool_new did not fail even though $POOL2 existed"
 
+test_1n() {
+    set_cleanup_trap
+    create_pool_nofail ${POOL}1234567
+
+    add_pool ${POOL}1234567 "OST0000" "$FSNAME-OST0000_UUID "
+    local POOL_ROOT=${POOL_ROOT:-$DIR/$tdir}
+    create_dir $POOL_ROOT ${POOL}1234567
+    dd if=/dev/zero of=$POOL_ROOT/file bs=1M count=100
+    RC=$?; [[ $RC -eq 0 ]] ||
+        error "failed to write to $POOL_ROOT/file: $RC"
+    do_facet $SINGLEMDS lctl pool_remove $FSNAME.${POOL}1234567 OST0000
+    drain_pool ${POOL}1234567
+
+    destroy_pool ${POOL}1234567
+}
+run_test 1n "Pool with a 15 char pool name works well"
+
 test_2a() {
     set_cleanup_trap
     destroy_pool $POOL
index 9225821..d97ff03 100644 (file)
@@ -868,7 +868,7 @@ int llapi_dir_create_pool(const char *name, int mode, int stripe_offset,
        lmu.lum_stripe_count = stripe_count;
        lmu.lum_hash_type = stripe_pattern;
        if (pool_name != NULL) {
-               if (strlen(pool_name) >= LOV_MAXPOOLNAME) {
+               if (strlen(pool_name) > LOV_MAXPOOLNAME) {
                        llapi_err_noerrno(LLAPI_MSG_ERROR,
                                  "error LL_IOC_LMV_SETSTRIPE '%s' : too large"
                                  "pool name: %s", name, pool_name);
index 5fa79d8..558bcb0 100644 (file)
@@ -679,7 +679,7 @@ check_lov_mds_md_v3(void)
        CHECK_MEMBER(lov_mds_md_v3, lmm_stripe_count);
        CHECK_MEMBER(lov_mds_md_v3, lmm_layout_gen);
        CHECK_CVALUE(LOV_MAXPOOLNAME);
-       CHECK_MEMBER(lov_mds_md_v3, lmm_pool_name[LOV_MAXPOOLNAME]);
+       CHECK_MEMBER(lov_mds_md_v3, lmm_pool_name[LOV_MAXPOOLNAME + 1]);
        CHECK_MEMBER(lov_mds_md_v3, lmm_objects[0]);
 
        CHECK_CDEFINE(LOV_MAGIC_V3);
index 612c5d4..702ae0b 100644 (file)
@@ -1506,7 +1506,7 @@ void lustre_assert_wire_constants(void)
                 (long long)(int)offsetof(struct lov_mds_md_v3, lmm_layout_gen));
        LASSERTF((int)sizeof(((struct lov_mds_md_v3 *)0)->lmm_layout_gen) == 2, "found %lld\n",
                 (long long)(int)sizeof(((struct lov_mds_md_v3 *)0)->lmm_layout_gen));
-       CLASSERT(LOV_MAXPOOLNAME == 16);
+       CLASSERT(LOV_MAXPOOLNAME == 15);
        LASSERTF((int)offsetof(struct lov_mds_md_v3, lmm_pool_name[16]) == 48, "found %lld\n",
                 (long long)(int)offsetof(struct lov_mds_md_v3, lmm_pool_name[16]));
        LASSERTF((int)sizeof(((struct lov_mds_md_v3 *)0)->lmm_pool_name[16]) == 1, "found %lld\n",