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 */
1214 ptr = strrchr(devname, '-');
1218 CDEBUG(D_MGS, "Device name %s without fsname\n",
1222 memset(fsname, 0, MTI_NAME_MAXLEN);
1223 strncpy(fsname, devname, ptr - devname);
1224 fsname[MTI_NAME_MAXLEN - 1] = 0;
1228 if (server_name2index(ptr, index, NULL) < 0) {
1229 CDEBUG(D_MGS, "Device name with wrong index\n");
1237 static int only_mgs_is_running(struct obd_device *mgs_obd)
1239 /* TDB: Is global variable with devices count exists? */
1240 int num_devices = get_devices_count();
1241 /* osd, MGS and MGC + self_export
1242 (wc -l /proc/fs/lustre/devices <= 2) && (num_exports <= 2) */
1243 return (num_devices <= 3) && (mgs_obd->obd_num_exports <= 2);
1246 static int name_create_mdt(char **logname, char *fsname, int i)
1250 sprintf(mdt_index, "-MDT%04x", i);
1251 return name_create(logname, fsname, mdt_index);
1255 * Replace nids for \a device to \a nids values
1257 * \param obd MGS obd device
1258 * \param devname nids need to be replaced for this device
1259 * (ex. lustre-OST0000)
1260 * \param nids nids list (ex. nid1,nid2,nid3)
1264 int mgs_replace_nids(const struct lu_env *env,
1265 struct mgs_device *mgs,
1266 char *devname, char *nids)
1268 /* Assume fsname is part of device name */
1269 char fsname[MTI_NAME_MAXLEN];
1276 struct obd_device *mgs_obd = mgs->mgs_obd;
1279 /* We can only change NIDs if no other nodes are connected */
1280 spin_lock(&mgs_obd->obd_dev_lock);
1281 conn_state = mgs_obd->obd_no_conn;
1282 mgs_obd->obd_no_conn = 1;
1283 spin_unlock(&mgs_obd->obd_dev_lock);
1285 /* We can not change nids if not only MGS is started */
1286 if (!only_mgs_is_running(mgs_obd)) {
1287 CERROR("Only MGS is allowed to be started\n");
1288 GOTO(out, rc = -EINPROGRESS);
1291 /* Get fsname and index*/
1292 rc = mgs_parse_devname(devname, fsname, &index);
1296 rc = mgs_find_or_make_fsdb(env, mgs, fsname, &fsdb);
1298 CERROR("%s: can't find fsdb: rc = %d\n", fsname, rc);
1302 /* Process client llogs */
1303 name_create(&logname, fsname, "-client");
1304 rc = mgs_replace_nids_log(env, mgs_obd, fsdb, logname, devname, nids);
1305 name_destroy(&logname);
1307 CERROR("%s: error while replacing NIDs for %s: rc = %d\n",
1308 fsname, devname, rc);
1312 /* Process MDT llogs */
1313 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
1314 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
1316 name_create_mdt(&logname, fsname, i);
1317 rc = mgs_replace_nids_log(env, mgs_obd, fsdb, logname, devname, nids);
1318 name_destroy(&logname);
1324 spin_lock(&mgs_obd->obd_dev_lock);
1325 mgs_obd->obd_no_conn = conn_state;
1326 spin_unlock(&mgs_obd->obd_dev_lock);
1331 static int record_lov_setup(const struct lu_env *env, struct llog_handle *llh,
1332 char *devname, struct lov_desc *desc)
1334 struct mgs_thread_info *mgi = mgs_env_info(env);
1335 struct lustre_cfg *lcfg;
1338 lustre_cfg_bufs_reset(&mgi->mgi_bufs, devname);
1339 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, desc, sizeof(*desc));
1340 lcfg = lustre_cfg_new(LCFG_SETUP, &mgi->mgi_bufs);
1343 rc = record_lcfg(env, llh, lcfg);
1345 lustre_cfg_free(lcfg);
1349 static int record_lmv_setup(const struct lu_env *env, struct llog_handle *llh,
1350 char *devname, struct lmv_desc *desc)
1352 struct mgs_thread_info *mgi = mgs_env_info(env);
1353 struct lustre_cfg *lcfg;
1356 lustre_cfg_bufs_reset(&mgi->mgi_bufs, devname);
1357 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, desc, sizeof(*desc));
1358 lcfg = lustre_cfg_new(LCFG_SETUP, &mgi->mgi_bufs);
1360 rc = record_lcfg(env, llh, lcfg);
1362 lustre_cfg_free(lcfg);
1366 static inline int record_mdc_add(const struct lu_env *env,
1367 struct llog_handle *llh,
1368 char *logname, char *mdcuuid,
1369 char *mdtuuid, char *index,
1372 return record_base(env,llh,logname,0,LCFG_ADD_MDC,
1373 mdtuuid,index,gen,mdcuuid);
1376 static inline int record_lov_add(const struct lu_env *env,
1377 struct llog_handle *llh,
1378 char *lov_name, char *ost_uuid,
1379 char *index, char *gen)
1381 return record_base(env,llh,lov_name,0,LCFG_LOV_ADD_OBD,
1382 ost_uuid, index, gen, 0);
1385 static inline int record_mount_opt(const struct lu_env *env,
1386 struct llog_handle *llh,
1387 char *profile, char *lov_name,
1390 return record_base(env,llh,NULL,0,LCFG_MOUNTOPT,
1391 profile,lov_name,mdc_name,0);
1394 static int record_marker(const struct lu_env *env,
1395 struct llog_handle *llh,
1396 struct fs_db *fsdb, __u32 flags,
1397 char *tgtname, char *comment)
1399 struct mgs_thread_info *mgi = mgs_env_info(env);
1400 struct lustre_cfg *lcfg;
1404 if (flags & CM_START)
1406 mgi->mgi_marker.cm_step = fsdb->fsdb_gen;
1407 mgi->mgi_marker.cm_flags = flags;
1408 mgi->mgi_marker.cm_vers = LUSTRE_VERSION_CODE;
1409 cplen = strlcpy(mgi->mgi_marker.cm_tgtname, tgtname,
1410 sizeof(mgi->mgi_marker.cm_tgtname));
1411 if (cplen >= sizeof(mgi->mgi_marker.cm_tgtname))
1413 cplen = strlcpy(mgi->mgi_marker.cm_comment, comment,
1414 sizeof(mgi->mgi_marker.cm_comment));
1415 if (cplen >= sizeof(mgi->mgi_marker.cm_comment))
1417 mgi->mgi_marker.cm_createtime = cfs_time_current_sec();
1418 mgi->mgi_marker.cm_canceltime = 0;
1419 lustre_cfg_bufs_reset(&mgi->mgi_bufs, NULL);
1420 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, &mgi->mgi_marker,
1421 sizeof(mgi->mgi_marker));
1422 lcfg = lustre_cfg_new(LCFG_MARKER, &mgi->mgi_bufs);
1425 rc = record_lcfg(env, llh, lcfg);
1427 lustre_cfg_free(lcfg);
1431 static int record_start_log(const struct lu_env *env, struct mgs_device *mgs,
1432 struct llog_handle **llh, char *name)
1434 static struct obd_uuid cfg_uuid = { .uuid = "config_uuid" };
1435 struct llog_ctxt *ctxt;
1439 GOTO(out, rc = -EBUSY);
1441 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
1443 GOTO(out, rc = -ENODEV);
1444 LASSERT(ctxt->loc_obd == mgs->mgs_obd);
1446 rc = llog_open_create(env, ctxt, llh, NULL, name);
1449 rc = llog_init_handle(env, *llh, LLOG_F_IS_PLAIN, &cfg_uuid);
1451 llog_close(env, *llh);
1453 llog_ctxt_put(ctxt);
1456 CERROR("%s: can't start log %s: rc = %d\n",
1457 mgs->mgs_obd->obd_name, name, rc);
1463 static int record_end_log(const struct lu_env *env, struct llog_handle **llh)
1467 rc = llog_close(env, *llh);
1473 static int mgs_log_is_empty(const struct lu_env *env,
1474 struct mgs_device *mgs, char *name)
1476 struct llog_handle *llh;
1477 struct llog_ctxt *ctxt;
1480 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
1481 LASSERT(ctxt != NULL);
1482 rc = llog_open(env, ctxt, &llh, NULL, name, LLOG_OPEN_EXISTS);
1489 rc = llog_init_handle(env, llh, LLOG_F_IS_PLAIN, NULL);
1491 GOTO(out_close, rc);
1492 rc = llog_get_size(llh);
1495 llog_close(env, llh);
1497 llog_ctxt_put(ctxt);
1498 /* header is record 1 */
1502 /******************** config "macros" *********************/
1504 /* write an lcfg directly into a log (with markers) */
1505 static int mgs_write_log_direct(const struct lu_env *env,
1506 struct mgs_device *mgs, struct fs_db *fsdb,
1507 char *logname, struct lustre_cfg *lcfg,
1508 char *devname, char *comment)
1510 struct llog_handle *llh = NULL;
1517 rc = record_start_log(env, mgs, &llh, logname);
1521 /* FIXME These should be a single journal transaction */
1522 rc = record_marker(env, llh, fsdb, CM_START, devname, comment);
1525 rc = record_lcfg(env, llh, lcfg);
1528 rc = record_marker(env, llh, fsdb, CM_END, devname, comment);
1532 record_end_log(env, &llh);
1536 /* write the lcfg in all logs for the given fs */
1537 int mgs_write_log_direct_all(const struct lu_env *env,
1538 struct mgs_device *mgs,
1540 struct mgs_target_info *mti,
1541 struct lustre_cfg *lcfg,
1542 char *devname, char *comment,
1546 struct mgs_direntry *dirent, *n;
1547 char *fsname = mti->mti_fsname;
1549 int rc = 0, len = strlen(fsname);
1552 /* We need to set params for any future logs
1553 as well. FIXME Append this file to every new log.
1554 Actually, we should store as params (text), not llogs. Or
1556 rc = name_create(&logname, fsname, "-params");
1559 if (mgs_log_is_empty(env, mgs, logname)) {
1560 struct llog_handle *llh = NULL;
1561 rc = record_start_log(env, mgs, &llh, logname);
1562 record_end_log(env, &llh);
1564 name_destroy(&logname);
1568 /* Find all the logs in the CONFIGS directory */
1569 rc = class_dentry_readdir(env, mgs, &list);
1573 /* Could use fsdb index maps instead of directory listing */
1574 cfs_list_for_each_entry_safe(dirent, n, &list, list) {
1575 cfs_list_del(&dirent->list);
1576 /* don't write to sptlrpc rule log */
1577 if (strstr(dirent->name, "-sptlrpc") != NULL)
1580 /* caller wants write server logs only */
1581 if (server_only && strstr(dirent->name, "-client") != NULL)
1584 if (strncmp(fsname, dirent->name, len) == 0) {
1585 CDEBUG(D_MGS, "Changing log %s\n", dirent->name);
1586 /* Erase any old settings of this same parameter */
1587 rc = mgs_modify(env, mgs, fsdb, mti, dirent->name,
1588 devname, comment, CM_SKIP);
1590 CERROR("%s: Can't modify llog %s: rc = %d\n",
1591 mgs->mgs_obd->obd_name, dirent->name,rc);
1592 /* Write the new one */
1594 rc = mgs_write_log_direct(env, mgs, fsdb,
1599 CERROR("%s: writing log %s: rc = %d\n",
1600 mgs->mgs_obd->obd_name,
1605 mgs_direntry_free(dirent);
1611 static int mgs_write_log_osp_to_mdt(const struct lu_env *env,
1612 struct mgs_device *mgs,
1614 struct mgs_target_info *mti,
1615 int index, char *logname);
1616 static int mgs_write_log_osc_to_lov(const struct lu_env *env,
1617 struct mgs_device *mgs,
1619 struct mgs_target_info *mti,
1620 char *logname, char *suffix, char *lovname,
1621 enum lustre_sec_part sec_part, int flags);
1622 static int name_create_mdt_and_lov(char **logname, char **lovname,
1623 struct fs_db *fsdb, int i);
1625 static int add_param(char *params, char *key, char *val)
1627 char *start = params + strlen(params);
1628 char *end = params + sizeof(((struct mgs_target_info *)0)->mti_params);
1632 keylen = strlen(key);
1633 if (start + 1 + keylen + strlen(val) >= end) {
1634 CERROR("params are too long: %s %s%s\n",
1635 params, key != NULL ? key : "", val);
1639 sprintf(start, " %s%s", key != NULL ? key : "", val);
1644 * Walk through client config log record and convert the related records
1647 static int mgs_steal_client_llog_handler(const struct lu_env *env,
1648 struct llog_handle *llh,
1649 struct llog_rec_hdr *rec, void *data)
1651 struct mgs_device *mgs;
1652 struct obd_device *obd;
1653 struct mgs_target_info *mti, *tmti;
1655 int cfg_len = rec->lrh_len;
1656 char *cfg_buf = (char*) (rec + 1);
1657 struct lustre_cfg *lcfg;
1659 struct llog_handle *mdt_llh = NULL;
1660 static int got_an_osc_or_mdc = 0;
1661 /* 0: not found any osc/mdc;
1665 static int last_step = -1;
1670 mti = ((struct temp_comp*)data)->comp_mti;
1671 tmti = ((struct temp_comp*)data)->comp_tmti;
1672 fsdb = ((struct temp_comp*)data)->comp_fsdb;
1673 obd = ((struct temp_comp *)data)->comp_obd;
1674 mgs = lu2mgs_dev(obd->obd_lu_dev);
1677 if (rec->lrh_type != OBD_CFG_REC) {
1678 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
1682 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
1684 CERROR("Insane cfg\n");
1688 lcfg = (struct lustre_cfg *)cfg_buf;
1690 if (lcfg->lcfg_command == LCFG_MARKER) {
1691 struct cfg_marker *marker;
1692 marker = lustre_cfg_buf(lcfg, 1);
1693 if (!strncmp(marker->cm_comment, "add osc", 7) &&
1694 (marker->cm_flags & CM_START) &&
1695 !(marker->cm_flags & CM_SKIP)) {
1696 got_an_osc_or_mdc = 1;
1697 cplen = strlcpy(tmti->mti_svname, marker->cm_tgtname,
1698 sizeof(tmti->mti_svname));
1699 if (cplen >= sizeof(tmti->mti_svname))
1701 rc = record_start_log(env, mgs, &mdt_llh,
1705 rc = record_marker(env, mdt_llh, fsdb, CM_START,
1706 mti->mti_svname, "add osc(copied)");
1707 record_end_log(env, &mdt_llh);
1708 last_step = marker->cm_step;
1711 if (!strncmp(marker->cm_comment, "add osc", 7) &&
1712 (marker->cm_flags & CM_END) &&
1713 !(marker->cm_flags & CM_SKIP)) {
1714 LASSERT(last_step == marker->cm_step);
1716 got_an_osc_or_mdc = 0;
1717 memset(tmti, 0, sizeof(*tmti));
1718 rc = record_start_log(env, mgs, &mdt_llh,
1722 rc = record_marker(env, mdt_llh, fsdb, CM_END,
1723 mti->mti_svname, "add osc(copied)");
1724 record_end_log(env, &mdt_llh);
1727 if (!strncmp(marker->cm_comment, "add mdc", 7) &&
1728 (marker->cm_flags & CM_START) &&
1729 !(marker->cm_flags & CM_SKIP)) {
1730 got_an_osc_or_mdc = 2;
1731 last_step = marker->cm_step;
1732 memcpy(tmti->mti_svname, marker->cm_tgtname,
1733 strlen(marker->cm_tgtname));
1737 if (!strncmp(marker->cm_comment, "add mdc", 7) &&
1738 (marker->cm_flags & CM_END) &&
1739 !(marker->cm_flags & CM_SKIP)) {
1740 LASSERT(last_step == marker->cm_step);
1742 got_an_osc_or_mdc = 0;
1743 memset(tmti, 0, sizeof(*tmti));
1748 if (got_an_osc_or_mdc == 0 || last_step < 0)
1751 if (lcfg->lcfg_command == LCFG_ADD_UUID) {
1752 uint64_t nodenid = lcfg->lcfg_nid;
1754 if (strlen(tmti->mti_uuid) == 0) {
1755 /* target uuid not set, this config record is before
1756 * LCFG_SETUP, this nid is one of target node nid.
1758 tmti->mti_nids[tmti->mti_nid_count] = nodenid;
1759 tmti->mti_nid_count++;
1761 /* failover node nid */
1762 rc = add_param(tmti->mti_params, PARAM_FAILNODE,
1763 libcfs_nid2str(nodenid));
1769 if (lcfg->lcfg_command == LCFG_SETUP) {
1772 target = lustre_cfg_string(lcfg, 1);
1773 memcpy(tmti->mti_uuid, target, strlen(target));
1777 /* ignore client side sptlrpc_conf_log */
1778 if (lcfg->lcfg_command == LCFG_SPTLRPC_CONF)
1781 if (lcfg->lcfg_command == LCFG_ADD_MDC) {
1784 if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1)
1787 memcpy(tmti->mti_fsname, mti->mti_fsname,
1788 strlen(mti->mti_fsname));
1789 tmti->mti_stripe_index = index;
1791 rc = mgs_write_log_osp_to_mdt(env, mgs, fsdb, tmti,
1792 mti->mti_stripe_index,
1794 memset(tmti, 0, sizeof(*tmti));
1798 if (lcfg->lcfg_command == LCFG_LOV_ADD_OBD) {
1801 char *logname, *lovname;
1803 rc = name_create_mdt_and_lov(&logname, &lovname, fsdb,
1804 mti->mti_stripe_index);
1807 sprintf(mdt_index, "-MDT%04x", mti->mti_stripe_index);
1809 if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1) {
1810 name_destroy(&logname);
1811 name_destroy(&lovname);
1815 tmti->mti_stripe_index = index;
1816 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, tmti, logname,
1819 name_destroy(&logname);
1820 name_destroy(&lovname);
1826 /* fsdb->fsdb_mutex is already held in mgs_write_log_target*/
1827 /* stealed from mgs_get_fsdb_from_llog*/
1828 static int mgs_steal_llog_for_mdt_from_client(const struct lu_env *env,
1829 struct mgs_device *mgs,
1831 struct temp_comp* comp)
1833 struct llog_handle *loghandle;
1834 struct mgs_target_info *tmti;
1835 struct llog_ctxt *ctxt;
1840 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
1841 LASSERT(ctxt != NULL);
1843 OBD_ALLOC_PTR(tmti);
1845 GOTO(out_ctxt, rc = -ENOMEM);
1847 comp->comp_tmti = tmti;
1848 comp->comp_obd = mgs->mgs_obd;
1850 rc = llog_open(env, ctxt, &loghandle, NULL, client_name,
1858 rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL);
1860 GOTO(out_close, rc);
1862 rc = llog_process_or_fork(env, loghandle, mgs_steal_client_llog_handler,
1863 (void *)comp, NULL, false);
1864 CDEBUG(D_MGS, "steal llog re = %d\n", rc);
1866 llog_close(env, loghandle);
1870 llog_ctxt_put(ctxt);
1874 /* lmv is the second thing for client logs */
1875 /* copied from mgs_write_log_lov. Please refer to that. */
1876 static int mgs_write_log_lmv(const struct lu_env *env,
1877 struct mgs_device *mgs,
1879 struct mgs_target_info *mti,
1880 char *logname, char *lmvname)
1882 struct llog_handle *llh = NULL;
1883 struct lmv_desc *lmvdesc;
1888 CDEBUG(D_MGS, "Writing lmv(%s) log for %s\n", lmvname,logname);
1890 OBD_ALLOC_PTR(lmvdesc);
1891 if (lmvdesc == NULL)
1893 lmvdesc->ld_active_tgt_count = 0;
1894 lmvdesc->ld_tgt_count = 0;
1895 sprintf((char*)lmvdesc->ld_uuid.uuid, "%s_UUID", lmvname);
1896 uuid = (char *)lmvdesc->ld_uuid.uuid;
1898 rc = record_start_log(env, mgs, &llh, logname);
1901 rc = record_marker(env, llh, fsdb, CM_START, lmvname, "lmv setup");
1904 rc = record_attach(env, llh, lmvname, "lmv", uuid);
1907 rc = record_lmv_setup(env, llh, lmvname, lmvdesc);
1910 rc = record_marker(env, llh, fsdb, CM_END, lmvname, "lmv setup");
1914 record_end_log(env, &llh);
1916 OBD_FREE_PTR(lmvdesc);
1920 /* lov is the first thing in the mdt and client logs */
1921 static int mgs_write_log_lov(const struct lu_env *env, struct mgs_device *mgs,
1922 struct fs_db *fsdb, struct mgs_target_info *mti,
1923 char *logname, char *lovname)
1925 struct llog_handle *llh = NULL;
1926 struct lov_desc *lovdesc;
1931 CDEBUG(D_MGS, "Writing lov(%s) log for %s\n", lovname, logname);
1934 #01 L attach 0:lov_mdsA 1:lov 2:71ccb_lov_mdsA_19f961a9e1
1935 #02 L lov_setup 0:lov_mdsA 1:(struct lov_desc)
1936 uuid=lov1_UUID, stripe count=1, size=1048576, offset=0, pattern=0
1939 /* FIXME just make lov_setup accept empty desc (put uuid in buf 2) */
1940 OBD_ALLOC_PTR(lovdesc);
1941 if (lovdesc == NULL)
1943 lovdesc->ld_magic = LOV_DESC_MAGIC;
1944 lovdesc->ld_tgt_count = 0;
1945 /* Defaults. Can be changed later by lcfg config_param */
1946 lovdesc->ld_default_stripe_count = 1;
1947 lovdesc->ld_pattern = LOV_PATTERN_RAID0;
1948 lovdesc->ld_default_stripe_size = 1024 * 1024;
1949 lovdesc->ld_default_stripe_offset = -1;
1950 lovdesc->ld_qos_maxage = QOS_DEFAULT_MAXAGE;
1951 sprintf((char*)lovdesc->ld_uuid.uuid, "%s_UUID", lovname);
1952 /* can these be the same? */
1953 uuid = (char *)lovdesc->ld_uuid.uuid;
1955 /* This should always be the first entry in a log.
1956 rc = mgs_clear_log(obd, logname); */
1957 rc = record_start_log(env, mgs, &llh, logname);
1960 /* FIXME these should be a single journal transaction */
1961 rc = record_marker(env, llh, fsdb, CM_START, lovname, "lov setup");
1964 rc = record_attach(env, llh, lovname, "lov", uuid);
1967 rc = record_lov_setup(env, llh, lovname, lovdesc);
1970 rc = record_marker(env, llh, fsdb, CM_END, lovname, "lov setup");
1975 record_end_log(env, &llh);
1977 OBD_FREE_PTR(lovdesc);
1981 /* add failnids to open log */
1982 static int mgs_write_log_failnids(const struct lu_env *env,
1983 struct mgs_target_info *mti,
1984 struct llog_handle *llh,
1987 char *failnodeuuid = NULL;
1988 char *ptr = mti->mti_params;
1993 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) nal=90 0: 1:uml1_UUID
1994 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
1995 #05 L setup 0:OSC_uml1_ost1_mdsA 1:ost1_UUID 2:uml1_UUID
1996 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) nal=90 0: 1:uml2_UUID
1997 #0x L add_uuid nid=2@elan(0x1000000000002) nal=90 0: 1:uml2_UUID
1998 #07 L add_conn 0:OSC_uml1_ost1_mdsA 1:uml2_UUID
2001 /* Pull failnid info out of params string */
2002 while (class_find_param(ptr, PARAM_FAILNODE, &ptr) == 0) {
2003 while (class_parse_nid(ptr, &nid, &ptr) == 0) {
2004 if (failnodeuuid == NULL) {
2005 /* We don't know the failover node name,
2006 so just use the first nid as the uuid */
2007 rc = name_create(&failnodeuuid,
2008 libcfs_nid2str(nid), "");
2012 CDEBUG(D_MGS, "add nid %s for failover uuid %s, "
2013 "client %s\n", libcfs_nid2str(nid),
2014 failnodeuuid, cliname);
2015 rc = record_add_uuid(env, llh, nid, failnodeuuid);
2018 rc = record_add_conn(env, llh, cliname, failnodeuuid);
2021 name_destroy(&failnodeuuid);
2025 static int mgs_write_log_mdc_to_lmv(const struct lu_env *env,
2026 struct mgs_device *mgs,
2028 struct mgs_target_info *mti,
2029 char *logname, char *lmvname)
2031 struct llog_handle *llh = NULL;
2032 char *mdcname = NULL;
2033 char *nodeuuid = NULL;
2034 char *mdcuuid = NULL;
2035 char *lmvuuid = NULL;
2040 if (mgs_log_is_empty(env, mgs, logname)) {
2041 CERROR("log is empty! Logical error\n");
2045 CDEBUG(D_MGS, "adding mdc for %s to log %s:lmv(%s)\n",
2046 mti->mti_svname, logname, lmvname);
2048 rc = name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
2051 rc = name_create(&mdcname, mti->mti_svname, "-mdc");
2054 rc = name_create(&mdcuuid, mdcname, "_UUID");
2057 rc = name_create(&lmvuuid, lmvname, "_UUID");
2061 rc = record_start_log(env, mgs, &llh, logname);
2064 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
2068 for (i = 0; i < mti->mti_nid_count; i++) {
2069 CDEBUG(D_MGS, "add nid %s for mdt\n",
2070 libcfs_nid2str(mti->mti_nids[i]));
2072 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
2077 rc = record_attach(env, llh, mdcname, LUSTRE_MDC_NAME, lmvuuid);
2080 rc = record_setup(env, llh, mdcname, mti->mti_uuid, nodeuuid, 0, 0);
2083 rc = mgs_write_log_failnids(env, mti, llh, mdcname);
2086 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
2087 rc = record_mdc_add(env, llh, lmvname, mdcuuid, mti->mti_uuid,
2091 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname,
2096 record_end_log(env, &llh);
2098 name_destroy(&lmvuuid);
2099 name_destroy(&mdcuuid);
2100 name_destroy(&mdcname);
2101 name_destroy(&nodeuuid);
2105 static inline int name_create_lov(char **lovname, char *mdtname,
2106 struct fs_db *fsdb, int index)
2109 if (index == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2110 return name_create(lovname, fsdb->fsdb_name, "-mdtlov");
2112 return name_create(lovname, mdtname, "-mdtlov");
2115 static int name_create_mdt_and_lov(char **logname, char **lovname,
2116 struct fs_db *fsdb, int i)
2120 rc = name_create_mdt(logname, fsdb->fsdb_name, i);
2124 if (i == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2125 rc = name_create(lovname, fsdb->fsdb_name, "-mdtlov");
2127 rc = name_create(lovname, *logname, "-mdtlov");
2129 name_destroy(logname);
2135 static inline int name_create_mdt_osc(char **oscname, char *ostname,
2136 struct fs_db *fsdb, int i)
2140 if (i == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2141 sprintf(suffix, "-osc");
2143 sprintf(suffix, "-osc-MDT%04x", i);
2144 return name_create(oscname, ostname, suffix);
2147 /* add new mdc to already existent MDS */
2148 static int mgs_write_log_osp_to_mdt(const struct lu_env *env,
2149 struct mgs_device *mgs,
2151 struct mgs_target_info *mti,
2152 int mdt_index, char *logname)
2154 struct llog_handle *llh = NULL;
2155 char *nodeuuid = NULL;
2156 char *ospname = NULL;
2157 char *lovuuid = NULL;
2158 char *mdtuuid = NULL;
2159 char *svname = NULL;
2160 char *mdtname = NULL;
2161 char *lovname = NULL;
2166 if (mgs_log_is_empty(env, mgs, mti->mti_svname)) {
2167 CERROR("log is empty! Logical error\n");
2171 CDEBUG(D_MGS, "adding osp index %d to %s\n", mti->mti_stripe_index,
2174 rc = name_create_mdt(&mdtname, fsdb->fsdb_name, mti->mti_stripe_index);
2178 rc = name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
2180 GOTO(out_destory, rc);
2182 rc = name_create(&svname, mdtname, "-osp");
2184 GOTO(out_destory, rc);
2186 sprintf(index_str, "-MDT%04x", mdt_index);
2187 rc = name_create(&ospname, svname, index_str);
2189 GOTO(out_destory, rc);
2191 rc = name_create_lov(&lovname, logname, fsdb, mdt_index);
2193 GOTO(out_destory, rc);
2195 rc = name_create(&lovuuid, lovname, "_UUID");
2197 GOTO(out_destory, rc);
2199 rc = name_create(&mdtuuid, mdtname, "_UUID");
2201 GOTO(out_destory, rc);
2203 rc = record_start_log(env, mgs, &llh, logname);
2205 GOTO(out_destory, rc);
2207 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
2210 GOTO(out_destory, rc);
2212 for (i = 0; i < mti->mti_nid_count; i++) {
2213 CDEBUG(D_MGS, "add nid %s for mdt\n",
2214 libcfs_nid2str(mti->mti_nids[i]));
2215 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
2220 rc = record_attach(env, llh, ospname, LUSTRE_OSP_NAME, lovuuid);
2224 rc = record_setup(env, llh, ospname, mti->mti_uuid, nodeuuid,
2229 rc = mgs_write_log_failnids(env, mti, llh, ospname);
2233 /* Add mdc(osp) to lod */
2234 snprintf(index_str, sizeof(mti->mti_stripe_index), "%d",
2235 mti->mti_stripe_index);
2236 rc = record_base(env, llh, lovname, 0, LCFG_ADD_MDC, mti->mti_uuid,
2237 index_str, "1", NULL);
2241 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname, "add osp");
2246 record_end_log(env, &llh);
2249 name_destroy(&mdtuuid);
2250 name_destroy(&lovuuid);
2251 name_destroy(&lovname);
2252 name_destroy(&ospname);
2253 name_destroy(&svname);
2254 name_destroy(&nodeuuid);
2255 name_destroy(&mdtname);
2259 static int mgs_write_log_mdt0(const struct lu_env *env,
2260 struct mgs_device *mgs,
2262 struct mgs_target_info *mti)
2264 char *log = mti->mti_svname;
2265 struct llog_handle *llh = NULL;
2266 char *uuid, *lovname;
2268 char *ptr = mti->mti_params;
2269 int rc = 0, failout = 0;
2272 OBD_ALLOC(uuid, sizeof(struct obd_uuid));
2276 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
2277 failout = (strncmp(ptr, "failout", 7) == 0);
2279 rc = name_create(&lovname, log, "-mdtlov");
2282 if (mgs_log_is_empty(env, mgs, log)) {
2283 rc = mgs_write_log_lov(env, mgs, fsdb, mti, log, lovname);
2288 sprintf(mdt_index, "%d", mti->mti_stripe_index);
2290 rc = record_start_log(env, mgs, &llh, log);
2294 /* add MDT itself */
2296 /* FIXME this whole fn should be a single journal transaction */
2297 sprintf(uuid, "%s_UUID", log);
2298 rc = record_marker(env, llh, fsdb, CM_START, log, "add mdt");
2301 rc = record_attach(env, llh, log, LUSTRE_MDT_NAME, uuid);
2304 rc = record_mount_opt(env, llh, log, lovname, NULL);
2307 rc = record_setup(env, llh, log, uuid, mdt_index, lovname,
2308 failout ? "n" : "f");
2311 rc = record_marker(env, llh, fsdb, CM_END, log, "add mdt");
2315 record_end_log(env, &llh);
2317 name_destroy(&lovname);
2319 OBD_FREE(uuid, sizeof(struct obd_uuid));
2323 /* envelope method for all layers log */
2324 static int mgs_write_log_mdt(const struct lu_env *env,
2325 struct mgs_device *mgs,
2327 struct mgs_target_info *mti)
2329 struct mgs_thread_info *mgi = mgs_env_info(env);
2330 struct llog_handle *llh = NULL;
2335 CDEBUG(D_MGS, "writing new mdt %s\n", mti->mti_svname);
2337 if (mti->mti_uuid[0] == '\0') {
2338 /* Make up our own uuid */
2339 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
2340 "%s_UUID", mti->mti_svname);
2344 rc = mgs_write_log_mdt0(env, mgs, fsdb, mti);
2347 /* Append the mdt info to the client log */
2348 rc = name_create(&cliname, mti->mti_fsname, "-client");
2352 if (mgs_log_is_empty(env, mgs, cliname)) {
2353 /* Start client log */
2354 rc = mgs_write_log_lov(env, mgs, fsdb, mti, cliname,
2358 rc = mgs_write_log_lmv(env, mgs, fsdb, mti, cliname,
2365 #09 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
2366 #10 L attach 0:MDC_uml1_mdsA_MNT_client 1:mdc 2:1d834_MNT_client_03f
2367 #11 L setup 0:MDC_uml1_mdsA_MNT_client 1:mdsA_UUID 2:uml1_UUID
2368 #12 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
2369 #13 L add_conn 0:MDC_uml1_mdsA_MNT_client 1:uml2_UUID
2370 #14 L mount_option 0: 1:client 2:lov1 3:MDC_uml1_mdsA_MNT_client
2373 /* copy client info about lov/lmv */
2374 mgi->mgi_comp.comp_mti = mti;
2375 mgi->mgi_comp.comp_fsdb = fsdb;
2377 rc = mgs_steal_llog_for_mdt_from_client(env, mgs, cliname,
2381 rc = mgs_write_log_mdc_to_lmv(env, mgs, fsdb, mti, cliname,
2387 rc = record_start_log(env, mgs, &llh, cliname);
2391 rc = record_marker(env, llh, fsdb, CM_START, cliname,
2395 rc = record_mount_opt(env, llh, cliname, fsdb->fsdb_clilov,
2399 rc = record_marker(env, llh, fsdb, CM_END, cliname,
2405 /* for_all_existing_mdt except current one */
2406 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2407 if (i != mti->mti_stripe_index &&
2408 test_bit(i, fsdb->fsdb_mdt_index_map)) {
2411 rc = name_create_mdt(&logname, fsdb->fsdb_name, i);
2415 rc = mgs_write_log_osp_to_mdt(env, mgs, fsdb, mti,
2417 name_destroy(&logname);
2423 record_end_log(env, &llh);
2425 name_destroy(&cliname);
2429 /* Add the ost info to the client/mdt lov */
2430 static int mgs_write_log_osc_to_lov(const struct lu_env *env,
2431 struct mgs_device *mgs, struct fs_db *fsdb,
2432 struct mgs_target_info *mti,
2433 char *logname, char *suffix, char *lovname,
2434 enum lustre_sec_part sec_part, int flags)
2436 struct llog_handle *llh = NULL;
2437 char *nodeuuid = NULL;
2438 char *oscname = NULL;
2439 char *oscuuid = NULL;
2440 char *lovuuid = NULL;
2441 char *svname = NULL;
2446 CDEBUG(D_INFO, "adding osc for %s to log %s\n",
2447 mti->mti_svname, logname);
2449 if (mgs_log_is_empty(env, mgs, logname)) {
2450 CERROR("log is empty! Logical error\n");
2454 rc = name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
2457 rc = name_create(&svname, mti->mti_svname, "-osc");
2461 /* for the system upgraded from old 1.8, keep using the old osc naming
2462 * style for mdt, see name_create_mdt_osc(). LU-1257 */
2463 if (test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2464 rc = name_create(&oscname, svname, "");
2466 rc = name_create(&oscname, svname, suffix);
2470 rc = name_create(&oscuuid, oscname, "_UUID");
2473 rc = name_create(&lovuuid, lovname, "_UUID");
2479 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
2481 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
2482 #04 L attach 0:OSC_uml1_ost1_MNT_client 1:osc 2:89070_lov1_a41dff51a
2483 #05 L setup 0:OSC_uml1_ost1_MNT_client 1:ost1_UUID 2:uml1_UUID
2485 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
2486 #07 L add_conn 0:OSC_uml1_ost1_MNT_client 1:uml2_UUID
2487 #08 L lov_modify_tgts add 0:lov1 1:ost1_UUID 2(index):0 3(gen):1
2490 rc = record_start_log(env, mgs, &llh, logname);
2494 /* FIXME these should be a single journal transaction */
2495 rc = record_marker(env, llh, fsdb, CM_START | flags, mti->mti_svname,
2500 /* NB: don't change record order, because upon MDT steal OSC config
2501 * from client, it treats all nids before LCFG_SETUP as target nids
2502 * (multiple interfaces), while nids after as failover node nids.
2503 * See mgs_steal_client_llog_handler() LCFG_ADD_UUID.
2505 for (i = 0; i < mti->mti_nid_count; i++) {
2506 CDEBUG(D_MGS, "add nid %s\n", libcfs_nid2str(mti->mti_nids[i]));
2507 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
2511 rc = record_attach(env, llh, oscname, LUSTRE_OSC_NAME, lovuuid);
2514 rc = record_setup(env, llh, oscname, mti->mti_uuid, nodeuuid, 0, 0);
2517 rc = mgs_write_log_failnids(env, mti, llh, oscname);
2521 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
2523 rc = record_lov_add(env, llh, lovname, mti->mti_uuid, index, "1");
2526 rc = record_marker(env, llh, fsdb, CM_END | flags, mti->mti_svname,
2531 record_end_log(env, &llh);
2533 name_destroy(&lovuuid);
2534 name_destroy(&oscuuid);
2535 name_destroy(&oscname);
2536 name_destroy(&svname);
2537 name_destroy(&nodeuuid);
2541 static int mgs_write_log_ost(const struct lu_env *env,
2542 struct mgs_device *mgs, struct fs_db *fsdb,
2543 struct mgs_target_info *mti)
2545 struct llog_handle *llh = NULL;
2546 char *logname, *lovname;
2547 char *ptr = mti->mti_params;
2548 int rc, flags = 0, failout = 0, i;
2551 CDEBUG(D_MGS, "writing new ost %s\n", mti->mti_svname);
2553 /* The ost startup log */
2555 /* If the ost log already exists, that means that someone reformatted
2556 the ost and it called target_add again. */
2557 if (!mgs_log_is_empty(env, mgs, mti->mti_svname)) {
2558 LCONSOLE_ERROR_MSG(0x141, "The config log for %s already "
2559 "exists, yet the server claims it never "
2560 "registered. It may have been reformatted, "
2561 "or the index changed. writeconf the MDT to "
2562 "regenerate all logs.\n", mti->mti_svname);
2567 attach obdfilter ost1 ost1_UUID
2568 setup /dev/loop2 ldiskfs f|n errors=remount-ro,user_xattr
2570 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
2571 failout = (strncmp(ptr, "failout", 7) == 0);
2572 rc = record_start_log(env, mgs, &llh, mti->mti_svname);
2575 /* FIXME these should be a single journal transaction */
2576 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,"add ost");
2579 if (*mti->mti_uuid == '\0')
2580 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
2581 "%s_UUID", mti->mti_svname);
2582 rc = record_attach(env, llh, mti->mti_svname,
2583 "obdfilter"/*LUSTRE_OST_NAME*/, mti->mti_uuid);
2586 rc = record_setup(env, llh, mti->mti_svname,
2587 "dev"/*ignored*/, "type"/*ignored*/,
2588 failout ? "n" : "f", 0/*options*/);
2591 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname, "add ost");
2595 record_end_log(env, &llh);
2598 /* We also have to update the other logs where this osc is part of
2601 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
2602 /* If we're upgrading, the old mdt log already has our
2603 entry. Let's do a fake one for fun. */
2604 /* Note that we can't add any new failnids, since we don't
2605 know the old osc names. */
2606 flags = CM_SKIP | CM_UPGRADE146;
2608 } else if ((mti->mti_flags & LDD_F_UPDATE) != LDD_F_UPDATE) {
2609 /* If the update flag isn't set, don't update client/mdt
2612 LCONSOLE_WARN("Client log for %s was not updated; writeconf "
2613 "the MDT first to regenerate it.\n",
2617 /* Add ost to all MDT lov defs */
2618 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
2619 if (test_bit(i, fsdb->fsdb_mdt_index_map)) {
2622 rc = name_create_mdt_and_lov(&logname, &lovname, fsdb,
2626 sprintf(mdt_index, "-MDT%04x", i);
2627 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, mti,
2629 lovname, LUSTRE_SP_MDT,
2631 name_destroy(&logname);
2632 name_destroy(&lovname);
2638 /* Append ost info to the client log */
2639 rc = name_create(&logname, mti->mti_fsname, "-client");
2642 if (mgs_log_is_empty(env, mgs, logname)) {
2643 /* Start client log */
2644 rc = mgs_write_log_lov(env, mgs, fsdb, mti, logname,
2648 rc = mgs_write_log_lmv(env, mgs, fsdb, mti, logname,
2653 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, mti, logname, "",
2654 fsdb->fsdb_clilov, LUSTRE_SP_CLI, 0);
2656 name_destroy(&logname);
2660 static __inline__ int mgs_param_empty(char *ptr)
2664 if ((tmp = strchr(ptr, '=')) && (*(++tmp) == '\0'))
2669 static int mgs_write_log_failnid_internal(const struct lu_env *env,
2670 struct mgs_device *mgs,
2672 struct mgs_target_info *mti,
2673 char *logname, char *cliname)
2676 struct llog_handle *llh = NULL;
2678 if (mgs_param_empty(mti->mti_params)) {
2679 /* Remove _all_ failnids */
2680 rc = mgs_modify(env, mgs, fsdb, mti, logname,
2681 mti->mti_svname, "add failnid", CM_SKIP);
2682 return rc < 0 ? rc : 0;
2685 /* Otherwise failover nids are additive */
2686 rc = record_start_log(env, mgs, &llh, logname);
2689 /* FIXME this should be a single journal transaction */
2690 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
2694 rc = mgs_write_log_failnids(env, mti, llh, cliname);
2697 rc = record_marker(env, llh, fsdb, CM_END,
2698 mti->mti_svname, "add failnid");
2700 record_end_log(env, &llh);
2705 /* Add additional failnids to an existing log.
2706 The mdc/osc must have been added to logs first */
2707 /* tcp nids must be in dotted-quad ascii -
2708 we can't resolve hostnames from the kernel. */
2709 static int mgs_write_log_add_failnid(const struct lu_env *env,
2710 struct mgs_device *mgs,
2712 struct mgs_target_info *mti)
2714 char *logname, *cliname;
2718 /* FIXME we currently can't erase the failnids
2719 * given when a target first registers, since they aren't part of
2720 * an "add uuid" stanza */
2722 /* Verify that we know about this target */
2723 if (mgs_log_is_empty(env, mgs, mti->mti_svname)) {
2724 LCONSOLE_ERROR_MSG(0x142, "The target %s has not registered "
2725 "yet. It must be started before failnids "
2726 "can be added.\n", mti->mti_svname);
2730 /* Create mdc/osc client name (e.g. lustre-OST0001-osc) */
2731 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
2732 rc = name_create(&cliname, mti->mti_svname, "-mdc");
2733 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2734 rc = name_create(&cliname, mti->mti_svname, "-osc");
2740 /* Add failover nids to the client log */
2741 rc = name_create(&logname, mti->mti_fsname, "-client");
2743 name_destroy(&cliname);
2746 rc = mgs_write_log_failnid_internal(env, mgs, fsdb,mti,logname,cliname);
2747 name_destroy(&logname);
2748 name_destroy(&cliname);
2752 if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2753 /* Add OST failover nids to the MDT logs as well */
2756 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2757 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
2759 rc = name_create_mdt(&logname, mti->mti_fsname, i);
2762 rc = name_create_mdt_osc(&cliname, mti->mti_svname,
2765 name_destroy(&logname);
2768 rc = mgs_write_log_failnid_internal(env, mgs, fsdb,
2771 name_destroy(&cliname);
2772 name_destroy(&logname);
2781 static int mgs_wlp_lcfg(const struct lu_env *env,
2782 struct mgs_device *mgs, struct fs_db *fsdb,
2783 struct mgs_target_info *mti,
2784 char *logname, struct lustre_cfg_bufs *bufs,
2785 char *tgtname, char *ptr)
2787 char comment[MTI_NAME_MAXLEN];
2789 struct lustre_cfg *lcfg;
2792 /* Erase any old settings of this same parameter */
2793 memcpy(comment, ptr, MTI_NAME_MAXLEN);
2794 comment[MTI_NAME_MAXLEN - 1] = 0;
2795 /* But don't try to match the value. */
2796 if ((tmp = strchr(comment, '=')))
2798 /* FIXME we should skip settings that are the same as old values */
2799 rc = mgs_modify(env, mgs, fsdb, mti, logname, tgtname, comment,CM_SKIP);
2802 del = mgs_param_empty(ptr);
2804 LCONSOLE_INFO("%sing parameter %s.%s in log %s\n", del ? "Disabl" : rc ?
2805 "Sett" : "Modify", tgtname, comment, logname);
2809 lustre_cfg_bufs_reset(bufs, tgtname);
2810 lustre_cfg_bufs_set_string(bufs, 1, ptr);
2811 lcfg = lustre_cfg_new(LCFG_PARAM, bufs);
2814 rc = mgs_write_log_direct(env, mgs, fsdb, logname,lcfg,tgtname,comment);
2815 lustre_cfg_free(lcfg);
2819 /* write global variable settings into log */
2820 static int mgs_write_log_sys(const struct lu_env *env,
2821 struct mgs_device *mgs, struct fs_db *fsdb,
2822 struct mgs_target_info *mti, char *sys, char *ptr)
2824 struct mgs_thread_info *mgi = mgs_env_info(env);
2825 struct lustre_cfg *lcfg;
2827 int rc, cmd, convert = 1;
2829 if (class_match_param(ptr, PARAM_TIMEOUT, &tmp) == 0) {
2830 cmd = LCFG_SET_TIMEOUT;
2831 } else if (class_match_param(ptr, PARAM_LDLM_TIMEOUT, &tmp) == 0) {
2832 cmd = LCFG_SET_LDLM_TIMEOUT;
2833 /* Check for known params here so we can return error to lctl */
2834 } else if ((class_match_param(ptr, PARAM_AT_MIN, &tmp) == 0) ||
2835 (class_match_param(ptr, PARAM_AT_MAX, &tmp) == 0) ||
2836 (class_match_param(ptr, PARAM_AT_EXTRA, &tmp) == 0) ||
2837 (class_match_param(ptr, PARAM_AT_EARLY_MARGIN, &tmp) == 0) ||
2838 (class_match_param(ptr, PARAM_AT_HISTORY, &tmp) == 0)) {
2840 } else if (class_match_param(ptr, PARAM_JOBID_VAR, &tmp) == 0) {
2841 convert = 0; /* Don't convert string value to integer */
2847 if (mgs_param_empty(ptr))
2848 CDEBUG(D_MGS, "global '%s' removed\n", sys);
2850 CDEBUG(D_MGS, "global '%s' val=%s\n", sys, tmp);
2852 lustre_cfg_bufs_reset(&mgi->mgi_bufs, NULL);
2853 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, sys);
2854 if (!convert && *tmp != '\0')
2855 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 2, tmp);
2856 lcfg = lustre_cfg_new(cmd, &mgi->mgi_bufs);
2857 lcfg->lcfg_num = convert ? simple_strtoul(tmp, NULL, 0) : 0;
2858 /* truncate the comment to the parameter name */
2862 /* modify all servers and clients */
2863 rc = mgs_write_log_direct_all(env, mgs, fsdb, mti,
2864 *tmp == '\0' ? NULL : lcfg,
2865 mti->mti_fsname, sys, 0);
2866 if (rc == 0 && *tmp != '\0') {
2868 case LCFG_SET_TIMEOUT:
2869 if (!obd_timeout_set || lcfg->lcfg_num > obd_timeout)
2870 class_process_config(lcfg);
2872 case LCFG_SET_LDLM_TIMEOUT:
2873 if (!ldlm_timeout_set || lcfg->lcfg_num > ldlm_timeout)
2874 class_process_config(lcfg);
2881 lustre_cfg_free(lcfg);
2885 /* write quota settings into log */
2886 static int mgs_write_log_quota(const struct lu_env *env, struct mgs_device *mgs,
2887 struct fs_db *fsdb, struct mgs_target_info *mti,
2888 char *quota, char *ptr)
2890 struct mgs_thread_info *mgi = mgs_env_info(env);
2891 struct lustre_cfg *lcfg;
2894 int rc, cmd = LCFG_PARAM;
2896 /* support only 'meta' and 'data' pools so far */
2897 if (class_match_param(ptr, QUOTA_METAPOOL_NAME, &tmp) != 0 &&
2898 class_match_param(ptr, QUOTA_DATAPOOL_NAME, &tmp) != 0) {
2899 CERROR("parameter quota.%s isn't supported (only quota.mdt "
2900 "& quota.ost are)\n", ptr);
2905 CDEBUG(D_MGS, "global '%s' removed\n", quota);
2907 CDEBUG(D_MGS, "global '%s'\n", quota);
2909 if (strchr(tmp, 'u') == NULL && strchr(tmp, 'g') == NULL &&
2910 strcmp(tmp, "none") != 0) {
2911 CERROR("enable option(%s) isn't supported\n", tmp);
2916 lustre_cfg_bufs_reset(&mgi->mgi_bufs, mti->mti_fsname);
2917 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, quota);
2918 lcfg = lustre_cfg_new(cmd, &mgi->mgi_bufs);
2919 /* truncate the comment to the parameter name */
2924 /* XXX we duplicated quota enable information in all server
2925 * config logs, it should be moved to a separate config
2926 * log once we cleanup the config log for global param. */
2927 /* modify all servers */
2928 rc = mgs_write_log_direct_all(env, mgs, fsdb, mti,
2929 *tmp == '\0' ? NULL : lcfg,
2930 mti->mti_fsname, quota, 1);
2932 lustre_cfg_free(lcfg);
2933 return rc < 0 ? rc : 0;
2936 static int mgs_srpc_set_param_disk(const struct lu_env *env,
2937 struct mgs_device *mgs,
2939 struct mgs_target_info *mti,
2942 struct mgs_thread_info *mgi = mgs_env_info(env);
2943 struct llog_handle *llh = NULL;
2945 char *comment, *ptr;
2946 struct lustre_cfg *lcfg;
2951 ptr = strchr(param, '=');
2955 OBD_ALLOC(comment, len + 1);
2956 if (comment == NULL)
2958 strncpy(comment, param, len);
2959 comment[len] = '\0';
2962 lustre_cfg_bufs_reset(&mgi->mgi_bufs, mti->mti_svname);
2963 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, param);
2964 lcfg = lustre_cfg_new(LCFG_SPTLRPC_CONF, &mgi->mgi_bufs);
2966 GOTO(out_comment, rc = -ENOMEM);
2968 /* construct log name */
2969 rc = name_create(&logname, mti->mti_fsname, "-sptlrpc");
2973 if (mgs_log_is_empty(env, mgs, logname)) {
2974 rc = record_start_log(env, mgs, &llh, logname);
2977 record_end_log(env, &llh);
2980 /* obsolete old one */
2981 rc = mgs_modify(env, mgs, fsdb, mti, logname, mti->mti_svname,
2985 /* write the new one */
2986 rc = mgs_write_log_direct(env, mgs, fsdb, logname, lcfg,
2987 mti->mti_svname, comment);
2989 CERROR("err %d writing log %s\n", rc, logname);
2991 name_destroy(&logname);
2993 lustre_cfg_free(lcfg);
2995 OBD_FREE(comment, len + 1);
2999 static int mgs_srpc_set_param_udesc_mem(struct fs_db *fsdb,
3004 /* disable the adjustable udesc parameter for now, i.e. use default
3005 * setting that client always ship udesc to MDT if possible. to enable
3006 * it simply remove the following line */
3009 ptr = strchr(param, '=');
3014 if (strcmp(param, PARAM_SRPC_UDESC))
3017 if (strcmp(ptr, "yes") == 0) {
3018 set_bit(FSDB_UDESC, &fsdb->fsdb_flags);
3019 CWARN("Enable user descriptor shipping from client to MDT\n");
3020 } else if (strcmp(ptr, "no") == 0) {
3021 clear_bit(FSDB_UDESC, &fsdb->fsdb_flags);
3022 CWARN("Disable user descriptor shipping from client to MDT\n");
3030 CERROR("Invalid param: %s\n", param);
3034 static int mgs_srpc_set_param_mem(struct fs_db *fsdb,
3038 struct sptlrpc_rule rule;
3039 struct sptlrpc_rule_set *rset;
3043 if (strncmp(param, PARAM_SRPC, sizeof(PARAM_SRPC) - 1) != 0) {
3044 CERROR("Invalid sptlrpc parameter: %s\n", param);
3048 if (strncmp(param, PARAM_SRPC_UDESC,
3049 sizeof(PARAM_SRPC_UDESC) - 1) == 0) {
3050 RETURN(mgs_srpc_set_param_udesc_mem(fsdb, param));
3053 if (strncmp(param, PARAM_SRPC_FLVR, sizeof(PARAM_SRPC_FLVR) - 1) != 0) {
3054 CERROR("Invalid sptlrpc flavor parameter: %s\n", param);
3058 param += sizeof(PARAM_SRPC_FLVR) - 1;
3060 rc = sptlrpc_parse_rule(param, &rule);
3064 /* mgs rules implies must be mgc->mgs */
3065 if (test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
3066 if ((rule.sr_from != LUSTRE_SP_MGC &&
3067 rule.sr_from != LUSTRE_SP_ANY) ||
3068 (rule.sr_to != LUSTRE_SP_MGS &&
3069 rule.sr_to != LUSTRE_SP_ANY))
3073 /* preapre room for this coming rule. svcname format should be:
3074 * - fsname: general rule
3075 * - fsname-tgtname: target-specific rule
3077 if (strchr(svname, '-')) {
3078 struct mgs_tgt_srpc_conf *tgtconf;
3081 for (tgtconf = fsdb->fsdb_srpc_tgt; tgtconf != NULL;
3082 tgtconf = tgtconf->mtsc_next) {
3083 if (!strcmp(tgtconf->mtsc_tgt, svname)) {
3092 OBD_ALLOC_PTR(tgtconf);
3093 if (tgtconf == NULL)
3096 name_len = strlen(svname);
3098 OBD_ALLOC(tgtconf->mtsc_tgt, name_len + 1);
3099 if (tgtconf->mtsc_tgt == NULL) {
3100 OBD_FREE_PTR(tgtconf);
3103 memcpy(tgtconf->mtsc_tgt, svname, name_len);
3105 tgtconf->mtsc_next = fsdb->fsdb_srpc_tgt;
3106 fsdb->fsdb_srpc_tgt = tgtconf;
3109 rset = &tgtconf->mtsc_rset;
3111 rset = &fsdb->fsdb_srpc_gen;
3114 rc = sptlrpc_rule_set_merge(rset, &rule);
3119 static int mgs_srpc_set_param(const struct lu_env *env,
3120 struct mgs_device *mgs,
3122 struct mgs_target_info *mti,
3132 /* keep a copy of original param, which could be destroied
3134 copy_size = strlen(param) + 1;
3135 OBD_ALLOC(copy, copy_size);
3138 memcpy(copy, param, copy_size);
3140 rc = mgs_srpc_set_param_mem(fsdb, mti->mti_svname, param);
3144 /* previous steps guaranteed the syntax is correct */
3145 rc = mgs_srpc_set_param_disk(env, mgs, fsdb, mti, copy);
3149 if (test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
3151 * for mgs rules, make them effective immediately.
3153 LASSERT(fsdb->fsdb_srpc_tgt == NULL);
3154 sptlrpc_target_update_exp_flavor(mgs->mgs_obd,
3155 &fsdb->fsdb_srpc_gen);
3159 OBD_FREE(copy, copy_size);
3163 struct mgs_srpc_read_data {
3164 struct fs_db *msrd_fsdb;
3168 static int mgs_srpc_read_handler(const struct lu_env *env,
3169 struct llog_handle *llh,
3170 struct llog_rec_hdr *rec, void *data)
3172 struct mgs_srpc_read_data *msrd = data;
3173 struct cfg_marker *marker;
3174 struct lustre_cfg *lcfg = REC_DATA(rec);
3175 char *svname, *param;
3179 if (rec->lrh_type != OBD_CFG_REC) {
3180 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
3184 cfg_len = rec->lrh_len - sizeof(struct llog_rec_hdr) -
3185 sizeof(struct llog_rec_tail);
3187 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
3189 CERROR("Insane cfg\n");
3193 if (lcfg->lcfg_command == LCFG_MARKER) {
3194 marker = lustre_cfg_buf(lcfg, 1);
3196 if (marker->cm_flags & CM_START &&
3197 marker->cm_flags & CM_SKIP)
3198 msrd->msrd_skip = 1;
3199 if (marker->cm_flags & CM_END)
3200 msrd->msrd_skip = 0;
3205 if (msrd->msrd_skip)
3208 if (lcfg->lcfg_command != LCFG_SPTLRPC_CONF) {
3209 CERROR("invalid command (%x)\n", lcfg->lcfg_command);
3213 svname = lustre_cfg_string(lcfg, 0);
3214 if (svname == NULL) {
3215 CERROR("svname is empty\n");
3219 param = lustre_cfg_string(lcfg, 1);
3220 if (param == NULL) {
3221 CERROR("param is empty\n");
3225 rc = mgs_srpc_set_param_mem(msrd->msrd_fsdb, svname, param);
3227 CERROR("read sptlrpc record error (%d): %s\n", rc, param);
3232 int mgs_get_fsdb_srpc_from_llog(const struct lu_env *env,
3233 struct mgs_device *mgs,
3236 struct llog_handle *llh = NULL;
3237 struct llog_ctxt *ctxt;
3239 struct mgs_srpc_read_data msrd;
3243 /* construct log name */
3244 rc = name_create(&logname, fsdb->fsdb_name, "-sptlrpc");
3248 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
3249 LASSERT(ctxt != NULL);
3251 if (mgs_log_is_empty(env, mgs, logname))
3254 rc = llog_open(env, ctxt, &llh, NULL, logname,
3262 rc = llog_init_handle(env, llh, LLOG_F_IS_PLAIN, NULL);
3264 GOTO(out_close, rc);
3266 if (llog_get_size(llh) <= 1)
3267 GOTO(out_close, rc = 0);
3269 msrd.msrd_fsdb = fsdb;
3272 rc = llog_process(env, llh, mgs_srpc_read_handler, (void *)&msrd,
3276 llog_close(env, llh);
3278 llog_ctxt_put(ctxt);
3279 name_destroy(&logname);
3282 CERROR("failed to read sptlrpc config database: %d\n", rc);
3286 /* Permanent settings of all parameters by writing into the appropriate
3287 * configuration logs.
3288 * A parameter with null value ("<param>='\0'") means to erase it out of
3291 static int mgs_write_log_param(const struct lu_env *env,
3292 struct mgs_device *mgs, struct fs_db *fsdb,
3293 struct mgs_target_info *mti, char *ptr)
3295 struct mgs_thread_info *mgi = mgs_env_info(env);
3298 int rc = 0, rc2 = 0;
3301 /* For various parameter settings, we have to figure out which logs
3302 care about them (e.g. both mdt and client for lov settings) */
3303 CDEBUG(D_MGS, "next param '%s'\n", ptr);
3305 /* The params are stored in MOUNT_DATA_FILE and modified via
3306 tunefs.lustre, or set using lctl conf_param */
3308 /* Processed in lustre_start_mgc */
3309 if (class_match_param(ptr, PARAM_MGSNODE, NULL) == 0)
3312 /* Processed in ost/mdt */
3313 if (class_match_param(ptr, PARAM_NETWORK, NULL) == 0)
3316 /* Processed in mgs_write_log_ost */
3317 if (class_match_param(ptr, PARAM_FAILMODE, NULL) == 0) {
3318 if (mti->mti_flags & LDD_F_PARAM) {
3319 LCONSOLE_ERROR_MSG(0x169, "%s can only be "
3320 "changed with tunefs.lustre"
3321 "and --writeconf\n", ptr);
3327 if (class_match_param(ptr, PARAM_SRPC, NULL) == 0) {
3328 rc = mgs_srpc_set_param(env, mgs, fsdb, mti, ptr);
3332 if (class_match_param(ptr, PARAM_FAILNODE, NULL) == 0) {
3333 /* Add a failover nidlist */
3335 /* We already processed failovers params for new
3336 targets in mgs_write_log_target */
3337 if (mti->mti_flags & LDD_F_PARAM) {
3338 CDEBUG(D_MGS, "Adding failnode\n");
3339 rc = mgs_write_log_add_failnid(env, mgs, fsdb, mti);
3344 if (class_match_param(ptr, PARAM_SYS, &tmp) == 0) {
3345 rc = mgs_write_log_sys(env, mgs, fsdb, mti, ptr, tmp);
3349 if (class_match_param(ptr, PARAM_QUOTA, &tmp) == 0) {
3350 rc = mgs_write_log_quota(env, mgs, fsdb, mti, ptr, tmp);
3354 if (class_match_param(ptr, PARAM_OSC""PARAM_ACTIVE, &tmp) == 0) {
3355 /* active=0 means off, anything else means on */
3356 int flag = (*tmp == '0') ? CM_EXCLUDE : 0;
3359 if (!(mti->mti_flags & LDD_F_SV_TYPE_OST)) {
3360 LCONSOLE_ERROR_MSG(0x144, "%s: Only OSCs can "
3361 "be (de)activated.\n",
3363 GOTO(end, rc = -EINVAL);
3365 LCONSOLE_WARN("Permanently %sactivating %s\n",
3366 flag ? "de": "re", mti->mti_svname);
3368 rc = name_create(&logname, mti->mti_fsname, "-client");
3371 rc = mgs_modify(env, mgs, fsdb, mti, logname,
3372 mti->mti_svname, "add osc", flag);
3373 name_destroy(&logname);
3377 /* Add to all MDT logs for CMD */
3378 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3379 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
3381 rc = name_create_mdt(&logname, mti->mti_fsname, i);
3384 rc = mgs_modify(env, mgs, fsdb, mti, logname,
3385 mti->mti_svname, "add osc", flag);
3386 name_destroy(&logname);
3392 LCONSOLE_ERROR_MSG(0x145, "Couldn't find %s in"
3393 "log (%d). No permanent "
3394 "changes were made to the "
3396 mti->mti_svname, rc);
3397 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags))
3398 LCONSOLE_ERROR_MSG(0x146, "This may be"
3403 "update the logs.\n");
3406 /* Fall through to osc proc for deactivating live OSC
3407 on running MDT / clients. */
3409 /* Below here, let obd's XXX_process_config methods handle it */
3411 /* All lov. in proc */
3412 if (class_match_param(ptr, PARAM_LOV, NULL) == 0) {
3415 CDEBUG(D_MGS, "lov param %s\n", ptr);
3416 if (!(mti->mti_flags & LDD_F_SV_TYPE_MDT)) {
3417 LCONSOLE_ERROR_MSG(0x147, "LOV params must be "
3418 "set on the MDT, not %s. "
3425 if (mgs_log_is_empty(env, mgs, mti->mti_svname))
3426 GOTO(end, rc = -ENODEV);
3428 rc = name_create_mdt_and_lov(&logname, &mdtlovname, fsdb,
3429 mti->mti_stripe_index);
3432 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, mti->mti_svname,
3433 &mgi->mgi_bufs, mdtlovname, ptr);
3434 name_destroy(&logname);
3435 name_destroy(&mdtlovname);
3440 rc = name_create(&logname, mti->mti_fsname, "-client");
3443 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname, &mgi->mgi_bufs,
3444 fsdb->fsdb_clilov, ptr);
3445 name_destroy(&logname);
3449 /* All osc., mdc., llite. params in proc */
3450 if ((class_match_param(ptr, PARAM_OSC, NULL) == 0) ||
3451 (class_match_param(ptr, PARAM_MDC, NULL) == 0) ||
3452 (class_match_param(ptr, PARAM_LLITE, NULL) == 0)) {
3455 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
3456 LCONSOLE_ERROR_MSG(0x148, "Upgraded client logs for %s"
3457 " cannot be modified. Consider"
3458 " updating the configuration with"
3461 GOTO(end, rc = -EINVAL);
3463 if (memcmp(ptr, PARAM_LLITE, strlen(PARAM_LLITE)) == 0) {
3464 rc = name_create(&cname, mti->mti_fsname, "-client");
3465 /* Add the client type to match the obdname in
3466 class_config_llog_handler */
3467 } else if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
3468 rc = name_create(&cname, mti->mti_svname, "-mdc");
3469 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
3470 rc = name_create(&cname, mti->mti_svname, "-osc");
3472 GOTO(end, rc = -EINVAL);
3477 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
3480 rc = name_create(&logname, mti->mti_fsname, "-client");
3482 name_destroy(&cname);
3485 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname, &mgi->mgi_bufs,
3488 /* osc params affect the MDT as well */
3489 if (!rc && (mti->mti_flags & LDD_F_SV_TYPE_OST)) {
3492 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
3493 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
3495 name_destroy(&cname);
3496 rc = name_create_mdt_osc(&cname, mti->mti_svname,
3498 name_destroy(&logname);
3501 rc = name_create_mdt(&logname,
3502 mti->mti_fsname, i);
3505 if (!mgs_log_is_empty(env, mgs, logname)) {
3506 rc = mgs_wlp_lcfg(env, mgs, fsdb,
3515 name_destroy(&logname);
3516 name_destroy(&cname);
3520 /* All mdt. params in proc */
3521 if (class_match_param(ptr, PARAM_MDT, NULL) == 0) {
3525 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
3526 if (strncmp(mti->mti_svname, mti->mti_fsname,
3527 MTI_NAME_MAXLEN) == 0)
3528 /* device is unspecified completely? */
3529 rc = LDD_F_SV_TYPE_MDT | LDD_F_SV_ALL;
3531 rc = server_name2index(mti->mti_svname, &idx, NULL);
3534 if ((rc & LDD_F_SV_TYPE_MDT) == 0)
3536 if (rc & LDD_F_SV_ALL) {
3537 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3539 fsdb->fsdb_mdt_index_map))
3541 rc = name_create_mdt(&logname,
3542 mti->mti_fsname, i);
3545 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti,
3546 logname, &mgi->mgi_bufs,
3548 name_destroy(&logname);
3553 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti,
3554 mti->mti_svname, &mgi->mgi_bufs,
3555 mti->mti_svname, ptr);
3562 /* All mdd., ost. params in proc */
3563 if ((class_match_param(ptr, PARAM_MDD, NULL) == 0) ||
3564 (class_match_param(ptr, PARAM_OST, NULL) == 0)) {
3565 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
3566 if (mgs_log_is_empty(env, mgs, mti->mti_svname))
3567 GOTO(end, rc = -ENODEV);
3569 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, mti->mti_svname,
3570 &mgi->mgi_bufs, mti->mti_svname, ptr);
3574 LCONSOLE_WARN("Ignoring unrecognized param '%s'\n", ptr);
3579 CERROR("err %d on param '%s'\n", rc, ptr);
3584 /* Not implementing automatic failover nid addition at this time. */
3585 int mgs_check_failnid(const struct lu_env *env, struct mgs_device *mgs,
3586 struct mgs_target_info *mti)
3593 rc = mgs_find_or_make_fsdb(obd, fsname, &fsdb);
3597 if (mgs_log_is_empty(obd, mti->mti_svname))
3598 /* should never happen */
3601 CDEBUG(D_MGS, "Checking for new failnids for %s\n", mti->mti_svname);
3603 /* FIXME We can just check mti->params to see if we're already in
3604 the failover list. Modify mti->params for rewriting back at
3605 server_register_target(). */
3607 mutex_lock(&fsdb->fsdb_mutex);
3608 rc = mgs_write_log_add_failnid(obd, fsdb, mti);
3609 mutex_unlock(&fsdb->fsdb_mutex);
3616 int mgs_write_log_target(const struct lu_env *env,
3617 struct mgs_device *mgs,
3618 struct mgs_target_info *mti,
3625 /* set/check the new target index */
3626 rc = mgs_set_index(env, mgs, mti);
3628 CERROR("Can't get index (%d)\n", rc);
3632 if (rc == EALREADY) {
3633 LCONSOLE_WARN("Found index %d for %s, updating log\n",
3634 mti->mti_stripe_index, mti->mti_svname);
3635 /* We would like to mark old log sections as invalid
3636 and add new log sections in the client and mdt logs.
3637 But if we add new sections, then live clients will
3638 get repeat setup instructions for already running
3639 osc's. So don't update the client/mdt logs. */
3640 mti->mti_flags &= ~LDD_F_UPDATE;
3644 mutex_lock(&fsdb->fsdb_mutex);
3646 if (mti->mti_flags &
3647 (LDD_F_VIRGIN | LDD_F_UPGRADE14 | LDD_F_WRITECONF)) {
3648 /* Generate a log from scratch */
3649 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
3650 rc = mgs_write_log_mdt(env, mgs, fsdb, mti);
3651 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
3652 rc = mgs_write_log_ost(env, mgs, fsdb, mti);
3654 CERROR("Unknown target type %#x, can't create log for "
3655 "%s\n", mti->mti_flags, mti->mti_svname);
3658 CERROR("Can't write logs for %s (%d)\n",
3659 mti->mti_svname, rc);
3663 /* Just update the params from tunefs in mgs_write_log_params */
3664 CDEBUG(D_MGS, "Update params for %s\n", mti->mti_svname);
3665 mti->mti_flags |= LDD_F_PARAM;
3668 /* allocate temporary buffer, where class_get_next_param will
3669 make copy of a current parameter */
3670 OBD_ALLOC(buf, strlen(mti->mti_params) + 1);
3672 GOTO(out_up, rc = -ENOMEM);
3673 params = mti->mti_params;
3674 while (params != NULL) {
3675 rc = class_get_next_param(¶ms, buf);
3678 /* there is no next parameter, that is
3683 CDEBUG(D_MGS, "remaining string: '%s', param: '%s'\n",
3685 rc = mgs_write_log_param(env, mgs, fsdb, mti, buf);
3690 OBD_FREE(buf, strlen(mti->mti_params) + 1);
3693 mutex_unlock(&fsdb->fsdb_mutex);
3697 int mgs_erase_log(const struct lu_env *env, struct mgs_device *mgs, char *name)
3699 struct llog_ctxt *ctxt;
3702 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
3704 CERROR("%s: MGS config context doesn't exist\n",
3705 mgs->mgs_obd->obd_name);
3708 rc = llog_erase(env, ctxt, NULL, name);
3709 /* llog may not exist */
3712 llog_ctxt_put(ctxt);
3716 CERROR("%s: failed to clear log %s: %d\n",
3717 mgs->mgs_obd->obd_name, name, rc);
3722 /* erase all logs for the given fs */
3723 int mgs_erase_logs(const struct lu_env *env, struct mgs_device *mgs, char *fsname)
3727 struct mgs_direntry *dirent, *n;
3728 int rc, len = strlen(fsname);
3732 /* Find all the logs in the CONFIGS directory */
3733 rc = class_dentry_readdir(env, mgs, &list);
3737 mutex_lock(&mgs->mgs_mutex);
3739 /* Delete the fs db */
3740 fsdb = mgs_find_fsdb(mgs, fsname);
3742 mgs_free_fsdb(mgs, fsdb);
3744 mutex_unlock(&mgs->mgs_mutex);
3746 cfs_list_for_each_entry_safe(dirent, n, &list, list) {
3747 cfs_list_del(&dirent->list);
3748 suffix = strrchr(dirent->name, '-');
3749 if (suffix != NULL) {
3750 if ((len == suffix - dirent->name) &&
3751 (strncmp(fsname, dirent->name, len) == 0)) {
3752 CDEBUG(D_MGS, "Removing log %s\n",
3754 mgs_erase_log(env, mgs, dirent->name);
3757 mgs_direntry_free(dirent);
3763 /* from llog_swab */
3764 static void print_lustre_cfg(struct lustre_cfg *lcfg)
3769 CDEBUG(D_MGS, "lustre_cfg: %p\n", lcfg);
3770 CDEBUG(D_MGS, "\tlcfg->lcfg_version: %#x\n", lcfg->lcfg_version);
3772 CDEBUG(D_MGS, "\tlcfg->lcfg_command: %#x\n", lcfg->lcfg_command);
3773 CDEBUG(D_MGS, "\tlcfg->lcfg_num: %#x\n", lcfg->lcfg_num);
3774 CDEBUG(D_MGS, "\tlcfg->lcfg_flags: %#x\n", lcfg->lcfg_flags);
3775 CDEBUG(D_MGS, "\tlcfg->lcfg_nid: %s\n", libcfs_nid2str(lcfg->lcfg_nid));
3777 CDEBUG(D_MGS, "\tlcfg->lcfg_bufcount: %d\n", lcfg->lcfg_bufcount);
3778 if (lcfg->lcfg_bufcount < LUSTRE_CFG_MAX_BUFCOUNT)
3779 for (i = 0; i < lcfg->lcfg_bufcount; i++) {
3780 CDEBUG(D_MGS, "\tlcfg->lcfg_buflens[%d]: %d %s\n",
3781 i, lcfg->lcfg_buflens[i],
3782 lustre_cfg_string(lcfg, i));
3787 /* Set a permanent (config log) param for a target or fs
3788 * \param lcfg buf0 may contain the device (testfs-MDT0000) name
3789 * buf1 contains the single parameter
3791 int mgs_setparam(const struct lu_env *env, struct mgs_device *mgs,
3792 struct lustre_cfg *lcfg, char *fsname)
3795 struct mgs_target_info *mti;
3796 char *devname, *param;
3803 print_lustre_cfg(lcfg);
3805 /* lustre, lustre-mdtlov, lustre-client, lustre-MDT0000 */
3806 devname = lustre_cfg_string(lcfg, 0);
3807 param = lustre_cfg_string(lcfg, 1);
3809 /* Assume device name embedded in param:
3810 lustre-OST0000.osc.max_dirty_mb=32 */
3811 ptr = strchr(param, '.');
3819 LCONSOLE_ERROR_MSG(0x14d, "No target specified: %s\n", param);
3823 rc = mgs_parse_devname(devname, fsname, NULL);
3824 if (rc == 0 && !mgs_parse_devname(devname, NULL, &index)) {
3825 /* param related to llite isn't allowed to set by OST or MDT */
3826 if (rc == 0 && strncmp(param, PARAM_LLITE,
3827 sizeof(PARAM_LLITE)) == 0)
3830 /* assume devname is the fsname */
3831 memset(fsname, 0, MTI_NAME_MAXLEN);
3832 strncpy(fsname, devname, MTI_NAME_MAXLEN);
3833 fsname[MTI_NAME_MAXLEN - 1] = 0;
3835 CDEBUG(D_MGS, "setparam fs='%s' device='%s'\n", fsname, devname);
3837 rc = mgs_find_or_make_fsdb(env, mgs, fsname, &fsdb);
3840 if (!test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags) &&
3841 test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
3842 CERROR("No filesystem targets for %s. cfg_device from lctl "
3843 "is '%s'\n", fsname, devname);
3844 mgs_free_fsdb(mgs, fsdb);
3848 /* Create a fake mti to hold everything */
3851 GOTO(out, rc = -ENOMEM);
3852 if (strlcpy(mti->mti_fsname, fsname, sizeof(mti->mti_fsname))
3853 >= sizeof(mti->mti_fsname))
3854 GOTO(out, rc = -E2BIG);
3855 if (strlcpy(mti->mti_svname, devname, sizeof(mti->mti_svname))
3856 >= sizeof(mti->mti_svname))
3857 GOTO(out, rc = -E2BIG);
3858 if (strlcpy(mti->mti_params, param, sizeof(mti->mti_params))
3859 >= sizeof(mti->mti_params))
3860 GOTO(out, rc = -E2BIG);
3861 rc = server_name2index(mti->mti_svname, &mti->mti_stripe_index, &tmp);
3863 /* Not a valid server; may be only fsname */
3866 /* Strip -osc or -mdc suffix from svname */
3867 if (server_make_name(rc, mti->mti_stripe_index, mti->mti_fsname,
3869 GOTO(out, rc = -EINVAL);
3871 mti->mti_flags = rc | LDD_F_PARAM;
3873 mutex_lock(&fsdb->fsdb_mutex);
3874 rc = mgs_write_log_param(env, mgs, fsdb, mti, mti->mti_params);
3875 mutex_unlock(&fsdb->fsdb_mutex);
3878 * Revoke lock so everyone updates. Should be alright if
3879 * someone was already reading while we were updating the logs,
3880 * so we don't really need to hold the lock while we're
3883 mgs_revoke_lock(mgs, fsdb, CONFIG_T_CONFIG);
3889 static int mgs_write_log_pool(const struct lu_env *env,
3890 struct mgs_device *mgs, char *logname,
3891 struct fs_db *fsdb, char *lovname,
3892 enum lcfg_command_type cmd,
3893 char *poolname, char *fsname,
3894 char *ostname, char *comment)
3896 struct llog_handle *llh = NULL;
3899 rc = record_start_log(env, mgs, &llh, logname);
3902 rc = record_marker(env, llh, fsdb, CM_START, lovname, comment);
3905 rc = record_base(env, llh, lovname, 0, cmd, poolname, fsname, ostname, 0);
3908 rc = record_marker(env, llh, fsdb, CM_END, lovname, comment);
3910 record_end_log(env, &llh);
3914 int mgs_pool_cmd(const struct lu_env *env, struct mgs_device *mgs,
3915 enum lcfg_command_type cmd, char *fsname,
3916 char *poolname, char *ostname)
3921 char *label = NULL, *canceled_label = NULL;
3923 struct mgs_target_info *mti = NULL;
3927 rc = mgs_find_or_make_fsdb(env, mgs, fsname, &fsdb);
3929 CERROR("Can't get db for %s\n", fsname);
3932 if (test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
3933 CERROR("%s is not defined\n", fsname);
3934 mgs_free_fsdb(mgs, fsdb);
3938 label_sz = 10 + strlen(fsname) + strlen(poolname);
3940 /* check if ostname match fsname */
3941 if (ostname != NULL) {
3944 ptr = strrchr(ostname, '-');
3945 if ((ptr == NULL) ||
3946 (strncmp(fsname, ostname, ptr-ostname) != 0))
3948 label_sz += strlen(ostname);
3951 OBD_ALLOC(label, label_sz);
3958 "new %s.%s", fsname, poolname);
3962 "add %s.%s.%s", fsname, poolname, ostname);
3965 OBD_ALLOC(canceled_label, label_sz);
3966 if (canceled_label == NULL)
3967 GOTO(out_label, rc = -ENOMEM);
3969 "rem %s.%s.%s", fsname, poolname, ostname);
3970 sprintf(canceled_label,
3971 "add %s.%s.%s", fsname, poolname, ostname);
3974 OBD_ALLOC(canceled_label, label_sz);
3975 if (canceled_label == NULL)
3976 GOTO(out_label, rc = -ENOMEM);
3978 "del %s.%s", fsname, poolname);
3979 sprintf(canceled_label,
3980 "new %s.%s", fsname, poolname);
3986 mutex_lock(&fsdb->fsdb_mutex);
3988 if (canceled_label != NULL) {
3991 GOTO(out_cancel, rc = -ENOMEM);
3994 /* write pool def to all MDT logs */
3995 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3996 if (test_bit(i, fsdb->fsdb_mdt_index_map)) {
3997 rc = name_create_mdt_and_lov(&logname, &lovname,
4000 mutex_unlock(&fsdb->fsdb_mutex);
4003 if (canceled_label != NULL) {
4004 strcpy(mti->mti_svname, "lov pool");
4005 rc = mgs_modify(env, mgs, fsdb, mti, logname,
4006 lovname, canceled_label,
4011 rc = mgs_write_log_pool(env, mgs, logname,
4015 name_destroy(&logname);
4016 name_destroy(&lovname);
4018 mutex_unlock(&fsdb->fsdb_mutex);
4024 rc = name_create(&logname, fsname, "-client");
4026 mutex_unlock(&fsdb->fsdb_mutex);
4029 if (canceled_label != NULL) {
4030 rc = mgs_modify(env, mgs, fsdb, mti, logname,
4031 fsdb->fsdb_clilov, canceled_label, CM_SKIP);
4033 mutex_unlock(&fsdb->fsdb_mutex);
4034 name_destroy(&logname);
4039 rc = mgs_write_log_pool(env, mgs, logname, fsdb, fsdb->fsdb_clilov,
4040 cmd, fsname, poolname, ostname, label);
4041 mutex_unlock(&fsdb->fsdb_mutex);
4042 name_destroy(&logname);
4043 /* request for update */
4044 mgs_revoke_lock(mgs, fsdb, CONFIG_T_CONFIG);
4051 if (canceled_label != NULL)
4052 OBD_FREE(canceled_label, label_sz);
4054 OBD_FREE(label, label_sz);