mkfs_lustre.c

来自「lustre 1.6.5 source code」· C语言 代码 · 共 1,598 行 · 第 1/4 页

C
1,598
字号
        fprintf(stderr, "WARNING: The e2fsprogs package currently installed on "                "your system does not support \"%s\" feature.\nPlease install "                "the latest version of e2fsprogs from http://www.clusterfs.com/"                "downloads/public/Lustre/Tools/e2fsprogs/\nto enable this "                "feature.\n", feature);        if (make_backfs)                fprintf(stderr, "Feature will not be enabled until e2fsprogs "                        "is updated and 'tune2fs -O %s %%{device}' "                        "is run.\n\n", feature);}/* Check whether the file exists in the device */static int file_in_dev(char *file_name, char *dev_name){        FILE *fp;        char debugfs_cmd[256];        unsigned int inode_num;        int i;        /* Construct debugfs command line. */        snprintf(debugfs_cmd, sizeof(debugfs_cmd),                "debugfs -c -R 'stat %s' %s 2>&1 | egrep '(Inode|unsupported)'",                file_name, dev_name);        fp = popen(debugfs_cmd, "r");        if (!fp) {                fprintf(stderr, "%s: %s\n", progname, strerror(errno));                return 0;        }        if (fscanf(fp, "Inode: %u", &inode_num) == 1) { /* exist */                pclose(fp);                return 1;        }        i = fread(debugfs_cmd, 1, sizeof(debugfs_cmd), fp);        if (i) {                debugfs_cmd[i] = 0;                fprintf(stderr, "%s", debugfs_cmd);                if (strstr(debugfs_cmd, "unsupported feature")) {                        disp_old_e2fsprogs_msg("an unknown", 0);                }                return -1;        }        pclose(fp);        return 0;}/* Check whether the device has already been used with lustre */static int is_lustre_target(struct mkfs_opts *mop){        int rc;        vprint("checking for existing Lustre data: ");        if ((rc = file_in_dev(MOUNT_DATA_FILE, mop->mo_device))) {                vprint("found %s\n",                       (rc == 1) ? MOUNT_DATA_FILE : "extents");                 /* in the -1 case, 'extents' means this really IS a lustre                    target */                return rc;        }        if ((rc = file_in_dev(LAST_RCVD, mop->mo_device))) {                vprint("found %s\n", LAST_RCVD);                return rc;        }        vprint("not found\n");        return 0; /* The device is not a lustre target. */}/* Check if a certain feature is supported by e2fsprogs. * Firstly we try to use "debugfs supported_features" command to check if * the feature is supported. If this fails we try to set this feature with * mke2fs to check for its support. */static int is_e2fsprogs_feature_supp(const char *feature){        FILE *fp;        char cmd[PATH_MAX];        char imgname[] = "/tmp/test-img-XXXXXX";        int fd = -1;        int ret = 0;        snprintf(cmd, sizeof(cmd),                 "debugfs -c -R \"supported_features %s\" 2>&1", feature);        /* Using popen() instead of run_command() since debugfs does not return         * proper error code if command is not supported */        fp = popen(cmd, "r");        if (!fp) {                fprintf(stderr, "%s: %s\n", progname, strerror(errno));                return 0;        }        ret = fread(cmd, 1, sizeof(cmd), fp);        if (ret > 0) {                if (strstr(cmd, feature) && !(strstr(cmd, "Unknown")))                        return 0;        }        if ((fd = mkstemp(imgname)) < 0)                return -1;        snprintf(cmd, sizeof(cmd), "mke2fs -F -O %s %s 100 >/dev/null 2>&1",                 feature, imgname);        /* run_command() displays the output of mke2fs when it fails for         * some feature, so use system() directly */        ret = system(cmd);        if (fd >= 0)                remove(imgname);        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_e2fsprogs_feature_supp("uninit_groups") == 0)                strscat(mop->mo_mkfsopts, ",uninit_groups",                        sizeof(mop->mo_mkfsopts));        else                disp_old_e2fsprogs_msg("uninit_groups", 1);        ret = uname(&uts);        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");                }        }}/* Build fs according to type */int make_lustre_backfs(struct mkfs_opts *mop){        char mkfs_cmd[PATH_MAX];        char buf[64];        char *dev;        int ret = 0;        int block_count = 0;        if (mop->mo_device_sz != 0) {                if (mop->mo_device_sz < 8096){                        fprintf(stderr, "%s: size of filesystem must be larger "                                "than 8MB, but is set to %lluKB\n",                                progname, (long long)mop->mo_device_sz);                        return EINVAL;                }                block_count = mop->mo_device_sz / (L_BLOCK_SIZE >> 10);        }        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 */                        long journal_sz = 0, max_sz;                        if (device_sz > 1024 * 1024) /* 1GB */                                journal_sz = (device_sz / 102400) * 4;                        /* man mkfs.ext3 */                        max_sz = (102400 * L_BLOCK_SIZE) >> 20; /* 400MB */                        if (journal_sz > max_sz)                                journal_sz = max_sz;                        if (journal_sz) {                                sprintf(buf, " -J size=%ld", journal_sz);                                strscat(mop->mo_mkfsopts, buf,                                        sizeof(mop->mo_mkfsopts));                        }                }                /* bytes_per_inode: disk size / num inodes */                if (strstr(mop->mo_mkfsopts, "-i") == NULL) {                        long bytes_per_inode = 0;                        if (IS_MDT(&mop->mo_ldd))                                bytes_per_inode = 4096;                        /* Allocate fewer inodes on large OST devices.  Most                           filesystems can be much more aggressive than even                           this. */                        if ((IS_OST(&mop->mo_ldd) && (device_sz > 1000000)))                                bytes_per_inode = 16384;                        if (bytes_per_inode > 0) {                                sprintf(buf, " -i %ld", bytes_per_inode);                                strscat(mop->mo_mkfsopts, buf,                                        sizeof(mop->mo_mkfsopts));                        }                }                /* Inode size (for extended attributes).  The LOV EA size is                 * 32 (EA hdr) + 32 (lov_mds_md) + stripes * 24 (lov_ost_data),                 * and we want some margin above that for ACLs, other EAs... */                if (strstr(mop->mo_mkfsopts, "-I") == NULL) {                        long inode_size = 0;                        if (IS_MDT(&mop->mo_ldd)) {                                if (mop->mo_stripe_count > 72)                                        inode_size = 512; /* bz 7241 */                                /* cray stripes across all osts (>60) */                                else if (mop->mo_stripe_count > 32)                                        inode_size = 2048;                                else if (mop->mo_stripe_count > 10)                                        inode_size = 1024;                                else                                        inode_size = 512;                        } else if (IS_OST(&mop->mo_ldd)) {                                /* now as we store fids in EA on OST we need                                   to make inode bigger */                                inode_size = 256;                        }                        if (inode_size > 0) {                                sprintf(buf, " -I %ld", inode_size);                                strscat(mop->mo_mkfsopts, buf,                                        sizeof(mop->mo_mkfsopts));                        }                }                if (verbose < 2) {                        strscat(mop->mo_mkfsopts, " -q",                                sizeof(mop->mo_mkfsopts));                }                if (strstr(mop->mo_mkfsopts, "-O") == NULL)                        enable_default_backfs_features(mop);                /* Allow reformat of full devices (as opposed to                   partitions.)  We already checked for mounted dev. */                strscat(mop->mo_mkfsopts, " -F", sizeof(mop->mo_mkfsopts));                snprintf(mkfs_cmd, sizeof(mkfs_cmd),                         "mkfs.ext2 -j -b %d -L %s ", L_BLOCK_SIZE,                         mop->mo_ldd.ldd_svname);        } else if (mop->mo_ldd.ldd_mount_type == LDD_MT_REISERFS) {                long journal_sz = 0; /* FIXME default journal size */                if (journal_sz > 0) {                        sprintf(buf, " --journal_size %ld", journal_sz);                        strscat(mop->mo_mkfsopts, buf,                                sizeof(mop->mo_mkfsopts));                }                snprintf(mkfs_cmd, sizeof(mkfs_cmd), "mkreiserfs -ff ");        } else {                fprintf(stderr,"%s: unsupported fs type: %d (%s)\n",                        progname, mop->mo_ldd.ldd_mount_type,                        MT_STR(&mop->mo_ldd));                return EINVAL;        }        /* For loop device format the dev, not the filename */        dev = mop->mo_device;        if (mop->mo_flags & MO_IS_LOOP)                dev = mop->mo_loopdev;        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("\toptions       %s\n", mop->mo_mkfsopts);        /* mkfs_cmd's trailing space is important! */        strscat(mkfs_cmd, mop->mo_mkfsopts, sizeof(mkfs_cmd));        strscat(mkfs_cmd, " ", sizeof(mkfs_cmd));        strscat(mkfs_cmd, dev, sizeof(mkfs_cmd));        if (block_count != 0) {                sprintf(buf, " %d", block_count);                strscat(mkfs_cmd, buf, sizeof(mkfs_cmd));        }        vprint("mkfs_cmd = %s\n", mkfs_cmd);        ret = run_command(mkfs_cmd, sizeof(mkfs_cmd));        if (ret) {                fatal();                fprintf(stderr, "Unable to build fs %s (%d)\n", dev, ret);        }        return ret;}/* ==================== Lustre config functions =============*/void print_ldd(char *str, struct lustre_disk_data *ldd){        printf("\n   %s:\n", str);        printf("Target:     %s\n", ldd->ldd_svname);        if (ldd->ldd_svindex == INDEX_UNASSIGNED)                printf("Index:      unassigned\n");        else                printf("Index:      %d\n", ldd->ldd_svindex);        if (ldd->ldd_uuid[0])                printf("UUID:       %s\n", (char *)ldd->ldd_uuid);        printf("Lustre FS:  %s\n", ldd->ldd_fsname);        printf("Mount type: %s\n", MT_STR(ldd));        printf("Flags:      %#x\n", ldd->ldd_flags);        printf("              (%s%s%s%s%s%s%s%s)\n",               IS_MDT(ldd) ? "MDT ":"",               IS_OST(ldd) ? "OST ":"",               IS_MGS(ldd) ? "MGS ":"",               ldd->ldd_flags & LDD_F_NEED_INDEX ? "needs_index ":"",               ldd->ldd_flags & LDD_F_VIRGIN     ? "first_time ":"",               ldd->ldd_flags & LDD_F_UPDATE     ? "update ":"",               ldd->ldd_flags & LDD_F_WRITECONF  ? "writeconf ":"",               ldd->ldd_flags & LDD_F_UPGRADE14  ? "upgrade1.4 ":"");        printf("Persistent mount opts: %s\n", ldd->ldd_mount_opts);        printf("Parameters:%s\n", ldd->ldd_params);        if (ldd->ldd_userdata[0])                printf("Comment: %s\n", ldd->ldd_userdata);        printf("\n");}/* Write the server config files */int write_local_files(struct mkfs_opts *mop){        char mntpt[] = "/tmp/mntXXXXXX";        char filepnm[128];        char *dev;        FILE *filep;        int ret = 0;        /* Mount this device temporarily in order to write these files */        if (!mkdtemp(mntpt)) {                fprintf(stderr, "%s: Can't create temp mount point %s: %s\n",                        progname, mntpt, strerror(errno));                return errno;        }        dev = mop->mo_device;        if (mop->mo_flags & MO_IS_LOOP)                dev = mop->mo_loopdev;        ret = mount(dev, mntpt, MT_STR(&mop->mo_ldd), 0, NULL);        if (ret) {                fprintf(stderr, "%s: Unable to mount %s: %s\n",                        progname, dev, strerror(errno));                ret = errno;                if (errno == ENODEV) {                        fprintf(stderr, "Is the %s module available?\n",                                MT_STR(&mop->mo_ldd));                }                goto out_rmdir;        }        /* Set up initial directories */        sprintf(filepnm, "%s/%s", mntpt, MOUNT_CONFIGS_DIR);        ret = mkdir(filepnm, 0777);        if ((ret != 0) && (errno != EEXIST)) {                fprintf(stderr, "%s: Can't make configs dir %s: %s\n",                        progname, filepnm, strerror(errno));                goto out_umnt;        } else if (errno == EEXIST) {                ret = 0;        }        /* Save the persistent mount data into a file. Lustre must pre-read           this file to get the real mount options. */        vprint("Writing %s\n", MOUNT_DATA_FILE);        sprintf(filepnm, "%s/%s", mntpt, MOUNT_DATA_FILE);        filep = fopen(filepnm, "w");        if (!filep) {                fprintf(stderr, "%s: Unable to create %s file: %s\n",                        progname, filepnm, strerror(errno));                goto out_umnt;        }        fwrite(&mop->mo_ldd, sizeof(mop->mo_ldd), 1, filep);        fclose(filep);

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?