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 static int only_mgs_is_running(struct obd_device *mgs_obd)
1175 /* TDB: Is global variable with devices count exists? */
1176 int num_devices = get_devices_count();
1177 /* osd, MGS and MGC + self_export
1178 (wc -l /proc/fs/lustre/devices <= 2) && (num_exports <= 2) */
1179 return (num_devices <= 3) && (mgs_obd->obd_num_exports <= 2);
1182 static int name_create_mdt(char **logname, char *fsname, int i)
1186 sprintf(mdt_index, "-MDT%04x", i);
1187 return name_create(logname, fsname, mdt_index);
1191 * Replace nids for \a device to \a nids values
1193 * \param obd MGS obd device
1194 * \param devname nids need to be replaced for this device
1195 * (ex. lustre-OST0000)
1196 * \param nids nids list (ex. nid1,nid2,nid3)
1200 int mgs_replace_nids(const struct lu_env *env,
1201 struct mgs_device *mgs,
1202 char *devname, char *nids)
1204 /* Assume fsname is part of device name */
1205 char fsname[MTI_NAME_MAXLEN];
1212 struct obd_device *mgs_obd = mgs->mgs_obd;
1215 /* We can only change NIDs if no other nodes are connected */
1216 spin_lock(&mgs_obd->obd_dev_lock);
1217 conn_state = mgs_obd->obd_no_conn;
1218 mgs_obd->obd_no_conn = 1;
1219 spin_unlock(&mgs_obd->obd_dev_lock);
1221 /* We can not change nids if not only MGS is started */
1222 if (!only_mgs_is_running(mgs_obd)) {
1223 CERROR("Only MGS is allowed to be started\n");
1224 GOTO(out, rc = -EINPROGRESS);
1227 /* Get fsname and index*/
1228 rc = mgs_parse_devname(devname, fsname, &index);
1232 rc = mgs_find_or_make_fsdb(env, mgs, fsname, &fsdb);
1234 CERROR("%s: can't find fsdb: rc = %d\n", fsname, rc);
1238 /* Process client llogs */
1239 name_create(&logname, fsname, "-client");
1240 rc = mgs_replace_nids_log(env, mgs_obd, fsdb, logname, devname, nids);
1241 name_destroy(&logname);
1243 CERROR("%s: error while replacing NIDs for %s: rc = %d\n",
1244 fsname, devname, rc);
1248 /* Process MDT llogs */
1249 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
1250 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
1252 name_create_mdt(&logname, fsname, i);
1253 rc = mgs_replace_nids_log(env, mgs_obd, fsdb, logname, devname, nids);
1254 name_destroy(&logname);
1260 spin_lock(&mgs_obd->obd_dev_lock);
1261 mgs_obd->obd_no_conn = conn_state;
1262 spin_unlock(&mgs_obd->obd_dev_lock);
1267 static int record_lov_setup(const struct lu_env *env, struct llog_handle *llh,
1268 char *devname, struct lov_desc *desc)
1270 struct mgs_thread_info *mgi = mgs_env_info(env);
1271 struct lustre_cfg *lcfg;
1274 lustre_cfg_bufs_reset(&mgi->mgi_bufs, devname);
1275 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, desc, sizeof(*desc));
1276 lcfg = lustre_cfg_new(LCFG_SETUP, &mgi->mgi_bufs);
1279 rc = record_lcfg(env, llh, lcfg);
1281 lustre_cfg_free(lcfg);
1285 static int record_lmv_setup(const struct lu_env *env, struct llog_handle *llh,
1286 char *devname, struct lmv_desc *desc)
1288 struct mgs_thread_info *mgi = mgs_env_info(env);
1289 struct lustre_cfg *lcfg;
1292 lustre_cfg_bufs_reset(&mgi->mgi_bufs, devname);
1293 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, desc, sizeof(*desc));
1294 lcfg = lustre_cfg_new(LCFG_SETUP, &mgi->mgi_bufs);
1296 rc = record_lcfg(env, llh, lcfg);
1298 lustre_cfg_free(lcfg);
1302 static inline int record_mdc_add(const struct lu_env *env,
1303 struct llog_handle *llh,
1304 char *logname, char *mdcuuid,
1305 char *mdtuuid, char *index,
1308 return record_base(env,llh,logname,0,LCFG_ADD_MDC,
1309 mdtuuid,index,gen,mdcuuid);
1312 static inline int record_lov_add(const struct lu_env *env,
1313 struct llog_handle *llh,
1314 char *lov_name, char *ost_uuid,
1315 char *index, char *gen)
1317 return record_base(env,llh,lov_name,0,LCFG_LOV_ADD_OBD,
1318 ost_uuid, index, gen, 0);
1321 static inline int record_mount_opt(const struct lu_env *env,
1322 struct llog_handle *llh,
1323 char *profile, char *lov_name,
1326 return record_base(env,llh,NULL,0,LCFG_MOUNTOPT,
1327 profile,lov_name,mdc_name,0);
1330 static int record_marker(const struct lu_env *env,
1331 struct llog_handle *llh,
1332 struct fs_db *fsdb, __u32 flags,
1333 char *tgtname, char *comment)
1335 struct mgs_thread_info *mgi = mgs_env_info(env);
1336 struct lustre_cfg *lcfg;
1340 if (flags & CM_START)
1342 mgi->mgi_marker.cm_step = fsdb->fsdb_gen;
1343 mgi->mgi_marker.cm_flags = flags;
1344 mgi->mgi_marker.cm_vers = LUSTRE_VERSION_CODE;
1345 cplen = strlcpy(mgi->mgi_marker.cm_tgtname, tgtname,
1346 sizeof(mgi->mgi_marker.cm_tgtname));
1347 if (cplen >= sizeof(mgi->mgi_marker.cm_tgtname))
1349 cplen = strlcpy(mgi->mgi_marker.cm_comment, comment,
1350 sizeof(mgi->mgi_marker.cm_comment));
1351 if (cplen >= sizeof(mgi->mgi_marker.cm_comment))
1353 mgi->mgi_marker.cm_createtime = cfs_time_current_sec();
1354 mgi->mgi_marker.cm_canceltime = 0;
1355 lustre_cfg_bufs_reset(&mgi->mgi_bufs, NULL);
1356 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, &mgi->mgi_marker,
1357 sizeof(mgi->mgi_marker));
1358 lcfg = lustre_cfg_new(LCFG_MARKER, &mgi->mgi_bufs);
1361 rc = record_lcfg(env, llh, lcfg);
1363 lustre_cfg_free(lcfg);
1367 static int record_start_log(const struct lu_env *env, struct mgs_device *mgs,
1368 struct llog_handle **llh, char *name)
1370 static struct obd_uuid cfg_uuid = { .uuid = "config_uuid" };
1371 struct llog_ctxt *ctxt;
1375 GOTO(out, rc = -EBUSY);
1377 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
1379 GOTO(out, rc = -ENODEV);
1380 LASSERT(ctxt->loc_obd == mgs->mgs_obd);
1382 rc = llog_open_create(env, ctxt, llh, NULL, name);
1385 rc = llog_init_handle(env, *llh, LLOG_F_IS_PLAIN, &cfg_uuid);
1387 llog_close(env, *llh);
1389 llog_ctxt_put(ctxt);
1392 CERROR("%s: can't start log %s: rc = %d\n",
1393 mgs->mgs_obd->obd_name, name, rc);
1399 static int record_end_log(const struct lu_env *env, struct llog_handle **llh)
1403 rc = llog_close(env, *llh);
1409 /******************** config "macros" *********************/
1411 /* write an lcfg directly into a log (with markers) */
1412 static int mgs_write_log_direct(const struct lu_env *env,
1413 struct mgs_device *mgs, struct fs_db *fsdb,
1414 char *logname, struct lustre_cfg *lcfg,
1415 char *devname, char *comment)
1417 struct llog_handle *llh = NULL;
1424 rc = record_start_log(env, mgs, &llh, logname);
1428 /* FIXME These should be a single journal transaction */
1429 rc = record_marker(env, llh, fsdb, CM_START, devname, comment);
1432 rc = record_lcfg(env, llh, lcfg);
1435 rc = record_marker(env, llh, fsdb, CM_END, devname, comment);
1439 record_end_log(env, &llh);
1443 /* write the lcfg in all logs for the given fs */
1444 int mgs_write_log_direct_all(const struct lu_env *env,
1445 struct mgs_device *mgs,
1447 struct mgs_target_info *mti,
1448 struct lustre_cfg *lcfg,
1449 char *devname, char *comment,
1453 struct mgs_direntry *dirent, *n;
1454 char *fsname = mti->mti_fsname;
1456 int rc = 0, len = strlen(fsname);
1459 /* We need to set params for any future logs
1460 as well. FIXME Append this file to every new log.
1461 Actually, we should store as params (text), not llogs. Or
1463 rc = name_create(&logname, fsname, "-params");
1466 if (mgs_log_is_empty(env, mgs, logname)) {
1467 struct llog_handle *llh = NULL;
1468 rc = record_start_log(env, mgs, &llh, logname);
1470 record_end_log(env, &llh);
1472 name_destroy(&logname);
1476 /* Find all the logs in the CONFIGS directory */
1477 rc = class_dentry_readdir(env, mgs, &list);
1481 /* Could use fsdb index maps instead of directory listing */
1482 cfs_list_for_each_entry_safe(dirent, n, &list, list) {
1483 cfs_list_del(&dirent->list);
1484 /* don't write to sptlrpc rule log */
1485 if (strstr(dirent->name, "-sptlrpc") != NULL)
1488 /* caller wants write server logs only */
1489 if (server_only && strstr(dirent->name, "-client") != NULL)
1492 if (strncmp(fsname, dirent->name, len) == 0) {
1493 CDEBUG(D_MGS, "Changing log %s\n", dirent->name);
1494 /* Erase any old settings of this same parameter */
1495 rc = mgs_modify(env, mgs, fsdb, mti, dirent->name,
1496 devname, comment, CM_SKIP);
1498 CERROR("%s: Can't modify llog %s: rc = %d\n",
1499 mgs->mgs_obd->obd_name, dirent->name,rc);
1500 /* Write the new one */
1502 rc = mgs_write_log_direct(env, mgs, fsdb,
1507 CERROR("%s: writing log %s: rc = %d\n",
1508 mgs->mgs_obd->obd_name,
1513 mgs_direntry_free(dirent);
1519 static int mgs_write_log_osp_to_mdt(const struct lu_env *env,
1520 struct mgs_device *mgs,
1522 struct mgs_target_info *mti,
1523 int index, char *logname);
1524 static int mgs_write_log_osc_to_lov(const struct lu_env *env,
1525 struct mgs_device *mgs,
1527 struct mgs_target_info *mti,
1528 char *logname, char *suffix, char *lovname,
1529 enum lustre_sec_part sec_part, int flags);
1530 static int name_create_mdt_and_lov(char **logname, char **lovname,
1531 struct fs_db *fsdb, int i);
1533 static int add_param(char *params, char *key, char *val)
1535 char *start = params + strlen(params);
1536 char *end = params + sizeof(((struct mgs_target_info *)0)->mti_params);
1540 keylen = strlen(key);
1541 if (start + 1 + keylen + strlen(val) >= end) {
1542 CERROR("params are too long: %s %s%s\n",
1543 params, key != NULL ? key : "", val);
1547 sprintf(start, " %s%s", key != NULL ? key : "", val);
1552 * Walk through client config log record and convert the related records
1555 static int mgs_steal_client_llog_handler(const struct lu_env *env,
1556 struct llog_handle *llh,
1557 struct llog_rec_hdr *rec, void *data)
1559 struct mgs_device *mgs;
1560 struct obd_device *obd;
1561 struct mgs_target_info *mti, *tmti;
1563 int cfg_len = rec->lrh_len;
1564 char *cfg_buf = (char*) (rec + 1);
1565 struct lustre_cfg *lcfg;
1567 struct llog_handle *mdt_llh = NULL;
1568 static int got_an_osc_or_mdc = 0;
1569 /* 0: not found any osc/mdc;
1573 static int last_step = -1;
1578 mti = ((struct temp_comp*)data)->comp_mti;
1579 tmti = ((struct temp_comp*)data)->comp_tmti;
1580 fsdb = ((struct temp_comp*)data)->comp_fsdb;
1581 obd = ((struct temp_comp *)data)->comp_obd;
1582 mgs = lu2mgs_dev(obd->obd_lu_dev);
1585 if (rec->lrh_type != OBD_CFG_REC) {
1586 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
1590 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
1592 CERROR("Insane cfg\n");
1596 lcfg = (struct lustre_cfg *)cfg_buf;
1598 if (lcfg->lcfg_command == LCFG_MARKER) {
1599 struct cfg_marker *marker;
1600 marker = lustre_cfg_buf(lcfg, 1);
1601 if (!strncmp(marker->cm_comment, "add osc", 7) &&
1602 (marker->cm_flags & CM_START) &&
1603 !(marker->cm_flags & CM_SKIP)) {
1604 got_an_osc_or_mdc = 1;
1605 cplen = strlcpy(tmti->mti_svname, marker->cm_tgtname,
1606 sizeof(tmti->mti_svname));
1607 if (cplen >= sizeof(tmti->mti_svname))
1609 rc = record_start_log(env, mgs, &mdt_llh,
1613 rc = record_marker(env, mdt_llh, fsdb, CM_START,
1614 mti->mti_svname, "add osc(copied)");
1615 record_end_log(env, &mdt_llh);
1616 last_step = marker->cm_step;
1619 if (!strncmp(marker->cm_comment, "add osc", 7) &&
1620 (marker->cm_flags & CM_END) &&
1621 !(marker->cm_flags & CM_SKIP)) {
1622 LASSERT(last_step == marker->cm_step);
1624 got_an_osc_or_mdc = 0;
1625 memset(tmti, 0, sizeof(*tmti));
1626 rc = record_start_log(env, mgs, &mdt_llh,
1630 rc = record_marker(env, mdt_llh, fsdb, CM_END,
1631 mti->mti_svname, "add osc(copied)");
1632 record_end_log(env, &mdt_llh);
1635 if (!strncmp(marker->cm_comment, "add mdc", 7) &&
1636 (marker->cm_flags & CM_START) &&
1637 !(marker->cm_flags & CM_SKIP)) {
1638 got_an_osc_or_mdc = 2;
1639 last_step = marker->cm_step;
1640 memcpy(tmti->mti_svname, marker->cm_tgtname,
1641 strlen(marker->cm_tgtname));
1645 if (!strncmp(marker->cm_comment, "add mdc", 7) &&
1646 (marker->cm_flags & CM_END) &&
1647 !(marker->cm_flags & CM_SKIP)) {
1648 LASSERT(last_step == marker->cm_step);
1650 got_an_osc_or_mdc = 0;
1651 memset(tmti, 0, sizeof(*tmti));
1656 if (got_an_osc_or_mdc == 0 || last_step < 0)
1659 if (lcfg->lcfg_command == LCFG_ADD_UUID) {
1660 uint64_t nodenid = lcfg->lcfg_nid;
1662 if (strlen(tmti->mti_uuid) == 0) {
1663 /* target uuid not set, this config record is before
1664 * LCFG_SETUP, this nid is one of target node nid.
1666 tmti->mti_nids[tmti->mti_nid_count] = nodenid;
1667 tmti->mti_nid_count++;
1669 /* failover node nid */
1670 rc = add_param(tmti->mti_params, PARAM_FAILNODE,
1671 libcfs_nid2str(nodenid));
1677 if (lcfg->lcfg_command == LCFG_SETUP) {
1680 target = lustre_cfg_string(lcfg, 1);
1681 memcpy(tmti->mti_uuid, target, strlen(target));
1685 /* ignore client side sptlrpc_conf_log */
1686 if (lcfg->lcfg_command == LCFG_SPTLRPC_CONF)
1689 if (lcfg->lcfg_command == LCFG_ADD_MDC) {
1692 if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1)
1695 memcpy(tmti->mti_fsname, mti->mti_fsname,
1696 strlen(mti->mti_fsname));
1697 tmti->mti_stripe_index = index;
1699 rc = mgs_write_log_osp_to_mdt(env, mgs, fsdb, tmti,
1700 mti->mti_stripe_index,
1702 memset(tmti, 0, sizeof(*tmti));
1706 if (lcfg->lcfg_command == LCFG_LOV_ADD_OBD) {
1709 char *logname, *lovname;
1711 rc = name_create_mdt_and_lov(&logname, &lovname, fsdb,
1712 mti->mti_stripe_index);
1715 sprintf(mdt_index, "-MDT%04x", mti->mti_stripe_index);
1717 if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1) {
1718 name_destroy(&logname);
1719 name_destroy(&lovname);
1723 tmti->mti_stripe_index = index;
1724 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, tmti, logname,
1727 name_destroy(&logname);
1728 name_destroy(&lovname);
1734 /* fsdb->fsdb_mutex is already held in mgs_write_log_target*/
1735 /* stealed from mgs_get_fsdb_from_llog*/
1736 static int mgs_steal_llog_for_mdt_from_client(const struct lu_env *env,
1737 struct mgs_device *mgs,
1739 struct temp_comp* comp)
1741 struct llog_handle *loghandle;
1742 struct mgs_target_info *tmti;
1743 struct llog_ctxt *ctxt;
1748 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
1749 LASSERT(ctxt != NULL);
1751 OBD_ALLOC_PTR(tmti);
1753 GOTO(out_ctxt, rc = -ENOMEM);
1755 comp->comp_tmti = tmti;
1756 comp->comp_obd = mgs->mgs_obd;
1758 rc = llog_open(env, ctxt, &loghandle, NULL, client_name,
1766 rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL);
1768 GOTO(out_close, rc);
1770 rc = llog_process_or_fork(env, loghandle, mgs_steal_client_llog_handler,
1771 (void *)comp, NULL, false);
1772 CDEBUG(D_MGS, "steal llog re = %d\n", rc);
1774 llog_close(env, loghandle);
1778 llog_ctxt_put(ctxt);
1782 /* lmv is the second thing for client logs */
1783 /* copied from mgs_write_log_lov. Please refer to that. */
1784 static int mgs_write_log_lmv(const struct lu_env *env,
1785 struct mgs_device *mgs,
1787 struct mgs_target_info *mti,
1788 char *logname, char *lmvname)
1790 struct llog_handle *llh = NULL;
1791 struct lmv_desc *lmvdesc;
1796 CDEBUG(D_MGS, "Writing lmv(%s) log for %s\n", lmvname,logname);
1798 OBD_ALLOC_PTR(lmvdesc);
1799 if (lmvdesc == NULL)
1801 lmvdesc->ld_active_tgt_count = 0;
1802 lmvdesc->ld_tgt_count = 0;
1803 sprintf((char*)lmvdesc->ld_uuid.uuid, "%s_UUID", lmvname);
1804 uuid = (char *)lmvdesc->ld_uuid.uuid;
1806 rc = record_start_log(env, mgs, &llh, logname);
1809 rc = record_marker(env, llh, fsdb, CM_START, lmvname, "lmv setup");
1812 rc = record_attach(env, llh, lmvname, "lmv", uuid);
1815 rc = record_lmv_setup(env, llh, lmvname, lmvdesc);
1818 rc = record_marker(env, llh, fsdb, CM_END, lmvname, "lmv setup");
1822 record_end_log(env, &llh);
1824 OBD_FREE_PTR(lmvdesc);
1828 /* lov is the first thing in the mdt and client logs */
1829 static int mgs_write_log_lov(const struct lu_env *env, struct mgs_device *mgs,
1830 struct fs_db *fsdb, struct mgs_target_info *mti,
1831 char *logname, char *lovname)
1833 struct llog_handle *llh = NULL;
1834 struct lov_desc *lovdesc;
1839 CDEBUG(D_MGS, "Writing lov(%s) log for %s\n", lovname, logname);
1842 #01 L attach 0:lov_mdsA 1:lov 2:71ccb_lov_mdsA_19f961a9e1
1843 #02 L lov_setup 0:lov_mdsA 1:(struct lov_desc)
1844 uuid=lov1_UUID, stripe count=1, size=1048576, offset=0, pattern=0
1847 /* FIXME just make lov_setup accept empty desc (put uuid in buf 2) */
1848 OBD_ALLOC_PTR(lovdesc);
1849 if (lovdesc == NULL)
1851 lovdesc->ld_magic = LOV_DESC_MAGIC;
1852 lovdesc->ld_tgt_count = 0;
1853 /* Defaults. Can be changed later by lcfg config_param */
1854 lovdesc->ld_default_stripe_count = 1;
1855 lovdesc->ld_pattern = LOV_PATTERN_RAID0;
1856 lovdesc->ld_default_stripe_size = LOV_DESC_STRIPE_SIZE_DEFAULT;
1857 lovdesc->ld_default_stripe_offset = -1;
1858 lovdesc->ld_qos_maxage = LOV_DESC_QOS_MAXAGE_DEFAULT;
1859 sprintf((char*)lovdesc->ld_uuid.uuid, "%s_UUID", lovname);
1860 /* can these be the same? */
1861 uuid = (char *)lovdesc->ld_uuid.uuid;
1863 /* This should always be the first entry in a log.
1864 rc = mgs_clear_log(obd, logname); */
1865 rc = record_start_log(env, mgs, &llh, logname);
1868 /* FIXME these should be a single journal transaction */
1869 rc = record_marker(env, llh, fsdb, CM_START, lovname, "lov setup");
1872 rc = record_attach(env, llh, lovname, "lov", uuid);
1875 rc = record_lov_setup(env, llh, lovname, lovdesc);
1878 rc = record_marker(env, llh, fsdb, CM_END, lovname, "lov setup");
1883 record_end_log(env, &llh);
1885 OBD_FREE_PTR(lovdesc);
1889 /* add failnids to open log */
1890 static int mgs_write_log_failnids(const struct lu_env *env,
1891 struct mgs_target_info *mti,
1892 struct llog_handle *llh,
1895 char *failnodeuuid = NULL;
1896 char *ptr = mti->mti_params;
1901 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) nal=90 0: 1:uml1_UUID
1902 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
1903 #05 L setup 0:OSC_uml1_ost1_mdsA 1:ost1_UUID 2:uml1_UUID
1904 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) nal=90 0: 1:uml2_UUID
1905 #0x L add_uuid nid=2@elan(0x1000000000002) nal=90 0: 1:uml2_UUID
1906 #07 L add_conn 0:OSC_uml1_ost1_mdsA 1:uml2_UUID
1909 /* Pull failnid info out of params string */
1910 while (class_find_param(ptr, PARAM_FAILNODE, &ptr) == 0) {
1911 while (class_parse_nid(ptr, &nid, &ptr) == 0) {
1912 if (failnodeuuid == NULL) {
1913 /* We don't know the failover node name,
1914 so just use the first nid as the uuid */
1915 rc = name_create(&failnodeuuid,
1916 libcfs_nid2str(nid), "");
1920 CDEBUG(D_MGS, "add nid %s for failover uuid %s, "
1921 "client %s\n", libcfs_nid2str(nid),
1922 failnodeuuid, cliname);
1923 rc = record_add_uuid(env, llh, nid, failnodeuuid);
1926 rc = record_add_conn(env, llh, cliname, failnodeuuid);
1927 name_destroy(&failnodeuuid);
1928 failnodeuuid = NULL;
1935 static int mgs_write_log_mdc_to_lmv(const struct lu_env *env,
1936 struct mgs_device *mgs,
1938 struct mgs_target_info *mti,
1939 char *logname, char *lmvname)
1941 struct llog_handle *llh = NULL;
1942 char *mdcname = NULL;
1943 char *nodeuuid = NULL;
1944 char *mdcuuid = NULL;
1945 char *lmvuuid = NULL;
1950 if (mgs_log_is_empty(env, mgs, logname)) {
1951 CERROR("log is empty! Logical error\n");
1955 CDEBUG(D_MGS, "adding mdc for %s to log %s:lmv(%s)\n",
1956 mti->mti_svname, logname, lmvname);
1958 rc = name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
1961 rc = name_create(&mdcname, mti->mti_svname, "-mdc");
1964 rc = name_create(&mdcuuid, mdcname, "_UUID");
1967 rc = name_create(&lmvuuid, lmvname, "_UUID");
1971 rc = record_start_log(env, mgs, &llh, logname);
1974 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
1978 for (i = 0; i < mti->mti_nid_count; i++) {
1979 CDEBUG(D_MGS, "add nid %s for mdt\n",
1980 libcfs_nid2str(mti->mti_nids[i]));
1982 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
1987 rc = record_attach(env, llh, mdcname, LUSTRE_MDC_NAME, lmvuuid);
1990 rc = record_setup(env, llh, mdcname, mti->mti_uuid, nodeuuid, 0, 0);
1993 rc = mgs_write_log_failnids(env, mti, llh, mdcname);
1996 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
1997 rc = record_mdc_add(env, llh, lmvname, mdcuuid, mti->mti_uuid,
2001 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname,
2006 record_end_log(env, &llh);
2008 name_destroy(&lmvuuid);
2009 name_destroy(&mdcuuid);
2010 name_destroy(&mdcname);
2011 name_destroy(&nodeuuid);
2015 static inline int name_create_lov(char **lovname, char *mdtname,
2016 struct fs_db *fsdb, int index)
2019 if (index == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2020 return name_create(lovname, fsdb->fsdb_name, "-mdtlov");
2022 return name_create(lovname, mdtname, "-mdtlov");
2025 static int name_create_mdt_and_lov(char **logname, char **lovname,
2026 struct fs_db *fsdb, int i)
2030 rc = name_create_mdt(logname, fsdb->fsdb_name, i);
2034 if (i == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2035 rc = name_create(lovname, fsdb->fsdb_name, "-mdtlov");
2037 rc = name_create(lovname, *logname, "-mdtlov");
2039 name_destroy(logname);
2045 static inline int name_create_mdt_osc(char **oscname, char *ostname,
2046 struct fs_db *fsdb, int i)
2050 if (i == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2051 sprintf(suffix, "-osc");
2053 sprintf(suffix, "-osc-MDT%04x", i);
2054 return name_create(oscname, ostname, suffix);
2057 /* add new mdc to already existent MDS */
2058 static int mgs_write_log_osp_to_mdt(const struct lu_env *env,
2059 struct mgs_device *mgs,
2061 struct mgs_target_info *mti,
2062 int mdt_index, char *logname)
2064 struct llog_handle *llh = NULL;
2065 char *nodeuuid = NULL;
2066 char *ospname = NULL;
2067 char *lovuuid = NULL;
2068 char *mdtuuid = NULL;
2069 char *svname = NULL;
2070 char *mdtname = NULL;
2071 char *lovname = NULL;
2076 if (mgs_log_is_empty(env, mgs, mti->mti_svname)) {
2077 CERROR("log is empty! Logical error\n");
2081 CDEBUG(D_MGS, "adding osp index %d to %s\n", mti->mti_stripe_index,
2084 rc = name_create_mdt(&mdtname, fsdb->fsdb_name, mti->mti_stripe_index);
2088 rc = name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
2090 GOTO(out_destory, rc);
2092 rc = name_create(&svname, mdtname, "-osp");
2094 GOTO(out_destory, rc);
2096 sprintf(index_str, "-MDT%04x", mdt_index);
2097 rc = name_create(&ospname, svname, index_str);
2099 GOTO(out_destory, rc);
2101 rc = name_create_lov(&lovname, logname, fsdb, mdt_index);
2103 GOTO(out_destory, rc);
2105 rc = name_create(&lovuuid, lovname, "_UUID");
2107 GOTO(out_destory, rc);
2109 rc = name_create(&mdtuuid, mdtname, "_UUID");
2111 GOTO(out_destory, rc);
2113 rc = record_start_log(env, mgs, &llh, logname);
2115 GOTO(out_destory, rc);
2117 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
2120 GOTO(out_destory, rc);
2122 for (i = 0; i < mti->mti_nid_count; i++) {
2123 CDEBUG(D_MGS, "add nid %s for mdt\n",
2124 libcfs_nid2str(mti->mti_nids[i]));
2125 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
2130 rc = record_attach(env, llh, ospname, LUSTRE_OSP_NAME, lovuuid);
2134 rc = record_setup(env, llh, ospname, mti->mti_uuid, nodeuuid,
2139 rc = mgs_write_log_failnids(env, mti, llh, ospname);
2143 /* Add mdc(osp) to lod */
2144 snprintf(index_str, sizeof(mti->mti_stripe_index), "%d",
2145 mti->mti_stripe_index);
2146 rc = record_base(env, llh, lovname, 0, LCFG_ADD_MDC, mti->mti_uuid,
2147 index_str, "1", NULL);
2151 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname, "add osp");
2156 record_end_log(env, &llh);
2159 name_destroy(&mdtuuid);
2160 name_destroy(&lovuuid);
2161 name_destroy(&lovname);
2162 name_destroy(&ospname);
2163 name_destroy(&svname);
2164 name_destroy(&nodeuuid);
2165 name_destroy(&mdtname);
2169 static int mgs_write_log_mdt0(const struct lu_env *env,
2170 struct mgs_device *mgs,
2172 struct mgs_target_info *mti)
2174 char *log = mti->mti_svname;
2175 struct llog_handle *llh = NULL;
2176 char *uuid, *lovname;
2178 char *ptr = mti->mti_params;
2179 int rc = 0, failout = 0;
2182 OBD_ALLOC(uuid, sizeof(struct obd_uuid));
2186 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
2187 failout = (strncmp(ptr, "failout", 7) == 0);
2189 rc = name_create(&lovname, log, "-mdtlov");
2192 if (mgs_log_is_empty(env, mgs, log)) {
2193 rc = mgs_write_log_lov(env, mgs, fsdb, mti, log, lovname);
2198 sprintf(mdt_index, "%d", mti->mti_stripe_index);
2200 rc = record_start_log(env, mgs, &llh, log);
2204 /* add MDT itself */
2206 /* FIXME this whole fn should be a single journal transaction */
2207 sprintf(uuid, "%s_UUID", log);
2208 rc = record_marker(env, llh, fsdb, CM_START, log, "add mdt");
2211 rc = record_attach(env, llh, log, LUSTRE_MDT_NAME, uuid);
2214 rc = record_mount_opt(env, llh, log, lovname, NULL);
2217 rc = record_setup(env, llh, log, uuid, mdt_index, lovname,
2218 failout ? "n" : "f");
2221 rc = record_marker(env, llh, fsdb, CM_END, log, "add mdt");
2225 record_end_log(env, &llh);
2227 name_destroy(&lovname);
2229 OBD_FREE(uuid, sizeof(struct obd_uuid));
2233 /* envelope method for all layers log */
2234 static int mgs_write_log_mdt(const struct lu_env *env,
2235 struct mgs_device *mgs,
2237 struct mgs_target_info *mti)
2239 struct mgs_thread_info *mgi = mgs_env_info(env);
2240 struct llog_handle *llh = NULL;
2245 CDEBUG(D_MGS, "writing new mdt %s\n", mti->mti_svname);
2247 if (mti->mti_uuid[0] == '\0') {
2248 /* Make up our own uuid */
2249 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
2250 "%s_UUID", mti->mti_svname);
2254 rc = mgs_write_log_mdt0(env, mgs, fsdb, mti);
2257 /* Append the mdt info to the client log */
2258 rc = name_create(&cliname, mti->mti_fsname, "-client");
2262 if (mgs_log_is_empty(env, mgs, cliname)) {
2263 /* Start client log */
2264 rc = mgs_write_log_lov(env, mgs, fsdb, mti, cliname,
2268 rc = mgs_write_log_lmv(env, mgs, fsdb, mti, cliname,
2275 #09 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
2276 #10 L attach 0:MDC_uml1_mdsA_MNT_client 1:mdc 2:1d834_MNT_client_03f
2277 #11 L setup 0:MDC_uml1_mdsA_MNT_client 1:mdsA_UUID 2:uml1_UUID
2278 #12 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
2279 #13 L add_conn 0:MDC_uml1_mdsA_MNT_client 1:uml2_UUID
2280 #14 L mount_option 0: 1:client 2:lov1 3:MDC_uml1_mdsA_MNT_client
2283 /* copy client info about lov/lmv */
2284 mgi->mgi_comp.comp_mti = mti;
2285 mgi->mgi_comp.comp_fsdb = fsdb;
2287 rc = mgs_steal_llog_for_mdt_from_client(env, mgs, cliname,
2291 rc = mgs_write_log_mdc_to_lmv(env, mgs, fsdb, mti, cliname,
2297 rc = record_start_log(env, mgs, &llh, cliname);
2301 rc = record_marker(env, llh, fsdb, CM_START, cliname,
2305 rc = record_mount_opt(env, llh, cliname, fsdb->fsdb_clilov,
2309 rc = record_marker(env, llh, fsdb, CM_END, cliname,
2315 /* for_all_existing_mdt except current one */
2316 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2317 if (i != mti->mti_stripe_index &&
2318 test_bit(i, fsdb->fsdb_mdt_index_map)) {
2321 rc = name_create_mdt(&logname, fsdb->fsdb_name, i);
2325 rc = mgs_write_log_osp_to_mdt(env, mgs, fsdb, mti,
2327 name_destroy(&logname);
2333 record_end_log(env, &llh);
2335 name_destroy(&cliname);
2339 /* Add the ost info to the client/mdt lov */
2340 static int mgs_write_log_osc_to_lov(const struct lu_env *env,
2341 struct mgs_device *mgs, struct fs_db *fsdb,
2342 struct mgs_target_info *mti,
2343 char *logname, char *suffix, char *lovname,
2344 enum lustre_sec_part sec_part, int flags)
2346 struct llog_handle *llh = NULL;
2347 char *nodeuuid = NULL;
2348 char *oscname = NULL;
2349 char *oscuuid = NULL;
2350 char *lovuuid = NULL;
2351 char *svname = NULL;
2356 CDEBUG(D_INFO, "adding osc for %s to log %s\n",
2357 mti->mti_svname, logname);
2359 if (mgs_log_is_empty(env, mgs, logname)) {
2360 CERROR("log is empty! Logical error\n");
2364 rc = name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
2367 rc = name_create(&svname, mti->mti_svname, "-osc");
2371 /* for the system upgraded from old 1.8, keep using the old osc naming
2372 * style for mdt, see name_create_mdt_osc(). LU-1257 */
2373 if (test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2374 rc = name_create(&oscname, svname, "");
2376 rc = name_create(&oscname, svname, suffix);
2380 rc = name_create(&oscuuid, oscname, "_UUID");
2383 rc = name_create(&lovuuid, lovname, "_UUID");
2389 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
2391 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
2392 #04 L attach 0:OSC_uml1_ost1_MNT_client 1:osc 2:89070_lov1_a41dff51a
2393 #05 L setup 0:OSC_uml1_ost1_MNT_client 1:ost1_UUID 2:uml1_UUID
2395 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
2396 #07 L add_conn 0:OSC_uml1_ost1_MNT_client 1:uml2_UUID
2397 #08 L lov_modify_tgts add 0:lov1 1:ost1_UUID 2(index):0 3(gen):1
2400 rc = record_start_log(env, mgs, &llh, logname);
2404 /* FIXME these should be a single journal transaction */
2405 rc = record_marker(env, llh, fsdb, CM_START | flags, mti->mti_svname,
2410 /* NB: don't change record order, because upon MDT steal OSC config
2411 * from client, it treats all nids before LCFG_SETUP as target nids
2412 * (multiple interfaces), while nids after as failover node nids.
2413 * See mgs_steal_client_llog_handler() LCFG_ADD_UUID.
2415 for (i = 0; i < mti->mti_nid_count; i++) {
2416 CDEBUG(D_MGS, "add nid %s\n", libcfs_nid2str(mti->mti_nids[i]));
2417 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
2421 rc = record_attach(env, llh, oscname, LUSTRE_OSC_NAME, lovuuid);
2424 rc = record_setup(env, llh, oscname, mti->mti_uuid, nodeuuid, 0, 0);
2427 rc = mgs_write_log_failnids(env, mti, llh, oscname);
2431 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
2433 rc = record_lov_add(env, llh, lovname, mti->mti_uuid, index, "1");
2436 rc = record_marker(env, llh, fsdb, CM_END | flags, mti->mti_svname,
2441 record_end_log(env, &llh);
2443 name_destroy(&lovuuid);
2444 name_destroy(&oscuuid);
2445 name_destroy(&oscname);
2446 name_destroy(&svname);
2447 name_destroy(&nodeuuid);
2451 static int mgs_write_log_ost(const struct lu_env *env,
2452 struct mgs_device *mgs, struct fs_db *fsdb,
2453 struct mgs_target_info *mti)
2455 struct llog_handle *llh = NULL;
2456 char *logname, *lovname;
2457 char *ptr = mti->mti_params;
2458 int rc, flags = 0, failout = 0, i;
2461 CDEBUG(D_MGS, "writing new ost %s\n", mti->mti_svname);
2463 /* The ost startup log */
2465 /* If the ost log already exists, that means that someone reformatted
2466 the ost and it called target_add again. */
2467 if (!mgs_log_is_empty(env, mgs, mti->mti_svname)) {
2468 LCONSOLE_ERROR_MSG(0x141, "The config log for %s already "
2469 "exists, yet the server claims it never "
2470 "registered. It may have been reformatted, "
2471 "or the index changed. writeconf the MDT to "
2472 "regenerate all logs.\n", mti->mti_svname);
2477 attach obdfilter ost1 ost1_UUID
2478 setup /dev/loop2 ldiskfs f|n errors=remount-ro,user_xattr
2480 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
2481 failout = (strncmp(ptr, "failout", 7) == 0);
2482 rc = record_start_log(env, mgs, &llh, mti->mti_svname);
2485 /* FIXME these should be a single journal transaction */
2486 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,"add ost");
2489 if (*mti->mti_uuid == '\0')
2490 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
2491 "%s_UUID", mti->mti_svname);
2492 rc = record_attach(env, llh, mti->mti_svname,
2493 "obdfilter"/*LUSTRE_OST_NAME*/, mti->mti_uuid);
2496 rc = record_setup(env, llh, mti->mti_svname,
2497 "dev"/*ignored*/, "type"/*ignored*/,
2498 failout ? "n" : "f", 0/*options*/);
2501 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname, "add ost");
2505 record_end_log(env, &llh);
2508 /* We also have to update the other logs where this osc is part of
2511 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
2512 /* If we're upgrading, the old mdt log already has our
2513 entry. Let's do a fake one for fun. */
2514 /* Note that we can't add any new failnids, since we don't
2515 know the old osc names. */
2516 flags = CM_SKIP | CM_UPGRADE146;
2518 } else if ((mti->mti_flags & LDD_F_UPDATE) != LDD_F_UPDATE) {
2519 /* If the update flag isn't set, don't update client/mdt
2522 LCONSOLE_WARN("Client log for %s was not updated; writeconf "
2523 "the MDT first to regenerate it.\n",
2527 /* Add ost to all MDT lov defs */
2528 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
2529 if (test_bit(i, fsdb->fsdb_mdt_index_map)) {
2532 rc = name_create_mdt_and_lov(&logname, &lovname, fsdb,
2536 sprintf(mdt_index, "-MDT%04x", i);
2537 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, mti,
2539 lovname, LUSTRE_SP_MDT,
2541 name_destroy(&logname);
2542 name_destroy(&lovname);
2548 /* Append ost info to the client log */
2549 rc = name_create(&logname, mti->mti_fsname, "-client");
2552 if (mgs_log_is_empty(env, mgs, logname)) {
2553 /* Start client log */
2554 rc = mgs_write_log_lov(env, mgs, fsdb, mti, logname,
2558 rc = mgs_write_log_lmv(env, mgs, fsdb, mti, logname,
2563 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, mti, logname, "",
2564 fsdb->fsdb_clilov, LUSTRE_SP_CLI, 0);
2566 name_destroy(&logname);
2570 static __inline__ int mgs_param_empty(char *ptr)
2574 if ((tmp = strchr(ptr, '=')) && (*(++tmp) == '\0'))
2579 static int mgs_write_log_failnid_internal(const struct lu_env *env,
2580 struct mgs_device *mgs,
2582 struct mgs_target_info *mti,
2583 char *logname, char *cliname)
2586 struct llog_handle *llh = NULL;
2588 if (mgs_param_empty(mti->mti_params)) {
2589 /* Remove _all_ failnids */
2590 rc = mgs_modify(env, mgs, fsdb, mti, logname,
2591 mti->mti_svname, "add failnid", CM_SKIP);
2592 return rc < 0 ? rc : 0;
2595 /* Otherwise failover nids are additive */
2596 rc = record_start_log(env, mgs, &llh, logname);
2599 /* FIXME this should be a single journal transaction */
2600 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
2604 rc = mgs_write_log_failnids(env, mti, llh, cliname);
2607 rc = record_marker(env, llh, fsdb, CM_END,
2608 mti->mti_svname, "add failnid");
2610 record_end_log(env, &llh);
2615 /* Add additional failnids to an existing log.
2616 The mdc/osc must have been added to logs first */
2617 /* tcp nids must be in dotted-quad ascii -
2618 we can't resolve hostnames from the kernel. */
2619 static int mgs_write_log_add_failnid(const struct lu_env *env,
2620 struct mgs_device *mgs,
2622 struct mgs_target_info *mti)
2624 char *logname, *cliname;
2628 /* FIXME we currently can't erase the failnids
2629 * given when a target first registers, since they aren't part of
2630 * an "add uuid" stanza */
2632 /* Verify that we know about this target */
2633 if (mgs_log_is_empty(env, mgs, mti->mti_svname)) {
2634 LCONSOLE_ERROR_MSG(0x142, "The target %s has not registered "
2635 "yet. It must be started before failnids "
2636 "can be added.\n", mti->mti_svname);
2640 /* Create mdc/osc client name (e.g. lustre-OST0001-osc) */
2641 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
2642 rc = name_create(&cliname, mti->mti_svname, "-mdc");
2643 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2644 rc = name_create(&cliname, mti->mti_svname, "-osc");
2650 /* Add failover nids to the client log */
2651 rc = name_create(&logname, mti->mti_fsname, "-client");
2653 name_destroy(&cliname);
2656 rc = mgs_write_log_failnid_internal(env, mgs, fsdb,mti,logname,cliname);
2657 name_destroy(&logname);
2658 name_destroy(&cliname);
2662 if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2663 /* Add OST failover nids to the MDT logs as well */
2666 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2667 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
2669 rc = name_create_mdt(&logname, mti->mti_fsname, i);
2672 rc = name_create_mdt_osc(&cliname, mti->mti_svname,
2675 name_destroy(&logname);
2678 rc = mgs_write_log_failnid_internal(env, mgs, fsdb,
2681 name_destroy(&cliname);
2682 name_destroy(&logname);
2691 static int mgs_wlp_lcfg(const struct lu_env *env,
2692 struct mgs_device *mgs, struct fs_db *fsdb,
2693 struct mgs_target_info *mti,
2694 char *logname, struct lustre_cfg_bufs *bufs,
2695 char *tgtname, char *ptr)
2697 char comment[MTI_NAME_MAXLEN];
2699 struct lustre_cfg *lcfg;
2702 /* Erase any old settings of this same parameter */
2703 memcpy(comment, ptr, MTI_NAME_MAXLEN);
2704 comment[MTI_NAME_MAXLEN - 1] = 0;
2705 /* But don't try to match the value. */
2706 if ((tmp = strchr(comment, '=')))
2708 /* FIXME we should skip settings that are the same as old values */
2709 rc = mgs_modify(env, mgs, fsdb, mti, logname, tgtname, comment,CM_SKIP);
2712 del = mgs_param_empty(ptr);
2714 LCONSOLE_INFO("%sing parameter %s.%s in log %s\n", del ? "Disabl" : rc ?
2715 "Sett" : "Modify", tgtname, comment, logname);
2719 lustre_cfg_bufs_reset(bufs, tgtname);
2720 lustre_cfg_bufs_set_string(bufs, 1, ptr);
2721 if (mti->mti_flags & LDD_F_PARAM2)
2722 lustre_cfg_bufs_set_string(bufs, 2, LCTL_UPCALL);
2724 lcfg = lustre_cfg_new((mti->mti_flags & LDD_F_PARAM2) ?
2725 LCFG_SET_PARAM : LCFG_PARAM, bufs);
2729 rc = mgs_write_log_direct(env, mgs, fsdb, logname,lcfg,tgtname,comment);
2730 lustre_cfg_free(lcfg);
2734 static int mgs_write_log_param2(const struct lu_env *env,
2735 struct mgs_device *mgs,
2737 struct mgs_target_info *mti, char *ptr)
2739 struct lustre_cfg_bufs bufs;
2743 CDEBUG(D_MGS, "next param '%s'\n", ptr);
2744 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, PARAMS_FILENAME, &bufs,
2745 mti->mti_svname, ptr);
2750 /* write global variable settings into log */
2751 static int mgs_write_log_sys(const struct lu_env *env,
2752 struct mgs_device *mgs, struct fs_db *fsdb,
2753 struct mgs_target_info *mti, char *sys, char *ptr)
2755 struct mgs_thread_info *mgi = mgs_env_info(env);
2756 struct lustre_cfg *lcfg;
2758 int rc, cmd, convert = 1;
2760 if (class_match_param(ptr, PARAM_TIMEOUT, &tmp) == 0) {
2761 cmd = LCFG_SET_TIMEOUT;
2762 } else if (class_match_param(ptr, PARAM_LDLM_TIMEOUT, &tmp) == 0) {
2763 cmd = LCFG_SET_LDLM_TIMEOUT;
2764 /* Check for known params here so we can return error to lctl */
2765 } else if ((class_match_param(ptr, PARAM_AT_MIN, &tmp) == 0) ||
2766 (class_match_param(ptr, PARAM_AT_MAX, &tmp) == 0) ||
2767 (class_match_param(ptr, PARAM_AT_EXTRA, &tmp) == 0) ||
2768 (class_match_param(ptr, PARAM_AT_EARLY_MARGIN, &tmp) == 0) ||
2769 (class_match_param(ptr, PARAM_AT_HISTORY, &tmp) == 0)) {
2771 } else if (class_match_param(ptr, PARAM_JOBID_VAR, &tmp) == 0) {
2772 convert = 0; /* Don't convert string value to integer */
2778 if (mgs_param_empty(ptr))
2779 CDEBUG(D_MGS, "global '%s' removed\n", sys);
2781 CDEBUG(D_MGS, "global '%s' val=%s\n", sys, tmp);
2783 lustre_cfg_bufs_reset(&mgi->mgi_bufs, NULL);
2784 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, sys);
2785 if (!convert && *tmp != '\0')
2786 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 2, tmp);
2787 lcfg = lustre_cfg_new(cmd, &mgi->mgi_bufs);
2788 lcfg->lcfg_num = convert ? simple_strtoul(tmp, NULL, 0) : 0;
2789 /* truncate the comment to the parameter name */
2793 /* modify all servers and clients */
2794 rc = mgs_write_log_direct_all(env, mgs, fsdb, mti,
2795 *tmp == '\0' ? NULL : lcfg,
2796 mti->mti_fsname, sys, 0);
2797 if (rc == 0 && *tmp != '\0') {
2799 case LCFG_SET_TIMEOUT:
2800 if (!obd_timeout_set || lcfg->lcfg_num > obd_timeout)
2801 class_process_config(lcfg);
2803 case LCFG_SET_LDLM_TIMEOUT:
2804 if (!ldlm_timeout_set || lcfg->lcfg_num > ldlm_timeout)
2805 class_process_config(lcfg);
2812 lustre_cfg_free(lcfg);
2816 /* write quota settings into log */
2817 static int mgs_write_log_quota(const struct lu_env *env, struct mgs_device *mgs,
2818 struct fs_db *fsdb, struct mgs_target_info *mti,
2819 char *quota, char *ptr)
2821 struct mgs_thread_info *mgi = mgs_env_info(env);
2822 struct lustre_cfg *lcfg;
2825 int rc, cmd = LCFG_PARAM;
2827 /* support only 'meta' and 'data' pools so far */
2828 if (class_match_param(ptr, QUOTA_METAPOOL_NAME, &tmp) != 0 &&
2829 class_match_param(ptr, QUOTA_DATAPOOL_NAME, &tmp) != 0) {
2830 CERROR("parameter quota.%s isn't supported (only quota.mdt "
2831 "& quota.ost are)\n", ptr);
2836 CDEBUG(D_MGS, "global '%s' removed\n", quota);
2838 CDEBUG(D_MGS, "global '%s'\n", quota);
2840 if (strchr(tmp, 'u') == NULL && strchr(tmp, 'g') == NULL &&
2841 strcmp(tmp, "none") != 0) {
2842 CERROR("enable option(%s) isn't supported\n", tmp);
2847 lustre_cfg_bufs_reset(&mgi->mgi_bufs, mti->mti_fsname);
2848 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, quota);
2849 lcfg = lustre_cfg_new(cmd, &mgi->mgi_bufs);
2850 /* truncate the comment to the parameter name */
2855 /* XXX we duplicated quota enable information in all server
2856 * config logs, it should be moved to a separate config
2857 * log once we cleanup the config log for global param. */
2858 /* modify all servers */
2859 rc = mgs_write_log_direct_all(env, mgs, fsdb, mti,
2860 *tmp == '\0' ? NULL : lcfg,
2861 mti->mti_fsname, quota, 1);
2863 lustre_cfg_free(lcfg);
2864 return rc < 0 ? rc : 0;
2867 static int mgs_srpc_set_param_disk(const struct lu_env *env,
2868 struct mgs_device *mgs,
2870 struct mgs_target_info *mti,
2873 struct mgs_thread_info *mgi = mgs_env_info(env);
2874 struct llog_handle *llh = NULL;
2876 char *comment, *ptr;
2877 struct lustre_cfg *lcfg;
2882 ptr = strchr(param, '=');
2886 OBD_ALLOC(comment, len + 1);
2887 if (comment == NULL)
2889 strncpy(comment, param, len);
2890 comment[len] = '\0';
2893 lustre_cfg_bufs_reset(&mgi->mgi_bufs, mti->mti_svname);
2894 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, param);
2895 lcfg = lustre_cfg_new(LCFG_SPTLRPC_CONF, &mgi->mgi_bufs);
2897 GOTO(out_comment, rc = -ENOMEM);
2899 /* construct log name */
2900 rc = name_create(&logname, mti->mti_fsname, "-sptlrpc");
2904 if (mgs_log_is_empty(env, mgs, logname)) {
2905 rc = record_start_log(env, mgs, &llh, logname);
2908 record_end_log(env, &llh);
2911 /* obsolete old one */
2912 rc = mgs_modify(env, mgs, fsdb, mti, logname, mti->mti_svname,
2916 /* write the new one */
2917 rc = mgs_write_log_direct(env, mgs, fsdb, logname, lcfg,
2918 mti->mti_svname, comment);
2920 CERROR("err %d writing log %s\n", rc, logname);
2922 name_destroy(&logname);
2924 lustre_cfg_free(lcfg);
2926 OBD_FREE(comment, len + 1);
2930 static int mgs_srpc_set_param_udesc_mem(struct fs_db *fsdb,
2935 /* disable the adjustable udesc parameter for now, i.e. use default
2936 * setting that client always ship udesc to MDT if possible. to enable
2937 * it simply remove the following line */
2940 ptr = strchr(param, '=');
2945 if (strcmp(param, PARAM_SRPC_UDESC))
2948 if (strcmp(ptr, "yes") == 0) {
2949 set_bit(FSDB_UDESC, &fsdb->fsdb_flags);
2950 CWARN("Enable user descriptor shipping from client to MDT\n");
2951 } else if (strcmp(ptr, "no") == 0) {
2952 clear_bit(FSDB_UDESC, &fsdb->fsdb_flags);
2953 CWARN("Disable user descriptor shipping from client to MDT\n");
2961 CERROR("Invalid param: %s\n", param);
2965 static int mgs_srpc_set_param_mem(struct fs_db *fsdb,
2969 struct sptlrpc_rule rule;
2970 struct sptlrpc_rule_set *rset;
2974 if (strncmp(param, PARAM_SRPC, sizeof(PARAM_SRPC) - 1) != 0) {
2975 CERROR("Invalid sptlrpc parameter: %s\n", param);
2979 if (strncmp(param, PARAM_SRPC_UDESC,
2980 sizeof(PARAM_SRPC_UDESC) - 1) == 0) {
2981 RETURN(mgs_srpc_set_param_udesc_mem(fsdb, param));
2984 if (strncmp(param, PARAM_SRPC_FLVR, sizeof(PARAM_SRPC_FLVR) - 1) != 0) {
2985 CERROR("Invalid sptlrpc flavor parameter: %s\n", param);
2989 param += sizeof(PARAM_SRPC_FLVR) - 1;
2991 rc = sptlrpc_parse_rule(param, &rule);
2995 /* mgs rules implies must be mgc->mgs */
2996 if (test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
2997 if ((rule.sr_from != LUSTRE_SP_MGC &&
2998 rule.sr_from != LUSTRE_SP_ANY) ||
2999 (rule.sr_to != LUSTRE_SP_MGS &&
3000 rule.sr_to != LUSTRE_SP_ANY))
3004 /* preapre room for this coming rule. svcname format should be:
3005 * - fsname: general rule
3006 * - fsname-tgtname: target-specific rule
3008 if (strchr(svname, '-')) {
3009 struct mgs_tgt_srpc_conf *tgtconf;
3012 for (tgtconf = fsdb->fsdb_srpc_tgt; tgtconf != NULL;
3013 tgtconf = tgtconf->mtsc_next) {
3014 if (!strcmp(tgtconf->mtsc_tgt, svname)) {
3023 OBD_ALLOC_PTR(tgtconf);
3024 if (tgtconf == NULL)
3027 name_len = strlen(svname);
3029 OBD_ALLOC(tgtconf->mtsc_tgt, name_len + 1);
3030 if (tgtconf->mtsc_tgt == NULL) {
3031 OBD_FREE_PTR(tgtconf);
3034 memcpy(tgtconf->mtsc_tgt, svname, name_len);
3036 tgtconf->mtsc_next = fsdb->fsdb_srpc_tgt;
3037 fsdb->fsdb_srpc_tgt = tgtconf;
3040 rset = &tgtconf->mtsc_rset;
3042 rset = &fsdb->fsdb_srpc_gen;
3045 rc = sptlrpc_rule_set_merge(rset, &rule);
3050 static int mgs_srpc_set_param(const struct lu_env *env,
3051 struct mgs_device *mgs,
3053 struct mgs_target_info *mti,
3063 /* keep a copy of original param, which could be destroied
3065 copy_size = strlen(param) + 1;
3066 OBD_ALLOC(copy, copy_size);
3069 memcpy(copy, param, copy_size);
3071 rc = mgs_srpc_set_param_mem(fsdb, mti->mti_svname, param);
3075 /* previous steps guaranteed the syntax is correct */
3076 rc = mgs_srpc_set_param_disk(env, mgs, fsdb, mti, copy);
3080 if (test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
3082 * for mgs rules, make them effective immediately.
3084 LASSERT(fsdb->fsdb_srpc_tgt == NULL);
3085 sptlrpc_target_update_exp_flavor(mgs->mgs_obd,
3086 &fsdb->fsdb_srpc_gen);
3090 OBD_FREE(copy, copy_size);
3094 struct mgs_srpc_read_data {
3095 struct fs_db *msrd_fsdb;
3099 static int mgs_srpc_read_handler(const struct lu_env *env,
3100 struct llog_handle *llh,
3101 struct llog_rec_hdr *rec, void *data)
3103 struct mgs_srpc_read_data *msrd = data;
3104 struct cfg_marker *marker;
3105 struct lustre_cfg *lcfg = REC_DATA(rec);
3106 char *svname, *param;
3110 if (rec->lrh_type != OBD_CFG_REC) {
3111 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
3115 cfg_len = rec->lrh_len - sizeof(struct llog_rec_hdr) -
3116 sizeof(struct llog_rec_tail);
3118 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
3120 CERROR("Insane cfg\n");
3124 if (lcfg->lcfg_command == LCFG_MARKER) {
3125 marker = lustre_cfg_buf(lcfg, 1);
3127 if (marker->cm_flags & CM_START &&
3128 marker->cm_flags & CM_SKIP)
3129 msrd->msrd_skip = 1;
3130 if (marker->cm_flags & CM_END)
3131 msrd->msrd_skip = 0;
3136 if (msrd->msrd_skip)
3139 if (lcfg->lcfg_command != LCFG_SPTLRPC_CONF) {
3140 CERROR("invalid command (%x)\n", lcfg->lcfg_command);
3144 svname = lustre_cfg_string(lcfg, 0);
3145 if (svname == NULL) {
3146 CERROR("svname is empty\n");
3150 param = lustre_cfg_string(lcfg, 1);
3151 if (param == NULL) {
3152 CERROR("param is empty\n");
3156 rc = mgs_srpc_set_param_mem(msrd->msrd_fsdb, svname, param);
3158 CERROR("read sptlrpc record error (%d): %s\n", rc, param);
3163 int mgs_get_fsdb_srpc_from_llog(const struct lu_env *env,
3164 struct mgs_device *mgs,
3167 struct llog_handle *llh = NULL;
3168 struct llog_ctxt *ctxt;
3170 struct mgs_srpc_read_data msrd;
3174 /* construct log name */
3175 rc = name_create(&logname, fsdb->fsdb_name, "-sptlrpc");
3179 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
3180 LASSERT(ctxt != NULL);
3182 if (mgs_log_is_empty(env, mgs, logname))
3185 rc = llog_open(env, ctxt, &llh, NULL, logname,
3193 rc = llog_init_handle(env, llh, LLOG_F_IS_PLAIN, NULL);
3195 GOTO(out_close, rc);
3197 if (llog_get_size(llh) <= 1)
3198 GOTO(out_close, rc = 0);
3200 msrd.msrd_fsdb = fsdb;
3203 rc = llog_process(env, llh, mgs_srpc_read_handler, (void *)&msrd,
3207 llog_close(env, llh);
3209 llog_ctxt_put(ctxt);
3210 name_destroy(&logname);
3213 CERROR("failed to read sptlrpc config database: %d\n", rc);
3217 /* Permanent settings of all parameters by writing into the appropriate
3218 * configuration logs.
3219 * A parameter with null value ("<param>='\0'") means to erase it out of
3222 static int mgs_write_log_param(const struct lu_env *env,
3223 struct mgs_device *mgs, struct fs_db *fsdb,
3224 struct mgs_target_info *mti, char *ptr)
3226 struct mgs_thread_info *mgi = mgs_env_info(env);
3229 int rc = 0, rc2 = 0;
3232 /* For various parameter settings, we have to figure out which logs
3233 care about them (e.g. both mdt and client for lov settings) */
3234 CDEBUG(D_MGS, "next param '%s'\n", ptr);
3236 /* The params are stored in MOUNT_DATA_FILE and modified via
3237 tunefs.lustre, or set using lctl conf_param */
3239 /* Processed in lustre_start_mgc */
3240 if (class_match_param(ptr, PARAM_MGSNODE, NULL) == 0)
3243 /* Processed in ost/mdt */
3244 if (class_match_param(ptr, PARAM_NETWORK, NULL) == 0)
3247 /* Processed in mgs_write_log_ost */
3248 if (class_match_param(ptr, PARAM_FAILMODE, NULL) == 0) {
3249 if (mti->mti_flags & LDD_F_PARAM) {
3250 LCONSOLE_ERROR_MSG(0x169, "%s can only be "
3251 "changed with tunefs.lustre"
3252 "and --writeconf\n", ptr);
3258 if (class_match_param(ptr, PARAM_SRPC, NULL) == 0) {
3259 rc = mgs_srpc_set_param(env, mgs, fsdb, mti, ptr);
3263 if (class_match_param(ptr, PARAM_FAILNODE, NULL) == 0) {
3264 /* Add a failover nidlist */
3266 /* We already processed failovers params for new
3267 targets in mgs_write_log_target */
3268 if (mti->mti_flags & LDD_F_PARAM) {
3269 CDEBUG(D_MGS, "Adding failnode\n");
3270 rc = mgs_write_log_add_failnid(env, mgs, fsdb, mti);
3275 if (class_match_param(ptr, PARAM_SYS, &tmp) == 0) {
3276 rc = mgs_write_log_sys(env, mgs, fsdb, mti, ptr, tmp);
3280 if (class_match_param(ptr, PARAM_QUOTA, &tmp) == 0) {
3281 rc = mgs_write_log_quota(env, mgs, fsdb, mti, ptr, tmp);
3285 if (class_match_param(ptr, PARAM_OSC""PARAM_ACTIVE, &tmp) == 0) {
3286 /* active=0 means off, anything else means on */
3287 int flag = (*tmp == '0') ? CM_EXCLUDE : 0;
3290 if (!(mti->mti_flags & LDD_F_SV_TYPE_OST)) {
3291 LCONSOLE_ERROR_MSG(0x144, "%s: Only OSCs can "
3292 "be (de)activated.\n",
3294 GOTO(end, rc = -EINVAL);
3296 LCONSOLE_WARN("Permanently %sactivating %s\n",
3297 flag ? "de": "re", mti->mti_svname);
3299 rc = name_create(&logname, mti->mti_fsname, "-client");
3302 rc = mgs_modify(env, mgs, fsdb, mti, logname,
3303 mti->mti_svname, "add osc", flag);
3304 name_destroy(&logname);
3308 /* Add to all MDT logs for CMD */
3309 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3310 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
3312 rc = name_create_mdt(&logname, mti->mti_fsname, i);
3315 rc = mgs_modify(env, mgs, fsdb, mti, logname,
3316 mti->mti_svname, "add osc", flag);
3317 name_destroy(&logname);
3323 LCONSOLE_ERROR_MSG(0x145, "Couldn't find %s in"
3324 "log (%d). No permanent "
3325 "changes were made to the "
3327 mti->mti_svname, rc);
3328 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags))
3329 LCONSOLE_ERROR_MSG(0x146, "This may be"
3334 "update the logs.\n");
3337 /* Fall through to osc proc for deactivating live OSC
3338 on running MDT / clients. */
3340 /* Below here, let obd's XXX_process_config methods handle it */
3342 /* All lov. in proc */
3343 if (class_match_param(ptr, PARAM_LOV, NULL) == 0) {
3346 CDEBUG(D_MGS, "lov param %s\n", ptr);
3347 if (!(mti->mti_flags & LDD_F_SV_TYPE_MDT)) {
3348 LCONSOLE_ERROR_MSG(0x147, "LOV params must be "
3349 "set on the MDT, not %s. "
3356 if (mgs_log_is_empty(env, mgs, mti->mti_svname))
3357 GOTO(end, rc = -ENODEV);
3359 rc = name_create_mdt_and_lov(&logname, &mdtlovname, fsdb,
3360 mti->mti_stripe_index);
3363 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, mti->mti_svname,
3364 &mgi->mgi_bufs, mdtlovname, ptr);
3365 name_destroy(&logname);
3366 name_destroy(&mdtlovname);
3371 rc = name_create(&logname, mti->mti_fsname, "-client");
3374 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname, &mgi->mgi_bufs,
3375 fsdb->fsdb_clilov, ptr);
3376 name_destroy(&logname);
3380 /* All osc., mdc., llite. params in proc */
3381 if ((class_match_param(ptr, PARAM_OSC, NULL) == 0) ||
3382 (class_match_param(ptr, PARAM_MDC, NULL) == 0) ||
3383 (class_match_param(ptr, PARAM_LLITE, NULL) == 0)) {
3386 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
3387 LCONSOLE_ERROR_MSG(0x148, "Upgraded client logs for %s"
3388 " cannot be modified. Consider"
3389 " updating the configuration with"
3392 GOTO(end, rc = -EINVAL);
3394 if (memcmp(ptr, PARAM_LLITE, strlen(PARAM_LLITE)) == 0) {
3395 rc = name_create(&cname, mti->mti_fsname, "-client");
3396 /* Add the client type to match the obdname in
3397 class_config_llog_handler */
3398 } else if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
3399 rc = name_create(&cname, mti->mti_svname, "-mdc");
3400 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
3401 rc = name_create(&cname, mti->mti_svname, "-osc");
3403 GOTO(end, rc = -EINVAL);
3408 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
3411 rc = name_create(&logname, mti->mti_fsname, "-client");
3413 name_destroy(&cname);
3416 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname, &mgi->mgi_bufs,
3419 /* osc params affect the MDT as well */
3420 if (!rc && (mti->mti_flags & LDD_F_SV_TYPE_OST)) {
3423 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
3424 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
3426 name_destroy(&cname);
3427 rc = name_create_mdt_osc(&cname, mti->mti_svname,
3429 name_destroy(&logname);
3432 rc = name_create_mdt(&logname,
3433 mti->mti_fsname, i);
3436 if (!mgs_log_is_empty(env, mgs, logname)) {
3437 rc = mgs_wlp_lcfg(env, mgs, fsdb,
3446 name_destroy(&logname);
3447 name_destroy(&cname);
3451 /* All mdt. params in proc */
3452 if (class_match_param(ptr, PARAM_MDT, NULL) == 0) {
3456 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
3457 if (strncmp(mti->mti_svname, mti->mti_fsname,
3458 MTI_NAME_MAXLEN) == 0)
3459 /* device is unspecified completely? */
3460 rc = LDD_F_SV_TYPE_MDT | LDD_F_SV_ALL;
3462 rc = server_name2index(mti->mti_svname, &idx, NULL);
3465 if ((rc & LDD_F_SV_TYPE_MDT) == 0)
3467 if (rc & LDD_F_SV_ALL) {
3468 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3470 fsdb->fsdb_mdt_index_map))
3472 rc = name_create_mdt(&logname,
3473 mti->mti_fsname, i);
3476 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti,
3477 logname, &mgi->mgi_bufs,
3479 name_destroy(&logname);
3484 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti,
3485 mti->mti_svname, &mgi->mgi_bufs,
3486 mti->mti_svname, ptr);
3493 /* All mdd., ost. and osd. params in proc */
3494 if ((class_match_param(ptr, PARAM_MDD, NULL) == 0) ||
3495 (class_match_param(ptr, PARAM_OST, NULL) == 0) ||
3496 (class_match_param(ptr, PARAM_OSD, NULL) == 0)) {
3497 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
3498 if (mgs_log_is_empty(env, mgs, mti->mti_svname))
3499 GOTO(end, rc = -ENODEV);
3501 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, mti->mti_svname,
3502 &mgi->mgi_bufs, mti->mti_svname, ptr);
3506 LCONSOLE_WARN("Ignoring unrecognized param '%s'\n", ptr);
3511 CERROR("err %d on param '%s'\n", rc, ptr);
3516 /* Not implementing automatic failover nid addition at this time. */
3517 int mgs_check_failnid(const struct lu_env *env, struct mgs_device *mgs,
3518 struct mgs_target_info *mti)
3525 rc = mgs_find_or_make_fsdb(obd, fsname, &fsdb);
3529 if (mgs_log_is_empty(obd, mti->mti_svname))
3530 /* should never happen */
3533 CDEBUG(D_MGS, "Checking for new failnids for %s\n", mti->mti_svname);
3535 /* FIXME We can just check mti->params to see if we're already in
3536 the failover list. Modify mti->params for rewriting back at
3537 server_register_target(). */
3539 mutex_lock(&fsdb->fsdb_mutex);
3540 rc = mgs_write_log_add_failnid(obd, fsdb, mti);
3541 mutex_unlock(&fsdb->fsdb_mutex);
3548 int mgs_write_log_target(const struct lu_env *env,
3549 struct mgs_device *mgs,
3550 struct mgs_target_info *mti,
3557 /* set/check the new target index */
3558 rc = mgs_set_index(env, mgs, mti);
3560 CERROR("Can't get index (%d)\n", rc);
3564 if (rc == EALREADY) {
3565 LCONSOLE_WARN("Found index %d for %s, updating log\n",
3566 mti->mti_stripe_index, mti->mti_svname);
3567 /* We would like to mark old log sections as invalid
3568 and add new log sections in the client and mdt logs.
3569 But if we add new sections, then live clients will
3570 get repeat setup instructions for already running
3571 osc's. So don't update the client/mdt logs. */
3572 mti->mti_flags &= ~LDD_F_UPDATE;
3576 mutex_lock(&fsdb->fsdb_mutex);
3578 if (mti->mti_flags &
3579 (LDD_F_VIRGIN | LDD_F_UPGRADE14 | LDD_F_WRITECONF)) {
3580 /* Generate a log from scratch */
3581 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
3582 rc = mgs_write_log_mdt(env, mgs, fsdb, mti);
3583 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
3584 rc = mgs_write_log_ost(env, mgs, fsdb, mti);
3586 CERROR("Unknown target type %#x, can't create log for "
3587 "%s\n", mti->mti_flags, mti->mti_svname);
3590 CERROR("Can't write logs for %s (%d)\n",
3591 mti->mti_svname, rc);
3595 /* Just update the params from tunefs in mgs_write_log_params */
3596 CDEBUG(D_MGS, "Update params for %s\n", mti->mti_svname);
3597 mti->mti_flags |= LDD_F_PARAM;
3600 /* allocate temporary buffer, where class_get_next_param will
3601 make copy of a current parameter */
3602 OBD_ALLOC(buf, strlen(mti->mti_params) + 1);
3604 GOTO(out_up, rc = -ENOMEM);
3605 params = mti->mti_params;
3606 while (params != NULL) {
3607 rc = class_get_next_param(¶ms, buf);
3610 /* there is no next parameter, that is
3615 CDEBUG(D_MGS, "remaining string: '%s', param: '%s'\n",
3617 rc = mgs_write_log_param(env, mgs, fsdb, mti, buf);
3622 OBD_FREE(buf, strlen(mti->mti_params) + 1);
3625 mutex_unlock(&fsdb->fsdb_mutex);
3629 int mgs_erase_log(const struct lu_env *env, struct mgs_device *mgs, char *name)
3631 struct llog_ctxt *ctxt;
3634 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
3636 CERROR("%s: MGS config context doesn't exist\n",
3637 mgs->mgs_obd->obd_name);
3640 rc = llog_erase(env, ctxt, NULL, name);
3641 /* llog may not exist */
3644 llog_ctxt_put(ctxt);
3648 CERROR("%s: failed to clear log %s: %d\n",
3649 mgs->mgs_obd->obd_name, name, rc);
3654 /* erase all logs for the given fs */
3655 int mgs_erase_logs(const struct lu_env *env, struct mgs_device *mgs, char *fsname)
3659 struct mgs_direntry *dirent, *n;
3660 int rc, len = strlen(fsname);
3664 /* Find all the logs in the CONFIGS directory */
3665 rc = class_dentry_readdir(env, mgs, &list);
3669 mutex_lock(&mgs->mgs_mutex);
3671 /* Delete the fs db */
3672 fsdb = mgs_find_fsdb(mgs, fsname);
3674 mgs_free_fsdb(mgs, fsdb);
3676 mutex_unlock(&mgs->mgs_mutex);
3678 cfs_list_for_each_entry_safe(dirent, n, &list, list) {
3679 cfs_list_del(&dirent->list);
3680 suffix = strrchr(dirent->name, '-');
3681 if (suffix != NULL) {
3682 if ((len == suffix - dirent->name) &&
3683 (strncmp(fsname, dirent->name, len) == 0)) {
3684 CDEBUG(D_MGS, "Removing log %s\n",
3686 mgs_erase_log(env, mgs, dirent->name);
3689 mgs_direntry_free(dirent);
3695 /* list all logs for the given fs */
3696 int mgs_list_logs(const struct lu_env *env, struct mgs_device *mgs,
3697 struct obd_ioctl_data *data)
3700 struct mgs_direntry *dirent, *n;
3706 /* Find all the logs in the CONFIGS directory */
3707 rc = class_dentry_readdir(env, mgs, &list);
3709 CERROR("%s: can't read %s dir = %d\n",
3710 mgs->mgs_obd->obd_name, MOUNT_CONFIGS_DIR, rc);
3714 out = data->ioc_bulk;
3715 remains = data->ioc_inllen1;
3716 cfs_list_for_each_entry_safe(dirent, n, &list, list) {
3717 cfs_list_del(&dirent->list);
3718 suffix = strrchr(dirent->name, '-');
3719 if (suffix != NULL) {
3720 l = snprintf(out, remains, "config log: $%s\n",
3725 mgs_direntry_free(dirent);
3732 /* from llog_swab */
3733 static void print_lustre_cfg(struct lustre_cfg *lcfg)
3738 CDEBUG(D_MGS, "lustre_cfg: %p\n", lcfg);
3739 CDEBUG(D_MGS, "\tlcfg->lcfg_version: %#x\n", lcfg->lcfg_version);
3741 CDEBUG(D_MGS, "\tlcfg->lcfg_command: %#x\n", lcfg->lcfg_command);
3742 CDEBUG(D_MGS, "\tlcfg->lcfg_num: %#x\n", lcfg->lcfg_num);
3743 CDEBUG(D_MGS, "\tlcfg->lcfg_flags: %#x\n", lcfg->lcfg_flags);
3744 CDEBUG(D_MGS, "\tlcfg->lcfg_nid: %s\n", libcfs_nid2str(lcfg->lcfg_nid));
3746 CDEBUG(D_MGS, "\tlcfg->lcfg_bufcount: %d\n", lcfg->lcfg_bufcount);
3747 if (lcfg->lcfg_bufcount < LUSTRE_CFG_MAX_BUFCOUNT)
3748 for (i = 0; i < lcfg->lcfg_bufcount; i++) {
3749 CDEBUG(D_MGS, "\tlcfg->lcfg_buflens[%d]: %d %s\n",
3750 i, lcfg->lcfg_buflens[i],
3751 lustre_cfg_string(lcfg, i));
3756 /* Set a permanent (config log) param for a target or fs
3757 * \param lcfg buf0 may contain the device (testfs-MDT0000) name
3758 * buf1 contains the single parameter
3760 int mgs_setparam(const struct lu_env *env, struct mgs_device *mgs,
3761 struct lustre_cfg *lcfg, char *fsname)
3764 struct mgs_target_info *mti;
3765 char *devname, *param;
3772 print_lustre_cfg(lcfg);
3774 /* lustre, lustre-mdtlov, lustre-client, lustre-MDT0000 */
3775 devname = lustre_cfg_string(lcfg, 0);
3776 param = lustre_cfg_string(lcfg, 1);
3778 /* Assume device name embedded in param:
3779 lustre-OST0000.osc.max_dirty_mb=32 */
3780 ptr = strchr(param, '.');
3788 LCONSOLE_ERROR_MSG(0x14d, "No target specified: %s\n", param);
3792 rc = mgs_parse_devname(devname, fsname, NULL);
3793 if (rc == 0 && !mgs_parse_devname(devname, NULL, &index)) {
3794 /* param related to llite isn't allowed to set by OST or MDT */
3795 if (rc == 0 && strncmp(param, PARAM_LLITE,
3796 sizeof(PARAM_LLITE) - 1) == 0)
3799 /* assume devname is the fsname */
3800 memset(fsname, 0, MTI_NAME_MAXLEN);
3801 strncpy(fsname, devname, MTI_NAME_MAXLEN);
3802 fsname[MTI_NAME_MAXLEN - 1] = 0;
3804 CDEBUG(D_MGS, "setparam fs='%s' device='%s'\n", fsname, devname);
3806 rc = mgs_find_or_make_fsdb(env, mgs,
3807 lcfg->lcfg_command == LCFG_SET_PARAM ?
3808 PARAMS_FILENAME : fsname, &fsdb);
3812 if (lcfg->lcfg_command != LCFG_SET_PARAM &&
3813 !test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags) &&
3814 test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
3815 CERROR("No filesystem targets for %s. cfg_device from lctl "
3816 "is '%s'\n", fsname, devname);
3817 mgs_free_fsdb(mgs, fsdb);
3821 /* Create a fake mti to hold everything */
3824 GOTO(out, rc = -ENOMEM);
3825 if (strlcpy(mti->mti_fsname, fsname, sizeof(mti->mti_fsname))
3826 >= sizeof(mti->mti_fsname))
3827 GOTO(out, rc = -E2BIG);
3828 if (strlcpy(mti->mti_svname, devname, sizeof(mti->mti_svname))
3829 >= sizeof(mti->mti_svname))
3830 GOTO(out, rc = -E2BIG);
3831 if (strlcpy(mti->mti_params, param, sizeof(mti->mti_params))
3832 >= sizeof(mti->mti_params))
3833 GOTO(out, rc = -E2BIG);
3834 rc = server_name2index(mti->mti_svname, &mti->mti_stripe_index, &tmp);
3836 /* Not a valid server; may be only fsname */
3839 /* Strip -osc or -mdc suffix from svname */
3840 if (server_make_name(rc, mti->mti_stripe_index, mti->mti_fsname,
3842 GOTO(out, rc = -EINVAL);
3844 * Revoke lock so everyone updates. Should be alright if
3845 * someone was already reading while we were updating the logs,
3846 * so we don't really need to hold the lock while we're
3849 if (lcfg->lcfg_command == LCFG_SET_PARAM) {
3850 mti->mti_flags = rc | LDD_F_PARAM2;
3851 mutex_lock(&fsdb->fsdb_mutex);
3852 rc = mgs_write_log_param2(env, mgs, fsdb, mti, mti->mti_params);
3853 mutex_unlock(&fsdb->fsdb_mutex);
3854 mgs_revoke_lock(mgs, fsdb, CONFIG_T_PARAMS);
3856 mti->mti_flags = rc | LDD_F_PARAM;
3857 mutex_lock(&fsdb->fsdb_mutex);
3858 rc = mgs_write_log_param(env, mgs, fsdb, mti, mti->mti_params);
3859 mutex_unlock(&fsdb->fsdb_mutex);
3860 mgs_revoke_lock(mgs, fsdb, CONFIG_T_CONFIG);
3868 static int mgs_write_log_pool(const struct lu_env *env,
3869 struct mgs_device *mgs, char *logname,
3870 struct fs_db *fsdb, char *tgtname,
3871 enum lcfg_command_type cmd,
3872 char *fsname, char *poolname,
3873 char *ostname, char *comment)
3875 struct llog_handle *llh = NULL;
3878 rc = record_start_log(env, mgs, &llh, logname);
3881 rc = record_marker(env, llh, fsdb, CM_START, tgtname, comment);
3884 rc = record_base(env, llh, tgtname, 0, cmd,
3885 fsname, poolname, ostname, 0);
3888 rc = record_marker(env, llh, fsdb, CM_END, tgtname, comment);
3890 record_end_log(env, &llh);
3894 int mgs_nodemap_cmd(const struct lu_env *env, struct mgs_device *mgs,
3895 enum lcfg_command_type cmd, const char *nodemap_name,
3906 case LCFG_NODEMAP_ADD:
3907 rc = nodemap_add(nodemap_name);
3909 case LCFG_NODEMAP_DEL:
3910 rc = nodemap_del(nodemap_name);
3912 case LCFG_NODEMAP_ADD_RANGE:
3913 rc = nodemap_parse_range(param, nid);
3916 rc = nodemap_add_range(nodemap_name, nid);
3918 case LCFG_NODEMAP_DEL_RANGE:
3919 rc = nodemap_parse_range(param, nid);
3922 rc = nodemap_del_range(nodemap_name, nid);
3924 case LCFG_NODEMAP_ADMIN:
3925 bool_switch = simple_strtoul(param, NULL, 10);
3926 rc = nodemap_set_allow_root(nodemap_name, bool_switch);
3928 case LCFG_NODEMAP_TRUSTED:
3929 bool_switch = simple_strtoul(param, NULL, 10);
3930 rc = nodemap_set_trust_client_ids(nodemap_name, bool_switch);
3932 case LCFG_NODEMAP_SQUASH_UID:
3933 int_id = simple_strtoul(param, NULL, 10);
3934 rc = nodemap_set_squash_uid(nodemap_name, int_id);
3936 case LCFG_NODEMAP_SQUASH_GID:
3937 int_id = simple_strtoul(param, NULL, 10);
3938 rc = nodemap_set_squash_gid(nodemap_name, int_id);
3940 case LCFG_NODEMAP_ADD_UIDMAP:
3941 case LCFG_NODEMAP_ADD_GIDMAP:
3942 rc = nodemap_parse_idmap(param, idmap);
3945 if (cmd == LCFG_NODEMAP_ADD_UIDMAP)
3946 rc = nodemap_add_idmap(nodemap_name, NODEMAP_UID,
3949 rc = nodemap_add_idmap(nodemap_name, NODEMAP_GID,
3952 case LCFG_NODEMAP_DEL_UIDMAP:
3953 case LCFG_NODEMAP_DEL_GIDMAP:
3954 rc = nodemap_parse_idmap(param, idmap);
3957 if (cmd == LCFG_NODEMAP_DEL_UIDMAP)
3958 rc = nodemap_del_idmap(nodemap_name, NODEMAP_UID,
3961 rc = nodemap_del_idmap(nodemap_name, NODEMAP_GID,
3971 int mgs_pool_cmd(const struct lu_env *env, struct mgs_device *mgs,
3972 enum lcfg_command_type cmd, char *fsname,
3973 char *poolname, char *ostname)
3978 char *label = NULL, *canceled_label = NULL;
3980 struct mgs_target_info *mti = NULL;
3984 rc = mgs_find_or_make_fsdb(env, mgs, fsname, &fsdb);
3986 CERROR("Can't get db for %s\n", fsname);
3989 if (test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
3990 CERROR("%s is not defined\n", fsname);
3991 mgs_free_fsdb(mgs, fsdb);
3995 label_sz = 10 + strlen(fsname) + strlen(poolname);
3997 /* check if ostname match fsname */
3998 if (ostname != NULL) {
4001 ptr = strrchr(ostname, '-');
4002 if ((ptr == NULL) ||
4003 (strncmp(fsname, ostname, ptr-ostname) != 0))
4005 label_sz += strlen(ostname);
4008 OBD_ALLOC(label, label_sz);
4015 "new %s.%s", fsname, poolname);
4019 "add %s.%s.%s", fsname, poolname, ostname);
4022 OBD_ALLOC(canceled_label, label_sz);
4023 if (canceled_label == NULL)
4024 GOTO(out_label, rc = -ENOMEM);
4026 "rem %s.%s.%s", fsname, poolname, ostname);
4027 sprintf(canceled_label,
4028 "add %s.%s.%s", fsname, poolname, ostname);
4031 OBD_ALLOC(canceled_label, label_sz);
4032 if (canceled_label == NULL)
4033 GOTO(out_label, rc = -ENOMEM);
4035 "del %s.%s", fsname, poolname);
4036 sprintf(canceled_label,
4037 "new %s.%s", fsname, poolname);
4043 if (canceled_label != NULL) {
4046 GOTO(out_cancel, rc = -ENOMEM);
4049 mutex_lock(&fsdb->fsdb_mutex);
4050 /* write pool def to all MDT logs */
4051 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
4052 if (test_bit(i, fsdb->fsdb_mdt_index_map)) {
4053 rc = name_create_mdt_and_lov(&logname, &lovname,
4056 mutex_unlock(&fsdb->fsdb_mutex);
4059 if (canceled_label != NULL) {
4060 strcpy(mti->mti_svname, "lov pool");
4061 rc = mgs_modify(env, mgs, fsdb, mti, logname,
4062 lovname, canceled_label,
4067 rc = mgs_write_log_pool(env, mgs, logname,
4071 name_destroy(&logname);
4072 name_destroy(&lovname);
4074 mutex_unlock(&fsdb->fsdb_mutex);
4080 rc = name_create(&logname, fsname, "-client");
4082 mutex_unlock(&fsdb->fsdb_mutex);
4085 if (canceled_label != NULL) {
4086 rc = mgs_modify(env, mgs, fsdb, mti, logname,
4087 fsdb->fsdb_clilov, canceled_label, CM_SKIP);
4089 mutex_unlock(&fsdb->fsdb_mutex);
4090 name_destroy(&logname);
4095 rc = mgs_write_log_pool(env, mgs, logname, fsdb, fsdb->fsdb_clilov,
4096 cmd, fsname, poolname, ostname, label);
4097 mutex_unlock(&fsdb->fsdb_mutex);
4098 name_destroy(&logname);
4099 /* request for update */
4100 mgs_revoke_lock(mgs, fsdb, CONFIG_T_CONFIG);
4107 if (canceled_label != NULL)
4108 OBD_FREE(canceled_label, label_sz);
4110 OBD_FREE(label, label_sz);