X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=blobdiff_plain;f=lustre%2Futils%2Fmkfs_lustre.c;fp=lustre%2Futils%2Fmkfs_lustre.c;h=098e607efc942e57d9ab53f60dd4eac861f2e340;hp=ab813fa6dc3e8442a4488adb2167f0e93e9a1db6;hb=107bf3389aed435c7148463817984af1a22200e7;hpb=3f7c5d26e6c14e4fb7575ee0b983133adf5e9a05;ds=sidebyside diff --git a/lustre/utils/mkfs_lustre.c b/lustre/utils/mkfs_lustre.c index ab813fa..098e607 100644 --- a/lustre/utils/mkfs_lustre.c +++ b/lustre/utils/mkfs_lustre.c @@ -154,6 +154,7 @@ void usage(FILE *out) "\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 : 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" @@ -173,8 +174,10 @@ void usage(FILE *out) /* ==================== 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) @@ -197,7 +200,7 @@ void print_ldd(char *str, struct lustre_disk_data *ldd) 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"); @@ -226,6 +229,71 @@ static inline void badopt(const char *opt, char *type) usage(stderr); } +#ifdef TUNEFS +/** + * Removes all existing instances of the parameter passed in \a param, + * which are in the form of "key=", 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=" 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=" + * 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=" */ + 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 @@ -308,6 +376,7 @@ int parse_opts(int argc, char *const argv[], struct mkfs_opts *mop, { "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' }, @@ -319,7 +388,7 @@ int parse_opts(int argc, char *const argv[], struct mkfs_opts *mop, #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 }; @@ -329,6 +398,26 @@ int parse_opts(int argc, char *const argv[], struct mkfs_opts *mop, 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) { @@ -446,10 +535,17 @@ int parse_opts(int argc, char *const argv[], struct mkfs_opts *mop, *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; @@ -539,12 +635,24 @@ int parse_opts(int argc, char *const argv[], struct mkfs_opts *mop, 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; @@ -730,7 +838,7 @@ int main(int argc, char *const argv[]) 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); @@ -782,7 +890,14 @@ int main(int argc, char *const argv[]) 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"); @@ -843,7 +958,7 @@ int main(int argc, char *const argv[]) } if (verbose >= 0) - print_ldd("Permanent disk data", ldd); + print_ldd("Permanent disk data", &mop); if (print_only) { printf("exiting before disk write.\n"); @@ -928,7 +1043,6 @@ int main(int argc, char *const argv[]) fprintf(stderr, "failed to write local files\n"); goto out; } - out: osd_fini(); ret2 = loop_cleanup(&mop);