- glob_t glob_info = { 0 };
- struct stat stat_buf;
- char *chk_major, *chk_minor;
- char *savept, *dev;
- char *ret_path;
- char buf[PATH_MAX] = {'\0'}, path[PATH_MAX] = {'\0'};
- char real_path[PATH_MAX] = {'\0'};
- int i, rc = 0;
- int major, minor;
-
- if (!source)
- return -EINVAL;
-
- ret_path = realpath(source, real_path);
- if (ret_path == NULL) {
- if (verbose)
- fprintf(stderr, "warning: %s: cannot resolve: %s\n",
- source, strerror(errno));
- return -EINVAL;
- }
-
- if (strncmp(real_path, "/dev/loop", 9) == 0)
- return 0;
-
- if ((real_path[0] != '/') && (strpbrk(real_path, ",:") != NULL))
- return 0;
-
- snprintf(path, sizeof(path), "/sys/block%s", real_path + 4);
- if (access(path, X_OK) == 0)
- goto set_params;
-
- /* The name of the device say 'X' specified in /dev/X may not
- * match any entry under /sys/block/. In that case we need to
- * match the major/minor number to find the entry under
- * sys/block corresponding to /dev/X */
-
- /* Don't chop tail digit on /dev/mapper/xxx, LU-478 */
- if (strncmp(real_path, "/dev/mapper", 11) != 0) {
- dev = real_path + strlen(real_path);
- while (--dev > real_path && isdigit(*dev))
- *dev = 0;
-
- if (strncmp(real_path, "/dev/md_", 8) == 0)
- *dev = 0;
- }
-
- rc = stat(real_path, &stat_buf);
- if (rc) {
- if (verbose)
- fprintf(stderr, "warning: %s, device %s stat failed\n",
- strerror(errno), real_path);
- return rc;
- }
-
- major = major(stat_buf.st_rdev);
- minor = minor(stat_buf.st_rdev);
- rc = glob("/sys/block/*", GLOB_NOSORT, NULL, &glob_info);
- if (rc) {
- if (verbose)
- fprintf(stderr, "warning: failed to read entries under "
- "/sys/block\n");
- globfree(&glob_info);
- return rc;
- }
-
- for (i = 0; i < glob_info.gl_pathc; i++){
- snprintf(path, sizeof(path), "%s/dev", glob_info.gl_pathv[i]);
-
- rc = read_file(path, buf, sizeof(buf));
- if (rc)
- continue;
-
- if (buf[strlen(buf) - 1] == '\n')
- buf[strlen(buf) - 1] = '\0';
-
- chk_major = strtok_r(buf, ":", &savept);
- chk_minor = savept;
- if (major == atoi(chk_major) &&minor == atoi(chk_minor))
- break;
- }
-
- if (i == glob_info.gl_pathc) {
- if (verbose)
- fprintf(stderr,"warning: device %s does not match any "
- "entry under /sys/block\n", real_path);
- globfree(&glob_info);
- return -EINVAL;
- }
-
- /* Chop off "/dev" from path we found */
- path[strlen(glob_info.gl_pathv[i])] = '\0';
- globfree(&glob_info);
-
-set_params:
- if (strncmp(real_path, "/dev/md", 7) == 0) {
- snprintf(real_path, sizeof(real_path), "%s/%s", path,
- STRIPE_CACHE_SIZE);
-
- rc = read_file(real_path, buf, sizeof(buf));
- if (rc) {
- if (verbose)
- fprintf(stderr, "warning: opening %s: %s\n",
- real_path, strerror(errno));
- return 0;
- }
-
- if (atoi(buf) >= md_stripe_cache_size)
- return 0;
-
- if (strlen(buf) - 1 > 0) {
- snprintf(buf, sizeof(buf), "%d", md_stripe_cache_size);
- rc = write_file(real_path, buf);
- if (rc && verbose)
- fprintf(stderr, "warning: opening %s: %s\n",
- real_path, strerror(errno));
- }
- /* Return since raid and disk tunables are different */
- return rc;
- }
-
- snprintf(real_path, sizeof(real_path), "%s/%s", path,
- MAX_HW_SECTORS_KB_PATH);
- rc = read_file(real_path, buf, sizeof(buf));
- if (rc) {
- if (verbose)
- fprintf(stderr, "warning: opening %s: %s\n",
- real_path, strerror(errno));
- /* No MAX_HW_SECTORS_KB_PATH isn't necessary an
- * error for some device. */
- rc = 0;
- }
-
- if (strlen(buf) - 1 > 0) {
- snprintf(real_path, sizeof(real_path), "%s/%s", path,
- MAX_SECTORS_KB_PATH);
- rc = write_file(real_path, buf);
- if (rc) {
- if (verbose)
- fprintf(stderr, "warning: writing to %s: %s\n",
- real_path, strerror(errno));
- /* No MAX_SECTORS_KB_PATH isn't necessary an
- * error for some device. */
- rc = 0;
- }
- }
+ struct lustre_disk_data *ldd = &mop->mo_ldd;
+ char *cur, *start;
+ int rc = 0;
+
+ rc = osd_is_lustre(source, &ldd->ldd_mount_type);
+ if (rc == 0) {
+ fprintf(stderr, "%s: %s has not been formatted with mkfs.lustre"
+ " or the backend filesystem type is not supported by "
+ "this tool\n", progname, source);
+ return ENODEV;
+ }
+
+ rc = osd_read_ldd(source, ldd);
+ if (rc) {
+ fprintf(stderr, "%s: %s failed to read permanent mount"
+ " data: %s\n", progname, source,
+ rc >= 0 ? strerror(rc) : "");
+ return rc;
+ }
+
+ if ((IS_MDT(ldd) || IS_OST(ldd)) &&
+ (ldd->ldd_flags & LDD_F_NEED_INDEX)) {
+ fprintf(stderr, "%s: %s has no index assigned "
+ "(probably formatted with old mkfs)\n",
+ progname, source);
+ return EINVAL;
+ }
+
+ if (ldd->ldd_flags & LDD_F_UPGRADE14) {
+ fprintf(stderr, "%s: we cannot upgrade %s from this (very old) "
+ "Lustre version\n", progname, source);
+ return EINVAL;
+ }
+
+ if (ldd->ldd_flags & LDD_F_UPDATE)
+ clear_update_ondisk(source, ldd);
+
+ /* Since we never rewrite ldd, ignore temp flags */
+ ldd->ldd_flags &= ~(LDD_F_VIRGIN | LDD_F_WRITECONF);
+
+ /* svname of the form lustre:OST1234 means never registered */
+ rc = strlen(ldd->ldd_svname);
+ if (strcmp(ldd->ldd_svname, "MGS") != 0) {
+ if (rc < 8) {
+ fprintf(stderr, "%s: invalid name '%s'\n",
+ progname, ldd->ldd_svname);
+ return EINVAL;
+ } else if (ldd->ldd_svname[rc - 8] == ':') {
+ ldd->ldd_svname[rc - 8] = '-';
+ ldd->ldd_flags |= LDD_F_VIRGIN;
+ } else if (ldd->ldd_svname[rc - 8] == '=') {
+ ldd->ldd_svname[rc - 8] = '-';
+ ldd->ldd_flags |= LDD_F_WRITECONF;
+ }
+ }
+ /* backend osd type */
+ rc = append_option(options, options_len, "osd=",
+ mt_type(ldd->ldd_mount_type));
+ if (rc != 0)
+ return rc;
+
+ rc = append_option(options, options_len, ldd->ldd_mount_opts, NULL);
+ if (rc != 0)
+ return rc;
+
+ if (!mop->mo_have_mgsnid) {
+ /* Only use disk data if mount -o mgsnode=nid wasn't
+ * specified */
+ if (ldd->ldd_flags & LDD_F_SV_TYPE_MGS) {
+ rc = append_option(options, options_len, "mgs", NULL);
+ if (rc != 0)
+ return rc;
+ mop->mo_have_mgsnid++;
+ } else {
+ if (add_mgsnids(mop, options, ldd->ldd_params,
+ options_len))
+ return E2BIG;
+ }
+ }
+ /* Better have an mgsnid by now */
+ if (!mop->mo_have_mgsnid) {
+ fprintf(stderr, "%s: missing option mgsnode=<nid>\n",
+ progname);
+ return EINVAL;
+ }
+
+ if (ldd->ldd_flags & LDD_F_VIRGIN) {
+ rc = append_option(options, options_len, "virgin", NULL);
+ if (rc != 0)
+ return rc;
+ }
+ if (ldd->ldd_flags & LDD_F_UPDATE) {
+ rc = append_option(options, options_len, "update", NULL);
+ if (rc != 0)
+ return rc;
+ }
+ if (ldd->ldd_flags & LDD_F_WRITECONF) {
+ rc = append_option(options, options_len, "writeconf", NULL);
+ if (rc != 0)
+ return rc;
+ }
+ if (ldd->ldd_flags & LDD_F_NO_PRIMNODE) {
+ rc = append_option(options, options_len, "noprimnode", NULL);
+ if (rc != 0)
+ return rc;
+ }
+
+ /* prefix every lustre parameter with param= so that in-kernel
+ * mount can recognize them properly and send to MGS at registration */
+ start = ldd->ldd_params;
+ while (start && *start != '\0') {
+ while (*start == ' ') start++;
+ if (*start == '\0')
+ break;
+ cur = start;
+ start = strchr(cur, ' ');
+ if (start) {
+ *start = '\0';
+ start++;
+ }
+ rc = append_option(options, options_len, "param=", cur);
+ if (rc != 0)
+ return rc;
+ }
+
+ /* svname must be last option */
+ rc = append_option(options, options_len, "svname=", ldd->ldd_svname);
+
+ return rc;
+}