"\t\t--replace: replace an old target with the same index\n"
"\t\t--stripe-count-hint=#N: for optimizing MDT inode size\n"
#else
+ "\t\t--erase-param <key>: erase all instances of a parameter\n"
"\t\t--erase-params: erase all old parameter settings\n"
"\t\t--writeconf: erase all config logs for this fs.\n"
"\t\t--quota: enable space accounting on old 2.x device.\n"
/* ==================== Lustre config functions =============*/
-void print_ldd(char *str, struct lustre_disk_data *ldd)
+void print_ldd(char *str, struct mkfs_opts *mop)
{
+ struct lustre_disk_data *ldd = &mop->mo_ldd;
+
printf("\n %s:\n", str);
printf("Target: %s\n", ldd->ldd_svname);
if (ldd->ldd_svindex == INDEX_UNASSIGNED)
ldd->ldd_flags & LDD_F_NO_PRIMNODE? "no_primnode ":"",
ldd->ldd_flags & LDD_F_UPGRADE14 ? "upgrade1.4 ":"");
printf("Persistent mount opts: %s\n", ldd->ldd_mount_opts);
- printf("Parameters:%s\n", ldd->ldd_params);
+ osd_print_ldd_params(mop);
if (ldd->ldd_userdata[0])
printf("Comment: %s\n", ldd->ldd_userdata);
printf("\n");
usage(stderr);
}
+#ifdef TUNEFS
+/**
+ * Removes all existing instances of the parameter passed in \a param,
+ * which are in the form of "key=<value>", from the buffer at \a buf.
+ *
+ * The parameter can be either in the form of "key" when passed by option
+ * "--erase-param", or in the form of "key=<value>" when passed by option
+ * "--param".
+ *
+ * \param buf the buffer holding on-disk server parameters.
+ * \param param the parameter whose instances are to be removed from \a buf.
+ * \param withval true means the parameter is in the form of "key=<value>"
+ * false means the parameter is in the form of "key"
+ *
+ * \retval 0 success, parameter was erased,
+ * \retval 1 success, parameter was not found, don't need to do erase_ldd,
+ * \retval EINVAL failure, invalid input parameter.
+ */
+static int erase_param(const char *const buf, const char *const param,
+ bool withval)
+{
+ char search[PARAM_MAX + 1] = "";
+ char *buffer = (char *)buf;
+ bool found = false;
+
+ if (strlen(param) > PARAM_MAX) {
+ fprintf(stderr, "%s: param to erase is too long-\n%s\n",
+ progname, param);
+ return EINVAL;
+ }
+
+ /* add_param() writes a space as the first character in ldd_params */
+ search[0] = ' ';
+
+ /* "key" or "key=<value>" */
+ if (withval) {
+ char *keyend;
+
+ keyend = strchr(param, '=');
+ if (!keyend)
+ return EINVAL;
+ strncpy(&search[1], param, keyend - param + 1);
+ } else {
+ strncpy(&search[1], param, strlen(param));
+ strncat(search, "=", 1);
+ }
+
+ while (1) {
+ char *space;
+
+ buffer = strstr(buffer, search);
+ if (!buffer)
+ return found == true ? 0 : 1;
+ found = true;
+ space = strchr(buffer + 1, ' ');
+ if (space) {
+ memmove(buffer, space, strlen(space) + 1);
+ } else {
+ *buffer = '\0';
+ return 0;
+ }
+ }
+}
+#endif
+
/* from mount_lustre */
/* Get rid of symbolic hostnames for tcp, since kernel can't do lookups */
#define MAXNIDSTR 1024
{ "reformat", no_argument, NULL, 'r' },
{ "replace", no_argument, NULL, 'R' },
#else
+ { "erase-param", required_argument, NULL, 'E' },
{ "erase-params", no_argument, NULL, 'e' },
{ "quota", no_argument, NULL, 'Q' },
{ "rename", optional_argument, NULL, 'R' },
#ifndef TUNEFS
"b:c:d:k:MOrR";
#else
- "eQR::w";
+ "E:eQR::w";
#endif
struct lustre_disk_data *ldd = &mop->mo_ldd;
char new_fsname[16] = { 0 };
int replace = 0;
bool index_option = false;
+#ifdef TUNEFS
+ /* For the right semantics, if '-e'/'--erase-params' is specified,
+ * it must be picked out and all old parameters should be erased
+ * before any other changes are done. */
+ while ((opt = getopt_long(argc, argv, optstring, long_opt, &longidx)) !=
+ EOF) {
+ switch (opt) {
+ case 'e':
+ ldd->ldd_params[0] = '\0';
+ mop->mo_flags |= MO_ERASE_ALL;
+ ldd->ldd_flags |= LDD_F_UPDATE;
+ break;
+ default:
+ break;
+ }
+ if (mop->mo_flags & MO_ERASE_ALL)
+ break;
+ }
+ optind = 0;
+#endif
while ((opt = getopt_long(argc, argv, optstring, long_opt, &longidx)) !=
EOF) {
switch (opt) {
*mountopts = optarg;
break;
case 'p':
+#ifdef TUNEFS
+ /* Removes all existing instances of the parameter
+ * before adding new values.
+ */
+ rc = erase_param(ldd->ldd_params, optarg, true);
+ if (rc > 1)
+ return rc;
+#endif
rc = add_param(ldd->ldd_params, NULL, optarg);
if (rc != 0)
return rc;
-
/* Must update the mgs logs */
ldd->ldd_flags |= LDD_F_UPDATE;
break;
case 'R':
replace = 1;
break;
-#else /* !TUNEFS */
- case 'e':
- ldd->ldd_params[0] = '\0';
+#else /* TUNEFS */
+ case 'E':
+ rc = erase_param(ldd->ldd_params, optarg, false);
+ /* (rc == 1) means not found, so don't need to
+ * call osd_erase_ldd(). */
+ if (rc > 1)
+ return rc;
+ if (!rc) {
+ rc = osd_erase_ldd(mop, optarg);
+ if (rc)
+ return rc;
+ }
/* Must update the mgs logs */
ldd->ldd_flags |= LDD_F_UPDATE;
break;
+ case 'e':
+ /* Already done in the beginning */
+ break;
case 'Q':
mop->mo_flags |= MO_QUOTA;
break;
mop.mo_mgs_failnodes++;
if (verbose > 0)
- print_ldd("Read previous values", ldd);
+ print_ldd("Read previous values", &mop);
#endif /* TUNEFS */
ret = parse_opts(argc, argv, &mop, &mountopts, old_fsname);
ldd->ldd_flags &= ~LDD_F_NEED_INDEX;
ldd->ldd_svindex = 0;
}
+#ifndef TUNEFS
if (!IS_MGS(ldd) && (mop.mo_mgs_failnodes == 0)) {
+#else
+ /* Don't check --mgs or --mgsnode if print_only is set or
+ * --erase-params is set. */
+ if (!IS_MGS(ldd) && (mop.mo_mgs_failnodes == 0) && !print_only &&
+ !(mop.mo_flags & MO_ERASE_ALL)) {
+#endif
fatal();
if (IS_MDT(ldd))
fprintf(stderr, "Must specify --mgs or --mgsnode\n");
}
if (verbose >= 0)
- print_ldd("Permanent disk data", ldd);
+ print_ldd("Permanent disk data", &mop);
if (print_only) {
printf("exiting before disk write.\n");
fprintf(stderr, "failed to write local files\n");
goto out;
}
-
out:
osd_fini();
ret2 = loop_cleanup(&mop);