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, 2013, 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
50 #include <lustre_param.h>
51 #include <lustre_sec.h>
52 #include <lustre_quota.h>
54 #include "mgs_internal.h"
56 /********************** Class functions ********************/
58 int class_dentry_readdir(const struct lu_env *env,
59 struct mgs_device *mgs, cfs_list_t *list)
61 struct dt_object *dir = mgs->mgs_configs_dir;
62 const struct dt_it_ops *iops;
64 struct mgs_direntry *de;
68 CFS_INIT_LIST_HEAD(list);
71 LASSERT(dir->do_index_ops);
73 iops = &dir->do_index_ops->dio_it;
74 it = iops->init(env, dir, LUDA_64BITHASH, BYPASS_CAPA);
78 rc = iops->load(env, it, 0);
84 key = (void *)iops->key(env, it);
86 CERROR("%s: key failed when listing %s: rc = %d\n",
87 mgs->mgs_obd->obd_name, MOUNT_CONFIGS_DIR,
91 key_sz = iops->key_size(env, it);
94 /* filter out "." and ".." entries */
98 if (key_sz == 2 && key[1] == '.')
102 de = mgs_direntry_alloc(key_sz + 1);
108 memcpy(de->name, key, key_sz);
109 de->name[key_sz] = 0;
111 cfs_list_add(&de->list, list);
114 rc = iops->next(env, it);
123 CERROR("%s: key failed when listing %s: rc = %d\n",
124 mgs->mgs_obd->obd_name, MOUNT_CONFIGS_DIR, rc);
128 /******************** DB functions *********************/
130 static inline int name_create(char **newname, char *prefix, char *suffix)
133 OBD_ALLOC(*newname, strlen(prefix) + strlen(suffix) + 1);
136 sprintf(*newname, "%s%s", prefix, suffix);
140 static inline void name_destroy(char **name)
143 OBD_FREE(*name, strlen(*name) + 1);
147 struct mgs_fsdb_handler_data
153 /* from the (client) config log, figure out:
154 1. which ost's/mdt's are configured (by index)
155 2. what the last config step is
156 3. COMPAT_18 osc name
158 /* It might be better to have a separate db file, instead of parsing the info
159 out of the client log. This is slow and potentially error-prone. */
160 static int mgs_fsdb_handler(const struct lu_env *env, struct llog_handle *llh,
161 struct llog_rec_hdr *rec, void *data)
163 struct mgs_fsdb_handler_data *d = data;
164 struct fs_db *fsdb = d->fsdb;
165 int cfg_len = rec->lrh_len;
166 char *cfg_buf = (char*) (rec + 1);
167 struct lustre_cfg *lcfg;
172 if (rec->lrh_type != OBD_CFG_REC) {
173 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
177 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
179 CERROR("Insane cfg\n");
183 lcfg = (struct lustre_cfg *)cfg_buf;
185 CDEBUG(D_INFO, "cmd %x %s %s\n", lcfg->lcfg_command,
186 lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));
188 /* Figure out ost indicies */
189 /* lov_modify_tgts add 0:lov1 1:ost1_UUID 2(index):0 3(gen):1 */
190 if (lcfg->lcfg_command == LCFG_LOV_ADD_OBD ||
191 lcfg->lcfg_command == LCFG_LOV_DEL_OBD) {
192 index = simple_strtoul(lustre_cfg_string(lcfg, 2),
194 CDEBUG(D_MGS, "OST index for %s is %u (%s)\n",
195 lustre_cfg_string(lcfg, 1), index,
196 lustre_cfg_string(lcfg, 2));
197 set_bit(index, fsdb->fsdb_ost_index_map);
200 /* Figure out mdt indicies */
201 /* attach 0:MDC_uml1_mdsA_MNT_client 1:mdc 2:1d834_MNT_client_03f */
202 if ((lcfg->lcfg_command == LCFG_ATTACH) &&
203 (strcmp(lustre_cfg_string(lcfg, 1), LUSTRE_MDC_NAME) == 0)) {
204 rc = server_name2index(lustre_cfg_string(lcfg, 0),
206 if (rc != LDD_F_SV_TYPE_MDT) {
207 CWARN("Unparsable MDC name %s, assuming index 0\n",
208 lustre_cfg_string(lcfg, 0));
212 CDEBUG(D_MGS, "MDT index is %u\n", index);
213 set_bit(index, fsdb->fsdb_mdt_index_map);
214 fsdb->fsdb_mdt_count ++;
218 * figure out the old config. fsdb_gen = 0 means old log
219 * It is obsoleted and not supported anymore
221 if (fsdb->fsdb_gen == 0) {
222 CERROR("Old config format is not supported\n");
227 * compat to 1.8, check osc name used by MDT0 to OSTs, bz18548.
229 if (!test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags) &&
230 lcfg->lcfg_command == LCFG_ATTACH &&
231 strcmp(lustre_cfg_string(lcfg, 1), LUSTRE_OSC_NAME) == 0) {
232 if (OBD_OCD_VERSION_MAJOR(d->ver) == 1 &&
233 OBD_OCD_VERSION_MINOR(d->ver) <= 8) {
234 CWARN("MDT using 1.8 OSC name scheme\n");
235 set_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags);
239 if (lcfg->lcfg_command == LCFG_MARKER) {
240 struct cfg_marker *marker;
241 marker = lustre_cfg_buf(lcfg, 1);
243 d->ver = marker->cm_vers;
245 /* Keep track of the latest marker step */
246 fsdb->fsdb_gen = max(fsdb->fsdb_gen, marker->cm_step);
252 /* fsdb->fsdb_mutex is already held in mgs_find_or_make_fsdb*/
253 static int mgs_get_fsdb_from_llog(const struct lu_env *env,
254 struct mgs_device *mgs,
258 struct llog_handle *loghandle;
259 struct llog_ctxt *ctxt;
260 struct mgs_fsdb_handler_data d = { fsdb, 0 };
265 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
266 LASSERT(ctxt != NULL);
267 rc = name_create(&logname, fsdb->fsdb_name, "-client");
270 rc = llog_open_create(env, ctxt, &loghandle, NULL, logname);
274 rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL);
278 if (llog_get_size(loghandle) <= 1)
279 set_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags);
281 rc = llog_process(env, loghandle, mgs_fsdb_handler, (void *)&d, NULL);
282 CDEBUG(D_INFO, "get_db = %d\n", rc);
284 llog_close(env, loghandle);
286 name_destroy(&logname);
293 static void mgs_free_fsdb_srpc(struct fs_db *fsdb)
295 struct mgs_tgt_srpc_conf *tgtconf;
297 /* free target-specific rules */
298 while (fsdb->fsdb_srpc_tgt) {
299 tgtconf = fsdb->fsdb_srpc_tgt;
300 fsdb->fsdb_srpc_tgt = tgtconf->mtsc_next;
302 LASSERT(tgtconf->mtsc_tgt);
304 sptlrpc_rule_set_free(&tgtconf->mtsc_rset);
305 OBD_FREE(tgtconf->mtsc_tgt, strlen(tgtconf->mtsc_tgt) + 1);
306 OBD_FREE_PTR(tgtconf);
309 /* free general rules */
310 sptlrpc_rule_set_free(&fsdb->fsdb_srpc_gen);
313 struct fs_db *mgs_find_fsdb(struct mgs_device *mgs, char *fsname)
318 cfs_list_for_each(tmp, &mgs->mgs_fs_db_list) {
319 fsdb = cfs_list_entry(tmp, struct fs_db, fsdb_list);
320 if (strcmp(fsdb->fsdb_name, fsname) == 0)
326 /* caller must hold the mgs->mgs_fs_db_lock */
327 static struct fs_db *mgs_new_fsdb(const struct lu_env *env,
328 struct mgs_device *mgs, char *fsname)
334 if (strlen(fsname) >= sizeof(fsdb->fsdb_name)) {
335 CERROR("fsname %s is too long\n", fsname);
343 strcpy(fsdb->fsdb_name, fsname);
344 mutex_init(&fsdb->fsdb_mutex);
345 set_bit(FSDB_UDESC, &fsdb->fsdb_flags);
348 if (strcmp(fsname, MGSSELF_NAME) == 0) {
349 set_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags);
351 OBD_ALLOC(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
352 OBD_ALLOC(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
353 if (!fsdb->fsdb_ost_index_map || !fsdb->fsdb_mdt_index_map) {
354 CERROR("No memory for index maps\n");
355 GOTO(err, rc = -ENOMEM);
358 rc = name_create(&fsdb->fsdb_clilov, fsname, "-clilov");
361 rc = name_create(&fsdb->fsdb_clilmv, fsname, "-clilmv");
365 /* initialise data for NID table */
366 mgs_ir_init_fs(env, mgs, fsdb);
368 lproc_mgs_add_live(mgs, fsdb);
371 cfs_list_add(&fsdb->fsdb_list, &mgs->mgs_fs_db_list);
375 if (fsdb->fsdb_ost_index_map)
376 OBD_FREE(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
377 if (fsdb->fsdb_mdt_index_map)
378 OBD_FREE(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
379 name_destroy(&fsdb->fsdb_clilov);
380 name_destroy(&fsdb->fsdb_clilmv);
385 static void mgs_free_fsdb(struct mgs_device *mgs, struct fs_db *fsdb)
387 /* wait for anyone with the sem */
388 mutex_lock(&fsdb->fsdb_mutex);
389 lproc_mgs_del_live(mgs, fsdb);
390 cfs_list_del(&fsdb->fsdb_list);
392 /* deinitialize fsr */
393 mgs_ir_fini_fs(mgs, fsdb);
395 if (fsdb->fsdb_ost_index_map)
396 OBD_FREE(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
397 if (fsdb->fsdb_mdt_index_map)
398 OBD_FREE(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
399 name_destroy(&fsdb->fsdb_clilov);
400 name_destroy(&fsdb->fsdb_clilmv);
401 mgs_free_fsdb_srpc(fsdb);
402 mutex_unlock(&fsdb->fsdb_mutex);
406 int mgs_init_fsdb_list(struct mgs_device *mgs)
408 CFS_INIT_LIST_HEAD(&mgs->mgs_fs_db_list);
412 int mgs_cleanup_fsdb_list(struct mgs_device *mgs)
415 cfs_list_t *tmp, *tmp2;
416 mutex_lock(&mgs->mgs_mutex);
417 cfs_list_for_each_safe(tmp, tmp2, &mgs->mgs_fs_db_list) {
418 fsdb = cfs_list_entry(tmp, struct fs_db, fsdb_list);
419 mgs_free_fsdb(mgs, fsdb);
421 mutex_unlock(&mgs->mgs_mutex);
425 int mgs_find_or_make_fsdb(const struct lu_env *env,
426 struct mgs_device *mgs, char *name,
433 mutex_lock(&mgs->mgs_mutex);
434 fsdb = mgs_find_fsdb(mgs, name);
436 mutex_unlock(&mgs->mgs_mutex);
441 CDEBUG(D_MGS, "Creating new db\n");
442 fsdb = mgs_new_fsdb(env, mgs, name);
443 /* lock fsdb_mutex until the db is loaded from llogs */
445 mutex_lock(&fsdb->fsdb_mutex);
446 mutex_unlock(&mgs->mgs_mutex);
450 if (!test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
451 /* populate the db from the client llog */
452 rc = mgs_get_fsdb_from_llog(env, mgs, fsdb);
454 CERROR("Can't get db from client log %d\n", rc);
459 /* populate srpc rules from params llog */
460 rc = mgs_get_fsdb_srpc_from_llog(env, mgs, fsdb);
462 CERROR("Can't get db from params log %d\n", rc);
466 mutex_unlock(&fsdb->fsdb_mutex);
472 mutex_unlock(&fsdb->fsdb_mutex);
473 mgs_free_fsdb(mgs, fsdb);
479 -1= empty client log */
480 int mgs_check_index(const struct lu_env *env,
481 struct mgs_device *mgs,
482 struct mgs_target_info *mti)
489 LASSERT(!(mti->mti_flags & LDD_F_NEED_INDEX));
491 rc = mgs_find_or_make_fsdb(env, mgs, mti->mti_fsname, &fsdb);
493 CERROR("Can't get db for %s\n", mti->mti_fsname);
497 if (test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags))
500 if (mti->mti_flags & LDD_F_SV_TYPE_OST)
501 imap = fsdb->fsdb_ost_index_map;
502 else if (mti->mti_flags & LDD_F_SV_TYPE_MDT)
503 imap = fsdb->fsdb_mdt_index_map;
507 if (test_bit(mti->mti_stripe_index, imap))
512 static __inline__ int next_index(void *index_map, int map_len)
515 for (i = 0; i < map_len * 8; i++)
516 if (!test_bit(i, index_map)) {
519 CERROR("max index %d exceeded.\n", i);
524 0 newly marked as in use
526 +EALREADY for update of an old index */
527 static int mgs_set_index(const struct lu_env *env,
528 struct mgs_device *mgs,
529 struct mgs_target_info *mti)
536 rc = mgs_find_or_make_fsdb(env, mgs, mti->mti_fsname, &fsdb);
538 CERROR("Can't get db for %s\n", mti->mti_fsname);
542 mutex_lock(&fsdb->fsdb_mutex);
543 if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
544 imap = fsdb->fsdb_ost_index_map;
545 } else if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
546 imap = fsdb->fsdb_mdt_index_map;
548 GOTO(out_up, rc = -EINVAL);
551 if (mti->mti_flags & LDD_F_NEED_INDEX) {
552 rc = next_index(imap, INDEX_MAP_SIZE);
554 GOTO(out_up, rc = -ERANGE);
555 mti->mti_stripe_index = rc;
556 if (mti->mti_flags & LDD_F_SV_TYPE_MDT)
557 fsdb->fsdb_mdt_count ++;
560 if (mti->mti_stripe_index >= INDEX_MAP_SIZE * 8) {
561 LCONSOLE_ERROR_MSG(0x13f, "Server %s requested index %d, "
562 "but the max index is %d.\n",
563 mti->mti_svname, mti->mti_stripe_index,
565 GOTO(out_up, rc = -ERANGE);
568 if (test_bit(mti->mti_stripe_index, imap)) {
569 if ((mti->mti_flags & LDD_F_VIRGIN) &&
570 !(mti->mti_flags & LDD_F_WRITECONF)) {
571 LCONSOLE_ERROR_MSG(0x140, "Server %s requested index "
572 "%d, but that index is already in "
573 "use. Use --writeconf to force\n",
575 mti->mti_stripe_index);
576 GOTO(out_up, rc = -EADDRINUSE);
578 CDEBUG(D_MGS, "Server %s updating index %d\n",
579 mti->mti_svname, mti->mti_stripe_index);
580 GOTO(out_up, rc = EALREADY);
584 set_bit(mti->mti_stripe_index, imap);
585 clear_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags);
586 mutex_unlock(&fsdb->fsdb_mutex);
587 server_make_name(mti->mti_flags & ~(LDD_F_VIRGIN | LDD_F_WRITECONF),
588 mti->mti_stripe_index, mti->mti_fsname, mti->mti_svname);
590 CDEBUG(D_MGS, "Set index for %s to %d\n", mti->mti_svname,
591 mti->mti_stripe_index);
595 mutex_unlock(&fsdb->fsdb_mutex);
599 struct mgs_modify_lookup {
600 struct cfg_marker mml_marker;
604 static int mgs_modify_handler(const struct lu_env *env,
605 struct llog_handle *llh,
606 struct llog_rec_hdr *rec, void *data)
608 struct mgs_modify_lookup *mml = data;
609 struct cfg_marker *marker;
610 struct lustre_cfg *lcfg = REC_DATA(rec);
611 int cfg_len = REC_DATA_LEN(rec);
615 if (rec->lrh_type != OBD_CFG_REC) {
616 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
620 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
622 CERROR("Insane cfg\n");
626 /* We only care about markers */
627 if (lcfg->lcfg_command != LCFG_MARKER)
630 marker = lustre_cfg_buf(lcfg, 1);
631 if ((strcmp(mml->mml_marker.cm_comment, marker->cm_comment) == 0) &&
632 (strcmp(mml->mml_marker.cm_tgtname, marker->cm_tgtname) == 0) &&
633 !(marker->cm_flags & CM_SKIP)) {
634 /* Found a non-skipped marker match */
635 CDEBUG(D_MGS, "Changing rec %u marker %d %x->%x: %s %s\n",
636 rec->lrh_index, marker->cm_step,
637 marker->cm_flags, mml->mml_marker.cm_flags,
638 marker->cm_tgtname, marker->cm_comment);
639 /* Overwrite the old marker llog entry */
640 marker->cm_flags &= ~CM_EXCLUDE; /* in case we're unexcluding */
641 marker->cm_flags |= mml->mml_marker.cm_flags;
642 marker->cm_canceltime = mml->mml_marker.cm_canceltime;
643 /* Header and tail are added back to lrh_len in
644 llog_lvfs_write_rec */
645 rec->lrh_len = cfg_len;
646 rc = llog_write(env, llh, rec, NULL, 0, (void *)lcfg,
656 * Modify an existing config log record (for CM_SKIP or CM_EXCLUDE)
658 * 0 - modified successfully,
659 * 1 - no modification was done
662 static int mgs_modify(const struct lu_env *env, struct mgs_device *mgs,
663 struct fs_db *fsdb, struct mgs_target_info *mti,
664 char *logname, char *devname, char *comment, int flags)
666 struct llog_handle *loghandle;
667 struct llog_ctxt *ctxt;
668 struct mgs_modify_lookup *mml;
673 LASSERT(mutex_is_locked(&fsdb->fsdb_mutex));
674 CDEBUG(D_MGS, "modify %s/%s/%s fl=%x\n", logname, devname, comment,
677 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
678 LASSERT(ctxt != NULL);
679 rc = llog_open(env, ctxt, &loghandle, NULL, logname, LLOG_OPEN_EXISTS);
686 rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL);
690 if (llog_get_size(loghandle) <= 1)
691 GOTO(out_close, rc = 0);
695 GOTO(out_close, rc = -ENOMEM);
696 if (strlcpy(mml->mml_marker.cm_comment, comment,
697 sizeof(mml->mml_marker.cm_comment)) >=
698 sizeof(mml->mml_marker.cm_comment))
699 GOTO(out_close, rc = -E2BIG);
700 if (strlcpy(mml->mml_marker.cm_tgtname, devname,
701 sizeof(mml->mml_marker.cm_tgtname)) >=
702 sizeof(mml->mml_marker.cm_tgtname))
703 GOTO(out_close, rc = -E2BIG);
704 /* Modify mostly means cancel */
705 mml->mml_marker.cm_flags = flags;
706 mml->mml_marker.cm_canceltime = flags ? cfs_time_current_sec() : 0;
707 mml->mml_modified = 0;
708 rc = llog_process(env, loghandle, mgs_modify_handler, (void *)mml,
710 if (!rc && !mml->mml_modified)
715 llog_close(env, loghandle);
718 CERROR("%s: modify %s/%s failed: rc = %d\n",
719 mgs->mgs_obd->obd_name, mti->mti_svname, comment, rc);
724 /** This structure is passed to mgs_replace_handler */
725 struct mgs_replace_uuid_lookup {
726 /* Nids are replaced for this target device */
727 struct mgs_target_info target;
728 /* Temporary modified llog */
729 struct llog_handle *temp_llh;
730 /* Flag is set if in target block*/
731 int in_target_device;
732 /* Nids already added. Just skip (multiple nids) */
733 int device_nids_added;
734 /* Flag is set if this block should not be copied */
739 * Check: a) if block should be skipped
740 * b) is it target block
745 * \retval 0 should not to be skipped
746 * \retval 1 should to be skipped
748 static int check_markers(struct lustre_cfg *lcfg,
749 struct mgs_replace_uuid_lookup *mrul)
751 struct cfg_marker *marker;
753 /* Track markers. Find given device */
754 if (lcfg->lcfg_command == LCFG_MARKER) {
755 marker = lustre_cfg_buf(lcfg, 1);
756 /* Clean llog from records marked as CM_EXCLUDE.
757 CM_SKIP records are used for "active" command
758 and can be restored if needed */
759 if ((marker->cm_flags & (CM_EXCLUDE | CM_START)) ==
760 (CM_EXCLUDE | CM_START)) {
765 if ((marker->cm_flags & (CM_EXCLUDE | CM_END)) ==
766 (CM_EXCLUDE | CM_END)) {
771 if (strcmp(mrul->target.mti_svname, marker->cm_tgtname) == 0) {
772 LASSERT(!(marker->cm_flags & CM_START) ||
773 !(marker->cm_flags & CM_END));
774 if (marker->cm_flags & CM_START) {
775 mrul->in_target_device = 1;
776 mrul->device_nids_added = 0;
777 } else if (marker->cm_flags & CM_END)
778 mrul->in_target_device = 0;
785 static int record_lcfg(const struct lu_env *env, struct llog_handle *llh,
786 struct lustre_cfg *lcfg)
788 struct llog_rec_hdr rec;
794 LASSERT(llh->lgh_ctxt);
796 buflen = lustre_cfg_len(lcfg->lcfg_bufcount,
798 rec.lrh_len = llog_data_len(buflen);
799 rec.lrh_type = OBD_CFG_REC;
801 /* idx = -1 means append */
802 rc = llog_write(env, llh, &rec, NULL, 0, (void *)lcfg, -1);
804 CERROR("failed %d\n", rc);
808 static int record_base(const struct lu_env *env, struct llog_handle *llh,
809 char *cfgname, lnet_nid_t nid, int cmd,
810 char *s1, char *s2, char *s3, char *s4)
812 struct mgs_thread_info *mgi = mgs_env_info(env);
813 struct lustre_cfg *lcfg;
816 CDEBUG(D_MGS, "lcfg %s %#x %s %s %s %s\n", cfgname,
817 cmd, s1, s2, s3, s4);
819 lustre_cfg_bufs_reset(&mgi->mgi_bufs, cfgname);
821 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, s1);
823 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 2, s2);
825 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 3, s3);
827 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 4, s4);
829 lcfg = lustre_cfg_new(cmd, &mgi->mgi_bufs);
832 lcfg->lcfg_nid = nid;
834 rc = record_lcfg(env, llh, lcfg);
836 lustre_cfg_free(lcfg);
839 CERROR("error %d: lcfg %s %#x %s %s %s %s\n", rc, cfgname,
840 cmd, s1, s2, s3, s4);
845 static inline int record_add_uuid(const struct lu_env *env,
846 struct llog_handle *llh,
847 uint64_t nid, char *uuid)
849 return record_base(env, llh, NULL, nid, LCFG_ADD_UUID, uuid, 0, 0, 0);
852 static inline int record_add_conn(const struct lu_env *env,
853 struct llog_handle *llh,
854 char *devname, char *uuid)
856 return record_base(env, llh, devname, 0, LCFG_ADD_CONN, uuid, 0, 0, 0);
859 static inline int record_attach(const struct lu_env *env,
860 struct llog_handle *llh, char *devname,
861 char *type, char *uuid)
863 return record_base(env, llh,devname, 0, LCFG_ATTACH, type, uuid, 0, 0);
866 static inline int record_setup(const struct lu_env *env,
867 struct llog_handle *llh, char *devname,
868 char *s1, char *s2, char *s3, char *s4)
870 return record_base(env, llh, devname, 0, LCFG_SETUP, s1, s2, s3, s4);
874 * \retval <0 record processing error
875 * \retval n record is processed. No need copy original one.
876 * \retval 0 record is not processed.
878 static int process_command(const struct lu_env *env, struct lustre_cfg *lcfg,
879 struct mgs_replace_uuid_lookup *mrul)
886 if (lcfg->lcfg_command == LCFG_ADD_UUID) {
887 /* LCFG_ADD_UUID command found. Let's skip original command
888 and add passed nids */
889 ptr = mrul->target.mti_params;
890 while (class_parse_nid(ptr, &nid, &ptr) == 0) {
891 CDEBUG(D_MGS, "add nid %s with uuid %s, "
892 "device %s\n", libcfs_nid2str(nid),
893 mrul->target.mti_params,
894 mrul->target.mti_svname);
895 rc = record_add_uuid(env,
897 mrul->target.mti_params);
902 if (nids_added == 0) {
903 CERROR("No new nids were added, nid %s with uuid %s, "
904 "device %s\n", libcfs_nid2str(nid),
905 mrul->target.mti_params,
906 mrul->target.mti_svname);
909 mrul->device_nids_added = 1;
915 if (mrul->device_nids_added && lcfg->lcfg_command == LCFG_SETUP) {
916 /* LCFG_SETUP command found. UUID should be changed */
917 rc = record_setup(env,
919 /* devname the same */
920 lustre_cfg_string(lcfg, 0),
921 /* s1 is not changed */
922 lustre_cfg_string(lcfg, 1),
923 /* new uuid should be
925 mrul->target.mti_params,
926 /* s3 is not changed */
927 lustre_cfg_string(lcfg, 3),
928 /* s4 is not changed */
929 lustre_cfg_string(lcfg, 4));
933 /* Another commands in target device block */
938 * Handler that called for every record in llog.
939 * Records are processed in order they placed in llog.
941 * \param[in] llh log to be processed
942 * \param[in] rec current record
943 * \param[in] data mgs_replace_uuid_lookup structure
947 static int mgs_replace_handler(const struct lu_env *env,
948 struct llog_handle *llh,
949 struct llog_rec_hdr *rec,
952 struct mgs_replace_uuid_lookup *mrul;
953 struct lustre_cfg *lcfg = REC_DATA(rec);
954 int cfg_len = REC_DATA_LEN(rec);
958 mrul = (struct mgs_replace_uuid_lookup *)data;
960 if (rec->lrh_type != OBD_CFG_REC) {
961 CERROR("unhandled lrh_type: %#x, cmd %x %s %s\n",
962 rec->lrh_type, lcfg->lcfg_command,
963 lustre_cfg_string(lcfg, 0),
964 lustre_cfg_string(lcfg, 1));
968 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
970 /* Do not copy any invalidated records */
971 GOTO(skip_out, rc = 0);
974 rc = check_markers(lcfg, mrul);
975 if (rc || mrul->skip_it)
976 GOTO(skip_out, rc = 0);
978 /* Write to new log all commands outside target device block */
979 if (!mrul->in_target_device)
980 GOTO(copy_out, rc = 0);
982 /* Skip all other LCFG_ADD_UUID and LCFG_ADD_CONN records
983 (failover nids) for this target, assuming that if then
984 primary is changing then so is the failover */
985 if (mrul->device_nids_added &&
986 (lcfg->lcfg_command == LCFG_ADD_UUID ||
987 lcfg->lcfg_command == LCFG_ADD_CONN))
988 GOTO(skip_out, rc = 0);
990 rc = process_command(env, lcfg, mrul);
997 /* Record is placed in temporary llog as is */
998 rc = llog_write(env, mrul->temp_llh, rec, NULL, 0, NULL, -1);
1000 CDEBUG(D_MGS, "Copied idx=%d, rc=%d, len=%d, cmd %x %s %s\n",
1001 rec->lrh_index, rc, rec->lrh_len, lcfg->lcfg_command,
1002 lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));
1006 CDEBUG(D_MGS, "Skipped idx=%d, rc=%d, len=%d, cmd %x %s %s\n",
1007 rec->lrh_index, rc, rec->lrh_len, lcfg->lcfg_command,
1008 lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));
1012 static int mgs_log_is_empty(const struct lu_env *env,
1013 struct mgs_device *mgs, char *name)
1015 struct llog_ctxt *ctxt;
1018 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
1019 LASSERT(ctxt != NULL);
1021 rc = llog_is_empty(env, ctxt, name);
1022 llog_ctxt_put(ctxt);
1026 static int mgs_replace_nids_log(const struct lu_env *env,
1027 struct obd_device *mgs, struct fs_db *fsdb,
1028 char *logname, char *devname, char *nids)
1030 struct llog_handle *orig_llh, *backup_llh;
1031 struct llog_ctxt *ctxt;
1032 struct mgs_replace_uuid_lookup *mrul;
1033 struct mgs_device *mgs_dev = lu2mgs_dev(mgs->obd_lu_dev);
1034 static struct obd_uuid cfg_uuid = { .uuid = "config_uuid" };
1039 CDEBUG(D_MGS, "Replace nids for %s in %s\n", devname, logname);
1041 ctxt = llog_get_context(mgs, LLOG_CONFIG_ORIG_CTXT);
1042 LASSERT(ctxt != NULL);
1044 if (mgs_log_is_empty(env, mgs_dev, logname)) {
1045 /* Log is empty. Nothing to replace */
1046 GOTO(out_put, rc = 0);
1049 OBD_ALLOC(backup, strlen(logname) + strlen(".bak") + 1);
1051 GOTO(out_put, rc = -ENOMEM);
1053 sprintf(backup, "%s.bak", logname);
1055 rc = llog_backup(env, mgs, ctxt, ctxt, logname, backup);
1057 /* Now erase original log file. Connections are not allowed.
1058 Backup is already saved */
1059 rc = llog_erase(env, ctxt, NULL, logname);
1062 } else if (rc != -ENOENT) {
1063 CERROR("%s: can't make backup for %s: rc = %d\n",
1064 mgs->obd_name, logname, rc);
1068 /* open local log */
1069 rc = llog_open_create(env, ctxt, &orig_llh, NULL, logname);
1071 GOTO(out_restore, rc);
1073 rc = llog_init_handle(env, orig_llh, LLOG_F_IS_PLAIN, &cfg_uuid);
1075 GOTO(out_closel, rc);
1077 /* open backup llog */
1078 rc = llog_open(env, ctxt, &backup_llh, NULL, backup,
1081 GOTO(out_closel, rc);
1083 rc = llog_init_handle(env, backup_llh, LLOG_F_IS_PLAIN, NULL);
1085 GOTO(out_close, rc);
1087 if (llog_get_size(backup_llh) <= 1)
1088 GOTO(out_close, rc = 0);
1090 OBD_ALLOC_PTR(mrul);
1092 GOTO(out_close, rc = -ENOMEM);
1093 /* devname is only needed information to replace UUID records */
1094 strncpy(mrul->target.mti_svname, devname, MTI_NAME_MAXLEN);
1095 /* parse nids later */
1096 strncpy(mrul->target.mti_params, nids, MTI_PARAM_MAXLEN);
1097 /* Copy records to this temporary llog */
1098 mrul->temp_llh = orig_llh;
1100 rc = llog_process(env, backup_llh, mgs_replace_handler,
1101 (void *)mrul, NULL);
1104 rc2 = llog_close(NULL, backup_llh);
1108 rc2 = llog_close(NULL, orig_llh);
1114 CERROR("%s: llog should be restored: rc = %d\n",
1116 rc2 = llog_backup(env, mgs, ctxt, ctxt, backup,
1119 CERROR("%s: can't restore backup %s: rc = %d\n",
1120 mgs->obd_name, logname, rc2);
1124 OBD_FREE(backup, strlen(backup) + 1);
1127 llog_ctxt_put(ctxt);
1130 CERROR("%s: failed to replace nids in log %s: rc = %d\n",
1131 mgs->obd_name, logname, rc);
1137 * Parse device name and get file system name and/or device index
1139 * \param[in] devname device name (ex. lustre-MDT0000)
1140 * \param[out] fsname file system name(optional)
1141 * \param[out] index device index(optional)
1145 static int mgs_parse_devname(char *devname, char *fsname, __u32 *index)
1150 /* Extract fsname */
1152 rc = server_name2fsname(devname, fsname, NULL);
1154 CDEBUG(D_MGS, "Device name %s without fsname\n",
1161 rc = server_name2index(devname, index, NULL);
1163 CDEBUG(D_MGS, "Device name %s with wrong index\n",
1172 static int only_mgs_is_running(struct obd_device *mgs_obd)
1174 /* TDB: Is global variable with devices count exists? */
1175 int num_devices = get_devices_count();
1176 /* osd, MGS and MGC + self_export
1177 (wc -l /proc/fs/lustre/devices <= 2) && (num_exports <= 2) */
1178 return (num_devices <= 3) && (mgs_obd->obd_num_exports <= 2);
1181 static int name_create_mdt(char **logname, char *fsname, int i)
1185 sprintf(mdt_index, "-MDT%04x", i);
1186 return name_create(logname, fsname, mdt_index);
1190 * Replace nids for \a device to \a nids values
1192 * \param obd MGS obd device
1193 * \param devname nids need to be replaced for this device
1194 * (ex. lustre-OST0000)
1195 * \param nids nids list (ex. nid1,nid2,nid3)
1199 int mgs_replace_nids(const struct lu_env *env,
1200 struct mgs_device *mgs,
1201 char *devname, char *nids)
1203 /* Assume fsname is part of device name */
1204 char fsname[MTI_NAME_MAXLEN];
1211 struct obd_device *mgs_obd = mgs->mgs_obd;
1214 /* We can only change NIDs if no other nodes are connected */
1215 spin_lock(&mgs_obd->obd_dev_lock);
1216 conn_state = mgs_obd->obd_no_conn;
1217 mgs_obd->obd_no_conn = 1;
1218 spin_unlock(&mgs_obd->obd_dev_lock);
1220 /* We can not change nids if not only MGS is started */
1221 if (!only_mgs_is_running(mgs_obd)) {
1222 CERROR("Only MGS is allowed to be started\n");
1223 GOTO(out, rc = -EINPROGRESS);
1226 /* Get fsname and index*/
1227 rc = mgs_parse_devname(devname, fsname, &index);
1231 rc = mgs_find_or_make_fsdb(env, mgs, fsname, &fsdb);
1233 CERROR("%s: can't find fsdb: rc = %d\n", fsname, rc);
1237 /* Process client llogs */
1238 name_create(&logname, fsname, "-client");
1239 rc = mgs_replace_nids_log(env, mgs_obd, fsdb, logname, devname, nids);
1240 name_destroy(&logname);
1242 CERROR("%s: error while replacing NIDs for %s: rc = %d\n",
1243 fsname, devname, rc);
1247 /* Process MDT llogs */
1248 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
1249 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
1251 name_create_mdt(&logname, fsname, i);
1252 rc = mgs_replace_nids_log(env, mgs_obd, fsdb, logname, devname, nids);
1253 name_destroy(&logname);
1259 spin_lock(&mgs_obd->obd_dev_lock);
1260 mgs_obd->obd_no_conn = conn_state;
1261 spin_unlock(&mgs_obd->obd_dev_lock);
1266 static int record_lov_setup(const struct lu_env *env, struct llog_handle *llh,
1267 char *devname, struct lov_desc *desc)
1269 struct mgs_thread_info *mgi = mgs_env_info(env);
1270 struct lustre_cfg *lcfg;
1273 lustre_cfg_bufs_reset(&mgi->mgi_bufs, devname);
1274 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, desc, sizeof(*desc));
1275 lcfg = lustre_cfg_new(LCFG_SETUP, &mgi->mgi_bufs);
1278 rc = record_lcfg(env, llh, lcfg);
1280 lustre_cfg_free(lcfg);
1284 static int record_lmv_setup(const struct lu_env *env, struct llog_handle *llh,
1285 char *devname, struct lmv_desc *desc)
1287 struct mgs_thread_info *mgi = mgs_env_info(env);
1288 struct lustre_cfg *lcfg;
1291 lustre_cfg_bufs_reset(&mgi->mgi_bufs, devname);
1292 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, desc, sizeof(*desc));
1293 lcfg = lustre_cfg_new(LCFG_SETUP, &mgi->mgi_bufs);
1295 rc = record_lcfg(env, llh, lcfg);
1297 lustre_cfg_free(lcfg);
1301 static inline int record_mdc_add(const struct lu_env *env,
1302 struct llog_handle *llh,
1303 char *logname, char *mdcuuid,
1304 char *mdtuuid, char *index,
1307 return record_base(env,llh,logname,0,LCFG_ADD_MDC,
1308 mdtuuid,index,gen,mdcuuid);
1311 static inline int record_lov_add(const struct lu_env *env,
1312 struct llog_handle *llh,
1313 char *lov_name, char *ost_uuid,
1314 char *index, char *gen)
1316 return record_base(env,llh,lov_name,0,LCFG_LOV_ADD_OBD,
1317 ost_uuid, index, gen, 0);
1320 static inline int record_mount_opt(const struct lu_env *env,
1321 struct llog_handle *llh,
1322 char *profile, char *lov_name,
1325 return record_base(env,llh,NULL,0,LCFG_MOUNTOPT,
1326 profile,lov_name,mdc_name,0);
1329 static int record_marker(const struct lu_env *env,
1330 struct llog_handle *llh,
1331 struct fs_db *fsdb, __u32 flags,
1332 char *tgtname, char *comment)
1334 struct mgs_thread_info *mgi = mgs_env_info(env);
1335 struct lustre_cfg *lcfg;
1339 if (flags & CM_START)
1341 mgi->mgi_marker.cm_step = fsdb->fsdb_gen;
1342 mgi->mgi_marker.cm_flags = flags;
1343 mgi->mgi_marker.cm_vers = LUSTRE_VERSION_CODE;
1344 cplen = strlcpy(mgi->mgi_marker.cm_tgtname, tgtname,
1345 sizeof(mgi->mgi_marker.cm_tgtname));
1346 if (cplen >= sizeof(mgi->mgi_marker.cm_tgtname))
1348 cplen = strlcpy(mgi->mgi_marker.cm_comment, comment,
1349 sizeof(mgi->mgi_marker.cm_comment));
1350 if (cplen >= sizeof(mgi->mgi_marker.cm_comment))
1352 mgi->mgi_marker.cm_createtime = cfs_time_current_sec();
1353 mgi->mgi_marker.cm_canceltime = 0;
1354 lustre_cfg_bufs_reset(&mgi->mgi_bufs, NULL);
1355 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, &mgi->mgi_marker,
1356 sizeof(mgi->mgi_marker));
1357 lcfg = lustre_cfg_new(LCFG_MARKER, &mgi->mgi_bufs);
1360 rc = record_lcfg(env, llh, lcfg);
1362 lustre_cfg_free(lcfg);
1366 static int record_start_log(const struct lu_env *env, struct mgs_device *mgs,
1367 struct llog_handle **llh, char *name)
1369 static struct obd_uuid cfg_uuid = { .uuid = "config_uuid" };
1370 struct llog_ctxt *ctxt;
1374 GOTO(out, rc = -EBUSY);
1376 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
1378 GOTO(out, rc = -ENODEV);
1379 LASSERT(ctxt->loc_obd == mgs->mgs_obd);
1381 rc = llog_open_create(env, ctxt, llh, NULL, name);
1384 rc = llog_init_handle(env, *llh, LLOG_F_IS_PLAIN, &cfg_uuid);
1386 llog_close(env, *llh);
1388 llog_ctxt_put(ctxt);
1391 CERROR("%s: can't start log %s: rc = %d\n",
1392 mgs->mgs_obd->obd_name, name, rc);
1398 static int record_end_log(const struct lu_env *env, struct llog_handle **llh)
1402 rc = llog_close(env, *llh);
1408 /******************** config "macros" *********************/
1410 /* write an lcfg directly into a log (with markers) */
1411 static int mgs_write_log_direct(const struct lu_env *env,
1412 struct mgs_device *mgs, struct fs_db *fsdb,
1413 char *logname, struct lustre_cfg *lcfg,
1414 char *devname, char *comment)
1416 struct llog_handle *llh = NULL;
1423 rc = record_start_log(env, mgs, &llh, logname);
1427 /* FIXME These should be a single journal transaction */
1428 rc = record_marker(env, llh, fsdb, CM_START, devname, comment);
1431 rc = record_lcfg(env, llh, lcfg);
1434 rc = record_marker(env, llh, fsdb, CM_END, devname, comment);
1438 record_end_log(env, &llh);
1442 /* write the lcfg in all logs for the given fs */
1443 int mgs_write_log_direct_all(const struct lu_env *env,
1444 struct mgs_device *mgs,
1446 struct mgs_target_info *mti,
1447 struct lustre_cfg *lcfg,
1448 char *devname, char *comment,
1452 struct mgs_direntry *dirent, *n;
1453 char *fsname = mti->mti_fsname;
1455 int rc = 0, len = strlen(fsname);
1458 /* We need to set params for any future logs
1459 as well. FIXME Append this file to every new log.
1460 Actually, we should store as params (text), not llogs. Or
1462 rc = name_create(&logname, fsname, "-params");
1465 if (mgs_log_is_empty(env, mgs, logname)) {
1466 struct llog_handle *llh = NULL;
1467 rc = record_start_log(env, mgs, &llh, logname);
1469 record_end_log(env, &llh);
1471 name_destroy(&logname);
1475 /* Find all the logs in the CONFIGS directory */
1476 rc = class_dentry_readdir(env, mgs, &list);
1480 /* Could use fsdb index maps instead of directory listing */
1481 cfs_list_for_each_entry_safe(dirent, n, &list, list) {
1482 cfs_list_del(&dirent->list);
1483 /* don't write to sptlrpc rule log */
1484 if (strstr(dirent->name, "-sptlrpc") != NULL)
1487 /* caller wants write server logs only */
1488 if (server_only && strstr(dirent->name, "-client") != NULL)
1491 if (strncmp(fsname, dirent->name, len) == 0) {
1492 CDEBUG(D_MGS, "Changing log %s\n", dirent->name);
1493 /* Erase any old settings of this same parameter */
1494 rc = mgs_modify(env, mgs, fsdb, mti, dirent->name,
1495 devname, comment, CM_SKIP);
1497 CERROR("%s: Can't modify llog %s: rc = %d\n",
1498 mgs->mgs_obd->obd_name, dirent->name,rc);
1499 /* Write the new one */
1501 rc = mgs_write_log_direct(env, mgs, fsdb,
1506 CERROR("%s: writing log %s: rc = %d\n",
1507 mgs->mgs_obd->obd_name,
1512 mgs_direntry_free(dirent);
1518 static int mgs_write_log_osp_to_mdt(const struct lu_env *env,
1519 struct mgs_device *mgs,
1521 struct mgs_target_info *mti,
1522 int index, char *logname);
1523 static int mgs_write_log_osc_to_lov(const struct lu_env *env,
1524 struct mgs_device *mgs,
1526 struct mgs_target_info *mti,
1527 char *logname, char *suffix, char *lovname,
1528 enum lustre_sec_part sec_part, int flags);
1529 static int name_create_mdt_and_lov(char **logname, char **lovname,
1530 struct fs_db *fsdb, int i);
1532 static int add_param(char *params, char *key, char *val)
1534 char *start = params + strlen(params);
1535 char *end = params + sizeof(((struct mgs_target_info *)0)->mti_params);
1539 keylen = strlen(key);
1540 if (start + 1 + keylen + strlen(val) >= end) {
1541 CERROR("params are too long: %s %s%s\n",
1542 params, key != NULL ? key : "", val);
1546 sprintf(start, " %s%s", key != NULL ? key : "", val);
1551 * Walk through client config log record and convert the related records
1554 static int mgs_steal_client_llog_handler(const struct lu_env *env,
1555 struct llog_handle *llh,
1556 struct llog_rec_hdr *rec, void *data)
1558 struct mgs_device *mgs;
1559 struct obd_device *obd;
1560 struct mgs_target_info *mti, *tmti;
1562 int cfg_len = rec->lrh_len;
1563 char *cfg_buf = (char*) (rec + 1);
1564 struct lustre_cfg *lcfg;
1566 struct llog_handle *mdt_llh = NULL;
1567 static int got_an_osc_or_mdc = 0;
1568 /* 0: not found any osc/mdc;
1572 static int last_step = -1;
1577 mti = ((struct temp_comp*)data)->comp_mti;
1578 tmti = ((struct temp_comp*)data)->comp_tmti;
1579 fsdb = ((struct temp_comp*)data)->comp_fsdb;
1580 obd = ((struct temp_comp *)data)->comp_obd;
1581 mgs = lu2mgs_dev(obd->obd_lu_dev);
1584 if (rec->lrh_type != OBD_CFG_REC) {
1585 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
1589 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
1591 CERROR("Insane cfg\n");
1595 lcfg = (struct lustre_cfg *)cfg_buf;
1597 if (lcfg->lcfg_command == LCFG_MARKER) {
1598 struct cfg_marker *marker;
1599 marker = lustre_cfg_buf(lcfg, 1);
1600 if (!strncmp(marker->cm_comment, "add osc", 7) &&
1601 (marker->cm_flags & CM_START) &&
1602 !(marker->cm_flags & CM_SKIP)) {
1603 got_an_osc_or_mdc = 1;
1604 cplen = strlcpy(tmti->mti_svname, marker->cm_tgtname,
1605 sizeof(tmti->mti_svname));
1606 if (cplen >= sizeof(tmti->mti_svname))
1608 rc = record_start_log(env, mgs, &mdt_llh,
1612 rc = record_marker(env, mdt_llh, fsdb, CM_START,
1613 mti->mti_svname, "add osc(copied)");
1614 record_end_log(env, &mdt_llh);
1615 last_step = marker->cm_step;
1618 if (!strncmp(marker->cm_comment, "add osc", 7) &&
1619 (marker->cm_flags & CM_END) &&
1620 !(marker->cm_flags & CM_SKIP)) {
1621 LASSERT(last_step == marker->cm_step);
1623 got_an_osc_or_mdc = 0;
1624 memset(tmti, 0, sizeof(*tmti));
1625 rc = record_start_log(env, mgs, &mdt_llh,
1629 rc = record_marker(env, mdt_llh, fsdb, CM_END,
1630 mti->mti_svname, "add osc(copied)");
1631 record_end_log(env, &mdt_llh);
1634 if (!strncmp(marker->cm_comment, "add mdc", 7) &&
1635 (marker->cm_flags & CM_START) &&
1636 !(marker->cm_flags & CM_SKIP)) {
1637 got_an_osc_or_mdc = 2;
1638 last_step = marker->cm_step;
1639 memcpy(tmti->mti_svname, marker->cm_tgtname,
1640 strlen(marker->cm_tgtname));
1644 if (!strncmp(marker->cm_comment, "add mdc", 7) &&
1645 (marker->cm_flags & CM_END) &&
1646 !(marker->cm_flags & CM_SKIP)) {
1647 LASSERT(last_step == marker->cm_step);
1649 got_an_osc_or_mdc = 0;
1650 memset(tmti, 0, sizeof(*tmti));
1655 if (got_an_osc_or_mdc == 0 || last_step < 0)
1658 if (lcfg->lcfg_command == LCFG_ADD_UUID) {
1659 uint64_t nodenid = lcfg->lcfg_nid;
1661 if (strlen(tmti->mti_uuid) == 0) {
1662 /* target uuid not set, this config record is before
1663 * LCFG_SETUP, this nid is one of target node nid.
1665 tmti->mti_nids[tmti->mti_nid_count] = nodenid;
1666 tmti->mti_nid_count++;
1668 /* failover node nid */
1669 rc = add_param(tmti->mti_params, PARAM_FAILNODE,
1670 libcfs_nid2str(nodenid));
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 = 1024 * 1024;
1856 lovdesc->ld_default_stripe_offset = -1;
1857 lovdesc->ld_qos_maxage = QOS_DEFAULT_MAXAGE;
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
1908 /* Pull failnid info out of params string */
1909 while (class_find_param(ptr, PARAM_FAILNODE, &ptr) == 0) {
1910 while (class_parse_nid(ptr, &nid, &ptr) == 0) {
1911 if (failnodeuuid == NULL) {
1912 /* We don't know the failover node name,
1913 so just use the first nid as the uuid */
1914 rc = name_create(&failnodeuuid,
1915 libcfs_nid2str(nid), "");
1919 CDEBUG(D_MGS, "add nid %s for failover uuid %s, "
1920 "client %s\n", libcfs_nid2str(nid),
1921 failnodeuuid, cliname);
1922 rc = record_add_uuid(env, llh, nid, failnodeuuid);
1925 rc = record_add_conn(env, llh, cliname, failnodeuuid);
1928 name_destroy(&failnodeuuid);
1932 static int mgs_write_log_mdc_to_lmv(const struct lu_env *env,
1933 struct mgs_device *mgs,
1935 struct mgs_target_info *mti,
1936 char *logname, char *lmvname)
1938 struct llog_handle *llh = NULL;
1939 char *mdcname = NULL;
1940 char *nodeuuid = NULL;
1941 char *mdcuuid = NULL;
1942 char *lmvuuid = NULL;
1947 if (mgs_log_is_empty(env, mgs, logname)) {
1948 CERROR("log is empty! Logical error\n");
1952 CDEBUG(D_MGS, "adding mdc for %s to log %s:lmv(%s)\n",
1953 mti->mti_svname, logname, lmvname);
1955 rc = name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
1958 rc = name_create(&mdcname, mti->mti_svname, "-mdc");
1961 rc = name_create(&mdcuuid, mdcname, "_UUID");
1964 rc = name_create(&lmvuuid, lmvname, "_UUID");
1968 rc = record_start_log(env, mgs, &llh, logname);
1971 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
1975 for (i = 0; i < mti->mti_nid_count; i++) {
1976 CDEBUG(D_MGS, "add nid %s for mdt\n",
1977 libcfs_nid2str(mti->mti_nids[i]));
1979 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
1984 rc = record_attach(env, llh, mdcname, LUSTRE_MDC_NAME, lmvuuid);
1987 rc = record_setup(env, llh, mdcname, mti->mti_uuid, nodeuuid, 0, 0);
1990 rc = mgs_write_log_failnids(env, mti, llh, mdcname);
1993 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
1994 rc = record_mdc_add(env, llh, lmvname, mdcuuid, mti->mti_uuid,
1998 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname,
2003 record_end_log(env, &llh);
2005 name_destroy(&lmvuuid);
2006 name_destroy(&mdcuuid);
2007 name_destroy(&mdcname);
2008 name_destroy(&nodeuuid);
2012 static inline int name_create_lov(char **lovname, char *mdtname,
2013 struct fs_db *fsdb, int index)
2016 if (index == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2017 return name_create(lovname, fsdb->fsdb_name, "-mdtlov");
2019 return name_create(lovname, mdtname, "-mdtlov");
2022 static int name_create_mdt_and_lov(char **logname, char **lovname,
2023 struct fs_db *fsdb, int i)
2027 rc = name_create_mdt(logname, fsdb->fsdb_name, i);
2031 if (i == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2032 rc = name_create(lovname, fsdb->fsdb_name, "-mdtlov");
2034 rc = name_create(lovname, *logname, "-mdtlov");
2036 name_destroy(logname);
2042 static inline int name_create_mdt_osc(char **oscname, char *ostname,
2043 struct fs_db *fsdb, int i)
2047 if (i == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2048 sprintf(suffix, "-osc");
2050 sprintf(suffix, "-osc-MDT%04x", i);
2051 return name_create(oscname, ostname, suffix);
2054 /* add new mdc to already existent MDS */
2055 static int mgs_write_log_osp_to_mdt(const struct lu_env *env,
2056 struct mgs_device *mgs,
2058 struct mgs_target_info *mti,
2059 int mdt_index, char *logname)
2061 struct llog_handle *llh = NULL;
2062 char *nodeuuid = NULL;
2063 char *ospname = NULL;
2064 char *lovuuid = NULL;
2065 char *mdtuuid = NULL;
2066 char *svname = NULL;
2067 char *mdtname = NULL;
2068 char *lovname = NULL;
2073 if (mgs_log_is_empty(env, mgs, mti->mti_svname)) {
2074 CERROR("log is empty! Logical error\n");
2078 CDEBUG(D_MGS, "adding osp index %d to %s\n", mti->mti_stripe_index,
2081 rc = name_create_mdt(&mdtname, fsdb->fsdb_name, mti->mti_stripe_index);
2085 rc = name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
2087 GOTO(out_destory, rc);
2089 rc = name_create(&svname, mdtname, "-osp");
2091 GOTO(out_destory, rc);
2093 sprintf(index_str, "-MDT%04x", mdt_index);
2094 rc = name_create(&ospname, svname, index_str);
2096 GOTO(out_destory, rc);
2098 rc = name_create_lov(&lovname, logname, fsdb, mdt_index);
2100 GOTO(out_destory, rc);
2102 rc = name_create(&lovuuid, lovname, "_UUID");
2104 GOTO(out_destory, rc);
2106 rc = name_create(&mdtuuid, mdtname, "_UUID");
2108 GOTO(out_destory, rc);
2110 rc = record_start_log(env, mgs, &llh, logname);
2112 GOTO(out_destory, rc);
2114 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
2117 GOTO(out_destory, rc);
2119 for (i = 0; i < mti->mti_nid_count; i++) {
2120 CDEBUG(D_MGS, "add nid %s for mdt\n",
2121 libcfs_nid2str(mti->mti_nids[i]));
2122 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
2127 rc = record_attach(env, llh, ospname, LUSTRE_OSP_NAME, lovuuid);
2131 rc = record_setup(env, llh, ospname, mti->mti_uuid, nodeuuid,
2136 rc = mgs_write_log_failnids(env, mti, llh, ospname);
2140 /* Add mdc(osp) to lod */
2141 snprintf(index_str, sizeof(mti->mti_stripe_index), "%d",
2142 mti->mti_stripe_index);
2143 rc = record_base(env, llh, lovname, 0, LCFG_ADD_MDC, mti->mti_uuid,
2144 index_str, "1", NULL);
2148 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname, "add osp");
2153 record_end_log(env, &llh);
2156 name_destroy(&mdtuuid);
2157 name_destroy(&lovuuid);
2158 name_destroy(&lovname);
2159 name_destroy(&ospname);
2160 name_destroy(&svname);
2161 name_destroy(&nodeuuid);
2162 name_destroy(&mdtname);
2166 static int mgs_write_log_mdt0(const struct lu_env *env,
2167 struct mgs_device *mgs,
2169 struct mgs_target_info *mti)
2171 char *log = mti->mti_svname;
2172 struct llog_handle *llh = NULL;
2173 char *uuid, *lovname;
2175 char *ptr = mti->mti_params;
2176 int rc = 0, failout = 0;
2179 OBD_ALLOC(uuid, sizeof(struct obd_uuid));
2183 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
2184 failout = (strncmp(ptr, "failout", 7) == 0);
2186 rc = name_create(&lovname, log, "-mdtlov");
2189 if (mgs_log_is_empty(env, mgs, log)) {
2190 rc = mgs_write_log_lov(env, mgs, fsdb, mti, log, lovname);
2195 sprintf(mdt_index, "%d", mti->mti_stripe_index);
2197 rc = record_start_log(env, mgs, &llh, log);
2201 /* add MDT itself */
2203 /* FIXME this whole fn should be a single journal transaction */
2204 sprintf(uuid, "%s_UUID", log);
2205 rc = record_marker(env, llh, fsdb, CM_START, log, "add mdt");
2208 rc = record_attach(env, llh, log, LUSTRE_MDT_NAME, uuid);
2211 rc = record_mount_opt(env, llh, log, lovname, NULL);
2214 rc = record_setup(env, llh, log, uuid, mdt_index, lovname,
2215 failout ? "n" : "f");
2218 rc = record_marker(env, llh, fsdb, CM_END, log, "add mdt");
2222 record_end_log(env, &llh);
2224 name_destroy(&lovname);
2226 OBD_FREE(uuid, sizeof(struct obd_uuid));
2230 /* envelope method for all layers log */
2231 static int mgs_write_log_mdt(const struct lu_env *env,
2232 struct mgs_device *mgs,
2234 struct mgs_target_info *mti)
2236 struct mgs_thread_info *mgi = mgs_env_info(env);
2237 struct llog_handle *llh = NULL;
2242 CDEBUG(D_MGS, "writing new mdt %s\n", mti->mti_svname);
2244 if (mti->mti_uuid[0] == '\0') {
2245 /* Make up our own uuid */
2246 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
2247 "%s_UUID", mti->mti_svname);
2251 rc = mgs_write_log_mdt0(env, mgs, fsdb, mti);
2254 /* Append the mdt info to the client log */
2255 rc = name_create(&cliname, mti->mti_fsname, "-client");
2259 if (mgs_log_is_empty(env, mgs, cliname)) {
2260 /* Start client log */
2261 rc = mgs_write_log_lov(env, mgs, fsdb, mti, cliname,
2265 rc = mgs_write_log_lmv(env, mgs, fsdb, mti, cliname,
2272 #09 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
2273 #10 L attach 0:MDC_uml1_mdsA_MNT_client 1:mdc 2:1d834_MNT_client_03f
2274 #11 L setup 0:MDC_uml1_mdsA_MNT_client 1:mdsA_UUID 2:uml1_UUID
2275 #12 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
2276 #13 L add_conn 0:MDC_uml1_mdsA_MNT_client 1:uml2_UUID
2277 #14 L mount_option 0: 1:client 2:lov1 3:MDC_uml1_mdsA_MNT_client
2280 /* copy client info about lov/lmv */
2281 mgi->mgi_comp.comp_mti = mti;
2282 mgi->mgi_comp.comp_fsdb = fsdb;
2284 rc = mgs_steal_llog_for_mdt_from_client(env, mgs, cliname,
2288 rc = mgs_write_log_mdc_to_lmv(env, mgs, fsdb, mti, cliname,
2294 rc = record_start_log(env, mgs, &llh, cliname);
2298 rc = record_marker(env, llh, fsdb, CM_START, cliname,
2302 rc = record_mount_opt(env, llh, cliname, fsdb->fsdb_clilov,
2306 rc = record_marker(env, llh, fsdb, CM_END, cliname,
2312 /* for_all_existing_mdt except current one */
2313 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2314 if (i != mti->mti_stripe_index &&
2315 test_bit(i, fsdb->fsdb_mdt_index_map)) {
2318 rc = name_create_mdt(&logname, fsdb->fsdb_name, i);
2322 rc = mgs_write_log_osp_to_mdt(env, mgs, fsdb, mti,
2324 name_destroy(&logname);
2330 record_end_log(env, &llh);
2332 name_destroy(&cliname);
2336 /* Add the ost info to the client/mdt lov */
2337 static int mgs_write_log_osc_to_lov(const struct lu_env *env,
2338 struct mgs_device *mgs, struct fs_db *fsdb,
2339 struct mgs_target_info *mti,
2340 char *logname, char *suffix, char *lovname,
2341 enum lustre_sec_part sec_part, int flags)
2343 struct llog_handle *llh = NULL;
2344 char *nodeuuid = NULL;
2345 char *oscname = NULL;
2346 char *oscuuid = NULL;
2347 char *lovuuid = NULL;
2348 char *svname = NULL;
2353 CDEBUG(D_INFO, "adding osc for %s to log %s\n",
2354 mti->mti_svname, logname);
2356 if (mgs_log_is_empty(env, mgs, logname)) {
2357 CERROR("log is empty! Logical error\n");
2361 rc = name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
2364 rc = name_create(&svname, mti->mti_svname, "-osc");
2368 /* for the system upgraded from old 1.8, keep using the old osc naming
2369 * style for mdt, see name_create_mdt_osc(). LU-1257 */
2370 if (test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2371 rc = name_create(&oscname, svname, "");
2373 rc = name_create(&oscname, svname, suffix);
2377 rc = name_create(&oscuuid, oscname, "_UUID");
2380 rc = name_create(&lovuuid, lovname, "_UUID");
2386 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
2388 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
2389 #04 L attach 0:OSC_uml1_ost1_MNT_client 1:osc 2:89070_lov1_a41dff51a
2390 #05 L setup 0:OSC_uml1_ost1_MNT_client 1:ost1_UUID 2:uml1_UUID
2392 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
2393 #07 L add_conn 0:OSC_uml1_ost1_MNT_client 1:uml2_UUID
2394 #08 L lov_modify_tgts add 0:lov1 1:ost1_UUID 2(index):0 3(gen):1
2397 rc = record_start_log(env, mgs, &llh, logname);
2401 /* FIXME these should be a single journal transaction */
2402 rc = record_marker(env, llh, fsdb, CM_START | flags, mti->mti_svname,
2407 /* NB: don't change record order, because upon MDT steal OSC config
2408 * from client, it treats all nids before LCFG_SETUP as target nids
2409 * (multiple interfaces), while nids after as failover node nids.
2410 * See mgs_steal_client_llog_handler() LCFG_ADD_UUID.
2412 for (i = 0; i < mti->mti_nid_count; i++) {
2413 CDEBUG(D_MGS, "add nid %s\n", libcfs_nid2str(mti->mti_nids[i]));
2414 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
2418 rc = record_attach(env, llh, oscname, LUSTRE_OSC_NAME, lovuuid);
2421 rc = record_setup(env, llh, oscname, mti->mti_uuid, nodeuuid, 0, 0);
2424 rc = mgs_write_log_failnids(env, mti, llh, oscname);
2428 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
2430 rc = record_lov_add(env, llh, lovname, mti->mti_uuid, index, "1");
2433 rc = record_marker(env, llh, fsdb, CM_END | flags, mti->mti_svname,
2438 record_end_log(env, &llh);
2440 name_destroy(&lovuuid);
2441 name_destroy(&oscuuid);
2442 name_destroy(&oscname);
2443 name_destroy(&svname);
2444 name_destroy(&nodeuuid);
2448 static int mgs_write_log_ost(const struct lu_env *env,
2449 struct mgs_device *mgs, struct fs_db *fsdb,
2450 struct mgs_target_info *mti)
2452 struct llog_handle *llh = NULL;
2453 char *logname, *lovname;
2454 char *ptr = mti->mti_params;
2455 int rc, flags = 0, failout = 0, i;
2458 CDEBUG(D_MGS, "writing new ost %s\n", mti->mti_svname);
2460 /* The ost startup log */
2462 /* If the ost log already exists, that means that someone reformatted
2463 the ost and it called target_add again. */
2464 if (!mgs_log_is_empty(env, mgs, mti->mti_svname)) {
2465 LCONSOLE_ERROR_MSG(0x141, "The config log for %s already "
2466 "exists, yet the server claims it never "
2467 "registered. It may have been reformatted, "
2468 "or the index changed. writeconf the MDT to "
2469 "regenerate all logs.\n", mti->mti_svname);
2474 attach obdfilter ost1 ost1_UUID
2475 setup /dev/loop2 ldiskfs f|n errors=remount-ro,user_xattr
2477 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
2478 failout = (strncmp(ptr, "failout", 7) == 0);
2479 rc = record_start_log(env, mgs, &llh, mti->mti_svname);
2482 /* FIXME these should be a single journal transaction */
2483 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,"add ost");
2486 if (*mti->mti_uuid == '\0')
2487 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
2488 "%s_UUID", mti->mti_svname);
2489 rc = record_attach(env, llh, mti->mti_svname,
2490 "obdfilter"/*LUSTRE_OST_NAME*/, mti->mti_uuid);
2493 rc = record_setup(env, llh, mti->mti_svname,
2494 "dev"/*ignored*/, "type"/*ignored*/,
2495 failout ? "n" : "f", 0/*options*/);
2498 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname, "add ost");
2502 record_end_log(env, &llh);
2505 /* We also have to update the other logs where this osc is part of
2508 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
2509 /* If we're upgrading, the old mdt log already has our
2510 entry. Let's do a fake one for fun. */
2511 /* Note that we can't add any new failnids, since we don't
2512 know the old osc names. */
2513 flags = CM_SKIP | CM_UPGRADE146;
2515 } else if ((mti->mti_flags & LDD_F_UPDATE) != LDD_F_UPDATE) {
2516 /* If the update flag isn't set, don't update client/mdt
2519 LCONSOLE_WARN("Client log for %s was not updated; writeconf "
2520 "the MDT first to regenerate it.\n",
2524 /* Add ost to all MDT lov defs */
2525 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
2526 if (test_bit(i, fsdb->fsdb_mdt_index_map)) {
2529 rc = name_create_mdt_and_lov(&logname, &lovname, fsdb,
2533 sprintf(mdt_index, "-MDT%04x", i);
2534 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, mti,
2536 lovname, LUSTRE_SP_MDT,
2538 name_destroy(&logname);
2539 name_destroy(&lovname);
2545 /* Append ost info to the client log */
2546 rc = name_create(&logname, mti->mti_fsname, "-client");
2549 if (mgs_log_is_empty(env, mgs, logname)) {
2550 /* Start client log */
2551 rc = mgs_write_log_lov(env, mgs, fsdb, mti, logname,
2555 rc = mgs_write_log_lmv(env, mgs, fsdb, mti, logname,
2560 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, mti, logname, "",
2561 fsdb->fsdb_clilov, LUSTRE_SP_CLI, 0);
2563 name_destroy(&logname);
2567 static __inline__ int mgs_param_empty(char *ptr)
2571 if ((tmp = strchr(ptr, '=')) && (*(++tmp) == '\0'))
2576 static int mgs_write_log_failnid_internal(const struct lu_env *env,
2577 struct mgs_device *mgs,
2579 struct mgs_target_info *mti,
2580 char *logname, char *cliname)
2583 struct llog_handle *llh = NULL;
2585 if (mgs_param_empty(mti->mti_params)) {
2586 /* Remove _all_ failnids */
2587 rc = mgs_modify(env, mgs, fsdb, mti, logname,
2588 mti->mti_svname, "add failnid", CM_SKIP);
2589 return rc < 0 ? rc : 0;
2592 /* Otherwise failover nids are additive */
2593 rc = record_start_log(env, mgs, &llh, logname);
2596 /* FIXME this should be a single journal transaction */
2597 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
2601 rc = mgs_write_log_failnids(env, mti, llh, cliname);
2604 rc = record_marker(env, llh, fsdb, CM_END,
2605 mti->mti_svname, "add failnid");
2607 record_end_log(env, &llh);
2612 /* Add additional failnids to an existing log.
2613 The mdc/osc must have been added to logs first */
2614 /* tcp nids must be in dotted-quad ascii -
2615 we can't resolve hostnames from the kernel. */
2616 static int mgs_write_log_add_failnid(const struct lu_env *env,
2617 struct mgs_device *mgs,
2619 struct mgs_target_info *mti)
2621 char *logname, *cliname;
2625 /* FIXME we currently can't erase the failnids
2626 * given when a target first registers, since they aren't part of
2627 * an "add uuid" stanza */
2629 /* Verify that we know about this target */
2630 if (mgs_log_is_empty(env, mgs, mti->mti_svname)) {
2631 LCONSOLE_ERROR_MSG(0x142, "The target %s has not registered "
2632 "yet. It must be started before failnids "
2633 "can be added.\n", mti->mti_svname);
2637 /* Create mdc/osc client name (e.g. lustre-OST0001-osc) */
2638 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
2639 rc = name_create(&cliname, mti->mti_svname, "-mdc");
2640 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2641 rc = name_create(&cliname, mti->mti_svname, "-osc");
2647 /* Add failover nids to the client log */
2648 rc = name_create(&logname, mti->mti_fsname, "-client");
2650 name_destroy(&cliname);
2653 rc = mgs_write_log_failnid_internal(env, mgs, fsdb,mti,logname,cliname);
2654 name_destroy(&logname);
2655 name_destroy(&cliname);
2659 if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2660 /* Add OST failover nids to the MDT logs as well */
2663 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2664 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
2666 rc = name_create_mdt(&logname, mti->mti_fsname, i);
2669 rc = name_create_mdt_osc(&cliname, mti->mti_svname,
2672 name_destroy(&logname);
2675 rc = mgs_write_log_failnid_internal(env, mgs, fsdb,
2678 name_destroy(&cliname);
2679 name_destroy(&logname);
2688 static int mgs_wlp_lcfg(const struct lu_env *env,
2689 struct mgs_device *mgs, struct fs_db *fsdb,
2690 struct mgs_target_info *mti,
2691 char *logname, struct lustre_cfg_bufs *bufs,
2692 char *tgtname, char *ptr)
2694 char comment[MTI_NAME_MAXLEN];
2696 struct lustre_cfg *lcfg;
2699 /* Erase any old settings of this same parameter */
2700 memcpy(comment, ptr, MTI_NAME_MAXLEN);
2701 comment[MTI_NAME_MAXLEN - 1] = 0;
2702 /* But don't try to match the value. */
2703 if ((tmp = strchr(comment, '=')))
2705 /* FIXME we should skip settings that are the same as old values */
2706 rc = mgs_modify(env, mgs, fsdb, mti, logname, tgtname, comment,CM_SKIP);
2709 del = mgs_param_empty(ptr);
2711 LCONSOLE_INFO("%sing parameter %s.%s in log %s\n", del ? "Disabl" : rc ?
2712 "Sett" : "Modify", tgtname, comment, logname);
2716 lustre_cfg_bufs_reset(bufs, tgtname);
2717 lustre_cfg_bufs_set_string(bufs, 1, ptr);
2718 if (mti->mti_flags & LDD_F_PARAM2)
2719 lustre_cfg_bufs_set_string(bufs, 2, LCTL_UPCALL);
2721 lcfg = lustre_cfg_new((mti->mti_flags & LDD_F_PARAM2) ?
2722 LCFG_SET_PARAM : LCFG_PARAM, bufs);
2726 rc = mgs_write_log_direct(env, mgs, fsdb, logname,lcfg,tgtname,comment);
2727 lustre_cfg_free(lcfg);
2731 static int mgs_write_log_param2(const struct lu_env *env,
2732 struct mgs_device *mgs,
2734 struct mgs_target_info *mti, char *ptr)
2736 struct lustre_cfg_bufs bufs;
2740 CDEBUG(D_MGS, "next param '%s'\n", ptr);
2741 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, PARAMS_FILENAME, &bufs,
2742 mti->mti_svname, ptr);
2747 /* write global variable settings into log */
2748 static int mgs_write_log_sys(const struct lu_env *env,
2749 struct mgs_device *mgs, struct fs_db *fsdb,
2750 struct mgs_target_info *mti, char *sys, char *ptr)
2752 struct mgs_thread_info *mgi = mgs_env_info(env);
2753 struct lustre_cfg *lcfg;
2755 int rc, cmd, convert = 1;
2757 if (class_match_param(ptr, PARAM_TIMEOUT, &tmp) == 0) {
2758 cmd = LCFG_SET_TIMEOUT;
2759 } else if (class_match_param(ptr, PARAM_LDLM_TIMEOUT, &tmp) == 0) {
2760 cmd = LCFG_SET_LDLM_TIMEOUT;
2761 /* Check for known params here so we can return error to lctl */
2762 } else if ((class_match_param(ptr, PARAM_AT_MIN, &tmp) == 0) ||
2763 (class_match_param(ptr, PARAM_AT_MAX, &tmp) == 0) ||
2764 (class_match_param(ptr, PARAM_AT_EXTRA, &tmp) == 0) ||
2765 (class_match_param(ptr, PARAM_AT_EARLY_MARGIN, &tmp) == 0) ||
2766 (class_match_param(ptr, PARAM_AT_HISTORY, &tmp) == 0)) {
2768 } else if (class_match_param(ptr, PARAM_JOBID_VAR, &tmp) == 0) {
2769 convert = 0; /* Don't convert string value to integer */
2775 if (mgs_param_empty(ptr))
2776 CDEBUG(D_MGS, "global '%s' removed\n", sys);
2778 CDEBUG(D_MGS, "global '%s' val=%s\n", sys, tmp);
2780 lustre_cfg_bufs_reset(&mgi->mgi_bufs, NULL);
2781 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, sys);
2782 if (!convert && *tmp != '\0')
2783 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 2, tmp);
2784 lcfg = lustre_cfg_new(cmd, &mgi->mgi_bufs);
2785 lcfg->lcfg_num = convert ? simple_strtoul(tmp, NULL, 0) : 0;
2786 /* truncate the comment to the parameter name */
2790 /* modify all servers and clients */
2791 rc = mgs_write_log_direct_all(env, mgs, fsdb, mti,
2792 *tmp == '\0' ? NULL : lcfg,
2793 mti->mti_fsname, sys, 0);
2794 if (rc == 0 && *tmp != '\0') {
2796 case LCFG_SET_TIMEOUT:
2797 if (!obd_timeout_set || lcfg->lcfg_num > obd_timeout)
2798 class_process_config(lcfg);
2800 case LCFG_SET_LDLM_TIMEOUT:
2801 if (!ldlm_timeout_set || lcfg->lcfg_num > ldlm_timeout)
2802 class_process_config(lcfg);
2809 lustre_cfg_free(lcfg);
2813 /* write quota settings into log */
2814 static int mgs_write_log_quota(const struct lu_env *env, struct mgs_device *mgs,
2815 struct fs_db *fsdb, struct mgs_target_info *mti,
2816 char *quota, char *ptr)
2818 struct mgs_thread_info *mgi = mgs_env_info(env);
2819 struct lustre_cfg *lcfg;
2822 int rc, cmd = LCFG_PARAM;
2824 /* support only 'meta' and 'data' pools so far */
2825 if (class_match_param(ptr, QUOTA_METAPOOL_NAME, &tmp) != 0 &&
2826 class_match_param(ptr, QUOTA_DATAPOOL_NAME, &tmp) != 0) {
2827 CERROR("parameter quota.%s isn't supported (only quota.mdt "
2828 "& quota.ost are)\n", ptr);
2833 CDEBUG(D_MGS, "global '%s' removed\n", quota);
2835 CDEBUG(D_MGS, "global '%s'\n", quota);
2837 if (strchr(tmp, 'u') == NULL && strchr(tmp, 'g') == NULL &&
2838 strcmp(tmp, "none") != 0) {
2839 CERROR("enable option(%s) isn't supported\n", tmp);
2844 lustre_cfg_bufs_reset(&mgi->mgi_bufs, mti->mti_fsname);
2845 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, quota);
2846 lcfg = lustre_cfg_new(cmd, &mgi->mgi_bufs);
2847 /* truncate the comment to the parameter name */
2852 /* XXX we duplicated quota enable information in all server
2853 * config logs, it should be moved to a separate config
2854 * log once we cleanup the config log for global param. */
2855 /* modify all servers */
2856 rc = mgs_write_log_direct_all(env, mgs, fsdb, mti,
2857 *tmp == '\0' ? NULL : lcfg,
2858 mti->mti_fsname, quota, 1);
2860 lustre_cfg_free(lcfg);
2861 return rc < 0 ? rc : 0;
2864 static int mgs_srpc_set_param_disk(const struct lu_env *env,
2865 struct mgs_device *mgs,
2867 struct mgs_target_info *mti,
2870 struct mgs_thread_info *mgi = mgs_env_info(env);
2871 struct llog_handle *llh = NULL;
2873 char *comment, *ptr;
2874 struct lustre_cfg *lcfg;
2879 ptr = strchr(param, '=');
2883 OBD_ALLOC(comment, len + 1);
2884 if (comment == NULL)
2886 strncpy(comment, param, len);
2887 comment[len] = '\0';
2890 lustre_cfg_bufs_reset(&mgi->mgi_bufs, mti->mti_svname);
2891 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, param);
2892 lcfg = lustre_cfg_new(LCFG_SPTLRPC_CONF, &mgi->mgi_bufs);
2894 GOTO(out_comment, rc = -ENOMEM);
2896 /* construct log name */
2897 rc = name_create(&logname, mti->mti_fsname, "-sptlrpc");
2901 if (mgs_log_is_empty(env, mgs, logname)) {
2902 rc = record_start_log(env, mgs, &llh, logname);
2905 record_end_log(env, &llh);
2908 /* obsolete old one */
2909 rc = mgs_modify(env, mgs, fsdb, mti, logname, mti->mti_svname,
2913 /* write the new one */
2914 rc = mgs_write_log_direct(env, mgs, fsdb, logname, lcfg,
2915 mti->mti_svname, comment);
2917 CERROR("err %d writing log %s\n", rc, logname);
2919 name_destroy(&logname);
2921 lustre_cfg_free(lcfg);
2923 OBD_FREE(comment, len + 1);
2927 static int mgs_srpc_set_param_udesc_mem(struct fs_db *fsdb,
2932 /* disable the adjustable udesc parameter for now, i.e. use default
2933 * setting that client always ship udesc to MDT if possible. to enable
2934 * it simply remove the following line */
2937 ptr = strchr(param, '=');
2942 if (strcmp(param, PARAM_SRPC_UDESC))
2945 if (strcmp(ptr, "yes") == 0) {
2946 set_bit(FSDB_UDESC, &fsdb->fsdb_flags);
2947 CWARN("Enable user descriptor shipping from client to MDT\n");
2948 } else if (strcmp(ptr, "no") == 0) {
2949 clear_bit(FSDB_UDESC, &fsdb->fsdb_flags);
2950 CWARN("Disable user descriptor shipping from client to MDT\n");
2958 CERROR("Invalid param: %s\n", param);
2962 static int mgs_srpc_set_param_mem(struct fs_db *fsdb,
2966 struct sptlrpc_rule rule;
2967 struct sptlrpc_rule_set *rset;
2971 if (strncmp(param, PARAM_SRPC, sizeof(PARAM_SRPC) - 1) != 0) {
2972 CERROR("Invalid sptlrpc parameter: %s\n", param);
2976 if (strncmp(param, PARAM_SRPC_UDESC,
2977 sizeof(PARAM_SRPC_UDESC) - 1) == 0) {
2978 RETURN(mgs_srpc_set_param_udesc_mem(fsdb, param));
2981 if (strncmp(param, PARAM_SRPC_FLVR, sizeof(PARAM_SRPC_FLVR) - 1) != 0) {
2982 CERROR("Invalid sptlrpc flavor parameter: %s\n", param);
2986 param += sizeof(PARAM_SRPC_FLVR) - 1;
2988 rc = sptlrpc_parse_rule(param, &rule);
2992 /* mgs rules implies must be mgc->mgs */
2993 if (test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
2994 if ((rule.sr_from != LUSTRE_SP_MGC &&
2995 rule.sr_from != LUSTRE_SP_ANY) ||
2996 (rule.sr_to != LUSTRE_SP_MGS &&
2997 rule.sr_to != LUSTRE_SP_ANY))
3001 /* preapre room for this coming rule. svcname format should be:
3002 * - fsname: general rule
3003 * - fsname-tgtname: target-specific rule
3005 if (strchr(svname, '-')) {
3006 struct mgs_tgt_srpc_conf *tgtconf;
3009 for (tgtconf = fsdb->fsdb_srpc_tgt; tgtconf != NULL;
3010 tgtconf = tgtconf->mtsc_next) {
3011 if (!strcmp(tgtconf->mtsc_tgt, svname)) {
3020 OBD_ALLOC_PTR(tgtconf);
3021 if (tgtconf == NULL)
3024 name_len = strlen(svname);
3026 OBD_ALLOC(tgtconf->mtsc_tgt, name_len + 1);
3027 if (tgtconf->mtsc_tgt == NULL) {
3028 OBD_FREE_PTR(tgtconf);
3031 memcpy(tgtconf->mtsc_tgt, svname, name_len);
3033 tgtconf->mtsc_next = fsdb->fsdb_srpc_tgt;
3034 fsdb->fsdb_srpc_tgt = tgtconf;
3037 rset = &tgtconf->mtsc_rset;
3039 rset = &fsdb->fsdb_srpc_gen;
3042 rc = sptlrpc_rule_set_merge(rset, &rule);
3047 static int mgs_srpc_set_param(const struct lu_env *env,
3048 struct mgs_device *mgs,
3050 struct mgs_target_info *mti,
3060 /* keep a copy of original param, which could be destroied
3062 copy_size = strlen(param) + 1;
3063 OBD_ALLOC(copy, copy_size);
3066 memcpy(copy, param, copy_size);
3068 rc = mgs_srpc_set_param_mem(fsdb, mti->mti_svname, param);
3072 /* previous steps guaranteed the syntax is correct */
3073 rc = mgs_srpc_set_param_disk(env, mgs, fsdb, mti, copy);
3077 if (test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
3079 * for mgs rules, make them effective immediately.
3081 LASSERT(fsdb->fsdb_srpc_tgt == NULL);
3082 sptlrpc_target_update_exp_flavor(mgs->mgs_obd,
3083 &fsdb->fsdb_srpc_gen);
3087 OBD_FREE(copy, copy_size);
3091 struct mgs_srpc_read_data {
3092 struct fs_db *msrd_fsdb;
3096 static int mgs_srpc_read_handler(const struct lu_env *env,
3097 struct llog_handle *llh,
3098 struct llog_rec_hdr *rec, void *data)
3100 struct mgs_srpc_read_data *msrd = data;
3101 struct cfg_marker *marker;
3102 struct lustre_cfg *lcfg = REC_DATA(rec);
3103 char *svname, *param;
3107 if (rec->lrh_type != OBD_CFG_REC) {
3108 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
3112 cfg_len = rec->lrh_len - sizeof(struct llog_rec_hdr) -
3113 sizeof(struct llog_rec_tail);
3115 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
3117 CERROR("Insane cfg\n");
3121 if (lcfg->lcfg_command == LCFG_MARKER) {
3122 marker = lustre_cfg_buf(lcfg, 1);
3124 if (marker->cm_flags & CM_START &&
3125 marker->cm_flags & CM_SKIP)
3126 msrd->msrd_skip = 1;
3127 if (marker->cm_flags & CM_END)
3128 msrd->msrd_skip = 0;
3133 if (msrd->msrd_skip)
3136 if (lcfg->lcfg_command != LCFG_SPTLRPC_CONF) {
3137 CERROR("invalid command (%x)\n", lcfg->lcfg_command);
3141 svname = lustre_cfg_string(lcfg, 0);
3142 if (svname == NULL) {
3143 CERROR("svname is empty\n");
3147 param = lustre_cfg_string(lcfg, 1);
3148 if (param == NULL) {
3149 CERROR("param is empty\n");
3153 rc = mgs_srpc_set_param_mem(msrd->msrd_fsdb, svname, param);
3155 CERROR("read sptlrpc record error (%d): %s\n", rc, param);
3160 int mgs_get_fsdb_srpc_from_llog(const struct lu_env *env,
3161 struct mgs_device *mgs,
3164 struct llog_handle *llh = NULL;
3165 struct llog_ctxt *ctxt;
3167 struct mgs_srpc_read_data msrd;
3171 /* construct log name */
3172 rc = name_create(&logname, fsdb->fsdb_name, "-sptlrpc");
3176 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
3177 LASSERT(ctxt != NULL);
3179 if (mgs_log_is_empty(env, mgs, logname))
3182 rc = llog_open(env, ctxt, &llh, NULL, logname,
3190 rc = llog_init_handle(env, llh, LLOG_F_IS_PLAIN, NULL);
3192 GOTO(out_close, rc);
3194 if (llog_get_size(llh) <= 1)
3195 GOTO(out_close, rc = 0);
3197 msrd.msrd_fsdb = fsdb;
3200 rc = llog_process(env, llh, mgs_srpc_read_handler, (void *)&msrd,
3204 llog_close(env, llh);
3206 llog_ctxt_put(ctxt);
3207 name_destroy(&logname);
3210 CERROR("failed to read sptlrpc config database: %d\n", rc);
3214 /* Permanent settings of all parameters by writing into the appropriate
3215 * configuration logs.
3216 * A parameter with null value ("<param>='\0'") means to erase it out of
3219 static int mgs_write_log_param(const struct lu_env *env,
3220 struct mgs_device *mgs, struct fs_db *fsdb,
3221 struct mgs_target_info *mti, char *ptr)
3223 struct mgs_thread_info *mgi = mgs_env_info(env);
3226 int rc = 0, rc2 = 0;
3229 /* For various parameter settings, we have to figure out which logs
3230 care about them (e.g. both mdt and client for lov settings) */
3231 CDEBUG(D_MGS, "next param '%s'\n", ptr);
3233 /* The params are stored in MOUNT_DATA_FILE and modified via
3234 tunefs.lustre, or set using lctl conf_param */
3236 /* Processed in lustre_start_mgc */
3237 if (class_match_param(ptr, PARAM_MGSNODE, NULL) == 0)
3240 /* Processed in ost/mdt */
3241 if (class_match_param(ptr, PARAM_NETWORK, NULL) == 0)
3244 /* Processed in mgs_write_log_ost */
3245 if (class_match_param(ptr, PARAM_FAILMODE, NULL) == 0) {
3246 if (mti->mti_flags & LDD_F_PARAM) {
3247 LCONSOLE_ERROR_MSG(0x169, "%s can only be "
3248 "changed with tunefs.lustre"
3249 "and --writeconf\n", ptr);
3255 if (class_match_param(ptr, PARAM_SRPC, NULL) == 0) {
3256 rc = mgs_srpc_set_param(env, mgs, fsdb, mti, ptr);
3260 if (class_match_param(ptr, PARAM_FAILNODE, NULL) == 0) {
3261 /* Add a failover nidlist */
3263 /* We already processed failovers params for new
3264 targets in mgs_write_log_target */
3265 if (mti->mti_flags & LDD_F_PARAM) {
3266 CDEBUG(D_MGS, "Adding failnode\n");
3267 rc = mgs_write_log_add_failnid(env, mgs, fsdb, mti);
3272 if (class_match_param(ptr, PARAM_SYS, &tmp) == 0) {
3273 rc = mgs_write_log_sys(env, mgs, fsdb, mti, ptr, tmp);
3277 if (class_match_param(ptr, PARAM_QUOTA, &tmp) == 0) {
3278 rc = mgs_write_log_quota(env, mgs, fsdb, mti, ptr, tmp);
3282 if (class_match_param(ptr, PARAM_OSC""PARAM_ACTIVE, &tmp) == 0) {
3283 /* active=0 means off, anything else means on */
3284 int flag = (*tmp == '0') ? CM_EXCLUDE : 0;
3287 if (!(mti->mti_flags & LDD_F_SV_TYPE_OST)) {
3288 LCONSOLE_ERROR_MSG(0x144, "%s: Only OSCs can "
3289 "be (de)activated.\n",
3291 GOTO(end, rc = -EINVAL);
3293 LCONSOLE_WARN("Permanently %sactivating %s\n",
3294 flag ? "de": "re", mti->mti_svname);
3296 rc = name_create(&logname, mti->mti_fsname, "-client");
3299 rc = mgs_modify(env, mgs, fsdb, mti, logname,
3300 mti->mti_svname, "add osc", flag);
3301 name_destroy(&logname);
3305 /* Add to all MDT logs for CMD */
3306 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3307 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
3309 rc = name_create_mdt(&logname, mti->mti_fsname, i);
3312 rc = mgs_modify(env, mgs, fsdb, mti, logname,
3313 mti->mti_svname, "add osc", flag);
3314 name_destroy(&logname);
3320 LCONSOLE_ERROR_MSG(0x145, "Couldn't find %s in"
3321 "log (%d). No permanent "
3322 "changes were made to the "
3324 mti->mti_svname, rc);
3325 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags))
3326 LCONSOLE_ERROR_MSG(0x146, "This may be"
3331 "update the logs.\n");
3334 /* Fall through to osc proc for deactivating live OSC
3335 on running MDT / clients. */
3337 /* Below here, let obd's XXX_process_config methods handle it */
3339 /* All lov. in proc */
3340 if (class_match_param(ptr, PARAM_LOV, NULL) == 0) {
3343 CDEBUG(D_MGS, "lov param %s\n", ptr);
3344 if (!(mti->mti_flags & LDD_F_SV_TYPE_MDT)) {
3345 LCONSOLE_ERROR_MSG(0x147, "LOV params must be "
3346 "set on the MDT, not %s. "
3353 if (mgs_log_is_empty(env, mgs, mti->mti_svname))
3354 GOTO(end, rc = -ENODEV);
3356 rc = name_create_mdt_and_lov(&logname, &mdtlovname, fsdb,
3357 mti->mti_stripe_index);
3360 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, mti->mti_svname,
3361 &mgi->mgi_bufs, mdtlovname, ptr);
3362 name_destroy(&logname);
3363 name_destroy(&mdtlovname);
3368 rc = name_create(&logname, mti->mti_fsname, "-client");
3371 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname, &mgi->mgi_bufs,
3372 fsdb->fsdb_clilov, ptr);
3373 name_destroy(&logname);
3377 /* All osc., mdc., llite. params in proc */
3378 if ((class_match_param(ptr, PARAM_OSC, NULL) == 0) ||
3379 (class_match_param(ptr, PARAM_MDC, NULL) == 0) ||
3380 (class_match_param(ptr, PARAM_LLITE, NULL) == 0)) {
3383 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
3384 LCONSOLE_ERROR_MSG(0x148, "Upgraded client logs for %s"
3385 " cannot be modified. Consider"
3386 " updating the configuration with"
3389 GOTO(end, rc = -EINVAL);
3391 if (memcmp(ptr, PARAM_LLITE, strlen(PARAM_LLITE)) == 0) {
3392 rc = name_create(&cname, mti->mti_fsname, "-client");
3393 /* Add the client type to match the obdname in
3394 class_config_llog_handler */
3395 } else if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
3396 rc = name_create(&cname, mti->mti_svname, "-mdc");
3397 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
3398 rc = name_create(&cname, mti->mti_svname, "-osc");
3400 GOTO(end, rc = -EINVAL);
3405 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
3408 rc = name_create(&logname, mti->mti_fsname, "-client");
3410 name_destroy(&cname);
3413 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname, &mgi->mgi_bufs,
3416 /* osc params affect the MDT as well */
3417 if (!rc && (mti->mti_flags & LDD_F_SV_TYPE_OST)) {
3420 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
3421 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
3423 name_destroy(&cname);
3424 rc = name_create_mdt_osc(&cname, mti->mti_svname,
3426 name_destroy(&logname);
3429 rc = name_create_mdt(&logname,
3430 mti->mti_fsname, i);
3433 if (!mgs_log_is_empty(env, mgs, logname)) {
3434 rc = mgs_wlp_lcfg(env, mgs, fsdb,
3443 name_destroy(&logname);
3444 name_destroy(&cname);
3448 /* All mdt. params in proc */
3449 if (class_match_param(ptr, PARAM_MDT, NULL) == 0) {
3453 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
3454 if (strncmp(mti->mti_svname, mti->mti_fsname,
3455 MTI_NAME_MAXLEN) == 0)
3456 /* device is unspecified completely? */
3457 rc = LDD_F_SV_TYPE_MDT | LDD_F_SV_ALL;
3459 rc = server_name2index(mti->mti_svname, &idx, NULL);
3462 if ((rc & LDD_F_SV_TYPE_MDT) == 0)
3464 if (rc & LDD_F_SV_ALL) {
3465 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3467 fsdb->fsdb_mdt_index_map))
3469 rc = name_create_mdt(&logname,
3470 mti->mti_fsname, i);
3473 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti,
3474 logname, &mgi->mgi_bufs,
3476 name_destroy(&logname);
3481 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti,
3482 mti->mti_svname, &mgi->mgi_bufs,
3483 mti->mti_svname, ptr);
3490 /* All mdd., ost. params in proc */
3491 if ((class_match_param(ptr, PARAM_MDD, NULL) == 0) ||
3492 (class_match_param(ptr, PARAM_OST, NULL) == 0)) {
3493 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
3494 if (mgs_log_is_empty(env, mgs, mti->mti_svname))
3495 GOTO(end, rc = -ENODEV);
3497 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, mti->mti_svname,
3498 &mgi->mgi_bufs, mti->mti_svname, ptr);
3502 LCONSOLE_WARN("Ignoring unrecognized param '%s'\n", ptr);
3507 CERROR("err %d on param '%s'\n", rc, ptr);
3512 /* Not implementing automatic failover nid addition at this time. */
3513 int mgs_check_failnid(const struct lu_env *env, struct mgs_device *mgs,
3514 struct mgs_target_info *mti)
3521 rc = mgs_find_or_make_fsdb(obd, fsname, &fsdb);
3525 if (mgs_log_is_empty(obd, mti->mti_svname))
3526 /* should never happen */
3529 CDEBUG(D_MGS, "Checking for new failnids for %s\n", mti->mti_svname);
3531 /* FIXME We can just check mti->params to see if we're already in
3532 the failover list. Modify mti->params for rewriting back at
3533 server_register_target(). */
3535 mutex_lock(&fsdb->fsdb_mutex);
3536 rc = mgs_write_log_add_failnid(obd, fsdb, mti);
3537 mutex_unlock(&fsdb->fsdb_mutex);
3544 int mgs_write_log_target(const struct lu_env *env,
3545 struct mgs_device *mgs,
3546 struct mgs_target_info *mti,
3553 /* set/check the new target index */
3554 rc = mgs_set_index(env, mgs, mti);
3556 CERROR("Can't get index (%d)\n", rc);
3560 if (rc == EALREADY) {
3561 LCONSOLE_WARN("Found index %d for %s, updating log\n",
3562 mti->mti_stripe_index, mti->mti_svname);
3563 /* We would like to mark old log sections as invalid
3564 and add new log sections in the client and mdt logs.
3565 But if we add new sections, then live clients will
3566 get repeat setup instructions for already running
3567 osc's. So don't update the client/mdt logs. */
3568 mti->mti_flags &= ~LDD_F_UPDATE;
3572 mutex_lock(&fsdb->fsdb_mutex);
3574 if (mti->mti_flags &
3575 (LDD_F_VIRGIN | LDD_F_UPGRADE14 | LDD_F_WRITECONF)) {
3576 /* Generate a log from scratch */
3577 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
3578 rc = mgs_write_log_mdt(env, mgs, fsdb, mti);
3579 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
3580 rc = mgs_write_log_ost(env, mgs, fsdb, mti);
3582 CERROR("Unknown target type %#x, can't create log for "
3583 "%s\n", mti->mti_flags, mti->mti_svname);
3586 CERROR("Can't write logs for %s (%d)\n",
3587 mti->mti_svname, rc);
3591 /* Just update the params from tunefs in mgs_write_log_params */
3592 CDEBUG(D_MGS, "Update params for %s\n", mti->mti_svname);
3593 mti->mti_flags |= LDD_F_PARAM;
3596 /* allocate temporary buffer, where class_get_next_param will
3597 make copy of a current parameter */
3598 OBD_ALLOC(buf, strlen(mti->mti_params) + 1);
3600 GOTO(out_up, rc = -ENOMEM);
3601 params = mti->mti_params;
3602 while (params != NULL) {
3603 rc = class_get_next_param(¶ms, buf);
3606 /* there is no next parameter, that is
3611 CDEBUG(D_MGS, "remaining string: '%s', param: '%s'\n",
3613 rc = mgs_write_log_param(env, mgs, fsdb, mti, buf);
3618 OBD_FREE(buf, strlen(mti->mti_params) + 1);
3621 mutex_unlock(&fsdb->fsdb_mutex);
3625 int mgs_erase_log(const struct lu_env *env, struct mgs_device *mgs, char *name)
3627 struct llog_ctxt *ctxt;
3630 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
3632 CERROR("%s: MGS config context doesn't exist\n",
3633 mgs->mgs_obd->obd_name);
3636 rc = llog_erase(env, ctxt, NULL, name);
3637 /* llog may not exist */
3640 llog_ctxt_put(ctxt);
3644 CERROR("%s: failed to clear log %s: %d\n",
3645 mgs->mgs_obd->obd_name, name, rc);
3650 /* erase all logs for the given fs */
3651 int mgs_erase_logs(const struct lu_env *env, struct mgs_device *mgs, char *fsname)
3655 struct mgs_direntry *dirent, *n;
3656 int rc, len = strlen(fsname);
3660 /* Find all the logs in the CONFIGS directory */
3661 rc = class_dentry_readdir(env, mgs, &list);
3665 mutex_lock(&mgs->mgs_mutex);
3667 /* Delete the fs db */
3668 fsdb = mgs_find_fsdb(mgs, fsname);
3670 mgs_free_fsdb(mgs, fsdb);
3672 mutex_unlock(&mgs->mgs_mutex);
3674 cfs_list_for_each_entry_safe(dirent, n, &list, list) {
3675 cfs_list_del(&dirent->list);
3676 suffix = strrchr(dirent->name, '-');
3677 if (suffix != NULL) {
3678 if ((len == suffix - dirent->name) &&
3679 (strncmp(fsname, dirent->name, len) == 0)) {
3680 CDEBUG(D_MGS, "Removing log %s\n",
3682 mgs_erase_log(env, mgs, dirent->name);
3685 mgs_direntry_free(dirent);
3691 /* list all logs for the given fs */
3692 int mgs_list_logs(const struct lu_env *env, struct mgs_device *mgs,
3693 struct obd_ioctl_data *data)
3696 struct mgs_direntry *dirent, *n;
3702 /* Find all the logs in the CONFIGS directory */
3703 rc = class_dentry_readdir(env, mgs, &list);
3705 CERROR("%s: can't read %s dir = %d\n",
3706 mgs->mgs_obd->obd_name, MOUNT_CONFIGS_DIR, rc);
3710 out = data->ioc_bulk;
3711 remains = data->ioc_inllen1;
3712 cfs_list_for_each_entry_safe(dirent, n, &list, list) {
3713 cfs_list_del(&dirent->list);
3714 suffix = strrchr(dirent->name, '-');
3715 if (suffix != NULL) {
3716 l = snprintf(out, remains, "config log: $%s\n",
3721 mgs_direntry_free(dirent);
3728 /* from llog_swab */
3729 static void print_lustre_cfg(struct lustre_cfg *lcfg)
3734 CDEBUG(D_MGS, "lustre_cfg: %p\n", lcfg);
3735 CDEBUG(D_MGS, "\tlcfg->lcfg_version: %#x\n", lcfg->lcfg_version);
3737 CDEBUG(D_MGS, "\tlcfg->lcfg_command: %#x\n", lcfg->lcfg_command);
3738 CDEBUG(D_MGS, "\tlcfg->lcfg_num: %#x\n", lcfg->lcfg_num);
3739 CDEBUG(D_MGS, "\tlcfg->lcfg_flags: %#x\n", lcfg->lcfg_flags);
3740 CDEBUG(D_MGS, "\tlcfg->lcfg_nid: %s\n", libcfs_nid2str(lcfg->lcfg_nid));
3742 CDEBUG(D_MGS, "\tlcfg->lcfg_bufcount: %d\n", lcfg->lcfg_bufcount);
3743 if (lcfg->lcfg_bufcount < LUSTRE_CFG_MAX_BUFCOUNT)
3744 for (i = 0; i < lcfg->lcfg_bufcount; i++) {
3745 CDEBUG(D_MGS, "\tlcfg->lcfg_buflens[%d]: %d %s\n",
3746 i, lcfg->lcfg_buflens[i],
3747 lustre_cfg_string(lcfg, i));
3752 /* Set a permanent (config log) param for a target or fs
3753 * \param lcfg buf0 may contain the device (testfs-MDT0000) name
3754 * buf1 contains the single parameter
3756 int mgs_setparam(const struct lu_env *env, struct mgs_device *mgs,
3757 struct lustre_cfg *lcfg, char *fsname)
3760 struct mgs_target_info *mti;
3761 char *devname, *param;
3768 print_lustre_cfg(lcfg);
3770 /* lustre, lustre-mdtlov, lustre-client, lustre-MDT0000 */
3771 devname = lustre_cfg_string(lcfg, 0);
3772 param = lustre_cfg_string(lcfg, 1);
3774 /* Assume device name embedded in param:
3775 lustre-OST0000.osc.max_dirty_mb=32 */
3776 ptr = strchr(param, '.');
3784 LCONSOLE_ERROR_MSG(0x14d, "No target specified: %s\n", param);
3788 rc = mgs_parse_devname(devname, fsname, NULL);
3789 if (rc == 0 && !mgs_parse_devname(devname, NULL, &index)) {
3790 /* param related to llite isn't allowed to set by OST or MDT */
3791 if (rc == 0 && strncmp(param, PARAM_LLITE,
3792 sizeof(PARAM_LLITE)) == 0)
3795 /* assume devname is the fsname */
3796 memset(fsname, 0, MTI_NAME_MAXLEN);
3797 strncpy(fsname, devname, MTI_NAME_MAXLEN);
3798 fsname[MTI_NAME_MAXLEN - 1] = 0;
3800 CDEBUG(D_MGS, "setparam fs='%s' device='%s'\n", fsname, devname);
3802 rc = mgs_find_or_make_fsdb(env, mgs,
3803 lcfg->lcfg_command == LCFG_SET_PARAM ?
3804 PARAMS_FILENAME : fsname, &fsdb);
3808 if (lcfg->lcfg_command != LCFG_SET_PARAM &&
3809 !test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags) &&
3810 test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
3811 CERROR("No filesystem targets for %s. cfg_device from lctl "
3812 "is '%s'\n", fsname, devname);
3813 mgs_free_fsdb(mgs, fsdb);
3817 /* Create a fake mti to hold everything */
3820 GOTO(out, rc = -ENOMEM);
3821 if (strlcpy(mti->mti_fsname, fsname, sizeof(mti->mti_fsname))
3822 >= sizeof(mti->mti_fsname))
3823 GOTO(out, rc = -E2BIG);
3824 if (strlcpy(mti->mti_svname, devname, sizeof(mti->mti_svname))
3825 >= sizeof(mti->mti_svname))
3826 GOTO(out, rc = -E2BIG);
3827 if (strlcpy(mti->mti_params, param, sizeof(mti->mti_params))
3828 >= sizeof(mti->mti_params))
3829 GOTO(out, rc = -E2BIG);
3830 rc = server_name2index(mti->mti_svname, &mti->mti_stripe_index, &tmp);
3832 /* Not a valid server; may be only fsname */
3835 /* Strip -osc or -mdc suffix from svname */
3836 if (server_make_name(rc, mti->mti_stripe_index, mti->mti_fsname,
3838 GOTO(out, rc = -EINVAL);
3840 * Revoke lock so everyone updates. Should be alright if
3841 * someone was already reading while we were updating the logs,
3842 * so we don't really need to hold the lock while we're
3845 if (lcfg->lcfg_command == LCFG_SET_PARAM) {
3846 mti->mti_flags = rc | LDD_F_PARAM2;
3847 mutex_lock(&fsdb->fsdb_mutex);
3848 rc = mgs_write_log_param2(env, mgs, fsdb, mti, mti->mti_params);
3849 mutex_unlock(&fsdb->fsdb_mutex);
3850 mgs_revoke_lock(mgs, fsdb, CONFIG_T_PARAMS);
3852 mti->mti_flags = rc | LDD_F_PARAM;
3853 mutex_lock(&fsdb->fsdb_mutex);
3854 rc = mgs_write_log_param(env, mgs, fsdb, mti, mti->mti_params);
3855 mutex_unlock(&fsdb->fsdb_mutex);
3856 mgs_revoke_lock(mgs, fsdb, CONFIG_T_CONFIG);
3864 static int mgs_write_log_pool(const struct lu_env *env,
3865 struct mgs_device *mgs, char *logname,
3866 struct fs_db *fsdb, char *tgtname,
3867 enum lcfg_command_type cmd,
3868 char *fsname, char *poolname,
3869 char *ostname, char *comment)
3871 struct llog_handle *llh = NULL;
3874 rc = record_start_log(env, mgs, &llh, logname);
3877 rc = record_marker(env, llh, fsdb, CM_START, tgtname, comment);
3880 rc = record_base(env, llh, tgtname, 0, cmd,
3881 fsname, poolname, ostname, 0);
3884 rc = record_marker(env, llh, fsdb, CM_END, tgtname, comment);
3886 record_end_log(env, &llh);
3890 int mgs_pool_cmd(const struct lu_env *env, struct mgs_device *mgs,
3891 enum lcfg_command_type cmd, char *fsname,
3892 char *poolname, char *ostname)
3897 char *label = NULL, *canceled_label = NULL;
3899 struct mgs_target_info *mti = NULL;
3903 rc = mgs_find_or_make_fsdb(env, mgs, fsname, &fsdb);
3905 CERROR("Can't get db for %s\n", fsname);
3908 if (test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
3909 CERROR("%s is not defined\n", fsname);
3910 mgs_free_fsdb(mgs, fsdb);
3914 label_sz = 10 + strlen(fsname) + strlen(poolname);
3916 /* check if ostname match fsname */
3917 if (ostname != NULL) {
3920 ptr = strrchr(ostname, '-');
3921 if ((ptr == NULL) ||
3922 (strncmp(fsname, ostname, ptr-ostname) != 0))
3924 label_sz += strlen(ostname);
3927 OBD_ALLOC(label, label_sz);
3934 "new %s.%s", fsname, poolname);
3938 "add %s.%s.%s", fsname, poolname, ostname);
3941 OBD_ALLOC(canceled_label, label_sz);
3942 if (canceled_label == NULL)
3943 GOTO(out_label, rc = -ENOMEM);
3945 "rem %s.%s.%s", fsname, poolname, ostname);
3946 sprintf(canceled_label,
3947 "add %s.%s.%s", fsname, poolname, ostname);
3950 OBD_ALLOC(canceled_label, label_sz);
3951 if (canceled_label == NULL)
3952 GOTO(out_label, rc = -ENOMEM);
3954 "del %s.%s", fsname, poolname);
3955 sprintf(canceled_label,
3956 "new %s.%s", fsname, poolname);
3962 if (canceled_label != NULL) {
3965 GOTO(out_cancel, rc = -ENOMEM);
3968 mutex_lock(&fsdb->fsdb_mutex);
3969 /* write pool def to all MDT logs */
3970 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3971 if (test_bit(i, fsdb->fsdb_mdt_index_map)) {
3972 rc = name_create_mdt_and_lov(&logname, &lovname,
3975 mutex_unlock(&fsdb->fsdb_mutex);
3978 if (canceled_label != NULL) {
3979 strcpy(mti->mti_svname, "lov pool");
3980 rc = mgs_modify(env, mgs, fsdb, mti, logname,
3981 lovname, canceled_label,
3986 rc = mgs_write_log_pool(env, mgs, logname,
3990 name_destroy(&logname);
3991 name_destroy(&lovname);
3993 mutex_unlock(&fsdb->fsdb_mutex);
3999 rc = name_create(&logname, fsname, "-client");
4001 mutex_unlock(&fsdb->fsdb_mutex);
4004 if (canceled_label != NULL) {
4005 rc = mgs_modify(env, mgs, fsdb, mti, logname,
4006 fsdb->fsdb_clilov, canceled_label, CM_SKIP);
4008 mutex_unlock(&fsdb->fsdb_mutex);
4009 name_destroy(&logname);
4014 rc = mgs_write_log_pool(env, mgs, logname, fsdb, fsdb->fsdb_clilov,
4015 cmd, fsname, poolname, ostname, label);
4016 mutex_unlock(&fsdb->fsdb_mutex);
4017 name_destroy(&logname);
4018 /* request for update */
4019 mgs_revoke_lock(mgs, fsdb, CONFIG_T_CONFIG);
4026 if (canceled_label != NULL)
4027 OBD_FREE(canceled_label, label_sz);
4029 OBD_FREE(label, label_sz);