X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lustre%2Fobdclass%2Fobd_mount_server.c;h=9945ef0fd6da98890c50fb733766012a7b2d73d9;hb=bccfc65d04dbd59bedb5dc1509bbdc732fc09b53;hp=8c3e8f2f1bc68a0f91d68d916368551c0d97d002;hpb=730a204e73667403e299936fafa0d3eb45099709;p=fs%2Flustre-release.git diff --git a/lustre/obdclass/obd_mount_server.c b/lustre/obdclass/obd_mount_server.c index 8c3e8f2..9945ef0 100644 --- a/lustre/obdclass/obd_mount_server.c +++ b/lustre/obdclass/obd_mount_server.c @@ -27,7 +27,7 @@ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2013, Intel Corporation. + * Copyright (c) 2013, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ @@ -46,34 +46,40 @@ #define PRINT_CMD CDEBUG #define PRINT_MASK (D_SUPER | D_CONFIG) -#include -#include -#include +#include +#include +#include #include -#include -#include -#include #ifdef HAVE_KERNEL_LOCKED #include #endif -#ifdef HAVE_SELINUX_IS_ENABLED -#include -#endif + +#include +#include + +#include +#include +#include +#include +#include +#include +#include /*********** mount lookup *********/ -DEFINE_MUTEX(lustre_mount_info_lock); -static CFS_LIST_HEAD(server_mount_info_list); +static DEFINE_MUTEX(lustre_mount_info_lock); +static struct list_head server_mount_info_list = + LIST_HEAD_INIT(server_mount_info_list); static struct lustre_mount_info *server_find_mount(const char *name) { - cfs_list_t *tmp; + struct list_head *tmp; struct lustre_mount_info *lmi; ENTRY; - cfs_list_for_each(tmp, &server_mount_info_list) { - lmi = cfs_list_entry(tmp, struct lustre_mount_info, - lmi_list_chain); + list_for_each(tmp, &server_mount_info_list) { + lmi = list_entry(tmp, struct lustre_mount_info, + lmi_list_chain); if (strcmp(name, lmi->lmi_name) == 0) RETURN(lmi); } @@ -112,7 +118,7 @@ static int server_register_mount(const char *name, struct super_block *sb) } lmi->lmi_name = name_cp; lmi->lmi_sb = sb; - cfs_list_add(&lmi->lmi_list_chain, &server_mount_info_list); + list_add(&lmi->lmi_list_chain, &server_mount_info_list); mutex_unlock(&lustre_mount_info_lock); @@ -138,7 +144,7 @@ static int server_deregister_mount(const char *name) CDEBUG(D_MOUNT, "deregister mount %p from %s\n", lmi->lmi_sb, name); OBD_FREE(lmi->lmi_name, strlen(lmi->lmi_name) + 1); - cfs_list_del(&lmi->lmi_list_chain); + list_del(&lmi->lmi_list_chain); OBD_FREE(lmi, sizeof(*lmi)); mutex_unlock(&lustre_mount_info_lock); @@ -172,28 +178,19 @@ struct lustre_mount_info *server_get_mount(const char *name) } EXPORT_SYMBOL(server_get_mount); -/* - * Used by mdt to get mount_info from obdname. - * There are no blocking when using the mount_info. - * Do not use server_get_mount for this purpose. +/** + * server_put_mount: to be called from obd_cleanup methods + * @name: obd name + * @dereg_mnt: 0 or 1 depending on whether the mount is to be deregistered or + * not + * + * The caller decides whether server_deregister_mount() needs to be called or + * not. Calling of server_deregister_mount() does not depend on refcounting on + * lsi because we could have say the mgs and mds on the same node and we + * unmount the mds, then the ref on the lsi would still be non-zero but we + * would still want to deregister the mds mount. */ -struct lustre_mount_info *server_get_mount_2(const char *name) -{ - struct lustre_mount_info *lmi; - ENTRY; - - mutex_lock(&lustre_mount_info_lock); - lmi = server_find_mount(name); - mutex_unlock(&lustre_mount_info_lock); - if (!lmi) - CERROR("Can't find mount for %s\n", name); - - RETURN(lmi); -} -EXPORT_SYMBOL(server_get_mount_2); - -/* to be called from obd_cleanup methods */ -int server_put_mount(const char *name) +int server_put_mount(const char *name, bool dereg_mnt) { struct lustre_mount_info *lmi; struct lustre_sb_info *lsi; @@ -215,21 +212,14 @@ int server_put_mount(const char *name) CDEBUG(D_MOUNT, "Last put of mount %p from %s\n", lmi->lmi_sb, name); - /* this obd should never need the mount again */ - server_deregister_mount(name); + if (dereg_mnt) + /* this obd should never need the mount again */ + server_deregister_mount(name); RETURN(0); } EXPORT_SYMBOL(server_put_mount); -/* Corresponding to server_get_mount_2 */ -int server_put_mount_2(const char *name, struct vfsmount *mnt) -{ - ENTRY; - RETURN(0); -} -EXPORT_SYMBOL(server_put_mount_2); - /* Set up a MGS to serve startup logs */ static int server_start_mgs(struct super_block *sb) { @@ -254,8 +244,8 @@ static int server_start_mgs(struct super_block *sb) if (!rc) { rc = lustre_start_simple(LUSTRE_MGS_OBDNAME, LUSTRE_MGS_NAME, - LUSTRE_MGS_OBDNAME, 0, 0, - lsi->lsi_osd_obdname, 0); + LUSTRE_MGS_OBDNAME, NULL, NULL, + lsi->lsi_osd_obdname, NULL); /* server_deregister_mount() is not called previously, for lsi * and other stuff can't be freed cleanly when mgs calls * server_put_mount() in error handling case (see b=17758), @@ -277,8 +267,14 @@ static int server_stop_mgs(struct super_block *sb) { struct obd_device *obd; int rc; + struct lustre_mount_info *lmi; ENTRY; + /* Do not stop MGS if this device is not the running MGT */ + lmi = server_find_mount(LUSTRE_MGS_OBDNAME); + if (lmi != NULL && lmi->lmi_sb != sb) + RETURN(0); + CDEBUG(D_MOUNT, "Stop MGS service %s\n", LUSTRE_MGS_OBDNAME); /* There better be only one MGS */ @@ -296,7 +292,8 @@ static int server_stop_mgs(struct super_block *sb) /* Since there's only one mgc per node, we have to change it's fs to get access to the right disk. */ -static int server_mgc_set_fs(struct obd_device *mgc, struct super_block *sb) +static int server_mgc_set_fs(const struct lu_env *env, + struct obd_device *mgc, struct super_block *sb) { struct lustre_sb_info *lsi = s2lsi(sb); int rc; @@ -305,7 +302,7 @@ static int server_mgc_set_fs(struct obd_device *mgc, struct super_block *sb) CDEBUG(D_MOUNT, "Set mgc disk for %s\n", lsi->lsi_lmd->lmd_dev); /* cl_mgc_sem in mgc insures we sleep if the mgc_fs is busy */ - rc = obd_set_info_async(NULL, mgc->obd_self_export, + rc = obd_set_info_async(env, mgc->obd_self_export, sizeof(KEY_SET_FS), KEY_SET_FS, sizeof(*sb), sb, NULL); if (rc != 0) @@ -314,14 +311,15 @@ static int server_mgc_set_fs(struct obd_device *mgc, struct super_block *sb) RETURN(rc); } -static int server_mgc_clear_fs(struct obd_device *mgc) +static int server_mgc_clear_fs(const struct lu_env *env, + struct obd_device *mgc) { int rc; ENTRY; CDEBUG(D_MOUNT, "Unassign mgc disk\n"); - rc = obd_set_info_async(NULL, mgc->obd_self_export, + rc = obd_set_info_async(env, mgc->obd_self_export, sizeof(KEY_CLEAR_FS), KEY_CLEAR_FS, 0, NULL, NULL); RETURN(rc); @@ -389,8 +387,20 @@ cleanup: } EXPORT_SYMBOL(tgt_name2lwp_name); -static CFS_LIST_HEAD(lwp_register_list); -DEFINE_MUTEX(lwp_register_list_lock); +static struct list_head lwp_register_list = + LIST_HEAD_INIT(lwp_register_list); +static DEFINE_SPINLOCK(lwp_register_list_lock); + +static void lustre_put_lwp_item(struct lwp_register_item *lri) +{ + if (atomic_dec_and_test(&lri->lri_ref)) { + LASSERT(list_empty(&lri->lri_list)); + + if (*lri->lri_exp != NULL) + class_export_put(*lri->lri_exp); + OBD_FREE_PTR(lri); + } +} int lustre_register_lwp_item(const char *lwpname, struct obd_export **exp, register_lwp_cb cb_func, void *cb_data) @@ -407,15 +417,12 @@ int lustre_register_lwp_item(const char *lwpname, struct obd_export **exp, if (lri == NULL) RETURN(-ENOMEM); - mutex_lock(&lwp_register_list_lock); - lwp = class_name2obd(lwpname); if (lwp != NULL && lwp->obd_set_up == 1) { struct obd_uuid *uuid; OBD_ALLOC_PTR(uuid); if (uuid == NULL) { - mutex_unlock(&lwp_register_list_lock); OBD_FREE_PTR(lri); RETURN(-ENOMEM); } @@ -428,32 +435,41 @@ int lustre_register_lwp_item(const char *lwpname, struct obd_export **exp, lri->lri_exp = exp; lri->lri_cb_func = cb_func; lri->lri_cb_data = cb_data; - CFS_INIT_LIST_HEAD(&lri->lri_list); - cfs_list_add(&lri->lri_list, &lwp_register_list); + INIT_LIST_HEAD(&lri->lri_list); + /* + * Initialize the lri_ref at 2, one will be released before + * current function returned via lustre_put_lwp_item(), the + * other will be released in lustre_deregister_lwp_item(). + */ + atomic_set(&lri->lri_ref, 2); + + spin_lock(&lwp_register_list_lock); + list_add(&lri->lri_list, &lwp_register_list); + spin_unlock(&lwp_register_list_lock); if (*exp != NULL && cb_func != NULL) cb_func(cb_data); + lustre_put_lwp_item(lri); - mutex_unlock(&lwp_register_list_lock); RETURN(0); } EXPORT_SYMBOL(lustre_register_lwp_item); void lustre_deregister_lwp_item(struct obd_export **exp) { - struct lwp_register_item *lri, *tmp; + struct lwp_register_item *lri; - mutex_lock(&lwp_register_list_lock); - cfs_list_for_each_entry_safe(lri, tmp, &lwp_register_list, lri_list) { + spin_lock(&lwp_register_list_lock); + list_for_each_entry(lri, &lwp_register_list, lri_list) { if (exp == lri->lri_exp) { - if (*exp) - class_export_put(*exp); - cfs_list_del(&lri->lri_list); - OBD_FREE_PTR(lri); - break; + list_del_init(&lri->lri_list); + spin_unlock(&lwp_register_list_lock); + + lustre_put_lwp_item(lri); + return; } } - mutex_unlock(&lwp_register_list_lock); + spin_unlock(&lwp_register_list_lock); } EXPORT_SYMBOL(lustre_deregister_lwp_item); @@ -467,7 +483,7 @@ struct obd_export *lustre_find_lwp_by_index(const char *dev, __u32 idx) char lwp_name[24]; int rc; - lmi = server_get_mount_2(dev); + lmi = server_get_mount(dev); if (lmi == NULL) return NULL; @@ -476,7 +492,7 @@ struct obd_export *lustre_find_lwp_by_index(const char *dev, __u32 idx) if (rc != 0) { CERROR("%s: failed to get fsname: rc = %d\n", lsi->lsi_svname, rc); - return NULL; + goto err_lmi; } snprintf(lwp_name, sizeof(lwp_name), "%s-MDT%04x", fsname, idx); @@ -484,34 +500,50 @@ struct obd_export *lustre_find_lwp_by_index(const char *dev, __u32 idx) list_for_each_entry(lwp, &lsi->lsi_lwp_list, obd_lwp_list) { char *ptr = strstr(lwp->obd_name, lwp_name); - if (ptr != NULL) { + if (ptr != NULL && lwp->obd_lwp_export != NULL) { exp = class_export_get(lwp->obd_lwp_export); break; } } spin_unlock(&lsi->lsi_lwp_lock); +err_lmi: + server_put_mount(dev, false); + return exp; } EXPORT_SYMBOL(lustre_find_lwp_by_index); -static void lustre_notify_lwp_list(struct obd_export *exp) +void lustre_notify_lwp_list(struct obd_export *exp) { - struct lwp_register_item *lri, *tmp; + struct lwp_register_item *lri; LASSERT(exp != NULL); - mutex_lock(&lwp_register_list_lock); - cfs_list_for_each_entry_safe(lri, tmp, &lwp_register_list, lri_list) { +again: + spin_lock(&lwp_register_list_lock); + list_for_each_entry(lri, &lwp_register_list, lri_list) { if (strcmp(exp->exp_obd->obd_name, lri->lri_name)) continue; if (*lri->lri_exp != NULL) continue; *lri->lri_exp = class_export_get(exp); + atomic_inc(&lri->lri_ref); + spin_unlock(&lwp_register_list_lock); + if (lri->lri_cb_func != NULL) lri->lri_cb_func(lri->lri_cb_data); + lustre_put_lwp_item(lri); + + /* Others may have changed the list after we unlock, we have + * to rescan the list from the beginning. Usually, the list + * 'lwp_register_list' is very short, and there is 'guard' + * lri::lri_exp that will prevent the callback to be done + * repeatedly. So rescanning the list has no problem. */ + goto again; } - mutex_unlock(&lwp_register_list_lock); + spin_unlock(&lwp_register_list_lock); } +EXPORT_SYMBOL(lustre_notify_lwp_list); static int lustre_lwp_connect(struct obd_device *lwp) { @@ -542,7 +574,8 @@ static int lustre_lwp_connect(struct obd_device *lwp) data->ocd_connect_flags |= OBD_CONNECT_MDS_MDS | OBD_CONNECT_FID | OBD_CONNECT_AT | OBD_CONNECT_LRU_RESIZE | OBD_CONNECT_FULL20 | OBD_CONNECT_LVB_TYPE | - OBD_CONNECT_LIGHTWEIGHT | OBD_CONNECT_LFSCK; + OBD_CONNECT_LIGHTWEIGHT | OBD_CONNECT_LFSCK | + OBD_CONNECT_BULK_MBITS; OBD_ALLOC_PTR(uuid); if (uuid == NULL) GOTO(out, rc = -ENOMEM); @@ -562,7 +595,6 @@ static int lustre_lwp_connect(struct obd_device *lwp) if (unlikely(lwp->obd_lwp_export != NULL)) class_export_put(lwp->obd_lwp_export); lwp->obd_lwp_export = class_export_get(exp); - lustre_notify_lwp_list(exp); } GOTO(out, rc); @@ -618,7 +650,7 @@ static int lustre_lwp_setup(struct lustre_cfg *lcfg, struct lustre_sb_info *lsi, sprintf(lwpuuid, "%s_UUID", lwpname); rc = lustre_start_simple(lwpname, LUSTRE_LWP_NAME, lwpuuid, lustre_cfg_string(lcfg, 1), - 0, 0, 0); + NULL, NULL, NULL); if (rc) { CERROR("%s: setup up failed: rc %d\n", lwpname, rc); GOTO(out, rc); @@ -710,16 +742,18 @@ static int lustre_lwp_add_conn(struct lustre_cfg *cfg, lustre_cfg_string(cfg, 1)); lcfg = lustre_cfg_new(LCFG_ADD_CONN, bufs); - + if (lcfg == NULL) + GOTO(out_cfg, rc = -ENOMEM); rc = class_add_conn(lwp, lcfg); if (rc) CERROR("%s: can't add conn: rc = %d\n", lwpname, rc); -out: - if (bufs != NULL) - OBD_FREE_PTR(bufs); if (lcfg != NULL) lustre_cfg_free(lcfg); +out_cfg: + if (bufs != NULL) + OBD_FREE_PTR(bufs); +out: if (lwpname != NULL) OBD_FREE(lwpname, MTI_NAME_MAXLEN); RETURN(rc); @@ -838,8 +872,11 @@ static int client_lwp_config_process(const struct lu_env *env, *ptr = '-'; break; } - *ptr = '-'; + + if (IS_MDT(lsi) && idx != 0) + break; + rc = lustre_lwp_add_conn(lcfg, lsi, idx); break; } @@ -881,7 +918,7 @@ static int lustre_disconnect_lwp(struct super_block *sb) /* end log first */ cfg->cfg_instance = sb; rc = lustre_end_log(sb, logname, cfg); - if (rc != 0) + if (rc != 0 && rc != -ENOENT) GOTO(out, rc); lsi->lsi_lwp_started = 0; @@ -990,8 +1027,8 @@ static int lustre_start_lwp(struct super_block *sb) cfg->cfg_callback = client_lwp_config_process; cfg->cfg_instance = sb; rc = lustre_process_log(sb, logname, cfg); - if (rc == 0) - lsi->lsi_lwp_started = 1; + /* need to remove config llog from mgc */ + lsi->lsi_lwp_started = 1; GOTO(out, rc); @@ -1003,7 +1040,7 @@ out: return rc; } -DEFINE_MUTEX(server_start_lock); +static DEFINE_MUTEX(server_start_lock); /* Stop MDS/OSS if nobody is using them */ static int server_stop_servers(int lsiflags) @@ -1051,7 +1088,6 @@ int server_mti_print(const char *title, struct mgs_target_info *mti) mti->mti_config_ver, mti->mti_flags); return 0; } -EXPORT_SYMBOL(server_mti_print); /* Generate data for registration */ static int server_lsi2mti(struct lustre_sb_info *lsi, @@ -1168,8 +1204,8 @@ static int server_register_target(struct lustre_sb_info *lsi) "rc = %d. Is the MGS running?\n", lsi->lsi_svname, rc); } else { - CERROR("%s: error registering with the MGS: rc = %d " - "(not fatal)\n", lsi->lsi_svname, rc); + CDEBUG(D_HA, "%s: error registering with the MGS: " + "rc = %d (not fatal)\n", lsi->lsi_svname, rc); /* reset the error code for non-fatal error. */ rc = 0; } @@ -1234,7 +1270,7 @@ static int server_start_targets(struct super_block *sb) struct obd_device *obd; struct lustre_sb_info *lsi = s2lsi(sb); struct config_llog_instance cfg; - struct lu_env env; + struct lu_env mgc_env; struct lu_device *dev; int rc; ENTRY; @@ -1249,7 +1285,7 @@ static int server_start_targets(struct super_block *sb) rc = lustre_start_simple(LUSTRE_MDS_OBDNAME, LUSTRE_MDS_NAME, LUSTRE_MDS_OBDNAME"_uuid", - 0, 0, 0, 0); + NULL, NULL, NULL, NULL); if (rc) { mutex_unlock(&server_start_lock); CERROR("failed to start MDS: %d\n", rc); @@ -1268,7 +1304,7 @@ static int server_start_targets(struct super_block *sb) rc = lustre_start_simple(LUSTRE_OSS_OBDNAME, LUSTRE_OSS_NAME, LUSTRE_OSS_OBDNAME"_uuid", - 0, 0, 0, 0); + NULL, NULL, NULL, NULL); if (rc) { mutex_unlock(&server_start_lock); CERROR("failed to start OSS: %d\n", rc); @@ -1278,11 +1314,15 @@ static int server_start_targets(struct super_block *sb) mutex_unlock(&server_start_lock); } + rc = lu_env_init(&mgc_env, LCT_MG_THREAD); + if (rc != 0) + GOTO(out_stop_service, rc); + /* Set the mgc fs to our server disk. This allows the MGC to * read and write configs locally, in case it can't talk to the MGS. */ - rc = server_mgc_set_fs(lsi->lsi_mgc, sb); + rc = server_mgc_set_fs(&mgc_env, lsi->lsi_mgc, sb); if (rc) - GOTO(out_stop_service, rc); + GOTO(out_env, rc); /* Register with MGS */ rc = server_register_target(lsi); @@ -1334,6 +1374,8 @@ static int server_start_targets(struct super_block *sb) /* log has been fully processed, let clients connect */ dev = obd->obd_lu_dev; if (dev && dev->ld_ops->ldo_prepare) { + struct lu_env env; + rc = lu_env_init(&env, dev->ld_type->ldt_ctx_tags); if (rc == 0) { struct lu_context session_ctx; @@ -1361,8 +1403,9 @@ static int server_start_targets(struct super_block *sb) out_mgc: /* Release the mgc fs for others to use */ - server_mgc_clear_fs(lsi->lsi_mgc); - + server_mgc_clear_fs(&mgc_env, lsi->lsi_mgc); +out_env: + lu_env_fini(&mgc_env); out_stop_service: if (rc != 0) server_stop_servers(lsi->lsi_flags); @@ -1372,6 +1415,8 @@ out_stop_service: static int lsi_prepare(struct lustre_sb_info *lsi) { + const char *osd_type; + const char *fstype; __u32 index; int rc; ENTRY; @@ -1385,28 +1430,26 @@ static int lsi_prepare(struct lustre_sb_info *lsi) RETURN(-EINVAL); } - if (strlen(lsi->lsi_lmd->lmd_profile) >= sizeof(lsi->lsi_svname)) - RETURN(-ENAMETOOLONG); - - 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)) - RETURN(-ENAMETOOLONG); - - strcpy(lsi->lsi_osd_type, lsi->lsi_lmd->lmd_osd_type); + if (lsi->lsi_lmd->lmd_osd_type == NULL) { + osd_type = LUSTRE_OSD_LDISKFS_NAME; + fstype = "ldiskfs"; } else { - strcpy(lsi->lsi_osd_type, LUSTRE_OSD_LDISKFS_NAME); + osd_type = lsi->lsi_lmd->lmd_osd_type; + fstype = lsi->lsi_lmd->lmd_osd_type; } + if (strlen(lsi->lsi_lmd->lmd_profile) >= sizeof(lsi->lsi_svname) || + strlen(osd_type) >= sizeof(lsi->lsi_osd_type) || + strlen(fstype) >= sizeof(lsi->lsi_fstype)) + RETURN(-ENAMETOOLONG); + + strlcpy(lsi->lsi_svname, lsi->lsi_lmd->lmd_profile, + sizeof(lsi->lsi_svname)); + strlcpy(lsi->lsi_osd_type, osd_type, sizeof(lsi->lsi_osd_type)); /* XXX: a temp. solution for components using ldiskfs * 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 - strcpy(lsi->lsi_fstype, lsi->lsi_lmd->lmd_osd_type); + strlcpy(lsi->lsi_fstype, fstype, sizeof(lsi->lsi_fstype)); /* Determine server type */ rc = server_name2index(lsi->lsi_svname, &index, NULL); @@ -1485,9 +1528,13 @@ static void server_put_super(struct super_block *sb) If there are any setup/cleanup errors, save the lov name for safety cleanup later. */ 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); + if (lprof != NULL) { + if (lprof->lp_dt != NULL) { + OBD_ALLOC(extraname, strlen(lprof->lp_dt) + 1); + strncpy(extraname, lprof->lp_dt, + strlen(lprof->lp_dt) + 1); + } + class_put_profile(lprof); } obd = class_name2obd(lsi->lsi_svname); @@ -1623,7 +1670,7 @@ static ssize_t lustre_listxattr(struct dentry *d_entry, char *name, return -EOPNOTSUPP; } -const struct inode_operations server_inode_operations = { +static const struct inode_operations server_inode_operations = { .setxattr = lustre_setxattr, .getxattr = lustre_getxattr, .listxattr = lustre_listxattr, @@ -1634,7 +1681,7 @@ const struct inode_operations server_inode_operations = { static int server_fill_super_common(struct super_block *sb) { - struct inode *root = 0; + struct inode *root = NULL; ENTRY; CDEBUG(D_MOUNT, "Server sb, dev=%d\n", (int)sb->s_dev); @@ -1695,10 +1742,20 @@ static int osd_start(struct lustre_sb_info *lsi, unsigned long mflags) GOTO(out, rc); obd = class_name2obd(lsi->lsi_osd_obdname); LASSERT(obd); + } else { + CDEBUG(D_MOUNT, "%s already started\n", lsi->lsi_osd_obdname); + /* but continue setup to allow special case of MDT and internal + * MGT being started separately. */ + if (!((IS_MGS(lsi) && (lsi->lsi_lmd->lmd_flags & + LMD_FLG_NOMGS)) || + (IS_MDT(lsi) && (lsi->lsi_lmd->lmd_flags & + LMD_FLG_NOSVC)))) + RETURN(-EALREADY); } rc = obd_connect(NULL, &lsi->lsi_osd_exp, obd, &obd->obd_uuid, NULL, NULL); + if (rc) { obd->obd_force = 1; class_manual_cleanup(obd); @@ -1731,6 +1788,9 @@ int server_fill_super(struct super_block *sb) int rc; ENTRY; + /* to simulate target mount race */ + OBD_RACE(OBD_FAIL_TGT_MOUNT_RACE); + rc = lsi_prepare(lsi); if (rc) RETURN(rc); @@ -1860,4 +1920,3 @@ void server_calc_timeout(struct lustre_sb_info *lsi, struct obd_device *obd) obd->obd_recovery_time_hard = hard; obd->obd_recovery_ir_factor = factor; } -EXPORT_SYMBOL(server_calc_timeout);