X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=blobdiff_plain;f=lustre%2Fobdclass%2Fobd_config.c;h=34c5711d68fd8cb00d912596b0b2917fe8027135;hp=28af8f83b714986811cf518e3754c2bfc23cf4fe;hb=939a742d5093c1a79cc9c08496d181597d28f243;hpb=d8278c699434fd7975609e121a1a75820595a601 diff --git a/lustre/obdclass/obd_config.c b/lustre/obdclass/obd_config.c index 28af8f8..34c5711 100644 --- a/lustre/obdclass/obd_config.c +++ b/lustre/obdclass/obd_config.c @@ -15,11 +15,7 @@ * * You should have received a copy of the GNU General Public License * version 2 along with this program; If not, see - * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf - * - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. + * http://www.gnu.org/licenses/gpl-2.0.html * * GPL HEADER END */ @@ -27,7 +23,7 @@ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2011, 2014, Intel Corporation. + * Copyright (c) 2011, 2016, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ @@ -39,19 +35,23 @@ */ #define DEBUG_SUBSYSTEM S_CLASS -#include + #include + +#include +#include #include #include #include -#include #include +#include #include "llog_internal.h" static struct cfs_hash_ops uuid_hash_ops; static struct cfs_hash_ops nid_hash_ops; static struct cfs_hash_ops nid_stat_hash_ops; +static struct cfs_hash_ops gen_hash_ops; /*********** string parsing utils *********/ @@ -394,7 +394,7 @@ int class_attach(struct lustre_cfg *lcfg) /* XXX belongs in setup not attach */ init_rwsem(&obd->obd_observer_link_sem); /* recovery data */ - cfs_init_timer(&obd->obd_recovery_timer); + init_timer(&obd->obd_recovery_timer); spin_lock_init(&obd->obd_recovery_task_lock); init_waitqueue_head(&obd->obd_next_transno_waitq); init_waitqueue_head(&obd->obd_evict_inprogress_waitq); @@ -478,6 +478,7 @@ int class_setup(struct obd_device *obd, struct lustre_cfg *lcfg) obd->obd_uuid_hash = NULL; obd->obd_nid_hash = NULL; obd->obd_nid_stats_hash = NULL; + obd->obd_gen_hash = NULL; spin_unlock(&obd->obd_dev_lock); /* create an uuid-export lustre hash */ @@ -513,6 +514,17 @@ int class_setup(struct obd_device *obd, struct lustre_cfg *lcfg) if (!obd->obd_nid_stats_hash) GOTO(err_hash, err = -ENOMEM); + /* create a client_generation-export lustre hash */ + obd->obd_gen_hash = cfs_hash_create("UUID_HASH", + HASH_GEN_CUR_BITS, + HASH_GEN_MAX_BITS, + HASH_GEN_BKT_BITS, 0, + CFS_HASH_MIN_THETA, + CFS_HASH_MAX_THETA, + &gen_hash_ops, CFS_HASH_DEFAULT); + if (!obd->obd_gen_hash) + GOTO(err_hash, err = -ENOMEM); + exp = class_new_export(obd, &obd->obd_uuid); if (IS_ERR(exp)) GOTO(err_hash, err = PTR_ERR(exp)); @@ -554,6 +566,10 @@ err_hash: cfs_hash_putref(obd->obd_nid_stats_hash); obd->obd_nid_stats_hash = NULL; } + if (obd->obd_gen_hash) { + cfs_hash_putref(obd->obd_gen_hash); + obd->obd_gen_hash = NULL; + } obd->obd_starting = 0; CERROR("setup %s failed (%d)\n", obd->obd_name, err); return err; @@ -595,16 +611,16 @@ EXPORT_SYMBOL(class_detach); */ int class_cleanup(struct obd_device *obd, struct lustre_cfg *lcfg) { - int err = 0; - char *flag; - ENTRY; + int err = 0; + char *flag; + ENTRY; - OBD_RACE(OBD_FAIL_LDLM_RECOV_CLIENTS); + OBD_RACE(OBD_FAIL_LDLM_RECOV_CLIENTS); - if (!obd->obd_set_up) { - CERROR("Device %d not setup\n", obd->obd_minor); - RETURN(-ENODEV); - } + if (!obd->obd_set_up) { + CERROR("Device %d not setup\n", obd->obd_minor); + RETURN(-ENODEV); + } spin_lock(&obd->obd_dev_lock); if (obd->obd_stopping) { @@ -621,71 +637,77 @@ int class_cleanup(struct obd_device *obd, struct lustre_cfg *lcfg) yield(); smp_rmb(); - if (lcfg->lcfg_bufcount >= 2 && LUSTRE_CFG_BUFLEN(lcfg, 1) > 0) { - for (flag = lustre_cfg_string(lcfg, 1); *flag != 0; flag++) - switch (*flag) { - case 'F': - obd->obd_force = 1; - break; - case 'A': - LCONSOLE_WARN("Failing over %s\n", - obd->obd_name); - obd->obd_fail = 1; - obd->obd_no_transno = 1; - obd->obd_no_recov = 1; - if (OBP(obd, iocontrol)) { - obd_iocontrol(OBD_IOC_SYNC, - obd->obd_self_export, - 0, NULL, NULL); - } - break; - default: - CERROR("Unrecognised flag '%c'\n", *flag); - } - } + if (lcfg->lcfg_bufcount >= 2 && LUSTRE_CFG_BUFLEN(lcfg, 1) > 0) { + for (flag = lustre_cfg_string(lcfg, 1); *flag != 0; flag++) + switch (*flag) { + case 'F': + obd->obd_force = 1; + break; + case 'A': + LCONSOLE_WARN("Failing over %s\n", + obd->obd_name); + obd->obd_fail = 1; + obd->obd_no_transno = 1; + obd->obd_no_recov = 1; + if (OBP(obd, iocontrol)) { + obd_iocontrol(OBD_IOC_SYNC, + obd->obd_self_export, + 0, NULL, NULL); + } + break; + default: + CERROR("Unrecognised flag '%c'\n", *flag); + } + } - LASSERT(obd->obd_self_export); + LASSERT(obd->obd_self_export); - /* The three references that should be remaining are the - * obd_self_export and the attach and setup references. */ + /* The three references that should be remaining are the + * obd_self_export and the attach and setup references. */ if (atomic_read(&obd->obd_refcount) > 3) { - /* refcounf - 3 might be the number of real exports - (excluding self export). But class_incref is called - by other things as well, so don't count on it. */ - CDEBUG(D_IOCTL, "%s: forcing exports to disconnect: %d\n", + /* refcounf - 3 might be the number of real exports + (excluding self export). But class_incref is called + by other things as well, so don't count on it. */ + CDEBUG(D_IOCTL, "%s: forcing exports to disconnect: %d\n", obd->obd_name, atomic_read(&obd->obd_refcount) - 3); - dump_exports(obd, 0); - class_disconnect_exports(obd); - } + dump_exports(obd, 0, D_HA); + class_disconnect_exports(obd); + } - /* Precleanup, we must make sure all exports get destroyed. */ - err = obd_precleanup(obd, OBD_CLEANUP_EXPORTS); - if (err) - CERROR("Precleanup %s returned %d\n", - obd->obd_name, err); + /* Precleanup, we must make sure all exports get destroyed. */ + err = obd_precleanup(obd); + if (err) + CERROR("Precleanup %s returned %d\n", + obd->obd_name, err); - /* destroy an uuid-export hash body */ - if (obd->obd_uuid_hash) { - cfs_hash_putref(obd->obd_uuid_hash); - obd->obd_uuid_hash = NULL; - } + /* destroy an uuid-export hash body */ + if (obd->obd_uuid_hash) { + cfs_hash_putref(obd->obd_uuid_hash); + obd->obd_uuid_hash = NULL; + } - /* destroy a nid-export hash body */ - if (obd->obd_nid_hash) { - cfs_hash_putref(obd->obd_nid_hash); - obd->obd_nid_hash = NULL; - } + /* destroy a nid-export hash body */ + if (obd->obd_nid_hash) { + cfs_hash_putref(obd->obd_nid_hash); + obd->obd_nid_hash = NULL; + } - /* destroy a nid-stats hash body */ - if (obd->obd_nid_stats_hash) { - cfs_hash_putref(obd->obd_nid_stats_hash); - obd->obd_nid_stats_hash = NULL; - } + /* destroy a nid-stats hash body */ + if (obd->obd_nid_stats_hash) { + cfs_hash_putref(obd->obd_nid_stats_hash); + obd->obd_nid_stats_hash = NULL; + } - class_decref(obd, "setup", obd); - obd->obd_set_up = 0; + /* destroy a client_generation-export hash body */ + if (obd->obd_gen_hash) { + cfs_hash_putref(obd->obd_gen_hash); + obd->obd_gen_hash = NULL; + } - RETURN(0); + class_decref(obd, "setup", obd); + obd->obd_set_up = 0; + + RETURN(0); } struct obd_device *class_incref(struct obd_device *obd, @@ -813,18 +835,23 @@ static int class_del_conn(struct obd_device *obd, struct lustre_cfg *lcfg) static struct list_head lustre_profile_list = LIST_HEAD_INIT(lustre_profile_list); +static DEFINE_SPINLOCK(lustre_profile_list_lock); struct lustre_profile *class_get_profile(const char * prof) { - struct lustre_profile *lprof; + struct lustre_profile *lprof; - ENTRY; + ENTRY; + spin_lock(&lustre_profile_list_lock); list_for_each_entry(lprof, &lustre_profile_list, lp_list) { - if (!strcmp(lprof->lp_profile, prof)) { - RETURN(lprof); - } - } - RETURN(NULL); + if (!strcmp(lprof->lp_profile, prof)) { + lprof->lp_refs++; + spin_unlock(&lustre_profile_list_lock); + RETURN(lprof); + } + } + spin_unlock(&lustre_profile_list_lock); + RETURN(NULL); } EXPORT_SYMBOL(class_get_profile); @@ -866,7 +893,12 @@ static int class_add_profile(int proflen, char *prof, int osclen, char *osc, memcpy(lprof->lp_md, mdc, mdclen); } + spin_lock(&lustre_profile_list_lock); + lprof->lp_refs = 1; + lprof->lp_list_deleted = false; + list_add(&lprof->lp_list, &lustre_profile_list); + spin_unlock(&lustre_profile_list_lock); RETURN(err); out: @@ -882,39 +914,68 @@ out: void class_del_profile(const char *prof) { - struct lustre_profile *lprof; - ENTRY; + struct lustre_profile *lprof; + ENTRY; - CDEBUG(D_CONFIG, "Del profile %s\n", prof); + CDEBUG(D_CONFIG, "Del profile %s\n", prof); - lprof = class_get_profile(prof); - if (lprof) { + lprof = class_get_profile(prof); + if (lprof) { + spin_lock(&lustre_profile_list_lock); + /* because get profile increments the ref counter */ + lprof->lp_refs--; list_del(&lprof->lp_list); - OBD_FREE(lprof->lp_profile, strlen(lprof->lp_profile) + 1); - OBD_FREE(lprof->lp_dt, strlen(lprof->lp_dt) + 1); - if (lprof->lp_md) - OBD_FREE(lprof->lp_md, strlen(lprof->lp_md) + 1); - OBD_FREE(lprof, sizeof *lprof); - } - EXIT; + lprof->lp_list_deleted = true; + spin_unlock(&lustre_profile_list_lock); + + class_put_profile(lprof); + } + EXIT; } EXPORT_SYMBOL(class_del_profile); +void class_put_profile(struct lustre_profile *lprof) +{ + spin_lock(&lustre_profile_list_lock); + if ((--lprof->lp_refs) > 0) { + LASSERT(lprof->lp_refs > 0); + spin_unlock(&lustre_profile_list_lock); + return; + } + spin_unlock(&lustre_profile_list_lock); + + /* confirm not a negative number */ + LASSERT(lprof->lp_refs == 0); + + /* At least one class_del_profile/profiles must be called + * on the target profile or lustre_profile_list will corrupt */ + LASSERT(lprof->lp_list_deleted); + OBD_FREE(lprof->lp_profile, strlen(lprof->lp_profile) + 1); + OBD_FREE(lprof->lp_dt, strlen(lprof->lp_dt) + 1); + if (lprof->lp_md != NULL) + OBD_FREE(lprof->lp_md, strlen(lprof->lp_md) + 1); + OBD_FREE(lprof, sizeof(*lprof)); +} +EXPORT_SYMBOL(class_put_profile); + /* COMPAT_146 */ void class_del_profiles(void) { - struct lustre_profile *lprof, *n; - ENTRY; + struct lustre_profile *lprof, *n; + ENTRY; + spin_lock(&lustre_profile_list_lock); list_for_each_entry_safe(lprof, n, &lustre_profile_list, lp_list) { list_del(&lprof->lp_list); - OBD_FREE(lprof->lp_profile, strlen(lprof->lp_profile) + 1); - OBD_FREE(lprof->lp_dt, strlen(lprof->lp_dt) + 1); - if (lprof->lp_md) - OBD_FREE(lprof->lp_md, strlen(lprof->lp_md) + 1); - OBD_FREE(lprof, sizeof *lprof); - } - EXIT; + lprof->lp_list_deleted = true; + spin_unlock(&lustre_profile_list_lock); + + class_put_profile(lprof); + + spin_lock(&lustre_profile_list_lock); + } + spin_unlock(&lustre_profile_list_lock); + EXIT; } EXPORT_SYMBOL(class_del_profiles); @@ -1035,8 +1096,8 @@ static int process_param2_config(struct lustre_cfg *lcfg) [2] = param, [3] = NULL }; - struct timeval start; - struct timeval end; + ktime_t start; + ktime_t end; int rc; ENTRY; @@ -1046,18 +1107,18 @@ static int process_param2_config(struct lustre_cfg *lcfg) RETURN(-EINVAL); } - do_gettimeofday(&start); + start = ktime_get(); rc = call_usermodehelper(argv[0], argv, NULL, UMH_WAIT_PROC); - do_gettimeofday(&end); + end = ktime_get(); if (rc < 0) { CERROR("lctl: error invoking upcall %s %s %s: rc = %d; " "time %ldus\n", argv[0], argv[1], argv[2], rc, - cfs_timeval_sub(&end, &start, NULL)); + (long)ktime_us_delta(end, start)); } else { CDEBUG(D_HA, "lctl: invoked upcall %s %s %s, time %ldus\n", argv[0], argv[1], argv[2], - cfs_timeval_sub(&end, &start, NULL)); + (long)ktime_us_delta(end, start)); rc = 0; } @@ -1089,7 +1150,7 @@ int class_process_config(struct lustre_cfg *lcfg) GOTO(out, err); } case LCFG_ADD_UUID: { - CDEBUG(D_IOCTL, "adding mapping from uuid %s to nid "LPX64 + CDEBUG(D_IOCTL, "adding mapping from uuid %s to nid %#llx" " (%s)\n", lustre_cfg_string(lcfg, 1), lcfg->lcfg_nid, libcfs_nid2str(lcfg->lcfg_nid)); @@ -1317,6 +1378,11 @@ int class_process_proc_param(char *prefix, struct lprocfs_vars *lvars, j++; } if (!matched) { + /* It was upgraded from old MDT/OST device, + * ignore the obsolete "sec_level" parameter. */ + if (strncmp("sec_level", key, keylen) == 0) + continue; + CERROR("%.*s: %s unknown param %s\n", (int)strlen(prefix) - 1, prefix, (char *)lustre_cfg_string(lcfg, 0), key); @@ -1387,101 +1453,101 @@ int class_config_llog_handler(const struct lu_env *env, struct llog_handle *handle, struct llog_rec_hdr *rec, void *data) { - struct config_llog_instance *clli = data; - int cfg_len = rec->lrh_len; - char *cfg_buf = (char*) (rec + 1); - int rc = 0; - ENTRY; + struct config_llog_instance *cfg = data; + int cfg_len = rec->lrh_len; + char *cfg_buf = (char *) (rec + 1); + int rc = 0; + ENTRY; - //class_config_dump_handler(handle, rec, data); + /* class_config_dump_handler(handle, rec, data); */ - switch (rec->lrh_type) { - case OBD_CFG_REC: { - struct lustre_cfg *lcfg, *lcfg_new; - struct lustre_cfg_bufs bufs; - char *inst_name = NULL; - int inst_len = 0; - int inst = 0, swab = 0; + switch (rec->lrh_type) { + case OBD_CFG_REC: { + struct lustre_cfg *lcfg, *lcfg_new; + struct lustre_cfg_bufs bufs; + char *inst_name = NULL; + int inst_len = 0; + int inst = 0, swab = 0; - lcfg = (struct lustre_cfg *)cfg_buf; - if (lcfg->lcfg_version == __swab32(LUSTRE_CFG_VERSION)) { - lustre_swab_lustre_cfg(lcfg); - swab = 1; - } + lcfg = (struct lustre_cfg *)cfg_buf; + if (lcfg->lcfg_version == __swab32(LUSTRE_CFG_VERSION)) { + lustre_swab_lustre_cfg(lcfg); + swab = 1; + } - rc = lustre_cfg_sanity_check(cfg_buf, cfg_len); - if (rc) - GOTO(out, rc); + rc = lustre_cfg_sanity_check(cfg_buf, cfg_len); + if (rc) + GOTO(out, rc); /* Figure out config state info */ - if (lcfg->lcfg_command == LCFG_MARKER) { - struct cfg_marker *marker = lustre_cfg_buf(lcfg, 1); - lustre_swab_cfg_marker(marker, swab, - LUSTRE_CFG_BUFLEN(lcfg, 1)); - CDEBUG(D_CONFIG, "Marker, inst_flg=%#x mark_flg=%#x\n", - clli->cfg_flags, marker->cm_flags); - if (marker->cm_flags & CM_START) { + if (lcfg->lcfg_command == LCFG_MARKER) { + struct cfg_marker *marker = lustre_cfg_buf(lcfg, 1); + lustre_swab_cfg_marker(marker, swab, + LUSTRE_CFG_BUFLEN(lcfg, 1)); + CDEBUG(D_CONFIG, "Marker, inst_flg=%#x mark_flg=%#x\n", + cfg->cfg_flags, marker->cm_flags); + if (marker->cm_flags & CM_START) { /* all previous flags off */ - clli->cfg_flags = CFG_F_MARKER; + cfg->cfg_flags = CFG_F_MARKER; server_name2index(marker->cm_tgtname, - &clli->cfg_lwp_idx, NULL); - if (marker->cm_flags & CM_SKIP) { - clli->cfg_flags |= CFG_F_SKIP; - CDEBUG(D_CONFIG, "SKIP #%d\n", - marker->cm_step); - } else if ((marker->cm_flags & CM_EXCLUDE) || - (clli->cfg_sb && - lustre_check_exclusion(clli->cfg_sb, - marker->cm_tgtname))) { - clli->cfg_flags |= CFG_F_EXCLUDE; - CDEBUG(D_CONFIG, "EXCLUDE %d\n", - marker->cm_step); - } - } else if (marker->cm_flags & CM_END) { - clli->cfg_flags = 0; - } - } - /* A config command without a start marker before it is - illegal (post 146) */ - if (!(clli->cfg_flags & CFG_F_COMPAT146) && - !(clli->cfg_flags & CFG_F_MARKER) && - (lcfg->lcfg_command != LCFG_MARKER)) { - CWARN("Config not inside markers, ignoring! " - "(inst: %p, uuid: %s, flags: %#x)\n", - clli->cfg_instance, - clli->cfg_uuid.uuid, clli->cfg_flags); - clli->cfg_flags |= CFG_F_SKIP; - } - if (clli->cfg_flags & CFG_F_SKIP) { - CDEBUG(D_CONFIG, "skipping %#x\n", - clli->cfg_flags); - rc = 0; - /* No processing! */ - break; - } + &cfg->cfg_lwp_idx, NULL); + if (marker->cm_flags & CM_SKIP) { + cfg->cfg_flags |= CFG_F_SKIP; + CDEBUG(D_CONFIG, "SKIP #%d\n", + marker->cm_step); + } else if ((marker->cm_flags & CM_EXCLUDE) || + (cfg->cfg_sb && + lustre_check_exclusion(cfg->cfg_sb, + marker->cm_tgtname))) { + cfg->cfg_flags |= CFG_F_EXCLUDE; + CDEBUG(D_CONFIG, "EXCLUDE %d\n", + marker->cm_step); + } + } else if (marker->cm_flags & CM_END) { + cfg->cfg_flags = 0; + } + } + /* A config command without a start marker before it is + illegal (post 146) */ + if (!(cfg->cfg_flags & CFG_F_COMPAT146) && + !(cfg->cfg_flags & CFG_F_MARKER) && + (lcfg->lcfg_command != LCFG_MARKER)) { + CWARN("Config not inside markers, ignoring! " + "(inst: %p, uuid: %s, flags: %#x)\n", + cfg->cfg_instance, + cfg->cfg_uuid.uuid, cfg->cfg_flags); + cfg->cfg_flags |= CFG_F_SKIP; + } + if (cfg->cfg_flags & CFG_F_SKIP) { + CDEBUG(D_CONFIG, "skipping %#x\n", + cfg->cfg_flags); + rc = 0; + /* No processing! */ + break; + } /* * For interoperability between 1.8 and 2.0, * rename "mds" obd device type to "mdt". */ - { - char *typename = lustre_cfg_string(lcfg, 1); - char *index = lustre_cfg_string(lcfg, 2); - - if ((lcfg->lcfg_command == LCFG_ATTACH && typename && - strcmp(typename, "mds") == 0)) { - CWARN("For 1.8 interoperability, rename obd " - "type from mds to mdt\n"); - typename[2] = 't'; - } - if ((lcfg->lcfg_command == LCFG_SETUP && index && - strcmp(index, "type") == 0)) { - CDEBUG(D_INFO, "For 1.8 interoperability, " - "set this index to '0'\n"); - index[0] = '0'; - index[1] = 0; - } - } + { + char *typename = lustre_cfg_string(lcfg, 1); + char *index = lustre_cfg_string(lcfg, 2); + + if ((lcfg->lcfg_command == LCFG_ATTACH && typename && + strcmp(typename, "mds") == 0)) { + CWARN("For 1.8 interoperability, rename obd " + "type from mds to mdt\n"); + typename[2] = 't'; + } + if ((lcfg->lcfg_command == LCFG_SETUP && index && + strcmp(index, "type") == 0)) { + CDEBUG(D_INFO, "For 1.8 interoperability, " + "set this index to '0'\n"); + index[0] = '0'; + index[1] = 0; + } + } #ifdef HAVE_SERVER_SUPPORT /* newer MDS replaces LOV/OSC with LOD/OSP */ @@ -1490,26 +1556,26 @@ int class_config_llog_handler(const struct lu_env *env, if ((lcfg->lcfg_command == LCFG_ATTACH && typename && strcmp(typename, LUSTRE_LOV_NAME) == 0) && - IS_MDT(s2lsi(clli->cfg_sb))) { + cfg->cfg_sb && IS_MDT(s2lsi(cfg->cfg_sb))) { CDEBUG(D_CONFIG, "For 2.x interoperability, rename obd " "type from lov to lod (%s)\n", - s2lsi(clli->cfg_sb)->lsi_svname); + s2lsi(cfg->cfg_sb)->lsi_svname); strcpy(typename, LUSTRE_LOD_NAME); } if ((lcfg->lcfg_command == LCFG_ATTACH && typename && strcmp(typename, LUSTRE_OSC_NAME) == 0) && - IS_MDT(s2lsi(clli->cfg_sb))) { + cfg->cfg_sb && IS_MDT(s2lsi(cfg->cfg_sb))) { CDEBUG(D_CONFIG, "For 2.x interoperability, rename obd " "type from osc to osp (%s)\n", - s2lsi(clli->cfg_sb)->lsi_svname); + s2lsi(cfg->cfg_sb)->lsi_svname); strcpy(typename, LUSTRE_OSP_NAME); } } #endif /* HAVE_SERVER_SUPPORT */ - if (clli->cfg_flags & CFG_F_EXCLUDE) { + if (cfg->cfg_flags & CFG_F_EXCLUDE) { CDEBUG(D_CONFIG, "cmd: %x marked EXCLUDED\n", lcfg->lcfg_command); if (lcfg->lcfg_command == LCFG_LOV_ADD_OBD) @@ -1517,31 +1583,32 @@ int class_config_llog_handler(const struct lu_env *env, lcfg->lcfg_command = LCFG_LOV_ADD_INA; } - lustre_cfg_bufs_init(&bufs, lcfg); - - if (clli && clli->cfg_instance && - LUSTRE_CFG_BUFLEN(lcfg, 0) > 0){ - inst = 1; - inst_len = LUSTRE_CFG_BUFLEN(lcfg, 0) + - sizeof(clli->cfg_instance) * 2 + 4; - OBD_ALLOC(inst_name, inst_len); - if (inst_name == NULL) - GOTO(out, rc = -ENOMEM); - sprintf(inst_name, "%s-%p", - lustre_cfg_string(lcfg, 0), - clli->cfg_instance); - lustre_cfg_bufs_set_string(&bufs, 0, inst_name); - CDEBUG(D_CONFIG, "cmd %x, instance name: %s\n", - lcfg->lcfg_command, inst_name); - } + lustre_cfg_bufs_reset(&bufs, NULL); + lustre_cfg_bufs_init(&bufs, lcfg); + + if (cfg->cfg_instance && + LUSTRE_CFG_BUFLEN(lcfg, 0) > 0) { + inst = 1; + inst_len = LUSTRE_CFG_BUFLEN(lcfg, 0) + + sizeof(cfg->cfg_instance) * 2 + 4; + OBD_ALLOC(inst_name, inst_len); + if (inst_name == NULL) + GOTO(out, rc = -ENOMEM); + snprintf(inst_name, inst_len, "%s-%p", + lustre_cfg_string(lcfg, 0), + cfg->cfg_instance); + lustre_cfg_bufs_set_string(&bufs, 0, inst_name); + CDEBUG(D_CONFIG, "cmd %x, instance name: %s\n", + lcfg->lcfg_command, inst_name); + } /* we override the llog's uuid for clients, to insure they are unique */ - if (clli && clli->cfg_instance != NULL && - lcfg->lcfg_command == LCFG_ATTACH) { - lustre_cfg_bufs_set_string(&bufs, 2, - clli->cfg_uuid.uuid); - } + if (cfg->cfg_instance != NULL && + lcfg->lcfg_command == LCFG_ATTACH) { + lustre_cfg_bufs_set_string(&bufs, 2, + cfg->cfg_uuid.uuid); + } /* * sptlrpc config record, we expect 2 data segments: * [0]: fs_name/target_name, @@ -1549,69 +1616,113 @@ int class_config_llog_handler(const struct lu_env *env, * moving them to index [1] and [2], and insert MGC's * obdname at index [0]. */ - if (clli && clli->cfg_instance == NULL && - lcfg->lcfg_command == LCFG_SPTLRPC_CONF) { - lustre_cfg_bufs_set(&bufs, 2, bufs.lcfg_buf[1], - bufs.lcfg_buflen[1]); - lustre_cfg_bufs_set(&bufs, 1, bufs.lcfg_buf[0], - bufs.lcfg_buflen[0]); - lustre_cfg_bufs_set_string(&bufs, 0, - clli->cfg_obdname); - } + if (cfg->cfg_instance == NULL && + lcfg->lcfg_command == LCFG_SPTLRPC_CONF) { + lustre_cfg_bufs_set(&bufs, 2, bufs.lcfg_buf[1], + bufs.lcfg_buflen[1]); + lustre_cfg_bufs_set(&bufs, 1, bufs.lcfg_buf[0], + bufs.lcfg_buflen[0]); + lustre_cfg_bufs_set_string(&bufs, 0, + cfg->cfg_obdname); + } + + /* Add net info to setup command + * if given on command line. + * So config log will be: + * [0]: client name + * [1]: client UUID + * [2]: server UUID + * [3]: inactive-on-startup + * [4]: restrictive net + */ + if (cfg && cfg->cfg_sb && s2lsi(cfg->cfg_sb) && + !IS_SERVER(s2lsi(cfg->cfg_sb))) { + struct lustre_sb_info *lsi = s2lsi(cfg->cfg_sb); + char *nidnet = lsi->lsi_lmd->lmd_nidnet; + + if (lcfg->lcfg_command == LCFG_SETUP && + lcfg->lcfg_bufcount != 2 && nidnet) { + CDEBUG(D_CONFIG, "Adding net %s info to setup " + "command for client %s\n", nidnet, + lustre_cfg_string(lcfg, 0)); + lustre_cfg_bufs_set_string(&bufs, 4, nidnet); + } + } + + /* Skip add_conn command if uuid is + * not on restricted net */ + if (cfg && cfg->cfg_sb && s2lsi(cfg->cfg_sb) && + !IS_SERVER(s2lsi(cfg->cfg_sb))) { + struct lustre_sb_info *lsi = s2lsi(cfg->cfg_sb); + char *uuid_str = lustre_cfg_string(lcfg, 1); + + if (lcfg->lcfg_command == LCFG_ADD_CONN && + lsi->lsi_lmd->lmd_nidnet && + LNET_NIDNET(libcfs_str2nid(uuid_str)) != + libcfs_str2net(lsi->lsi_lmd->lmd_nidnet)) { + CDEBUG(D_CONFIG, "skipping add_conn for %s\n", + uuid_str); + rc = 0; + /* No processing! */ + break; + } + } - lcfg_new = lustre_cfg_new(lcfg->lcfg_command, &bufs); + lcfg_new = lustre_cfg_new(lcfg->lcfg_command, &bufs); if (lcfg_new == NULL) GOTO(out, rc = -ENOMEM); - lcfg_new->lcfg_num = lcfg->lcfg_num; - lcfg_new->lcfg_flags = lcfg->lcfg_flags; - - /* XXX Hack to try to remain binary compatible with - * pre-newconfig logs */ - if (lcfg->lcfg_nal != 0 && /* pre-newconfig log? */ - (lcfg->lcfg_nid >> 32) == 0) { - __u32 addr = (__u32)(lcfg->lcfg_nid & 0xffffffff); - - lcfg_new->lcfg_nid = - LNET_MKNID(LNET_MKNET(lcfg->lcfg_nal, 0), addr); - CWARN("Converted pre-newconfig NAL %d NID %x to %s\n", - lcfg->lcfg_nal, addr, - libcfs_nid2str(lcfg_new->lcfg_nid)); - } else { - lcfg_new->lcfg_nid = lcfg->lcfg_nid; - } + lcfg_new->lcfg_num = lcfg->lcfg_num; + lcfg_new->lcfg_flags = lcfg->lcfg_flags; + + /* XXX Hack to try to remain binary compatible with + * pre-newconfig logs */ + if (lcfg->lcfg_nal != 0 && /* pre-newconfig log? */ + (lcfg->lcfg_nid >> 32) == 0) { + __u32 addr = (__u32)(lcfg->lcfg_nid & 0xffffffff); + + lcfg_new->lcfg_nid = + LNET_MKNID(LNET_MKNET(lcfg->lcfg_nal, 0), addr); + CWARN("Converted pre-newconfig NAL %d NID %x to %s\n", + lcfg->lcfg_nal, addr, + libcfs_nid2str(lcfg_new->lcfg_nid)); + } else { + lcfg_new->lcfg_nid = lcfg->lcfg_nid; + } - lcfg_new->lcfg_nal = 0; /* illegal value for obsolete field */ + lcfg_new->lcfg_nal = 0; /* illegal value for obsolete field */ rc = class_process_config(lcfg_new); - lustre_cfg_free(lcfg_new); + lustre_cfg_free(lcfg_new); - if (inst) - OBD_FREE(inst_name, inst_len); - break; - } - default: - CERROR("Unknown llog record type %#x encountered\n", - rec->lrh_type); - break; - } + if (inst) + OBD_FREE(inst_name, inst_len); + break; + } + default: + CERROR("Unknown llog record type %#x encountered\n", + rec->lrh_type); + break; + } out: - if (rc) { + if (rc) { CERROR("%s: cfg command failed: rc = %d\n", - handle->lgh_ctxt->loc_obd->obd_name, rc); + handle->lgh_ctxt->loc_obd->obd_name, rc); class_config_dump_handler(NULL, handle, rec, data); - } - RETURN(rc); + } + RETURN(rc); } EXPORT_SYMBOL(class_config_llog_handler); int class_config_parse_llog(const struct lu_env *env, struct llog_ctxt *ctxt, char *name, struct config_llog_instance *cfg) { - struct llog_process_cat_data cd = {0, 0}; - struct llog_handle *llh; - llog_cb_t callback; - int rc; + struct llog_process_cat_data cd = { + .lpcd_first_idx = 0, + }; + struct llog_handle *llh; + llog_cb_t callback; + int rc; ENTRY; CDEBUG(D_INFO, "looking up llog %s\n", name); @@ -1737,7 +1848,7 @@ int class_config_yaml_output(struct llog_rec_hdr *rec, char *buf, int size) char nidstr[LNET_NIDSTR_SIZE]; libcfs_nid2str_r(lcfg->lcfg_nid, nidstr, sizeof(nidstr)); - ptr += snprintf(ptr, end - ptr, ", nid: %s("LPX64")", + ptr += snprintf(ptr, end - ptr, ", nid: %s(%#llx)", nidstr, lcfg->lcfg_nid); } @@ -1789,7 +1900,7 @@ static int class_config_parse_rec(struct llog_rec_hdr *rec, char *buf, int size) char nidstr[LNET_NIDSTR_SIZE]; libcfs_nid2str_r(lcfg->lcfg_nid, nidstr, sizeof(nidstr)); - ptr += snprintf(ptr, end-ptr, "nid=%s("LPX64")\n ", + ptr += snprintf(ptr, end-ptr, "nid=%s(%#llx)\n ", nidstr, lcfg->lcfg_nid); } @@ -1838,33 +1949,6 @@ int class_config_dump_handler(const struct lu_env *env, RETURN(rc); } -int class_config_dump_llog(const struct lu_env *env, struct llog_ctxt *ctxt, - char *name, struct config_llog_instance *cfg) -{ - struct llog_handle *llh; - int rc; - - ENTRY; - - LCONSOLE_INFO("Dumping config log %s\n", name); - - rc = llog_open(env, ctxt, &llh, NULL, name, LLOG_OPEN_EXISTS); - if (rc) - RETURN(rc); - - rc = llog_init_handle(env, llh, LLOG_F_IS_PLAIN, NULL); - if (rc) - GOTO(parse_out, rc); - - rc = llog_process(env, llh, class_config_dump_handler, cfg, NULL); -parse_out: - llog_close(env, llh); - - LCONSOLE_INFO("End config log %s\n", name); - RETURN(rc); -} -EXPORT_SYMBOL(class_config_dump_llog); - /** Call class_cleanup and class_detach. * "Manual" only in the sense that we're faking lcfg commands. */ @@ -2105,3 +2189,73 @@ static struct cfs_hash_ops nid_stat_hash_ops = { .hs_get = nidstats_get, .hs_put_locked = nidstats_put_locked, }; + + +/* + * client_generation<->export hash operations + */ + +static unsigned +gen_hash(struct cfs_hash *hs, const void *key, unsigned mask) +{ + return cfs_hash_djb2_hash(key, sizeof(__u32), mask); +} + +static void * +gen_key(struct hlist_node *hnode) +{ + struct obd_export *exp; + + exp = hlist_entry(hnode, struct obd_export, exp_gen_hash); + + RETURN(&exp->exp_target_data.ted_lcd->lcd_generation); +} + +/* + * NOTE: It is impossible to find an export that is in failed + * state with this function + */ +static int +gen_kepcmp(const void *key, struct hlist_node *hnode) +{ + struct obd_export *exp; + + LASSERT(key); + exp = hlist_entry(hnode, struct obd_export, exp_gen_hash); + + RETURN(exp->exp_target_data.ted_lcd->lcd_generation == *(__u32 *)key && + !exp->exp_failed); +} + +static void * +gen_export_object(struct hlist_node *hnode) +{ + return hlist_entry(hnode, struct obd_export, exp_gen_hash); +} + +static void +gen_export_get(struct cfs_hash *hs, struct hlist_node *hnode) +{ + struct obd_export *exp; + + exp = hlist_entry(hnode, struct obd_export, exp_gen_hash); + class_export_get(exp); +} + +static void +gen_export_put_locked(struct cfs_hash *hs, struct hlist_node *hnode) +{ + struct obd_export *exp; + + exp = hlist_entry(hnode, struct obd_export, exp_gen_hash); + class_export_put(exp); +} + +static struct cfs_hash_ops gen_hash_ops = { + .hs_hash = gen_hash, + .hs_key = gen_key, + .hs_keycmp = gen_kepcmp, + .hs_object = gen_export_object, + .hs_get = gen_export_get, + .hs_put_locked = gen_export_put_locked, +};