readonly_mount
.RS 4
Defaults to off, which lets clients mount in read-write mode. If set to 1,
-clients are only allowed to mount in read-only mount, and get -EROFS otherwise.
+clients are forced to a read-only mount if not specified explicitly.
.RE
.RE
spin_unlock(&fld->lcf_lock);
RETURN(-ENOENT);
}
+EXPORT_SYMBOL(fld_client_del_target);
struct dentry *fld_debugfs_dir;
u64 lu_prandom_u64_max(u64 ep_ro);
int lu_qos_add_tgt(struct lu_qos *qos, struct lu_tgt_desc *ltd);
+int lu_qos_del_tgt(struct lu_qos *qos, struct lu_tgt_desc *ltd);
void lu_tgt_qos_weight_calc(struct lu_tgt_desc *tgt);
int lu_tgt_descs_init(struct lu_tgt_descs *ltd, bool is_mdt);
LASSERT(obd->obd_namespace);
+ spin_lock(&imp->imp_lock);
+ if (imp->imp_state == LUSTRE_IMP_CLOSED && imp->imp_deactive) {
+ /* need to reactivate import if trying to connect
+ * to a previously disconnected
+ */
+ imp->imp_deactive = 0;
+ imp->imp_invalid = 0;
+ }
+ spin_unlock(&imp->imp_lock);
+
imp->imp_dlm_handle = conn;
rc = ptlrpc_init_import(imp);
if (rc != 0)
out_sem:
up_write(&cli->cl_sem);
- if (!rc && localdata) {
- LASSERT(cli->cl_cache == NULL); /* only once */
+ if (!rc && localdata && !cli->cl_cache) {
cli->cl_cache = (struct cl_client_cache *)localdata;
cl_cache_incref(cli->cl_cache);
cli->cl_lru_left = &cli->cl_cache->ccc_lru_left;
data->ocd_ibits_known = MDS_INODELOCK_FULL;
data->ocd_version = LUSTRE_VERSION_CODE;
- if (sb->s_flags & SB_RDONLY)
- data->ocd_connect_flags |= OBD_CONNECT_RDONLY;
if (test_bit(LL_SBI_USER_XATTR, sbi->ll_flags))
data->ocd_connect_flags |= OBD_CONNECT_XATTR;
data->ocd_brw_size = MD_MAX_BRW_SIZE;
+retry_connect:
+ if (sb->s_flags & SB_RDONLY)
+ data->ocd_connect_flags |= OBD_CONNECT_RDONLY;
err = obd_connect(NULL, &sbi->ll_md_exp, sbi->ll_md_obd,
&sbi->ll_sb_uuid, data, sbi->ll_cache);
if (err == -EBUSY) {
err = obd_statfs(NULL, sbi->ll_md_exp, osfs,
ktime_get_seconds() - sbi->ll_statfs_max_age,
OBD_STATFS_FOR_MDT0);
- if (err)
+ if (err == -EROFS && !(sb->s_flags & SB_RDONLY)) {
+ /* We got -EROFS from the server, maybe it is imposing
+ * read-only mount. So just retry like this.
+ */
+ cfs_tty_write_msg("Forcing read-only mount.\n\r");
+ CERROR("%s: mount failed with %d, forcing read-only mount.\n",
+ sbi->ll_md_exp->exp_obd->obd_name, err);
+ sb->s_flags |= SB_RDONLY;
+ obd_fid_fini(sbi->ll_md_exp->exp_obd);
+ obd_disconnect(sbi->ll_md_exp);
+ GOTO(retry_connect, err);
+ } else if (err) {
GOTO(out_md_fid, err);
+ }
/* This needs to be after statfs to ensure connect has finished.
* Note that "data" does NOT contain the valid connect reply.
if (err)
ll_put_super(sb);
else if (test_bit(LL_SBI_VERBOSE, sbi->ll_flags))
- LCONSOLE_WARN("Mounted %s\n", profilenm);
+ LCONSOLE_WARN("Mounted %s%s\n", profilenm,
+ sb->s_flags & SB_RDONLY ? " read-only" : "");
RETURN(err);
} /* ll_fill_super */
mdc_obd->obd_name);
}
+ rc = lu_qos_del_tgt(&lmv->lmv_qos, tgt);
+ if (rc)
+ CERROR("%s: Can't del target from QoS table: rc = %d\n",
+ tgt->ltd_exp->exp_obd->obd_name, rc);
+
+ rc = fld_client_del_target(&lmv->lmv_fld, tgt->ltd_index);
+ if (rc)
+ CERROR("%s: Can't del fld targets: rc = %d\n",
+ tgt->ltd_exp->exp_obd->obd_name, rc);
+
rc = obd_fid_fini(tgt->ltd_exp->exp_obd);
if (rc)
- CERROR("Can't finalize fids factory\n");
+ CERROR("%s: Can't finalize fids factory: rc = %d\n",
+ tgt->ltd_exp->exp_obd->obd_name, rc);
CDEBUG(D_INFO, "Disconnected from %s(%s) successfully\n",
tgt->ltd_exp->exp_obd->obd_name,
tgt->ltd_exp->exp_obd->obd_uuid.uuid);
+ lmv_activate_target(lmv, tgt, 0);
obd_register_observer(tgt->ltd_exp->exp_obd, NULL);
rc = obd_disconnect(tgt->ltd_exp);
if (rc) {
- if (tgt->ltd_active) {
- CERROR("Target %s disconnect error %d\n",
- tgt->ltd_uuid.uuid, rc);
- }
+ CERROR("%s: Target %s disconnect error: rc = %d\n",
+ tgt->ltd_exp->exp_obd->obd_name,
+ tgt->ltd_uuid.uuid, rc);
}
-
- lmv_activate_target(lmv, tgt, 0);
tgt->ltd_exp = NULL;
RETURN(0);
}
* \retval 0 on success
* \retval -ENOENT if no server was found
*/
-static int lu_qos_del_tgt(struct lu_qos *qos, struct lu_tgt_desc *ltd)
+int lu_qos_del_tgt(struct lu_qos *qos, struct lu_tgt_desc *ltd)
{
struct lu_svr_qos *svr;
int rc = 0;
if (!svr)
GOTO(out, rc = -ENOENT);
+ ltd->ltd_qos.ltq_svr = NULL;
svr->lsq_tgt_count--;
if (svr->lsq_tgt_count == 0) {
CDEBUG(D_OTHER, "removing server %s\n",
obd_uuid2str(&svr->lsq_uuid));
list_del(&svr->lsq_svr_list);
- ltd->ltd_qos.ltq_svr = NULL;
OBD_FREE_PTR(svr);
}
up_write(&qos->lq_rw_sem);
RETURN(rc);
}
+EXPORT_SYMBOL(lu_qos_del_tgt);
static inline __u64 tgt_statfs_bavail(struct lu_tgt_desc *tgt)
{
do_facet mgs $LCTL nodemap_modify --name default \
--property readonly_mount --value 1
wait_nm_sync default readonly_mount
- mount_client $MOUNT ${MOUNT_OPTS},rw &&
- error "mount '-o rw' should have failed"
+ mount_client $MOUNT ${MOUNT_OPTS} ||
+ error "mount failed"
+ findmnt $MOUNT --output=options -n -f | grep -q "ro," ||
+ error "mount should have been turned into ro"
+ cat $testfile || error "read $testfile failed (1)"
+ echo b > $testfile && error "write $testfile should fail (1)"
+ umount_client $MOUNT || error "umount $MOUNT failed (3)"
+ mount_client $MOUNT ${MOUNT_OPTS},rw ||
+ error "mount '-o rw' failed"
+ findmnt $MOUNT --output=options -n -f | grep -q "ro," ||
+ error "mount rw should have been turned into ro"
+ cat $testfile || error "read $testfile failed (2)"
+ echo b > $testfile && error "write $testfile should fail (2)"
+ umount_client $MOUNT || error "umount $MOUNT failed (4)"
mount_client $MOUNT ${MOUNT_OPTS},ro ||
error "mount '-o ro' failed"
wait_ssk
- cat $testfile || error "read $testfile failed"
- echo b > $testfile && error "write $testfile should fail"
- umount_client $MOUNT || error "umount $MOUNT failed (3)"
+ cat $testfile || error "read $testfile failed (3)"
+ echo b > $testfile && error "write $testfile should fail (3)"
+ umount_client $MOUNT || error "umount $MOUNT failed (5)"
}
run_test 61 "Nodemap enforces read-only mount"