From 3e358040ae4b6fe8f28f20f8f1a07217d67d7e1a Mon Sep 17 00:00:00 2001 From: Alex Zhuravlev Date: Wed, 1 Aug 2012 13:39:02 +0400 Subject: [PATCH] LU-1581 mount: get rid of ldd in the kernel all ldd parsing is now done outside of the kernel by mount.lustre utility. Signed-off-by: Alex Zhuravlev Change-Id: Iea6257b75f7573b6594c6bc7a2fa3a86b1c91700 Reviewed-on: http://review.whamcloud.com/3614 Tested-by: Hudson Tested-by: Maloo Reviewed-by: Jinshan Xiong Reviewed-by: Andreas Dilger --- lustre/include/lustre_disk.h | 21 ++- lustre/ldlm/ldlm_lib.c | 2 +- lustre/llite/llite_lib.c | 4 - lustre/mds/handler.c | 2 +- lustre/mdt/mdt_handler.c | 6 +- lustre/mdt/mdt_recovery.c | 2 +- lustre/mgc/mgc_request.c | 23 ++- lustre/mgs/mgs_handler.c | 2 +- lustre/obdclass/obd_mount.c | 398 +++++++++++++++++++++------------------ lustre/obdfilter/filter.c | 2 +- lustre/osd-ldiskfs/osd_handler.c | 6 +- lustre/osd-zfs/osd_handler.c | 2 +- lustre/utils/mount_utils.h | 9 + 13 files changed, 253 insertions(+), 226 deletions(-) diff --git a/lustre/include/lustre_disk.h b/lustre/include/lustre_disk.h index 7ccce88..fbc945a 100644 --- a/lustre/include/lustre_disk.h +++ b/lustre/include/lustre_disk.h @@ -107,6 +107,8 @@ #define LDD_F_ONDISK_MASK (LDD_F_SV_TYPE_MASK | LDD_F_IAM_DIR) +#define LDD_F_MASK 0xFFFF + enum ldd_mount_type { LDD_MT_EXT3 = 0, LDD_MT_LDISKFS, @@ -171,9 +173,11 @@ struct lustre_disk_data { /*8192*/char ldd_params[4096]; /* key=value pairs */ }; -#define IS_MDT(data) ((data)->ldd_flags & LDD_F_SV_TYPE_MDT) -#define IS_OST(data) ((data)->ldd_flags & LDD_F_SV_TYPE_OST) -#define IS_MGS(data) ((data)->ldd_flags & LDD_F_SV_TYPE_MGS) +#define IS_MDT(data) ((data)->lsi_flags & LDD_F_SV_TYPE_MDT) +#define IS_OST(data) ((data)->lsi_flags & LDD_F_SV_TYPE_OST) +#define IS_MGS(data) ((data)->lsi_flags & LDD_F_SV_TYPE_MGS) +#define IS_SERVER(data) ((data)->lsi_flags & (LDD_F_SV_TYPE_MGS | \ + LDD_F_SV_TYPE_MDT | LDD_F_SV_TYPE_OST)) #define MT_STR(data) mt_str((data)->ldd_mount_type) /* Make the mdt/ost server obd name based on the filesystem name */ @@ -198,6 +202,7 @@ static inline int server_make_name(__u32 flags, __u16 index, char *fs, /* Get the index from the obd name */ int server_name2index(char *svname, __u32 *idx, char **endptr); +int server_name2svname(char *label, char *svname, char **endptr); /****************** mount command *********************/ @@ -484,21 +489,18 @@ struct lustre_sb_info { int lsi_flags; struct obd_device *lsi_mgc; /* mgc obd */ struct lustre_mount_data *lsi_lmd; /* mount command info */ - struct lustre_disk_data *lsi_ldd; /* mount info on-disk */ struct ll_sb_info *lsi_llsbi; /* add'l client sbi info */ struct vfsmount *lsi_srv_mnt; /* the one server mount */ cfs_atomic_t lsi_mounts; /* references to the srv_mnt */ char lsi_svname[MTI_NAME_MAXLEN]; char lsi_osd_type[16]; + char lsi_fstype[16]; struct backing_dev_info lsi_bdi; /* each client mountpoint needs own backing_dev_info */ }; -#define LSI_SERVER 0x00000001 -#define LSI_UMOUNT_FORCE 0x00000010 -#define LSI_UMOUNT_FAILOVER 0x00000020 -#define LSI_BDI_INITIALIZED 0x00000040 -#define LSI_IR_CAPABLE 0x00000080 +#define LSI_UMOUNT_FAILOVER 0x00200000 +#define LSI_BDI_INITIALIZED 0x00400000 #define s2lsi(sb) ((struct lustre_sb_info *)((sb)->s_fs_info)) #define s2lsi_nocast(sb) ((sb)->s_fs_info) @@ -533,7 +535,6 @@ struct lustre_mount_info *server_get_mount(const char *name); struct lustre_mount_info *server_get_mount_2(const char *name); int server_put_mount(const char *name, struct vfsmount *mnt); int server_put_mount_2(const char *name, struct vfsmount *mnt); -int server_register_target(struct super_block *sb); struct mgs_target_info; int server_mti_print(char *title, struct mgs_target_info *mti); void server_calc_timeout(struct lustre_sb_info *lsi, struct obd_device *obd); diff --git a/lustre/ldlm/ldlm_lib.c b/lustre/ldlm/ldlm_lib.c index f79160f..06473f8 100644 --- a/lustre/ldlm/ldlm_lib.c +++ b/lustre/ldlm/ldlm_lib.c @@ -1622,7 +1622,7 @@ check_and_start_recovery_timer(struct obd_device *obd, LASSERT(obt->obt_magic == OBT_MAGIC); lsi = s2lsi(obt->obt_sb); - if (!(lsi->lsi_flags | LSI_IR_CAPABLE)) + if (!(lsi->lsi_flags | LDD_F_IR_CAPABLE)) service_time += 2 * (CONNECTION_SWITCH_MAX + CONNECTION_SWITCH_INC); if (service_time > obd->obd_recovery_timeout && !new_client) diff --git a/lustre/llite/llite_lib.c b/lustre/llite/llite_lib.c index c43c6a8..9980c2c 100644 --- a/lustre/llite/llite_lib.c +++ b/lustre/llite/llite_lib.c @@ -2001,7 +2001,6 @@ void ll_umount_begin(struct vfsmount *vfsmnt, int flags) void ll_umount_begin(struct super_block *sb) { #endif - struct lustre_sb_info *lsi = s2lsi(sb); struct ll_sb_info *sbi = ll_s2sbi(sb); struct obd_device *obd; struct obd_ioctl_data *ioc_data; @@ -2014,9 +2013,6 @@ void ll_umount_begin(struct super_block *sb) } #endif - /* Tell the MGC we got umount -f */ - lsi->lsi_flags |= LSI_UMOUNT_FORCE; - CDEBUG(D_VFSTRACE, "VFS Op: superblock %p count %d active %d\n", sb, sb->s_count, atomic_read(&sb->s_active)); diff --git a/lustre/mds/handler.c b/lustre/mds/handler.c index f9fd7da..71ea401 100644 --- a/lustre/mds/handler.c +++ b/lustre/mds/handler.c @@ -315,7 +315,7 @@ static int mds_cmd_setup(struct obd_device *obd, struct lustre_cfg *lcfg) mntput(mnt); cfs_init_rwsem(&mds->mds_notify_lock); - obd->obd_fsops = fsfilt_get_ops(MT_STR(lsi->lsi_ldd)); + obd->obd_fsops = fsfilt_get_ops(lsi->lsi_fstype); rc = mds_init_ctxt(obd, mnt); if (rc) GOTO(err_putfs, rc); diff --git a/lustre/mdt/mdt_handler.c b/lustre/mdt/mdt_handler.c index 4ed6d5e..36d6ef5 100644 --- a/lustre/mdt/mdt_handler.c +++ b/lustre/mdt/mdt_handler.c @@ -4494,7 +4494,7 @@ static int mdt_obd_llog_setup(struct obd_device *obd, LASSERT(obd->obd_fsops == NULL); - obd->obd_fsops = fsfilt_get_ops(MT_STR(lsi->lsi_ldd)); + obd->obd_fsops = fsfilt_get_ops(lsi->lsi_fstype); if (IS_ERR(obd->obd_fsops)) return PTR_ERR(obd->obd_fsops); @@ -4636,7 +4636,6 @@ static int mdt_init0(const struct lu_env *env, struct mdt_device *m, const char *num = lustre_cfg_string(cfg, 2); struct lustre_mount_info *lmi = NULL; struct lustre_sb_info *lsi; - struct lustre_disk_data *ldd; struct lu_site *s; struct md_site *mite; const char *identity_upcall = "NONE"; @@ -4678,10 +4677,9 @@ static int mdt_init0(const struct lu_env *env, struct mdt_device *m, } else { lsi = s2lsi(lmi->lmi_sb); /* CMD is supported only in IAM mode */ - ldd = lsi->lsi_ldd; LASSERT(num); node_id = simple_strtol(num, NULL, 10); - if (!(ldd->ldd_flags & LDD_F_IAM_DIR) && node_id) { + if (!(lsi->lsi_flags & LDD_F_IAM_DIR) && node_id) { CERROR("CMD Operation not allowed in IOP mode\n"); GOTO(err_lmi, rc = -EINVAL); } diff --git a/lustre/mdt/mdt_recovery.c b/lustre/mdt/mdt_recovery.c index 08ddc03..6c4b38f 100644 --- a/lustre/mdt/mdt_recovery.c +++ b/lustre/mdt/mdt_recovery.c @@ -268,7 +268,7 @@ static int mdt_server_data_init(const struct lu_env *env, lsd->lsd_feature_compat |= OBD_COMPAT_20; } - if (lsi->lsi_ldd->ldd_flags & LDD_F_IAM_DIR) + if (lsi->lsi_flags & LDD_F_IAM_DIR) lsd->lsd_feature_incompat |= OBD_INCOMPAT_IAM_DIR; lsd->lsd_feature_incompat |= OBD_INCOMPAT_FID; diff --git a/lustre/mgc/mgc_request.c b/lustre/mgc/mgc_request.c index 67df5eb..4ed45a0 100644 --- a/lustre/mgc/mgc_request.c +++ b/lustre/mgc/mgc_request.c @@ -259,14 +259,14 @@ static struct config_llog_data *config_recover_log_add(struct obd_device *obd, struct config_llog_data *cld; char logname[32]; - if ((lsi->lsi_flags & LSI_SERVER) && IS_OST(lsi->lsi_ldd)) + if (IS_OST(lsi)) return NULL; /* we have to use different llog for clients and mdts for cmd * where only clients are notified if one of cmd server restarts */ LASSERT(strlen(fsname) < sizeof(logname) / 2); strcpy(logname, fsname); - if (lsi->lsi_flags & LSI_SERVER) { /* mdt */ + if (IS_SERVER(lsi)) { /* mdt */ LASSERT(lcfg.cfg_instance == NULL); lcfg.cfg_instance = sb; strcat(logname, "-mdtir"); @@ -619,10 +619,10 @@ static int mgc_fs_setup(struct obd_device *obd, struct super_block *sb, cfs_cleanup_group_info(); - obd->obd_fsops = fsfilt_get_ops(MT_STR(lsi->lsi_ldd)); + obd->obd_fsops = fsfilt_get_ops(lsi->lsi_fstype); if (IS_ERR(obd->obd_fsops)) { cfs_up(&cli->cl_mgc_sem); - CERROR("No fstype %s rc=%ld\n", MT_STR(lsi->lsi_ldd), + CERROR("No fstype %s rc=%ld\n", lsi->lsi_fstype, PTR_ERR(obd->obd_fsops)); RETURN(PTR_ERR(obd->obd_fsops)); } @@ -926,7 +926,7 @@ static int mgc_enqueue(struct obd_export *exp, struct lov_stripe_md *lsm, /* check if this is server or client */ if (cld->cld_cfg.cfg_sb) { struct lustre_sb_info *lsi = s2lsi(cld->cld_cfg.cfg_sb); - if (lsi && (lsi->lsi_flags & LSI_SERVER)) + if (lsi && IS_SERVER(lsi)) short_limit = 1; } /* Limit how long we will wait for the enqueue to complete */ @@ -1254,11 +1254,14 @@ static int mgc_apply_recover_logs(struct obd_device *mgc, if (inst == NULL) RETURN(-ENOMEM); - if (!(lsi->lsi_flags & LSI_SERVER)) { + if (!IS_SERVER(lsi)) { pos = sprintf(inst, "%p", cfg->cfg_instance); } else { - LASSERT(IS_MDT(lsi->lsi_ldd)); - pos = sprintf(inst, "MDT%04x", lsi->lsi_ldd->ldd_svindex); + LASSERT(IS_MDT(lsi)); + rc = server_name2svname(lsi->lsi_svname, inst, NULL); + if (rc) + RETURN(-EINVAL); + pos = strlen(inst); } ++pos; @@ -1721,9 +1724,9 @@ static int mgc_process_cfg_log(struct obd_device *mgc, /* Copy the setup log locally if we can. Don't mess around if we're running an MGS though (logs are already local). */ - if (lctxt && lsi && (lsi->lsi_flags & LSI_SERVER) && + if (lctxt && lsi && IS_SERVER(lsi) && (lsi->lsi_srv_mnt == cli->cl_mgc_vfsmnt) && - !IS_MGS(lsi->lsi_ldd) && lsi->lsi_srv_mnt) { + !IS_MGS(lsi) && lsi->lsi_srv_mnt) { push_ctxt(saved_ctxt, &mgc->obd_lvfs_ctxt, NULL); must_pop++; if (!local_only) diff --git a/lustre/mgs/mgs_handler.c b/lustre/mgs/mgs_handler.c index 06a60b5..4c88968 100644 --- a/lustre/mgs/mgs_handler.c +++ b/lustre/mgs/mgs_handler.c @@ -185,7 +185,7 @@ static int mgs_setup(struct obd_device *obd, struct lustre_cfg *lcfg) mnt = lmi->lmi_mnt; lsi = s2lsi(lmi->lmi_sb); - obd->obd_fsops = fsfilt_get_ops(MT_STR(lsi->lsi_ldd)); + obd->obd_fsops = fsfilt_get_ops(lsi->lsi_fstype); if (IS_ERR(obd->obd_fsops)) GOTO(err_put, rc = PTR_ERR(obd->obd_fsops)); diff --git a/lustre/obdclass/obd_mount.c b/lustre/obdclass/obd_mount.c index bc08b46..f844734 100644 --- a/lustre/obdclass/obd_mount.c +++ b/lustre/obdclass/obd_mount.c @@ -432,8 +432,7 @@ static int server_start_mgs(struct super_block *sb) if (lmi) { lsi = s2lsi(lmi->lmi_sb); LCONSOLE_ERROR_MSG(0x15d, "The MGS service was already started" - " from server %s\n", - lsi->lsi_ldd->ldd_svname); + " from server\n"); RETURN(-EALREADY); } @@ -503,17 +502,13 @@ static int lustre_start_mgc(struct super_block *sb) LASSERT(lsi->lsi_lmd); /* Find the first non-lo MGS nid for our MGC name */ - if (lsi->lsi_flags & LSI_SERVER) { - ptr = lsi->lsi_ldd->ldd_params; + if (IS_SERVER(lsi)) { /* mount -o mgsnode=nid */ + ptr = lsi->lsi_lmd->lmd_mgs; if (lsi->lsi_lmd->lmd_mgs && (class_parse_nid(lsi->lsi_lmd->lmd_mgs, &nid, &ptr) == 0)) { i++; - /* Use mgsnode= nids */ - } else if ((class_find_param(ptr, PARAM_MGSNODE, &ptr) == 0) && - (class_parse_nid(ptr, &nid, &ptr) == 0)) { - i++; - } else if (IS_MGS(lsi->lsi_ldd)) { + } else if (IS_MGS(lsi)) { lnet_process_id_t id; while ((rc = LNetGetId(i++, &id)) != -ENOENT) { if (LNET_NETTYP(LNET_NIDNET(id.nid)) == LOLND) @@ -589,7 +584,7 @@ static int lustre_start_mgc(struct super_block *sb) recov_bk = 0; /* If we are restarting the MGS, don't try to keep the MGC's old connection, or registration will fail. */ - if ((lsi->lsi_flags & LSI_SERVER) && IS_MGS(lsi->lsi_ldd)) { + if (IS_MGS(lsi)) { CDEBUG(D_MOUNT, "New MGS with live MGC\n"); recov_bk = 1; } @@ -612,9 +607,9 @@ static int lustre_start_mgc(struct super_block *sb) /* Add the primary nids for the MGS */ i = 0; sprintf(niduuid, "%s_%x", mgcname, i); - if (lsi->lsi_flags & LSI_SERVER) { - ptr = lsi->lsi_ldd->ldd_params; - if (IS_MGS(lsi->lsi_ldd)) { + if (IS_SERVER(lsi)) { + ptr = lsi->lsi_lmd->lmd_mgs; + if (IS_MGS(lsi)) { /* Use local nids (including LO) */ lnet_process_id_t id; while ((rc = LNetGetId(i++, &id)) != -ENOENT) { @@ -670,8 +665,8 @@ static int lustre_start_mgc(struct super_block *sb) /* Add any failover MGS nids */ i = 1; - while ((*ptr == ':' || - class_find_param(ptr, PARAM_MGSNODE, &ptr) == 0)) { + while (ptr && ((*ptr == ':' || + class_find_param(ptr, PARAM_MGSNODE, &ptr) == 0))) { /* New failover node */ sprintf(niduuid, "%s_%x", mgcname, i); j = 0; @@ -859,7 +854,7 @@ static int server_mgc_clear_fs(struct obd_device *mgc) CFS_DEFINE_MUTEX(server_start_lock); /* Stop MDS/OSS if nobody is using them */ -static int server_stop_servers(int lddflags, int lsiflags) +static int server_stop_servers(int lsiflags) { struct obd_device *obd = NULL; struct obd_type *type = NULL; @@ -870,13 +865,13 @@ static int server_stop_servers(int lddflags, int lsiflags) /* Either an MDT or an OST or neither */ /* if this was an MDT, and there are no more MDT's, clean up the MDS */ - if ((lddflags & LDD_F_SV_TYPE_MDT) && + if ((lsiflags & LDD_F_SV_TYPE_MDT) && (obd = class_name2obd(LUSTRE_MDS_OBDNAME))) { /*FIXME pre-rename, should eventually be LUSTRE_MDT_NAME*/ type = class_search_type(LUSTRE_MDS_NAME); } /* if this was an OST, and there are no more OST's, clean up the OSS */ - if ((lddflags & LDD_F_SV_TYPE_OST) && + if ((lsiflags & LDD_F_SV_TYPE_OST) && (obd = class_name2obd(LUSTRE_OSS_OBDNAME))) { type = class_search_type(LUSTRE_OST_NAME); } @@ -905,23 +900,111 @@ int server_mti_print(char *title, struct mgs_target_info *mti) mti->mti_config_ver, mti->mti_flags); return(0); } -EXPORT_SYMBOL(server_mti_print); -static int server_sb2mti(struct super_block *sb, struct mgs_target_info *mti) +/** Get the fsname ("lustre") from the server name ("lustre-OST003F"). + * @param [in] svname server name including type and index + * @param [out] fsname Buffer to copy filesystem name prefix into. + * Must have at least 'strlen(fsname) + 1' chars. + * @param [out] endptr if endptr isn't NULL it is set to end of fsname + * rc < 0 on error + */ +static int server_name2fsname(char *svname, char *fsname, char **endptr) { - struct lustre_sb_info *lsi = s2lsi(sb); - struct lustre_disk_data *ldd = lsi->lsi_ldd; - lnet_process_id_t id; - int i = 0; + char *p; + + p = strstr(svname, "-OST"); + if (p == NULL) + p = strstr(svname, "-MDT"); + if (p == NULL) + return -1; + + if (fsname) { + strncpy(fsname, svname, p - svname); + fsname[p - svname] = '\0'; + } + + if (endptr != NULL) + *endptr = p; + + return 0; +} + +/** + * Get service name (svname) from string + * rc < 0 on error + * if endptr isn't NULL it is set to end of fsname * + */ +int server_name2svname(char *label, char *svname, char **endptr) +{ + int rc; + char *dash; + + /* We use server_name2fsname() just for parsing */ + rc = server_name2fsname(label, NULL, &dash); + if (rc != 0) + return rc; + + if (*dash != '-') + return -1; + + strncpy(svname, dash + 1, MTI_NAME_MAXLEN); + + return 0; +} +EXPORT_SYMBOL(server_name2svname); + + +/* Get the index from the obd name. + rc = server type, or + rc < 0 on error + if endptr isn't NULL it is set to end of name */ +int server_name2index(char *svname, __u32 *idx, char **endptr) +{ + unsigned long index; + int rc; + char *dash; + + /* We use server_name2fsname() just for parsing */ + rc = server_name2fsname(svname, NULL, &dash); + if (rc != 0) + return rc; + + if (*dash != '-') + return -EINVAL; + + dash++; + + if (strncmp(dash, "MDT", 3) == 0) + rc = LDD_F_SV_TYPE_MDT; + else if (strncmp(dash, "OST", 3) == 0) + rc = LDD_F_SV_TYPE_OST; + else + return -EINVAL; + + dash += 3; + + if (strcmp(dash, "all") == 0) + return rc | LDD_F_SV_ALL; + + index = simple_strtoul(dash, endptr, 16); + *idx = index; + + return rc; +} +EXPORT_SYMBOL(server_name2index); + +/* Generate data for registration */ +static int server_lsi2mti(struct lustre_sb_info *lsi, + struct mgs_target_info *mti) +{ + lnet_process_id_t id; + int rc, i = 0; ENTRY; - if (!(lsi->lsi_flags & LSI_SERVER)) + if (!IS_SERVER(lsi)) RETURN(-EINVAL); - strncpy(mti->mti_fsname, ldd->ldd_fsname, - sizeof(mti->mti_fsname)); - strncpy(mti->mti_svname, ldd->ldd_svname, - sizeof(mti->mti_svname)); + strncpy(mti->mti_svname, lsi->lsi_svname, sizeof(mti->mti_svname)); mti->mti_nid_count = 0; while (LNetGetId(i++, &id) != -ENOENT) { @@ -951,27 +1034,29 @@ static int server_sb2mti(struct super_block *sb, struct mgs_target_info *mti) mti->mti_lustre_ver = LUSTRE_VERSION_CODE; mti->mti_config_ver = 0; - if (lsi->lsi_lmd->lmd_flags & LMD_FLG_WRITECONF) - ldd->ldd_flags |= LDD_F_WRITECONF; - mti->mti_flags = ldd->ldd_flags; - mti->mti_stripe_index = ldd->ldd_svindex; - memcpy(mti->mti_uuid, ldd->ldd_uuid, sizeof(mti->mti_uuid)); - if (strlen(ldd->ldd_params) > sizeof(mti->mti_params)) { - CERROR("params too big for mti\n"); - RETURN(-ENOMEM); - } + + rc = server_name2fsname(lsi->lsi_svname, mti->mti_fsname, NULL); + if (rc != 0) + return rc; + + rc = server_name2index(lsi->lsi_svname, &mti->mti_stripe_index, NULL); + if (rc < 0) + return rc; + /* Orion requires index to be set */ + LASSERT(!(rc & LDD_F_NEED_INDEX)); + /* keep only LDD flags */ + mti->mti_flags = lsi->lsi_flags & LDD_F_MASK; + mti->mti_flags |= LDD_F_UPDATE; strncpy(mti->mti_params, lsi->lsi_lmd->lmd_params, - sizeof(mti->mti_params)); - RETURN(0); + sizeof(mti->mti_params)); + return 0; } /* Register an old or new target with the MGS. If needed MGS will construct startup logs and assign index */ -int server_register_target(struct super_block *sb) +static int server_register_target(struct lustre_sb_info *lsi) { - struct lustre_sb_info *lsi = s2lsi(sb); struct obd_device *mgc = lsi->lsi_mgc; - struct lustre_disk_data *ldd = lsi->lsi_ldd; struct mgs_target_info *mti = NULL; bool writeconf; int rc; @@ -979,13 +1064,14 @@ int server_register_target(struct super_block *sb) LASSERT(mgc); - if (!(lsi->lsi_flags & LSI_SERVER)) + if (!IS_SERVER(lsi)) RETURN(-EINVAL); OBD_ALLOC_PTR(mti); if (!mti) RETURN(-ENOMEM); - rc = server_sb2mti(sb, mti); + + rc = server_lsi2mti(lsi, mti); if (rc) GOTO(out, rc); @@ -995,7 +1081,7 @@ int server_register_target(struct super_block *sb) mti->mti_flags); /* if write_conf is true, the registration must succeed */ - writeconf = !!(ldd->ldd_flags & (LDD_F_NEED_INDEX | LDD_F_UPDATE)); + writeconf = !!(lsi->lsi_flags & (LDD_F_NEED_INDEX | LDD_F_UPDATE)); mti->mti_flags |= LDD_F_OPC_REG; /* Register the target */ @@ -1008,7 +1094,7 @@ int server_register_target(struct super_block *sb) LCONSOLE_ERROR_MSG(0x160, "The MGS is refusing to allow this " "server (%s) to start. Please see messages" - " on the MGS node.\n", ldd->ldd_svname); + " on the MGS node.\n", lsi->lsi_svname); } else if (writeconf) { LCONSOLE_ERROR_MSG(0x15f, "Communication to the MGS return error %d. " @@ -1026,7 +1112,6 @@ out: OBD_FREE_PTR(mti); RETURN(rc); } -EXPORT_SYMBOL(server_register_target); /** * Notify the MGS that this target is ready. @@ -1042,13 +1127,13 @@ static int server_notify_target(struct super_block *sb, struct obd_device *obd) LASSERT(mgc); - if (!(lsi->lsi_flags & LSI_SERVER)) + if (!(IS_SERVER(lsi))) RETURN(-EINVAL); OBD_ALLOC_PTR(mti); if (!mti) RETURN(-ENOMEM); - rc = server_sb2mti(sb, mti); + rc = server_lsi2mti(lsi, mti); if (rc) GOTO(out, rc); @@ -1064,7 +1149,7 @@ static int server_notify_target(struct super_block *sb, struct obd_device *obd) /* Imperative recovery: if the mgs informs us to use IR? */ if (!rc && !(mti->mti_flags & LDD_F_ERROR) && (mti->mti_flags & LDD_F_IR_CAPABLE)) - lsi->lsi_flags |= LSI_IR_CAPABLE; + lsi->lsi_flags |= LDD_F_IR_CAPABLE; out: if (mti) @@ -1083,7 +1168,7 @@ static int server_start_targets(struct super_block *sb, struct vfsmount *mnt) int rc; ENTRY; - CDEBUG(D_MOUNT, "starting target %s\n", lsi->lsi_ldd->ldd_svname); + CDEBUG(D_MOUNT, "starting target %s\n", lsi->lsi_svname); #if 0 /* If we're an MDT, make sure the global MDS is running */ @@ -1108,7 +1193,7 @@ static int server_start_targets(struct super_block *sb, struct vfsmount *mnt) #endif /* If we're an OST, make sure the global OSS is running */ - if (IS_OST(lsi->lsi_ldd)) { + if (IS_OST(lsi)) { /* make sure OSS is started */ cfs_mutex_lock(&server_start_lock); obd = class_name2obd(LUSTRE_OSS_OBDNAME); @@ -1135,27 +1220,27 @@ static int server_start_targets(struct super_block *sb, struct vfsmount *mnt) } /* Register with MGS */ - rc = server_register_target(sb); + rc = server_register_target(lsi); if (rc) GOTO(out_mgc, rc); /* Let the target look up the mount using the target's name (we can't pass the sb or mnt through class_process_config.) */ - rc = server_register_mount(lsi->lsi_ldd->ldd_svname, sb, mnt); + rc = server_register_mount(lsi->lsi_svname, sb, mnt); if (rc) GOTO(out_mgc, rc); - /* Start targets using the llog named for the target */ - memset(&cfg, 0, sizeof(cfg)); - rc = lustre_process_log(sb, lsi->lsi_ldd->ldd_svname, &cfg); - if (rc) { - CERROR("failed to start server %s: %d\n", - lsi->lsi_ldd->ldd_svname, rc); - /* Do NOT call server_deregister_mount() here. This makes it - * impossible to find mount later in cleanup time and leaves - * @lsi and othder stuff leaked. -umka */ - GOTO(out_mgc, rc); - } + /* Start targets using the llog named for the target */ + memset(&cfg, 0, sizeof(cfg)); + rc = lustre_process_log(sb, lsi->lsi_svname, &cfg); + if (rc) { + CERROR("failed to start server %s: %d\n", + lsi->lsi_svname, rc); + /* Do NOT call server_deregister_mount() here. This makes it + * impossible to find mount later in cleanup time and leaves + * @lsi and othder stuff leaked. -umka */ + GOTO(out_mgc, rc); + } out_mgc: /* Release the mgc fs for others to use */ @@ -1163,10 +1248,10 @@ out_mgc: server_mgc_clear_fs(lsi->lsi_mgc); if (!rc) { - obd = class_name2obd(lsi->lsi_ldd->ldd_svname); + obd = class_name2obd(lsi->lsi_svname); if (!obd) { CERROR("no server named %s was started\n", - lsi->lsi_ldd->ldd_svname); + lsi->lsi_svname); RETURN(-ENXIO); } @@ -1228,9 +1313,6 @@ static int lustre_free_lsi(struct super_block *sb) /* someone didn't call server_put_mount. */ LASSERT(cfs_atomic_read(&lsi->lsi_mounts) == 0); - if (lsi->lsi_ldd != NULL) - OBD_FREE(lsi->lsi_ldd, sizeof(*lsi->lsi_ldd)); - if (lsi->lsi_lmd != NULL) { if (lsi->lsi_lmd->lmd_dev != NULL) OBD_FREE(lsi->lsi_lmd->lmd_dev, @@ -1286,88 +1368,73 @@ static int lustre_put_lsi(struct super_block *sb) static int lsi_prepare(struct lustre_sb_info *lsi) { - struct lustre_disk_data *ldd; - char *p; - int rc, len; + __u32 index; + int rc; ENTRY; LASSERT(lsi); LASSERT(lsi->lsi_lmd); - OBD_ALLOC(ldd, sizeof(*ldd)); - if (ldd == NULL) - RETURN(-ENOMEM); - - strcpy(lsi->lsi_osd_type, LUSTRE_OSD_NAME); - ldd->ldd_mount_type = LDD_MT_LDISKFS; - /* The server name is given as a mount line option */ if (lsi->lsi_lmd->lmd_profile == NULL) { LCONSOLE_ERROR("Can't determine server name\n"); - GOTO(err, rc = -EINVAL); + RETURN(-EINVAL); } - if (strlen(lsi->lsi_lmd->lmd_profile) >= sizeof(ldd->ldd_svname)) - GOTO(err, rc = -ENAMETOOLONG); + if (strlen(lsi->lsi_lmd->lmd_profile) >= sizeof(lsi->lsi_svname)) + RETURN(-ENAMETOOLONG); - strcpy(ldd->ldd_svname, lsi->lsi_lmd->lmd_profile); + strcpy(lsi->lsi_svname, lsi->lsi_lmd->lmd_profile); /* Determine osd type */ if (lsi->lsi_lmd->lmd_osd_type != NULL) { if (strlen(lsi->lsi_lmd->lmd_osd_type) >= sizeof(lsi->lsi_osd_type)) - GOTO(err, rc = -ENAMETOOLONG); + RETURN(-ENAMETOOLONG); strcpy(lsi->lsi_osd_type, lsi->lsi_lmd->lmd_osd_type); + } else { + strcpy(lsi->lsi_osd_type, LUSTRE_OSD_NAME); } - if ((p = strstr(ldd->ldd_svname, "-OST"))) { - ldd->ldd_flags = LDD_F_SV_TYPE_OST; - } else if ((p = strstr(ldd->ldd_svname, "-MDT"))) { - ldd->ldd_flags = LDD_F_SV_TYPE_MDT; + /* XXX: a temp. solution for components using fsfilt + * to be removed in one of the subsequent patches */ + if (!strcmp(lsi->lsi_lmd->lmd_osd_type, "osd-ldiskfs")) { + strcpy(lsi->lsi_fstype, "ldiskfs"); } else { - LCONSOLE_ERROR("Can't determine server type of '%s'\n", - ldd->ldd_svname); - GOTO(err, rc = -EINVAL); + strcpy(lsi->lsi_fstype, lsi->lsi_lmd->lmd_osd_type); } - len = p - ldd->ldd_svname; - if (len >= MTI_NAME_MAXLEN) - GOTO(err, rc = -ENAMETOOLONG); - memcpy(ldd->ldd_fsname, ldd->ldd_svname, len); - ldd->ldd_fsname[len] = '\0'; - - ldd->ldd_svindex = simple_strtoul(p + 4, NULL, 16); - ldd->ldd_flags |= (lsi->lsi_lmd->lmd_flags & LMD_FLG_WRITECONF) ? - LDD_F_WRITECONF : 0; - ldd->ldd_flags |= (lsi->lsi_lmd->lmd_flags & LMD_FLG_VIRGIN) ? - LDD_F_VIRGIN | LDD_F_UPDATE : 0; - ldd->ldd_flags |= (lsi->lsi_lmd->lmd_flags & LMD_FLG_MGS) ? - LDD_F_SV_TYPE_MGS : 0; - ldd->ldd_flags |= (lsi->lsi_lmd->lmd_flags & LMD_FLG_NO_PRIMNODE) ? - LDD_F_NO_PRIMNODE : 0; - - lsi->lsi_ldd = ldd; + /* Determine server type */ + rc = server_name2index(lsi->lsi_svname, &index, NULL); + if (rc < 0) { + if (lsi->lsi_lmd->lmd_flags & LMD_FLG_MGS) { + /* Assume we're a bare MGS */ + rc = 0; + lsi->lsi_lmd->lmd_flags |= LMD_FLG_NOSVC; + } else { + LCONSOLE_ERROR("Can't determine server type of '%s'\n", + lsi->lsi_svname); + RETURN(rc); + } + } + lsi->lsi_flags |= rc; /* Add mount line flags that used to be in ldd: * writeconf, mgs, iam, anything else? */ -#if 0 lsi->lsi_flags |= (lsi->lsi_lmd->lmd_flags & LMD_FLG_WRITECONF) ? LDD_F_WRITECONF : 0; + lsi->lsi_flags |= (lsi->lsi_lmd->lmd_flags & LMD_FLG_VIRGIN) ? + LDD_F_VIRGIN : 0; lsi->lsi_flags |= (lsi->lsi_lmd->lmd_flags & LMD_FLG_MGS) ? LDD_F_SV_TYPE_MGS : 0; lsi->lsi_flags |= (lsi->lsi_lmd->lmd_flags & LMD_FLG_IAM) ? LDD_F_IAM_DIR : 0; lsi->lsi_flags |= (lsi->lsi_lmd->lmd_flags & LMD_FLG_NO_PRIMNODE) ? LDD_F_NO_PRIMNODE : 0; -#endif RETURN(0); - -err: - OBD_FREE(ldd, sizeof(*ldd)); - RETURN(rc); } /*************** server mount ******************/ @@ -1380,7 +1447,6 @@ err: static struct vfsmount *server_kernel_mount(struct super_block *sb) { struct lustre_sb_info *lsi = s2lsi(sb); - struct lustre_disk_data *ldd; struct lustre_mount_data *lmd = lsi->lsi_lmd; struct vfsmount *mnt; struct file_system_type *type; @@ -1405,8 +1471,6 @@ static struct vfsmount *server_kernel_mount(struct super_block *sb) RETURN(NULL); } - ldd = lsi->lsi_ldd; - /* In the past, we have always used flags = 0. Note ext3/ldiskfs can't be mounted ro. */ s_flags = sb->s_flags; @@ -1421,7 +1485,7 @@ static struct vfsmount *server_kernel_mount(struct super_block *sb) /* Glom up mount options */ memset(options, 0, CFS_PAGE_SIZE); - strncpy(options, ldd->ldd_mount_opts, CFS_PAGE_SIZE - 2); + strncpy(options, lsi->lsi_lmd->lmd_opts, CFS_PAGE_SIZE - 2); len = CFS_PAGE_SIZE - strlen(options) - 2; if (*options != 0) @@ -1436,12 +1500,12 @@ static struct vfsmount *server_kernel_mount(struct super_block *sb) } /* Special permanent mount flags */ - if (IS_OST(ldd)) + if (IS_OST(lsi)) s_flags |= MS_NOATIME | MS_NODIRATIME; CDEBUG(D_MOUNT, "kern_mount: %s %s %s\n", - MT_STR(ldd), lmd->lmd_dev, options); - type = get_fs_type(MT_STR(ldd)); + lsi->lsi_osd_type, lmd->lmd_dev, options); + type = get_fs_type(lsi->lsi_fstype); if (!type) { CERROR("get_fs_type failed\n"); GOTO(out_free, rc = -ENODEV); @@ -1459,15 +1523,12 @@ static struct vfsmount *server_kernel_mount(struct super_block *sb) LR_CLIENT_START); OBD_PAGE_FREE(__page); - lsi->lsi_ldd = ldd; /* freed at lsi cleanup */ CDEBUG(D_SUPER, "%s: mnt = %p\n", lmd->lmd_dev, mnt); RETURN(mnt); out_free: if (__page) OBD_PAGE_FREE(__page); - OBD_FREE(ldd, sizeof(*ldd)); - lsi->lsi_ldd = NULL; RETURN(ERR_PTR(rc)); } @@ -1525,37 +1586,36 @@ static void server_put_super(struct super_block *sb) struct vfsmount *mnt = lsi->lsi_srv_mnt; char *tmpname, *extraname = NULL; int tmpname_sz; - int lddflags = lsi->lsi_ldd->ldd_flags; int lsiflags = lsi->lsi_flags; ENTRY; - LASSERT(lsiflags & LSI_SERVER); + LASSERT(IS_SERVER(lsi)); - tmpname_sz = strlen(lsi->lsi_ldd->ldd_svname) + 1; + tmpname_sz = strlen(lsi->lsi_svname) + 1; OBD_ALLOC(tmpname, tmpname_sz); - memcpy(tmpname, lsi->lsi_ldd->ldd_svname, tmpname_sz); + memcpy(tmpname, lsi->lsi_svname, tmpname_sz); CDEBUG(D_MOUNT, "server put_super %s\n", tmpname); - if (IS_MDT(lsi->lsi_ldd) && (lsi->lsi_lmd->lmd_flags & LMD_FLG_NOSVC)) + if (IS_MDT(lsi) && (lsi->lsi_lmd->lmd_flags & LMD_FLG_NOSVC)) snprintf(tmpname, tmpname_sz, "MGS"); /* Stop the target */ if (!(lsi->lsi_lmd->lmd_flags & LMD_FLG_NOSVC) && - (IS_MDT(lsi->lsi_ldd) || IS_OST(lsi->lsi_ldd))) { + (IS_MDT(lsi) || IS_OST(lsi))) { struct lustre_profile *lprof = NULL; /* tell the mgc to drop the config log */ - lustre_end_log(sb, lsi->lsi_ldd->ldd_svname, NULL); + lustre_end_log(sb, lsi->lsi_svname, NULL); /* COMPAT_146 - profile may get deleted in mgc_cleanup. If there are any setup/cleanup errors, save the lov name for safety cleanup later. */ - lprof = class_get_profile(lsi->lsi_ldd->ldd_svname); + lprof = class_get_profile(lsi->lsi_svname); if (lprof && lprof->lp_dt) { OBD_ALLOC(extraname, strlen(lprof->lp_dt) + 1); strcpy(extraname, lprof->lp_dt); } - obd = class_name2obd(lsi->lsi_ldd->ldd_svname); + obd = class_name2obd(lsi->lsi_svname); if (obd) { CDEBUG(D_MOUNT, "stopping %s\n", obd->obd_name); if (lsi->lsi_flags & LSI_UMOUNT_FAILOVER) @@ -1565,14 +1625,14 @@ static void server_put_super(struct super_block *sb) obd->obd_force = 1; class_manual_cleanup(obd); } else { - CERROR("no obd %s\n", lsi->lsi_ldd->ldd_svname); - server_deregister_mount(lsi->lsi_ldd->ldd_svname); + CERROR("no obd %s\n", lsi->lsi_svname); + server_deregister_mount(lsi->lsi_svname); } } /* If they wanted the mgs to stop separately from the mdt, they should have put it on a different device. */ - if (IS_MGS(lsi->lsi_ldd)) { + if (IS_MGS(lsi)) { /* if MDS start with --nomgs, don't stop MGS then */ if (!(lsi->lsi_lmd->lmd_flags & LMD_FLG_NOMGS)) server_stop_mgs(sb); @@ -1592,7 +1652,7 @@ static void server_put_super(struct super_block *sb) /* Stop the servers (MDS, OSS) if no longer needed. We must wait until the target is really gone so that our type refcount check is right. */ - server_stop_servers(lddflags, lsiflags); + server_stop_servers(lsiflags); /* In case of startup or cleanup err, stop related obds */ if (extraname) { @@ -1635,7 +1695,6 @@ static void server_umount_begin(struct super_block *sb) umount -f = force no third way to do non-force, non-failover */ lsi->lsi_flags &= ~LSI_UMOUNT_FAILOVER; - lsi->lsi_flags |= LSI_UMOUNT_FORCE; EXIT; } @@ -1736,23 +1795,21 @@ static int server_fill_super(struct super_block *sb) } lsi->lsi_srv_mnt = mnt; - LASSERT(lsi->lsi_ldd); - CDEBUG(D_MOUNT, "Found service %s for fs '%s' on device %s\n", - lsi->lsi_ldd->ldd_svname, lsi->lsi_ldd->ldd_fsname, - lsi->lsi_lmd->lmd_dev); + CDEBUG(D_MOUNT, "Found service %s on device %s\n", + lsi->lsi_svname, lsi->lsi_lmd->lmd_dev); - if (class_name2obd(lsi->lsi_ldd->ldd_svname)) { + if (class_name2obd(lsi->lsi_svname)) { LCONSOLE_ERROR_MSG(0x161, "The target named %s is already " "running. Double-mount may have compromised" " the disk journal.\n", - lsi->lsi_ldd->ldd_svname); + lsi->lsi_svname); lustre_put_lsi(sb); unlock_mntput(mnt); RETURN(-EALREADY); } /* Start MGS before MGC */ - if (IS_MGS(lsi->lsi_ldd) && !(lsi->lsi_lmd->lmd_flags & LMD_FLG_NOMGS)){ + if (IS_MGS(lsi) && !(lsi->lsi_lmd->lmd_flags & LMD_FLG_NOMGS)){ rc = server_start_mgs(sb); if (rc) GOTO(out_mnt, rc); @@ -1765,7 +1822,7 @@ static int server_fill_super(struct super_block *sb) /* Set up all obd devices for service */ if (!(lsi->lsi_lmd->lmd_flags & LMD_FLG_NOSVC) && - (IS_OST(lsi->lsi_ldd) || IS_MDT(lsi->lsi_ldd))) { + (IS_OST(lsi) || IS_MDT(lsi))) { rc = server_start_targets(sb, mnt); if (rc < 0) { CERROR("Unable to start targets: %d\n", rc); @@ -1795,42 +1852,6 @@ out_mnt: return rc; } -/* Get the index from the obd name. - rc = server type, or - rc < 0 on error - if endptr isn't NULL it is set to end of name */ -int server_name2index(char *svname, __u32 *idx, char **endptr) -{ - unsigned long index; - int rc; - char *dash = strrchr(svname, '-'); - if (!dash) - return(-EINVAL); - - /* intepret -MDTXXXXX-mdc as mdt, the better way is to pass - * in the fsname, then determine the server index */ - if (!strcmp(LUSTRE_MDC_NAME, dash + 1)) { - dash--; - for (; dash > svname && *dash != '-'; dash--); - if (dash == svname) - return(-EINVAL); - } - - if (strncmp(dash + 1, "MDT", 3) == 0) - rc = LDD_F_SV_TYPE_MDT; - else if (strncmp(dash + 1, "OST", 3) == 0) - rc = LDD_F_SV_TYPE_OST; - else - return(-EINVAL); - if (strcmp(dash + 4, "all") == 0) - return rc | LDD_F_SV_ALL; - - index = simple_strtoul(dash + 4, endptr, 16); - *idx = index; - return rc; -} -EXPORT_SYMBOL(server_name2index); - /* * Calculate timeout value for a target. */ @@ -1840,10 +1861,10 @@ void server_calc_timeout(struct lustre_sb_info *lsi, struct obd_device *obd) int soft = 0; int hard = 0; int factor = 0; - bool has_ir = !!(lsi->lsi_flags & LSI_IR_CAPABLE); + bool has_ir = !!(lsi->lsi_flags & LDD_F_IR_CAPABLE); int min = OBD_RECOVERY_TIME_MIN; - LASSERT(lsi->lsi_flags & LSI_SERVER); + LASSERT(IS_SERVER(lsi)); lmd = lsi->lsi_lmd; if (lmd) { @@ -2379,7 +2400,6 @@ int lustre_fill_super(struct super_block *sb, void *data, int silent) } } else { CDEBUG(D_MOUNT, "Mounting server from %s\n", lmd->lmd_dev); - lsi->lsi_flags |= LSI_SERVER; rc = server_fill_super(sb); /* s_f_s calls lustre_start_mgc after the mount because we need the MGS nids which are stored on disk. Plus, we may @@ -2441,7 +2461,7 @@ void lustre_kill_super(struct super_block *sb) { struct lustre_sb_info *lsi = s2lsi(sb); - if (kill_super_cb && lsi && !(lsi->lsi_flags & LSI_SERVER)) + if (kill_super_cb && lsi && !IS_SERVER(lsi)) (*kill_super_cb)(sb); kill_anon_super(sb); @@ -2474,3 +2494,5 @@ int lustre_unregister_fs(void) { return unregister_filesystem(&lustre_fs_type); } + +EXPORT_SYMBOL(server_mti_print); diff --git a/lustre/obdfilter/filter.c b/lustre/obdfilter/filter.c index 4e634e4..23a992e 100644 --- a/lustre/obdfilter/filter.c +++ b/lustre/obdfilter/filter.c @@ -2054,7 +2054,7 @@ int filter_common_setup(struct obd_device *obd, struct lustre_cfg* lcfg, lcfg bufs 1, 2, 4 (device, fstype, mount opts) are ignored.*/ struct lustre_sb_info *lsi = s2lsi(lmi->lmi_sb); mnt = lmi->lmi_mnt; - obd->obd_fsops = fsfilt_get_ops(MT_STR(lsi->lsi_ldd)); + obd->obd_fsops = fsfilt_get_ops(lsi->lsi_fstype); } else { /* old path - used by lctl */ CERROR("Using old MDS mount method\n"); diff --git a/lustre/osd-ldiskfs/osd_handler.c b/lustre/osd-ldiskfs/osd_handler.c index db890c7..b50d865 100644 --- a/lustre/osd-ldiskfs/osd_handler.c +++ b/lustre/osd-ldiskfs/osd_handler.c @@ -4333,7 +4333,6 @@ static int osd_mount(const struct lu_env *env, { struct lustre_mount_info *lmi; const char *dev = lustre_cfg_string(cfg, 0); - struct lustre_disk_data *ldd; struct lustre_sb_info *lsi; int rc = 0; @@ -4363,15 +4362,14 @@ static int osd_mount(const struct lu_env *env, o->od_mnt = lmi->lmi_mnt; lsi = s2lsi(lmi->lmi_sb); - ldd = lsi->lsi_ldd; - if (ldd->ldd_flags & LDD_F_IAM_DIR) { + if (lsi->lsi_flags & LDD_F_IAM_DIR) { o->od_iop_mode = 0; LCONSOLE_WARN("%s: OSD: IAM mode enabled\n", dev); } else o->od_iop_mode = 1; - if (ldd->ldd_flags & LDD_F_SV_TYPE_OST) { + if (lsi->lsi_flags & LDD_F_SV_TYPE_OST) { rc = osd_compat_init(o); if (rc) CERROR("%s: can't initialize compats: %d\n", dev, rc); diff --git a/lustre/osd-zfs/osd_handler.c b/lustre/osd-zfs/osd_handler.c index 3c2abe5..e4f97cc 100644 --- a/lustre/osd-zfs/osd_handler.c +++ b/lustre/osd-zfs/osd_handler.c @@ -506,7 +506,7 @@ static int osd_mount(const struct lu_env *env, RETURN(-E2BIG); strcpy(o->od_mntdev, dev); - strcpy(o->od_svname, lsi->lsi_ldd->ldd_svname); + strcpy(o->od_svname, lsi->lsi_svname); rc = -udmu_objset_open(o->od_mntdev, &o->od_objset); if (rc) { diff --git a/lustre/utils/mount_utils.h b/lustre/utils/mount_utils.h index d0eca33..d7c965a 100644 --- a/lustre/utils/mount_utils.h +++ b/lustre/utils/mount_utils.h @@ -87,6 +87,15 @@ struct mount_opts { int get_mountdata(char *, struct lustre_disk_data *); +#define MT_STR(data) mt_str((data)->ldd_mount_type) + +#undef IS_MDT +#define IS_MDT(data) ((data)->ldd_flags & LDD_F_SV_TYPE_MDT) +#undef IS_OST +#define IS_OST(data) ((data)->ldd_flags & LDD_F_SV_TYPE_OST) +#undef IS_MGS +#define IS_MGS(data) ((data)->ldd_flags & LDD_F_SV_TYPE_MGS) + /* mkfs/mount helper functions */ void fatal(void); int run_command_err(char *cmd, int cmdsz, char *error_msg); -- 1.8.3.1