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.sun.com/software/products/lustre/docs/GPLv2.pdf
20 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
21 * CA 95054 USA or visit www.sun.com if you need additional information or
27 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
28 * Use is subject to license terms.
30 * Copyright (c) 2011, 2015, Intel Corporation.
33 * This file is part of Lustre, http://www.lustre.org/
34 * Lustre is a trademark of Sun Microsystems, Inc.
36 * lustre/mgs/mgs_llog.c
38 * Lustre Management Server (mgs) config llog creation
40 * Author: Nathan Rutman <nathan@clusterfs.com>
41 * Author: Alex Zhuravlev <bzzz@whamcloud.com>
42 * Author: Mikhail Pershin <tappro@whamcloud.com>
45 #define DEBUG_SUBSYSTEM S_MGS
46 #define D_MGS D_CONFIG
49 #include <lustre_ioctl.h>
50 #include <lustre_param.h>
51 #include <lustre_sec.h>
52 #include <lustre_quota.h>
54 #include "mgs_internal.h"
56 /********************** Class functions ********************/
58 /* Find all logs in CONFIG directory and link then into list */
59 int class_dentry_readdir(const struct lu_env *env,
60 struct mgs_device *mgs, struct list_head *log_list)
62 struct dt_object *dir = mgs->mgs_configs_dir;
63 const struct dt_it_ops *iops;
65 struct mgs_direntry *de;
69 INIT_LIST_HEAD(log_list);
72 LASSERT(dir->do_index_ops);
74 iops = &dir->do_index_ops->dio_it;
75 it = iops->init(env, dir, LUDA_64BITHASH);
79 rc = iops->load(env, it, 0);
85 key = (void *)iops->key(env, it);
87 CERROR("%s: key failed when listing %s: rc = %d\n",
88 mgs->mgs_obd->obd_name, MOUNT_CONFIGS_DIR,
92 key_sz = iops->key_size(env, it);
95 /* filter out "." and ".." entries */
99 if (key_sz == 2 && key[1] == '.')
103 /* filter out ".bak" files */
104 /* sizeof(".bak") - 1 == 3 */
106 !memcmp(".bak", key + key_sz - 3, 3)) {
107 CDEBUG(D_MGS, "Skipping backup file %.*s\n",
112 de = mgs_direntry_alloc(key_sz + 1);
118 memcpy(de->mde_name, key, key_sz);
119 de->mde_name[key_sz] = 0;
121 list_add(&de->mde_list, log_list);
124 rc = iops->next(env, it);
134 CERROR("%s: key failed when listing %s: rc = %d\n",
135 mgs->mgs_obd->obd_name, MOUNT_CONFIGS_DIR, rc);
139 /******************** DB functions *********************/
141 static inline int name_create(char **newname, char *prefix, char *suffix)
144 OBD_ALLOC(*newname, strlen(prefix) + strlen(suffix) + 1);
147 sprintf(*newname, "%s%s", prefix, suffix);
151 static inline void name_destroy(char **name)
154 OBD_FREE(*name, strlen(*name) + 1);
158 struct mgs_fsdb_handler_data
164 /* from the (client) config log, figure out:
165 1. which ost's/mdt's are configured (by index)
166 2. what the last config step is
167 3. COMPAT_18 osc name
169 /* It might be better to have a separate db file, instead of parsing the info
170 out of the client log. This is slow and potentially error-prone. */
171 static int mgs_fsdb_handler(const struct lu_env *env, struct llog_handle *llh,
172 struct llog_rec_hdr *rec, void *data)
174 struct mgs_fsdb_handler_data *d = data;
175 struct fs_db *fsdb = d->fsdb;
176 int cfg_len = rec->lrh_len;
177 char *cfg_buf = (char*) (rec + 1);
178 struct lustre_cfg *lcfg;
183 if (rec->lrh_type != OBD_CFG_REC) {
184 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
188 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
190 CERROR("Insane cfg\n");
194 lcfg = (struct lustre_cfg *)cfg_buf;
196 CDEBUG(D_INFO, "cmd %x %s %s\n", lcfg->lcfg_command,
197 lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));
199 /* Figure out ost indicies */
200 /* lov_modify_tgts add 0:lov1 1:ost1_UUID 2(index):0 3(gen):1 */
201 if (lcfg->lcfg_command == LCFG_LOV_ADD_OBD ||
202 lcfg->lcfg_command == LCFG_LOV_DEL_OBD) {
203 index = simple_strtoul(lustre_cfg_string(lcfg, 2),
205 CDEBUG(D_MGS, "OST index for %s is %u (%s)\n",
206 lustre_cfg_string(lcfg, 1), index,
207 lustre_cfg_string(lcfg, 2));
208 set_bit(index, fsdb->fsdb_ost_index_map);
211 /* Figure out mdt indicies */
212 /* attach 0:MDC_uml1_mdsA_MNT_client 1:mdc 2:1d834_MNT_client_03f */
213 if ((lcfg->lcfg_command == LCFG_ATTACH) &&
214 (strcmp(lustre_cfg_string(lcfg, 1), LUSTRE_MDC_NAME) == 0)) {
215 rc = server_name2index(lustre_cfg_string(lcfg, 0),
217 if (rc != LDD_F_SV_TYPE_MDT) {
218 CWARN("Unparsable MDC name %s, assuming index 0\n",
219 lustre_cfg_string(lcfg, 0));
223 CDEBUG(D_MGS, "MDT index is %u\n", index);
224 set_bit(index, fsdb->fsdb_mdt_index_map);
225 fsdb->fsdb_mdt_count ++;
229 * figure out the old config. fsdb_gen = 0 means old log
230 * It is obsoleted and not supported anymore
232 if (fsdb->fsdb_gen == 0) {
233 CERROR("Old config format is not supported\n");
238 * compat to 1.8, check osc name used by MDT0 to OSTs, bz18548.
240 if (!test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags) &&
241 lcfg->lcfg_command == LCFG_ATTACH &&
242 strcmp(lustre_cfg_string(lcfg, 1), LUSTRE_OSC_NAME) == 0) {
243 if (OBD_OCD_VERSION_MAJOR(d->ver) == 1 &&
244 OBD_OCD_VERSION_MINOR(d->ver) <= 8) {
245 CWARN("MDT using 1.8 OSC name scheme\n");
246 set_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags);
250 if (lcfg->lcfg_command == LCFG_MARKER) {
251 struct cfg_marker *marker;
252 marker = lustre_cfg_buf(lcfg, 1);
254 d->ver = marker->cm_vers;
256 /* Keep track of the latest marker step */
257 fsdb->fsdb_gen = max(fsdb->fsdb_gen, marker->cm_step);
263 /* fsdb->fsdb_mutex is already held in mgs_find_or_make_fsdb*/
264 static int mgs_get_fsdb_from_llog(const struct lu_env *env,
265 struct mgs_device *mgs,
269 struct llog_handle *loghandle;
270 struct llog_ctxt *ctxt;
271 struct mgs_fsdb_handler_data d = { fsdb, 0 };
276 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
277 LASSERT(ctxt != NULL);
278 rc = name_create(&logname, fsdb->fsdb_name, "-client");
281 rc = llog_open_create(env, ctxt, &loghandle, NULL, logname);
285 rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL);
289 if (llog_get_size(loghandle) <= 1)
290 set_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags);
292 rc = llog_process(env, loghandle, mgs_fsdb_handler, (void *)&d, NULL);
293 CDEBUG(D_INFO, "get_db = %d\n", rc);
295 llog_close(env, loghandle);
297 name_destroy(&logname);
304 static void mgs_free_fsdb_srpc(struct fs_db *fsdb)
306 struct mgs_tgt_srpc_conf *tgtconf;
308 /* free target-specific rules */
309 while (fsdb->fsdb_srpc_tgt) {
310 tgtconf = fsdb->fsdb_srpc_tgt;
311 fsdb->fsdb_srpc_tgt = tgtconf->mtsc_next;
313 LASSERT(tgtconf->mtsc_tgt);
315 sptlrpc_rule_set_free(&tgtconf->mtsc_rset);
316 OBD_FREE(tgtconf->mtsc_tgt, strlen(tgtconf->mtsc_tgt) + 1);
317 OBD_FREE_PTR(tgtconf);
320 /* free general rules */
321 sptlrpc_rule_set_free(&fsdb->fsdb_srpc_gen);
324 struct fs_db *mgs_find_fsdb(struct mgs_device *mgs, char *fsname)
327 struct list_head *tmp;
329 list_for_each(tmp, &mgs->mgs_fs_db_list) {
330 fsdb = list_entry(tmp, struct fs_db, fsdb_list);
331 if (strcmp(fsdb->fsdb_name, fsname) == 0)
337 /* caller must hold the mgs->mgs_fs_db_lock */
338 static struct fs_db *mgs_new_fsdb(const struct lu_env *env,
339 struct mgs_device *mgs, char *fsname)
345 if (strlen(fsname) >= sizeof(fsdb->fsdb_name)) {
346 CERROR("fsname %s is too long\n", fsname);
347 RETURN(ERR_PTR(-EINVAL));
352 RETURN(ERR_PTR(-ENOMEM));
354 strcpy(fsdb->fsdb_name, fsname);
355 mutex_init(&fsdb->fsdb_mutex);
356 set_bit(FSDB_UDESC, &fsdb->fsdb_flags);
359 if (strcmp(fsname, MGSSELF_NAME) == 0) {
360 set_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags);
361 fsdb->fsdb_mgs = mgs;
363 OBD_ALLOC(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
364 OBD_ALLOC(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
365 if (!fsdb->fsdb_ost_index_map || !fsdb->fsdb_mdt_index_map) {
366 CERROR("No memory for index maps\n");
367 GOTO(err, rc = -ENOMEM);
370 rc = name_create(&fsdb->fsdb_clilov, fsname, "-clilov");
373 rc = name_create(&fsdb->fsdb_clilmv, fsname, "-clilmv");
377 /* initialise data for NID table */
378 mgs_ir_init_fs(env, mgs, fsdb);
380 lproc_mgs_add_live(mgs, fsdb);
383 list_add(&fsdb->fsdb_list, &mgs->mgs_fs_db_list);
387 if (fsdb->fsdb_ost_index_map)
388 OBD_FREE(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
389 if (fsdb->fsdb_mdt_index_map)
390 OBD_FREE(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
391 name_destroy(&fsdb->fsdb_clilov);
392 name_destroy(&fsdb->fsdb_clilmv);
397 static void mgs_free_fsdb(struct mgs_device *mgs, struct fs_db *fsdb)
399 /* wait for anyone with the sem */
400 mutex_lock(&fsdb->fsdb_mutex);
401 lproc_mgs_del_live(mgs, fsdb);
402 list_del(&fsdb->fsdb_list);
404 /* deinitialize fsr */
405 mgs_ir_fini_fs(mgs, fsdb);
407 if (fsdb->fsdb_ost_index_map)
408 OBD_FREE(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
409 if (fsdb->fsdb_mdt_index_map)
410 OBD_FREE(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
411 name_destroy(&fsdb->fsdb_clilov);
412 name_destroy(&fsdb->fsdb_clilmv);
413 mgs_free_fsdb_srpc(fsdb);
414 mutex_unlock(&fsdb->fsdb_mutex);
418 int mgs_init_fsdb_list(struct mgs_device *mgs)
420 INIT_LIST_HEAD(&mgs->mgs_fs_db_list);
424 int mgs_cleanup_fsdb_list(struct mgs_device *mgs)
427 struct list_head *tmp, *tmp2;
429 mutex_lock(&mgs->mgs_mutex);
430 list_for_each_safe(tmp, tmp2, &mgs->mgs_fs_db_list) {
431 fsdb = list_entry(tmp, struct fs_db, fsdb_list);
432 mgs_free_fsdb(mgs, fsdb);
434 mutex_unlock(&mgs->mgs_mutex);
438 int mgs_find_or_make_fsdb(const struct lu_env *env,
439 struct mgs_device *mgs, char *name,
446 mutex_lock(&mgs->mgs_mutex);
447 fsdb = mgs_find_fsdb(mgs, name);
449 mutex_unlock(&mgs->mgs_mutex);
454 CDEBUG(D_MGS, "Creating new db\n");
455 fsdb = mgs_new_fsdb(env, mgs, name);
456 /* lock fsdb_mutex until the db is loaded from llogs */
458 mutex_lock(&fsdb->fsdb_mutex);
459 mutex_unlock(&mgs->mgs_mutex);
461 RETURN(PTR_ERR(fsdb));
463 if (!test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
464 /* populate the db from the client llog */
465 rc = mgs_get_fsdb_from_llog(env, mgs, fsdb);
467 CERROR("Can't get db from client log %d\n", rc);
472 /* populate srpc rules from params llog */
473 rc = mgs_get_fsdb_srpc_from_llog(env, mgs, fsdb);
475 CERROR("Can't get db from params log %d\n", rc);
479 mutex_unlock(&fsdb->fsdb_mutex);
485 mutex_unlock(&fsdb->fsdb_mutex);
486 mgs_free_fsdb(mgs, fsdb);
492 -1= empty client log */
493 int mgs_check_index(const struct lu_env *env,
494 struct mgs_device *mgs,
495 struct mgs_target_info *mti)
502 LASSERT(!(mti->mti_flags & LDD_F_NEED_INDEX));
504 rc = mgs_find_or_make_fsdb(env, mgs, mti->mti_fsname, &fsdb);
506 CERROR("Can't get db for %s\n", mti->mti_fsname);
510 if (test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags))
513 if (mti->mti_flags & LDD_F_SV_TYPE_OST)
514 imap = fsdb->fsdb_ost_index_map;
515 else if (mti->mti_flags & LDD_F_SV_TYPE_MDT)
516 imap = fsdb->fsdb_mdt_index_map;
520 if (test_bit(mti->mti_stripe_index, imap))
525 static __inline__ int next_index(void *index_map, int map_len)
528 for (i = 0; i < map_len * 8; i++)
529 if (!test_bit(i, index_map)) {
532 CERROR("max index %d exceeded.\n", i);
537 0 newly marked as in use
539 +EALREADY for update of an old index */
540 static int mgs_set_index(const struct lu_env *env,
541 struct mgs_device *mgs,
542 struct mgs_target_info *mti)
549 rc = mgs_find_or_make_fsdb(env, mgs, mti->mti_fsname, &fsdb);
551 CERROR("Can't get db for %s\n", mti->mti_fsname);
555 mutex_lock(&fsdb->fsdb_mutex);
556 if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
557 imap = fsdb->fsdb_ost_index_map;
558 } else if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
559 imap = fsdb->fsdb_mdt_index_map;
561 GOTO(out_up, rc = -EINVAL);
564 if (mti->mti_flags & LDD_F_NEED_INDEX) {
565 rc = next_index(imap, INDEX_MAP_SIZE);
567 GOTO(out_up, rc = -ERANGE);
568 mti->mti_stripe_index = rc;
569 if (mti->mti_flags & LDD_F_SV_TYPE_MDT)
570 fsdb->fsdb_mdt_count ++;
573 /* the last index(0xffff) is reserved for default value. */
574 if (mti->mti_stripe_index >= INDEX_MAP_SIZE * 8 - 1) {
575 LCONSOLE_ERROR_MSG(0x13f, "Server %s requested index %u, "
576 "but index must be less than %u.\n",
577 mti->mti_svname, mti->mti_stripe_index,
578 INDEX_MAP_SIZE * 8 - 1);
579 GOTO(out_up, rc = -ERANGE);
582 if (test_bit(mti->mti_stripe_index, imap)) {
583 if ((mti->mti_flags & LDD_F_VIRGIN) &&
584 !(mti->mti_flags & LDD_F_WRITECONF)) {
585 LCONSOLE_ERROR_MSG(0x140, "Server %s requested index "
586 "%d, but that index is already in "
587 "use. Use --writeconf to force\n",
589 mti->mti_stripe_index);
590 GOTO(out_up, rc = -EADDRINUSE);
592 CDEBUG(D_MGS, "Server %s updating index %d\n",
593 mti->mti_svname, mti->mti_stripe_index);
594 GOTO(out_up, rc = EALREADY);
598 set_bit(mti->mti_stripe_index, imap);
599 clear_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags);
600 mutex_unlock(&fsdb->fsdb_mutex);
601 server_make_name(mti->mti_flags & ~(LDD_F_VIRGIN | LDD_F_WRITECONF),
602 mti->mti_stripe_index, mti->mti_fsname, mti->mti_svname);
604 CDEBUG(D_MGS, "Set index for %s to %d\n", mti->mti_svname,
605 mti->mti_stripe_index);
609 mutex_unlock(&fsdb->fsdb_mutex);
613 struct mgs_modify_lookup {
614 struct cfg_marker mml_marker;
618 static int mgs_modify_handler(const struct lu_env *env,
619 struct llog_handle *llh,
620 struct llog_rec_hdr *rec, void *data)
622 struct mgs_modify_lookup *mml = data;
623 struct cfg_marker *marker;
624 struct lustre_cfg *lcfg = REC_DATA(rec);
625 int cfg_len = REC_DATA_LEN(rec);
629 if (rec->lrh_type != OBD_CFG_REC) {
630 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
634 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
636 CERROR("Insane cfg\n");
640 /* We only care about markers */
641 if (lcfg->lcfg_command != LCFG_MARKER)
644 marker = lustre_cfg_buf(lcfg, 1);
645 if ((strcmp(mml->mml_marker.cm_comment, marker->cm_comment) == 0) &&
646 (strcmp(mml->mml_marker.cm_tgtname, marker->cm_tgtname) == 0) &&
647 !(marker->cm_flags & CM_SKIP)) {
648 /* Found a non-skipped marker match */
649 CDEBUG(D_MGS, "Changing rec %u marker %d %x->%x: %s %s\n",
650 rec->lrh_index, marker->cm_step,
651 marker->cm_flags, mml->mml_marker.cm_flags,
652 marker->cm_tgtname, marker->cm_comment);
653 /* Overwrite the old marker llog entry */
654 marker->cm_flags &= ~CM_EXCLUDE; /* in case we're unexcluding */
655 marker->cm_flags |= mml->mml_marker.cm_flags;
656 marker->cm_canceltime = mml->mml_marker.cm_canceltime;
657 rc = llog_write(env, llh, rec, rec->lrh_index);
666 * Modify an existing config log record (for CM_SKIP or CM_EXCLUDE)
668 * 0 - modified successfully,
669 * 1 - no modification was done
672 static int mgs_modify(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, int flags)
676 struct llog_handle *loghandle;
677 struct llog_ctxt *ctxt;
678 struct mgs_modify_lookup *mml;
683 LASSERT(mutex_is_locked(&fsdb->fsdb_mutex));
684 CDEBUG(D_MGS, "modify %s/%s/%s fl=%x\n", logname, devname, comment,
687 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
688 LASSERT(ctxt != NULL);
689 rc = llog_open(env, ctxt, &loghandle, NULL, logname, LLOG_OPEN_EXISTS);
696 rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL);
700 if (llog_get_size(loghandle) <= 1)
701 GOTO(out_close, rc = 0);
705 GOTO(out_close, rc = -ENOMEM);
706 if (strlcpy(mml->mml_marker.cm_comment, comment,
707 sizeof(mml->mml_marker.cm_comment)) >=
708 sizeof(mml->mml_marker.cm_comment))
709 GOTO(out_free, rc = -E2BIG);
710 if (strlcpy(mml->mml_marker.cm_tgtname, devname,
711 sizeof(mml->mml_marker.cm_tgtname)) >=
712 sizeof(mml->mml_marker.cm_tgtname))
713 GOTO(out_free, rc = -E2BIG);
714 /* Modify mostly means cancel */
715 mml->mml_marker.cm_flags = flags;
716 mml->mml_marker.cm_canceltime = flags ? cfs_time_current_sec() : 0;
717 mml->mml_modified = 0;
718 rc = llog_process(env, loghandle, mgs_modify_handler, (void *)mml,
720 if (!rc && !mml->mml_modified)
727 llog_close(env, loghandle);
730 CERROR("%s: modify %s/%s failed: rc = %d\n",
731 mgs->mgs_obd->obd_name, mti->mti_svname, comment, rc);
736 /** This structure is passed to mgs_replace_handler */
737 struct mgs_replace_uuid_lookup {
738 /* Nids are replaced for this target device */
739 struct mgs_target_info target;
740 /* Temporary modified llog */
741 struct llog_handle *temp_llh;
742 /* Flag is set if in target block*/
743 int in_target_device;
744 /* Nids already added. Just skip (multiple nids) */
745 int device_nids_added;
746 /* Flag is set if this block should not be copied */
751 * Check: a) if block should be skipped
752 * b) is it target block
757 * \retval 0 should not to be skipped
758 * \retval 1 should to be skipped
760 static int check_markers(struct lustre_cfg *lcfg,
761 struct mgs_replace_uuid_lookup *mrul)
763 struct cfg_marker *marker;
765 /* Track markers. Find given device */
766 if (lcfg->lcfg_command == LCFG_MARKER) {
767 marker = lustre_cfg_buf(lcfg, 1);
768 /* Clean llog from records marked as CM_EXCLUDE.
769 CM_SKIP records are used for "active" command
770 and can be restored if needed */
771 if ((marker->cm_flags & (CM_EXCLUDE | CM_START)) ==
772 (CM_EXCLUDE | CM_START)) {
777 if ((marker->cm_flags & (CM_EXCLUDE | CM_END)) ==
778 (CM_EXCLUDE | CM_END)) {
783 if (strcmp(mrul->target.mti_svname, marker->cm_tgtname) == 0) {
784 LASSERT(!(marker->cm_flags & CM_START) ||
785 !(marker->cm_flags & CM_END));
786 if (marker->cm_flags & CM_START) {
787 mrul->in_target_device = 1;
788 mrul->device_nids_added = 0;
789 } else if (marker->cm_flags & CM_END)
790 mrul->in_target_device = 0;
797 static int record_base(const struct lu_env *env, struct llog_handle *llh,
798 char *cfgname, lnet_nid_t nid, int cmd,
799 char *s1, char *s2, char *s3, char *s4)
801 struct mgs_thread_info *mgi = mgs_env_info(env);
802 struct llog_cfg_rec *lcr;
805 CDEBUG(D_MGS, "lcfg %s %#x %s %s %s %s\n", cfgname,
806 cmd, s1, s2, s3, s4);
808 lustre_cfg_bufs_reset(&mgi->mgi_bufs, cfgname);
810 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, s1);
812 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 2, s2);
814 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 3, s3);
816 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 4, s4);
818 lcr = lustre_cfg_rec_new(cmd, &mgi->mgi_bufs);
822 lcr->lcr_cfg.lcfg_nid = nid;
823 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
825 lustre_cfg_rec_free(lcr);
829 "failed to write lcfg %s %#x %s %s %s %s: rc = %d\n",
830 cfgname, cmd, s1, s2, s3, s4, rc);
834 static inline int record_add_uuid(const struct lu_env *env,
835 struct llog_handle *llh,
836 uint64_t nid, char *uuid)
838 return record_base(env, llh, NULL, nid, LCFG_ADD_UUID, uuid,
842 static inline int record_add_conn(const struct lu_env *env,
843 struct llog_handle *llh,
844 char *devname, char *uuid)
846 return record_base(env, llh, devname, 0, LCFG_ADD_CONN, uuid,
850 static inline int record_attach(const struct lu_env *env,
851 struct llog_handle *llh, char *devname,
852 char *type, char *uuid)
854 return record_base(env, llh, devname, 0, LCFG_ATTACH, type, uuid,
858 static inline int record_setup(const struct lu_env *env,
859 struct llog_handle *llh, char *devname,
860 char *s1, char *s2, char *s3, char *s4)
862 return record_base(env, llh, devname, 0, LCFG_SETUP, s1, s2, s3, s4);
866 * \retval <0 record processing error
867 * \retval n record is processed. No need copy original one.
868 * \retval 0 record is not processed.
870 static int process_command(const struct lu_env *env, struct lustre_cfg *lcfg,
871 struct mgs_replace_uuid_lookup *mrul)
878 if (lcfg->lcfg_command == LCFG_ADD_UUID) {
879 /* LCFG_ADD_UUID command found. Let's skip original command
880 and add passed nids */
881 ptr = mrul->target.mti_params;
882 while (class_parse_nid(ptr, &nid, &ptr) == 0) {
883 CDEBUG(D_MGS, "add nid %s with uuid %s, "
884 "device %s\n", libcfs_nid2str(nid),
885 mrul->target.mti_params,
886 mrul->target.mti_svname);
887 rc = record_add_uuid(env,
889 mrul->target.mti_params);
894 if (nids_added == 0) {
895 CERROR("No new nids were added, nid %s with uuid %s, "
896 "device %s\n", libcfs_nid2str(nid),
897 mrul->target.mti_params,
898 mrul->target.mti_svname);
901 mrul->device_nids_added = 1;
907 if (mrul->device_nids_added && lcfg->lcfg_command == LCFG_SETUP) {
908 /* LCFG_SETUP command found. UUID should be changed */
909 rc = record_setup(env,
911 /* devname the same */
912 lustre_cfg_string(lcfg, 0),
913 /* s1 is not changed */
914 lustre_cfg_string(lcfg, 1),
915 /* new uuid should be
917 mrul->target.mti_params,
918 /* s3 is not changed */
919 lustre_cfg_string(lcfg, 3),
920 /* s4 is not changed */
921 lustre_cfg_string(lcfg, 4));
925 /* Another commands in target device block */
930 * Handler that called for every record in llog.
931 * Records are processed in order they placed in llog.
933 * \param[in] llh log to be processed
934 * \param[in] rec current record
935 * \param[in] data mgs_replace_uuid_lookup structure
939 static int mgs_replace_handler(const struct lu_env *env,
940 struct llog_handle *llh,
941 struct llog_rec_hdr *rec,
944 struct mgs_replace_uuid_lookup *mrul;
945 struct lustre_cfg *lcfg = REC_DATA(rec);
946 int cfg_len = REC_DATA_LEN(rec);
950 mrul = (struct mgs_replace_uuid_lookup *)data;
952 if (rec->lrh_type != OBD_CFG_REC) {
953 CERROR("unhandled lrh_type: %#x, cmd %x %s %s\n",
954 rec->lrh_type, lcfg->lcfg_command,
955 lustre_cfg_string(lcfg, 0),
956 lustre_cfg_string(lcfg, 1));
960 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
962 /* Do not copy any invalidated records */
963 GOTO(skip_out, rc = 0);
966 rc = check_markers(lcfg, mrul);
967 if (rc || mrul->skip_it)
968 GOTO(skip_out, rc = 0);
970 /* Write to new log all commands outside target device block */
971 if (!mrul->in_target_device)
972 GOTO(copy_out, rc = 0);
974 /* Skip all other LCFG_ADD_UUID and LCFG_ADD_CONN records
975 (failover nids) for this target, assuming that if then
976 primary is changing then so is the failover */
977 if (mrul->device_nids_added &&
978 (lcfg->lcfg_command == LCFG_ADD_UUID ||
979 lcfg->lcfg_command == LCFG_ADD_CONN))
980 GOTO(skip_out, rc = 0);
982 rc = process_command(env, lcfg, mrul);
989 /* Record is placed in temporary llog as is */
990 rc = llog_write(env, mrul->temp_llh, rec, LLOG_NEXT_IDX);
992 CDEBUG(D_MGS, "Copied idx=%d, rc=%d, len=%d, cmd %x %s %s\n",
993 rec->lrh_index, rc, rec->lrh_len, lcfg->lcfg_command,
994 lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));
998 CDEBUG(D_MGS, "Skipped idx=%d, rc=%d, len=%d, cmd %x %s %s\n",
999 rec->lrh_index, rc, rec->lrh_len, lcfg->lcfg_command,
1000 lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));
1004 static int mgs_log_is_empty(const struct lu_env *env,
1005 struct mgs_device *mgs, char *name)
1007 struct llog_ctxt *ctxt;
1010 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
1011 LASSERT(ctxt != NULL);
1013 rc = llog_is_empty(env, ctxt, name);
1014 llog_ctxt_put(ctxt);
1018 static int mgs_replace_nids_log(const struct lu_env *env,
1019 struct obd_device *mgs, struct fs_db *fsdb,
1020 char *logname, char *devname, char *nids)
1022 struct llog_handle *orig_llh, *backup_llh;
1023 struct llog_ctxt *ctxt;
1024 struct mgs_replace_uuid_lookup *mrul;
1025 struct mgs_device *mgs_dev = lu2mgs_dev(mgs->obd_lu_dev);
1026 static struct obd_uuid cfg_uuid = { .uuid = "config_uuid" };
1031 CDEBUG(D_MGS, "Replace nids for %s in %s\n", devname, logname);
1033 ctxt = llog_get_context(mgs, LLOG_CONFIG_ORIG_CTXT);
1034 LASSERT(ctxt != NULL);
1036 if (mgs_log_is_empty(env, mgs_dev, logname)) {
1037 /* Log is empty. Nothing to replace */
1038 GOTO(out_put, rc = 0);
1041 OBD_ALLOC(backup, strlen(logname) + strlen(".bak") + 1);
1043 GOTO(out_put, rc = -ENOMEM);
1045 sprintf(backup, "%s.bak", logname);
1047 rc = llog_backup(env, mgs, ctxt, ctxt, logname, backup);
1049 /* Now erase original log file. Connections are not allowed.
1050 Backup is already saved */
1051 rc = llog_erase(env, ctxt, NULL, logname);
1054 } else if (rc != -ENOENT) {
1055 CERROR("%s: can't make backup for %s: rc = %d\n",
1056 mgs->obd_name, logname, rc);
1060 /* open local log */
1061 rc = llog_open_create(env, ctxt, &orig_llh, NULL, logname);
1063 GOTO(out_restore, rc);
1065 rc = llog_init_handle(env, orig_llh, LLOG_F_IS_PLAIN, &cfg_uuid);
1067 GOTO(out_closel, rc);
1069 /* open backup llog */
1070 rc = llog_open(env, ctxt, &backup_llh, NULL, backup,
1073 GOTO(out_closel, rc);
1075 rc = llog_init_handle(env, backup_llh, LLOG_F_IS_PLAIN, NULL);
1077 GOTO(out_close, rc);
1079 if (llog_get_size(backup_llh) <= 1)
1080 GOTO(out_close, rc = 0);
1082 OBD_ALLOC_PTR(mrul);
1084 GOTO(out_close, rc = -ENOMEM);
1085 /* devname is only needed information to replace UUID records */
1086 strlcpy(mrul->target.mti_svname, devname,
1087 sizeof(mrul->target.mti_svname));
1088 /* parse nids later */
1089 strlcpy(mrul->target.mti_params, nids, sizeof(mrul->target.mti_params));
1090 /* Copy records to this temporary llog */
1091 mrul->temp_llh = orig_llh;
1093 rc = llog_process(env, backup_llh, mgs_replace_handler,
1094 (void *)mrul, NULL);
1097 rc2 = llog_close(NULL, backup_llh);
1101 rc2 = llog_close(NULL, orig_llh);
1107 CERROR("%s: llog should be restored: rc = %d\n",
1109 rc2 = llog_backup(env, mgs, ctxt, ctxt, backup,
1112 CERROR("%s: can't restore backup %s: rc = %d\n",
1113 mgs->obd_name, logname, rc2);
1117 OBD_FREE(backup, strlen(backup) + 1);
1120 llog_ctxt_put(ctxt);
1123 CERROR("%s: failed to replace nids in log %s: rc = %d\n",
1124 mgs->obd_name, logname, rc);
1130 * Parse device name and get file system name and/or device index
1132 * \param[in] devname device name (ex. lustre-MDT0000)
1133 * \param[out] fsname file system name(optional)
1134 * \param[out] index device index(optional)
1138 static int mgs_parse_devname(char *devname, char *fsname, __u32 *index)
1143 /* Extract fsname */
1145 rc = server_name2fsname(devname, fsname, NULL);
1147 CDEBUG(D_MGS, "Device name %s without fsname\n",
1154 rc = server_name2index(devname, index, NULL);
1156 CDEBUG(D_MGS, "Device name %s with wrong index\n",
1165 /* This is only called during replace_nids */
1166 static int only_mgs_is_running(struct obd_device *mgs_obd)
1168 /* TDB: Is global variable with devices count exists? */
1169 int num_devices = get_devices_count();
1170 int num_exports = 0;
1171 struct obd_export *exp;
1173 spin_lock(&mgs_obd->obd_dev_lock);
1174 list_for_each_entry(exp, &mgs_obd->obd_exports, exp_obd_chain) {
1175 /* skip self export */
1176 if (exp == mgs_obd->obd_self_export)
1178 if (exp_connect_flags(exp) & OBD_CONNECT_MDS_MDS)
1183 CERROR("%s: node %s still connected during replace_nids "
1184 "connect_flags:%llx\n",
1186 libcfs_nid2str(exp->exp_nid_stats->nid),
1187 exp_connect_flags(exp));
1190 spin_unlock(&mgs_obd->obd_dev_lock);
1192 /* osd, MGS and MGC + self_export
1193 (wc -l /proc/fs/lustre/devices <= 2) && (non self exports == 0) */
1194 return (num_devices <= 3) && (num_exports == 0);
1197 static int name_create_mdt(char **logname, char *fsname, int i)
1201 sprintf(mdt_index, "-MDT%04x", i);
1202 return name_create(logname, fsname, mdt_index);
1206 * Replace nids for \a device to \a nids values
1208 * \param obd MGS obd device
1209 * \param devname nids need to be replaced for this device
1210 * (ex. lustre-OST0000)
1211 * \param nids nids list (ex. nid1,nid2,nid3)
1215 int mgs_replace_nids(const struct lu_env *env,
1216 struct mgs_device *mgs,
1217 char *devname, char *nids)
1219 /* Assume fsname is part of device name */
1220 char fsname[MTI_NAME_MAXLEN];
1227 struct obd_device *mgs_obd = mgs->mgs_obd;
1230 /* We can only change NIDs if no other nodes are connected */
1231 spin_lock(&mgs_obd->obd_dev_lock);
1232 conn_state = mgs_obd->obd_no_conn;
1233 mgs_obd->obd_no_conn = 1;
1234 spin_unlock(&mgs_obd->obd_dev_lock);
1236 /* We can not change nids if not only MGS is started */
1237 if (!only_mgs_is_running(mgs_obd)) {
1238 CERROR("Only MGS is allowed to be started\n");
1239 GOTO(out, rc = -EINPROGRESS);
1242 /* Get fsname and index*/
1243 rc = mgs_parse_devname(devname, fsname, &index);
1247 rc = mgs_find_or_make_fsdb(env, mgs, fsname, &fsdb);
1249 CERROR("%s: can't find fsdb: rc = %d\n", fsname, rc);
1253 /* Process client llogs */
1254 name_create(&logname, fsname, "-client");
1255 rc = mgs_replace_nids_log(env, mgs_obd, fsdb, logname, devname, nids);
1256 name_destroy(&logname);
1258 CERROR("%s: error while replacing NIDs for %s: rc = %d\n",
1259 fsname, devname, rc);
1263 /* Process MDT llogs */
1264 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
1265 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
1267 name_create_mdt(&logname, fsname, i);
1268 rc = mgs_replace_nids_log(env, mgs_obd, fsdb, logname, devname, nids);
1269 name_destroy(&logname);
1275 spin_lock(&mgs_obd->obd_dev_lock);
1276 mgs_obd->obd_no_conn = conn_state;
1277 spin_unlock(&mgs_obd->obd_dev_lock);
1282 static int record_lov_setup(const struct lu_env *env, struct llog_handle *llh,
1283 char *devname, struct lov_desc *desc)
1285 struct mgs_thread_info *mgi = mgs_env_info(env);
1286 struct llog_cfg_rec *lcr;
1289 lustre_cfg_bufs_reset(&mgi->mgi_bufs, devname);
1290 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, desc, sizeof(*desc));
1291 lcr = lustre_cfg_rec_new(LCFG_SETUP, &mgi->mgi_bufs);
1295 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1296 lustre_cfg_rec_free(lcr);
1300 static int record_lmv_setup(const struct lu_env *env, struct llog_handle *llh,
1301 char *devname, struct lmv_desc *desc)
1303 struct mgs_thread_info *mgi = mgs_env_info(env);
1304 struct llog_cfg_rec *lcr;
1307 lustre_cfg_bufs_reset(&mgi->mgi_bufs, devname);
1308 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, desc, sizeof(*desc));
1309 lcr = lustre_cfg_rec_new(LCFG_SETUP, &mgi->mgi_bufs);
1313 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1314 lustre_cfg_rec_free(lcr);
1318 static inline int record_mdc_add(const struct lu_env *env,
1319 struct llog_handle *llh,
1320 char *logname, char *mdcuuid,
1321 char *mdtuuid, char *index,
1324 return record_base(env,llh,logname,0,LCFG_ADD_MDC,
1325 mdtuuid,index,gen,mdcuuid);
1328 static inline int record_lov_add(const struct lu_env *env,
1329 struct llog_handle *llh,
1330 char *lov_name, char *ost_uuid,
1331 char *index, char *gen)
1333 return record_base(env, llh, lov_name, 0, LCFG_LOV_ADD_OBD,
1334 ost_uuid, index, gen, NULL);
1337 static inline int record_mount_opt(const struct lu_env *env,
1338 struct llog_handle *llh,
1339 char *profile, char *lov_name,
1342 return record_base(env, llh, NULL, 0, LCFG_MOUNTOPT,
1343 profile, lov_name, mdc_name, NULL);
1346 static int record_marker(const struct lu_env *env,
1347 struct llog_handle *llh,
1348 struct fs_db *fsdb, __u32 flags,
1349 char *tgtname, char *comment)
1351 struct mgs_thread_info *mgi = mgs_env_info(env);
1352 struct llog_cfg_rec *lcr;
1356 if (flags & CM_START)
1358 mgi->mgi_marker.cm_step = fsdb->fsdb_gen;
1359 mgi->mgi_marker.cm_flags = flags;
1360 mgi->mgi_marker.cm_vers = LUSTRE_VERSION_CODE;
1361 cplen = strlcpy(mgi->mgi_marker.cm_tgtname, tgtname,
1362 sizeof(mgi->mgi_marker.cm_tgtname));
1363 if (cplen >= sizeof(mgi->mgi_marker.cm_tgtname))
1365 cplen = strlcpy(mgi->mgi_marker.cm_comment, comment,
1366 sizeof(mgi->mgi_marker.cm_comment));
1367 if (cplen >= sizeof(mgi->mgi_marker.cm_comment))
1369 mgi->mgi_marker.cm_createtime = cfs_time_current_sec();
1370 mgi->mgi_marker.cm_canceltime = 0;
1371 lustre_cfg_bufs_reset(&mgi->mgi_bufs, NULL);
1372 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, &mgi->mgi_marker,
1373 sizeof(mgi->mgi_marker));
1374 lcr = lustre_cfg_rec_new(LCFG_MARKER, &mgi->mgi_bufs);
1378 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1379 lustre_cfg_rec_free(lcr);
1383 static int record_start_log(const struct lu_env *env, struct mgs_device *mgs,
1384 struct llog_handle **llh, char *name)
1386 static struct obd_uuid cfg_uuid = { .uuid = "config_uuid" };
1387 struct llog_ctxt *ctxt;
1392 GOTO(out, rc = -EBUSY);
1394 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
1396 GOTO(out, rc = -ENODEV);
1397 LASSERT(ctxt->loc_obd == mgs->mgs_obd);
1399 rc = llog_open_create(env, ctxt, llh, NULL, name);
1402 rc = llog_init_handle(env, *llh, LLOG_F_IS_PLAIN, &cfg_uuid);
1404 llog_close(env, *llh);
1406 llog_ctxt_put(ctxt);
1409 CERROR("%s: can't start log %s: rc = %d\n",
1410 mgs->mgs_obd->obd_name, name, rc);
1416 static int record_end_log(const struct lu_env *env, struct llog_handle **llh)
1420 rc = llog_close(env, *llh);
1426 /******************** config "macros" *********************/
1428 /* write an lcfg directly into a log (with markers) */
1429 static int mgs_write_log_direct(const struct lu_env *env,
1430 struct mgs_device *mgs, struct fs_db *fsdb,
1431 char *logname, struct llog_cfg_rec *lcr,
1432 char *devname, char *comment)
1434 struct llog_handle *llh = NULL;
1439 rc = record_start_log(env, mgs, &llh, logname);
1443 /* FIXME These should be a single journal transaction */
1444 rc = record_marker(env, llh, fsdb, CM_START, devname, comment);
1447 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1450 rc = record_marker(env, llh, fsdb, CM_END, devname, comment);
1454 record_end_log(env, &llh);
1458 /* write the lcfg in all logs for the given fs */
1459 static int mgs_write_log_direct_all(const struct lu_env *env,
1460 struct mgs_device *mgs,
1462 struct mgs_target_info *mti,
1463 struct llog_cfg_rec *lcr, char *devname,
1464 char *comment, int server_only)
1466 struct list_head log_list;
1467 struct mgs_direntry *dirent, *n;
1468 char *fsname = mti->mti_fsname;
1469 int rc = 0, len = strlen(fsname);
1472 /* Find all the logs in the CONFIGS directory */
1473 rc = class_dentry_readdir(env, mgs, &log_list);
1477 /* Could use fsdb index maps instead of directory listing */
1478 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
1479 list_del_init(&dirent->mde_list);
1480 /* don't write to sptlrpc rule log */
1481 if (strstr(dirent->mde_name, "-sptlrpc") != NULL)
1484 /* caller wants write server logs only */
1485 if (server_only && strstr(dirent->mde_name, "-client") != NULL)
1488 if (strlen(dirent->mde_name) <= len ||
1489 strncmp(fsname, dirent->mde_name, len) != 0 ||
1490 dirent->mde_name[len] != '-')
1493 CDEBUG(D_MGS, "Changing log %s\n", dirent->mde_name);
1494 /* Erase any old settings of this same parameter */
1495 rc = mgs_modify(env, mgs, fsdb, mti, dirent->mde_name,
1496 devname, comment, CM_SKIP);
1498 CERROR("%s: Can't modify llog %s: rc = %d\n",
1499 mgs->mgs_obd->obd_name, dirent->mde_name, rc);
1502 /* Write the new one */
1503 rc = mgs_write_log_direct(env, mgs, fsdb, dirent->mde_name,
1504 lcr, devname, comment);
1506 CERROR("%s: writing log %s: rc = %d\n",
1507 mgs->mgs_obd->obd_name, dirent->mde_name, rc);
1509 mgs_direntry_free(dirent);
1515 static int mgs_write_log_osp_to_mdt(const struct lu_env *env,
1516 struct mgs_device *mgs,
1518 struct mgs_target_info *mti,
1519 int index, char *logname);
1520 static int mgs_write_log_osc_to_lov(const struct lu_env *env,
1521 struct mgs_device *mgs,
1523 struct mgs_target_info *mti,
1524 char *logname, char *suffix, char *lovname,
1525 enum lustre_sec_part sec_part, int flags);
1526 static int name_create_mdt_and_lov(char **logname, char **lovname,
1527 struct fs_db *fsdb, int i);
1529 static int add_param(char *params, char *key, char *val)
1531 char *start = params + strlen(params);
1532 char *end = params + sizeof(((struct mgs_target_info *)0)->mti_params);
1536 keylen = strlen(key);
1537 if (start + 1 + keylen + strlen(val) >= end) {
1538 CERROR("params are too long: %s %s%s\n",
1539 params, key != NULL ? key : "", val);
1543 sprintf(start, " %s%s", key != NULL ? key : "", val);
1548 * Walk through client config log record and convert the related records
1551 static int mgs_steal_client_llog_handler(const struct lu_env *env,
1552 struct llog_handle *llh,
1553 struct llog_rec_hdr *rec, void *data)
1555 struct mgs_device *mgs;
1556 struct obd_device *obd;
1557 struct mgs_target_info *mti, *tmti;
1559 int cfg_len = rec->lrh_len;
1560 char *cfg_buf = (char*) (rec + 1);
1561 struct lustre_cfg *lcfg;
1563 struct llog_handle *mdt_llh = NULL;
1564 static int got_an_osc_or_mdc = 0;
1565 /* 0: not found any osc/mdc;
1569 static int last_step = -1;
1574 mti = ((struct temp_comp*)data)->comp_mti;
1575 tmti = ((struct temp_comp*)data)->comp_tmti;
1576 fsdb = ((struct temp_comp*)data)->comp_fsdb;
1577 obd = ((struct temp_comp *)data)->comp_obd;
1578 mgs = lu2mgs_dev(obd->obd_lu_dev);
1581 if (rec->lrh_type != OBD_CFG_REC) {
1582 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
1586 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
1588 CERROR("Insane cfg\n");
1592 lcfg = (struct lustre_cfg *)cfg_buf;
1594 if (lcfg->lcfg_command == LCFG_MARKER) {
1595 struct cfg_marker *marker;
1596 marker = lustre_cfg_buf(lcfg, 1);
1597 if (!strncmp(marker->cm_comment, "add osc", 7) &&
1598 (marker->cm_flags & CM_START) &&
1599 !(marker->cm_flags & CM_SKIP)) {
1600 got_an_osc_or_mdc = 1;
1601 cplen = strlcpy(tmti->mti_svname, marker->cm_tgtname,
1602 sizeof(tmti->mti_svname));
1603 if (cplen >= sizeof(tmti->mti_svname))
1605 rc = record_start_log(env, mgs, &mdt_llh,
1609 rc = record_marker(env, mdt_llh, fsdb, CM_START,
1610 mti->mti_svname, "add osc(copied)");
1611 record_end_log(env, &mdt_llh);
1612 last_step = marker->cm_step;
1615 if (!strncmp(marker->cm_comment, "add osc", 7) &&
1616 (marker->cm_flags & CM_END) &&
1617 !(marker->cm_flags & CM_SKIP)) {
1618 LASSERT(last_step == marker->cm_step);
1620 got_an_osc_or_mdc = 0;
1621 memset(tmti, 0, sizeof(*tmti));
1622 rc = record_start_log(env, mgs, &mdt_llh,
1626 rc = record_marker(env, mdt_llh, fsdb, CM_END,
1627 mti->mti_svname, "add osc(copied)");
1628 record_end_log(env, &mdt_llh);
1631 if (!strncmp(marker->cm_comment, "add mdc", 7) &&
1632 (marker->cm_flags & CM_START) &&
1633 !(marker->cm_flags & CM_SKIP)) {
1634 got_an_osc_or_mdc = 2;
1635 last_step = marker->cm_step;
1636 memcpy(tmti->mti_svname, marker->cm_tgtname,
1637 strlen(marker->cm_tgtname));
1641 if (!strncmp(marker->cm_comment, "add mdc", 7) &&
1642 (marker->cm_flags & CM_END) &&
1643 !(marker->cm_flags & CM_SKIP)) {
1644 LASSERT(last_step == marker->cm_step);
1646 got_an_osc_or_mdc = 0;
1647 memset(tmti, 0, sizeof(*tmti));
1652 if (got_an_osc_or_mdc == 0 || last_step < 0)
1655 if (lcfg->lcfg_command == LCFG_ADD_UUID) {
1656 __u64 nodenid = lcfg->lcfg_nid;
1658 if (strlen(tmti->mti_uuid) == 0) {
1659 /* target uuid not set, this config record is before
1660 * LCFG_SETUP, this nid is one of target node nid.
1662 tmti->mti_nids[tmti->mti_nid_count] = nodenid;
1663 tmti->mti_nid_count++;
1665 char nidstr[LNET_NIDSTR_SIZE];
1667 /* failover node nid */
1668 libcfs_nid2str_r(nodenid, nidstr, sizeof(nidstr));
1669 rc = add_param(tmti->mti_params, PARAM_FAILNODE,
1676 if (lcfg->lcfg_command == LCFG_SETUP) {
1679 target = lustre_cfg_string(lcfg, 1);
1680 memcpy(tmti->mti_uuid, target, strlen(target));
1684 /* ignore client side sptlrpc_conf_log */
1685 if (lcfg->lcfg_command == LCFG_SPTLRPC_CONF)
1688 if (lcfg->lcfg_command == LCFG_ADD_MDC) {
1691 if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1)
1694 memcpy(tmti->mti_fsname, mti->mti_fsname,
1695 strlen(mti->mti_fsname));
1696 tmti->mti_stripe_index = index;
1698 rc = mgs_write_log_osp_to_mdt(env, mgs, fsdb, tmti,
1699 mti->mti_stripe_index,
1701 memset(tmti, 0, sizeof(*tmti));
1705 if (lcfg->lcfg_command == LCFG_LOV_ADD_OBD) {
1708 char *logname, *lovname;
1710 rc = name_create_mdt_and_lov(&logname, &lovname, fsdb,
1711 mti->mti_stripe_index);
1714 sprintf(mdt_index, "-MDT%04x", mti->mti_stripe_index);
1716 if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1) {
1717 name_destroy(&logname);
1718 name_destroy(&lovname);
1722 tmti->mti_stripe_index = index;
1723 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, tmti, logname,
1726 name_destroy(&logname);
1727 name_destroy(&lovname);
1733 /* fsdb->fsdb_mutex is already held in mgs_write_log_target*/
1734 /* stealed from mgs_get_fsdb_from_llog*/
1735 static int mgs_steal_llog_for_mdt_from_client(const struct lu_env *env,
1736 struct mgs_device *mgs,
1738 struct temp_comp* comp)
1740 struct llog_handle *loghandle;
1741 struct mgs_target_info *tmti;
1742 struct llog_ctxt *ctxt;
1747 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
1748 LASSERT(ctxt != NULL);
1750 OBD_ALLOC_PTR(tmti);
1752 GOTO(out_ctxt, rc = -ENOMEM);
1754 comp->comp_tmti = tmti;
1755 comp->comp_obd = mgs->mgs_obd;
1757 rc = llog_open(env, ctxt, &loghandle, NULL, client_name,
1765 rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL);
1767 GOTO(out_close, rc);
1769 rc = llog_process_or_fork(env, loghandle, mgs_steal_client_llog_handler,
1770 (void *)comp, NULL, false);
1771 CDEBUG(D_MGS, "steal llog re = %d\n", rc);
1773 llog_close(env, loghandle);
1777 llog_ctxt_put(ctxt);
1781 /* lmv is the second thing for client logs */
1782 /* copied from mgs_write_log_lov. Please refer to that. */
1783 static int mgs_write_log_lmv(const struct lu_env *env,
1784 struct mgs_device *mgs,
1786 struct mgs_target_info *mti,
1787 char *logname, char *lmvname)
1789 struct llog_handle *llh = NULL;
1790 struct lmv_desc *lmvdesc;
1795 CDEBUG(D_MGS, "Writing lmv(%s) log for %s\n", lmvname,logname);
1797 OBD_ALLOC_PTR(lmvdesc);
1798 if (lmvdesc == NULL)
1800 lmvdesc->ld_active_tgt_count = 0;
1801 lmvdesc->ld_tgt_count = 0;
1802 sprintf((char*)lmvdesc->ld_uuid.uuid, "%s_UUID", lmvname);
1803 uuid = (char *)lmvdesc->ld_uuid.uuid;
1805 rc = record_start_log(env, mgs, &llh, logname);
1808 rc = record_marker(env, llh, fsdb, CM_START, lmvname, "lmv setup");
1811 rc = record_attach(env, llh, lmvname, "lmv", uuid);
1814 rc = record_lmv_setup(env, llh, lmvname, lmvdesc);
1817 rc = record_marker(env, llh, fsdb, CM_END, lmvname, "lmv setup");
1821 record_end_log(env, &llh);
1823 OBD_FREE_PTR(lmvdesc);
1827 /* lov is the first thing in the mdt and client logs */
1828 static int mgs_write_log_lov(const struct lu_env *env, struct mgs_device *mgs,
1829 struct fs_db *fsdb, struct mgs_target_info *mti,
1830 char *logname, char *lovname)
1832 struct llog_handle *llh = NULL;
1833 struct lov_desc *lovdesc;
1838 CDEBUG(D_MGS, "Writing lov(%s) log for %s\n", lovname, logname);
1841 #01 L attach 0:lov_mdsA 1:lov 2:71ccb_lov_mdsA_19f961a9e1
1842 #02 L lov_setup 0:lov_mdsA 1:(struct lov_desc)
1843 uuid=lov1_UUID, stripe count=1, size=1048576, offset=0, pattern=0
1846 /* FIXME just make lov_setup accept empty desc (put uuid in buf 2) */
1847 OBD_ALLOC_PTR(lovdesc);
1848 if (lovdesc == NULL)
1850 lovdesc->ld_magic = LOV_DESC_MAGIC;
1851 lovdesc->ld_tgt_count = 0;
1852 /* Defaults. Can be changed later by lcfg config_param */
1853 lovdesc->ld_default_stripe_count = 1;
1854 lovdesc->ld_pattern = LOV_PATTERN_RAID0;
1855 lovdesc->ld_default_stripe_size = LOV_DESC_STRIPE_SIZE_DEFAULT;
1856 lovdesc->ld_default_stripe_offset = -1;
1857 lovdesc->ld_qos_maxage = LOV_DESC_QOS_MAXAGE_DEFAULT;
1858 sprintf((char*)lovdesc->ld_uuid.uuid, "%s_UUID", lovname);
1859 /* can these be the same? */
1860 uuid = (char *)lovdesc->ld_uuid.uuid;
1862 /* This should always be the first entry in a log.
1863 rc = mgs_clear_log(obd, logname); */
1864 rc = record_start_log(env, mgs, &llh, logname);
1867 /* FIXME these should be a single journal transaction */
1868 rc = record_marker(env, llh, fsdb, CM_START, lovname, "lov setup");
1871 rc = record_attach(env, llh, lovname, "lov", uuid);
1874 rc = record_lov_setup(env, llh, lovname, lovdesc);
1877 rc = record_marker(env, llh, fsdb, CM_END, lovname, "lov setup");
1882 record_end_log(env, &llh);
1884 OBD_FREE_PTR(lovdesc);
1888 /* add failnids to open log */
1889 static int mgs_write_log_failnids(const struct lu_env *env,
1890 struct mgs_target_info *mti,
1891 struct llog_handle *llh,
1894 char *failnodeuuid = NULL;
1895 char *ptr = mti->mti_params;
1900 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) nal=90 0: 1:uml1_UUID
1901 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
1902 #05 L setup 0:OSC_uml1_ost1_mdsA 1:ost1_UUID 2:uml1_UUID
1903 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) nal=90 0: 1:uml2_UUID
1904 #0x L add_uuid nid=2@elan(0x1000000000002) nal=90 0: 1:uml2_UUID
1905 #07 L add_conn 0:OSC_uml1_ost1_mdsA 1:uml2_UUID
1909 * Pull failnid info out of params string, which may contain something
1910 * like "<nid1>,<nid2>:<nid3>,<nid4>". class_parse_nid() does not
1911 * complain about abnormal inputs like ",:<nid1>", "<nid1>:,<nid2>",
1912 * etc. However, convert_hostnames() should have caught those.
1914 while (class_find_param(ptr, PARAM_FAILNODE, &ptr) == 0) {
1915 while (class_parse_nid(ptr, &nid, &ptr) == 0) {
1916 char nidstr[LNET_NIDSTR_SIZE];
1918 if (failnodeuuid == NULL) {
1919 /* We don't know the failover node name,
1920 * so just use the first nid as the uuid */
1921 libcfs_nid2str_r(nid, nidstr, sizeof(nidstr));
1922 rc = name_create(&failnodeuuid, nidstr, "");
1926 CDEBUG(D_MGS, "add nid %s for failover uuid %s, "
1928 libcfs_nid2str_r(nid, nidstr, sizeof(nidstr)),
1929 failnodeuuid, cliname);
1930 rc = record_add_uuid(env, llh, nid, failnodeuuid);
1932 * If *ptr is ':', we have added all NIDs for
1936 rc = record_add_conn(env, llh, cliname,
1938 name_destroy(&failnodeuuid);
1939 failnodeuuid = NULL;
1943 rc = record_add_conn(env, llh, cliname, failnodeuuid);
1944 name_destroy(&failnodeuuid);
1945 failnodeuuid = NULL;
1952 static int mgs_write_log_mdc_to_lmv(const struct lu_env *env,
1953 struct mgs_device *mgs,
1955 struct mgs_target_info *mti,
1956 char *logname, char *lmvname)
1958 struct llog_handle *llh = NULL;
1959 char *mdcname = NULL;
1960 char *nodeuuid = NULL;
1961 char *mdcuuid = NULL;
1962 char *lmvuuid = NULL;
1964 char nidstr[LNET_NIDSTR_SIZE];
1968 if (mgs_log_is_empty(env, mgs, logname)) {
1969 CERROR("log is empty! Logical error\n");
1973 CDEBUG(D_MGS, "adding mdc for %s to log %s:lmv(%s)\n",
1974 mti->mti_svname, logname, lmvname);
1976 libcfs_nid2str_r(mti->mti_nids[0], nidstr, sizeof(nidstr));
1977 rc = name_create(&nodeuuid, nidstr, "");
1980 rc = name_create(&mdcname, mti->mti_svname, "-mdc");
1983 rc = name_create(&mdcuuid, mdcname, "_UUID");
1986 rc = name_create(&lmvuuid, lmvname, "_UUID");
1990 rc = record_start_log(env, mgs, &llh, logname);
1993 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
1997 for (i = 0; i < mti->mti_nid_count; i++) {
1998 CDEBUG(D_MGS, "add nid %s for mdt\n",
1999 libcfs_nid2str_r(mti->mti_nids[i],
2000 nidstr, sizeof(nidstr)));
2002 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
2007 rc = record_attach(env, llh, mdcname, LUSTRE_MDC_NAME, lmvuuid);
2010 rc = record_setup(env, llh, mdcname, mti->mti_uuid, nodeuuid,
2014 rc = mgs_write_log_failnids(env, mti, llh, mdcname);
2017 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
2018 rc = record_mdc_add(env, llh, lmvname, mdcuuid, mti->mti_uuid,
2022 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname,
2027 record_end_log(env, &llh);
2029 name_destroy(&lmvuuid);
2030 name_destroy(&mdcuuid);
2031 name_destroy(&mdcname);
2032 name_destroy(&nodeuuid);
2036 static inline int name_create_lov(char **lovname, char *mdtname,
2037 struct fs_db *fsdb, int index)
2040 if (index == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2041 return name_create(lovname, fsdb->fsdb_name, "-mdtlov");
2043 return name_create(lovname, mdtname, "-mdtlov");
2046 static int name_create_mdt_and_lov(char **logname, char **lovname,
2047 struct fs_db *fsdb, int i)
2051 rc = name_create_mdt(logname, fsdb->fsdb_name, i);
2055 if (i == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2056 rc = name_create(lovname, fsdb->fsdb_name, "-mdtlov");
2058 rc = name_create(lovname, *logname, "-mdtlov");
2060 name_destroy(logname);
2066 static inline int name_create_mdt_osc(char **oscname, char *ostname,
2067 struct fs_db *fsdb, int i)
2071 if (i == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2072 sprintf(suffix, "-osc");
2074 sprintf(suffix, "-osc-MDT%04x", i);
2075 return name_create(oscname, ostname, suffix);
2078 /* add new mdc to already existent MDS */
2079 static int mgs_write_log_osp_to_mdt(const struct lu_env *env,
2080 struct mgs_device *mgs,
2082 struct mgs_target_info *mti,
2083 int mdt_index, char *logname)
2085 struct llog_handle *llh = NULL;
2086 char *nodeuuid = NULL;
2087 char *ospname = NULL;
2088 char *lovuuid = NULL;
2089 char *mdtuuid = NULL;
2090 char *svname = NULL;
2091 char *mdtname = NULL;
2092 char *lovname = NULL;
2094 char nidstr[LNET_NIDSTR_SIZE];
2098 if (mgs_log_is_empty(env, mgs, mti->mti_svname)) {
2099 CERROR("log is empty! Logical error\n");
2103 CDEBUG(D_MGS, "adding osp index %d to %s\n", mti->mti_stripe_index,
2106 rc = name_create_mdt(&mdtname, fsdb->fsdb_name, mti->mti_stripe_index);
2110 libcfs_nid2str_r(mti->mti_nids[0], nidstr, sizeof(nidstr));
2111 rc = name_create(&nodeuuid, nidstr, "");
2113 GOTO(out_destory, rc);
2115 rc = name_create(&svname, mdtname, "-osp");
2117 GOTO(out_destory, rc);
2119 sprintf(index_str, "-MDT%04x", mdt_index);
2120 rc = name_create(&ospname, svname, index_str);
2122 GOTO(out_destory, rc);
2124 rc = name_create_lov(&lovname, logname, fsdb, mdt_index);
2126 GOTO(out_destory, rc);
2128 rc = name_create(&lovuuid, lovname, "_UUID");
2130 GOTO(out_destory, rc);
2132 rc = name_create(&mdtuuid, mdtname, "_UUID");
2134 GOTO(out_destory, rc);
2136 rc = record_start_log(env, mgs, &llh, logname);
2138 GOTO(out_destory, rc);
2140 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
2143 GOTO(out_destory, rc);
2145 for (i = 0; i < mti->mti_nid_count; i++) {
2146 CDEBUG(D_MGS, "add nid %s for mdt\n",
2147 libcfs_nid2str_r(mti->mti_nids[i],
2148 nidstr, sizeof(nidstr)));
2149 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
2154 rc = record_attach(env, llh, ospname, LUSTRE_OSP_NAME, lovuuid);
2158 rc = record_setup(env, llh, ospname, mti->mti_uuid, nodeuuid,
2163 rc = mgs_write_log_failnids(env, mti, llh, ospname);
2167 /* Add mdc(osp) to lod */
2168 snprintf(index_str, sizeof(index_str), "%d", mti->mti_stripe_index);
2169 rc = record_base(env, llh, lovname, 0, LCFG_ADD_MDC, mti->mti_uuid,
2170 index_str, "1", NULL);
2174 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname, "add osp");
2179 record_end_log(env, &llh);
2182 name_destroy(&mdtuuid);
2183 name_destroy(&lovuuid);
2184 name_destroy(&lovname);
2185 name_destroy(&ospname);
2186 name_destroy(&svname);
2187 name_destroy(&nodeuuid);
2188 name_destroy(&mdtname);
2192 static int mgs_write_log_mdt0(const struct lu_env *env,
2193 struct mgs_device *mgs,
2195 struct mgs_target_info *mti)
2197 char *log = mti->mti_svname;
2198 struct llog_handle *llh = NULL;
2199 char *uuid, *lovname;
2201 char *ptr = mti->mti_params;
2202 int rc = 0, failout = 0;
2205 OBD_ALLOC(uuid, sizeof(struct obd_uuid));
2209 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
2210 failout = (strncmp(ptr, "failout", 7) == 0);
2212 rc = name_create(&lovname, log, "-mdtlov");
2215 if (mgs_log_is_empty(env, mgs, log)) {
2216 rc = mgs_write_log_lov(env, mgs, fsdb, mti, log, lovname);
2221 sprintf(mdt_index, "%d", mti->mti_stripe_index);
2223 rc = record_start_log(env, mgs, &llh, log);
2227 /* add MDT itself */
2229 /* FIXME this whole fn should be a single journal transaction */
2230 sprintf(uuid, "%s_UUID", log);
2231 rc = record_marker(env, llh, fsdb, CM_START, log, "add mdt");
2234 rc = record_attach(env, llh, log, LUSTRE_MDT_NAME, uuid);
2237 rc = record_mount_opt(env, llh, log, lovname, NULL);
2240 rc = record_setup(env, llh, log, uuid, mdt_index, lovname,
2241 failout ? "n" : "f");
2244 rc = record_marker(env, llh, fsdb, CM_END, log, "add mdt");
2248 record_end_log(env, &llh);
2250 name_destroy(&lovname);
2252 OBD_FREE(uuid, sizeof(struct obd_uuid));
2256 /* envelope method for all layers log */
2257 static int mgs_write_log_mdt(const struct lu_env *env,
2258 struct mgs_device *mgs,
2260 struct mgs_target_info *mti)
2262 struct mgs_thread_info *mgi = mgs_env_info(env);
2263 struct llog_handle *llh = NULL;
2268 CDEBUG(D_MGS, "writing new mdt %s\n", mti->mti_svname);
2270 if (mti->mti_uuid[0] == '\0') {
2271 /* Make up our own uuid */
2272 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
2273 "%s_UUID", mti->mti_svname);
2277 rc = mgs_write_log_mdt0(env, mgs, fsdb, mti);
2280 /* Append the mdt info to the client log */
2281 rc = name_create(&cliname, mti->mti_fsname, "-client");
2285 if (mgs_log_is_empty(env, mgs, cliname)) {
2286 /* Start client log */
2287 rc = mgs_write_log_lov(env, mgs, fsdb, mti, cliname,
2291 rc = mgs_write_log_lmv(env, mgs, fsdb, mti, cliname,
2298 #09 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
2299 #10 L attach 0:MDC_uml1_mdsA_MNT_client 1:mdc 2:1d834_MNT_client_03f
2300 #11 L setup 0:MDC_uml1_mdsA_MNT_client 1:mdsA_UUID 2:uml1_UUID
2301 #12 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
2302 #13 L add_conn 0:MDC_uml1_mdsA_MNT_client 1:uml2_UUID
2303 #14 L mount_option 0: 1:client 2:lov1 3:MDC_uml1_mdsA_MNT_client
2306 /* copy client info about lov/lmv */
2307 mgi->mgi_comp.comp_mti = mti;
2308 mgi->mgi_comp.comp_fsdb = fsdb;
2310 rc = mgs_steal_llog_for_mdt_from_client(env, mgs, cliname,
2314 rc = mgs_write_log_mdc_to_lmv(env, mgs, fsdb, mti, cliname,
2320 rc = record_start_log(env, mgs, &llh, cliname);
2324 rc = record_marker(env, llh, fsdb, CM_START, cliname,
2328 rc = record_mount_opt(env, llh, cliname, fsdb->fsdb_clilov,
2332 rc = record_marker(env, llh, fsdb, CM_END, cliname,
2338 /* for_all_existing_mdt except current one */
2339 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2340 if (i != mti->mti_stripe_index &&
2341 test_bit(i, fsdb->fsdb_mdt_index_map)) {
2344 rc = name_create_mdt(&logname, fsdb->fsdb_name, i);
2348 /* NB: If the log for the MDT is empty, it means
2349 * the MDT is only added to the index
2350 * map, and not being process yet, i.e. this
2351 * is an unregistered MDT, see mgs_write_log_target().
2352 * so we should skip it. Otherwise
2354 * 1. MGS get register request for MDT1 and MDT2.
2356 * 2. Then both MDT1 and MDT2 are added into
2357 * fsdb_mdt_index_map. (see mgs_set_index()).
2359 * 3. Then MDT1 get the lock of fsdb_mutex, then
2360 * generate the config log, here, it will regard MDT2
2361 * as an existent MDT, and generate "add osp" for
2362 * lustre-MDT0001-osp-MDT0002. Note: at the moment
2363 * MDT0002 config log is still empty, so it will
2364 * add "add osp" even before "lov setup", which
2365 * will definitly cause trouble.
2367 * 4. MDT1 registeration finished, fsdb_mutex is
2368 * released, then MDT2 get in, then in above
2369 * mgs_steal_llog_for_mdt_from_client(), it will
2370 * add another osp log for lustre-MDT0001-osp-MDT0002,
2371 * which will cause another trouble.*/
2372 if (!mgs_log_is_empty(env, mgs, logname))
2373 rc = mgs_write_log_osp_to_mdt(env, mgs, fsdb,
2376 name_destroy(&logname);
2382 record_end_log(env, &llh);
2384 name_destroy(&cliname);
2388 /* Add the ost info to the client/mdt lov */
2389 static int mgs_write_log_osc_to_lov(const struct lu_env *env,
2390 struct mgs_device *mgs, struct fs_db *fsdb,
2391 struct mgs_target_info *mti,
2392 char *logname, char *suffix, char *lovname,
2393 enum lustre_sec_part sec_part, int flags)
2395 struct llog_handle *llh = NULL;
2396 char *nodeuuid = NULL;
2397 char *oscname = NULL;
2398 char *oscuuid = NULL;
2399 char *lovuuid = NULL;
2400 char *svname = NULL;
2402 char nidstr[LNET_NIDSTR_SIZE];
2406 CDEBUG(D_INFO, "adding osc for %s to log %s\n",
2407 mti->mti_svname, logname);
2409 if (mgs_log_is_empty(env, mgs, logname)) {
2410 CERROR("log is empty! Logical error\n");
2414 libcfs_nid2str_r(mti->mti_nids[0], nidstr, sizeof(nidstr));
2415 rc = name_create(&nodeuuid, nidstr, "");
2418 rc = name_create(&svname, mti->mti_svname, "-osc");
2422 /* for the system upgraded from old 1.8, keep using the old osc naming
2423 * style for mdt, see name_create_mdt_osc(). LU-1257 */
2424 if (test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2425 rc = name_create(&oscname, svname, "");
2427 rc = name_create(&oscname, svname, suffix);
2431 rc = name_create(&oscuuid, oscname, "_UUID");
2434 rc = name_create(&lovuuid, lovname, "_UUID");
2440 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
2442 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
2443 #04 L attach 0:OSC_uml1_ost1_MNT_client 1:osc 2:89070_lov1_a41dff51a
2444 #05 L setup 0:OSC_uml1_ost1_MNT_client 1:ost1_UUID 2:uml1_UUID
2446 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
2447 #07 L add_conn 0:OSC_uml1_ost1_MNT_client 1:uml2_UUID
2448 #08 L lov_modify_tgts add 0:lov1 1:ost1_UUID 2(index):0 3(gen):1
2451 rc = record_start_log(env, mgs, &llh, logname);
2455 /* FIXME these should be a single journal transaction */
2456 rc = record_marker(env, llh, fsdb, CM_START | flags, mti->mti_svname,
2461 /* NB: don't change record order, because upon MDT steal OSC config
2462 * from client, it treats all nids before LCFG_SETUP as target nids
2463 * (multiple interfaces), while nids after as failover node nids.
2464 * See mgs_steal_client_llog_handler() LCFG_ADD_UUID.
2466 for (i = 0; i < mti->mti_nid_count; i++) {
2467 CDEBUG(D_MGS, "add nid %s\n",
2468 libcfs_nid2str_r(mti->mti_nids[i],
2469 nidstr, sizeof(nidstr)));
2470 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
2474 rc = record_attach(env, llh, oscname, LUSTRE_OSC_NAME, lovuuid);
2477 rc = record_setup(env, llh, oscname, mti->mti_uuid, nodeuuid,
2481 rc = mgs_write_log_failnids(env, mti, llh, oscname);
2485 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
2487 rc = record_lov_add(env, llh, lovname, mti->mti_uuid, index, "1");
2490 rc = record_marker(env, llh, fsdb, CM_END | flags, mti->mti_svname,
2495 record_end_log(env, &llh);
2497 name_destroy(&lovuuid);
2498 name_destroy(&oscuuid);
2499 name_destroy(&oscname);
2500 name_destroy(&svname);
2501 name_destroy(&nodeuuid);
2505 static int mgs_write_log_ost(const struct lu_env *env,
2506 struct mgs_device *mgs, struct fs_db *fsdb,
2507 struct mgs_target_info *mti)
2509 struct llog_handle *llh = NULL;
2510 char *logname, *lovname;
2511 char *ptr = mti->mti_params;
2512 int rc, flags = 0, failout = 0, i;
2515 CDEBUG(D_MGS, "writing new ost %s\n", mti->mti_svname);
2517 /* The ost startup log */
2519 /* If the ost log already exists, that means that someone reformatted
2520 the ost and it called target_add again. */
2521 if (!mgs_log_is_empty(env, mgs, mti->mti_svname)) {
2522 LCONSOLE_ERROR_MSG(0x141, "The config log for %s already "
2523 "exists, yet the server claims it never "
2524 "registered. It may have been reformatted, "
2525 "or the index changed. writeconf the MDT to "
2526 "regenerate all logs.\n", mti->mti_svname);
2531 attach obdfilter ost1 ost1_UUID
2532 setup /dev/loop2 ldiskfs f|n errors=remount-ro,user_xattr
2534 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
2535 failout = (strncmp(ptr, "failout", 7) == 0);
2536 rc = record_start_log(env, mgs, &llh, mti->mti_svname);
2539 /* FIXME these should be a single journal transaction */
2540 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,"add ost");
2543 if (*mti->mti_uuid == '\0')
2544 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
2545 "%s_UUID", mti->mti_svname);
2546 rc = record_attach(env, llh, mti->mti_svname,
2547 "obdfilter"/*LUSTRE_OST_NAME*/, mti->mti_uuid);
2550 rc = record_setup(env, llh, mti->mti_svname,
2551 "dev"/*ignored*/, "type"/*ignored*/,
2552 failout ? "n" : "f", NULL/*options*/);
2555 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname, "add ost");
2559 record_end_log(env, &llh);
2562 /* We also have to update the other logs where this osc is part of
2565 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
2566 /* If we're upgrading, the old mdt log already has our
2567 entry. Let's do a fake one for fun. */
2568 /* Note that we can't add any new failnids, since we don't
2569 know the old osc names. */
2570 flags = CM_SKIP | CM_UPGRADE146;
2572 } else if ((mti->mti_flags & LDD_F_UPDATE) != LDD_F_UPDATE) {
2573 /* If the update flag isn't set, don't update client/mdt
2576 LCONSOLE_WARN("Client log for %s was not updated; writeconf "
2577 "the MDT first to regenerate it.\n",
2581 /* Add ost to all MDT lov defs */
2582 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
2583 if (test_bit(i, fsdb->fsdb_mdt_index_map)) {
2586 rc = name_create_mdt_and_lov(&logname, &lovname, fsdb,
2590 sprintf(mdt_index, "-MDT%04x", i);
2591 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, mti,
2593 lovname, LUSTRE_SP_MDT,
2595 name_destroy(&logname);
2596 name_destroy(&lovname);
2602 /* Append ost info to the client log */
2603 rc = name_create(&logname, mti->mti_fsname, "-client");
2606 if (mgs_log_is_empty(env, mgs, logname)) {
2607 /* Start client log */
2608 rc = mgs_write_log_lov(env, mgs, fsdb, mti, logname,
2612 rc = mgs_write_log_lmv(env, mgs, fsdb, mti, logname,
2617 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, mti, logname, "",
2618 fsdb->fsdb_clilov, LUSTRE_SP_CLI, flags);
2620 name_destroy(&logname);
2624 static __inline__ int mgs_param_empty(char *ptr)
2628 if ((tmp = strchr(ptr, '=')) && (*(++tmp) == '\0'))
2633 static int mgs_write_log_failnid_internal(const struct lu_env *env,
2634 struct mgs_device *mgs,
2636 struct mgs_target_info *mti,
2637 char *logname, char *cliname)
2640 struct llog_handle *llh = NULL;
2642 if (mgs_param_empty(mti->mti_params)) {
2643 /* Remove _all_ failnids */
2644 rc = mgs_modify(env, mgs, fsdb, mti, logname,
2645 mti->mti_svname, "add failnid", CM_SKIP);
2646 return rc < 0 ? rc : 0;
2649 /* Otherwise failover nids are additive */
2650 rc = record_start_log(env, mgs, &llh, logname);
2653 /* FIXME this should be a single journal transaction */
2654 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
2658 rc = mgs_write_log_failnids(env, mti, llh, cliname);
2661 rc = record_marker(env, llh, fsdb, CM_END,
2662 mti->mti_svname, "add failnid");
2664 record_end_log(env, &llh);
2669 /* Add additional failnids to an existing log.
2670 The mdc/osc must have been added to logs first */
2671 /* tcp nids must be in dotted-quad ascii -
2672 we can't resolve hostnames from the kernel. */
2673 static int mgs_write_log_add_failnid(const struct lu_env *env,
2674 struct mgs_device *mgs,
2676 struct mgs_target_info *mti)
2678 char *logname, *cliname;
2682 /* FIXME we currently can't erase the failnids
2683 * given when a target first registers, since they aren't part of
2684 * an "add uuid" stanza */
2686 /* Verify that we know about this target */
2687 if (mgs_log_is_empty(env, mgs, mti->mti_svname)) {
2688 LCONSOLE_ERROR_MSG(0x142, "The target %s has not registered "
2689 "yet. It must be started before failnids "
2690 "can be added.\n", mti->mti_svname);
2694 /* Create mdc/osc client name (e.g. lustre-OST0001-osc) */
2695 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
2696 rc = name_create(&cliname, mti->mti_svname, "-mdc");
2697 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2698 rc = name_create(&cliname, mti->mti_svname, "-osc");
2704 /* Add failover nids to the client log */
2705 rc = name_create(&logname, mti->mti_fsname, "-client");
2707 name_destroy(&cliname);
2710 rc = mgs_write_log_failnid_internal(env, mgs, fsdb,mti,logname,cliname);
2711 name_destroy(&logname);
2712 name_destroy(&cliname);
2716 if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2717 /* Add OST failover nids to the MDT logs as well */
2720 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2721 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
2723 rc = name_create_mdt(&logname, mti->mti_fsname, i);
2726 rc = name_create_mdt_osc(&cliname, mti->mti_svname,
2729 name_destroy(&logname);
2732 rc = mgs_write_log_failnid_internal(env, mgs, fsdb,
2735 name_destroy(&cliname);
2736 name_destroy(&logname);
2745 static int mgs_wlp_lcfg(const struct lu_env *env,
2746 struct mgs_device *mgs, struct fs_db *fsdb,
2747 struct mgs_target_info *mti,
2748 char *logname, struct lustre_cfg_bufs *bufs,
2749 char *tgtname, char *ptr)
2751 char comment[MTI_NAME_MAXLEN];
2753 struct llog_cfg_rec *lcr;
2756 /* Erase any old settings of this same parameter */
2757 memcpy(comment, ptr, MTI_NAME_MAXLEN);
2758 comment[MTI_NAME_MAXLEN - 1] = 0;
2759 /* But don't try to match the value. */
2760 tmp = strchr(comment, '=');
2763 /* FIXME we should skip settings that are the same as old values */
2764 rc = mgs_modify(env, mgs, fsdb, mti, logname, tgtname, comment,CM_SKIP);
2767 del = mgs_param_empty(ptr);
2769 LCONSOLE_INFO("%s parameter %s.%s in log %s\n", del ? "Disabling" : rc ?
2770 "Setting" : "Modifying", tgtname, comment, logname);
2772 /* mgs_modify() will return 1 if nothing had to be done */
2778 lustre_cfg_bufs_reset(bufs, tgtname);
2779 lustre_cfg_bufs_set_string(bufs, 1, ptr);
2780 if (mti->mti_flags & LDD_F_PARAM2)
2781 lustre_cfg_bufs_set_string(bufs, 2, LCTL_UPCALL);
2783 lcr = lustre_cfg_rec_new((mti->mti_flags & LDD_F_PARAM2) ?
2784 LCFG_SET_PARAM : LCFG_PARAM, bufs);
2788 rc = mgs_write_log_direct(env, mgs, fsdb, logname, lcr, tgtname,
2790 lustre_cfg_rec_free(lcr);
2794 static int mgs_write_log_param2(const struct lu_env *env,
2795 struct mgs_device *mgs,
2797 struct mgs_target_info *mti, char *ptr)
2799 struct lustre_cfg_bufs bufs;
2803 CDEBUG(D_MGS, "next param '%s'\n", ptr);
2804 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, PARAMS_FILENAME, &bufs,
2805 mti->mti_svname, ptr);
2810 /* write global variable settings into log */
2811 static int mgs_write_log_sys(const struct lu_env *env,
2812 struct mgs_device *mgs, struct fs_db *fsdb,
2813 struct mgs_target_info *mti, char *sys, char *ptr)
2815 struct mgs_thread_info *mgi = mgs_env_info(env);
2816 struct lustre_cfg *lcfg;
2817 struct llog_cfg_rec *lcr;
2819 int rc, cmd, convert = 1;
2821 if (class_match_param(ptr, PARAM_TIMEOUT, &tmp) == 0) {
2822 cmd = LCFG_SET_TIMEOUT;
2823 } else if (class_match_param(ptr, PARAM_LDLM_TIMEOUT, &tmp) == 0) {
2824 cmd = LCFG_SET_LDLM_TIMEOUT;
2825 /* Check for known params here so we can return error to lctl */
2826 } else if ((class_match_param(ptr, PARAM_AT_MIN, &tmp) == 0) ||
2827 (class_match_param(ptr, PARAM_AT_MAX, &tmp) == 0) ||
2828 (class_match_param(ptr, PARAM_AT_EXTRA, &tmp) == 0) ||
2829 (class_match_param(ptr, PARAM_AT_EARLY_MARGIN, &tmp) == 0) ||
2830 (class_match_param(ptr, PARAM_AT_HISTORY, &tmp) == 0)) {
2832 } else if (class_match_param(ptr, PARAM_JOBID_VAR, &tmp) == 0) {
2833 convert = 0; /* Don't convert string value to integer */
2839 if (mgs_param_empty(ptr))
2840 CDEBUG(D_MGS, "global '%s' removed\n", sys);
2842 CDEBUG(D_MGS, "global '%s' val=%s\n", sys, tmp);
2844 lustre_cfg_bufs_reset(&mgi->mgi_bufs, NULL);
2845 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, sys);
2846 if (!convert && *tmp != '\0')
2847 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 2, tmp);
2848 lcr = lustre_cfg_rec_new(cmd, &mgi->mgi_bufs);
2852 lcfg = &lcr->lcr_cfg;
2853 lcfg->lcfg_num = convert ? simple_strtoul(tmp, NULL, 0) : 0;
2854 /* truncate the comment to the parameter name */
2858 /* modify all servers and clients */
2859 rc = mgs_write_log_direct_all(env, mgs, fsdb, mti,
2860 *tmp == '\0' ? NULL : lcr,
2861 mti->mti_fsname, sys, 0);
2862 if (rc == 0 && *tmp != '\0') {
2864 case LCFG_SET_TIMEOUT:
2865 if (!obd_timeout_set || lcfg->lcfg_num > obd_timeout)
2866 class_process_config(lcfg);
2868 case LCFG_SET_LDLM_TIMEOUT:
2869 if (!ldlm_timeout_set || lcfg->lcfg_num > ldlm_timeout)
2870 class_process_config(lcfg);
2877 lustre_cfg_rec_free(lcr);
2881 /* write quota settings into log */
2882 static int mgs_write_log_quota(const struct lu_env *env, struct mgs_device *mgs,
2883 struct fs_db *fsdb, struct mgs_target_info *mti,
2884 char *quota, char *ptr)
2886 struct mgs_thread_info *mgi = mgs_env_info(env);
2887 struct llog_cfg_rec *lcr;
2890 int rc, cmd = LCFG_PARAM;
2892 /* support only 'meta' and 'data' pools so far */
2893 if (class_match_param(ptr, QUOTA_METAPOOL_NAME, &tmp) != 0 &&
2894 class_match_param(ptr, QUOTA_DATAPOOL_NAME, &tmp) != 0) {
2895 CERROR("parameter quota.%s isn't supported (only quota.mdt "
2896 "& quota.ost are)\n", ptr);
2901 CDEBUG(D_MGS, "global '%s' removed\n", quota);
2903 CDEBUG(D_MGS, "global '%s'\n", quota);
2905 if (strchr(tmp, 'u') == NULL && strchr(tmp, 'g') == NULL &&
2906 strcmp(tmp, "none") != 0) {
2907 CERROR("enable option(%s) isn't supported\n", tmp);
2912 lustre_cfg_bufs_reset(&mgi->mgi_bufs, mti->mti_fsname);
2913 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, quota);
2914 lcr = lustre_cfg_rec_new(cmd, &mgi->mgi_bufs);
2918 /* truncate the comment to the parameter name */
2923 /* XXX we duplicated quota enable information in all server
2924 * config logs, it should be moved to a separate config
2925 * log once we cleanup the config log for global param. */
2926 /* modify all servers */
2927 rc = mgs_write_log_direct_all(env, mgs, fsdb, mti,
2928 *tmp == '\0' ? NULL : lcr,
2929 mti->mti_fsname, quota, 1);
2931 lustre_cfg_rec_free(lcr);
2932 return rc < 0 ? rc : 0;
2935 static int mgs_srpc_set_param_disk(const struct lu_env *env,
2936 struct mgs_device *mgs,
2938 struct mgs_target_info *mti,
2941 struct mgs_thread_info *mgi = mgs_env_info(env);
2942 struct llog_cfg_rec *lcr;
2943 struct llog_handle *llh = NULL;
2945 char *comment, *ptr;
2951 ptr = strchr(param, '=');
2952 LASSERT(ptr != NULL);
2955 OBD_ALLOC(comment, len + 1);
2956 if (comment == NULL)
2958 strncpy(comment, param, len);
2959 comment[len] = '\0';
2962 lustre_cfg_bufs_reset(&mgi->mgi_bufs, mti->mti_svname);
2963 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, param);
2964 lcr = lustre_cfg_rec_new(LCFG_SPTLRPC_CONF, &mgi->mgi_bufs);
2966 GOTO(out_comment, rc = -ENOMEM);
2968 /* construct log name */
2969 rc = name_create(&logname, mti->mti_fsname, "-sptlrpc");
2973 if (mgs_log_is_empty(env, mgs, logname)) {
2974 rc = record_start_log(env, mgs, &llh, logname);
2977 record_end_log(env, &llh);
2980 /* obsolete old one */
2981 rc = mgs_modify(env, mgs, fsdb, mti, logname, mti->mti_svname,
2985 /* write the new one */
2986 rc = mgs_write_log_direct(env, mgs, fsdb, logname, lcr,
2987 mti->mti_svname, comment);
2989 CERROR("%s: error writing log %s: rc = %d\n",
2990 mgs->mgs_obd->obd_name, logname, rc);
2992 name_destroy(&logname);
2994 lustre_cfg_rec_free(lcr);
2996 OBD_FREE(comment, len + 1);
3000 static int mgs_srpc_set_param_udesc_mem(struct fs_db *fsdb,
3005 /* disable the adjustable udesc parameter for now, i.e. use default
3006 * setting that client always ship udesc to MDT if possible. to enable
3007 * it simply remove the following line */
3010 ptr = strchr(param, '=');
3015 if (strcmp(param, PARAM_SRPC_UDESC))
3018 if (strcmp(ptr, "yes") == 0) {
3019 set_bit(FSDB_UDESC, &fsdb->fsdb_flags);
3020 CWARN("Enable user descriptor shipping from client to MDT\n");
3021 } else if (strcmp(ptr, "no") == 0) {
3022 clear_bit(FSDB_UDESC, &fsdb->fsdb_flags);
3023 CWARN("Disable user descriptor shipping from client to MDT\n");
3031 CERROR("Invalid param: %s\n", param);
3035 static int mgs_srpc_set_param_mem(struct fs_db *fsdb,
3039 struct sptlrpc_rule rule;
3040 struct sptlrpc_rule_set *rset;
3044 if (strncmp(param, PARAM_SRPC, sizeof(PARAM_SRPC) - 1) != 0) {
3045 CERROR("Invalid sptlrpc parameter: %s\n", param);
3049 if (strncmp(param, PARAM_SRPC_UDESC,
3050 sizeof(PARAM_SRPC_UDESC) - 1) == 0) {
3051 RETURN(mgs_srpc_set_param_udesc_mem(fsdb, param));
3054 if (strncmp(param, PARAM_SRPC_FLVR, sizeof(PARAM_SRPC_FLVR) - 1) != 0) {
3055 CERROR("Invalid sptlrpc flavor parameter: %s\n", param);
3059 param += sizeof(PARAM_SRPC_FLVR) - 1;
3061 rc = sptlrpc_parse_rule(param, &rule);
3065 /* mgs rules implies must be mgc->mgs */
3066 if (test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
3067 if ((rule.sr_from != LUSTRE_SP_MGC &&
3068 rule.sr_from != LUSTRE_SP_ANY) ||
3069 (rule.sr_to != LUSTRE_SP_MGS &&
3070 rule.sr_to != LUSTRE_SP_ANY))
3074 /* preapre room for this coming rule. svcname format should be:
3075 * - fsname: general rule
3076 * - fsname-tgtname: target-specific rule
3078 if (strchr(svname, '-')) {
3079 struct mgs_tgt_srpc_conf *tgtconf;
3082 for (tgtconf = fsdb->fsdb_srpc_tgt; tgtconf != NULL;
3083 tgtconf = tgtconf->mtsc_next) {
3084 if (!strcmp(tgtconf->mtsc_tgt, svname)) {
3093 OBD_ALLOC_PTR(tgtconf);
3094 if (tgtconf == NULL)
3097 name_len = strlen(svname);
3099 OBD_ALLOC(tgtconf->mtsc_tgt, name_len + 1);
3100 if (tgtconf->mtsc_tgt == NULL) {
3101 OBD_FREE_PTR(tgtconf);
3104 memcpy(tgtconf->mtsc_tgt, svname, name_len);
3106 tgtconf->mtsc_next = fsdb->fsdb_srpc_tgt;
3107 fsdb->fsdb_srpc_tgt = tgtconf;
3110 rset = &tgtconf->mtsc_rset;
3111 } else if (strcmp(svname, MGSSELF_NAME) == 0) {
3112 /* put _mgs related srpc rule directly in mgs ruleset */
3113 rset = &fsdb->fsdb_mgs->mgs_lut.lut_sptlrpc_rset;
3115 rset = &fsdb->fsdb_srpc_gen;
3118 rc = sptlrpc_rule_set_merge(rset, &rule);
3123 static int mgs_srpc_set_param(const struct lu_env *env,
3124 struct mgs_device *mgs,
3126 struct mgs_target_info *mti,
3136 /* keep a copy of original param, which could be destroied
3138 copy_size = strlen(param) + 1;
3139 OBD_ALLOC(copy, copy_size);
3142 memcpy(copy, param, copy_size);
3144 rc = mgs_srpc_set_param_mem(fsdb, mti->mti_svname, param);
3148 /* previous steps guaranteed the syntax is correct */
3149 rc = mgs_srpc_set_param_disk(env, mgs, fsdb, mti, copy);
3153 if (test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
3155 * for mgs rules, make them effective immediately.
3157 LASSERT(fsdb->fsdb_srpc_tgt == NULL);
3158 sptlrpc_target_update_exp_flavor(mgs->mgs_obd,
3159 &fsdb->fsdb_srpc_gen);
3163 OBD_FREE(copy, copy_size);
3167 struct mgs_srpc_read_data {
3168 struct fs_db *msrd_fsdb;
3172 static int mgs_srpc_read_handler(const struct lu_env *env,
3173 struct llog_handle *llh,
3174 struct llog_rec_hdr *rec, void *data)
3176 struct mgs_srpc_read_data *msrd = data;
3177 struct cfg_marker *marker;
3178 struct lustre_cfg *lcfg = REC_DATA(rec);
3179 char *svname, *param;
3183 if (rec->lrh_type != OBD_CFG_REC) {
3184 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
3188 cfg_len = REC_DATA_LEN(rec);
3190 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
3192 CERROR("Insane cfg\n");
3196 if (lcfg->lcfg_command == LCFG_MARKER) {
3197 marker = lustre_cfg_buf(lcfg, 1);
3199 if (marker->cm_flags & CM_START &&
3200 marker->cm_flags & CM_SKIP)
3201 msrd->msrd_skip = 1;
3202 if (marker->cm_flags & CM_END)
3203 msrd->msrd_skip = 0;
3208 if (msrd->msrd_skip)
3211 if (lcfg->lcfg_command != LCFG_SPTLRPC_CONF) {
3212 CERROR("invalid command (%x)\n", lcfg->lcfg_command);
3216 svname = lustre_cfg_string(lcfg, 0);
3217 if (svname == NULL) {
3218 CERROR("svname is empty\n");
3222 param = lustre_cfg_string(lcfg, 1);
3223 if (param == NULL) {
3224 CERROR("param is empty\n");
3228 rc = mgs_srpc_set_param_mem(msrd->msrd_fsdb, svname, param);
3230 CERROR("read sptlrpc record error (%d): %s\n", rc, param);
3235 int mgs_get_fsdb_srpc_from_llog(const struct lu_env *env,
3236 struct mgs_device *mgs,
3239 struct llog_handle *llh = NULL;
3240 struct llog_ctxt *ctxt;
3242 struct mgs_srpc_read_data msrd;
3246 /* construct log name */
3247 rc = name_create(&logname, fsdb->fsdb_name, "-sptlrpc");
3251 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
3252 LASSERT(ctxt != NULL);
3254 if (mgs_log_is_empty(env, mgs, logname))
3257 rc = llog_open(env, ctxt, &llh, NULL, logname,
3265 rc = llog_init_handle(env, llh, LLOG_F_IS_PLAIN, NULL);
3267 GOTO(out_close, rc);
3269 if (llog_get_size(llh) <= 1)
3270 GOTO(out_close, rc = 0);
3272 msrd.msrd_fsdb = fsdb;
3275 rc = llog_process(env, llh, mgs_srpc_read_handler, (void *)&msrd,
3279 llog_close(env, llh);
3281 llog_ctxt_put(ctxt);
3282 name_destroy(&logname);
3285 CERROR("failed to read sptlrpc config database: %d\n", rc);
3289 /* Permanent settings of all parameters by writing into the appropriate
3290 * configuration logs.
3291 * A parameter with null value ("<param>='\0'") means to erase it out of
3294 static int mgs_write_log_param(const struct lu_env *env,
3295 struct mgs_device *mgs, struct fs_db *fsdb,
3296 struct mgs_target_info *mti, char *ptr)
3298 struct mgs_thread_info *mgi = mgs_env_info(env);
3301 int rc = 0, rc2 = 0;
3304 /* For various parameter settings, we have to figure out which logs
3305 care about them (e.g. both mdt and client for lov settings) */
3306 CDEBUG(D_MGS, "next param '%s'\n", ptr);
3308 /* The params are stored in MOUNT_DATA_FILE and modified via
3309 tunefs.lustre, or set using lctl conf_param */
3311 /* Processed in lustre_start_mgc */
3312 if (class_match_param(ptr, PARAM_MGSNODE, NULL) == 0)
3315 /* Processed in ost/mdt */
3316 if (class_match_param(ptr, PARAM_NETWORK, NULL) == 0)
3319 /* Processed in mgs_write_log_ost */
3320 if (class_match_param(ptr, PARAM_FAILMODE, NULL) == 0) {
3321 if (mti->mti_flags & LDD_F_PARAM) {
3322 LCONSOLE_ERROR_MSG(0x169, "%s can only be "
3323 "changed with tunefs.lustre"
3324 "and --writeconf\n", ptr);
3330 if (class_match_param(ptr, PARAM_SRPC, NULL) == 0) {
3331 rc = mgs_srpc_set_param(env, mgs, fsdb, mti, ptr);
3335 if (class_match_param(ptr, PARAM_FAILNODE, NULL) == 0) {
3336 /* Add a failover nidlist */
3338 /* We already processed failovers params for new
3339 targets in mgs_write_log_target */
3340 if (mti->mti_flags & LDD_F_PARAM) {
3341 CDEBUG(D_MGS, "Adding failnode\n");
3342 rc = mgs_write_log_add_failnid(env, mgs, fsdb, mti);
3347 if (class_match_param(ptr, PARAM_SYS, &tmp) == 0) {
3348 rc = mgs_write_log_sys(env, mgs, fsdb, mti, ptr, tmp);
3352 if (class_match_param(ptr, PARAM_QUOTA, &tmp) == 0) {
3353 rc = mgs_write_log_quota(env, mgs, fsdb, mti, ptr, tmp);
3357 if (class_match_param(ptr, PARAM_OSC PARAM_ACTIVE, &tmp) == 0 ||
3358 class_match_param(ptr, PARAM_MDC PARAM_ACTIVE, &tmp) == 0) {
3359 /* active=0 means off, anything else means on */
3360 int flag = (*tmp == '0') ? CM_EXCLUDE : 0;
3361 bool deactive_osc = memcmp(ptr, PARAM_OSC PARAM_ACTIVE,
3362 strlen(PARAM_OSC PARAM_ACTIVE)) == 0;
3365 if (!deactive_osc) {
3368 rc = server_name2index(mti->mti_svname, &index, NULL);
3373 LCONSOLE_ERROR_MSG(0x144, "%s: MDC0 can not be"
3374 " (de)activated.\n",
3376 GOTO(end, rc = -EINVAL);
3380 LCONSOLE_WARN("Permanently %sactivating %s\n",
3381 flag ? "de" : "re", mti->mti_svname);
3383 rc = name_create(&logname, mti->mti_fsname, "-client");
3386 rc = mgs_modify(env, mgs, fsdb, mti, logname,
3388 deactive_osc ? "add osc" : "add mdc", flag);
3389 name_destroy(&logname);
3394 /* Add to all MDT logs for DNE */
3395 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3396 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
3398 rc = name_create_mdt(&logname, mti->mti_fsname, i);
3401 rc = mgs_modify(env, mgs, fsdb, mti, logname,
3403 deactive_osc ? "add osc" : "add osp",
3405 name_destroy(&logname);
3411 LCONSOLE_ERROR_MSG(0x145, "Couldn't find %s in"
3412 "log (%d). No permanent "
3413 "changes were made to the "
3415 mti->mti_svname, rc);
3416 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags))
3417 LCONSOLE_ERROR_MSG(0x146, "This may be"
3422 "update the logs.\n");
3425 /* Fall through to osc/mdc proc for deactivating live
3426 OSC/OSP on running MDT / clients. */
3428 /* Below here, let obd's XXX_process_config methods handle it */
3430 /* All lov. in proc */
3431 if (class_match_param(ptr, PARAM_LOV, NULL) == 0) {
3434 CDEBUG(D_MGS, "lov param %s\n", ptr);
3435 if (!(mti->mti_flags & LDD_F_SV_TYPE_MDT)) {
3436 LCONSOLE_ERROR_MSG(0x147, "LOV params must be "
3437 "set on the MDT, not %s. "
3444 if (mgs_log_is_empty(env, mgs, mti->mti_svname))
3445 GOTO(end, rc = -ENODEV);
3447 rc = name_create_mdt_and_lov(&logname, &mdtlovname, fsdb,
3448 mti->mti_stripe_index);
3451 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, mti->mti_svname,
3452 &mgi->mgi_bufs, mdtlovname, ptr);
3453 name_destroy(&logname);
3454 name_destroy(&mdtlovname);
3459 rc = name_create(&logname, mti->mti_fsname, "-client");
3462 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname, &mgi->mgi_bufs,
3463 fsdb->fsdb_clilov, ptr);
3464 name_destroy(&logname);
3468 /* All osc., mdc., llite. params in proc */
3469 if ((class_match_param(ptr, PARAM_OSC, NULL) == 0) ||
3470 (class_match_param(ptr, PARAM_MDC, NULL) == 0) ||
3471 (class_match_param(ptr, PARAM_LLITE, NULL) == 0)) {
3474 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
3475 LCONSOLE_ERROR_MSG(0x148, "Upgraded client logs for %s"
3476 " cannot be modified. Consider"
3477 " updating the configuration with"
3480 GOTO(end, rc = -EINVAL);
3482 if (memcmp(ptr, PARAM_LLITE, strlen(PARAM_LLITE)) == 0) {
3483 rc = name_create(&cname, mti->mti_fsname, "-client");
3484 /* Add the client type to match the obdname in
3485 class_config_llog_handler */
3486 } else if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
3487 rc = name_create(&cname, mti->mti_svname, "-mdc");
3488 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
3489 rc = name_create(&cname, mti->mti_svname, "-osc");
3491 GOTO(end, rc = -EINVAL);
3496 /* Forbid direct update of llite root squash parameters.
3497 * These parameters are indirectly set via the MDT settings.
3499 if ((class_match_param(ptr, PARAM_LLITE, &tmp) == 0) &&
3500 ((memcmp(tmp, "root_squash=", 12) == 0) ||
3501 (memcmp(tmp, "nosquash_nids=", 14) == 0))) {
3502 LCONSOLE_ERROR("%s: root squash parameters can only "
3503 "be updated through MDT component\n",
3505 name_destroy(&cname);
3506 GOTO(end, rc = -EINVAL);
3509 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
3512 rc = name_create(&logname, mti->mti_fsname, "-client");
3514 name_destroy(&cname);
3517 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname, &mgi->mgi_bufs,
3520 /* osc params affect the MDT as well */
3521 if (!rc && (mti->mti_flags & LDD_F_SV_TYPE_OST)) {
3524 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
3525 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
3527 name_destroy(&cname);
3528 rc = name_create_mdt_osc(&cname, mti->mti_svname,
3530 name_destroy(&logname);
3533 rc = name_create_mdt(&logname,
3534 mti->mti_fsname, i);
3537 if (!mgs_log_is_empty(env, mgs, logname)) {
3538 rc = mgs_wlp_lcfg(env, mgs, fsdb,
3548 /* For mdc activate/deactivate, it affects OSP on MDT as well */
3549 if (class_match_param(ptr, PARAM_MDC PARAM_ACTIVE, &tmp) == 0 &&
3552 char *lodname = NULL;
3553 char *param_str = NULL;
3557 /* replace mdc with osp */
3558 memcpy(ptr, PARAM_OSP, strlen(PARAM_OSP));
3559 rc = server_name2index(mti->mti_svname, &index, NULL);
3561 memcpy(ptr, PARAM_MDC, strlen(PARAM_MDC));
3565 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3566 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
3572 name_destroy(&logname);
3573 rc = name_create_mdt(&logname, mti->mti_fsname,
3578 if (mgs_log_is_empty(env, mgs, logname))
3581 snprintf(suffix, sizeof(suffix), "-osp-MDT%04x",
3583 name_destroy(&cname);
3584 rc = name_create(&cname, mti->mti_svname,
3589 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname,
3590 &mgi->mgi_bufs, cname, ptr);
3594 /* Add configuration log for noitfying LOD
3595 * to active/deactive the OSP. */
3596 name_destroy(¶m_str);
3597 rc = name_create(¶m_str, cname,
3598 (*tmp == '0') ? ".active=0" :
3603 name_destroy(&lodname);
3604 rc = name_create(&lodname, logname, "-mdtlov");
3608 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname,
3609 &mgi->mgi_bufs, lodname,
3614 memcpy(ptr, PARAM_MDC, strlen(PARAM_MDC));
3615 name_destroy(&lodname);
3616 name_destroy(¶m_str);
3619 name_destroy(&logname);
3620 name_destroy(&cname);
3624 /* All mdt. params in proc */
3625 if (class_match_param(ptr, PARAM_MDT, &tmp) == 0) {
3629 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
3630 if (strncmp(mti->mti_svname, mti->mti_fsname,
3631 MTI_NAME_MAXLEN) == 0)
3632 /* device is unspecified completely? */
3633 rc = LDD_F_SV_TYPE_MDT | LDD_F_SV_ALL;
3635 rc = server_name2index(mti->mti_svname, &idx, NULL);
3638 if ((rc & LDD_F_SV_TYPE_MDT) == 0)
3640 if (rc & LDD_F_SV_ALL) {
3641 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3643 fsdb->fsdb_mdt_index_map))
3645 rc = name_create_mdt(&logname,
3646 mti->mti_fsname, i);
3649 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti,
3650 logname, &mgi->mgi_bufs,
3652 name_destroy(&logname);
3657 if ((memcmp(tmp, "root_squash=", 12) == 0) ||
3658 (memcmp(tmp, "nosquash_nids=", 14) == 0)) {
3659 LCONSOLE_ERROR("%s: root squash parameters "
3660 "cannot be applied to a single MDT\n",
3662 GOTO(end, rc = -EINVAL);
3664 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti,
3665 mti->mti_svname, &mgi->mgi_bufs,
3666 mti->mti_svname, ptr);
3671 /* root squash settings are also applied to llite
3672 * config log (see LU-1778) */
3674 ((memcmp(tmp, "root_squash=", 12) == 0) ||
3675 (memcmp(tmp, "nosquash_nids=", 14) == 0))) {
3679 rc = name_create(&cname, mti->mti_fsname, "-client");
3682 rc = name_create(&logname, mti->mti_fsname, "-client");
3684 name_destroy(&cname);
3687 rc = name_create(&ptr2, PARAM_LLITE, tmp);
3689 name_destroy(&cname);
3690 name_destroy(&logname);
3693 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname,
3694 &mgi->mgi_bufs, cname, ptr2);
3695 name_destroy(&ptr2);
3696 name_destroy(&logname);
3697 name_destroy(&cname);
3702 /* All mdd., ost. and osd. params in proc */
3703 if ((class_match_param(ptr, PARAM_MDD, NULL) == 0) ||
3704 (class_match_param(ptr, PARAM_OST, NULL) == 0) ||
3705 (class_match_param(ptr, PARAM_OSD, NULL) == 0)) {
3706 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
3707 if (mgs_log_is_empty(env, mgs, mti->mti_svname))
3708 GOTO(end, rc = -ENODEV);
3710 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, mti->mti_svname,
3711 &mgi->mgi_bufs, mti->mti_svname, ptr);
3715 LCONSOLE_WARN("Ignoring unrecognized param '%s'\n", ptr);
3720 CERROR("err %d on param '%s'\n", rc, ptr);
3725 int mgs_write_log_target(const struct lu_env *env, struct mgs_device *mgs,
3726 struct mgs_target_info *mti, struct fs_db *fsdb)
3733 /* set/check the new target index */
3734 rc = mgs_set_index(env, mgs, mti);
3738 if (rc == EALREADY) {
3739 LCONSOLE_WARN("Found index %d for %s, updating log\n",
3740 mti->mti_stripe_index, mti->mti_svname);
3741 /* We would like to mark old log sections as invalid
3742 and add new log sections in the client and mdt logs.
3743 But if we add new sections, then live clients will
3744 get repeat setup instructions for already running
3745 osc's. So don't update the client/mdt logs. */
3746 mti->mti_flags &= ~LDD_F_UPDATE;
3750 OBD_FAIL_TIMEOUT(OBD_FAIL_MGS_WRITE_TARGET_DELAY, cfs_fail_val > 0 ?
3753 mutex_lock(&fsdb->fsdb_mutex);
3755 if (mti->mti_flags &
3756 (LDD_F_VIRGIN | LDD_F_UPGRADE14 | LDD_F_WRITECONF)) {
3757 /* Generate a log from scratch */
3758 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
3759 rc = mgs_write_log_mdt(env, mgs, fsdb, mti);
3760 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
3761 rc = mgs_write_log_ost(env, mgs, fsdb, mti);
3763 CERROR("Unknown target type %#x, can't create log for "
3764 "%s\n", mti->mti_flags, mti->mti_svname);
3767 CERROR("Can't write logs for %s (%d)\n",
3768 mti->mti_svname, rc);
3772 /* Just update the params from tunefs in mgs_write_log_params */
3773 CDEBUG(D_MGS, "Update params for %s\n", mti->mti_svname);
3774 mti->mti_flags |= LDD_F_PARAM;
3777 /* allocate temporary buffer, where class_get_next_param will
3778 make copy of a current parameter */
3779 OBD_ALLOC(buf, strlen(mti->mti_params) + 1);
3781 GOTO(out_up, rc = -ENOMEM);
3782 params = mti->mti_params;
3783 while (params != NULL) {
3784 rc = class_get_next_param(¶ms, buf);
3787 /* there is no next parameter, that is
3792 CDEBUG(D_MGS, "remaining string: '%s', param: '%s'\n",
3794 rc = mgs_write_log_param(env, mgs, fsdb, mti, buf);
3799 OBD_FREE(buf, strlen(mti->mti_params) + 1);
3802 mutex_unlock(&fsdb->fsdb_mutex);
3806 int mgs_erase_log(const struct lu_env *env, struct mgs_device *mgs, char *name)
3808 struct llog_ctxt *ctxt;
3811 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
3813 CERROR("%s: MGS config context doesn't exist\n",
3814 mgs->mgs_obd->obd_name);
3817 rc = llog_erase(env, ctxt, NULL, name);
3818 /* llog may not exist */
3821 llog_ctxt_put(ctxt);
3825 CERROR("%s: failed to clear log %s: %d\n",
3826 mgs->mgs_obd->obd_name, name, rc);
3831 /* erase all logs for the given fs */
3832 int mgs_erase_logs(const struct lu_env *env, struct mgs_device *mgs, char *fsname)
3835 struct list_head log_list;
3836 struct mgs_direntry *dirent, *n;
3837 int rc, len = strlen(fsname);
3841 /* Find all the logs in the CONFIGS directory */
3842 rc = class_dentry_readdir(env, mgs, &log_list);
3846 mutex_lock(&mgs->mgs_mutex);
3848 /* Delete the fs db */
3849 fsdb = mgs_find_fsdb(mgs, fsname);
3851 mgs_free_fsdb(mgs, fsdb);
3853 mutex_unlock(&mgs->mgs_mutex);
3855 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
3856 list_del_init(&dirent->mde_list);
3857 suffix = strrchr(dirent->mde_name, '-');
3858 if (suffix != NULL) {
3859 if ((len == suffix - dirent->mde_name) &&
3860 (strncmp(fsname, dirent->mde_name, len) == 0)) {
3861 CDEBUG(D_MGS, "Removing log %s\n",
3863 mgs_erase_log(env, mgs, dirent->mde_name);
3866 mgs_direntry_free(dirent);
3872 /* list all logs for the given fs */
3873 int mgs_list_logs(const struct lu_env *env, struct mgs_device *mgs,
3874 struct obd_ioctl_data *data)
3876 struct list_head log_list;
3877 struct mgs_direntry *dirent, *n;
3883 /* Find all the logs in the CONFIGS directory */
3884 rc = class_dentry_readdir(env, mgs, &log_list);
3888 out = data->ioc_bulk;
3889 remains = data->ioc_inllen1;
3890 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
3891 list_del_init(&dirent->mde_list);
3892 suffix = strrchr(dirent->mde_name, '-');
3893 if (suffix != NULL) {
3894 l = snprintf(out, remains, "config log: $%s\n",
3899 mgs_direntry_free(dirent);
3906 /* from llog_swab */
3907 static void print_lustre_cfg(struct lustre_cfg *lcfg)
3912 CDEBUG(D_MGS, "lustre_cfg: %p\n", lcfg);
3913 CDEBUG(D_MGS, "\tlcfg->lcfg_version: %#x\n", lcfg->lcfg_version);
3915 CDEBUG(D_MGS, "\tlcfg->lcfg_command: %#x\n", lcfg->lcfg_command);
3916 CDEBUG(D_MGS, "\tlcfg->lcfg_num: %#x\n", lcfg->lcfg_num);
3917 CDEBUG(D_MGS, "\tlcfg->lcfg_flags: %#x\n", lcfg->lcfg_flags);
3918 CDEBUG(D_MGS, "\tlcfg->lcfg_nid: %s\n", libcfs_nid2str(lcfg->lcfg_nid));
3920 CDEBUG(D_MGS, "\tlcfg->lcfg_bufcount: %d\n", lcfg->lcfg_bufcount);
3921 if (lcfg->lcfg_bufcount < LUSTRE_CFG_MAX_BUFCOUNT)
3922 for (i = 0; i < lcfg->lcfg_bufcount; i++) {
3923 CDEBUG(D_MGS, "\tlcfg->lcfg_buflens[%d]: %d %s\n",
3924 i, lcfg->lcfg_buflens[i],
3925 lustre_cfg_string(lcfg, i));
3930 /* Setup _mgs fsdb and log
3932 int mgs__mgs_fsdb_setup(const struct lu_env *env, struct mgs_device *mgs,
3938 rc = mgs_find_or_make_fsdb(env, mgs, MGSSELF_NAME, &fsdb);
3943 /* Setup params fsdb and log
3945 int mgs_params_fsdb_setup(const struct lu_env *env, struct mgs_device *mgs,
3948 struct llog_handle *params_llh = NULL;
3952 rc = mgs_find_or_make_fsdb(env, mgs, PARAMS_FILENAME, &fsdb);
3954 mutex_lock(&fsdb->fsdb_mutex);
3955 rc = record_start_log(env, mgs, ¶ms_llh, PARAMS_FILENAME);
3957 rc = record_end_log(env, ¶ms_llh);
3958 mutex_unlock(&fsdb->fsdb_mutex);
3964 /* Cleanup params fsdb and log
3966 int mgs_params_fsdb_cleanup(const struct lu_env *env, struct mgs_device *mgs)
3968 return mgs_erase_logs(env, mgs, PARAMS_FILENAME);
3971 /* Set a permanent (config log) param for a target or fs
3972 * \param lcfg buf0 may contain the device (testfs-MDT0000) name
3973 * buf1 contains the single parameter
3975 int mgs_setparam(const struct lu_env *env, struct mgs_device *mgs,
3976 struct lustre_cfg *lcfg, char *fsname)
3979 struct mgs_target_info *mti;
3980 char *devname, *param;
3987 print_lustre_cfg(lcfg);
3989 /* lustre, lustre-mdtlov, lustre-client, lustre-MDT0000 */
3990 devname = lustre_cfg_string(lcfg, 0);
3991 param = lustre_cfg_string(lcfg, 1);
3993 /* Assume device name embedded in param:
3994 lustre-OST0000.osc.max_dirty_mb=32 */
3995 ptr = strchr(param, '.');
4003 LCONSOLE_ERROR_MSG(0x14d, "No target specified: %s\n", param);
4007 rc = mgs_parse_devname(devname, fsname, NULL);
4008 if (rc == 0 && !mgs_parse_devname(devname, NULL, &index)) {
4009 /* param related to llite isn't allowed to set by OST or MDT */
4010 if (rc == 0 && strncmp(param, PARAM_LLITE,
4011 sizeof(PARAM_LLITE) - 1) == 0)
4014 /* assume devname is the fsname */
4015 strlcpy(fsname, devname, MTI_NAME_MAXLEN);
4017 CDEBUG(D_MGS, "setparam fs='%s' device='%s'\n", fsname, devname);
4019 rc = mgs_find_or_make_fsdb(env, mgs,
4020 lcfg->lcfg_command == LCFG_SET_PARAM ?
4021 PARAMS_FILENAME : fsname, &fsdb);
4025 if (lcfg->lcfg_command != LCFG_SET_PARAM &&
4026 !test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags) &&
4027 test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
4028 CERROR("No filesystem targets for %s. cfg_device from lctl "
4029 "is '%s'\n", fsname, devname);
4030 mgs_free_fsdb(mgs, fsdb);
4034 /* Create a fake mti to hold everything */
4037 GOTO(out, rc = -ENOMEM);
4038 if (strlcpy(mti->mti_fsname, fsname, sizeof(mti->mti_fsname))
4039 >= sizeof(mti->mti_fsname))
4040 GOTO(out, rc = -E2BIG);
4041 if (strlcpy(mti->mti_svname, devname, sizeof(mti->mti_svname))
4042 >= sizeof(mti->mti_svname))
4043 GOTO(out, rc = -E2BIG);
4044 if (strlcpy(mti->mti_params, param, sizeof(mti->mti_params))
4045 >= sizeof(mti->mti_params))
4046 GOTO(out, rc = -E2BIG);
4047 rc = server_name2index(mti->mti_svname, &mti->mti_stripe_index, &tmp);
4049 /* Not a valid server; may be only fsname */
4052 /* Strip -osc or -mdc suffix from svname */
4053 if (server_make_name(rc, mti->mti_stripe_index, mti->mti_fsname,
4055 GOTO(out, rc = -EINVAL);
4057 * Revoke lock so everyone updates. Should be alright if
4058 * someone was already reading while we were updating the logs,
4059 * so we don't really need to hold the lock while we're
4062 if (lcfg->lcfg_command == LCFG_SET_PARAM) {
4063 mti->mti_flags = rc | LDD_F_PARAM2;
4064 mutex_lock(&fsdb->fsdb_mutex);
4065 rc = mgs_write_log_param2(env, mgs, fsdb, mti, mti->mti_params);
4066 mutex_unlock(&fsdb->fsdb_mutex);
4067 mgs_revoke_lock(mgs, fsdb, CONFIG_T_PARAMS);
4069 mti->mti_flags = rc | LDD_F_PARAM;
4070 mutex_lock(&fsdb->fsdb_mutex);
4071 rc = mgs_write_log_param(env, mgs, fsdb, mti, mti->mti_params);
4072 mutex_unlock(&fsdb->fsdb_mutex);
4073 mgs_revoke_lock(mgs, fsdb, CONFIG_T_CONFIG);
4081 static int mgs_write_log_pool(const struct lu_env *env,
4082 struct mgs_device *mgs, char *logname,
4083 struct fs_db *fsdb, char *tgtname,
4084 enum lcfg_command_type cmd,
4085 char *fsname, char *poolname,
4086 char *ostname, char *comment)
4088 struct llog_handle *llh = NULL;
4091 rc = record_start_log(env, mgs, &llh, logname);
4094 rc = record_marker(env, llh, fsdb, CM_START, tgtname, comment);
4097 rc = record_base(env, llh, tgtname, 0, cmd,
4098 fsname, poolname, ostname, NULL);
4101 rc = record_marker(env, llh, fsdb, CM_END, tgtname, comment);
4103 record_end_log(env, &llh);
4107 int mgs_nodemap_cmd(const struct lu_env *env, struct mgs_device *mgs,
4108 enum lcfg_command_type cmd, const char *nodemap_name,
4119 case LCFG_NODEMAP_ADD:
4120 rc = nodemap_add(nodemap_name);
4122 case LCFG_NODEMAP_DEL:
4123 rc = nodemap_del(nodemap_name);
4125 case LCFG_NODEMAP_ADD_RANGE:
4126 rc = nodemap_parse_range(param, nid);
4129 rc = nodemap_add_range(nodemap_name, nid);
4131 case LCFG_NODEMAP_DEL_RANGE:
4132 rc = nodemap_parse_range(param, nid);
4135 rc = nodemap_del_range(nodemap_name, nid);
4137 case LCFG_NODEMAP_ADMIN:
4138 bool_switch = simple_strtoul(param, NULL, 10);
4139 rc = nodemap_set_allow_root(nodemap_name, bool_switch);
4141 case LCFG_NODEMAP_DENY_UNKNOWN:
4142 bool_switch = simple_strtoul(param, NULL, 10);
4143 rc = nodemap_set_deny_unknown(nodemap_name, bool_switch);
4145 case LCFG_NODEMAP_TRUSTED:
4146 bool_switch = simple_strtoul(param, NULL, 10);
4147 rc = nodemap_set_trust_client_ids(nodemap_name, bool_switch);
4149 case LCFG_NODEMAP_SQUASH_UID:
4150 int_id = simple_strtoul(param, NULL, 10);
4151 rc = nodemap_set_squash_uid(nodemap_name, int_id);
4153 case LCFG_NODEMAP_SQUASH_GID:
4154 int_id = simple_strtoul(param, NULL, 10);
4155 rc = nodemap_set_squash_gid(nodemap_name, int_id);
4157 case LCFG_NODEMAP_ADD_UIDMAP:
4158 case LCFG_NODEMAP_ADD_GIDMAP:
4159 rc = nodemap_parse_idmap(param, idmap);
4162 if (cmd == LCFG_NODEMAP_ADD_UIDMAP)
4163 rc = nodemap_add_idmap(nodemap_name, NODEMAP_UID,
4166 rc = nodemap_add_idmap(nodemap_name, NODEMAP_GID,
4169 case LCFG_NODEMAP_DEL_UIDMAP:
4170 case LCFG_NODEMAP_DEL_GIDMAP:
4171 rc = nodemap_parse_idmap(param, idmap);
4174 if (cmd == LCFG_NODEMAP_DEL_UIDMAP)
4175 rc = nodemap_del_idmap(nodemap_name, NODEMAP_UID,
4178 rc = nodemap_del_idmap(nodemap_name, NODEMAP_GID,
4181 case LCFG_NODEMAP_SET_FILESET:
4182 rc = nodemap_set_fileset(nodemap_name, param);
4191 int mgs_pool_cmd(const struct lu_env *env, struct mgs_device *mgs,
4192 enum lcfg_command_type cmd, char *fsname,
4193 char *poolname, char *ostname)
4198 char *label = NULL, *canceled_label = NULL;
4200 struct mgs_target_info *mti = NULL;
4204 rc = mgs_find_or_make_fsdb(env, mgs, fsname, &fsdb);
4206 CERROR("Can't get db for %s\n", fsname);
4209 if (test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
4210 CERROR("%s is not defined\n", fsname);
4211 mgs_free_fsdb(mgs, fsdb);
4215 label_sz = 10 + strlen(fsname) + strlen(poolname);
4217 /* check if ostname match fsname */
4218 if (ostname != NULL) {
4221 ptr = strrchr(ostname, '-');
4222 if ((ptr == NULL) ||
4223 (strncmp(fsname, ostname, ptr-ostname) != 0))
4225 label_sz += strlen(ostname);
4228 OBD_ALLOC(label, label_sz);
4235 "new %s.%s", fsname, poolname);
4239 "add %s.%s.%s", fsname, poolname, ostname);
4242 OBD_ALLOC(canceled_label, label_sz);
4243 if (canceled_label == NULL)
4244 GOTO(out_label, rc = -ENOMEM);
4246 "rem %s.%s.%s", fsname, poolname, ostname);
4247 sprintf(canceled_label,
4248 "add %s.%s.%s", fsname, poolname, ostname);
4251 OBD_ALLOC(canceled_label, label_sz);
4252 if (canceled_label == NULL)
4253 GOTO(out_label, rc = -ENOMEM);
4255 "del %s.%s", fsname, poolname);
4256 sprintf(canceled_label,
4257 "new %s.%s", fsname, poolname);
4263 if (canceled_label != NULL) {
4266 GOTO(out_cancel, rc = -ENOMEM);
4269 mutex_lock(&fsdb->fsdb_mutex);
4270 /* write pool def to all MDT logs */
4271 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
4272 if (test_bit(i, fsdb->fsdb_mdt_index_map)) {
4273 rc = name_create_mdt_and_lov(&logname, &lovname,
4276 mutex_unlock(&fsdb->fsdb_mutex);
4279 if (canceled_label != NULL) {
4280 strcpy(mti->mti_svname, "lov pool");
4281 rc = mgs_modify(env, mgs, fsdb, mti, logname,
4282 lovname, canceled_label,
4287 rc = mgs_write_log_pool(env, mgs, logname,
4291 name_destroy(&logname);
4292 name_destroy(&lovname);
4294 mutex_unlock(&fsdb->fsdb_mutex);
4300 rc = name_create(&logname, fsname, "-client");
4302 mutex_unlock(&fsdb->fsdb_mutex);
4305 if (canceled_label != NULL) {
4306 rc = mgs_modify(env, mgs, fsdb, mti, logname,
4307 fsdb->fsdb_clilov, canceled_label, CM_SKIP);
4309 mutex_unlock(&fsdb->fsdb_mutex);
4310 name_destroy(&logname);
4315 rc = mgs_write_log_pool(env, mgs, logname, fsdb, fsdb->fsdb_clilov,
4316 cmd, fsname, poolname, ostname, label);
4317 mutex_unlock(&fsdb->fsdb_mutex);
4318 name_destroy(&logname);
4319 /* request for update */
4320 mgs_revoke_lock(mgs, fsdb, CONFIG_T_CONFIG);
4327 if (canceled_label != NULL)
4328 OBD_FREE(canceled_label, label_sz);
4330 OBD_FREE(label, label_sz);