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, 2014, 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_ioctl.h>
50 #include <lustre_param.h>
51 #include <lustre_sec.h>
52 #include <lustre_quota.h>
54 #include "mgs_internal.h"
56 /********************** Class functions ********************/
58 /* Find all logs in CONFIG directory and link then into list */
59 int class_dentry_readdir(const struct lu_env *env,
60 struct mgs_device *mgs, struct list_head *log_list)
62 struct dt_object *dir = mgs->mgs_configs_dir;
63 const struct dt_it_ops *iops;
65 struct mgs_direntry *de;
69 INIT_LIST_HEAD(log_list);
72 LASSERT(dir->do_index_ops);
74 iops = &dir->do_index_ops->dio_it;
75 it = iops->init(env, dir, LUDA_64BITHASH, BYPASS_CAPA);
79 rc = iops->load(env, it, 0);
85 key = (void *)iops->key(env, it);
87 CERROR("%s: key failed when listing %s: rc = %d\n",
88 mgs->mgs_obd->obd_name, MOUNT_CONFIGS_DIR,
92 key_sz = iops->key_size(env, it);
95 /* filter out "." and ".." entries */
99 if (key_sz == 2 && key[1] == '.')
103 de = mgs_direntry_alloc(key_sz + 1);
109 memcpy(de->mde_name, key, key_sz);
110 de->mde_name[key_sz] = 0;
112 list_add(&de->mde_list, log_list);
115 rc = iops->next(env, it);
124 CERROR("%s: key failed when listing %s: rc = %d\n",
125 mgs->mgs_obd->obd_name, MOUNT_CONFIGS_DIR, rc);
129 /******************** DB functions *********************/
131 static inline int name_create(char **newname, char *prefix, char *suffix)
134 OBD_ALLOC(*newname, strlen(prefix) + strlen(suffix) + 1);
137 sprintf(*newname, "%s%s", prefix, suffix);
141 static inline void name_destroy(char **name)
144 OBD_FREE(*name, strlen(*name) + 1);
148 struct mgs_fsdb_handler_data
154 /* from the (client) config log, figure out:
155 1. which ost's/mdt's are configured (by index)
156 2. what the last config step is
157 3. COMPAT_18 osc name
159 /* It might be better to have a separate db file, instead of parsing the info
160 out of the client log. This is slow and potentially error-prone. */
161 static int mgs_fsdb_handler(const struct lu_env *env, struct llog_handle *llh,
162 struct llog_rec_hdr *rec, void *data)
164 struct mgs_fsdb_handler_data *d = data;
165 struct fs_db *fsdb = d->fsdb;
166 int cfg_len = rec->lrh_len;
167 char *cfg_buf = (char*) (rec + 1);
168 struct lustre_cfg *lcfg;
173 if (rec->lrh_type != OBD_CFG_REC) {
174 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
178 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
180 CERROR("Insane cfg\n");
184 lcfg = (struct lustre_cfg *)cfg_buf;
186 CDEBUG(D_INFO, "cmd %x %s %s\n", lcfg->lcfg_command,
187 lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));
189 /* Figure out ost indicies */
190 /* lov_modify_tgts add 0:lov1 1:ost1_UUID 2(index):0 3(gen):1 */
191 if (lcfg->lcfg_command == LCFG_LOV_ADD_OBD ||
192 lcfg->lcfg_command == LCFG_LOV_DEL_OBD) {
193 index = simple_strtoul(lustre_cfg_string(lcfg, 2),
195 CDEBUG(D_MGS, "OST index for %s is %u (%s)\n",
196 lustre_cfg_string(lcfg, 1), index,
197 lustre_cfg_string(lcfg, 2));
198 set_bit(index, fsdb->fsdb_ost_index_map);
201 /* Figure out mdt indicies */
202 /* attach 0:MDC_uml1_mdsA_MNT_client 1:mdc 2:1d834_MNT_client_03f */
203 if ((lcfg->lcfg_command == LCFG_ATTACH) &&
204 (strcmp(lustre_cfg_string(lcfg, 1), LUSTRE_MDC_NAME) == 0)) {
205 rc = server_name2index(lustre_cfg_string(lcfg, 0),
207 if (rc != LDD_F_SV_TYPE_MDT) {
208 CWARN("Unparsable MDC name %s, assuming index 0\n",
209 lustre_cfg_string(lcfg, 0));
213 CDEBUG(D_MGS, "MDT index is %u\n", index);
214 set_bit(index, fsdb->fsdb_mdt_index_map);
215 fsdb->fsdb_mdt_count ++;
219 * figure out the old config. fsdb_gen = 0 means old log
220 * It is obsoleted and not supported anymore
222 if (fsdb->fsdb_gen == 0) {
223 CERROR("Old config format is not supported\n");
228 * compat to 1.8, check osc name used by MDT0 to OSTs, bz18548.
230 if (!test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags) &&
231 lcfg->lcfg_command == LCFG_ATTACH &&
232 strcmp(lustre_cfg_string(lcfg, 1), LUSTRE_OSC_NAME) == 0) {
233 if (OBD_OCD_VERSION_MAJOR(d->ver) == 1 &&
234 OBD_OCD_VERSION_MINOR(d->ver) <= 8) {
235 CWARN("MDT using 1.8 OSC name scheme\n");
236 set_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags);
240 if (lcfg->lcfg_command == LCFG_MARKER) {
241 struct cfg_marker *marker;
242 marker = lustre_cfg_buf(lcfg, 1);
244 d->ver = marker->cm_vers;
246 /* Keep track of the latest marker step */
247 fsdb->fsdb_gen = max(fsdb->fsdb_gen, marker->cm_step);
253 /* fsdb->fsdb_mutex is already held in mgs_find_or_make_fsdb*/
254 static int mgs_get_fsdb_from_llog(const struct lu_env *env,
255 struct mgs_device *mgs,
259 struct llog_handle *loghandle;
260 struct llog_ctxt *ctxt;
261 struct mgs_fsdb_handler_data d = { fsdb, 0 };
266 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
267 LASSERT(ctxt != NULL);
268 rc = name_create(&logname, fsdb->fsdb_name, "-client");
271 rc = llog_open_create(env, ctxt, &loghandle, NULL, logname);
275 rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL);
279 if (llog_get_size(loghandle) <= 1)
280 set_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags);
282 rc = llog_process(env, loghandle, mgs_fsdb_handler, (void *)&d, NULL);
283 CDEBUG(D_INFO, "get_db = %d\n", rc);
285 llog_close(env, loghandle);
287 name_destroy(&logname);
294 static void mgs_free_fsdb_srpc(struct fs_db *fsdb)
296 struct mgs_tgt_srpc_conf *tgtconf;
298 /* free target-specific rules */
299 while (fsdb->fsdb_srpc_tgt) {
300 tgtconf = fsdb->fsdb_srpc_tgt;
301 fsdb->fsdb_srpc_tgt = tgtconf->mtsc_next;
303 LASSERT(tgtconf->mtsc_tgt);
305 sptlrpc_rule_set_free(&tgtconf->mtsc_rset);
306 OBD_FREE(tgtconf->mtsc_tgt, strlen(tgtconf->mtsc_tgt) + 1);
307 OBD_FREE_PTR(tgtconf);
310 /* free general rules */
311 sptlrpc_rule_set_free(&fsdb->fsdb_srpc_gen);
314 struct fs_db *mgs_find_fsdb(struct mgs_device *mgs, char *fsname)
317 struct list_head *tmp;
319 list_for_each(tmp, &mgs->mgs_fs_db_list) {
320 fsdb = list_entry(tmp, struct fs_db, fsdb_list);
321 if (strcmp(fsdb->fsdb_name, fsname) == 0)
327 /* caller must hold the mgs->mgs_fs_db_lock */
328 static struct fs_db *mgs_new_fsdb(const struct lu_env *env,
329 struct mgs_device *mgs, char *fsname)
335 if (strlen(fsname) >= sizeof(fsdb->fsdb_name)) {
336 CERROR("fsname %s is too long\n", fsname);
344 strcpy(fsdb->fsdb_name, fsname);
345 mutex_init(&fsdb->fsdb_mutex);
346 set_bit(FSDB_UDESC, &fsdb->fsdb_flags);
349 if (strcmp(fsname, MGSSELF_NAME) == 0) {
350 set_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags);
352 OBD_ALLOC(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
353 OBD_ALLOC(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
354 if (!fsdb->fsdb_ost_index_map || !fsdb->fsdb_mdt_index_map) {
355 CERROR("No memory for index maps\n");
356 GOTO(err, rc = -ENOMEM);
359 rc = name_create(&fsdb->fsdb_clilov, fsname, "-clilov");
362 rc = name_create(&fsdb->fsdb_clilmv, fsname, "-clilmv");
366 /* initialise data for NID table */
367 mgs_ir_init_fs(env, mgs, fsdb);
369 lproc_mgs_add_live(mgs, fsdb);
372 list_add(&fsdb->fsdb_list, &mgs->mgs_fs_db_list);
376 if (fsdb->fsdb_ost_index_map)
377 OBD_FREE(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
378 if (fsdb->fsdb_mdt_index_map)
379 OBD_FREE(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
380 name_destroy(&fsdb->fsdb_clilov);
381 name_destroy(&fsdb->fsdb_clilmv);
386 static void mgs_free_fsdb(struct mgs_device *mgs, struct fs_db *fsdb)
388 /* wait for anyone with the sem */
389 mutex_lock(&fsdb->fsdb_mutex);
390 lproc_mgs_del_live(mgs, fsdb);
391 list_del(&fsdb->fsdb_list);
393 /* deinitialize fsr */
394 mgs_ir_fini_fs(mgs, fsdb);
396 if (fsdb->fsdb_ost_index_map)
397 OBD_FREE(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
398 if (fsdb->fsdb_mdt_index_map)
399 OBD_FREE(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
400 name_destroy(&fsdb->fsdb_clilov);
401 name_destroy(&fsdb->fsdb_clilmv);
402 mgs_free_fsdb_srpc(fsdb);
403 mutex_unlock(&fsdb->fsdb_mutex);
407 int mgs_init_fsdb_list(struct mgs_device *mgs)
409 INIT_LIST_HEAD(&mgs->mgs_fs_db_list);
413 int mgs_cleanup_fsdb_list(struct mgs_device *mgs)
416 struct list_head *tmp, *tmp2;
418 mutex_lock(&mgs->mgs_mutex);
419 list_for_each_safe(tmp, tmp2, &mgs->mgs_fs_db_list) {
420 fsdb = list_entry(tmp, struct fs_db, fsdb_list);
421 mgs_free_fsdb(mgs, fsdb);
423 mutex_unlock(&mgs->mgs_mutex);
427 int mgs_find_or_make_fsdb(const struct lu_env *env,
428 struct mgs_device *mgs, char *name,
435 mutex_lock(&mgs->mgs_mutex);
436 fsdb = mgs_find_fsdb(mgs, name);
438 mutex_unlock(&mgs->mgs_mutex);
443 CDEBUG(D_MGS, "Creating new db\n");
444 fsdb = mgs_new_fsdb(env, mgs, name);
445 /* lock fsdb_mutex until the db is loaded from llogs */
447 mutex_lock(&fsdb->fsdb_mutex);
448 mutex_unlock(&mgs->mgs_mutex);
452 if (!test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
453 /* populate the db from the client llog */
454 rc = mgs_get_fsdb_from_llog(env, mgs, fsdb);
456 CERROR("Can't get db from client log %d\n", rc);
461 /* populate srpc rules from params llog */
462 rc = mgs_get_fsdb_srpc_from_llog(env, mgs, fsdb);
464 CERROR("Can't get db from params log %d\n", rc);
468 mutex_unlock(&fsdb->fsdb_mutex);
474 mutex_unlock(&fsdb->fsdb_mutex);
475 mgs_free_fsdb(mgs, fsdb);
481 -1= empty client log */
482 int mgs_check_index(const struct lu_env *env,
483 struct mgs_device *mgs,
484 struct mgs_target_info *mti)
491 LASSERT(!(mti->mti_flags & LDD_F_NEED_INDEX));
493 rc = mgs_find_or_make_fsdb(env, mgs, mti->mti_fsname, &fsdb);
495 CERROR("Can't get db for %s\n", mti->mti_fsname);
499 if (test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags))
502 if (mti->mti_flags & LDD_F_SV_TYPE_OST)
503 imap = fsdb->fsdb_ost_index_map;
504 else if (mti->mti_flags & LDD_F_SV_TYPE_MDT)
505 imap = fsdb->fsdb_mdt_index_map;
509 if (test_bit(mti->mti_stripe_index, imap))
514 static __inline__ int next_index(void *index_map, int map_len)
517 for (i = 0; i < map_len * 8; i++)
518 if (!test_bit(i, index_map)) {
521 CERROR("max index %d exceeded.\n", i);
526 0 newly marked as in use
528 +EALREADY for update of an old index */
529 static int mgs_set_index(const struct lu_env *env,
530 struct mgs_device *mgs,
531 struct mgs_target_info *mti)
538 rc = mgs_find_or_make_fsdb(env, mgs, mti->mti_fsname, &fsdb);
540 CERROR("Can't get db for %s\n", mti->mti_fsname);
544 mutex_lock(&fsdb->fsdb_mutex);
545 if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
546 imap = fsdb->fsdb_ost_index_map;
547 } else if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
548 imap = fsdb->fsdb_mdt_index_map;
550 GOTO(out_up, rc = -EINVAL);
553 if (mti->mti_flags & LDD_F_NEED_INDEX) {
554 rc = next_index(imap, INDEX_MAP_SIZE);
556 GOTO(out_up, rc = -ERANGE);
557 mti->mti_stripe_index = rc;
558 if (mti->mti_flags & LDD_F_SV_TYPE_MDT)
559 fsdb->fsdb_mdt_count ++;
562 /* the last index(0xffff) is reserved for default value. */
563 if (mti->mti_stripe_index >= INDEX_MAP_SIZE * 8 - 1) {
564 LCONSOLE_ERROR_MSG(0x13f, "Server %s requested index %u, "
565 "but index must be less than %u.\n",
566 mti->mti_svname, mti->mti_stripe_index,
567 INDEX_MAP_SIZE * 8 - 1);
568 GOTO(out_up, rc = -ERANGE);
571 if (test_bit(mti->mti_stripe_index, imap)) {
572 if ((mti->mti_flags & LDD_F_VIRGIN) &&
573 !(mti->mti_flags & LDD_F_WRITECONF)) {
574 LCONSOLE_ERROR_MSG(0x140, "Server %s requested index "
575 "%d, but that index is already in "
576 "use. Use --writeconf to force\n",
578 mti->mti_stripe_index);
579 GOTO(out_up, rc = -EADDRINUSE);
581 CDEBUG(D_MGS, "Server %s updating index %d\n",
582 mti->mti_svname, mti->mti_stripe_index);
583 GOTO(out_up, rc = EALREADY);
587 set_bit(mti->mti_stripe_index, imap);
588 clear_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags);
589 mutex_unlock(&fsdb->fsdb_mutex);
590 server_make_name(mti->mti_flags & ~(LDD_F_VIRGIN | LDD_F_WRITECONF),
591 mti->mti_stripe_index, mti->mti_fsname, mti->mti_svname);
593 CDEBUG(D_MGS, "Set index for %s to %d\n", mti->mti_svname,
594 mti->mti_stripe_index);
598 mutex_unlock(&fsdb->fsdb_mutex);
602 struct mgs_modify_lookup {
603 struct cfg_marker mml_marker;
607 static int mgs_modify_handler(const struct lu_env *env,
608 struct llog_handle *llh,
609 struct llog_rec_hdr *rec, void *data)
611 struct mgs_modify_lookup *mml = data;
612 struct cfg_marker *marker;
613 struct lustre_cfg *lcfg = REC_DATA(rec);
614 int cfg_len = REC_DATA_LEN(rec);
618 if (rec->lrh_type != OBD_CFG_REC) {
619 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
623 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
625 CERROR("Insane cfg\n");
629 /* We only care about markers */
630 if (lcfg->lcfg_command != LCFG_MARKER)
633 marker = lustre_cfg_buf(lcfg, 1);
634 if ((strcmp(mml->mml_marker.cm_comment, marker->cm_comment) == 0) &&
635 (strcmp(mml->mml_marker.cm_tgtname, marker->cm_tgtname) == 0) &&
636 !(marker->cm_flags & CM_SKIP)) {
637 /* Found a non-skipped marker match */
638 CDEBUG(D_MGS, "Changing rec %u marker %d %x->%x: %s %s\n",
639 rec->lrh_index, marker->cm_step,
640 marker->cm_flags, mml->mml_marker.cm_flags,
641 marker->cm_tgtname, marker->cm_comment);
642 /* Overwrite the old marker llog entry */
643 marker->cm_flags &= ~CM_EXCLUDE; /* in case we're unexcluding */
644 marker->cm_flags |= mml->mml_marker.cm_flags;
645 marker->cm_canceltime = mml->mml_marker.cm_canceltime;
646 rc = llog_write(env, llh, rec, rec->lrh_index);
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_base(const struct lu_env *env, struct llog_handle *llh,
787 char *cfgname, lnet_nid_t nid, int cmd,
788 char *s1, char *s2, char *s3, char *s4)
790 struct mgs_thread_info *mgi = mgs_env_info(env);
791 struct llog_cfg_rec *lcr;
794 CDEBUG(D_MGS, "lcfg %s %#x %s %s %s %s\n", cfgname,
795 cmd, s1, s2, s3, s4);
797 lustre_cfg_bufs_reset(&mgi->mgi_bufs, cfgname);
799 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, s1);
801 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 2, s2);
803 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 3, s3);
805 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 4, s4);
807 lcr = lustre_cfg_rec_new(cmd, &mgi->mgi_bufs);
811 lcr->lcr_cfg.lcfg_nid = nid;
812 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
814 lustre_cfg_rec_free(lcr);
818 "failed to write lcfg %s %#x %s %s %s %s: rc = %d\n",
819 cfgname, cmd, s1, s2, s3, s4, rc);
823 static inline int record_add_uuid(const struct lu_env *env,
824 struct llog_handle *llh,
825 uint64_t nid, char *uuid)
827 return record_base(env, llh, NULL, nid, LCFG_ADD_UUID, uuid, 0, 0, 0);
830 static inline int record_add_conn(const struct lu_env *env,
831 struct llog_handle *llh,
832 char *devname, char *uuid)
834 return record_base(env, llh, devname, 0, LCFG_ADD_CONN, uuid, 0, 0, 0);
837 static inline int record_attach(const struct lu_env *env,
838 struct llog_handle *llh, char *devname,
839 char *type, char *uuid)
841 return record_base(env, llh,devname, 0, LCFG_ATTACH, type, uuid, 0, 0);
844 static inline int record_setup(const struct lu_env *env,
845 struct llog_handle *llh, char *devname,
846 char *s1, char *s2, char *s3, char *s4)
848 return record_base(env, llh, devname, 0, LCFG_SETUP, s1, s2, s3, s4);
852 * \retval <0 record processing error
853 * \retval n record is processed. No need copy original one.
854 * \retval 0 record is not processed.
856 static int process_command(const struct lu_env *env, struct lustre_cfg *lcfg,
857 struct mgs_replace_uuid_lookup *mrul)
864 if (lcfg->lcfg_command == LCFG_ADD_UUID) {
865 /* LCFG_ADD_UUID command found. Let's skip original command
866 and add passed nids */
867 ptr = mrul->target.mti_params;
868 while (class_parse_nid(ptr, &nid, &ptr) == 0) {
869 CDEBUG(D_MGS, "add nid %s with uuid %s, "
870 "device %s\n", libcfs_nid2str(nid),
871 mrul->target.mti_params,
872 mrul->target.mti_svname);
873 rc = record_add_uuid(env,
875 mrul->target.mti_params);
880 if (nids_added == 0) {
881 CERROR("No new nids were added, nid %s with uuid %s, "
882 "device %s\n", libcfs_nid2str(nid),
883 mrul->target.mti_params,
884 mrul->target.mti_svname);
887 mrul->device_nids_added = 1;
893 if (mrul->device_nids_added && lcfg->lcfg_command == LCFG_SETUP) {
894 /* LCFG_SETUP command found. UUID should be changed */
895 rc = record_setup(env,
897 /* devname the same */
898 lustre_cfg_string(lcfg, 0),
899 /* s1 is not changed */
900 lustre_cfg_string(lcfg, 1),
901 /* new uuid should be
903 mrul->target.mti_params,
904 /* s3 is not changed */
905 lustre_cfg_string(lcfg, 3),
906 /* s4 is not changed */
907 lustre_cfg_string(lcfg, 4));
911 /* Another commands in target device block */
916 * Handler that called for every record in llog.
917 * Records are processed in order they placed in llog.
919 * \param[in] llh log to be processed
920 * \param[in] rec current record
921 * \param[in] data mgs_replace_uuid_lookup structure
925 static int mgs_replace_handler(const struct lu_env *env,
926 struct llog_handle *llh,
927 struct llog_rec_hdr *rec,
930 struct mgs_replace_uuid_lookup *mrul;
931 struct lustre_cfg *lcfg = REC_DATA(rec);
932 int cfg_len = REC_DATA_LEN(rec);
936 mrul = (struct mgs_replace_uuid_lookup *)data;
938 if (rec->lrh_type != OBD_CFG_REC) {
939 CERROR("unhandled lrh_type: %#x, cmd %x %s %s\n",
940 rec->lrh_type, lcfg->lcfg_command,
941 lustre_cfg_string(lcfg, 0),
942 lustre_cfg_string(lcfg, 1));
946 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
948 /* Do not copy any invalidated records */
949 GOTO(skip_out, rc = 0);
952 rc = check_markers(lcfg, mrul);
953 if (rc || mrul->skip_it)
954 GOTO(skip_out, rc = 0);
956 /* Write to new log all commands outside target device block */
957 if (!mrul->in_target_device)
958 GOTO(copy_out, rc = 0);
960 /* Skip all other LCFG_ADD_UUID and LCFG_ADD_CONN records
961 (failover nids) for this target, assuming that if then
962 primary is changing then so is the failover */
963 if (mrul->device_nids_added &&
964 (lcfg->lcfg_command == LCFG_ADD_UUID ||
965 lcfg->lcfg_command == LCFG_ADD_CONN))
966 GOTO(skip_out, rc = 0);
968 rc = process_command(env, lcfg, mrul);
975 /* Record is placed in temporary llog as is */
976 rc = llog_write(env, mrul->temp_llh, rec, LLOG_NEXT_IDX);
978 CDEBUG(D_MGS, "Copied idx=%d, rc=%d, len=%d, cmd %x %s %s\n",
979 rec->lrh_index, rc, rec->lrh_len, lcfg->lcfg_command,
980 lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));
984 CDEBUG(D_MGS, "Skipped idx=%d, rc=%d, len=%d, cmd %x %s %s\n",
985 rec->lrh_index, rc, rec->lrh_len, lcfg->lcfg_command,
986 lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));
990 static int mgs_log_is_empty(const struct lu_env *env,
991 struct mgs_device *mgs, char *name)
993 struct llog_ctxt *ctxt;
996 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
997 LASSERT(ctxt != NULL);
999 rc = llog_is_empty(env, ctxt, name);
1000 llog_ctxt_put(ctxt);
1004 static int mgs_replace_nids_log(const struct lu_env *env,
1005 struct obd_device *mgs, struct fs_db *fsdb,
1006 char *logname, char *devname, char *nids)
1008 struct llog_handle *orig_llh, *backup_llh;
1009 struct llog_ctxt *ctxt;
1010 struct mgs_replace_uuid_lookup *mrul;
1011 struct mgs_device *mgs_dev = lu2mgs_dev(mgs->obd_lu_dev);
1012 static struct obd_uuid cfg_uuid = { .uuid = "config_uuid" };
1017 CDEBUG(D_MGS, "Replace nids for %s in %s\n", devname, logname);
1019 ctxt = llog_get_context(mgs, LLOG_CONFIG_ORIG_CTXT);
1020 LASSERT(ctxt != NULL);
1022 if (mgs_log_is_empty(env, mgs_dev, logname)) {
1023 /* Log is empty. Nothing to replace */
1024 GOTO(out_put, rc = 0);
1027 OBD_ALLOC(backup, strlen(logname) + strlen(".bak") + 1);
1029 GOTO(out_put, rc = -ENOMEM);
1031 sprintf(backup, "%s.bak", logname);
1033 rc = llog_backup(env, mgs, ctxt, ctxt, logname, backup);
1035 /* Now erase original log file. Connections are not allowed.
1036 Backup is already saved */
1037 rc = llog_erase(env, ctxt, NULL, logname);
1040 } else if (rc != -ENOENT) {
1041 CERROR("%s: can't make backup for %s: rc = %d\n",
1042 mgs->obd_name, logname, rc);
1046 /* open local log */
1047 rc = llog_open_create(env, ctxt, &orig_llh, NULL, logname);
1049 GOTO(out_restore, rc);
1051 rc = llog_init_handle(env, orig_llh, LLOG_F_IS_PLAIN, &cfg_uuid);
1053 GOTO(out_closel, rc);
1055 /* open backup llog */
1056 rc = llog_open(env, ctxt, &backup_llh, NULL, backup,
1059 GOTO(out_closel, rc);
1061 rc = llog_init_handle(env, backup_llh, LLOG_F_IS_PLAIN, NULL);
1063 GOTO(out_close, rc);
1065 if (llog_get_size(backup_llh) <= 1)
1066 GOTO(out_close, rc = 0);
1068 OBD_ALLOC_PTR(mrul);
1070 GOTO(out_close, rc = -ENOMEM);
1071 /* devname is only needed information to replace UUID records */
1072 strlcpy(mrul->target.mti_svname, devname,
1073 sizeof(mrul->target.mti_svname));
1074 /* parse nids later */
1075 strlcpy(mrul->target.mti_params, nids, sizeof(mrul->target.mti_params));
1076 /* Copy records to this temporary llog */
1077 mrul->temp_llh = orig_llh;
1079 rc = llog_process(env, backup_llh, mgs_replace_handler,
1080 (void *)mrul, NULL);
1083 rc2 = llog_close(NULL, backup_llh);
1087 rc2 = llog_close(NULL, orig_llh);
1093 CERROR("%s: llog should be restored: rc = %d\n",
1095 rc2 = llog_backup(env, mgs, ctxt, ctxt, backup,
1098 CERROR("%s: can't restore backup %s: rc = %d\n",
1099 mgs->obd_name, logname, rc2);
1103 OBD_FREE(backup, strlen(backup) + 1);
1106 llog_ctxt_put(ctxt);
1109 CERROR("%s: failed to replace nids in log %s: rc = %d\n",
1110 mgs->obd_name, logname, rc);
1116 * Parse device name and get file system name and/or device index
1118 * \param[in] devname device name (ex. lustre-MDT0000)
1119 * \param[out] fsname file system name(optional)
1120 * \param[out] index device index(optional)
1124 static int mgs_parse_devname(char *devname, char *fsname, __u32 *index)
1129 /* Extract fsname */
1131 rc = server_name2fsname(devname, fsname, NULL);
1133 CDEBUG(D_MGS, "Device name %s without fsname\n",
1140 rc = server_name2index(devname, index, NULL);
1142 CDEBUG(D_MGS, "Device name %s with wrong index\n",
1151 /* This is only called during replace_nids */
1152 static int only_mgs_is_running(struct obd_device *mgs_obd)
1154 /* TDB: Is global variable with devices count exists? */
1155 int num_devices = get_devices_count();
1156 int num_exports = 0;
1157 struct obd_export *exp;
1159 spin_lock(&mgs_obd->obd_dev_lock);
1160 list_for_each_entry(exp, &mgs_obd->obd_exports, exp_obd_chain) {
1161 /* skip self export */
1162 if (exp == mgs_obd->obd_self_export)
1164 if (exp_connect_flags(exp) & OBD_CONNECT_MDS_MDS)
1169 CERROR("%s: node %s still connected during replace_nids "
1170 "connect_flags:%llx\n",
1172 libcfs_nid2str(exp->exp_nid_stats->nid),
1173 exp_connect_flags(exp));
1176 spin_unlock(&mgs_obd->obd_dev_lock);
1178 /* osd, MGS and MGC + self_export
1179 (wc -l /proc/fs/lustre/devices <= 2) && (non self exports == 0) */
1180 return (num_devices <= 3) && (num_exports == 0);
1183 static int name_create_mdt(char **logname, char *fsname, int i)
1187 sprintf(mdt_index, "-MDT%04x", i);
1188 return name_create(logname, fsname, mdt_index);
1192 * Replace nids for \a device to \a nids values
1194 * \param obd MGS obd device
1195 * \param devname nids need to be replaced for this device
1196 * (ex. lustre-OST0000)
1197 * \param nids nids list (ex. nid1,nid2,nid3)
1201 int mgs_replace_nids(const struct lu_env *env,
1202 struct mgs_device *mgs,
1203 char *devname, char *nids)
1205 /* Assume fsname is part of device name */
1206 char fsname[MTI_NAME_MAXLEN];
1213 struct obd_device *mgs_obd = mgs->mgs_obd;
1216 /* We can only change NIDs if no other nodes are connected */
1217 spin_lock(&mgs_obd->obd_dev_lock);
1218 conn_state = mgs_obd->obd_no_conn;
1219 mgs_obd->obd_no_conn = 1;
1220 spin_unlock(&mgs_obd->obd_dev_lock);
1222 /* We can not change nids if not only MGS is started */
1223 if (!only_mgs_is_running(mgs_obd)) {
1224 CERROR("Only MGS is allowed to be started\n");
1225 GOTO(out, rc = -EINPROGRESS);
1228 /* Get fsname and index*/
1229 rc = mgs_parse_devname(devname, fsname, &index);
1233 rc = mgs_find_or_make_fsdb(env, mgs, fsname, &fsdb);
1235 CERROR("%s: can't find fsdb: rc = %d\n", fsname, rc);
1239 /* Process client llogs */
1240 name_create(&logname, fsname, "-client");
1241 rc = mgs_replace_nids_log(env, mgs_obd, fsdb, logname, devname, nids);
1242 name_destroy(&logname);
1244 CERROR("%s: error while replacing NIDs for %s: rc = %d\n",
1245 fsname, devname, rc);
1249 /* Process MDT llogs */
1250 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
1251 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
1253 name_create_mdt(&logname, fsname, i);
1254 rc = mgs_replace_nids_log(env, mgs_obd, fsdb, logname, devname, nids);
1255 name_destroy(&logname);
1261 spin_lock(&mgs_obd->obd_dev_lock);
1262 mgs_obd->obd_no_conn = conn_state;
1263 spin_unlock(&mgs_obd->obd_dev_lock);
1268 static int record_lov_setup(const struct lu_env *env, struct llog_handle *llh,
1269 char *devname, struct lov_desc *desc)
1271 struct mgs_thread_info *mgi = mgs_env_info(env);
1272 struct llog_cfg_rec *lcr;
1275 lustre_cfg_bufs_reset(&mgi->mgi_bufs, devname);
1276 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, desc, sizeof(*desc));
1277 lcr = lustre_cfg_rec_new(LCFG_SETUP, &mgi->mgi_bufs);
1281 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1282 lustre_cfg_rec_free(lcr);
1286 static int record_lmv_setup(const struct lu_env *env, struct llog_handle *llh,
1287 char *devname, struct lmv_desc *desc)
1289 struct mgs_thread_info *mgi = mgs_env_info(env);
1290 struct llog_cfg_rec *lcr;
1293 lustre_cfg_bufs_reset(&mgi->mgi_bufs, devname);
1294 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, desc, sizeof(*desc));
1295 lcr = lustre_cfg_rec_new(LCFG_SETUP, &mgi->mgi_bufs);
1299 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1300 lustre_cfg_rec_free(lcr);
1304 static inline int record_mdc_add(const struct lu_env *env,
1305 struct llog_handle *llh,
1306 char *logname, char *mdcuuid,
1307 char *mdtuuid, char *index,
1310 return record_base(env,llh,logname,0,LCFG_ADD_MDC,
1311 mdtuuid,index,gen,mdcuuid);
1314 static inline int record_lov_add(const struct lu_env *env,
1315 struct llog_handle *llh,
1316 char *lov_name, char *ost_uuid,
1317 char *index, char *gen)
1319 return record_base(env,llh,lov_name,0,LCFG_LOV_ADD_OBD,
1320 ost_uuid, index, gen, 0);
1323 static inline int record_mount_opt(const struct lu_env *env,
1324 struct llog_handle *llh,
1325 char *profile, char *lov_name,
1328 return record_base(env,llh,NULL,0,LCFG_MOUNTOPT,
1329 profile,lov_name,mdc_name,0);
1332 static int record_marker(const struct lu_env *env,
1333 struct llog_handle *llh,
1334 struct fs_db *fsdb, __u32 flags,
1335 char *tgtname, char *comment)
1337 struct mgs_thread_info *mgi = mgs_env_info(env);
1338 struct llog_cfg_rec *lcr;
1342 if (flags & CM_START)
1344 mgi->mgi_marker.cm_step = fsdb->fsdb_gen;
1345 mgi->mgi_marker.cm_flags = flags;
1346 mgi->mgi_marker.cm_vers = LUSTRE_VERSION_CODE;
1347 cplen = strlcpy(mgi->mgi_marker.cm_tgtname, tgtname,
1348 sizeof(mgi->mgi_marker.cm_tgtname));
1349 if (cplen >= sizeof(mgi->mgi_marker.cm_tgtname))
1351 cplen = strlcpy(mgi->mgi_marker.cm_comment, comment,
1352 sizeof(mgi->mgi_marker.cm_comment));
1353 if (cplen >= sizeof(mgi->mgi_marker.cm_comment))
1355 mgi->mgi_marker.cm_createtime = cfs_time_current_sec();
1356 mgi->mgi_marker.cm_canceltime = 0;
1357 lustre_cfg_bufs_reset(&mgi->mgi_bufs, NULL);
1358 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, &mgi->mgi_marker,
1359 sizeof(mgi->mgi_marker));
1360 lcr = lustre_cfg_rec_new(LCFG_MARKER, &mgi->mgi_bufs);
1364 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1365 lustre_cfg_rec_free(lcr);
1369 static int record_start_log(const struct lu_env *env, struct mgs_device *mgs,
1370 struct llog_handle **llh, char *name)
1372 static struct obd_uuid cfg_uuid = { .uuid = "config_uuid" };
1373 struct llog_ctxt *ctxt;
1378 GOTO(out, rc = -EBUSY);
1380 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
1382 GOTO(out, rc = -ENODEV);
1383 LASSERT(ctxt->loc_obd == mgs->mgs_obd);
1385 rc = llog_open_create(env, ctxt, llh, NULL, name);
1388 rc = llog_init_handle(env, *llh, LLOG_F_IS_PLAIN, &cfg_uuid);
1390 llog_close(env, *llh);
1392 llog_ctxt_put(ctxt);
1395 CERROR("%s: can't start log %s: rc = %d\n",
1396 mgs->mgs_obd->obd_name, name, rc);
1402 static int record_end_log(const struct lu_env *env, struct llog_handle **llh)
1406 rc = llog_close(env, *llh);
1412 /******************** config "macros" *********************/
1414 /* write an lcfg directly into a log (with markers) */
1415 static int mgs_write_log_direct(const struct lu_env *env,
1416 struct mgs_device *mgs, struct fs_db *fsdb,
1417 char *logname, struct llog_cfg_rec *lcr,
1418 char *devname, char *comment)
1420 struct llog_handle *llh = NULL;
1425 rc = record_start_log(env, mgs, &llh, logname);
1429 /* FIXME These should be a single journal transaction */
1430 rc = record_marker(env, llh, fsdb, CM_START, devname, comment);
1433 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1436 rc = record_marker(env, llh, fsdb, CM_END, devname, comment);
1440 record_end_log(env, &llh);
1444 /* write the lcfg in all logs for the given fs */
1445 int mgs_write_log_direct_all(const struct lu_env *env, struct mgs_device *mgs,
1446 struct fs_db *fsdb, struct mgs_target_info *mti,
1447 struct llog_cfg_rec *lcr, char *devname,
1448 char *comment, int server_only)
1450 struct list_head log_list;
1451 struct mgs_direntry *dirent, *n;
1452 char *fsname = mti->mti_fsname;
1453 int rc = 0, len = strlen(fsname);
1456 /* Find all the logs in the CONFIGS directory */
1457 rc = class_dentry_readdir(env, mgs, &log_list);
1461 /* Could use fsdb index maps instead of directory listing */
1462 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
1463 list_del_init(&dirent->mde_list);
1464 /* don't write to sptlrpc rule log */
1465 if (strstr(dirent->mde_name, "-sptlrpc") != NULL)
1468 /* caller wants write server logs only */
1469 if (server_only && strstr(dirent->mde_name, "-client") != NULL)
1472 if (strlen(dirent->mde_name) <= len ||
1473 strncmp(fsname, dirent->mde_name, len) != 0 ||
1474 dirent->mde_name[len] != '-')
1477 CDEBUG(D_MGS, "Changing log %s\n", dirent->mde_name);
1478 /* Erase any old settings of this same parameter */
1479 rc = mgs_modify(env, mgs, fsdb, mti, dirent->mde_name,
1480 devname, comment, CM_SKIP);
1482 CERROR("%s: Can't modify llog %s: rc = %d\n",
1483 mgs->mgs_obd->obd_name, dirent->mde_name, rc);
1486 /* Write the new one */
1487 rc = mgs_write_log_direct(env, mgs, fsdb, dirent->mde_name,
1488 lcr, devname, comment);
1490 CERROR("%s: writing log %s: rc = %d\n",
1491 mgs->mgs_obd->obd_name, dirent->mde_name, rc);
1493 mgs_direntry_free(dirent);
1499 static int mgs_write_log_osp_to_mdt(const struct lu_env *env,
1500 struct mgs_device *mgs,
1502 struct mgs_target_info *mti,
1503 int index, char *logname);
1504 static int mgs_write_log_osc_to_lov(const struct lu_env *env,
1505 struct mgs_device *mgs,
1507 struct mgs_target_info *mti,
1508 char *logname, char *suffix, char *lovname,
1509 enum lustre_sec_part sec_part, int flags);
1510 static int name_create_mdt_and_lov(char **logname, char **lovname,
1511 struct fs_db *fsdb, int i);
1513 static int add_param(char *params, char *key, char *val)
1515 char *start = params + strlen(params);
1516 char *end = params + sizeof(((struct mgs_target_info *)0)->mti_params);
1520 keylen = strlen(key);
1521 if (start + 1 + keylen + strlen(val) >= end) {
1522 CERROR("params are too long: %s %s%s\n",
1523 params, key != NULL ? key : "", val);
1527 sprintf(start, " %s%s", key != NULL ? key : "", val);
1532 * Walk through client config log record and convert the related records
1535 static int mgs_steal_client_llog_handler(const struct lu_env *env,
1536 struct llog_handle *llh,
1537 struct llog_rec_hdr *rec, void *data)
1539 struct mgs_device *mgs;
1540 struct obd_device *obd;
1541 struct mgs_target_info *mti, *tmti;
1543 int cfg_len = rec->lrh_len;
1544 char *cfg_buf = (char*) (rec + 1);
1545 struct lustre_cfg *lcfg;
1547 struct llog_handle *mdt_llh = NULL;
1548 static int got_an_osc_or_mdc = 0;
1549 /* 0: not found any osc/mdc;
1553 static int last_step = -1;
1558 mti = ((struct temp_comp*)data)->comp_mti;
1559 tmti = ((struct temp_comp*)data)->comp_tmti;
1560 fsdb = ((struct temp_comp*)data)->comp_fsdb;
1561 obd = ((struct temp_comp *)data)->comp_obd;
1562 mgs = lu2mgs_dev(obd->obd_lu_dev);
1565 if (rec->lrh_type != OBD_CFG_REC) {
1566 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
1570 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
1572 CERROR("Insane cfg\n");
1576 lcfg = (struct lustre_cfg *)cfg_buf;
1578 if (lcfg->lcfg_command == LCFG_MARKER) {
1579 struct cfg_marker *marker;
1580 marker = lustre_cfg_buf(lcfg, 1);
1581 if (!strncmp(marker->cm_comment, "add osc", 7) &&
1582 (marker->cm_flags & CM_START) &&
1583 !(marker->cm_flags & CM_SKIP)) {
1584 got_an_osc_or_mdc = 1;
1585 cplen = strlcpy(tmti->mti_svname, marker->cm_tgtname,
1586 sizeof(tmti->mti_svname));
1587 if (cplen >= sizeof(tmti->mti_svname))
1589 rc = record_start_log(env, mgs, &mdt_llh,
1593 rc = record_marker(env, mdt_llh, fsdb, CM_START,
1594 mti->mti_svname, "add osc(copied)");
1595 record_end_log(env, &mdt_llh);
1596 last_step = marker->cm_step;
1599 if (!strncmp(marker->cm_comment, "add osc", 7) &&
1600 (marker->cm_flags & CM_END) &&
1601 !(marker->cm_flags & CM_SKIP)) {
1602 LASSERT(last_step == marker->cm_step);
1604 got_an_osc_or_mdc = 0;
1605 memset(tmti, 0, sizeof(*tmti));
1606 rc = record_start_log(env, mgs, &mdt_llh,
1610 rc = record_marker(env, mdt_llh, fsdb, CM_END,
1611 mti->mti_svname, "add osc(copied)");
1612 record_end_log(env, &mdt_llh);
1615 if (!strncmp(marker->cm_comment, "add mdc", 7) &&
1616 (marker->cm_flags & CM_START) &&
1617 !(marker->cm_flags & CM_SKIP)) {
1618 got_an_osc_or_mdc = 2;
1619 last_step = marker->cm_step;
1620 memcpy(tmti->mti_svname, marker->cm_tgtname,
1621 strlen(marker->cm_tgtname));
1625 if (!strncmp(marker->cm_comment, "add mdc", 7) &&
1626 (marker->cm_flags & CM_END) &&
1627 !(marker->cm_flags & CM_SKIP)) {
1628 LASSERT(last_step == marker->cm_step);
1630 got_an_osc_or_mdc = 0;
1631 memset(tmti, 0, sizeof(*tmti));
1636 if (got_an_osc_or_mdc == 0 || last_step < 0)
1639 if (lcfg->lcfg_command == LCFG_ADD_UUID) {
1640 uint64_t nodenid = lcfg->lcfg_nid;
1642 if (strlen(tmti->mti_uuid) == 0) {
1643 /* target uuid not set, this config record is before
1644 * LCFG_SETUP, this nid is one of target node nid.
1646 tmti->mti_nids[tmti->mti_nid_count] = nodenid;
1647 tmti->mti_nid_count++;
1649 /* failover node nid */
1650 rc = add_param(tmti->mti_params, PARAM_FAILNODE,
1651 libcfs_nid2str(nodenid));
1657 if (lcfg->lcfg_command == LCFG_SETUP) {
1660 target = lustre_cfg_string(lcfg, 1);
1661 memcpy(tmti->mti_uuid, target, strlen(target));
1665 /* ignore client side sptlrpc_conf_log */
1666 if (lcfg->lcfg_command == LCFG_SPTLRPC_CONF)
1669 if (lcfg->lcfg_command == LCFG_ADD_MDC) {
1672 if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1)
1675 memcpy(tmti->mti_fsname, mti->mti_fsname,
1676 strlen(mti->mti_fsname));
1677 tmti->mti_stripe_index = index;
1679 rc = mgs_write_log_osp_to_mdt(env, mgs, fsdb, tmti,
1680 mti->mti_stripe_index,
1682 memset(tmti, 0, sizeof(*tmti));
1686 if (lcfg->lcfg_command == LCFG_LOV_ADD_OBD) {
1689 char *logname, *lovname;
1691 rc = name_create_mdt_and_lov(&logname, &lovname, fsdb,
1692 mti->mti_stripe_index);
1695 sprintf(mdt_index, "-MDT%04x", mti->mti_stripe_index);
1697 if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1) {
1698 name_destroy(&logname);
1699 name_destroy(&lovname);
1703 tmti->mti_stripe_index = index;
1704 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, tmti, logname,
1707 name_destroy(&logname);
1708 name_destroy(&lovname);
1714 /* fsdb->fsdb_mutex is already held in mgs_write_log_target*/
1715 /* stealed from mgs_get_fsdb_from_llog*/
1716 static int mgs_steal_llog_for_mdt_from_client(const struct lu_env *env,
1717 struct mgs_device *mgs,
1719 struct temp_comp* comp)
1721 struct llog_handle *loghandle;
1722 struct mgs_target_info *tmti;
1723 struct llog_ctxt *ctxt;
1728 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
1729 LASSERT(ctxt != NULL);
1731 OBD_ALLOC_PTR(tmti);
1733 GOTO(out_ctxt, rc = -ENOMEM);
1735 comp->comp_tmti = tmti;
1736 comp->comp_obd = mgs->mgs_obd;
1738 rc = llog_open(env, ctxt, &loghandle, NULL, client_name,
1746 rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL);
1748 GOTO(out_close, rc);
1750 rc = llog_process_or_fork(env, loghandle, mgs_steal_client_llog_handler,
1751 (void *)comp, NULL, false);
1752 CDEBUG(D_MGS, "steal llog re = %d\n", rc);
1754 llog_close(env, loghandle);
1758 llog_ctxt_put(ctxt);
1762 /* lmv is the second thing for client logs */
1763 /* copied from mgs_write_log_lov. Please refer to that. */
1764 static int mgs_write_log_lmv(const struct lu_env *env,
1765 struct mgs_device *mgs,
1767 struct mgs_target_info *mti,
1768 char *logname, char *lmvname)
1770 struct llog_handle *llh = NULL;
1771 struct lmv_desc *lmvdesc;
1776 CDEBUG(D_MGS, "Writing lmv(%s) log for %s\n", lmvname,logname);
1778 OBD_ALLOC_PTR(lmvdesc);
1779 if (lmvdesc == NULL)
1781 lmvdesc->ld_active_tgt_count = 0;
1782 lmvdesc->ld_tgt_count = 0;
1783 sprintf((char*)lmvdesc->ld_uuid.uuid, "%s_UUID", lmvname);
1784 uuid = (char *)lmvdesc->ld_uuid.uuid;
1786 rc = record_start_log(env, mgs, &llh, logname);
1789 rc = record_marker(env, llh, fsdb, CM_START, lmvname, "lmv setup");
1792 rc = record_attach(env, llh, lmvname, "lmv", uuid);
1795 rc = record_lmv_setup(env, llh, lmvname, lmvdesc);
1798 rc = record_marker(env, llh, fsdb, CM_END, lmvname, "lmv setup");
1802 record_end_log(env, &llh);
1804 OBD_FREE_PTR(lmvdesc);
1808 /* lov is the first thing in the mdt and client logs */
1809 static int mgs_write_log_lov(const struct lu_env *env, struct mgs_device *mgs,
1810 struct fs_db *fsdb, struct mgs_target_info *mti,
1811 char *logname, char *lovname)
1813 struct llog_handle *llh = NULL;
1814 struct lov_desc *lovdesc;
1819 CDEBUG(D_MGS, "Writing lov(%s) log for %s\n", lovname, logname);
1822 #01 L attach 0:lov_mdsA 1:lov 2:71ccb_lov_mdsA_19f961a9e1
1823 #02 L lov_setup 0:lov_mdsA 1:(struct lov_desc)
1824 uuid=lov1_UUID, stripe count=1, size=1048576, offset=0, pattern=0
1827 /* FIXME just make lov_setup accept empty desc (put uuid in buf 2) */
1828 OBD_ALLOC_PTR(lovdesc);
1829 if (lovdesc == NULL)
1831 lovdesc->ld_magic = LOV_DESC_MAGIC;
1832 lovdesc->ld_tgt_count = 0;
1833 /* Defaults. Can be changed later by lcfg config_param */
1834 lovdesc->ld_default_stripe_count = 1;
1835 lovdesc->ld_pattern = LOV_PATTERN_RAID0;
1836 lovdesc->ld_default_stripe_size = LOV_DESC_STRIPE_SIZE_DEFAULT;
1837 lovdesc->ld_default_stripe_offset = -1;
1838 lovdesc->ld_qos_maxage = LOV_DESC_QOS_MAXAGE_DEFAULT;
1839 sprintf((char*)lovdesc->ld_uuid.uuid, "%s_UUID", lovname);
1840 /* can these be the same? */
1841 uuid = (char *)lovdesc->ld_uuid.uuid;
1843 /* This should always be the first entry in a log.
1844 rc = mgs_clear_log(obd, logname); */
1845 rc = record_start_log(env, mgs, &llh, logname);
1848 /* FIXME these should be a single journal transaction */
1849 rc = record_marker(env, llh, fsdb, CM_START, lovname, "lov setup");
1852 rc = record_attach(env, llh, lovname, "lov", uuid);
1855 rc = record_lov_setup(env, llh, lovname, lovdesc);
1858 rc = record_marker(env, llh, fsdb, CM_END, lovname, "lov setup");
1863 record_end_log(env, &llh);
1865 OBD_FREE_PTR(lovdesc);
1869 /* add failnids to open log */
1870 static int mgs_write_log_failnids(const struct lu_env *env,
1871 struct mgs_target_info *mti,
1872 struct llog_handle *llh,
1875 char *failnodeuuid = NULL;
1876 char *ptr = mti->mti_params;
1881 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) nal=90 0: 1:uml1_UUID
1882 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
1883 #05 L setup 0:OSC_uml1_ost1_mdsA 1:ost1_UUID 2:uml1_UUID
1884 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) nal=90 0: 1:uml2_UUID
1885 #0x L add_uuid nid=2@elan(0x1000000000002) nal=90 0: 1:uml2_UUID
1886 #07 L add_conn 0:OSC_uml1_ost1_mdsA 1:uml2_UUID
1890 * Pull failnid info out of params string, which may contain something
1891 * like "<nid1>,<nid2>:<nid3>,<nid4>". class_parse_nid() does not
1892 * complain about abnormal inputs like ",:<nid1>", "<nid1>:,<nid2>",
1893 * etc. However, convert_hostnames() should have caught those.
1895 while (class_find_param(ptr, PARAM_FAILNODE, &ptr) == 0) {
1896 while (class_parse_nid(ptr, &nid, &ptr) == 0) {
1897 if (failnodeuuid == NULL) {
1898 /* We don't know the failover node name,
1899 so just use the first nid as the uuid */
1900 rc = name_create(&failnodeuuid,
1901 libcfs_nid2str(nid), "");
1905 CDEBUG(D_MGS, "add nid %s for failover uuid %s, "
1906 "client %s\n", libcfs_nid2str(nid),
1907 failnodeuuid, cliname);
1908 rc = record_add_uuid(env, llh, nid, failnodeuuid);
1910 * If *ptr is ':', we have added all NIDs for
1914 rc = record_add_conn(env, llh, cliname,
1916 name_destroy(&failnodeuuid);
1917 failnodeuuid = NULL;
1921 rc = record_add_conn(env, llh, cliname, failnodeuuid);
1922 name_destroy(&failnodeuuid);
1923 failnodeuuid = NULL;
1930 static int mgs_write_log_mdc_to_lmv(const struct lu_env *env,
1931 struct mgs_device *mgs,
1933 struct mgs_target_info *mti,
1934 char *logname, char *lmvname)
1936 struct llog_handle *llh = NULL;
1937 char *mdcname = NULL;
1938 char *nodeuuid = NULL;
1939 char *mdcuuid = NULL;
1940 char *lmvuuid = NULL;
1945 if (mgs_log_is_empty(env, mgs, logname)) {
1946 CERROR("log is empty! Logical error\n");
1950 CDEBUG(D_MGS, "adding mdc for %s to log %s:lmv(%s)\n",
1951 mti->mti_svname, logname, lmvname);
1953 rc = name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
1956 rc = name_create(&mdcname, mti->mti_svname, "-mdc");
1959 rc = name_create(&mdcuuid, mdcname, "_UUID");
1962 rc = name_create(&lmvuuid, lmvname, "_UUID");
1966 rc = record_start_log(env, mgs, &llh, logname);
1969 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
1973 for (i = 0; i < mti->mti_nid_count; i++) {
1974 CDEBUG(D_MGS, "add nid %s for mdt\n",
1975 libcfs_nid2str(mti->mti_nids[i]));
1977 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
1982 rc = record_attach(env, llh, mdcname, LUSTRE_MDC_NAME, lmvuuid);
1985 rc = record_setup(env, llh, mdcname, mti->mti_uuid, nodeuuid, 0, 0);
1988 rc = mgs_write_log_failnids(env, mti, llh, mdcname);
1991 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
1992 rc = record_mdc_add(env, llh, lmvname, mdcuuid, mti->mti_uuid,
1996 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname,
2001 record_end_log(env, &llh);
2003 name_destroy(&lmvuuid);
2004 name_destroy(&mdcuuid);
2005 name_destroy(&mdcname);
2006 name_destroy(&nodeuuid);
2010 static inline int name_create_lov(char **lovname, char *mdtname,
2011 struct fs_db *fsdb, int index)
2014 if (index == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2015 return name_create(lovname, fsdb->fsdb_name, "-mdtlov");
2017 return name_create(lovname, mdtname, "-mdtlov");
2020 static int name_create_mdt_and_lov(char **logname, char **lovname,
2021 struct fs_db *fsdb, int i)
2025 rc = name_create_mdt(logname, fsdb->fsdb_name, i);
2029 if (i == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2030 rc = name_create(lovname, fsdb->fsdb_name, "-mdtlov");
2032 rc = name_create(lovname, *logname, "-mdtlov");
2034 name_destroy(logname);
2040 static inline int name_create_mdt_osc(char **oscname, char *ostname,
2041 struct fs_db *fsdb, int i)
2045 if (i == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2046 sprintf(suffix, "-osc");
2048 sprintf(suffix, "-osc-MDT%04x", i);
2049 return name_create(oscname, ostname, suffix);
2052 /* add new mdc to already existent MDS */
2053 static int mgs_write_log_osp_to_mdt(const struct lu_env *env,
2054 struct mgs_device *mgs,
2056 struct mgs_target_info *mti,
2057 int mdt_index, char *logname)
2059 struct llog_handle *llh = NULL;
2060 char *nodeuuid = NULL;
2061 char *ospname = NULL;
2062 char *lovuuid = NULL;
2063 char *mdtuuid = NULL;
2064 char *svname = NULL;
2065 char *mdtname = NULL;
2066 char *lovname = NULL;
2071 if (mgs_log_is_empty(env, mgs, mti->mti_svname)) {
2072 CERROR("log is empty! Logical error\n");
2076 CDEBUG(D_MGS, "adding osp index %d to %s\n", mti->mti_stripe_index,
2079 rc = name_create_mdt(&mdtname, fsdb->fsdb_name, mti->mti_stripe_index);
2083 rc = name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
2085 GOTO(out_destory, rc);
2087 rc = name_create(&svname, mdtname, "-osp");
2089 GOTO(out_destory, rc);
2091 sprintf(index_str, "-MDT%04x", mdt_index);
2092 rc = name_create(&ospname, svname, index_str);
2094 GOTO(out_destory, rc);
2096 rc = name_create_lov(&lovname, logname, fsdb, mdt_index);
2098 GOTO(out_destory, rc);
2100 rc = name_create(&lovuuid, lovname, "_UUID");
2102 GOTO(out_destory, rc);
2104 rc = name_create(&mdtuuid, mdtname, "_UUID");
2106 GOTO(out_destory, rc);
2108 rc = record_start_log(env, mgs, &llh, logname);
2110 GOTO(out_destory, rc);
2112 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
2115 GOTO(out_destory, rc);
2117 for (i = 0; i < mti->mti_nid_count; i++) {
2118 CDEBUG(D_MGS, "add nid %s for mdt\n",
2119 libcfs_nid2str(mti->mti_nids[i]));
2120 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
2125 rc = record_attach(env, llh, ospname, LUSTRE_OSP_NAME, lovuuid);
2129 rc = record_setup(env, llh, ospname, mti->mti_uuid, nodeuuid,
2134 rc = mgs_write_log_failnids(env, mti, llh, ospname);
2138 /* Add mdc(osp) to lod */
2139 snprintf(index_str, sizeof(mti->mti_stripe_index), "%d",
2140 mti->mti_stripe_index);
2141 rc = record_base(env, llh, lovname, 0, LCFG_ADD_MDC, mti->mti_uuid,
2142 index_str, "1", NULL);
2146 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname, "add osp");
2151 record_end_log(env, &llh);
2154 name_destroy(&mdtuuid);
2155 name_destroy(&lovuuid);
2156 name_destroy(&lovname);
2157 name_destroy(&ospname);
2158 name_destroy(&svname);
2159 name_destroy(&nodeuuid);
2160 name_destroy(&mdtname);
2164 static int mgs_write_log_mdt0(const struct lu_env *env,
2165 struct mgs_device *mgs,
2167 struct mgs_target_info *mti)
2169 char *log = mti->mti_svname;
2170 struct llog_handle *llh = NULL;
2171 char *uuid, *lovname;
2173 char *ptr = mti->mti_params;
2174 int rc = 0, failout = 0;
2177 OBD_ALLOC(uuid, sizeof(struct obd_uuid));
2181 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
2182 failout = (strncmp(ptr, "failout", 7) == 0);
2184 rc = name_create(&lovname, log, "-mdtlov");
2187 if (mgs_log_is_empty(env, mgs, log)) {
2188 rc = mgs_write_log_lov(env, mgs, fsdb, mti, log, lovname);
2193 sprintf(mdt_index, "%d", mti->mti_stripe_index);
2195 rc = record_start_log(env, mgs, &llh, log);
2199 /* add MDT itself */
2201 /* FIXME this whole fn should be a single journal transaction */
2202 sprintf(uuid, "%s_UUID", log);
2203 rc = record_marker(env, llh, fsdb, CM_START, log, "add mdt");
2206 rc = record_attach(env, llh, log, LUSTRE_MDT_NAME, uuid);
2209 rc = record_mount_opt(env, llh, log, lovname, NULL);
2212 rc = record_setup(env, llh, log, uuid, mdt_index, lovname,
2213 failout ? "n" : "f");
2216 rc = record_marker(env, llh, fsdb, CM_END, log, "add mdt");
2220 record_end_log(env, &llh);
2222 name_destroy(&lovname);
2224 OBD_FREE(uuid, sizeof(struct obd_uuid));
2228 /* envelope method for all layers log */
2229 static int mgs_write_log_mdt(const struct lu_env *env,
2230 struct mgs_device *mgs,
2232 struct mgs_target_info *mti)
2234 struct mgs_thread_info *mgi = mgs_env_info(env);
2235 struct llog_handle *llh = NULL;
2240 CDEBUG(D_MGS, "writing new mdt %s\n", mti->mti_svname);
2242 if (mti->mti_uuid[0] == '\0') {
2243 /* Make up our own uuid */
2244 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
2245 "%s_UUID", mti->mti_svname);
2249 rc = mgs_write_log_mdt0(env, mgs, fsdb, mti);
2252 /* Append the mdt info to the client log */
2253 rc = name_create(&cliname, mti->mti_fsname, "-client");
2257 if (mgs_log_is_empty(env, mgs, cliname)) {
2258 /* Start client log */
2259 rc = mgs_write_log_lov(env, mgs, fsdb, mti, cliname,
2263 rc = mgs_write_log_lmv(env, mgs, fsdb, mti, cliname,
2270 #09 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
2271 #10 L attach 0:MDC_uml1_mdsA_MNT_client 1:mdc 2:1d834_MNT_client_03f
2272 #11 L setup 0:MDC_uml1_mdsA_MNT_client 1:mdsA_UUID 2:uml1_UUID
2273 #12 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
2274 #13 L add_conn 0:MDC_uml1_mdsA_MNT_client 1:uml2_UUID
2275 #14 L mount_option 0: 1:client 2:lov1 3:MDC_uml1_mdsA_MNT_client
2278 /* copy client info about lov/lmv */
2279 mgi->mgi_comp.comp_mti = mti;
2280 mgi->mgi_comp.comp_fsdb = fsdb;
2282 rc = mgs_steal_llog_for_mdt_from_client(env, mgs, cliname,
2286 rc = mgs_write_log_mdc_to_lmv(env, mgs, fsdb, mti, cliname,
2292 rc = record_start_log(env, mgs, &llh, cliname);
2296 rc = record_marker(env, llh, fsdb, CM_START, cliname,
2300 rc = record_mount_opt(env, llh, cliname, fsdb->fsdb_clilov,
2304 rc = record_marker(env, llh, fsdb, CM_END, cliname,
2310 /* for_all_existing_mdt except current one */
2311 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2312 if (i != mti->mti_stripe_index &&
2313 test_bit(i, fsdb->fsdb_mdt_index_map)) {
2316 rc = name_create_mdt(&logname, fsdb->fsdb_name, i);
2320 rc = mgs_write_log_osp_to_mdt(env, mgs, fsdb, mti,
2322 name_destroy(&logname);
2328 record_end_log(env, &llh);
2330 name_destroy(&cliname);
2334 /* Add the ost info to the client/mdt lov */
2335 static int mgs_write_log_osc_to_lov(const struct lu_env *env,
2336 struct mgs_device *mgs, struct fs_db *fsdb,
2337 struct mgs_target_info *mti,
2338 char *logname, char *suffix, char *lovname,
2339 enum lustre_sec_part sec_part, int flags)
2341 struct llog_handle *llh = NULL;
2342 char *nodeuuid = NULL;
2343 char *oscname = NULL;
2344 char *oscuuid = NULL;
2345 char *lovuuid = NULL;
2346 char *svname = NULL;
2351 CDEBUG(D_INFO, "adding osc for %s to log %s\n",
2352 mti->mti_svname, logname);
2354 if (mgs_log_is_empty(env, mgs, logname)) {
2355 CERROR("log is empty! Logical error\n");
2359 rc = name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
2362 rc = name_create(&svname, mti->mti_svname, "-osc");
2366 /* for the system upgraded from old 1.8, keep using the old osc naming
2367 * style for mdt, see name_create_mdt_osc(). LU-1257 */
2368 if (test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2369 rc = name_create(&oscname, svname, "");
2371 rc = name_create(&oscname, svname, suffix);
2375 rc = name_create(&oscuuid, oscname, "_UUID");
2378 rc = name_create(&lovuuid, lovname, "_UUID");
2384 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
2386 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
2387 #04 L attach 0:OSC_uml1_ost1_MNT_client 1:osc 2:89070_lov1_a41dff51a
2388 #05 L setup 0:OSC_uml1_ost1_MNT_client 1:ost1_UUID 2:uml1_UUID
2390 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
2391 #07 L add_conn 0:OSC_uml1_ost1_MNT_client 1:uml2_UUID
2392 #08 L lov_modify_tgts add 0:lov1 1:ost1_UUID 2(index):0 3(gen):1
2395 rc = record_start_log(env, mgs, &llh, logname);
2399 /* FIXME these should be a single journal transaction */
2400 rc = record_marker(env, llh, fsdb, CM_START | flags, mti->mti_svname,
2405 /* NB: don't change record order, because upon MDT steal OSC config
2406 * from client, it treats all nids before LCFG_SETUP as target nids
2407 * (multiple interfaces), while nids after as failover node nids.
2408 * See mgs_steal_client_llog_handler() LCFG_ADD_UUID.
2410 for (i = 0; i < mti->mti_nid_count; i++) {
2411 CDEBUG(D_MGS, "add nid %s\n", libcfs_nid2str(mti->mti_nids[i]));
2412 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
2416 rc = record_attach(env, llh, oscname, LUSTRE_OSC_NAME, lovuuid);
2419 rc = record_setup(env, llh, oscname, mti->mti_uuid, nodeuuid, 0, 0);
2422 rc = mgs_write_log_failnids(env, mti, llh, oscname);
2426 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
2428 rc = record_lov_add(env, llh, lovname, mti->mti_uuid, index, "1");
2431 rc = record_marker(env, llh, fsdb, CM_END | flags, mti->mti_svname,
2436 record_end_log(env, &llh);
2438 name_destroy(&lovuuid);
2439 name_destroy(&oscuuid);
2440 name_destroy(&oscname);
2441 name_destroy(&svname);
2442 name_destroy(&nodeuuid);
2446 static int mgs_write_log_ost(const struct lu_env *env,
2447 struct mgs_device *mgs, struct fs_db *fsdb,
2448 struct mgs_target_info *mti)
2450 struct llog_handle *llh = NULL;
2451 char *logname, *lovname;
2452 char *ptr = mti->mti_params;
2453 int rc, flags = 0, failout = 0, i;
2456 CDEBUG(D_MGS, "writing new ost %s\n", mti->mti_svname);
2458 /* The ost startup log */
2460 /* If the ost log already exists, that means that someone reformatted
2461 the ost and it called target_add again. */
2462 if (!mgs_log_is_empty(env, mgs, mti->mti_svname)) {
2463 LCONSOLE_ERROR_MSG(0x141, "The config log for %s already "
2464 "exists, yet the server claims it never "
2465 "registered. It may have been reformatted, "
2466 "or the index changed. writeconf the MDT to "
2467 "regenerate all logs.\n", mti->mti_svname);
2472 attach obdfilter ost1 ost1_UUID
2473 setup /dev/loop2 ldiskfs f|n errors=remount-ro,user_xattr
2475 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
2476 failout = (strncmp(ptr, "failout", 7) == 0);
2477 rc = record_start_log(env, mgs, &llh, mti->mti_svname);
2480 /* FIXME these should be a single journal transaction */
2481 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,"add ost");
2484 if (*mti->mti_uuid == '\0')
2485 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
2486 "%s_UUID", mti->mti_svname);
2487 rc = record_attach(env, llh, mti->mti_svname,
2488 "obdfilter"/*LUSTRE_OST_NAME*/, mti->mti_uuid);
2491 rc = record_setup(env, llh, mti->mti_svname,
2492 "dev"/*ignored*/, "type"/*ignored*/,
2493 failout ? "n" : "f", 0/*options*/);
2496 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname, "add ost");
2500 record_end_log(env, &llh);
2503 /* We also have to update the other logs where this osc is part of
2506 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
2507 /* If we're upgrading, the old mdt log already has our
2508 entry. Let's do a fake one for fun. */
2509 /* Note that we can't add any new failnids, since we don't
2510 know the old osc names. */
2511 flags = CM_SKIP | CM_UPGRADE146;
2513 } else if ((mti->mti_flags & LDD_F_UPDATE) != LDD_F_UPDATE) {
2514 /* If the update flag isn't set, don't update client/mdt
2517 LCONSOLE_WARN("Client log for %s was not updated; writeconf "
2518 "the MDT first to regenerate it.\n",
2522 /* Add ost to all MDT lov defs */
2523 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
2524 if (test_bit(i, fsdb->fsdb_mdt_index_map)) {
2527 rc = name_create_mdt_and_lov(&logname, &lovname, fsdb,
2531 sprintf(mdt_index, "-MDT%04x", i);
2532 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, mti,
2534 lovname, LUSTRE_SP_MDT,
2536 name_destroy(&logname);
2537 name_destroy(&lovname);
2543 /* Append ost info to the client log */
2544 rc = name_create(&logname, mti->mti_fsname, "-client");
2547 if (mgs_log_is_empty(env, mgs, logname)) {
2548 /* Start client log */
2549 rc = mgs_write_log_lov(env, mgs, fsdb, mti, logname,
2553 rc = mgs_write_log_lmv(env, mgs, fsdb, mti, logname,
2558 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, mti, logname, "",
2559 fsdb->fsdb_clilov, LUSTRE_SP_CLI, 0);
2561 name_destroy(&logname);
2565 static __inline__ int mgs_param_empty(char *ptr)
2569 if ((tmp = strchr(ptr, '=')) && (*(++tmp) == '\0'))
2574 static int mgs_write_log_failnid_internal(const struct lu_env *env,
2575 struct mgs_device *mgs,
2577 struct mgs_target_info *mti,
2578 char *logname, char *cliname)
2581 struct llog_handle *llh = NULL;
2583 if (mgs_param_empty(mti->mti_params)) {
2584 /* Remove _all_ failnids */
2585 rc = mgs_modify(env, mgs, fsdb, mti, logname,
2586 mti->mti_svname, "add failnid", CM_SKIP);
2587 return rc < 0 ? rc : 0;
2590 /* Otherwise failover nids are additive */
2591 rc = record_start_log(env, mgs, &llh, logname);
2594 /* FIXME this should be a single journal transaction */
2595 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
2599 rc = mgs_write_log_failnids(env, mti, llh, cliname);
2602 rc = record_marker(env, llh, fsdb, CM_END,
2603 mti->mti_svname, "add failnid");
2605 record_end_log(env, &llh);
2610 /* Add additional failnids to an existing log.
2611 The mdc/osc must have been added to logs first */
2612 /* tcp nids must be in dotted-quad ascii -
2613 we can't resolve hostnames from the kernel. */
2614 static int mgs_write_log_add_failnid(const struct lu_env *env,
2615 struct mgs_device *mgs,
2617 struct mgs_target_info *mti)
2619 char *logname, *cliname;
2623 /* FIXME we currently can't erase the failnids
2624 * given when a target first registers, since they aren't part of
2625 * an "add uuid" stanza */
2627 /* Verify that we know about this target */
2628 if (mgs_log_is_empty(env, mgs, mti->mti_svname)) {
2629 LCONSOLE_ERROR_MSG(0x142, "The target %s has not registered "
2630 "yet. It must be started before failnids "
2631 "can be added.\n", mti->mti_svname);
2635 /* Create mdc/osc client name (e.g. lustre-OST0001-osc) */
2636 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
2637 rc = name_create(&cliname, mti->mti_svname, "-mdc");
2638 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2639 rc = name_create(&cliname, mti->mti_svname, "-osc");
2645 /* Add failover nids to the client log */
2646 rc = name_create(&logname, mti->mti_fsname, "-client");
2648 name_destroy(&cliname);
2651 rc = mgs_write_log_failnid_internal(env, mgs, fsdb,mti,logname,cliname);
2652 name_destroy(&logname);
2653 name_destroy(&cliname);
2657 if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2658 /* Add OST failover nids to the MDT logs as well */
2661 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2662 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
2664 rc = name_create_mdt(&logname, mti->mti_fsname, i);
2667 rc = name_create_mdt_osc(&cliname, mti->mti_svname,
2670 name_destroy(&logname);
2673 rc = mgs_write_log_failnid_internal(env, mgs, fsdb,
2676 name_destroy(&cliname);
2677 name_destroy(&logname);
2686 static int mgs_wlp_lcfg(const struct lu_env *env,
2687 struct mgs_device *mgs, struct fs_db *fsdb,
2688 struct mgs_target_info *mti,
2689 char *logname, struct lustre_cfg_bufs *bufs,
2690 char *tgtname, char *ptr)
2692 char comment[MTI_NAME_MAXLEN];
2694 struct llog_cfg_rec *lcr;
2697 /* Erase any old settings of this same parameter */
2698 memcpy(comment, ptr, MTI_NAME_MAXLEN);
2699 comment[MTI_NAME_MAXLEN - 1] = 0;
2700 /* But don't try to match the value. */
2701 tmp = strchr(comment, '=');
2704 /* FIXME we should skip settings that are the same as old values */
2705 rc = mgs_modify(env, mgs, fsdb, mti, logname, tgtname, comment,CM_SKIP);
2708 del = mgs_param_empty(ptr);
2710 LCONSOLE_INFO("%s parameter %s.%s in log %s\n", del ? "Disabling" : rc ?
2711 "Setting" : "Modifying", tgtname, comment, logname);
2713 /* mgs_modify() will return 1 if nothing had to be done */
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 lcr = lustre_cfg_rec_new((mti->mti_flags & LDD_F_PARAM2) ?
2725 LCFG_SET_PARAM : LCFG_PARAM, bufs);
2729 rc = mgs_write_log_direct(env, mgs, fsdb, logname, lcr, tgtname,
2731 lustre_cfg_rec_free(lcr);
2735 static int mgs_write_log_param2(const struct lu_env *env,
2736 struct mgs_device *mgs,
2738 struct mgs_target_info *mti, char *ptr)
2740 struct lustre_cfg_bufs bufs;
2744 CDEBUG(D_MGS, "next param '%s'\n", ptr);
2745 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, PARAMS_FILENAME, &bufs,
2746 mti->mti_svname, ptr);
2751 /* write global variable settings into log */
2752 static int mgs_write_log_sys(const struct lu_env *env,
2753 struct mgs_device *mgs, struct fs_db *fsdb,
2754 struct mgs_target_info *mti, char *sys, char *ptr)
2756 struct mgs_thread_info *mgi = mgs_env_info(env);
2757 struct lustre_cfg *lcfg;
2758 struct llog_cfg_rec *lcr;
2760 int rc, cmd, convert = 1;
2762 if (class_match_param(ptr, PARAM_TIMEOUT, &tmp) == 0) {
2763 cmd = LCFG_SET_TIMEOUT;
2764 } else if (class_match_param(ptr, PARAM_LDLM_TIMEOUT, &tmp) == 0) {
2765 cmd = LCFG_SET_LDLM_TIMEOUT;
2766 /* Check for known params here so we can return error to lctl */
2767 } else if ((class_match_param(ptr, PARAM_AT_MIN, &tmp) == 0) ||
2768 (class_match_param(ptr, PARAM_AT_MAX, &tmp) == 0) ||
2769 (class_match_param(ptr, PARAM_AT_EXTRA, &tmp) == 0) ||
2770 (class_match_param(ptr, PARAM_AT_EARLY_MARGIN, &tmp) == 0) ||
2771 (class_match_param(ptr, PARAM_AT_HISTORY, &tmp) == 0)) {
2773 } else if (class_match_param(ptr, PARAM_JOBID_VAR, &tmp) == 0) {
2774 convert = 0; /* Don't convert string value to integer */
2780 if (mgs_param_empty(ptr))
2781 CDEBUG(D_MGS, "global '%s' removed\n", sys);
2783 CDEBUG(D_MGS, "global '%s' val=%s\n", sys, tmp);
2785 lustre_cfg_bufs_reset(&mgi->mgi_bufs, NULL);
2786 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, sys);
2787 if (!convert && *tmp != '\0')
2788 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 2, tmp);
2789 lcr = lustre_cfg_rec_new(cmd, &mgi->mgi_bufs);
2793 lcfg = &lcr->lcr_cfg;
2794 lcfg->lcfg_num = convert ? simple_strtoul(tmp, NULL, 0) : 0;
2795 /* truncate the comment to the parameter name */
2799 /* modify all servers and clients */
2800 rc = mgs_write_log_direct_all(env, mgs, fsdb, mti,
2801 *tmp == '\0' ? NULL : lcr,
2802 mti->mti_fsname, sys, 0);
2803 if (rc == 0 && *tmp != '\0') {
2805 case LCFG_SET_TIMEOUT:
2806 if (!obd_timeout_set || lcfg->lcfg_num > obd_timeout)
2807 class_process_config(lcfg);
2809 case LCFG_SET_LDLM_TIMEOUT:
2810 if (!ldlm_timeout_set || lcfg->lcfg_num > ldlm_timeout)
2811 class_process_config(lcfg);
2818 lustre_cfg_rec_free(lcr);
2822 /* write quota settings into log */
2823 static int mgs_write_log_quota(const struct lu_env *env, struct mgs_device *mgs,
2824 struct fs_db *fsdb, struct mgs_target_info *mti,
2825 char *quota, char *ptr)
2827 struct mgs_thread_info *mgi = mgs_env_info(env);
2828 struct llog_cfg_rec *lcr;
2831 int rc, cmd = LCFG_PARAM;
2833 /* support only 'meta' and 'data' pools so far */
2834 if (class_match_param(ptr, QUOTA_METAPOOL_NAME, &tmp) != 0 &&
2835 class_match_param(ptr, QUOTA_DATAPOOL_NAME, &tmp) != 0) {
2836 CERROR("parameter quota.%s isn't supported (only quota.mdt "
2837 "& quota.ost are)\n", ptr);
2842 CDEBUG(D_MGS, "global '%s' removed\n", quota);
2844 CDEBUG(D_MGS, "global '%s'\n", quota);
2846 if (strchr(tmp, 'u') == NULL && strchr(tmp, 'g') == NULL &&
2847 strcmp(tmp, "none") != 0) {
2848 CERROR("enable option(%s) isn't supported\n", tmp);
2853 lustre_cfg_bufs_reset(&mgi->mgi_bufs, mti->mti_fsname);
2854 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, quota);
2855 lcr = lustre_cfg_rec_new(cmd, &mgi->mgi_bufs);
2859 /* truncate the comment to the parameter name */
2864 /* XXX we duplicated quota enable information in all server
2865 * config logs, it should be moved to a separate config
2866 * log once we cleanup the config log for global param. */
2867 /* modify all servers */
2868 rc = mgs_write_log_direct_all(env, mgs, fsdb, mti,
2869 *tmp == '\0' ? NULL : lcr,
2870 mti->mti_fsname, quota, 1);
2872 lustre_cfg_rec_free(lcr);
2873 return rc < 0 ? rc : 0;
2876 static int mgs_srpc_set_param_disk(const struct lu_env *env,
2877 struct mgs_device *mgs,
2879 struct mgs_target_info *mti,
2882 struct mgs_thread_info *mgi = mgs_env_info(env);
2883 struct llog_cfg_rec *lcr;
2884 struct llog_handle *llh = NULL;
2886 char *comment, *ptr;
2892 ptr = strchr(param, '=');
2893 LASSERT(ptr != NULL);
2896 OBD_ALLOC(comment, len + 1);
2897 if (comment == NULL)
2899 strncpy(comment, param, len);
2900 comment[len] = '\0';
2903 lustre_cfg_bufs_reset(&mgi->mgi_bufs, mti->mti_svname);
2904 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, param);
2905 lcr = lustre_cfg_rec_new(LCFG_SPTLRPC_CONF, &mgi->mgi_bufs);
2907 GOTO(out_comment, rc = -ENOMEM);
2909 /* construct log name */
2910 rc = name_create(&logname, mti->mti_fsname, "-sptlrpc");
2914 if (mgs_log_is_empty(env, mgs, logname)) {
2915 rc = record_start_log(env, mgs, &llh, logname);
2918 record_end_log(env, &llh);
2921 /* obsolete old one */
2922 rc = mgs_modify(env, mgs, fsdb, mti, logname, mti->mti_svname,
2926 /* write the new one */
2927 rc = mgs_write_log_direct(env, mgs, fsdb, logname, lcr,
2928 mti->mti_svname, comment);
2930 CERROR("%s: error writing log %s: rc = %d\n",
2931 mgs->mgs_obd->obd_name, logname, rc);
2933 name_destroy(&logname);
2935 lustre_cfg_rec_free(lcr);
2937 OBD_FREE(comment, len + 1);
2941 static int mgs_srpc_set_param_udesc_mem(struct fs_db *fsdb,
2946 /* disable the adjustable udesc parameter for now, i.e. use default
2947 * setting that client always ship udesc to MDT if possible. to enable
2948 * it simply remove the following line */
2951 ptr = strchr(param, '=');
2956 if (strcmp(param, PARAM_SRPC_UDESC))
2959 if (strcmp(ptr, "yes") == 0) {
2960 set_bit(FSDB_UDESC, &fsdb->fsdb_flags);
2961 CWARN("Enable user descriptor shipping from client to MDT\n");
2962 } else if (strcmp(ptr, "no") == 0) {
2963 clear_bit(FSDB_UDESC, &fsdb->fsdb_flags);
2964 CWARN("Disable user descriptor shipping from client to MDT\n");
2972 CERROR("Invalid param: %s\n", param);
2976 static int mgs_srpc_set_param_mem(struct fs_db *fsdb,
2980 struct sptlrpc_rule rule;
2981 struct sptlrpc_rule_set *rset;
2985 if (strncmp(param, PARAM_SRPC, sizeof(PARAM_SRPC) - 1) != 0) {
2986 CERROR("Invalid sptlrpc parameter: %s\n", param);
2990 if (strncmp(param, PARAM_SRPC_UDESC,
2991 sizeof(PARAM_SRPC_UDESC) - 1) == 0) {
2992 RETURN(mgs_srpc_set_param_udesc_mem(fsdb, param));
2995 if (strncmp(param, PARAM_SRPC_FLVR, sizeof(PARAM_SRPC_FLVR) - 1) != 0) {
2996 CERROR("Invalid sptlrpc flavor parameter: %s\n", param);
3000 param += sizeof(PARAM_SRPC_FLVR) - 1;
3002 rc = sptlrpc_parse_rule(param, &rule);
3006 /* mgs rules implies must be mgc->mgs */
3007 if (test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
3008 if ((rule.sr_from != LUSTRE_SP_MGC &&
3009 rule.sr_from != LUSTRE_SP_ANY) ||
3010 (rule.sr_to != LUSTRE_SP_MGS &&
3011 rule.sr_to != LUSTRE_SP_ANY))
3015 /* preapre room for this coming rule. svcname format should be:
3016 * - fsname: general rule
3017 * - fsname-tgtname: target-specific rule
3019 if (strchr(svname, '-')) {
3020 struct mgs_tgt_srpc_conf *tgtconf;
3023 for (tgtconf = fsdb->fsdb_srpc_tgt; tgtconf != NULL;
3024 tgtconf = tgtconf->mtsc_next) {
3025 if (!strcmp(tgtconf->mtsc_tgt, svname)) {
3034 OBD_ALLOC_PTR(tgtconf);
3035 if (tgtconf == NULL)
3038 name_len = strlen(svname);
3040 OBD_ALLOC(tgtconf->mtsc_tgt, name_len + 1);
3041 if (tgtconf->mtsc_tgt == NULL) {
3042 OBD_FREE_PTR(tgtconf);
3045 memcpy(tgtconf->mtsc_tgt, svname, name_len);
3047 tgtconf->mtsc_next = fsdb->fsdb_srpc_tgt;
3048 fsdb->fsdb_srpc_tgt = tgtconf;
3051 rset = &tgtconf->mtsc_rset;
3053 rset = &fsdb->fsdb_srpc_gen;
3056 rc = sptlrpc_rule_set_merge(rset, &rule);
3061 static int mgs_srpc_set_param(const struct lu_env *env,
3062 struct mgs_device *mgs,
3064 struct mgs_target_info *mti,
3074 /* keep a copy of original param, which could be destroied
3076 copy_size = strlen(param) + 1;
3077 OBD_ALLOC(copy, copy_size);
3080 memcpy(copy, param, copy_size);
3082 rc = mgs_srpc_set_param_mem(fsdb, mti->mti_svname, param);
3086 /* previous steps guaranteed the syntax is correct */
3087 rc = mgs_srpc_set_param_disk(env, mgs, fsdb, mti, copy);
3091 if (test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
3093 * for mgs rules, make them effective immediately.
3095 LASSERT(fsdb->fsdb_srpc_tgt == NULL);
3096 sptlrpc_target_update_exp_flavor(mgs->mgs_obd,
3097 &fsdb->fsdb_srpc_gen);
3101 OBD_FREE(copy, copy_size);
3105 struct mgs_srpc_read_data {
3106 struct fs_db *msrd_fsdb;
3110 static int mgs_srpc_read_handler(const struct lu_env *env,
3111 struct llog_handle *llh,
3112 struct llog_rec_hdr *rec, void *data)
3114 struct mgs_srpc_read_data *msrd = data;
3115 struct cfg_marker *marker;
3116 struct lustre_cfg *lcfg = REC_DATA(rec);
3117 char *svname, *param;
3121 if (rec->lrh_type != OBD_CFG_REC) {
3122 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
3126 cfg_len = REC_DATA_LEN(rec);
3128 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
3130 CERROR("Insane cfg\n");
3134 if (lcfg->lcfg_command == LCFG_MARKER) {
3135 marker = lustre_cfg_buf(lcfg, 1);
3137 if (marker->cm_flags & CM_START &&
3138 marker->cm_flags & CM_SKIP)
3139 msrd->msrd_skip = 1;
3140 if (marker->cm_flags & CM_END)
3141 msrd->msrd_skip = 0;
3146 if (msrd->msrd_skip)
3149 if (lcfg->lcfg_command != LCFG_SPTLRPC_CONF) {
3150 CERROR("invalid command (%x)\n", lcfg->lcfg_command);
3154 svname = lustre_cfg_string(lcfg, 0);
3155 if (svname == NULL) {
3156 CERROR("svname is empty\n");
3160 param = lustre_cfg_string(lcfg, 1);
3161 if (param == NULL) {
3162 CERROR("param is empty\n");
3166 rc = mgs_srpc_set_param_mem(msrd->msrd_fsdb, svname, param);
3168 CERROR("read sptlrpc record error (%d): %s\n", rc, param);
3173 int mgs_get_fsdb_srpc_from_llog(const struct lu_env *env,
3174 struct mgs_device *mgs,
3177 struct llog_handle *llh = NULL;
3178 struct llog_ctxt *ctxt;
3180 struct mgs_srpc_read_data msrd;
3184 /* construct log name */
3185 rc = name_create(&logname, fsdb->fsdb_name, "-sptlrpc");
3189 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
3190 LASSERT(ctxt != NULL);
3192 if (mgs_log_is_empty(env, mgs, logname))
3195 rc = llog_open(env, ctxt, &llh, NULL, logname,
3203 rc = llog_init_handle(env, llh, LLOG_F_IS_PLAIN, NULL);
3205 GOTO(out_close, rc);
3207 if (llog_get_size(llh) <= 1)
3208 GOTO(out_close, rc = 0);
3210 msrd.msrd_fsdb = fsdb;
3213 rc = llog_process(env, llh, mgs_srpc_read_handler, (void *)&msrd,
3217 llog_close(env, llh);
3219 llog_ctxt_put(ctxt);
3220 name_destroy(&logname);
3223 CERROR("failed to read sptlrpc config database: %d\n", rc);
3227 /* Permanent settings of all parameters by writing into the appropriate
3228 * configuration logs.
3229 * A parameter with null value ("<param>='\0'") means to erase it out of
3232 static int mgs_write_log_param(const struct lu_env *env,
3233 struct mgs_device *mgs, struct fs_db *fsdb,
3234 struct mgs_target_info *mti, char *ptr)
3236 struct mgs_thread_info *mgi = mgs_env_info(env);
3239 int rc = 0, rc2 = 0;
3242 /* For various parameter settings, we have to figure out which logs
3243 care about them (e.g. both mdt and client for lov settings) */
3244 CDEBUG(D_MGS, "next param '%s'\n", ptr);
3246 /* The params are stored in MOUNT_DATA_FILE and modified via
3247 tunefs.lustre, or set using lctl conf_param */
3249 /* Processed in lustre_start_mgc */
3250 if (class_match_param(ptr, PARAM_MGSNODE, NULL) == 0)
3253 /* Processed in ost/mdt */
3254 if (class_match_param(ptr, PARAM_NETWORK, NULL) == 0)
3257 /* Processed in mgs_write_log_ost */
3258 if (class_match_param(ptr, PARAM_FAILMODE, NULL) == 0) {
3259 if (mti->mti_flags & LDD_F_PARAM) {
3260 LCONSOLE_ERROR_MSG(0x169, "%s can only be "
3261 "changed with tunefs.lustre"
3262 "and --writeconf\n", ptr);
3268 if (class_match_param(ptr, PARAM_SRPC, NULL) == 0) {
3269 rc = mgs_srpc_set_param(env, mgs, fsdb, mti, ptr);
3273 if (class_match_param(ptr, PARAM_FAILNODE, NULL) == 0) {
3274 /* Add a failover nidlist */
3276 /* We already processed failovers params for new
3277 targets in mgs_write_log_target */
3278 if (mti->mti_flags & LDD_F_PARAM) {
3279 CDEBUG(D_MGS, "Adding failnode\n");
3280 rc = mgs_write_log_add_failnid(env, mgs, fsdb, mti);
3285 if (class_match_param(ptr, PARAM_SYS, &tmp) == 0) {
3286 rc = mgs_write_log_sys(env, mgs, fsdb, mti, ptr, tmp);
3290 if (class_match_param(ptr, PARAM_QUOTA, &tmp) == 0) {
3291 rc = mgs_write_log_quota(env, mgs, fsdb, mti, ptr, tmp);
3295 if (class_match_param(ptr, PARAM_OSC""PARAM_ACTIVE, &tmp) == 0) {
3296 /* active=0 means off, anything else means on */
3297 int flag = (*tmp == '0') ? CM_EXCLUDE : 0;
3300 if (!(mti->mti_flags & LDD_F_SV_TYPE_OST)) {
3301 LCONSOLE_ERROR_MSG(0x144, "%s: Only OSCs can "
3302 "be (de)activated.\n",
3304 GOTO(end, rc = -EINVAL);
3306 LCONSOLE_WARN("Permanently %sactivating %s\n",
3307 flag ? "de": "re", mti->mti_svname);
3309 rc = name_create(&logname, mti->mti_fsname, "-client");
3312 rc = mgs_modify(env, mgs, fsdb, mti, logname,
3313 mti->mti_svname, "add osc", flag);
3314 name_destroy(&logname);
3318 /* Add to all MDT logs for CMD */
3319 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3320 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
3322 rc = name_create_mdt(&logname, mti->mti_fsname, i);
3325 rc = mgs_modify(env, mgs, fsdb, mti, logname,
3326 mti->mti_svname, "add osc", flag);
3327 name_destroy(&logname);
3333 LCONSOLE_ERROR_MSG(0x145, "Couldn't find %s in"
3334 "log (%d). No permanent "
3335 "changes were made to the "
3337 mti->mti_svname, rc);
3338 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags))
3339 LCONSOLE_ERROR_MSG(0x146, "This may be"
3344 "update the logs.\n");
3347 /* Fall through to osc proc for deactivating live OSC
3348 on running MDT / clients. */
3350 /* Below here, let obd's XXX_process_config methods handle it */
3352 /* All lov. in proc */
3353 if (class_match_param(ptr, PARAM_LOV, NULL) == 0) {
3356 CDEBUG(D_MGS, "lov param %s\n", ptr);
3357 if (!(mti->mti_flags & LDD_F_SV_TYPE_MDT)) {
3358 LCONSOLE_ERROR_MSG(0x147, "LOV params must be "
3359 "set on the MDT, not %s. "
3366 if (mgs_log_is_empty(env, mgs, mti->mti_svname))
3367 GOTO(end, rc = -ENODEV);
3369 rc = name_create_mdt_and_lov(&logname, &mdtlovname, fsdb,
3370 mti->mti_stripe_index);
3373 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, mti->mti_svname,
3374 &mgi->mgi_bufs, mdtlovname, ptr);
3375 name_destroy(&logname);
3376 name_destroy(&mdtlovname);
3381 rc = name_create(&logname, mti->mti_fsname, "-client");
3384 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname, &mgi->mgi_bufs,
3385 fsdb->fsdb_clilov, ptr);
3386 name_destroy(&logname);
3390 /* All osc., mdc., llite. params in proc */
3391 if ((class_match_param(ptr, PARAM_OSC, NULL) == 0) ||
3392 (class_match_param(ptr, PARAM_MDC, NULL) == 0) ||
3393 (class_match_param(ptr, PARAM_LLITE, NULL) == 0)) {
3396 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
3397 LCONSOLE_ERROR_MSG(0x148, "Upgraded client logs for %s"
3398 " cannot be modified. Consider"
3399 " updating the configuration with"
3402 GOTO(end, rc = -EINVAL);
3404 if (memcmp(ptr, PARAM_LLITE, strlen(PARAM_LLITE)) == 0) {
3405 rc = name_create(&cname, mti->mti_fsname, "-client");
3406 /* Add the client type to match the obdname in
3407 class_config_llog_handler */
3408 } else if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
3409 rc = name_create(&cname, mti->mti_svname, "-mdc");
3410 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
3411 rc = name_create(&cname, mti->mti_svname, "-osc");
3413 GOTO(end, rc = -EINVAL);
3418 /* Forbid direct update of llite root squash parameters.
3419 * These parameters are indirectly set via the MDT settings.
3421 if ((class_match_param(ptr, PARAM_LLITE, &tmp) == 0) &&
3422 ((memcmp(tmp, "root_squash=", 12) == 0) ||
3423 (memcmp(tmp, "nosquash_nids=", 14) == 0))) {
3424 LCONSOLE_ERROR("%s: root squash parameters can only "
3425 "be updated through MDT component\n",
3427 name_destroy(&cname);
3428 GOTO(end, rc = -EINVAL);
3431 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
3434 rc = name_create(&logname, mti->mti_fsname, "-client");
3436 name_destroy(&cname);
3439 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname, &mgi->mgi_bufs,
3442 /* osc params affect the MDT as well */
3443 if (!rc && (mti->mti_flags & LDD_F_SV_TYPE_OST)) {
3446 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
3447 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
3449 name_destroy(&cname);
3450 rc = name_create_mdt_osc(&cname, mti->mti_svname,
3452 name_destroy(&logname);
3455 rc = name_create_mdt(&logname,
3456 mti->mti_fsname, i);
3459 if (!mgs_log_is_empty(env, mgs, logname)) {
3460 rc = mgs_wlp_lcfg(env, mgs, fsdb,
3469 name_destroy(&logname);
3470 name_destroy(&cname);
3474 /* All mdt. params in proc */
3475 if (class_match_param(ptr, PARAM_MDT, &tmp) == 0) {
3479 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
3480 if (strncmp(mti->mti_svname, mti->mti_fsname,
3481 MTI_NAME_MAXLEN) == 0)
3482 /* device is unspecified completely? */
3483 rc = LDD_F_SV_TYPE_MDT | LDD_F_SV_ALL;
3485 rc = server_name2index(mti->mti_svname, &idx, NULL);
3488 if ((rc & LDD_F_SV_TYPE_MDT) == 0)
3490 if (rc & LDD_F_SV_ALL) {
3491 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3493 fsdb->fsdb_mdt_index_map))
3495 rc = name_create_mdt(&logname,
3496 mti->mti_fsname, i);
3499 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti,
3500 logname, &mgi->mgi_bufs,
3502 name_destroy(&logname);
3507 if ((memcmp(tmp, "root_squash=", 12) == 0) ||
3508 (memcmp(tmp, "nosquash_nids=", 14) == 0)) {
3509 LCONSOLE_ERROR("%s: root squash parameters "
3510 "cannot be applied to a single MDT\n",
3512 GOTO(end, rc = -EINVAL);
3514 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti,
3515 mti->mti_svname, &mgi->mgi_bufs,
3516 mti->mti_svname, ptr);
3521 /* root squash settings are also applied to llite
3522 * config log (see LU-1778) */
3524 ((memcmp(tmp, "root_squash=", 12) == 0) ||
3525 (memcmp(tmp, "nosquash_nids=", 14) == 0))) {
3529 rc = name_create(&cname, mti->mti_fsname, "-client");
3532 rc = name_create(&logname, mti->mti_fsname, "-client");
3534 name_destroy(&cname);
3537 rc = name_create(&ptr2, PARAM_LLITE, tmp);
3539 name_destroy(&cname);
3540 name_destroy(&logname);
3543 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname,
3544 &mgi->mgi_bufs, cname, ptr2);
3545 name_destroy(&ptr2);
3546 name_destroy(&logname);
3547 name_destroy(&cname);
3552 /* All mdd., ost. and osd. params in proc */
3553 if ((class_match_param(ptr, PARAM_MDD, NULL) == 0) ||
3554 (class_match_param(ptr, PARAM_OST, NULL) == 0) ||
3555 (class_match_param(ptr, PARAM_OSD, NULL) == 0)) {
3556 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
3557 if (mgs_log_is_empty(env, mgs, mti->mti_svname))
3558 GOTO(end, rc = -ENODEV);
3560 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, mti->mti_svname,
3561 &mgi->mgi_bufs, mti->mti_svname, ptr);
3565 LCONSOLE_WARN("Ignoring unrecognized param '%s'\n", ptr);
3570 CERROR("err %d on param '%s'\n", rc, ptr);
3575 /* Not implementing automatic failover nid addition at this time. */
3576 int mgs_check_failnid(const struct lu_env *env, struct mgs_device *mgs,
3577 struct mgs_target_info *mti)
3584 rc = mgs_find_or_make_fsdb(obd, fsname, &fsdb);
3588 if (mgs_log_is_empty(obd, mti->mti_svname))
3589 /* should never happen */
3592 CDEBUG(D_MGS, "Checking for new failnids for %s\n", mti->mti_svname);
3594 /* FIXME We can just check mti->params to see if we're already in
3595 the failover list. Modify mti->params for rewriting back at
3596 server_register_target(). */
3598 mutex_lock(&fsdb->fsdb_mutex);
3599 rc = mgs_write_log_add_failnid(obd, fsdb, mti);
3600 mutex_unlock(&fsdb->fsdb_mutex);
3609 int mgs_write_log_target(const struct lu_env *env, struct mgs_device *mgs,
3610 struct mgs_target_info *mti, struct fs_db *fsdb)
3617 /* set/check the new target index */
3618 rc = mgs_set_index(env, mgs, mti);
3622 if (rc == EALREADY) {
3623 LCONSOLE_WARN("Found index %d for %s, updating log\n",
3624 mti->mti_stripe_index, mti->mti_svname);
3625 /* We would like to mark old log sections as invalid
3626 and add new log sections in the client and mdt logs.
3627 But if we add new sections, then live clients will
3628 get repeat setup instructions for already running
3629 osc's. So don't update the client/mdt logs. */
3630 mti->mti_flags &= ~LDD_F_UPDATE;
3634 mutex_lock(&fsdb->fsdb_mutex);
3636 if (mti->mti_flags &
3637 (LDD_F_VIRGIN | LDD_F_UPGRADE14 | LDD_F_WRITECONF)) {
3638 /* Generate a log from scratch */
3639 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
3640 rc = mgs_write_log_mdt(env, mgs, fsdb, mti);
3641 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
3642 rc = mgs_write_log_ost(env, mgs, fsdb, mti);
3644 CERROR("Unknown target type %#x, can't create log for "
3645 "%s\n", mti->mti_flags, mti->mti_svname);
3648 CERROR("Can't write logs for %s (%d)\n",
3649 mti->mti_svname, rc);
3653 /* Just update the params from tunefs in mgs_write_log_params */
3654 CDEBUG(D_MGS, "Update params for %s\n", mti->mti_svname);
3655 mti->mti_flags |= LDD_F_PARAM;
3658 /* allocate temporary buffer, where class_get_next_param will
3659 make copy of a current parameter */
3660 OBD_ALLOC(buf, strlen(mti->mti_params) + 1);
3662 GOTO(out_up, rc = -ENOMEM);
3663 params = mti->mti_params;
3664 while (params != NULL) {
3665 rc = class_get_next_param(¶ms, buf);
3668 /* there is no next parameter, that is
3673 CDEBUG(D_MGS, "remaining string: '%s', param: '%s'\n",
3675 rc = mgs_write_log_param(env, mgs, fsdb, mti, buf);
3680 OBD_FREE(buf, strlen(mti->mti_params) + 1);
3683 mutex_unlock(&fsdb->fsdb_mutex);
3687 int mgs_erase_log(const struct lu_env *env, struct mgs_device *mgs, char *name)
3689 struct llog_ctxt *ctxt;
3692 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
3694 CERROR("%s: MGS config context doesn't exist\n",
3695 mgs->mgs_obd->obd_name);
3698 rc = llog_erase(env, ctxt, NULL, name);
3699 /* llog may not exist */
3702 llog_ctxt_put(ctxt);
3706 CERROR("%s: failed to clear log %s: %d\n",
3707 mgs->mgs_obd->obd_name, name, rc);
3712 /* erase all logs for the given fs */
3713 int mgs_erase_logs(const struct lu_env *env, struct mgs_device *mgs, char *fsname)
3716 struct list_head log_list;
3717 struct mgs_direntry *dirent, *n;
3718 int rc, len = strlen(fsname);
3722 /* Find all the logs in the CONFIGS directory */
3723 rc = class_dentry_readdir(env, mgs, &log_list);
3727 mutex_lock(&mgs->mgs_mutex);
3729 /* Delete the fs db */
3730 fsdb = mgs_find_fsdb(mgs, fsname);
3732 mgs_free_fsdb(mgs, fsdb);
3734 mutex_unlock(&mgs->mgs_mutex);
3736 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
3737 list_del_init(&dirent->mde_list);
3738 suffix = strrchr(dirent->mde_name, '-');
3739 if (suffix != NULL) {
3740 if ((len == suffix - dirent->mde_name) &&
3741 (strncmp(fsname, dirent->mde_name, len) == 0)) {
3742 CDEBUG(D_MGS, "Removing log %s\n",
3744 mgs_erase_log(env, mgs, dirent->mde_name);
3747 mgs_direntry_free(dirent);
3753 /* list all logs for the given fs */
3754 int mgs_list_logs(const struct lu_env *env, struct mgs_device *mgs,
3755 struct obd_ioctl_data *data)
3757 struct list_head log_list;
3758 struct mgs_direntry *dirent, *n;
3764 /* Find all the logs in the CONFIGS directory */
3765 rc = class_dentry_readdir(env, mgs, &log_list);
3769 out = data->ioc_bulk;
3770 remains = data->ioc_inllen1;
3771 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
3772 list_del_init(&dirent->mde_list);
3773 suffix = strrchr(dirent->mde_name, '-');
3774 if (suffix != NULL) {
3775 l = snprintf(out, remains, "config log: $%s\n",
3780 mgs_direntry_free(dirent);
3787 /* from llog_swab */
3788 static void print_lustre_cfg(struct lustre_cfg *lcfg)
3793 CDEBUG(D_MGS, "lustre_cfg: %p\n", lcfg);
3794 CDEBUG(D_MGS, "\tlcfg->lcfg_version: %#x\n", lcfg->lcfg_version);
3796 CDEBUG(D_MGS, "\tlcfg->lcfg_command: %#x\n", lcfg->lcfg_command);
3797 CDEBUG(D_MGS, "\tlcfg->lcfg_num: %#x\n", lcfg->lcfg_num);
3798 CDEBUG(D_MGS, "\tlcfg->lcfg_flags: %#x\n", lcfg->lcfg_flags);
3799 CDEBUG(D_MGS, "\tlcfg->lcfg_nid: %s\n", libcfs_nid2str(lcfg->lcfg_nid));
3801 CDEBUG(D_MGS, "\tlcfg->lcfg_bufcount: %d\n", lcfg->lcfg_bufcount);
3802 if (lcfg->lcfg_bufcount < LUSTRE_CFG_MAX_BUFCOUNT)
3803 for (i = 0; i < lcfg->lcfg_bufcount; i++) {
3804 CDEBUG(D_MGS, "\tlcfg->lcfg_buflens[%d]: %d %s\n",
3805 i, lcfg->lcfg_buflens[i],
3806 lustre_cfg_string(lcfg, i));
3811 /* Setup params fsdb and log
3813 int mgs_params_fsdb_setup(const struct lu_env *env, struct mgs_device *mgs,
3816 struct llog_handle *params_llh = NULL;
3820 rc = mgs_find_or_make_fsdb(env, mgs, PARAMS_FILENAME, &fsdb);
3822 mutex_lock(&fsdb->fsdb_mutex);
3823 rc = record_start_log(env, mgs, ¶ms_llh, PARAMS_FILENAME);
3825 rc = record_end_log(env, ¶ms_llh);
3826 mutex_unlock(&fsdb->fsdb_mutex);
3832 /* Cleanup params fsdb and log
3834 int mgs_params_fsdb_cleanup(const struct lu_env *env, struct mgs_device *mgs)
3836 return mgs_erase_logs(env, mgs, PARAMS_FILENAME);
3839 /* Set a permanent (config log) param for a target or fs
3840 * \param lcfg buf0 may contain the device (testfs-MDT0000) name
3841 * buf1 contains the single parameter
3843 int mgs_setparam(const struct lu_env *env, struct mgs_device *mgs,
3844 struct lustre_cfg *lcfg, char *fsname)
3847 struct mgs_target_info *mti;
3848 char *devname, *param;
3855 print_lustre_cfg(lcfg);
3857 /* lustre, lustre-mdtlov, lustre-client, lustre-MDT0000 */
3858 devname = lustre_cfg_string(lcfg, 0);
3859 param = lustre_cfg_string(lcfg, 1);
3861 /* Assume device name embedded in param:
3862 lustre-OST0000.osc.max_dirty_mb=32 */
3863 ptr = strchr(param, '.');
3871 LCONSOLE_ERROR_MSG(0x14d, "No target specified: %s\n", param);
3875 rc = mgs_parse_devname(devname, fsname, NULL);
3876 if (rc == 0 && !mgs_parse_devname(devname, NULL, &index)) {
3877 /* param related to llite isn't allowed to set by OST or MDT */
3878 if (rc == 0 && strncmp(param, PARAM_LLITE,
3879 sizeof(PARAM_LLITE) - 1) == 0)
3882 /* assume devname is the fsname */
3883 strlcpy(fsname, devname, MTI_NAME_MAXLEN);
3885 CDEBUG(D_MGS, "setparam fs='%s' device='%s'\n", fsname, devname);
3887 rc = mgs_find_or_make_fsdb(env, mgs,
3888 lcfg->lcfg_command == LCFG_SET_PARAM ?
3889 PARAMS_FILENAME : fsname, &fsdb);
3893 if (lcfg->lcfg_command != LCFG_SET_PARAM &&
3894 !test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags) &&
3895 test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
3896 CERROR("No filesystem targets for %s. cfg_device from lctl "
3897 "is '%s'\n", fsname, devname);
3898 mgs_free_fsdb(mgs, fsdb);
3902 /* Create a fake mti to hold everything */
3905 GOTO(out, rc = -ENOMEM);
3906 if (strlcpy(mti->mti_fsname, fsname, sizeof(mti->mti_fsname))
3907 >= sizeof(mti->mti_fsname))
3908 GOTO(out, rc = -E2BIG);
3909 if (strlcpy(mti->mti_svname, devname, sizeof(mti->mti_svname))
3910 >= sizeof(mti->mti_svname))
3911 GOTO(out, rc = -E2BIG);
3912 if (strlcpy(mti->mti_params, param, sizeof(mti->mti_params))
3913 >= sizeof(mti->mti_params))
3914 GOTO(out, rc = -E2BIG);
3915 rc = server_name2index(mti->mti_svname, &mti->mti_stripe_index, &tmp);
3917 /* Not a valid server; may be only fsname */
3920 /* Strip -osc or -mdc suffix from svname */
3921 if (server_make_name(rc, mti->mti_stripe_index, mti->mti_fsname,
3923 GOTO(out, rc = -EINVAL);
3925 * Revoke lock so everyone updates. Should be alright if
3926 * someone was already reading while we were updating the logs,
3927 * so we don't really need to hold the lock while we're
3930 if (lcfg->lcfg_command == LCFG_SET_PARAM) {
3931 mti->mti_flags = rc | LDD_F_PARAM2;
3932 mutex_lock(&fsdb->fsdb_mutex);
3933 rc = mgs_write_log_param2(env, mgs, fsdb, mti, mti->mti_params);
3934 mutex_unlock(&fsdb->fsdb_mutex);
3935 mgs_revoke_lock(mgs, fsdb, CONFIG_T_PARAMS);
3937 mti->mti_flags = rc | LDD_F_PARAM;
3938 mutex_lock(&fsdb->fsdb_mutex);
3939 rc = mgs_write_log_param(env, mgs, fsdb, mti, mti->mti_params);
3940 mutex_unlock(&fsdb->fsdb_mutex);
3941 mgs_revoke_lock(mgs, fsdb, CONFIG_T_CONFIG);
3949 static int mgs_write_log_pool(const struct lu_env *env,
3950 struct mgs_device *mgs, char *logname,
3951 struct fs_db *fsdb, char *tgtname,
3952 enum lcfg_command_type cmd,
3953 char *fsname, char *poolname,
3954 char *ostname, char *comment)
3956 struct llog_handle *llh = NULL;
3959 rc = record_start_log(env, mgs, &llh, logname);
3962 rc = record_marker(env, llh, fsdb, CM_START, tgtname, comment);
3965 rc = record_base(env, llh, tgtname, 0, cmd,
3966 fsname, poolname, ostname, 0);
3969 rc = record_marker(env, llh, fsdb, CM_END, tgtname, comment);
3971 record_end_log(env, &llh);
3975 int mgs_nodemap_cmd(const struct lu_env *env, struct mgs_device *mgs,
3976 enum lcfg_command_type cmd, const char *nodemap_name,
3987 case LCFG_NODEMAP_ADD:
3988 rc = nodemap_add(nodemap_name);
3990 case LCFG_NODEMAP_DEL:
3991 rc = nodemap_del(nodemap_name);
3993 case LCFG_NODEMAP_ADD_RANGE:
3994 rc = nodemap_parse_range(param, nid);
3997 rc = nodemap_add_range(nodemap_name, nid);
3999 case LCFG_NODEMAP_DEL_RANGE:
4000 rc = nodemap_parse_range(param, nid);
4003 rc = nodemap_del_range(nodemap_name, nid);
4005 case LCFG_NODEMAP_ADMIN:
4006 bool_switch = simple_strtoul(param, NULL, 10);
4007 rc = nodemap_set_allow_root(nodemap_name, bool_switch);
4009 case LCFG_NODEMAP_TRUSTED:
4010 bool_switch = simple_strtoul(param, NULL, 10);
4011 rc = nodemap_set_trust_client_ids(nodemap_name, bool_switch);
4013 case LCFG_NODEMAP_SQUASH_UID:
4014 int_id = simple_strtoul(param, NULL, 10);
4015 rc = nodemap_set_squash_uid(nodemap_name, int_id);
4017 case LCFG_NODEMAP_SQUASH_GID:
4018 int_id = simple_strtoul(param, NULL, 10);
4019 rc = nodemap_set_squash_gid(nodemap_name, int_id);
4021 case LCFG_NODEMAP_ADD_UIDMAP:
4022 case LCFG_NODEMAP_ADD_GIDMAP:
4023 rc = nodemap_parse_idmap(param, idmap);
4026 if (cmd == LCFG_NODEMAP_ADD_UIDMAP)
4027 rc = nodemap_add_idmap(nodemap_name, NODEMAP_UID,
4030 rc = nodemap_add_idmap(nodemap_name, NODEMAP_GID,
4033 case LCFG_NODEMAP_DEL_UIDMAP:
4034 case LCFG_NODEMAP_DEL_GIDMAP:
4035 rc = nodemap_parse_idmap(param, idmap);
4038 if (cmd == LCFG_NODEMAP_DEL_UIDMAP)
4039 rc = nodemap_del_idmap(nodemap_name, NODEMAP_UID,
4042 rc = nodemap_del_idmap(nodemap_name, NODEMAP_GID,
4052 int mgs_pool_cmd(const struct lu_env *env, struct mgs_device *mgs,
4053 enum lcfg_command_type cmd, char *fsname,
4054 char *poolname, char *ostname)
4059 char *label = NULL, *canceled_label = NULL;
4061 struct mgs_target_info *mti = NULL;
4065 rc = mgs_find_or_make_fsdb(env, mgs, fsname, &fsdb);
4067 CERROR("Can't get db for %s\n", fsname);
4070 if (test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
4071 CERROR("%s is not defined\n", fsname);
4072 mgs_free_fsdb(mgs, fsdb);
4076 label_sz = 10 + strlen(fsname) + strlen(poolname);
4078 /* check if ostname match fsname */
4079 if (ostname != NULL) {
4082 ptr = strrchr(ostname, '-');
4083 if ((ptr == NULL) ||
4084 (strncmp(fsname, ostname, ptr-ostname) != 0))
4086 label_sz += strlen(ostname);
4089 OBD_ALLOC(label, label_sz);
4096 "new %s.%s", fsname, poolname);
4100 "add %s.%s.%s", fsname, poolname, ostname);
4103 OBD_ALLOC(canceled_label, label_sz);
4104 if (canceled_label == NULL)
4105 GOTO(out_label, rc = -ENOMEM);
4107 "rem %s.%s.%s", fsname, poolname, ostname);
4108 sprintf(canceled_label,
4109 "add %s.%s.%s", fsname, poolname, ostname);
4112 OBD_ALLOC(canceled_label, label_sz);
4113 if (canceled_label == NULL)
4114 GOTO(out_label, rc = -ENOMEM);
4116 "del %s.%s", fsname, poolname);
4117 sprintf(canceled_label,
4118 "new %s.%s", fsname, poolname);
4124 if (canceled_label != NULL) {
4127 GOTO(out_cancel, rc = -ENOMEM);
4130 mutex_lock(&fsdb->fsdb_mutex);
4131 /* write pool def to all MDT logs */
4132 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
4133 if (test_bit(i, fsdb->fsdb_mdt_index_map)) {
4134 rc = name_create_mdt_and_lov(&logname, &lovname,
4137 mutex_unlock(&fsdb->fsdb_mutex);
4140 if (canceled_label != NULL) {
4141 strcpy(mti->mti_svname, "lov pool");
4142 rc = mgs_modify(env, mgs, fsdb, mti, logname,
4143 lovname, canceled_label,
4148 rc = mgs_write_log_pool(env, mgs, logname,
4152 name_destroy(&logname);
4153 name_destroy(&lovname);
4155 mutex_unlock(&fsdb->fsdb_mutex);
4161 rc = name_create(&logname, fsname, "-client");
4163 mutex_unlock(&fsdb->fsdb_mutex);
4166 if (canceled_label != NULL) {
4167 rc = mgs_modify(env, mgs, fsdb, mti, logname,
4168 fsdb->fsdb_clilov, canceled_label, CM_SKIP);
4170 mutex_unlock(&fsdb->fsdb_mutex);
4171 name_destroy(&logname);
4176 rc = mgs_write_log_pool(env, mgs, logname, fsdb, fsdb->fsdb_clilov,
4177 cmd, fsname, poolname, ostname, label);
4178 mutex_unlock(&fsdb->fsdb_mutex);
4179 name_destroy(&logname);
4180 /* request for update */
4181 mgs_revoke_lock(mgs, fsdb, CONFIG_T_CONFIG);
4188 if (canceled_label != NULL)
4189 OBD_FREE(canceled_label, label_sz);
4191 OBD_FREE(label, label_sz);