4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 only,
8 * as published by the Free Software Foundation.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License version 2 for more details (a copy is included
14 * in the LICENSE file that accompanied this code).
16 * You should have received a copy of the GNU General Public License
17 * version 2 along with this program; If not, see
18 * http://www.gnu.org/licenses/gpl-2.0.html
23 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
24 * Use is subject to license terms.
26 * Copyright (c) 2011, 2016, Intel Corporation.
29 * This file is part of Lustre, http://www.lustre.org/
30 * Lustre is a trademark of Sun Microsystems, Inc.
32 * lustre/mgs/mgs_llog.c
34 * Lustre Management Server (mgs) config llog creation
36 * Author: Nathan Rutman <nathan@clusterfs.com>
37 * Author: Alex Zhuravlev <bzzz@whamcloud.com>
38 * Author: Mikhail Pershin <tappro@whamcloud.com>
41 #define DEBUG_SUBSYSTEM S_MGS
42 #define D_MGS D_CONFIG
45 #include <lustre_ioctl.h>
46 #include <lustre_param.h>
47 #include <lustre_sec.h>
48 #include <lustre_quota.h>
50 #include "mgs_internal.h"
52 /********************** Class functions ********************/
54 /* Find all logs in CONFIG directory and link then into list */
55 int class_dentry_readdir(const struct lu_env *env,
56 struct mgs_device *mgs, struct list_head *log_list)
58 struct dt_object *dir = mgs->mgs_configs_dir;
59 const struct dt_it_ops *iops;
61 struct mgs_direntry *de;
65 INIT_LIST_HEAD(log_list);
68 LASSERT(dir->do_index_ops);
70 iops = &dir->do_index_ops->dio_it;
71 it = iops->init(env, dir, LUDA_64BITHASH);
75 rc = iops->load(env, it, 0);
81 key = (void *)iops->key(env, it);
83 CERROR("%s: key failed when listing %s: rc = %d\n",
84 mgs->mgs_obd->obd_name, MOUNT_CONFIGS_DIR,
88 key_sz = iops->key_size(env, it);
91 /* filter out "." and ".." entries */
95 if (key_sz == 2 && key[1] == '.')
99 /* filter out ".bak" files */
100 /* sizeof(".bak") - 1 == 3 */
102 !memcmp(".bak", key + key_sz - 3, 3)) {
103 CDEBUG(D_MGS, "Skipping backup file %.*s\n",
108 de = mgs_direntry_alloc(key_sz + 1);
114 memcpy(de->mde_name, key, key_sz);
115 de->mde_name[key_sz] = 0;
117 list_add(&de->mde_list, log_list);
120 rc = iops->next(env, it);
130 CERROR("%s: key failed when listing %s: rc = %d\n",
131 mgs->mgs_obd->obd_name, MOUNT_CONFIGS_DIR, rc);
135 /******************** DB functions *********************/
137 static inline int name_create(char **newname, char *prefix, char *suffix)
140 OBD_ALLOC(*newname, strlen(prefix) + strlen(suffix) + 1);
143 sprintf(*newname, "%s%s", prefix, suffix);
147 static inline void name_destroy(char **name)
150 OBD_FREE(*name, strlen(*name) + 1);
154 struct mgs_fsdb_handler_data
160 /* from the (client) config log, figure out:
161 1. which ost's/mdt's are configured (by index)
162 2. what the last config step is
163 3. COMPAT_18 osc name
165 /* It might be better to have a separate db file, instead of parsing the info
166 out of the client log. This is slow and potentially error-prone. */
167 static int mgs_fsdb_handler(const struct lu_env *env, struct llog_handle *llh,
168 struct llog_rec_hdr *rec, void *data)
170 struct mgs_fsdb_handler_data *d = data;
171 struct fs_db *fsdb = d->fsdb;
172 int cfg_len = rec->lrh_len;
173 char *cfg_buf = (char*) (rec + 1);
174 struct lustre_cfg *lcfg;
179 if (rec->lrh_type != OBD_CFG_REC) {
180 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
184 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
186 CERROR("Insane cfg\n");
190 lcfg = (struct lustre_cfg *)cfg_buf;
192 CDEBUG(D_INFO, "cmd %x %s %s\n", lcfg->lcfg_command,
193 lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));
195 /* Figure out ost indicies */
196 /* lov_modify_tgts add 0:lov1 1:ost1_UUID 2(index):0 3(gen):1 */
197 if (lcfg->lcfg_command == LCFG_LOV_ADD_OBD ||
198 lcfg->lcfg_command == LCFG_LOV_DEL_OBD) {
199 index = simple_strtoul(lustre_cfg_string(lcfg, 2),
201 CDEBUG(D_MGS, "OST index for %s is %u (%s)\n",
202 lustre_cfg_string(lcfg, 1), index,
203 lustre_cfg_string(lcfg, 2));
204 set_bit(index, fsdb->fsdb_ost_index_map);
207 /* Figure out mdt indicies */
208 /* attach 0:MDC_uml1_mdsA_MNT_client 1:mdc 2:1d834_MNT_client_03f */
209 if ((lcfg->lcfg_command == LCFG_ATTACH) &&
210 (strcmp(lustre_cfg_string(lcfg, 1), LUSTRE_MDC_NAME) == 0)) {
211 rc = server_name2index(lustre_cfg_string(lcfg, 0),
213 if (rc != LDD_F_SV_TYPE_MDT) {
214 CWARN("Unparsable MDC name %s, assuming index 0\n",
215 lustre_cfg_string(lcfg, 0));
219 CDEBUG(D_MGS, "MDT index is %u\n", index);
220 set_bit(index, fsdb->fsdb_mdt_index_map);
221 fsdb->fsdb_mdt_count ++;
225 * figure out the old config. fsdb_gen = 0 means old log
226 * It is obsoleted and not supported anymore
228 if (fsdb->fsdb_gen == 0) {
229 CERROR("Old config format is not supported\n");
234 * compat to 1.8, check osc name used by MDT0 to OSTs, bz18548.
236 if (!test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags) &&
237 lcfg->lcfg_command == LCFG_ATTACH &&
238 strcmp(lustre_cfg_string(lcfg, 1), LUSTRE_OSC_NAME) == 0) {
239 if (OBD_OCD_VERSION_MAJOR(d->ver) == 1 &&
240 OBD_OCD_VERSION_MINOR(d->ver) <= 8) {
241 CWARN("MDT using 1.8 OSC name scheme\n");
242 set_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags);
246 if (lcfg->lcfg_command == LCFG_MARKER) {
247 struct cfg_marker *marker;
248 marker = lustre_cfg_buf(lcfg, 1);
250 d->ver = marker->cm_vers;
252 /* Keep track of the latest marker step */
253 fsdb->fsdb_gen = max(fsdb->fsdb_gen, marker->cm_step);
259 /* fsdb->fsdb_mutex is already held in mgs_find_or_make_fsdb*/
260 static int mgs_get_fsdb_from_llog(const struct lu_env *env,
261 struct mgs_device *mgs,
265 struct llog_handle *loghandle;
266 struct llog_ctxt *ctxt;
267 struct mgs_fsdb_handler_data d = {
274 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
275 LASSERT(ctxt != NULL);
276 rc = name_create(&logname, fsdb->fsdb_name, "-client");
279 rc = llog_open_create(env, ctxt, &loghandle, NULL, logname);
283 rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL);
287 if (llog_get_size(loghandle) <= 1)
288 set_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags);
290 rc = llog_process(env, loghandle, mgs_fsdb_handler, (void *)&d, NULL);
291 CDEBUG(D_INFO, "get_db = %d\n", rc);
293 llog_close(env, loghandle);
295 name_destroy(&logname);
302 static void mgs_free_fsdb_srpc(struct fs_db *fsdb)
304 struct mgs_tgt_srpc_conf *tgtconf;
306 /* free target-specific rules */
307 while (fsdb->fsdb_srpc_tgt) {
308 tgtconf = fsdb->fsdb_srpc_tgt;
309 fsdb->fsdb_srpc_tgt = tgtconf->mtsc_next;
311 LASSERT(tgtconf->mtsc_tgt);
313 sptlrpc_rule_set_free(&tgtconf->mtsc_rset);
314 OBD_FREE(tgtconf->mtsc_tgt, strlen(tgtconf->mtsc_tgt) + 1);
315 OBD_FREE_PTR(tgtconf);
318 /* free general rules */
319 sptlrpc_rule_set_free(&fsdb->fsdb_srpc_gen);
322 struct fs_db *mgs_find_fsdb(struct mgs_device *mgs, char *fsname)
325 struct list_head *tmp;
327 list_for_each(tmp, &mgs->mgs_fs_db_list) {
328 fsdb = list_entry(tmp, struct fs_db, fsdb_list);
329 if (strcmp(fsdb->fsdb_name, fsname) == 0)
335 /* caller must hold the mgs->mgs_fs_db_lock */
336 static struct fs_db *mgs_new_fsdb(const struct lu_env *env,
337 struct mgs_device *mgs, char *fsname)
343 if (strlen(fsname) >= sizeof(fsdb->fsdb_name)) {
344 CERROR("fsname %s is too long\n", fsname);
345 RETURN(ERR_PTR(-EINVAL));
350 RETURN(ERR_PTR(-ENOMEM));
352 strcpy(fsdb->fsdb_name, fsname);
353 mutex_init(&fsdb->fsdb_mutex);
354 set_bit(FSDB_UDESC, &fsdb->fsdb_flags);
357 if (strcmp(fsname, MGSSELF_NAME) == 0) {
358 set_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags);
359 fsdb->fsdb_mgs = mgs;
361 OBD_ALLOC(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
362 OBD_ALLOC(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
363 if (!fsdb->fsdb_ost_index_map || !fsdb->fsdb_mdt_index_map) {
364 CERROR("No memory for index maps\n");
365 GOTO(err, rc = -ENOMEM);
368 rc = name_create(&fsdb->fsdb_clilov, fsname, "-clilov");
371 rc = name_create(&fsdb->fsdb_clilmv, fsname, "-clilmv");
375 /* initialise data for NID table */
376 mgs_ir_init_fs(env, mgs, fsdb);
378 lproc_mgs_add_live(mgs, fsdb);
381 list_add(&fsdb->fsdb_list, &mgs->mgs_fs_db_list);
385 if (fsdb->fsdb_ost_index_map)
386 OBD_FREE(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
387 if (fsdb->fsdb_mdt_index_map)
388 OBD_FREE(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
389 name_destroy(&fsdb->fsdb_clilov);
390 name_destroy(&fsdb->fsdb_clilmv);
395 static void mgs_free_fsdb(struct mgs_device *mgs, struct fs_db *fsdb)
397 /* wait for anyone with the sem */
398 mutex_lock(&fsdb->fsdb_mutex);
399 lproc_mgs_del_live(mgs, fsdb);
400 list_del(&fsdb->fsdb_list);
402 /* deinitialize fsr */
403 mgs_ir_fini_fs(mgs, fsdb);
405 if (fsdb->fsdb_ost_index_map)
406 OBD_FREE(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
407 if (fsdb->fsdb_mdt_index_map)
408 OBD_FREE(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
409 name_destroy(&fsdb->fsdb_clilov);
410 name_destroy(&fsdb->fsdb_clilmv);
411 mgs_free_fsdb_srpc(fsdb);
412 mutex_unlock(&fsdb->fsdb_mutex);
416 int mgs_init_fsdb_list(struct mgs_device *mgs)
418 INIT_LIST_HEAD(&mgs->mgs_fs_db_list);
422 int mgs_cleanup_fsdb_list(struct mgs_device *mgs)
425 struct list_head *tmp, *tmp2;
427 mutex_lock(&mgs->mgs_mutex);
428 list_for_each_safe(tmp, tmp2, &mgs->mgs_fs_db_list) {
429 fsdb = list_entry(tmp, struct fs_db, fsdb_list);
430 mgs_free_fsdb(mgs, fsdb);
432 mutex_unlock(&mgs->mgs_mutex);
436 int mgs_find_or_make_fsdb(const struct lu_env *env,
437 struct mgs_device *mgs, char *name,
444 mutex_lock(&mgs->mgs_mutex);
445 fsdb = mgs_find_fsdb(mgs, name);
447 mutex_unlock(&mgs->mgs_mutex);
452 CDEBUG(D_MGS, "Creating new db\n");
453 fsdb = mgs_new_fsdb(env, mgs, name);
454 /* lock fsdb_mutex until the db is loaded from llogs */
456 mutex_lock(&fsdb->fsdb_mutex);
457 mutex_unlock(&mgs->mgs_mutex);
459 RETURN(PTR_ERR(fsdb));
461 if (!test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
462 /* populate the db from the client llog */
463 rc = mgs_get_fsdb_from_llog(env, mgs, fsdb);
465 CERROR("Can't get db from client log %d\n", rc);
470 /* populate srpc rules from params llog */
471 rc = mgs_get_fsdb_srpc_from_llog(env, mgs, fsdb);
473 CERROR("Can't get db from params log %d\n", rc);
477 mutex_unlock(&fsdb->fsdb_mutex);
483 mutex_unlock(&fsdb->fsdb_mutex);
484 mgs_free_fsdb(mgs, fsdb);
490 -1= empty client log */
491 int mgs_check_index(const struct lu_env *env,
492 struct mgs_device *mgs,
493 struct mgs_target_info *mti)
500 LASSERT(!(mti->mti_flags & LDD_F_NEED_INDEX));
502 rc = mgs_find_or_make_fsdb(env, mgs, mti->mti_fsname, &fsdb);
504 CERROR("Can't get db for %s\n", mti->mti_fsname);
508 if (test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags))
511 if (mti->mti_flags & LDD_F_SV_TYPE_OST)
512 imap = fsdb->fsdb_ost_index_map;
513 else if (mti->mti_flags & LDD_F_SV_TYPE_MDT)
514 imap = fsdb->fsdb_mdt_index_map;
518 if (test_bit(mti->mti_stripe_index, imap))
523 static __inline__ int next_index(void *index_map, int map_len)
526 for (i = 0; i < map_len * 8; i++)
527 if (!test_bit(i, index_map)) {
530 CERROR("max index %d exceeded.\n", i);
535 0 newly marked as in use
537 +EALREADY for update of an old index */
538 static int mgs_set_index(const struct lu_env *env,
539 struct mgs_device *mgs,
540 struct mgs_target_info *mti)
547 rc = mgs_find_or_make_fsdb(env, mgs, mti->mti_fsname, &fsdb);
549 CERROR("Can't get db for %s\n", mti->mti_fsname);
553 mutex_lock(&fsdb->fsdb_mutex);
554 if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
555 imap = fsdb->fsdb_ost_index_map;
556 } else if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
557 imap = fsdb->fsdb_mdt_index_map;
559 GOTO(out_up, rc = -EINVAL);
562 if (mti->mti_flags & LDD_F_NEED_INDEX) {
563 rc = next_index(imap, INDEX_MAP_SIZE);
565 GOTO(out_up, rc = -ERANGE);
566 mti->mti_stripe_index = rc;
567 if (mti->mti_flags & LDD_F_SV_TYPE_MDT)
568 fsdb->fsdb_mdt_count ++;
571 /* the last index(0xffff) is reserved for default value. */
572 if (mti->mti_stripe_index >= INDEX_MAP_SIZE * 8 - 1) {
573 LCONSOLE_ERROR_MSG(0x13f, "Server %s requested index %u, "
574 "but index must be less than %u.\n",
575 mti->mti_svname, mti->mti_stripe_index,
576 INDEX_MAP_SIZE * 8 - 1);
577 GOTO(out_up, rc = -ERANGE);
580 if (test_bit(mti->mti_stripe_index, imap)) {
581 if ((mti->mti_flags & LDD_F_VIRGIN) &&
582 !(mti->mti_flags & LDD_F_WRITECONF)) {
583 LCONSOLE_ERROR_MSG(0x140, "Server %s requested index "
584 "%d, but that index is already in "
585 "use. Use --writeconf to force\n",
587 mti->mti_stripe_index);
588 GOTO(out_up, rc = -EADDRINUSE);
590 CDEBUG(D_MGS, "Server %s updating index %d\n",
591 mti->mti_svname, mti->mti_stripe_index);
592 GOTO(out_up, rc = EALREADY);
596 set_bit(mti->mti_stripe_index, imap);
597 clear_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags);
598 mutex_unlock(&fsdb->fsdb_mutex);
599 if (server_make_name(mti->mti_flags & ~(LDD_F_VIRGIN | LDD_F_WRITECONF),
600 mti->mti_stripe_index, mti->mti_fsname,
602 CERROR("unknown server type %#x\n", mti->mti_flags);
606 CDEBUG(D_MGS, "Set index for %s to %d\n", mti->mti_svname,
607 mti->mti_stripe_index);
611 mutex_unlock(&fsdb->fsdb_mutex);
615 struct mgs_modify_lookup {
616 struct cfg_marker mml_marker;
620 static int mgs_check_record_match(const struct lu_env *env,
621 struct llog_handle *llh,
622 struct llog_rec_hdr *rec, void *data)
624 struct cfg_marker *mc_marker = data;
625 struct cfg_marker *marker;
626 struct lustre_cfg *lcfg = REC_DATA(rec);
627 int cfg_len = REC_DATA_LEN(rec);
632 if (rec->lrh_type != OBD_CFG_REC) {
633 CDEBUG(D_ERROR, "Unhandled lrh_type: %#x\n", rec->lrh_type);
637 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
639 CDEBUG(D_ERROR, "Insane cfg\n");
643 /* We only care about markers */
644 if (lcfg->lcfg_command != LCFG_MARKER)
647 marker = lustre_cfg_buf(lcfg, 1);
649 if (marker->cm_flags & CM_SKIP)
652 if ((strcmp(mc_marker->cm_comment, marker->cm_comment) == 0) &&
653 (strcmp(mc_marker->cm_tgtname, marker->cm_tgtname) == 0)) {
654 /* Found a non-skipped marker match */
655 CDEBUG(D_MGS, "Matched rec %u marker %d flag %x %s %s\n",
656 rec->lrh_index, marker->cm_step,
657 marker->cm_flags, marker->cm_tgtname,
659 rc = LLOG_PROC_BREAK;
666 * Check an existing config log record with matching comment and device
668 * 0 - checked successfully,
669 * LLOG_PROC_BREAK - record matches
672 static int mgs_check_marker(const struct lu_env *env, struct mgs_device *mgs,
673 struct fs_db *fsdb, struct mgs_target_info *mti,
674 char *logname, char *devname, char *comment)
676 struct llog_handle *loghandle;
677 struct llog_ctxt *ctxt;
678 struct cfg_marker *mc_marker;
683 LASSERT(mutex_is_locked(&fsdb->fsdb_mutex));
684 CDEBUG(D_MGS, "mgs check %s/%s/%s\n", logname, devname, comment);
686 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
687 LASSERT(ctxt != NULL);
688 rc = llog_open(env, ctxt, &loghandle, NULL, logname, LLOG_OPEN_EXISTS);
695 rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL);
699 if (llog_get_size(loghandle) <= 1)
700 GOTO(out_close, rc = 0);
702 OBD_ALLOC_PTR(mc_marker);
704 GOTO(out_close, rc = -ENOMEM);
705 if (strlcpy(mc_marker->cm_comment, comment,
706 sizeof(mc_marker->cm_comment)) >=
707 sizeof(mc_marker->cm_comment))
708 GOTO(out_free, rc = -E2BIG);
709 if (strlcpy(mc_marker->cm_tgtname, devname,
710 sizeof(mc_marker->cm_tgtname)) >=
711 sizeof(mc_marker->cm_tgtname))
712 GOTO(out_free, rc = -E2BIG);
714 rc = llog_process(env, loghandle, mgs_check_record_match,
715 (void *)mc_marker, NULL);
718 OBD_FREE_PTR(mc_marker);
721 llog_close(env, loghandle);
723 if (rc && rc != LLOG_PROC_BREAK)
724 CDEBUG(D_ERROR, "%s: mgs check %s/%s failed: rc = %d\n",
725 mgs->mgs_obd->obd_name, mti->mti_svname, comment, rc);
730 static int mgs_modify_handler(const struct lu_env *env,
731 struct llog_handle *llh,
732 struct llog_rec_hdr *rec, void *data)
734 struct mgs_modify_lookup *mml = data;
735 struct cfg_marker *marker;
736 struct lustre_cfg *lcfg = REC_DATA(rec);
737 int cfg_len = REC_DATA_LEN(rec);
741 if (rec->lrh_type != OBD_CFG_REC) {
742 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
746 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
748 CERROR("Insane cfg\n");
752 /* We only care about markers */
753 if (lcfg->lcfg_command != LCFG_MARKER)
756 marker = lustre_cfg_buf(lcfg, 1);
757 if ((strcmp(mml->mml_marker.cm_comment, marker->cm_comment) == 0) &&
758 (strcmp(mml->mml_marker.cm_tgtname, marker->cm_tgtname) == 0) &&
759 !(marker->cm_flags & CM_SKIP)) {
760 /* Found a non-skipped marker match */
761 CDEBUG(D_MGS, "Changing rec %u marker %d %x->%x: %s %s\n",
762 rec->lrh_index, marker->cm_step,
763 marker->cm_flags, mml->mml_marker.cm_flags,
764 marker->cm_tgtname, marker->cm_comment);
765 /* Overwrite the old marker llog entry */
766 marker->cm_flags &= ~CM_EXCLUDE; /* in case we're unexcluding */
767 marker->cm_flags |= mml->mml_marker.cm_flags;
768 marker->cm_canceltime = mml->mml_marker.cm_canceltime;
769 rc = llog_write(env, llh, rec, rec->lrh_index);
778 * Modify an existing config log record (for CM_SKIP or CM_EXCLUDE)
780 * 0 - modified successfully,
781 * 1 - no modification was done
784 static int mgs_modify(const struct lu_env *env, struct mgs_device *mgs,
785 struct fs_db *fsdb, struct mgs_target_info *mti,
786 char *logname, char *devname, char *comment, int flags)
788 struct llog_handle *loghandle;
789 struct llog_ctxt *ctxt;
790 struct mgs_modify_lookup *mml;
795 LASSERT(mutex_is_locked(&fsdb->fsdb_mutex));
796 CDEBUG(D_MGS, "modify %s/%s/%s fl=%x\n", logname, devname, comment,
799 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
800 LASSERT(ctxt != NULL);
801 rc = llog_open(env, ctxt, &loghandle, NULL, logname, LLOG_OPEN_EXISTS);
808 rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL);
812 if (llog_get_size(loghandle) <= 1)
813 GOTO(out_close, rc = 0);
817 GOTO(out_close, rc = -ENOMEM);
818 if (strlcpy(mml->mml_marker.cm_comment, comment,
819 sizeof(mml->mml_marker.cm_comment)) >=
820 sizeof(mml->mml_marker.cm_comment))
821 GOTO(out_free, rc = -E2BIG);
822 if (strlcpy(mml->mml_marker.cm_tgtname, devname,
823 sizeof(mml->mml_marker.cm_tgtname)) >=
824 sizeof(mml->mml_marker.cm_tgtname))
825 GOTO(out_free, rc = -E2BIG);
826 /* Modify mostly means cancel */
827 mml->mml_marker.cm_flags = flags;
828 mml->mml_marker.cm_canceltime = flags ? cfs_time_current_sec() : 0;
829 mml->mml_modified = 0;
830 rc = llog_process(env, loghandle, mgs_modify_handler, (void *)mml,
832 if (!rc && !mml->mml_modified)
839 llog_close(env, loghandle);
842 CERROR("%s: modify %s/%s failed: rc = %d\n",
843 mgs->mgs_obd->obd_name, mti->mti_svname, comment, rc);
848 /** This structure is passed to mgs_replace_handler */
849 struct mgs_replace_uuid_lookup {
850 /* Nids are replaced for this target device */
851 struct mgs_target_info target;
852 /* Temporary modified llog */
853 struct llog_handle *temp_llh;
854 /* Flag is set if in target block*/
855 int in_target_device;
856 /* Nids already added. Just skip (multiple nids) */
857 int device_nids_added;
858 /* Flag is set if this block should not be copied */
863 * Check: a) if block should be skipped
864 * b) is it target block
869 * \retval 0 should not to be skipped
870 * \retval 1 should to be skipped
872 static int check_markers(struct lustre_cfg *lcfg,
873 struct mgs_replace_uuid_lookup *mrul)
875 struct cfg_marker *marker;
877 /* Track markers. Find given device */
878 if (lcfg->lcfg_command == LCFG_MARKER) {
879 marker = lustre_cfg_buf(lcfg, 1);
880 /* Clean llog from records marked as CM_EXCLUDE.
881 CM_SKIP records are used for "active" command
882 and can be restored if needed */
883 if ((marker->cm_flags & (CM_EXCLUDE | CM_START)) ==
884 (CM_EXCLUDE | CM_START)) {
889 if ((marker->cm_flags & (CM_EXCLUDE | CM_END)) ==
890 (CM_EXCLUDE | CM_END)) {
895 if (strcmp(mrul->target.mti_svname, marker->cm_tgtname) == 0) {
896 LASSERT(!(marker->cm_flags & CM_START) ||
897 !(marker->cm_flags & CM_END));
898 if (marker->cm_flags & CM_START) {
899 mrul->in_target_device = 1;
900 mrul->device_nids_added = 0;
901 } else if (marker->cm_flags & CM_END)
902 mrul->in_target_device = 0;
909 static int record_base(const struct lu_env *env, struct llog_handle *llh,
910 char *cfgname, lnet_nid_t nid, int cmd,
911 char *s1, char *s2, char *s3, char *s4)
913 struct mgs_thread_info *mgi = mgs_env_info(env);
914 struct llog_cfg_rec *lcr;
917 CDEBUG(D_MGS, "lcfg %s %#x %s %s %s %s\n", cfgname,
918 cmd, s1, s2, s3, s4);
920 lustre_cfg_bufs_reset(&mgi->mgi_bufs, cfgname);
922 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, s1);
924 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 2, s2);
926 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 3, s3);
928 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 4, s4);
930 lcr = lustre_cfg_rec_new(cmd, &mgi->mgi_bufs);
934 lcr->lcr_cfg.lcfg_nid = nid;
935 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
937 lustre_cfg_rec_free(lcr);
941 "failed to write lcfg %s %#x %s %s %s %s: rc = %d\n",
942 cfgname, cmd, s1, s2, s3, s4, rc);
946 static inline int record_add_uuid(const struct lu_env *env,
947 struct llog_handle *llh,
948 uint64_t nid, char *uuid)
950 return record_base(env, llh, NULL, nid, LCFG_ADD_UUID, uuid,
954 static inline int record_add_conn(const struct lu_env *env,
955 struct llog_handle *llh,
956 char *devname, char *uuid)
958 return record_base(env, llh, devname, 0, LCFG_ADD_CONN, uuid,
962 static inline int record_attach(const struct lu_env *env,
963 struct llog_handle *llh, char *devname,
964 char *type, char *uuid)
966 return record_base(env, llh, devname, 0, LCFG_ATTACH, type, uuid,
970 static inline int record_setup(const struct lu_env *env,
971 struct llog_handle *llh, char *devname,
972 char *s1, char *s2, char *s3, char *s4)
974 return record_base(env, llh, devname, 0, LCFG_SETUP, s1, s2, s3, s4);
978 * \retval <0 record processing error
979 * \retval n record is processed. No need copy original one.
980 * \retval 0 record is not processed.
982 static int process_command(const struct lu_env *env, struct lustre_cfg *lcfg,
983 struct mgs_replace_uuid_lookup *mrul)
990 if (lcfg->lcfg_command == LCFG_ADD_UUID) {
991 /* LCFG_ADD_UUID command found. Let's skip original command
992 and add passed nids */
993 ptr = mrul->target.mti_params;
994 while (class_parse_nid(ptr, &nid, &ptr) == 0) {
995 CDEBUG(D_MGS, "add nid %s with uuid %s, "
996 "device %s\n", libcfs_nid2str(nid),
997 mrul->target.mti_params,
998 mrul->target.mti_svname);
999 rc = record_add_uuid(env,
1000 mrul->temp_llh, nid,
1001 mrul->target.mti_params);
1006 if (nids_added == 0) {
1007 CERROR("No new nids were added, nid %s with uuid %s, "
1008 "device %s\n", libcfs_nid2str(nid),
1009 mrul->target.mti_params,
1010 mrul->target.mti_svname);
1013 mrul->device_nids_added = 1;
1019 if (mrul->device_nids_added && lcfg->lcfg_command == LCFG_SETUP) {
1020 /* LCFG_SETUP command found. UUID should be changed */
1021 rc = record_setup(env,
1023 /* devname the same */
1024 lustre_cfg_string(lcfg, 0),
1025 /* s1 is not changed */
1026 lustre_cfg_string(lcfg, 1),
1027 /* new uuid should be
1029 mrul->target.mti_params,
1030 /* s3 is not changed */
1031 lustre_cfg_string(lcfg, 3),
1032 /* s4 is not changed */
1033 lustre_cfg_string(lcfg, 4));
1037 /* Another commands in target device block */
1042 * Handler that called for every record in llog.
1043 * Records are processed in order they placed in llog.
1045 * \param[in] llh log to be processed
1046 * \param[in] rec current record
1047 * \param[in] data mgs_replace_uuid_lookup structure
1051 static int mgs_replace_handler(const struct lu_env *env,
1052 struct llog_handle *llh,
1053 struct llog_rec_hdr *rec,
1056 struct mgs_replace_uuid_lookup *mrul;
1057 struct lustre_cfg *lcfg = REC_DATA(rec);
1058 int cfg_len = REC_DATA_LEN(rec);
1062 mrul = (struct mgs_replace_uuid_lookup *)data;
1064 if (rec->lrh_type != OBD_CFG_REC) {
1065 CERROR("unhandled lrh_type: %#x, cmd %x %s %s\n",
1066 rec->lrh_type, lcfg->lcfg_command,
1067 lustre_cfg_string(lcfg, 0),
1068 lustre_cfg_string(lcfg, 1));
1072 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
1074 /* Do not copy any invalidated records */
1075 GOTO(skip_out, rc = 0);
1078 rc = check_markers(lcfg, mrul);
1079 if (rc || mrul->skip_it)
1080 GOTO(skip_out, rc = 0);
1082 /* Write to new log all commands outside target device block */
1083 if (!mrul->in_target_device)
1084 GOTO(copy_out, rc = 0);
1086 /* Skip all other LCFG_ADD_UUID and LCFG_ADD_CONN records
1087 (failover nids) for this target, assuming that if then
1088 primary is changing then so is the failover */
1089 if (mrul->device_nids_added &&
1090 (lcfg->lcfg_command == LCFG_ADD_UUID ||
1091 lcfg->lcfg_command == LCFG_ADD_CONN))
1092 GOTO(skip_out, rc = 0);
1094 rc = process_command(env, lcfg, mrul);
1101 /* Record is placed in temporary llog as is */
1102 rc = llog_write(env, mrul->temp_llh, rec, LLOG_NEXT_IDX);
1104 CDEBUG(D_MGS, "Copied idx=%d, rc=%d, len=%d, cmd %x %s %s\n",
1105 rec->lrh_index, rc, rec->lrh_len, lcfg->lcfg_command,
1106 lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));
1110 CDEBUG(D_MGS, "Skipped idx=%d, rc=%d, len=%d, cmd %x %s %s\n",
1111 rec->lrh_index, rc, rec->lrh_len, lcfg->lcfg_command,
1112 lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));
1116 static int mgs_log_is_empty(const struct lu_env *env,
1117 struct mgs_device *mgs, char *name)
1119 struct llog_ctxt *ctxt;
1122 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
1123 LASSERT(ctxt != NULL);
1125 rc = llog_is_empty(env, ctxt, name);
1126 llog_ctxt_put(ctxt);
1130 static int mgs_replace_nids_log(const struct lu_env *env,
1131 struct obd_device *mgs, struct fs_db *fsdb,
1132 char *logname, char *devname, char *nids)
1134 struct llog_handle *orig_llh, *backup_llh;
1135 struct llog_ctxt *ctxt;
1136 struct mgs_replace_uuid_lookup *mrul;
1137 struct mgs_device *mgs_dev = lu2mgs_dev(mgs->obd_lu_dev);
1138 static struct obd_uuid cfg_uuid = { .uuid = "config_uuid" };
1143 CDEBUG(D_MGS, "Replace nids for %s in %s\n", devname, logname);
1145 ctxt = llog_get_context(mgs, LLOG_CONFIG_ORIG_CTXT);
1146 LASSERT(ctxt != NULL);
1148 if (mgs_log_is_empty(env, mgs_dev, logname)) {
1149 /* Log is empty. Nothing to replace */
1150 GOTO(out_put, rc = 0);
1153 OBD_ALLOC(backup, strlen(logname) + strlen(".bak") + 1);
1155 GOTO(out_put, rc = -ENOMEM);
1157 sprintf(backup, "%s.bak", logname);
1159 rc = llog_backup(env, mgs, ctxt, ctxt, logname, backup);
1161 /* Now erase original log file. Connections are not allowed.
1162 Backup is already saved */
1163 rc = llog_erase(env, ctxt, NULL, logname);
1166 } else if (rc != -ENOENT) {
1167 CERROR("%s: can't make backup for %s: rc = %d\n",
1168 mgs->obd_name, logname, rc);
1172 /* open local log */
1173 rc = llog_open_create(env, ctxt, &orig_llh, NULL, logname);
1175 GOTO(out_restore, rc);
1177 rc = llog_init_handle(env, orig_llh, LLOG_F_IS_PLAIN, &cfg_uuid);
1179 GOTO(out_closel, rc);
1181 /* open backup llog */
1182 rc = llog_open(env, ctxt, &backup_llh, NULL, backup,
1185 GOTO(out_closel, rc);
1187 rc = llog_init_handle(env, backup_llh, LLOG_F_IS_PLAIN, NULL);
1189 GOTO(out_close, rc);
1191 if (llog_get_size(backup_llh) <= 1)
1192 GOTO(out_close, rc = 0);
1194 OBD_ALLOC_PTR(mrul);
1196 GOTO(out_close, rc = -ENOMEM);
1197 /* devname is only needed information to replace UUID records */
1198 strlcpy(mrul->target.mti_svname, devname,
1199 sizeof(mrul->target.mti_svname));
1200 /* parse nids later */
1201 strlcpy(mrul->target.mti_params, nids, sizeof(mrul->target.mti_params));
1202 /* Copy records to this temporary llog */
1203 mrul->temp_llh = orig_llh;
1205 rc = llog_process(env, backup_llh, mgs_replace_handler,
1206 (void *)mrul, NULL);
1209 rc2 = llog_close(NULL, backup_llh);
1213 rc2 = llog_close(NULL, orig_llh);
1219 CERROR("%s: llog should be restored: rc = %d\n",
1221 rc2 = llog_backup(env, mgs, ctxt, ctxt, backup,
1224 CERROR("%s: can't restore backup %s: rc = %d\n",
1225 mgs->obd_name, logname, rc2);
1229 OBD_FREE(backup, strlen(backup) + 1);
1232 llog_ctxt_put(ctxt);
1235 CERROR("%s: failed to replace nids in log %s: rc = %d\n",
1236 mgs->obd_name, logname, rc);
1242 * Parse device name and get file system name and/or device index
1244 * \param[in] devname device name (ex. lustre-MDT0000)
1245 * \param[out] fsname file system name(optional)
1246 * \param[out] index device index(optional)
1250 static int mgs_parse_devname(char *devname, char *fsname, __u32 *index)
1255 /* Extract fsname */
1257 rc = server_name2fsname(devname, fsname, NULL);
1259 CDEBUG(D_MGS, "Device name %s without fsname\n",
1266 rc = server_name2index(devname, index, NULL);
1268 CDEBUG(D_MGS, "Device name %s with wrong index\n",
1277 /* This is only called during replace_nids */
1278 static int only_mgs_is_running(struct obd_device *mgs_obd)
1280 /* TDB: Is global variable with devices count exists? */
1281 int num_devices = get_devices_count();
1282 int num_exports = 0;
1283 struct obd_export *exp;
1285 spin_lock(&mgs_obd->obd_dev_lock);
1286 list_for_each_entry(exp, &mgs_obd->obd_exports, exp_obd_chain) {
1287 /* skip self export */
1288 if (exp == mgs_obd->obd_self_export)
1290 if (exp_connect_flags(exp) & OBD_CONNECT_MDS_MDS)
1295 CERROR("%s: node %s still connected during replace_nids "
1296 "connect_flags:%llx\n",
1298 libcfs_nid2str(exp->exp_nid_stats->nid),
1299 exp_connect_flags(exp));
1302 spin_unlock(&mgs_obd->obd_dev_lock);
1304 /* osd, MGS and MGC + self_export
1305 (wc -l /proc/fs/lustre/devices <= 2) && (non self exports == 0) */
1306 return (num_devices <= 3) && (num_exports == 0);
1309 static int name_create_mdt(char **logname, char *fsname, int i)
1313 sprintf(mdt_index, "-MDT%04x", i);
1314 return name_create(logname, fsname, mdt_index);
1318 * Replace nids for \a device to \a nids values
1320 * \param obd MGS obd device
1321 * \param devname nids need to be replaced for this device
1322 * (ex. lustre-OST0000)
1323 * \param nids nids list (ex. nid1,nid2,nid3)
1327 int mgs_replace_nids(const struct lu_env *env,
1328 struct mgs_device *mgs,
1329 char *devname, char *nids)
1331 /* Assume fsname is part of device name */
1332 char fsname[MTI_NAME_MAXLEN];
1339 struct obd_device *mgs_obd = mgs->mgs_obd;
1342 /* We can only change NIDs if no other nodes are connected */
1343 spin_lock(&mgs_obd->obd_dev_lock);
1344 conn_state = mgs_obd->obd_no_conn;
1345 mgs_obd->obd_no_conn = 1;
1346 spin_unlock(&mgs_obd->obd_dev_lock);
1348 /* We can not change nids if not only MGS is started */
1349 if (!only_mgs_is_running(mgs_obd)) {
1350 CERROR("Only MGS is allowed to be started\n");
1351 GOTO(out, rc = -EINPROGRESS);
1354 /* Get fsname and index*/
1355 rc = mgs_parse_devname(devname, fsname, &index);
1359 rc = mgs_find_or_make_fsdb(env, mgs, fsname, &fsdb);
1361 CERROR("%s: can't find fsdb: rc = %d\n", fsname, rc);
1365 /* Process client llogs */
1366 name_create(&logname, fsname, "-client");
1367 rc = mgs_replace_nids_log(env, mgs_obd, fsdb, logname, devname, nids);
1368 name_destroy(&logname);
1370 CERROR("%s: error while replacing NIDs for %s: rc = %d\n",
1371 fsname, devname, rc);
1375 /* Process MDT llogs */
1376 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
1377 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
1379 name_create_mdt(&logname, fsname, i);
1380 rc = mgs_replace_nids_log(env, mgs_obd, fsdb, logname, devname, nids);
1381 name_destroy(&logname);
1387 spin_lock(&mgs_obd->obd_dev_lock);
1388 mgs_obd->obd_no_conn = conn_state;
1389 spin_unlock(&mgs_obd->obd_dev_lock);
1394 static int record_lov_setup(const struct lu_env *env, struct llog_handle *llh,
1395 char *devname, struct lov_desc *desc)
1397 struct mgs_thread_info *mgi = mgs_env_info(env);
1398 struct llog_cfg_rec *lcr;
1401 lustre_cfg_bufs_reset(&mgi->mgi_bufs, devname);
1402 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, desc, sizeof(*desc));
1403 lcr = lustre_cfg_rec_new(LCFG_SETUP, &mgi->mgi_bufs);
1407 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1408 lustre_cfg_rec_free(lcr);
1412 static int record_lmv_setup(const struct lu_env *env, struct llog_handle *llh,
1413 char *devname, struct lmv_desc *desc)
1415 struct mgs_thread_info *mgi = mgs_env_info(env);
1416 struct llog_cfg_rec *lcr;
1419 lustre_cfg_bufs_reset(&mgi->mgi_bufs, devname);
1420 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, desc, sizeof(*desc));
1421 lcr = lustre_cfg_rec_new(LCFG_SETUP, &mgi->mgi_bufs);
1425 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1426 lustre_cfg_rec_free(lcr);
1430 static inline int record_mdc_add(const struct lu_env *env,
1431 struct llog_handle *llh,
1432 char *logname, char *mdcuuid,
1433 char *mdtuuid, char *index,
1436 return record_base(env,llh,logname,0,LCFG_ADD_MDC,
1437 mdtuuid,index,gen,mdcuuid);
1440 static inline int record_lov_add(const struct lu_env *env,
1441 struct llog_handle *llh,
1442 char *lov_name, char *ost_uuid,
1443 char *index, char *gen)
1445 return record_base(env, llh, lov_name, 0, LCFG_LOV_ADD_OBD,
1446 ost_uuid, index, gen, NULL);
1449 static inline int record_mount_opt(const struct lu_env *env,
1450 struct llog_handle *llh,
1451 char *profile, char *lov_name,
1454 return record_base(env, llh, NULL, 0, LCFG_MOUNTOPT,
1455 profile, lov_name, mdc_name, NULL);
1458 static int record_marker(const struct lu_env *env,
1459 struct llog_handle *llh,
1460 struct fs_db *fsdb, __u32 flags,
1461 char *tgtname, char *comment)
1463 struct mgs_thread_info *mgi = mgs_env_info(env);
1464 struct llog_cfg_rec *lcr;
1468 if (flags & CM_START)
1470 mgi->mgi_marker.cm_step = fsdb->fsdb_gen;
1471 mgi->mgi_marker.cm_flags = flags;
1472 mgi->mgi_marker.cm_vers = LUSTRE_VERSION_CODE;
1473 cplen = strlcpy(mgi->mgi_marker.cm_tgtname, tgtname,
1474 sizeof(mgi->mgi_marker.cm_tgtname));
1475 if (cplen >= sizeof(mgi->mgi_marker.cm_tgtname))
1477 cplen = strlcpy(mgi->mgi_marker.cm_comment, comment,
1478 sizeof(mgi->mgi_marker.cm_comment));
1479 if (cplen >= sizeof(mgi->mgi_marker.cm_comment))
1481 mgi->mgi_marker.cm_createtime = cfs_time_current_sec();
1482 mgi->mgi_marker.cm_canceltime = 0;
1483 lustre_cfg_bufs_reset(&mgi->mgi_bufs, NULL);
1484 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, &mgi->mgi_marker,
1485 sizeof(mgi->mgi_marker));
1486 lcr = lustre_cfg_rec_new(LCFG_MARKER, &mgi->mgi_bufs);
1490 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1491 lustre_cfg_rec_free(lcr);
1495 static int record_start_log(const struct lu_env *env, struct mgs_device *mgs,
1496 struct llog_handle **llh, char *name)
1498 static struct obd_uuid cfg_uuid = { .uuid = "config_uuid" };
1499 struct llog_ctxt *ctxt;
1504 GOTO(out, rc = -EBUSY);
1506 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
1508 GOTO(out, rc = -ENODEV);
1509 LASSERT(ctxt->loc_obd == mgs->mgs_obd);
1511 rc = llog_open_create(env, ctxt, llh, NULL, name);
1514 rc = llog_init_handle(env, *llh, LLOG_F_IS_PLAIN, &cfg_uuid);
1516 llog_close(env, *llh);
1518 llog_ctxt_put(ctxt);
1521 CERROR("%s: can't start log %s: rc = %d\n",
1522 mgs->mgs_obd->obd_name, name, rc);
1528 static int record_end_log(const struct lu_env *env, struct llog_handle **llh)
1532 rc = llog_close(env, *llh);
1538 /******************** config "macros" *********************/
1540 /* write an lcfg directly into a log (with markers) */
1541 static int mgs_write_log_direct(const struct lu_env *env,
1542 struct mgs_device *mgs, struct fs_db *fsdb,
1543 char *logname, struct llog_cfg_rec *lcr,
1544 char *devname, char *comment)
1546 struct llog_handle *llh = NULL;
1551 rc = record_start_log(env, mgs, &llh, logname);
1555 /* FIXME These should be a single journal transaction */
1556 rc = record_marker(env, llh, fsdb, CM_START, devname, comment);
1559 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1562 rc = record_marker(env, llh, fsdb, CM_END, devname, comment);
1566 record_end_log(env, &llh);
1570 /* write the lcfg in all logs for the given fs */
1571 static int mgs_write_log_direct_all(const struct lu_env *env,
1572 struct mgs_device *mgs,
1574 struct mgs_target_info *mti,
1575 struct llog_cfg_rec *lcr, char *devname,
1576 char *comment, int server_only)
1578 struct list_head log_list;
1579 struct mgs_direntry *dirent, *n;
1580 char *fsname = mti->mti_fsname;
1581 int rc = 0, len = strlen(fsname);
1584 /* Find all the logs in the CONFIGS directory */
1585 rc = class_dentry_readdir(env, mgs, &log_list);
1589 /* Could use fsdb index maps instead of directory listing */
1590 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
1591 list_del_init(&dirent->mde_list);
1592 /* don't write to sptlrpc rule log */
1593 if (strstr(dirent->mde_name, "-sptlrpc") != NULL)
1596 /* caller wants write server logs only */
1597 if (server_only && strstr(dirent->mde_name, "-client") != NULL)
1600 if (strlen(dirent->mde_name) <= len ||
1601 strncmp(fsname, dirent->mde_name, len) != 0 ||
1602 dirent->mde_name[len] != '-')
1605 CDEBUG(D_MGS, "Changing log %s\n", dirent->mde_name);
1606 /* Erase any old settings of this same parameter */
1607 rc = mgs_modify(env, mgs, fsdb, mti, dirent->mde_name,
1608 devname, comment, CM_SKIP);
1610 CERROR("%s: Can't modify llog %s: rc = %d\n",
1611 mgs->mgs_obd->obd_name, dirent->mde_name, rc);
1614 /* Write the new one */
1615 rc = mgs_write_log_direct(env, mgs, fsdb, dirent->mde_name,
1616 lcr, devname, comment);
1618 CERROR("%s: writing log %s: rc = %d\n",
1619 mgs->mgs_obd->obd_name, dirent->mde_name, rc);
1621 mgs_direntry_free(dirent);
1627 static int mgs_write_log_osp_to_mdt(const struct lu_env *env,
1628 struct mgs_device *mgs,
1630 struct mgs_target_info *mti,
1631 int index, char *logname);
1632 static int mgs_write_log_osc_to_lov(const struct lu_env *env,
1633 struct mgs_device *mgs,
1635 struct mgs_target_info *mti,
1636 char *logname, char *suffix, char *lovname,
1637 enum lustre_sec_part sec_part, int flags);
1638 static int name_create_mdt_and_lov(char **logname, char **lovname,
1639 struct fs_db *fsdb, int i);
1641 static int add_param(char *params, char *key, char *val)
1643 char *start = params + strlen(params);
1644 char *end = params + sizeof(((struct mgs_target_info *)0)->mti_params);
1648 keylen = strlen(key);
1649 if (start + 1 + keylen + strlen(val) >= end) {
1650 CERROR("params are too long: %s %s%s\n",
1651 params, key != NULL ? key : "", val);
1655 sprintf(start, " %s%s", key != NULL ? key : "", val);
1660 * Walk through client config log record and convert the related records
1663 static int mgs_steal_client_llog_handler(const struct lu_env *env,
1664 struct llog_handle *llh,
1665 struct llog_rec_hdr *rec, void *data)
1667 struct mgs_device *mgs;
1668 struct obd_device *obd;
1669 struct mgs_target_info *mti, *tmti;
1671 int cfg_len = rec->lrh_len;
1672 char *cfg_buf = (char*) (rec + 1);
1673 struct lustre_cfg *lcfg;
1675 struct llog_handle *mdt_llh = NULL;
1676 static int got_an_osc_or_mdc = 0;
1677 /* 0: not found any osc/mdc;
1681 static int last_step = -1;
1686 mti = ((struct temp_comp*)data)->comp_mti;
1687 tmti = ((struct temp_comp*)data)->comp_tmti;
1688 fsdb = ((struct temp_comp*)data)->comp_fsdb;
1689 obd = ((struct temp_comp *)data)->comp_obd;
1690 mgs = lu2mgs_dev(obd->obd_lu_dev);
1693 if (rec->lrh_type != OBD_CFG_REC) {
1694 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
1698 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
1700 CERROR("Insane cfg\n");
1704 lcfg = (struct lustre_cfg *)cfg_buf;
1706 if (lcfg->lcfg_command == LCFG_MARKER) {
1707 struct cfg_marker *marker;
1708 marker = lustre_cfg_buf(lcfg, 1);
1709 if (!strncmp(marker->cm_comment, "add osc", 7) &&
1710 (marker->cm_flags & CM_START) &&
1711 !(marker->cm_flags & CM_SKIP)) {
1712 got_an_osc_or_mdc = 1;
1713 cplen = strlcpy(tmti->mti_svname, marker->cm_tgtname,
1714 sizeof(tmti->mti_svname));
1715 if (cplen >= sizeof(tmti->mti_svname))
1717 rc = record_start_log(env, mgs, &mdt_llh,
1721 rc = record_marker(env, mdt_llh, fsdb, CM_START,
1722 mti->mti_svname, "add osc(copied)");
1723 record_end_log(env, &mdt_llh);
1724 last_step = marker->cm_step;
1727 if (!strncmp(marker->cm_comment, "add osc", 7) &&
1728 (marker->cm_flags & CM_END) &&
1729 !(marker->cm_flags & CM_SKIP)) {
1730 LASSERT(last_step == marker->cm_step);
1732 got_an_osc_or_mdc = 0;
1733 memset(tmti, 0, sizeof(*tmti));
1734 rc = record_start_log(env, mgs, &mdt_llh,
1738 rc = record_marker(env, mdt_llh, fsdb, CM_END,
1739 mti->mti_svname, "add osc(copied)");
1740 record_end_log(env, &mdt_llh);
1743 if (!strncmp(marker->cm_comment, "add mdc", 7) &&
1744 (marker->cm_flags & CM_START) &&
1745 !(marker->cm_flags & CM_SKIP)) {
1746 got_an_osc_or_mdc = 2;
1747 last_step = marker->cm_step;
1748 memcpy(tmti->mti_svname, marker->cm_tgtname,
1749 strlen(marker->cm_tgtname));
1753 if (!strncmp(marker->cm_comment, "add mdc", 7) &&
1754 (marker->cm_flags & CM_END) &&
1755 !(marker->cm_flags & CM_SKIP)) {
1756 LASSERT(last_step == marker->cm_step);
1758 got_an_osc_or_mdc = 0;
1759 memset(tmti, 0, sizeof(*tmti));
1764 if (got_an_osc_or_mdc == 0 || last_step < 0)
1767 if (lcfg->lcfg_command == LCFG_ADD_UUID) {
1768 __u64 nodenid = lcfg->lcfg_nid;
1770 if (strlen(tmti->mti_uuid) == 0) {
1771 /* target uuid not set, this config record is before
1772 * LCFG_SETUP, this nid is one of target node nid.
1774 tmti->mti_nids[tmti->mti_nid_count] = nodenid;
1775 tmti->mti_nid_count++;
1777 char nidstr[LNET_NIDSTR_SIZE];
1779 /* failover node nid */
1780 libcfs_nid2str_r(nodenid, nidstr, sizeof(nidstr));
1781 rc = add_param(tmti->mti_params, PARAM_FAILNODE,
1788 if (lcfg->lcfg_command == LCFG_SETUP) {
1791 target = lustre_cfg_string(lcfg, 1);
1792 memcpy(tmti->mti_uuid, target, strlen(target));
1796 /* ignore client side sptlrpc_conf_log */
1797 if (lcfg->lcfg_command == LCFG_SPTLRPC_CONF)
1800 if (lcfg->lcfg_command == LCFG_ADD_MDC) {
1803 if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1)
1806 memcpy(tmti->mti_fsname, mti->mti_fsname,
1807 strlen(mti->mti_fsname));
1808 tmti->mti_stripe_index = index;
1810 rc = mgs_write_log_osp_to_mdt(env, mgs, fsdb, tmti,
1811 mti->mti_stripe_index,
1813 memset(tmti, 0, sizeof(*tmti));
1817 if (lcfg->lcfg_command == LCFG_LOV_ADD_OBD) {
1820 char *logname, *lovname;
1822 rc = name_create_mdt_and_lov(&logname, &lovname, fsdb,
1823 mti->mti_stripe_index);
1826 sprintf(mdt_index, "-MDT%04x", mti->mti_stripe_index);
1828 if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1) {
1829 name_destroy(&logname);
1830 name_destroy(&lovname);
1834 tmti->mti_stripe_index = index;
1835 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, tmti, logname,
1838 name_destroy(&logname);
1839 name_destroy(&lovname);
1845 /* fsdb->fsdb_mutex is already held in mgs_write_log_target*/
1846 /* stealed from mgs_get_fsdb_from_llog*/
1847 static int mgs_steal_llog_for_mdt_from_client(const struct lu_env *env,
1848 struct mgs_device *mgs,
1850 struct temp_comp* comp)
1852 struct llog_handle *loghandle;
1853 struct mgs_target_info *tmti;
1854 struct llog_ctxt *ctxt;
1859 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
1860 LASSERT(ctxt != NULL);
1862 OBD_ALLOC_PTR(tmti);
1864 GOTO(out_ctxt, rc = -ENOMEM);
1866 comp->comp_tmti = tmti;
1867 comp->comp_obd = mgs->mgs_obd;
1869 rc = llog_open(env, ctxt, &loghandle, NULL, client_name,
1877 rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL);
1879 GOTO(out_close, rc);
1881 rc = llog_process_or_fork(env, loghandle, mgs_steal_client_llog_handler,
1882 (void *)comp, NULL, false);
1883 CDEBUG(D_MGS, "steal llog re = %d\n", rc);
1885 llog_close(env, loghandle);
1889 llog_ctxt_put(ctxt);
1893 /* lmv is the second thing for client logs */
1894 /* copied from mgs_write_log_lov. Please refer to that. */
1895 static int mgs_write_log_lmv(const struct lu_env *env,
1896 struct mgs_device *mgs,
1898 struct mgs_target_info *mti,
1899 char *logname, char *lmvname)
1901 struct llog_handle *llh = NULL;
1902 struct lmv_desc *lmvdesc;
1907 CDEBUG(D_MGS, "Writing lmv(%s) log for %s\n", lmvname,logname);
1909 OBD_ALLOC_PTR(lmvdesc);
1910 if (lmvdesc == NULL)
1912 lmvdesc->ld_active_tgt_count = 0;
1913 lmvdesc->ld_tgt_count = 0;
1914 sprintf((char*)lmvdesc->ld_uuid.uuid, "%s_UUID", lmvname);
1915 uuid = (char *)lmvdesc->ld_uuid.uuid;
1917 rc = record_start_log(env, mgs, &llh, logname);
1920 rc = record_marker(env, llh, fsdb, CM_START, lmvname, "lmv setup");
1923 rc = record_attach(env, llh, lmvname, "lmv", uuid);
1926 rc = record_lmv_setup(env, llh, lmvname, lmvdesc);
1929 rc = record_marker(env, llh, fsdb, CM_END, lmvname, "lmv setup");
1933 record_end_log(env, &llh);
1935 OBD_FREE_PTR(lmvdesc);
1939 /* lov is the first thing in the mdt and client logs */
1940 static int mgs_write_log_lov(const struct lu_env *env, struct mgs_device *mgs,
1941 struct fs_db *fsdb, struct mgs_target_info *mti,
1942 char *logname, char *lovname)
1944 struct llog_handle *llh = NULL;
1945 struct lov_desc *lovdesc;
1950 CDEBUG(D_MGS, "Writing lov(%s) log for %s\n", lovname, logname);
1953 #01 L attach 0:lov_mdsA 1:lov 2:71ccb_lov_mdsA_19f961a9e1
1954 #02 L lov_setup 0:lov_mdsA 1:(struct lov_desc)
1955 uuid=lov1_UUID, stripe count=1, size=1048576, offset=0, pattern=0
1958 /* FIXME just make lov_setup accept empty desc (put uuid in buf 2) */
1959 OBD_ALLOC_PTR(lovdesc);
1960 if (lovdesc == NULL)
1962 lovdesc->ld_magic = LOV_DESC_MAGIC;
1963 lovdesc->ld_tgt_count = 0;
1964 /* Defaults. Can be changed later by lcfg config_param */
1965 lovdesc->ld_default_stripe_count = 1;
1966 lovdesc->ld_pattern = LOV_PATTERN_RAID0;
1967 lovdesc->ld_default_stripe_size = LOV_DESC_STRIPE_SIZE_DEFAULT;
1968 lovdesc->ld_default_stripe_offset = -1;
1969 lovdesc->ld_qos_maxage = LOV_DESC_QOS_MAXAGE_DEFAULT;
1970 sprintf((char*)lovdesc->ld_uuid.uuid, "%s_UUID", lovname);
1971 /* can these be the same? */
1972 uuid = (char *)lovdesc->ld_uuid.uuid;
1974 /* This should always be the first entry in a log.
1975 rc = mgs_clear_log(obd, logname); */
1976 rc = record_start_log(env, mgs, &llh, logname);
1979 /* FIXME these should be a single journal transaction */
1980 rc = record_marker(env, llh, fsdb, CM_START, lovname, "lov setup");
1983 rc = record_attach(env, llh, lovname, "lov", uuid);
1986 rc = record_lov_setup(env, llh, lovname, lovdesc);
1989 rc = record_marker(env, llh, fsdb, CM_END, lovname, "lov setup");
1994 record_end_log(env, &llh);
1996 OBD_FREE_PTR(lovdesc);
2000 /* add failnids to open log */
2001 static int mgs_write_log_failnids(const struct lu_env *env,
2002 struct mgs_target_info *mti,
2003 struct llog_handle *llh,
2006 char *failnodeuuid = NULL;
2007 char *ptr = mti->mti_params;
2012 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) nal=90 0: 1:uml1_UUID
2013 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
2014 #05 L setup 0:OSC_uml1_ost1_mdsA 1:ost1_UUID 2:uml1_UUID
2015 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) nal=90 0: 1:uml2_UUID
2016 #0x L add_uuid nid=2@elan(0x1000000000002) nal=90 0: 1:uml2_UUID
2017 #07 L add_conn 0:OSC_uml1_ost1_mdsA 1:uml2_UUID
2021 * Pull failnid info out of params string, which may contain something
2022 * like "<nid1>,<nid2>:<nid3>,<nid4>". class_parse_nid() does not
2023 * complain about abnormal inputs like ",:<nid1>", "<nid1>:,<nid2>",
2024 * etc. However, convert_hostnames() should have caught those.
2026 while (class_find_param(ptr, PARAM_FAILNODE, &ptr) == 0) {
2027 while (class_parse_nid(ptr, &nid, &ptr) == 0) {
2028 char nidstr[LNET_NIDSTR_SIZE];
2030 if (failnodeuuid == NULL) {
2031 /* We don't know the failover node name,
2032 * so just use the first nid as the uuid */
2033 libcfs_nid2str_r(nid, nidstr, sizeof(nidstr));
2034 rc = name_create(&failnodeuuid, nidstr, "");
2038 CDEBUG(D_MGS, "add nid %s for failover uuid %s, "
2040 libcfs_nid2str_r(nid, nidstr, sizeof(nidstr)),
2041 failnodeuuid, cliname);
2042 rc = record_add_uuid(env, llh, nid, failnodeuuid);
2044 * If *ptr is ':', we have added all NIDs for
2048 rc = record_add_conn(env, llh, cliname,
2050 name_destroy(&failnodeuuid);
2051 failnodeuuid = NULL;
2055 rc = record_add_conn(env, llh, cliname, failnodeuuid);
2056 name_destroy(&failnodeuuid);
2057 failnodeuuid = NULL;
2064 static int mgs_write_log_mdc_to_lmv(const struct lu_env *env,
2065 struct mgs_device *mgs,
2067 struct mgs_target_info *mti,
2068 char *logname, char *lmvname)
2070 struct llog_handle *llh = NULL;
2071 char *mdcname = NULL;
2072 char *nodeuuid = NULL;
2073 char *mdcuuid = NULL;
2074 char *lmvuuid = NULL;
2076 char nidstr[LNET_NIDSTR_SIZE];
2080 if (mgs_log_is_empty(env, mgs, logname)) {
2081 CERROR("log is empty! Logical error\n");
2085 CDEBUG(D_MGS, "adding mdc for %s to log %s:lmv(%s)\n",
2086 mti->mti_svname, logname, lmvname);
2088 libcfs_nid2str_r(mti->mti_nids[0], nidstr, sizeof(nidstr));
2089 rc = name_create(&nodeuuid, nidstr, "");
2092 rc = name_create(&mdcname, mti->mti_svname, "-mdc");
2095 rc = name_create(&mdcuuid, mdcname, "_UUID");
2098 rc = name_create(&lmvuuid, lmvname, "_UUID");
2102 rc = record_start_log(env, mgs, &llh, logname);
2105 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
2109 for (i = 0; i < mti->mti_nid_count; i++) {
2110 CDEBUG(D_MGS, "add nid %s for mdt\n",
2111 libcfs_nid2str_r(mti->mti_nids[i],
2112 nidstr, sizeof(nidstr)));
2114 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
2119 rc = record_attach(env, llh, mdcname, LUSTRE_MDC_NAME, lmvuuid);
2122 rc = record_setup(env, llh, mdcname, mti->mti_uuid, nodeuuid,
2126 rc = mgs_write_log_failnids(env, mti, llh, mdcname);
2129 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
2130 rc = record_mdc_add(env, llh, lmvname, mdcuuid, mti->mti_uuid,
2134 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname,
2139 record_end_log(env, &llh);
2141 name_destroy(&lmvuuid);
2142 name_destroy(&mdcuuid);
2143 name_destroy(&mdcname);
2144 name_destroy(&nodeuuid);
2148 static inline int name_create_lov(char **lovname, char *mdtname,
2149 struct fs_db *fsdb, int index)
2152 if (index == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2153 return name_create(lovname, fsdb->fsdb_name, "-mdtlov");
2155 return name_create(lovname, mdtname, "-mdtlov");
2158 static int name_create_mdt_and_lov(char **logname, char **lovname,
2159 struct fs_db *fsdb, int i)
2163 rc = name_create_mdt(logname, fsdb->fsdb_name, i);
2167 if (i == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2168 rc = name_create(lovname, fsdb->fsdb_name, "-mdtlov");
2170 rc = name_create(lovname, *logname, "-mdtlov");
2172 name_destroy(logname);
2178 static inline int name_create_mdt_osc(char **oscname, char *ostname,
2179 struct fs_db *fsdb, int i)
2183 if (i == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2184 sprintf(suffix, "-osc");
2186 sprintf(suffix, "-osc-MDT%04x", i);
2187 return name_create(oscname, ostname, suffix);
2190 /* add new mdc to already existent MDS */
2191 static int mgs_write_log_osp_to_mdt(const struct lu_env *env,
2192 struct mgs_device *mgs,
2194 struct mgs_target_info *mti,
2195 int mdt_index, char *logname)
2197 struct llog_handle *llh = NULL;
2198 char *nodeuuid = NULL;
2199 char *ospname = NULL;
2200 char *lovuuid = NULL;
2201 char *mdtuuid = NULL;
2202 char *svname = NULL;
2203 char *mdtname = NULL;
2204 char *lovname = NULL;
2206 char nidstr[LNET_NIDSTR_SIZE];
2210 if (mgs_log_is_empty(env, mgs, mti->mti_svname)) {
2211 CERROR("log is empty! Logical error\n");
2215 CDEBUG(D_MGS, "adding osp index %d to %s\n", mti->mti_stripe_index,
2218 rc = name_create_mdt(&mdtname, fsdb->fsdb_name, mti->mti_stripe_index);
2222 libcfs_nid2str_r(mti->mti_nids[0], nidstr, sizeof(nidstr));
2223 rc = name_create(&nodeuuid, nidstr, "");
2225 GOTO(out_destory, rc);
2227 rc = name_create(&svname, mdtname, "-osp");
2229 GOTO(out_destory, rc);
2231 sprintf(index_str, "-MDT%04x", mdt_index);
2232 rc = name_create(&ospname, svname, index_str);
2234 GOTO(out_destory, rc);
2236 rc = name_create_lov(&lovname, logname, fsdb, mdt_index);
2238 GOTO(out_destory, rc);
2240 rc = name_create(&lovuuid, lovname, "_UUID");
2242 GOTO(out_destory, rc);
2244 rc = name_create(&mdtuuid, mdtname, "_UUID");
2246 GOTO(out_destory, rc);
2248 rc = record_start_log(env, mgs, &llh, logname);
2250 GOTO(out_destory, rc);
2252 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
2255 GOTO(out_destory, rc);
2257 for (i = 0; i < mti->mti_nid_count; i++) {
2258 CDEBUG(D_MGS, "add nid %s for mdt\n",
2259 libcfs_nid2str_r(mti->mti_nids[i],
2260 nidstr, sizeof(nidstr)));
2261 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
2266 rc = record_attach(env, llh, ospname, LUSTRE_OSP_NAME, lovuuid);
2270 rc = record_setup(env, llh, ospname, mti->mti_uuid, nodeuuid,
2275 rc = mgs_write_log_failnids(env, mti, llh, ospname);
2279 /* Add mdc(osp) to lod */
2280 snprintf(index_str, sizeof(index_str), "%d", mti->mti_stripe_index);
2281 rc = record_base(env, llh, lovname, 0, LCFG_ADD_MDC, mti->mti_uuid,
2282 index_str, "1", NULL);
2286 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname, "add osp");
2291 record_end_log(env, &llh);
2294 name_destroy(&mdtuuid);
2295 name_destroy(&lovuuid);
2296 name_destroy(&lovname);
2297 name_destroy(&ospname);
2298 name_destroy(&svname);
2299 name_destroy(&nodeuuid);
2300 name_destroy(&mdtname);
2304 static int mgs_write_log_mdt0(const struct lu_env *env,
2305 struct mgs_device *mgs,
2307 struct mgs_target_info *mti)
2309 char *log = mti->mti_svname;
2310 struct llog_handle *llh = NULL;
2311 char *uuid, *lovname;
2313 char *ptr = mti->mti_params;
2314 int rc = 0, failout = 0;
2317 OBD_ALLOC(uuid, sizeof(struct obd_uuid));
2321 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
2322 failout = (strncmp(ptr, "failout", 7) == 0);
2324 rc = name_create(&lovname, log, "-mdtlov");
2327 if (mgs_log_is_empty(env, mgs, log)) {
2328 rc = mgs_write_log_lov(env, mgs, fsdb, mti, log, lovname);
2333 sprintf(mdt_index, "%d", mti->mti_stripe_index);
2335 rc = record_start_log(env, mgs, &llh, log);
2339 /* add MDT itself */
2341 /* FIXME this whole fn should be a single journal transaction */
2342 sprintf(uuid, "%s_UUID", log);
2343 rc = record_marker(env, llh, fsdb, CM_START, log, "add mdt");
2346 rc = record_attach(env, llh, log, LUSTRE_MDT_NAME, uuid);
2349 rc = record_mount_opt(env, llh, log, lovname, NULL);
2352 rc = record_setup(env, llh, log, uuid, mdt_index, lovname,
2353 failout ? "n" : "f");
2356 rc = record_marker(env, llh, fsdb, CM_END, log, "add mdt");
2360 record_end_log(env, &llh);
2362 name_destroy(&lovname);
2364 OBD_FREE(uuid, sizeof(struct obd_uuid));
2368 /* envelope method for all layers log */
2369 static int mgs_write_log_mdt(const struct lu_env *env,
2370 struct mgs_device *mgs,
2372 struct mgs_target_info *mti)
2374 struct mgs_thread_info *mgi = mgs_env_info(env);
2375 struct llog_handle *llh = NULL;
2380 CDEBUG(D_MGS, "writing new mdt %s\n", mti->mti_svname);
2382 if (mti->mti_uuid[0] == '\0') {
2383 /* Make up our own uuid */
2384 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
2385 "%s_UUID", mti->mti_svname);
2389 rc = mgs_write_log_mdt0(env, mgs, fsdb, mti);
2392 /* Append the mdt info to the client log */
2393 rc = name_create(&cliname, mti->mti_fsname, "-client");
2397 if (mgs_log_is_empty(env, mgs, cliname)) {
2398 /* Start client log */
2399 rc = mgs_write_log_lov(env, mgs, fsdb, mti, cliname,
2403 rc = mgs_write_log_lmv(env, mgs, fsdb, mti, cliname,
2410 #09 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
2411 #10 L attach 0:MDC_uml1_mdsA_MNT_client 1:mdc 2:1d834_MNT_client_03f
2412 #11 L setup 0:MDC_uml1_mdsA_MNT_client 1:mdsA_UUID 2:uml1_UUID
2413 #12 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
2414 #13 L add_conn 0:MDC_uml1_mdsA_MNT_client 1:uml2_UUID
2415 #14 L mount_option 0: 1:client 2:lov1 3:MDC_uml1_mdsA_MNT_client
2418 /* copy client info about lov/lmv */
2419 mgi->mgi_comp.comp_mti = mti;
2420 mgi->mgi_comp.comp_fsdb = fsdb;
2422 rc = mgs_steal_llog_for_mdt_from_client(env, mgs, cliname,
2426 rc = mgs_write_log_mdc_to_lmv(env, mgs, fsdb, mti, cliname,
2432 rc = record_start_log(env, mgs, &llh, cliname);
2436 rc = record_marker(env, llh, fsdb, CM_START, cliname,
2440 rc = record_mount_opt(env, llh, cliname, fsdb->fsdb_clilov,
2444 rc = record_marker(env, llh, fsdb, CM_END, cliname,
2450 /* for_all_existing_mdt except current one */
2451 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2452 if (i != mti->mti_stripe_index &&
2453 test_bit(i, fsdb->fsdb_mdt_index_map)) {
2456 rc = name_create_mdt(&logname, fsdb->fsdb_name, i);
2460 /* NB: If the log for the MDT is empty, it means
2461 * the MDT is only added to the index
2462 * map, and not being process yet, i.e. this
2463 * is an unregistered MDT, see mgs_write_log_target().
2464 * so we should skip it. Otherwise
2466 * 1. MGS get register request for MDT1 and MDT2.
2468 * 2. Then both MDT1 and MDT2 are added into
2469 * fsdb_mdt_index_map. (see mgs_set_index()).
2471 * 3. Then MDT1 get the lock of fsdb_mutex, then
2472 * generate the config log, here, it will regard MDT2
2473 * as an existent MDT, and generate "add osp" for
2474 * lustre-MDT0001-osp-MDT0002. Note: at the moment
2475 * MDT0002 config log is still empty, so it will
2476 * add "add osp" even before "lov setup", which
2477 * will definitly cause trouble.
2479 * 4. MDT1 registeration finished, fsdb_mutex is
2480 * released, then MDT2 get in, then in above
2481 * mgs_steal_llog_for_mdt_from_client(), it will
2482 * add another osp log for lustre-MDT0001-osp-MDT0002,
2483 * which will cause another trouble.*/
2484 if (!mgs_log_is_empty(env, mgs, logname))
2485 rc = mgs_write_log_osp_to_mdt(env, mgs, fsdb,
2488 name_destroy(&logname);
2494 record_end_log(env, &llh);
2496 name_destroy(&cliname);
2500 /* Add the ost info to the client/mdt lov */
2501 static int mgs_write_log_osc_to_lov(const struct lu_env *env,
2502 struct mgs_device *mgs, struct fs_db *fsdb,
2503 struct mgs_target_info *mti,
2504 char *logname, char *suffix, char *lovname,
2505 enum lustre_sec_part sec_part, int flags)
2507 struct llog_handle *llh = NULL;
2508 char *nodeuuid = NULL;
2509 char *oscname = NULL;
2510 char *oscuuid = NULL;
2511 char *lovuuid = NULL;
2512 char *svname = NULL;
2514 char nidstr[LNET_NIDSTR_SIZE];
2518 CDEBUG(D_INFO, "adding osc for %s to log %s\n",
2519 mti->mti_svname, logname);
2521 if (mgs_log_is_empty(env, mgs, logname)) {
2522 CERROR("log is empty! Logical error\n");
2526 libcfs_nid2str_r(mti->mti_nids[0], nidstr, sizeof(nidstr));
2527 rc = name_create(&nodeuuid, nidstr, "");
2530 rc = name_create(&svname, mti->mti_svname, "-osc");
2534 /* for the system upgraded from old 1.8, keep using the old osc naming
2535 * style for mdt, see name_create_mdt_osc(). LU-1257 */
2536 if (test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2537 rc = name_create(&oscname, svname, "");
2539 rc = name_create(&oscname, svname, suffix);
2543 rc = name_create(&oscuuid, oscname, "_UUID");
2546 rc = name_create(&lovuuid, lovname, "_UUID");
2552 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
2554 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
2555 #04 L attach 0:OSC_uml1_ost1_MNT_client 1:osc 2:89070_lov1_a41dff51a
2556 #05 L setup 0:OSC_uml1_ost1_MNT_client 1:ost1_UUID 2:uml1_UUID
2558 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
2559 #07 L add_conn 0:OSC_uml1_ost1_MNT_client 1:uml2_UUID
2560 #08 L lov_modify_tgts add 0:lov1 1:ost1_UUID 2(index):0 3(gen):1
2563 rc = record_start_log(env, mgs, &llh, logname);
2567 /* FIXME these should be a single journal transaction */
2568 rc = record_marker(env, llh, fsdb, CM_START | flags, mti->mti_svname,
2573 /* NB: don't change record order, because upon MDT steal OSC config
2574 * from client, it treats all nids before LCFG_SETUP as target nids
2575 * (multiple interfaces), while nids after as failover node nids.
2576 * See mgs_steal_client_llog_handler() LCFG_ADD_UUID.
2578 for (i = 0; i < mti->mti_nid_count; i++) {
2579 CDEBUG(D_MGS, "add nid %s\n",
2580 libcfs_nid2str_r(mti->mti_nids[i],
2581 nidstr, sizeof(nidstr)));
2582 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
2586 rc = record_attach(env, llh, oscname, LUSTRE_OSC_NAME, lovuuid);
2589 rc = record_setup(env, llh, oscname, mti->mti_uuid, nodeuuid,
2593 rc = mgs_write_log_failnids(env, mti, llh, oscname);
2597 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
2599 rc = record_lov_add(env, llh, lovname, mti->mti_uuid, index, "1");
2602 rc = record_marker(env, llh, fsdb, CM_END | flags, mti->mti_svname,
2607 record_end_log(env, &llh);
2609 name_destroy(&lovuuid);
2610 name_destroy(&oscuuid);
2611 name_destroy(&oscname);
2612 name_destroy(&svname);
2613 name_destroy(&nodeuuid);
2617 static int mgs_write_log_ost(const struct lu_env *env,
2618 struct mgs_device *mgs, struct fs_db *fsdb,
2619 struct mgs_target_info *mti)
2621 struct llog_handle *llh = NULL;
2622 char *logname, *lovname;
2623 char *ptr = mti->mti_params;
2624 int rc, flags = 0, failout = 0, i;
2627 CDEBUG(D_MGS, "writing new ost %s\n", mti->mti_svname);
2629 /* The ost startup log */
2631 /* If the ost log already exists, that means that someone reformatted
2632 the ost and it called target_add again. */
2633 if (!mgs_log_is_empty(env, mgs, mti->mti_svname)) {
2634 LCONSOLE_ERROR_MSG(0x141, "The config log for %s already "
2635 "exists, yet the server claims it never "
2636 "registered. It may have been reformatted, "
2637 "or the index changed. writeconf the MDT to "
2638 "regenerate all logs.\n", mti->mti_svname);
2643 attach obdfilter ost1 ost1_UUID
2644 setup /dev/loop2 ldiskfs f|n errors=remount-ro,user_xattr
2646 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
2647 failout = (strncmp(ptr, "failout", 7) == 0);
2648 rc = record_start_log(env, mgs, &llh, mti->mti_svname);
2651 /* FIXME these should be a single journal transaction */
2652 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,"add ost");
2655 if (*mti->mti_uuid == '\0')
2656 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
2657 "%s_UUID", mti->mti_svname);
2658 rc = record_attach(env, llh, mti->mti_svname,
2659 "obdfilter"/*LUSTRE_OST_NAME*/, mti->mti_uuid);
2662 rc = record_setup(env, llh, mti->mti_svname,
2663 "dev"/*ignored*/, "type"/*ignored*/,
2664 failout ? "n" : "f", NULL/*options*/);
2667 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname, "add ost");
2671 record_end_log(env, &llh);
2674 /* We also have to update the other logs where this osc is part of
2677 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
2678 /* If we're upgrading, the old mdt log already has our
2679 entry. Let's do a fake one for fun. */
2680 /* Note that we can't add any new failnids, since we don't
2681 know the old osc names. */
2682 flags = CM_SKIP | CM_UPGRADE146;
2684 } else if ((mti->mti_flags & LDD_F_UPDATE) != LDD_F_UPDATE) {
2685 /* If the update flag isn't set, don't update client/mdt
2688 LCONSOLE_WARN("Client log for %s was not updated; writeconf "
2689 "the MDT first to regenerate it.\n",
2693 /* Add ost to all MDT lov defs */
2694 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
2695 if (test_bit(i, fsdb->fsdb_mdt_index_map)) {
2698 rc = name_create_mdt_and_lov(&logname, &lovname, fsdb,
2702 sprintf(mdt_index, "-MDT%04x", i);
2703 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, mti,
2705 lovname, LUSTRE_SP_MDT,
2707 name_destroy(&logname);
2708 name_destroy(&lovname);
2714 /* Append ost info to the client log */
2715 rc = name_create(&logname, mti->mti_fsname, "-client");
2718 if (mgs_log_is_empty(env, mgs, logname)) {
2719 /* Start client log */
2720 rc = mgs_write_log_lov(env, mgs, fsdb, mti, logname,
2724 rc = mgs_write_log_lmv(env, mgs, fsdb, mti, logname,
2729 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, mti, logname, "",
2730 fsdb->fsdb_clilov, LUSTRE_SP_CLI, flags);
2732 name_destroy(&logname);
2736 static __inline__ int mgs_param_empty(char *ptr)
2740 if ((tmp = strchr(ptr, '=')) && (*(++tmp) == '\0'))
2745 static int mgs_write_log_failnid_internal(const struct lu_env *env,
2746 struct mgs_device *mgs,
2748 struct mgs_target_info *mti,
2749 char *logname, char *cliname)
2752 struct llog_handle *llh = NULL;
2754 if (mgs_param_empty(mti->mti_params)) {
2755 /* Remove _all_ failnids */
2756 rc = mgs_modify(env, mgs, fsdb, mti, logname,
2757 mti->mti_svname, "add failnid", CM_SKIP);
2758 return rc < 0 ? rc : 0;
2761 /* Otherwise failover nids are additive */
2762 rc = record_start_log(env, mgs, &llh, logname);
2765 /* FIXME this should be a single journal transaction */
2766 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
2770 rc = mgs_write_log_failnids(env, mti, llh, cliname);
2773 rc = record_marker(env, llh, fsdb, CM_END,
2774 mti->mti_svname, "add failnid");
2776 record_end_log(env, &llh);
2781 /* Add additional failnids to an existing log.
2782 The mdc/osc must have been added to logs first */
2783 /* tcp nids must be in dotted-quad ascii -
2784 we can't resolve hostnames from the kernel. */
2785 static int mgs_write_log_add_failnid(const struct lu_env *env,
2786 struct mgs_device *mgs,
2788 struct mgs_target_info *mti)
2790 char *logname, *cliname;
2794 /* FIXME we currently can't erase the failnids
2795 * given when a target first registers, since they aren't part of
2796 * an "add uuid" stanza */
2798 /* Verify that we know about this target */
2799 if (mgs_log_is_empty(env, mgs, mti->mti_svname)) {
2800 LCONSOLE_ERROR_MSG(0x142, "The target %s has not registered "
2801 "yet. It must be started before failnids "
2802 "can be added.\n", mti->mti_svname);
2806 /* Create mdc/osc client name (e.g. lustre-OST0001-osc) */
2807 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
2808 rc = name_create(&cliname, mti->mti_svname, "-mdc");
2809 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2810 rc = name_create(&cliname, mti->mti_svname, "-osc");
2816 /* Add failover nids to the client log */
2817 rc = name_create(&logname, mti->mti_fsname, "-client");
2819 name_destroy(&cliname);
2822 rc = mgs_write_log_failnid_internal(env, mgs, fsdb,mti,logname,cliname);
2823 name_destroy(&logname);
2824 name_destroy(&cliname);
2828 if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2829 /* Add OST failover nids to the MDT logs as well */
2832 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2833 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
2835 rc = name_create_mdt(&logname, mti->mti_fsname, i);
2838 rc = name_create_mdt_osc(&cliname, mti->mti_svname,
2841 name_destroy(&logname);
2844 rc = mgs_write_log_failnid_internal(env, mgs, fsdb,
2847 name_destroy(&cliname);
2848 name_destroy(&logname);
2857 static int mgs_wlp_lcfg(const struct lu_env *env,
2858 struct mgs_device *mgs, struct fs_db *fsdb,
2859 struct mgs_target_info *mti,
2860 char *logname, struct lustre_cfg_bufs *bufs,
2861 char *tgtname, char *ptr)
2863 char comment[MTI_NAME_MAXLEN];
2865 struct llog_cfg_rec *lcr;
2868 /* Erase any old settings of this same parameter */
2869 memcpy(comment, ptr, MTI_NAME_MAXLEN);
2870 comment[MTI_NAME_MAXLEN - 1] = 0;
2871 /* But don't try to match the value. */
2872 tmp = strchr(comment, '=');
2875 /* FIXME we should skip settings that are the same as old values */
2876 rc = mgs_modify(env, mgs, fsdb, mti, logname, tgtname, comment,CM_SKIP);
2879 del = mgs_param_empty(ptr);
2881 LCONSOLE_INFO("%s parameter %s.%s in log %s\n", del ? "Disabling" : rc ?
2882 "Setting" : "Modifying", tgtname, comment, logname);
2884 /* mgs_modify() will return 1 if nothing had to be done */
2890 lustre_cfg_bufs_reset(bufs, tgtname);
2891 lustre_cfg_bufs_set_string(bufs, 1, ptr);
2892 if (mti->mti_flags & LDD_F_PARAM2)
2893 lustre_cfg_bufs_set_string(bufs, 2, LCTL_UPCALL);
2895 lcr = lustre_cfg_rec_new((mti->mti_flags & LDD_F_PARAM2) ?
2896 LCFG_SET_PARAM : LCFG_PARAM, bufs);
2900 rc = mgs_write_log_direct(env, mgs, fsdb, logname, lcr, tgtname,
2902 lustre_cfg_rec_free(lcr);
2906 static int mgs_write_log_param2(const struct lu_env *env,
2907 struct mgs_device *mgs,
2909 struct mgs_target_info *mti, char *ptr)
2911 struct lustre_cfg_bufs bufs;
2915 CDEBUG(D_MGS, "next param '%s'\n", ptr);
2916 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, PARAMS_FILENAME, &bufs,
2917 mti->mti_svname, ptr);
2922 /* write global variable settings into log */
2923 static int mgs_write_log_sys(const struct lu_env *env,
2924 struct mgs_device *mgs, struct fs_db *fsdb,
2925 struct mgs_target_info *mti, char *sys, char *ptr)
2927 struct mgs_thread_info *mgi = mgs_env_info(env);
2928 struct lustre_cfg *lcfg;
2929 struct llog_cfg_rec *lcr;
2931 int rc, cmd, convert = 1;
2933 if (class_match_param(ptr, PARAM_TIMEOUT, &tmp) == 0) {
2934 cmd = LCFG_SET_TIMEOUT;
2935 } else if (class_match_param(ptr, PARAM_LDLM_TIMEOUT, &tmp) == 0) {
2936 cmd = LCFG_SET_LDLM_TIMEOUT;
2937 /* Check for known params here so we can return error to lctl */
2938 } else if ((class_match_param(ptr, PARAM_AT_MIN, &tmp) == 0) ||
2939 (class_match_param(ptr, PARAM_AT_MAX, &tmp) == 0) ||
2940 (class_match_param(ptr, PARAM_AT_EXTRA, &tmp) == 0) ||
2941 (class_match_param(ptr, PARAM_AT_EARLY_MARGIN, &tmp) == 0) ||
2942 (class_match_param(ptr, PARAM_AT_HISTORY, &tmp) == 0)) {
2944 } else if (class_match_param(ptr, PARAM_JOBID_VAR, &tmp) == 0) {
2945 convert = 0; /* Don't convert string value to integer */
2951 if (mgs_param_empty(ptr))
2952 CDEBUG(D_MGS, "global '%s' removed\n", sys);
2954 CDEBUG(D_MGS, "global '%s' val=%s\n", sys, tmp);
2956 lustre_cfg_bufs_reset(&mgi->mgi_bufs, NULL);
2957 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, sys);
2958 if (!convert && *tmp != '\0')
2959 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 2, tmp);
2960 lcr = lustre_cfg_rec_new(cmd, &mgi->mgi_bufs);
2964 lcfg = &lcr->lcr_cfg;
2965 lcfg->lcfg_num = convert ? simple_strtoul(tmp, NULL, 0) : 0;
2966 /* truncate the comment to the parameter name */
2970 /* modify all servers and clients */
2971 rc = mgs_write_log_direct_all(env, mgs, fsdb, mti,
2972 *tmp == '\0' ? NULL : lcr,
2973 mti->mti_fsname, sys, 0);
2974 if (rc == 0 && *tmp != '\0') {
2976 case LCFG_SET_TIMEOUT:
2977 if (!obd_timeout_set || lcfg->lcfg_num > obd_timeout)
2978 class_process_config(lcfg);
2980 case LCFG_SET_LDLM_TIMEOUT:
2981 if (!ldlm_timeout_set || lcfg->lcfg_num > ldlm_timeout)
2982 class_process_config(lcfg);
2989 lustre_cfg_rec_free(lcr);
2993 /* write quota settings into log */
2994 static int mgs_write_log_quota(const struct lu_env *env, struct mgs_device *mgs,
2995 struct fs_db *fsdb, struct mgs_target_info *mti,
2996 char *quota, char *ptr)
2998 struct mgs_thread_info *mgi = mgs_env_info(env);
2999 struct llog_cfg_rec *lcr;
3002 int rc, cmd = LCFG_PARAM;
3004 /* support only 'meta' and 'data' pools so far */
3005 if (class_match_param(ptr, QUOTA_METAPOOL_NAME, &tmp) != 0 &&
3006 class_match_param(ptr, QUOTA_DATAPOOL_NAME, &tmp) != 0) {
3007 CERROR("parameter quota.%s isn't supported (only quota.mdt "
3008 "& quota.ost are)\n", ptr);
3013 CDEBUG(D_MGS, "global '%s' removed\n", quota);
3015 CDEBUG(D_MGS, "global '%s'\n", quota);
3017 if (strchr(tmp, 'u') == NULL && strchr(tmp, 'g') == NULL &&
3018 strcmp(tmp, "none") != 0) {
3019 CERROR("enable option(%s) isn't supported\n", tmp);
3024 lustre_cfg_bufs_reset(&mgi->mgi_bufs, mti->mti_fsname);
3025 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, quota);
3026 lcr = lustre_cfg_rec_new(cmd, &mgi->mgi_bufs);
3030 /* truncate the comment to the parameter name */
3035 /* XXX we duplicated quota enable information in all server
3036 * config logs, it should be moved to a separate config
3037 * log once we cleanup the config log for global param. */
3038 /* modify all servers */
3039 rc = mgs_write_log_direct_all(env, mgs, fsdb, mti,
3040 *tmp == '\0' ? NULL : lcr,
3041 mti->mti_fsname, quota, 1);
3043 lustre_cfg_rec_free(lcr);
3044 return rc < 0 ? rc : 0;
3047 static int mgs_srpc_set_param_disk(const struct lu_env *env,
3048 struct mgs_device *mgs,
3050 struct mgs_target_info *mti,
3053 struct mgs_thread_info *mgi = mgs_env_info(env);
3054 struct llog_cfg_rec *lcr;
3055 struct llog_handle *llh = NULL;
3057 char *comment, *ptr;
3063 ptr = strchr(param, '=');
3064 LASSERT(ptr != NULL);
3067 OBD_ALLOC(comment, len + 1);
3068 if (comment == NULL)
3070 strncpy(comment, param, len);
3071 comment[len] = '\0';
3074 lustre_cfg_bufs_reset(&mgi->mgi_bufs, mti->mti_svname);
3075 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, param);
3076 lcr = lustre_cfg_rec_new(LCFG_SPTLRPC_CONF, &mgi->mgi_bufs);
3078 GOTO(out_comment, rc = -ENOMEM);
3080 /* construct log name */
3081 rc = name_create(&logname, mti->mti_fsname, "-sptlrpc");
3085 if (mgs_log_is_empty(env, mgs, logname)) {
3086 rc = record_start_log(env, mgs, &llh, logname);
3089 record_end_log(env, &llh);
3092 /* obsolete old one */
3093 rc = mgs_modify(env, mgs, fsdb, mti, logname, mti->mti_svname,
3097 /* write the new one */
3098 rc = mgs_write_log_direct(env, mgs, fsdb, logname, lcr,
3099 mti->mti_svname, comment);
3101 CERROR("%s: error writing log %s: rc = %d\n",
3102 mgs->mgs_obd->obd_name, logname, rc);
3104 name_destroy(&logname);
3106 lustre_cfg_rec_free(lcr);
3108 OBD_FREE(comment, len + 1);
3112 static int mgs_srpc_set_param_udesc_mem(struct fs_db *fsdb,
3117 /* disable the adjustable udesc parameter for now, i.e. use default
3118 * setting that client always ship udesc to MDT if possible. to enable
3119 * it simply remove the following line */
3122 ptr = strchr(param, '=');
3127 if (strcmp(param, PARAM_SRPC_UDESC))
3130 if (strcmp(ptr, "yes") == 0) {
3131 set_bit(FSDB_UDESC, &fsdb->fsdb_flags);
3132 CWARN("Enable user descriptor shipping from client to MDT\n");
3133 } else if (strcmp(ptr, "no") == 0) {
3134 clear_bit(FSDB_UDESC, &fsdb->fsdb_flags);
3135 CWARN("Disable user descriptor shipping from client to MDT\n");
3143 CERROR("Invalid param: %s\n", param);
3147 static int mgs_srpc_set_param_mem(struct fs_db *fsdb,
3151 struct sptlrpc_rule rule;
3152 struct sptlrpc_rule_set *rset;
3156 if (strncmp(param, PARAM_SRPC, sizeof(PARAM_SRPC) - 1) != 0) {
3157 CERROR("Invalid sptlrpc parameter: %s\n", param);
3161 if (strncmp(param, PARAM_SRPC_UDESC,
3162 sizeof(PARAM_SRPC_UDESC) - 1) == 0) {
3163 RETURN(mgs_srpc_set_param_udesc_mem(fsdb, param));
3166 if (strncmp(param, PARAM_SRPC_FLVR, sizeof(PARAM_SRPC_FLVR) - 1) != 0) {
3167 CERROR("Invalid sptlrpc flavor parameter: %s\n", param);
3171 param += sizeof(PARAM_SRPC_FLVR) - 1;
3173 rc = sptlrpc_parse_rule(param, &rule);
3177 /* mgs rules implies must be mgc->mgs */
3178 if (test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
3179 if ((rule.sr_from != LUSTRE_SP_MGC &&
3180 rule.sr_from != LUSTRE_SP_ANY) ||
3181 (rule.sr_to != LUSTRE_SP_MGS &&
3182 rule.sr_to != LUSTRE_SP_ANY))
3186 /* preapre room for this coming rule. svcname format should be:
3187 * - fsname: general rule
3188 * - fsname-tgtname: target-specific rule
3190 if (strchr(svname, '-')) {
3191 struct mgs_tgt_srpc_conf *tgtconf;
3194 for (tgtconf = fsdb->fsdb_srpc_tgt; tgtconf != NULL;
3195 tgtconf = tgtconf->mtsc_next) {
3196 if (!strcmp(tgtconf->mtsc_tgt, svname)) {
3205 OBD_ALLOC_PTR(tgtconf);
3206 if (tgtconf == NULL)
3209 name_len = strlen(svname);
3211 OBD_ALLOC(tgtconf->mtsc_tgt, name_len + 1);
3212 if (tgtconf->mtsc_tgt == NULL) {
3213 OBD_FREE_PTR(tgtconf);
3216 memcpy(tgtconf->mtsc_tgt, svname, name_len);
3218 tgtconf->mtsc_next = fsdb->fsdb_srpc_tgt;
3219 fsdb->fsdb_srpc_tgt = tgtconf;
3222 rset = &tgtconf->mtsc_rset;
3223 } else if (strcmp(svname, MGSSELF_NAME) == 0) {
3224 /* put _mgs related srpc rule directly in mgs ruleset */
3225 rset = &fsdb->fsdb_mgs->mgs_lut.lut_sptlrpc_rset;
3227 rset = &fsdb->fsdb_srpc_gen;
3230 rc = sptlrpc_rule_set_merge(rset, &rule);
3235 static int mgs_srpc_set_param(const struct lu_env *env,
3236 struct mgs_device *mgs,
3238 struct mgs_target_info *mti,
3248 /* keep a copy of original param, which could be destroied
3250 copy_size = strlen(param) + 1;
3251 OBD_ALLOC(copy, copy_size);
3254 memcpy(copy, param, copy_size);
3256 rc = mgs_srpc_set_param_mem(fsdb, mti->mti_svname, param);
3260 /* previous steps guaranteed the syntax is correct */
3261 rc = mgs_srpc_set_param_disk(env, mgs, fsdb, mti, copy);
3265 if (test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
3267 * for mgs rules, make them effective immediately.
3269 LASSERT(fsdb->fsdb_srpc_tgt == NULL);
3270 sptlrpc_target_update_exp_flavor(mgs->mgs_obd,
3271 &fsdb->fsdb_srpc_gen);
3275 OBD_FREE(copy, copy_size);
3279 struct mgs_srpc_read_data {
3280 struct fs_db *msrd_fsdb;
3284 static int mgs_srpc_read_handler(const struct lu_env *env,
3285 struct llog_handle *llh,
3286 struct llog_rec_hdr *rec, void *data)
3288 struct mgs_srpc_read_data *msrd = data;
3289 struct cfg_marker *marker;
3290 struct lustre_cfg *lcfg = REC_DATA(rec);
3291 char *svname, *param;
3295 if (rec->lrh_type != OBD_CFG_REC) {
3296 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
3300 cfg_len = REC_DATA_LEN(rec);
3302 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
3304 CERROR("Insane cfg\n");
3308 if (lcfg->lcfg_command == LCFG_MARKER) {
3309 marker = lustre_cfg_buf(lcfg, 1);
3311 if (marker->cm_flags & CM_START &&
3312 marker->cm_flags & CM_SKIP)
3313 msrd->msrd_skip = 1;
3314 if (marker->cm_flags & CM_END)
3315 msrd->msrd_skip = 0;
3320 if (msrd->msrd_skip)
3323 if (lcfg->lcfg_command != LCFG_SPTLRPC_CONF) {
3324 CERROR("invalid command (%x)\n", lcfg->lcfg_command);
3328 svname = lustre_cfg_string(lcfg, 0);
3329 if (svname == NULL) {
3330 CERROR("svname is empty\n");
3334 param = lustre_cfg_string(lcfg, 1);
3335 if (param == NULL) {
3336 CERROR("param is empty\n");
3340 rc = mgs_srpc_set_param_mem(msrd->msrd_fsdb, svname, param);
3342 CERROR("read sptlrpc record error (%d): %s\n", rc, param);
3347 int mgs_get_fsdb_srpc_from_llog(const struct lu_env *env,
3348 struct mgs_device *mgs,
3351 struct llog_handle *llh = NULL;
3352 struct llog_ctxt *ctxt;
3354 struct mgs_srpc_read_data msrd;
3358 /* construct log name */
3359 rc = name_create(&logname, fsdb->fsdb_name, "-sptlrpc");
3363 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
3364 LASSERT(ctxt != NULL);
3366 if (mgs_log_is_empty(env, mgs, logname))
3369 rc = llog_open(env, ctxt, &llh, NULL, logname,
3377 rc = llog_init_handle(env, llh, LLOG_F_IS_PLAIN, NULL);
3379 GOTO(out_close, rc);
3381 if (llog_get_size(llh) <= 1)
3382 GOTO(out_close, rc = 0);
3384 msrd.msrd_fsdb = fsdb;
3387 rc = llog_process(env, llh, mgs_srpc_read_handler, (void *)&msrd,
3391 llog_close(env, llh);
3393 llog_ctxt_put(ctxt);
3394 name_destroy(&logname);
3397 CERROR("failed to read sptlrpc config database: %d\n", rc);
3401 /* Permanent settings of all parameters by writing into the appropriate
3402 * configuration logs.
3403 * A parameter with null value ("<param>='\0'") means to erase it out of
3406 static int mgs_write_log_param(const struct lu_env *env,
3407 struct mgs_device *mgs, struct fs_db *fsdb,
3408 struct mgs_target_info *mti, char *ptr)
3410 struct mgs_thread_info *mgi = mgs_env_info(env);
3416 /* For various parameter settings, we have to figure out which logs
3417 care about them (e.g. both mdt and client for lov settings) */
3418 CDEBUG(D_MGS, "next param '%s'\n", ptr);
3420 /* The params are stored in MOUNT_DATA_FILE and modified via
3421 tunefs.lustre, or set using lctl conf_param */
3423 /* Processed in lustre_start_mgc */
3424 if (class_match_param(ptr, PARAM_MGSNODE, NULL) == 0)
3427 /* Processed in ost/mdt */
3428 if (class_match_param(ptr, PARAM_NETWORK, NULL) == 0)
3431 /* Processed in mgs_write_log_ost */
3432 if (class_match_param(ptr, PARAM_FAILMODE, NULL) == 0) {
3433 if (mti->mti_flags & LDD_F_PARAM) {
3434 LCONSOLE_ERROR_MSG(0x169, "%s can only be "
3435 "changed with tunefs.lustre"
3436 "and --writeconf\n", ptr);
3442 if (class_match_param(ptr, PARAM_SRPC, NULL) == 0) {
3443 rc = mgs_srpc_set_param(env, mgs, fsdb, mti, ptr);
3447 if (class_match_param(ptr, PARAM_FAILNODE, NULL) == 0) {
3448 /* Add a failover nidlist */
3450 /* We already processed failovers params for new
3451 targets in mgs_write_log_target */
3452 if (mti->mti_flags & LDD_F_PARAM) {
3453 CDEBUG(D_MGS, "Adding failnode\n");
3454 rc = mgs_write_log_add_failnid(env, mgs, fsdb, mti);
3459 if (class_match_param(ptr, PARAM_SYS, &tmp) == 0) {
3460 rc = mgs_write_log_sys(env, mgs, fsdb, mti, ptr, tmp);
3464 if (class_match_param(ptr, PARAM_QUOTA, &tmp) == 0) {
3465 rc = mgs_write_log_quota(env, mgs, fsdb, mti, ptr, tmp);
3469 if (class_match_param(ptr, PARAM_OSC PARAM_ACTIVE, &tmp) == 0 ||
3470 class_match_param(ptr, PARAM_MDC PARAM_ACTIVE, &tmp) == 0) {
3471 /* active=0 means off, anything else means on */
3472 int flag = (*tmp == '0') ? CM_EXCLUDE : 0;
3473 bool deactive_osc = memcmp(ptr, PARAM_OSC PARAM_ACTIVE,
3474 strlen(PARAM_OSC PARAM_ACTIVE)) == 0;
3477 if (!deactive_osc) {
3480 rc = server_name2index(mti->mti_svname, &index, NULL);
3485 LCONSOLE_ERROR_MSG(0x144, "%s: MDC0 can not be"
3486 " (de)activated.\n",
3488 GOTO(end, rc = -EINVAL);
3492 LCONSOLE_WARN("Permanently %sactivating %s\n",
3493 flag ? "de" : "re", mti->mti_svname);
3495 rc = name_create(&logname, mti->mti_fsname, "-client");
3498 rc = mgs_modify(env, mgs, fsdb, mti, logname,
3500 deactive_osc ? "add osc" : "add mdc", flag);
3501 name_destroy(&logname);
3506 /* Add to all MDT logs for DNE */
3507 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3508 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
3510 rc = name_create_mdt(&logname, mti->mti_fsname, i);
3513 rc = mgs_modify(env, mgs, fsdb, mti, logname,
3515 deactive_osc ? "add osc" : "add osp",
3517 name_destroy(&logname);
3523 LCONSOLE_ERROR_MSG(0x145, "Couldn't find %s in"
3524 "log (%d). No permanent "
3525 "changes were made to the "
3527 mti->mti_svname, rc);
3528 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags))
3529 LCONSOLE_ERROR_MSG(0x146, "This may be"
3534 "update the logs.\n");
3537 /* Fall through to osc/mdc proc for deactivating live
3538 OSC/OSP on running MDT / clients. */
3540 /* Below here, let obd's XXX_process_config methods handle it */
3542 /* All lov. in proc */
3543 if (class_match_param(ptr, PARAM_LOV, NULL) == 0) {
3546 CDEBUG(D_MGS, "lov param %s\n", ptr);
3547 if (!(mti->mti_flags & LDD_F_SV_TYPE_MDT)) {
3548 LCONSOLE_ERROR_MSG(0x147, "LOV params must be "
3549 "set on the MDT, not %s. "
3556 if (mgs_log_is_empty(env, mgs, mti->mti_svname))
3557 GOTO(end, rc = -ENODEV);
3559 rc = name_create_mdt_and_lov(&logname, &mdtlovname, fsdb,
3560 mti->mti_stripe_index);
3563 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, mti->mti_svname,
3564 &mgi->mgi_bufs, mdtlovname, ptr);
3565 name_destroy(&logname);
3566 name_destroy(&mdtlovname);
3571 rc = name_create(&logname, mti->mti_fsname, "-client");
3574 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname, &mgi->mgi_bufs,
3575 fsdb->fsdb_clilov, ptr);
3576 name_destroy(&logname);
3580 /* All osc., mdc., llite. params in proc */
3581 if ((class_match_param(ptr, PARAM_OSC, NULL) == 0) ||
3582 (class_match_param(ptr, PARAM_MDC, NULL) == 0) ||
3583 (class_match_param(ptr, PARAM_LLITE, NULL) == 0)) {
3586 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
3587 LCONSOLE_ERROR_MSG(0x148, "Upgraded client logs for %s"
3588 " cannot be modified. Consider"
3589 " updating the configuration with"
3592 GOTO(end, rc = -EINVAL);
3594 if (memcmp(ptr, PARAM_LLITE, strlen(PARAM_LLITE)) == 0) {
3595 rc = name_create(&cname, mti->mti_fsname, "-client");
3596 /* Add the client type to match the obdname in
3597 class_config_llog_handler */
3598 } else if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
3599 rc = name_create(&cname, mti->mti_svname, "-mdc");
3600 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
3601 rc = name_create(&cname, mti->mti_svname, "-osc");
3603 GOTO(end, rc = -EINVAL);
3608 /* Forbid direct update of llite root squash parameters.
3609 * These parameters are indirectly set via the MDT settings.
3611 if ((class_match_param(ptr, PARAM_LLITE, &tmp) == 0) &&
3612 ((memcmp(tmp, "root_squash=", 12) == 0) ||
3613 (memcmp(tmp, "nosquash_nids=", 14) == 0))) {
3614 LCONSOLE_ERROR("%s: root squash parameters can only "
3615 "be updated through MDT component\n",
3617 name_destroy(&cname);
3618 GOTO(end, rc = -EINVAL);
3621 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
3624 rc = name_create(&logname, mti->mti_fsname, "-client");
3626 name_destroy(&cname);
3629 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname, &mgi->mgi_bufs,
3632 /* osc params affect the MDT as well */
3633 if (!rc && (mti->mti_flags & LDD_F_SV_TYPE_OST)) {
3636 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
3637 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
3639 name_destroy(&cname);
3640 rc = name_create_mdt_osc(&cname, mti->mti_svname,
3642 name_destroy(&logname);
3645 rc = name_create_mdt(&logname,
3646 mti->mti_fsname, i);
3649 if (!mgs_log_is_empty(env, mgs, logname)) {
3650 rc = mgs_wlp_lcfg(env, mgs, fsdb,
3660 /* For mdc activate/deactivate, it affects OSP on MDT as well */
3661 if (class_match_param(ptr, PARAM_MDC PARAM_ACTIVE, &tmp) == 0 &&
3664 char *lodname = NULL;
3665 char *param_str = NULL;
3669 /* replace mdc with osp */
3670 memcpy(ptr, PARAM_OSP, strlen(PARAM_OSP));
3671 rc = server_name2index(mti->mti_svname, &index, NULL);
3673 memcpy(ptr, PARAM_MDC, strlen(PARAM_MDC));
3677 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3678 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
3684 name_destroy(&logname);
3685 rc = name_create_mdt(&logname, mti->mti_fsname,
3690 if (mgs_log_is_empty(env, mgs, logname))
3693 snprintf(suffix, sizeof(suffix), "-osp-MDT%04x",
3695 name_destroy(&cname);
3696 rc = name_create(&cname, mti->mti_svname,
3701 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname,
3702 &mgi->mgi_bufs, cname, ptr);
3706 /* Add configuration log for noitfying LOD
3707 * to active/deactive the OSP. */
3708 name_destroy(¶m_str);
3709 rc = name_create(¶m_str, cname,
3710 (*tmp == '0') ? ".active=0" :
3715 name_destroy(&lodname);
3716 rc = name_create(&lodname, logname, "-mdtlov");
3720 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname,
3721 &mgi->mgi_bufs, lodname,
3726 memcpy(ptr, PARAM_MDC, strlen(PARAM_MDC));
3727 name_destroy(&lodname);
3728 name_destroy(¶m_str);
3731 name_destroy(&logname);
3732 name_destroy(&cname);
3736 /* All mdt. params in proc */
3737 if (class_match_param(ptr, PARAM_MDT, &tmp) == 0) {
3741 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
3742 if (strncmp(mti->mti_svname, mti->mti_fsname,
3743 MTI_NAME_MAXLEN) == 0)
3744 /* device is unspecified completely? */
3745 rc = LDD_F_SV_TYPE_MDT | LDD_F_SV_ALL;
3747 rc = server_name2index(mti->mti_svname, &idx, NULL);
3750 if ((rc & LDD_F_SV_TYPE_MDT) == 0)
3752 if (rc & LDD_F_SV_ALL) {
3753 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3755 fsdb->fsdb_mdt_index_map))
3757 rc = name_create_mdt(&logname,
3758 mti->mti_fsname, i);
3761 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti,
3762 logname, &mgi->mgi_bufs,
3764 name_destroy(&logname);
3769 if ((memcmp(tmp, "root_squash=", 12) == 0) ||
3770 (memcmp(tmp, "nosquash_nids=", 14) == 0)) {
3771 LCONSOLE_ERROR("%s: root squash parameters "
3772 "cannot be applied to a single MDT\n",
3774 GOTO(end, rc = -EINVAL);
3776 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti,
3777 mti->mti_svname, &mgi->mgi_bufs,
3778 mti->mti_svname, ptr);
3783 /* root squash settings are also applied to llite
3784 * config log (see LU-1778) */
3786 ((memcmp(tmp, "root_squash=", 12) == 0) ||
3787 (memcmp(tmp, "nosquash_nids=", 14) == 0))) {
3791 rc = name_create(&cname, mti->mti_fsname, "-client");
3794 rc = name_create(&logname, mti->mti_fsname, "-client");
3796 name_destroy(&cname);
3799 rc = name_create(&ptr2, PARAM_LLITE, tmp);
3801 name_destroy(&cname);
3802 name_destroy(&logname);
3805 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname,
3806 &mgi->mgi_bufs, cname, ptr2);
3807 name_destroy(&ptr2);
3808 name_destroy(&logname);
3809 name_destroy(&cname);
3814 /* All mdd., ost. and osd. params in proc */
3815 if ((class_match_param(ptr, PARAM_MDD, NULL) == 0) ||
3816 (class_match_param(ptr, PARAM_OST, NULL) == 0) ||
3817 (class_match_param(ptr, PARAM_OSD, NULL) == 0)) {
3818 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
3819 if (mgs_log_is_empty(env, mgs, mti->mti_svname))
3820 GOTO(end, rc = -ENODEV);
3822 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, mti->mti_svname,
3823 &mgi->mgi_bufs, mti->mti_svname, ptr);
3827 LCONSOLE_WARN("Ignoring unrecognized param '%s'\n", ptr);
3831 CERROR("err %d on param '%s'\n", rc, ptr);
3836 int mgs_write_log_target(const struct lu_env *env, struct mgs_device *mgs,
3837 struct mgs_target_info *mti, struct fs_db *fsdb)
3844 /* set/check the new target index */
3845 rc = mgs_set_index(env, mgs, mti);
3849 if (rc == EALREADY) {
3850 LCONSOLE_WARN("Found index %d for %s, updating log\n",
3851 mti->mti_stripe_index, mti->mti_svname);
3852 /* We would like to mark old log sections as invalid
3853 and add new log sections in the client and mdt logs.
3854 But if we add new sections, then live clients will
3855 get repeat setup instructions for already running
3856 osc's. So don't update the client/mdt logs. */
3857 mti->mti_flags &= ~LDD_F_UPDATE;
3861 OBD_FAIL_TIMEOUT(OBD_FAIL_MGS_WRITE_TARGET_DELAY, cfs_fail_val > 0 ?
3864 mutex_lock(&fsdb->fsdb_mutex);
3866 if (mti->mti_flags &
3867 (LDD_F_VIRGIN | LDD_F_UPGRADE14 | LDD_F_WRITECONF)) {
3868 /* Generate a log from scratch */
3869 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
3870 rc = mgs_write_log_mdt(env, mgs, fsdb, mti);
3871 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
3872 rc = mgs_write_log_ost(env, mgs, fsdb, mti);
3874 CERROR("Unknown target type %#x, can't create log for "
3875 "%s\n", mti->mti_flags, mti->mti_svname);
3878 CERROR("Can't write logs for %s (%d)\n",
3879 mti->mti_svname, rc);
3883 /* Just update the params from tunefs in mgs_write_log_params */
3884 CDEBUG(D_MGS, "Update params for %s\n", mti->mti_svname);
3885 mti->mti_flags |= LDD_F_PARAM;
3888 /* allocate temporary buffer, where class_get_next_param will
3889 make copy of a current parameter */
3890 OBD_ALLOC(buf, strlen(mti->mti_params) + 1);
3892 GOTO(out_up, rc = -ENOMEM);
3893 params = mti->mti_params;
3894 while (params != NULL) {
3895 rc = class_get_next_param(¶ms, buf);
3898 /* there is no next parameter, that is
3903 CDEBUG(D_MGS, "remaining string: '%s', param: '%s'\n",
3905 rc = mgs_write_log_param(env, mgs, fsdb, mti, buf);
3910 OBD_FREE(buf, strlen(mti->mti_params) + 1);
3913 mutex_unlock(&fsdb->fsdb_mutex);
3917 int mgs_erase_log(const struct lu_env *env, struct mgs_device *mgs, char *name)
3919 struct llog_ctxt *ctxt;
3922 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
3924 CERROR("%s: MGS config context doesn't exist\n",
3925 mgs->mgs_obd->obd_name);
3928 rc = llog_erase(env, ctxt, NULL, name);
3929 /* llog may not exist */
3932 llog_ctxt_put(ctxt);
3936 CERROR("%s: failed to clear log %s: %d\n",
3937 mgs->mgs_obd->obd_name, name, rc);
3942 /* erase all logs for the given fs */
3943 int mgs_erase_logs(const struct lu_env *env, struct mgs_device *mgs, char *fsname)
3946 struct list_head log_list;
3947 struct mgs_direntry *dirent, *n;
3948 int rc, len = strlen(fsname);
3952 /* Find all the logs in the CONFIGS directory */
3953 rc = class_dentry_readdir(env, mgs, &log_list);
3957 mutex_lock(&mgs->mgs_mutex);
3959 /* Delete the fs db */
3960 fsdb = mgs_find_fsdb(mgs, fsname);
3962 mgs_free_fsdb(mgs, fsdb);
3964 mutex_unlock(&mgs->mgs_mutex);
3966 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
3967 list_del_init(&dirent->mde_list);
3968 suffix = strrchr(dirent->mde_name, '-');
3969 if (suffix != NULL) {
3970 if ((len == suffix - dirent->mde_name) &&
3971 (strncmp(fsname, dirent->mde_name, len) == 0)) {
3972 CDEBUG(D_MGS, "Removing log %s\n",
3974 mgs_erase_log(env, mgs, dirent->mde_name);
3977 mgs_direntry_free(dirent);
3983 /* list all logs for the given fs */
3984 int mgs_list_logs(const struct lu_env *env, struct mgs_device *mgs,
3985 struct obd_ioctl_data *data)
3987 struct list_head log_list;
3988 struct mgs_direntry *dirent, *n;
3994 /* Find all the logs in the CONFIGS directory */
3995 rc = class_dentry_readdir(env, mgs, &log_list);
3999 out = data->ioc_bulk;
4000 remains = data->ioc_inllen1;
4001 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
4002 list_del_init(&dirent->mde_list);
4003 suffix = strrchr(dirent->mde_name, '-');
4004 if (suffix != NULL) {
4005 l = snprintf(out, remains, "config log: $%s\n",
4010 mgs_direntry_free(dirent);
4017 /* from llog_swab */
4018 static void print_lustre_cfg(struct lustre_cfg *lcfg)
4023 CDEBUG(D_MGS, "lustre_cfg: %p\n", lcfg);
4024 CDEBUG(D_MGS, "\tlcfg->lcfg_version: %#x\n", lcfg->lcfg_version);
4026 CDEBUG(D_MGS, "\tlcfg->lcfg_command: %#x\n", lcfg->lcfg_command);
4027 CDEBUG(D_MGS, "\tlcfg->lcfg_num: %#x\n", lcfg->lcfg_num);
4028 CDEBUG(D_MGS, "\tlcfg->lcfg_flags: %#x\n", lcfg->lcfg_flags);
4029 CDEBUG(D_MGS, "\tlcfg->lcfg_nid: %s\n", libcfs_nid2str(lcfg->lcfg_nid));
4031 CDEBUG(D_MGS, "\tlcfg->lcfg_bufcount: %d\n", lcfg->lcfg_bufcount);
4032 if (lcfg->lcfg_bufcount < LUSTRE_CFG_MAX_BUFCOUNT)
4033 for (i = 0; i < lcfg->lcfg_bufcount; i++) {
4034 CDEBUG(D_MGS, "\tlcfg->lcfg_buflens[%d]: %d %s\n",
4035 i, lcfg->lcfg_buflens[i],
4036 lustre_cfg_string(lcfg, i));
4041 /* Setup _mgs fsdb and log
4043 int mgs__mgs_fsdb_setup(const struct lu_env *env, struct mgs_device *mgs,
4049 rc = mgs_find_or_make_fsdb(env, mgs, MGSSELF_NAME, &fsdb);
4054 /* Setup params fsdb and log
4056 int mgs_params_fsdb_setup(const struct lu_env *env, struct mgs_device *mgs,
4059 struct llog_handle *params_llh = NULL;
4063 rc = mgs_find_or_make_fsdb(env, mgs, PARAMS_FILENAME, &fsdb);
4065 mutex_lock(&fsdb->fsdb_mutex);
4066 rc = record_start_log(env, mgs, ¶ms_llh, PARAMS_FILENAME);
4068 rc = record_end_log(env, ¶ms_llh);
4069 mutex_unlock(&fsdb->fsdb_mutex);
4075 /* Cleanup params fsdb and log
4077 int mgs_params_fsdb_cleanup(const struct lu_env *env, struct mgs_device *mgs)
4079 return mgs_erase_logs(env, mgs, PARAMS_FILENAME);
4082 /* Set a permanent (config log) param for a target or fs
4083 * \param lcfg buf0 may contain the device (testfs-MDT0000) name
4084 * buf1 contains the single parameter
4086 int mgs_setparam(const struct lu_env *env, struct mgs_device *mgs,
4087 struct lustre_cfg *lcfg, char *fsname)
4090 struct mgs_target_info *mti;
4091 char *devname, *param;
4098 print_lustre_cfg(lcfg);
4100 /* lustre, lustre-mdtlov, lustre-client, lustre-MDT0000 */
4101 devname = lustre_cfg_string(lcfg, 0);
4102 param = lustre_cfg_string(lcfg, 1);
4104 /* Assume device name embedded in param:
4105 lustre-OST0000.osc.max_dirty_mb=32 */
4106 ptr = strchr(param, '.');
4114 LCONSOLE_ERROR_MSG(0x14d, "No target specified: %s\n", param);
4118 rc = mgs_parse_devname(devname, fsname, NULL);
4119 if (rc == 0 && !mgs_parse_devname(devname, NULL, &index)) {
4120 /* param related to llite isn't allowed to set by OST or MDT */
4121 if (rc == 0 && strncmp(param, PARAM_LLITE,
4122 sizeof(PARAM_LLITE) - 1) == 0)
4125 /* assume devname is the fsname */
4126 strlcpy(fsname, devname, MTI_NAME_MAXLEN);
4128 CDEBUG(D_MGS, "setparam fs='%s' device='%s'\n", fsname, devname);
4130 rc = mgs_find_or_make_fsdb(env, mgs,
4131 lcfg->lcfg_command == LCFG_SET_PARAM ?
4132 PARAMS_FILENAME : fsname, &fsdb);
4136 if (lcfg->lcfg_command != LCFG_SET_PARAM &&
4137 !test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags) &&
4138 test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
4139 CERROR("No filesystem targets for %s. cfg_device from lctl "
4140 "is '%s'\n", fsname, devname);
4141 mgs_free_fsdb(mgs, fsdb);
4145 /* Create a fake mti to hold everything */
4148 GOTO(out, rc = -ENOMEM);
4149 if (strlcpy(mti->mti_fsname, fsname, sizeof(mti->mti_fsname))
4150 >= sizeof(mti->mti_fsname))
4151 GOTO(out, rc = -E2BIG);
4152 if (strlcpy(mti->mti_svname, devname, sizeof(mti->mti_svname))
4153 >= sizeof(mti->mti_svname))
4154 GOTO(out, rc = -E2BIG);
4155 if (strlcpy(mti->mti_params, param, sizeof(mti->mti_params))
4156 >= sizeof(mti->mti_params))
4157 GOTO(out, rc = -E2BIG);
4158 rc = server_name2index(mti->mti_svname, &mti->mti_stripe_index, &tmp);
4160 /* Not a valid server; may be only fsname */
4163 /* Strip -osc or -mdc suffix from svname */
4164 if (server_make_name(rc, mti->mti_stripe_index, mti->mti_fsname,
4166 GOTO(out, rc = -EINVAL);
4168 * Revoke lock so everyone updates. Should be alright if
4169 * someone was already reading while we were updating the logs,
4170 * so we don't really need to hold the lock while we're
4173 if (lcfg->lcfg_command == LCFG_SET_PARAM) {
4174 mti->mti_flags = rc | LDD_F_PARAM2;
4175 mutex_lock(&fsdb->fsdb_mutex);
4176 rc = mgs_write_log_param2(env, mgs, fsdb, mti, mti->mti_params);
4177 mutex_unlock(&fsdb->fsdb_mutex);
4178 mgs_revoke_lock(mgs, fsdb, CONFIG_T_PARAMS);
4180 mti->mti_flags = rc | LDD_F_PARAM;
4181 mutex_lock(&fsdb->fsdb_mutex);
4182 rc = mgs_write_log_param(env, mgs, fsdb, mti, mti->mti_params);
4183 mutex_unlock(&fsdb->fsdb_mutex);
4184 mgs_revoke_lock(mgs, fsdb, CONFIG_T_CONFIG);
4192 static int mgs_write_log_pool(const struct lu_env *env,
4193 struct mgs_device *mgs, char *logname,
4194 struct fs_db *fsdb, char *tgtname,
4195 enum lcfg_command_type cmd,
4196 char *fsname, char *poolname,
4197 char *ostname, char *comment)
4199 struct llog_handle *llh = NULL;
4202 rc = record_start_log(env, mgs, &llh, logname);
4205 rc = record_marker(env, llh, fsdb, CM_START, tgtname, comment);
4208 rc = record_base(env, llh, tgtname, 0, cmd,
4209 fsname, poolname, ostname, NULL);
4212 rc = record_marker(env, llh, fsdb, CM_END, tgtname, comment);
4214 record_end_log(env, &llh);
4218 int mgs_nodemap_cmd(const struct lu_env *env, struct mgs_device *mgs,
4219 enum lcfg_command_type cmd, const char *nodemap_name,
4230 case LCFG_NODEMAP_ADD:
4231 rc = nodemap_add(nodemap_name);
4233 case LCFG_NODEMAP_DEL:
4234 rc = nodemap_del(nodemap_name);
4236 case LCFG_NODEMAP_ADD_RANGE:
4237 rc = nodemap_parse_range(param, nid);
4240 rc = nodemap_add_range(nodemap_name, nid);
4242 case LCFG_NODEMAP_DEL_RANGE:
4243 rc = nodemap_parse_range(param, nid);
4246 rc = nodemap_del_range(nodemap_name, nid);
4248 case LCFG_NODEMAP_ADMIN:
4249 bool_switch = simple_strtoul(param, NULL, 10);
4250 rc = nodemap_set_allow_root(nodemap_name, bool_switch);
4252 case LCFG_NODEMAP_DENY_UNKNOWN:
4253 bool_switch = simple_strtoul(param, NULL, 10);
4254 rc = nodemap_set_deny_unknown(nodemap_name, bool_switch);
4256 case LCFG_NODEMAP_TRUSTED:
4257 bool_switch = simple_strtoul(param, NULL, 10);
4258 rc = nodemap_set_trust_client_ids(nodemap_name, bool_switch);
4260 case LCFG_NODEMAP_SQUASH_UID:
4261 int_id = simple_strtoul(param, NULL, 10);
4262 rc = nodemap_set_squash_uid(nodemap_name, int_id);
4264 case LCFG_NODEMAP_SQUASH_GID:
4265 int_id = simple_strtoul(param, NULL, 10);
4266 rc = nodemap_set_squash_gid(nodemap_name, int_id);
4268 case LCFG_NODEMAP_ADD_UIDMAP:
4269 case LCFG_NODEMAP_ADD_GIDMAP:
4270 rc = nodemap_parse_idmap(param, idmap);
4273 if (cmd == LCFG_NODEMAP_ADD_UIDMAP)
4274 rc = nodemap_add_idmap(nodemap_name, NODEMAP_UID,
4277 rc = nodemap_add_idmap(nodemap_name, NODEMAP_GID,
4280 case LCFG_NODEMAP_DEL_UIDMAP:
4281 case LCFG_NODEMAP_DEL_GIDMAP:
4282 rc = nodemap_parse_idmap(param, idmap);
4285 if (cmd == LCFG_NODEMAP_DEL_UIDMAP)
4286 rc = nodemap_del_idmap(nodemap_name, NODEMAP_UID,
4289 rc = nodemap_del_idmap(nodemap_name, NODEMAP_GID,
4292 case LCFG_NODEMAP_SET_FILESET:
4293 rc = nodemap_set_fileset(nodemap_name, param);
4302 int mgs_pool_cmd(const struct lu_env *env, struct mgs_device *mgs,
4303 enum lcfg_command_type cmd, char *fsname,
4304 char *poolname, char *ostname)
4309 char *label = NULL, *canceled_label = NULL;
4311 struct mgs_target_info *mti = NULL;
4312 bool checked = false;
4316 rc = mgs_find_or_make_fsdb(env, mgs, fsname, &fsdb);
4318 CERROR("Can't get db for %s\n", fsname);
4321 if (test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
4322 CERROR("%s is not defined\n", fsname);
4323 mgs_free_fsdb(mgs, fsdb);
4327 label_sz = 10 + strlen(fsname) + strlen(poolname);
4329 /* check if ostname match fsname */
4330 if (ostname != NULL) {
4333 ptr = strrchr(ostname, '-');
4334 if ((ptr == NULL) ||
4335 (strncmp(fsname, ostname, ptr-ostname) != 0))
4337 label_sz += strlen(ostname);
4340 OBD_ALLOC(label, label_sz);
4347 "new %s.%s", fsname, poolname);
4351 "add %s.%s.%s", fsname, poolname, ostname);
4354 OBD_ALLOC(canceled_label, label_sz);
4355 if (canceled_label == NULL)
4356 GOTO(out_label, rc = -ENOMEM);
4358 "rem %s.%s.%s", fsname, poolname, ostname);
4359 sprintf(canceled_label,
4360 "add %s.%s.%s", fsname, poolname, ostname);
4363 OBD_ALLOC(canceled_label, label_sz);
4364 if (canceled_label == NULL)
4365 GOTO(out_label, rc = -ENOMEM);
4367 "del %s.%s", fsname, poolname);
4368 sprintf(canceled_label,
4369 "new %s.%s", fsname, poolname);
4377 GOTO(out_cancel, rc = -ENOMEM);
4378 strncpy(mti->mti_svname, "lov pool", sizeof(mti->mti_svname));
4380 mutex_lock(&fsdb->fsdb_mutex);
4381 /* write pool def to all MDT logs */
4382 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
4383 if (test_bit(i, fsdb->fsdb_mdt_index_map)) {
4384 rc = name_create_mdt_and_lov(&logname, &lovname,
4387 mutex_unlock(&fsdb->fsdb_mutex);
4391 if (!checked && (canceled_label == NULL)) {
4392 rc = mgs_check_marker(env, mgs, fsdb, mti,
4393 logname, lovname, label);
4395 name_destroy(&logname);
4396 name_destroy(&lovname);
4397 mutex_unlock(&fsdb->fsdb_mutex);
4399 rc = (rc == LLOG_PROC_BREAK ?
4404 if (canceled_label != NULL)
4405 rc = mgs_modify(env, mgs, fsdb, mti, logname,
4406 lovname, canceled_label,
4410 rc = mgs_write_log_pool(env, mgs, logname,
4414 name_destroy(&logname);
4415 name_destroy(&lovname);
4417 mutex_unlock(&fsdb->fsdb_mutex);
4423 rc = name_create(&logname, fsname, "-client");
4425 mutex_unlock(&fsdb->fsdb_mutex);
4429 if (!checked && (canceled_label == NULL)) {
4430 rc = mgs_check_marker(env, mgs, fsdb, mti, logname,
4431 fsdb->fsdb_clilov, label);
4433 name_destroy(&logname);
4434 mutex_unlock(&fsdb->fsdb_mutex);
4435 GOTO(out_mti, rc = (rc == LLOG_PROC_BREAK ?
4439 if (canceled_label != NULL) {
4440 rc = mgs_modify(env, mgs, fsdb, mti, logname,
4441 fsdb->fsdb_clilov, canceled_label, CM_SKIP);
4443 mutex_unlock(&fsdb->fsdb_mutex);
4444 name_destroy(&logname);
4449 rc = mgs_write_log_pool(env, mgs, logname, fsdb, fsdb->fsdb_clilov,
4450 cmd, fsname, poolname, ostname, label);
4451 mutex_unlock(&fsdb->fsdb_mutex);
4452 name_destroy(&logname);
4453 /* request for update */
4454 mgs_revoke_lock(mgs, fsdb, CONFIG_T_CONFIG);
4461 if (canceled_label != NULL)
4462 OBD_FREE(canceled_label, label_sz);
4464 OBD_FREE(label, label_sz);