static int parse_ldd(char *source, struct mount_opts *mop, char *options) { struct lustre_disk_data *ldd = &mop->mo_ldd; char *cur, *start; int rc; 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 */ append_option(options, "osd="); strcat(options, mt_type(ldd->ldd_mount_type)); append_option(options, ldd->ldd_mount_opts); 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) { append_option(options, "mgs"); mop->mo_have_mgsnid++; } else { add_mgsnids(mop, options, ldd->ldd_params); } } /* 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) append_option(options, "virgin"); if (ldd->ldd_flags & LDD_F_UPDATE) append_option(options, "update"); if (ldd->ldd_flags & LDD_F_WRITECONF) append_option(options, "writeconf"); if (ldd->ldd_flags & LDD_F_NO_PRIMNODE) append_option(options, "noprimnode"); /* 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++; } append_option(options, "param="); strcat(options, cur); } /* svname must be last option */ append_option(options, "svname="); strcat(options, ldd->ldd_svname); return 0; }
int main(int argc, char *const argv[]) { struct mkfs_opts mop; struct lustre_disk_data *ldd = &mop.mo_ldd; char *mountopts = NULL; char wanted_mountopts[512] = ""; unsigned mount_type; int ret = 0; int ret2 = 0; progname = strrchr(argv[0], '/'); if (progname != NULL) progname++; else progname = argv[0]; if ((argc < 2) || (argv[argc - 1][0] == '-')) { usage(stderr); return EINVAL; } memset(&mop, 0, sizeof(mop)); set_defaults(&mop); /* device is last arg */ strscpy(mop.mo_device, argv[argc - 1], sizeof(mop.mo_device)); ret = osd_init(); if (ret != 0) return ret; #ifdef TUNEFS /* For tunefs, we must read in the old values before parsing any new ones. */ /* Check whether the disk has already been formatted by mkfs.lustre */ ret = osd_is_lustre(mop.mo_device, &mount_type); if (ret == 0) { fatal(); fprintf(stderr, "Device %s has not been formatted with " "mkfs.lustre\n", mop.mo_device); ret = ENODEV; goto out; } ldd->ldd_mount_type = mount_type; ret = osd_read_ldd(mop.mo_device, ldd); if (ret != 0) { fatal(); fprintf(stderr, "Failed to read previous Lustre data from %s " "(%d)\n", mop.mo_device, ret); goto out; } ldd->ldd_flags &= ~(LDD_F_WRITECONF | LDD_F_VIRGIN); /* svname of the form lustre:OST1234 means never registered */ ret = strlen(ldd->ldd_svname); if (ldd->ldd_svname[ret - 8] == ':') { ldd->ldd_svname[ret - 8] = '-'; ldd->ldd_flags |= LDD_F_VIRGIN; } else if (ldd->ldd_svname[ret - 8] == '=') { ldd->ldd_svname[ret - 8] = '-'; ldd->ldd_flags |= LDD_F_WRITECONF; } if (strstr(ldd->ldd_params, PARAM_MGSNODE)) mop.mo_mgs_failnodes++; if (verbose > 0) print_ldd("Read previous values", ldd); #endif /* TUNEFS */ ret = parse_opts(argc, argv, &mop, &mountopts); if (ret != 0 || version) goto out; if (!IS_MDT(ldd) && !IS_OST(ldd) && !IS_MGS(ldd)) { fatal(); fprintf(stderr, "must set target type: MDT,OST,MGS\n"); ret = EINVAL; goto out; } if (((IS_MDT(ldd) || IS_MGS(ldd))) && IS_OST(ldd)) { fatal(); fprintf(stderr, "OST type is exclusive with MDT,MGS\n"); ret = EINVAL; goto out; } /* Stand alone MGS doesn't need an index */ if (!IS_MDT(ldd) && IS_MGS(ldd)) { #ifndef TUNEFS /* But if --index was specified flag an error */ if (!(ldd->ldd_flags & LDD_F_NEED_INDEX)) { badopt("index", "MDT,OST"); goto out; } #endif ldd->ldd_flags &= ~LDD_F_NEED_INDEX; } if ((ldd->ldd_flags & (LDD_F_NEED_INDEX | LDD_F_UPGRADE14)) == (LDD_F_NEED_INDEX | LDD_F_UPGRADE14)) { fatal(); fprintf(stderr, "Can't find the target index, " "specify with --index\n"); ret = EINVAL; goto out; } if (ldd->ldd_flags & LDD_F_NEED_INDEX) fprintf(stderr, "warning: %s: for Lustre 2.4 and later, the " "target index must be specified with --index\n", mop.mo_device); /* If no index is supplied for MDT by default set index to zero */ if (IS_MDT(ldd) && (ldd->ldd_svindex == INDEX_UNASSIGNED)) { ldd->ldd_flags &= ~LDD_F_NEED_INDEX; ldd->ldd_svindex = 0; } if (!IS_MGS(ldd) && (mop.mo_mgs_failnodes == 0)) { fatal(); if (IS_MDT(ldd)) fprintf(stderr, "Must specify --mgs or --mgsnode\n"); else fprintf(stderr, "Must specify --mgsnode\n"); ret = EINVAL; goto out; } if ((IS_MDT(ldd) || IS_OST(ldd)) && ldd->ldd_fsname[0] == '\0') { fatal(); fprintf(stderr, "Must specify --fsname for MDT/OST device\n"); ret = EINVAL; goto out; } /* These are the permanent mount options (always included) */ ret = osd_prepare_lustre(&mop, wanted_mountopts, sizeof(wanted_mountopts)); if (ret != 0) { fatal(); fprintf(stderr, "unable to prepare backend (%d)\n", ret); goto out; } if (mountopts) { trim_mountfsoptions(mountopts); if (check_mountfsoptions(mountopts, wanted_mountopts)) { ret = EINVAL; goto out; } snprintf(ldd->ldd_mount_opts, sizeof(ldd->ldd_mount_opts), "%s", mountopts); } else { #ifdef TUNEFS if (ldd->ldd_mount_opts[0] == 0) /* use the defaults unless old opts exist */ #endif { snprintf(ldd->ldd_mount_opts, sizeof(ldd->ldd_mount_opts), "%s", wanted_mountopts); trim_mountfsoptions(ldd->ldd_mount_opts); } } ret = osd_fix_mountopts(&mop, ldd->ldd_mount_opts, sizeof(ldd->ldd_mount_opts)); if (ret != 0) { fatal(); fprintf(stderr, "unable to fix mountfsoptions (%d)\n", ret); goto out; } server_make_name(ldd->ldd_flags, ldd->ldd_svindex, ldd->ldd_fsname, ldd->ldd_svname); if (verbose >= 0) print_ldd("Permanent disk data", ldd); if (print_only) { printf("exiting before disk write.\n"); goto out; } if (check_mtab_entry(mop.mo_device, mop.mo_device, NULL, NULL)) return(EEXIST); /* Create the loopback file */ if (mop.mo_flags & MO_IS_LOOP) { ret = access(mop.mo_device, F_OK); if (ret != 0) ret = errno; #ifndef TUNEFS /* Reformat the loopback file */ if (ret != 0 || (mop.mo_flags & MO_FORCEFORMAT)) { ret = loop_format(&mop); if (ret != 0) goto out; } #endif if (ret == 0) ret = loop_setup(&mop); if (ret != 0) { fatal(); fprintf(stderr, "Loop device setup for %s failed: %s\n", mop.mo_device, strerror(ret)); goto out; } } #ifndef TUNEFS /* Check whether the disk has already been formatted by mkfs.lustre */ if (!(mop.mo_flags & MO_FORCEFORMAT)) { ret = osd_is_lustre(mop.mo_device, &mount_type); if (ret != 0) { fatal(); fprintf(stderr, "Device %s was previously formatted " "for lustre. Use --reformat to reformat it, " "or tunefs.lustre to modify.\n", mop.mo_device); goto out; } } /* Format the backing filesystem */ ret = osd_make_lustre(&mop); if (ret != 0) { fatal(); fprintf(stderr, "mkfs failed %d\n", ret); goto out; } #else /* !TUNEFS */ /* update svname with '=' to refresh config */ if (ldd->ldd_flags & LDD_F_WRITECONF) { struct mount_opts opts; opts.mo_ldd = *ldd; opts.mo_source = mop.mo_device; (void) osd_label_lustre(&opts); } /* Enable quota accounting */ if (mop.mo_flags & MO_QUOTA) { ret = osd_enable_quota(&mop); goto out; } #endif /* !TUNEFS */ /* Write our config files */ ret = osd_write_ldd(&mop); if (ret != 0) { fatal(); fprintf(stderr, "failed to write local files\n"); goto out; } out: osd_fini(); ret2 = loop_cleanup(&mop); if (ret == 0) ret = ret2; /* Fix any crazy return values from system() */ if (ret != 0 && ((ret & 255) == 0)) return 1; if (ret != 0) verrprint("%s: exiting with %d (%s)\n", progname, ret, strerror(ret)); return ret; }