X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lustre%2Futils%2Fmkfs_lustre.c;h=0e62785001c3c46ec65b1c6a23ab6b7ed9b76acd;hb=2e0ad6d40070d38076c77038b7d48ac90af7b130;hp=41f5b192418513106f541b4f18f5dbd982d9e678;hpb=c73162fd3537726ef187fe2fd5f926813f79578b;p=fs%2Flustre-release.git diff --git a/lustre/utils/mkfs_lustre.c b/lustre/utils/mkfs_lustre.c index 41f5b19..0e62785 100644 --- a/lustre/utils/mkfs_lustre.c +++ b/lustre/utils/mkfs_lustre.c @@ -26,7 +26,7 @@ * GPL HEADER END */ /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved + * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. */ /* @@ -62,12 +62,15 @@ #include #include #include +#include #ifdef __linux__ /* libcfs.h is not really needed here, but on SLES10/PPC, fs.h includes idr.h which * requires BITS_PER_LONG to be defined */ #include +#ifndef BLKGETSIZE64 #include /* for BLKGETSIZE64 */ +#endif #include #endif #include @@ -129,6 +132,7 @@ void usage(FILE *out) */ "\t\t--comment=: arbitrary user string (%d bytes)\n" "\t\t--mountfsoptions= : permanent mount options\n" + "\t\t--network=[,<...>] : network(s) to restrict this ost/mdt to\n" #ifndef TUNEFS "\t\t--backfstype= : backing fs type (ext3, ldiskfs)\n" "\t\t--device-size=#N(KB) : device size for loop devices\n" @@ -195,7 +199,12 @@ int get_os_version() fprintf(stderr, "%s: Warning: Can't resolve kernel " "version, assuming 2.6\n", progname); else { - read(fd, release, 4); + if (read(fd, release, 4) < 0) { + fprintf(stderr, "reading from /proc/sys/kernel" + "/osrelease: %s\n", strerror(errno)); + close(fd); + exit(-1); + } close(fd); } if (strncmp(release, "2.4.", 4) == 0) @@ -265,6 +274,10 @@ int loop_setup(struct mkfs_opts *mop) snprintf(cmd, cmdsz, "losetup %s %s", l_device, mop->mo_device); ret = run_command(cmd, cmdsz); + if (ret == 256) + /* someone else picked up this loop device + * behind our back */ + continue; if (ret) { fprintf(stderr, "%s: error %d on losetup: %s\n", progname, ret, strerror(ret)); @@ -504,28 +517,29 @@ static int is_e2fsprogs_feature_supp(const char *feature) return ret; } -static void disp_old_kernel_msg(char *feature) -{ - fprintf(stderr, "WARNING: ldiskfs filesystem does not support \"%s\" " - "feature.\n\n", feature); -} - static void enable_default_backfs_features(struct mkfs_opts *mop) { struct utsname uts; - int maj_high, maj_low, min; int ret; - strscat(mop->mo_mkfsopts, " -O dir_index", sizeof(mop->mo_mkfsopts)); + if (IS_OST(&mop->mo_ldd)) + strscat(mop->mo_mkfsopts, " -O dir_index,extents", + sizeof(mop->mo_mkfsopts)); + else if (IS_MDT(&mop->mo_ldd)) + strscat(mop->mo_mkfsopts, " -O dir_index,dirdata", + sizeof(mop->mo_mkfsopts)); + else + strscat(mop->mo_mkfsopts, " -O dir_index", + sizeof(mop->mo_mkfsopts)); /* Upstream e2fsprogs called our uninit_groups feature uninit_bg, * check for both of them when testing e2fsprogs features. */ - if (is_e2fsprogs_feature_supp("uninit_groups") == 0) - strscat(mop->mo_mkfsopts, ",uninit_groups", - sizeof(mop->mo_mkfsopts)); - else if (is_e2fsprogs_feature_supp("uninit_bg") == 0) + if (is_e2fsprogs_feature_supp("uninit_bg") == 0) strscat(mop->mo_mkfsopts, ",uninit_bg", sizeof(mop->mo_mkfsopts)); + else if (is_e2fsprogs_feature_supp("uninit_groups") == 0) + strscat(mop->mo_mkfsopts, ",uninit_groups", + sizeof(mop->mo_mkfsopts)); else disp_old_e2fsprogs_msg("uninit_bg", 1); @@ -533,32 +547,37 @@ static void enable_default_backfs_features(struct mkfs_opts *mop) if (ret) return; - sscanf(uts.release, "%d.%d.%d", &maj_high, &maj_low, &min); - printf("%d %d %d\n", maj_high, maj_low, min); - /* Multiple mount protection is enabled only if failover node is * specified and if kernel version is higher than 2.6.9 */ if (failover) { - if (KERNEL_VERSION(maj_high, maj_low, min) >= - KERNEL_VERSION(2,6,9)) { - if (is_e2fsprogs_feature_supp("mmp") == 0) - strscat(mop->mo_mkfsopts, ",mmp", - sizeof(mop->mo_mkfsopts)); - else - disp_old_e2fsprogs_msg("mmp", 1); - } else { - disp_old_kernel_msg("mmp"); - } + if (is_e2fsprogs_feature_supp("mmp") == 0) + strscat(mop->mo_mkfsopts, ",mmp", + sizeof(mop->mo_mkfsopts)); + else + disp_old_e2fsprogs_msg("mmp", 1); } } /* Build fs according to type */ int make_lustre_backfs(struct mkfs_opts *mop) { + __u64 device_sz = mop->mo_device_sz, block_count = 0; char mkfs_cmd[PATH_MAX]; char buf[64]; char *dev; int ret = 0; - int block_count = 0; + + if (!(mop->mo_flags & MO_IS_LOOP)) { + mop->mo_device_sz = get_device_size(mop->mo_device); + + if (mop->mo_device_sz == 0) + return ENODEV; + + /* Compare to real size */ + if (device_sz == 0 || device_sz > mop->mo_device_sz) + device_sz = mop->mo_device_sz; + else + mop->mo_device_sz = device_sz; + } if (mop->mo_device_sz != 0) { if (mop->mo_device_sz < 8096){ @@ -568,20 +587,16 @@ int make_lustre_backfs(struct mkfs_opts *mop) return EINVAL; } block_count = mop->mo_device_sz / (L_BLOCK_SIZE >> 10); + /* If the LUN size is just over 2^32 blocks, limit the + * filesystem size to 2^32-1 blocks to avoid problems with + * ldiskfs/mkfs not handling this size. Bug 22906 */ + if (block_count > 0xffffffffULL && block_count < 0x100002000ULL) + block_count = 0xffffffffULL; } if ((mop->mo_ldd.ldd_mount_type == LDD_MT_EXT3) || (mop->mo_ldd.ldd_mount_type == LDD_MT_LDISKFS) || (mop->mo_ldd.ldd_mount_type == LDD_MT_LDISKFS2)) { - __u64 device_sz = mop->mo_device_sz; - - /* we really need the size */ - if (device_sz == 0) { - device_sz = get_device_size(mop->mo_device); - if (device_sz == 0) - return ENODEV; - } - /* Journal size in MB */ if (strstr(mop->mo_mkfsopts, "-J") == NULL) { /* Choose our own default journal size */ @@ -689,7 +704,7 @@ int make_lustre_backfs(struct mkfs_opts *mop) vprint("formatting backing filesystem %s on %s\n", MT_STR(&mop->mo_ldd), dev); vprint("\ttarget name %s\n", mop->mo_ldd.ldd_svname); - vprint("\t4k blocks %d\n", block_count); + vprint("\t4k blocks "LPU64"\n", block_count); vprint("\toptions %s\n", mop->mo_mkfsopts); /* mkfs_cmd's trailing space is important! */ @@ -697,7 +712,7 @@ int make_lustre_backfs(struct mkfs_opts *mop) strscat(mkfs_cmd, " ", sizeof(mkfs_cmd)); strscat(mkfs_cmd, dev, sizeof(mkfs_cmd)); if (block_count != 0) { - sprintf(buf, " %d", block_count); + sprintf(buf, " "LPU64, block_count); strscat(mkfs_cmd, buf, sizeof(mkfs_cmd)); } @@ -811,6 +826,7 @@ int write_local_files(struct mkfs_opts *mop) char *dev; FILE *filep; int ret = 0; + size_t num; /* Mount this device temporarily in order to write these files */ if (!mkdtemp(mntpt)) { @@ -823,7 +839,8 @@ int write_local_files(struct mkfs_opts *mop) if (mop->mo_flags & MO_IS_LOOP) dev = mop->mo_loopdev; - ret = mount(dev, mntpt, MT_STR(&mop->mo_ldd), 0, NULL); + ret = mount(dev, mntpt, MT_STR(&mop->mo_ldd), 0, + mop->mo_ldd.ldd_mount_opts); if (ret) { fprintf(stderr, "%s: Unable to mount %s: %s\n", progname, dev, strerror(errno)); @@ -856,7 +873,12 @@ int write_local_files(struct mkfs_opts *mop) progname, filepnm, strerror(errno)); goto out_umnt; } - fwrite(&mop->mo_ldd, sizeof(mop->mo_ldd), 1, filep); + num = fwrite(&mop->mo_ldd, sizeof(mop->mo_ldd), 1, filep); + if (num < 1 && ferror(filep)) { + fprintf(stderr, "%s: Unable to write to file (%s): %s\n", + progname, filepnm, strerror(errno)); + goto out_umnt; + } fclose(filep); /* COMPAT_146 */ #ifdef TUNEFS @@ -961,8 +983,14 @@ int read_local_files(struct mkfs_opts *mop) sprintf(filepnm, "%s/mountdata", tmpdir); filep = fopen(filepnm, "r"); if (filep) { + size_t num_read; vprint("Reading %s\n", MOUNT_DATA_FILE); - fread(&mop->mo_ldd, sizeof(mop->mo_ldd), 1, filep); + num_read = fread(&mop->mo_ldd, sizeof(mop->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 { /* COMPAT_146 */ /* Try to read pre-1.6 config from last_rcvd */ @@ -1191,6 +1219,7 @@ int parse_opts(int argc, char *const argv[], struct mkfs_opts *mop, {"verbose", 0, 0, 'v'}, {"writeconf", 0, 0, 'w'}, {"upgrade_to_18", 0, 0, 'U'}, + {"network", 1, 0, 't'}, {0, 0, 0, 0} }; char *optstring = "b:c:C:d:ef:Ghi:k:L:m:MnNo:Op:Pqru:vw"; @@ -1346,6 +1375,22 @@ int parse_opts(int argc, char *const argv[], struct mkfs_opts *mop, case 'r': mop->mo_flags |= MO_FORCEFORMAT; break; + case 't': + if (!IS_MDT(&mop->mo_ldd) && !IS_OST(&mop->mo_ldd)) { + badopt(long_opt[longidx].name, "MDT,OST"); + return 1; + } + + if (!optarg) + return 1; + + rc = add_param(mop->mo_ldd.ldd_params, + PARAM_NETWORK, optarg); + if (rc != 0) + return rc; + /* Must update the mgs logs */ + mop->mo_ldd.ldd_flags |= LDD_F_UPDATE; + break; case 'u': strscpy(mop->mo_ldd.ldd_userdata, optarg, sizeof(mop->mo_ldd.ldd_userdata)); @@ -1382,6 +1427,76 @@ int parse_opts(int argc, char *const argv[], struct mkfs_opts *mop, return 0; } +/* Search for opt in mntlist, returning true if found. + */ +static int in_mntlist(char *opt, char *mntlist) +{ + char *ml, *mlp, *item, *ctx = NULL; + + if (!(ml = strdup(mntlist))) { + fprintf(stderr, "%s: out of memory\n", progname); + exit(1); + } + mlp = ml; + while ((item = strtok_r(mlp, ",", &ctx))) { + if (!strcmp(opt, item)) + break; + mlp = NULL; + } + free(ml); + return (item != NULL); +} + +/* Issue a message on stderr for every item in wanted_mountopts that is not + * present in mountopts. The justwarn boolean toggles between error and + * warning message. Return an error count. + */ +static int check_mountfsoptions(char *mountopts, char *wanted_mountopts, + int justwarn) +{ + char *ml, *mlp, *item, *ctx = NULL; + int errors = 0; + + if (!(ml = strdup(wanted_mountopts))) { + fprintf(stderr, "%s: out of memory\n", progname); + exit(1); + } + mlp = ml; + while ((item = strtok_r(mlp, ",", &ctx))) { + if (!in_mntlist(item, mountopts)) { + fprintf(stderr, "%s: %s mount option `%s' is missing\n", + progname, justwarn ? "Warning: default" + : "Error: mandatory", item); + errors++; + } + mlp = NULL; + } + free(ml); + return errors; +} + +/* Trim embedded white space, leading and trailing commas from string s. + */ +static void trim_mountfsoptions(char *s) +{ + char *p; + + for (p = s; *p; ) { + if (isspace(*p)) { + memmove(p, p + 1, strlen(p + 1) + 1); + continue; + } + p++; + } + + while (s[0] == ',') + memmove(&s[0], &s[1], strlen(&s[1]) + 1); + + p = s + strlen(s) - 1; + while (p >= s && *p == ',') + *p-- = '\0'; +} + int main(int argc, char *const argv[]) { struct mkfs_opts mop; @@ -1496,7 +1611,8 @@ int main(int argc, char *const argv[]) case LDD_MT_EXT3: case LDD_MT_LDISKFS: case LDD_MT_LDISKFS2: { - sprintf(always_mountopts, "errors=remount-ro"); + strscat(default_mountopts, ",errors=remount-ro", + sizeof(default_mountopts)); if (IS_MDT(ldd) || IS_MGS(ldd)) strscat(always_mountopts, ",iopen_nopriv,user_xattr", sizeof(always_mountopts)); @@ -1516,7 +1632,7 @@ int main(int argc, char *const argv[]) } case LDD_MT_SMFS: { mop.mo_flags |= MO_IS_LOOP; - sprintf(always_mountopts, "type=ext3,dev=%s", + sprintf(always_mountopts, ",type=ext3,dev=%s", mop.mo_device); break; } @@ -1531,10 +1647,13 @@ int main(int argc, char *const argv[]) } if (mountopts) { - /* If user specifies mount opts, don't use defaults, - but always use always_mountopts */ - sprintf(ldd->ldd_mount_opts, "%s,%s", - always_mountopts, mountopts); + trim_mountfsoptions(mountopts); + (void)check_mountfsoptions(mountopts, default_mountopts, 1); + if (check_mountfsoptions(mountopts, always_mountopts, 0)) { + ret = EINVAL; + goto out; + } + sprintf(ldd->ldd_mount_opts, "%s", mountopts); } else { #ifdef TUNEFS if (ldd->ldd_mount_opts[0] == 0) @@ -1543,6 +1662,7 @@ int main(int argc, char *const argv[]) { sprintf(ldd->ldd_mount_opts, "%s%s", always_mountopts, default_mountopts); + trim_mountfsoptions(ldd->ldd_mount_opts); } }