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);
70 if (!dt_try_as_dir(env, dir))
71 GOTO(out, rc = -ENOTDIR);
74 LASSERT(dir->do_index_ops);
76 iops = &dir->do_index_ops->dio_it;
77 it = iops->init(env, dir, LUDA_64BITHASH, BYPASS_CAPA);
81 rc = iops->load(env, it, 0);
87 key = (void *)iops->key(env, it);
89 CERROR("%s: key failed when listing %s: rc = %d\n",
90 mgs->mgs_obd->obd_name, MOUNT_CONFIGS_DIR,
94 key_sz = iops->key_size(env, it);
97 /* filter out "." and ".." entries */
101 if (key_sz == 2 && key[1] == '.')
105 de = mgs_direntry_alloc(key_sz + 1);
111 memcpy(de->name, key, key_sz);
112 de->name[key_sz] = 0;
114 cfs_list_add(&de->list, list);
117 rc = iops->next(env, it);
127 CERROR("%s: key failed when listing %s: rc = %d\n",
128 mgs->mgs_obd->obd_name, MOUNT_CONFIGS_DIR, rc);
132 /******************** DB functions *********************/
134 static inline int name_create(char **newname, char *prefix, char *suffix)
137 OBD_ALLOC(*newname, strlen(prefix) + strlen(suffix) + 1);
140 sprintf(*newname, "%s%s", prefix, suffix);
144 static inline void name_destroy(char **name)
147 OBD_FREE(*name, strlen(*name) + 1);
151 struct mgs_fsdb_handler_data
157 /* from the (client) config log, figure out:
158 1. which ost's/mdt's are configured (by index)
159 2. what the last config step is
160 3. COMPAT_18 osc name
162 /* It might be better to have a separate db file, instead of parsing the info
163 out of the client log. This is slow and potentially error-prone. */
164 static int mgs_fsdb_handler(const struct lu_env *env, struct llog_handle *llh,
165 struct llog_rec_hdr *rec, void *data)
167 struct mgs_fsdb_handler_data *d = data;
168 struct fs_db *fsdb = d->fsdb;
169 int cfg_len = rec->lrh_len;
170 char *cfg_buf = (char*) (rec + 1);
171 struct lustre_cfg *lcfg;
176 if (rec->lrh_type != OBD_CFG_REC) {
177 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
181 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
183 CERROR("Insane cfg\n");
187 lcfg = (struct lustre_cfg *)cfg_buf;
189 CDEBUG(D_INFO, "cmd %x %s %s\n", lcfg->lcfg_command,
190 lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));
192 /* Figure out ost indicies */
193 /* lov_modify_tgts add 0:lov1 1:ost1_UUID 2(index):0 3(gen):1 */
194 if (lcfg->lcfg_command == LCFG_LOV_ADD_OBD ||
195 lcfg->lcfg_command == LCFG_LOV_DEL_OBD) {
196 index = simple_strtoul(lustre_cfg_string(lcfg, 2),
198 CDEBUG(D_MGS, "OST index for %s is %u (%s)\n",
199 lustre_cfg_string(lcfg, 1), index,
200 lustre_cfg_string(lcfg, 2));
201 set_bit(index, fsdb->fsdb_ost_index_map);
204 /* Figure out mdt indicies */
205 /* attach 0:MDC_uml1_mdsA_MNT_client 1:mdc 2:1d834_MNT_client_03f */
206 if ((lcfg->lcfg_command == LCFG_ATTACH) &&
207 (strcmp(lustre_cfg_string(lcfg, 1), LUSTRE_MDC_NAME) == 0)) {
208 rc = server_name2index(lustre_cfg_string(lcfg, 0),
210 if (rc != LDD_F_SV_TYPE_MDT) {
211 CWARN("Unparsable MDC name %s, assuming index 0\n",
212 lustre_cfg_string(lcfg, 0));
216 CDEBUG(D_MGS, "MDT index is %u\n", index);
217 set_bit(index, fsdb->fsdb_mdt_index_map);
218 fsdb->fsdb_mdt_count ++;
222 * figure out the old config. fsdb_gen = 0 means old log
223 * It is obsoleted and not supported anymore
225 if (fsdb->fsdb_gen == 0) {
226 CERROR("Old config format is not supported\n");
231 * compat to 1.8, check osc name used by MDT0 to OSTs, bz18548.
233 if (!test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags) &&
234 lcfg->lcfg_command == LCFG_ATTACH &&
235 strcmp(lustre_cfg_string(lcfg, 1), LUSTRE_OSC_NAME) == 0) {
236 if (OBD_OCD_VERSION_MAJOR(d->ver) == 1 &&
237 OBD_OCD_VERSION_MINOR(d->ver) <= 8) {
238 CWARN("MDT using 1.8 OSC name scheme\n");
239 set_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags);
243 if (lcfg->lcfg_command == LCFG_MARKER) {
244 struct cfg_marker *marker;
245 marker = lustre_cfg_buf(lcfg, 1);
247 d->ver = marker->cm_vers;
249 /* Keep track of the latest marker step */
250 fsdb->fsdb_gen = max(fsdb->fsdb_gen, marker->cm_step);
256 /* fsdb->fsdb_mutex is already held in mgs_find_or_make_fsdb*/
257 static int mgs_get_fsdb_from_llog(const struct lu_env *env,
258 struct mgs_device *mgs,
262 struct llog_handle *loghandle;
263 struct llog_ctxt *ctxt;
264 struct mgs_fsdb_handler_data d = { fsdb, 0 };
269 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
270 LASSERT(ctxt != NULL);
271 rc = name_create(&logname, fsdb->fsdb_name, "-client");
274 rc = llog_open_create(env, ctxt, &loghandle, NULL, logname);
278 rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL);
282 if (llog_get_size(loghandle) <= 1)
283 set_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags);
285 rc = llog_process(env, loghandle, mgs_fsdb_handler, (void *)&d, NULL);
286 CDEBUG(D_INFO, "get_db = %d\n", rc);
288 llog_close(env, loghandle);
290 name_destroy(&logname);
297 static void mgs_free_fsdb_srpc(struct fs_db *fsdb)
299 struct mgs_tgt_srpc_conf *tgtconf;
301 /* free target-specific rules */
302 while (fsdb->fsdb_srpc_tgt) {
303 tgtconf = fsdb->fsdb_srpc_tgt;
304 fsdb->fsdb_srpc_tgt = tgtconf->mtsc_next;
306 LASSERT(tgtconf->mtsc_tgt);
308 sptlrpc_rule_set_free(&tgtconf->mtsc_rset);
309 OBD_FREE(tgtconf->mtsc_tgt, strlen(tgtconf->mtsc_tgt) + 1);
310 OBD_FREE_PTR(tgtconf);
313 /* free general rules */
314 sptlrpc_rule_set_free(&fsdb->fsdb_srpc_gen);
317 struct fs_db *mgs_find_fsdb(struct mgs_device *mgs, char *fsname)
322 cfs_list_for_each(tmp, &mgs->mgs_fs_db_list) {
323 fsdb = cfs_list_entry(tmp, struct fs_db, fsdb_list);
324 if (strcmp(fsdb->fsdb_name, fsname) == 0)
330 /* caller must hold the mgs->mgs_fs_db_lock */
331 static struct fs_db *mgs_new_fsdb(const struct lu_env *env,
332 struct mgs_device *mgs, char *fsname)
338 if (strlen(fsname) >= sizeof(fsdb->fsdb_name)) {
339 CERROR("fsname %s is too long\n", fsname);
347 strcpy(fsdb->fsdb_name, fsname);
348 mutex_init(&fsdb->fsdb_mutex);
349 set_bit(FSDB_UDESC, &fsdb->fsdb_flags);
352 if (strcmp(fsname, MGSSELF_NAME) == 0) {
353 set_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags);
355 OBD_ALLOC(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
356 OBD_ALLOC(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
357 if (!fsdb->fsdb_ost_index_map || !fsdb->fsdb_mdt_index_map) {
358 CERROR("No memory for index maps\n");
359 GOTO(err, rc = -ENOMEM);
362 rc = name_create(&fsdb->fsdb_clilov, fsname, "-clilov");
365 rc = name_create(&fsdb->fsdb_clilmv, fsname, "-clilmv");
369 /* initialise data for NID table */
370 mgs_ir_init_fs(env, mgs, fsdb);
372 lproc_mgs_add_live(mgs, fsdb);
375 cfs_list_add(&fsdb->fsdb_list, &mgs->mgs_fs_db_list);
379 if (fsdb->fsdb_ost_index_map)
380 OBD_FREE(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
381 if (fsdb->fsdb_mdt_index_map)
382 OBD_FREE(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
383 name_destroy(&fsdb->fsdb_clilov);
384 name_destroy(&fsdb->fsdb_clilmv);
389 static void mgs_free_fsdb(struct mgs_device *mgs, struct fs_db *fsdb)
391 /* wait for anyone with the sem */
392 mutex_lock(&fsdb->fsdb_mutex);
393 lproc_mgs_del_live(mgs, fsdb);
394 cfs_list_del(&fsdb->fsdb_list);
396 /* deinitialize fsr */
397 mgs_ir_fini_fs(mgs, fsdb);
399 if (fsdb->fsdb_ost_index_map)
400 OBD_FREE(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
401 if (fsdb->fsdb_mdt_index_map)
402 OBD_FREE(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
403 name_destroy(&fsdb->fsdb_clilov);
404 name_destroy(&fsdb->fsdb_clilmv);
405 mgs_free_fsdb_srpc(fsdb);
406 mutex_unlock(&fsdb->fsdb_mutex);
410 int mgs_init_fsdb_list(struct mgs_device *mgs)
412 CFS_INIT_LIST_HEAD(&mgs->mgs_fs_db_list);
416 int mgs_cleanup_fsdb_list(struct mgs_device *mgs)
419 cfs_list_t *tmp, *tmp2;
420 mutex_lock(&mgs->mgs_mutex);
421 cfs_list_for_each_safe(tmp, tmp2, &mgs->mgs_fs_db_list) {
422 fsdb = cfs_list_entry(tmp, struct fs_db, fsdb_list);
423 mgs_free_fsdb(mgs, fsdb);
425 mutex_unlock(&mgs->mgs_mutex);
429 int mgs_find_or_make_fsdb(const struct lu_env *env,
430 struct mgs_device *mgs, char *name,
437 mutex_lock(&mgs->mgs_mutex);
438 fsdb = mgs_find_fsdb(mgs, name);
440 mutex_unlock(&mgs->mgs_mutex);
445 CDEBUG(D_MGS, "Creating new db\n");
446 fsdb = mgs_new_fsdb(env, mgs, name);
447 /* lock fsdb_mutex until the db is loaded from llogs */
449 mutex_lock(&fsdb->fsdb_mutex);
450 mutex_unlock(&mgs->mgs_mutex);
454 if (!test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
455 /* populate the db from the client llog */
456 rc = mgs_get_fsdb_from_llog(env, mgs, fsdb);
458 CERROR("Can't get db from client log %d\n", rc);
463 /* populate srpc rules from params llog */
464 rc = mgs_get_fsdb_srpc_from_llog(env, mgs, fsdb);
466 CERROR("Can't get db from params log %d\n", rc);
470 mutex_unlock(&fsdb->fsdb_mutex);
476 mutex_unlock(&fsdb->fsdb_mutex);
477 mgs_free_fsdb(mgs, fsdb);
483 -1= empty client log */
484 int mgs_check_index(const struct lu_env *env,
485 struct mgs_device *mgs,
486 struct mgs_target_info *mti)
493 LASSERT(!(mti->mti_flags & LDD_F_NEED_INDEX));
495 rc = mgs_find_or_make_fsdb(env, mgs, mti->mti_fsname, &fsdb);
497 CERROR("Can't get db for %s\n", mti->mti_fsname);
501 if (test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags))
504 if (mti->mti_flags & LDD_F_SV_TYPE_OST)
505 imap = fsdb->fsdb_ost_index_map;
506 else if (mti->mti_flags & LDD_F_SV_TYPE_MDT)
507 imap = fsdb->fsdb_mdt_index_map;
511 if (test_bit(mti->mti_stripe_index, imap))
516 static __inline__ int next_index(void *index_map, int map_len)
519 for (i = 0; i < map_len * 8; i++)
520 if (!test_bit(i, index_map)) {
523 CERROR("max index %d exceeded.\n", i);
528 0 newly marked as in use
530 +EALREADY for update of an old index */
531 static int mgs_set_index(const struct lu_env *env,
532 struct mgs_device *mgs,
533 struct mgs_target_info *mti)
540 rc = mgs_find_or_make_fsdb(env, mgs, mti->mti_fsname, &fsdb);
542 CERROR("Can't get db for %s\n", mti->mti_fsname);
546 mutex_lock(&fsdb->fsdb_mutex);
547 if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
548 imap = fsdb->fsdb_ost_index_map;
549 } else if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
550 imap = fsdb->fsdb_mdt_index_map;
552 GOTO(out_up, rc = -EINVAL);
555 if (mti->mti_flags & LDD_F_NEED_INDEX) {
556 rc = next_index(imap, INDEX_MAP_SIZE);
558 GOTO(out_up, rc = -ERANGE);
559 mti->mti_stripe_index = rc;
560 if (mti->mti_flags & LDD_F_SV_TYPE_MDT)
561 fsdb->fsdb_mdt_count ++;
564 if (mti->mti_stripe_index >= INDEX_MAP_SIZE * 8) {
565 LCONSOLE_ERROR_MSG(0x13f, "Server %s requested index %d, "
566 "but the max index is %d.\n",
567 mti->mti_svname, mti->mti_stripe_index,
569 GOTO(out_up, rc = -ERANGE);
572 if (test_bit(mti->mti_stripe_index, imap)) {
573 if ((mti->mti_flags & LDD_F_VIRGIN) &&
574 !(mti->mti_flags & LDD_F_WRITECONF)) {
575 LCONSOLE_ERROR_MSG(0x140, "Server %s requested index "
576 "%d, but that index is already in "
577 "use. Use --writeconf to force\n",
579 mti->mti_stripe_index);
580 GOTO(out_up, rc = -EADDRINUSE);
582 CDEBUG(D_MGS, "Server %s updating index %d\n",
583 mti->mti_svname, mti->mti_stripe_index);
584 GOTO(out_up, rc = EALREADY);
588 set_bit(mti->mti_stripe_index, imap);
589 clear_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags);
590 mutex_unlock(&fsdb->fsdb_mutex);
591 server_make_name(mti->mti_flags & ~(LDD_F_VIRGIN | LDD_F_WRITECONF),
592 mti->mti_stripe_index, mti->mti_fsname, mti->mti_svname);
594 CDEBUG(D_MGS, "Set index for %s to %d\n", mti->mti_svname,
595 mti->mti_stripe_index);
599 mutex_unlock(&fsdb->fsdb_mutex);
603 struct mgs_modify_lookup {
604 struct cfg_marker mml_marker;
608 static int mgs_modify_handler(const struct lu_env *env,
609 struct llog_handle *llh,
610 struct llog_rec_hdr *rec, void *data)
612 struct mgs_modify_lookup *mml = data;
613 struct cfg_marker *marker;
614 struct lustre_cfg *lcfg = REC_DATA(rec);
615 int cfg_len = REC_DATA_LEN(rec);
619 if (rec->lrh_type != OBD_CFG_REC) {
620 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
624 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
626 CERROR("Insane cfg\n");
630 /* We only care about markers */
631 if (lcfg->lcfg_command != LCFG_MARKER)
634 marker = lustre_cfg_buf(lcfg, 1);
635 if ((strcmp(mml->mml_marker.cm_comment, marker->cm_comment) == 0) &&
636 (strcmp(mml->mml_marker.cm_tgtname, marker->cm_tgtname) == 0) &&
637 !(marker->cm_flags & CM_SKIP)) {
638 /* Found a non-skipped marker match */
639 CDEBUG(D_MGS, "Changing rec %u marker %d %x->%x: %s %s\n",
640 rec->lrh_index, marker->cm_step,
641 marker->cm_flags, mml->mml_marker.cm_flags,
642 marker->cm_tgtname, marker->cm_comment);
643 /* Overwrite the old marker llog entry */
644 marker->cm_flags &= ~CM_EXCLUDE; /* in case we're unexcluding */
645 marker->cm_flags |= mml->mml_marker.cm_flags;
646 marker->cm_canceltime = mml->mml_marker.cm_canceltime;
647 /* Header and tail are added back to lrh_len in
648 llog_lvfs_write_rec */
649 rec->lrh_len = cfg_len;
650 rc = llog_write(env, llh, rec, NULL, 0, (void *)lcfg,
660 * Modify an existing config log record (for CM_SKIP or CM_EXCLUDE)
662 * 0 - modified successfully,
663 * 1 - no modification was done
666 static int mgs_modify(const struct lu_env *env, struct mgs_device *mgs,
667 struct fs_db *fsdb, struct mgs_target_info *mti,
668 char *logname, char *devname, char *comment, int flags)
670 struct llog_handle *loghandle;
671 struct llog_ctxt *ctxt;
672 struct mgs_modify_lookup *mml;
677 LASSERT(mutex_is_locked(&fsdb->fsdb_mutex));
678 CDEBUG(D_MGS, "modify %s/%s/%s fl=%x\n", logname, devname, comment,
681 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
682 LASSERT(ctxt != NULL);
683 rc = llog_open(env, ctxt, &loghandle, NULL, logname, LLOG_OPEN_EXISTS);
690 rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL);
694 if (llog_get_size(loghandle) <= 1)
695 GOTO(out_close, rc = 0);
699 GOTO(out_close, rc = -ENOMEM);
700 strcpy(mml->mml_marker.cm_comment, comment);
701 strcpy(mml->mml_marker.cm_tgtname, devname);
702 /* Modify mostly means cancel */
703 mml->mml_marker.cm_flags = flags;
704 mml->mml_marker.cm_canceltime = flags ? cfs_time_current_sec() : 0;
705 mml->mml_modified = 0;
706 rc = llog_process(env, loghandle, mgs_modify_handler, (void *)mml,
708 if (!rc && !mml->mml_modified)
713 llog_close(env, loghandle);
716 CERROR("%s: modify %s/%s failed: rc = %d\n",
717 mgs->mgs_obd->obd_name, mti->mti_svname, comment, rc);
722 /** This structure is passed to mgs_replace_handler */
723 struct mgs_replace_uuid_lookup {
724 /* Nids are replaced for this target device */
725 struct mgs_target_info target;
726 /* Temporary modified llog */
727 struct llog_handle *temp_llh;
728 /* Flag is set if in target block*/
729 int in_target_device;
730 /* Nids already added. Just skip (multiple nids) */
731 int device_nids_added;
732 /* Flag is set if this block should not be copied */
737 * Check: a) if block should be skipped
738 * b) is it target block
743 * \retval 0 should not to be skipped
744 * \retval 1 should to be skipped
746 static int check_markers(struct lustre_cfg *lcfg,
747 struct mgs_replace_uuid_lookup *mrul)
749 struct cfg_marker *marker;
751 /* Track markers. Find given device */
752 if (lcfg->lcfg_command == LCFG_MARKER) {
753 marker = lustre_cfg_buf(lcfg, 1);
754 /* Clean llog from records marked as CM_EXCLUDE.
755 CM_SKIP records are used for "active" command
756 and can be restored if needed */
757 if ((marker->cm_flags & (CM_EXCLUDE | CM_START)) ==
758 (CM_EXCLUDE | CM_START)) {
763 if ((marker->cm_flags & (CM_EXCLUDE | CM_END)) ==
764 (CM_EXCLUDE | CM_END)) {
769 if (strcmp(mrul->target.mti_svname, marker->cm_tgtname) == 0) {
770 LASSERT(!(marker->cm_flags & CM_START) ||
771 !(marker->cm_flags & CM_END));
772 if (marker->cm_flags & CM_START) {
773 mrul->in_target_device = 1;
774 mrul->device_nids_added = 0;
775 } else if (marker->cm_flags & CM_END)
776 mrul->in_target_device = 0;
783 static int record_lcfg(const struct lu_env *env, struct llog_handle *llh,
784 struct lustre_cfg *lcfg)
786 struct llog_rec_hdr rec;
792 LASSERT(llh->lgh_ctxt);
794 buflen = lustre_cfg_len(lcfg->lcfg_bufcount,
796 rec.lrh_len = llog_data_len(buflen);
797 rec.lrh_type = OBD_CFG_REC;
799 /* idx = -1 means append */
800 rc = llog_write(env, llh, &rec, NULL, 0, (void *)lcfg, -1);
802 CERROR("failed %d\n", rc);
806 static int record_base(const struct lu_env *env, struct llog_handle *llh,
807 char *cfgname, lnet_nid_t nid, int cmd,
808 char *s1, char *s2, char *s3, char *s4)
810 struct mgs_thread_info *mgi = mgs_env_info(env);
811 struct lustre_cfg *lcfg;
814 CDEBUG(D_MGS, "lcfg %s %#x %s %s %s %s\n", cfgname,
815 cmd, s1, s2, s3, s4);
817 lustre_cfg_bufs_reset(&mgi->mgi_bufs, cfgname);
819 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, s1);
821 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 2, s2);
823 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 3, s3);
825 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 4, s4);
827 lcfg = lustre_cfg_new(cmd, &mgi->mgi_bufs);
830 lcfg->lcfg_nid = nid;
832 rc = record_lcfg(env, llh, lcfg);
834 lustre_cfg_free(lcfg);
837 CERROR("error %d: lcfg %s %#x %s %s %s %s\n", rc, cfgname,
838 cmd, s1, s2, s3, s4);
843 static inline int record_add_uuid(const struct lu_env *env,
844 struct llog_handle *llh,
845 uint64_t nid, char *uuid)
847 return record_base(env, llh, NULL, nid, LCFG_ADD_UUID, uuid, 0, 0, 0);
850 static inline int record_add_conn(const struct lu_env *env,
851 struct llog_handle *llh,
852 char *devname, char *uuid)
854 return record_base(env, llh, devname, 0, LCFG_ADD_CONN, uuid, 0, 0, 0);
857 static inline int record_attach(const struct lu_env *env,
858 struct llog_handle *llh, char *devname,
859 char *type, char *uuid)
861 return record_base(env, llh,devname, 0, LCFG_ATTACH, type, uuid, 0, 0);
864 static inline int record_setup(const struct lu_env *env,
865 struct llog_handle *llh, char *devname,
866 char *s1, char *s2, char *s3, char *s4)
868 return record_base(env, llh, devname, 0, LCFG_SETUP, s1, s2, s3, s4);
872 * \retval <0 record processing error
873 * \retval n record is processed. No need copy original one.
874 * \retval 0 record is not processed.
876 static int process_command(const struct lu_env *env, struct lustre_cfg *lcfg,
877 struct mgs_replace_uuid_lookup *mrul)
884 if (lcfg->lcfg_command == LCFG_ADD_UUID) {
885 /* LCFG_ADD_UUID command found. Let's skip original command
886 and add passed nids */
887 ptr = mrul->target.mti_params;
888 while (class_parse_nid(ptr, &nid, &ptr) == 0) {
889 CDEBUG(D_MGS, "add nid %s with uuid %s, "
890 "device %s\n", libcfs_nid2str(nid),
891 mrul->target.mti_params,
892 mrul->target.mti_svname);
893 rc = record_add_uuid(env,
895 mrul->target.mti_params);
900 if (nids_added == 0) {
901 CERROR("No new nids were added, nid %s with uuid %s, "
902 "device %s\n", libcfs_nid2str(nid),
903 mrul->target.mti_params,
904 mrul->target.mti_svname);
907 mrul->device_nids_added = 1;
913 if (mrul->device_nids_added && lcfg->lcfg_command == LCFG_SETUP) {
914 /* LCFG_SETUP command found. UUID should be changed */
915 rc = record_setup(env,
917 /* devname the same */
918 lustre_cfg_string(lcfg, 0),
919 /* s1 is not changed */
920 lustre_cfg_string(lcfg, 1),
921 /* new uuid should be
923 mrul->target.mti_params,
924 /* s3 is not changed */
925 lustre_cfg_string(lcfg, 3),
926 /* s4 is not changed */
927 lustre_cfg_string(lcfg, 4));
931 /* Another commands in target device block */
936 * Handler that called for every record in llog.
937 * Records are processed in order they placed in llog.
939 * \param[in] llh log to be processed
940 * \param[in] rec current record
941 * \param[in] data mgs_replace_uuid_lookup structure
945 static int mgs_replace_handler(const struct lu_env *env,
946 struct llog_handle *llh,
947 struct llog_rec_hdr *rec,
950 struct llog_rec_hdr local_rec = *rec;
951 struct mgs_replace_uuid_lookup *mrul;
952 struct lustre_cfg *lcfg = REC_DATA(rec);
953 int cfg_len = REC_DATA_LEN(rec);
957 mrul = (struct mgs_replace_uuid_lookup *)data;
959 if (rec->lrh_type != OBD_CFG_REC) {
960 CERROR("unhandled lrh_type: %#x, cmd %x %s %s\n",
961 rec->lrh_type, lcfg->lcfg_command,
962 lustre_cfg_string(lcfg, 0),
963 lustre_cfg_string(lcfg, 1));
967 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
969 /* Do not copy any invalidated records */
970 GOTO(skip_out, rc = 0);
973 rc = check_markers(lcfg, mrul);
974 if (rc || mrul->skip_it)
975 GOTO(skip_out, rc = 0);
977 /* Write to new log all commands outside target device block */
978 if (!mrul->in_target_device)
979 GOTO(copy_out, rc = 0);
981 /* Skip all other LCFG_ADD_UUID and LCFG_ADD_CONN records
982 (failover nids) for this target, assuming that if then
983 primary is changing then so is the failover */
984 if (mrul->device_nids_added &&
985 (lcfg->lcfg_command == LCFG_ADD_UUID ||
986 lcfg->lcfg_command == LCFG_ADD_CONN))
987 GOTO(skip_out, rc = 0);
989 rc = process_command(env, lcfg, mrul);
996 /* Record is placed in temporary llog as is */
997 local_rec.lrh_len -= sizeof(*rec) + sizeof(struct llog_rec_tail);
998 rc = llog_write(env, mrul->temp_llh, &local_rec, NULL, 0,
1001 CDEBUG(D_MGS, "Copied idx=%d, rc=%d, len=%d, cmd %x %s %s\n",
1002 rec->lrh_index, rc, rec->lrh_len, lcfg->lcfg_command,
1003 lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));
1007 CDEBUG(D_MGS, "Skipped idx=%d, rc=%d, len=%d, cmd %x %s %s\n",
1008 rec->lrh_index, rc, rec->lrh_len, lcfg->lcfg_command,
1009 lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));
1013 static int mgs_backup_llog(const struct lu_env *env,
1014 struct obd_device *mgs,
1015 char *fsname, char *backup)
1017 struct obd_uuid *uuid;
1018 struct llog_handle *orig_llh, *bak_llh;
1019 struct llog_ctxt *lctxt;
1023 lctxt = llog_get_context(mgs, LLOG_CONFIG_ORIG_CTXT);
1025 CERROR("%s: missing llog context\n", mgs->obd_name);
1026 GOTO(out, rc = -EINVAL);
1029 /* Make sure there's no old backup log */
1030 rc = llog_erase(env, lctxt, NULL, backup);
1031 if (rc < 0 && rc != -ENOENT)
1034 /* open backup log */
1035 rc = llog_open_create(env, lctxt, &bak_llh, NULL, backup);
1037 CERROR("%s: backup logfile open %s: rc = %d\n",
1038 mgs->obd_name, backup, rc);
1042 /* set the log header uuid */
1043 OBD_ALLOC_PTR(uuid);
1045 GOTO(out_put, rc = -ENOMEM);
1046 obd_str2uuid(uuid, backup);
1047 rc = llog_init_handle(env, bak_llh, LLOG_F_IS_PLAIN, uuid);
1050 GOTO(out_close1, rc);
1052 /* open original log */
1053 rc = llog_open(env, lctxt, &orig_llh, NULL, fsname,
1058 GOTO(out_close1, rc);
1061 rc = llog_init_handle(env, orig_llh, LLOG_F_IS_PLAIN, NULL);
1063 GOTO(out_close2, rc);
1065 /* Copy remote log */
1066 rc = llog_process(env, orig_llh, llog_copy_handler,
1067 (void *)bak_llh, NULL);
1070 rc2 = llog_close(env, orig_llh);
1074 rc2 = llog_close(env, bak_llh);
1079 llog_ctxt_put(lctxt);
1082 CERROR("%s: Failed to backup log %s: rc = %d\n",
1083 mgs->obd_name, fsname, rc);
1087 static int mgs_log_is_empty(const struct lu_env *env, struct mgs_device *mgs,
1090 static int mgs_replace_nids_log(const struct lu_env *env,
1091 struct obd_device *mgs, struct fs_db *fsdb,
1092 char *logname, char *devname, char *nids)
1094 struct llog_handle *orig_llh, *backup_llh;
1095 struct llog_ctxt *ctxt;
1096 struct mgs_replace_uuid_lookup *mrul;
1097 struct mgs_device *mgs_dev = lu2mgs_dev(mgs->obd_lu_dev);
1098 static struct obd_uuid cfg_uuid = { .uuid = "config_uuid" };
1103 CDEBUG(D_MGS, "Replace nids for %s in %s\n", devname, logname);
1105 ctxt = llog_get_context(mgs, LLOG_CONFIG_ORIG_CTXT);
1106 LASSERT(ctxt != NULL);
1108 if (mgs_log_is_empty(env, mgs_dev, logname)) {
1109 /* Log is empty. Nothing to replace */
1110 GOTO(out_put, rc = 0);
1113 OBD_ALLOC(backup, strlen(logname) + strlen(".bak") + 1);
1115 GOTO(out_put, rc = -ENOMEM);
1117 sprintf(backup, "%s.bak", logname);
1119 rc = mgs_backup_llog(env, mgs, logname, backup);
1121 CERROR("%s: can't make backup for %s: rc = %d\n",
1122 mgs->obd_name, logname, rc);
1126 /* Now erase original log file. Connections are not allowed.
1127 Backup is already saved */
1128 rc = llog_erase(env, ctxt, NULL, logname);
1129 if (rc < 0 && rc != -ENOENT)
1132 /* open local log */
1133 rc = llog_open_create(env, ctxt, &orig_llh, NULL, logname);
1135 GOTO(out_restore, rc);
1137 rc = llog_init_handle(env, orig_llh, LLOG_F_IS_PLAIN, &cfg_uuid);
1139 GOTO(out_closel, rc);
1141 /* open backup llog */
1142 rc = llog_open(env, ctxt, &backup_llh, NULL, backup,
1145 GOTO(out_closel, rc);
1147 rc = llog_init_handle(env, backup_llh, LLOG_F_IS_PLAIN, NULL);
1149 GOTO(out_close, rc);
1151 if (llog_get_size(backup_llh) <= 1)
1152 GOTO(out_close, rc = 0);
1154 OBD_ALLOC_PTR(mrul);
1156 GOTO(out_close, rc = -ENOMEM);
1157 /* devname is only needed information to replace UUID records */
1158 strncpy(mrul->target.mti_svname, devname, MTI_NAME_MAXLEN);
1159 /* parse nids later */
1160 strncpy(mrul->target.mti_params, nids, MTI_PARAM_MAXLEN);
1161 /* Copy records to this temporary llog */
1162 mrul->temp_llh = orig_llh;
1164 rc = llog_process(env, backup_llh, mgs_replace_handler,
1165 (void *)mrul, NULL);
1168 rc2 = llog_close(NULL, backup_llh);
1172 rc2 = llog_close(NULL, orig_llh);
1178 CERROR("%s: llog should be restored: rc = %d\n",
1180 rc2 = mgs_backup_llog(env, mgs, backup, logname);
1182 CERROR("%s: can't restore backup %s: rc = %d\n",
1183 mgs->obd_name, logname, rc2);
1187 OBD_FREE(backup, strlen(backup) + 1);
1190 llog_ctxt_put(ctxt);
1193 CERROR("%s: failed to replace nids in log %s: rc = %d\n",
1194 mgs->obd_name, logname, rc);
1200 * Parse device name and get file system name and/or device index
1202 * \param[in] devname device name (ex. lustre-MDT0000)
1203 * \param[out] fsname file system name(optional)
1204 * \param[out] index device index(optional)
1208 static int mgs_parse_devname(char *devname, char *fsname, __u32 *index)
1213 /* Extract fsname */
1215 rc = server_name2fsname(devname, fsname, NULL);
1217 CDEBUG(D_MGS, "Device name %s without fsname\n",
1224 rc = server_name2index(devname, index, NULL);
1226 CDEBUG(D_MGS, "Device name %s with wrong index\n",
1235 static int only_mgs_is_running(struct obd_device *mgs_obd)
1237 /* TDB: Is global variable with devices count exists? */
1238 int num_devices = get_devices_count();
1239 /* osd, MGS and MGC + self_export
1240 (wc -l /proc/fs/lustre/devices <= 2) && (num_exports <= 2) */
1241 return (num_devices <= 3) && (mgs_obd->obd_num_exports <= 2);
1244 static int name_create_mdt(char **logname, char *fsname, int i)
1248 sprintf(mdt_index, "-MDT%04x", i);
1249 return name_create(logname, fsname, mdt_index);
1253 * Replace nids for \a device to \a nids values
1255 * \param obd MGS obd device
1256 * \param devname nids need to be replaced for this device
1257 * (ex. lustre-OST0000)
1258 * \param nids nids list (ex. nid1,nid2,nid3)
1262 int mgs_replace_nids(const struct lu_env *env,
1263 struct mgs_device *mgs,
1264 char *devname, char *nids)
1266 /* Assume fsname is part of device name */
1267 char fsname[MTI_NAME_MAXLEN];
1274 struct obd_device *mgs_obd = mgs->mgs_obd;
1277 /* We can only change NIDs if no other nodes are connected */
1278 spin_lock(&mgs_obd->obd_dev_lock);
1279 conn_state = mgs_obd->obd_no_conn;
1280 mgs_obd->obd_no_conn = 1;
1281 spin_unlock(&mgs_obd->obd_dev_lock);
1283 /* We can not change nids if not only MGS is started */
1284 if (!only_mgs_is_running(mgs_obd)) {
1285 CERROR("Only MGS is allowed to be started\n");
1286 GOTO(out, rc = -EINPROGRESS);
1289 /* Get fsname and index*/
1290 rc = mgs_parse_devname(devname, fsname, &index);
1294 rc = mgs_find_or_make_fsdb(env, mgs, fsname, &fsdb);
1296 CERROR("%s: can't find fsdb: rc = %d\n", fsname, rc);
1300 /* Process client llogs */
1301 name_create(&logname, fsname, "-client");
1302 rc = mgs_replace_nids_log(env, mgs_obd, fsdb, logname, devname, nids);
1303 name_destroy(&logname);
1305 CERROR("%s: error while replacing NIDs for %s: rc = %d\n",
1306 fsname, devname, rc);
1310 /* Process MDT llogs */
1311 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
1312 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
1314 name_create_mdt(&logname, fsname, i);
1315 rc = mgs_replace_nids_log(env, mgs_obd, fsdb, logname, devname, nids);
1316 name_destroy(&logname);
1322 spin_lock(&mgs_obd->obd_dev_lock);
1323 mgs_obd->obd_no_conn = conn_state;
1324 spin_unlock(&mgs_obd->obd_dev_lock);
1329 static int record_lov_setup(const struct lu_env *env, struct llog_handle *llh,
1330 char *devname, struct lov_desc *desc)
1332 struct mgs_thread_info *mgi = mgs_env_info(env);
1333 struct lustre_cfg *lcfg;
1336 lustre_cfg_bufs_reset(&mgi->mgi_bufs, devname);
1337 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, desc, sizeof(*desc));
1338 lcfg = lustre_cfg_new(LCFG_SETUP, &mgi->mgi_bufs);
1341 rc = record_lcfg(env, llh, lcfg);
1343 lustre_cfg_free(lcfg);
1347 static int record_lmv_setup(const struct lu_env *env, struct llog_handle *llh,
1348 char *devname, struct lmv_desc *desc)
1350 struct mgs_thread_info *mgi = mgs_env_info(env);
1351 struct lustre_cfg *lcfg;
1354 lustre_cfg_bufs_reset(&mgi->mgi_bufs, devname);
1355 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, desc, sizeof(*desc));
1356 lcfg = lustre_cfg_new(LCFG_SETUP, &mgi->mgi_bufs);
1358 rc = record_lcfg(env, llh, lcfg);
1360 lustre_cfg_free(lcfg);
1364 static inline int record_mdc_add(const struct lu_env *env,
1365 struct llog_handle *llh,
1366 char *logname, char *mdcuuid,
1367 char *mdtuuid, char *index,
1370 return record_base(env,llh,logname,0,LCFG_ADD_MDC,
1371 mdtuuid,index,gen,mdcuuid);
1374 static inline int record_lov_add(const struct lu_env *env,
1375 struct llog_handle *llh,
1376 char *lov_name, char *ost_uuid,
1377 char *index, char *gen)
1379 return record_base(env,llh,lov_name,0,LCFG_LOV_ADD_OBD,
1380 ost_uuid, index, gen, 0);
1383 static inline int record_mount_opt(const struct lu_env *env,
1384 struct llog_handle *llh,
1385 char *profile, char *lov_name,
1388 return record_base(env,llh,NULL,0,LCFG_MOUNTOPT,
1389 profile,lov_name,mdc_name,0);
1392 static int record_marker(const struct lu_env *env,
1393 struct llog_handle *llh,
1394 struct fs_db *fsdb, __u32 flags,
1395 char *tgtname, char *comment)
1397 struct mgs_thread_info *mgi = mgs_env_info(env);
1398 struct lustre_cfg *lcfg;
1402 if (flags & CM_START)
1404 mgi->mgi_marker.cm_step = fsdb->fsdb_gen;
1405 mgi->mgi_marker.cm_flags = flags;
1406 mgi->mgi_marker.cm_vers = LUSTRE_VERSION_CODE;
1407 cplen = strlcpy(mgi->mgi_marker.cm_tgtname, tgtname,
1408 sizeof(mgi->mgi_marker.cm_tgtname));
1409 if (cplen >= sizeof(mgi->mgi_marker.cm_tgtname))
1411 cplen = strlcpy(mgi->mgi_marker.cm_comment, comment,
1412 sizeof(mgi->mgi_marker.cm_comment));
1413 if (cplen >= sizeof(mgi->mgi_marker.cm_comment))
1415 mgi->mgi_marker.cm_createtime = cfs_time_current_sec();
1416 mgi->mgi_marker.cm_canceltime = 0;
1417 lustre_cfg_bufs_reset(&mgi->mgi_bufs, NULL);
1418 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, &mgi->mgi_marker,
1419 sizeof(mgi->mgi_marker));
1420 lcfg = lustre_cfg_new(LCFG_MARKER, &mgi->mgi_bufs);
1423 rc = record_lcfg(env, llh, lcfg);
1425 lustre_cfg_free(lcfg);
1429 static int record_start_log(const struct lu_env *env, struct mgs_device *mgs,
1430 struct llog_handle **llh, char *name)
1432 static struct obd_uuid cfg_uuid = { .uuid = "config_uuid" };
1433 struct llog_ctxt *ctxt;
1437 GOTO(out, rc = -EBUSY);
1439 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
1441 GOTO(out, rc = -ENODEV);
1442 LASSERT(ctxt->loc_obd == mgs->mgs_obd);
1444 rc = llog_open_create(env, ctxt, llh, NULL, name);
1447 rc = llog_init_handle(env, *llh, LLOG_F_IS_PLAIN, &cfg_uuid);
1449 llog_close(env, *llh);
1451 llog_ctxt_put(ctxt);
1454 CERROR("%s: can't start log %s: rc = %d\n",
1455 mgs->mgs_obd->obd_name, name, rc);
1461 static int record_end_log(const struct lu_env *env, struct llog_handle **llh)
1465 rc = llog_close(env, *llh);
1471 static int mgs_log_is_empty(const struct lu_env *env,
1472 struct mgs_device *mgs, char *name)
1474 struct llog_handle *llh;
1475 struct llog_ctxt *ctxt;
1478 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
1479 LASSERT(ctxt != NULL);
1480 rc = llog_open(env, ctxt, &llh, NULL, name, LLOG_OPEN_EXISTS);
1487 rc = llog_init_handle(env, llh, LLOG_F_IS_PLAIN, NULL);
1489 GOTO(out_close, rc);
1490 rc = llog_get_size(llh);
1493 llog_close(env, llh);
1495 llog_ctxt_put(ctxt);
1496 /* header is record 1 */
1500 /******************** config "macros" *********************/
1502 /* write an lcfg directly into a log (with markers) */
1503 static int mgs_write_log_direct(const struct lu_env *env,
1504 struct mgs_device *mgs, struct fs_db *fsdb,
1505 char *logname, struct lustre_cfg *lcfg,
1506 char *devname, char *comment)
1508 struct llog_handle *llh = NULL;
1515 rc = record_start_log(env, mgs, &llh, logname);
1519 /* FIXME These should be a single journal transaction */
1520 rc = record_marker(env, llh, fsdb, CM_START, devname, comment);
1523 rc = record_lcfg(env, llh, lcfg);
1526 rc = record_marker(env, llh, fsdb, CM_END, devname, comment);
1530 record_end_log(env, &llh);
1534 /* write the lcfg in all logs for the given fs */
1535 int mgs_write_log_direct_all(const struct lu_env *env,
1536 struct mgs_device *mgs,
1538 struct mgs_target_info *mti,
1539 struct lustre_cfg *lcfg,
1540 char *devname, char *comment,
1544 struct mgs_direntry *dirent, *n;
1545 char *fsname = mti->mti_fsname;
1547 int rc = 0, len = strlen(fsname);
1550 /* We need to set params for any future logs
1551 as well. FIXME Append this file to every new log.
1552 Actually, we should store as params (text), not llogs. Or
1554 rc = name_create(&logname, fsname, "-params");
1557 if (mgs_log_is_empty(env, mgs, logname)) {
1558 struct llog_handle *llh = NULL;
1559 rc = record_start_log(env, mgs, &llh, logname);
1560 record_end_log(env, &llh);
1562 name_destroy(&logname);
1566 /* Find all the logs in the CONFIGS directory */
1567 rc = class_dentry_readdir(env, mgs, &list);
1571 /* Could use fsdb index maps instead of directory listing */
1572 cfs_list_for_each_entry_safe(dirent, n, &list, list) {
1573 cfs_list_del(&dirent->list);
1574 /* don't write to sptlrpc rule log */
1575 if (strstr(dirent->name, "-sptlrpc") != NULL)
1578 /* caller wants write server logs only */
1579 if (server_only && strstr(dirent->name, "-client") != NULL)
1582 if (strncmp(fsname, dirent->name, len) == 0) {
1583 CDEBUG(D_MGS, "Changing log %s\n", dirent->name);
1584 /* Erase any old settings of this same parameter */
1585 rc = mgs_modify(env, mgs, fsdb, mti, dirent->name,
1586 devname, comment, CM_SKIP);
1588 CERROR("%s: Can't modify llog %s: rc = %d\n",
1589 mgs->mgs_obd->obd_name, dirent->name,rc);
1590 /* Write the new one */
1592 rc = mgs_write_log_direct(env, mgs, fsdb,
1597 CERROR("%s: writing log %s: rc = %d\n",
1598 mgs->mgs_obd->obd_name,
1603 mgs_direntry_free(dirent);
1609 static int mgs_write_log_osp_to_mdt(const struct lu_env *env,
1610 struct mgs_device *mgs,
1612 struct mgs_target_info *mti,
1613 int index, char *logname);
1614 static int mgs_write_log_osc_to_lov(const struct lu_env *env,
1615 struct mgs_device *mgs,
1617 struct mgs_target_info *mti,
1618 char *logname, char *suffix, char *lovname,
1619 enum lustre_sec_part sec_part, int flags);
1620 static int name_create_mdt_and_lov(char **logname, char **lovname,
1621 struct fs_db *fsdb, int i);
1623 static int add_param(char *params, char *key, char *val)
1625 char *start = params + strlen(params);
1626 char *end = params + sizeof(((struct mgs_target_info *)0)->mti_params);
1630 keylen = strlen(key);
1631 if (start + 1 + keylen + strlen(val) >= end) {
1632 CERROR("params are too long: %s %s%s\n",
1633 params, key != NULL ? key : "", val);
1637 sprintf(start, " %s%s", key != NULL ? key : "", val);
1642 * Walk through client config log record and convert the related records
1645 static int mgs_steal_client_llog_handler(const struct lu_env *env,
1646 struct llog_handle *llh,
1647 struct llog_rec_hdr *rec, void *data)
1649 struct mgs_device *mgs;
1650 struct obd_device *obd;
1651 struct mgs_target_info *mti, *tmti;
1653 int cfg_len = rec->lrh_len;
1654 char *cfg_buf = (char*) (rec + 1);
1655 struct lustre_cfg *lcfg;
1657 struct llog_handle *mdt_llh = NULL;
1658 static int got_an_osc_or_mdc = 0;
1659 /* 0: not found any osc/mdc;
1663 static int last_step = -1;
1668 mti = ((struct temp_comp*)data)->comp_mti;
1669 tmti = ((struct temp_comp*)data)->comp_tmti;
1670 fsdb = ((struct temp_comp*)data)->comp_fsdb;
1671 obd = ((struct temp_comp *)data)->comp_obd;
1672 mgs = lu2mgs_dev(obd->obd_lu_dev);
1675 if (rec->lrh_type != OBD_CFG_REC) {
1676 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
1680 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
1682 CERROR("Insane cfg\n");
1686 lcfg = (struct lustre_cfg *)cfg_buf;
1688 if (lcfg->lcfg_command == LCFG_MARKER) {
1689 struct cfg_marker *marker;
1690 marker = lustre_cfg_buf(lcfg, 1);
1691 if (!strncmp(marker->cm_comment, "add osc", 7) &&
1692 (marker->cm_flags & CM_START) &&
1693 !(marker->cm_flags & CM_SKIP)) {
1694 got_an_osc_or_mdc = 1;
1695 cplen = strlcpy(tmti->mti_svname, marker->cm_tgtname,
1696 sizeof(tmti->mti_svname));
1697 if (cplen >= sizeof(tmti->mti_svname))
1699 rc = record_start_log(env, mgs, &mdt_llh,
1703 rc = record_marker(env, mdt_llh, fsdb, CM_START,
1704 mti->mti_svname, "add osc(copied)");
1705 record_end_log(env, &mdt_llh);
1706 last_step = marker->cm_step;
1709 if (!strncmp(marker->cm_comment, "add osc", 7) &&
1710 (marker->cm_flags & CM_END) &&
1711 !(marker->cm_flags & CM_SKIP)) {
1712 LASSERT(last_step == marker->cm_step);
1714 got_an_osc_or_mdc = 0;
1715 memset(tmti, 0, sizeof(*tmti));
1716 rc = record_start_log(env, mgs, &mdt_llh,
1720 rc = record_marker(env, mdt_llh, fsdb, CM_END,
1721 mti->mti_svname, "add osc(copied)");
1722 record_end_log(env, &mdt_llh);
1725 if (!strncmp(marker->cm_comment, "add mdc", 7) &&
1726 (marker->cm_flags & CM_START) &&
1727 !(marker->cm_flags & CM_SKIP)) {
1728 got_an_osc_or_mdc = 2;
1729 last_step = marker->cm_step;
1730 memcpy(tmti->mti_svname, marker->cm_tgtname,
1731 strlen(marker->cm_tgtname));
1735 if (!strncmp(marker->cm_comment, "add mdc", 7) &&
1736 (marker->cm_flags & CM_END) &&
1737 !(marker->cm_flags & CM_SKIP)) {
1738 LASSERT(last_step == marker->cm_step);
1740 got_an_osc_or_mdc = 0;
1741 memset(tmti, 0, sizeof(*tmti));
1746 if (got_an_osc_or_mdc == 0 || last_step < 0)
1749 if (lcfg->lcfg_command == LCFG_ADD_UUID) {
1750 uint64_t nodenid = lcfg->lcfg_nid;
1752 if (strlen(tmti->mti_uuid) == 0) {
1753 /* target uuid not set, this config record is before
1754 * LCFG_SETUP, this nid is one of target node nid.
1756 tmti->mti_nids[tmti->mti_nid_count] = nodenid;
1757 tmti->mti_nid_count++;
1759 /* failover node nid */
1760 rc = add_param(tmti->mti_params, PARAM_FAILNODE,
1761 libcfs_nid2str(nodenid));
1767 if (lcfg->lcfg_command == LCFG_SETUP) {
1770 target = lustre_cfg_string(lcfg, 1);
1771 memcpy(tmti->mti_uuid, target, strlen(target));
1775 /* ignore client side sptlrpc_conf_log */
1776 if (lcfg->lcfg_command == LCFG_SPTLRPC_CONF)
1779 if (lcfg->lcfg_command == LCFG_ADD_MDC) {
1782 if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1)
1785 memcpy(tmti->mti_fsname, mti->mti_fsname,
1786 strlen(mti->mti_fsname));
1787 tmti->mti_stripe_index = index;
1789 rc = mgs_write_log_osp_to_mdt(env, mgs, fsdb, tmti,
1790 mti->mti_stripe_index,
1792 memset(tmti, 0, sizeof(*tmti));
1796 if (lcfg->lcfg_command == LCFG_LOV_ADD_OBD) {
1799 char *logname, *lovname;
1801 rc = name_create_mdt_and_lov(&logname, &lovname, fsdb,
1802 mti->mti_stripe_index);
1805 sprintf(mdt_index, "-MDT%04x", mti->mti_stripe_index);
1807 if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1) {
1808 name_destroy(&logname);
1809 name_destroy(&lovname);
1813 tmti->mti_stripe_index = index;
1814 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, tmti, logname,
1817 name_destroy(&logname);
1818 name_destroy(&lovname);
1824 /* fsdb->fsdb_mutex is already held in mgs_write_log_target*/
1825 /* stealed from mgs_get_fsdb_from_llog*/
1826 static int mgs_steal_llog_for_mdt_from_client(const struct lu_env *env,
1827 struct mgs_device *mgs,
1829 struct temp_comp* comp)
1831 struct llog_handle *loghandle;
1832 struct mgs_target_info *tmti;
1833 struct llog_ctxt *ctxt;
1838 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
1839 LASSERT(ctxt != NULL);
1841 OBD_ALLOC_PTR(tmti);
1843 GOTO(out_ctxt, rc = -ENOMEM);
1845 comp->comp_tmti = tmti;
1846 comp->comp_obd = mgs->mgs_obd;
1848 rc = llog_open(env, ctxt, &loghandle, NULL, client_name,
1856 rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL);
1858 GOTO(out_close, rc);
1860 rc = llog_process_or_fork(env, loghandle, mgs_steal_client_llog_handler,
1861 (void *)comp, NULL, false);
1862 CDEBUG(D_MGS, "steal llog re = %d\n", rc);
1864 llog_close(env, loghandle);
1868 llog_ctxt_put(ctxt);
1872 /* lmv is the second thing for client logs */
1873 /* copied from mgs_write_log_lov. Please refer to that. */
1874 static int mgs_write_log_lmv(const struct lu_env *env,
1875 struct mgs_device *mgs,
1877 struct mgs_target_info *mti,
1878 char *logname, char *lmvname)
1880 struct llog_handle *llh = NULL;
1881 struct lmv_desc *lmvdesc;
1886 CDEBUG(D_MGS, "Writing lmv(%s) log for %s\n", lmvname,logname);
1888 OBD_ALLOC_PTR(lmvdesc);
1889 if (lmvdesc == NULL)
1891 lmvdesc->ld_active_tgt_count = 0;
1892 lmvdesc->ld_tgt_count = 0;
1893 sprintf((char*)lmvdesc->ld_uuid.uuid, "%s_UUID", lmvname);
1894 uuid = (char *)lmvdesc->ld_uuid.uuid;
1896 rc = record_start_log(env, mgs, &llh, logname);
1899 rc = record_marker(env, llh, fsdb, CM_START, lmvname, "lmv setup");
1902 rc = record_attach(env, llh, lmvname, "lmv", uuid);
1905 rc = record_lmv_setup(env, llh, lmvname, lmvdesc);
1908 rc = record_marker(env, llh, fsdb, CM_END, lmvname, "lmv setup");
1912 record_end_log(env, &llh);
1914 OBD_FREE_PTR(lmvdesc);
1918 /* lov is the first thing in the mdt and client logs */
1919 static int mgs_write_log_lov(const struct lu_env *env, struct mgs_device *mgs,
1920 struct fs_db *fsdb, struct mgs_target_info *mti,
1921 char *logname, char *lovname)
1923 struct llog_handle *llh = NULL;
1924 struct lov_desc *lovdesc;
1929 CDEBUG(D_MGS, "Writing lov(%s) log for %s\n", lovname, logname);
1932 #01 L attach 0:lov_mdsA 1:lov 2:71ccb_lov_mdsA_19f961a9e1
1933 #02 L lov_setup 0:lov_mdsA 1:(struct lov_desc)
1934 uuid=lov1_UUID, stripe count=1, size=1048576, offset=0, pattern=0
1937 /* FIXME just make lov_setup accept empty desc (put uuid in buf 2) */
1938 OBD_ALLOC_PTR(lovdesc);
1939 if (lovdesc == NULL)
1941 lovdesc->ld_magic = LOV_DESC_MAGIC;
1942 lovdesc->ld_tgt_count = 0;
1943 /* Defaults. Can be changed later by lcfg config_param */
1944 lovdesc->ld_default_stripe_count = 1;
1945 lovdesc->ld_pattern = LOV_PATTERN_RAID0;
1946 lovdesc->ld_default_stripe_size = 1024 * 1024;
1947 lovdesc->ld_default_stripe_offset = -1;
1948 lovdesc->ld_qos_maxage = QOS_DEFAULT_MAXAGE;
1949 sprintf((char*)lovdesc->ld_uuid.uuid, "%s_UUID", lovname);
1950 /* can these be the same? */
1951 uuid = (char *)lovdesc->ld_uuid.uuid;
1953 /* This should always be the first entry in a log.
1954 rc = mgs_clear_log(obd, logname); */
1955 rc = record_start_log(env, mgs, &llh, logname);
1958 /* FIXME these should be a single journal transaction */
1959 rc = record_marker(env, llh, fsdb, CM_START, lovname, "lov setup");
1962 rc = record_attach(env, llh, lovname, "lov", uuid);
1965 rc = record_lov_setup(env, llh, lovname, lovdesc);
1968 rc = record_marker(env, llh, fsdb, CM_END, lovname, "lov setup");
1973 record_end_log(env, &llh);
1975 OBD_FREE_PTR(lovdesc);
1979 /* add failnids to open log */
1980 static int mgs_write_log_failnids(const struct lu_env *env,
1981 struct mgs_target_info *mti,
1982 struct llog_handle *llh,
1985 char *failnodeuuid = NULL;
1986 char *ptr = mti->mti_params;
1991 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) nal=90 0: 1:uml1_UUID
1992 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
1993 #05 L setup 0:OSC_uml1_ost1_mdsA 1:ost1_UUID 2:uml1_UUID
1994 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) nal=90 0: 1:uml2_UUID
1995 #0x L add_uuid nid=2@elan(0x1000000000002) nal=90 0: 1:uml2_UUID
1996 #07 L add_conn 0:OSC_uml1_ost1_mdsA 1:uml2_UUID
1999 /* Pull failnid info out of params string */
2000 while (class_find_param(ptr, PARAM_FAILNODE, &ptr) == 0) {
2001 while (class_parse_nid(ptr, &nid, &ptr) == 0) {
2002 if (failnodeuuid == NULL) {
2003 /* We don't know the failover node name,
2004 so just use the first nid as the uuid */
2005 rc = name_create(&failnodeuuid,
2006 libcfs_nid2str(nid), "");
2010 CDEBUG(D_MGS, "add nid %s for failover uuid %s, "
2011 "client %s\n", libcfs_nid2str(nid),
2012 failnodeuuid, cliname);
2013 rc = record_add_uuid(env, llh, nid, failnodeuuid);
2016 rc = record_add_conn(env, llh, cliname, failnodeuuid);
2019 name_destroy(&failnodeuuid);
2023 static int mgs_write_log_mdc_to_lmv(const struct lu_env *env,
2024 struct mgs_device *mgs,
2026 struct mgs_target_info *mti,
2027 char *logname, char *lmvname)
2029 struct llog_handle *llh = NULL;
2030 char *mdcname = NULL;
2031 char *nodeuuid = NULL;
2032 char *mdcuuid = NULL;
2033 char *lmvuuid = NULL;
2038 if (mgs_log_is_empty(env, mgs, logname)) {
2039 CERROR("log is empty! Logical error\n");
2043 CDEBUG(D_MGS, "adding mdc for %s to log %s:lmv(%s)\n",
2044 mti->mti_svname, logname, lmvname);
2046 rc = name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
2049 rc = name_create(&mdcname, mti->mti_svname, "-mdc");
2052 rc = name_create(&mdcuuid, mdcname, "_UUID");
2055 rc = name_create(&lmvuuid, lmvname, "_UUID");
2059 rc = record_start_log(env, mgs, &llh, logname);
2062 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
2066 for (i = 0; i < mti->mti_nid_count; i++) {
2067 CDEBUG(D_MGS, "add nid %s for mdt\n",
2068 libcfs_nid2str(mti->mti_nids[i]));
2070 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
2075 rc = record_attach(env, llh, mdcname, LUSTRE_MDC_NAME, lmvuuid);
2078 rc = record_setup(env, llh, mdcname, mti->mti_uuid, nodeuuid, 0, 0);
2081 rc = mgs_write_log_failnids(env, mti, llh, mdcname);
2084 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
2085 rc = record_mdc_add(env, llh, lmvname, mdcuuid, mti->mti_uuid,
2089 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname,
2094 record_end_log(env, &llh);
2096 name_destroy(&lmvuuid);
2097 name_destroy(&mdcuuid);
2098 name_destroy(&mdcname);
2099 name_destroy(&nodeuuid);
2103 static inline int name_create_lov(char **lovname, char *mdtname,
2104 struct fs_db *fsdb, int index)
2107 if (index == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2108 return name_create(lovname, fsdb->fsdb_name, "-mdtlov");
2110 return name_create(lovname, mdtname, "-mdtlov");
2113 static int name_create_mdt_and_lov(char **logname, char **lovname,
2114 struct fs_db *fsdb, int i)
2118 rc = name_create_mdt(logname, fsdb->fsdb_name, i);
2122 if (i == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2123 rc = name_create(lovname, fsdb->fsdb_name, "-mdtlov");
2125 rc = name_create(lovname, *logname, "-mdtlov");
2127 name_destroy(logname);
2133 static inline int name_create_mdt_osc(char **oscname, char *ostname,
2134 struct fs_db *fsdb, int i)
2138 if (i == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2139 sprintf(suffix, "-osc");
2141 sprintf(suffix, "-osc-MDT%04x", i);
2142 return name_create(oscname, ostname, suffix);
2145 /* add new mdc to already existent MDS */
2146 static int mgs_write_log_osp_to_mdt(const struct lu_env *env,
2147 struct mgs_device *mgs,
2149 struct mgs_target_info *mti,
2150 int mdt_index, char *logname)
2152 struct llog_handle *llh = NULL;
2153 char *nodeuuid = NULL;
2154 char *ospname = NULL;
2155 char *lovuuid = NULL;
2156 char *mdtuuid = NULL;
2157 char *svname = NULL;
2158 char *mdtname = NULL;
2159 char *lovname = NULL;
2164 if (mgs_log_is_empty(env, mgs, mti->mti_svname)) {
2165 CERROR("log is empty! Logical error\n");
2169 CDEBUG(D_MGS, "adding osp index %d to %s\n", mti->mti_stripe_index,
2172 rc = name_create_mdt(&mdtname, fsdb->fsdb_name, mti->mti_stripe_index);
2176 rc = name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
2178 GOTO(out_destory, rc);
2180 rc = name_create(&svname, mdtname, "-osp");
2182 GOTO(out_destory, rc);
2184 sprintf(index_str, "-MDT%04x", mdt_index);
2185 rc = name_create(&ospname, svname, index_str);
2187 GOTO(out_destory, rc);
2189 rc = name_create_lov(&lovname, logname, fsdb, mdt_index);
2191 GOTO(out_destory, rc);
2193 rc = name_create(&lovuuid, lovname, "_UUID");
2195 GOTO(out_destory, rc);
2197 rc = name_create(&mdtuuid, mdtname, "_UUID");
2199 GOTO(out_destory, rc);
2201 rc = record_start_log(env, mgs, &llh, logname);
2203 GOTO(out_destory, rc);
2205 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
2208 GOTO(out_destory, rc);
2210 for (i = 0; i < mti->mti_nid_count; i++) {
2211 CDEBUG(D_MGS, "add nid %s for mdt\n",
2212 libcfs_nid2str(mti->mti_nids[i]));
2213 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
2218 rc = record_attach(env, llh, ospname, LUSTRE_OSP_NAME, lovuuid);
2222 rc = record_setup(env, llh, ospname, mti->mti_uuid, nodeuuid,
2227 rc = mgs_write_log_failnids(env, mti, llh, ospname);
2231 /* Add mdc(osp) to lod */
2232 snprintf(index_str, sizeof(mti->mti_stripe_index), "%d",
2233 mti->mti_stripe_index);
2234 rc = record_base(env, llh, lovname, 0, LCFG_ADD_MDC, mti->mti_uuid,
2235 index_str, "1", NULL);
2239 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname, "add osp");
2244 record_end_log(env, &llh);
2247 name_destroy(&mdtuuid);
2248 name_destroy(&lovuuid);
2249 name_destroy(&lovname);
2250 name_destroy(&ospname);
2251 name_destroy(&svname);
2252 name_destroy(&nodeuuid);
2253 name_destroy(&mdtname);
2257 static int mgs_write_log_mdt0(const struct lu_env *env,
2258 struct mgs_device *mgs,
2260 struct mgs_target_info *mti)
2262 char *log = mti->mti_svname;
2263 struct llog_handle *llh = NULL;
2264 char *uuid, *lovname;
2266 char *ptr = mti->mti_params;
2267 int rc = 0, failout = 0;
2270 OBD_ALLOC(uuid, sizeof(struct obd_uuid));
2274 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
2275 failout = (strncmp(ptr, "failout", 7) == 0);
2277 rc = name_create(&lovname, log, "-mdtlov");
2280 if (mgs_log_is_empty(env, mgs, log)) {
2281 rc = mgs_write_log_lov(env, mgs, fsdb, mti, log, lovname);
2286 sprintf(mdt_index, "%d", mti->mti_stripe_index);
2288 rc = record_start_log(env, mgs, &llh, log);
2292 /* add MDT itself */
2294 /* FIXME this whole fn should be a single journal transaction */
2295 sprintf(uuid, "%s_UUID", log);
2296 rc = record_marker(env, llh, fsdb, CM_START, log, "add mdt");
2299 rc = record_attach(env, llh, log, LUSTRE_MDT_NAME, uuid);
2302 rc = record_mount_opt(env, llh, log, lovname, NULL);
2305 rc = record_setup(env, llh, log, uuid, mdt_index, lovname,
2306 failout ? "n" : "f");
2309 rc = record_marker(env, llh, fsdb, CM_END, log, "add mdt");
2313 record_end_log(env, &llh);
2315 name_destroy(&lovname);
2317 OBD_FREE(uuid, sizeof(struct obd_uuid));
2321 /* envelope method for all layers log */
2322 static int mgs_write_log_mdt(const struct lu_env *env,
2323 struct mgs_device *mgs,
2325 struct mgs_target_info *mti)
2327 struct mgs_thread_info *mgi = mgs_env_info(env);
2328 struct llog_handle *llh = NULL;
2333 CDEBUG(D_MGS, "writing new mdt %s\n", mti->mti_svname);
2335 if (mti->mti_uuid[0] == '\0') {
2336 /* Make up our own uuid */
2337 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
2338 "%s_UUID", mti->mti_svname);
2342 rc = mgs_write_log_mdt0(env, mgs, fsdb, mti);
2345 /* Append the mdt info to the client log */
2346 rc = name_create(&cliname, mti->mti_fsname, "-client");
2350 if (mgs_log_is_empty(env, mgs, cliname)) {
2351 /* Start client log */
2352 rc = mgs_write_log_lov(env, mgs, fsdb, mti, cliname,
2356 rc = mgs_write_log_lmv(env, mgs, fsdb, mti, cliname,
2363 #09 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
2364 #10 L attach 0:MDC_uml1_mdsA_MNT_client 1:mdc 2:1d834_MNT_client_03f
2365 #11 L setup 0:MDC_uml1_mdsA_MNT_client 1:mdsA_UUID 2:uml1_UUID
2366 #12 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
2367 #13 L add_conn 0:MDC_uml1_mdsA_MNT_client 1:uml2_UUID
2368 #14 L mount_option 0: 1:client 2:lov1 3:MDC_uml1_mdsA_MNT_client
2371 /* copy client info about lov/lmv */
2372 mgi->mgi_comp.comp_mti = mti;
2373 mgi->mgi_comp.comp_fsdb = fsdb;
2375 rc = mgs_steal_llog_for_mdt_from_client(env, mgs, cliname,
2379 rc = mgs_write_log_mdc_to_lmv(env, mgs, fsdb, mti, cliname,
2385 rc = record_start_log(env, mgs, &llh, cliname);
2389 rc = record_marker(env, llh, fsdb, CM_START, cliname,
2393 rc = record_mount_opt(env, llh, cliname, fsdb->fsdb_clilov,
2397 rc = record_marker(env, llh, fsdb, CM_END, cliname,
2403 /* for_all_existing_mdt except current one */
2404 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2405 if (i != mti->mti_stripe_index &&
2406 test_bit(i, fsdb->fsdb_mdt_index_map)) {
2409 rc = name_create_mdt(&logname, fsdb->fsdb_name, i);
2413 rc = mgs_write_log_osp_to_mdt(env, mgs, fsdb, mti,
2415 name_destroy(&logname);
2421 record_end_log(env, &llh);
2423 name_destroy(&cliname);
2427 /* Add the ost info to the client/mdt lov */
2428 static int mgs_write_log_osc_to_lov(const struct lu_env *env,
2429 struct mgs_device *mgs, struct fs_db *fsdb,
2430 struct mgs_target_info *mti,
2431 char *logname, char *suffix, char *lovname,
2432 enum lustre_sec_part sec_part, int flags)
2434 struct llog_handle *llh = NULL;
2435 char *nodeuuid = NULL;
2436 char *oscname = NULL;
2437 char *oscuuid = NULL;
2438 char *lovuuid = NULL;
2439 char *svname = NULL;
2444 CDEBUG(D_INFO, "adding osc for %s to log %s\n",
2445 mti->mti_svname, logname);
2447 if (mgs_log_is_empty(env, mgs, logname)) {
2448 CERROR("log is empty! Logical error\n");
2452 rc = name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
2455 rc = name_create(&svname, mti->mti_svname, "-osc");
2459 /* for the system upgraded from old 1.8, keep using the old osc naming
2460 * style for mdt, see name_create_mdt_osc(). LU-1257 */
2461 if (test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2462 rc = name_create(&oscname, svname, "");
2464 rc = name_create(&oscname, svname, suffix);
2468 rc = name_create(&oscuuid, oscname, "_UUID");
2471 rc = name_create(&lovuuid, lovname, "_UUID");
2477 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
2479 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
2480 #04 L attach 0:OSC_uml1_ost1_MNT_client 1:osc 2:89070_lov1_a41dff51a
2481 #05 L setup 0:OSC_uml1_ost1_MNT_client 1:ost1_UUID 2:uml1_UUID
2483 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
2484 #07 L add_conn 0:OSC_uml1_ost1_MNT_client 1:uml2_UUID
2485 #08 L lov_modify_tgts add 0:lov1 1:ost1_UUID 2(index):0 3(gen):1
2488 rc = record_start_log(env, mgs, &llh, logname);
2492 /* FIXME these should be a single journal transaction */
2493 rc = record_marker(env, llh, fsdb, CM_START | flags, mti->mti_svname,
2498 /* NB: don't change record order, because upon MDT steal OSC config
2499 * from client, it treats all nids before LCFG_SETUP as target nids
2500 * (multiple interfaces), while nids after as failover node nids.
2501 * See mgs_steal_client_llog_handler() LCFG_ADD_UUID.
2503 for (i = 0; i < mti->mti_nid_count; i++) {
2504 CDEBUG(D_MGS, "add nid %s\n", libcfs_nid2str(mti->mti_nids[i]));
2505 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
2509 rc = record_attach(env, llh, oscname, LUSTRE_OSC_NAME, lovuuid);
2512 rc = record_setup(env, llh, oscname, mti->mti_uuid, nodeuuid, 0, 0);
2515 rc = mgs_write_log_failnids(env, mti, llh, oscname);
2519 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
2521 rc = record_lov_add(env, llh, lovname, mti->mti_uuid, index, "1");
2524 rc = record_marker(env, llh, fsdb, CM_END | flags, mti->mti_svname,
2529 record_end_log(env, &llh);
2531 name_destroy(&lovuuid);
2532 name_destroy(&oscuuid);
2533 name_destroy(&oscname);
2534 name_destroy(&svname);
2535 name_destroy(&nodeuuid);
2539 static int mgs_write_log_ost(const struct lu_env *env,
2540 struct mgs_device *mgs, struct fs_db *fsdb,
2541 struct mgs_target_info *mti)
2543 struct llog_handle *llh = NULL;
2544 char *logname, *lovname;
2545 char *ptr = mti->mti_params;
2546 int rc, flags = 0, failout = 0, i;
2549 CDEBUG(D_MGS, "writing new ost %s\n", mti->mti_svname);
2551 /* The ost startup log */
2553 /* If the ost log already exists, that means that someone reformatted
2554 the ost and it called target_add again. */
2555 if (!mgs_log_is_empty(env, mgs, mti->mti_svname)) {
2556 LCONSOLE_ERROR_MSG(0x141, "The config log for %s already "
2557 "exists, yet the server claims it never "
2558 "registered. It may have been reformatted, "
2559 "or the index changed. writeconf the MDT to "
2560 "regenerate all logs.\n", mti->mti_svname);
2565 attach obdfilter ost1 ost1_UUID
2566 setup /dev/loop2 ldiskfs f|n errors=remount-ro,user_xattr
2568 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
2569 failout = (strncmp(ptr, "failout", 7) == 0);
2570 rc = record_start_log(env, mgs, &llh, mti->mti_svname);
2573 /* FIXME these should be a single journal transaction */
2574 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,"add ost");
2577 if (*mti->mti_uuid == '\0')
2578 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
2579 "%s_UUID", mti->mti_svname);
2580 rc = record_attach(env, llh, mti->mti_svname,
2581 "obdfilter"/*LUSTRE_OST_NAME*/, mti->mti_uuid);
2584 rc = record_setup(env, llh, mti->mti_svname,
2585 "dev"/*ignored*/, "type"/*ignored*/,
2586 failout ? "n" : "f", 0/*options*/);
2589 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname, "add ost");
2593 record_end_log(env, &llh);
2596 /* We also have to update the other logs where this osc is part of
2599 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
2600 /* If we're upgrading, the old mdt log already has our
2601 entry. Let's do a fake one for fun. */
2602 /* Note that we can't add any new failnids, since we don't
2603 know the old osc names. */
2604 flags = CM_SKIP | CM_UPGRADE146;
2606 } else if ((mti->mti_flags & LDD_F_UPDATE) != LDD_F_UPDATE) {
2607 /* If the update flag isn't set, don't update client/mdt
2610 LCONSOLE_WARN("Client log for %s was not updated; writeconf "
2611 "the MDT first to regenerate it.\n",
2615 /* Add ost to all MDT lov defs */
2616 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
2617 if (test_bit(i, fsdb->fsdb_mdt_index_map)) {
2620 rc = name_create_mdt_and_lov(&logname, &lovname, fsdb,
2624 sprintf(mdt_index, "-MDT%04x", i);
2625 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, mti,
2627 lovname, LUSTRE_SP_MDT,
2629 name_destroy(&logname);
2630 name_destroy(&lovname);
2636 /* Append ost info to the client log */
2637 rc = name_create(&logname, mti->mti_fsname, "-client");
2640 if (mgs_log_is_empty(env, mgs, logname)) {
2641 /* Start client log */
2642 rc = mgs_write_log_lov(env, mgs, fsdb, mti, logname,
2646 rc = mgs_write_log_lmv(env, mgs, fsdb, mti, logname,
2651 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, mti, logname, "",
2652 fsdb->fsdb_clilov, LUSTRE_SP_CLI, 0);
2654 name_destroy(&logname);
2658 static __inline__ int mgs_param_empty(char *ptr)
2662 if ((tmp = strchr(ptr, '=')) && (*(++tmp) == '\0'))
2667 static int mgs_write_log_failnid_internal(const struct lu_env *env,
2668 struct mgs_device *mgs,
2670 struct mgs_target_info *mti,
2671 char *logname, char *cliname)
2674 struct llog_handle *llh = NULL;
2676 if (mgs_param_empty(mti->mti_params)) {
2677 /* Remove _all_ failnids */
2678 rc = mgs_modify(env, mgs, fsdb, mti, logname,
2679 mti->mti_svname, "add failnid", CM_SKIP);
2680 return rc < 0 ? rc : 0;
2683 /* Otherwise failover nids are additive */
2684 rc = record_start_log(env, mgs, &llh, logname);
2687 /* FIXME this should be a single journal transaction */
2688 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
2692 rc = mgs_write_log_failnids(env, mti, llh, cliname);
2695 rc = record_marker(env, llh, fsdb, CM_END,
2696 mti->mti_svname, "add failnid");
2698 record_end_log(env, &llh);
2703 /* Add additional failnids to an existing log.
2704 The mdc/osc must have been added to logs first */
2705 /* tcp nids must be in dotted-quad ascii -
2706 we can't resolve hostnames from the kernel. */
2707 static int mgs_write_log_add_failnid(const struct lu_env *env,
2708 struct mgs_device *mgs,
2710 struct mgs_target_info *mti)
2712 char *logname, *cliname;
2716 /* FIXME we currently can't erase the failnids
2717 * given when a target first registers, since they aren't part of
2718 * an "add uuid" stanza */
2720 /* Verify that we know about this target */
2721 if (mgs_log_is_empty(env, mgs, mti->mti_svname)) {
2722 LCONSOLE_ERROR_MSG(0x142, "The target %s has not registered "
2723 "yet. It must be started before failnids "
2724 "can be added.\n", mti->mti_svname);
2728 /* Create mdc/osc client name (e.g. lustre-OST0001-osc) */
2729 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
2730 rc = name_create(&cliname, mti->mti_svname, "-mdc");
2731 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2732 rc = name_create(&cliname, mti->mti_svname, "-osc");
2738 /* Add failover nids to the client log */
2739 rc = name_create(&logname, mti->mti_fsname, "-client");
2741 name_destroy(&cliname);
2744 rc = mgs_write_log_failnid_internal(env, mgs, fsdb,mti,logname,cliname);
2745 name_destroy(&logname);
2746 name_destroy(&cliname);
2750 if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2751 /* Add OST failover nids to the MDT logs as well */
2754 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2755 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
2757 rc = name_create_mdt(&logname, mti->mti_fsname, i);
2760 rc = name_create_mdt_osc(&cliname, mti->mti_svname,
2763 name_destroy(&logname);
2766 rc = mgs_write_log_failnid_internal(env, mgs, fsdb,
2769 name_destroy(&cliname);
2770 name_destroy(&logname);
2779 static int mgs_wlp_lcfg(const struct lu_env *env,
2780 struct mgs_device *mgs, struct fs_db *fsdb,
2781 struct mgs_target_info *mti,
2782 char *logname, struct lustre_cfg_bufs *bufs,
2783 char *tgtname, char *ptr)
2785 char comment[MTI_NAME_MAXLEN];
2787 struct lustre_cfg *lcfg;
2790 /* Erase any old settings of this same parameter */
2791 memcpy(comment, ptr, MTI_NAME_MAXLEN);
2792 comment[MTI_NAME_MAXLEN - 1] = 0;
2793 /* But don't try to match the value. */
2794 if ((tmp = strchr(comment, '=')))
2796 /* FIXME we should skip settings that are the same as old values */
2797 rc = mgs_modify(env, mgs, fsdb, mti, logname, tgtname, comment,CM_SKIP);
2800 del = mgs_param_empty(ptr);
2802 LCONSOLE_INFO("%sing parameter %s.%s in log %s\n", del ? "Disabl" : rc ?
2803 "Sett" : "Modify", tgtname, comment, logname);
2807 lustre_cfg_bufs_reset(bufs, tgtname);
2808 lustre_cfg_bufs_set_string(bufs, 1, ptr);
2809 lcfg = lustre_cfg_new(LCFG_PARAM, bufs);
2812 rc = mgs_write_log_direct(env, mgs, fsdb, logname,lcfg,tgtname,comment);
2813 lustre_cfg_free(lcfg);
2817 /* write global variable settings into log */
2818 static int mgs_write_log_sys(const struct lu_env *env,
2819 struct mgs_device *mgs, struct fs_db *fsdb,
2820 struct mgs_target_info *mti, char *sys, char *ptr)
2822 struct mgs_thread_info *mgi = mgs_env_info(env);
2823 struct lustre_cfg *lcfg;
2825 int rc, cmd, convert = 1;
2827 if (class_match_param(ptr, PARAM_TIMEOUT, &tmp) == 0) {
2828 cmd = LCFG_SET_TIMEOUT;
2829 } else if (class_match_param(ptr, PARAM_LDLM_TIMEOUT, &tmp) == 0) {
2830 cmd = LCFG_SET_LDLM_TIMEOUT;
2831 /* Check for known params here so we can return error to lctl */
2832 } else if ((class_match_param(ptr, PARAM_AT_MIN, &tmp) == 0) ||
2833 (class_match_param(ptr, PARAM_AT_MAX, &tmp) == 0) ||
2834 (class_match_param(ptr, PARAM_AT_EXTRA, &tmp) == 0) ||
2835 (class_match_param(ptr, PARAM_AT_EARLY_MARGIN, &tmp) == 0) ||
2836 (class_match_param(ptr, PARAM_AT_HISTORY, &tmp) == 0)) {
2838 } else if (class_match_param(ptr, PARAM_JOBID_VAR, &tmp) == 0) {
2839 convert = 0; /* Don't convert string value to integer */
2845 if (mgs_param_empty(ptr))
2846 CDEBUG(D_MGS, "global '%s' removed\n", sys);
2848 CDEBUG(D_MGS, "global '%s' val=%s\n", sys, tmp);
2850 lustre_cfg_bufs_reset(&mgi->mgi_bufs, NULL);
2851 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, sys);
2852 if (!convert && *tmp != '\0')
2853 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 2, tmp);
2854 lcfg = lustre_cfg_new(cmd, &mgi->mgi_bufs);
2855 lcfg->lcfg_num = convert ? simple_strtoul(tmp, NULL, 0) : 0;
2856 /* truncate the comment to the parameter name */
2860 /* modify all servers and clients */
2861 rc = mgs_write_log_direct_all(env, mgs, fsdb, mti,
2862 *tmp == '\0' ? NULL : lcfg,
2863 mti->mti_fsname, sys, 0);
2864 if (rc == 0 && *tmp != '\0') {
2866 case LCFG_SET_TIMEOUT:
2867 if (!obd_timeout_set || lcfg->lcfg_num > obd_timeout)
2868 class_process_config(lcfg);
2870 case LCFG_SET_LDLM_TIMEOUT:
2871 if (!ldlm_timeout_set || lcfg->lcfg_num > ldlm_timeout)
2872 class_process_config(lcfg);
2879 lustre_cfg_free(lcfg);
2883 /* write quota settings into log */
2884 static int mgs_write_log_quota(const struct lu_env *env, struct mgs_device *mgs,
2885 struct fs_db *fsdb, struct mgs_target_info *mti,
2886 char *quota, char *ptr)
2888 struct mgs_thread_info *mgi = mgs_env_info(env);
2889 struct lustre_cfg *lcfg;
2892 int rc, cmd = LCFG_PARAM;
2894 /* support only 'meta' and 'data' pools so far */
2895 if (class_match_param(ptr, QUOTA_METAPOOL_NAME, &tmp) != 0 &&
2896 class_match_param(ptr, QUOTA_DATAPOOL_NAME, &tmp) != 0) {
2897 CERROR("parameter quota.%s isn't supported (only quota.mdt "
2898 "& quota.ost are)\n", ptr);
2903 CDEBUG(D_MGS, "global '%s' removed\n", quota);
2905 CDEBUG(D_MGS, "global '%s'\n", quota);
2907 if (strchr(tmp, 'u') == NULL && strchr(tmp, 'g') == NULL &&
2908 strcmp(tmp, "none") != 0) {
2909 CERROR("enable option(%s) isn't supported\n", tmp);
2914 lustre_cfg_bufs_reset(&mgi->mgi_bufs, mti->mti_fsname);
2915 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, quota);
2916 lcfg = lustre_cfg_new(cmd, &mgi->mgi_bufs);
2917 /* truncate the comment to the parameter name */
2922 /* XXX we duplicated quota enable information in all server
2923 * config logs, it should be moved to a separate config
2924 * log once we cleanup the config log for global param. */
2925 /* modify all servers */
2926 rc = mgs_write_log_direct_all(env, mgs, fsdb, mti,
2927 *tmp == '\0' ? NULL : lcfg,
2928 mti->mti_fsname, quota, 1);
2930 lustre_cfg_free(lcfg);
2931 return rc < 0 ? rc : 0;
2934 static int mgs_srpc_set_param_disk(const struct lu_env *env,
2935 struct mgs_device *mgs,
2937 struct mgs_target_info *mti,
2940 struct mgs_thread_info *mgi = mgs_env_info(env);
2941 struct llog_handle *llh = NULL;
2943 char *comment, *ptr;
2944 struct lustre_cfg *lcfg;
2949 ptr = strchr(param, '=');
2953 OBD_ALLOC(comment, len + 1);
2954 if (comment == NULL)
2956 strncpy(comment, param, len);
2957 comment[len] = '\0';
2960 lustre_cfg_bufs_reset(&mgi->mgi_bufs, mti->mti_svname);
2961 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, param);
2962 lcfg = lustre_cfg_new(LCFG_SPTLRPC_CONF, &mgi->mgi_bufs);
2964 GOTO(out_comment, rc = -ENOMEM);
2966 /* construct log name */
2967 rc = name_create(&logname, mti->mti_fsname, "-sptlrpc");
2971 if (mgs_log_is_empty(env, mgs, logname)) {
2972 rc = record_start_log(env, mgs, &llh, logname);
2975 record_end_log(env, &llh);
2978 /* obsolete old one */
2979 rc = mgs_modify(env, mgs, fsdb, mti, logname, mti->mti_svname,
2983 /* write the new one */
2984 rc = mgs_write_log_direct(env, mgs, fsdb, logname, lcfg,
2985 mti->mti_svname, comment);
2987 CERROR("err %d writing log %s\n", rc, logname);
2989 name_destroy(&logname);
2991 lustre_cfg_free(lcfg);
2993 OBD_FREE(comment, len + 1);
2997 static int mgs_srpc_set_param_udesc_mem(struct fs_db *fsdb,
3002 /* disable the adjustable udesc parameter for now, i.e. use default
3003 * setting that client always ship udesc to MDT if possible. to enable
3004 * it simply remove the following line */
3007 ptr = strchr(param, '=');
3012 if (strcmp(param, PARAM_SRPC_UDESC))
3015 if (strcmp(ptr, "yes") == 0) {
3016 set_bit(FSDB_UDESC, &fsdb->fsdb_flags);
3017 CWARN("Enable user descriptor shipping from client to MDT\n");
3018 } else if (strcmp(ptr, "no") == 0) {
3019 clear_bit(FSDB_UDESC, &fsdb->fsdb_flags);
3020 CWARN("Disable user descriptor shipping from client to MDT\n");
3028 CERROR("Invalid param: %s\n", param);
3032 static int mgs_srpc_set_param_mem(struct fs_db *fsdb,
3036 struct sptlrpc_rule rule;
3037 struct sptlrpc_rule_set *rset;
3041 if (strncmp(param, PARAM_SRPC, sizeof(PARAM_SRPC) - 1) != 0) {
3042 CERROR("Invalid sptlrpc parameter: %s\n", param);
3046 if (strncmp(param, PARAM_SRPC_UDESC,
3047 sizeof(PARAM_SRPC_UDESC) - 1) == 0) {
3048 RETURN(mgs_srpc_set_param_udesc_mem(fsdb, param));
3051 if (strncmp(param, PARAM_SRPC_FLVR, sizeof(PARAM_SRPC_FLVR) - 1) != 0) {
3052 CERROR("Invalid sptlrpc flavor parameter: %s\n", param);
3056 param += sizeof(PARAM_SRPC_FLVR) - 1;
3058 rc = sptlrpc_parse_rule(param, &rule);
3062 /* mgs rules implies must be mgc->mgs */
3063 if (test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
3064 if ((rule.sr_from != LUSTRE_SP_MGC &&
3065 rule.sr_from != LUSTRE_SP_ANY) ||
3066 (rule.sr_to != LUSTRE_SP_MGS &&
3067 rule.sr_to != LUSTRE_SP_ANY))
3071 /* preapre room for this coming rule. svcname format should be:
3072 * - fsname: general rule
3073 * - fsname-tgtname: target-specific rule
3075 if (strchr(svname, '-')) {
3076 struct mgs_tgt_srpc_conf *tgtconf;
3079 for (tgtconf = fsdb->fsdb_srpc_tgt; tgtconf != NULL;
3080 tgtconf = tgtconf->mtsc_next) {
3081 if (!strcmp(tgtconf->mtsc_tgt, svname)) {
3090 OBD_ALLOC_PTR(tgtconf);
3091 if (tgtconf == NULL)
3094 name_len = strlen(svname);
3096 OBD_ALLOC(tgtconf->mtsc_tgt, name_len + 1);
3097 if (tgtconf->mtsc_tgt == NULL) {
3098 OBD_FREE_PTR(tgtconf);
3101 memcpy(tgtconf->mtsc_tgt, svname, name_len);
3103 tgtconf->mtsc_next = fsdb->fsdb_srpc_tgt;
3104 fsdb->fsdb_srpc_tgt = tgtconf;
3107 rset = &tgtconf->mtsc_rset;
3109 rset = &fsdb->fsdb_srpc_gen;
3112 rc = sptlrpc_rule_set_merge(rset, &rule);
3117 static int mgs_srpc_set_param(const struct lu_env *env,
3118 struct mgs_device *mgs,
3120 struct mgs_target_info *mti,
3130 /* keep a copy of original param, which could be destroied
3132 copy_size = strlen(param) + 1;
3133 OBD_ALLOC(copy, copy_size);
3136 memcpy(copy, param, copy_size);
3138 rc = mgs_srpc_set_param_mem(fsdb, mti->mti_svname, param);
3142 /* previous steps guaranteed the syntax is correct */
3143 rc = mgs_srpc_set_param_disk(env, mgs, fsdb, mti, copy);
3147 if (test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
3149 * for mgs rules, make them effective immediately.
3151 LASSERT(fsdb->fsdb_srpc_tgt == NULL);
3152 sptlrpc_target_update_exp_flavor(mgs->mgs_obd,
3153 &fsdb->fsdb_srpc_gen);
3157 OBD_FREE(copy, copy_size);
3161 struct mgs_srpc_read_data {
3162 struct fs_db *msrd_fsdb;
3166 static int mgs_srpc_read_handler(const struct lu_env *env,
3167 struct llog_handle *llh,
3168 struct llog_rec_hdr *rec, void *data)
3170 struct mgs_srpc_read_data *msrd = data;
3171 struct cfg_marker *marker;
3172 struct lustre_cfg *lcfg = REC_DATA(rec);
3173 char *svname, *param;
3177 if (rec->lrh_type != OBD_CFG_REC) {
3178 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
3182 cfg_len = rec->lrh_len - sizeof(struct llog_rec_hdr) -
3183 sizeof(struct llog_rec_tail);
3185 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
3187 CERROR("Insane cfg\n");
3191 if (lcfg->lcfg_command == LCFG_MARKER) {
3192 marker = lustre_cfg_buf(lcfg, 1);
3194 if (marker->cm_flags & CM_START &&
3195 marker->cm_flags & CM_SKIP)
3196 msrd->msrd_skip = 1;
3197 if (marker->cm_flags & CM_END)
3198 msrd->msrd_skip = 0;
3203 if (msrd->msrd_skip)
3206 if (lcfg->lcfg_command != LCFG_SPTLRPC_CONF) {
3207 CERROR("invalid command (%x)\n", lcfg->lcfg_command);
3211 svname = lustre_cfg_string(lcfg, 0);
3212 if (svname == NULL) {
3213 CERROR("svname is empty\n");
3217 param = lustre_cfg_string(lcfg, 1);
3218 if (param == NULL) {
3219 CERROR("param is empty\n");
3223 rc = mgs_srpc_set_param_mem(msrd->msrd_fsdb, svname, param);
3225 CERROR("read sptlrpc record error (%d): %s\n", rc, param);
3230 int mgs_get_fsdb_srpc_from_llog(const struct lu_env *env,
3231 struct mgs_device *mgs,
3234 struct llog_handle *llh = NULL;
3235 struct llog_ctxt *ctxt;
3237 struct mgs_srpc_read_data msrd;
3241 /* construct log name */
3242 rc = name_create(&logname, fsdb->fsdb_name, "-sptlrpc");
3246 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
3247 LASSERT(ctxt != NULL);
3249 if (mgs_log_is_empty(env, mgs, logname))
3252 rc = llog_open(env, ctxt, &llh, NULL, logname,
3260 rc = llog_init_handle(env, llh, LLOG_F_IS_PLAIN, NULL);
3262 GOTO(out_close, rc);
3264 if (llog_get_size(llh) <= 1)
3265 GOTO(out_close, rc = 0);
3267 msrd.msrd_fsdb = fsdb;
3270 rc = llog_process(env, llh, mgs_srpc_read_handler, (void *)&msrd,
3274 llog_close(env, llh);
3276 llog_ctxt_put(ctxt);
3277 name_destroy(&logname);
3280 CERROR("failed to read sptlrpc config database: %d\n", rc);
3284 /* Permanent settings of all parameters by writing into the appropriate
3285 * configuration logs.
3286 * A parameter with null value ("<param>='\0'") means to erase it out of
3289 static int mgs_write_log_param(const struct lu_env *env,
3290 struct mgs_device *mgs, struct fs_db *fsdb,
3291 struct mgs_target_info *mti, char *ptr)
3293 struct mgs_thread_info *mgi = mgs_env_info(env);
3296 int rc = 0, rc2 = 0;
3299 /* For various parameter settings, we have to figure out which logs
3300 care about them (e.g. both mdt and client for lov settings) */
3301 CDEBUG(D_MGS, "next param '%s'\n", ptr);
3303 /* The params are stored in MOUNT_DATA_FILE and modified via
3304 tunefs.lustre, or set using lctl conf_param */
3306 /* Processed in lustre_start_mgc */
3307 if (class_match_param(ptr, PARAM_MGSNODE, NULL) == 0)
3310 /* Processed in ost/mdt */
3311 if (class_match_param(ptr, PARAM_NETWORK, NULL) == 0)
3314 /* Processed in mgs_write_log_ost */
3315 if (class_match_param(ptr, PARAM_FAILMODE, NULL) == 0) {
3316 if (mti->mti_flags & LDD_F_PARAM) {
3317 LCONSOLE_ERROR_MSG(0x169, "%s can only be "
3318 "changed with tunefs.lustre"
3319 "and --writeconf\n", ptr);
3325 if (class_match_param(ptr, PARAM_SRPC, NULL) == 0) {
3326 rc = mgs_srpc_set_param(env, mgs, fsdb, mti, ptr);
3330 if (class_match_param(ptr, PARAM_FAILNODE, NULL) == 0) {
3331 /* Add a failover nidlist */
3333 /* We already processed failovers params for new
3334 targets in mgs_write_log_target */
3335 if (mti->mti_flags & LDD_F_PARAM) {
3336 CDEBUG(D_MGS, "Adding failnode\n");
3337 rc = mgs_write_log_add_failnid(env, mgs, fsdb, mti);
3342 if (class_match_param(ptr, PARAM_SYS, &tmp) == 0) {
3343 rc = mgs_write_log_sys(env, mgs, fsdb, mti, ptr, tmp);
3347 if (class_match_param(ptr, PARAM_QUOTA, &tmp) == 0) {
3348 rc = mgs_write_log_quota(env, mgs, fsdb, mti, ptr, tmp);
3352 if (class_match_param(ptr, PARAM_OSC""PARAM_ACTIVE, &tmp) == 0) {
3353 /* active=0 means off, anything else means on */
3354 int flag = (*tmp == '0') ? CM_EXCLUDE : 0;
3357 if (!(mti->mti_flags & LDD_F_SV_TYPE_OST)) {
3358 LCONSOLE_ERROR_MSG(0x144, "%s: Only OSCs can "
3359 "be (de)activated.\n",
3361 GOTO(end, rc = -EINVAL);
3363 LCONSOLE_WARN("Permanently %sactivating %s\n",
3364 flag ? "de": "re", mti->mti_svname);
3366 rc = name_create(&logname, mti->mti_fsname, "-client");
3369 rc = mgs_modify(env, mgs, fsdb, mti, logname,
3370 mti->mti_svname, "add osc", flag);
3371 name_destroy(&logname);
3375 /* Add to all MDT logs for CMD */
3376 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3377 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
3379 rc = name_create_mdt(&logname, mti->mti_fsname, i);
3382 rc = mgs_modify(env, mgs, fsdb, mti, logname,
3383 mti->mti_svname, "add osc", flag);
3384 name_destroy(&logname);
3390 LCONSOLE_ERROR_MSG(0x145, "Couldn't find %s in"
3391 "log (%d). No permanent "
3392 "changes were made to the "
3394 mti->mti_svname, rc);
3395 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags))
3396 LCONSOLE_ERROR_MSG(0x146, "This may be"
3401 "update the logs.\n");
3404 /* Fall through to osc proc for deactivating live OSC
3405 on running MDT / clients. */
3407 /* Below here, let obd's XXX_process_config methods handle it */
3409 /* All lov. in proc */
3410 if (class_match_param(ptr, PARAM_LOV, NULL) == 0) {
3413 CDEBUG(D_MGS, "lov param %s\n", ptr);
3414 if (!(mti->mti_flags & LDD_F_SV_TYPE_MDT)) {
3415 LCONSOLE_ERROR_MSG(0x147, "LOV params must be "
3416 "set on the MDT, not %s. "
3423 if (mgs_log_is_empty(env, mgs, mti->mti_svname))
3424 GOTO(end, rc = -ENODEV);
3426 rc = name_create_mdt_and_lov(&logname, &mdtlovname, fsdb,
3427 mti->mti_stripe_index);
3430 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, mti->mti_svname,
3431 &mgi->mgi_bufs, mdtlovname, ptr);
3432 name_destroy(&logname);
3433 name_destroy(&mdtlovname);
3438 rc = name_create(&logname, mti->mti_fsname, "-client");
3441 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname, &mgi->mgi_bufs,
3442 fsdb->fsdb_clilov, ptr);
3443 name_destroy(&logname);
3447 /* All osc., mdc., llite. params in proc */
3448 if ((class_match_param(ptr, PARAM_OSC, NULL) == 0) ||
3449 (class_match_param(ptr, PARAM_MDC, NULL) == 0) ||
3450 (class_match_param(ptr, PARAM_LLITE, NULL) == 0)) {
3453 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
3454 LCONSOLE_ERROR_MSG(0x148, "Upgraded client logs for %s"
3455 " cannot be modified. Consider"
3456 " updating the configuration with"
3459 GOTO(end, rc = -EINVAL);
3461 if (memcmp(ptr, PARAM_LLITE, strlen(PARAM_LLITE)) == 0) {
3462 rc = name_create(&cname, mti->mti_fsname, "-client");
3463 /* Add the client type to match the obdname in
3464 class_config_llog_handler */
3465 } else if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
3466 rc = name_create(&cname, mti->mti_svname, "-mdc");
3467 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
3468 rc = name_create(&cname, mti->mti_svname, "-osc");
3470 GOTO(end, rc = -EINVAL);
3475 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
3478 rc = name_create(&logname, mti->mti_fsname, "-client");
3480 name_destroy(&cname);
3483 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname, &mgi->mgi_bufs,
3486 /* osc params affect the MDT as well */
3487 if (!rc && (mti->mti_flags & LDD_F_SV_TYPE_OST)) {
3490 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
3491 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
3493 name_destroy(&cname);
3494 rc = name_create_mdt_osc(&cname, mti->mti_svname,
3496 name_destroy(&logname);
3499 rc = name_create_mdt(&logname,
3500 mti->mti_fsname, i);
3503 if (!mgs_log_is_empty(env, mgs, logname)) {
3504 rc = mgs_wlp_lcfg(env, mgs, fsdb,
3513 name_destroy(&logname);
3514 name_destroy(&cname);
3518 /* All mdt. params in proc */
3519 if (class_match_param(ptr, PARAM_MDT, NULL) == 0) {
3523 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
3524 if (strncmp(mti->mti_svname, mti->mti_fsname,
3525 MTI_NAME_MAXLEN) == 0)
3526 /* device is unspecified completely? */
3527 rc = LDD_F_SV_TYPE_MDT | LDD_F_SV_ALL;
3529 rc = server_name2index(mti->mti_svname, &idx, NULL);
3532 if ((rc & LDD_F_SV_TYPE_MDT) == 0)
3534 if (rc & LDD_F_SV_ALL) {
3535 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3537 fsdb->fsdb_mdt_index_map))
3539 rc = name_create_mdt(&logname,
3540 mti->mti_fsname, i);
3543 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti,
3544 logname, &mgi->mgi_bufs,
3546 name_destroy(&logname);
3551 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti,
3552 mti->mti_svname, &mgi->mgi_bufs,
3553 mti->mti_svname, ptr);
3560 /* All mdd., ost. params in proc */
3561 if ((class_match_param(ptr, PARAM_MDD, NULL) == 0) ||
3562 (class_match_param(ptr, PARAM_OST, NULL) == 0)) {
3563 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
3564 if (mgs_log_is_empty(env, mgs, mti->mti_svname))
3565 GOTO(end, rc = -ENODEV);
3567 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, mti->mti_svname,
3568 &mgi->mgi_bufs, mti->mti_svname, ptr);
3572 LCONSOLE_WARN("Ignoring unrecognized param '%s'\n", ptr);
3577 CERROR("err %d on param '%s'\n", rc, ptr);
3582 /* Not implementing automatic failover nid addition at this time. */
3583 int mgs_check_failnid(const struct lu_env *env, struct mgs_device *mgs,
3584 struct mgs_target_info *mti)
3591 rc = mgs_find_or_make_fsdb(obd, fsname, &fsdb);
3595 if (mgs_log_is_empty(obd, mti->mti_svname))
3596 /* should never happen */
3599 CDEBUG(D_MGS, "Checking for new failnids for %s\n", mti->mti_svname);
3601 /* FIXME We can just check mti->params to see if we're already in
3602 the failover list. Modify mti->params for rewriting back at
3603 server_register_target(). */
3605 mutex_lock(&fsdb->fsdb_mutex);
3606 rc = mgs_write_log_add_failnid(obd, fsdb, mti);
3607 mutex_unlock(&fsdb->fsdb_mutex);
3614 int mgs_write_log_target(const struct lu_env *env,
3615 struct mgs_device *mgs,
3616 struct mgs_target_info *mti,
3623 /* set/check the new target index */
3624 rc = mgs_set_index(env, mgs, mti);
3626 CERROR("Can't get index (%d)\n", rc);
3630 if (rc == EALREADY) {
3631 LCONSOLE_WARN("Found index %d for %s, updating log\n",
3632 mti->mti_stripe_index, mti->mti_svname);
3633 /* We would like to mark old log sections as invalid
3634 and add new log sections in the client and mdt logs.
3635 But if we add new sections, then live clients will
3636 get repeat setup instructions for already running
3637 osc's. So don't update the client/mdt logs. */
3638 mti->mti_flags &= ~LDD_F_UPDATE;
3642 mutex_lock(&fsdb->fsdb_mutex);
3644 if (mti->mti_flags &
3645 (LDD_F_VIRGIN | LDD_F_UPGRADE14 | LDD_F_WRITECONF)) {
3646 /* Generate a log from scratch */
3647 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
3648 rc = mgs_write_log_mdt(env, mgs, fsdb, mti);
3649 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
3650 rc = mgs_write_log_ost(env, mgs, fsdb, mti);
3652 CERROR("Unknown target type %#x, can't create log for "
3653 "%s\n", mti->mti_flags, mti->mti_svname);
3656 CERROR("Can't write logs for %s (%d)\n",
3657 mti->mti_svname, rc);
3661 /* Just update the params from tunefs in mgs_write_log_params */
3662 CDEBUG(D_MGS, "Update params for %s\n", mti->mti_svname);
3663 mti->mti_flags |= LDD_F_PARAM;
3666 /* allocate temporary buffer, where class_get_next_param will
3667 make copy of a current parameter */
3668 OBD_ALLOC(buf, strlen(mti->mti_params) + 1);
3670 GOTO(out_up, rc = -ENOMEM);
3671 params = mti->mti_params;
3672 while (params != NULL) {
3673 rc = class_get_next_param(¶ms, buf);
3676 /* there is no next parameter, that is
3681 CDEBUG(D_MGS, "remaining string: '%s', param: '%s'\n",
3683 rc = mgs_write_log_param(env, mgs, fsdb, mti, buf);
3688 OBD_FREE(buf, strlen(mti->mti_params) + 1);
3691 mutex_unlock(&fsdb->fsdb_mutex);
3695 int mgs_erase_log(const struct lu_env *env, struct mgs_device *mgs, char *name)
3697 struct llog_ctxt *ctxt;
3700 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
3702 CERROR("%s: MGS config context doesn't exist\n",
3703 mgs->mgs_obd->obd_name);
3706 rc = llog_erase(env, ctxt, NULL, name);
3707 /* llog may not exist */
3710 llog_ctxt_put(ctxt);
3714 CERROR("%s: failed to clear log %s: %d\n",
3715 mgs->mgs_obd->obd_name, name, rc);
3720 /* erase all logs for the given fs */
3721 int mgs_erase_logs(const struct lu_env *env, struct mgs_device *mgs, char *fsname)
3725 struct mgs_direntry *dirent, *n;
3726 int rc, len = strlen(fsname);
3730 /* Find all the logs in the CONFIGS directory */
3731 rc = class_dentry_readdir(env, mgs, &list);
3735 mutex_lock(&mgs->mgs_mutex);
3737 /* Delete the fs db */
3738 fsdb = mgs_find_fsdb(mgs, fsname);
3740 mgs_free_fsdb(mgs, fsdb);
3742 mutex_unlock(&mgs->mgs_mutex);
3744 cfs_list_for_each_entry_safe(dirent, n, &list, list) {
3745 cfs_list_del(&dirent->list);
3746 suffix = strrchr(dirent->name, '-');
3747 if (suffix != NULL) {
3748 if ((len == suffix - dirent->name) &&
3749 (strncmp(fsname, dirent->name, len) == 0)) {
3750 CDEBUG(D_MGS, "Removing log %s\n",
3752 mgs_erase_log(env, mgs, dirent->name);
3755 mgs_direntry_free(dirent);
3761 /* from llog_swab */
3762 static void print_lustre_cfg(struct lustre_cfg *lcfg)
3767 CDEBUG(D_MGS, "lustre_cfg: %p\n", lcfg);
3768 CDEBUG(D_MGS, "\tlcfg->lcfg_version: %#x\n", lcfg->lcfg_version);
3770 CDEBUG(D_MGS, "\tlcfg->lcfg_command: %#x\n", lcfg->lcfg_command);
3771 CDEBUG(D_MGS, "\tlcfg->lcfg_num: %#x\n", lcfg->lcfg_num);
3772 CDEBUG(D_MGS, "\tlcfg->lcfg_flags: %#x\n", lcfg->lcfg_flags);
3773 CDEBUG(D_MGS, "\tlcfg->lcfg_nid: %s\n", libcfs_nid2str(lcfg->lcfg_nid));
3775 CDEBUG(D_MGS, "\tlcfg->lcfg_bufcount: %d\n", lcfg->lcfg_bufcount);
3776 if (lcfg->lcfg_bufcount < LUSTRE_CFG_MAX_BUFCOUNT)
3777 for (i = 0; i < lcfg->lcfg_bufcount; i++) {
3778 CDEBUG(D_MGS, "\tlcfg->lcfg_buflens[%d]: %d %s\n",
3779 i, lcfg->lcfg_buflens[i],
3780 lustre_cfg_string(lcfg, i));
3785 /* Set a permanent (config log) param for a target or fs
3786 * \param lcfg buf0 may contain the device (testfs-MDT0000) name
3787 * buf1 contains the single parameter
3789 int mgs_setparam(const struct lu_env *env, struct mgs_device *mgs,
3790 struct lustre_cfg *lcfg, char *fsname)
3793 struct mgs_target_info *mti;
3794 char *devname, *param;
3801 print_lustre_cfg(lcfg);
3803 /* lustre, lustre-mdtlov, lustre-client, lustre-MDT0000 */
3804 devname = lustre_cfg_string(lcfg, 0);
3805 param = lustre_cfg_string(lcfg, 1);
3807 /* Assume device name embedded in param:
3808 lustre-OST0000.osc.max_dirty_mb=32 */
3809 ptr = strchr(param, '.');
3817 LCONSOLE_ERROR_MSG(0x14d, "No target specified: %s\n", param);
3821 rc = mgs_parse_devname(devname, fsname, NULL);
3822 if (rc == 0 && !mgs_parse_devname(devname, NULL, &index)) {
3823 /* param related to llite isn't allowed to set by OST or MDT */
3824 if (rc == 0 && strncmp(param, PARAM_LLITE,
3825 sizeof(PARAM_LLITE)) == 0)
3828 /* assume devname is the fsname */
3829 memset(fsname, 0, MTI_NAME_MAXLEN);
3830 strncpy(fsname, devname, MTI_NAME_MAXLEN);
3831 fsname[MTI_NAME_MAXLEN - 1] = 0;
3833 CDEBUG(D_MGS, "setparam fs='%s' device='%s'\n", fsname, devname);
3835 rc = mgs_find_or_make_fsdb(env, mgs, fsname, &fsdb);
3838 if (!test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags) &&
3839 test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
3840 CERROR("No filesystem targets for %s. cfg_device from lctl "
3841 "is '%s'\n", fsname, devname);
3842 mgs_free_fsdb(mgs, fsdb);
3846 /* Create a fake mti to hold everything */
3849 GOTO(out, rc = -ENOMEM);
3850 if (strlcpy(mti->mti_fsname, fsname, sizeof(mti->mti_fsname))
3851 >= sizeof(mti->mti_fsname))
3852 GOTO(out, rc = -E2BIG);
3853 if (strlcpy(mti->mti_svname, devname, sizeof(mti->mti_svname))
3854 >= sizeof(mti->mti_svname))
3855 GOTO(out, rc = -E2BIG);
3856 if (strlcpy(mti->mti_params, param, sizeof(mti->mti_params))
3857 >= sizeof(mti->mti_params))
3858 GOTO(out, rc = -E2BIG);
3859 rc = server_name2index(mti->mti_svname, &mti->mti_stripe_index, &tmp);
3861 /* Not a valid server; may be only fsname */
3864 /* Strip -osc or -mdc suffix from svname */
3865 if (server_make_name(rc, mti->mti_stripe_index, mti->mti_fsname,
3867 GOTO(out, rc = -EINVAL);
3869 mti->mti_flags = rc | LDD_F_PARAM;
3871 mutex_lock(&fsdb->fsdb_mutex);
3872 rc = mgs_write_log_param(env, mgs, fsdb, mti, mti->mti_params);
3873 mutex_unlock(&fsdb->fsdb_mutex);
3876 * Revoke lock so everyone updates. Should be alright if
3877 * someone was already reading while we were updating the logs,
3878 * so we don't really need to hold the lock while we're
3881 mgs_revoke_lock(mgs, fsdb, CONFIG_T_CONFIG);
3887 static int mgs_write_log_pool(const struct lu_env *env,
3888 struct mgs_device *mgs, char *logname,
3889 struct fs_db *fsdb, char *lovname,
3890 enum lcfg_command_type cmd,
3891 char *poolname, char *fsname,
3892 char *ostname, char *comment)
3894 struct llog_handle *llh = NULL;
3897 rc = record_start_log(env, mgs, &llh, logname);
3900 rc = record_marker(env, llh, fsdb, CM_START, lovname, comment);
3903 rc = record_base(env, llh, lovname, 0, cmd, poolname, fsname, ostname, 0);
3906 rc = record_marker(env, llh, fsdb, CM_END, lovname, comment);
3908 record_end_log(env, &llh);
3912 int mgs_pool_cmd(const struct lu_env *env, struct mgs_device *mgs,
3913 enum lcfg_command_type cmd, char *fsname,
3914 char *poolname, char *ostname)
3919 char *label = NULL, *canceled_label = NULL;
3921 struct mgs_target_info *mti = NULL;
3925 rc = mgs_find_or_make_fsdb(env, mgs, fsname, &fsdb);
3927 CERROR("Can't get db for %s\n", fsname);
3930 if (test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
3931 CERROR("%s is not defined\n", fsname);
3932 mgs_free_fsdb(mgs, fsdb);
3936 label_sz = 10 + strlen(fsname) + strlen(poolname);
3938 /* check if ostname match fsname */
3939 if (ostname != NULL) {
3942 ptr = strrchr(ostname, '-');
3943 if ((ptr == NULL) ||
3944 (strncmp(fsname, ostname, ptr-ostname) != 0))
3946 label_sz += strlen(ostname);
3949 OBD_ALLOC(label, label_sz);
3956 "new %s.%s", fsname, poolname);
3960 "add %s.%s.%s", fsname, poolname, ostname);
3963 OBD_ALLOC(canceled_label, label_sz);
3964 if (canceled_label == NULL)
3965 GOTO(out_label, rc = -ENOMEM);
3967 "rem %s.%s.%s", fsname, poolname, ostname);
3968 sprintf(canceled_label,
3969 "add %s.%s.%s", fsname, poolname, ostname);
3972 OBD_ALLOC(canceled_label, label_sz);
3973 if (canceled_label == NULL)
3974 GOTO(out_label, rc = -ENOMEM);
3976 "del %s.%s", fsname, poolname);
3977 sprintf(canceled_label,
3978 "new %s.%s", fsname, poolname);
3984 mutex_lock(&fsdb->fsdb_mutex);
3986 if (canceled_label != NULL) {
3989 GOTO(out_cancel, rc = -ENOMEM);
3992 /* write pool def to all MDT logs */
3993 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3994 if (test_bit(i, fsdb->fsdb_mdt_index_map)) {
3995 rc = name_create_mdt_and_lov(&logname, &lovname,
3998 mutex_unlock(&fsdb->fsdb_mutex);
4001 if (canceled_label != NULL) {
4002 strcpy(mti->mti_svname, "lov pool");
4003 rc = mgs_modify(env, mgs, fsdb, mti, logname,
4004 lovname, canceled_label,
4009 rc = mgs_write_log_pool(env, mgs, logname,
4013 name_destroy(&logname);
4014 name_destroy(&lovname);
4016 mutex_unlock(&fsdb->fsdb_mutex);
4022 rc = name_create(&logname, fsname, "-client");
4024 mutex_unlock(&fsdb->fsdb_mutex);
4027 if (canceled_label != NULL) {
4028 rc = mgs_modify(env, mgs, fsdb, mti, logname,
4029 fsdb->fsdb_clilov, canceled_label, CM_SKIP);
4031 mutex_unlock(&fsdb->fsdb_mutex);
4032 name_destroy(&logname);
4037 rc = mgs_write_log_pool(env, mgs, logname, fsdb, fsdb->fsdb_clilov,
4038 cmd, fsname, poolname, ostname, label);
4039 mutex_unlock(&fsdb->fsdb_mutex);
4040 name_destroy(&logname);
4041 /* request for update */
4042 mgs_revoke_lock(mgs, fsdb, CONFIG_T_CONFIG);
4049 if (canceled_label != NULL)
4050 OBD_FREE(canceled_label, label_sz);
4052 OBD_FREE(label, label_sz);