diff --git a/lustre/ChangeLog b/lustre/ChangeLog index 8ef4590a960c43ccc82010a733b2fd521c62c89c..a6b8a3ed996a6dff82c6ff8a40039a6187dc8063 100644 --- a/lustre/ChangeLog +++ b/lustre/ChangeLog @@ -239,6 +239,14 @@ Details : During a commanded failover stop, we set the disk device read-only while the server shuts down. We now also set any external journal device read-only at the same time. +Severity : minor +Frequency : when upgrading from 1.4 while trying to change parameters +Bugzilla : 11692 +Description: The wrong (new) MDC name was used when setting parameters for + upgraded MDT's. Also allows changing of OSC (and MDC) + parameters if --writeconf is specified at tunefs upgrade time. + + ------------------------------------------------------------------------------ TBD Cluster File Systems, Inc. <info@clusterfs.com> diff --git a/lustre/mgs/mgs_handler.c b/lustre/mgs/mgs_handler.c index 5e112a63fe572eb52086be8e4fcab94ad9cb8e45..e161ad30da381681013409fd9f6c358d99810b8b 100644 --- a/lustre/mgs/mgs_handler.c +++ b/lustre/mgs/mgs_handler.c @@ -384,23 +384,6 @@ static int mgs_handle_target_reg(struct ptlrpc_request *req) /* Log writing contention is handled by the fsdb_sem */ - /* COMPAT_146 */ - if (mti->mti_flags & LDD_F_UPGRADE14) { - rc = mgs_upgrade_sv_14(obd, mti); - if (rc) { - CERROR("Can't upgrade from 1.4 (%d)\n", rc); - GOTO(out, rc); - } - - /* Turn off all other update-related flags; we're done. */ - mti->mti_flags &= ~(LDD_F_UPGRADE14 | - LDD_F_VIRGIN | LDD_F_UPDATE | - LDD_F_NEED_INDEX | LDD_F_WRITECONF); - mti->mti_flags |= LDD_F_REWRITE_LDD; - goto out; - } - /* end COMPAT_146 */ - if (mti->mti_flags & LDD_F_WRITECONF) { if (mti->mti_flags & LDD_F_SV_TYPE_MDT) { rc = mgs_erase_logs(obd, mti->mti_fsname); @@ -415,8 +398,23 @@ static int mgs_handle_target_reg(struct ptlrpc_request *req) obd->obd_name, mti->mti_svname); } mti->mti_flags |= LDD_F_UPDATE; + /* Erased logs means start from scratch. */ + mti->mti_flags &= ~LDD_F_UPGRADE14; } + /* COMPAT_146 */ + if (mti->mti_flags & LDD_F_UPGRADE14) { + rc = mgs_upgrade_sv_14(obd, mti); + 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); diff --git a/lustre/mgs/mgs_llog.c b/lustre/mgs/mgs_llog.c index e062bfcdb85d562a72b160d6320ccc3f70391d76..1278e8ba87569ed3c822275fd1c03dc5206e508f 100644 --- a/lustre/mgs/mgs_llog.c +++ b/lustre/mgs/mgs_llog.c @@ -1025,21 +1025,6 @@ static int mgs_write_log_mdt(struct obd_device *obd, struct fs_db *fsdb, ENTRY; CDEBUG(D_MGS, "writing new mdt %s\n", mti->mti_svname); - - /* COMPAT_146 */ - if (mti->mti_flags & LDD_F_UPGRADE14) { - /* We're starting with an old uuid. Assume old name for lov - as well since the lov entry already exists in the log. */ - CDEBUG(D_MGS, "old mds uuid %s\n", mti->mti_uuid); - if (strncmp(mti->mti_uuid, fsdb->fsdb_mdtlov + 4, - strlen(fsdb->fsdb_mdtlov) - 4) != 0) { - CERROR("old mds uuid %s doesn't match log %s (%s)\n", - mti->mti_uuid, fsdb->fsdb_mdtlov, - fsdb->fsdb_mdtlov + 4); - RETURN(-EINVAL); - } - } - /* end COMPAT_146 */ if (mti->mti_uuid[0] == '\0') { /* Make up our own uuid */ @@ -1105,7 +1090,7 @@ static int mgs_write_log_mdt(struct obd_device *obd, struct fs_db *fsdb, GOTO(out, rc); rc = record_marker(obd, llh, fsdb, CM_START, mti->mti_svname,"add mdc"); /* COMPAT_146 */ - if (mti->mti_flags & LDD_F_UPGRADE14) { + if (fsdb->fsdb_flags & FSDB_OLDLOG14) { /* Old client log already has MDC entry, but needs mount opt for new client name (lustre-client) */ /* FIXME Old MDT log already has an old mount opt @@ -1113,6 +1098,9 @@ static int mgs_write_log_mdt(struct obd_device *obd, struct fs_db *fsdb, class_del_profiles()) */ rc = record_mount_opt(obd, llh, cliname, fsdb->fsdb_clilov, fsdb->fsdb_mdc); + /* Only add failnids with --writeconf + rc = mgs_write_log_failnids(obd, mti, llh, fsdb->fsdb_mdc); + */ /* end COMPAT_146 */ } else { for (i = 0; i < mti->mti_nid_count; i++) { @@ -1247,9 +1235,11 @@ static int mgs_write_log_ost(struct obd_device *obd, struct fs_db *fsdb, /* We also have to update the other logs where this osc is part of the lov */ - if (mti->mti_flags & LDD_F_UPGRADE14) { + if (fsdb->fsdb_flags & FSDB_OLDLOG14) { /* If we're upgrading, the old mdt log already has our entry. Let's do a fake one for fun. */ + /* Note that we can't add any new failnids, since we don't + know the old osc names. */ flags = CM_SKIP | CM_UPGRADE146; } else if ((mti->mti_flags & LDD_F_UPDATE) != LDD_F_UPDATE) { /* If the update flag isn't set, don't really update @@ -1289,6 +1279,12 @@ static int mgs_write_log_add_failnid(struct obd_device *obd, struct fs_db *fsdb, int rc; ENTRY; + /* FIXME how do we delete a failnid? Currently --writeconf is the + only way. Maybe make --erase-params pass a flag to really + erase all params from logs - except it can't erase the failnids + given when a target first registers, since they aren't processed + as params... */ + /* Verify that we know about this target */ if (mgs_log_is_empty(obd, mti->mti_svname)) { LCONSOLE_ERROR("The target %s has not registered yet. " @@ -1299,8 +1295,20 @@ static int mgs_write_log_add_failnid(struct obd_device *obd, struct fs_db *fsdb, /* Create mdc/osc client name (e.g. lustre-OST0001-osc) */ if (mti->mti_flags & LDD_F_SV_TYPE_MDT) { - name_create(&cliname, mti->mti_svname, "-mdc"); + /* COMPAT_146 */ + if (fsdb->fsdb_mdc) + name_create(&cliname, fsdb->fsdb_mdc, ""); + else + name_create(&cliname, mti->mti_svname, "-mdc"); } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) { + /* COMPAT_146 */ + if (fsdb->fsdb_flags & FSDB_OLDLOG14) { + LCONSOLE_ERROR("Failover NIDs cannot be added to old " + "clients for %s. Consider updating the " + "configuration with --writeconf.\n", + mti->mti_svname); + RETURN(-EINVAL); + } name_create(&cliname, mti->mti_svname, "-osc"); } else { RETURN(-EINVAL); @@ -1355,6 +1363,7 @@ static int mgs_wlp_lcfg(struct obd_device *obd, struct fs_db *fsdb, /* But don't try to match the value. */ if ((tmp = strchr(comment, '='))) *tmp = 0; + /* FIXME we should skip settings that are the same as old values */ rc = mgs_modify(obd, fsdb, mti, logname, tgtname, comment, CM_SKIP); LCONSOLE_INFO("%sing parameter %s.%s in log %s\n", rc ? "Sett" : "Modify", tgtname, comment, logname); @@ -1383,9 +1392,6 @@ static int mgs_write_log_params(struct obd_device *obd, struct fs_db *fsdb, if (!mti->mti_params) RETURN(0); - /* FIXME we should cancel out old settings of the same parameters, - and skip settings that are the same as old values */ - /* For various parameter settings, we have to figure out which logs care about them (e.g. both mdt and client for lov settings) */ while (ptr) { @@ -1519,8 +1525,24 @@ active_err: /* Add the client type to match the obdname in class_config_llog_handler */ } else if (mti->mti_flags & LDD_F_SV_TYPE_MDT) { - name_create(&cname, mti->mti_svname, "-mdc"); + /* COMPAT_146 */ + if (fsdb->fsdb_mdc) + name_create(&cname, fsdb->fsdb_mdc, ""); + else + name_create(&cname, mti->mti_svname, + "-mdc"); } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) { + /* COMPAT_146 */ + if (fsdb->fsdb_flags & FSDB_OLDLOG14) { + LCONSOLE_ERROR("Old clients for %s can't " + "be modified. Consider updating the " + "configuration with --writeconf\n", + mti->mti_svname); + /* We don't know the names of all the + old oscs*/ + rc = -EINVAL; + goto end_while; + } name_create(&cname, mti->mti_svname, "-osc"); } else { rc = -EINVAL; @@ -1700,7 +1722,7 @@ out_up: } /* COMPAT_146 */ -/* upgrade pre-mountconf logs to mountconf at first connect */ +/* verify that we can handle the old config logs */ int mgs_upgrade_sv_14(struct obd_device *obd, struct mgs_target_info *mti) { struct fs_db *fsdb; @@ -1725,7 +1747,7 @@ int mgs_upgrade_sv_14(struct obd_device *obd, struct mgs_target_info *mti) rc = mgs_find_or_make_fsdb(obd, mti->mti_fsname, &fsdb); if (rc) RETURN(rc); - + if (fsdb->fsdb_flags & FSDB_LOG_EMPTY) { LCONSOLE_ERROR("The old client log %s-client is missing. Was " "tunefs.lustre successful?\n", @@ -1739,15 +1761,33 @@ int mgs_upgrade_sv_14(struct obd_device *obd, struct mgs_target_info *mti) CDEBUG(D_MGS, "found old, unupdated client log\n"); } - if ((mti->mti_flags & LDD_F_SV_TYPE_MDT) && - mgs_log_is_empty(obd, mti->mti_svname)) { - LCONSOLE_ERROR("The old MDT log %s is missing. Was " - "tunefs.lustre successful?\n", - mti->mti_svname); - RETURN(-ENOENT); + if (mti->mti_flags & LDD_F_SV_TYPE_MDT) { + if (mgs_log_is_empty(obd, mti->mti_svname)) { + LCONSOLE_ERROR("The old MDT log %s is missing. Was " + "tunefs.lustre successful?\n", + mti->mti_svname); + RETURN(-ENOENT); + } + + /* We're starting with an old uuid. Assume old name for lov + as well since the lov entry already exists in the log. */ + CDEBUG(D_MGS, "old mds uuid %s\n", mti->mti_uuid); + if (strncmp(mti->mti_uuid, fsdb->fsdb_mdtlov + 4, + strlen(fsdb->fsdb_mdtlov) - 4) != 0) { + CERROR("old mds uuid %s doesn't match log %s (%s)\n", + mti->mti_uuid, fsdb->fsdb_mdtlov, + fsdb->fsdb_mdtlov + 4); + RETURN(-EINVAL); + } + } + + if (!(fsdb->fsdb_flags & FSDB_OLDLOG14)) { + LCONSOLE_ERROR("%s-client is supposedly an old log, but no old " + "LOV or MDT was found. Consider updating the " + "configuration with --writeconf.\n", + mti->mti_fsname); } - rc = mgs_write_log_target(obd, mti); RETURN(rc); } /* end COMPAT_146 */ @@ -1876,14 +1916,16 @@ int mgs_setparam(struct obd_device *obd, struct lustre_cfg *lcfg, char *fsname) } else { strncpy(fsname, devname, ptr - devname); } - fsname[MTI_NAME_MAXLEN] = 0; + fsname[MTI_NAME_MAXLEN - 1] = 0; CDEBUG(D_MGS, "setparam on fs %s device %s\n", fsname, devname); rc = mgs_find_or_make_fsdb(obd, fsname, &fsdb); if (rc) RETURN(rc); if (fsdb->fsdb_flags & FSDB_LOG_EMPTY) { - CERROR("No filesystem targets for %s\n", fsname); + CERROR("No filesystem targets for %s. cfg_device from lctl " + "is '%s'\n", fsname, devname); + mgs_free_fsdb(obd, fsdb); RETURN(-EINVAL); } diff --git a/lustre/obdclass/obd_config.c b/lustre/obdclass/obd_config.c index e4b3ed322cf75699cd7ed421ab7df8c9eda5d153..51badf4ea04c253eb1160be111731d3beb633bd1 100644 --- a/lustre/obdclass/obd_config.c +++ b/lustre/obdclass/obd_config.c @@ -859,7 +859,8 @@ int class_process_proc_param(char *prefix, struct lprocfs_vars *lvars, j++; } if (!matched) { - CERROR("Unknown param %s\n", key); + CERROR("%s: unknown param %s\n", + lustre_cfg_buf(lcfg, 0), key); rc = -EINVAL; /* continue parsing other params */ } else { diff --git a/lustre/tests/conf-sanity.sh b/lustre/tests/conf-sanity.sh index 546a0d89ddc6f07e3861dcc9974b1f368eb9493a..98d6c479c50e81d694a13718fbe3699cadfc9115 100644 --- a/lustre/tests/conf-sanity.sh +++ b/lustre/tests/conf-sanity.sh @@ -1048,6 +1048,90 @@ test_31() { # bug 10734 } run_test 31 "Connect to non-existent node (shouldn't crash)" +test_32a() { + [ -z "$TUNEFS" ] && echo "No tunefs" && return + [ ! -r disk1_4.zip ] && echo "Cant find disk1_4.zip, skipping" && return + unzip -o -j -d $TMP/$tdir disk1_4.zip || { echo "Cant unzip disk1_4, skipping" && return ; } + load_modules + sysctl lnet.debug=$PTLDEBUG + + $TUNEFS $TMP/$tdir/mds || error "tunefs failed" + # nids are wrong, so client wont work, but server should start + start mds $TMP/$tdir/mds "-o loop" || return 3 + local UUID=$(cat $LPROC/mds/lustre-MDT0000/uuid) + echo MDS uuid $UUID + [ "$UUID" == "mdsA_UUID" ] || error "UUID is wrong: $UUID" + + $TUNEFS --mgsnode=`hostname` $TMP/$tdir/ost1 || error "tunefs failed" + start ost1 $TMP/$tdir/ost1 "-o loop" || return 5 + UUID=$(cat $LPROC/obdfilter/lustre-OST0000/uuid) + echo OST uuid $UUID + [ "$UUID" == "ost1_UUID" ] || error "UUID is wrong: $UUID" + + local NID=$($LCTL list_nids | head -1) + + echo "OSC changes should return err:" + $LCTL conf_param lustre-OST0000.osc.max_dirty_mb=15 && return 7 + $LCTL conf_param lustre-OST0000.failover.node=$NID && return 8 + echo "ok." + echo "MDC changes should succeed:" + $LCTL conf_param lustre-MDT0000.mdc.max_rpcs_in_flight=9 || return 9 + $LCTL conf_param lustre-MDT0000.failover.node=$NID || return 10 + echo "ok." + + #With a new good MDT failover nid, we should be able to mount a client + #(but it cant talk to OST) + mount_client $MOUNT + set_and_check "cat $LPROC/mdc/*/max_rpcs_in_flight" "lustre-MDT0000.mdc.max_rpcs_in_flight" || return 11 + + zconf_umount `hostname` $MOUNT -f + cleanup_nocli + + [ -d $TMP/$tdir ] && rm -rf $TMP/$tdir +} +run_test 32a "Upgrade from 1.4 (not live)" + +test_32b() { + [ -z "$TUNEFS" ] && echo "No tunefs" && return + [ ! -r disk1_4.zip ] && echo "Cant find disk1_4.zip, skipping" && return + unzip -o -j -d $TMP/$tdir disk1_4.zip || { echo "Cant unzip disk1_4, skipping" && return ; } + load_modules + sysctl lnet.debug=$PTLDEBUG + + # writeconf will cause servers to register with their current nids + $TUNEFS --writeconf $TMP/$tdir/mds || error "tunefs failed" + start mds $TMP/$tdir/mds "-o loop" || return 3 + local UUID=$(cat $LPROC/mds/lustre-MDT0000/uuid) + echo MDS uuid $UUID + [ "$UUID" == "mdsA_UUID" ] || error "UUID is wrong: $UUID" + + $TUNEFS --mgsnode=`hostname` $TMP/$tdir/ost1 || error "tunefs failed" + start ost1 $TMP/$tdir/ost1 "-o loop" || return 5 + UUID=$(cat $LPROC/obdfilter/lustre-OST0000/uuid) + echo OST uuid $UUID + [ "$UUID" == "ost1_UUID" ] || error "UUID is wrong: $UUID" + + echo "OSC changes should succeed:" + $LCTL conf_param lustre-OST0000.osc.max_dirty_mb=15 || return 7 + $LCTL conf_param lustre-OST0000.failover.node=$NID || return 8 + echo "ok." + echo "MDC changes should succeed:" + $LCTL conf_param lustre-MDT0000.mdc.max_rpcs_in_flight=9 || return 9 + echo "ok." + + # MDT and OST should have registered with new nids, so we should have + # a fully-functioning client + echo "Check client and old fs contents" + mount_client $MOUNT + set_and_check "cat $LPROC/mdc/*/max_rpcs_in_flight" "lustre-MDT0000.mdc.max_rpcs_in_flight" || return 11 + [ "$(cksum $MOUNT/passwd | cut -d' ' -f 1,2)" == "2479747619 779" ] || return 12 + echo "ok." + + cleanup + [ -d $TMP/$tdir ] && rm -rf $TMP/$tdir +} +run_test 32b "Upgrade from 1.4 with writeconf" + umount_client $MOUNT cleanup_nocli diff --git a/lustre/tests/disk1_4.zip b/lustre/tests/disk1_4.zip new file mode 100644 index 0000000000000000000000000000000000000000..c5773e703135e94827f06922b91c478531328206 Binary files /dev/null and b/lustre/tests/disk1_4.zip differ diff --git a/lustre/tests/test-framework.sh b/lustre/tests/test-framework.sh index 2803ee169e5bd3a333b3b7e2910a493973bcb8c1..557f2c28a4a1a7f8bdf6fb4742ae91688cc036d8 100644 --- a/lustre/tests/test-framework.sh +++ b/lustre/tests/test-framework.sh @@ -42,6 +42,7 @@ init_test_env() { export LCTL=${LCTL:-"$LUSTRE/utils/lctl"} export MKFS=${MKFS:-"$LUSTRE/utils/mkfs.lustre"} export TUNEFS=${TUNEFS:-"$LUSTRE/utils/tunefs.lustre"} + [ ! -f "$TUNEFS" ] && export TUNEFS=$((which tunefs.lustre)) export CHECKSTAT="${CHECKSTAT:-checkstat} " export FSYTPE=${FSTYPE:-"ext3"} export NAME=${NAME:-local} diff --git a/lustre/utils/lctl.c b/lustre/utils/lctl.c index 37dab47fe2467d8dc5ad278fb4820ce842cdae03..3d9fbc06cd19f85eb994170d68bfd36b45b75b90 100644 --- a/lustre/utils/lctl.c +++ b/lustre/utils/lctl.c @@ -117,9 +117,9 @@ command_t cmdlist[] = { "usage: conf_param obd_timeout=<secs>\n"}, {"conf_param", jt_lcfg_mgsparam, 0, "set a permanent config param. " "This command must be run on the MGS node\n" - "usage: conf_param <keyword=val> ...\n"}, + "usage: conf_param <target.keyword=val> ...\n"}, {"local_param", jt_lcfg_param, 0, "set a temporary, local param\n" - "usage: local_param <keyword=val> ...\n"}, + "usage: local_param <target.keyword=val> ...\n"}, /* Debug commands */ {"==== debugging control ===", jt_noop, 0, "debug"}, diff --git a/lustre/utils/lustre_cfg.c b/lustre/utils/lustre_cfg.c index b973113a4736e667e7009110f0d36c59b2eb75b2..cc29553e43902ae278d5f70d89bb2a92e0b241d9 100644 --- a/lustre/utils/lustre_cfg.c +++ b/lustre/utils/lustre_cfg.c @@ -460,7 +460,7 @@ int jt_lcfg_param(int argc, char **argv) if (argc >= LUSTRE_CFG_MAX_BUFCOUNT) return CMD_HELP; - lustre_cfg_bufs_reset(&bufs, lcfg_devname); + lustre_cfg_bufs_reset(&bufs, NULL); for (i = 1; i < argc; i++) { lustre_cfg_bufs_set_string(&bufs, i, argv[i]); @@ -478,28 +478,20 @@ int jt_lcfg_param(int argc, char **argv) } /* Param set in config log on MGS */ -/* conf_param <cfg_device> key1=value1 [key2=value2...] */ +/* conf_param key1=value1 [key2=value2...] */ int jt_lcfg_mgsparam(int argc, char **argv) { - int i, rc, index_offset = 0; + int i, rc; struct lustre_cfg_bufs bufs; struct lustre_cfg *lcfg; if ((argc >= LUSTRE_CFG_MAX_BUFCOUNT) || (argc <= 1)) return CMD_HELP; - if (!strchr(argv[1], '=')) { - /* Not key=val, assume <cfg_device> */ - rc = jt_obd_device(2, argv); - if (rc) - return rc; - index_offset = 1; - } - - lustre_cfg_bufs_reset(&bufs, lcfg_devname); + lustre_cfg_bufs_reset(&bufs, NULL); - for (i = 1; i < (argc - index_offset); i++) { - lustre_cfg_bufs_set_string(&bufs, i, argv[i + index_offset]); + for (i = 1; i < argc; i++) { + lustre_cfg_bufs_set_string(&bufs, i, argv[i]); } /* We could put other opcodes here. */