From: Mikhail Pershin Date: Thu, 19 Dec 2024 22:00:20 +0000 (+0300) Subject: LU-18587 utils: allow large NID lists in mount tools X-Git-Tag: 2.16.52~92 X-Git-Url: https://git.whamcloud.com/?a=commitdiff_plain;h=f9d346f0c1;p=fs%2Flustre-release.git LU-18587 utils: allow large NID lists in mount tools While ldd_params are 4096 bytes long a NID lists in params "failnode" and "mgsnode" are limited by 1024 bytes only. Patch removes that limitation and allows as many NIDs as can fit into ldd_params 4k total size Signed-off-by: Mikhail Pershin Change-Id: I8f3867e0f31c75e6261434d4aef48eaf4e8f4507 Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/57560 Tested-by: jenkins Tested-by: Maloo Reviewed-by: Andreas Dilger Reviewed-by: James Simmons Reviewed-by: Oleg Drokin --- diff --git a/lustre/include/uapi/linux/lustre/lustre_disk.h b/lustre/include/uapi/linux/lustre/lustre_disk.h index 8d406b8..75e6fe1 100644 --- a/lustre/include/uapi/linux/lustre/lustre_disk.h +++ b/lustre/include/uapi/linux/lustre/lustre_disk.h @@ -25,6 +25,7 @@ #include #include #include /* for lnet_nid_t */ +#include /* for LDD_PARAM_LEN */ /****************** on-disk files ********************/ @@ -76,7 +77,7 @@ struct lustre_disk_data { char ldd_userdata[1024 - 200]; /* arbitrary user string '200' */ __u8 ldd_padding[4096 - 1024]; /* 1024 */ char ldd_mount_opts[4096]; /* target fs mount opts '4096' */ - char ldd_params[4096]; /* key=value pairs '8192' */ + char ldd_params[LDD_PARAM_LEN];/* key=value pairs '8192' */ }; /****************** persistent mount data *********************/ diff --git a/lustre/include/uapi/linux/lustre/lustre_param.h b/lustre/include/uapi/linux/lustre/lustre_param.h index 8b852cf..1714f76 100644 --- a/lustre/include/uapi/linux/lustre/lustre_param.h +++ b/lustre/include/uapi/linux/lustre/lustre_param.h @@ -49,7 +49,7 @@ #define PARAM_FAILMODE "failover.mode=" /* initial mount only */ #define PARAM_ACTIVE "active=" /* activate/deactivate */ #define PARAM_NETWORK "network=" /* bind on nid */ -#define PARAM_ID_UPCALL "identity_upcall=" /* identity upcall */ +#define PARAM_ID_UPCALL "identity_upcall=" /* identity upcall */ #define PARAM_ROOTSQUASH "root_squash=" /* root squash */ #define PARAM_NOSQUASHNIDS "nosquash_nids=" /* no squash nids */ #define PARAM_AUTODEGRADE "autodegrade=" /* autodegrade OST's */ @@ -73,6 +73,8 @@ #define PARAM_SEC "security." #define PARAM_QUOTA "quota." /* global */ +#define LDD_PARAM_LEN 4096 + /** @} param */ #endif /* _UAPI_LUSTRE_PARAM_H */ diff --git a/lustre/tests/conf-sanity.sh b/lustre/tests/conf-sanity.sh index 63f223f..ccdc71d 100755 --- a/lustre/tests/conf-sanity.sh +++ b/lustre/tests/conf-sanity.sh @@ -6635,20 +6635,56 @@ test_72() { #LU-2634 } run_test 72 "test fast symlink with extents flag enabled" -test_73() { #LU-3006 - [ "$ost1_FSTYPE" == zfs ] && import_zpool ost1 - do_facet ost1 "$TUNEFS --failnode=1.2.3.4@$NETTYPE $(ostdevname 1)" || +test_73a() { #LU-3006 + [[ "$ost1_FSTYPE" == zfs ]] && import_zpool ost1 + local ostdev=$(ostdevname 1) + + do_facet ost1 "$TUNEFS --failnode=1.2.3.4@$NETTYPE $ostdev" || error "1st tunefs failed" start_mgsmds || error "start mds failed" start_ost || error "start ost failed" mount_client $MOUNT || error "mount client failed" - $LCTL get_param -n osc.*OST0000-osc-[^M]*.import | grep failover_nids | - grep 1.2.3.4@$NETTYPE || error "failover nids haven't changed" + $LCTL get_param -n osc.*OST0000-osc-[^M]*.import | + grep "failover_nids.*1.2.3.4@$NETTYPE" || + error "failover nids haven't changed" umount_client $MOUNT || error "umount client failed" stop_ost + do_facet ost1 "$TUNEFS --erase-param failover.node $ostdev" stop_mds } -run_test 73 "failnode to update from mountdata properly" +run_test 73a "failnode to update from mountdata properly" + +test_73b() { + (( $OST1_VERSION >= $(version_code 2.16.50) )) || + skip "need OST >= 2.16.50 for many NID support" + [[ "$ost1_FSTYPE" == zfs ]] && import_zpool ost1 + + local ostdev=$(ostdevname 1) + local nids="111.222.173._@$NETTYPE,111.222.142._@$NETTYPE" + local min=160 + local iter=$((min * 14 / 20)) + + do_facet ost1 "$TUNEFS --comment='just a comment for tail' $ostdev" || + error "1st tunefs failed" + + # 4K can fit ~180 IPv4 NIDs, try more for checking failure case too + # add in pairs just to reduce test time + for ((i = 1; i <= $iter; i++)); do + do_facet ost1 "$TUNEFS --failnode=${nids//_/$i} $ostdev" >/dev/null || + break + done + echo "added $i/$iter NID failover pairs" + # count the actual number of failover NIDs configured in failover.node + # there may be some previously configured, so they should also count + local count=$(do_facet ost1 $TUNEFS --dryrun $ostdev | grep "^Param" | + sed -e "s/.*failover.node=//" -e "s/[:,]/\n/g" | + grep -c $NETTYPE) + do_facet ost1 "$TUNEFS --erase-param failover.node $ostdev" + + # expect to fit more that 160 NIDs at least + ((count >= min)) || error "Only $count NIDs configured, need >= $min" +} +run_test 73b "Large failnode NID list in mountdata" # LU-15246 test_74() { diff --git a/lustre/utils/mount_utils.c b/lustre/utils/mount_utils.c index bdd4015..d0095b9 100644 --- a/lustre/utils/mount_utils.c +++ b/lustre/utils/mount_utils.c @@ -120,10 +120,12 @@ int run_command(char *cmd, int cmdsz) return rc; } +#define MAXNIDSTR LDD_PARAM_LEN + #ifdef HAVE_SERVER_SUPPORT int add_param(char *buf, char *key, char *val) { - int end = sizeof(((struct lustre_disk_data *)0)->ldd_params); + int end = MAXNIDSTR; int start = strlen(buf); int keylen = 0; @@ -139,32 +141,11 @@ int add_param(char *buf, char *key, char *val) return 0; } -int get_param(char *buf, char *key, char **val) -{ - int i, key_len = strlen(key); - char *ptr; - - ptr = strstr(buf, key); - if (ptr) { - *val = strdup(ptr + key_len); - if (!(*val)) - return ENOMEM; - - for (i = 0; i < strlen(*val); i++) - if (((*val)[i] == ' ') || ((*val)[i] == '\0')) - break; - - (*val)[i] = '\0'; - return 0; - } - - return ENOENT; -} - int append_param(char *buf, char *key, char *val, char sep) { - int key_len, i, offset, old_val_len; - char *ptr = NULL, str[1024]; + char *ptr = NULL, *next, *cur; + int bufsize = MAXNIDSTR; + int buflen = strlen(buf), vallen = strlen(val); if (key) ptr = strstr(buf, key); @@ -173,30 +154,24 @@ int append_param(char *buf, char *key, char *val, char sep) if (!ptr) return add_param(buf, key, val); - key_len = strlen(key); - - /* Copy previous values to str */ - for (i = 0; i < sizeof(str); ++i) { - if ((ptr[i + key_len] == ' ') || (ptr[i + key_len] == '\0')) - break; - str[i] = ptr[i + key_len]; - } - if (i == sizeof(str)) + /* check extra new val + sep can fit */ + if (bufsize <= buflen + vallen + 1) { + fprintf(stderr, "%s: params are too long:\n%s +%s=%s\n", + progname, buf, key, val); return E2BIG; - old_val_len = i; - - offset = old_val_len + key_len; - - /* Move rest of buf to overwrite previous key and value */ - for (i = 0; ptr[i + offset] != '\0'; ++i) - ptr[i] = ptr[i + offset]; + } - ptr[i] = '\0'; + next = strchrnul(ptr, ' '); + cur = buf + buflen; + /* shift tail further at vallen + sep */ + while (cur-- > next) + *(cur + vallen + 1) = *cur; - snprintf(str + old_val_len, sizeof(str) - old_val_len, - "%c%s", sep, val); + /* fill gap with sep + new values */ + *next = sep; + memcpy(next + 1, val, vallen); - return add_param(buf, key, str); + return 0; } #endif @@ -946,13 +921,12 @@ int file_create(char *path, __u64 size) } /* Get rid of symbolic hostnames for tcp, since kernel can't do lookups */ -#define MAXNIDSTR 1024 - char *convert_hostnames(char *buf, bool mount) { char *converted, *c, *end, sep; char *delimiter = buf; - int left = MAXNIDSTR; + int bufsize = MAXNIDSTR; + int left = bufsize; struct lnet_nid nid; converted = malloc(left); @@ -1008,7 +982,7 @@ char *convert_hostnames(char *buf, bool mount) else c += scnprintf(c, left, "%s", libcfs_nidstr(&nid)); - left = converted + MAXNIDSTR - c; + left = converted + bufsize - c; buf = delimiter + 1; }