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%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_NO_PRIMNODE? "no_primnode ":"", 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"); }
/* Enable quota accounting */ int osd_enable_quota(struct mkfs_opts *mop) { struct lustre_disk_data *ldd = &mop->mo_ldd; int ret; switch (ldd->ldd_mount_type) { #ifdef HAVE_LDISKFS_OSD case LDD_MT_EXT3: case LDD_MT_LDISKFS: case LDD_MT_LDISKFS2: ret = ldiskfs_enable_quota(mop); break; #endif /* HAVE_LDISKFS_OSD */ #ifdef HAVE_ZFS_OSD case LDD_MT_ZFS: fprintf(stderr, "this option is only valid for ldiskfs\n"); ret = EINVAL; break; #endif /* HAVE_ZFS_OSD */ default: fatal(); fprintf(stderr, "unknown fs type %d '%s'\n", ldd->ldd_mount_type, MT_STR(ldd)); ret = EINVAL; break; } return ret; }
int osd_label_lustre(struct mount_opts *mop) { struct lustre_disk_data *ldd = &mop->mo_ldd; int ret; switch (ldd->ldd_mount_type) { #ifdef HAVE_LDISKFS_OSD case LDD_MT_LDISKFS: case LDD_MT_LDISKFS2: ret = ldiskfs_label_lustre(mop); break; #endif /* HAVE_LDISKFS_OSD */ #ifdef HAVE_ZFS_OSD case LDD_MT_ZFS: ret = zfs_label_lustre(mop); break; #endif /* HAVE_ZFS_OSD */ default: fatal(); fprintf(stderr, "unknown fs type %d '%s'\n", ldd->ldd_mount_type, MT_STR(ldd)); ret = EINVAL; break; } return ret; }
int osd_prepare_lustre(struct mkfs_opts *mop, char *default_mountopts, int default_len, char *always_mountopts, int always_len) { struct lustre_disk_data *ldd = &mop->mo_ldd; int ret; switch (ldd->ldd_mount_type) { #ifdef HAVE_LDISKFS_OSD case LDD_MT_LDISKFS: case LDD_MT_LDISKFS2: ret = ldiskfs_prepare_lustre(mop, default_mountopts, default_len, always_mountopts, always_len); break; #endif /* HAVE_LDISKFS_OSD */ #ifdef HAVE_ZFS_OSD case LDD_MT_ZFS: ret = zfs_prepare_lustre(mop, default_mountopts, default_len, always_mountopts, always_len); break; #endif /* HAVE_ZFS_OSD */ default: fatal(); fprintf(stderr, "unknown fs type %d '%s'\n", ldd->ldd_mount_type, MT_STR(ldd)); ret = EINVAL; break; } return ret; }
/* Read the server config files */ int osd_read_ldd(char *dev, struct lustre_disk_data *ldd) { int ret; switch (ldd->ldd_mount_type) { #ifdef HAVE_LDISKFS_OSD case LDD_MT_LDISKFS: case LDD_MT_LDISKFS2: ret = ldiskfs_read_ldd(dev, ldd); break; #endif /* HAVE_LDISKFS_OSD */ #ifdef HAVE_ZFS_OSD case LDD_MT_ZFS: ret = zfs_read_ldd(dev, ldd); break; #endif /* HAVE_ZFS_OSD */ default: fatal(); fprintf(stderr, "unknown fs type %d '%s'\n", ldd->ldd_mount_type, MT_STR(ldd)); ret = EINVAL; break; } return ret; }
/* Build fs according to type */ int ldiskfs_make_lustre(struct mkfs_opts *mop) { char mkfs_cmd[PATH_MAX]; char buf[64]; char *start; char *dev; int ret = 0, ext_opts = 0; bool enable_64bit = false; long inode_size = 0; size_t maxbuflen; mop->mo_blocksize_kb = 4; start = strstr(mop->mo_mkfsopts, "-b"); if (start) { char *end = NULL; long blocksize; blocksize = strtol(start + 2, &end, 0); if (end && (*end == 'k' || *end == 'K')) blocksize *= 1024; /* EXT4_MIN_BLOCK_SIZE || EXT4_MAX_BLOCK_SIZE */ if (blocksize < 1024 || blocksize > 65536) { fprintf(stderr, "%s: blocksize %lu not in 1024-65536 bytes, normally 4096 bytes\n", progname, blocksize); return EINVAL; } if ((blocksize & (blocksize - 1)) != 0) { fprintf(stderr, "%s: blocksize %lu not a power-of-two value\n", progname, blocksize); return EINVAL; } mop->mo_blocksize_kb = blocksize >> 10; } if (!(mop->mo_flags & MO_IS_LOOP)) { __u64 device_kb = get_device_size(mop->mo_device); if (device_kb == 0) return ENODEV; /* Compare to real size */ if (mop->mo_device_kb == 0 || device_kb < mop->mo_device_kb) mop->mo_device_kb = device_kb; } if (mop->mo_device_kb != 0) { __u64 block_count; if (mop->mo_device_kb < 32384) { fprintf(stderr, "%s: size of filesystem must be larger " "than 32MB, but is set to %lldKB\n", progname, (long long)mop->mo_device_kb); return EINVAL; } block_count = mop->mo_device_kb / mop->mo_blocksize_kb; if (block_count > 0xffffffffULL) { /* 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 well. b=22906 */ if (block_count < 0x100002000ULL) mop->mo_device_kb = 0xffffffffULL * mop->mo_blocksize_kb; else enable_64bit = true; } } 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)) { fprintf(stderr, "%s: unsupported fs type: %d (%s)\n", progname, mop->mo_ldd.ldd_mount_type, MT_STR(&mop->mo_ldd)); return EINVAL; } /* Journal size in MB */ if (strstr(mop->mo_mkfsopts, "-J") == NULL && mop->mo_device_kb > 1024 * 1024) { /* Choose our own default journal size */ long journal_mb = 0, max_mb; /* cap journal size at 4GB for MDT, leave at 1GB for OSTs */ if (IS_MDT(&mop->mo_ldd)) max_mb = 4096; else if (IS_OST(&mop->mo_ldd)) max_mb = 1024; else /* Use mke2fs default size for MGS */ max_mb = 0; /* Use at most 4% of device for journal */ journal_mb = mop->mo_device_kb * 4 / (1024 * 100); if (journal_mb > max_mb) journal_mb = max_mb; if (journal_mb) { snprintf(buf, sizeof(buf), " -J size=%ld", journal_mb); strscat(mop->mo_mkfsopts, buf, sizeof(mop->mo_mkfsopts)); } } /* * The inode size is constituted by following elements * (assuming all files are in composite layout and has * 3 components): * * ldiskfs inode size: 160 * MDT extended attributes size, including: * ext4_xattr_header: 32 * LOV EA size: 32(lov_comp_md_v1) + * 3 * 40(lov_comp_md_entry_v1) + * 3 * 32(lov_mds_md) + * stripes * 24(lov_ost_data) + * 16(xattr_entry) + 4("lov") * LMA EA size: 24(lustre_mdt_attrs) + * 16(xattr_entry) + 4("lma") * SOM EA size: 24(lustre_som_attrs) + * 16(xattr_entry) + 4("som") * link EA size: 24(link_ea_header) + 18(link_ea_entry) + * 16(filename) + 16(xattr_entry) + 4("link") * and some margin for 4-byte alignment, ACLs and other EAs. * * If we say the average filename length is about 32 bytes, * the calculation looks like: * 160 + 32 + (32+3*(40+32)+24*stripes+20) + (24+20) + (24+20) + * (24+20) + (~42+16+20) + other <= 512*2^m, {m=0,1,2,3} */ if (strstr(mop->mo_mkfsopts, "-I") == NULL) { if (IS_MDT(&mop->mo_ldd)) { if (mop->mo_stripe_count > 59) inode_size = 512; /* bz 7241 */ /* see also "-i" below for EA blocks */ else if (mop->mo_stripe_count > 16) inode_size = 2048; else inode_size = 1024; } else if (IS_OST(&mop->mo_ldd)) { /* We store MDS FID and necessary composite * layout information in the OST object EA: * ldiskfs inode size: 160 * OST extended attributes size, including: * ext4_xattr_header: 32 * LMA EA size: 24(lustre_mdt_attrs) + * 16(xattr_entry) + 4("lma") * FID EA size: 52(filter_fid) + * 16(xattr_entry) + 4("fid") * 160 + 32 + (24+20) + (52+20) = 308 */ inode_size = 512; } if (inode_size > 0) { snprintf(buf, sizeof(buf), " -I %ld", inode_size); strscat(mop->mo_mkfsopts, buf, sizeof(mop->mo_mkfsopts)); } } /* Bytes_per_inode: disk size / num inodes */ if (strstr(mop->mo_mkfsopts, "-i") == NULL && strstr(mop->mo_mkfsopts, "-N") == NULL) { long bytes_per_inode = 0; /* Allocate more inodes on MDT devices. There is * no data stored on the MDT, and very little extra * metadata beyond the inode. It could go down as * low as 1024 bytes, but this is conservative. * Account for external EA blocks for wide striping. */ if (IS_MDT(&mop->mo_ldd)) { bytes_per_inode = inode_size + 1536; if (mop->mo_stripe_count > 59) { int extra = mop->mo_stripe_count * 24; extra = ((extra - 1) | 4095) + 1; bytes_per_inode += extra; } } /* Allocate fewer inodes on large OST devices. Most * filesystems can be much more aggressive than even * this, but it is impossible to know in advance. */ if (IS_OST(&mop->mo_ldd)) { /* OST > 16TB assume average file size 1MB */ if (mop->mo_device_kb > (16ULL << 30)) bytes_per_inode = 1024 * 1024; /* OST > 4TB assume average file size 512kB */ else if (mop->mo_device_kb > (4ULL << 30)) bytes_per_inode = 512 * 1024; /* OST > 1TB assume average file size 256kB */ else if (mop->mo_device_kb > (1ULL << 30)) bytes_per_inode = 256 * 1024; /* OST > 10GB assume average file size 64kB, * plus a bit so that inodes will fit into a * 256x flex_bg without overflowing. */ else if (mop->mo_device_kb > (10ULL << 20)) bytes_per_inode = 69905; } if (bytes_per_inode > 0) { snprintf(buf, sizeof(buf), " -i %ld", bytes_per_inode); strscat(mop->mo_mkfsopts, buf, sizeof(mop->mo_mkfsopts)); mop->mo_inode_size = bytes_per_inode; } } if (verbose < 2) strscat(mop->mo_mkfsopts, " -q", sizeof(mop->mo_mkfsopts)); /* start handle -O mkfs options */ start = strstr(mop->mo_mkfsopts, "-O"); if (start) { if (strstr(start + 2, "-O") != NULL) { fprintf(stderr, "%s: don't specify multiple -O options\n", progname); return EINVAL; } start = moveopts_to_end(start); maxbuflen = sizeof(mop->mo_mkfsopts) - (start - mop->mo_mkfsopts) - strlen(start); ret = enable_default_ext4_features(mop, start, maxbuflen, 1); } else { start = mop->mo_mkfsopts + strlen(mop->mo_mkfsopts); maxbuflen = sizeof(mop->mo_mkfsopts) - strlen(mop->mo_mkfsopts); ret = enable_default_ext4_features(mop, start, maxbuflen, 0); } if (ret) return ret; /* end handle -O mkfs options */ /* start handle -E mkfs options */ start = strstr(mop->mo_mkfsopts, "-E"); if (start) { if (strstr(start + 2, "-E") != NULL) { fprintf(stderr, "%s: don't specify multiple -E options\n", progname); return EINVAL; } start = moveopts_to_end(start); maxbuflen = sizeof(mop->mo_mkfsopts) - (start - mop->mo_mkfsopts) - strlen(start); ext_opts = 1; } else { start = mop->mo_mkfsopts + strlen(mop->mo_mkfsopts); maxbuflen = sizeof(mop->mo_mkfsopts) - strlen(mop->mo_mkfsopts); } /* In order to align the filesystem metadata on 1MB boundaries, * give a resize value that will reserve a power-of-two group * descriptor blocks, but leave one block for the superblock. * Only useful for filesystems with < 2^32 blocks due to resize * limitations. */ if (!enable_64bit && strstr(mop->mo_mkfsopts, "meta_bg") == NULL && IS_OST(&mop->mo_ldd) && mop->mo_device_kb > 100 * 1024) { unsigned int group_blocks = mop->mo_blocksize_kb * 8192; unsigned int desc_per_block = mop->mo_blocksize_kb * 1024 / 32; unsigned int resize_blks; resize_blks = (1ULL<<32) - desc_per_block*group_blocks; snprintf(buf, sizeof(buf), "%u", resize_blks); append_unique(start, ext_opts ? "," : " -E ", "resize", buf, maxbuflen); ext_opts = 1; } /* Avoid zeroing out the full journal - speeds up mkfs */ if (is_e2fsprogs_feature_supp("-E lazy_journal_init")) append_unique(start, ext_opts ? "," : " -E ", "lazy_journal_init", NULL, maxbuflen); /* end handle -E mkfs options */ /* 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), "%s -j -b %d -L %s ", MKE2FS, mop->mo_blocksize_kb * 1024, mop->mo_ldd.ldd_svname); /* 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("\tkilobytes %llu\n", mop->mo_device_kb); 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 (mop->mo_device_kb != 0) { snprintf(buf, sizeof(buf), " %lluk", (unsigned long long)mop->mo_device_kb); 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; }
/* Write the server config files */ int ldiskfs_write_ldd(struct mkfs_opts *mop) { char mntpt[] = "/tmp/mntXXXXXX"; char filepnm[192]; char *dev; FILE *filep; int ret = 0; size_t num; /* 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; } /* * Append file context to mount options if SE Linux is enabled */ #ifdef HAVE_SELINUX if (is_selinux_enabled() > 0) append_context_for_mount(mntpt, mop); #endif dev = mop->mo_device; if (mop->mo_flags & MO_IS_LOOP) dev = mop->mo_loopdev; /* Multiple mount protection enabled if failover node specified */ if (mop->mo_flags & MO_FAILOVER && !is_feature_enabled("mmp", dev)) { if (is_e2fsprogs_feature_supp("-O mmp")) { char *command = filepnm; snprintf(command, sizeof(filepnm), TUNE2FS" -O mmp '%s' >/dev/null 2>&1", dev); ret = run_command(command, sizeof(filepnm)); if (ret) fprintf(stderr, "%s: Unable to set 'mmp' on %s: %d\n", progname, dev, ret); } else { disp_old_e2fsprogs_msg("mmp", 1); } } ret = mount(dev, mntpt, MT_STR(&mop->mo_ldd), 0, (mop->mo_mountopts == NULL) ? "errors=remount-ro" : mop->mo_mountopts); 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; } 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)); fclose(filep); goto out_umnt; } fsync(filep->_fileno); fclose(filep); out_umnt: umount(mntpt); out_rmdir: rmdir(mntpt); return ret; }
int ldiskfs_rename_fsname(struct mkfs_opts *mop, const char *oldname) { struct mount_opts opts; struct lustre_disk_data *ldd = &mop->mo_ldd; char mntpt[] = "/tmp/mntXXXXXX"; char *dev; int ret; /* Change the filesystem label. */ opts.mo_ldd = *ldd; opts.mo_source = mop->mo_device; ret = ldiskfs_label_lustre(&opts); if (ret) { if (errno != 0) ret = errno; fprintf(stderr, "Can't change filesystem label: %s\n", strerror(ret)); return ret; } /* Mount this device temporarily in order to write these files */ if (mkdtemp(mntpt) == NULL) { if (errno != 0) ret = errno; else ret = EINVAL; fprintf(stderr, "Can't create temp mount point %s: %s\n", mntpt, strerror(ret)); return ret; } #ifdef HAVE_SELINUX /* * Append file context to mount options if SE Linux is enabled */ if (is_selinux_enabled() > 0) append_context_for_mount(mntpt, mop); #endif if (mop->mo_flags & MO_IS_LOOP) dev = mop->mo_loopdev; else dev = mop->mo_device; ret = mount(dev, mntpt, MT_STR(ldd), 0, ldd->ldd_mount_opts); if (ret) { if (errno != 0) ret = errno; fprintf(stderr, "Unable to mount %s: %s\n", dev, strerror(ret)); if (ret == ENODEV) fprintf(stderr, "Is the %s module available?\n", MT_STR(ldd)); goto out_rmdir; } ret = lustre_rename_fsname(mop, mntpt, oldname); umount(mntpt); out_rmdir: rmdir(mntpt); return ret; }
/*mds still need lov setup here*/ static int mds_cmd_setup(struct obd_device *obd, struct lustre_cfg *lcfg) { struct mds_obd *mds = &obd->u.mds; struct lvfs_run_ctxt saved; const char *dev; struct vfsmount *mnt; struct lustre_sb_info *lsi; struct lustre_mount_info *lmi; struct dentry *dentry; int rc = 0; ENTRY; CDEBUG(D_INFO, "obd %s setup \n", obd->obd_name); if (strncmp(obd->obd_name, MDD_OBD_NAME, strlen(MDD_OBD_NAME))) RETURN(0); if (lcfg->lcfg_bufcount < 5) { CERROR("invalid arg for setup %s\n", MDD_OBD_NAME); RETURN(-EINVAL); } dev = lustre_cfg_string(lcfg, 4); lmi = server_get_mount(dev); LASSERT(lmi != NULL); lsi = s2lsi(lmi->lmi_sb); mnt = lmi->lmi_mnt; /* FIXME: MDD LOV initialize objects. * we need only lmi here but not get mount * OSD did mount already, so put mount back */ cfs_atomic_dec(&lsi->lsi_mounts); mntput(mnt); cfs_init_rwsem(&mds->mds_notify_lock); obd->obd_fsops = fsfilt_get_ops(MT_STR(lsi->lsi_ldd)); mds_init_ctxt(obd, mnt); push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL); dentry = simple_mkdir(current->fs->pwd, mnt, "OBJECTS", 0777, 1); if (IS_ERR(dentry)) { rc = PTR_ERR(dentry); CERROR("cannot create OBJECTS directory: rc = %d\n", rc); GOTO(err_putfs, rc); } mds->mds_objects_dir = dentry; dentry = ll_lookup_one_len("__iopen__", current->fs->pwd, strlen("__iopen__")); if (IS_ERR(dentry)) { rc = PTR_ERR(dentry); CERROR("cannot lookup __iopen__ directory: rc = %d\n", rc); GOTO(err_objects, rc); } mds->mds_fid_de = dentry; if (!dentry->d_inode || is_bad_inode(dentry->d_inode)) { rc = -ENOENT; CERROR("__iopen__ directory has no inode? rc = %d\n", rc); GOTO(err_fid, rc); } rc = mds_lov_init_objids(obd); if (rc != 0) { CERROR("cannot init lov objid rc = %d\n", rc); GOTO(err_fid, rc ); } rc = mds_lov_presetup(mds, lcfg); if (rc < 0) GOTO(err_objects, rc); /* Don't wait for mds_postrecov trying to clear orphans */ obd->obd_async_recov = 1; rc = mds_postsetup(obd); /* Bug 11557 - allow async abort_recov start FIXME can remove most of this obd_async_recov plumbing obd->obd_async_recov = 0; */ if (rc) GOTO(err_objects, rc); err_pop: pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL); RETURN(rc); err_fid: dput(mds->mds_fid_de); err_objects: dput(mds->mds_objects_dir); err_putfs: fsfilt_put_ops(obd->obd_fsops); goto err_pop; }
/* Start the MGS obd */ static int mgs_setup(struct obd_device *obd, struct lustre_cfg *lcfg) { struct lprocfs_static_vars lvars; struct mgs_obd *mgs = &obd->u.mgs; struct lustre_mount_info *lmi; struct lustre_sb_info *lsi; struct vfsmount *mnt; int rc = 0; ENTRY; CDEBUG(D_CONFIG, "Starting MGS\n"); /* Find our disk */ lmi = server_get_mount(obd->obd_name); if (!lmi) RETURN(rc = -EINVAL); mnt = lmi->lmi_mnt; lsi = s2lsi(lmi->lmi_sb); obd->obd_fsops = fsfilt_get_ops(MT_STR(lsi->lsi_ldd)); if (IS_ERR(obd->obd_fsops)) GOTO(err_put, rc = PTR_ERR(obd->obd_fsops)); if (lvfs_check_rdonly(lvfs_sbdev(mnt->mnt_sb))) { CERROR("%s: Underlying device is marked as read-only. " "Setup failed\n", obd->obd_name); GOTO(err_ops, rc = -EROFS); } obd->u.obt.obt_magic = OBT_MAGIC; obd->u.obt.obt_instance = 0; /* namespace for mgs llog */ obd->obd_namespace = ldlm_namespace_new(obd ,"MGS", LDLM_NAMESPACE_SERVER, LDLM_NAMESPACE_MODEST, LDLM_NS_TYPE_MGT); if (obd->obd_namespace == NULL) GOTO(err_ops, rc = -ENOMEM); /* ldlm setup */ ptlrpc_init_client(LDLM_CB_REQUEST_PORTAL, LDLM_CB_REPLY_PORTAL, "mgs_ldlm_client", &obd->obd_ldlm_client); rc = mgs_fs_setup(obd, mnt); if (rc) { CERROR("%s: MGS filesystem method init failed: rc = %d\n", obd->obd_name, rc); GOTO(err_ns, rc); } rc = obd_llog_init(obd, &obd->obd_olg, obd, NULL); if (rc) GOTO(err_fs, rc); /* No recovery for MGC's */ obd->obd_replayable = 0; /* Internal mgs setup */ mgs_init_fsdb_list(obd); cfs_mutex_init(&mgs->mgs_mutex); mgs->mgs_start_time = cfs_time_current_sec(); /* Setup proc */ lprocfs_mgs_init_vars(&lvars); if (lprocfs_obd_setup(obd, lvars.obd_vars) == 0) { lproc_mgs_setup(obd); rc = lprocfs_alloc_md_stats(obd, LPROC_MGS_LAST); if (rc) GOTO(err_llog, rc); } /* Start the service threads */ mgs->mgs_service = ptlrpc_init_svc(MGS_NBUFS, MGS_BUFSIZE, MGS_MAXREQSIZE, MGS_MAXREPSIZE, MGS_REQUEST_PORTAL, MGC_REPLY_PORTAL, 2, mgs_handle, LUSTRE_MGS_NAME, obd->obd_proc_entry, target_print_req, MGS_THREADS_AUTO_MIN, MGS_THREADS_AUTO_MAX, "ll_mgs", LCT_MD_THREAD, NULL); if (!mgs->mgs_service) { CERROR("failed to start service\n"); GOTO(err_llog, rc = -ENOMEM); } rc = ptlrpc_start_threads(mgs->mgs_service); if (rc) GOTO(err_thread, rc); ping_evictor_start(); CDEBUG(D_INFO, "MGS %s started\n", obd->obd_name); RETURN(0); err_thread: ptlrpc_unregister_service(mgs->mgs_service); err_llog: lproc_mgs_cleanup(obd); obd_llog_finish(obd, 0); err_fs: /* No extra cleanup needed for llog_init_commit_thread() */ mgs_fs_cleanup(obd); err_ns: ldlm_namespace_free(obd->obd_namespace, NULL, 0); obd->obd_namespace = NULL; err_ops: fsfilt_put_ops(obd->obd_fsops); err_put: server_put_mount(obd->obd_name, mnt); mgs->mgs_sb = 0; return rc; }