/** * Match client and OST server connection feature flags. * * Compute the compatibility flags for a connection request based on * features mutually supported by client and server. * * The obd_export::exp_connect_data.ocd_connect_flags field in \a exp * must not be updated here, otherwise a partially initialized value may * be exposed. After the connection request is successfully processed, * the top-level tgt_connect() request handler atomically updates the export * connect flags from the obd_connect_data::ocd_connect_flags field of the * reply. \see tgt_connect(). * * \param[in] env execution environment * \param[in] exp the obd_export associated with this * client/target pair * \param[in] data stores data for this connect request * \param[in] new_connection is this connection new or not * * \retval 0 if success * \retval -EPROTO client and server feature requirements are * incompatible * \retval -EBADF OST index in connect request doesn't match * real OST index */ static int ofd_parse_connect_data(const struct lu_env *env, struct obd_export *exp, struct obd_connect_data *data, bool new_connection) { struct ofd_device *ofd = ofd_exp(exp); struct filter_export_data *fed = &exp->exp_filter_data; if (!data) RETURN(0); CDEBUG(D_RPCTRACE, "%s: cli %s/%p ocd_connect_flags: "LPX64 " ocd_version: %x ocd_grant: %d ocd_index: %u" " ocd_group %u\n", exp->exp_obd->obd_name, exp->exp_client_uuid.uuid, exp, data->ocd_connect_flags, data->ocd_version, data->ocd_grant, data->ocd_index, data->ocd_group); if (fed->fed_group != 0 && fed->fed_group != data->ocd_group) { CWARN("!!! This export (nid %s) used object group %d " "earlier; now it's trying to use group %d! This could " "be a bug in the MDS. Please report to " "https://jira.hpdd.intel.com/\n", obd_export_nid2str(exp), fed->fed_group, data->ocd_group); RETURN(-EPROTO); } fed->fed_group = data->ocd_group; data->ocd_connect_flags &= OST_CONNECT_SUPPORTED; data->ocd_version = LUSTRE_VERSION_CODE; /* Kindly make sure the SKIP_ORPHAN flag is from MDS. */ if (data->ocd_connect_flags & OBD_CONNECT_MDS) CDEBUG(D_HA, "%s: Received MDS connection for group %u\n", exp->exp_obd->obd_name, data->ocd_group); else if (data->ocd_connect_flags & OBD_CONNECT_SKIP_ORPHAN) RETURN(-EPROTO); if (ofd_grant_param_supp(exp)) { exp->exp_filter_data.fed_pagesize = data->ocd_blocksize; /* ocd_{blocksize,inodespace} are log2 values */ data->ocd_blocksize = ofd->ofd_blockbits; data->ocd_inodespace = ofd->ofd_dt_conf.ddp_inodespace; /* ocd_grant_extent is in 1K blocks */ data->ocd_grant_extent = ofd->ofd_dt_conf.ddp_grant_frag >> 10; } if (data->ocd_connect_flags & OBD_CONNECT_GRANT) data->ocd_grant = ofd_grant_connect(env, exp, data->ocd_grant, new_connection); if (data->ocd_connect_flags & OBD_CONNECT_INDEX) { struct lr_server_data *lsd = &ofd->ofd_lut.lut_lsd; int index = lsd->lsd_osd_index; if (index != data->ocd_index) { LCONSOLE_ERROR_MSG(0x136, "Connection from %s to index" " %u doesn't match actual OST index" " %u in last_rcvd file, bad " "configuration?\n", obd_export_nid2str(exp), index, data->ocd_index); RETURN(-EBADF); } if (!(lsd->lsd_feature_compat & OBD_COMPAT_OST)) { /* this will only happen on the first connect */ lsd->lsd_feature_compat |= OBD_COMPAT_OST; /* sync is not needed here as lut_client_add will * set exp_need_sync flag */ tgt_server_data_update(env, &ofd->ofd_lut, 0); } } if (OBD_FAIL_CHECK(OBD_FAIL_OST_BRW_SIZE)) { data->ocd_brw_size = 65536; } else if (data->ocd_connect_flags & OBD_CONNECT_BRW_SIZE) { data->ocd_brw_size = min(data->ocd_brw_size, (__u32)DT_MAX_BRW_SIZE); if (data->ocd_brw_size == 0) { CERROR("%s: cli %s/%p ocd_connect_flags: "LPX64 " ocd_version: %x ocd_grant: %d ocd_index: %u " "ocd_brw_size is unexpectedly zero, " "network data corruption?" "Refusing connection of this client\n", exp->exp_obd->obd_name, exp->exp_client_uuid.uuid, exp, data->ocd_connect_flags, data->ocd_version, data->ocd_grant, data->ocd_index); RETURN(-EPROTO); } } if (data->ocd_connect_flags & OBD_CONNECT_CKSUM) { __u32 cksum_types = data->ocd_cksum_types; /* The client set in ocd_cksum_types the checksum types it * supports. We have to mask off the algorithms that we don't * support */ data->ocd_cksum_types &= cksum_types_supported_server(); if (unlikely(data->ocd_cksum_types == 0)) { CERROR("%s: Connect with checksum support but no " "ocd_cksum_types is set\n", exp->exp_obd->obd_name); RETURN(-EPROTO); } CDEBUG(D_RPCTRACE, "%s: cli %s supports cksum type %x, return " "%x\n", exp->exp_obd->obd_name, obd_export_nid2str(exp), cksum_types, data->ocd_cksum_types); } else { /* This client does not support OBD_CONNECT_CKSUM * fall back to CRC32 */ CDEBUG(D_RPCTRACE, "%s: cli %s does not support " "OBD_CONNECT_CKSUM, CRC32 will be used\n", exp->exp_obd->obd_name, obd_export_nid2str(exp)); } if (data->ocd_connect_flags & OBD_CONNECT_MAXBYTES) data->ocd_maxbytes = ofd->ofd_dt_conf.ddp_maxbytes; if (OCD_HAS_FLAG(data, PINGLESS)) { if (ptlrpc_pinger_suppress_pings()) { spin_lock(&exp->exp_obd->obd_dev_lock); list_del_init(&exp->exp_obd_chain_timed); spin_unlock(&exp->exp_obd->obd_dev_lock); } else { data->ocd_connect_flags &= ~OBD_CONNECT_PINGLESS; } } RETURN(0); }
int lprocfs_exp_nid_seq_show(struct seq_file *m, void *data) { struct obd_export *exp = m->private; LASSERT(exp != NULL); return seq_printf(m, "%s\n", obd_export_nid2str(exp)); }
/* Called whenever a target starts up. Flags indicate first connect, etc. */ static int mgs_handle_target_reg(struct ptlrpc_request *req) { struct obd_device *obd = req->rq_export->exp_obd; struct mgs_target_info *mti, *rep_mti; struct fs_db *fsdb; int opc; int rc = 0; ENTRY; mgs_counter_incr(req->rq_export, LPROC_MGS_TARGET_REG); mti = req_capsule_client_get(&req->rq_pill, &RMF_MGS_TARGET_INFO); opc = mti->mti_flags & LDD_F_OPC_MASK; if (opc == LDD_F_OPC_READY) { CDEBUG(D_MGS, "fs: %s index: %d is ready to reconnect.\n", mti->mti_fsname, mti->mti_stripe_index); rc = mgs_ir_update(obd, mti); if (rc) { LASSERT(!(mti->mti_flags & LDD_F_IR_CAPABLE)); CERROR("Update IR return with %d(ignore and IR " "disabled)\n", rc); } GOTO(out_nolock, rc); } /* Do not support unregistering right now. */ if (opc != LDD_F_OPC_REG) GOTO(out_nolock, rc = -EINVAL); CDEBUG(D_MGS, "fs: %s index: %d is registered to MGS.\n", mti->mti_fsname, mti->mti_stripe_index); if (mti->mti_flags & LDD_F_NEED_INDEX) mti->mti_flags |= LDD_F_WRITECONF; if (!(mti->mti_flags & (LDD_F_WRITECONF | LDD_F_UPGRADE14 | LDD_F_UPDATE))) { /* We're just here as a startup ping. */ CDEBUG(D_MGS, "Server %s is running on %s\n", mti->mti_svname, obd_export_nid2str(req->rq_export)); rc = mgs_check_target(obd, mti); /* above will set appropriate mti flags */ if (rc <= 0) /* Nothing wrong, or fatal error */ GOTO(out_nolock, rc); } else { if (!(mti->mti_flags & LDD_F_NO_PRIMNODE) && (rc = mgs_check_failover_reg(mti))) GOTO(out_nolock, rc); } OBD_FAIL_TIMEOUT(OBD_FAIL_MGS_PAUSE_TARGET_REG, 10); if (mti->mti_flags & LDD_F_WRITECONF) { if (mti->mti_flags & LDD_F_SV_TYPE_MDT && mti->mti_stripe_index == 0) { rc = mgs_erase_logs(obd, mti->mti_fsname); LCONSOLE_WARN("%s: Logs for fs %s were removed by user " "request. All servers must be restarted " "in order to regenerate the logs." "\n", obd->obd_name, mti->mti_fsname); } else if (mti->mti_flags & (LDD_F_SV_TYPE_OST | LDD_F_SV_TYPE_MDT)) { rc = mgs_erase_log(obd, mti->mti_svname); LCONSOLE_WARN("%s: Regenerating %s log by user " "request.\n", obd->obd_name, mti->mti_svname); } mti->mti_flags |= LDD_F_UPDATE; /* Erased logs means start from scratch. */ mti->mti_flags &= ~LDD_F_UPGRADE14; } rc = mgs_find_or_make_fsdb(obd, mti->mti_fsname, &fsdb); if (rc) { CERROR("Can't get db for %s: %d\n", mti->mti_fsname, rc); GOTO(out_nolock, rc); } /* * Log writing contention is handled by the fsdb_mutex. * * It should be alright if someone was reading while we were * updating the logs - if we revoke at the end they will just update * from where they left off. */ /* COMPAT_146 */ if (mti->mti_flags & LDD_F_UPGRADE14) { rc = mgs_upgrade_sv_14(obd, mti, fsdb); if (rc) { CERROR("Can't upgrade from 1.4 (%d)\n", rc); GOTO(out, rc); } /* We're good to go */ mti->mti_flags |= LDD_F_UPDATE; } /* end COMPAT_146 */ if (mti->mti_flags & LDD_F_UPDATE) { CDEBUG(D_MGS, "updating %s, index=%d\n", mti->mti_svname, mti->mti_stripe_index); /* create or update the target log and update the client/mdt logs */ rc = mgs_write_log_target(obd, mti, fsdb); if (rc) { CERROR("Failed to write %s log (%d)\n", mti->mti_svname, rc); GOTO(out, rc); } mti->mti_flags &= ~(LDD_F_VIRGIN | LDD_F_UPDATE | LDD_F_NEED_INDEX | LDD_F_WRITECONF | LDD_F_UPGRADE14); mti->mti_flags |= LDD_F_REWRITE_LDD; } out: mgs_revoke_lock(obd, fsdb, CONFIG_T_CONFIG); out_nolock: CDEBUG(D_MGS, "replying with %s, index=%d, rc=%d\n", mti->mti_svname, mti->mti_stripe_index, rc); req->rq_status = rc; if (rc) /* we need an error flag to tell the target what's going on, * instead of just doing it by error code only. */ mti->mti_flags |= LDD_F_ERROR; rc = req_capsule_server_pack(&req->rq_pill); if (rc) RETURN(rc); /* send back the whole mti in the reply */ rep_mti = req_capsule_server_get(&req->rq_pill, &RMF_MGS_TARGET_INFO); *rep_mti = *mti; /* Flush logs to disk */ fsfilt_sync(obd, obd->u.mgs.mgs_sb); RETURN(rc); }