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_free, 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_free, 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)
717 llog_close(env, loghandle);
720 CERROR("%s: modify %s/%s failed: rc = %d\n",
721 mgs->mgs_obd->obd_name, mti->mti_svname, comment, rc);
726 /** This structure is passed to mgs_replace_handler */
727 struct mgs_replace_uuid_lookup {
728 /* Nids are replaced for this target device */
729 struct mgs_target_info target;
730 /* Temporary modified llog */
731 struct llog_handle *temp_llh;
732 /* Flag is set if in target block*/
733 int in_target_device;
734 /* Nids already added. Just skip (multiple nids) */
735 int device_nids_added;
736 /* Flag is set if this block should not be copied */
741 * Check: a) if block should be skipped
742 * b) is it target block
747 * \retval 0 should not to be skipped
748 * \retval 1 should to be skipped
750 static int check_markers(struct lustre_cfg *lcfg,
751 struct mgs_replace_uuid_lookup *mrul)
753 struct cfg_marker *marker;
755 /* Track markers. Find given device */
756 if (lcfg->lcfg_command == LCFG_MARKER) {
757 marker = lustre_cfg_buf(lcfg, 1);
758 /* Clean llog from records marked as CM_EXCLUDE.
759 CM_SKIP records are used for "active" command
760 and can be restored if needed */
761 if ((marker->cm_flags & (CM_EXCLUDE | CM_START)) ==
762 (CM_EXCLUDE | CM_START)) {
767 if ((marker->cm_flags & (CM_EXCLUDE | CM_END)) ==
768 (CM_EXCLUDE | CM_END)) {
773 if (strcmp(mrul->target.mti_svname, marker->cm_tgtname) == 0) {
774 LASSERT(!(marker->cm_flags & CM_START) ||
775 !(marker->cm_flags & CM_END));
776 if (marker->cm_flags & CM_START) {
777 mrul->in_target_device = 1;
778 mrul->device_nids_added = 0;
779 } else if (marker->cm_flags & CM_END)
780 mrul->in_target_device = 0;
787 static int record_lcfg(const struct lu_env *env, struct llog_handle *llh,
788 struct lustre_cfg *lcfg)
790 struct llog_rec_hdr rec;
796 LASSERT(llh->lgh_ctxt);
798 buflen = lustre_cfg_len(lcfg->lcfg_bufcount,
800 rec.lrh_len = llog_data_len(buflen);
801 rec.lrh_type = OBD_CFG_REC;
803 /* idx = -1 means append */
804 rc = llog_write(env, llh, &rec, NULL, 0, (void *)lcfg, -1);
806 CERROR("failed %d\n", rc);
810 static int record_base(const struct lu_env *env, struct llog_handle *llh,
811 char *cfgname, lnet_nid_t nid, int cmd,
812 char *s1, char *s2, char *s3, char *s4)
814 struct mgs_thread_info *mgi = mgs_env_info(env);
815 struct lustre_cfg *lcfg;
818 CDEBUG(D_MGS, "lcfg %s %#x %s %s %s %s\n", cfgname,
819 cmd, s1, s2, s3, s4);
821 lustre_cfg_bufs_reset(&mgi->mgi_bufs, cfgname);
823 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, s1);
825 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 2, s2);
827 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 3, s3);
829 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 4, s4);
831 lcfg = lustre_cfg_new(cmd, &mgi->mgi_bufs);
834 lcfg->lcfg_nid = nid;
836 rc = record_lcfg(env, llh, lcfg);
838 lustre_cfg_free(lcfg);
841 CERROR("error %d: lcfg %s %#x %s %s %s %s\n", rc, cfgname,
842 cmd, s1, s2, s3, s4);
847 static inline int record_add_uuid(const struct lu_env *env,
848 struct llog_handle *llh,
849 uint64_t nid, char *uuid)
851 return record_base(env, llh, NULL, nid, LCFG_ADD_UUID, uuid, 0, 0, 0);
854 static inline int record_add_conn(const struct lu_env *env,
855 struct llog_handle *llh,
856 char *devname, char *uuid)
858 return record_base(env, llh, devname, 0, LCFG_ADD_CONN, uuid, 0, 0, 0);
861 static inline int record_attach(const struct lu_env *env,
862 struct llog_handle *llh, char *devname,
863 char *type, char *uuid)
865 return record_base(env, llh,devname, 0, LCFG_ATTACH, type, uuid, 0, 0);
868 static inline int record_setup(const struct lu_env *env,
869 struct llog_handle *llh, char *devname,
870 char *s1, char *s2, char *s3, char *s4)
872 return record_base(env, llh, devname, 0, LCFG_SETUP, s1, s2, s3, s4);
876 * \retval <0 record processing error
877 * \retval n record is processed. No need copy original one.
878 * \retval 0 record is not processed.
880 static int process_command(const struct lu_env *env, struct lustre_cfg *lcfg,
881 struct mgs_replace_uuid_lookup *mrul)
888 if (lcfg->lcfg_command == LCFG_ADD_UUID) {
889 /* LCFG_ADD_UUID command found. Let's skip original command
890 and add passed nids */
891 ptr = mrul->target.mti_params;
892 while (class_parse_nid(ptr, &nid, &ptr) == 0) {
893 CDEBUG(D_MGS, "add nid %s with uuid %s, "
894 "device %s\n", libcfs_nid2str(nid),
895 mrul->target.mti_params,
896 mrul->target.mti_svname);
897 rc = record_add_uuid(env,
899 mrul->target.mti_params);
904 if (nids_added == 0) {
905 CERROR("No new nids were added, nid %s with uuid %s, "
906 "device %s\n", libcfs_nid2str(nid),
907 mrul->target.mti_params,
908 mrul->target.mti_svname);
911 mrul->device_nids_added = 1;
917 if (mrul->device_nids_added && lcfg->lcfg_command == LCFG_SETUP) {
918 /* LCFG_SETUP command found. UUID should be changed */
919 rc = record_setup(env,
921 /* devname the same */
922 lustre_cfg_string(lcfg, 0),
923 /* s1 is not changed */
924 lustre_cfg_string(lcfg, 1),
925 /* new uuid should be
927 mrul->target.mti_params,
928 /* s3 is not changed */
929 lustre_cfg_string(lcfg, 3),
930 /* s4 is not changed */
931 lustre_cfg_string(lcfg, 4));
935 /* Another commands in target device block */
940 * Handler that called for every record in llog.
941 * Records are processed in order they placed in llog.
943 * \param[in] llh log to be processed
944 * \param[in] rec current record
945 * \param[in] data mgs_replace_uuid_lookup structure
949 static int mgs_replace_handler(const struct lu_env *env,
950 struct llog_handle *llh,
951 struct llog_rec_hdr *rec,
954 struct mgs_replace_uuid_lookup *mrul;
955 struct lustre_cfg *lcfg = REC_DATA(rec);
956 int cfg_len = REC_DATA_LEN(rec);
960 mrul = (struct mgs_replace_uuid_lookup *)data;
962 if (rec->lrh_type != OBD_CFG_REC) {
963 CERROR("unhandled lrh_type: %#x, cmd %x %s %s\n",
964 rec->lrh_type, lcfg->lcfg_command,
965 lustre_cfg_string(lcfg, 0),
966 lustre_cfg_string(lcfg, 1));
970 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
972 /* Do not copy any invalidated records */
973 GOTO(skip_out, rc = 0);
976 rc = check_markers(lcfg, mrul);
977 if (rc || mrul->skip_it)
978 GOTO(skip_out, rc = 0);
980 /* Write to new log all commands outside target device block */
981 if (!mrul->in_target_device)
982 GOTO(copy_out, rc = 0);
984 /* Skip all other LCFG_ADD_UUID and LCFG_ADD_CONN records
985 (failover nids) for this target, assuming that if then
986 primary is changing then so is the failover */
987 if (mrul->device_nids_added &&
988 (lcfg->lcfg_command == LCFG_ADD_UUID ||
989 lcfg->lcfg_command == LCFG_ADD_CONN))
990 GOTO(skip_out, rc = 0);
992 rc = process_command(env, lcfg, mrul);
999 /* Record is placed in temporary llog as is */
1000 rc = llog_write(env, mrul->temp_llh, rec, NULL, 0, NULL, -1);
1002 CDEBUG(D_MGS, "Copied idx=%d, rc=%d, len=%d, cmd %x %s %s\n",
1003 rec->lrh_index, rc, rec->lrh_len, lcfg->lcfg_command,
1004 lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));
1008 CDEBUG(D_MGS, "Skipped idx=%d, rc=%d, len=%d, cmd %x %s %s\n",
1009 rec->lrh_index, rc, rec->lrh_len, lcfg->lcfg_command,
1010 lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));
1014 static int mgs_log_is_empty(const struct lu_env *env,
1015 struct mgs_device *mgs, char *name)
1017 struct llog_ctxt *ctxt;
1020 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
1021 LASSERT(ctxt != NULL);
1023 rc = llog_is_empty(env, ctxt, name);
1024 llog_ctxt_put(ctxt);
1028 static int mgs_replace_nids_log(const struct lu_env *env,
1029 struct obd_device *mgs, struct fs_db *fsdb,
1030 char *logname, char *devname, char *nids)
1032 struct llog_handle *orig_llh, *backup_llh;
1033 struct llog_ctxt *ctxt;
1034 struct mgs_replace_uuid_lookup *mrul;
1035 struct mgs_device *mgs_dev = lu2mgs_dev(mgs->obd_lu_dev);
1036 static struct obd_uuid cfg_uuid = { .uuid = "config_uuid" };
1041 CDEBUG(D_MGS, "Replace nids for %s in %s\n", devname, logname);
1043 ctxt = llog_get_context(mgs, LLOG_CONFIG_ORIG_CTXT);
1044 LASSERT(ctxt != NULL);
1046 if (mgs_log_is_empty(env, mgs_dev, logname)) {
1047 /* Log is empty. Nothing to replace */
1048 GOTO(out_put, rc = 0);
1051 OBD_ALLOC(backup, strlen(logname) + strlen(".bak") + 1);
1053 GOTO(out_put, rc = -ENOMEM);
1055 sprintf(backup, "%s.bak", logname);
1057 rc = llog_backup(env, mgs, ctxt, ctxt, logname, backup);
1059 /* Now erase original log file. Connections are not allowed.
1060 Backup is already saved */
1061 rc = llog_erase(env, ctxt, NULL, logname);
1064 } else if (rc != -ENOENT) {
1065 CERROR("%s: can't make backup for %s: rc = %d\n",
1066 mgs->obd_name, logname, rc);
1070 /* open local log */
1071 rc = llog_open_create(env, ctxt, &orig_llh, NULL, logname);
1073 GOTO(out_restore, rc);
1075 rc = llog_init_handle(env, orig_llh, LLOG_F_IS_PLAIN, &cfg_uuid);
1077 GOTO(out_closel, rc);
1079 /* open backup llog */
1080 rc = llog_open(env, ctxt, &backup_llh, NULL, backup,
1083 GOTO(out_closel, rc);
1085 rc = llog_init_handle(env, backup_llh, LLOG_F_IS_PLAIN, NULL);
1087 GOTO(out_close, rc);
1089 if (llog_get_size(backup_llh) <= 1)
1090 GOTO(out_close, rc = 0);
1092 OBD_ALLOC_PTR(mrul);
1094 GOTO(out_close, rc = -ENOMEM);
1095 /* devname is only needed information to replace UUID records */
1096 strncpy(mrul->target.mti_svname, devname, MTI_NAME_MAXLEN);
1097 /* parse nids later */
1098 strncpy(mrul->target.mti_params, nids, MTI_PARAM_MAXLEN);
1099 /* Copy records to this temporary llog */
1100 mrul->temp_llh = orig_llh;
1102 rc = llog_process(env, backup_llh, mgs_replace_handler,
1103 (void *)mrul, NULL);
1106 rc2 = llog_close(NULL, backup_llh);
1110 rc2 = llog_close(NULL, orig_llh);
1116 CERROR("%s: llog should be restored: rc = %d\n",
1118 rc2 = llog_backup(env, mgs, ctxt, ctxt, backup,
1121 CERROR("%s: can't restore backup %s: rc = %d\n",
1122 mgs->obd_name, logname, rc2);
1126 OBD_FREE(backup, strlen(backup) + 1);
1129 llog_ctxt_put(ctxt);
1132 CERROR("%s: failed to replace nids in log %s: rc = %d\n",
1133 mgs->obd_name, logname, rc);
1139 * Parse device name and get file system name and/or device index
1141 * \param[in] devname device name (ex. lustre-MDT0000)
1142 * \param[out] fsname file system name(optional)
1143 * \param[out] index device index(optional)
1147 static int mgs_parse_devname(char *devname, char *fsname, __u32 *index)
1152 /* Extract fsname */
1154 rc = server_name2fsname(devname, fsname, NULL);
1156 CDEBUG(D_MGS, "Device name %s without fsname\n",
1163 rc = server_name2index(devname, index, NULL);
1165 CDEBUG(D_MGS, "Device name %s with wrong index\n",
1174 static int only_mgs_is_running(struct obd_device *mgs_obd)
1176 /* TDB: Is global variable with devices count exists? */
1177 int num_devices = get_devices_count();
1178 /* osd, MGS and MGC + self_export
1179 (wc -l /proc/fs/lustre/devices <= 2) && (num_exports <= 2) */
1180 return (num_devices <= 3) && (mgs_obd->obd_num_exports <= 2);
1183 static int name_create_mdt(char **logname, char *fsname, int i)
1187 sprintf(mdt_index, "-MDT%04x", i);
1188 return name_create(logname, fsname, mdt_index);
1192 * Replace nids for \a device to \a nids values
1194 * \param obd MGS obd device
1195 * \param devname nids need to be replaced for this device
1196 * (ex. lustre-OST0000)
1197 * \param nids nids list (ex. nid1,nid2,nid3)
1201 int mgs_replace_nids(const struct lu_env *env,
1202 struct mgs_device *mgs,
1203 char *devname, char *nids)
1205 /* Assume fsname is part of device name */
1206 char fsname[MTI_NAME_MAXLEN];
1213 struct obd_device *mgs_obd = mgs->mgs_obd;
1216 /* We can only change NIDs if no other nodes are connected */
1217 spin_lock(&mgs_obd->obd_dev_lock);
1218 conn_state = mgs_obd->obd_no_conn;
1219 mgs_obd->obd_no_conn = 1;
1220 spin_unlock(&mgs_obd->obd_dev_lock);
1222 /* We can not change nids if not only MGS is started */
1223 if (!only_mgs_is_running(mgs_obd)) {
1224 CERROR("Only MGS is allowed to be started\n");
1225 GOTO(out, rc = -EINPROGRESS);
1228 /* Get fsname and index*/
1229 rc = mgs_parse_devname(devname, fsname, &index);
1233 rc = mgs_find_or_make_fsdb(env, mgs, fsname, &fsdb);
1235 CERROR("%s: can't find fsdb: rc = %d\n", fsname, rc);
1239 /* Process client llogs */
1240 name_create(&logname, fsname, "-client");
1241 rc = mgs_replace_nids_log(env, mgs_obd, fsdb, logname, devname, nids);
1242 name_destroy(&logname);
1244 CERROR("%s: error while replacing NIDs for %s: rc = %d\n",
1245 fsname, devname, rc);
1249 /* Process MDT llogs */
1250 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
1251 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
1253 name_create_mdt(&logname, fsname, i);
1254 rc = mgs_replace_nids_log(env, mgs_obd, fsdb, logname, devname, nids);
1255 name_destroy(&logname);
1261 spin_lock(&mgs_obd->obd_dev_lock);
1262 mgs_obd->obd_no_conn = conn_state;
1263 spin_unlock(&mgs_obd->obd_dev_lock);
1268 static int record_lov_setup(const struct lu_env *env, struct llog_handle *llh,
1269 char *devname, struct lov_desc *desc)
1271 struct mgs_thread_info *mgi = mgs_env_info(env);
1272 struct lustre_cfg *lcfg;
1275 lustre_cfg_bufs_reset(&mgi->mgi_bufs, devname);
1276 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, desc, sizeof(*desc));
1277 lcfg = lustre_cfg_new(LCFG_SETUP, &mgi->mgi_bufs);
1280 rc = record_lcfg(env, llh, lcfg);
1282 lustre_cfg_free(lcfg);
1286 static int record_lmv_setup(const struct lu_env *env, struct llog_handle *llh,
1287 char *devname, struct lmv_desc *desc)
1289 struct mgs_thread_info *mgi = mgs_env_info(env);
1290 struct lustre_cfg *lcfg;
1293 lustre_cfg_bufs_reset(&mgi->mgi_bufs, devname);
1294 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, desc, sizeof(*desc));
1295 lcfg = lustre_cfg_new(LCFG_SETUP, &mgi->mgi_bufs);
1297 rc = record_lcfg(env, llh, lcfg);
1299 lustre_cfg_free(lcfg);
1303 static inline int record_mdc_add(const struct lu_env *env,
1304 struct llog_handle *llh,
1305 char *logname, char *mdcuuid,
1306 char *mdtuuid, char *index,
1309 return record_base(env,llh,logname,0,LCFG_ADD_MDC,
1310 mdtuuid,index,gen,mdcuuid);
1313 static inline int record_lov_add(const struct lu_env *env,
1314 struct llog_handle *llh,
1315 char *lov_name, char *ost_uuid,
1316 char *index, char *gen)
1318 return record_base(env,llh,lov_name,0,LCFG_LOV_ADD_OBD,
1319 ost_uuid, index, gen, 0);
1322 static inline int record_mount_opt(const struct lu_env *env,
1323 struct llog_handle *llh,
1324 char *profile, char *lov_name,
1327 return record_base(env,llh,NULL,0,LCFG_MOUNTOPT,
1328 profile,lov_name,mdc_name,0);
1331 static int record_marker(const struct lu_env *env,
1332 struct llog_handle *llh,
1333 struct fs_db *fsdb, __u32 flags,
1334 char *tgtname, char *comment)
1336 struct mgs_thread_info *mgi = mgs_env_info(env);
1337 struct lustre_cfg *lcfg;
1341 if (flags & CM_START)
1343 mgi->mgi_marker.cm_step = fsdb->fsdb_gen;
1344 mgi->mgi_marker.cm_flags = flags;
1345 mgi->mgi_marker.cm_vers = LUSTRE_VERSION_CODE;
1346 cplen = strlcpy(mgi->mgi_marker.cm_tgtname, tgtname,
1347 sizeof(mgi->mgi_marker.cm_tgtname));
1348 if (cplen >= sizeof(mgi->mgi_marker.cm_tgtname))
1350 cplen = strlcpy(mgi->mgi_marker.cm_comment, comment,
1351 sizeof(mgi->mgi_marker.cm_comment));
1352 if (cplen >= sizeof(mgi->mgi_marker.cm_comment))
1354 mgi->mgi_marker.cm_createtime = cfs_time_current_sec();
1355 mgi->mgi_marker.cm_canceltime = 0;
1356 lustre_cfg_bufs_reset(&mgi->mgi_bufs, NULL);
1357 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, &mgi->mgi_marker,
1358 sizeof(mgi->mgi_marker));
1359 lcfg = lustre_cfg_new(LCFG_MARKER, &mgi->mgi_bufs);
1362 rc = record_lcfg(env, llh, lcfg);
1364 lustre_cfg_free(lcfg);
1368 static int record_start_log(const struct lu_env *env, struct mgs_device *mgs,
1369 struct llog_handle **llh, char *name)
1371 static struct obd_uuid cfg_uuid = { .uuid = "config_uuid" };
1372 struct llog_ctxt *ctxt;
1376 GOTO(out, rc = -EBUSY);
1378 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
1380 GOTO(out, rc = -ENODEV);
1381 LASSERT(ctxt->loc_obd == mgs->mgs_obd);
1383 rc = llog_open_create(env, ctxt, llh, NULL, name);
1386 rc = llog_init_handle(env, *llh, LLOG_F_IS_PLAIN, &cfg_uuid);
1388 llog_close(env, *llh);
1390 llog_ctxt_put(ctxt);
1393 CERROR("%s: can't start log %s: rc = %d\n",
1394 mgs->mgs_obd->obd_name, name, rc);
1400 static int record_end_log(const struct lu_env *env, struct llog_handle **llh)
1404 rc = llog_close(env, *llh);
1410 /******************** config "macros" *********************/
1412 /* write an lcfg directly into a log (with markers) */
1413 static int mgs_write_log_direct(const struct lu_env *env,
1414 struct mgs_device *mgs, struct fs_db *fsdb,
1415 char *logname, struct lustre_cfg *lcfg,
1416 char *devname, char *comment)
1418 struct llog_handle *llh = NULL;
1425 rc = record_start_log(env, mgs, &llh, logname);
1429 /* FIXME These should be a single journal transaction */
1430 rc = record_marker(env, llh, fsdb, CM_START, devname, comment);
1433 rc = record_lcfg(env, llh, lcfg);
1436 rc = record_marker(env, llh, fsdb, CM_END, devname, comment);
1440 record_end_log(env, &llh);
1444 /* write the lcfg in all logs for the given fs */
1445 int mgs_write_log_direct_all(const struct lu_env *env,
1446 struct mgs_device *mgs,
1448 struct mgs_target_info *mti,
1449 struct lustre_cfg *lcfg,
1450 char *devname, char *comment,
1454 struct mgs_direntry *dirent, *n;
1455 char *fsname = mti->mti_fsname;
1457 int rc = 0, len = strlen(fsname);
1460 /* We need to set params for any future logs
1461 as well. FIXME Append this file to every new log.
1462 Actually, we should store as params (text), not llogs. Or
1464 rc = name_create(&logname, fsname, "-params");
1467 if (mgs_log_is_empty(env, mgs, logname)) {
1468 struct llog_handle *llh = NULL;
1469 rc = record_start_log(env, mgs, &llh, logname);
1471 record_end_log(env, &llh);
1473 name_destroy(&logname);
1477 /* Find all the logs in the CONFIGS directory */
1478 rc = class_dentry_readdir(env, mgs, &list);
1482 /* Could use fsdb index maps instead of directory listing */
1483 cfs_list_for_each_entry_safe(dirent, n, &list, list) {
1484 cfs_list_del(&dirent->list);
1485 /* don't write to sptlrpc rule log */
1486 if (strstr(dirent->name, "-sptlrpc") != NULL)
1489 /* caller wants write server logs only */
1490 if (server_only && strstr(dirent->name, "-client") != NULL)
1493 if (strncmp(fsname, dirent->name, len) == 0) {
1494 CDEBUG(D_MGS, "Changing log %s\n", dirent->name);
1495 /* Erase any old settings of this same parameter */
1496 rc = mgs_modify(env, mgs, fsdb, mti, dirent->name,
1497 devname, comment, CM_SKIP);
1499 CERROR("%s: Can't modify llog %s: rc = %d\n",
1500 mgs->mgs_obd->obd_name, dirent->name,rc);
1501 /* Write the new one */
1503 rc = mgs_write_log_direct(env, mgs, fsdb,
1508 CERROR("%s: writing log %s: rc = %d\n",
1509 mgs->mgs_obd->obd_name,
1514 mgs_direntry_free(dirent);
1520 static int mgs_write_log_osp_to_mdt(const struct lu_env *env,
1521 struct mgs_device *mgs,
1523 struct mgs_target_info *mti,
1524 int index, char *logname);
1525 static int mgs_write_log_osc_to_lov(const struct lu_env *env,
1526 struct mgs_device *mgs,
1528 struct mgs_target_info *mti,
1529 char *logname, char *suffix, char *lovname,
1530 enum lustre_sec_part sec_part, int flags);
1531 static int name_create_mdt_and_lov(char **logname, char **lovname,
1532 struct fs_db *fsdb, int i);
1534 static int add_param(char *params, char *key, char *val)
1536 char *start = params + strlen(params);
1537 char *end = params + sizeof(((struct mgs_target_info *)0)->mti_params);
1541 keylen = strlen(key);
1542 if (start + 1 + keylen + strlen(val) >= end) {
1543 CERROR("params are too long: %s %s%s\n",
1544 params, key != NULL ? key : "", val);
1548 sprintf(start, " %s%s", key != NULL ? key : "", val);
1553 * Walk through client config log record and convert the related records
1556 static int mgs_steal_client_llog_handler(const struct lu_env *env,
1557 struct llog_handle *llh,
1558 struct llog_rec_hdr *rec, void *data)
1560 struct mgs_device *mgs;
1561 struct obd_device *obd;
1562 struct mgs_target_info *mti, *tmti;
1564 int cfg_len = rec->lrh_len;
1565 char *cfg_buf = (char*) (rec + 1);
1566 struct lustre_cfg *lcfg;
1568 struct llog_handle *mdt_llh = NULL;
1569 static int got_an_osc_or_mdc = 0;
1570 /* 0: not found any osc/mdc;
1574 static int last_step = -1;
1579 mti = ((struct temp_comp*)data)->comp_mti;
1580 tmti = ((struct temp_comp*)data)->comp_tmti;
1581 fsdb = ((struct temp_comp*)data)->comp_fsdb;
1582 obd = ((struct temp_comp *)data)->comp_obd;
1583 mgs = lu2mgs_dev(obd->obd_lu_dev);
1586 if (rec->lrh_type != OBD_CFG_REC) {
1587 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
1591 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
1593 CERROR("Insane cfg\n");
1597 lcfg = (struct lustre_cfg *)cfg_buf;
1599 if (lcfg->lcfg_command == LCFG_MARKER) {
1600 struct cfg_marker *marker;
1601 marker = lustre_cfg_buf(lcfg, 1);
1602 if (!strncmp(marker->cm_comment, "add osc", 7) &&
1603 (marker->cm_flags & CM_START) &&
1604 !(marker->cm_flags & CM_SKIP)) {
1605 got_an_osc_or_mdc = 1;
1606 cplen = strlcpy(tmti->mti_svname, marker->cm_tgtname,
1607 sizeof(tmti->mti_svname));
1608 if (cplen >= sizeof(tmti->mti_svname))
1610 rc = record_start_log(env, mgs, &mdt_llh,
1614 rc = record_marker(env, mdt_llh, fsdb, CM_START,
1615 mti->mti_svname, "add osc(copied)");
1616 record_end_log(env, &mdt_llh);
1617 last_step = marker->cm_step;
1620 if (!strncmp(marker->cm_comment, "add osc", 7) &&
1621 (marker->cm_flags & CM_END) &&
1622 !(marker->cm_flags & CM_SKIP)) {
1623 LASSERT(last_step == marker->cm_step);
1625 got_an_osc_or_mdc = 0;
1626 memset(tmti, 0, sizeof(*tmti));
1627 rc = record_start_log(env, mgs, &mdt_llh,
1631 rc = record_marker(env, mdt_llh, fsdb, CM_END,
1632 mti->mti_svname, "add osc(copied)");
1633 record_end_log(env, &mdt_llh);
1636 if (!strncmp(marker->cm_comment, "add mdc", 7) &&
1637 (marker->cm_flags & CM_START) &&
1638 !(marker->cm_flags & CM_SKIP)) {
1639 got_an_osc_or_mdc = 2;
1640 last_step = marker->cm_step;
1641 memcpy(tmti->mti_svname, marker->cm_tgtname,
1642 strlen(marker->cm_tgtname));
1646 if (!strncmp(marker->cm_comment, "add mdc", 7) &&
1647 (marker->cm_flags & CM_END) &&
1648 !(marker->cm_flags & CM_SKIP)) {
1649 LASSERT(last_step == marker->cm_step);
1651 got_an_osc_or_mdc = 0;
1652 memset(tmti, 0, sizeof(*tmti));
1657 if (got_an_osc_or_mdc == 0 || last_step < 0)
1660 if (lcfg->lcfg_command == LCFG_ADD_UUID) {
1661 uint64_t nodenid = lcfg->lcfg_nid;
1663 if (strlen(tmti->mti_uuid) == 0) {
1664 /* target uuid not set, this config record is before
1665 * LCFG_SETUP, this nid is one of target node nid.
1667 tmti->mti_nids[tmti->mti_nid_count] = nodenid;
1668 tmti->mti_nid_count++;
1670 /* failover node nid */
1671 rc = add_param(tmti->mti_params, PARAM_FAILNODE,
1672 libcfs_nid2str(nodenid));
1678 if (lcfg->lcfg_command == LCFG_SETUP) {
1681 target = lustre_cfg_string(lcfg, 1);
1682 memcpy(tmti->mti_uuid, target, strlen(target));
1686 /* ignore client side sptlrpc_conf_log */
1687 if (lcfg->lcfg_command == LCFG_SPTLRPC_CONF)
1690 if (lcfg->lcfg_command == LCFG_ADD_MDC) {
1693 if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1)
1696 memcpy(tmti->mti_fsname, mti->mti_fsname,
1697 strlen(mti->mti_fsname));
1698 tmti->mti_stripe_index = index;
1700 rc = mgs_write_log_osp_to_mdt(env, mgs, fsdb, tmti,
1701 mti->mti_stripe_index,
1703 memset(tmti, 0, sizeof(*tmti));
1707 if (lcfg->lcfg_command == LCFG_LOV_ADD_OBD) {
1710 char *logname, *lovname;
1712 rc = name_create_mdt_and_lov(&logname, &lovname, fsdb,
1713 mti->mti_stripe_index);
1716 sprintf(mdt_index, "-MDT%04x", mti->mti_stripe_index);
1718 if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1) {
1719 name_destroy(&logname);
1720 name_destroy(&lovname);
1724 tmti->mti_stripe_index = index;
1725 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, tmti, logname,
1728 name_destroy(&logname);
1729 name_destroy(&lovname);
1735 /* fsdb->fsdb_mutex is already held in mgs_write_log_target*/
1736 /* stealed from mgs_get_fsdb_from_llog*/
1737 static int mgs_steal_llog_for_mdt_from_client(const struct lu_env *env,
1738 struct mgs_device *mgs,
1740 struct temp_comp* comp)
1742 struct llog_handle *loghandle;
1743 struct mgs_target_info *tmti;
1744 struct llog_ctxt *ctxt;
1749 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
1750 LASSERT(ctxt != NULL);
1752 OBD_ALLOC_PTR(tmti);
1754 GOTO(out_ctxt, rc = -ENOMEM);
1756 comp->comp_tmti = tmti;
1757 comp->comp_obd = mgs->mgs_obd;
1759 rc = llog_open(env, ctxt, &loghandle, NULL, client_name,
1767 rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL);
1769 GOTO(out_close, rc);
1771 rc = llog_process_or_fork(env, loghandle, mgs_steal_client_llog_handler,
1772 (void *)comp, NULL, false);
1773 CDEBUG(D_MGS, "steal llog re = %d\n", rc);
1775 llog_close(env, loghandle);
1779 llog_ctxt_put(ctxt);
1783 /* lmv is the second thing for client logs */
1784 /* copied from mgs_write_log_lov. Please refer to that. */
1785 static int mgs_write_log_lmv(const struct lu_env *env,
1786 struct mgs_device *mgs,
1788 struct mgs_target_info *mti,
1789 char *logname, char *lmvname)
1791 struct llog_handle *llh = NULL;
1792 struct lmv_desc *lmvdesc;
1797 CDEBUG(D_MGS, "Writing lmv(%s) log for %s\n", lmvname,logname);
1799 OBD_ALLOC_PTR(lmvdesc);
1800 if (lmvdesc == NULL)
1802 lmvdesc->ld_active_tgt_count = 0;
1803 lmvdesc->ld_tgt_count = 0;
1804 sprintf((char*)lmvdesc->ld_uuid.uuid, "%s_UUID", lmvname);
1805 uuid = (char *)lmvdesc->ld_uuid.uuid;
1807 rc = record_start_log(env, mgs, &llh, logname);
1810 rc = record_marker(env, llh, fsdb, CM_START, lmvname, "lmv setup");
1813 rc = record_attach(env, llh, lmvname, "lmv", uuid);
1816 rc = record_lmv_setup(env, llh, lmvname, lmvdesc);
1819 rc = record_marker(env, llh, fsdb, CM_END, lmvname, "lmv setup");
1823 record_end_log(env, &llh);
1825 OBD_FREE_PTR(lmvdesc);
1829 /* lov is the first thing in the mdt and client logs */
1830 static int mgs_write_log_lov(const struct lu_env *env, struct mgs_device *mgs,
1831 struct fs_db *fsdb, struct mgs_target_info *mti,
1832 char *logname, char *lovname)
1834 struct llog_handle *llh = NULL;
1835 struct lov_desc *lovdesc;
1840 CDEBUG(D_MGS, "Writing lov(%s) log for %s\n", lovname, logname);
1843 #01 L attach 0:lov_mdsA 1:lov 2:71ccb_lov_mdsA_19f961a9e1
1844 #02 L lov_setup 0:lov_mdsA 1:(struct lov_desc)
1845 uuid=lov1_UUID, stripe count=1, size=1048576, offset=0, pattern=0
1848 /* FIXME just make lov_setup accept empty desc (put uuid in buf 2) */
1849 OBD_ALLOC_PTR(lovdesc);
1850 if (lovdesc == NULL)
1852 lovdesc->ld_magic = LOV_DESC_MAGIC;
1853 lovdesc->ld_tgt_count = 0;
1854 /* Defaults. Can be changed later by lcfg config_param */
1855 lovdesc->ld_default_stripe_count = 1;
1856 lovdesc->ld_pattern = LOV_PATTERN_RAID0;
1857 lovdesc->ld_default_stripe_size = 1024 * 1024;
1858 lovdesc->ld_default_stripe_offset = -1;
1859 lovdesc->ld_qos_maxage = QOS_DEFAULT_MAXAGE;
1860 sprintf((char*)lovdesc->ld_uuid.uuid, "%s_UUID", lovname);
1861 /* can these be the same? */
1862 uuid = (char *)lovdesc->ld_uuid.uuid;
1864 /* This should always be the first entry in a log.
1865 rc = mgs_clear_log(obd, logname); */
1866 rc = record_start_log(env, mgs, &llh, logname);
1869 /* FIXME these should be a single journal transaction */
1870 rc = record_marker(env, llh, fsdb, CM_START, lovname, "lov setup");
1873 rc = record_attach(env, llh, lovname, "lov", uuid);
1876 rc = record_lov_setup(env, llh, lovname, lovdesc);
1879 rc = record_marker(env, llh, fsdb, CM_END, lovname, "lov setup");
1884 record_end_log(env, &llh);
1886 OBD_FREE_PTR(lovdesc);
1890 /* add failnids to open log */
1891 static int mgs_write_log_failnids(const struct lu_env *env,
1892 struct mgs_target_info *mti,
1893 struct llog_handle *llh,
1896 char *failnodeuuid = NULL;
1897 char *ptr = mti->mti_params;
1902 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) nal=90 0: 1:uml1_UUID
1903 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
1904 #05 L setup 0:OSC_uml1_ost1_mdsA 1:ost1_UUID 2:uml1_UUID
1905 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) nal=90 0: 1:uml2_UUID
1906 #0x L add_uuid nid=2@elan(0x1000000000002) nal=90 0: 1:uml2_UUID
1907 #07 L add_conn 0:OSC_uml1_ost1_mdsA 1:uml2_UUID
1910 /* Pull failnid info out of params string */
1911 while (class_find_param(ptr, PARAM_FAILNODE, &ptr) == 0) {
1912 while (class_parse_nid(ptr, &nid, &ptr) == 0) {
1913 if (failnodeuuid == NULL) {
1914 /* We don't know the failover node name,
1915 so just use the first nid as the uuid */
1916 rc = name_create(&failnodeuuid,
1917 libcfs_nid2str(nid), "");
1921 CDEBUG(D_MGS, "add nid %s for failover uuid %s, "
1922 "client %s\n", libcfs_nid2str(nid),
1923 failnodeuuid, cliname);
1924 rc = record_add_uuid(env, llh, nid, failnodeuuid);
1927 rc = record_add_conn(env, llh, cliname, failnodeuuid);
1930 name_destroy(&failnodeuuid);
1934 static int mgs_write_log_mdc_to_lmv(const struct lu_env *env,
1935 struct mgs_device *mgs,
1937 struct mgs_target_info *mti,
1938 char *logname, char *lmvname)
1940 struct llog_handle *llh = NULL;
1941 char *mdcname = NULL;
1942 char *nodeuuid = NULL;
1943 char *mdcuuid = NULL;
1944 char *lmvuuid = NULL;
1949 if (mgs_log_is_empty(env, mgs, logname)) {
1950 CERROR("log is empty! Logical error\n");
1954 CDEBUG(D_MGS, "adding mdc for %s to log %s:lmv(%s)\n",
1955 mti->mti_svname, logname, lmvname);
1957 rc = name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
1960 rc = name_create(&mdcname, mti->mti_svname, "-mdc");
1963 rc = name_create(&mdcuuid, mdcname, "_UUID");
1966 rc = name_create(&lmvuuid, lmvname, "_UUID");
1970 rc = record_start_log(env, mgs, &llh, logname);
1973 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
1977 for (i = 0; i < mti->mti_nid_count; i++) {
1978 CDEBUG(D_MGS, "add nid %s for mdt\n",
1979 libcfs_nid2str(mti->mti_nids[i]));
1981 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
1986 rc = record_attach(env, llh, mdcname, LUSTRE_MDC_NAME, lmvuuid);
1989 rc = record_setup(env, llh, mdcname, mti->mti_uuid, nodeuuid, 0, 0);
1992 rc = mgs_write_log_failnids(env, mti, llh, mdcname);
1995 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
1996 rc = record_mdc_add(env, llh, lmvname, mdcuuid, mti->mti_uuid,
2000 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname,
2005 record_end_log(env, &llh);
2007 name_destroy(&lmvuuid);
2008 name_destroy(&mdcuuid);
2009 name_destroy(&mdcname);
2010 name_destroy(&nodeuuid);
2014 static inline int name_create_lov(char **lovname, char *mdtname,
2015 struct fs_db *fsdb, int index)
2018 if (index == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2019 return name_create(lovname, fsdb->fsdb_name, "-mdtlov");
2021 return name_create(lovname, mdtname, "-mdtlov");
2024 static int name_create_mdt_and_lov(char **logname, char **lovname,
2025 struct fs_db *fsdb, int i)
2029 rc = name_create_mdt(logname, fsdb->fsdb_name, i);
2033 if (i == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2034 rc = name_create(lovname, fsdb->fsdb_name, "-mdtlov");
2036 rc = name_create(lovname, *logname, "-mdtlov");
2038 name_destroy(logname);
2044 static inline int name_create_mdt_osc(char **oscname, char *ostname,
2045 struct fs_db *fsdb, int i)
2049 if (i == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2050 sprintf(suffix, "-osc");
2052 sprintf(suffix, "-osc-MDT%04x", i);
2053 return name_create(oscname, ostname, suffix);
2056 /* add new mdc to already existent MDS */
2057 static int mgs_write_log_osp_to_mdt(const struct lu_env *env,
2058 struct mgs_device *mgs,
2060 struct mgs_target_info *mti,
2061 int mdt_index, char *logname)
2063 struct llog_handle *llh = NULL;
2064 char *nodeuuid = NULL;
2065 char *ospname = NULL;
2066 char *lovuuid = NULL;
2067 char *mdtuuid = NULL;
2068 char *svname = NULL;
2069 char *mdtname = NULL;
2070 char *lovname = NULL;
2075 if (mgs_log_is_empty(env, mgs, mti->mti_svname)) {
2076 CERROR("log is empty! Logical error\n");
2080 CDEBUG(D_MGS, "adding osp index %d to %s\n", mti->mti_stripe_index,
2083 rc = name_create_mdt(&mdtname, fsdb->fsdb_name, mti->mti_stripe_index);
2087 rc = name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
2089 GOTO(out_destory, rc);
2091 rc = name_create(&svname, mdtname, "-osp");
2093 GOTO(out_destory, rc);
2095 sprintf(index_str, "-MDT%04x", mdt_index);
2096 rc = name_create(&ospname, svname, index_str);
2098 GOTO(out_destory, rc);
2100 rc = name_create_lov(&lovname, logname, fsdb, mdt_index);
2102 GOTO(out_destory, rc);
2104 rc = name_create(&lovuuid, lovname, "_UUID");
2106 GOTO(out_destory, rc);
2108 rc = name_create(&mdtuuid, mdtname, "_UUID");
2110 GOTO(out_destory, rc);
2112 rc = record_start_log(env, mgs, &llh, logname);
2114 GOTO(out_destory, rc);
2116 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
2119 GOTO(out_destory, rc);
2121 for (i = 0; i < mti->mti_nid_count; i++) {
2122 CDEBUG(D_MGS, "add nid %s for mdt\n",
2123 libcfs_nid2str(mti->mti_nids[i]));
2124 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
2129 rc = record_attach(env, llh, ospname, LUSTRE_OSP_NAME, lovuuid);
2133 rc = record_setup(env, llh, ospname, mti->mti_uuid, nodeuuid,
2138 rc = mgs_write_log_failnids(env, mti, llh, ospname);
2142 /* Add mdc(osp) to lod */
2143 snprintf(index_str, sizeof(mti->mti_stripe_index), "%d",
2144 mti->mti_stripe_index);
2145 rc = record_base(env, llh, lovname, 0, LCFG_ADD_MDC, mti->mti_uuid,
2146 index_str, "1", NULL);
2150 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname, "add osp");
2155 record_end_log(env, &llh);
2158 name_destroy(&mdtuuid);
2159 name_destroy(&lovuuid);
2160 name_destroy(&lovname);
2161 name_destroy(&ospname);
2162 name_destroy(&svname);
2163 name_destroy(&nodeuuid);
2164 name_destroy(&mdtname);
2168 static int mgs_write_log_mdt0(const struct lu_env *env,
2169 struct mgs_device *mgs,
2171 struct mgs_target_info *mti)
2173 char *log = mti->mti_svname;
2174 struct llog_handle *llh = NULL;
2175 char *uuid, *lovname;
2177 char *ptr = mti->mti_params;
2178 int rc = 0, failout = 0;
2181 OBD_ALLOC(uuid, sizeof(struct obd_uuid));
2185 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
2186 failout = (strncmp(ptr, "failout", 7) == 0);
2188 rc = name_create(&lovname, log, "-mdtlov");
2191 if (mgs_log_is_empty(env, mgs, log)) {
2192 rc = mgs_write_log_lov(env, mgs, fsdb, mti, log, lovname);
2197 sprintf(mdt_index, "%d", mti->mti_stripe_index);
2199 rc = record_start_log(env, mgs, &llh, log);
2203 /* add MDT itself */
2205 /* FIXME this whole fn should be a single journal transaction */
2206 sprintf(uuid, "%s_UUID", log);
2207 rc = record_marker(env, llh, fsdb, CM_START, log, "add mdt");
2210 rc = record_attach(env, llh, log, LUSTRE_MDT_NAME, uuid);
2213 rc = record_mount_opt(env, llh, log, lovname, NULL);
2216 rc = record_setup(env, llh, log, uuid, mdt_index, lovname,
2217 failout ? "n" : "f");
2220 rc = record_marker(env, llh, fsdb, CM_END, log, "add mdt");
2224 record_end_log(env, &llh);
2226 name_destroy(&lovname);
2228 OBD_FREE(uuid, sizeof(struct obd_uuid));
2232 /* envelope method for all layers log */
2233 static int mgs_write_log_mdt(const struct lu_env *env,
2234 struct mgs_device *mgs,
2236 struct mgs_target_info *mti)
2238 struct mgs_thread_info *mgi = mgs_env_info(env);
2239 struct llog_handle *llh = NULL;
2244 CDEBUG(D_MGS, "writing new mdt %s\n", mti->mti_svname);
2246 if (mti->mti_uuid[0] == '\0') {
2247 /* Make up our own uuid */
2248 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
2249 "%s_UUID", mti->mti_svname);
2253 rc = mgs_write_log_mdt0(env, mgs, fsdb, mti);
2256 /* Append the mdt info to the client log */
2257 rc = name_create(&cliname, mti->mti_fsname, "-client");
2261 if (mgs_log_is_empty(env, mgs, cliname)) {
2262 /* Start client log */
2263 rc = mgs_write_log_lov(env, mgs, fsdb, mti, cliname,
2267 rc = mgs_write_log_lmv(env, mgs, fsdb, mti, cliname,
2274 #09 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
2275 #10 L attach 0:MDC_uml1_mdsA_MNT_client 1:mdc 2:1d834_MNT_client_03f
2276 #11 L setup 0:MDC_uml1_mdsA_MNT_client 1:mdsA_UUID 2:uml1_UUID
2277 #12 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
2278 #13 L add_conn 0:MDC_uml1_mdsA_MNT_client 1:uml2_UUID
2279 #14 L mount_option 0: 1:client 2:lov1 3:MDC_uml1_mdsA_MNT_client
2282 /* copy client info about lov/lmv */
2283 mgi->mgi_comp.comp_mti = mti;
2284 mgi->mgi_comp.comp_fsdb = fsdb;
2286 rc = mgs_steal_llog_for_mdt_from_client(env, mgs, cliname,
2290 rc = mgs_write_log_mdc_to_lmv(env, mgs, fsdb, mti, cliname,
2296 rc = record_start_log(env, mgs, &llh, cliname);
2300 rc = record_marker(env, llh, fsdb, CM_START, cliname,
2304 rc = record_mount_opt(env, llh, cliname, fsdb->fsdb_clilov,
2308 rc = record_marker(env, llh, fsdb, CM_END, cliname,
2314 /* for_all_existing_mdt except current one */
2315 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2316 if (i != mti->mti_stripe_index &&
2317 test_bit(i, fsdb->fsdb_mdt_index_map)) {
2320 rc = name_create_mdt(&logname, fsdb->fsdb_name, i);
2324 rc = mgs_write_log_osp_to_mdt(env, mgs, fsdb, mti,
2326 name_destroy(&logname);
2332 record_end_log(env, &llh);
2334 name_destroy(&cliname);
2338 /* Add the ost info to the client/mdt lov */
2339 static int mgs_write_log_osc_to_lov(const struct lu_env *env,
2340 struct mgs_device *mgs, struct fs_db *fsdb,
2341 struct mgs_target_info *mti,
2342 char *logname, char *suffix, char *lovname,
2343 enum lustre_sec_part sec_part, int flags)
2345 struct llog_handle *llh = NULL;
2346 char *nodeuuid = NULL;
2347 char *oscname = NULL;
2348 char *oscuuid = NULL;
2349 char *lovuuid = NULL;
2350 char *svname = NULL;
2355 CDEBUG(D_INFO, "adding osc for %s to log %s\n",
2356 mti->mti_svname, logname);
2358 if (mgs_log_is_empty(env, mgs, logname)) {
2359 CERROR("log is empty! Logical error\n");
2363 rc = name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
2366 rc = name_create(&svname, mti->mti_svname, "-osc");
2370 /* for the system upgraded from old 1.8, keep using the old osc naming
2371 * style for mdt, see name_create_mdt_osc(). LU-1257 */
2372 if (test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2373 rc = name_create(&oscname, svname, "");
2375 rc = name_create(&oscname, svname, suffix);
2379 rc = name_create(&oscuuid, oscname, "_UUID");
2382 rc = name_create(&lovuuid, lovname, "_UUID");
2388 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
2390 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
2391 #04 L attach 0:OSC_uml1_ost1_MNT_client 1:osc 2:89070_lov1_a41dff51a
2392 #05 L setup 0:OSC_uml1_ost1_MNT_client 1:ost1_UUID 2:uml1_UUID
2394 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
2395 #07 L add_conn 0:OSC_uml1_ost1_MNT_client 1:uml2_UUID
2396 #08 L lov_modify_tgts add 0:lov1 1:ost1_UUID 2(index):0 3(gen):1
2399 rc = record_start_log(env, mgs, &llh, logname);
2403 /* FIXME these should be a single journal transaction */
2404 rc = record_marker(env, llh, fsdb, CM_START | flags, mti->mti_svname,
2409 /* NB: don't change record order, because upon MDT steal OSC config
2410 * from client, it treats all nids before LCFG_SETUP as target nids
2411 * (multiple interfaces), while nids after as failover node nids.
2412 * See mgs_steal_client_llog_handler() LCFG_ADD_UUID.
2414 for (i = 0; i < mti->mti_nid_count; i++) {
2415 CDEBUG(D_MGS, "add nid %s\n", libcfs_nid2str(mti->mti_nids[i]));
2416 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
2420 rc = record_attach(env, llh, oscname, LUSTRE_OSC_NAME, lovuuid);
2423 rc = record_setup(env, llh, oscname, mti->mti_uuid, nodeuuid, 0, 0);
2426 rc = mgs_write_log_failnids(env, mti, llh, oscname);
2430 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
2432 rc = record_lov_add(env, llh, lovname, mti->mti_uuid, index, "1");
2435 rc = record_marker(env, llh, fsdb, CM_END | flags, mti->mti_svname,
2440 record_end_log(env, &llh);
2442 name_destroy(&lovuuid);
2443 name_destroy(&oscuuid);
2444 name_destroy(&oscname);
2445 name_destroy(&svname);
2446 name_destroy(&nodeuuid);
2450 static int mgs_write_log_ost(const struct lu_env *env,
2451 struct mgs_device *mgs, struct fs_db *fsdb,
2452 struct mgs_target_info *mti)
2454 struct llog_handle *llh = NULL;
2455 char *logname, *lovname;
2456 char *ptr = mti->mti_params;
2457 int rc, flags = 0, failout = 0, i;
2460 CDEBUG(D_MGS, "writing new ost %s\n", mti->mti_svname);
2462 /* The ost startup log */
2464 /* If the ost log already exists, that means that someone reformatted
2465 the ost and it called target_add again. */
2466 if (!mgs_log_is_empty(env, mgs, mti->mti_svname)) {
2467 LCONSOLE_ERROR_MSG(0x141, "The config log for %s already "
2468 "exists, yet the server claims it never "
2469 "registered. It may have been reformatted, "
2470 "or the index changed. writeconf the MDT to "
2471 "regenerate all logs.\n", mti->mti_svname);
2476 attach obdfilter ost1 ost1_UUID
2477 setup /dev/loop2 ldiskfs f|n errors=remount-ro,user_xattr
2479 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
2480 failout = (strncmp(ptr, "failout", 7) == 0);
2481 rc = record_start_log(env, mgs, &llh, mti->mti_svname);
2484 /* FIXME these should be a single journal transaction */
2485 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,"add ost");
2488 if (*mti->mti_uuid == '\0')
2489 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
2490 "%s_UUID", mti->mti_svname);
2491 rc = record_attach(env, llh, mti->mti_svname,
2492 "obdfilter"/*LUSTRE_OST_NAME*/, mti->mti_uuid);
2495 rc = record_setup(env, llh, mti->mti_svname,
2496 "dev"/*ignored*/, "type"/*ignored*/,
2497 failout ? "n" : "f", 0/*options*/);
2500 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname, "add ost");
2504 record_end_log(env, &llh);
2507 /* We also have to update the other logs where this osc is part of
2510 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
2511 /* If we're upgrading, the old mdt log already has our
2512 entry. Let's do a fake one for fun. */
2513 /* Note that we can't add any new failnids, since we don't
2514 know the old osc names. */
2515 flags = CM_SKIP | CM_UPGRADE146;
2517 } else if ((mti->mti_flags & LDD_F_UPDATE) != LDD_F_UPDATE) {
2518 /* If the update flag isn't set, don't update client/mdt
2521 LCONSOLE_WARN("Client log for %s was not updated; writeconf "
2522 "the MDT first to regenerate it.\n",
2526 /* Add ost to all MDT lov defs */
2527 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
2528 if (test_bit(i, fsdb->fsdb_mdt_index_map)) {
2531 rc = name_create_mdt_and_lov(&logname, &lovname, fsdb,
2535 sprintf(mdt_index, "-MDT%04x", i);
2536 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, mti,
2538 lovname, LUSTRE_SP_MDT,
2540 name_destroy(&logname);
2541 name_destroy(&lovname);
2547 /* Append ost info to the client log */
2548 rc = name_create(&logname, mti->mti_fsname, "-client");
2551 if (mgs_log_is_empty(env, mgs, logname)) {
2552 /* Start client log */
2553 rc = mgs_write_log_lov(env, mgs, fsdb, mti, logname,
2557 rc = mgs_write_log_lmv(env, mgs, fsdb, mti, logname,
2562 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, mti, logname, "",
2563 fsdb->fsdb_clilov, LUSTRE_SP_CLI, 0);
2565 name_destroy(&logname);
2569 static __inline__ int mgs_param_empty(char *ptr)
2573 if ((tmp = strchr(ptr, '=')) && (*(++tmp) == '\0'))
2578 static int mgs_write_log_failnid_internal(const struct lu_env *env,
2579 struct mgs_device *mgs,
2581 struct mgs_target_info *mti,
2582 char *logname, char *cliname)
2585 struct llog_handle *llh = NULL;
2587 if (mgs_param_empty(mti->mti_params)) {
2588 /* Remove _all_ failnids */
2589 rc = mgs_modify(env, mgs, fsdb, mti, logname,
2590 mti->mti_svname, "add failnid", CM_SKIP);
2591 return rc < 0 ? rc : 0;
2594 /* Otherwise failover nids are additive */
2595 rc = record_start_log(env, mgs, &llh, logname);
2598 /* FIXME this should be a single journal transaction */
2599 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
2603 rc = mgs_write_log_failnids(env, mti, llh, cliname);
2606 rc = record_marker(env, llh, fsdb, CM_END,
2607 mti->mti_svname, "add failnid");
2609 record_end_log(env, &llh);
2614 /* Add additional failnids to an existing log.
2615 The mdc/osc must have been added to logs first */
2616 /* tcp nids must be in dotted-quad ascii -
2617 we can't resolve hostnames from the kernel. */
2618 static int mgs_write_log_add_failnid(const struct lu_env *env,
2619 struct mgs_device *mgs,
2621 struct mgs_target_info *mti)
2623 char *logname, *cliname;
2627 /* FIXME we currently can't erase the failnids
2628 * given when a target first registers, since they aren't part of
2629 * an "add uuid" stanza */
2631 /* Verify that we know about this target */
2632 if (mgs_log_is_empty(env, mgs, mti->mti_svname)) {
2633 LCONSOLE_ERROR_MSG(0x142, "The target %s has not registered "
2634 "yet. It must be started before failnids "
2635 "can be added.\n", mti->mti_svname);
2639 /* Create mdc/osc client name (e.g. lustre-OST0001-osc) */
2640 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
2641 rc = name_create(&cliname, mti->mti_svname, "-mdc");
2642 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2643 rc = name_create(&cliname, mti->mti_svname, "-osc");
2649 /* Add failover nids to the client log */
2650 rc = name_create(&logname, mti->mti_fsname, "-client");
2652 name_destroy(&cliname);
2655 rc = mgs_write_log_failnid_internal(env, mgs, fsdb,mti,logname,cliname);
2656 name_destroy(&logname);
2657 name_destroy(&cliname);
2661 if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2662 /* Add OST failover nids to the MDT logs as well */
2665 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2666 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
2668 rc = name_create_mdt(&logname, mti->mti_fsname, i);
2671 rc = name_create_mdt_osc(&cliname, mti->mti_svname,
2674 name_destroy(&logname);
2677 rc = mgs_write_log_failnid_internal(env, mgs, fsdb,
2680 name_destroy(&cliname);
2681 name_destroy(&logname);
2690 static int mgs_wlp_lcfg(const struct lu_env *env,
2691 struct mgs_device *mgs, struct fs_db *fsdb,
2692 struct mgs_target_info *mti,
2693 char *logname, struct lustre_cfg_bufs *bufs,
2694 char *tgtname, char *ptr)
2696 char comment[MTI_NAME_MAXLEN];
2698 struct lustre_cfg *lcfg;
2701 /* Erase any old settings of this same parameter */
2702 memcpy(comment, ptr, MTI_NAME_MAXLEN);
2703 comment[MTI_NAME_MAXLEN - 1] = 0;
2704 /* But don't try to match the value. */
2705 if ((tmp = strchr(comment, '=')))
2707 /* FIXME we should skip settings that are the same as old values */
2708 rc = mgs_modify(env, mgs, fsdb, mti, logname, tgtname, comment,CM_SKIP);
2711 del = mgs_param_empty(ptr);
2713 LCONSOLE_INFO("%sing parameter %s.%s in log %s\n", del ? "Disabl" : rc ?
2714 "Sett" : "Modify", tgtname, comment, logname);
2718 lustre_cfg_bufs_reset(bufs, tgtname);
2719 lustre_cfg_bufs_set_string(bufs, 1, ptr);
2720 if (mti->mti_flags & LDD_F_PARAM2)
2721 lustre_cfg_bufs_set_string(bufs, 2, LCTL_UPCALL);
2723 lcfg = lustre_cfg_new((mti->mti_flags & LDD_F_PARAM2) ?
2724 LCFG_SET_PARAM : LCFG_PARAM, bufs);
2728 rc = mgs_write_log_direct(env, mgs, fsdb, logname,lcfg,tgtname,comment);
2729 lustre_cfg_free(lcfg);
2733 static int mgs_write_log_param2(const struct lu_env *env,
2734 struct mgs_device *mgs,
2736 struct mgs_target_info *mti, char *ptr)
2738 struct lustre_cfg_bufs bufs;
2742 CDEBUG(D_MGS, "next param '%s'\n", ptr);
2743 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, PARAMS_FILENAME, &bufs,
2744 mti->mti_svname, ptr);
2749 /* write global variable settings into log */
2750 static int mgs_write_log_sys(const struct lu_env *env,
2751 struct mgs_device *mgs, struct fs_db *fsdb,
2752 struct mgs_target_info *mti, char *sys, char *ptr)
2754 struct mgs_thread_info *mgi = mgs_env_info(env);
2755 struct lustre_cfg *lcfg;
2757 int rc, cmd, convert = 1;
2759 if (class_match_param(ptr, PARAM_TIMEOUT, &tmp) == 0) {
2760 cmd = LCFG_SET_TIMEOUT;
2761 } else if (class_match_param(ptr, PARAM_LDLM_TIMEOUT, &tmp) == 0) {
2762 cmd = LCFG_SET_LDLM_TIMEOUT;
2763 /* Check for known params here so we can return error to lctl */
2764 } else if ((class_match_param(ptr, PARAM_AT_MIN, &tmp) == 0) ||
2765 (class_match_param(ptr, PARAM_AT_MAX, &tmp) == 0) ||
2766 (class_match_param(ptr, PARAM_AT_EXTRA, &tmp) == 0) ||
2767 (class_match_param(ptr, PARAM_AT_EARLY_MARGIN, &tmp) == 0) ||
2768 (class_match_param(ptr, PARAM_AT_HISTORY, &tmp) == 0)) {
2770 } else if (class_match_param(ptr, PARAM_JOBID_VAR, &tmp) == 0) {
2771 convert = 0; /* Don't convert string value to integer */
2777 if (mgs_param_empty(ptr))
2778 CDEBUG(D_MGS, "global '%s' removed\n", sys);
2780 CDEBUG(D_MGS, "global '%s' val=%s\n", sys, tmp);
2782 lustre_cfg_bufs_reset(&mgi->mgi_bufs, NULL);
2783 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, sys);
2784 if (!convert && *tmp != '\0')
2785 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 2, tmp);
2786 lcfg = lustre_cfg_new(cmd, &mgi->mgi_bufs);
2787 lcfg->lcfg_num = convert ? simple_strtoul(tmp, NULL, 0) : 0;
2788 /* truncate the comment to the parameter name */
2792 /* modify all servers and clients */
2793 rc = mgs_write_log_direct_all(env, mgs, fsdb, mti,
2794 *tmp == '\0' ? NULL : lcfg,
2795 mti->mti_fsname, sys, 0);
2796 if (rc == 0 && *tmp != '\0') {
2798 case LCFG_SET_TIMEOUT:
2799 if (!obd_timeout_set || lcfg->lcfg_num > obd_timeout)
2800 class_process_config(lcfg);
2802 case LCFG_SET_LDLM_TIMEOUT:
2803 if (!ldlm_timeout_set || lcfg->lcfg_num > ldlm_timeout)
2804 class_process_config(lcfg);
2811 lustre_cfg_free(lcfg);
2815 /* write quota settings into log */
2816 static int mgs_write_log_quota(const struct lu_env *env, struct mgs_device *mgs,
2817 struct fs_db *fsdb, struct mgs_target_info *mti,
2818 char *quota, char *ptr)
2820 struct mgs_thread_info *mgi = mgs_env_info(env);
2821 struct lustre_cfg *lcfg;
2824 int rc, cmd = LCFG_PARAM;
2826 /* support only 'meta' and 'data' pools so far */
2827 if (class_match_param(ptr, QUOTA_METAPOOL_NAME, &tmp) != 0 &&
2828 class_match_param(ptr, QUOTA_DATAPOOL_NAME, &tmp) != 0) {
2829 CERROR("parameter quota.%s isn't supported (only quota.mdt "
2830 "& quota.ost are)\n", ptr);
2835 CDEBUG(D_MGS, "global '%s' removed\n", quota);
2837 CDEBUG(D_MGS, "global '%s'\n", quota);
2839 if (strchr(tmp, 'u') == NULL && strchr(tmp, 'g') == NULL &&
2840 strcmp(tmp, "none") != 0) {
2841 CERROR("enable option(%s) isn't supported\n", tmp);
2846 lustre_cfg_bufs_reset(&mgi->mgi_bufs, mti->mti_fsname);
2847 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, quota);
2848 lcfg = lustre_cfg_new(cmd, &mgi->mgi_bufs);
2849 /* truncate the comment to the parameter name */
2854 /* XXX we duplicated quota enable information in all server
2855 * config logs, it should be moved to a separate config
2856 * log once we cleanup the config log for global param. */
2857 /* modify all servers */
2858 rc = mgs_write_log_direct_all(env, mgs, fsdb, mti,
2859 *tmp == '\0' ? NULL : lcfg,
2860 mti->mti_fsname, quota, 1);
2862 lustre_cfg_free(lcfg);
2863 return rc < 0 ? rc : 0;
2866 static int mgs_srpc_set_param_disk(const struct lu_env *env,
2867 struct mgs_device *mgs,
2869 struct mgs_target_info *mti,
2872 struct mgs_thread_info *mgi = mgs_env_info(env);
2873 struct llog_handle *llh = NULL;
2875 char *comment, *ptr;
2876 struct lustre_cfg *lcfg;
2881 ptr = strchr(param, '=');
2885 OBD_ALLOC(comment, len + 1);
2886 if (comment == NULL)
2888 strncpy(comment, param, len);
2889 comment[len] = '\0';
2892 lustre_cfg_bufs_reset(&mgi->mgi_bufs, mti->mti_svname);
2893 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, param);
2894 lcfg = lustre_cfg_new(LCFG_SPTLRPC_CONF, &mgi->mgi_bufs);
2896 GOTO(out_comment, rc = -ENOMEM);
2898 /* construct log name */
2899 rc = name_create(&logname, mti->mti_fsname, "-sptlrpc");
2903 if (mgs_log_is_empty(env, mgs, logname)) {
2904 rc = record_start_log(env, mgs, &llh, logname);
2907 record_end_log(env, &llh);
2910 /* obsolete old one */
2911 rc = mgs_modify(env, mgs, fsdb, mti, logname, mti->mti_svname,
2915 /* write the new one */
2916 rc = mgs_write_log_direct(env, mgs, fsdb, logname, lcfg,
2917 mti->mti_svname, comment);
2919 CERROR("err %d writing log %s\n", rc, logname);
2921 name_destroy(&logname);
2923 lustre_cfg_free(lcfg);
2925 OBD_FREE(comment, len + 1);
2929 static int mgs_srpc_set_param_udesc_mem(struct fs_db *fsdb,
2934 /* disable the adjustable udesc parameter for now, i.e. use default
2935 * setting that client always ship udesc to MDT if possible. to enable
2936 * it simply remove the following line */
2939 ptr = strchr(param, '=');
2944 if (strcmp(param, PARAM_SRPC_UDESC))
2947 if (strcmp(ptr, "yes") == 0) {
2948 set_bit(FSDB_UDESC, &fsdb->fsdb_flags);
2949 CWARN("Enable user descriptor shipping from client to MDT\n");
2950 } else if (strcmp(ptr, "no") == 0) {
2951 clear_bit(FSDB_UDESC, &fsdb->fsdb_flags);
2952 CWARN("Disable user descriptor shipping from client to MDT\n");
2960 CERROR("Invalid param: %s\n", param);
2964 static int mgs_srpc_set_param_mem(struct fs_db *fsdb,
2968 struct sptlrpc_rule rule;
2969 struct sptlrpc_rule_set *rset;
2973 if (strncmp(param, PARAM_SRPC, sizeof(PARAM_SRPC) - 1) != 0) {
2974 CERROR("Invalid sptlrpc parameter: %s\n", param);
2978 if (strncmp(param, PARAM_SRPC_UDESC,
2979 sizeof(PARAM_SRPC_UDESC) - 1) == 0) {
2980 RETURN(mgs_srpc_set_param_udesc_mem(fsdb, param));
2983 if (strncmp(param, PARAM_SRPC_FLVR, sizeof(PARAM_SRPC_FLVR) - 1) != 0) {
2984 CERROR("Invalid sptlrpc flavor parameter: %s\n", param);
2988 param += sizeof(PARAM_SRPC_FLVR) - 1;
2990 rc = sptlrpc_parse_rule(param, &rule);
2994 /* mgs rules implies must be mgc->mgs */
2995 if (test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
2996 if ((rule.sr_from != LUSTRE_SP_MGC &&
2997 rule.sr_from != LUSTRE_SP_ANY) ||
2998 (rule.sr_to != LUSTRE_SP_MGS &&
2999 rule.sr_to != LUSTRE_SP_ANY))
3003 /* preapre room for this coming rule. svcname format should be:
3004 * - fsname: general rule
3005 * - fsname-tgtname: target-specific rule
3007 if (strchr(svname, '-')) {
3008 struct mgs_tgt_srpc_conf *tgtconf;
3011 for (tgtconf = fsdb->fsdb_srpc_tgt; tgtconf != NULL;
3012 tgtconf = tgtconf->mtsc_next) {
3013 if (!strcmp(tgtconf->mtsc_tgt, svname)) {
3022 OBD_ALLOC_PTR(tgtconf);
3023 if (tgtconf == NULL)
3026 name_len = strlen(svname);
3028 OBD_ALLOC(tgtconf->mtsc_tgt, name_len + 1);
3029 if (tgtconf->mtsc_tgt == NULL) {
3030 OBD_FREE_PTR(tgtconf);
3033 memcpy(tgtconf->mtsc_tgt, svname, name_len);
3035 tgtconf->mtsc_next = fsdb->fsdb_srpc_tgt;
3036 fsdb->fsdb_srpc_tgt = tgtconf;
3039 rset = &tgtconf->mtsc_rset;
3041 rset = &fsdb->fsdb_srpc_gen;
3044 rc = sptlrpc_rule_set_merge(rset, &rule);
3049 static int mgs_srpc_set_param(const struct lu_env *env,
3050 struct mgs_device *mgs,
3052 struct mgs_target_info *mti,
3062 /* keep a copy of original param, which could be destroied
3064 copy_size = strlen(param) + 1;
3065 OBD_ALLOC(copy, copy_size);
3068 memcpy(copy, param, copy_size);
3070 rc = mgs_srpc_set_param_mem(fsdb, mti->mti_svname, param);
3074 /* previous steps guaranteed the syntax is correct */
3075 rc = mgs_srpc_set_param_disk(env, mgs, fsdb, mti, copy);
3079 if (test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
3081 * for mgs rules, make them effective immediately.
3083 LASSERT(fsdb->fsdb_srpc_tgt == NULL);
3084 sptlrpc_target_update_exp_flavor(mgs->mgs_obd,
3085 &fsdb->fsdb_srpc_gen);
3089 OBD_FREE(copy, copy_size);
3093 struct mgs_srpc_read_data {
3094 struct fs_db *msrd_fsdb;
3098 static int mgs_srpc_read_handler(const struct lu_env *env,
3099 struct llog_handle *llh,
3100 struct llog_rec_hdr *rec, void *data)
3102 struct mgs_srpc_read_data *msrd = data;
3103 struct cfg_marker *marker;
3104 struct lustre_cfg *lcfg = REC_DATA(rec);
3105 char *svname, *param;
3109 if (rec->lrh_type != OBD_CFG_REC) {
3110 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
3114 cfg_len = rec->lrh_len - sizeof(struct llog_rec_hdr) -
3115 sizeof(struct llog_rec_tail);
3117 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
3119 CERROR("Insane cfg\n");
3123 if (lcfg->lcfg_command == LCFG_MARKER) {
3124 marker = lustre_cfg_buf(lcfg, 1);
3126 if (marker->cm_flags & CM_START &&
3127 marker->cm_flags & CM_SKIP)
3128 msrd->msrd_skip = 1;
3129 if (marker->cm_flags & CM_END)
3130 msrd->msrd_skip = 0;
3135 if (msrd->msrd_skip)
3138 if (lcfg->lcfg_command != LCFG_SPTLRPC_CONF) {
3139 CERROR("invalid command (%x)\n", lcfg->lcfg_command);
3143 svname = lustre_cfg_string(lcfg, 0);
3144 if (svname == NULL) {
3145 CERROR("svname is empty\n");
3149 param = lustre_cfg_string(lcfg, 1);
3150 if (param == NULL) {
3151 CERROR("param is empty\n");
3155 rc = mgs_srpc_set_param_mem(msrd->msrd_fsdb, svname, param);
3157 CERROR("read sptlrpc record error (%d): %s\n", rc, param);
3162 int mgs_get_fsdb_srpc_from_llog(const struct lu_env *env,
3163 struct mgs_device *mgs,
3166 struct llog_handle *llh = NULL;
3167 struct llog_ctxt *ctxt;
3169 struct mgs_srpc_read_data msrd;
3173 /* construct log name */
3174 rc = name_create(&logname, fsdb->fsdb_name, "-sptlrpc");
3178 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
3179 LASSERT(ctxt != NULL);
3181 if (mgs_log_is_empty(env, mgs, logname))
3184 rc = llog_open(env, ctxt, &llh, NULL, logname,
3192 rc = llog_init_handle(env, llh, LLOG_F_IS_PLAIN, NULL);
3194 GOTO(out_close, rc);
3196 if (llog_get_size(llh) <= 1)
3197 GOTO(out_close, rc = 0);
3199 msrd.msrd_fsdb = fsdb;
3202 rc = llog_process(env, llh, mgs_srpc_read_handler, (void *)&msrd,
3206 llog_close(env, llh);
3208 llog_ctxt_put(ctxt);
3209 name_destroy(&logname);
3212 CERROR("failed to read sptlrpc config database: %d\n", rc);
3216 /* Permanent settings of all parameters by writing into the appropriate
3217 * configuration logs.
3218 * A parameter with null value ("<param>='\0'") means to erase it out of
3221 static int mgs_write_log_param(const struct lu_env *env,
3222 struct mgs_device *mgs, struct fs_db *fsdb,
3223 struct mgs_target_info *mti, char *ptr)
3225 struct mgs_thread_info *mgi = mgs_env_info(env);
3228 int rc = 0, rc2 = 0;
3231 /* For various parameter settings, we have to figure out which logs
3232 care about them (e.g. both mdt and client for lov settings) */
3233 CDEBUG(D_MGS, "next param '%s'\n", ptr);
3235 /* The params are stored in MOUNT_DATA_FILE and modified via
3236 tunefs.lustre, or set using lctl conf_param */
3238 /* Processed in lustre_start_mgc */
3239 if (class_match_param(ptr, PARAM_MGSNODE, NULL) == 0)
3242 /* Processed in ost/mdt */
3243 if (class_match_param(ptr, PARAM_NETWORK, NULL) == 0)
3246 /* Processed in mgs_write_log_ost */
3247 if (class_match_param(ptr, PARAM_FAILMODE, NULL) == 0) {
3248 if (mti->mti_flags & LDD_F_PARAM) {
3249 LCONSOLE_ERROR_MSG(0x169, "%s can only be "
3250 "changed with tunefs.lustre"
3251 "and --writeconf\n", ptr);
3257 if (class_match_param(ptr, PARAM_SRPC, NULL) == 0) {
3258 rc = mgs_srpc_set_param(env, mgs, fsdb, mti, ptr);
3262 if (class_match_param(ptr, PARAM_FAILNODE, NULL) == 0) {
3263 /* Add a failover nidlist */
3265 /* We already processed failovers params for new
3266 targets in mgs_write_log_target */
3267 if (mti->mti_flags & LDD_F_PARAM) {
3268 CDEBUG(D_MGS, "Adding failnode\n");
3269 rc = mgs_write_log_add_failnid(env, mgs, fsdb, mti);
3274 if (class_match_param(ptr, PARAM_SYS, &tmp) == 0) {
3275 rc = mgs_write_log_sys(env, mgs, fsdb, mti, ptr, tmp);
3279 if (class_match_param(ptr, PARAM_QUOTA, &tmp) == 0) {
3280 rc = mgs_write_log_quota(env, mgs, fsdb, mti, ptr, tmp);
3284 if (class_match_param(ptr, PARAM_OSC""PARAM_ACTIVE, &tmp) == 0) {
3285 /* active=0 means off, anything else means on */
3286 int flag = (*tmp == '0') ? CM_EXCLUDE : 0;
3289 if (!(mti->mti_flags & LDD_F_SV_TYPE_OST)) {
3290 LCONSOLE_ERROR_MSG(0x144, "%s: Only OSCs can "
3291 "be (de)activated.\n",
3293 GOTO(end, rc = -EINVAL);
3295 LCONSOLE_WARN("Permanently %sactivating %s\n",
3296 flag ? "de": "re", mti->mti_svname);
3298 rc = name_create(&logname, mti->mti_fsname, "-client");
3301 rc = mgs_modify(env, mgs, fsdb, mti, logname,
3302 mti->mti_svname, "add osc", flag);
3303 name_destroy(&logname);
3307 /* Add to all MDT logs for CMD */
3308 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3309 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
3311 rc = name_create_mdt(&logname, mti->mti_fsname, i);
3314 rc = mgs_modify(env, mgs, fsdb, mti, logname,
3315 mti->mti_svname, "add osc", flag);
3316 name_destroy(&logname);
3322 LCONSOLE_ERROR_MSG(0x145, "Couldn't find %s in"
3323 "log (%d). No permanent "
3324 "changes were made to the "
3326 mti->mti_svname, rc);
3327 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags))
3328 LCONSOLE_ERROR_MSG(0x146, "This may be"
3333 "update the logs.\n");
3336 /* Fall through to osc proc for deactivating live OSC
3337 on running MDT / clients. */
3339 /* Below here, let obd's XXX_process_config methods handle it */
3341 /* All lov. in proc */
3342 if (class_match_param(ptr, PARAM_LOV, NULL) == 0) {
3345 CDEBUG(D_MGS, "lov param %s\n", ptr);
3346 if (!(mti->mti_flags & LDD_F_SV_TYPE_MDT)) {
3347 LCONSOLE_ERROR_MSG(0x147, "LOV params must be "
3348 "set on the MDT, not %s. "
3355 if (mgs_log_is_empty(env, mgs, mti->mti_svname))
3356 GOTO(end, rc = -ENODEV);
3358 rc = name_create_mdt_and_lov(&logname, &mdtlovname, fsdb,
3359 mti->mti_stripe_index);
3362 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, mti->mti_svname,
3363 &mgi->mgi_bufs, mdtlovname, ptr);
3364 name_destroy(&logname);
3365 name_destroy(&mdtlovname);
3370 rc = name_create(&logname, mti->mti_fsname, "-client");
3373 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname, &mgi->mgi_bufs,
3374 fsdb->fsdb_clilov, ptr);
3375 name_destroy(&logname);
3379 /* All osc., mdc., llite. params in proc */
3380 if ((class_match_param(ptr, PARAM_OSC, NULL) == 0) ||
3381 (class_match_param(ptr, PARAM_MDC, NULL) == 0) ||
3382 (class_match_param(ptr, PARAM_LLITE, NULL) == 0)) {
3385 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
3386 LCONSOLE_ERROR_MSG(0x148, "Upgraded client logs for %s"
3387 " cannot be modified. Consider"
3388 " updating the configuration with"
3391 GOTO(end, rc = -EINVAL);
3393 if (memcmp(ptr, PARAM_LLITE, strlen(PARAM_LLITE)) == 0) {
3394 rc = name_create(&cname, mti->mti_fsname, "-client");
3395 /* Add the client type to match the obdname in
3396 class_config_llog_handler */
3397 } else if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
3398 rc = name_create(&cname, mti->mti_svname, "-mdc");
3399 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
3400 rc = name_create(&cname, mti->mti_svname, "-osc");
3402 GOTO(end, rc = -EINVAL);
3407 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
3410 rc = name_create(&logname, mti->mti_fsname, "-client");
3412 name_destroy(&cname);
3415 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname, &mgi->mgi_bufs,
3418 /* osc params affect the MDT as well */
3419 if (!rc && (mti->mti_flags & LDD_F_SV_TYPE_OST)) {
3422 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
3423 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
3425 name_destroy(&cname);
3426 rc = name_create_mdt_osc(&cname, mti->mti_svname,
3428 name_destroy(&logname);
3431 rc = name_create_mdt(&logname,
3432 mti->mti_fsname, i);
3435 if (!mgs_log_is_empty(env, mgs, logname)) {
3436 rc = mgs_wlp_lcfg(env, mgs, fsdb,
3445 name_destroy(&logname);
3446 name_destroy(&cname);
3450 /* All mdt. params in proc */
3451 if (class_match_param(ptr, PARAM_MDT, NULL) == 0) {
3455 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
3456 if (strncmp(mti->mti_svname, mti->mti_fsname,
3457 MTI_NAME_MAXLEN) == 0)
3458 /* device is unspecified completely? */
3459 rc = LDD_F_SV_TYPE_MDT | LDD_F_SV_ALL;
3461 rc = server_name2index(mti->mti_svname, &idx, NULL);
3464 if ((rc & LDD_F_SV_TYPE_MDT) == 0)
3466 if (rc & LDD_F_SV_ALL) {
3467 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3469 fsdb->fsdb_mdt_index_map))
3471 rc = name_create_mdt(&logname,
3472 mti->mti_fsname, i);
3475 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti,
3476 logname, &mgi->mgi_bufs,
3478 name_destroy(&logname);
3483 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti,
3484 mti->mti_svname, &mgi->mgi_bufs,
3485 mti->mti_svname, ptr);
3492 /* All mdd., ost. params in proc */
3493 if ((class_match_param(ptr, PARAM_MDD, NULL) == 0) ||
3494 (class_match_param(ptr, PARAM_OST, NULL) == 0)) {
3495 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
3496 if (mgs_log_is_empty(env, mgs, mti->mti_svname))
3497 GOTO(end, rc = -ENODEV);
3499 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, mti->mti_svname,
3500 &mgi->mgi_bufs, mti->mti_svname, ptr);
3504 LCONSOLE_WARN("Ignoring unrecognized param '%s'\n", ptr);
3509 CERROR("err %d on param '%s'\n", rc, ptr);
3514 /* Not implementing automatic failover nid addition at this time. */
3515 int mgs_check_failnid(const struct lu_env *env, struct mgs_device *mgs,
3516 struct mgs_target_info *mti)
3523 rc = mgs_find_or_make_fsdb(obd, fsname, &fsdb);
3527 if (mgs_log_is_empty(obd, mti->mti_svname))
3528 /* should never happen */
3531 CDEBUG(D_MGS, "Checking for new failnids for %s\n", mti->mti_svname);
3533 /* FIXME We can just check mti->params to see if we're already in
3534 the failover list. Modify mti->params for rewriting back at
3535 server_register_target(). */
3537 mutex_lock(&fsdb->fsdb_mutex);
3538 rc = mgs_write_log_add_failnid(obd, fsdb, mti);
3539 mutex_unlock(&fsdb->fsdb_mutex);
3546 int mgs_write_log_target(const struct lu_env *env,
3547 struct mgs_device *mgs,
3548 struct mgs_target_info *mti,
3555 /* set/check the new target index */
3556 rc = mgs_set_index(env, mgs, mti);
3558 CERROR("Can't get index (%d)\n", rc);
3562 if (rc == EALREADY) {
3563 LCONSOLE_WARN("Found index %d for %s, updating log\n",
3564 mti->mti_stripe_index, mti->mti_svname);
3565 /* We would like to mark old log sections as invalid
3566 and add new log sections in the client and mdt logs.
3567 But if we add new sections, then live clients will
3568 get repeat setup instructions for already running
3569 osc's. So don't update the client/mdt logs. */
3570 mti->mti_flags &= ~LDD_F_UPDATE;
3574 mutex_lock(&fsdb->fsdb_mutex);
3576 if (mti->mti_flags &
3577 (LDD_F_VIRGIN | LDD_F_UPGRADE14 | LDD_F_WRITECONF)) {
3578 /* Generate a log from scratch */
3579 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
3580 rc = mgs_write_log_mdt(env, mgs, fsdb, mti);
3581 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
3582 rc = mgs_write_log_ost(env, mgs, fsdb, mti);
3584 CERROR("Unknown target type %#x, can't create log for "
3585 "%s\n", mti->mti_flags, mti->mti_svname);
3588 CERROR("Can't write logs for %s (%d)\n",
3589 mti->mti_svname, rc);
3593 /* Just update the params from tunefs in mgs_write_log_params */
3594 CDEBUG(D_MGS, "Update params for %s\n", mti->mti_svname);
3595 mti->mti_flags |= LDD_F_PARAM;
3598 /* allocate temporary buffer, where class_get_next_param will
3599 make copy of a current parameter */
3600 OBD_ALLOC(buf, strlen(mti->mti_params) + 1);
3602 GOTO(out_up, rc = -ENOMEM);
3603 params = mti->mti_params;
3604 while (params != NULL) {
3605 rc = class_get_next_param(¶ms, buf);
3608 /* there is no next parameter, that is
3613 CDEBUG(D_MGS, "remaining string: '%s', param: '%s'\n",
3615 rc = mgs_write_log_param(env, mgs, fsdb, mti, buf);
3620 OBD_FREE(buf, strlen(mti->mti_params) + 1);
3623 mutex_unlock(&fsdb->fsdb_mutex);
3627 int mgs_erase_log(const struct lu_env *env, struct mgs_device *mgs, char *name)
3629 struct llog_ctxt *ctxt;
3632 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
3634 CERROR("%s: MGS config context doesn't exist\n",
3635 mgs->mgs_obd->obd_name);
3638 rc = llog_erase(env, ctxt, NULL, name);
3639 /* llog may not exist */
3642 llog_ctxt_put(ctxt);
3646 CERROR("%s: failed to clear log %s: %d\n",
3647 mgs->mgs_obd->obd_name, name, rc);
3652 /* erase all logs for the given fs */
3653 int mgs_erase_logs(const struct lu_env *env, struct mgs_device *mgs, char *fsname)
3657 struct mgs_direntry *dirent, *n;
3658 int rc, len = strlen(fsname);
3662 /* Find all the logs in the CONFIGS directory */
3663 rc = class_dentry_readdir(env, mgs, &list);
3667 mutex_lock(&mgs->mgs_mutex);
3669 /* Delete the fs db */
3670 fsdb = mgs_find_fsdb(mgs, fsname);
3672 mgs_free_fsdb(mgs, fsdb);
3674 mutex_unlock(&mgs->mgs_mutex);
3676 cfs_list_for_each_entry_safe(dirent, n, &list, list) {
3677 cfs_list_del(&dirent->list);
3678 suffix = strrchr(dirent->name, '-');
3679 if (suffix != NULL) {
3680 if ((len == suffix - dirent->name) &&
3681 (strncmp(fsname, dirent->name, len) == 0)) {
3682 CDEBUG(D_MGS, "Removing log %s\n",
3684 mgs_erase_log(env, mgs, dirent->name);
3687 mgs_direntry_free(dirent);
3693 /* list all logs for the given fs */
3694 int mgs_list_logs(const struct lu_env *env, struct mgs_device *mgs,
3695 struct obd_ioctl_data *data)
3698 struct mgs_direntry *dirent, *n;
3704 /* Find all the logs in the CONFIGS directory */
3705 rc = class_dentry_readdir(env, mgs, &list);
3707 CERROR("%s: can't read %s dir = %d\n",
3708 mgs->mgs_obd->obd_name, MOUNT_CONFIGS_DIR, rc);
3712 out = data->ioc_bulk;
3713 remains = data->ioc_inllen1;
3714 cfs_list_for_each_entry_safe(dirent, n, &list, list) {
3715 cfs_list_del(&dirent->list);
3716 suffix = strrchr(dirent->name, '-');
3717 if (suffix != NULL) {
3718 l = snprintf(out, remains, "config log: $%s\n",
3723 mgs_direntry_free(dirent);
3730 /* from llog_swab */
3731 static void print_lustre_cfg(struct lustre_cfg *lcfg)
3736 CDEBUG(D_MGS, "lustre_cfg: %p\n", lcfg);
3737 CDEBUG(D_MGS, "\tlcfg->lcfg_version: %#x\n", lcfg->lcfg_version);
3739 CDEBUG(D_MGS, "\tlcfg->lcfg_command: %#x\n", lcfg->lcfg_command);
3740 CDEBUG(D_MGS, "\tlcfg->lcfg_num: %#x\n", lcfg->lcfg_num);
3741 CDEBUG(D_MGS, "\tlcfg->lcfg_flags: %#x\n", lcfg->lcfg_flags);
3742 CDEBUG(D_MGS, "\tlcfg->lcfg_nid: %s\n", libcfs_nid2str(lcfg->lcfg_nid));
3744 CDEBUG(D_MGS, "\tlcfg->lcfg_bufcount: %d\n", lcfg->lcfg_bufcount);
3745 if (lcfg->lcfg_bufcount < LUSTRE_CFG_MAX_BUFCOUNT)
3746 for (i = 0; i < lcfg->lcfg_bufcount; i++) {
3747 CDEBUG(D_MGS, "\tlcfg->lcfg_buflens[%d]: %d %s\n",
3748 i, lcfg->lcfg_buflens[i],
3749 lustre_cfg_string(lcfg, i));
3754 /* Set a permanent (config log) param for a target or fs
3755 * \param lcfg buf0 may contain the device (testfs-MDT0000) name
3756 * buf1 contains the single parameter
3758 int mgs_setparam(const struct lu_env *env, struct mgs_device *mgs,
3759 struct lustre_cfg *lcfg, char *fsname)
3762 struct mgs_target_info *mti;
3763 char *devname, *param;
3770 print_lustre_cfg(lcfg);
3772 /* lustre, lustre-mdtlov, lustre-client, lustre-MDT0000 */
3773 devname = lustre_cfg_string(lcfg, 0);
3774 param = lustre_cfg_string(lcfg, 1);
3776 /* Assume device name embedded in param:
3777 lustre-OST0000.osc.max_dirty_mb=32 */
3778 ptr = strchr(param, '.');
3786 LCONSOLE_ERROR_MSG(0x14d, "No target specified: %s\n", param);
3790 rc = mgs_parse_devname(devname, fsname, NULL);
3791 if (rc == 0 && !mgs_parse_devname(devname, NULL, &index)) {
3792 /* param related to llite isn't allowed to set by OST or MDT */
3793 if (rc == 0 && strncmp(param, PARAM_LLITE,
3794 sizeof(PARAM_LLITE)) == 0)
3797 /* assume devname is the fsname */
3798 memset(fsname, 0, MTI_NAME_MAXLEN);
3799 strncpy(fsname, devname, MTI_NAME_MAXLEN);
3800 fsname[MTI_NAME_MAXLEN - 1] = 0;
3802 CDEBUG(D_MGS, "setparam fs='%s' device='%s'\n", fsname, devname);
3804 rc = mgs_find_or_make_fsdb(env, mgs,
3805 lcfg->lcfg_command == LCFG_SET_PARAM ?
3806 PARAMS_FILENAME : fsname, &fsdb);
3810 if (lcfg->lcfg_command != LCFG_SET_PARAM &&
3811 !test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags) &&
3812 test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
3813 CERROR("No filesystem targets for %s. cfg_device from lctl "
3814 "is '%s'\n", fsname, devname);
3815 mgs_free_fsdb(mgs, fsdb);
3819 /* Create a fake mti to hold everything */
3822 GOTO(out, rc = -ENOMEM);
3823 if (strlcpy(mti->mti_fsname, fsname, sizeof(mti->mti_fsname))
3824 >= sizeof(mti->mti_fsname))
3825 GOTO(out, rc = -E2BIG);
3826 if (strlcpy(mti->mti_svname, devname, sizeof(mti->mti_svname))
3827 >= sizeof(mti->mti_svname))
3828 GOTO(out, rc = -E2BIG);
3829 if (strlcpy(mti->mti_params, param, sizeof(mti->mti_params))
3830 >= sizeof(mti->mti_params))
3831 GOTO(out, rc = -E2BIG);
3832 rc = server_name2index(mti->mti_svname, &mti->mti_stripe_index, &tmp);
3834 /* Not a valid server; may be only fsname */
3837 /* Strip -osc or -mdc suffix from svname */
3838 if (server_make_name(rc, mti->mti_stripe_index, mti->mti_fsname,
3840 GOTO(out, rc = -EINVAL);
3842 * Revoke lock so everyone updates. Should be alright if
3843 * someone was already reading while we were updating the logs,
3844 * so we don't really need to hold the lock while we're
3847 if (lcfg->lcfg_command == LCFG_SET_PARAM) {
3848 mti->mti_flags = rc | LDD_F_PARAM2;
3849 mutex_lock(&fsdb->fsdb_mutex);
3850 rc = mgs_write_log_param2(env, mgs, fsdb, mti, mti->mti_params);
3851 mutex_unlock(&fsdb->fsdb_mutex);
3852 mgs_revoke_lock(mgs, fsdb, CONFIG_T_PARAMS);
3854 mti->mti_flags = rc | LDD_F_PARAM;
3855 mutex_lock(&fsdb->fsdb_mutex);
3856 rc = mgs_write_log_param(env, mgs, fsdb, mti, mti->mti_params);
3857 mutex_unlock(&fsdb->fsdb_mutex);
3858 mgs_revoke_lock(mgs, fsdb, CONFIG_T_CONFIG);
3866 static int mgs_write_log_pool(const struct lu_env *env,
3867 struct mgs_device *mgs, char *logname,
3868 struct fs_db *fsdb, char *tgtname,
3869 enum lcfg_command_type cmd,
3870 char *fsname, char *poolname,
3871 char *ostname, char *comment)
3873 struct llog_handle *llh = NULL;
3876 rc = record_start_log(env, mgs, &llh, logname);
3879 rc = record_marker(env, llh, fsdb, CM_START, tgtname, comment);
3882 rc = record_base(env, llh, tgtname, 0, cmd,
3883 fsname, poolname, ostname, 0);
3886 rc = record_marker(env, llh, fsdb, CM_END, tgtname, comment);
3888 record_end_log(env, &llh);
3892 int mgs_pool_cmd(const struct lu_env *env, struct mgs_device *mgs,
3893 enum lcfg_command_type cmd, char *fsname,
3894 char *poolname, char *ostname)
3899 char *label = NULL, *canceled_label = NULL;
3901 struct mgs_target_info *mti = NULL;
3905 rc = mgs_find_or_make_fsdb(env, mgs, fsname, &fsdb);
3907 CERROR("Can't get db for %s\n", fsname);
3910 if (test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
3911 CERROR("%s is not defined\n", fsname);
3912 mgs_free_fsdb(mgs, fsdb);
3916 label_sz = 10 + strlen(fsname) + strlen(poolname);
3918 /* check if ostname match fsname */
3919 if (ostname != NULL) {
3922 ptr = strrchr(ostname, '-');
3923 if ((ptr == NULL) ||
3924 (strncmp(fsname, ostname, ptr-ostname) != 0))
3926 label_sz += strlen(ostname);
3929 OBD_ALLOC(label, label_sz);
3936 "new %s.%s", fsname, poolname);
3940 "add %s.%s.%s", fsname, poolname, ostname);
3943 OBD_ALLOC(canceled_label, label_sz);
3944 if (canceled_label == NULL)
3945 GOTO(out_label, rc = -ENOMEM);
3947 "rem %s.%s.%s", fsname, poolname, ostname);
3948 sprintf(canceled_label,
3949 "add %s.%s.%s", fsname, poolname, ostname);
3952 OBD_ALLOC(canceled_label, label_sz);
3953 if (canceled_label == NULL)
3954 GOTO(out_label, rc = -ENOMEM);
3956 "del %s.%s", fsname, poolname);
3957 sprintf(canceled_label,
3958 "new %s.%s", fsname, poolname);
3964 if (canceled_label != NULL) {
3967 GOTO(out_cancel, rc = -ENOMEM);
3970 mutex_lock(&fsdb->fsdb_mutex);
3971 /* write pool def to all MDT logs */
3972 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3973 if (test_bit(i, fsdb->fsdb_mdt_index_map)) {
3974 rc = name_create_mdt_and_lov(&logname, &lovname,
3977 mutex_unlock(&fsdb->fsdb_mutex);
3980 if (canceled_label != NULL) {
3981 strcpy(mti->mti_svname, "lov pool");
3982 rc = mgs_modify(env, mgs, fsdb, mti, logname,
3983 lovname, canceled_label,
3988 rc = mgs_write_log_pool(env, mgs, logname,
3992 name_destroy(&logname);
3993 name_destroy(&lovname);
3995 mutex_unlock(&fsdb->fsdb_mutex);
4001 rc = name_create(&logname, fsname, "-client");
4003 mutex_unlock(&fsdb->fsdb_mutex);
4006 if (canceled_label != NULL) {
4007 rc = mgs_modify(env, mgs, fsdb, mti, logname,
4008 fsdb->fsdb_clilov, canceled_label, CM_SKIP);
4010 mutex_unlock(&fsdb->fsdb_mutex);
4011 name_destroy(&logname);
4016 rc = mgs_write_log_pool(env, mgs, logname, fsdb, fsdb->fsdb_clilov,
4017 cmd, fsname, poolname, ostname, label);
4018 mutex_unlock(&fsdb->fsdb_mutex);
4019 name_destroy(&logname);
4020 /* request for update */
4021 mgs_revoke_lock(mgs, fsdb, CONFIG_T_CONFIG);
4028 if (canceled_label != NULL)
4029 OBD_FREE(canceled_label, label_sz);
4031 OBD_FREE(label, label_sz);