return 0;
}
+/**
+ * Find the first comma delimiter from the specified \a buf and make \a *endh
+ * point to the string starting with the comma. The commas in expression list
+ * [...] will be skipped.
+ *
+ * \param[in] buf a comma-separated string
+ * \param[in] endh a pointer to a pointer that will point to the string
+ * starting with the comma
+ *
+ * \retval 0 if comma delimiter is found
+ * \retval 1 if comma delimiter is not found
+ */
+static int lmd_find_comma(char *buf, char **endh)
+{
+ char *c = buf;
+ int skip = 0;
+
+ if (buf == NULL)
+ return 1;
+
+ while (*c != '\0') {
+ if (*c == '[')
+ skip++;
+ else if (*c == ']')
+ skip--;
+
+ if (*c == ',' && skip == 0) {
+ if (endh != NULL)
+ *endh = c;
+ return 0;
+ }
+
+ c++;
+ }
+
+ return 1;
+}
+
+/**
+ * Find the first valid string delimited by comma from the specified \a buf
+ # and parse it to see whether it's a valid nid list. If yes, \a *endh will
+ * point to the next string starting with the comma.
+ *
+ * \param[in] buf a comma-separated string
+ * \param[in] endh a pointer to a pointer that will point to the string
+ * starting with the comma
+ *
+ * \retval 0 if the string is a valid nid list
+ * \retval 1 if the string is not a valid nid list
+ */
+static int lmd_parse_nidlist(char *buf, char **endh)
+{
+ struct list_head nidlist;
+ char *endp = buf;
+ char tmp;
+ int rc = 0;
+
+ if (buf == NULL)
+ return 1;
+ while (*buf == ',' || *buf == ':')
+ buf++;
+ if (*buf == ' ' || *buf == '/' || *buf == '\0')
+ return 1;
+
+ if (lmd_find_comma(buf, &endp) != 0)
+ endp = buf + strlen(buf);
+
+ tmp = *endp;
+ *endp = '\0';
+
+ INIT_LIST_HEAD(&nidlist);
+ if (cfs_parse_nidlist(buf, strlen(buf), &nidlist) <= 0)
+ rc = 1;
+ cfs_free_nidlist(&nidlist);
+
+ *endp = tmp;
+ if (rc != 0)
+ return rc;
+ if (endh != NULL)
+ *endh = endp;
+ return 0;
+}
+
/** Parse mount line options
* e.g. mount -v -t lustre -o abort_recov uml1:uml2:/lustre-client /mnt/lustre
* dev is passed as device=uml1:/lustre by mount.lustre
clear++;
} else if (strncmp(s1, "param=", 6) == 0) {
size_t length, params_length;
- char *tail = strchr(s1 + 6, ',');
- if (tail == NULL) {
+ char *tail = s1;
+ if (lmd_find_comma(s1 + 6, &tail) != 0)
length = strlen(s1);
- } else {
- lnet_nid_t nid;
- char *param_str = tail + 1;
- int supplementary = 1;
-
- while (class_parse_nid_quiet(param_str, &nid,
- ¶m_str) == 0) {
+ else {
+ char *param_str = tail + 1;
+ int supplementary = 1;
+ while (lmd_parse_nidlist(param_str,
+ ¶m_str) == 0) {
supplementary = 0;
}
length = param_str - s1 - supplementary;
}
run_test 42 "allow client/server mount/unmount with invalid config param"
-test_43() {
+test_43a() {
[[ $(lustre_version_code mgs) -ge $(version_code 2.5.58) ]] ||
{ skip "Need MDS version at least 2.5.58" && return 0; }
[ $UID -ne 0 -o $RUNAS_ID -eq 0 ] && skip_env "run as root"
touch $DIR/$tdir-rootdir/tfile-2 ||
error "$ST: root create permission is denied"
echo "$ST: root create permission is granted - ok"
+ cleanup || error "cleanup failed with $?"
+}
+run_test 43a "check root_squash and nosquash_nids"
+
+test_43b() { # LU-5690
+ [[ $(lustre_version_code mgs) -ge $(version_code 2.7.62) ]] ||
+ { skip "Need MGS version 2.7.62+"; return; }
+
+ if [[ -z "$fs2mds_DEV" ]]; then
+ is_blkdev $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) &&
+ skip_env "mixed loopback and real device not working" && return
+ fi
+
+ local fs2mdsdev=$(mdsdevname 1_2)
+ local fs2mdsvdev=$(mdsvdevname 1_2)
+
+ # temporarily use fs2mds as fs2mgs
+ local fs2mgs=fs2mds
+ local fs2mgsdev=$fs2mdsdev
+ local fs2mgsvdev=$fs2mdsvdev
+
+ local fsname=test1234
+
+ load_module llite/lustre
+ local client_ip=$(host_nids_address $HOSTNAME $NETTYPE)
+ local host=${client_ip//*./}
+ local net=${client_ip/%$host/}
+ local nosquash_nids=$(h2$NETTYPE $net[$host,$host,$host])
+
+ add $fs2mgs $(mkfs_opts mgs $fs2mgsdev) --fsname=$fsname \
+ --param mdt.root_squash=$RUNAS_ID:$RUNAS_ID \
+ --param mdt.nosquash_nids=$nosquash_nids \
+ --reformat $fs2mgsdev $fs2mgsvdev || error "add fs2mgs failed"
+ start $fs2mgs $fs2mgsdev $MGS_MOUNT_OPTS || error "start fs2mgs failed"
+ stop $fs2mgs -f || error "stop fs2mgs failed"
}
-run_test 43 "check root_squash and nosquash_nids"
+run_test 43b "parse nosquash_nids with commas in expr_list"
umount_client $MOUNT
cleanup_nocli