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);
1928 name_destroy(&failnodeuuid);
1929 failnodeuuid = NULL;
1936 static int mgs_write_log_mdc_to_lmv(const struct lu_env *env,
1937 struct mgs_device *mgs,
1939 struct mgs_target_info *mti,
1940 char *logname, char *lmvname)
1942 struct llog_handle *llh = NULL;
1943 char *mdcname = NULL;
1944 char *nodeuuid = NULL;
1945 char *mdcuuid = NULL;
1946 char *lmvuuid = NULL;
1951 if (mgs_log_is_empty(env, mgs, logname)) {
1952 CERROR("log is empty! Logical error\n");
1956 CDEBUG(D_MGS, "adding mdc for %s to log %s:lmv(%s)\n",
1957 mti->mti_svname, logname, lmvname);
1959 rc = name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
1962 rc = name_create(&mdcname, mti->mti_svname, "-mdc");
1965 rc = name_create(&mdcuuid, mdcname, "_UUID");
1968 rc = name_create(&lmvuuid, lmvname, "_UUID");
1972 rc = record_start_log(env, mgs, &llh, logname);
1975 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
1979 for (i = 0; i < mti->mti_nid_count; i++) {
1980 CDEBUG(D_MGS, "add nid %s for mdt\n",
1981 libcfs_nid2str(mti->mti_nids[i]));
1983 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
1988 rc = record_attach(env, llh, mdcname, LUSTRE_MDC_NAME, lmvuuid);
1991 rc = record_setup(env, llh, mdcname, mti->mti_uuid, nodeuuid, 0, 0);
1994 rc = mgs_write_log_failnids(env, mti, llh, mdcname);
1997 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
1998 rc = record_mdc_add(env, llh, lmvname, mdcuuid, mti->mti_uuid,
2002 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname,
2007 record_end_log(env, &llh);
2009 name_destroy(&lmvuuid);
2010 name_destroy(&mdcuuid);
2011 name_destroy(&mdcname);
2012 name_destroy(&nodeuuid);
2016 static inline int name_create_lov(char **lovname, char *mdtname,
2017 struct fs_db *fsdb, int index)
2020 if (index == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2021 return name_create(lovname, fsdb->fsdb_name, "-mdtlov");
2023 return name_create(lovname, mdtname, "-mdtlov");
2026 static int name_create_mdt_and_lov(char **logname, char **lovname,
2027 struct fs_db *fsdb, int i)
2031 rc = name_create_mdt(logname, fsdb->fsdb_name, i);
2035 if (i == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2036 rc = name_create(lovname, fsdb->fsdb_name, "-mdtlov");
2038 rc = name_create(lovname, *logname, "-mdtlov");
2040 name_destroy(logname);
2046 static inline int name_create_mdt_osc(char **oscname, char *ostname,
2047 struct fs_db *fsdb, int i)
2051 if (i == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2052 sprintf(suffix, "-osc");
2054 sprintf(suffix, "-osc-MDT%04x", i);
2055 return name_create(oscname, ostname, suffix);
2058 /* add new mdc to already existent MDS */
2059 static int mgs_write_log_osp_to_mdt(const struct lu_env *env,
2060 struct mgs_device *mgs,
2062 struct mgs_target_info *mti,
2063 int mdt_index, char *logname)
2065 struct llog_handle *llh = NULL;
2066 char *nodeuuid = NULL;
2067 char *ospname = NULL;
2068 char *lovuuid = NULL;
2069 char *mdtuuid = NULL;
2070 char *svname = NULL;
2071 char *mdtname = NULL;
2072 char *lovname = NULL;
2077 if (mgs_log_is_empty(env, mgs, mti->mti_svname)) {
2078 CERROR("log is empty! Logical error\n");
2082 CDEBUG(D_MGS, "adding osp index %d to %s\n", mti->mti_stripe_index,
2085 rc = name_create_mdt(&mdtname, fsdb->fsdb_name, mti->mti_stripe_index);
2089 rc = name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
2091 GOTO(out_destory, rc);
2093 rc = name_create(&svname, mdtname, "-osp");
2095 GOTO(out_destory, rc);
2097 sprintf(index_str, "-MDT%04x", mdt_index);
2098 rc = name_create(&ospname, svname, index_str);
2100 GOTO(out_destory, rc);
2102 rc = name_create_lov(&lovname, logname, fsdb, mdt_index);
2104 GOTO(out_destory, rc);
2106 rc = name_create(&lovuuid, lovname, "_UUID");
2108 GOTO(out_destory, rc);
2110 rc = name_create(&mdtuuid, mdtname, "_UUID");
2112 GOTO(out_destory, rc);
2114 rc = record_start_log(env, mgs, &llh, logname);
2116 GOTO(out_destory, rc);
2118 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
2121 GOTO(out_destory, rc);
2123 for (i = 0; i < mti->mti_nid_count; i++) {
2124 CDEBUG(D_MGS, "add nid %s for mdt\n",
2125 libcfs_nid2str(mti->mti_nids[i]));
2126 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
2131 rc = record_attach(env, llh, ospname, LUSTRE_OSP_NAME, lovuuid);
2135 rc = record_setup(env, llh, ospname, mti->mti_uuid, nodeuuid,
2140 rc = mgs_write_log_failnids(env, mti, llh, ospname);
2144 /* Add mdc(osp) to lod */
2145 snprintf(index_str, sizeof(mti->mti_stripe_index), "%d",
2146 mti->mti_stripe_index);
2147 rc = record_base(env, llh, lovname, 0, LCFG_ADD_MDC, mti->mti_uuid,
2148 index_str, "1", NULL);
2152 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname, "add osp");
2157 record_end_log(env, &llh);
2160 name_destroy(&mdtuuid);
2161 name_destroy(&lovuuid);
2162 name_destroy(&lovname);
2163 name_destroy(&ospname);
2164 name_destroy(&svname);
2165 name_destroy(&nodeuuid);
2166 name_destroy(&mdtname);
2170 static int mgs_write_log_mdt0(const struct lu_env *env,
2171 struct mgs_device *mgs,
2173 struct mgs_target_info *mti)
2175 char *log = mti->mti_svname;
2176 struct llog_handle *llh = NULL;
2177 char *uuid, *lovname;
2179 char *ptr = mti->mti_params;
2180 int rc = 0, failout = 0;
2183 OBD_ALLOC(uuid, sizeof(struct obd_uuid));
2187 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
2188 failout = (strncmp(ptr, "failout", 7) == 0);
2190 rc = name_create(&lovname, log, "-mdtlov");
2193 if (mgs_log_is_empty(env, mgs, log)) {
2194 rc = mgs_write_log_lov(env, mgs, fsdb, mti, log, lovname);
2199 sprintf(mdt_index, "%d", mti->mti_stripe_index);
2201 rc = record_start_log(env, mgs, &llh, log);
2205 /* add MDT itself */
2207 /* FIXME this whole fn should be a single journal transaction */
2208 sprintf(uuid, "%s_UUID", log);
2209 rc = record_marker(env, llh, fsdb, CM_START, log, "add mdt");
2212 rc = record_attach(env, llh, log, LUSTRE_MDT_NAME, uuid);
2215 rc = record_mount_opt(env, llh, log, lovname, NULL);
2218 rc = record_setup(env, llh, log, uuid, mdt_index, lovname,
2219 failout ? "n" : "f");
2222 rc = record_marker(env, llh, fsdb, CM_END, log, "add mdt");
2226 record_end_log(env, &llh);
2228 name_destroy(&lovname);
2230 OBD_FREE(uuid, sizeof(struct obd_uuid));
2234 /* envelope method for all layers log */
2235 static int mgs_write_log_mdt(const struct lu_env *env,
2236 struct mgs_device *mgs,
2238 struct mgs_target_info *mti)
2240 struct mgs_thread_info *mgi = mgs_env_info(env);
2241 struct llog_handle *llh = NULL;
2246 CDEBUG(D_MGS, "writing new mdt %s\n", mti->mti_svname);
2248 if (mti->mti_uuid[0] == '\0') {
2249 /* Make up our own uuid */
2250 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
2251 "%s_UUID", mti->mti_svname);
2255 rc = mgs_write_log_mdt0(env, mgs, fsdb, mti);
2258 /* Append the mdt info to the client log */
2259 rc = name_create(&cliname, mti->mti_fsname, "-client");
2263 if (mgs_log_is_empty(env, mgs, cliname)) {
2264 /* Start client log */
2265 rc = mgs_write_log_lov(env, mgs, fsdb, mti, cliname,
2269 rc = mgs_write_log_lmv(env, mgs, fsdb, mti, cliname,
2276 #09 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
2277 #10 L attach 0:MDC_uml1_mdsA_MNT_client 1:mdc 2:1d834_MNT_client_03f
2278 #11 L setup 0:MDC_uml1_mdsA_MNT_client 1:mdsA_UUID 2:uml1_UUID
2279 #12 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
2280 #13 L add_conn 0:MDC_uml1_mdsA_MNT_client 1:uml2_UUID
2281 #14 L mount_option 0: 1:client 2:lov1 3:MDC_uml1_mdsA_MNT_client
2284 /* copy client info about lov/lmv */
2285 mgi->mgi_comp.comp_mti = mti;
2286 mgi->mgi_comp.comp_fsdb = fsdb;
2288 rc = mgs_steal_llog_for_mdt_from_client(env, mgs, cliname,
2292 rc = mgs_write_log_mdc_to_lmv(env, mgs, fsdb, mti, cliname,
2298 rc = record_start_log(env, mgs, &llh, cliname);
2302 rc = record_marker(env, llh, fsdb, CM_START, cliname,
2306 rc = record_mount_opt(env, llh, cliname, fsdb->fsdb_clilov,
2310 rc = record_marker(env, llh, fsdb, CM_END, cliname,
2316 /* for_all_existing_mdt except current one */
2317 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2318 if (i != mti->mti_stripe_index &&
2319 test_bit(i, fsdb->fsdb_mdt_index_map)) {
2322 rc = name_create_mdt(&logname, fsdb->fsdb_name, i);
2326 rc = mgs_write_log_osp_to_mdt(env, mgs, fsdb, mti,
2328 name_destroy(&logname);
2334 record_end_log(env, &llh);
2336 name_destroy(&cliname);
2340 /* Add the ost info to the client/mdt lov */
2341 static int mgs_write_log_osc_to_lov(const struct lu_env *env,
2342 struct mgs_device *mgs, struct fs_db *fsdb,
2343 struct mgs_target_info *mti,
2344 char *logname, char *suffix, char *lovname,
2345 enum lustre_sec_part sec_part, int flags)
2347 struct llog_handle *llh = NULL;
2348 char *nodeuuid = NULL;
2349 char *oscname = NULL;
2350 char *oscuuid = NULL;
2351 char *lovuuid = NULL;
2352 char *svname = NULL;
2357 CDEBUG(D_INFO, "adding osc for %s to log %s\n",
2358 mti->mti_svname, logname);
2360 if (mgs_log_is_empty(env, mgs, logname)) {
2361 CERROR("log is empty! Logical error\n");
2365 rc = name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
2368 rc = name_create(&svname, mti->mti_svname, "-osc");
2372 /* for the system upgraded from old 1.8, keep using the old osc naming
2373 * style for mdt, see name_create_mdt_osc(). LU-1257 */
2374 if (test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2375 rc = name_create(&oscname, svname, "");
2377 rc = name_create(&oscname, svname, suffix);
2381 rc = name_create(&oscuuid, oscname, "_UUID");
2384 rc = name_create(&lovuuid, lovname, "_UUID");
2390 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
2392 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
2393 #04 L attach 0:OSC_uml1_ost1_MNT_client 1:osc 2:89070_lov1_a41dff51a
2394 #05 L setup 0:OSC_uml1_ost1_MNT_client 1:ost1_UUID 2:uml1_UUID
2396 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
2397 #07 L add_conn 0:OSC_uml1_ost1_MNT_client 1:uml2_UUID
2398 #08 L lov_modify_tgts add 0:lov1 1:ost1_UUID 2(index):0 3(gen):1
2401 rc = record_start_log(env, mgs, &llh, logname);
2405 /* FIXME these should be a single journal transaction */
2406 rc = record_marker(env, llh, fsdb, CM_START | flags, mti->mti_svname,
2411 /* NB: don't change record order, because upon MDT steal OSC config
2412 * from client, it treats all nids before LCFG_SETUP as target nids
2413 * (multiple interfaces), while nids after as failover node nids.
2414 * See mgs_steal_client_llog_handler() LCFG_ADD_UUID.
2416 for (i = 0; i < mti->mti_nid_count; i++) {
2417 CDEBUG(D_MGS, "add nid %s\n", libcfs_nid2str(mti->mti_nids[i]));
2418 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
2422 rc = record_attach(env, llh, oscname, LUSTRE_OSC_NAME, lovuuid);
2425 rc = record_setup(env, llh, oscname, mti->mti_uuid, nodeuuid, 0, 0);
2428 rc = mgs_write_log_failnids(env, mti, llh, oscname);
2432 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
2434 rc = record_lov_add(env, llh, lovname, mti->mti_uuid, index, "1");
2437 rc = record_marker(env, llh, fsdb, CM_END | flags, mti->mti_svname,
2442 record_end_log(env, &llh);
2444 name_destroy(&lovuuid);
2445 name_destroy(&oscuuid);
2446 name_destroy(&oscname);
2447 name_destroy(&svname);
2448 name_destroy(&nodeuuid);
2452 static int mgs_write_log_ost(const struct lu_env *env,
2453 struct mgs_device *mgs, struct fs_db *fsdb,
2454 struct mgs_target_info *mti)
2456 struct llog_handle *llh = NULL;
2457 char *logname, *lovname;
2458 char *ptr = mti->mti_params;
2459 int rc, flags = 0, failout = 0, i;
2462 CDEBUG(D_MGS, "writing new ost %s\n", mti->mti_svname);
2464 /* The ost startup log */
2466 /* If the ost log already exists, that means that someone reformatted
2467 the ost and it called target_add again. */
2468 if (!mgs_log_is_empty(env, mgs, mti->mti_svname)) {
2469 LCONSOLE_ERROR_MSG(0x141, "The config log for %s already "
2470 "exists, yet the server claims it never "
2471 "registered. It may have been reformatted, "
2472 "or the index changed. writeconf the MDT to "
2473 "regenerate all logs.\n", mti->mti_svname);
2478 attach obdfilter ost1 ost1_UUID
2479 setup /dev/loop2 ldiskfs f|n errors=remount-ro,user_xattr
2481 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
2482 failout = (strncmp(ptr, "failout", 7) == 0);
2483 rc = record_start_log(env, mgs, &llh, mti->mti_svname);
2486 /* FIXME these should be a single journal transaction */
2487 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,"add ost");
2490 if (*mti->mti_uuid == '\0')
2491 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
2492 "%s_UUID", mti->mti_svname);
2493 rc = record_attach(env, llh, mti->mti_svname,
2494 "obdfilter"/*LUSTRE_OST_NAME*/, mti->mti_uuid);
2497 rc = record_setup(env, llh, mti->mti_svname,
2498 "dev"/*ignored*/, "type"/*ignored*/,
2499 failout ? "n" : "f", 0/*options*/);
2502 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname, "add ost");
2506 record_end_log(env, &llh);
2509 /* We also have to update the other logs where this osc is part of
2512 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
2513 /* If we're upgrading, the old mdt log already has our
2514 entry. Let's do a fake one for fun. */
2515 /* Note that we can't add any new failnids, since we don't
2516 know the old osc names. */
2517 flags = CM_SKIP | CM_UPGRADE146;
2519 } else if ((mti->mti_flags & LDD_F_UPDATE) != LDD_F_UPDATE) {
2520 /* If the update flag isn't set, don't update client/mdt
2523 LCONSOLE_WARN("Client log for %s was not updated; writeconf "
2524 "the MDT first to regenerate it.\n",
2528 /* Add ost to all MDT lov defs */
2529 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
2530 if (test_bit(i, fsdb->fsdb_mdt_index_map)) {
2533 rc = name_create_mdt_and_lov(&logname, &lovname, fsdb,
2537 sprintf(mdt_index, "-MDT%04x", i);
2538 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, mti,
2540 lovname, LUSTRE_SP_MDT,
2542 name_destroy(&logname);
2543 name_destroy(&lovname);
2549 /* Append ost info to the client log */
2550 rc = name_create(&logname, mti->mti_fsname, "-client");
2553 if (mgs_log_is_empty(env, mgs, logname)) {
2554 /* Start client log */
2555 rc = mgs_write_log_lov(env, mgs, fsdb, mti, logname,
2559 rc = mgs_write_log_lmv(env, mgs, fsdb, mti, logname,
2564 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, mti, logname, "",
2565 fsdb->fsdb_clilov, LUSTRE_SP_CLI, 0);
2567 name_destroy(&logname);
2571 static __inline__ int mgs_param_empty(char *ptr)
2575 if ((tmp = strchr(ptr, '=')) && (*(++tmp) == '\0'))
2580 static int mgs_write_log_failnid_internal(const struct lu_env *env,
2581 struct mgs_device *mgs,
2583 struct mgs_target_info *mti,
2584 char *logname, char *cliname)
2587 struct llog_handle *llh = NULL;
2589 if (mgs_param_empty(mti->mti_params)) {
2590 /* Remove _all_ failnids */
2591 rc = mgs_modify(env, mgs, fsdb, mti, logname,
2592 mti->mti_svname, "add failnid", CM_SKIP);
2593 return rc < 0 ? rc : 0;
2596 /* Otherwise failover nids are additive */
2597 rc = record_start_log(env, mgs, &llh, logname);
2600 /* FIXME this should be a single journal transaction */
2601 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
2605 rc = mgs_write_log_failnids(env, mti, llh, cliname);
2608 rc = record_marker(env, llh, fsdb, CM_END,
2609 mti->mti_svname, "add failnid");
2611 record_end_log(env, &llh);
2616 /* Add additional failnids to an existing log.
2617 The mdc/osc must have been added to logs first */
2618 /* tcp nids must be in dotted-quad ascii -
2619 we can't resolve hostnames from the kernel. */
2620 static int mgs_write_log_add_failnid(const struct lu_env *env,
2621 struct mgs_device *mgs,
2623 struct mgs_target_info *mti)
2625 char *logname, *cliname;
2629 /* FIXME we currently can't erase the failnids
2630 * given when a target first registers, since they aren't part of
2631 * an "add uuid" stanza */
2633 /* Verify that we know about this target */
2634 if (mgs_log_is_empty(env, mgs, mti->mti_svname)) {
2635 LCONSOLE_ERROR_MSG(0x142, "The target %s has not registered "
2636 "yet. It must be started before failnids "
2637 "can be added.\n", mti->mti_svname);
2641 /* Create mdc/osc client name (e.g. lustre-OST0001-osc) */
2642 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
2643 rc = name_create(&cliname, mti->mti_svname, "-mdc");
2644 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2645 rc = name_create(&cliname, mti->mti_svname, "-osc");
2651 /* Add failover nids to the client log */
2652 rc = name_create(&logname, mti->mti_fsname, "-client");
2654 name_destroy(&cliname);
2657 rc = mgs_write_log_failnid_internal(env, mgs, fsdb,mti,logname,cliname);
2658 name_destroy(&logname);
2659 name_destroy(&cliname);
2663 if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2664 /* Add OST failover nids to the MDT logs as well */
2667 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2668 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
2670 rc = name_create_mdt(&logname, mti->mti_fsname, i);
2673 rc = name_create_mdt_osc(&cliname, mti->mti_svname,
2676 name_destroy(&logname);
2679 rc = mgs_write_log_failnid_internal(env, mgs, fsdb,
2682 name_destroy(&cliname);
2683 name_destroy(&logname);
2692 static int mgs_wlp_lcfg(const struct lu_env *env,
2693 struct mgs_device *mgs, struct fs_db *fsdb,
2694 struct mgs_target_info *mti,
2695 char *logname, struct lustre_cfg_bufs *bufs,
2696 char *tgtname, char *ptr)
2698 char comment[MTI_NAME_MAXLEN];
2700 struct lustre_cfg *lcfg;
2703 /* Erase any old settings of this same parameter */
2704 memcpy(comment, ptr, MTI_NAME_MAXLEN);
2705 comment[MTI_NAME_MAXLEN - 1] = 0;
2706 /* But don't try to match the value. */
2707 if ((tmp = strchr(comment, '=')))
2709 /* FIXME we should skip settings that are the same as old values */
2710 rc = mgs_modify(env, mgs, fsdb, mti, logname, tgtname, comment,CM_SKIP);
2713 del = mgs_param_empty(ptr);
2715 LCONSOLE_INFO("%sing parameter %s.%s in log %s\n", del ? "Disabl" : rc ?
2716 "Sett" : "Modify", tgtname, comment, logname);
2720 lustre_cfg_bufs_reset(bufs, tgtname);
2721 lustre_cfg_bufs_set_string(bufs, 1, ptr);
2722 if (mti->mti_flags & LDD_F_PARAM2)
2723 lustre_cfg_bufs_set_string(bufs, 2, LCTL_UPCALL);
2725 lcfg = lustre_cfg_new((mti->mti_flags & LDD_F_PARAM2) ?
2726 LCFG_SET_PARAM : LCFG_PARAM, bufs);
2730 rc = mgs_write_log_direct(env, mgs, fsdb, logname,lcfg,tgtname,comment);
2731 lustre_cfg_free(lcfg);
2735 static int mgs_write_log_param2(const struct lu_env *env,
2736 struct mgs_device *mgs,
2738 struct mgs_target_info *mti, char *ptr)
2740 struct lustre_cfg_bufs bufs;
2744 CDEBUG(D_MGS, "next param '%s'\n", ptr);
2745 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, PARAMS_FILENAME, &bufs,
2746 mti->mti_svname, ptr);
2751 /* write global variable settings into log */
2752 static int mgs_write_log_sys(const struct lu_env *env,
2753 struct mgs_device *mgs, struct fs_db *fsdb,
2754 struct mgs_target_info *mti, char *sys, char *ptr)
2756 struct mgs_thread_info *mgi = mgs_env_info(env);
2757 struct lustre_cfg *lcfg;
2759 int rc, cmd, convert = 1;
2761 if (class_match_param(ptr, PARAM_TIMEOUT, &tmp) == 0) {
2762 cmd = LCFG_SET_TIMEOUT;
2763 } else if (class_match_param(ptr, PARAM_LDLM_TIMEOUT, &tmp) == 0) {
2764 cmd = LCFG_SET_LDLM_TIMEOUT;
2765 /* Check for known params here so we can return error to lctl */
2766 } else if ((class_match_param(ptr, PARAM_AT_MIN, &tmp) == 0) ||
2767 (class_match_param(ptr, PARAM_AT_MAX, &tmp) == 0) ||
2768 (class_match_param(ptr, PARAM_AT_EXTRA, &tmp) == 0) ||
2769 (class_match_param(ptr, PARAM_AT_EARLY_MARGIN, &tmp) == 0) ||
2770 (class_match_param(ptr, PARAM_AT_HISTORY, &tmp) == 0)) {
2772 } else if (class_match_param(ptr, PARAM_JOBID_VAR, &tmp) == 0) {
2773 convert = 0; /* Don't convert string value to integer */
2779 if (mgs_param_empty(ptr))
2780 CDEBUG(D_MGS, "global '%s' removed\n", sys);
2782 CDEBUG(D_MGS, "global '%s' val=%s\n", sys, tmp);
2784 lustre_cfg_bufs_reset(&mgi->mgi_bufs, NULL);
2785 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, sys);
2786 if (!convert && *tmp != '\0')
2787 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 2, tmp);
2788 lcfg = lustre_cfg_new(cmd, &mgi->mgi_bufs);
2789 lcfg->lcfg_num = convert ? simple_strtoul(tmp, NULL, 0) : 0;
2790 /* truncate the comment to the parameter name */
2794 /* modify all servers and clients */
2795 rc = mgs_write_log_direct_all(env, mgs, fsdb, mti,
2796 *tmp == '\0' ? NULL : lcfg,
2797 mti->mti_fsname, sys, 0);
2798 if (rc == 0 && *tmp != '\0') {
2800 case LCFG_SET_TIMEOUT:
2801 if (!obd_timeout_set || lcfg->lcfg_num > obd_timeout)
2802 class_process_config(lcfg);
2804 case LCFG_SET_LDLM_TIMEOUT:
2805 if (!ldlm_timeout_set || lcfg->lcfg_num > ldlm_timeout)
2806 class_process_config(lcfg);
2813 lustre_cfg_free(lcfg);
2817 /* write quota settings into log */
2818 static int mgs_write_log_quota(const struct lu_env *env, struct mgs_device *mgs,
2819 struct fs_db *fsdb, struct mgs_target_info *mti,
2820 char *quota, char *ptr)
2822 struct mgs_thread_info *mgi = mgs_env_info(env);
2823 struct lustre_cfg *lcfg;
2826 int rc, cmd = LCFG_PARAM;
2828 /* support only 'meta' and 'data' pools so far */
2829 if (class_match_param(ptr, QUOTA_METAPOOL_NAME, &tmp) != 0 &&
2830 class_match_param(ptr, QUOTA_DATAPOOL_NAME, &tmp) != 0) {
2831 CERROR("parameter quota.%s isn't supported (only quota.mdt "
2832 "& quota.ost are)\n", ptr);
2837 CDEBUG(D_MGS, "global '%s' removed\n", quota);
2839 CDEBUG(D_MGS, "global '%s'\n", quota);
2841 if (strchr(tmp, 'u') == NULL && strchr(tmp, 'g') == NULL &&
2842 strcmp(tmp, "none") != 0) {
2843 CERROR("enable option(%s) isn't supported\n", tmp);
2848 lustre_cfg_bufs_reset(&mgi->mgi_bufs, mti->mti_fsname);
2849 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, quota);
2850 lcfg = lustre_cfg_new(cmd, &mgi->mgi_bufs);
2851 /* truncate the comment to the parameter name */
2856 /* XXX we duplicated quota enable information in all server
2857 * config logs, it should be moved to a separate config
2858 * log once we cleanup the config log for global param. */
2859 /* modify all servers */
2860 rc = mgs_write_log_direct_all(env, mgs, fsdb, mti,
2861 *tmp == '\0' ? NULL : lcfg,
2862 mti->mti_fsname, quota, 1);
2864 lustre_cfg_free(lcfg);
2865 return rc < 0 ? rc : 0;
2868 static int mgs_srpc_set_param_disk(const struct lu_env *env,
2869 struct mgs_device *mgs,
2871 struct mgs_target_info *mti,
2874 struct mgs_thread_info *mgi = mgs_env_info(env);
2875 struct llog_handle *llh = NULL;
2877 char *comment, *ptr;
2878 struct lustre_cfg *lcfg;
2883 ptr = strchr(param, '=');
2887 OBD_ALLOC(comment, len + 1);
2888 if (comment == NULL)
2890 strncpy(comment, param, len);
2891 comment[len] = '\0';
2894 lustre_cfg_bufs_reset(&mgi->mgi_bufs, mti->mti_svname);
2895 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, param);
2896 lcfg = lustre_cfg_new(LCFG_SPTLRPC_CONF, &mgi->mgi_bufs);
2898 GOTO(out_comment, rc = -ENOMEM);
2900 /* construct log name */
2901 rc = name_create(&logname, mti->mti_fsname, "-sptlrpc");
2905 if (mgs_log_is_empty(env, mgs, logname)) {
2906 rc = record_start_log(env, mgs, &llh, logname);
2909 record_end_log(env, &llh);
2912 /* obsolete old one */
2913 rc = mgs_modify(env, mgs, fsdb, mti, logname, mti->mti_svname,
2917 /* write the new one */
2918 rc = mgs_write_log_direct(env, mgs, fsdb, logname, lcfg,
2919 mti->mti_svname, comment);
2921 CERROR("err %d writing log %s\n", rc, logname);
2923 name_destroy(&logname);
2925 lustre_cfg_free(lcfg);
2927 OBD_FREE(comment, len + 1);
2931 static int mgs_srpc_set_param_udesc_mem(struct fs_db *fsdb,
2936 /* disable the adjustable udesc parameter for now, i.e. use default
2937 * setting that client always ship udesc to MDT if possible. to enable
2938 * it simply remove the following line */
2941 ptr = strchr(param, '=');
2946 if (strcmp(param, PARAM_SRPC_UDESC))
2949 if (strcmp(ptr, "yes") == 0) {
2950 set_bit(FSDB_UDESC, &fsdb->fsdb_flags);
2951 CWARN("Enable user descriptor shipping from client to MDT\n");
2952 } else if (strcmp(ptr, "no") == 0) {
2953 clear_bit(FSDB_UDESC, &fsdb->fsdb_flags);
2954 CWARN("Disable user descriptor shipping from client to MDT\n");
2962 CERROR("Invalid param: %s\n", param);
2966 static int mgs_srpc_set_param_mem(struct fs_db *fsdb,
2970 struct sptlrpc_rule rule;
2971 struct sptlrpc_rule_set *rset;
2975 if (strncmp(param, PARAM_SRPC, sizeof(PARAM_SRPC) - 1) != 0) {
2976 CERROR("Invalid sptlrpc parameter: %s\n", param);
2980 if (strncmp(param, PARAM_SRPC_UDESC,
2981 sizeof(PARAM_SRPC_UDESC) - 1) == 0) {
2982 RETURN(mgs_srpc_set_param_udesc_mem(fsdb, param));
2985 if (strncmp(param, PARAM_SRPC_FLVR, sizeof(PARAM_SRPC_FLVR) - 1) != 0) {
2986 CERROR("Invalid sptlrpc flavor parameter: %s\n", param);
2990 param += sizeof(PARAM_SRPC_FLVR) - 1;
2992 rc = sptlrpc_parse_rule(param, &rule);
2996 /* mgs rules implies must be mgc->mgs */
2997 if (test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
2998 if ((rule.sr_from != LUSTRE_SP_MGC &&
2999 rule.sr_from != LUSTRE_SP_ANY) ||
3000 (rule.sr_to != LUSTRE_SP_MGS &&
3001 rule.sr_to != LUSTRE_SP_ANY))
3005 /* preapre room for this coming rule. svcname format should be:
3006 * - fsname: general rule
3007 * - fsname-tgtname: target-specific rule
3009 if (strchr(svname, '-')) {
3010 struct mgs_tgt_srpc_conf *tgtconf;
3013 for (tgtconf = fsdb->fsdb_srpc_tgt; tgtconf != NULL;
3014 tgtconf = tgtconf->mtsc_next) {
3015 if (!strcmp(tgtconf->mtsc_tgt, svname)) {
3024 OBD_ALLOC_PTR(tgtconf);
3025 if (tgtconf == NULL)
3028 name_len = strlen(svname);
3030 OBD_ALLOC(tgtconf->mtsc_tgt, name_len + 1);
3031 if (tgtconf->mtsc_tgt == NULL) {
3032 OBD_FREE_PTR(tgtconf);
3035 memcpy(tgtconf->mtsc_tgt, svname, name_len);
3037 tgtconf->mtsc_next = fsdb->fsdb_srpc_tgt;
3038 fsdb->fsdb_srpc_tgt = tgtconf;
3041 rset = &tgtconf->mtsc_rset;
3043 rset = &fsdb->fsdb_srpc_gen;
3046 rc = sptlrpc_rule_set_merge(rset, &rule);
3051 static int mgs_srpc_set_param(const struct lu_env *env,
3052 struct mgs_device *mgs,
3054 struct mgs_target_info *mti,
3064 /* keep a copy of original param, which could be destroied
3066 copy_size = strlen(param) + 1;
3067 OBD_ALLOC(copy, copy_size);
3070 memcpy(copy, param, copy_size);
3072 rc = mgs_srpc_set_param_mem(fsdb, mti->mti_svname, param);
3076 /* previous steps guaranteed the syntax is correct */
3077 rc = mgs_srpc_set_param_disk(env, mgs, fsdb, mti, copy);
3081 if (test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
3083 * for mgs rules, make them effective immediately.
3085 LASSERT(fsdb->fsdb_srpc_tgt == NULL);
3086 sptlrpc_target_update_exp_flavor(mgs->mgs_obd,
3087 &fsdb->fsdb_srpc_gen);
3091 OBD_FREE(copy, copy_size);
3095 struct mgs_srpc_read_data {
3096 struct fs_db *msrd_fsdb;
3100 static int mgs_srpc_read_handler(const struct lu_env *env,
3101 struct llog_handle *llh,
3102 struct llog_rec_hdr *rec, void *data)
3104 struct mgs_srpc_read_data *msrd = data;
3105 struct cfg_marker *marker;
3106 struct lustre_cfg *lcfg = REC_DATA(rec);
3107 char *svname, *param;
3111 if (rec->lrh_type != OBD_CFG_REC) {
3112 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
3116 cfg_len = rec->lrh_len - sizeof(struct llog_rec_hdr) -
3117 sizeof(struct llog_rec_tail);
3119 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
3121 CERROR("Insane cfg\n");
3125 if (lcfg->lcfg_command == LCFG_MARKER) {
3126 marker = lustre_cfg_buf(lcfg, 1);
3128 if (marker->cm_flags & CM_START &&
3129 marker->cm_flags & CM_SKIP)
3130 msrd->msrd_skip = 1;
3131 if (marker->cm_flags & CM_END)
3132 msrd->msrd_skip = 0;
3137 if (msrd->msrd_skip)
3140 if (lcfg->lcfg_command != LCFG_SPTLRPC_CONF) {
3141 CERROR("invalid command (%x)\n", lcfg->lcfg_command);
3145 svname = lustre_cfg_string(lcfg, 0);
3146 if (svname == NULL) {
3147 CERROR("svname is empty\n");
3151 param = lustre_cfg_string(lcfg, 1);
3152 if (param == NULL) {
3153 CERROR("param is empty\n");
3157 rc = mgs_srpc_set_param_mem(msrd->msrd_fsdb, svname, param);
3159 CERROR("read sptlrpc record error (%d): %s\n", rc, param);
3164 int mgs_get_fsdb_srpc_from_llog(const struct lu_env *env,
3165 struct mgs_device *mgs,
3168 struct llog_handle *llh = NULL;
3169 struct llog_ctxt *ctxt;
3171 struct mgs_srpc_read_data msrd;
3175 /* construct log name */
3176 rc = name_create(&logname, fsdb->fsdb_name, "-sptlrpc");
3180 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
3181 LASSERT(ctxt != NULL);
3183 if (mgs_log_is_empty(env, mgs, logname))
3186 rc = llog_open(env, ctxt, &llh, NULL, logname,
3194 rc = llog_init_handle(env, llh, LLOG_F_IS_PLAIN, NULL);
3196 GOTO(out_close, rc);
3198 if (llog_get_size(llh) <= 1)
3199 GOTO(out_close, rc = 0);
3201 msrd.msrd_fsdb = fsdb;
3204 rc = llog_process(env, llh, mgs_srpc_read_handler, (void *)&msrd,
3208 llog_close(env, llh);
3210 llog_ctxt_put(ctxt);
3211 name_destroy(&logname);
3214 CERROR("failed to read sptlrpc config database: %d\n", rc);
3218 /* Permanent settings of all parameters by writing into the appropriate
3219 * configuration logs.
3220 * A parameter with null value ("<param>='\0'") means to erase it out of
3223 static int mgs_write_log_param(const struct lu_env *env,
3224 struct mgs_device *mgs, struct fs_db *fsdb,
3225 struct mgs_target_info *mti, char *ptr)
3227 struct mgs_thread_info *mgi = mgs_env_info(env);
3230 int rc = 0, rc2 = 0;
3233 /* For various parameter settings, we have to figure out which logs
3234 care about them (e.g. both mdt and client for lov settings) */
3235 CDEBUG(D_MGS, "next param '%s'\n", ptr);
3237 /* The params are stored in MOUNT_DATA_FILE and modified via
3238 tunefs.lustre, or set using lctl conf_param */
3240 /* Processed in lustre_start_mgc */
3241 if (class_match_param(ptr, PARAM_MGSNODE, NULL) == 0)
3244 /* Processed in ost/mdt */
3245 if (class_match_param(ptr, PARAM_NETWORK, NULL) == 0)
3248 /* Processed in mgs_write_log_ost */
3249 if (class_match_param(ptr, PARAM_FAILMODE, NULL) == 0) {
3250 if (mti->mti_flags & LDD_F_PARAM) {
3251 LCONSOLE_ERROR_MSG(0x169, "%s can only be "
3252 "changed with tunefs.lustre"
3253 "and --writeconf\n", ptr);
3259 if (class_match_param(ptr, PARAM_SRPC, NULL) == 0) {
3260 rc = mgs_srpc_set_param(env, mgs, fsdb, mti, ptr);
3264 if (class_match_param(ptr, PARAM_FAILNODE, NULL) == 0) {
3265 /* Add a failover nidlist */
3267 /* We already processed failovers params for new
3268 targets in mgs_write_log_target */
3269 if (mti->mti_flags & LDD_F_PARAM) {
3270 CDEBUG(D_MGS, "Adding failnode\n");
3271 rc = mgs_write_log_add_failnid(env, mgs, fsdb, mti);
3276 if (class_match_param(ptr, PARAM_SYS, &tmp) == 0) {
3277 rc = mgs_write_log_sys(env, mgs, fsdb, mti, ptr, tmp);
3281 if (class_match_param(ptr, PARAM_QUOTA, &tmp) == 0) {
3282 rc = mgs_write_log_quota(env, mgs, fsdb, mti, ptr, tmp);
3286 if (class_match_param(ptr, PARAM_OSC""PARAM_ACTIVE, &tmp) == 0) {
3287 /* active=0 means off, anything else means on */
3288 int flag = (*tmp == '0') ? CM_EXCLUDE : 0;
3291 if (!(mti->mti_flags & LDD_F_SV_TYPE_OST)) {
3292 LCONSOLE_ERROR_MSG(0x144, "%s: Only OSCs can "
3293 "be (de)activated.\n",
3295 GOTO(end, rc = -EINVAL);
3297 LCONSOLE_WARN("Permanently %sactivating %s\n",
3298 flag ? "de": "re", mti->mti_svname);
3300 rc = name_create(&logname, mti->mti_fsname, "-client");
3303 rc = mgs_modify(env, mgs, fsdb, mti, logname,
3304 mti->mti_svname, "add osc", flag);
3305 name_destroy(&logname);
3309 /* Add to all MDT logs for CMD */
3310 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3311 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
3313 rc = name_create_mdt(&logname, mti->mti_fsname, i);
3316 rc = mgs_modify(env, mgs, fsdb, mti, logname,
3317 mti->mti_svname, "add osc", flag);
3318 name_destroy(&logname);
3324 LCONSOLE_ERROR_MSG(0x145, "Couldn't find %s in"
3325 "log (%d). No permanent "
3326 "changes were made to the "
3328 mti->mti_svname, rc);
3329 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags))
3330 LCONSOLE_ERROR_MSG(0x146, "This may be"
3335 "update the logs.\n");
3338 /* Fall through to osc proc for deactivating live OSC
3339 on running MDT / clients. */
3341 /* Below here, let obd's XXX_process_config methods handle it */
3343 /* All lov. in proc */
3344 if (class_match_param(ptr, PARAM_LOV, NULL) == 0) {
3347 CDEBUG(D_MGS, "lov param %s\n", ptr);
3348 if (!(mti->mti_flags & LDD_F_SV_TYPE_MDT)) {
3349 LCONSOLE_ERROR_MSG(0x147, "LOV params must be "
3350 "set on the MDT, not %s. "
3357 if (mgs_log_is_empty(env, mgs, mti->mti_svname))
3358 GOTO(end, rc = -ENODEV);
3360 rc = name_create_mdt_and_lov(&logname, &mdtlovname, fsdb,
3361 mti->mti_stripe_index);
3364 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, mti->mti_svname,
3365 &mgi->mgi_bufs, mdtlovname, ptr);
3366 name_destroy(&logname);
3367 name_destroy(&mdtlovname);
3372 rc = name_create(&logname, mti->mti_fsname, "-client");
3375 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname, &mgi->mgi_bufs,
3376 fsdb->fsdb_clilov, ptr);
3377 name_destroy(&logname);
3381 /* All osc., mdc., llite. params in proc */
3382 if ((class_match_param(ptr, PARAM_OSC, NULL) == 0) ||
3383 (class_match_param(ptr, PARAM_MDC, NULL) == 0) ||
3384 (class_match_param(ptr, PARAM_LLITE, NULL) == 0)) {
3387 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
3388 LCONSOLE_ERROR_MSG(0x148, "Upgraded client logs for %s"
3389 " cannot be modified. Consider"
3390 " updating the configuration with"
3393 GOTO(end, rc = -EINVAL);
3395 if (memcmp(ptr, PARAM_LLITE, strlen(PARAM_LLITE)) == 0) {
3396 rc = name_create(&cname, mti->mti_fsname, "-client");
3397 /* Add the client type to match the obdname in
3398 class_config_llog_handler */
3399 } else if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
3400 rc = name_create(&cname, mti->mti_svname, "-mdc");
3401 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
3402 rc = name_create(&cname, mti->mti_svname, "-osc");
3404 GOTO(end, rc = -EINVAL);
3409 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
3412 rc = name_create(&logname, mti->mti_fsname, "-client");
3414 name_destroy(&cname);
3417 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname, &mgi->mgi_bufs,
3420 /* osc params affect the MDT as well */
3421 if (!rc && (mti->mti_flags & LDD_F_SV_TYPE_OST)) {
3424 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
3425 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
3427 name_destroy(&cname);
3428 rc = name_create_mdt_osc(&cname, mti->mti_svname,
3430 name_destroy(&logname);
3433 rc = name_create_mdt(&logname,
3434 mti->mti_fsname, i);
3437 if (!mgs_log_is_empty(env, mgs, logname)) {
3438 rc = mgs_wlp_lcfg(env, mgs, fsdb,
3447 name_destroy(&logname);
3448 name_destroy(&cname);
3452 /* All mdt. params in proc */
3453 if (class_match_param(ptr, PARAM_MDT, NULL) == 0) {
3457 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
3458 if (strncmp(mti->mti_svname, mti->mti_fsname,
3459 MTI_NAME_MAXLEN) == 0)
3460 /* device is unspecified completely? */
3461 rc = LDD_F_SV_TYPE_MDT | LDD_F_SV_ALL;
3463 rc = server_name2index(mti->mti_svname, &idx, NULL);
3466 if ((rc & LDD_F_SV_TYPE_MDT) == 0)
3468 if (rc & LDD_F_SV_ALL) {
3469 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3471 fsdb->fsdb_mdt_index_map))
3473 rc = name_create_mdt(&logname,
3474 mti->mti_fsname, i);
3477 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti,
3478 logname, &mgi->mgi_bufs,
3480 name_destroy(&logname);
3485 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti,
3486 mti->mti_svname, &mgi->mgi_bufs,
3487 mti->mti_svname, ptr);
3494 /* All mdd., ost. and osd. params in proc */
3495 if ((class_match_param(ptr, PARAM_MDD, NULL) == 0) ||
3496 (class_match_param(ptr, PARAM_OST, NULL) == 0) ||
3497 (class_match_param(ptr, PARAM_OSD, NULL) == 0)) {
3498 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
3499 if (mgs_log_is_empty(env, mgs, mti->mti_svname))
3500 GOTO(end, rc = -ENODEV);
3502 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, mti->mti_svname,
3503 &mgi->mgi_bufs, mti->mti_svname, ptr);
3507 LCONSOLE_WARN("Ignoring unrecognized param '%s'\n", ptr);
3512 CERROR("err %d on param '%s'\n", rc, ptr);
3517 /* Not implementing automatic failover nid addition at this time. */
3518 int mgs_check_failnid(const struct lu_env *env, struct mgs_device *mgs,
3519 struct mgs_target_info *mti)
3526 rc = mgs_find_or_make_fsdb(obd, fsname, &fsdb);
3530 if (mgs_log_is_empty(obd, mti->mti_svname))
3531 /* should never happen */
3534 CDEBUG(D_MGS, "Checking for new failnids for %s\n", mti->mti_svname);
3536 /* FIXME We can just check mti->params to see if we're already in
3537 the failover list. Modify mti->params for rewriting back at
3538 server_register_target(). */
3540 mutex_lock(&fsdb->fsdb_mutex);
3541 rc = mgs_write_log_add_failnid(obd, fsdb, mti);
3542 mutex_unlock(&fsdb->fsdb_mutex);
3549 int mgs_write_log_target(const struct lu_env *env,
3550 struct mgs_device *mgs,
3551 struct mgs_target_info *mti,
3558 /* set/check the new target index */
3559 rc = mgs_set_index(env, mgs, mti);
3561 CERROR("Can't get index (%d)\n", rc);
3565 if (rc == EALREADY) {
3566 LCONSOLE_WARN("Found index %d for %s, updating log\n",
3567 mti->mti_stripe_index, mti->mti_svname);
3568 /* We would like to mark old log sections as invalid
3569 and add new log sections in the client and mdt logs.
3570 But if we add new sections, then live clients will
3571 get repeat setup instructions for already running
3572 osc's. So don't update the client/mdt logs. */
3573 mti->mti_flags &= ~LDD_F_UPDATE;
3577 mutex_lock(&fsdb->fsdb_mutex);
3579 if (mti->mti_flags &
3580 (LDD_F_VIRGIN | LDD_F_UPGRADE14 | LDD_F_WRITECONF)) {
3581 /* Generate a log from scratch */
3582 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
3583 rc = mgs_write_log_mdt(env, mgs, fsdb, mti);
3584 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
3585 rc = mgs_write_log_ost(env, mgs, fsdb, mti);
3587 CERROR("Unknown target type %#x, can't create log for "
3588 "%s\n", mti->mti_flags, mti->mti_svname);
3591 CERROR("Can't write logs for %s (%d)\n",
3592 mti->mti_svname, rc);
3596 /* Just update the params from tunefs in mgs_write_log_params */
3597 CDEBUG(D_MGS, "Update params for %s\n", mti->mti_svname);
3598 mti->mti_flags |= LDD_F_PARAM;
3601 /* allocate temporary buffer, where class_get_next_param will
3602 make copy of a current parameter */
3603 OBD_ALLOC(buf, strlen(mti->mti_params) + 1);
3605 GOTO(out_up, rc = -ENOMEM);
3606 params = mti->mti_params;
3607 while (params != NULL) {
3608 rc = class_get_next_param(¶ms, buf);
3611 /* there is no next parameter, that is
3616 CDEBUG(D_MGS, "remaining string: '%s', param: '%s'\n",
3618 rc = mgs_write_log_param(env, mgs, fsdb, mti, buf);
3623 OBD_FREE(buf, strlen(mti->mti_params) + 1);
3626 mutex_unlock(&fsdb->fsdb_mutex);
3630 int mgs_erase_log(const struct lu_env *env, struct mgs_device *mgs, char *name)
3632 struct llog_ctxt *ctxt;
3635 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
3637 CERROR("%s: MGS config context doesn't exist\n",
3638 mgs->mgs_obd->obd_name);
3641 rc = llog_erase(env, ctxt, NULL, name);
3642 /* llog may not exist */
3645 llog_ctxt_put(ctxt);
3649 CERROR("%s: failed to clear log %s: %d\n",
3650 mgs->mgs_obd->obd_name, name, rc);
3655 /* erase all logs for the given fs */
3656 int mgs_erase_logs(const struct lu_env *env, struct mgs_device *mgs, char *fsname)
3660 struct mgs_direntry *dirent, *n;
3661 int rc, len = strlen(fsname);
3665 /* Find all the logs in the CONFIGS directory */
3666 rc = class_dentry_readdir(env, mgs, &list);
3670 mutex_lock(&mgs->mgs_mutex);
3672 /* Delete the fs db */
3673 fsdb = mgs_find_fsdb(mgs, fsname);
3675 mgs_free_fsdb(mgs, fsdb);
3677 mutex_unlock(&mgs->mgs_mutex);
3679 cfs_list_for_each_entry_safe(dirent, n, &list, list) {
3680 cfs_list_del(&dirent->list);
3681 suffix = strrchr(dirent->name, '-');
3682 if (suffix != NULL) {
3683 if ((len == suffix - dirent->name) &&
3684 (strncmp(fsname, dirent->name, len) == 0)) {
3685 CDEBUG(D_MGS, "Removing log %s\n",
3687 mgs_erase_log(env, mgs, dirent->name);
3690 mgs_direntry_free(dirent);
3696 /* list all logs for the given fs */
3697 int mgs_list_logs(const struct lu_env *env, struct mgs_device *mgs,
3698 struct obd_ioctl_data *data)
3701 struct mgs_direntry *dirent, *n;
3707 /* Find all the logs in the CONFIGS directory */
3708 rc = class_dentry_readdir(env, mgs, &list);
3710 CERROR("%s: can't read %s dir = %d\n",
3711 mgs->mgs_obd->obd_name, MOUNT_CONFIGS_DIR, rc);
3715 out = data->ioc_bulk;
3716 remains = data->ioc_inllen1;
3717 cfs_list_for_each_entry_safe(dirent, n, &list, list) {
3718 cfs_list_del(&dirent->list);
3719 suffix = strrchr(dirent->name, '-');
3720 if (suffix != NULL) {
3721 l = snprintf(out, remains, "config log: $%s\n",
3726 mgs_direntry_free(dirent);
3733 /* from llog_swab */
3734 static void print_lustre_cfg(struct lustre_cfg *lcfg)
3739 CDEBUG(D_MGS, "lustre_cfg: %p\n", lcfg);
3740 CDEBUG(D_MGS, "\tlcfg->lcfg_version: %#x\n", lcfg->lcfg_version);
3742 CDEBUG(D_MGS, "\tlcfg->lcfg_command: %#x\n", lcfg->lcfg_command);
3743 CDEBUG(D_MGS, "\tlcfg->lcfg_num: %#x\n", lcfg->lcfg_num);
3744 CDEBUG(D_MGS, "\tlcfg->lcfg_flags: %#x\n", lcfg->lcfg_flags);
3745 CDEBUG(D_MGS, "\tlcfg->lcfg_nid: %s\n", libcfs_nid2str(lcfg->lcfg_nid));
3747 CDEBUG(D_MGS, "\tlcfg->lcfg_bufcount: %d\n", lcfg->lcfg_bufcount);
3748 if (lcfg->lcfg_bufcount < LUSTRE_CFG_MAX_BUFCOUNT)
3749 for (i = 0; i < lcfg->lcfg_bufcount; i++) {
3750 CDEBUG(D_MGS, "\tlcfg->lcfg_buflens[%d]: %d %s\n",
3751 i, lcfg->lcfg_buflens[i],
3752 lustre_cfg_string(lcfg, i));
3757 /* Set a permanent (config log) param for a target or fs
3758 * \param lcfg buf0 may contain the device (testfs-MDT0000) name
3759 * buf1 contains the single parameter
3761 int mgs_setparam(const struct lu_env *env, struct mgs_device *mgs,
3762 struct lustre_cfg *lcfg, char *fsname)
3765 struct mgs_target_info *mti;
3766 char *devname, *param;
3773 print_lustre_cfg(lcfg);
3775 /* lustre, lustre-mdtlov, lustre-client, lustre-MDT0000 */
3776 devname = lustre_cfg_string(lcfg, 0);
3777 param = lustre_cfg_string(lcfg, 1);
3779 /* Assume device name embedded in param:
3780 lustre-OST0000.osc.max_dirty_mb=32 */
3781 ptr = strchr(param, '.');
3789 LCONSOLE_ERROR_MSG(0x14d, "No target specified: %s\n", param);
3793 rc = mgs_parse_devname(devname, fsname, NULL);
3794 if (rc == 0 && !mgs_parse_devname(devname, NULL, &index)) {
3795 /* param related to llite isn't allowed to set by OST or MDT */
3796 if (rc == 0 && strncmp(param, PARAM_LLITE,
3797 sizeof(PARAM_LLITE) - 1) == 0)
3800 /* assume devname is the fsname */
3801 memset(fsname, 0, MTI_NAME_MAXLEN);
3802 strncpy(fsname, devname, MTI_NAME_MAXLEN);
3803 fsname[MTI_NAME_MAXLEN - 1] = 0;
3805 CDEBUG(D_MGS, "setparam fs='%s' device='%s'\n", fsname, devname);
3807 rc = mgs_find_or_make_fsdb(env, mgs,
3808 lcfg->lcfg_command == LCFG_SET_PARAM ?
3809 PARAMS_FILENAME : fsname, &fsdb);
3813 if (lcfg->lcfg_command != LCFG_SET_PARAM &&
3814 !test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags) &&
3815 test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
3816 CERROR("No filesystem targets for %s. cfg_device from lctl "
3817 "is '%s'\n", fsname, devname);
3818 mgs_free_fsdb(mgs, fsdb);
3822 /* Create a fake mti to hold everything */
3825 GOTO(out, rc = -ENOMEM);
3826 if (strlcpy(mti->mti_fsname, fsname, sizeof(mti->mti_fsname))
3827 >= sizeof(mti->mti_fsname))
3828 GOTO(out, rc = -E2BIG);
3829 if (strlcpy(mti->mti_svname, devname, sizeof(mti->mti_svname))
3830 >= sizeof(mti->mti_svname))
3831 GOTO(out, rc = -E2BIG);
3832 if (strlcpy(mti->mti_params, param, sizeof(mti->mti_params))
3833 >= sizeof(mti->mti_params))
3834 GOTO(out, rc = -E2BIG);
3835 rc = server_name2index(mti->mti_svname, &mti->mti_stripe_index, &tmp);
3837 /* Not a valid server; may be only fsname */
3840 /* Strip -osc or -mdc suffix from svname */
3841 if (server_make_name(rc, mti->mti_stripe_index, mti->mti_fsname,
3843 GOTO(out, rc = -EINVAL);
3845 * Revoke lock so everyone updates. Should be alright if
3846 * someone was already reading while we were updating the logs,
3847 * so we don't really need to hold the lock while we're
3850 if (lcfg->lcfg_command == LCFG_SET_PARAM) {
3851 mti->mti_flags = rc | LDD_F_PARAM2;
3852 mutex_lock(&fsdb->fsdb_mutex);
3853 rc = mgs_write_log_param2(env, mgs, fsdb, mti, mti->mti_params);
3854 mutex_unlock(&fsdb->fsdb_mutex);
3855 mgs_revoke_lock(mgs, fsdb, CONFIG_T_PARAMS);
3857 mti->mti_flags = rc | LDD_F_PARAM;
3858 mutex_lock(&fsdb->fsdb_mutex);
3859 rc = mgs_write_log_param(env, mgs, fsdb, mti, mti->mti_params);
3860 mutex_unlock(&fsdb->fsdb_mutex);
3861 mgs_revoke_lock(mgs, fsdb, CONFIG_T_CONFIG);
3869 static int mgs_write_log_pool(const struct lu_env *env,
3870 struct mgs_device *mgs, char *logname,
3871 struct fs_db *fsdb, char *tgtname,
3872 enum lcfg_command_type cmd,
3873 char *fsname, char *poolname,
3874 char *ostname, char *comment)
3876 struct llog_handle *llh = NULL;
3879 rc = record_start_log(env, mgs, &llh, logname);
3882 rc = record_marker(env, llh, fsdb, CM_START, tgtname, comment);
3885 rc = record_base(env, llh, tgtname, 0, cmd,
3886 fsname, poolname, ostname, 0);
3889 rc = record_marker(env, llh, fsdb, CM_END, tgtname, comment);
3891 record_end_log(env, &llh);
3895 int mgs_nodemap_cmd(const struct lu_env *env, struct mgs_device *mgs,
3896 enum lcfg_command_type cmd, const char *nodemap_name,
3903 case LCFG_NODEMAP_ADD:
3904 rc = nodemap_add(nodemap_name);
3906 case LCFG_NODEMAP_DEL:
3907 rc = nodemap_del(nodemap_name);
3916 int mgs_pool_cmd(const struct lu_env *env, struct mgs_device *mgs,
3917 enum lcfg_command_type cmd, char *fsname,
3918 char *poolname, char *ostname)
3923 char *label = NULL, *canceled_label = NULL;
3925 struct mgs_target_info *mti = NULL;
3929 rc = mgs_find_or_make_fsdb(env, mgs, fsname, &fsdb);
3931 CERROR("Can't get db for %s\n", fsname);
3934 if (test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
3935 CERROR("%s is not defined\n", fsname);
3936 mgs_free_fsdb(mgs, fsdb);
3940 label_sz = 10 + strlen(fsname) + strlen(poolname);
3942 /* check if ostname match fsname */
3943 if (ostname != NULL) {
3946 ptr = strrchr(ostname, '-');
3947 if ((ptr == NULL) ||
3948 (strncmp(fsname, ostname, ptr-ostname) != 0))
3950 label_sz += strlen(ostname);
3953 OBD_ALLOC(label, label_sz);
3960 "new %s.%s", fsname, poolname);
3964 "add %s.%s.%s", fsname, poolname, ostname);
3967 OBD_ALLOC(canceled_label, label_sz);
3968 if (canceled_label == NULL)
3969 GOTO(out_label, rc = -ENOMEM);
3971 "rem %s.%s.%s", fsname, poolname, ostname);
3972 sprintf(canceled_label,
3973 "add %s.%s.%s", fsname, poolname, ostname);
3976 OBD_ALLOC(canceled_label, label_sz);
3977 if (canceled_label == NULL)
3978 GOTO(out_label, rc = -ENOMEM);
3980 "del %s.%s", fsname, poolname);
3981 sprintf(canceled_label,
3982 "new %s.%s", fsname, poolname);
3988 if (canceled_label != NULL) {
3991 GOTO(out_cancel, rc = -ENOMEM);
3994 mutex_lock(&fsdb->fsdb_mutex);
3995 /* write pool def to all MDT logs */
3996 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3997 if (test_bit(i, fsdb->fsdb_mdt_index_map)) {
3998 rc = name_create_mdt_and_lov(&logname, &lovname,
4001 mutex_unlock(&fsdb->fsdb_mutex);
4004 if (canceled_label != NULL) {
4005 strcpy(mti->mti_svname, "lov pool");
4006 rc = mgs_modify(env, mgs, fsdb, mti, logname,
4007 lovname, canceled_label,
4012 rc = mgs_write_log_pool(env, mgs, logname,
4016 name_destroy(&logname);
4017 name_destroy(&lovname);
4019 mutex_unlock(&fsdb->fsdb_mutex);
4025 rc = name_create(&logname, fsname, "-client");
4027 mutex_unlock(&fsdb->fsdb_mutex);
4030 if (canceled_label != NULL) {
4031 rc = mgs_modify(env, mgs, fsdb, mti, logname,
4032 fsdb->fsdb_clilov, canceled_label, CM_SKIP);
4034 mutex_unlock(&fsdb->fsdb_mutex);
4035 name_destroy(&logname);
4040 rc = mgs_write_log_pool(env, mgs, logname, fsdb, fsdb->fsdb_clilov,
4041 cmd, fsname, poolname, ostname, label);
4042 mutex_unlock(&fsdb->fsdb_mutex);
4043 name_destroy(&logname);
4044 /* request for update */
4045 mgs_revoke_lock(mgs, fsdb, CONFIG_T_CONFIG);
4052 if (canceled_label != NULL)
4053 OBD_FREE(canceled_label, label_sz);
4055 OBD_FREE(label, label_sz);