diff --git a/lustre/utils/mount_lustre.c b/lustre/utils/mount_lustre.c index 579728dd55801fed296ca3be7c005fdac060113f..3d9d3161fdac6e6dafa9659e93e0732fde24a6ac 100644 --- a/lustre/utils/mount_lustre.c +++ b/lustre/utils/mount_lustre.c @@ -60,11 +60,13 @@ #define MAX_HW_SECTORS_KB_PATH "queue/max_hw_sectors_kb" #define MAX_SECTORS_KB_PATH "queue/max_sectors_kb" +#define MAX_RETRIES 99 int verbose = 0; int nomtab = 0; int fake = 0; int force = 0; +int retry = 0; char *progname = NULL; void usage(FILE *out) @@ -90,6 +92,7 @@ void usage(FILE *out) "\t\tnomgs: only start target obds, using existing MGS\n" "\t\texclude=<ostname>[:<ostname>] : colon-separated list of " "inactive OSTs (e.g. lustre-OST0001)\n" + "\t\tretry=<num>: number of times mount is retried by client\n" ); exit((out != stdout) ? EINVAL : 0); } @@ -255,7 +258,7 @@ static int parse_one_option(const char *check, int *flagp) fill in mount flags */ int parse_options(char *orig_options, int *flagp) { - char *options, *opt, *nextopt; + char *options, *opt, *nextopt, *arg, *val; options = calloc(strlen(orig_options) + 1, 1); *flagp = 0; @@ -264,7 +267,19 @@ int parse_options(char *orig_options, int *flagp) if (!*opt) /* empty option */ continue; - if (parse_one_option(opt, flagp) == 0) { + + /* Handle retries in a slightly different + * manner */ + arg = opt; + val = strchr(opt, '='); + if (val != NULL && strncmp(arg, "retry", 5) == 0) { + retry = atoi(val + 1); + if (retry > MAX_RETRIES) + retry = MAX_RETRIES; + else if (retry < 0) + retry = 0; + } + else if (parse_one_option(opt, flagp) == 0) { /* pass this on as an option */ if (*options) strcat(options, ","); @@ -324,7 +339,7 @@ int set_tunables(char *source, int src_len) ret_path = realpath(source, real_path); if (ret_path == NULL) { if (verbose) - fprintf(stderr, "warning: %s: cannot resolve: %s", + fprintf(stderr, "warning: %s: cannot resolve: %s\n", source, strerror(errno)); return -EINVAL; } @@ -574,11 +589,31 @@ int main(int argc, char *const argv[]) register_service_tags(usource, source, target); - if (!fake) + if (!fake) { /* flags and target get to lustre_get_sb, but not lustre_fill_super. Lustre ignores the flags, but mount does not. */ - rc = mount(source, target, "lustre", flags, (void *)optcopy); + for (i = 0, rc = -EAGAIN; i <= retry && rc != 0; i++) { + rc = mount(source, target, "lustre", flags, + (void *)optcopy); + if (rc) { + if (verbose) { + fprintf(stderr, "%s: mount %s at %s " + "failed: %s retries left: " + "%d\n", basename(progname), + usource, target, + strerror(errno), retry-i); + } + + if (retry) { + sleep(1 << max((i/2), 5)); + } + else { + rc = errno; + } + } + } + } if (rc) { char *cli;