#include <linux/types.h>
#include <linux/uuid.h>
#include <linux/lnet/lnet-types.h> /* for lnet_nid_t */
+#include <linux/lustre/lustre_param.h> /* for LDD_PARAM_LEN */
/****************** on-disk files ********************/
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 *********************/
#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 */
#define PARAM_SEC "security."
#define PARAM_QUOTA "quota." /* global */
+#define LDD_PARAM_LEN 4096
+
/** @} param */
#endif /* _UAPI_LUSTRE_PARAM_H */
}
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() {
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;
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);
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
}
/* 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);
else
c += scnprintf(c, left, "%s", libcfs_nidstr(&nid));
- left = converted + MAXNIDSTR - c;
+ left = converted + bufsize - c;
buf = delimiter + 1;
}