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 static int mgs_write_log_direct_all(const struct lu_env *env,
1446 struct mgs_device *mgs,
1448 struct mgs_target_info *mti,
1449 struct llog_cfg_rec *lcr, char *devname,
1450 char *comment, int server_only)
1452 struct list_head log_list;
1453 struct mgs_direntry *dirent, *n;
1454 char *fsname = mti->mti_fsname;
1455 int rc = 0, len = strlen(fsname);
1458 /* Find all the logs in the CONFIGS directory */
1459 rc = class_dentry_readdir(env, mgs, &log_list);
1463 /* Could use fsdb index maps instead of directory listing */
1464 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
1465 list_del_init(&dirent->mde_list);
1466 /* don't write to sptlrpc rule log */
1467 if (strstr(dirent->mde_name, "-sptlrpc") != NULL)
1470 /* caller wants write server logs only */
1471 if (server_only && strstr(dirent->mde_name, "-client") != NULL)
1474 if (strlen(dirent->mde_name) <= len ||
1475 strncmp(fsname, dirent->mde_name, len) != 0 ||
1476 dirent->mde_name[len] != '-')
1479 CDEBUG(D_MGS, "Changing log %s\n", dirent->mde_name);
1480 /* Erase any old settings of this same parameter */
1481 rc = mgs_modify(env, mgs, fsdb, mti, dirent->mde_name,
1482 devname, comment, CM_SKIP);
1484 CERROR("%s: Can't modify llog %s: rc = %d\n",
1485 mgs->mgs_obd->obd_name, dirent->mde_name, rc);
1488 /* Write the new one */
1489 rc = mgs_write_log_direct(env, mgs, fsdb, dirent->mde_name,
1490 lcr, devname, comment);
1492 CERROR("%s: writing log %s: rc = %d\n",
1493 mgs->mgs_obd->obd_name, dirent->mde_name, rc);
1495 mgs_direntry_free(dirent);
1501 static int mgs_write_log_osp_to_mdt(const struct lu_env *env,
1502 struct mgs_device *mgs,
1504 struct mgs_target_info *mti,
1505 int index, char *logname);
1506 static int mgs_write_log_osc_to_lov(const struct lu_env *env,
1507 struct mgs_device *mgs,
1509 struct mgs_target_info *mti,
1510 char *logname, char *suffix, char *lovname,
1511 enum lustre_sec_part sec_part, int flags);
1512 static int name_create_mdt_and_lov(char **logname, char **lovname,
1513 struct fs_db *fsdb, int i);
1515 static int add_param(char *params, char *key, char *val)
1517 char *start = params + strlen(params);
1518 char *end = params + sizeof(((struct mgs_target_info *)0)->mti_params);
1522 keylen = strlen(key);
1523 if (start + 1 + keylen + strlen(val) >= end) {
1524 CERROR("params are too long: %s %s%s\n",
1525 params, key != NULL ? key : "", val);
1529 sprintf(start, " %s%s", key != NULL ? key : "", val);
1534 * Walk through client config log record and convert the related records
1537 static int mgs_steal_client_llog_handler(const struct lu_env *env,
1538 struct llog_handle *llh,
1539 struct llog_rec_hdr *rec, void *data)
1541 struct mgs_device *mgs;
1542 struct obd_device *obd;
1543 struct mgs_target_info *mti, *tmti;
1545 int cfg_len = rec->lrh_len;
1546 char *cfg_buf = (char*) (rec + 1);
1547 struct lustre_cfg *lcfg;
1549 struct llog_handle *mdt_llh = NULL;
1550 static int got_an_osc_or_mdc = 0;
1551 /* 0: not found any osc/mdc;
1555 static int last_step = -1;
1560 mti = ((struct temp_comp*)data)->comp_mti;
1561 tmti = ((struct temp_comp*)data)->comp_tmti;
1562 fsdb = ((struct temp_comp*)data)->comp_fsdb;
1563 obd = ((struct temp_comp *)data)->comp_obd;
1564 mgs = lu2mgs_dev(obd->obd_lu_dev);
1567 if (rec->lrh_type != OBD_CFG_REC) {
1568 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
1572 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
1574 CERROR("Insane cfg\n");
1578 lcfg = (struct lustre_cfg *)cfg_buf;
1580 if (lcfg->lcfg_command == LCFG_MARKER) {
1581 struct cfg_marker *marker;
1582 marker = lustre_cfg_buf(lcfg, 1);
1583 if (!strncmp(marker->cm_comment, "add osc", 7) &&
1584 (marker->cm_flags & CM_START) &&
1585 !(marker->cm_flags & CM_SKIP)) {
1586 got_an_osc_or_mdc = 1;
1587 cplen = strlcpy(tmti->mti_svname, marker->cm_tgtname,
1588 sizeof(tmti->mti_svname));
1589 if (cplen >= sizeof(tmti->mti_svname))
1591 rc = record_start_log(env, mgs, &mdt_llh,
1595 rc = record_marker(env, mdt_llh, fsdb, CM_START,
1596 mti->mti_svname, "add osc(copied)");
1597 record_end_log(env, &mdt_llh);
1598 last_step = marker->cm_step;
1601 if (!strncmp(marker->cm_comment, "add osc", 7) &&
1602 (marker->cm_flags & CM_END) &&
1603 !(marker->cm_flags & CM_SKIP)) {
1604 LASSERT(last_step == marker->cm_step);
1606 got_an_osc_or_mdc = 0;
1607 memset(tmti, 0, sizeof(*tmti));
1608 rc = record_start_log(env, mgs, &mdt_llh,
1612 rc = record_marker(env, mdt_llh, fsdb, CM_END,
1613 mti->mti_svname, "add osc(copied)");
1614 record_end_log(env, &mdt_llh);
1617 if (!strncmp(marker->cm_comment, "add mdc", 7) &&
1618 (marker->cm_flags & CM_START) &&
1619 !(marker->cm_flags & CM_SKIP)) {
1620 got_an_osc_or_mdc = 2;
1621 last_step = marker->cm_step;
1622 memcpy(tmti->mti_svname, marker->cm_tgtname,
1623 strlen(marker->cm_tgtname));
1627 if (!strncmp(marker->cm_comment, "add mdc", 7) &&
1628 (marker->cm_flags & CM_END) &&
1629 !(marker->cm_flags & CM_SKIP)) {
1630 LASSERT(last_step == marker->cm_step);
1632 got_an_osc_or_mdc = 0;
1633 memset(tmti, 0, sizeof(*tmti));
1638 if (got_an_osc_or_mdc == 0 || last_step < 0)
1641 if (lcfg->lcfg_command == LCFG_ADD_UUID) {
1642 uint64_t nodenid = lcfg->lcfg_nid;
1644 if (strlen(tmti->mti_uuid) == 0) {
1645 /* target uuid not set, this config record is before
1646 * LCFG_SETUP, this nid is one of target node nid.
1648 tmti->mti_nids[tmti->mti_nid_count] = nodenid;
1649 tmti->mti_nid_count++;
1651 /* failover node nid */
1652 rc = add_param(tmti->mti_params, PARAM_FAILNODE,
1653 libcfs_nid2str(nodenid));
1659 if (lcfg->lcfg_command == LCFG_SETUP) {
1662 target = lustre_cfg_string(lcfg, 1);
1663 memcpy(tmti->mti_uuid, target, strlen(target));
1667 /* ignore client side sptlrpc_conf_log */
1668 if (lcfg->lcfg_command == LCFG_SPTLRPC_CONF)
1671 if (lcfg->lcfg_command == LCFG_ADD_MDC) {
1674 if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1)
1677 memcpy(tmti->mti_fsname, mti->mti_fsname,
1678 strlen(mti->mti_fsname));
1679 tmti->mti_stripe_index = index;
1681 rc = mgs_write_log_osp_to_mdt(env, mgs, fsdb, tmti,
1682 mti->mti_stripe_index,
1684 memset(tmti, 0, sizeof(*tmti));
1688 if (lcfg->lcfg_command == LCFG_LOV_ADD_OBD) {
1691 char *logname, *lovname;
1693 rc = name_create_mdt_and_lov(&logname, &lovname, fsdb,
1694 mti->mti_stripe_index);
1697 sprintf(mdt_index, "-MDT%04x", mti->mti_stripe_index);
1699 if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1) {
1700 name_destroy(&logname);
1701 name_destroy(&lovname);
1705 tmti->mti_stripe_index = index;
1706 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, tmti, logname,
1709 name_destroy(&logname);
1710 name_destroy(&lovname);
1716 /* fsdb->fsdb_mutex is already held in mgs_write_log_target*/
1717 /* stealed from mgs_get_fsdb_from_llog*/
1718 static int mgs_steal_llog_for_mdt_from_client(const struct lu_env *env,
1719 struct mgs_device *mgs,
1721 struct temp_comp* comp)
1723 struct llog_handle *loghandle;
1724 struct mgs_target_info *tmti;
1725 struct llog_ctxt *ctxt;
1730 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
1731 LASSERT(ctxt != NULL);
1733 OBD_ALLOC_PTR(tmti);
1735 GOTO(out_ctxt, rc = -ENOMEM);
1737 comp->comp_tmti = tmti;
1738 comp->comp_obd = mgs->mgs_obd;
1740 rc = llog_open(env, ctxt, &loghandle, NULL, client_name,
1748 rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL);
1750 GOTO(out_close, rc);
1752 rc = llog_process_or_fork(env, loghandle, mgs_steal_client_llog_handler,
1753 (void *)comp, NULL, false);
1754 CDEBUG(D_MGS, "steal llog re = %d\n", rc);
1756 llog_close(env, loghandle);
1760 llog_ctxt_put(ctxt);
1764 /* lmv is the second thing for client logs */
1765 /* copied from mgs_write_log_lov. Please refer to that. */
1766 static int mgs_write_log_lmv(const struct lu_env *env,
1767 struct mgs_device *mgs,
1769 struct mgs_target_info *mti,
1770 char *logname, char *lmvname)
1772 struct llog_handle *llh = NULL;
1773 struct lmv_desc *lmvdesc;
1778 CDEBUG(D_MGS, "Writing lmv(%s) log for %s\n", lmvname,logname);
1780 OBD_ALLOC_PTR(lmvdesc);
1781 if (lmvdesc == NULL)
1783 lmvdesc->ld_active_tgt_count = 0;
1784 lmvdesc->ld_tgt_count = 0;
1785 sprintf((char*)lmvdesc->ld_uuid.uuid, "%s_UUID", lmvname);
1786 uuid = (char *)lmvdesc->ld_uuid.uuid;
1788 rc = record_start_log(env, mgs, &llh, logname);
1791 rc = record_marker(env, llh, fsdb, CM_START, lmvname, "lmv setup");
1794 rc = record_attach(env, llh, lmvname, "lmv", uuid);
1797 rc = record_lmv_setup(env, llh, lmvname, lmvdesc);
1800 rc = record_marker(env, llh, fsdb, CM_END, lmvname, "lmv setup");
1804 record_end_log(env, &llh);
1806 OBD_FREE_PTR(lmvdesc);
1810 /* lov is the first thing in the mdt and client logs */
1811 static int mgs_write_log_lov(const struct lu_env *env, struct mgs_device *mgs,
1812 struct fs_db *fsdb, struct mgs_target_info *mti,
1813 char *logname, char *lovname)
1815 struct llog_handle *llh = NULL;
1816 struct lov_desc *lovdesc;
1821 CDEBUG(D_MGS, "Writing lov(%s) log for %s\n", lovname, logname);
1824 #01 L attach 0:lov_mdsA 1:lov 2:71ccb_lov_mdsA_19f961a9e1
1825 #02 L lov_setup 0:lov_mdsA 1:(struct lov_desc)
1826 uuid=lov1_UUID, stripe count=1, size=1048576, offset=0, pattern=0
1829 /* FIXME just make lov_setup accept empty desc (put uuid in buf 2) */
1830 OBD_ALLOC_PTR(lovdesc);
1831 if (lovdesc == NULL)
1833 lovdesc->ld_magic = LOV_DESC_MAGIC;
1834 lovdesc->ld_tgt_count = 0;
1835 /* Defaults. Can be changed later by lcfg config_param */
1836 lovdesc->ld_default_stripe_count = 1;
1837 lovdesc->ld_pattern = LOV_PATTERN_RAID0;
1838 lovdesc->ld_default_stripe_size = LOV_DESC_STRIPE_SIZE_DEFAULT;
1839 lovdesc->ld_default_stripe_offset = -1;
1840 lovdesc->ld_qos_maxage = LOV_DESC_QOS_MAXAGE_DEFAULT;
1841 sprintf((char*)lovdesc->ld_uuid.uuid, "%s_UUID", lovname);
1842 /* can these be the same? */
1843 uuid = (char *)lovdesc->ld_uuid.uuid;
1845 /* This should always be the first entry in a log.
1846 rc = mgs_clear_log(obd, logname); */
1847 rc = record_start_log(env, mgs, &llh, logname);
1850 /* FIXME these should be a single journal transaction */
1851 rc = record_marker(env, llh, fsdb, CM_START, lovname, "lov setup");
1854 rc = record_attach(env, llh, lovname, "lov", uuid);
1857 rc = record_lov_setup(env, llh, lovname, lovdesc);
1860 rc = record_marker(env, llh, fsdb, CM_END, lovname, "lov setup");
1865 record_end_log(env, &llh);
1867 OBD_FREE_PTR(lovdesc);
1871 /* add failnids to open log */
1872 static int mgs_write_log_failnids(const struct lu_env *env,
1873 struct mgs_target_info *mti,
1874 struct llog_handle *llh,
1877 char *failnodeuuid = NULL;
1878 char *ptr = mti->mti_params;
1883 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) nal=90 0: 1:uml1_UUID
1884 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
1885 #05 L setup 0:OSC_uml1_ost1_mdsA 1:ost1_UUID 2:uml1_UUID
1886 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) nal=90 0: 1:uml2_UUID
1887 #0x L add_uuid nid=2@elan(0x1000000000002) nal=90 0: 1:uml2_UUID
1888 #07 L add_conn 0:OSC_uml1_ost1_mdsA 1:uml2_UUID
1892 * Pull failnid info out of params string, which may contain something
1893 * like "<nid1>,<nid2>:<nid3>,<nid4>". class_parse_nid() does not
1894 * complain about abnormal inputs like ",:<nid1>", "<nid1>:,<nid2>",
1895 * etc. However, convert_hostnames() should have caught those.
1897 while (class_find_param(ptr, PARAM_FAILNODE, &ptr) == 0) {
1898 while (class_parse_nid(ptr, &nid, &ptr) == 0) {
1899 if (failnodeuuid == NULL) {
1900 /* We don't know the failover node name,
1901 so just use the first nid as the uuid */
1902 rc = name_create(&failnodeuuid,
1903 libcfs_nid2str(nid), "");
1907 CDEBUG(D_MGS, "add nid %s for failover uuid %s, "
1908 "client %s\n", libcfs_nid2str(nid),
1909 failnodeuuid, cliname);
1910 rc = record_add_uuid(env, llh, nid, failnodeuuid);
1912 * If *ptr is ':', we have added all NIDs for
1916 rc = record_add_conn(env, llh, cliname,
1918 name_destroy(&failnodeuuid);
1919 failnodeuuid = NULL;
1923 rc = record_add_conn(env, llh, cliname, failnodeuuid);
1924 name_destroy(&failnodeuuid);
1925 failnodeuuid = NULL;
1932 static int mgs_write_log_mdc_to_lmv(const struct lu_env *env,
1933 struct mgs_device *mgs,
1935 struct mgs_target_info *mti,
1936 char *logname, char *lmvname)
1938 struct llog_handle *llh = NULL;
1939 char *mdcname = NULL;
1940 char *nodeuuid = NULL;
1941 char *mdcuuid = NULL;
1942 char *lmvuuid = NULL;
1947 if (mgs_log_is_empty(env, mgs, logname)) {
1948 CERROR("log is empty! Logical error\n");
1952 CDEBUG(D_MGS, "adding mdc for %s to log %s:lmv(%s)\n",
1953 mti->mti_svname, logname, lmvname);
1955 rc = name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
1958 rc = name_create(&mdcname, mti->mti_svname, "-mdc");
1961 rc = name_create(&mdcuuid, mdcname, "_UUID");
1964 rc = name_create(&lmvuuid, lmvname, "_UUID");
1968 rc = record_start_log(env, mgs, &llh, logname);
1971 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
1975 for (i = 0; i < mti->mti_nid_count; i++) {
1976 CDEBUG(D_MGS, "add nid %s for mdt\n",
1977 libcfs_nid2str(mti->mti_nids[i]));
1979 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
1984 rc = record_attach(env, llh, mdcname, LUSTRE_MDC_NAME, lmvuuid);
1987 rc = record_setup(env, llh, mdcname, mti->mti_uuid, nodeuuid, 0, 0);
1990 rc = mgs_write_log_failnids(env, mti, llh, mdcname);
1993 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
1994 rc = record_mdc_add(env, llh, lmvname, mdcuuid, mti->mti_uuid,
1998 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname,
2003 record_end_log(env, &llh);
2005 name_destroy(&lmvuuid);
2006 name_destroy(&mdcuuid);
2007 name_destroy(&mdcname);
2008 name_destroy(&nodeuuid);
2012 static inline int name_create_lov(char **lovname, char *mdtname,
2013 struct fs_db *fsdb, int index)
2016 if (index == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2017 return name_create(lovname, fsdb->fsdb_name, "-mdtlov");
2019 return name_create(lovname, mdtname, "-mdtlov");
2022 static int name_create_mdt_and_lov(char **logname, char **lovname,
2023 struct fs_db *fsdb, int i)
2027 rc = name_create_mdt(logname, fsdb->fsdb_name, i);
2031 if (i == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2032 rc = name_create(lovname, fsdb->fsdb_name, "-mdtlov");
2034 rc = name_create(lovname, *logname, "-mdtlov");
2036 name_destroy(logname);
2042 static inline int name_create_mdt_osc(char **oscname, char *ostname,
2043 struct fs_db *fsdb, int i)
2047 if (i == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2048 sprintf(suffix, "-osc");
2050 sprintf(suffix, "-osc-MDT%04x", i);
2051 return name_create(oscname, ostname, suffix);
2054 /* add new mdc to already existent MDS */
2055 static int mgs_write_log_osp_to_mdt(const struct lu_env *env,
2056 struct mgs_device *mgs,
2058 struct mgs_target_info *mti,
2059 int mdt_index, char *logname)
2061 struct llog_handle *llh = NULL;
2062 char *nodeuuid = NULL;
2063 char *ospname = NULL;
2064 char *lovuuid = NULL;
2065 char *mdtuuid = NULL;
2066 char *svname = NULL;
2067 char *mdtname = NULL;
2068 char *lovname = NULL;
2073 if (mgs_log_is_empty(env, mgs, mti->mti_svname)) {
2074 CERROR("log is empty! Logical error\n");
2078 CDEBUG(D_MGS, "adding osp index %d to %s\n", mti->mti_stripe_index,
2081 rc = name_create_mdt(&mdtname, fsdb->fsdb_name, mti->mti_stripe_index);
2085 rc = name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
2087 GOTO(out_destory, rc);
2089 rc = name_create(&svname, mdtname, "-osp");
2091 GOTO(out_destory, rc);
2093 sprintf(index_str, "-MDT%04x", mdt_index);
2094 rc = name_create(&ospname, svname, index_str);
2096 GOTO(out_destory, rc);
2098 rc = name_create_lov(&lovname, logname, fsdb, mdt_index);
2100 GOTO(out_destory, rc);
2102 rc = name_create(&lovuuid, lovname, "_UUID");
2104 GOTO(out_destory, rc);
2106 rc = name_create(&mdtuuid, mdtname, "_UUID");
2108 GOTO(out_destory, rc);
2110 rc = record_start_log(env, mgs, &llh, logname);
2112 GOTO(out_destory, rc);
2114 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
2117 GOTO(out_destory, rc);
2119 for (i = 0; i < mti->mti_nid_count; i++) {
2120 CDEBUG(D_MGS, "add nid %s for mdt\n",
2121 libcfs_nid2str(mti->mti_nids[i]));
2122 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
2127 rc = record_attach(env, llh, ospname, LUSTRE_OSP_NAME, lovuuid);
2131 rc = record_setup(env, llh, ospname, mti->mti_uuid, nodeuuid,
2136 rc = mgs_write_log_failnids(env, mti, llh, ospname);
2140 /* Add mdc(osp) to lod */
2141 snprintf(index_str, sizeof(mti->mti_stripe_index), "%d",
2142 mti->mti_stripe_index);
2143 rc = record_base(env, llh, lovname, 0, LCFG_ADD_MDC, mti->mti_uuid,
2144 index_str, "1", NULL);
2148 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname, "add osp");
2153 record_end_log(env, &llh);
2156 name_destroy(&mdtuuid);
2157 name_destroy(&lovuuid);
2158 name_destroy(&lovname);
2159 name_destroy(&ospname);
2160 name_destroy(&svname);
2161 name_destroy(&nodeuuid);
2162 name_destroy(&mdtname);
2166 static int mgs_write_log_mdt0(const struct lu_env *env,
2167 struct mgs_device *mgs,
2169 struct mgs_target_info *mti)
2171 char *log = mti->mti_svname;
2172 struct llog_handle *llh = NULL;
2173 char *uuid, *lovname;
2175 char *ptr = mti->mti_params;
2176 int rc = 0, failout = 0;
2179 OBD_ALLOC(uuid, sizeof(struct obd_uuid));
2183 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
2184 failout = (strncmp(ptr, "failout", 7) == 0);
2186 rc = name_create(&lovname, log, "-mdtlov");
2189 if (mgs_log_is_empty(env, mgs, log)) {
2190 rc = mgs_write_log_lov(env, mgs, fsdb, mti, log, lovname);
2195 sprintf(mdt_index, "%d", mti->mti_stripe_index);
2197 rc = record_start_log(env, mgs, &llh, log);
2201 /* add MDT itself */
2203 /* FIXME this whole fn should be a single journal transaction */
2204 sprintf(uuid, "%s_UUID", log);
2205 rc = record_marker(env, llh, fsdb, CM_START, log, "add mdt");
2208 rc = record_attach(env, llh, log, LUSTRE_MDT_NAME, uuid);
2211 rc = record_mount_opt(env, llh, log, lovname, NULL);
2214 rc = record_setup(env, llh, log, uuid, mdt_index, lovname,
2215 failout ? "n" : "f");
2218 rc = record_marker(env, llh, fsdb, CM_END, log, "add mdt");
2222 record_end_log(env, &llh);
2224 name_destroy(&lovname);
2226 OBD_FREE(uuid, sizeof(struct obd_uuid));
2230 /* envelope method for all layers log */
2231 static int mgs_write_log_mdt(const struct lu_env *env,
2232 struct mgs_device *mgs,
2234 struct mgs_target_info *mti)
2236 struct mgs_thread_info *mgi = mgs_env_info(env);
2237 struct llog_handle *llh = NULL;
2242 CDEBUG(D_MGS, "writing new mdt %s\n", mti->mti_svname);
2244 if (mti->mti_uuid[0] == '\0') {
2245 /* Make up our own uuid */
2246 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
2247 "%s_UUID", mti->mti_svname);
2251 rc = mgs_write_log_mdt0(env, mgs, fsdb, mti);
2254 /* Append the mdt info to the client log */
2255 rc = name_create(&cliname, mti->mti_fsname, "-client");
2259 if (mgs_log_is_empty(env, mgs, cliname)) {
2260 /* Start client log */
2261 rc = mgs_write_log_lov(env, mgs, fsdb, mti, cliname,
2265 rc = mgs_write_log_lmv(env, mgs, fsdb, mti, cliname,
2272 #09 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
2273 #10 L attach 0:MDC_uml1_mdsA_MNT_client 1:mdc 2:1d834_MNT_client_03f
2274 #11 L setup 0:MDC_uml1_mdsA_MNT_client 1:mdsA_UUID 2:uml1_UUID
2275 #12 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
2276 #13 L add_conn 0:MDC_uml1_mdsA_MNT_client 1:uml2_UUID
2277 #14 L mount_option 0: 1:client 2:lov1 3:MDC_uml1_mdsA_MNT_client
2280 /* copy client info about lov/lmv */
2281 mgi->mgi_comp.comp_mti = mti;
2282 mgi->mgi_comp.comp_fsdb = fsdb;
2284 rc = mgs_steal_llog_for_mdt_from_client(env, mgs, cliname,
2288 rc = mgs_write_log_mdc_to_lmv(env, mgs, fsdb, mti, cliname,
2294 rc = record_start_log(env, mgs, &llh, cliname);
2298 rc = record_marker(env, llh, fsdb, CM_START, cliname,
2302 rc = record_mount_opt(env, llh, cliname, fsdb->fsdb_clilov,
2306 rc = record_marker(env, llh, fsdb, CM_END, cliname,
2312 /* for_all_existing_mdt except current one */
2313 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2314 if (i != mti->mti_stripe_index &&
2315 test_bit(i, fsdb->fsdb_mdt_index_map)) {
2318 rc = name_create_mdt(&logname, fsdb->fsdb_name, i);
2322 rc = mgs_write_log_osp_to_mdt(env, mgs, fsdb, mti,
2324 name_destroy(&logname);
2330 record_end_log(env, &llh);
2332 name_destroy(&cliname);
2336 /* Add the ost info to the client/mdt lov */
2337 static int mgs_write_log_osc_to_lov(const struct lu_env *env,
2338 struct mgs_device *mgs, struct fs_db *fsdb,
2339 struct mgs_target_info *mti,
2340 char *logname, char *suffix, char *lovname,
2341 enum lustre_sec_part sec_part, int flags)
2343 struct llog_handle *llh = NULL;
2344 char *nodeuuid = NULL;
2345 char *oscname = NULL;
2346 char *oscuuid = NULL;
2347 char *lovuuid = NULL;
2348 char *svname = NULL;
2353 CDEBUG(D_INFO, "adding osc for %s to log %s\n",
2354 mti->mti_svname, logname);
2356 if (mgs_log_is_empty(env, mgs, logname)) {
2357 CERROR("log is empty! Logical error\n");
2361 rc = name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
2364 rc = name_create(&svname, mti->mti_svname, "-osc");
2368 /* for the system upgraded from old 1.8, keep using the old osc naming
2369 * style for mdt, see name_create_mdt_osc(). LU-1257 */
2370 if (test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2371 rc = name_create(&oscname, svname, "");
2373 rc = name_create(&oscname, svname, suffix);
2377 rc = name_create(&oscuuid, oscname, "_UUID");
2380 rc = name_create(&lovuuid, lovname, "_UUID");
2386 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
2388 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
2389 #04 L attach 0:OSC_uml1_ost1_MNT_client 1:osc 2:89070_lov1_a41dff51a
2390 #05 L setup 0:OSC_uml1_ost1_MNT_client 1:ost1_UUID 2:uml1_UUID
2392 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
2393 #07 L add_conn 0:OSC_uml1_ost1_MNT_client 1:uml2_UUID
2394 #08 L lov_modify_tgts add 0:lov1 1:ost1_UUID 2(index):0 3(gen):1
2397 rc = record_start_log(env, mgs, &llh, logname);
2401 /* FIXME these should be a single journal transaction */
2402 rc = record_marker(env, llh, fsdb, CM_START | flags, mti->mti_svname,
2407 /* NB: don't change record order, because upon MDT steal OSC config
2408 * from client, it treats all nids before LCFG_SETUP as target nids
2409 * (multiple interfaces), while nids after as failover node nids.
2410 * See mgs_steal_client_llog_handler() LCFG_ADD_UUID.
2412 for (i = 0; i < mti->mti_nid_count; i++) {
2413 CDEBUG(D_MGS, "add nid %s\n", libcfs_nid2str(mti->mti_nids[i]));
2414 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
2418 rc = record_attach(env, llh, oscname, LUSTRE_OSC_NAME, lovuuid);
2421 rc = record_setup(env, llh, oscname, mti->mti_uuid, nodeuuid, 0, 0);
2424 rc = mgs_write_log_failnids(env, mti, llh, oscname);
2428 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
2430 rc = record_lov_add(env, llh, lovname, mti->mti_uuid, index, "1");
2433 rc = record_marker(env, llh, fsdb, CM_END | flags, mti->mti_svname,
2438 record_end_log(env, &llh);
2440 name_destroy(&lovuuid);
2441 name_destroy(&oscuuid);
2442 name_destroy(&oscname);
2443 name_destroy(&svname);
2444 name_destroy(&nodeuuid);
2448 static int mgs_write_log_ost(const struct lu_env *env,
2449 struct mgs_device *mgs, struct fs_db *fsdb,
2450 struct mgs_target_info *mti)
2452 struct llog_handle *llh = NULL;
2453 char *logname, *lovname;
2454 char *ptr = mti->mti_params;
2455 int rc, flags = 0, failout = 0, i;
2458 CDEBUG(D_MGS, "writing new ost %s\n", mti->mti_svname);
2460 /* The ost startup log */
2462 /* If the ost log already exists, that means that someone reformatted
2463 the ost and it called target_add again. */
2464 if (!mgs_log_is_empty(env, mgs, mti->mti_svname)) {
2465 LCONSOLE_ERROR_MSG(0x141, "The config log for %s already "
2466 "exists, yet the server claims it never "
2467 "registered. It may have been reformatted, "
2468 "or the index changed. writeconf the MDT to "
2469 "regenerate all logs.\n", mti->mti_svname);
2474 attach obdfilter ost1 ost1_UUID
2475 setup /dev/loop2 ldiskfs f|n errors=remount-ro,user_xattr
2477 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
2478 failout = (strncmp(ptr, "failout", 7) == 0);
2479 rc = record_start_log(env, mgs, &llh, mti->mti_svname);
2482 /* FIXME these should be a single journal transaction */
2483 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,"add ost");
2486 if (*mti->mti_uuid == '\0')
2487 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
2488 "%s_UUID", mti->mti_svname);
2489 rc = record_attach(env, llh, mti->mti_svname,
2490 "obdfilter"/*LUSTRE_OST_NAME*/, mti->mti_uuid);
2493 rc = record_setup(env, llh, mti->mti_svname,
2494 "dev"/*ignored*/, "type"/*ignored*/,
2495 failout ? "n" : "f", 0/*options*/);
2498 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname, "add ost");
2502 record_end_log(env, &llh);
2505 /* We also have to update the other logs where this osc is part of
2508 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
2509 /* If we're upgrading, the old mdt log already has our
2510 entry. Let's do a fake one for fun. */
2511 /* Note that we can't add any new failnids, since we don't
2512 know the old osc names. */
2513 flags = CM_SKIP | CM_UPGRADE146;
2515 } else if ((mti->mti_flags & LDD_F_UPDATE) != LDD_F_UPDATE) {
2516 /* If the update flag isn't set, don't update client/mdt
2519 LCONSOLE_WARN("Client log for %s was not updated; writeconf "
2520 "the MDT first to regenerate it.\n",
2524 /* Add ost to all MDT lov defs */
2525 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
2526 if (test_bit(i, fsdb->fsdb_mdt_index_map)) {
2529 rc = name_create_mdt_and_lov(&logname, &lovname, fsdb,
2533 sprintf(mdt_index, "-MDT%04x", i);
2534 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, mti,
2536 lovname, LUSTRE_SP_MDT,
2538 name_destroy(&logname);
2539 name_destroy(&lovname);
2545 /* Append ost info to the client log */
2546 rc = name_create(&logname, mti->mti_fsname, "-client");
2549 if (mgs_log_is_empty(env, mgs, logname)) {
2550 /* Start client log */
2551 rc = mgs_write_log_lov(env, mgs, fsdb, mti, logname,
2555 rc = mgs_write_log_lmv(env, mgs, fsdb, mti, logname,
2560 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, mti, logname, "",
2561 fsdb->fsdb_clilov, LUSTRE_SP_CLI, 0);
2563 name_destroy(&logname);
2567 static __inline__ int mgs_param_empty(char *ptr)
2571 if ((tmp = strchr(ptr, '=')) && (*(++tmp) == '\0'))
2576 static int mgs_write_log_failnid_internal(const struct lu_env *env,
2577 struct mgs_device *mgs,
2579 struct mgs_target_info *mti,
2580 char *logname, char *cliname)
2583 struct llog_handle *llh = NULL;
2585 if (mgs_param_empty(mti->mti_params)) {
2586 /* Remove _all_ failnids */
2587 rc = mgs_modify(env, mgs, fsdb, mti, logname,
2588 mti->mti_svname, "add failnid", CM_SKIP);
2589 return rc < 0 ? rc : 0;
2592 /* Otherwise failover nids are additive */
2593 rc = record_start_log(env, mgs, &llh, logname);
2596 /* FIXME this should be a single journal transaction */
2597 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
2601 rc = mgs_write_log_failnids(env, mti, llh, cliname);
2604 rc = record_marker(env, llh, fsdb, CM_END,
2605 mti->mti_svname, "add failnid");
2607 record_end_log(env, &llh);
2612 /* Add additional failnids to an existing log.
2613 The mdc/osc must have been added to logs first */
2614 /* tcp nids must be in dotted-quad ascii -
2615 we can't resolve hostnames from the kernel. */
2616 static int mgs_write_log_add_failnid(const struct lu_env *env,
2617 struct mgs_device *mgs,
2619 struct mgs_target_info *mti)
2621 char *logname, *cliname;
2625 /* FIXME we currently can't erase the failnids
2626 * given when a target first registers, since they aren't part of
2627 * an "add uuid" stanza */
2629 /* Verify that we know about this target */
2630 if (mgs_log_is_empty(env, mgs, mti->mti_svname)) {
2631 LCONSOLE_ERROR_MSG(0x142, "The target %s has not registered "
2632 "yet. It must be started before failnids "
2633 "can be added.\n", mti->mti_svname);
2637 /* Create mdc/osc client name (e.g. lustre-OST0001-osc) */
2638 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
2639 rc = name_create(&cliname, mti->mti_svname, "-mdc");
2640 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2641 rc = name_create(&cliname, mti->mti_svname, "-osc");
2647 /* Add failover nids to the client log */
2648 rc = name_create(&logname, mti->mti_fsname, "-client");
2650 name_destroy(&cliname);
2653 rc = mgs_write_log_failnid_internal(env, mgs, fsdb,mti,logname,cliname);
2654 name_destroy(&logname);
2655 name_destroy(&cliname);
2659 if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2660 /* Add OST failover nids to the MDT logs as well */
2663 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2664 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
2666 rc = name_create_mdt(&logname, mti->mti_fsname, i);
2669 rc = name_create_mdt_osc(&cliname, mti->mti_svname,
2672 name_destroy(&logname);
2675 rc = mgs_write_log_failnid_internal(env, mgs, fsdb,
2678 name_destroy(&cliname);
2679 name_destroy(&logname);
2688 static int mgs_wlp_lcfg(const struct lu_env *env,
2689 struct mgs_device *mgs, struct fs_db *fsdb,
2690 struct mgs_target_info *mti,
2691 char *logname, struct lustre_cfg_bufs *bufs,
2692 char *tgtname, char *ptr)
2694 char comment[MTI_NAME_MAXLEN];
2696 struct llog_cfg_rec *lcr;
2699 /* Erase any old settings of this same parameter */
2700 memcpy(comment, ptr, MTI_NAME_MAXLEN);
2701 comment[MTI_NAME_MAXLEN - 1] = 0;
2702 /* But don't try to match the value. */
2703 tmp = strchr(comment, '=');
2706 /* FIXME we should skip settings that are the same as old values */
2707 rc = mgs_modify(env, mgs, fsdb, mti, logname, tgtname, comment,CM_SKIP);
2710 del = mgs_param_empty(ptr);
2712 LCONSOLE_INFO("%s parameter %s.%s in log %s\n", del ? "Disabling" : rc ?
2713 "Setting" : "Modifying", tgtname, comment, logname);
2715 /* mgs_modify() will return 1 if nothing had to be done */
2721 lustre_cfg_bufs_reset(bufs, tgtname);
2722 lustre_cfg_bufs_set_string(bufs, 1, ptr);
2723 if (mti->mti_flags & LDD_F_PARAM2)
2724 lustre_cfg_bufs_set_string(bufs, 2, LCTL_UPCALL);
2726 lcr = lustre_cfg_rec_new((mti->mti_flags & LDD_F_PARAM2) ?
2727 LCFG_SET_PARAM : LCFG_PARAM, bufs);
2731 rc = mgs_write_log_direct(env, mgs, fsdb, logname, lcr, tgtname,
2733 lustre_cfg_rec_free(lcr);
2737 static int mgs_write_log_param2(const struct lu_env *env,
2738 struct mgs_device *mgs,
2740 struct mgs_target_info *mti, char *ptr)
2742 struct lustre_cfg_bufs bufs;
2746 CDEBUG(D_MGS, "next param '%s'\n", ptr);
2747 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, PARAMS_FILENAME, &bufs,
2748 mti->mti_svname, ptr);
2753 /* write global variable settings into log */
2754 static int mgs_write_log_sys(const struct lu_env *env,
2755 struct mgs_device *mgs, struct fs_db *fsdb,
2756 struct mgs_target_info *mti, char *sys, char *ptr)
2758 struct mgs_thread_info *mgi = mgs_env_info(env);
2759 struct lustre_cfg *lcfg;
2760 struct llog_cfg_rec *lcr;
2762 int rc, cmd, convert = 1;
2764 if (class_match_param(ptr, PARAM_TIMEOUT, &tmp) == 0) {
2765 cmd = LCFG_SET_TIMEOUT;
2766 } else if (class_match_param(ptr, PARAM_LDLM_TIMEOUT, &tmp) == 0) {
2767 cmd = LCFG_SET_LDLM_TIMEOUT;
2768 /* Check for known params here so we can return error to lctl */
2769 } else if ((class_match_param(ptr, PARAM_AT_MIN, &tmp) == 0) ||
2770 (class_match_param(ptr, PARAM_AT_MAX, &tmp) == 0) ||
2771 (class_match_param(ptr, PARAM_AT_EXTRA, &tmp) == 0) ||
2772 (class_match_param(ptr, PARAM_AT_EARLY_MARGIN, &tmp) == 0) ||
2773 (class_match_param(ptr, PARAM_AT_HISTORY, &tmp) == 0)) {
2775 } else if (class_match_param(ptr, PARAM_JOBID_VAR, &tmp) == 0) {
2776 convert = 0; /* Don't convert string value to integer */
2782 if (mgs_param_empty(ptr))
2783 CDEBUG(D_MGS, "global '%s' removed\n", sys);
2785 CDEBUG(D_MGS, "global '%s' val=%s\n", sys, tmp);
2787 lustre_cfg_bufs_reset(&mgi->mgi_bufs, NULL);
2788 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, sys);
2789 if (!convert && *tmp != '\0')
2790 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 2, tmp);
2791 lcr = lustre_cfg_rec_new(cmd, &mgi->mgi_bufs);
2795 lcfg = &lcr->lcr_cfg;
2796 lcfg->lcfg_num = convert ? simple_strtoul(tmp, NULL, 0) : 0;
2797 /* truncate the comment to the parameter name */
2801 /* modify all servers and clients */
2802 rc = mgs_write_log_direct_all(env, mgs, fsdb, mti,
2803 *tmp == '\0' ? NULL : lcr,
2804 mti->mti_fsname, sys, 0);
2805 if (rc == 0 && *tmp != '\0') {
2807 case LCFG_SET_TIMEOUT:
2808 if (!obd_timeout_set || lcfg->lcfg_num > obd_timeout)
2809 class_process_config(lcfg);
2811 case LCFG_SET_LDLM_TIMEOUT:
2812 if (!ldlm_timeout_set || lcfg->lcfg_num > ldlm_timeout)
2813 class_process_config(lcfg);
2820 lustre_cfg_rec_free(lcr);
2824 /* write quota settings into log */
2825 static int mgs_write_log_quota(const struct lu_env *env, struct mgs_device *mgs,
2826 struct fs_db *fsdb, struct mgs_target_info *mti,
2827 char *quota, char *ptr)
2829 struct mgs_thread_info *mgi = mgs_env_info(env);
2830 struct llog_cfg_rec *lcr;
2833 int rc, cmd = LCFG_PARAM;
2835 /* support only 'meta' and 'data' pools so far */
2836 if (class_match_param(ptr, QUOTA_METAPOOL_NAME, &tmp) != 0 &&
2837 class_match_param(ptr, QUOTA_DATAPOOL_NAME, &tmp) != 0) {
2838 CERROR("parameter quota.%s isn't supported (only quota.mdt "
2839 "& quota.ost are)\n", ptr);
2844 CDEBUG(D_MGS, "global '%s' removed\n", quota);
2846 CDEBUG(D_MGS, "global '%s'\n", quota);
2848 if (strchr(tmp, 'u') == NULL && strchr(tmp, 'g') == NULL &&
2849 strcmp(tmp, "none") != 0) {
2850 CERROR("enable option(%s) isn't supported\n", tmp);
2855 lustre_cfg_bufs_reset(&mgi->mgi_bufs, mti->mti_fsname);
2856 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, quota);
2857 lcr = lustre_cfg_rec_new(cmd, &mgi->mgi_bufs);
2861 /* truncate the comment to the parameter name */
2866 /* XXX we duplicated quota enable information in all server
2867 * config logs, it should be moved to a separate config
2868 * log once we cleanup the config log for global param. */
2869 /* modify all servers */
2870 rc = mgs_write_log_direct_all(env, mgs, fsdb, mti,
2871 *tmp == '\0' ? NULL : lcr,
2872 mti->mti_fsname, quota, 1);
2874 lustre_cfg_rec_free(lcr);
2875 return rc < 0 ? rc : 0;
2878 static int mgs_srpc_set_param_disk(const struct lu_env *env,
2879 struct mgs_device *mgs,
2881 struct mgs_target_info *mti,
2884 struct mgs_thread_info *mgi = mgs_env_info(env);
2885 struct llog_cfg_rec *lcr;
2886 struct llog_handle *llh = NULL;
2888 char *comment, *ptr;
2894 ptr = strchr(param, '=');
2895 LASSERT(ptr != NULL);
2898 OBD_ALLOC(comment, len + 1);
2899 if (comment == NULL)
2901 strncpy(comment, param, len);
2902 comment[len] = '\0';
2905 lustre_cfg_bufs_reset(&mgi->mgi_bufs, mti->mti_svname);
2906 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, param);
2907 lcr = lustre_cfg_rec_new(LCFG_SPTLRPC_CONF, &mgi->mgi_bufs);
2909 GOTO(out_comment, rc = -ENOMEM);
2911 /* construct log name */
2912 rc = name_create(&logname, mti->mti_fsname, "-sptlrpc");
2916 if (mgs_log_is_empty(env, mgs, logname)) {
2917 rc = record_start_log(env, mgs, &llh, logname);
2920 record_end_log(env, &llh);
2923 /* obsolete old one */
2924 rc = mgs_modify(env, mgs, fsdb, mti, logname, mti->mti_svname,
2928 /* write the new one */
2929 rc = mgs_write_log_direct(env, mgs, fsdb, logname, lcr,
2930 mti->mti_svname, comment);
2932 CERROR("%s: error writing log %s: rc = %d\n",
2933 mgs->mgs_obd->obd_name, logname, rc);
2935 name_destroy(&logname);
2937 lustre_cfg_rec_free(lcr);
2939 OBD_FREE(comment, len + 1);
2943 static int mgs_srpc_set_param_udesc_mem(struct fs_db *fsdb,
2948 /* disable the adjustable udesc parameter for now, i.e. use default
2949 * setting that client always ship udesc to MDT if possible. to enable
2950 * it simply remove the following line */
2953 ptr = strchr(param, '=');
2958 if (strcmp(param, PARAM_SRPC_UDESC))
2961 if (strcmp(ptr, "yes") == 0) {
2962 set_bit(FSDB_UDESC, &fsdb->fsdb_flags);
2963 CWARN("Enable user descriptor shipping from client to MDT\n");
2964 } else if (strcmp(ptr, "no") == 0) {
2965 clear_bit(FSDB_UDESC, &fsdb->fsdb_flags);
2966 CWARN("Disable user descriptor shipping from client to MDT\n");
2974 CERROR("Invalid param: %s\n", param);
2978 static int mgs_srpc_set_param_mem(struct fs_db *fsdb,
2982 struct sptlrpc_rule rule;
2983 struct sptlrpc_rule_set *rset;
2987 if (strncmp(param, PARAM_SRPC, sizeof(PARAM_SRPC) - 1) != 0) {
2988 CERROR("Invalid sptlrpc parameter: %s\n", param);
2992 if (strncmp(param, PARAM_SRPC_UDESC,
2993 sizeof(PARAM_SRPC_UDESC) - 1) == 0) {
2994 RETURN(mgs_srpc_set_param_udesc_mem(fsdb, param));
2997 if (strncmp(param, PARAM_SRPC_FLVR, sizeof(PARAM_SRPC_FLVR) - 1) != 0) {
2998 CERROR("Invalid sptlrpc flavor parameter: %s\n", param);
3002 param += sizeof(PARAM_SRPC_FLVR) - 1;
3004 rc = sptlrpc_parse_rule(param, &rule);
3008 /* mgs rules implies must be mgc->mgs */
3009 if (test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
3010 if ((rule.sr_from != LUSTRE_SP_MGC &&
3011 rule.sr_from != LUSTRE_SP_ANY) ||
3012 (rule.sr_to != LUSTRE_SP_MGS &&
3013 rule.sr_to != LUSTRE_SP_ANY))
3017 /* preapre room for this coming rule. svcname format should be:
3018 * - fsname: general rule
3019 * - fsname-tgtname: target-specific rule
3021 if (strchr(svname, '-')) {
3022 struct mgs_tgt_srpc_conf *tgtconf;
3025 for (tgtconf = fsdb->fsdb_srpc_tgt; tgtconf != NULL;
3026 tgtconf = tgtconf->mtsc_next) {
3027 if (!strcmp(tgtconf->mtsc_tgt, svname)) {
3036 OBD_ALLOC_PTR(tgtconf);
3037 if (tgtconf == NULL)
3040 name_len = strlen(svname);
3042 OBD_ALLOC(tgtconf->mtsc_tgt, name_len + 1);
3043 if (tgtconf->mtsc_tgt == NULL) {
3044 OBD_FREE_PTR(tgtconf);
3047 memcpy(tgtconf->mtsc_tgt, svname, name_len);
3049 tgtconf->mtsc_next = fsdb->fsdb_srpc_tgt;
3050 fsdb->fsdb_srpc_tgt = tgtconf;
3053 rset = &tgtconf->mtsc_rset;
3055 rset = &fsdb->fsdb_srpc_gen;
3058 rc = sptlrpc_rule_set_merge(rset, &rule);
3063 static int mgs_srpc_set_param(const struct lu_env *env,
3064 struct mgs_device *mgs,
3066 struct mgs_target_info *mti,
3076 /* keep a copy of original param, which could be destroied
3078 copy_size = strlen(param) + 1;
3079 OBD_ALLOC(copy, copy_size);
3082 memcpy(copy, param, copy_size);
3084 rc = mgs_srpc_set_param_mem(fsdb, mti->mti_svname, param);
3088 /* previous steps guaranteed the syntax is correct */
3089 rc = mgs_srpc_set_param_disk(env, mgs, fsdb, mti, copy);
3093 if (test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
3095 * for mgs rules, make them effective immediately.
3097 LASSERT(fsdb->fsdb_srpc_tgt == NULL);
3098 sptlrpc_target_update_exp_flavor(mgs->mgs_obd,
3099 &fsdb->fsdb_srpc_gen);
3103 OBD_FREE(copy, copy_size);
3107 struct mgs_srpc_read_data {
3108 struct fs_db *msrd_fsdb;
3112 static int mgs_srpc_read_handler(const struct lu_env *env,
3113 struct llog_handle *llh,
3114 struct llog_rec_hdr *rec, void *data)
3116 struct mgs_srpc_read_data *msrd = data;
3117 struct cfg_marker *marker;
3118 struct lustre_cfg *lcfg = REC_DATA(rec);
3119 char *svname, *param;
3123 if (rec->lrh_type != OBD_CFG_REC) {
3124 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
3128 cfg_len = REC_DATA_LEN(rec);
3130 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
3132 CERROR("Insane cfg\n");
3136 if (lcfg->lcfg_command == LCFG_MARKER) {
3137 marker = lustre_cfg_buf(lcfg, 1);
3139 if (marker->cm_flags & CM_START &&
3140 marker->cm_flags & CM_SKIP)
3141 msrd->msrd_skip = 1;
3142 if (marker->cm_flags & CM_END)
3143 msrd->msrd_skip = 0;
3148 if (msrd->msrd_skip)
3151 if (lcfg->lcfg_command != LCFG_SPTLRPC_CONF) {
3152 CERROR("invalid command (%x)\n", lcfg->lcfg_command);
3156 svname = lustre_cfg_string(lcfg, 0);
3157 if (svname == NULL) {
3158 CERROR("svname is empty\n");
3162 param = lustre_cfg_string(lcfg, 1);
3163 if (param == NULL) {
3164 CERROR("param is empty\n");
3168 rc = mgs_srpc_set_param_mem(msrd->msrd_fsdb, svname, param);
3170 CERROR("read sptlrpc record error (%d): %s\n", rc, param);
3175 int mgs_get_fsdb_srpc_from_llog(const struct lu_env *env,
3176 struct mgs_device *mgs,
3179 struct llog_handle *llh = NULL;
3180 struct llog_ctxt *ctxt;
3182 struct mgs_srpc_read_data msrd;
3186 /* construct log name */
3187 rc = name_create(&logname, fsdb->fsdb_name, "-sptlrpc");
3191 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
3192 LASSERT(ctxt != NULL);
3194 if (mgs_log_is_empty(env, mgs, logname))
3197 rc = llog_open(env, ctxt, &llh, NULL, logname,
3205 rc = llog_init_handle(env, llh, LLOG_F_IS_PLAIN, NULL);
3207 GOTO(out_close, rc);
3209 if (llog_get_size(llh) <= 1)
3210 GOTO(out_close, rc = 0);
3212 msrd.msrd_fsdb = fsdb;
3215 rc = llog_process(env, llh, mgs_srpc_read_handler, (void *)&msrd,
3219 llog_close(env, llh);
3221 llog_ctxt_put(ctxt);
3222 name_destroy(&logname);
3225 CERROR("failed to read sptlrpc config database: %d\n", rc);
3229 /* Permanent settings of all parameters by writing into the appropriate
3230 * configuration logs.
3231 * A parameter with null value ("<param>='\0'") means to erase it out of
3234 static int mgs_write_log_param(const struct lu_env *env,
3235 struct mgs_device *mgs, struct fs_db *fsdb,
3236 struct mgs_target_info *mti, char *ptr)
3238 struct mgs_thread_info *mgi = mgs_env_info(env);
3241 int rc = 0, rc2 = 0;
3244 /* For various parameter settings, we have to figure out which logs
3245 care about them (e.g. both mdt and client for lov settings) */
3246 CDEBUG(D_MGS, "next param '%s'\n", ptr);
3248 /* The params are stored in MOUNT_DATA_FILE and modified via
3249 tunefs.lustre, or set using lctl conf_param */
3251 /* Processed in lustre_start_mgc */
3252 if (class_match_param(ptr, PARAM_MGSNODE, NULL) == 0)
3255 /* Processed in ost/mdt */
3256 if (class_match_param(ptr, PARAM_NETWORK, NULL) == 0)
3259 /* Processed in mgs_write_log_ost */
3260 if (class_match_param(ptr, PARAM_FAILMODE, NULL) == 0) {
3261 if (mti->mti_flags & LDD_F_PARAM) {
3262 LCONSOLE_ERROR_MSG(0x169, "%s can only be "
3263 "changed with tunefs.lustre"
3264 "and --writeconf\n", ptr);
3270 if (class_match_param(ptr, PARAM_SRPC, NULL) == 0) {
3271 rc = mgs_srpc_set_param(env, mgs, fsdb, mti, ptr);
3275 if (class_match_param(ptr, PARAM_FAILNODE, NULL) == 0) {
3276 /* Add a failover nidlist */
3278 /* We already processed failovers params for new
3279 targets in mgs_write_log_target */
3280 if (mti->mti_flags & LDD_F_PARAM) {
3281 CDEBUG(D_MGS, "Adding failnode\n");
3282 rc = mgs_write_log_add_failnid(env, mgs, fsdb, mti);
3287 if (class_match_param(ptr, PARAM_SYS, &tmp) == 0) {
3288 rc = mgs_write_log_sys(env, mgs, fsdb, mti, ptr, tmp);
3292 if (class_match_param(ptr, PARAM_QUOTA, &tmp) == 0) {
3293 rc = mgs_write_log_quota(env, mgs, fsdb, mti, ptr, tmp);
3297 if (class_match_param(ptr, PARAM_OSC""PARAM_ACTIVE, &tmp) == 0) {
3298 /* active=0 means off, anything else means on */
3299 int flag = (*tmp == '0') ? CM_EXCLUDE : 0;
3302 if (!(mti->mti_flags & LDD_F_SV_TYPE_OST)) {
3303 LCONSOLE_ERROR_MSG(0x144, "%s: Only OSCs can "
3304 "be (de)activated.\n",
3306 GOTO(end, rc = -EINVAL);
3308 LCONSOLE_WARN("Permanently %sactivating %s\n",
3309 flag ? "de": "re", mti->mti_svname);
3311 rc = name_create(&logname, mti->mti_fsname, "-client");
3314 rc = mgs_modify(env, mgs, fsdb, mti, logname,
3315 mti->mti_svname, "add osc", flag);
3316 name_destroy(&logname);
3320 /* Add to all MDT logs for CMD */
3321 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3322 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
3324 rc = name_create_mdt(&logname, mti->mti_fsname, i);
3327 rc = mgs_modify(env, mgs, fsdb, mti, logname,
3328 mti->mti_svname, "add osc", flag);
3329 name_destroy(&logname);
3335 LCONSOLE_ERROR_MSG(0x145, "Couldn't find %s in"
3336 "log (%d). No permanent "
3337 "changes were made to the "
3339 mti->mti_svname, rc);
3340 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags))
3341 LCONSOLE_ERROR_MSG(0x146, "This may be"
3346 "update the logs.\n");
3349 /* Fall through to osc proc for deactivating live OSC
3350 on running MDT / clients. */
3352 /* Below here, let obd's XXX_process_config methods handle it */
3354 /* All lov. in proc */
3355 if (class_match_param(ptr, PARAM_LOV, NULL) == 0) {
3358 CDEBUG(D_MGS, "lov param %s\n", ptr);
3359 if (!(mti->mti_flags & LDD_F_SV_TYPE_MDT)) {
3360 LCONSOLE_ERROR_MSG(0x147, "LOV params must be "
3361 "set on the MDT, not %s. "
3368 if (mgs_log_is_empty(env, mgs, mti->mti_svname))
3369 GOTO(end, rc = -ENODEV);
3371 rc = name_create_mdt_and_lov(&logname, &mdtlovname, fsdb,
3372 mti->mti_stripe_index);
3375 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, mti->mti_svname,
3376 &mgi->mgi_bufs, mdtlovname, ptr);
3377 name_destroy(&logname);
3378 name_destroy(&mdtlovname);
3383 rc = name_create(&logname, mti->mti_fsname, "-client");
3386 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname, &mgi->mgi_bufs,
3387 fsdb->fsdb_clilov, ptr);
3388 name_destroy(&logname);
3392 /* All osc., mdc., llite. params in proc */
3393 if ((class_match_param(ptr, PARAM_OSC, NULL) == 0) ||
3394 (class_match_param(ptr, PARAM_MDC, NULL) == 0) ||
3395 (class_match_param(ptr, PARAM_LLITE, NULL) == 0)) {
3398 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
3399 LCONSOLE_ERROR_MSG(0x148, "Upgraded client logs for %s"
3400 " cannot be modified. Consider"
3401 " updating the configuration with"
3404 GOTO(end, rc = -EINVAL);
3406 if (memcmp(ptr, PARAM_LLITE, strlen(PARAM_LLITE)) == 0) {
3407 rc = name_create(&cname, mti->mti_fsname, "-client");
3408 /* Add the client type to match the obdname in
3409 class_config_llog_handler */
3410 } else if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
3411 rc = name_create(&cname, mti->mti_svname, "-mdc");
3412 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
3413 rc = name_create(&cname, mti->mti_svname, "-osc");
3415 GOTO(end, rc = -EINVAL);
3420 /* Forbid direct update of llite root squash parameters.
3421 * These parameters are indirectly set via the MDT settings.
3423 if ((class_match_param(ptr, PARAM_LLITE, &tmp) == 0) &&
3424 ((memcmp(tmp, "root_squash=", 12) == 0) ||
3425 (memcmp(tmp, "nosquash_nids=", 14) == 0))) {
3426 LCONSOLE_ERROR("%s: root squash parameters can only "
3427 "be updated through MDT component\n",
3429 name_destroy(&cname);
3430 GOTO(end, rc = -EINVAL);
3433 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
3436 rc = name_create(&logname, mti->mti_fsname, "-client");
3438 name_destroy(&cname);
3441 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname, &mgi->mgi_bufs,
3444 /* osc params affect the MDT as well */
3445 if (!rc && (mti->mti_flags & LDD_F_SV_TYPE_OST)) {
3448 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
3449 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
3451 name_destroy(&cname);
3452 rc = name_create_mdt_osc(&cname, mti->mti_svname,
3454 name_destroy(&logname);
3457 rc = name_create_mdt(&logname,
3458 mti->mti_fsname, i);
3461 if (!mgs_log_is_empty(env, mgs, logname)) {
3462 rc = mgs_wlp_lcfg(env, mgs, fsdb,
3471 name_destroy(&logname);
3472 name_destroy(&cname);
3476 /* All mdt. params in proc */
3477 if (class_match_param(ptr, PARAM_MDT, &tmp) == 0) {
3481 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
3482 if (strncmp(mti->mti_svname, mti->mti_fsname,
3483 MTI_NAME_MAXLEN) == 0)
3484 /* device is unspecified completely? */
3485 rc = LDD_F_SV_TYPE_MDT | LDD_F_SV_ALL;
3487 rc = server_name2index(mti->mti_svname, &idx, NULL);
3490 if ((rc & LDD_F_SV_TYPE_MDT) == 0)
3492 if (rc & LDD_F_SV_ALL) {
3493 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3495 fsdb->fsdb_mdt_index_map))
3497 rc = name_create_mdt(&logname,
3498 mti->mti_fsname, i);
3501 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti,
3502 logname, &mgi->mgi_bufs,
3504 name_destroy(&logname);
3509 if ((memcmp(tmp, "root_squash=", 12) == 0) ||
3510 (memcmp(tmp, "nosquash_nids=", 14) == 0)) {
3511 LCONSOLE_ERROR("%s: root squash parameters "
3512 "cannot be applied to a single MDT\n",
3514 GOTO(end, rc = -EINVAL);
3516 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti,
3517 mti->mti_svname, &mgi->mgi_bufs,
3518 mti->mti_svname, ptr);
3523 /* root squash settings are also applied to llite
3524 * config log (see LU-1778) */
3526 ((memcmp(tmp, "root_squash=", 12) == 0) ||
3527 (memcmp(tmp, "nosquash_nids=", 14) == 0))) {
3531 rc = name_create(&cname, mti->mti_fsname, "-client");
3534 rc = name_create(&logname, mti->mti_fsname, "-client");
3536 name_destroy(&cname);
3539 rc = name_create(&ptr2, PARAM_LLITE, tmp);
3541 name_destroy(&cname);
3542 name_destroy(&logname);
3545 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname,
3546 &mgi->mgi_bufs, cname, ptr2);
3547 name_destroy(&ptr2);
3548 name_destroy(&logname);
3549 name_destroy(&cname);
3554 /* All mdd., ost. and osd. params in proc */
3555 if ((class_match_param(ptr, PARAM_MDD, NULL) == 0) ||
3556 (class_match_param(ptr, PARAM_OST, NULL) == 0) ||
3557 (class_match_param(ptr, PARAM_OSD, NULL) == 0)) {
3558 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
3559 if (mgs_log_is_empty(env, mgs, mti->mti_svname))
3560 GOTO(end, rc = -ENODEV);
3562 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, mti->mti_svname,
3563 &mgi->mgi_bufs, mti->mti_svname, ptr);
3567 LCONSOLE_WARN("Ignoring unrecognized param '%s'\n", ptr);
3572 CERROR("err %d on param '%s'\n", rc, ptr);
3577 /* Not implementing automatic failover nid addition at this time. */
3578 int mgs_check_failnid(const struct lu_env *env, struct mgs_device *mgs,
3579 struct mgs_target_info *mti)
3586 rc = mgs_find_or_make_fsdb(obd, fsname, &fsdb);
3590 if (mgs_log_is_empty(obd, mti->mti_svname))
3591 /* should never happen */
3594 CDEBUG(D_MGS, "Checking for new failnids for %s\n", mti->mti_svname);
3596 /* FIXME We can just check mti->params to see if we're already in
3597 the failover list. Modify mti->params for rewriting back at
3598 server_register_target(). */
3600 mutex_lock(&fsdb->fsdb_mutex);
3601 rc = mgs_write_log_add_failnid(obd, fsdb, mti);
3602 mutex_unlock(&fsdb->fsdb_mutex);
3611 int mgs_write_log_target(const struct lu_env *env, struct mgs_device *mgs,
3612 struct mgs_target_info *mti, struct fs_db *fsdb)
3619 /* set/check the new target index */
3620 rc = mgs_set_index(env, mgs, mti);
3624 if (rc == EALREADY) {
3625 LCONSOLE_WARN("Found index %d for %s, updating log\n",
3626 mti->mti_stripe_index, mti->mti_svname);
3627 /* We would like to mark old log sections as invalid
3628 and add new log sections in the client and mdt logs.
3629 But if we add new sections, then live clients will
3630 get repeat setup instructions for already running
3631 osc's. So don't update the client/mdt logs. */
3632 mti->mti_flags &= ~LDD_F_UPDATE;
3636 mutex_lock(&fsdb->fsdb_mutex);
3638 if (mti->mti_flags &
3639 (LDD_F_VIRGIN | LDD_F_UPGRADE14 | LDD_F_WRITECONF)) {
3640 /* Generate a log from scratch */
3641 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
3642 rc = mgs_write_log_mdt(env, mgs, fsdb, mti);
3643 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
3644 rc = mgs_write_log_ost(env, mgs, fsdb, mti);
3646 CERROR("Unknown target type %#x, can't create log for "
3647 "%s\n", mti->mti_flags, mti->mti_svname);
3650 CERROR("Can't write logs for %s (%d)\n",
3651 mti->mti_svname, rc);
3655 /* Just update the params from tunefs in mgs_write_log_params */
3656 CDEBUG(D_MGS, "Update params for %s\n", mti->mti_svname);
3657 mti->mti_flags |= LDD_F_PARAM;
3660 /* allocate temporary buffer, where class_get_next_param will
3661 make copy of a current parameter */
3662 OBD_ALLOC(buf, strlen(mti->mti_params) + 1);
3664 GOTO(out_up, rc = -ENOMEM);
3665 params = mti->mti_params;
3666 while (params != NULL) {
3667 rc = class_get_next_param(¶ms, buf);
3670 /* there is no next parameter, that is
3675 CDEBUG(D_MGS, "remaining string: '%s', param: '%s'\n",
3677 rc = mgs_write_log_param(env, mgs, fsdb, mti, buf);
3682 OBD_FREE(buf, strlen(mti->mti_params) + 1);
3685 mutex_unlock(&fsdb->fsdb_mutex);
3689 int mgs_erase_log(const struct lu_env *env, struct mgs_device *mgs, char *name)
3691 struct llog_ctxt *ctxt;
3694 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
3696 CERROR("%s: MGS config context doesn't exist\n",
3697 mgs->mgs_obd->obd_name);
3700 rc = llog_erase(env, ctxt, NULL, name);
3701 /* llog may not exist */
3704 llog_ctxt_put(ctxt);
3708 CERROR("%s: failed to clear log %s: %d\n",
3709 mgs->mgs_obd->obd_name, name, rc);
3714 /* erase all logs for the given fs */
3715 int mgs_erase_logs(const struct lu_env *env, struct mgs_device *mgs, char *fsname)
3718 struct list_head log_list;
3719 struct mgs_direntry *dirent, *n;
3720 int rc, len = strlen(fsname);
3724 /* Find all the logs in the CONFIGS directory */
3725 rc = class_dentry_readdir(env, mgs, &log_list);
3729 mutex_lock(&mgs->mgs_mutex);
3731 /* Delete the fs db */
3732 fsdb = mgs_find_fsdb(mgs, fsname);
3734 mgs_free_fsdb(mgs, fsdb);
3736 mutex_unlock(&mgs->mgs_mutex);
3738 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
3739 list_del_init(&dirent->mde_list);
3740 suffix = strrchr(dirent->mde_name, '-');
3741 if (suffix != NULL) {
3742 if ((len == suffix - dirent->mde_name) &&
3743 (strncmp(fsname, dirent->mde_name, len) == 0)) {
3744 CDEBUG(D_MGS, "Removing log %s\n",
3746 mgs_erase_log(env, mgs, dirent->mde_name);
3749 mgs_direntry_free(dirent);
3755 /* list all logs for the given fs */
3756 int mgs_list_logs(const struct lu_env *env, struct mgs_device *mgs,
3757 struct obd_ioctl_data *data)
3759 struct list_head log_list;
3760 struct mgs_direntry *dirent, *n;
3766 /* Find all the logs in the CONFIGS directory */
3767 rc = class_dentry_readdir(env, mgs, &log_list);
3771 out = data->ioc_bulk;
3772 remains = data->ioc_inllen1;
3773 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
3774 list_del_init(&dirent->mde_list);
3775 suffix = strrchr(dirent->mde_name, '-');
3776 if (suffix != NULL) {
3777 l = snprintf(out, remains, "config log: $%s\n",
3782 mgs_direntry_free(dirent);
3789 /* from llog_swab */
3790 static void print_lustre_cfg(struct lustre_cfg *lcfg)
3795 CDEBUG(D_MGS, "lustre_cfg: %p\n", lcfg);
3796 CDEBUG(D_MGS, "\tlcfg->lcfg_version: %#x\n", lcfg->lcfg_version);
3798 CDEBUG(D_MGS, "\tlcfg->lcfg_command: %#x\n", lcfg->lcfg_command);
3799 CDEBUG(D_MGS, "\tlcfg->lcfg_num: %#x\n", lcfg->lcfg_num);
3800 CDEBUG(D_MGS, "\tlcfg->lcfg_flags: %#x\n", lcfg->lcfg_flags);
3801 CDEBUG(D_MGS, "\tlcfg->lcfg_nid: %s\n", libcfs_nid2str(lcfg->lcfg_nid));
3803 CDEBUG(D_MGS, "\tlcfg->lcfg_bufcount: %d\n", lcfg->lcfg_bufcount);
3804 if (lcfg->lcfg_bufcount < LUSTRE_CFG_MAX_BUFCOUNT)
3805 for (i = 0; i < lcfg->lcfg_bufcount; i++) {
3806 CDEBUG(D_MGS, "\tlcfg->lcfg_buflens[%d]: %d %s\n",
3807 i, lcfg->lcfg_buflens[i],
3808 lustre_cfg_string(lcfg, i));
3813 /* Setup params fsdb and log
3815 int mgs_params_fsdb_setup(const struct lu_env *env, struct mgs_device *mgs,
3818 struct llog_handle *params_llh = NULL;
3822 rc = mgs_find_or_make_fsdb(env, mgs, PARAMS_FILENAME, &fsdb);
3824 mutex_lock(&fsdb->fsdb_mutex);
3825 rc = record_start_log(env, mgs, ¶ms_llh, PARAMS_FILENAME);
3827 rc = record_end_log(env, ¶ms_llh);
3828 mutex_unlock(&fsdb->fsdb_mutex);
3834 /* Cleanup params fsdb and log
3836 int mgs_params_fsdb_cleanup(const struct lu_env *env, struct mgs_device *mgs)
3838 return mgs_erase_logs(env, mgs, PARAMS_FILENAME);
3841 /* Set a permanent (config log) param for a target or fs
3842 * \param lcfg buf0 may contain the device (testfs-MDT0000) name
3843 * buf1 contains the single parameter
3845 int mgs_setparam(const struct lu_env *env, struct mgs_device *mgs,
3846 struct lustre_cfg *lcfg, char *fsname)
3849 struct mgs_target_info *mti;
3850 char *devname, *param;
3857 print_lustre_cfg(lcfg);
3859 /* lustre, lustre-mdtlov, lustre-client, lustre-MDT0000 */
3860 devname = lustre_cfg_string(lcfg, 0);
3861 param = lustre_cfg_string(lcfg, 1);
3863 /* Assume device name embedded in param:
3864 lustre-OST0000.osc.max_dirty_mb=32 */
3865 ptr = strchr(param, '.');
3873 LCONSOLE_ERROR_MSG(0x14d, "No target specified: %s\n", param);
3877 rc = mgs_parse_devname(devname, fsname, NULL);
3878 if (rc == 0 && !mgs_parse_devname(devname, NULL, &index)) {
3879 /* param related to llite isn't allowed to set by OST or MDT */
3880 if (rc == 0 && strncmp(param, PARAM_LLITE,
3881 sizeof(PARAM_LLITE) - 1) == 0)
3884 /* assume devname is the fsname */
3885 strlcpy(fsname, devname, MTI_NAME_MAXLEN);
3887 CDEBUG(D_MGS, "setparam fs='%s' device='%s'\n", fsname, devname);
3889 rc = mgs_find_or_make_fsdb(env, mgs,
3890 lcfg->lcfg_command == LCFG_SET_PARAM ?
3891 PARAMS_FILENAME : fsname, &fsdb);
3895 if (lcfg->lcfg_command != LCFG_SET_PARAM &&
3896 !test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags) &&
3897 test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
3898 CERROR("No filesystem targets for %s. cfg_device from lctl "
3899 "is '%s'\n", fsname, devname);
3900 mgs_free_fsdb(mgs, fsdb);
3904 /* Create a fake mti to hold everything */
3907 GOTO(out, rc = -ENOMEM);
3908 if (strlcpy(mti->mti_fsname, fsname, sizeof(mti->mti_fsname))
3909 >= sizeof(mti->mti_fsname))
3910 GOTO(out, rc = -E2BIG);
3911 if (strlcpy(mti->mti_svname, devname, sizeof(mti->mti_svname))
3912 >= sizeof(mti->mti_svname))
3913 GOTO(out, rc = -E2BIG);
3914 if (strlcpy(mti->mti_params, param, sizeof(mti->mti_params))
3915 >= sizeof(mti->mti_params))
3916 GOTO(out, rc = -E2BIG);
3917 rc = server_name2index(mti->mti_svname, &mti->mti_stripe_index, &tmp);
3919 /* Not a valid server; may be only fsname */
3922 /* Strip -osc or -mdc suffix from svname */
3923 if (server_make_name(rc, mti->mti_stripe_index, mti->mti_fsname,
3925 GOTO(out, rc = -EINVAL);
3927 * Revoke lock so everyone updates. Should be alright if
3928 * someone was already reading while we were updating the logs,
3929 * so we don't really need to hold the lock while we're
3932 if (lcfg->lcfg_command == LCFG_SET_PARAM) {
3933 mti->mti_flags = rc | LDD_F_PARAM2;
3934 mutex_lock(&fsdb->fsdb_mutex);
3935 rc = mgs_write_log_param2(env, mgs, fsdb, mti, mti->mti_params);
3936 mutex_unlock(&fsdb->fsdb_mutex);
3937 mgs_revoke_lock(mgs, fsdb, CONFIG_T_PARAMS);
3939 mti->mti_flags = rc | LDD_F_PARAM;
3940 mutex_lock(&fsdb->fsdb_mutex);
3941 rc = mgs_write_log_param(env, mgs, fsdb, mti, mti->mti_params);
3942 mutex_unlock(&fsdb->fsdb_mutex);
3943 mgs_revoke_lock(mgs, fsdb, CONFIG_T_CONFIG);
3951 static int mgs_write_log_pool(const struct lu_env *env,
3952 struct mgs_device *mgs, char *logname,
3953 struct fs_db *fsdb, char *tgtname,
3954 enum lcfg_command_type cmd,
3955 char *fsname, char *poolname,
3956 char *ostname, char *comment)
3958 struct llog_handle *llh = NULL;
3961 rc = record_start_log(env, mgs, &llh, logname);
3964 rc = record_marker(env, llh, fsdb, CM_START, tgtname, comment);
3967 rc = record_base(env, llh, tgtname, 0, cmd,
3968 fsname, poolname, ostname, 0);
3971 rc = record_marker(env, llh, fsdb, CM_END, tgtname, comment);
3973 record_end_log(env, &llh);
3977 int mgs_nodemap_cmd(const struct lu_env *env, struct mgs_device *mgs,
3978 enum lcfg_command_type cmd, const char *nodemap_name,
3989 case LCFG_NODEMAP_ADD:
3990 rc = nodemap_add(nodemap_name);
3992 case LCFG_NODEMAP_DEL:
3993 rc = nodemap_del(nodemap_name);
3995 case LCFG_NODEMAP_ADD_RANGE:
3996 rc = nodemap_parse_range(param, nid);
3999 rc = nodemap_add_range(nodemap_name, nid);
4001 case LCFG_NODEMAP_DEL_RANGE:
4002 rc = nodemap_parse_range(param, nid);
4005 rc = nodemap_del_range(nodemap_name, nid);
4007 case LCFG_NODEMAP_ADMIN:
4008 bool_switch = simple_strtoul(param, NULL, 10);
4009 rc = nodemap_set_allow_root(nodemap_name, bool_switch);
4011 case LCFG_NODEMAP_TRUSTED:
4012 bool_switch = simple_strtoul(param, NULL, 10);
4013 rc = nodemap_set_trust_client_ids(nodemap_name, bool_switch);
4015 case LCFG_NODEMAP_SQUASH_UID:
4016 int_id = simple_strtoul(param, NULL, 10);
4017 rc = nodemap_set_squash_uid(nodemap_name, int_id);
4019 case LCFG_NODEMAP_SQUASH_GID:
4020 int_id = simple_strtoul(param, NULL, 10);
4021 rc = nodemap_set_squash_gid(nodemap_name, int_id);
4023 case LCFG_NODEMAP_ADD_UIDMAP:
4024 case LCFG_NODEMAP_ADD_GIDMAP:
4025 rc = nodemap_parse_idmap(param, idmap);
4028 if (cmd == LCFG_NODEMAP_ADD_UIDMAP)
4029 rc = nodemap_add_idmap(nodemap_name, NODEMAP_UID,
4032 rc = nodemap_add_idmap(nodemap_name, NODEMAP_GID,
4035 case LCFG_NODEMAP_DEL_UIDMAP:
4036 case LCFG_NODEMAP_DEL_GIDMAP:
4037 rc = nodemap_parse_idmap(param, idmap);
4040 if (cmd == LCFG_NODEMAP_DEL_UIDMAP)
4041 rc = nodemap_del_idmap(nodemap_name, NODEMAP_UID,
4044 rc = nodemap_del_idmap(nodemap_name, NODEMAP_GID,
4054 int mgs_pool_cmd(const struct lu_env *env, struct mgs_device *mgs,
4055 enum lcfg_command_type cmd, char *fsname,
4056 char *poolname, char *ostname)
4061 char *label = NULL, *canceled_label = NULL;
4063 struct mgs_target_info *mti = NULL;
4067 rc = mgs_find_or_make_fsdb(env, mgs, fsname, &fsdb);
4069 CERROR("Can't get db for %s\n", fsname);
4072 if (test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
4073 CERROR("%s is not defined\n", fsname);
4074 mgs_free_fsdb(mgs, fsdb);
4078 label_sz = 10 + strlen(fsname) + strlen(poolname);
4080 /* check if ostname match fsname */
4081 if (ostname != NULL) {
4084 ptr = strrchr(ostname, '-');
4085 if ((ptr == NULL) ||
4086 (strncmp(fsname, ostname, ptr-ostname) != 0))
4088 label_sz += strlen(ostname);
4091 OBD_ALLOC(label, label_sz);
4098 "new %s.%s", fsname, poolname);
4102 "add %s.%s.%s", fsname, poolname, ostname);
4105 OBD_ALLOC(canceled_label, label_sz);
4106 if (canceled_label == NULL)
4107 GOTO(out_label, rc = -ENOMEM);
4109 "rem %s.%s.%s", fsname, poolname, ostname);
4110 sprintf(canceled_label,
4111 "add %s.%s.%s", fsname, poolname, ostname);
4114 OBD_ALLOC(canceled_label, label_sz);
4115 if (canceled_label == NULL)
4116 GOTO(out_label, rc = -ENOMEM);
4118 "del %s.%s", fsname, poolname);
4119 sprintf(canceled_label,
4120 "new %s.%s", fsname, poolname);
4126 if (canceled_label != NULL) {
4129 GOTO(out_cancel, rc = -ENOMEM);
4132 mutex_lock(&fsdb->fsdb_mutex);
4133 /* write pool def to all MDT logs */
4134 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
4135 if (test_bit(i, fsdb->fsdb_mdt_index_map)) {
4136 rc = name_create_mdt_and_lov(&logname, &lovname,
4139 mutex_unlock(&fsdb->fsdb_mutex);
4142 if (canceled_label != NULL) {
4143 strcpy(mti->mti_svname, "lov pool");
4144 rc = mgs_modify(env, mgs, fsdb, mti, logname,
4145 lovname, canceled_label,
4150 rc = mgs_write_log_pool(env, mgs, logname,
4154 name_destroy(&logname);
4155 name_destroy(&lovname);
4157 mutex_unlock(&fsdb->fsdb_mutex);
4163 rc = name_create(&logname, fsname, "-client");
4165 mutex_unlock(&fsdb->fsdb_mutex);
4168 if (canceled_label != NULL) {
4169 rc = mgs_modify(env, mgs, fsdb, mti, logname,
4170 fsdb->fsdb_clilov, canceled_label, CM_SKIP);
4172 mutex_unlock(&fsdb->fsdb_mutex);
4173 name_destroy(&logname);
4178 rc = mgs_write_log_pool(env, mgs, logname, fsdb, fsdb->fsdb_clilov,
4179 cmd, fsname, poolname, ostname, label);
4180 mutex_unlock(&fsdb->fsdb_mutex);
4181 name_destroy(&logname);
4182 /* request for update */
4183 mgs_revoke_lock(mgs, fsdb, CONFIG_T_CONFIG);
4190 if (canceled_label != NULL)
4191 OBD_FREE(canceled_label, label_sz);
4193 OBD_FREE(label, label_sz);