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
49 #include <lustre_param.h>
50 #include <lustre_sec.h>
51 #include <lustre_quota.h>
53 #include "mgs_internal.h"
55 /********************** Class functions ********************/
57 int class_dentry_readdir(const struct lu_env *env,
58 struct mgs_device *mgs, cfs_list_t *list)
60 struct dt_object *dir = mgs->mgs_configs_dir;
61 const struct dt_it_ops *iops;
63 struct mgs_direntry *de;
67 CFS_INIT_LIST_HEAD(list);
70 LASSERT(dir->do_index_ops);
72 iops = &dir->do_index_ops->dio_it;
73 it = iops->init(env, dir, LUDA_64BITHASH, BYPASS_CAPA);
77 rc = iops->load(env, it, 0);
83 key = (void *)iops->key(env, it);
85 CERROR("%s: key failed when listing %s: rc = %d\n",
86 mgs->mgs_obd->obd_name, MOUNT_CONFIGS_DIR,
90 key_sz = iops->key_size(env, it);
93 /* filter out "." and ".." entries */
97 if (key_sz == 2 && key[1] == '.')
101 de = mgs_direntry_alloc(key_sz + 1);
107 memcpy(de->name, key, key_sz);
108 de->name[key_sz] = 0;
110 cfs_list_add(&de->list, list);
113 rc = iops->next(env, it);
122 CERROR("%s: key failed when listing %s: rc = %d\n",
123 mgs->mgs_obd->obd_name, MOUNT_CONFIGS_DIR, rc);
127 /******************** DB functions *********************/
129 static inline int name_create(char **newname, char *prefix, char *suffix)
132 OBD_ALLOC(*newname, strlen(prefix) + strlen(suffix) + 1);
135 sprintf(*newname, "%s%s", prefix, suffix);
139 static inline void name_destroy(char **name)
142 OBD_FREE(*name, strlen(*name) + 1);
146 struct mgs_fsdb_handler_data
152 /* from the (client) config log, figure out:
153 1. which ost's/mdt's are configured (by index)
154 2. what the last config step is
155 3. COMPAT_18 osc name
157 /* It might be better to have a separate db file, instead of parsing the info
158 out of the client log. This is slow and potentially error-prone. */
159 static int mgs_fsdb_handler(const struct lu_env *env, struct llog_handle *llh,
160 struct llog_rec_hdr *rec, void *data)
162 struct mgs_fsdb_handler_data *d = data;
163 struct fs_db *fsdb = d->fsdb;
164 int cfg_len = rec->lrh_len;
165 char *cfg_buf = (char*) (rec + 1);
166 struct lustre_cfg *lcfg;
171 if (rec->lrh_type != OBD_CFG_REC) {
172 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
176 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
178 CERROR("Insane cfg\n");
182 lcfg = (struct lustre_cfg *)cfg_buf;
184 CDEBUG(D_INFO, "cmd %x %s %s\n", lcfg->lcfg_command,
185 lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));
187 /* Figure out ost indicies */
188 /* lov_modify_tgts add 0:lov1 1:ost1_UUID 2(index):0 3(gen):1 */
189 if (lcfg->lcfg_command == LCFG_LOV_ADD_OBD ||
190 lcfg->lcfg_command == LCFG_LOV_DEL_OBD) {
191 index = simple_strtoul(lustre_cfg_string(lcfg, 2),
193 CDEBUG(D_MGS, "OST index for %s is %u (%s)\n",
194 lustre_cfg_string(lcfg, 1), index,
195 lustre_cfg_string(lcfg, 2));
196 set_bit(index, fsdb->fsdb_ost_index_map);
199 /* Figure out mdt indicies */
200 /* attach 0:MDC_uml1_mdsA_MNT_client 1:mdc 2:1d834_MNT_client_03f */
201 if ((lcfg->lcfg_command == LCFG_ATTACH) &&
202 (strcmp(lustre_cfg_string(lcfg, 1), LUSTRE_MDC_NAME) == 0)) {
203 rc = server_name2index(lustre_cfg_string(lcfg, 0),
205 if (rc != LDD_F_SV_TYPE_MDT) {
206 CWARN("Unparsable MDC name %s, assuming index 0\n",
207 lustre_cfg_string(lcfg, 0));
211 CDEBUG(D_MGS, "MDT index is %u\n", index);
212 set_bit(index, fsdb->fsdb_mdt_index_map);
213 fsdb->fsdb_mdt_count ++;
217 * figure out the old config. fsdb_gen = 0 means old log
218 * It is obsoleted and not supported anymore
220 if (fsdb->fsdb_gen == 0) {
221 CERROR("Old config format is not supported\n");
226 * compat to 1.8, check osc name used by MDT0 to OSTs, bz18548.
228 if (!test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags) &&
229 lcfg->lcfg_command == LCFG_ATTACH &&
230 strcmp(lustre_cfg_string(lcfg, 1), LUSTRE_OSC_NAME) == 0) {
231 if (OBD_OCD_VERSION_MAJOR(d->ver) == 1 &&
232 OBD_OCD_VERSION_MINOR(d->ver) <= 8) {
233 CWARN("MDT using 1.8 OSC name scheme\n");
234 set_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags);
238 if (lcfg->lcfg_command == LCFG_MARKER) {
239 struct cfg_marker *marker;
240 marker = lustre_cfg_buf(lcfg, 1);
242 d->ver = marker->cm_vers;
244 /* Keep track of the latest marker step */
245 fsdb->fsdb_gen = max(fsdb->fsdb_gen, marker->cm_step);
251 /* fsdb->fsdb_mutex is already held in mgs_find_or_make_fsdb*/
252 static int mgs_get_fsdb_from_llog(const struct lu_env *env,
253 struct mgs_device *mgs,
257 struct llog_handle *loghandle;
258 struct llog_ctxt *ctxt;
259 struct mgs_fsdb_handler_data d = { fsdb, 0 };
264 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
265 LASSERT(ctxt != NULL);
266 rc = name_create(&logname, fsdb->fsdb_name, "-client");
269 rc = llog_open_create(env, ctxt, &loghandle, NULL, logname);
273 rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL);
277 if (llog_get_size(loghandle) <= 1)
278 set_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags);
280 rc = llog_process(env, loghandle, mgs_fsdb_handler, (void *)&d, NULL);
281 CDEBUG(D_INFO, "get_db = %d\n", rc);
283 llog_close(env, loghandle);
285 name_destroy(&logname);
292 static void mgs_free_fsdb_srpc(struct fs_db *fsdb)
294 struct mgs_tgt_srpc_conf *tgtconf;
296 /* free target-specific rules */
297 while (fsdb->fsdb_srpc_tgt) {
298 tgtconf = fsdb->fsdb_srpc_tgt;
299 fsdb->fsdb_srpc_tgt = tgtconf->mtsc_next;
301 LASSERT(tgtconf->mtsc_tgt);
303 sptlrpc_rule_set_free(&tgtconf->mtsc_rset);
304 OBD_FREE(tgtconf->mtsc_tgt, strlen(tgtconf->mtsc_tgt) + 1);
305 OBD_FREE_PTR(tgtconf);
308 /* free general rules */
309 sptlrpc_rule_set_free(&fsdb->fsdb_srpc_gen);
312 struct fs_db *mgs_find_fsdb(struct mgs_device *mgs, char *fsname)
317 cfs_list_for_each(tmp, &mgs->mgs_fs_db_list) {
318 fsdb = cfs_list_entry(tmp, struct fs_db, fsdb_list);
319 if (strcmp(fsdb->fsdb_name, fsname) == 0)
325 /* caller must hold the mgs->mgs_fs_db_lock */
326 static struct fs_db *mgs_new_fsdb(const struct lu_env *env,
327 struct mgs_device *mgs, char *fsname)
333 if (strlen(fsname) >= sizeof(fsdb->fsdb_name)) {
334 CERROR("fsname %s is too long\n", fsname);
342 strcpy(fsdb->fsdb_name, fsname);
343 mutex_init(&fsdb->fsdb_mutex);
344 set_bit(FSDB_UDESC, &fsdb->fsdb_flags);
347 if (strcmp(fsname, MGSSELF_NAME) == 0) {
348 set_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags);
350 OBD_ALLOC(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
351 OBD_ALLOC(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
352 if (!fsdb->fsdb_ost_index_map || !fsdb->fsdb_mdt_index_map) {
353 CERROR("No memory for index maps\n");
354 GOTO(err, rc = -ENOMEM);
357 rc = name_create(&fsdb->fsdb_clilov, fsname, "-clilov");
360 rc = name_create(&fsdb->fsdb_clilmv, fsname, "-clilmv");
364 /* initialise data for NID table */
365 mgs_ir_init_fs(env, mgs, fsdb);
367 lproc_mgs_add_live(mgs, fsdb);
370 cfs_list_add(&fsdb->fsdb_list, &mgs->mgs_fs_db_list);
374 if (fsdb->fsdb_ost_index_map)
375 OBD_FREE(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
376 if (fsdb->fsdb_mdt_index_map)
377 OBD_FREE(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
378 name_destroy(&fsdb->fsdb_clilov);
379 name_destroy(&fsdb->fsdb_clilmv);
384 static void mgs_free_fsdb(struct mgs_device *mgs, struct fs_db *fsdb)
386 /* wait for anyone with the sem */
387 mutex_lock(&fsdb->fsdb_mutex);
388 lproc_mgs_del_live(mgs, fsdb);
389 cfs_list_del(&fsdb->fsdb_list);
391 /* deinitialize fsr */
392 mgs_ir_fini_fs(mgs, fsdb);
394 if (fsdb->fsdb_ost_index_map)
395 OBD_FREE(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
396 if (fsdb->fsdb_mdt_index_map)
397 OBD_FREE(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
398 name_destroy(&fsdb->fsdb_clilov);
399 name_destroy(&fsdb->fsdb_clilmv);
400 mgs_free_fsdb_srpc(fsdb);
401 mutex_unlock(&fsdb->fsdb_mutex);
405 int mgs_init_fsdb_list(struct mgs_device *mgs)
407 CFS_INIT_LIST_HEAD(&mgs->mgs_fs_db_list);
411 int mgs_cleanup_fsdb_list(struct mgs_device *mgs)
414 cfs_list_t *tmp, *tmp2;
415 mutex_lock(&mgs->mgs_mutex);
416 cfs_list_for_each_safe(tmp, tmp2, &mgs->mgs_fs_db_list) {
417 fsdb = cfs_list_entry(tmp, struct fs_db, fsdb_list);
418 mgs_free_fsdb(mgs, fsdb);
420 mutex_unlock(&mgs->mgs_mutex);
424 int mgs_find_or_make_fsdb(const struct lu_env *env,
425 struct mgs_device *mgs, char *name,
432 mutex_lock(&mgs->mgs_mutex);
433 fsdb = mgs_find_fsdb(mgs, name);
435 mutex_unlock(&mgs->mgs_mutex);
440 CDEBUG(D_MGS, "Creating new db\n");
441 fsdb = mgs_new_fsdb(env, mgs, name);
442 /* lock fsdb_mutex until the db is loaded from llogs */
444 mutex_lock(&fsdb->fsdb_mutex);
445 mutex_unlock(&mgs->mgs_mutex);
449 if (!test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
450 /* populate the db from the client llog */
451 rc = mgs_get_fsdb_from_llog(env, mgs, fsdb);
453 CERROR("Can't get db from client log %d\n", rc);
458 /* populate srpc rules from params llog */
459 rc = mgs_get_fsdb_srpc_from_llog(env, mgs, fsdb);
461 CERROR("Can't get db from params log %d\n", rc);
465 mutex_unlock(&fsdb->fsdb_mutex);
471 mutex_unlock(&fsdb->fsdb_mutex);
472 mgs_free_fsdb(mgs, fsdb);
478 -1= empty client log */
479 int mgs_check_index(const struct lu_env *env,
480 struct mgs_device *mgs,
481 struct mgs_target_info *mti)
488 LASSERT(!(mti->mti_flags & LDD_F_NEED_INDEX));
490 rc = mgs_find_or_make_fsdb(env, mgs, mti->mti_fsname, &fsdb);
492 CERROR("Can't get db for %s\n", mti->mti_fsname);
496 if (test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags))
499 if (mti->mti_flags & LDD_F_SV_TYPE_OST)
500 imap = fsdb->fsdb_ost_index_map;
501 else if (mti->mti_flags & LDD_F_SV_TYPE_MDT)
502 imap = fsdb->fsdb_mdt_index_map;
506 if (test_bit(mti->mti_stripe_index, imap))
511 static __inline__ int next_index(void *index_map, int map_len)
514 for (i = 0; i < map_len * 8; i++)
515 if (!test_bit(i, index_map)) {
518 CERROR("max index %d exceeded.\n", i);
523 0 newly marked as in use
525 +EALREADY for update of an old index */
526 static int mgs_set_index(const struct lu_env *env,
527 struct mgs_device *mgs,
528 struct mgs_target_info *mti)
535 rc = mgs_find_or_make_fsdb(env, mgs, mti->mti_fsname, &fsdb);
537 CERROR("Can't get db for %s\n", mti->mti_fsname);
541 mutex_lock(&fsdb->fsdb_mutex);
542 if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
543 imap = fsdb->fsdb_ost_index_map;
544 } else if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
545 imap = fsdb->fsdb_mdt_index_map;
547 GOTO(out_up, rc = -EINVAL);
550 if (mti->mti_flags & LDD_F_NEED_INDEX) {
551 rc = next_index(imap, INDEX_MAP_SIZE);
553 GOTO(out_up, rc = -ERANGE);
554 mti->mti_stripe_index = rc;
555 if (mti->mti_flags & LDD_F_SV_TYPE_MDT)
556 fsdb->fsdb_mdt_count ++;
559 if (mti->mti_stripe_index >= INDEX_MAP_SIZE * 8) {
560 LCONSOLE_ERROR_MSG(0x13f, "Server %s requested index %d, "
561 "but the max index is %d.\n",
562 mti->mti_svname, mti->mti_stripe_index,
564 GOTO(out_up, rc = -ERANGE);
567 if (test_bit(mti->mti_stripe_index, imap)) {
568 if ((mti->mti_flags & LDD_F_VIRGIN) &&
569 !(mti->mti_flags & LDD_F_WRITECONF)) {
570 LCONSOLE_ERROR_MSG(0x140, "Server %s requested index "
571 "%d, but that index is already in "
572 "use. Use --writeconf to force\n",
574 mti->mti_stripe_index);
575 GOTO(out_up, rc = -EADDRINUSE);
577 CDEBUG(D_MGS, "Server %s updating index %d\n",
578 mti->mti_svname, mti->mti_stripe_index);
579 GOTO(out_up, rc = EALREADY);
583 set_bit(mti->mti_stripe_index, imap);
584 clear_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags);
585 mutex_unlock(&fsdb->fsdb_mutex);
586 server_make_name(mti->mti_flags & ~(LDD_F_VIRGIN | LDD_F_WRITECONF),
587 mti->mti_stripe_index, mti->mti_fsname, mti->mti_svname);
589 CDEBUG(D_MGS, "Set index for %s to %d\n", mti->mti_svname,
590 mti->mti_stripe_index);
594 mutex_unlock(&fsdb->fsdb_mutex);
598 struct mgs_modify_lookup {
599 struct cfg_marker mml_marker;
603 static int mgs_modify_handler(const struct lu_env *env,
604 struct llog_handle *llh,
605 struct llog_rec_hdr *rec, void *data)
607 struct mgs_modify_lookup *mml = data;
608 struct cfg_marker *marker;
609 struct lustre_cfg *lcfg = REC_DATA(rec);
610 int cfg_len = REC_DATA_LEN(rec);
614 if (rec->lrh_type != OBD_CFG_REC) {
615 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
619 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
621 CERROR("Insane cfg\n");
625 /* We only care about markers */
626 if (lcfg->lcfg_command != LCFG_MARKER)
629 marker = lustre_cfg_buf(lcfg, 1);
630 if ((strcmp(mml->mml_marker.cm_comment, marker->cm_comment) == 0) &&
631 (strcmp(mml->mml_marker.cm_tgtname, marker->cm_tgtname) == 0) &&
632 !(marker->cm_flags & CM_SKIP)) {
633 /* Found a non-skipped marker match */
634 CDEBUG(D_MGS, "Changing rec %u marker %d %x->%x: %s %s\n",
635 rec->lrh_index, marker->cm_step,
636 marker->cm_flags, mml->mml_marker.cm_flags,
637 marker->cm_tgtname, marker->cm_comment);
638 /* Overwrite the old marker llog entry */
639 marker->cm_flags &= ~CM_EXCLUDE; /* in case we're unexcluding */
640 marker->cm_flags |= mml->mml_marker.cm_flags;
641 marker->cm_canceltime = mml->mml_marker.cm_canceltime;
642 /* Header and tail are added back to lrh_len in
643 llog_lvfs_write_rec */
644 rec->lrh_len = cfg_len;
645 rc = llog_write(env, llh, rec, NULL, 0, (void *)lcfg,
655 * Modify an existing config log record (for CM_SKIP or CM_EXCLUDE)
657 * 0 - modified successfully,
658 * 1 - no modification was done
661 static int mgs_modify(const struct lu_env *env, struct mgs_device *mgs,
662 struct fs_db *fsdb, struct mgs_target_info *mti,
663 char *logname, char *devname, char *comment, int flags)
665 struct llog_handle *loghandle;
666 struct llog_ctxt *ctxt;
667 struct mgs_modify_lookup *mml;
672 LASSERT(mutex_is_locked(&fsdb->fsdb_mutex));
673 CDEBUG(D_MGS, "modify %s/%s/%s fl=%x\n", logname, devname, comment,
676 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
677 LASSERT(ctxt != NULL);
678 rc = llog_open(env, ctxt, &loghandle, NULL, logname, LLOG_OPEN_EXISTS);
685 rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL);
689 if (llog_get_size(loghandle) <= 1)
690 GOTO(out_close, rc = 0);
694 GOTO(out_close, rc = -ENOMEM);
695 if (strlcpy(mml->mml_marker.cm_comment, comment,
696 sizeof(mml->mml_marker.cm_comment)) >=
697 sizeof(mml->mml_marker.cm_comment))
698 GOTO(out_free, rc = -E2BIG);
699 if (strlcpy(mml->mml_marker.cm_tgtname, devname,
700 sizeof(mml->mml_marker.cm_tgtname)) >=
701 sizeof(mml->mml_marker.cm_tgtname))
702 GOTO(out_free, rc = -E2BIG);
703 /* Modify mostly means cancel */
704 mml->mml_marker.cm_flags = flags;
705 mml->mml_marker.cm_canceltime = flags ? cfs_time_current_sec() : 0;
706 mml->mml_modified = 0;
707 rc = llog_process(env, loghandle, mgs_modify_handler, (void *)mml,
709 if (!rc && !mml->mml_modified)
716 llog_close(env, loghandle);
719 CERROR("%s: modify %s/%s failed: rc = %d\n",
720 mgs->mgs_obd->obd_name, mti->mti_svname, comment, rc);
725 /** This structure is passed to mgs_replace_handler */
726 struct mgs_replace_uuid_lookup {
727 /* Nids are replaced for this target device */
728 struct mgs_target_info target;
729 /* Temporary modified llog */
730 struct llog_handle *temp_llh;
731 /* Flag is set if in target block*/
732 int in_target_device;
733 /* Nids already added. Just skip (multiple nids) */
734 int device_nids_added;
735 /* Flag is set if this block should not be copied */
740 * Check: a) if block should be skipped
741 * b) is it target block
746 * \retval 0 should not to be skipped
747 * \retval 1 should to be skipped
749 static int check_markers(struct lustre_cfg *lcfg,
750 struct mgs_replace_uuid_lookup *mrul)
752 struct cfg_marker *marker;
754 /* Track markers. Find given device */
755 if (lcfg->lcfg_command == LCFG_MARKER) {
756 marker = lustre_cfg_buf(lcfg, 1);
757 /* Clean llog from records marked as CM_EXCLUDE.
758 CM_SKIP records are used for "active" command
759 and can be restored if needed */
760 if ((marker->cm_flags & (CM_EXCLUDE | CM_START)) ==
761 (CM_EXCLUDE | CM_START)) {
766 if ((marker->cm_flags & (CM_EXCLUDE | CM_END)) ==
767 (CM_EXCLUDE | CM_END)) {
772 if (strcmp(mrul->target.mti_svname, marker->cm_tgtname) == 0) {
773 LASSERT(!(marker->cm_flags & CM_START) ||
774 !(marker->cm_flags & CM_END));
775 if (marker->cm_flags & CM_START) {
776 mrul->in_target_device = 1;
777 mrul->device_nids_added = 0;
778 } else if (marker->cm_flags & CM_END)
779 mrul->in_target_device = 0;
786 static int record_lcfg(const struct lu_env *env, struct llog_handle *llh,
787 struct lustre_cfg *lcfg)
789 struct llog_rec_hdr rec;
795 LASSERT(llh->lgh_ctxt);
797 buflen = lustre_cfg_len(lcfg->lcfg_bufcount,
799 rec.lrh_len = llog_data_len(buflen);
800 rec.lrh_type = OBD_CFG_REC;
802 /* idx = -1 means append */
803 rc = llog_write(env, llh, &rec, NULL, 0, (void *)lcfg, -1);
805 CERROR("failed %d\n", rc);
809 static int record_base(const struct lu_env *env, struct llog_handle *llh,
810 char *cfgname, lnet_nid_t nid, int cmd,
811 char *s1, char *s2, char *s3, char *s4)
813 struct mgs_thread_info *mgi = mgs_env_info(env);
814 struct lustre_cfg *lcfg;
817 CDEBUG(D_MGS, "lcfg %s %#x %s %s %s %s\n", cfgname,
818 cmd, s1, s2, s3, s4);
820 lustre_cfg_bufs_reset(&mgi->mgi_bufs, cfgname);
822 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, s1);
824 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 2, s2);
826 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 3, s3);
828 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 4, s4);
830 lcfg = lustre_cfg_new(cmd, &mgi->mgi_bufs);
833 lcfg->lcfg_nid = nid;
835 rc = record_lcfg(env, llh, lcfg);
837 lustre_cfg_free(lcfg);
840 CERROR("error %d: lcfg %s %#x %s %s %s %s\n", rc, cfgname,
841 cmd, s1, s2, s3, s4);
846 static inline int record_add_uuid(const struct lu_env *env,
847 struct llog_handle *llh,
848 uint64_t nid, char *uuid)
850 return record_base(env, llh, NULL, nid, LCFG_ADD_UUID, uuid, 0, 0, 0);
853 static inline int record_add_conn(const struct lu_env *env,
854 struct llog_handle *llh,
855 char *devname, char *uuid)
857 return record_base(env, llh, devname, 0, LCFG_ADD_CONN, uuid, 0, 0, 0);
860 static inline int record_attach(const struct lu_env *env,
861 struct llog_handle *llh, char *devname,
862 char *type, char *uuid)
864 return record_base(env, llh,devname, 0, LCFG_ATTACH, type, uuid, 0, 0);
867 static inline int record_setup(const struct lu_env *env,
868 struct llog_handle *llh, char *devname,
869 char *s1, char *s2, char *s3, char *s4)
871 return record_base(env, llh, devname, 0, LCFG_SETUP, s1, s2, s3, s4);
875 * \retval <0 record processing error
876 * \retval n record is processed. No need copy original one.
877 * \retval 0 record is not processed.
879 static int process_command(const struct lu_env *env, struct lustre_cfg *lcfg,
880 struct mgs_replace_uuid_lookup *mrul)
887 if (lcfg->lcfg_command == LCFG_ADD_UUID) {
888 /* LCFG_ADD_UUID command found. Let's skip original command
889 and add passed nids */
890 ptr = mrul->target.mti_params;
891 while (class_parse_nid(ptr, &nid, &ptr) == 0) {
892 CDEBUG(D_MGS, "add nid %s with uuid %s, "
893 "device %s\n", libcfs_nid2str(nid),
894 mrul->target.mti_params,
895 mrul->target.mti_svname);
896 rc = record_add_uuid(env,
898 mrul->target.mti_params);
903 if (nids_added == 0) {
904 CERROR("No new nids were added, nid %s with uuid %s, "
905 "device %s\n", libcfs_nid2str(nid),
906 mrul->target.mti_params,
907 mrul->target.mti_svname);
910 mrul->device_nids_added = 1;
916 if (mrul->device_nids_added && lcfg->lcfg_command == LCFG_SETUP) {
917 /* LCFG_SETUP command found. UUID should be changed */
918 rc = record_setup(env,
920 /* devname the same */
921 lustre_cfg_string(lcfg, 0),
922 /* s1 is not changed */
923 lustre_cfg_string(lcfg, 1),
924 /* new uuid should be
926 mrul->target.mti_params,
927 /* s3 is not changed */
928 lustre_cfg_string(lcfg, 3),
929 /* s4 is not changed */
930 lustre_cfg_string(lcfg, 4));
934 /* Another commands in target device block */
939 * Handler that called for every record in llog.
940 * Records are processed in order they placed in llog.
942 * \param[in] llh log to be processed
943 * \param[in] rec current record
944 * \param[in] data mgs_replace_uuid_lookup structure
948 static int mgs_replace_handler(const struct lu_env *env,
949 struct llog_handle *llh,
950 struct llog_rec_hdr *rec,
953 struct mgs_replace_uuid_lookup *mrul;
954 struct lustre_cfg *lcfg = REC_DATA(rec);
955 int cfg_len = REC_DATA_LEN(rec);
959 mrul = (struct mgs_replace_uuid_lookup *)data;
961 if (rec->lrh_type != OBD_CFG_REC) {
962 CERROR("unhandled lrh_type: %#x, cmd %x %s %s\n",
963 rec->lrh_type, lcfg->lcfg_command,
964 lustre_cfg_string(lcfg, 0),
965 lustre_cfg_string(lcfg, 1));
969 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
971 /* Do not copy any invalidated records */
972 GOTO(skip_out, rc = 0);
975 rc = check_markers(lcfg, mrul);
976 if (rc || mrul->skip_it)
977 GOTO(skip_out, rc = 0);
979 /* Write to new log all commands outside target device block */
980 if (!mrul->in_target_device)
981 GOTO(copy_out, rc = 0);
983 /* Skip all other LCFG_ADD_UUID and LCFG_ADD_CONN records
984 (failover nids) for this target, assuming that if then
985 primary is changing then so is the failover */
986 if (mrul->device_nids_added &&
987 (lcfg->lcfg_command == LCFG_ADD_UUID ||
988 lcfg->lcfg_command == LCFG_ADD_CONN))
989 GOTO(skip_out, rc = 0);
991 rc = process_command(env, lcfg, mrul);
998 /* Record is placed in temporary llog as is */
999 rc = llog_write(env, mrul->temp_llh, rec, NULL, 0, NULL, -1);
1001 CDEBUG(D_MGS, "Copied idx=%d, rc=%d, len=%d, cmd %x %s %s\n",
1002 rec->lrh_index, rc, rec->lrh_len, lcfg->lcfg_command,
1003 lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));
1007 CDEBUG(D_MGS, "Skipped idx=%d, rc=%d, len=%d, cmd %x %s %s\n",
1008 rec->lrh_index, rc, rec->lrh_len, lcfg->lcfg_command,
1009 lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));
1013 static int mgs_log_is_empty(const struct lu_env *env,
1014 struct mgs_device *mgs, char *name)
1016 struct llog_ctxt *ctxt;
1019 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
1020 LASSERT(ctxt != NULL);
1022 rc = llog_is_empty(env, ctxt, name);
1023 llog_ctxt_put(ctxt);
1027 static int mgs_replace_nids_log(const struct lu_env *env,
1028 struct obd_device *mgs, struct fs_db *fsdb,
1029 char *logname, char *devname, char *nids)
1031 struct llog_handle *orig_llh, *backup_llh;
1032 struct llog_ctxt *ctxt;
1033 struct mgs_replace_uuid_lookup *mrul;
1034 struct mgs_device *mgs_dev = lu2mgs_dev(mgs->obd_lu_dev);
1035 static struct obd_uuid cfg_uuid = { .uuid = "config_uuid" };
1040 CDEBUG(D_MGS, "Replace nids for %s in %s\n", devname, logname);
1042 ctxt = llog_get_context(mgs, LLOG_CONFIG_ORIG_CTXT);
1043 LASSERT(ctxt != NULL);
1045 if (mgs_log_is_empty(env, mgs_dev, logname)) {
1046 /* Log is empty. Nothing to replace */
1047 GOTO(out_put, rc = 0);
1050 OBD_ALLOC(backup, strlen(logname) + strlen(".bak") + 1);
1052 GOTO(out_put, rc = -ENOMEM);
1054 sprintf(backup, "%s.bak", logname);
1056 rc = llog_backup(env, mgs, ctxt, ctxt, logname, backup);
1058 /* Now erase original log file. Connections are not allowed.
1059 Backup is already saved */
1060 rc = llog_erase(env, ctxt, NULL, logname);
1063 } else if (rc != -ENOENT) {
1064 CERROR("%s: can't make backup for %s: rc = %d\n",
1065 mgs->obd_name, logname, rc);
1069 /* open local log */
1070 rc = llog_open_create(env, ctxt, &orig_llh, NULL, logname);
1072 GOTO(out_restore, rc);
1074 rc = llog_init_handle(env, orig_llh, LLOG_F_IS_PLAIN, &cfg_uuid);
1076 GOTO(out_closel, rc);
1078 /* open backup llog */
1079 rc = llog_open(env, ctxt, &backup_llh, NULL, backup,
1082 GOTO(out_closel, rc);
1084 rc = llog_init_handle(env, backup_llh, LLOG_F_IS_PLAIN, NULL);
1086 GOTO(out_close, rc);
1088 if (llog_get_size(backup_llh) <= 1)
1089 GOTO(out_close, rc = 0);
1091 OBD_ALLOC_PTR(mrul);
1093 GOTO(out_close, rc = -ENOMEM);
1094 /* devname is only needed information to replace UUID records */
1095 strncpy(mrul->target.mti_svname, devname, MTI_NAME_MAXLEN);
1096 /* parse nids later */
1097 strncpy(mrul->target.mti_params, nids, MTI_PARAM_MAXLEN);
1098 /* Copy records to this temporary llog */
1099 mrul->temp_llh = orig_llh;
1101 rc = llog_process(env, backup_llh, mgs_replace_handler,
1102 (void *)mrul, NULL);
1105 rc2 = llog_close(NULL, backup_llh);
1109 rc2 = llog_close(NULL, orig_llh);
1115 CERROR("%s: llog should be restored: rc = %d\n",
1117 rc2 = llog_backup(env, mgs, ctxt, ctxt, backup,
1120 CERROR("%s: can't restore backup %s: rc = %d\n",
1121 mgs->obd_name, logname, rc2);
1125 OBD_FREE(backup, strlen(backup) + 1);
1128 llog_ctxt_put(ctxt);
1131 CERROR("%s: failed to replace nids in log %s: rc = %d\n",
1132 mgs->obd_name, logname, rc);
1138 * Parse device name and get file system name and/or device index
1140 * \param[in] devname device name (ex. lustre-MDT0000)
1141 * \param[out] fsname file system name(optional)
1142 * \param[out] index device index(optional)
1146 static int mgs_parse_devname(char *devname, char *fsname, __u32 *index)
1151 /* Extract fsname */
1153 rc = server_name2fsname(devname, fsname, NULL);
1155 CDEBUG(D_MGS, "Device name %s without fsname\n",
1162 rc = server_name2index(devname, index, NULL);
1164 CDEBUG(D_MGS, "Device name %s with wrong index\n",
1173 /* This is only called during replace_nids */
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 int num_exports = 0;
1179 struct obd_export *exp;
1181 spin_lock(&mgs_obd->obd_dev_lock);
1182 list_for_each_entry(exp, &mgs_obd->obd_exports, exp_obd_chain) {
1183 /* skip self export */
1184 if (exp == mgs_obd->obd_self_export)
1186 if (exp_connect_flags(exp) & OBD_CONNECT_MDS_MDS)
1191 CERROR("%s: node %s still connected during replace_nids "
1192 "connect_flags:%llx\n",
1194 libcfs_nid2str(exp->exp_nid_stats->nid),
1195 exp_connect_flags(exp));
1198 spin_unlock(&mgs_obd->obd_dev_lock);
1200 /* osd, MGS and MGC + self_export
1201 (wc -l /proc/fs/lustre/devices <= 2) && (non self exports == 0) */
1202 return (num_devices <= 3) && (num_exports == 0);
1205 static int name_create_mdt(char **logname, char *fsname, int i)
1209 sprintf(mdt_index, "-MDT%04x", i);
1210 return name_create(logname, fsname, mdt_index);
1214 * Replace nids for \a device to \a nids values
1216 * \param obd MGS obd device
1217 * \param devname nids need to be replaced for this device
1218 * (ex. lustre-OST0000)
1219 * \param nids nids list (ex. nid1,nid2,nid3)
1223 int mgs_replace_nids(const struct lu_env *env,
1224 struct mgs_device *mgs,
1225 char *devname, char *nids)
1227 /* Assume fsname is part of device name */
1228 char fsname[MTI_NAME_MAXLEN];
1235 struct obd_device *mgs_obd = mgs->mgs_obd;
1238 /* We can only change NIDs if no other nodes are connected */
1239 spin_lock(&mgs_obd->obd_dev_lock);
1240 conn_state = mgs_obd->obd_no_conn;
1241 mgs_obd->obd_no_conn = 1;
1242 spin_unlock(&mgs_obd->obd_dev_lock);
1244 /* We can not change nids if not only MGS is started */
1245 if (!only_mgs_is_running(mgs_obd)) {
1246 CERROR("Only MGS is allowed to be started\n");
1247 GOTO(out, rc = -EINPROGRESS);
1250 /* Get fsname and index*/
1251 rc = mgs_parse_devname(devname, fsname, &index);
1255 rc = mgs_find_or_make_fsdb(env, mgs, fsname, &fsdb);
1257 CERROR("%s: can't find fsdb: rc = %d\n", fsname, rc);
1261 /* Process client llogs */
1262 name_create(&logname, fsname, "-client");
1263 rc = mgs_replace_nids_log(env, mgs_obd, fsdb, logname, devname, nids);
1264 name_destroy(&logname);
1266 CERROR("%s: error while replacing NIDs for %s: rc = %d\n",
1267 fsname, devname, rc);
1271 /* Process MDT llogs */
1272 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
1273 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
1275 name_create_mdt(&logname, fsname, i);
1276 rc = mgs_replace_nids_log(env, mgs_obd, fsdb, logname, devname, nids);
1277 name_destroy(&logname);
1283 spin_lock(&mgs_obd->obd_dev_lock);
1284 mgs_obd->obd_no_conn = conn_state;
1285 spin_unlock(&mgs_obd->obd_dev_lock);
1290 static int record_lov_setup(const struct lu_env *env, struct llog_handle *llh,
1291 char *devname, struct lov_desc *desc)
1293 struct mgs_thread_info *mgi = mgs_env_info(env);
1294 struct lustre_cfg *lcfg;
1297 lustre_cfg_bufs_reset(&mgi->mgi_bufs, devname);
1298 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, desc, sizeof(*desc));
1299 lcfg = lustre_cfg_new(LCFG_SETUP, &mgi->mgi_bufs);
1302 rc = record_lcfg(env, llh, lcfg);
1304 lustre_cfg_free(lcfg);
1308 static int record_lmv_setup(const struct lu_env *env, struct llog_handle *llh,
1309 char *devname, struct lmv_desc *desc)
1311 struct mgs_thread_info *mgi = mgs_env_info(env);
1312 struct lustre_cfg *lcfg;
1315 lustre_cfg_bufs_reset(&mgi->mgi_bufs, devname);
1316 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, desc, sizeof(*desc));
1317 lcfg = lustre_cfg_new(LCFG_SETUP, &mgi->mgi_bufs);
1319 rc = record_lcfg(env, llh, lcfg);
1321 lustre_cfg_free(lcfg);
1325 static inline int record_mdc_add(const struct lu_env *env,
1326 struct llog_handle *llh,
1327 char *logname, char *mdcuuid,
1328 char *mdtuuid, char *index,
1331 return record_base(env,llh,logname,0,LCFG_ADD_MDC,
1332 mdtuuid,index,gen,mdcuuid);
1335 static inline int record_lov_add(const struct lu_env *env,
1336 struct llog_handle *llh,
1337 char *lov_name, char *ost_uuid,
1338 char *index, char *gen)
1340 return record_base(env,llh,lov_name,0,LCFG_LOV_ADD_OBD,
1341 ost_uuid, index, gen, 0);
1344 static inline int record_mount_opt(const struct lu_env *env,
1345 struct llog_handle *llh,
1346 char *profile, char *lov_name,
1349 return record_base(env,llh,NULL,0,LCFG_MOUNTOPT,
1350 profile,lov_name,mdc_name,0);
1353 static int record_marker(const struct lu_env *env,
1354 struct llog_handle *llh,
1355 struct fs_db *fsdb, __u32 flags,
1356 char *tgtname, char *comment)
1358 struct mgs_thread_info *mgi = mgs_env_info(env);
1359 struct lustre_cfg *lcfg;
1363 if (flags & CM_START)
1365 mgi->mgi_marker.cm_step = fsdb->fsdb_gen;
1366 mgi->mgi_marker.cm_flags = flags;
1367 mgi->mgi_marker.cm_vers = LUSTRE_VERSION_CODE;
1368 cplen = strlcpy(mgi->mgi_marker.cm_tgtname, tgtname,
1369 sizeof(mgi->mgi_marker.cm_tgtname));
1370 if (cplen >= sizeof(mgi->mgi_marker.cm_tgtname))
1372 cplen = strlcpy(mgi->mgi_marker.cm_comment, comment,
1373 sizeof(mgi->mgi_marker.cm_comment));
1374 if (cplen >= sizeof(mgi->mgi_marker.cm_comment))
1376 mgi->mgi_marker.cm_createtime = cfs_time_current_sec();
1377 mgi->mgi_marker.cm_canceltime = 0;
1378 lustre_cfg_bufs_reset(&mgi->mgi_bufs, NULL);
1379 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, &mgi->mgi_marker,
1380 sizeof(mgi->mgi_marker));
1381 lcfg = lustre_cfg_new(LCFG_MARKER, &mgi->mgi_bufs);
1384 rc = record_lcfg(env, llh, lcfg);
1386 lustre_cfg_free(lcfg);
1390 static int record_start_log(const struct lu_env *env, struct mgs_device *mgs,
1391 struct llog_handle **llh, char *name)
1393 static struct obd_uuid cfg_uuid = { .uuid = "config_uuid" };
1394 struct llog_ctxt *ctxt;
1398 GOTO(out, rc = -EBUSY);
1400 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
1402 GOTO(out, rc = -ENODEV);
1403 LASSERT(ctxt->loc_obd == mgs->mgs_obd);
1405 rc = llog_open_create(env, ctxt, llh, NULL, name);
1408 rc = llog_init_handle(env, *llh, LLOG_F_IS_PLAIN, &cfg_uuid);
1410 llog_close(env, *llh);
1412 llog_ctxt_put(ctxt);
1415 CERROR("%s: can't start log %s: rc = %d\n",
1416 mgs->mgs_obd->obd_name, name, rc);
1422 static int record_end_log(const struct lu_env *env, struct llog_handle **llh)
1426 rc = llog_close(env, *llh);
1432 /******************** config "macros" *********************/
1434 /* write an lcfg directly into a log (with markers) */
1435 static int mgs_write_log_direct(const struct lu_env *env,
1436 struct mgs_device *mgs, struct fs_db *fsdb,
1437 char *logname, struct lustre_cfg *lcfg,
1438 char *devname, char *comment)
1440 struct llog_handle *llh = NULL;
1447 rc = record_start_log(env, mgs, &llh, logname);
1451 /* FIXME These should be a single journal transaction */
1452 rc = record_marker(env, llh, fsdb, CM_START, devname, comment);
1455 rc = record_lcfg(env, llh, lcfg);
1458 rc = record_marker(env, llh, fsdb, CM_END, devname, comment);
1462 record_end_log(env, &llh);
1466 /* write the lcfg in all logs for the given fs */
1467 int mgs_write_log_direct_all(const struct lu_env *env,
1468 struct mgs_device *mgs,
1470 struct mgs_target_info *mti,
1471 struct lustre_cfg *lcfg,
1472 char *devname, char *comment,
1476 struct mgs_direntry *dirent, *n;
1477 char *fsname = mti->mti_fsname;
1479 int rc = 0, len = strlen(fsname);
1482 /* We need to set params for any future logs
1483 as well. FIXME Append this file to every new log.
1484 Actually, we should store as params (text), not llogs. Or
1486 rc = name_create(&logname, fsname, "-params");
1489 if (mgs_log_is_empty(env, mgs, logname)) {
1490 struct llog_handle *llh = NULL;
1491 rc = record_start_log(env, mgs, &llh, logname);
1493 record_end_log(env, &llh);
1495 name_destroy(&logname);
1499 /* Find all the logs in the CONFIGS directory */
1500 rc = class_dentry_readdir(env, mgs, &list);
1504 /* Could use fsdb index maps instead of directory listing */
1505 cfs_list_for_each_entry_safe(dirent, n, &list, list) {
1506 cfs_list_del(&dirent->list);
1507 /* don't write to sptlrpc rule log */
1508 if (strstr(dirent->name, "-sptlrpc") != NULL)
1511 /* caller wants write server logs only */
1512 if (server_only && strstr(dirent->name, "-client") != NULL)
1515 if (strncmp(fsname, dirent->name, len) == 0) {
1516 CDEBUG(D_MGS, "Changing log %s\n", dirent->name);
1517 /* Erase any old settings of this same parameter */
1518 rc = mgs_modify(env, mgs, fsdb, mti, dirent->name,
1519 devname, comment, CM_SKIP);
1521 CERROR("%s: Can't modify llog %s: rc = %d\n",
1522 mgs->mgs_obd->obd_name, dirent->name,rc);
1523 /* Write the new one */
1525 rc = mgs_write_log_direct(env, mgs, fsdb,
1530 CERROR("%s: writing log %s: rc = %d\n",
1531 mgs->mgs_obd->obd_name,
1536 mgs_direntry_free(dirent);
1542 static int mgs_write_log_osp_to_mdt(const struct lu_env *env,
1543 struct mgs_device *mgs,
1545 struct mgs_target_info *mti,
1546 int index, char *logname);
1547 static int mgs_write_log_osc_to_lov(const struct lu_env *env,
1548 struct mgs_device *mgs,
1550 struct mgs_target_info *mti,
1551 char *logname, char *suffix, char *lovname,
1552 enum lustre_sec_part sec_part, int flags);
1553 static int name_create_mdt_and_lov(char **logname, char **lovname,
1554 struct fs_db *fsdb, int i);
1556 static int add_param(char *params, char *key, char *val)
1558 char *start = params + strlen(params);
1559 char *end = params + sizeof(((struct mgs_target_info *)0)->mti_params);
1563 keylen = strlen(key);
1564 if (start + 1 + keylen + strlen(val) >= end) {
1565 CERROR("params are too long: %s %s%s\n",
1566 params, key != NULL ? key : "", val);
1570 sprintf(start, " %s%s", key != NULL ? key : "", val);
1575 * Walk through client config log record and convert the related records
1578 static int mgs_steal_client_llog_handler(const struct lu_env *env,
1579 struct llog_handle *llh,
1580 struct llog_rec_hdr *rec, void *data)
1582 struct mgs_device *mgs;
1583 struct obd_device *obd;
1584 struct mgs_target_info *mti, *tmti;
1586 int cfg_len = rec->lrh_len;
1587 char *cfg_buf = (char*) (rec + 1);
1588 struct lustre_cfg *lcfg;
1590 struct llog_handle *mdt_llh = NULL;
1591 static int got_an_osc_or_mdc = 0;
1592 /* 0: not found any osc/mdc;
1596 static int last_step = -1;
1601 mti = ((struct temp_comp*)data)->comp_mti;
1602 tmti = ((struct temp_comp*)data)->comp_tmti;
1603 fsdb = ((struct temp_comp*)data)->comp_fsdb;
1604 obd = ((struct temp_comp *)data)->comp_obd;
1605 mgs = lu2mgs_dev(obd->obd_lu_dev);
1608 if (rec->lrh_type != OBD_CFG_REC) {
1609 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
1613 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
1615 CERROR("Insane cfg\n");
1619 lcfg = (struct lustre_cfg *)cfg_buf;
1621 if (lcfg->lcfg_command == LCFG_MARKER) {
1622 struct cfg_marker *marker;
1623 marker = lustre_cfg_buf(lcfg, 1);
1624 if (!strncmp(marker->cm_comment, "add osc", 7) &&
1625 (marker->cm_flags & CM_START) &&
1626 !(marker->cm_flags & CM_SKIP)) {
1627 got_an_osc_or_mdc = 1;
1628 cplen = strlcpy(tmti->mti_svname, marker->cm_tgtname,
1629 sizeof(tmti->mti_svname));
1630 if (cplen >= sizeof(tmti->mti_svname))
1632 rc = record_start_log(env, mgs, &mdt_llh,
1636 rc = record_marker(env, mdt_llh, fsdb, CM_START,
1637 mti->mti_svname, "add osc(copied)");
1638 record_end_log(env, &mdt_llh);
1639 last_step = marker->cm_step;
1642 if (!strncmp(marker->cm_comment, "add osc", 7) &&
1643 (marker->cm_flags & CM_END) &&
1644 !(marker->cm_flags & CM_SKIP)) {
1645 LASSERT(last_step == marker->cm_step);
1647 got_an_osc_or_mdc = 0;
1648 memset(tmti, 0, sizeof(*tmti));
1649 rc = record_start_log(env, mgs, &mdt_llh,
1653 rc = record_marker(env, mdt_llh, fsdb, CM_END,
1654 mti->mti_svname, "add osc(copied)");
1655 record_end_log(env, &mdt_llh);
1658 if (!strncmp(marker->cm_comment, "add mdc", 7) &&
1659 (marker->cm_flags & CM_START) &&
1660 !(marker->cm_flags & CM_SKIP)) {
1661 got_an_osc_or_mdc = 2;
1662 last_step = marker->cm_step;
1663 memcpy(tmti->mti_svname, marker->cm_tgtname,
1664 strlen(marker->cm_tgtname));
1668 if (!strncmp(marker->cm_comment, "add mdc", 7) &&
1669 (marker->cm_flags & CM_END) &&
1670 !(marker->cm_flags & CM_SKIP)) {
1671 LASSERT(last_step == marker->cm_step);
1673 got_an_osc_or_mdc = 0;
1674 memset(tmti, 0, sizeof(*tmti));
1679 if (got_an_osc_or_mdc == 0 || last_step < 0)
1682 if (lcfg->lcfg_command == LCFG_ADD_UUID) {
1683 uint64_t nodenid = lcfg->lcfg_nid;
1685 if (strlen(tmti->mti_uuid) == 0) {
1686 /* target uuid not set, this config record is before
1687 * LCFG_SETUP, this nid is one of target node nid.
1689 tmti->mti_nids[tmti->mti_nid_count] = nodenid;
1690 tmti->mti_nid_count++;
1692 /* failover node nid */
1693 rc = add_param(tmti->mti_params, PARAM_FAILNODE,
1694 libcfs_nid2str(nodenid));
1700 if (lcfg->lcfg_command == LCFG_SETUP) {
1703 target = lustre_cfg_string(lcfg, 1);
1704 memcpy(tmti->mti_uuid, target, strlen(target));
1708 /* ignore client side sptlrpc_conf_log */
1709 if (lcfg->lcfg_command == LCFG_SPTLRPC_CONF)
1712 if (lcfg->lcfg_command == LCFG_ADD_MDC) {
1715 if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1)
1718 memcpy(tmti->mti_fsname, mti->mti_fsname,
1719 strlen(mti->mti_fsname));
1720 tmti->mti_stripe_index = index;
1722 rc = mgs_write_log_osp_to_mdt(env, mgs, fsdb, tmti,
1723 mti->mti_stripe_index,
1725 memset(tmti, 0, sizeof(*tmti));
1729 if (lcfg->lcfg_command == LCFG_LOV_ADD_OBD) {
1732 char *logname, *lovname;
1734 rc = name_create_mdt_and_lov(&logname, &lovname, fsdb,
1735 mti->mti_stripe_index);
1738 sprintf(mdt_index, "-MDT%04x", mti->mti_stripe_index);
1740 if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1) {
1741 name_destroy(&logname);
1742 name_destroy(&lovname);
1746 tmti->mti_stripe_index = index;
1747 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, tmti, logname,
1750 name_destroy(&logname);
1751 name_destroy(&lovname);
1757 /* fsdb->fsdb_mutex is already held in mgs_write_log_target*/
1758 /* stealed from mgs_get_fsdb_from_llog*/
1759 static int mgs_steal_llog_for_mdt_from_client(const struct lu_env *env,
1760 struct mgs_device *mgs,
1762 struct temp_comp* comp)
1764 struct llog_handle *loghandle;
1765 struct mgs_target_info *tmti;
1766 struct llog_ctxt *ctxt;
1771 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
1772 LASSERT(ctxt != NULL);
1774 OBD_ALLOC_PTR(tmti);
1776 GOTO(out_ctxt, rc = -ENOMEM);
1778 comp->comp_tmti = tmti;
1779 comp->comp_obd = mgs->mgs_obd;
1781 rc = llog_open(env, ctxt, &loghandle, NULL, client_name,
1789 rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL);
1791 GOTO(out_close, rc);
1793 rc = llog_process_or_fork(env, loghandle, mgs_steal_client_llog_handler,
1794 (void *)comp, NULL, false);
1795 CDEBUG(D_MGS, "steal llog re = %d\n", rc);
1797 llog_close(env, loghandle);
1801 llog_ctxt_put(ctxt);
1805 /* lmv is the second thing for client logs */
1806 /* copied from mgs_write_log_lov. Please refer to that. */
1807 static int mgs_write_log_lmv(const struct lu_env *env,
1808 struct mgs_device *mgs,
1810 struct mgs_target_info *mti,
1811 char *logname, char *lmvname)
1813 struct llog_handle *llh = NULL;
1814 struct lmv_desc *lmvdesc;
1819 CDEBUG(D_MGS, "Writing lmv(%s) log for %s\n", lmvname,logname);
1821 OBD_ALLOC_PTR(lmvdesc);
1822 if (lmvdesc == NULL)
1824 lmvdesc->ld_active_tgt_count = 0;
1825 lmvdesc->ld_tgt_count = 0;
1826 sprintf((char*)lmvdesc->ld_uuid.uuid, "%s_UUID", lmvname);
1827 uuid = (char *)lmvdesc->ld_uuid.uuid;
1829 rc = record_start_log(env, mgs, &llh, logname);
1832 rc = record_marker(env, llh, fsdb, CM_START, lmvname, "lmv setup");
1835 rc = record_attach(env, llh, lmvname, "lmv", uuid);
1838 rc = record_lmv_setup(env, llh, lmvname, lmvdesc);
1841 rc = record_marker(env, llh, fsdb, CM_END, lmvname, "lmv setup");
1845 record_end_log(env, &llh);
1847 OBD_FREE_PTR(lmvdesc);
1851 /* lov is the first thing in the mdt and client logs */
1852 static int mgs_write_log_lov(const struct lu_env *env, struct mgs_device *mgs,
1853 struct fs_db *fsdb, struct mgs_target_info *mti,
1854 char *logname, char *lovname)
1856 struct llog_handle *llh = NULL;
1857 struct lov_desc *lovdesc;
1862 CDEBUG(D_MGS, "Writing lov(%s) log for %s\n", lovname, logname);
1865 #01 L attach 0:lov_mdsA 1:lov 2:71ccb_lov_mdsA_19f961a9e1
1866 #02 L lov_setup 0:lov_mdsA 1:(struct lov_desc)
1867 uuid=lov1_UUID, stripe count=1, size=1048576, offset=0, pattern=0
1870 /* FIXME just make lov_setup accept empty desc (put uuid in buf 2) */
1871 OBD_ALLOC_PTR(lovdesc);
1872 if (lovdesc == NULL)
1874 lovdesc->ld_magic = LOV_DESC_MAGIC;
1875 lovdesc->ld_tgt_count = 0;
1876 /* Defaults. Can be changed later by lcfg config_param */
1877 lovdesc->ld_default_stripe_count = 1;
1878 lovdesc->ld_pattern = LOV_PATTERN_RAID0;
1879 lovdesc->ld_default_stripe_size = LOV_DESC_STRIPE_SIZE_DEFAULT;
1880 lovdesc->ld_default_stripe_offset = -1;
1881 lovdesc->ld_qos_maxage = LOV_DESC_QOS_MAXAGE_DEFAULT;
1882 sprintf((char*)lovdesc->ld_uuid.uuid, "%s_UUID", lovname);
1883 /* can these be the same? */
1884 uuid = (char *)lovdesc->ld_uuid.uuid;
1886 /* This should always be the first entry in a log.
1887 rc = mgs_clear_log(obd, logname); */
1888 rc = record_start_log(env, mgs, &llh, logname);
1891 /* FIXME these should be a single journal transaction */
1892 rc = record_marker(env, llh, fsdb, CM_START, lovname, "lov setup");
1895 rc = record_attach(env, llh, lovname, "lov", uuid);
1898 rc = record_lov_setup(env, llh, lovname, lovdesc);
1901 rc = record_marker(env, llh, fsdb, CM_END, lovname, "lov setup");
1906 record_end_log(env, &llh);
1908 OBD_FREE_PTR(lovdesc);
1912 /* add failnids to open log */
1913 static int mgs_write_log_failnids(const struct lu_env *env,
1914 struct mgs_target_info *mti,
1915 struct llog_handle *llh,
1918 char *failnodeuuid = NULL;
1919 char *ptr = mti->mti_params;
1924 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) nal=90 0: 1:uml1_UUID
1925 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
1926 #05 L setup 0:OSC_uml1_ost1_mdsA 1:ost1_UUID 2:uml1_UUID
1927 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) nal=90 0: 1:uml2_UUID
1928 #0x L add_uuid nid=2@elan(0x1000000000002) nal=90 0: 1:uml2_UUID
1929 #07 L add_conn 0:OSC_uml1_ost1_mdsA 1:uml2_UUID
1932 /* Pull failnid info out of params string */
1933 while (class_find_param(ptr, PARAM_FAILNODE, &ptr) == 0) {
1934 while (class_parse_nid(ptr, &nid, &ptr) == 0) {
1935 if (failnodeuuid == NULL) {
1936 /* We don't know the failover node name,
1937 so just use the first nid as the uuid */
1938 rc = name_create(&failnodeuuid,
1939 libcfs_nid2str(nid), "");
1943 CDEBUG(D_MGS, "add nid %s for failover uuid %s, "
1944 "client %s\n", libcfs_nid2str(nid),
1945 failnodeuuid, cliname);
1946 rc = record_add_uuid(env, llh, nid, failnodeuuid);
1949 rc = record_add_conn(env, llh, cliname, failnodeuuid);
1950 name_destroy(&failnodeuuid);
1951 failnodeuuid = NULL;
1958 static int mgs_write_log_mdc_to_lmv(const struct lu_env *env,
1959 struct mgs_device *mgs,
1961 struct mgs_target_info *mti,
1962 char *logname, char *lmvname)
1964 struct llog_handle *llh = NULL;
1965 char *mdcname = NULL;
1966 char *nodeuuid = NULL;
1967 char *mdcuuid = NULL;
1968 char *lmvuuid = NULL;
1973 if (mgs_log_is_empty(env, mgs, logname)) {
1974 CERROR("log is empty! Logical error\n");
1978 CDEBUG(D_MGS, "adding mdc for %s to log %s:lmv(%s)\n",
1979 mti->mti_svname, logname, lmvname);
1981 rc = name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
1984 rc = name_create(&mdcname, mti->mti_svname, "-mdc");
1987 rc = name_create(&mdcuuid, mdcname, "_UUID");
1990 rc = name_create(&lmvuuid, lmvname, "_UUID");
1994 rc = record_start_log(env, mgs, &llh, logname);
1997 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
2001 for (i = 0; i < mti->mti_nid_count; i++) {
2002 CDEBUG(D_MGS, "add nid %s for mdt\n",
2003 libcfs_nid2str(mti->mti_nids[i]));
2005 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
2010 rc = record_attach(env, llh, mdcname, LUSTRE_MDC_NAME, lmvuuid);
2013 rc = record_setup(env, llh, mdcname, mti->mti_uuid, nodeuuid, 0, 0);
2016 rc = mgs_write_log_failnids(env, mti, llh, mdcname);
2019 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
2020 rc = record_mdc_add(env, llh, lmvname, mdcuuid, mti->mti_uuid,
2024 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname,
2029 record_end_log(env, &llh);
2031 name_destroy(&lmvuuid);
2032 name_destroy(&mdcuuid);
2033 name_destroy(&mdcname);
2034 name_destroy(&nodeuuid);
2038 static inline int name_create_lov(char **lovname, char *mdtname,
2039 struct fs_db *fsdb, int index)
2042 if (index == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2043 return name_create(lovname, fsdb->fsdb_name, "-mdtlov");
2045 return name_create(lovname, mdtname, "-mdtlov");
2048 static int name_create_mdt_and_lov(char **logname, char **lovname,
2049 struct fs_db *fsdb, int i)
2053 rc = name_create_mdt(logname, fsdb->fsdb_name, i);
2057 if (i == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2058 rc = name_create(lovname, fsdb->fsdb_name, "-mdtlov");
2060 rc = name_create(lovname, *logname, "-mdtlov");
2062 name_destroy(logname);
2068 static inline int name_create_mdt_osc(char **oscname, char *ostname,
2069 struct fs_db *fsdb, int i)
2073 if (i == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2074 sprintf(suffix, "-osc");
2076 sprintf(suffix, "-osc-MDT%04x", i);
2077 return name_create(oscname, ostname, suffix);
2080 /* add new mdc to already existent MDS */
2081 static int mgs_write_log_osp_to_mdt(const struct lu_env *env,
2082 struct mgs_device *mgs,
2084 struct mgs_target_info *mti,
2085 int mdt_index, char *logname)
2087 struct llog_handle *llh = NULL;
2088 char *nodeuuid = NULL;
2089 char *ospname = NULL;
2090 char *lovuuid = NULL;
2091 char *mdtuuid = NULL;
2092 char *svname = NULL;
2093 char *mdtname = NULL;
2094 char *lovname = NULL;
2099 if (mgs_log_is_empty(env, mgs, mti->mti_svname)) {
2100 CERROR("log is empty! Logical error\n");
2104 CDEBUG(D_MGS, "adding osp index %d to %s\n", mti->mti_stripe_index,
2107 rc = name_create_mdt(&mdtname, fsdb->fsdb_name, mti->mti_stripe_index);
2111 rc = name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
2113 GOTO(out_destory, rc);
2115 rc = name_create(&svname, mdtname, "-osp");
2117 GOTO(out_destory, rc);
2119 sprintf(index_str, "-MDT%04x", mdt_index);
2120 rc = name_create(&ospname, svname, index_str);
2122 GOTO(out_destory, rc);
2124 rc = name_create_lov(&lovname, logname, fsdb, mdt_index);
2126 GOTO(out_destory, rc);
2128 rc = name_create(&lovuuid, lovname, "_UUID");
2130 GOTO(out_destory, rc);
2132 rc = name_create(&mdtuuid, mdtname, "_UUID");
2134 GOTO(out_destory, rc);
2136 rc = record_start_log(env, mgs, &llh, logname);
2138 GOTO(out_destory, rc);
2140 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
2143 GOTO(out_destory, rc);
2145 for (i = 0; i < mti->mti_nid_count; i++) {
2146 CDEBUG(D_MGS, "add nid %s for mdt\n",
2147 libcfs_nid2str(mti->mti_nids[i]));
2148 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
2153 rc = record_attach(env, llh, ospname, LUSTRE_OSP_NAME, lovuuid);
2157 rc = record_setup(env, llh, ospname, mti->mti_uuid, nodeuuid,
2162 rc = mgs_write_log_failnids(env, mti, llh, ospname);
2166 /* Add mdc(osp) to lod */
2167 snprintf(index_str, sizeof(mti->mti_stripe_index), "%d",
2168 mti->mti_stripe_index);
2169 rc = record_base(env, llh, lovname, 0, LCFG_ADD_MDC, mti->mti_uuid,
2170 index_str, "1", NULL);
2174 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname, "add osp");
2179 record_end_log(env, &llh);
2182 name_destroy(&mdtuuid);
2183 name_destroy(&lovuuid);
2184 name_destroy(&lovname);
2185 name_destroy(&ospname);
2186 name_destroy(&svname);
2187 name_destroy(&nodeuuid);
2188 name_destroy(&mdtname);
2192 static int mgs_write_log_mdt0(const struct lu_env *env,
2193 struct mgs_device *mgs,
2195 struct mgs_target_info *mti)
2197 char *log = mti->mti_svname;
2198 struct llog_handle *llh = NULL;
2199 char *uuid, *lovname;
2201 char *ptr = mti->mti_params;
2202 int rc = 0, failout = 0;
2205 OBD_ALLOC(uuid, sizeof(struct obd_uuid));
2209 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
2210 failout = (strncmp(ptr, "failout", 7) == 0);
2212 rc = name_create(&lovname, log, "-mdtlov");
2215 if (mgs_log_is_empty(env, mgs, log)) {
2216 rc = mgs_write_log_lov(env, mgs, fsdb, mti, log, lovname);
2221 sprintf(mdt_index, "%d", mti->mti_stripe_index);
2223 rc = record_start_log(env, mgs, &llh, log);
2227 /* add MDT itself */
2229 /* FIXME this whole fn should be a single journal transaction */
2230 sprintf(uuid, "%s_UUID", log);
2231 rc = record_marker(env, llh, fsdb, CM_START, log, "add mdt");
2234 rc = record_attach(env, llh, log, LUSTRE_MDT_NAME, uuid);
2237 rc = record_mount_opt(env, llh, log, lovname, NULL);
2240 rc = record_setup(env, llh, log, uuid, mdt_index, lovname,
2241 failout ? "n" : "f");
2244 rc = record_marker(env, llh, fsdb, CM_END, log, "add mdt");
2248 record_end_log(env, &llh);
2250 name_destroy(&lovname);
2252 OBD_FREE(uuid, sizeof(struct obd_uuid));
2256 /* envelope method for all layers log */
2257 static int mgs_write_log_mdt(const struct lu_env *env,
2258 struct mgs_device *mgs,
2260 struct mgs_target_info *mti)
2262 struct mgs_thread_info *mgi = mgs_env_info(env);
2263 struct llog_handle *llh = NULL;
2268 CDEBUG(D_MGS, "writing new mdt %s\n", mti->mti_svname);
2270 if (mti->mti_uuid[0] == '\0') {
2271 /* Make up our own uuid */
2272 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
2273 "%s_UUID", mti->mti_svname);
2277 rc = mgs_write_log_mdt0(env, mgs, fsdb, mti);
2280 /* Append the mdt info to the client log */
2281 rc = name_create(&cliname, mti->mti_fsname, "-client");
2285 if (mgs_log_is_empty(env, mgs, cliname)) {
2286 /* Start client log */
2287 rc = mgs_write_log_lov(env, mgs, fsdb, mti, cliname,
2291 rc = mgs_write_log_lmv(env, mgs, fsdb, mti, cliname,
2298 #09 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
2299 #10 L attach 0:MDC_uml1_mdsA_MNT_client 1:mdc 2:1d834_MNT_client_03f
2300 #11 L setup 0:MDC_uml1_mdsA_MNT_client 1:mdsA_UUID 2:uml1_UUID
2301 #12 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
2302 #13 L add_conn 0:MDC_uml1_mdsA_MNT_client 1:uml2_UUID
2303 #14 L mount_option 0: 1:client 2:lov1 3:MDC_uml1_mdsA_MNT_client
2306 /* copy client info about lov/lmv */
2307 mgi->mgi_comp.comp_mti = mti;
2308 mgi->mgi_comp.comp_fsdb = fsdb;
2310 rc = mgs_steal_llog_for_mdt_from_client(env, mgs, cliname,
2314 rc = mgs_write_log_mdc_to_lmv(env, mgs, fsdb, mti, cliname,
2320 rc = record_start_log(env, mgs, &llh, cliname);
2324 rc = record_marker(env, llh, fsdb, CM_START, cliname,
2328 rc = record_mount_opt(env, llh, cliname, fsdb->fsdb_clilov,
2332 rc = record_marker(env, llh, fsdb, CM_END, cliname,
2338 /* for_all_existing_mdt except current one */
2339 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2340 if (i != mti->mti_stripe_index &&
2341 test_bit(i, fsdb->fsdb_mdt_index_map)) {
2344 rc = name_create_mdt(&logname, fsdb->fsdb_name, i);
2348 rc = mgs_write_log_osp_to_mdt(env, mgs, fsdb, mti,
2350 name_destroy(&logname);
2356 record_end_log(env, &llh);
2358 name_destroy(&cliname);
2362 /* Add the ost info to the client/mdt lov */
2363 static int mgs_write_log_osc_to_lov(const struct lu_env *env,
2364 struct mgs_device *mgs, struct fs_db *fsdb,
2365 struct mgs_target_info *mti,
2366 char *logname, char *suffix, char *lovname,
2367 enum lustre_sec_part sec_part, int flags)
2369 struct llog_handle *llh = NULL;
2370 char *nodeuuid = NULL;
2371 char *oscname = NULL;
2372 char *oscuuid = NULL;
2373 char *lovuuid = NULL;
2374 char *svname = NULL;
2379 CDEBUG(D_INFO, "adding osc for %s to log %s\n",
2380 mti->mti_svname, logname);
2382 if (mgs_log_is_empty(env, mgs, logname)) {
2383 CERROR("log is empty! Logical error\n");
2387 rc = name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
2390 rc = name_create(&svname, mti->mti_svname, "-osc");
2394 /* for the system upgraded from old 1.8, keep using the old osc naming
2395 * style for mdt, see name_create_mdt_osc(). LU-1257 */
2396 if (test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2397 rc = name_create(&oscname, svname, "");
2399 rc = name_create(&oscname, svname, suffix);
2403 rc = name_create(&oscuuid, oscname, "_UUID");
2406 rc = name_create(&lovuuid, lovname, "_UUID");
2412 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
2414 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
2415 #04 L attach 0:OSC_uml1_ost1_MNT_client 1:osc 2:89070_lov1_a41dff51a
2416 #05 L setup 0:OSC_uml1_ost1_MNT_client 1:ost1_UUID 2:uml1_UUID
2418 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
2419 #07 L add_conn 0:OSC_uml1_ost1_MNT_client 1:uml2_UUID
2420 #08 L lov_modify_tgts add 0:lov1 1:ost1_UUID 2(index):0 3(gen):1
2423 rc = record_start_log(env, mgs, &llh, logname);
2427 /* FIXME these should be a single journal transaction */
2428 rc = record_marker(env, llh, fsdb, CM_START | flags, mti->mti_svname,
2433 /* NB: don't change record order, because upon MDT steal OSC config
2434 * from client, it treats all nids before LCFG_SETUP as target nids
2435 * (multiple interfaces), while nids after as failover node nids.
2436 * See mgs_steal_client_llog_handler() LCFG_ADD_UUID.
2438 for (i = 0; i < mti->mti_nid_count; i++) {
2439 CDEBUG(D_MGS, "add nid %s\n", libcfs_nid2str(mti->mti_nids[i]));
2440 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
2444 rc = record_attach(env, llh, oscname, LUSTRE_OSC_NAME, lovuuid);
2447 rc = record_setup(env, llh, oscname, mti->mti_uuid, nodeuuid, 0, 0);
2450 rc = mgs_write_log_failnids(env, mti, llh, oscname);
2454 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
2456 rc = record_lov_add(env, llh, lovname, mti->mti_uuid, index, "1");
2459 rc = record_marker(env, llh, fsdb, CM_END | flags, mti->mti_svname,
2464 record_end_log(env, &llh);
2466 name_destroy(&lovuuid);
2467 name_destroy(&oscuuid);
2468 name_destroy(&oscname);
2469 name_destroy(&svname);
2470 name_destroy(&nodeuuid);
2474 static int mgs_write_log_ost(const struct lu_env *env,
2475 struct mgs_device *mgs, struct fs_db *fsdb,
2476 struct mgs_target_info *mti)
2478 struct llog_handle *llh = NULL;
2479 char *logname, *lovname;
2480 char *ptr = mti->mti_params;
2481 int rc, flags = 0, failout = 0, i;
2484 CDEBUG(D_MGS, "writing new ost %s\n", mti->mti_svname);
2486 /* The ost startup log */
2488 /* If the ost log already exists, that means that someone reformatted
2489 the ost and it called target_add again. */
2490 if (!mgs_log_is_empty(env, mgs, mti->mti_svname)) {
2491 LCONSOLE_ERROR_MSG(0x141, "The config log for %s already "
2492 "exists, yet the server claims it never "
2493 "registered. It may have been reformatted, "
2494 "or the index changed. writeconf the MDT to "
2495 "regenerate all logs.\n", mti->mti_svname);
2500 attach obdfilter ost1 ost1_UUID
2501 setup /dev/loop2 ldiskfs f|n errors=remount-ro,user_xattr
2503 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
2504 failout = (strncmp(ptr, "failout", 7) == 0);
2505 rc = record_start_log(env, mgs, &llh, mti->mti_svname);
2508 /* FIXME these should be a single journal transaction */
2509 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,"add ost");
2512 if (*mti->mti_uuid == '\0')
2513 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
2514 "%s_UUID", mti->mti_svname);
2515 rc = record_attach(env, llh, mti->mti_svname,
2516 "obdfilter"/*LUSTRE_OST_NAME*/, mti->mti_uuid);
2519 rc = record_setup(env, llh, mti->mti_svname,
2520 "dev"/*ignored*/, "type"/*ignored*/,
2521 failout ? "n" : "f", 0/*options*/);
2524 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname, "add ost");
2528 record_end_log(env, &llh);
2531 /* We also have to update the other logs where this osc is part of
2534 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
2535 /* If we're upgrading, the old mdt log already has our
2536 entry. Let's do a fake one for fun. */
2537 /* Note that we can't add any new failnids, since we don't
2538 know the old osc names. */
2539 flags = CM_SKIP | CM_UPGRADE146;
2541 } else if ((mti->mti_flags & LDD_F_UPDATE) != LDD_F_UPDATE) {
2542 /* If the update flag isn't set, don't update client/mdt
2545 LCONSOLE_WARN("Client log for %s was not updated; writeconf "
2546 "the MDT first to regenerate it.\n",
2550 /* Add ost to all MDT lov defs */
2551 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
2552 if (test_bit(i, fsdb->fsdb_mdt_index_map)) {
2555 rc = name_create_mdt_and_lov(&logname, &lovname, fsdb,
2559 sprintf(mdt_index, "-MDT%04x", i);
2560 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, mti,
2562 lovname, LUSTRE_SP_MDT,
2564 name_destroy(&logname);
2565 name_destroy(&lovname);
2571 /* Append ost info to the client log */
2572 rc = name_create(&logname, mti->mti_fsname, "-client");
2575 if (mgs_log_is_empty(env, mgs, logname)) {
2576 /* Start client log */
2577 rc = mgs_write_log_lov(env, mgs, fsdb, mti, logname,
2581 rc = mgs_write_log_lmv(env, mgs, fsdb, mti, logname,
2586 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, mti, logname, "",
2587 fsdb->fsdb_clilov, LUSTRE_SP_CLI, 0);
2589 name_destroy(&logname);
2593 static __inline__ int mgs_param_empty(char *ptr)
2597 if ((tmp = strchr(ptr, '=')) && (*(++tmp) == '\0'))
2602 static int mgs_write_log_failnid_internal(const struct lu_env *env,
2603 struct mgs_device *mgs,
2605 struct mgs_target_info *mti,
2606 char *logname, char *cliname)
2609 struct llog_handle *llh = NULL;
2611 if (mgs_param_empty(mti->mti_params)) {
2612 /* Remove _all_ failnids */
2613 rc = mgs_modify(env, mgs, fsdb, mti, logname,
2614 mti->mti_svname, "add failnid", CM_SKIP);
2615 return rc < 0 ? rc : 0;
2618 /* Otherwise failover nids are additive */
2619 rc = record_start_log(env, mgs, &llh, logname);
2622 /* FIXME this should be a single journal transaction */
2623 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
2627 rc = mgs_write_log_failnids(env, mti, llh, cliname);
2630 rc = record_marker(env, llh, fsdb, CM_END,
2631 mti->mti_svname, "add failnid");
2633 record_end_log(env, &llh);
2638 /* Add additional failnids to an existing log.
2639 The mdc/osc must have been added to logs first */
2640 /* tcp nids must be in dotted-quad ascii -
2641 we can't resolve hostnames from the kernel. */
2642 static int mgs_write_log_add_failnid(const struct lu_env *env,
2643 struct mgs_device *mgs,
2645 struct mgs_target_info *mti)
2647 char *logname, *cliname;
2651 /* FIXME we currently can't erase the failnids
2652 * given when a target first registers, since they aren't part of
2653 * an "add uuid" stanza */
2655 /* Verify that we know about this target */
2656 if (mgs_log_is_empty(env, mgs, mti->mti_svname)) {
2657 LCONSOLE_ERROR_MSG(0x142, "The target %s has not registered "
2658 "yet. It must be started before failnids "
2659 "can be added.\n", mti->mti_svname);
2663 /* Create mdc/osc client name (e.g. lustre-OST0001-osc) */
2664 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
2665 rc = name_create(&cliname, mti->mti_svname, "-mdc");
2666 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2667 rc = name_create(&cliname, mti->mti_svname, "-osc");
2673 /* Add failover nids to the client log */
2674 rc = name_create(&logname, mti->mti_fsname, "-client");
2676 name_destroy(&cliname);
2679 rc = mgs_write_log_failnid_internal(env, mgs, fsdb,mti,logname,cliname);
2680 name_destroy(&logname);
2681 name_destroy(&cliname);
2685 if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2686 /* Add OST failover nids to the MDT logs as well */
2689 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2690 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
2692 rc = name_create_mdt(&logname, mti->mti_fsname, i);
2695 rc = name_create_mdt_osc(&cliname, mti->mti_svname,
2698 name_destroy(&logname);
2701 rc = mgs_write_log_failnid_internal(env, mgs, fsdb,
2704 name_destroy(&cliname);
2705 name_destroy(&logname);
2714 static int mgs_wlp_lcfg(const struct lu_env *env,
2715 struct mgs_device *mgs, struct fs_db *fsdb,
2716 struct mgs_target_info *mti,
2717 char *logname, struct lustre_cfg_bufs *bufs,
2718 char *tgtname, char *ptr)
2720 char comment[MTI_NAME_MAXLEN];
2722 struct lustre_cfg *lcfg;
2725 /* Erase any old settings of this same parameter */
2726 memcpy(comment, ptr, MTI_NAME_MAXLEN);
2727 comment[MTI_NAME_MAXLEN - 1] = 0;
2728 /* But don't try to match the value. */
2729 if ((tmp = strchr(comment, '=')))
2731 /* FIXME we should skip settings that are the same as old values */
2732 rc = mgs_modify(env, mgs, fsdb, mti, logname, tgtname, comment,CM_SKIP);
2735 del = mgs_param_empty(ptr);
2737 LCONSOLE_INFO("%sing parameter %s.%s in log %s\n", del ? "Disabl" : rc ?
2738 "Sett" : "Modify", tgtname, comment, logname);
2742 lustre_cfg_bufs_reset(bufs, tgtname);
2743 lustre_cfg_bufs_set_string(bufs, 1, ptr);
2744 if (mti->mti_flags & LDD_F_PARAM2)
2745 lustre_cfg_bufs_set_string(bufs, 2, LCTL_UPCALL);
2747 lcfg = lustre_cfg_new((mti->mti_flags & LDD_F_PARAM2) ?
2748 LCFG_SET_PARAM : LCFG_PARAM, bufs);
2752 rc = mgs_write_log_direct(env, mgs, fsdb, logname,lcfg,tgtname,comment);
2753 lustre_cfg_free(lcfg);
2757 static int mgs_write_log_param2(const struct lu_env *env,
2758 struct mgs_device *mgs,
2760 struct mgs_target_info *mti, char *ptr)
2762 struct lustre_cfg_bufs bufs;
2766 CDEBUG(D_MGS, "next param '%s'\n", ptr);
2767 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, PARAMS_FILENAME, &bufs,
2768 mti->mti_svname, ptr);
2773 /* write global variable settings into log */
2774 static int mgs_write_log_sys(const struct lu_env *env,
2775 struct mgs_device *mgs, struct fs_db *fsdb,
2776 struct mgs_target_info *mti, char *sys, char *ptr)
2778 struct mgs_thread_info *mgi = mgs_env_info(env);
2779 struct lustre_cfg *lcfg;
2781 int rc, cmd, convert = 1;
2783 if (class_match_param(ptr, PARAM_TIMEOUT, &tmp) == 0) {
2784 cmd = LCFG_SET_TIMEOUT;
2785 } else if (class_match_param(ptr, PARAM_LDLM_TIMEOUT, &tmp) == 0) {
2786 cmd = LCFG_SET_LDLM_TIMEOUT;
2787 /* Check for known params here so we can return error to lctl */
2788 } else if ((class_match_param(ptr, PARAM_AT_MIN, &tmp) == 0) ||
2789 (class_match_param(ptr, PARAM_AT_MAX, &tmp) == 0) ||
2790 (class_match_param(ptr, PARAM_AT_EXTRA, &tmp) == 0) ||
2791 (class_match_param(ptr, PARAM_AT_EARLY_MARGIN, &tmp) == 0) ||
2792 (class_match_param(ptr, PARAM_AT_HISTORY, &tmp) == 0)) {
2794 } else if (class_match_param(ptr, PARAM_JOBID_VAR, &tmp) == 0) {
2795 convert = 0; /* Don't convert string value to integer */
2801 if (mgs_param_empty(ptr))
2802 CDEBUG(D_MGS, "global '%s' removed\n", sys);
2804 CDEBUG(D_MGS, "global '%s' val=%s\n", sys, tmp);
2806 lustre_cfg_bufs_reset(&mgi->mgi_bufs, NULL);
2807 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, sys);
2808 if (!convert && *tmp != '\0')
2809 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 2, tmp);
2810 lcfg = lustre_cfg_new(cmd, &mgi->mgi_bufs);
2811 lcfg->lcfg_num = convert ? simple_strtoul(tmp, NULL, 0) : 0;
2812 /* truncate the comment to the parameter name */
2816 /* modify all servers and clients */
2817 rc = mgs_write_log_direct_all(env, mgs, fsdb, mti,
2818 *tmp == '\0' ? NULL : lcfg,
2819 mti->mti_fsname, sys, 0);
2820 if (rc == 0 && *tmp != '\0') {
2822 case LCFG_SET_TIMEOUT:
2823 if (!obd_timeout_set || lcfg->lcfg_num > obd_timeout)
2824 class_process_config(lcfg);
2826 case LCFG_SET_LDLM_TIMEOUT:
2827 if (!ldlm_timeout_set || lcfg->lcfg_num > ldlm_timeout)
2828 class_process_config(lcfg);
2835 lustre_cfg_free(lcfg);
2839 /* write quota settings into log */
2840 static int mgs_write_log_quota(const struct lu_env *env, struct mgs_device *mgs,
2841 struct fs_db *fsdb, struct mgs_target_info *mti,
2842 char *quota, char *ptr)
2844 struct mgs_thread_info *mgi = mgs_env_info(env);
2845 struct lustre_cfg *lcfg;
2848 int rc, cmd = LCFG_PARAM;
2850 /* support only 'meta' and 'data' pools so far */
2851 if (class_match_param(ptr, QUOTA_METAPOOL_NAME, &tmp) != 0 &&
2852 class_match_param(ptr, QUOTA_DATAPOOL_NAME, &tmp) != 0) {
2853 CERROR("parameter quota.%s isn't supported (only quota.mdt "
2854 "& quota.ost are)\n", ptr);
2859 CDEBUG(D_MGS, "global '%s' removed\n", quota);
2861 CDEBUG(D_MGS, "global '%s'\n", quota);
2863 if (strchr(tmp, 'u') == NULL && strchr(tmp, 'g') == NULL &&
2864 strcmp(tmp, "none") != 0) {
2865 CERROR("enable option(%s) isn't supported\n", tmp);
2870 lustre_cfg_bufs_reset(&mgi->mgi_bufs, mti->mti_fsname);
2871 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, quota);
2872 lcfg = lustre_cfg_new(cmd, &mgi->mgi_bufs);
2873 /* truncate the comment to the parameter name */
2878 /* XXX we duplicated quota enable information in all server
2879 * config logs, it should be moved to a separate config
2880 * log once we cleanup the config log for global param. */
2881 /* modify all servers */
2882 rc = mgs_write_log_direct_all(env, mgs, fsdb, mti,
2883 *tmp == '\0' ? NULL : lcfg,
2884 mti->mti_fsname, quota, 1);
2886 lustre_cfg_free(lcfg);
2887 return rc < 0 ? rc : 0;
2890 static int mgs_srpc_set_param_disk(const struct lu_env *env,
2891 struct mgs_device *mgs,
2893 struct mgs_target_info *mti,
2896 struct mgs_thread_info *mgi = mgs_env_info(env);
2897 struct llog_handle *llh = NULL;
2899 char *comment, *ptr;
2900 struct lustre_cfg *lcfg;
2905 ptr = strchr(param, '=');
2909 OBD_ALLOC(comment, len + 1);
2910 if (comment == NULL)
2912 strncpy(comment, param, len);
2913 comment[len] = '\0';
2916 lustre_cfg_bufs_reset(&mgi->mgi_bufs, mti->mti_svname);
2917 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, param);
2918 lcfg = lustre_cfg_new(LCFG_SPTLRPC_CONF, &mgi->mgi_bufs);
2920 GOTO(out_comment, rc = -ENOMEM);
2922 /* construct log name */
2923 rc = name_create(&logname, mti->mti_fsname, "-sptlrpc");
2927 if (mgs_log_is_empty(env, mgs, logname)) {
2928 rc = record_start_log(env, mgs, &llh, logname);
2931 record_end_log(env, &llh);
2934 /* obsolete old one */
2935 rc = mgs_modify(env, mgs, fsdb, mti, logname, mti->mti_svname,
2939 /* write the new one */
2940 rc = mgs_write_log_direct(env, mgs, fsdb, logname, lcfg,
2941 mti->mti_svname, comment);
2943 CERROR("err %d writing log %s\n", rc, logname);
2945 name_destroy(&logname);
2947 lustre_cfg_free(lcfg);
2949 OBD_FREE(comment, len + 1);
2953 static int mgs_srpc_set_param_udesc_mem(struct fs_db *fsdb,
2958 /* disable the adjustable udesc parameter for now, i.e. use default
2959 * setting that client always ship udesc to MDT if possible. to enable
2960 * it simply remove the following line */
2963 ptr = strchr(param, '=');
2968 if (strcmp(param, PARAM_SRPC_UDESC))
2971 if (strcmp(ptr, "yes") == 0) {
2972 set_bit(FSDB_UDESC, &fsdb->fsdb_flags);
2973 CWARN("Enable user descriptor shipping from client to MDT\n");
2974 } else if (strcmp(ptr, "no") == 0) {
2975 clear_bit(FSDB_UDESC, &fsdb->fsdb_flags);
2976 CWARN("Disable user descriptor shipping from client to MDT\n");
2984 CERROR("Invalid param: %s\n", param);
2988 static int mgs_srpc_set_param_mem(struct fs_db *fsdb,
2992 struct sptlrpc_rule rule;
2993 struct sptlrpc_rule_set *rset;
2997 if (strncmp(param, PARAM_SRPC, sizeof(PARAM_SRPC) - 1) != 0) {
2998 CERROR("Invalid sptlrpc parameter: %s\n", param);
3002 if (strncmp(param, PARAM_SRPC_UDESC,
3003 sizeof(PARAM_SRPC_UDESC) - 1) == 0) {
3004 RETURN(mgs_srpc_set_param_udesc_mem(fsdb, param));
3007 if (strncmp(param, PARAM_SRPC_FLVR, sizeof(PARAM_SRPC_FLVR) - 1) != 0) {
3008 CERROR("Invalid sptlrpc flavor parameter: %s\n", param);
3012 param += sizeof(PARAM_SRPC_FLVR) - 1;
3014 rc = sptlrpc_parse_rule(param, &rule);
3018 /* mgs rules implies must be mgc->mgs */
3019 if (test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
3020 if ((rule.sr_from != LUSTRE_SP_MGC &&
3021 rule.sr_from != LUSTRE_SP_ANY) ||
3022 (rule.sr_to != LUSTRE_SP_MGS &&
3023 rule.sr_to != LUSTRE_SP_ANY))
3027 /* preapre room for this coming rule. svcname format should be:
3028 * - fsname: general rule
3029 * - fsname-tgtname: target-specific rule
3031 if (strchr(svname, '-')) {
3032 struct mgs_tgt_srpc_conf *tgtconf;
3035 for (tgtconf = fsdb->fsdb_srpc_tgt; tgtconf != NULL;
3036 tgtconf = tgtconf->mtsc_next) {
3037 if (!strcmp(tgtconf->mtsc_tgt, svname)) {
3046 OBD_ALLOC_PTR(tgtconf);
3047 if (tgtconf == NULL)
3050 name_len = strlen(svname);
3052 OBD_ALLOC(tgtconf->mtsc_tgt, name_len + 1);
3053 if (tgtconf->mtsc_tgt == NULL) {
3054 OBD_FREE_PTR(tgtconf);
3057 memcpy(tgtconf->mtsc_tgt, svname, name_len);
3059 tgtconf->mtsc_next = fsdb->fsdb_srpc_tgt;
3060 fsdb->fsdb_srpc_tgt = tgtconf;
3063 rset = &tgtconf->mtsc_rset;
3065 rset = &fsdb->fsdb_srpc_gen;
3068 rc = sptlrpc_rule_set_merge(rset, &rule);
3073 static int mgs_srpc_set_param(const struct lu_env *env,
3074 struct mgs_device *mgs,
3076 struct mgs_target_info *mti,
3086 /* keep a copy of original param, which could be destroied
3088 copy_size = strlen(param) + 1;
3089 OBD_ALLOC(copy, copy_size);
3092 memcpy(copy, param, copy_size);
3094 rc = mgs_srpc_set_param_mem(fsdb, mti->mti_svname, param);
3098 /* previous steps guaranteed the syntax is correct */
3099 rc = mgs_srpc_set_param_disk(env, mgs, fsdb, mti, copy);
3103 if (test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
3105 * for mgs rules, make them effective immediately.
3107 LASSERT(fsdb->fsdb_srpc_tgt == NULL);
3108 sptlrpc_target_update_exp_flavor(mgs->mgs_obd,
3109 &fsdb->fsdb_srpc_gen);
3113 OBD_FREE(copy, copy_size);
3117 struct mgs_srpc_read_data {
3118 struct fs_db *msrd_fsdb;
3122 static int mgs_srpc_read_handler(const struct lu_env *env,
3123 struct llog_handle *llh,
3124 struct llog_rec_hdr *rec, void *data)
3126 struct mgs_srpc_read_data *msrd = data;
3127 struct cfg_marker *marker;
3128 struct lustre_cfg *lcfg = REC_DATA(rec);
3129 char *svname, *param;
3133 if (rec->lrh_type != OBD_CFG_REC) {
3134 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
3138 cfg_len = rec->lrh_len - sizeof(struct llog_rec_hdr) -
3139 sizeof(struct llog_rec_tail);
3141 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
3143 CERROR("Insane cfg\n");
3147 if (lcfg->lcfg_command == LCFG_MARKER) {
3148 marker = lustre_cfg_buf(lcfg, 1);
3150 if (marker->cm_flags & CM_START &&
3151 marker->cm_flags & CM_SKIP)
3152 msrd->msrd_skip = 1;
3153 if (marker->cm_flags & CM_END)
3154 msrd->msrd_skip = 0;
3159 if (msrd->msrd_skip)
3162 if (lcfg->lcfg_command != LCFG_SPTLRPC_CONF) {
3163 CERROR("invalid command (%x)\n", lcfg->lcfg_command);
3167 svname = lustre_cfg_string(lcfg, 0);
3168 if (svname == NULL) {
3169 CERROR("svname is empty\n");
3173 param = lustre_cfg_string(lcfg, 1);
3174 if (param == NULL) {
3175 CERROR("param is empty\n");
3179 rc = mgs_srpc_set_param_mem(msrd->msrd_fsdb, svname, param);
3181 CERROR("read sptlrpc record error (%d): %s\n", rc, param);
3186 int mgs_get_fsdb_srpc_from_llog(const struct lu_env *env,
3187 struct mgs_device *mgs,
3190 struct llog_handle *llh = NULL;
3191 struct llog_ctxt *ctxt;
3193 struct mgs_srpc_read_data msrd;
3197 /* construct log name */
3198 rc = name_create(&logname, fsdb->fsdb_name, "-sptlrpc");
3202 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
3203 LASSERT(ctxt != NULL);
3205 if (mgs_log_is_empty(env, mgs, logname))
3208 rc = llog_open(env, ctxt, &llh, NULL, logname,
3216 rc = llog_init_handle(env, llh, LLOG_F_IS_PLAIN, NULL);
3218 GOTO(out_close, rc);
3220 if (llog_get_size(llh) <= 1)
3221 GOTO(out_close, rc = 0);
3223 msrd.msrd_fsdb = fsdb;
3226 rc = llog_process(env, llh, mgs_srpc_read_handler, (void *)&msrd,
3230 llog_close(env, llh);
3232 llog_ctxt_put(ctxt);
3233 name_destroy(&logname);
3236 CERROR("failed to read sptlrpc config database: %d\n", rc);
3240 /* Permanent settings of all parameters by writing into the appropriate
3241 * configuration logs.
3242 * A parameter with null value ("<param>='\0'") means to erase it out of
3245 static int mgs_write_log_param(const struct lu_env *env,
3246 struct mgs_device *mgs, struct fs_db *fsdb,
3247 struct mgs_target_info *mti, char *ptr)
3249 struct mgs_thread_info *mgi = mgs_env_info(env);
3252 int rc = 0, rc2 = 0;
3255 /* For various parameter settings, we have to figure out which logs
3256 care about them (e.g. both mdt and client for lov settings) */
3257 CDEBUG(D_MGS, "next param '%s'\n", ptr);
3259 /* The params are stored in MOUNT_DATA_FILE and modified via
3260 tunefs.lustre, or set using lctl conf_param */
3262 /* Processed in lustre_start_mgc */
3263 if (class_match_param(ptr, PARAM_MGSNODE, NULL) == 0)
3266 /* Processed in ost/mdt */
3267 if (class_match_param(ptr, PARAM_NETWORK, NULL) == 0)
3270 /* Processed in mgs_write_log_ost */
3271 if (class_match_param(ptr, PARAM_FAILMODE, NULL) == 0) {
3272 if (mti->mti_flags & LDD_F_PARAM) {
3273 LCONSOLE_ERROR_MSG(0x169, "%s can only be "
3274 "changed with tunefs.lustre"
3275 "and --writeconf\n", ptr);
3281 if (class_match_param(ptr, PARAM_SRPC, NULL) == 0) {
3282 rc = mgs_srpc_set_param(env, mgs, fsdb, mti, ptr);
3286 if (class_match_param(ptr, PARAM_FAILNODE, NULL) == 0) {
3287 /* Add a failover nidlist */
3289 /* We already processed failovers params for new
3290 targets in mgs_write_log_target */
3291 if (mti->mti_flags & LDD_F_PARAM) {
3292 CDEBUG(D_MGS, "Adding failnode\n");
3293 rc = mgs_write_log_add_failnid(env, mgs, fsdb, mti);
3298 if (class_match_param(ptr, PARAM_SYS, &tmp) == 0) {
3299 rc = mgs_write_log_sys(env, mgs, fsdb, mti, ptr, tmp);
3303 if (class_match_param(ptr, PARAM_QUOTA, &tmp) == 0) {
3304 rc = mgs_write_log_quota(env, mgs, fsdb, mti, ptr, tmp);
3308 if (class_match_param(ptr, PARAM_OSC""PARAM_ACTIVE, &tmp) == 0) {
3309 /* active=0 means off, anything else means on */
3310 int flag = (*tmp == '0') ? CM_EXCLUDE : 0;
3313 if (!(mti->mti_flags & LDD_F_SV_TYPE_OST)) {
3314 LCONSOLE_ERROR_MSG(0x144, "%s: Only OSCs can "
3315 "be (de)activated.\n",
3317 GOTO(end, rc = -EINVAL);
3319 LCONSOLE_WARN("Permanently %sactivating %s\n",
3320 flag ? "de": "re", mti->mti_svname);
3322 rc = name_create(&logname, mti->mti_fsname, "-client");
3325 rc = mgs_modify(env, mgs, fsdb, mti, logname,
3326 mti->mti_svname, "add osc", flag);
3327 name_destroy(&logname);
3331 /* Add to all MDT logs for CMD */
3332 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3333 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
3335 rc = name_create_mdt(&logname, mti->mti_fsname, i);
3338 rc = mgs_modify(env, mgs, fsdb, mti, logname,
3339 mti->mti_svname, "add osc", flag);
3340 name_destroy(&logname);
3346 LCONSOLE_ERROR_MSG(0x145, "Couldn't find %s in"
3347 "log (%d). No permanent "
3348 "changes were made to the "
3350 mti->mti_svname, rc);
3351 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags))
3352 LCONSOLE_ERROR_MSG(0x146, "This may be"
3357 "update the logs.\n");
3360 /* Fall through to osc proc for deactivating live OSC
3361 on running MDT / clients. */
3363 /* Below here, let obd's XXX_process_config methods handle it */
3365 /* All lov. in proc */
3366 if (class_match_param(ptr, PARAM_LOV, NULL) == 0) {
3369 CDEBUG(D_MGS, "lov param %s\n", ptr);
3370 if (!(mti->mti_flags & LDD_F_SV_TYPE_MDT)) {
3371 LCONSOLE_ERROR_MSG(0x147, "LOV params must be "
3372 "set on the MDT, not %s. "
3379 if (mgs_log_is_empty(env, mgs, mti->mti_svname))
3380 GOTO(end, rc = -ENODEV);
3382 rc = name_create_mdt_and_lov(&logname, &mdtlovname, fsdb,
3383 mti->mti_stripe_index);
3386 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, mti->mti_svname,
3387 &mgi->mgi_bufs, mdtlovname, ptr);
3388 name_destroy(&logname);
3389 name_destroy(&mdtlovname);
3394 rc = name_create(&logname, mti->mti_fsname, "-client");
3397 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname, &mgi->mgi_bufs,
3398 fsdb->fsdb_clilov, ptr);
3399 name_destroy(&logname);
3403 /* All osc., mdc., llite. params in proc */
3404 if ((class_match_param(ptr, PARAM_OSC, NULL) == 0) ||
3405 (class_match_param(ptr, PARAM_MDC, NULL) == 0) ||
3406 (class_match_param(ptr, PARAM_LLITE, NULL) == 0)) {
3409 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
3410 LCONSOLE_ERROR_MSG(0x148, "Upgraded client logs for %s"
3411 " cannot be modified. Consider"
3412 " updating the configuration with"
3415 GOTO(end, rc = -EINVAL);
3417 if (memcmp(ptr, PARAM_LLITE, strlen(PARAM_LLITE)) == 0) {
3418 rc = name_create(&cname, mti->mti_fsname, "-client");
3419 /* Add the client type to match the obdname in
3420 class_config_llog_handler */
3421 } else if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
3422 rc = name_create(&cname, mti->mti_svname, "-mdc");
3423 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
3424 rc = name_create(&cname, mti->mti_svname, "-osc");
3426 GOTO(end, rc = -EINVAL);
3431 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
3434 rc = name_create(&logname, mti->mti_fsname, "-client");
3436 name_destroy(&cname);
3439 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname, &mgi->mgi_bufs,
3442 /* osc params affect the MDT as well */
3443 if (!rc && (mti->mti_flags & LDD_F_SV_TYPE_OST)) {
3446 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
3447 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
3449 name_destroy(&cname);
3450 rc = name_create_mdt_osc(&cname, mti->mti_svname,
3452 name_destroy(&logname);
3455 rc = name_create_mdt(&logname,
3456 mti->mti_fsname, i);
3459 if (!mgs_log_is_empty(env, mgs, logname)) {
3460 rc = mgs_wlp_lcfg(env, mgs, fsdb,
3469 name_destroy(&logname);
3470 name_destroy(&cname);
3474 /* All mdt. params in proc */
3475 if (class_match_param(ptr, PARAM_MDT, NULL) == 0) {
3479 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
3480 if (strncmp(mti->mti_svname, mti->mti_fsname,
3481 MTI_NAME_MAXLEN) == 0)
3482 /* device is unspecified completely? */
3483 rc = LDD_F_SV_TYPE_MDT | LDD_F_SV_ALL;
3485 rc = server_name2index(mti->mti_svname, &idx, NULL);
3488 if ((rc & LDD_F_SV_TYPE_MDT) == 0)
3490 if (rc & LDD_F_SV_ALL) {
3491 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3493 fsdb->fsdb_mdt_index_map))
3495 rc = name_create_mdt(&logname,
3496 mti->mti_fsname, i);
3499 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti,
3500 logname, &mgi->mgi_bufs,
3502 name_destroy(&logname);
3507 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti,
3508 mti->mti_svname, &mgi->mgi_bufs,
3509 mti->mti_svname, ptr);
3516 /* All mdd., ost. and osd. params in proc */
3517 if ((class_match_param(ptr, PARAM_MDD, NULL) == 0) ||
3518 (class_match_param(ptr, PARAM_OST, NULL) == 0) ||
3519 (class_match_param(ptr, PARAM_OSD, NULL) == 0)) {
3520 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
3521 if (mgs_log_is_empty(env, mgs, mti->mti_svname))
3522 GOTO(end, rc = -ENODEV);
3524 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, mti->mti_svname,
3525 &mgi->mgi_bufs, mti->mti_svname, ptr);
3529 LCONSOLE_WARN("Ignoring unrecognized param '%s'\n", ptr);
3534 CERROR("err %d on param '%s'\n", rc, ptr);
3539 /* Not implementing automatic failover nid addition at this time. */
3540 int mgs_check_failnid(const struct lu_env *env, struct mgs_device *mgs,
3541 struct mgs_target_info *mti)
3548 rc = mgs_find_or_make_fsdb(obd, fsname, &fsdb);
3552 if (mgs_log_is_empty(obd, mti->mti_svname))
3553 /* should never happen */
3556 CDEBUG(D_MGS, "Checking for new failnids for %s\n", mti->mti_svname);
3558 /* FIXME We can just check mti->params to see if we're already in
3559 the failover list. Modify mti->params for rewriting back at
3560 server_register_target(). */
3562 mutex_lock(&fsdb->fsdb_mutex);
3563 rc = mgs_write_log_add_failnid(obd, fsdb, mti);
3564 mutex_unlock(&fsdb->fsdb_mutex);
3571 int mgs_write_log_target(const struct lu_env *env,
3572 struct mgs_device *mgs,
3573 struct mgs_target_info *mti,
3580 /* set/check the new target index */
3581 rc = mgs_set_index(env, mgs, mti);
3583 CERROR("Can't get index (%d)\n", rc);
3587 if (rc == EALREADY) {
3588 LCONSOLE_WARN("Found index %d for %s, updating log\n",
3589 mti->mti_stripe_index, mti->mti_svname);
3590 /* We would like to mark old log sections as invalid
3591 and add new log sections in the client and mdt logs.
3592 But if we add new sections, then live clients will
3593 get repeat setup instructions for already running
3594 osc's. So don't update the client/mdt logs. */
3595 mti->mti_flags &= ~LDD_F_UPDATE;
3599 mutex_lock(&fsdb->fsdb_mutex);
3601 if (mti->mti_flags &
3602 (LDD_F_VIRGIN | LDD_F_UPGRADE14 | LDD_F_WRITECONF)) {
3603 /* Generate a log from scratch */
3604 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
3605 rc = mgs_write_log_mdt(env, mgs, fsdb, mti);
3606 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
3607 rc = mgs_write_log_ost(env, mgs, fsdb, mti);
3609 CERROR("Unknown target type %#x, can't create log for "
3610 "%s\n", mti->mti_flags, mti->mti_svname);
3613 CERROR("Can't write logs for %s (%d)\n",
3614 mti->mti_svname, rc);
3618 /* Just update the params from tunefs in mgs_write_log_params */
3619 CDEBUG(D_MGS, "Update params for %s\n", mti->mti_svname);
3620 mti->mti_flags |= LDD_F_PARAM;
3623 /* allocate temporary buffer, where class_get_next_param will
3624 make copy of a current parameter */
3625 OBD_ALLOC(buf, strlen(mti->mti_params) + 1);
3627 GOTO(out_up, rc = -ENOMEM);
3628 params = mti->mti_params;
3629 while (params != NULL) {
3630 rc = class_get_next_param(¶ms, buf);
3633 /* there is no next parameter, that is
3638 CDEBUG(D_MGS, "remaining string: '%s', param: '%s'\n",
3640 rc = mgs_write_log_param(env, mgs, fsdb, mti, buf);
3645 OBD_FREE(buf, strlen(mti->mti_params) + 1);
3648 mutex_unlock(&fsdb->fsdb_mutex);
3652 int mgs_erase_log(const struct lu_env *env, struct mgs_device *mgs, char *name)
3654 struct llog_ctxt *ctxt;
3657 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
3659 CERROR("%s: MGS config context doesn't exist\n",
3660 mgs->mgs_obd->obd_name);
3663 rc = llog_erase(env, ctxt, NULL, name);
3664 /* llog may not exist */
3667 llog_ctxt_put(ctxt);
3671 CERROR("%s: failed to clear log %s: %d\n",
3672 mgs->mgs_obd->obd_name, name, rc);
3677 /* erase all logs for the given fs */
3678 int mgs_erase_logs(const struct lu_env *env, struct mgs_device *mgs, char *fsname)
3682 struct mgs_direntry *dirent, *n;
3683 int rc, len = strlen(fsname);
3687 /* Find all the logs in the CONFIGS directory */
3688 rc = class_dentry_readdir(env, mgs, &list);
3692 mutex_lock(&mgs->mgs_mutex);
3694 /* Delete the fs db */
3695 fsdb = mgs_find_fsdb(mgs, fsname);
3697 mgs_free_fsdb(mgs, fsdb);
3699 mutex_unlock(&mgs->mgs_mutex);
3701 cfs_list_for_each_entry_safe(dirent, n, &list, list) {
3702 cfs_list_del(&dirent->list);
3703 suffix = strrchr(dirent->name, '-');
3704 if (suffix != NULL) {
3705 if ((len == suffix - dirent->name) &&
3706 (strncmp(fsname, dirent->name, len) == 0)) {
3707 CDEBUG(D_MGS, "Removing log %s\n",
3709 mgs_erase_log(env, mgs, dirent->name);
3712 mgs_direntry_free(dirent);
3718 /* list all logs for the given fs */
3719 int mgs_list_logs(const struct lu_env *env, struct mgs_device *mgs,
3720 struct obd_ioctl_data *data)
3723 struct mgs_direntry *dirent, *n;
3729 /* Find all the logs in the CONFIGS directory */
3730 rc = class_dentry_readdir(env, mgs, &list);
3732 CERROR("%s: can't read %s dir = %d\n",
3733 mgs->mgs_obd->obd_name, MOUNT_CONFIGS_DIR, rc);
3737 out = data->ioc_bulk;
3738 remains = data->ioc_inllen1;
3739 cfs_list_for_each_entry_safe(dirent, n, &list, list) {
3740 cfs_list_del(&dirent->list);
3741 suffix = strrchr(dirent->name, '-');
3742 if (suffix != NULL) {
3743 l = snprintf(out, remains, "config log: $%s\n",
3748 mgs_direntry_free(dirent);
3755 /* from llog_swab */
3756 static void print_lustre_cfg(struct lustre_cfg *lcfg)
3761 CDEBUG(D_MGS, "lustre_cfg: %p\n", lcfg);
3762 CDEBUG(D_MGS, "\tlcfg->lcfg_version: %#x\n", lcfg->lcfg_version);
3764 CDEBUG(D_MGS, "\tlcfg->lcfg_command: %#x\n", lcfg->lcfg_command);
3765 CDEBUG(D_MGS, "\tlcfg->lcfg_num: %#x\n", lcfg->lcfg_num);
3766 CDEBUG(D_MGS, "\tlcfg->lcfg_flags: %#x\n", lcfg->lcfg_flags);
3767 CDEBUG(D_MGS, "\tlcfg->lcfg_nid: %s\n", libcfs_nid2str(lcfg->lcfg_nid));
3769 CDEBUG(D_MGS, "\tlcfg->lcfg_bufcount: %d\n", lcfg->lcfg_bufcount);
3770 if (lcfg->lcfg_bufcount < LUSTRE_CFG_MAX_BUFCOUNT)
3771 for (i = 0; i < lcfg->lcfg_bufcount; i++) {
3772 CDEBUG(D_MGS, "\tlcfg->lcfg_buflens[%d]: %d %s\n",
3773 i, lcfg->lcfg_buflens[i],
3774 lustre_cfg_string(lcfg, i));
3779 /* Set a permanent (config log) param for a target or fs
3780 * \param lcfg buf0 may contain the device (testfs-MDT0000) name
3781 * buf1 contains the single parameter
3783 int mgs_setparam(const struct lu_env *env, struct mgs_device *mgs,
3784 struct lustre_cfg *lcfg, char *fsname)
3787 struct mgs_target_info *mti;
3788 char *devname, *param;
3795 print_lustre_cfg(lcfg);
3797 /* lustre, lustre-mdtlov, lustre-client, lustre-MDT0000 */
3798 devname = lustre_cfg_string(lcfg, 0);
3799 param = lustre_cfg_string(lcfg, 1);
3801 /* Assume device name embedded in param:
3802 lustre-OST0000.osc.max_dirty_mb=32 */
3803 ptr = strchr(param, '.');
3811 LCONSOLE_ERROR_MSG(0x14d, "No target specified: %s\n", param);
3815 rc = mgs_parse_devname(devname, fsname, NULL);
3816 if (rc == 0 && !mgs_parse_devname(devname, NULL, &index)) {
3817 /* param related to llite isn't allowed to set by OST or MDT */
3818 if (rc == 0 && strncmp(param, PARAM_LLITE,
3819 sizeof(PARAM_LLITE) - 1) == 0)
3822 /* assume devname is the fsname */
3823 memset(fsname, 0, MTI_NAME_MAXLEN);
3824 strncpy(fsname, devname, MTI_NAME_MAXLEN);
3825 fsname[MTI_NAME_MAXLEN - 1] = 0;
3827 CDEBUG(D_MGS, "setparam fs='%s' device='%s'\n", fsname, devname);
3829 rc = mgs_find_or_make_fsdb(env, mgs,
3830 lcfg->lcfg_command == LCFG_SET_PARAM ?
3831 PARAMS_FILENAME : fsname, &fsdb);
3835 if (lcfg->lcfg_command != LCFG_SET_PARAM &&
3836 !test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags) &&
3837 test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
3838 CERROR("No filesystem targets for %s. cfg_device from lctl "
3839 "is '%s'\n", fsname, devname);
3840 mgs_free_fsdb(mgs, fsdb);
3844 /* Create a fake mti to hold everything */
3847 GOTO(out, rc = -ENOMEM);
3848 if (strlcpy(mti->mti_fsname, fsname, sizeof(mti->mti_fsname))
3849 >= sizeof(mti->mti_fsname))
3850 GOTO(out, rc = -E2BIG);
3851 if (strlcpy(mti->mti_svname, devname, sizeof(mti->mti_svname))
3852 >= sizeof(mti->mti_svname))
3853 GOTO(out, rc = -E2BIG);
3854 if (strlcpy(mti->mti_params, param, sizeof(mti->mti_params))
3855 >= sizeof(mti->mti_params))
3856 GOTO(out, rc = -E2BIG);
3857 rc = server_name2index(mti->mti_svname, &mti->mti_stripe_index, &tmp);
3859 /* Not a valid server; may be only fsname */
3862 /* Strip -osc or -mdc suffix from svname */
3863 if (server_make_name(rc, mti->mti_stripe_index, mti->mti_fsname,
3865 GOTO(out, rc = -EINVAL);
3867 * Revoke lock so everyone updates. Should be alright if
3868 * someone was already reading while we were updating the logs,
3869 * so we don't really need to hold the lock while we're
3872 if (lcfg->lcfg_command == LCFG_SET_PARAM) {
3873 mti->mti_flags = rc | LDD_F_PARAM2;
3874 mutex_lock(&fsdb->fsdb_mutex);
3875 rc = mgs_write_log_param2(env, mgs, fsdb, mti, mti->mti_params);
3876 mutex_unlock(&fsdb->fsdb_mutex);
3877 mgs_revoke_lock(mgs, fsdb, CONFIG_T_PARAMS);
3879 mti->mti_flags = rc | LDD_F_PARAM;
3880 mutex_lock(&fsdb->fsdb_mutex);
3881 rc = mgs_write_log_param(env, mgs, fsdb, mti, mti->mti_params);
3882 mutex_unlock(&fsdb->fsdb_mutex);
3883 mgs_revoke_lock(mgs, fsdb, CONFIG_T_CONFIG);
3891 static int mgs_write_log_pool(const struct lu_env *env,
3892 struct mgs_device *mgs, char *logname,
3893 struct fs_db *fsdb, char *tgtname,
3894 enum lcfg_command_type cmd,
3895 char *fsname, char *poolname,
3896 char *ostname, char *comment)
3898 struct llog_handle *llh = NULL;
3901 rc = record_start_log(env, mgs, &llh, logname);
3904 rc = record_marker(env, llh, fsdb, CM_START, tgtname, comment);
3907 rc = record_base(env, llh, tgtname, 0, cmd,
3908 fsname, poolname, ostname, 0);
3911 rc = record_marker(env, llh, fsdb, CM_END, tgtname, comment);
3913 record_end_log(env, &llh);
3917 int mgs_nodemap_cmd(const struct lu_env *env, struct mgs_device *mgs,
3918 enum lcfg_command_type cmd, const char *nodemap_name,
3929 case LCFG_NODEMAP_ADD:
3930 rc = nodemap_add(nodemap_name);
3932 case LCFG_NODEMAP_DEL:
3933 rc = nodemap_del(nodemap_name);
3935 case LCFG_NODEMAP_ADD_RANGE:
3936 rc = nodemap_parse_range(param, nid);
3939 rc = nodemap_add_range(nodemap_name, nid);
3941 case LCFG_NODEMAP_DEL_RANGE:
3942 rc = nodemap_parse_range(param, nid);
3945 rc = nodemap_del_range(nodemap_name, nid);
3947 case LCFG_NODEMAP_ADMIN:
3948 bool_switch = simple_strtoul(param, NULL, 10);
3949 rc = nodemap_set_allow_root(nodemap_name, bool_switch);
3951 case LCFG_NODEMAP_TRUSTED:
3952 bool_switch = simple_strtoul(param, NULL, 10);
3953 rc = nodemap_set_trust_client_ids(nodemap_name, bool_switch);
3955 case LCFG_NODEMAP_SQUASH_UID:
3956 int_id = simple_strtoul(param, NULL, 10);
3957 rc = nodemap_set_squash_uid(nodemap_name, int_id);
3959 case LCFG_NODEMAP_SQUASH_GID:
3960 int_id = simple_strtoul(param, NULL, 10);
3961 rc = nodemap_set_squash_gid(nodemap_name, int_id);
3963 case LCFG_NODEMAP_ADD_UIDMAP:
3964 case LCFG_NODEMAP_ADD_GIDMAP:
3965 rc = nodemap_parse_idmap(param, idmap);
3968 if (cmd == LCFG_NODEMAP_ADD_UIDMAP)
3969 rc = nodemap_add_idmap(nodemap_name, NODEMAP_UID,
3972 rc = nodemap_add_idmap(nodemap_name, NODEMAP_GID,
3975 case LCFG_NODEMAP_DEL_UIDMAP:
3976 case LCFG_NODEMAP_DEL_GIDMAP:
3977 rc = nodemap_parse_idmap(param, idmap);
3980 if (cmd == LCFG_NODEMAP_DEL_UIDMAP)
3981 rc = nodemap_del_idmap(nodemap_name, NODEMAP_UID,
3984 rc = nodemap_del_idmap(nodemap_name, NODEMAP_GID,
3994 int mgs_pool_cmd(const struct lu_env *env, struct mgs_device *mgs,
3995 enum lcfg_command_type cmd, char *fsname,
3996 char *poolname, char *ostname)
4001 char *label = NULL, *canceled_label = NULL;
4003 struct mgs_target_info *mti = NULL;
4007 rc = mgs_find_or_make_fsdb(env, mgs, fsname, &fsdb);
4009 CERROR("Can't get db for %s\n", fsname);
4012 if (test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
4013 CERROR("%s is not defined\n", fsname);
4014 mgs_free_fsdb(mgs, fsdb);
4018 label_sz = 10 + strlen(fsname) + strlen(poolname);
4020 /* check if ostname match fsname */
4021 if (ostname != NULL) {
4024 ptr = strrchr(ostname, '-');
4025 if ((ptr == NULL) ||
4026 (strncmp(fsname, ostname, ptr-ostname) != 0))
4028 label_sz += strlen(ostname);
4031 OBD_ALLOC(label, label_sz);
4038 "new %s.%s", fsname, poolname);
4042 "add %s.%s.%s", fsname, poolname, ostname);
4045 OBD_ALLOC(canceled_label, label_sz);
4046 if (canceled_label == NULL)
4047 GOTO(out_label, rc = -ENOMEM);
4049 "rem %s.%s.%s", fsname, poolname, ostname);
4050 sprintf(canceled_label,
4051 "add %s.%s.%s", fsname, poolname, ostname);
4054 OBD_ALLOC(canceled_label, label_sz);
4055 if (canceled_label == NULL)
4056 GOTO(out_label, rc = -ENOMEM);
4058 "del %s.%s", fsname, poolname);
4059 sprintf(canceled_label,
4060 "new %s.%s", fsname, poolname);
4066 if (canceled_label != NULL) {
4069 GOTO(out_cancel, rc = -ENOMEM);
4072 mutex_lock(&fsdb->fsdb_mutex);
4073 /* write pool def to all MDT logs */
4074 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
4075 if (test_bit(i, fsdb->fsdb_mdt_index_map)) {
4076 rc = name_create_mdt_and_lov(&logname, &lovname,
4079 mutex_unlock(&fsdb->fsdb_mutex);
4082 if (canceled_label != NULL) {
4083 strcpy(mti->mti_svname, "lov pool");
4084 rc = mgs_modify(env, mgs, fsdb, mti, logname,
4085 lovname, canceled_label,
4090 rc = mgs_write_log_pool(env, mgs, logname,
4094 name_destroy(&logname);
4095 name_destroy(&lovname);
4097 mutex_unlock(&fsdb->fsdb_mutex);
4103 rc = name_create(&logname, fsname, "-client");
4105 mutex_unlock(&fsdb->fsdb_mutex);
4108 if (canceled_label != NULL) {
4109 rc = mgs_modify(env, mgs, fsdb, mti, logname,
4110 fsdb->fsdb_clilov, canceled_label, CM_SKIP);
4112 mutex_unlock(&fsdb->fsdb_mutex);
4113 name_destroy(&logname);
4118 rc = mgs_write_log_pool(env, mgs, logname, fsdb, fsdb->fsdb_clilov,
4119 cmd, fsname, poolname, ostname, label);
4120 mutex_unlock(&fsdb->fsdb_mutex);
4121 name_destroy(&logname);
4122 /* request for update */
4123 mgs_revoke_lock(mgs, fsdb, CONFIG_T_CONFIG);
4130 if (canceled_label != NULL)
4131 OBD_FREE(canceled_label, label_sz);
4133 OBD_FREE(label, label_sz);