Whamcloud - gitweb
Branch HEAD
[fs/lustre-release.git] / lustre / utils / mount_lustre.c
index 385cd6c..e41a1c2 100644 (file)
 
 #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);
 }
@@ -256,7 +259,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;
@@ -265,7 +268,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, ",");
@@ -325,7 +340,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;
         }
@@ -575,11 +590,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;