int ldiskfs_read_ldd(char *dev, struct lustre_disk_data *mo_ldd) { char tmpdir[] = "/tmp/dirXXXXXX"; char cmd[PATH_MAX]; char filepnm[128]; FILE *filep; int ret = 0; int cmdsz = sizeof(cmd); /* Make a temporary directory to hold Lustre data files. */ if (!mkdtemp(tmpdir)) { fprintf(stderr, "%s: Can't create temporary directory %s: %s\n", progname, tmpdir, strerror(errno)); return errno; } /* TODO: it's worth observing the get_mountdata() function that is in mount_utils.c for getting the mountdata out of the filesystem */ /* Construct debugfs command line. */ snprintf(cmd, cmdsz, "%s -c -R 'dump /%s %s/mountdata' '%s'", DEBUGFS, MOUNT_DATA_FILE, tmpdir, dev); ret = run_command(cmd, cmdsz); if (ret) verrprint("%s: Unable to dump %s dir (%d)\n", progname, MOUNT_CONFIGS_DIR, ret); sprintf(filepnm, "%s/mountdata", tmpdir); filep = fopen(filepnm, "r"); if (filep) { size_t num_read; vprint("Reading %s\n", MOUNT_DATA_FILE); num_read = fread(mo_ldd, sizeof(*mo_ldd), 1, filep); if (num_read < 1 && ferror(filep)) { fprintf(stderr, "%s: Unable to read from file %s: %s\n", progname, filepnm, strerror(errno)); } fclose(filep); } snprintf(cmd, cmdsz, "rm -rf %s", tmpdir); run_command(cmd, cmdsz); if (ret) verrprint("Failed to read old data (%d)\n", ret); /* As long as we at least have the label, we're good to go */ snprintf(cmd, sizeof(cmd), E2LABEL" %s", dev); ret = readcmd(cmd, mo_ldd->ldd_svname, sizeof(mo_ldd->ldd_svname) - 1); return ret; }
void errprint(char *fmt, ...) { va_list ap; va_start(ap, fmt); verrprint(fmt, ap); va_end(ap); }
int get_mountdata(char *dev, struct lustre_disk_data *mo_ldd) { char tmpdir[] = "/tmp/lustre_tmp.XXXXXX"; char cmd[256]; char filepnm[128]; FILE *filep; int ret = 0; int ret2 = 0; int cmdsz = sizeof(cmd); /* Make a temporary directory to hold Lustre data files. */ if (!mkdtemp(tmpdir)) { verrprint("%s: Can't create temporary directory %s: %s\n", progname, tmpdir, strerror(errno)); return errno; } snprintf(cmd, cmdsz, "%s -c -R 'dump /%s %s/mountdata' %s", DEBUGFS, MOUNT_DATA_FILE, tmpdir, dev); ret = run_command(cmd, cmdsz); if (ret) { verrprint("%s: Unable to dump %s dir (%d)\n", progname, MOUNT_CONFIGS_DIR, ret); goto out_rmdir; } sprintf(filepnm, "%s/mountdata", tmpdir); filep = fopen(filepnm, "r"); if (filep) { size_t num_read; vprint("Reading %s\n", MOUNT_DATA_FILE); num_read = fread(mo_ldd, sizeof(*mo_ldd), 1, filep); if (num_read < 1 && ferror(filep)) { fprintf(stderr, "%s: Unable to read from file (%s): %s\n", progname, filepnm, strerror(errno)); goto out_close; } } else { verrprint("%s: Unable to read %d.%d config %s.\n", progname, LUSTRE_MAJOR, LUSTRE_MINOR, filepnm); ret = 1; goto out_rmdir; } out_close: fclose(filep); out_rmdir: snprintf(cmd, cmdsz, "rm -rf %s", tmpdir); ret2 = run_command(cmd, cmdsz); if (ret2) { verrprint("Failed to remove temp dir %s (%d)\n", tmpdir, ret2); /* failure return from run_command() is more important * than the failure to remove a dir */ if (!ret) ret = ret2; } return ret; }
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; }