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);
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);
337 RETURN(ERR_PTR(-EINVAL));
342 RETURN(ERR_PTR(-ENOMEM));
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);
450 RETURN(PTR_ERR(fsdb));
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,
831 static inline int record_add_conn(const struct lu_env *env,
832 struct llog_handle *llh,
833 char *devname, char *uuid)
835 return record_base(env, llh, devname, 0, LCFG_ADD_CONN, uuid,
839 static inline int record_attach(const struct lu_env *env,
840 struct llog_handle *llh, char *devname,
841 char *type, char *uuid)
843 return record_base(env, llh, devname, 0, LCFG_ATTACH, type, uuid,
847 static inline int record_setup(const struct lu_env *env,
848 struct llog_handle *llh, char *devname,
849 char *s1, char *s2, char *s3, char *s4)
851 return record_base(env, llh, devname, 0, LCFG_SETUP, s1, s2, s3, s4);
855 * \retval <0 record processing error
856 * \retval n record is processed. No need copy original one.
857 * \retval 0 record is not processed.
859 static int process_command(const struct lu_env *env, struct lustre_cfg *lcfg,
860 struct mgs_replace_uuid_lookup *mrul)
867 if (lcfg->lcfg_command == LCFG_ADD_UUID) {
868 /* LCFG_ADD_UUID command found. Let's skip original command
869 and add passed nids */
870 ptr = mrul->target.mti_params;
871 while (class_parse_nid(ptr, &nid, &ptr) == 0) {
872 CDEBUG(D_MGS, "add nid %s with uuid %s, "
873 "device %s\n", libcfs_nid2str(nid),
874 mrul->target.mti_params,
875 mrul->target.mti_svname);
876 rc = record_add_uuid(env,
878 mrul->target.mti_params);
883 if (nids_added == 0) {
884 CERROR("No new nids were added, nid %s with uuid %s, "
885 "device %s\n", libcfs_nid2str(nid),
886 mrul->target.mti_params,
887 mrul->target.mti_svname);
890 mrul->device_nids_added = 1;
896 if (mrul->device_nids_added && lcfg->lcfg_command == LCFG_SETUP) {
897 /* LCFG_SETUP command found. UUID should be changed */
898 rc = record_setup(env,
900 /* devname the same */
901 lustre_cfg_string(lcfg, 0),
902 /* s1 is not changed */
903 lustre_cfg_string(lcfg, 1),
904 /* new uuid should be
906 mrul->target.mti_params,
907 /* s3 is not changed */
908 lustre_cfg_string(lcfg, 3),
909 /* s4 is not changed */
910 lustre_cfg_string(lcfg, 4));
914 /* Another commands in target device block */
919 * Handler that called for every record in llog.
920 * Records are processed in order they placed in llog.
922 * \param[in] llh log to be processed
923 * \param[in] rec current record
924 * \param[in] data mgs_replace_uuid_lookup structure
928 static int mgs_replace_handler(const struct lu_env *env,
929 struct llog_handle *llh,
930 struct llog_rec_hdr *rec,
933 struct mgs_replace_uuid_lookup *mrul;
934 struct lustre_cfg *lcfg = REC_DATA(rec);
935 int cfg_len = REC_DATA_LEN(rec);
939 mrul = (struct mgs_replace_uuid_lookup *)data;
941 if (rec->lrh_type != OBD_CFG_REC) {
942 CERROR("unhandled lrh_type: %#x, cmd %x %s %s\n",
943 rec->lrh_type, lcfg->lcfg_command,
944 lustre_cfg_string(lcfg, 0),
945 lustre_cfg_string(lcfg, 1));
949 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
951 /* Do not copy any invalidated records */
952 GOTO(skip_out, rc = 0);
955 rc = check_markers(lcfg, mrul);
956 if (rc || mrul->skip_it)
957 GOTO(skip_out, rc = 0);
959 /* Write to new log all commands outside target device block */
960 if (!mrul->in_target_device)
961 GOTO(copy_out, rc = 0);
963 /* Skip all other LCFG_ADD_UUID and LCFG_ADD_CONN records
964 (failover nids) for this target, assuming that if then
965 primary is changing then so is the failover */
966 if (mrul->device_nids_added &&
967 (lcfg->lcfg_command == LCFG_ADD_UUID ||
968 lcfg->lcfg_command == LCFG_ADD_CONN))
969 GOTO(skip_out, rc = 0);
971 rc = process_command(env, lcfg, mrul);
978 /* Record is placed in temporary llog as is */
979 rc = llog_write(env, mrul->temp_llh, rec, LLOG_NEXT_IDX);
981 CDEBUG(D_MGS, "Copied idx=%d, rc=%d, len=%d, cmd %x %s %s\n",
982 rec->lrh_index, rc, rec->lrh_len, lcfg->lcfg_command,
983 lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));
987 CDEBUG(D_MGS, "Skipped idx=%d, rc=%d, len=%d, cmd %x %s %s\n",
988 rec->lrh_index, rc, rec->lrh_len, lcfg->lcfg_command,
989 lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));
993 static int mgs_log_is_empty(const struct lu_env *env,
994 struct mgs_device *mgs, char *name)
996 struct llog_ctxt *ctxt;
999 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
1000 LASSERT(ctxt != NULL);
1002 rc = llog_is_empty(env, ctxt, name);
1003 llog_ctxt_put(ctxt);
1007 static int mgs_replace_nids_log(const struct lu_env *env,
1008 struct obd_device *mgs, struct fs_db *fsdb,
1009 char *logname, char *devname, char *nids)
1011 struct llog_handle *orig_llh, *backup_llh;
1012 struct llog_ctxt *ctxt;
1013 struct mgs_replace_uuid_lookup *mrul;
1014 struct mgs_device *mgs_dev = lu2mgs_dev(mgs->obd_lu_dev);
1015 static struct obd_uuid cfg_uuid = { .uuid = "config_uuid" };
1020 CDEBUG(D_MGS, "Replace nids for %s in %s\n", devname, logname);
1022 ctxt = llog_get_context(mgs, LLOG_CONFIG_ORIG_CTXT);
1023 LASSERT(ctxt != NULL);
1025 if (mgs_log_is_empty(env, mgs_dev, logname)) {
1026 /* Log is empty. Nothing to replace */
1027 GOTO(out_put, rc = 0);
1030 OBD_ALLOC(backup, strlen(logname) + strlen(".bak") + 1);
1032 GOTO(out_put, rc = -ENOMEM);
1034 sprintf(backup, "%s.bak", logname);
1036 rc = llog_backup(env, mgs, ctxt, ctxt, logname, backup);
1038 /* Now erase original log file. Connections are not allowed.
1039 Backup is already saved */
1040 rc = llog_erase(env, ctxt, NULL, logname);
1043 } else if (rc != -ENOENT) {
1044 CERROR("%s: can't make backup for %s: rc = %d\n",
1045 mgs->obd_name, logname, rc);
1049 /* open local log */
1050 rc = llog_open_create(env, ctxt, &orig_llh, NULL, logname);
1052 GOTO(out_restore, rc);
1054 rc = llog_init_handle(env, orig_llh, LLOG_F_IS_PLAIN, &cfg_uuid);
1056 GOTO(out_closel, rc);
1058 /* open backup llog */
1059 rc = llog_open(env, ctxt, &backup_llh, NULL, backup,
1062 GOTO(out_closel, rc);
1064 rc = llog_init_handle(env, backup_llh, LLOG_F_IS_PLAIN, NULL);
1066 GOTO(out_close, rc);
1068 if (llog_get_size(backup_llh) <= 1)
1069 GOTO(out_close, rc = 0);
1071 OBD_ALLOC_PTR(mrul);
1073 GOTO(out_close, rc = -ENOMEM);
1074 /* devname is only needed information to replace UUID records */
1075 strlcpy(mrul->target.mti_svname, devname,
1076 sizeof(mrul->target.mti_svname));
1077 /* parse nids later */
1078 strlcpy(mrul->target.mti_params, nids, sizeof(mrul->target.mti_params));
1079 /* Copy records to this temporary llog */
1080 mrul->temp_llh = orig_llh;
1082 rc = llog_process(env, backup_llh, mgs_replace_handler,
1083 (void *)mrul, NULL);
1086 rc2 = llog_close(NULL, backup_llh);
1090 rc2 = llog_close(NULL, orig_llh);
1096 CERROR("%s: llog should be restored: rc = %d\n",
1098 rc2 = llog_backup(env, mgs, ctxt, ctxt, backup,
1101 CERROR("%s: can't restore backup %s: rc = %d\n",
1102 mgs->obd_name, logname, rc2);
1106 OBD_FREE(backup, strlen(backup) + 1);
1109 llog_ctxt_put(ctxt);
1112 CERROR("%s: failed to replace nids in log %s: rc = %d\n",
1113 mgs->obd_name, logname, rc);
1119 * Parse device name and get file system name and/or device index
1121 * \param[in] devname device name (ex. lustre-MDT0000)
1122 * \param[out] fsname file system name(optional)
1123 * \param[out] index device index(optional)
1127 static int mgs_parse_devname(char *devname, char *fsname, __u32 *index)
1132 /* Extract fsname */
1134 rc = server_name2fsname(devname, fsname, NULL);
1136 CDEBUG(D_MGS, "Device name %s without fsname\n",
1143 rc = server_name2index(devname, index, NULL);
1145 CDEBUG(D_MGS, "Device name %s with wrong index\n",
1154 /* This is only called during replace_nids */
1155 static int only_mgs_is_running(struct obd_device *mgs_obd)
1157 /* TDB: Is global variable with devices count exists? */
1158 int num_devices = get_devices_count();
1159 int num_exports = 0;
1160 struct obd_export *exp;
1162 spin_lock(&mgs_obd->obd_dev_lock);
1163 list_for_each_entry(exp, &mgs_obd->obd_exports, exp_obd_chain) {
1164 /* skip self export */
1165 if (exp == mgs_obd->obd_self_export)
1167 if (exp_connect_flags(exp) & OBD_CONNECT_MDS_MDS)
1172 CERROR("%s: node %s still connected during replace_nids "
1173 "connect_flags:%llx\n",
1175 libcfs_nid2str(exp->exp_nid_stats->nid),
1176 exp_connect_flags(exp));
1179 spin_unlock(&mgs_obd->obd_dev_lock);
1181 /* osd, MGS and MGC + self_export
1182 (wc -l /proc/fs/lustre/devices <= 2) && (non self exports == 0) */
1183 return (num_devices <= 3) && (num_exports == 0);
1186 static int name_create_mdt(char **logname, char *fsname, int i)
1190 sprintf(mdt_index, "-MDT%04x", i);
1191 return name_create(logname, fsname, mdt_index);
1195 * Replace nids for \a device to \a nids values
1197 * \param obd MGS obd device
1198 * \param devname nids need to be replaced for this device
1199 * (ex. lustre-OST0000)
1200 * \param nids nids list (ex. nid1,nid2,nid3)
1204 int mgs_replace_nids(const struct lu_env *env,
1205 struct mgs_device *mgs,
1206 char *devname, char *nids)
1208 /* Assume fsname is part of device name */
1209 char fsname[MTI_NAME_MAXLEN];
1216 struct obd_device *mgs_obd = mgs->mgs_obd;
1219 /* We can only change NIDs if no other nodes are connected */
1220 spin_lock(&mgs_obd->obd_dev_lock);
1221 conn_state = mgs_obd->obd_no_conn;
1222 mgs_obd->obd_no_conn = 1;
1223 spin_unlock(&mgs_obd->obd_dev_lock);
1225 /* We can not change nids if not only MGS is started */
1226 if (!only_mgs_is_running(mgs_obd)) {
1227 CERROR("Only MGS is allowed to be started\n");
1228 GOTO(out, rc = -EINPROGRESS);
1231 /* Get fsname and index*/
1232 rc = mgs_parse_devname(devname, fsname, &index);
1236 rc = mgs_find_or_make_fsdb(env, mgs, fsname, &fsdb);
1238 CERROR("%s: can't find fsdb: rc = %d\n", fsname, rc);
1242 /* Process client llogs */
1243 name_create(&logname, fsname, "-client");
1244 rc = mgs_replace_nids_log(env, mgs_obd, fsdb, logname, devname, nids);
1245 name_destroy(&logname);
1247 CERROR("%s: error while replacing NIDs for %s: rc = %d\n",
1248 fsname, devname, rc);
1252 /* Process MDT llogs */
1253 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
1254 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
1256 name_create_mdt(&logname, fsname, i);
1257 rc = mgs_replace_nids_log(env, mgs_obd, fsdb, logname, devname, nids);
1258 name_destroy(&logname);
1264 spin_lock(&mgs_obd->obd_dev_lock);
1265 mgs_obd->obd_no_conn = conn_state;
1266 spin_unlock(&mgs_obd->obd_dev_lock);
1271 static int record_lov_setup(const struct lu_env *env, struct llog_handle *llh,
1272 char *devname, struct lov_desc *desc)
1274 struct mgs_thread_info *mgi = mgs_env_info(env);
1275 struct llog_cfg_rec *lcr;
1278 lustre_cfg_bufs_reset(&mgi->mgi_bufs, devname);
1279 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, desc, sizeof(*desc));
1280 lcr = lustre_cfg_rec_new(LCFG_SETUP, &mgi->mgi_bufs);
1284 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1285 lustre_cfg_rec_free(lcr);
1289 static int record_lmv_setup(const struct lu_env *env, struct llog_handle *llh,
1290 char *devname, struct lmv_desc *desc)
1292 struct mgs_thread_info *mgi = mgs_env_info(env);
1293 struct llog_cfg_rec *lcr;
1296 lustre_cfg_bufs_reset(&mgi->mgi_bufs, devname);
1297 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, desc, sizeof(*desc));
1298 lcr = lustre_cfg_rec_new(LCFG_SETUP, &mgi->mgi_bufs);
1302 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1303 lustre_cfg_rec_free(lcr);
1307 static inline int record_mdc_add(const struct lu_env *env,
1308 struct llog_handle *llh,
1309 char *logname, char *mdcuuid,
1310 char *mdtuuid, char *index,
1313 return record_base(env,llh,logname,0,LCFG_ADD_MDC,
1314 mdtuuid,index,gen,mdcuuid);
1317 static inline int record_lov_add(const struct lu_env *env,
1318 struct llog_handle *llh,
1319 char *lov_name, char *ost_uuid,
1320 char *index, char *gen)
1322 return record_base(env, llh, lov_name, 0, LCFG_LOV_ADD_OBD,
1323 ost_uuid, index, gen, NULL);
1326 static inline int record_mount_opt(const struct lu_env *env,
1327 struct llog_handle *llh,
1328 char *profile, char *lov_name,
1331 return record_base(env, llh, NULL, 0, LCFG_MOUNTOPT,
1332 profile, lov_name, mdc_name, NULL);
1335 static int record_marker(const struct lu_env *env,
1336 struct llog_handle *llh,
1337 struct fs_db *fsdb, __u32 flags,
1338 char *tgtname, char *comment)
1340 struct mgs_thread_info *mgi = mgs_env_info(env);
1341 struct llog_cfg_rec *lcr;
1345 if (flags & CM_START)
1347 mgi->mgi_marker.cm_step = fsdb->fsdb_gen;
1348 mgi->mgi_marker.cm_flags = flags;
1349 mgi->mgi_marker.cm_vers = LUSTRE_VERSION_CODE;
1350 cplen = strlcpy(mgi->mgi_marker.cm_tgtname, tgtname,
1351 sizeof(mgi->mgi_marker.cm_tgtname));
1352 if (cplen >= sizeof(mgi->mgi_marker.cm_tgtname))
1354 cplen = strlcpy(mgi->mgi_marker.cm_comment, comment,
1355 sizeof(mgi->mgi_marker.cm_comment));
1356 if (cplen >= sizeof(mgi->mgi_marker.cm_comment))
1358 mgi->mgi_marker.cm_createtime = cfs_time_current_sec();
1359 mgi->mgi_marker.cm_canceltime = 0;
1360 lustre_cfg_bufs_reset(&mgi->mgi_bufs, NULL);
1361 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, &mgi->mgi_marker,
1362 sizeof(mgi->mgi_marker));
1363 lcr = lustre_cfg_rec_new(LCFG_MARKER, &mgi->mgi_bufs);
1367 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1368 lustre_cfg_rec_free(lcr);
1372 static int record_start_log(const struct lu_env *env, struct mgs_device *mgs,
1373 struct llog_handle **llh, char *name)
1375 static struct obd_uuid cfg_uuid = { .uuid = "config_uuid" };
1376 struct llog_ctxt *ctxt;
1381 GOTO(out, rc = -EBUSY);
1383 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
1385 GOTO(out, rc = -ENODEV);
1386 LASSERT(ctxt->loc_obd == mgs->mgs_obd);
1388 rc = llog_open_create(env, ctxt, llh, NULL, name);
1391 rc = llog_init_handle(env, *llh, LLOG_F_IS_PLAIN, &cfg_uuid);
1393 llog_close(env, *llh);
1395 llog_ctxt_put(ctxt);
1398 CERROR("%s: can't start log %s: rc = %d\n",
1399 mgs->mgs_obd->obd_name, name, rc);
1405 static int record_end_log(const struct lu_env *env, struct llog_handle **llh)
1409 rc = llog_close(env, *llh);
1415 /******************** config "macros" *********************/
1417 /* write an lcfg directly into a log (with markers) */
1418 static int mgs_write_log_direct(const struct lu_env *env,
1419 struct mgs_device *mgs, struct fs_db *fsdb,
1420 char *logname, struct llog_cfg_rec *lcr,
1421 char *devname, char *comment)
1423 struct llog_handle *llh = NULL;
1428 rc = record_start_log(env, mgs, &llh, logname);
1432 /* FIXME These should be a single journal transaction */
1433 rc = record_marker(env, llh, fsdb, CM_START, devname, comment);
1436 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1439 rc = record_marker(env, llh, fsdb, CM_END, devname, comment);
1443 record_end_log(env, &llh);
1447 /* write the lcfg in all logs for the given fs */
1448 static int mgs_write_log_direct_all(const struct lu_env *env,
1449 struct mgs_device *mgs,
1451 struct mgs_target_info *mti,
1452 struct llog_cfg_rec *lcr, char *devname,
1453 char *comment, int server_only)
1455 struct list_head log_list;
1456 struct mgs_direntry *dirent, *n;
1457 char *fsname = mti->mti_fsname;
1458 int rc = 0, len = strlen(fsname);
1461 /* Find all the logs in the CONFIGS directory */
1462 rc = class_dentry_readdir(env, mgs, &log_list);
1466 /* Could use fsdb index maps instead of directory listing */
1467 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
1468 list_del_init(&dirent->mde_list);
1469 /* don't write to sptlrpc rule log */
1470 if (strstr(dirent->mde_name, "-sptlrpc") != NULL)
1473 /* caller wants write server logs only */
1474 if (server_only && strstr(dirent->mde_name, "-client") != NULL)
1477 if (strlen(dirent->mde_name) <= len ||
1478 strncmp(fsname, dirent->mde_name, len) != 0 ||
1479 dirent->mde_name[len] != '-')
1482 CDEBUG(D_MGS, "Changing log %s\n", dirent->mde_name);
1483 /* Erase any old settings of this same parameter */
1484 rc = mgs_modify(env, mgs, fsdb, mti, dirent->mde_name,
1485 devname, comment, CM_SKIP);
1487 CERROR("%s: Can't modify llog %s: rc = %d\n",
1488 mgs->mgs_obd->obd_name, dirent->mde_name, rc);
1491 /* Write the new one */
1492 rc = mgs_write_log_direct(env, mgs, fsdb, dirent->mde_name,
1493 lcr, devname, comment);
1495 CERROR("%s: writing log %s: rc = %d\n",
1496 mgs->mgs_obd->obd_name, dirent->mde_name, rc);
1498 mgs_direntry_free(dirent);
1504 static int mgs_write_log_osp_to_mdt(const struct lu_env *env,
1505 struct mgs_device *mgs,
1507 struct mgs_target_info *mti,
1508 int index, char *logname);
1509 static int mgs_write_log_osc_to_lov(const struct lu_env *env,
1510 struct mgs_device *mgs,
1512 struct mgs_target_info *mti,
1513 char *logname, char *suffix, char *lovname,
1514 enum lustre_sec_part sec_part, int flags);
1515 static int name_create_mdt_and_lov(char **logname, char **lovname,
1516 struct fs_db *fsdb, int i);
1518 static int add_param(char *params, char *key, char *val)
1520 char *start = params + strlen(params);
1521 char *end = params + sizeof(((struct mgs_target_info *)0)->mti_params);
1525 keylen = strlen(key);
1526 if (start + 1 + keylen + strlen(val) >= end) {
1527 CERROR("params are too long: %s %s%s\n",
1528 params, key != NULL ? key : "", val);
1532 sprintf(start, " %s%s", key != NULL ? key : "", val);
1537 * Walk through client config log record and convert the related records
1540 static int mgs_steal_client_llog_handler(const struct lu_env *env,
1541 struct llog_handle *llh,
1542 struct llog_rec_hdr *rec, void *data)
1544 struct mgs_device *mgs;
1545 struct obd_device *obd;
1546 struct mgs_target_info *mti, *tmti;
1548 int cfg_len = rec->lrh_len;
1549 char *cfg_buf = (char*) (rec + 1);
1550 struct lustre_cfg *lcfg;
1552 struct llog_handle *mdt_llh = NULL;
1553 static int got_an_osc_or_mdc = 0;
1554 /* 0: not found any osc/mdc;
1558 static int last_step = -1;
1563 mti = ((struct temp_comp*)data)->comp_mti;
1564 tmti = ((struct temp_comp*)data)->comp_tmti;
1565 fsdb = ((struct temp_comp*)data)->comp_fsdb;
1566 obd = ((struct temp_comp *)data)->comp_obd;
1567 mgs = lu2mgs_dev(obd->obd_lu_dev);
1570 if (rec->lrh_type != OBD_CFG_REC) {
1571 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
1575 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
1577 CERROR("Insane cfg\n");
1581 lcfg = (struct lustre_cfg *)cfg_buf;
1583 if (lcfg->lcfg_command == LCFG_MARKER) {
1584 struct cfg_marker *marker;
1585 marker = lustre_cfg_buf(lcfg, 1);
1586 if (!strncmp(marker->cm_comment, "add osc", 7) &&
1587 (marker->cm_flags & CM_START) &&
1588 !(marker->cm_flags & CM_SKIP)) {
1589 got_an_osc_or_mdc = 1;
1590 cplen = strlcpy(tmti->mti_svname, marker->cm_tgtname,
1591 sizeof(tmti->mti_svname));
1592 if (cplen >= sizeof(tmti->mti_svname))
1594 rc = record_start_log(env, mgs, &mdt_llh,
1598 rc = record_marker(env, mdt_llh, fsdb, CM_START,
1599 mti->mti_svname, "add osc(copied)");
1600 record_end_log(env, &mdt_llh);
1601 last_step = marker->cm_step;
1604 if (!strncmp(marker->cm_comment, "add osc", 7) &&
1605 (marker->cm_flags & CM_END) &&
1606 !(marker->cm_flags & CM_SKIP)) {
1607 LASSERT(last_step == marker->cm_step);
1609 got_an_osc_or_mdc = 0;
1610 memset(tmti, 0, sizeof(*tmti));
1611 rc = record_start_log(env, mgs, &mdt_llh,
1615 rc = record_marker(env, mdt_llh, fsdb, CM_END,
1616 mti->mti_svname, "add osc(copied)");
1617 record_end_log(env, &mdt_llh);
1620 if (!strncmp(marker->cm_comment, "add mdc", 7) &&
1621 (marker->cm_flags & CM_START) &&
1622 !(marker->cm_flags & CM_SKIP)) {
1623 got_an_osc_or_mdc = 2;
1624 last_step = marker->cm_step;
1625 memcpy(tmti->mti_svname, marker->cm_tgtname,
1626 strlen(marker->cm_tgtname));
1630 if (!strncmp(marker->cm_comment, "add mdc", 7) &&
1631 (marker->cm_flags & CM_END) &&
1632 !(marker->cm_flags & CM_SKIP)) {
1633 LASSERT(last_step == marker->cm_step);
1635 got_an_osc_or_mdc = 0;
1636 memset(tmti, 0, sizeof(*tmti));
1641 if (got_an_osc_or_mdc == 0 || last_step < 0)
1644 if (lcfg->lcfg_command == LCFG_ADD_UUID) {
1645 __u64 nodenid = lcfg->lcfg_nid;
1647 if (strlen(tmti->mti_uuid) == 0) {
1648 /* target uuid not set, this config record is before
1649 * LCFG_SETUP, this nid is one of target node nid.
1651 tmti->mti_nids[tmti->mti_nid_count] = nodenid;
1652 tmti->mti_nid_count++;
1654 char nidstr[LNET_NIDSTR_SIZE];
1656 /* failover node nid */
1657 libcfs_nid2str_r(nodenid, nidstr, sizeof(nidstr));
1658 rc = add_param(tmti->mti_params, PARAM_FAILNODE,
1665 if (lcfg->lcfg_command == LCFG_SETUP) {
1668 target = lustre_cfg_string(lcfg, 1);
1669 memcpy(tmti->mti_uuid, target, strlen(target));
1673 /* ignore client side sptlrpc_conf_log */
1674 if (lcfg->lcfg_command == LCFG_SPTLRPC_CONF)
1677 if (lcfg->lcfg_command == LCFG_ADD_MDC) {
1680 if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1)
1683 memcpy(tmti->mti_fsname, mti->mti_fsname,
1684 strlen(mti->mti_fsname));
1685 tmti->mti_stripe_index = index;
1687 rc = mgs_write_log_osp_to_mdt(env, mgs, fsdb, tmti,
1688 mti->mti_stripe_index,
1690 memset(tmti, 0, sizeof(*tmti));
1694 if (lcfg->lcfg_command == LCFG_LOV_ADD_OBD) {
1697 char *logname, *lovname;
1699 rc = name_create_mdt_and_lov(&logname, &lovname, fsdb,
1700 mti->mti_stripe_index);
1703 sprintf(mdt_index, "-MDT%04x", mti->mti_stripe_index);
1705 if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1) {
1706 name_destroy(&logname);
1707 name_destroy(&lovname);
1711 tmti->mti_stripe_index = index;
1712 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, tmti, logname,
1715 name_destroy(&logname);
1716 name_destroy(&lovname);
1722 /* fsdb->fsdb_mutex is already held in mgs_write_log_target*/
1723 /* stealed from mgs_get_fsdb_from_llog*/
1724 static int mgs_steal_llog_for_mdt_from_client(const struct lu_env *env,
1725 struct mgs_device *mgs,
1727 struct temp_comp* comp)
1729 struct llog_handle *loghandle;
1730 struct mgs_target_info *tmti;
1731 struct llog_ctxt *ctxt;
1736 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
1737 LASSERT(ctxt != NULL);
1739 OBD_ALLOC_PTR(tmti);
1741 GOTO(out_ctxt, rc = -ENOMEM);
1743 comp->comp_tmti = tmti;
1744 comp->comp_obd = mgs->mgs_obd;
1746 rc = llog_open(env, ctxt, &loghandle, NULL, client_name,
1754 rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL);
1756 GOTO(out_close, rc);
1758 rc = llog_process_or_fork(env, loghandle, mgs_steal_client_llog_handler,
1759 (void *)comp, NULL, false);
1760 CDEBUG(D_MGS, "steal llog re = %d\n", rc);
1762 llog_close(env, loghandle);
1766 llog_ctxt_put(ctxt);
1770 /* lmv is the second thing for client logs */
1771 /* copied from mgs_write_log_lov. Please refer to that. */
1772 static int mgs_write_log_lmv(const struct lu_env *env,
1773 struct mgs_device *mgs,
1775 struct mgs_target_info *mti,
1776 char *logname, char *lmvname)
1778 struct llog_handle *llh = NULL;
1779 struct lmv_desc *lmvdesc;
1784 CDEBUG(D_MGS, "Writing lmv(%s) log for %s\n", lmvname,logname);
1786 OBD_ALLOC_PTR(lmvdesc);
1787 if (lmvdesc == NULL)
1789 lmvdesc->ld_active_tgt_count = 0;
1790 lmvdesc->ld_tgt_count = 0;
1791 sprintf((char*)lmvdesc->ld_uuid.uuid, "%s_UUID", lmvname);
1792 uuid = (char *)lmvdesc->ld_uuid.uuid;
1794 rc = record_start_log(env, mgs, &llh, logname);
1797 rc = record_marker(env, llh, fsdb, CM_START, lmvname, "lmv setup");
1800 rc = record_attach(env, llh, lmvname, "lmv", uuid);
1803 rc = record_lmv_setup(env, llh, lmvname, lmvdesc);
1806 rc = record_marker(env, llh, fsdb, CM_END, lmvname, "lmv setup");
1810 record_end_log(env, &llh);
1812 OBD_FREE_PTR(lmvdesc);
1816 /* lov is the first thing in the mdt and client logs */
1817 static int mgs_write_log_lov(const struct lu_env *env, struct mgs_device *mgs,
1818 struct fs_db *fsdb, struct mgs_target_info *mti,
1819 char *logname, char *lovname)
1821 struct llog_handle *llh = NULL;
1822 struct lov_desc *lovdesc;
1827 CDEBUG(D_MGS, "Writing lov(%s) log for %s\n", lovname, logname);
1830 #01 L attach 0:lov_mdsA 1:lov 2:71ccb_lov_mdsA_19f961a9e1
1831 #02 L lov_setup 0:lov_mdsA 1:(struct lov_desc)
1832 uuid=lov1_UUID, stripe count=1, size=1048576, offset=0, pattern=0
1835 /* FIXME just make lov_setup accept empty desc (put uuid in buf 2) */
1836 OBD_ALLOC_PTR(lovdesc);
1837 if (lovdesc == NULL)
1839 lovdesc->ld_magic = LOV_DESC_MAGIC;
1840 lovdesc->ld_tgt_count = 0;
1841 /* Defaults. Can be changed later by lcfg config_param */
1842 lovdesc->ld_default_stripe_count = 1;
1843 lovdesc->ld_pattern = LOV_PATTERN_RAID0;
1844 lovdesc->ld_default_stripe_size = LOV_DESC_STRIPE_SIZE_DEFAULT;
1845 lovdesc->ld_default_stripe_offset = -1;
1846 lovdesc->ld_qos_maxage = LOV_DESC_QOS_MAXAGE_DEFAULT;
1847 sprintf((char*)lovdesc->ld_uuid.uuid, "%s_UUID", lovname);
1848 /* can these be the same? */
1849 uuid = (char *)lovdesc->ld_uuid.uuid;
1851 /* This should always be the first entry in a log.
1852 rc = mgs_clear_log(obd, logname); */
1853 rc = record_start_log(env, mgs, &llh, logname);
1856 /* FIXME these should be a single journal transaction */
1857 rc = record_marker(env, llh, fsdb, CM_START, lovname, "lov setup");
1860 rc = record_attach(env, llh, lovname, "lov", uuid);
1863 rc = record_lov_setup(env, llh, lovname, lovdesc);
1866 rc = record_marker(env, llh, fsdb, CM_END, lovname, "lov setup");
1871 record_end_log(env, &llh);
1873 OBD_FREE_PTR(lovdesc);
1877 /* add failnids to open log */
1878 static int mgs_write_log_failnids(const struct lu_env *env,
1879 struct mgs_target_info *mti,
1880 struct llog_handle *llh,
1883 char *failnodeuuid = NULL;
1884 char *ptr = mti->mti_params;
1889 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) nal=90 0: 1:uml1_UUID
1890 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
1891 #05 L setup 0:OSC_uml1_ost1_mdsA 1:ost1_UUID 2:uml1_UUID
1892 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) nal=90 0: 1:uml2_UUID
1893 #0x L add_uuid nid=2@elan(0x1000000000002) nal=90 0: 1:uml2_UUID
1894 #07 L add_conn 0:OSC_uml1_ost1_mdsA 1:uml2_UUID
1898 * Pull failnid info out of params string, which may contain something
1899 * like "<nid1>,<nid2>:<nid3>,<nid4>". class_parse_nid() does not
1900 * complain about abnormal inputs like ",:<nid1>", "<nid1>:,<nid2>",
1901 * etc. However, convert_hostnames() should have caught those.
1903 while (class_find_param(ptr, PARAM_FAILNODE, &ptr) == 0) {
1904 while (class_parse_nid(ptr, &nid, &ptr) == 0) {
1905 char nidstr[LNET_NIDSTR_SIZE];
1907 if (failnodeuuid == NULL) {
1908 /* We don't know the failover node name,
1909 * so just use the first nid as the uuid */
1910 libcfs_nid2str_r(nid, nidstr, sizeof(nidstr));
1911 rc = name_create(&failnodeuuid, nidstr, "");
1915 CDEBUG(D_MGS, "add nid %s for failover uuid %s, "
1917 libcfs_nid2str_r(nid, nidstr, sizeof(nidstr)),
1918 failnodeuuid, cliname);
1919 rc = record_add_uuid(env, llh, nid, failnodeuuid);
1921 * If *ptr is ':', we have added all NIDs for
1925 rc = record_add_conn(env, llh, cliname,
1927 name_destroy(&failnodeuuid);
1928 failnodeuuid = NULL;
1932 rc = record_add_conn(env, llh, cliname, failnodeuuid);
1933 name_destroy(&failnodeuuid);
1934 failnodeuuid = NULL;
1941 static int mgs_write_log_mdc_to_lmv(const struct lu_env *env,
1942 struct mgs_device *mgs,
1944 struct mgs_target_info *mti,
1945 char *logname, char *lmvname)
1947 struct llog_handle *llh = NULL;
1948 char *mdcname = NULL;
1949 char *nodeuuid = NULL;
1950 char *mdcuuid = NULL;
1951 char *lmvuuid = NULL;
1953 char nidstr[LNET_NIDSTR_SIZE];
1957 if (mgs_log_is_empty(env, mgs, logname)) {
1958 CERROR("log is empty! Logical error\n");
1962 CDEBUG(D_MGS, "adding mdc for %s to log %s:lmv(%s)\n",
1963 mti->mti_svname, logname, lmvname);
1965 libcfs_nid2str_r(mti->mti_nids[0], nidstr, sizeof(nidstr));
1966 rc = name_create(&nodeuuid, nidstr, "");
1969 rc = name_create(&mdcname, mti->mti_svname, "-mdc");
1972 rc = name_create(&mdcuuid, mdcname, "_UUID");
1975 rc = name_create(&lmvuuid, lmvname, "_UUID");
1979 rc = record_start_log(env, mgs, &llh, logname);
1982 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
1986 for (i = 0; i < mti->mti_nid_count; i++) {
1987 CDEBUG(D_MGS, "add nid %s for mdt\n",
1988 libcfs_nid2str_r(mti->mti_nids[i],
1989 nidstr, sizeof(nidstr)));
1991 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
1996 rc = record_attach(env, llh, mdcname, LUSTRE_MDC_NAME, lmvuuid);
1999 rc = record_setup(env, llh, mdcname, mti->mti_uuid, nodeuuid,
2003 rc = mgs_write_log_failnids(env, mti, llh, mdcname);
2006 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
2007 rc = record_mdc_add(env, llh, lmvname, mdcuuid, mti->mti_uuid,
2011 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname,
2016 record_end_log(env, &llh);
2018 name_destroy(&lmvuuid);
2019 name_destroy(&mdcuuid);
2020 name_destroy(&mdcname);
2021 name_destroy(&nodeuuid);
2025 static inline int name_create_lov(char **lovname, char *mdtname,
2026 struct fs_db *fsdb, int index)
2029 if (index == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2030 return name_create(lovname, fsdb->fsdb_name, "-mdtlov");
2032 return name_create(lovname, mdtname, "-mdtlov");
2035 static int name_create_mdt_and_lov(char **logname, char **lovname,
2036 struct fs_db *fsdb, int i)
2040 rc = name_create_mdt(logname, fsdb->fsdb_name, i);
2044 if (i == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2045 rc = name_create(lovname, fsdb->fsdb_name, "-mdtlov");
2047 rc = name_create(lovname, *logname, "-mdtlov");
2049 name_destroy(logname);
2055 static inline int name_create_mdt_osc(char **oscname, char *ostname,
2056 struct fs_db *fsdb, int i)
2060 if (i == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2061 sprintf(suffix, "-osc");
2063 sprintf(suffix, "-osc-MDT%04x", i);
2064 return name_create(oscname, ostname, suffix);
2067 /* add new mdc to already existent MDS */
2068 static int mgs_write_log_osp_to_mdt(const struct lu_env *env,
2069 struct mgs_device *mgs,
2071 struct mgs_target_info *mti,
2072 int mdt_index, char *logname)
2074 struct llog_handle *llh = NULL;
2075 char *nodeuuid = NULL;
2076 char *ospname = NULL;
2077 char *lovuuid = NULL;
2078 char *mdtuuid = NULL;
2079 char *svname = NULL;
2080 char *mdtname = NULL;
2081 char *lovname = NULL;
2083 char nidstr[LNET_NIDSTR_SIZE];
2087 if (mgs_log_is_empty(env, mgs, mti->mti_svname)) {
2088 CERROR("log is empty! Logical error\n");
2092 CDEBUG(D_MGS, "adding osp index %d to %s\n", mti->mti_stripe_index,
2095 rc = name_create_mdt(&mdtname, fsdb->fsdb_name, mti->mti_stripe_index);
2099 libcfs_nid2str_r(mti->mti_nids[0], nidstr, sizeof(nidstr));
2100 rc = name_create(&nodeuuid, nidstr, "");
2102 GOTO(out_destory, rc);
2104 rc = name_create(&svname, mdtname, "-osp");
2106 GOTO(out_destory, rc);
2108 sprintf(index_str, "-MDT%04x", mdt_index);
2109 rc = name_create(&ospname, svname, index_str);
2111 GOTO(out_destory, rc);
2113 rc = name_create_lov(&lovname, logname, fsdb, mdt_index);
2115 GOTO(out_destory, rc);
2117 rc = name_create(&lovuuid, lovname, "_UUID");
2119 GOTO(out_destory, rc);
2121 rc = name_create(&mdtuuid, mdtname, "_UUID");
2123 GOTO(out_destory, rc);
2125 rc = record_start_log(env, mgs, &llh, logname);
2127 GOTO(out_destory, rc);
2129 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
2132 GOTO(out_destory, rc);
2134 for (i = 0; i < mti->mti_nid_count; i++) {
2135 CDEBUG(D_MGS, "add nid %s for mdt\n",
2136 libcfs_nid2str_r(mti->mti_nids[i],
2137 nidstr, sizeof(nidstr)));
2138 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
2143 rc = record_attach(env, llh, ospname, LUSTRE_OSP_NAME, lovuuid);
2147 rc = record_setup(env, llh, ospname, mti->mti_uuid, nodeuuid,
2152 rc = mgs_write_log_failnids(env, mti, llh, ospname);
2156 /* Add mdc(osp) to lod */
2157 snprintf(index_str, sizeof(mti->mti_stripe_index), "%d",
2158 mti->mti_stripe_index);
2159 rc = record_base(env, llh, lovname, 0, LCFG_ADD_MDC, mti->mti_uuid,
2160 index_str, "1", NULL);
2164 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname, "add osp");
2169 record_end_log(env, &llh);
2172 name_destroy(&mdtuuid);
2173 name_destroy(&lovuuid);
2174 name_destroy(&lovname);
2175 name_destroy(&ospname);
2176 name_destroy(&svname);
2177 name_destroy(&nodeuuid);
2178 name_destroy(&mdtname);
2182 static int mgs_write_log_mdt0(const struct lu_env *env,
2183 struct mgs_device *mgs,
2185 struct mgs_target_info *mti)
2187 char *log = mti->mti_svname;
2188 struct llog_handle *llh = NULL;
2189 char *uuid, *lovname;
2191 char *ptr = mti->mti_params;
2192 int rc = 0, failout = 0;
2195 OBD_ALLOC(uuid, sizeof(struct obd_uuid));
2199 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
2200 failout = (strncmp(ptr, "failout", 7) == 0);
2202 rc = name_create(&lovname, log, "-mdtlov");
2205 if (mgs_log_is_empty(env, mgs, log)) {
2206 rc = mgs_write_log_lov(env, mgs, fsdb, mti, log, lovname);
2211 sprintf(mdt_index, "%d", mti->mti_stripe_index);
2213 rc = record_start_log(env, mgs, &llh, log);
2217 /* add MDT itself */
2219 /* FIXME this whole fn should be a single journal transaction */
2220 sprintf(uuid, "%s_UUID", log);
2221 rc = record_marker(env, llh, fsdb, CM_START, log, "add mdt");
2224 rc = record_attach(env, llh, log, LUSTRE_MDT_NAME, uuid);
2227 rc = record_mount_opt(env, llh, log, lovname, NULL);
2230 rc = record_setup(env, llh, log, uuid, mdt_index, lovname,
2231 failout ? "n" : "f");
2234 rc = record_marker(env, llh, fsdb, CM_END, log, "add mdt");
2238 record_end_log(env, &llh);
2240 name_destroy(&lovname);
2242 OBD_FREE(uuid, sizeof(struct obd_uuid));
2246 /* envelope method for all layers log */
2247 static int mgs_write_log_mdt(const struct lu_env *env,
2248 struct mgs_device *mgs,
2250 struct mgs_target_info *mti)
2252 struct mgs_thread_info *mgi = mgs_env_info(env);
2253 struct llog_handle *llh = NULL;
2258 CDEBUG(D_MGS, "writing new mdt %s\n", mti->mti_svname);
2260 if (mti->mti_uuid[0] == '\0') {
2261 /* Make up our own uuid */
2262 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
2263 "%s_UUID", mti->mti_svname);
2267 rc = mgs_write_log_mdt0(env, mgs, fsdb, mti);
2270 /* Append the mdt info to the client log */
2271 rc = name_create(&cliname, mti->mti_fsname, "-client");
2275 if (mgs_log_is_empty(env, mgs, cliname)) {
2276 /* Start client log */
2277 rc = mgs_write_log_lov(env, mgs, fsdb, mti, cliname,
2281 rc = mgs_write_log_lmv(env, mgs, fsdb, mti, cliname,
2288 #09 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
2289 #10 L attach 0:MDC_uml1_mdsA_MNT_client 1:mdc 2:1d834_MNT_client_03f
2290 #11 L setup 0:MDC_uml1_mdsA_MNT_client 1:mdsA_UUID 2:uml1_UUID
2291 #12 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
2292 #13 L add_conn 0:MDC_uml1_mdsA_MNT_client 1:uml2_UUID
2293 #14 L mount_option 0: 1:client 2:lov1 3:MDC_uml1_mdsA_MNT_client
2296 /* copy client info about lov/lmv */
2297 mgi->mgi_comp.comp_mti = mti;
2298 mgi->mgi_comp.comp_fsdb = fsdb;
2300 rc = mgs_steal_llog_for_mdt_from_client(env, mgs, cliname,
2304 rc = mgs_write_log_mdc_to_lmv(env, mgs, fsdb, mti, cliname,
2310 rc = record_start_log(env, mgs, &llh, cliname);
2314 rc = record_marker(env, llh, fsdb, CM_START, cliname,
2318 rc = record_mount_opt(env, llh, cliname, fsdb->fsdb_clilov,
2322 rc = record_marker(env, llh, fsdb, CM_END, cliname,
2328 /* for_all_existing_mdt except current one */
2329 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2330 if (i != mti->mti_stripe_index &&
2331 test_bit(i, fsdb->fsdb_mdt_index_map)) {
2334 rc = name_create_mdt(&logname, fsdb->fsdb_name, i);
2338 rc = mgs_write_log_osp_to_mdt(env, mgs, fsdb, mti,
2340 name_destroy(&logname);
2346 record_end_log(env, &llh);
2348 name_destroy(&cliname);
2352 /* Add the ost info to the client/mdt lov */
2353 static int mgs_write_log_osc_to_lov(const struct lu_env *env,
2354 struct mgs_device *mgs, struct fs_db *fsdb,
2355 struct mgs_target_info *mti,
2356 char *logname, char *suffix, char *lovname,
2357 enum lustre_sec_part sec_part, int flags)
2359 struct llog_handle *llh = NULL;
2360 char *nodeuuid = NULL;
2361 char *oscname = NULL;
2362 char *oscuuid = NULL;
2363 char *lovuuid = NULL;
2364 char *svname = NULL;
2366 char nidstr[LNET_NIDSTR_SIZE];
2370 CDEBUG(D_INFO, "adding osc for %s to log %s\n",
2371 mti->mti_svname, logname);
2373 if (mgs_log_is_empty(env, mgs, logname)) {
2374 CERROR("log is empty! Logical error\n");
2378 libcfs_nid2str_r(mti->mti_nids[0], nidstr, sizeof(nidstr));
2379 rc = name_create(&nodeuuid, nidstr, "");
2382 rc = name_create(&svname, mti->mti_svname, "-osc");
2386 /* for the system upgraded from old 1.8, keep using the old osc naming
2387 * style for mdt, see name_create_mdt_osc(). LU-1257 */
2388 if (test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2389 rc = name_create(&oscname, svname, "");
2391 rc = name_create(&oscname, svname, suffix);
2395 rc = name_create(&oscuuid, oscname, "_UUID");
2398 rc = name_create(&lovuuid, lovname, "_UUID");
2404 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
2406 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
2407 #04 L attach 0:OSC_uml1_ost1_MNT_client 1:osc 2:89070_lov1_a41dff51a
2408 #05 L setup 0:OSC_uml1_ost1_MNT_client 1:ost1_UUID 2:uml1_UUID
2410 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
2411 #07 L add_conn 0:OSC_uml1_ost1_MNT_client 1:uml2_UUID
2412 #08 L lov_modify_tgts add 0:lov1 1:ost1_UUID 2(index):0 3(gen):1
2415 rc = record_start_log(env, mgs, &llh, logname);
2419 /* FIXME these should be a single journal transaction */
2420 rc = record_marker(env, llh, fsdb, CM_START | flags, mti->mti_svname,
2425 /* NB: don't change record order, because upon MDT steal OSC config
2426 * from client, it treats all nids before LCFG_SETUP as target nids
2427 * (multiple interfaces), while nids after as failover node nids.
2428 * See mgs_steal_client_llog_handler() LCFG_ADD_UUID.
2430 for (i = 0; i < mti->mti_nid_count; i++) {
2431 CDEBUG(D_MGS, "add nid %s\n",
2432 libcfs_nid2str_r(mti->mti_nids[i],
2433 nidstr, sizeof(nidstr)));
2434 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
2438 rc = record_attach(env, llh, oscname, LUSTRE_OSC_NAME, lovuuid);
2441 rc = record_setup(env, llh, oscname, mti->mti_uuid, nodeuuid,
2445 rc = mgs_write_log_failnids(env, mti, llh, oscname);
2449 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
2451 rc = record_lov_add(env, llh, lovname, mti->mti_uuid, index, "1");
2454 rc = record_marker(env, llh, fsdb, CM_END | flags, mti->mti_svname,
2459 record_end_log(env, &llh);
2461 name_destroy(&lovuuid);
2462 name_destroy(&oscuuid);
2463 name_destroy(&oscname);
2464 name_destroy(&svname);
2465 name_destroy(&nodeuuid);
2469 static int mgs_write_log_ost(const struct lu_env *env,
2470 struct mgs_device *mgs, struct fs_db *fsdb,
2471 struct mgs_target_info *mti)
2473 struct llog_handle *llh = NULL;
2474 char *logname, *lovname;
2475 char *ptr = mti->mti_params;
2476 int rc, flags = 0, failout = 0, i;
2479 CDEBUG(D_MGS, "writing new ost %s\n", mti->mti_svname);
2481 /* The ost startup log */
2483 /* If the ost log already exists, that means that someone reformatted
2484 the ost and it called target_add again. */
2485 if (!mgs_log_is_empty(env, mgs, mti->mti_svname)) {
2486 LCONSOLE_ERROR_MSG(0x141, "The config log for %s already "
2487 "exists, yet the server claims it never "
2488 "registered. It may have been reformatted, "
2489 "or the index changed. writeconf the MDT to "
2490 "regenerate all logs.\n", mti->mti_svname);
2495 attach obdfilter ost1 ost1_UUID
2496 setup /dev/loop2 ldiskfs f|n errors=remount-ro,user_xattr
2498 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
2499 failout = (strncmp(ptr, "failout", 7) == 0);
2500 rc = record_start_log(env, mgs, &llh, mti->mti_svname);
2503 /* FIXME these should be a single journal transaction */
2504 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,"add ost");
2507 if (*mti->mti_uuid == '\0')
2508 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
2509 "%s_UUID", mti->mti_svname);
2510 rc = record_attach(env, llh, mti->mti_svname,
2511 "obdfilter"/*LUSTRE_OST_NAME*/, mti->mti_uuid);
2514 rc = record_setup(env, llh, mti->mti_svname,
2515 "dev"/*ignored*/, "type"/*ignored*/,
2516 failout ? "n" : "f", NULL/*options*/);
2519 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname, "add ost");
2523 record_end_log(env, &llh);
2526 /* We also have to update the other logs where this osc is part of
2529 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
2530 /* If we're upgrading, the old mdt log already has our
2531 entry. Let's do a fake one for fun. */
2532 /* Note that we can't add any new failnids, since we don't
2533 know the old osc names. */
2534 flags = CM_SKIP | CM_UPGRADE146;
2536 } else if ((mti->mti_flags & LDD_F_UPDATE) != LDD_F_UPDATE) {
2537 /* If the update flag isn't set, don't update client/mdt
2540 LCONSOLE_WARN("Client log for %s was not updated; writeconf "
2541 "the MDT first to regenerate it.\n",
2545 /* Add ost to all MDT lov defs */
2546 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
2547 if (test_bit(i, fsdb->fsdb_mdt_index_map)) {
2550 rc = name_create_mdt_and_lov(&logname, &lovname, fsdb,
2554 sprintf(mdt_index, "-MDT%04x", i);
2555 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, mti,
2557 lovname, LUSTRE_SP_MDT,
2559 name_destroy(&logname);
2560 name_destroy(&lovname);
2566 /* Append ost info to the client log */
2567 rc = name_create(&logname, mti->mti_fsname, "-client");
2570 if (mgs_log_is_empty(env, mgs, logname)) {
2571 /* Start client log */
2572 rc = mgs_write_log_lov(env, mgs, fsdb, mti, logname,
2576 rc = mgs_write_log_lmv(env, mgs, fsdb, mti, logname,
2581 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, mti, logname, "",
2582 fsdb->fsdb_clilov, LUSTRE_SP_CLI, 0);
2584 name_destroy(&logname);
2588 static __inline__ int mgs_param_empty(char *ptr)
2592 if ((tmp = strchr(ptr, '=')) && (*(++tmp) == '\0'))
2597 static int mgs_write_log_failnid_internal(const struct lu_env *env,
2598 struct mgs_device *mgs,
2600 struct mgs_target_info *mti,
2601 char *logname, char *cliname)
2604 struct llog_handle *llh = NULL;
2606 if (mgs_param_empty(mti->mti_params)) {
2607 /* Remove _all_ failnids */
2608 rc = mgs_modify(env, mgs, fsdb, mti, logname,
2609 mti->mti_svname, "add failnid", CM_SKIP);
2610 return rc < 0 ? rc : 0;
2613 /* Otherwise failover nids are additive */
2614 rc = record_start_log(env, mgs, &llh, logname);
2617 /* FIXME this should be a single journal transaction */
2618 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
2622 rc = mgs_write_log_failnids(env, mti, llh, cliname);
2625 rc = record_marker(env, llh, fsdb, CM_END,
2626 mti->mti_svname, "add failnid");
2628 record_end_log(env, &llh);
2633 /* Add additional failnids to an existing log.
2634 The mdc/osc must have been added to logs first */
2635 /* tcp nids must be in dotted-quad ascii -
2636 we can't resolve hostnames from the kernel. */
2637 static int mgs_write_log_add_failnid(const struct lu_env *env,
2638 struct mgs_device *mgs,
2640 struct mgs_target_info *mti)
2642 char *logname, *cliname;
2646 /* FIXME we currently can't erase the failnids
2647 * given when a target first registers, since they aren't part of
2648 * an "add uuid" stanza */
2650 /* Verify that we know about this target */
2651 if (mgs_log_is_empty(env, mgs, mti->mti_svname)) {
2652 LCONSOLE_ERROR_MSG(0x142, "The target %s has not registered "
2653 "yet. It must be started before failnids "
2654 "can be added.\n", mti->mti_svname);
2658 /* Create mdc/osc client name (e.g. lustre-OST0001-osc) */
2659 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
2660 rc = name_create(&cliname, mti->mti_svname, "-mdc");
2661 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2662 rc = name_create(&cliname, mti->mti_svname, "-osc");
2668 /* Add failover nids to the client log */
2669 rc = name_create(&logname, mti->mti_fsname, "-client");
2671 name_destroy(&cliname);
2674 rc = mgs_write_log_failnid_internal(env, mgs, fsdb,mti,logname,cliname);
2675 name_destroy(&logname);
2676 name_destroy(&cliname);
2680 if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2681 /* Add OST failover nids to the MDT logs as well */
2684 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2685 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
2687 rc = name_create_mdt(&logname, mti->mti_fsname, i);
2690 rc = name_create_mdt_osc(&cliname, mti->mti_svname,
2693 name_destroy(&logname);
2696 rc = mgs_write_log_failnid_internal(env, mgs, fsdb,
2699 name_destroy(&cliname);
2700 name_destroy(&logname);
2709 static int mgs_wlp_lcfg(const struct lu_env *env,
2710 struct mgs_device *mgs, struct fs_db *fsdb,
2711 struct mgs_target_info *mti,
2712 char *logname, struct lustre_cfg_bufs *bufs,
2713 char *tgtname, char *ptr)
2715 char comment[MTI_NAME_MAXLEN];
2717 struct llog_cfg_rec *lcr;
2720 /* Erase any old settings of this same parameter */
2721 memcpy(comment, ptr, MTI_NAME_MAXLEN);
2722 comment[MTI_NAME_MAXLEN - 1] = 0;
2723 /* But don't try to match the value. */
2724 tmp = strchr(comment, '=');
2727 /* FIXME we should skip settings that are the same as old values */
2728 rc = mgs_modify(env, mgs, fsdb, mti, logname, tgtname, comment,CM_SKIP);
2731 del = mgs_param_empty(ptr);
2733 LCONSOLE_INFO("%s parameter %s.%s in log %s\n", del ? "Disabling" : rc ?
2734 "Setting" : "Modifying", tgtname, comment, logname);
2736 /* mgs_modify() will return 1 if nothing had to be done */
2742 lustre_cfg_bufs_reset(bufs, tgtname);
2743 lustre_cfg_bufs_set_string(bufs, 1, ptr);
2744 if (mti->mti_flags & LDD_F_PARAM2)
2745 lustre_cfg_bufs_set_string(bufs, 2, LCTL_UPCALL);
2747 lcr = lustre_cfg_rec_new((mti->mti_flags & LDD_F_PARAM2) ?
2748 LCFG_SET_PARAM : LCFG_PARAM, bufs);
2752 rc = mgs_write_log_direct(env, mgs, fsdb, logname, lcr, tgtname,
2754 lustre_cfg_rec_free(lcr);
2758 static int mgs_write_log_param2(const struct lu_env *env,
2759 struct mgs_device *mgs,
2761 struct mgs_target_info *mti, char *ptr)
2763 struct lustre_cfg_bufs bufs;
2767 CDEBUG(D_MGS, "next param '%s'\n", ptr);
2768 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, PARAMS_FILENAME, &bufs,
2769 mti->mti_svname, ptr);
2774 /* write global variable settings into log */
2775 static int mgs_write_log_sys(const struct lu_env *env,
2776 struct mgs_device *mgs, struct fs_db *fsdb,
2777 struct mgs_target_info *mti, char *sys, char *ptr)
2779 struct mgs_thread_info *mgi = mgs_env_info(env);
2780 struct lustre_cfg *lcfg;
2781 struct llog_cfg_rec *lcr;
2783 int rc, cmd, convert = 1;
2785 if (class_match_param(ptr, PARAM_TIMEOUT, &tmp) == 0) {
2786 cmd = LCFG_SET_TIMEOUT;
2787 } else if (class_match_param(ptr, PARAM_LDLM_TIMEOUT, &tmp) == 0) {
2788 cmd = LCFG_SET_LDLM_TIMEOUT;
2789 /* Check for known params here so we can return error to lctl */
2790 } else if ((class_match_param(ptr, PARAM_AT_MIN, &tmp) == 0) ||
2791 (class_match_param(ptr, PARAM_AT_MAX, &tmp) == 0) ||
2792 (class_match_param(ptr, PARAM_AT_EXTRA, &tmp) == 0) ||
2793 (class_match_param(ptr, PARAM_AT_EARLY_MARGIN, &tmp) == 0) ||
2794 (class_match_param(ptr, PARAM_AT_HISTORY, &tmp) == 0)) {
2796 } else if (class_match_param(ptr, PARAM_JOBID_VAR, &tmp) == 0) {
2797 convert = 0; /* Don't convert string value to integer */
2803 if (mgs_param_empty(ptr))
2804 CDEBUG(D_MGS, "global '%s' removed\n", sys);
2806 CDEBUG(D_MGS, "global '%s' val=%s\n", sys, tmp);
2808 lustre_cfg_bufs_reset(&mgi->mgi_bufs, NULL);
2809 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, sys);
2810 if (!convert && *tmp != '\0')
2811 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 2, tmp);
2812 lcr = lustre_cfg_rec_new(cmd, &mgi->mgi_bufs);
2816 lcfg = &lcr->lcr_cfg;
2817 lcfg->lcfg_num = convert ? simple_strtoul(tmp, NULL, 0) : 0;
2818 /* truncate the comment to the parameter name */
2822 /* modify all servers and clients */
2823 rc = mgs_write_log_direct_all(env, mgs, fsdb, mti,
2824 *tmp == '\0' ? NULL : lcr,
2825 mti->mti_fsname, sys, 0);
2826 if (rc == 0 && *tmp != '\0') {
2828 case LCFG_SET_TIMEOUT:
2829 if (!obd_timeout_set || lcfg->lcfg_num > obd_timeout)
2830 class_process_config(lcfg);
2832 case LCFG_SET_LDLM_TIMEOUT:
2833 if (!ldlm_timeout_set || lcfg->lcfg_num > ldlm_timeout)
2834 class_process_config(lcfg);
2841 lustre_cfg_rec_free(lcr);
2845 /* write quota settings into log */
2846 static int mgs_write_log_quota(const struct lu_env *env, struct mgs_device *mgs,
2847 struct fs_db *fsdb, struct mgs_target_info *mti,
2848 char *quota, char *ptr)
2850 struct mgs_thread_info *mgi = mgs_env_info(env);
2851 struct llog_cfg_rec *lcr;
2854 int rc, cmd = LCFG_PARAM;
2856 /* support only 'meta' and 'data' pools so far */
2857 if (class_match_param(ptr, QUOTA_METAPOOL_NAME, &tmp) != 0 &&
2858 class_match_param(ptr, QUOTA_DATAPOOL_NAME, &tmp) != 0) {
2859 CERROR("parameter quota.%s isn't supported (only quota.mdt "
2860 "& quota.ost are)\n", ptr);
2865 CDEBUG(D_MGS, "global '%s' removed\n", quota);
2867 CDEBUG(D_MGS, "global '%s'\n", quota);
2869 if (strchr(tmp, 'u') == NULL && strchr(tmp, 'g') == NULL &&
2870 strcmp(tmp, "none") != 0) {
2871 CERROR("enable option(%s) isn't supported\n", tmp);
2876 lustre_cfg_bufs_reset(&mgi->mgi_bufs, mti->mti_fsname);
2877 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, quota);
2878 lcr = lustre_cfg_rec_new(cmd, &mgi->mgi_bufs);
2882 /* truncate the comment to the parameter name */
2887 /* XXX we duplicated quota enable information in all server
2888 * config logs, it should be moved to a separate config
2889 * log once we cleanup the config log for global param. */
2890 /* modify all servers */
2891 rc = mgs_write_log_direct_all(env, mgs, fsdb, mti,
2892 *tmp == '\0' ? NULL : lcr,
2893 mti->mti_fsname, quota, 1);
2895 lustre_cfg_rec_free(lcr);
2896 return rc < 0 ? rc : 0;
2899 static int mgs_srpc_set_param_disk(const struct lu_env *env,
2900 struct mgs_device *mgs,
2902 struct mgs_target_info *mti,
2905 struct mgs_thread_info *mgi = mgs_env_info(env);
2906 struct llog_cfg_rec *lcr;
2907 struct llog_handle *llh = NULL;
2909 char *comment, *ptr;
2915 ptr = strchr(param, '=');
2916 LASSERT(ptr != NULL);
2919 OBD_ALLOC(comment, len + 1);
2920 if (comment == NULL)
2922 strncpy(comment, param, len);
2923 comment[len] = '\0';
2926 lustre_cfg_bufs_reset(&mgi->mgi_bufs, mti->mti_svname);
2927 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, param);
2928 lcr = lustre_cfg_rec_new(LCFG_SPTLRPC_CONF, &mgi->mgi_bufs);
2930 GOTO(out_comment, rc = -ENOMEM);
2932 /* construct log name */
2933 rc = name_create(&logname, mti->mti_fsname, "-sptlrpc");
2937 if (mgs_log_is_empty(env, mgs, logname)) {
2938 rc = record_start_log(env, mgs, &llh, logname);
2941 record_end_log(env, &llh);
2944 /* obsolete old one */
2945 rc = mgs_modify(env, mgs, fsdb, mti, logname, mti->mti_svname,
2949 /* write the new one */
2950 rc = mgs_write_log_direct(env, mgs, fsdb, logname, lcr,
2951 mti->mti_svname, comment);
2953 CERROR("%s: error writing log %s: rc = %d\n",
2954 mgs->mgs_obd->obd_name, logname, rc);
2956 name_destroy(&logname);
2958 lustre_cfg_rec_free(lcr);
2960 OBD_FREE(comment, len + 1);
2964 static int mgs_srpc_set_param_udesc_mem(struct fs_db *fsdb,
2969 /* disable the adjustable udesc parameter for now, i.e. use default
2970 * setting that client always ship udesc to MDT if possible. to enable
2971 * it simply remove the following line */
2974 ptr = strchr(param, '=');
2979 if (strcmp(param, PARAM_SRPC_UDESC))
2982 if (strcmp(ptr, "yes") == 0) {
2983 set_bit(FSDB_UDESC, &fsdb->fsdb_flags);
2984 CWARN("Enable user descriptor shipping from client to MDT\n");
2985 } else if (strcmp(ptr, "no") == 0) {
2986 clear_bit(FSDB_UDESC, &fsdb->fsdb_flags);
2987 CWARN("Disable user descriptor shipping from client to MDT\n");
2995 CERROR("Invalid param: %s\n", param);
2999 static int mgs_srpc_set_param_mem(struct fs_db *fsdb,
3003 struct sptlrpc_rule rule;
3004 struct sptlrpc_rule_set *rset;
3008 if (strncmp(param, PARAM_SRPC, sizeof(PARAM_SRPC) - 1) != 0) {
3009 CERROR("Invalid sptlrpc parameter: %s\n", param);
3013 if (strncmp(param, PARAM_SRPC_UDESC,
3014 sizeof(PARAM_SRPC_UDESC) - 1) == 0) {
3015 RETURN(mgs_srpc_set_param_udesc_mem(fsdb, param));
3018 if (strncmp(param, PARAM_SRPC_FLVR, sizeof(PARAM_SRPC_FLVR) - 1) != 0) {
3019 CERROR("Invalid sptlrpc flavor parameter: %s\n", param);
3023 param += sizeof(PARAM_SRPC_FLVR) - 1;
3025 rc = sptlrpc_parse_rule(param, &rule);
3029 /* mgs rules implies must be mgc->mgs */
3030 if (test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
3031 if ((rule.sr_from != LUSTRE_SP_MGC &&
3032 rule.sr_from != LUSTRE_SP_ANY) ||
3033 (rule.sr_to != LUSTRE_SP_MGS &&
3034 rule.sr_to != LUSTRE_SP_ANY))
3038 /* preapre room for this coming rule. svcname format should be:
3039 * - fsname: general rule
3040 * - fsname-tgtname: target-specific rule
3042 if (strchr(svname, '-')) {
3043 struct mgs_tgt_srpc_conf *tgtconf;
3046 for (tgtconf = fsdb->fsdb_srpc_tgt; tgtconf != NULL;
3047 tgtconf = tgtconf->mtsc_next) {
3048 if (!strcmp(tgtconf->mtsc_tgt, svname)) {
3057 OBD_ALLOC_PTR(tgtconf);
3058 if (tgtconf == NULL)
3061 name_len = strlen(svname);
3063 OBD_ALLOC(tgtconf->mtsc_tgt, name_len + 1);
3064 if (tgtconf->mtsc_tgt == NULL) {
3065 OBD_FREE_PTR(tgtconf);
3068 memcpy(tgtconf->mtsc_tgt, svname, name_len);
3070 tgtconf->mtsc_next = fsdb->fsdb_srpc_tgt;
3071 fsdb->fsdb_srpc_tgt = tgtconf;
3074 rset = &tgtconf->mtsc_rset;
3076 rset = &fsdb->fsdb_srpc_gen;
3079 rc = sptlrpc_rule_set_merge(rset, &rule);
3084 static int mgs_srpc_set_param(const struct lu_env *env,
3085 struct mgs_device *mgs,
3087 struct mgs_target_info *mti,
3097 /* keep a copy of original param, which could be destroied
3099 copy_size = strlen(param) + 1;
3100 OBD_ALLOC(copy, copy_size);
3103 memcpy(copy, param, copy_size);
3105 rc = mgs_srpc_set_param_mem(fsdb, mti->mti_svname, param);
3109 /* previous steps guaranteed the syntax is correct */
3110 rc = mgs_srpc_set_param_disk(env, mgs, fsdb, mti, copy);
3114 if (test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
3116 * for mgs rules, make them effective immediately.
3118 LASSERT(fsdb->fsdb_srpc_tgt == NULL);
3119 sptlrpc_target_update_exp_flavor(mgs->mgs_obd,
3120 &fsdb->fsdb_srpc_gen);
3124 OBD_FREE(copy, copy_size);
3128 struct mgs_srpc_read_data {
3129 struct fs_db *msrd_fsdb;
3133 static int mgs_srpc_read_handler(const struct lu_env *env,
3134 struct llog_handle *llh,
3135 struct llog_rec_hdr *rec, void *data)
3137 struct mgs_srpc_read_data *msrd = data;
3138 struct cfg_marker *marker;
3139 struct lustre_cfg *lcfg = REC_DATA(rec);
3140 char *svname, *param;
3144 if (rec->lrh_type != OBD_CFG_REC) {
3145 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
3149 cfg_len = REC_DATA_LEN(rec);
3151 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
3153 CERROR("Insane cfg\n");
3157 if (lcfg->lcfg_command == LCFG_MARKER) {
3158 marker = lustre_cfg_buf(lcfg, 1);
3160 if (marker->cm_flags & CM_START &&
3161 marker->cm_flags & CM_SKIP)
3162 msrd->msrd_skip = 1;
3163 if (marker->cm_flags & CM_END)
3164 msrd->msrd_skip = 0;
3169 if (msrd->msrd_skip)
3172 if (lcfg->lcfg_command != LCFG_SPTLRPC_CONF) {
3173 CERROR("invalid command (%x)\n", lcfg->lcfg_command);
3177 svname = lustre_cfg_string(lcfg, 0);
3178 if (svname == NULL) {
3179 CERROR("svname is empty\n");
3183 param = lustre_cfg_string(lcfg, 1);
3184 if (param == NULL) {
3185 CERROR("param is empty\n");
3189 rc = mgs_srpc_set_param_mem(msrd->msrd_fsdb, svname, param);
3191 CERROR("read sptlrpc record error (%d): %s\n", rc, param);
3196 int mgs_get_fsdb_srpc_from_llog(const struct lu_env *env,
3197 struct mgs_device *mgs,
3200 struct llog_handle *llh = NULL;
3201 struct llog_ctxt *ctxt;
3203 struct mgs_srpc_read_data msrd;
3207 /* construct log name */
3208 rc = name_create(&logname, fsdb->fsdb_name, "-sptlrpc");
3212 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
3213 LASSERT(ctxt != NULL);
3215 if (mgs_log_is_empty(env, mgs, logname))
3218 rc = llog_open(env, ctxt, &llh, NULL, logname,
3226 rc = llog_init_handle(env, llh, LLOG_F_IS_PLAIN, NULL);
3228 GOTO(out_close, rc);
3230 if (llog_get_size(llh) <= 1)
3231 GOTO(out_close, rc = 0);
3233 msrd.msrd_fsdb = fsdb;
3236 rc = llog_process(env, llh, mgs_srpc_read_handler, (void *)&msrd,
3240 llog_close(env, llh);
3242 llog_ctxt_put(ctxt);
3243 name_destroy(&logname);
3246 CERROR("failed to read sptlrpc config database: %d\n", rc);
3250 /* Permanent settings of all parameters by writing into the appropriate
3251 * configuration logs.
3252 * A parameter with null value ("<param>='\0'") means to erase it out of
3255 static int mgs_write_log_param(const struct lu_env *env,
3256 struct mgs_device *mgs, struct fs_db *fsdb,
3257 struct mgs_target_info *mti, char *ptr)
3259 struct mgs_thread_info *mgi = mgs_env_info(env);
3262 int rc = 0, rc2 = 0;
3265 /* For various parameter settings, we have to figure out which logs
3266 care about them (e.g. both mdt and client for lov settings) */
3267 CDEBUG(D_MGS, "next param '%s'\n", ptr);
3269 /* The params are stored in MOUNT_DATA_FILE and modified via
3270 tunefs.lustre, or set using lctl conf_param */
3272 /* Processed in lustre_start_mgc */
3273 if (class_match_param(ptr, PARAM_MGSNODE, NULL) == 0)
3276 /* Processed in ost/mdt */
3277 if (class_match_param(ptr, PARAM_NETWORK, NULL) == 0)
3280 /* Processed in mgs_write_log_ost */
3281 if (class_match_param(ptr, PARAM_FAILMODE, NULL) == 0) {
3282 if (mti->mti_flags & LDD_F_PARAM) {
3283 LCONSOLE_ERROR_MSG(0x169, "%s can only be "
3284 "changed with tunefs.lustre"
3285 "and --writeconf\n", ptr);
3291 if (class_match_param(ptr, PARAM_SRPC, NULL) == 0) {
3292 rc = mgs_srpc_set_param(env, mgs, fsdb, mti, ptr);
3296 if (class_match_param(ptr, PARAM_FAILNODE, NULL) == 0) {
3297 /* Add a failover nidlist */
3299 /* We already processed failovers params for new
3300 targets in mgs_write_log_target */
3301 if (mti->mti_flags & LDD_F_PARAM) {
3302 CDEBUG(D_MGS, "Adding failnode\n");
3303 rc = mgs_write_log_add_failnid(env, mgs, fsdb, mti);
3308 if (class_match_param(ptr, PARAM_SYS, &tmp) == 0) {
3309 rc = mgs_write_log_sys(env, mgs, fsdb, mti, ptr, tmp);
3313 if (class_match_param(ptr, PARAM_QUOTA, &tmp) == 0) {
3314 rc = mgs_write_log_quota(env, mgs, fsdb, mti, ptr, tmp);
3318 if (class_match_param(ptr, PARAM_OSC""PARAM_ACTIVE, &tmp) == 0) {
3319 /* active=0 means off, anything else means on */
3320 int flag = (*tmp == '0') ? CM_EXCLUDE : 0;
3323 if (!(mti->mti_flags & LDD_F_SV_TYPE_OST)) {
3324 LCONSOLE_ERROR_MSG(0x144, "%s: Only OSCs can "
3325 "be (de)activated.\n",
3327 GOTO(end, rc = -EINVAL);
3329 LCONSOLE_WARN("Permanently %sactivating %s\n",
3330 flag ? "de": "re", mti->mti_svname);
3332 rc = name_create(&logname, mti->mti_fsname, "-client");
3335 rc = mgs_modify(env, mgs, fsdb, mti, logname,
3336 mti->mti_svname, "add osc", flag);
3337 name_destroy(&logname);
3341 /* Add to all MDT logs for CMD */
3342 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3343 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
3345 rc = name_create_mdt(&logname, mti->mti_fsname, i);
3348 rc = mgs_modify(env, mgs, fsdb, mti, logname,
3349 mti->mti_svname, "add osc", flag);
3350 name_destroy(&logname);
3356 LCONSOLE_ERROR_MSG(0x145, "Couldn't find %s in"
3357 "log (%d). No permanent "
3358 "changes were made to the "
3360 mti->mti_svname, rc);
3361 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags))
3362 LCONSOLE_ERROR_MSG(0x146, "This may be"
3367 "update the logs.\n");
3370 /* Fall through to osc proc for deactivating live OSC
3371 on running MDT / clients. */
3373 /* Below here, let obd's XXX_process_config methods handle it */
3375 /* All lov. in proc */
3376 if (class_match_param(ptr, PARAM_LOV, NULL) == 0) {
3379 CDEBUG(D_MGS, "lov param %s\n", ptr);
3380 if (!(mti->mti_flags & LDD_F_SV_TYPE_MDT)) {
3381 LCONSOLE_ERROR_MSG(0x147, "LOV params must be "
3382 "set on the MDT, not %s. "
3389 if (mgs_log_is_empty(env, mgs, mti->mti_svname))
3390 GOTO(end, rc = -ENODEV);
3392 rc = name_create_mdt_and_lov(&logname, &mdtlovname, fsdb,
3393 mti->mti_stripe_index);
3396 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, mti->mti_svname,
3397 &mgi->mgi_bufs, mdtlovname, ptr);
3398 name_destroy(&logname);
3399 name_destroy(&mdtlovname);
3404 rc = name_create(&logname, mti->mti_fsname, "-client");
3407 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname, &mgi->mgi_bufs,
3408 fsdb->fsdb_clilov, ptr);
3409 name_destroy(&logname);
3413 /* All osc., mdc., llite. params in proc */
3414 if ((class_match_param(ptr, PARAM_OSC, NULL) == 0) ||
3415 (class_match_param(ptr, PARAM_MDC, NULL) == 0) ||
3416 (class_match_param(ptr, PARAM_LLITE, NULL) == 0)) {
3419 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
3420 LCONSOLE_ERROR_MSG(0x148, "Upgraded client logs for %s"
3421 " cannot be modified. Consider"
3422 " updating the configuration with"
3425 GOTO(end, rc = -EINVAL);
3427 if (memcmp(ptr, PARAM_LLITE, strlen(PARAM_LLITE)) == 0) {
3428 rc = name_create(&cname, mti->mti_fsname, "-client");
3429 /* Add the client type to match the obdname in
3430 class_config_llog_handler */
3431 } else if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
3432 rc = name_create(&cname, mti->mti_svname, "-mdc");
3433 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
3434 rc = name_create(&cname, mti->mti_svname, "-osc");
3436 GOTO(end, rc = -EINVAL);
3441 /* Forbid direct update of llite root squash parameters.
3442 * These parameters are indirectly set via the MDT settings.
3444 if ((class_match_param(ptr, PARAM_LLITE, &tmp) == 0) &&
3445 ((memcmp(tmp, "root_squash=", 12) == 0) ||
3446 (memcmp(tmp, "nosquash_nids=", 14) == 0))) {
3447 LCONSOLE_ERROR("%s: root squash parameters can only "
3448 "be updated through MDT component\n",
3450 name_destroy(&cname);
3451 GOTO(end, rc = -EINVAL);
3454 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
3457 rc = name_create(&logname, mti->mti_fsname, "-client");
3459 name_destroy(&cname);
3462 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname, &mgi->mgi_bufs,
3465 /* osc params affect the MDT as well */
3466 if (!rc && (mti->mti_flags & LDD_F_SV_TYPE_OST)) {
3469 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
3470 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
3472 name_destroy(&cname);
3473 rc = name_create_mdt_osc(&cname, mti->mti_svname,
3475 name_destroy(&logname);
3478 rc = name_create_mdt(&logname,
3479 mti->mti_fsname, i);
3482 if (!mgs_log_is_empty(env, mgs, logname)) {
3483 rc = mgs_wlp_lcfg(env, mgs, fsdb,
3492 name_destroy(&logname);
3493 name_destroy(&cname);
3497 /* All mdt. params in proc */
3498 if (class_match_param(ptr, PARAM_MDT, &tmp) == 0) {
3502 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
3503 if (strncmp(mti->mti_svname, mti->mti_fsname,
3504 MTI_NAME_MAXLEN) == 0)
3505 /* device is unspecified completely? */
3506 rc = LDD_F_SV_TYPE_MDT | LDD_F_SV_ALL;
3508 rc = server_name2index(mti->mti_svname, &idx, NULL);
3511 if ((rc & LDD_F_SV_TYPE_MDT) == 0)
3513 if (rc & LDD_F_SV_ALL) {
3514 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3516 fsdb->fsdb_mdt_index_map))
3518 rc = name_create_mdt(&logname,
3519 mti->mti_fsname, i);
3522 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti,
3523 logname, &mgi->mgi_bufs,
3525 name_destroy(&logname);
3530 if ((memcmp(tmp, "root_squash=", 12) == 0) ||
3531 (memcmp(tmp, "nosquash_nids=", 14) == 0)) {
3532 LCONSOLE_ERROR("%s: root squash parameters "
3533 "cannot be applied to a single MDT\n",
3535 GOTO(end, rc = -EINVAL);
3537 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti,
3538 mti->mti_svname, &mgi->mgi_bufs,
3539 mti->mti_svname, ptr);
3544 /* root squash settings are also applied to llite
3545 * config log (see LU-1778) */
3547 ((memcmp(tmp, "root_squash=", 12) == 0) ||
3548 (memcmp(tmp, "nosquash_nids=", 14) == 0))) {
3552 rc = name_create(&cname, mti->mti_fsname, "-client");
3555 rc = name_create(&logname, mti->mti_fsname, "-client");
3557 name_destroy(&cname);
3560 rc = name_create(&ptr2, PARAM_LLITE, tmp);
3562 name_destroy(&cname);
3563 name_destroy(&logname);
3566 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname,
3567 &mgi->mgi_bufs, cname, ptr2);
3568 name_destroy(&ptr2);
3569 name_destroy(&logname);
3570 name_destroy(&cname);
3575 /* All mdd., ost. and osd. params in proc */
3576 if ((class_match_param(ptr, PARAM_MDD, NULL) == 0) ||
3577 (class_match_param(ptr, PARAM_OST, NULL) == 0) ||
3578 (class_match_param(ptr, PARAM_OSD, NULL) == 0)) {
3579 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
3580 if (mgs_log_is_empty(env, mgs, mti->mti_svname))
3581 GOTO(end, rc = -ENODEV);
3583 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, mti->mti_svname,
3584 &mgi->mgi_bufs, mti->mti_svname, ptr);
3588 LCONSOLE_WARN("Ignoring unrecognized param '%s'\n", ptr);
3593 CERROR("err %d on param '%s'\n", rc, ptr);
3598 /* Not implementing automatic failover nid addition at this time. */
3599 int mgs_check_failnid(const struct lu_env *env, struct mgs_device *mgs,
3600 struct mgs_target_info *mti)
3607 rc = mgs_find_or_make_fsdb(obd, fsname, &fsdb);
3611 if (mgs_log_is_empty(obd, mti->mti_svname))
3612 /* should never happen */
3615 CDEBUG(D_MGS, "Checking for new failnids for %s\n", mti->mti_svname);
3617 /* FIXME We can just check mti->params to see if we're already in
3618 the failover list. Modify mti->params for rewriting back at
3619 server_register_target(). */
3621 mutex_lock(&fsdb->fsdb_mutex);
3622 rc = mgs_write_log_add_failnid(obd, fsdb, mti);
3623 mutex_unlock(&fsdb->fsdb_mutex);
3632 int mgs_write_log_target(const struct lu_env *env, struct mgs_device *mgs,
3633 struct mgs_target_info *mti, struct fs_db *fsdb)
3640 /* set/check the new target index */
3641 rc = mgs_set_index(env, mgs, mti);
3645 if (rc == EALREADY) {
3646 LCONSOLE_WARN("Found index %d for %s, updating log\n",
3647 mti->mti_stripe_index, mti->mti_svname);
3648 /* We would like to mark old log sections as invalid
3649 and add new log sections in the client and mdt logs.
3650 But if we add new sections, then live clients will
3651 get repeat setup instructions for already running
3652 osc's. So don't update the client/mdt logs. */
3653 mti->mti_flags &= ~LDD_F_UPDATE;
3657 mutex_lock(&fsdb->fsdb_mutex);
3659 if (mti->mti_flags &
3660 (LDD_F_VIRGIN | LDD_F_UPGRADE14 | LDD_F_WRITECONF)) {
3661 /* Generate a log from scratch */
3662 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
3663 rc = mgs_write_log_mdt(env, mgs, fsdb, mti);
3664 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
3665 rc = mgs_write_log_ost(env, mgs, fsdb, mti);
3667 CERROR("Unknown target type %#x, can't create log for "
3668 "%s\n", mti->mti_flags, mti->mti_svname);
3671 CERROR("Can't write logs for %s (%d)\n",
3672 mti->mti_svname, rc);
3676 /* Just update the params from tunefs in mgs_write_log_params */
3677 CDEBUG(D_MGS, "Update params for %s\n", mti->mti_svname);
3678 mti->mti_flags |= LDD_F_PARAM;
3681 /* allocate temporary buffer, where class_get_next_param will
3682 make copy of a current parameter */
3683 OBD_ALLOC(buf, strlen(mti->mti_params) + 1);
3685 GOTO(out_up, rc = -ENOMEM);
3686 params = mti->mti_params;
3687 while (params != NULL) {
3688 rc = class_get_next_param(¶ms, buf);
3691 /* there is no next parameter, that is
3696 CDEBUG(D_MGS, "remaining string: '%s', param: '%s'\n",
3698 rc = mgs_write_log_param(env, mgs, fsdb, mti, buf);
3703 OBD_FREE(buf, strlen(mti->mti_params) + 1);
3706 mutex_unlock(&fsdb->fsdb_mutex);
3710 int mgs_erase_log(const struct lu_env *env, struct mgs_device *mgs, char *name)
3712 struct llog_ctxt *ctxt;
3715 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
3717 CERROR("%s: MGS config context doesn't exist\n",
3718 mgs->mgs_obd->obd_name);
3721 rc = llog_erase(env, ctxt, NULL, name);
3722 /* llog may not exist */
3725 llog_ctxt_put(ctxt);
3729 CERROR("%s: failed to clear log %s: %d\n",
3730 mgs->mgs_obd->obd_name, name, rc);
3735 /* erase all logs for the given fs */
3736 int mgs_erase_logs(const struct lu_env *env, struct mgs_device *mgs, char *fsname)
3739 struct list_head log_list;
3740 struct mgs_direntry *dirent, *n;
3741 int rc, len = strlen(fsname);
3745 /* Find all the logs in the CONFIGS directory */
3746 rc = class_dentry_readdir(env, mgs, &log_list);
3750 mutex_lock(&mgs->mgs_mutex);
3752 /* Delete the fs db */
3753 fsdb = mgs_find_fsdb(mgs, fsname);
3755 mgs_free_fsdb(mgs, fsdb);
3757 mutex_unlock(&mgs->mgs_mutex);
3759 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
3760 list_del_init(&dirent->mde_list);
3761 suffix = strrchr(dirent->mde_name, '-');
3762 if (suffix != NULL) {
3763 if ((len == suffix - dirent->mde_name) &&
3764 (strncmp(fsname, dirent->mde_name, len) == 0)) {
3765 CDEBUG(D_MGS, "Removing log %s\n",
3767 mgs_erase_log(env, mgs, dirent->mde_name);
3770 mgs_direntry_free(dirent);
3776 /* list all logs for the given fs */
3777 int mgs_list_logs(const struct lu_env *env, struct mgs_device *mgs,
3778 struct obd_ioctl_data *data)
3780 struct list_head log_list;
3781 struct mgs_direntry *dirent, *n;
3787 /* Find all the logs in the CONFIGS directory */
3788 rc = class_dentry_readdir(env, mgs, &log_list);
3792 out = data->ioc_bulk;
3793 remains = data->ioc_inllen1;
3794 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
3795 list_del_init(&dirent->mde_list);
3796 suffix = strrchr(dirent->mde_name, '-');
3797 if (suffix != NULL) {
3798 l = snprintf(out, remains, "config log: $%s\n",
3803 mgs_direntry_free(dirent);
3810 /* from llog_swab */
3811 static void print_lustre_cfg(struct lustre_cfg *lcfg)
3816 CDEBUG(D_MGS, "lustre_cfg: %p\n", lcfg);
3817 CDEBUG(D_MGS, "\tlcfg->lcfg_version: %#x\n", lcfg->lcfg_version);
3819 CDEBUG(D_MGS, "\tlcfg->lcfg_command: %#x\n", lcfg->lcfg_command);
3820 CDEBUG(D_MGS, "\tlcfg->lcfg_num: %#x\n", lcfg->lcfg_num);
3821 CDEBUG(D_MGS, "\tlcfg->lcfg_flags: %#x\n", lcfg->lcfg_flags);
3822 CDEBUG(D_MGS, "\tlcfg->lcfg_nid: %s\n", libcfs_nid2str(lcfg->lcfg_nid));
3824 CDEBUG(D_MGS, "\tlcfg->lcfg_bufcount: %d\n", lcfg->lcfg_bufcount);
3825 if (lcfg->lcfg_bufcount < LUSTRE_CFG_MAX_BUFCOUNT)
3826 for (i = 0; i < lcfg->lcfg_bufcount; i++) {
3827 CDEBUG(D_MGS, "\tlcfg->lcfg_buflens[%d]: %d %s\n",
3828 i, lcfg->lcfg_buflens[i],
3829 lustre_cfg_string(lcfg, i));
3834 /* Setup params fsdb and log
3836 int mgs_params_fsdb_setup(const struct lu_env *env, struct mgs_device *mgs,
3839 struct llog_handle *params_llh = NULL;
3843 rc = mgs_find_or_make_fsdb(env, mgs, PARAMS_FILENAME, &fsdb);
3845 mutex_lock(&fsdb->fsdb_mutex);
3846 rc = record_start_log(env, mgs, ¶ms_llh, PARAMS_FILENAME);
3848 rc = record_end_log(env, ¶ms_llh);
3849 mutex_unlock(&fsdb->fsdb_mutex);
3855 /* Cleanup params fsdb and log
3857 int mgs_params_fsdb_cleanup(const struct lu_env *env, struct mgs_device *mgs)
3859 return mgs_erase_logs(env, mgs, PARAMS_FILENAME);
3862 /* Set a permanent (config log) param for a target or fs
3863 * \param lcfg buf0 may contain the device (testfs-MDT0000) name
3864 * buf1 contains the single parameter
3866 int mgs_setparam(const struct lu_env *env, struct mgs_device *mgs,
3867 struct lustre_cfg *lcfg, char *fsname)
3870 struct mgs_target_info *mti;
3871 char *devname, *param;
3878 print_lustre_cfg(lcfg);
3880 /* lustre, lustre-mdtlov, lustre-client, lustre-MDT0000 */
3881 devname = lustre_cfg_string(lcfg, 0);
3882 param = lustre_cfg_string(lcfg, 1);
3884 /* Assume device name embedded in param:
3885 lustre-OST0000.osc.max_dirty_mb=32 */
3886 ptr = strchr(param, '.');
3894 LCONSOLE_ERROR_MSG(0x14d, "No target specified: %s\n", param);
3898 rc = mgs_parse_devname(devname, fsname, NULL);
3899 if (rc == 0 && !mgs_parse_devname(devname, NULL, &index)) {
3900 /* param related to llite isn't allowed to set by OST or MDT */
3901 if (rc == 0 && strncmp(param, PARAM_LLITE,
3902 sizeof(PARAM_LLITE) - 1) == 0)
3905 /* assume devname is the fsname */
3906 strlcpy(fsname, devname, MTI_NAME_MAXLEN);
3908 CDEBUG(D_MGS, "setparam fs='%s' device='%s'\n", fsname, devname);
3910 rc = mgs_find_or_make_fsdb(env, mgs,
3911 lcfg->lcfg_command == LCFG_SET_PARAM ?
3912 PARAMS_FILENAME : fsname, &fsdb);
3916 if (lcfg->lcfg_command != LCFG_SET_PARAM &&
3917 !test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags) &&
3918 test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
3919 CERROR("No filesystem targets for %s. cfg_device from lctl "
3920 "is '%s'\n", fsname, devname);
3921 mgs_free_fsdb(mgs, fsdb);
3925 /* Create a fake mti to hold everything */
3928 GOTO(out, rc = -ENOMEM);
3929 if (strlcpy(mti->mti_fsname, fsname, sizeof(mti->mti_fsname))
3930 >= sizeof(mti->mti_fsname))
3931 GOTO(out, rc = -E2BIG);
3932 if (strlcpy(mti->mti_svname, devname, sizeof(mti->mti_svname))
3933 >= sizeof(mti->mti_svname))
3934 GOTO(out, rc = -E2BIG);
3935 if (strlcpy(mti->mti_params, param, sizeof(mti->mti_params))
3936 >= sizeof(mti->mti_params))
3937 GOTO(out, rc = -E2BIG);
3938 rc = server_name2index(mti->mti_svname, &mti->mti_stripe_index, &tmp);
3940 /* Not a valid server; may be only fsname */
3943 /* Strip -osc or -mdc suffix from svname */
3944 if (server_make_name(rc, mti->mti_stripe_index, mti->mti_fsname,
3946 GOTO(out, rc = -EINVAL);
3948 * Revoke lock so everyone updates. Should be alright if
3949 * someone was already reading while we were updating the logs,
3950 * so we don't really need to hold the lock while we're
3953 if (lcfg->lcfg_command == LCFG_SET_PARAM) {
3954 mti->mti_flags = rc | LDD_F_PARAM2;
3955 mutex_lock(&fsdb->fsdb_mutex);
3956 rc = mgs_write_log_param2(env, mgs, fsdb, mti, mti->mti_params);
3957 mutex_unlock(&fsdb->fsdb_mutex);
3958 mgs_revoke_lock(mgs, fsdb, CONFIG_T_PARAMS);
3960 mti->mti_flags = rc | LDD_F_PARAM;
3961 mutex_lock(&fsdb->fsdb_mutex);
3962 rc = mgs_write_log_param(env, mgs, fsdb, mti, mti->mti_params);
3963 mutex_unlock(&fsdb->fsdb_mutex);
3964 mgs_revoke_lock(mgs, fsdb, CONFIG_T_CONFIG);
3972 static int mgs_write_log_pool(const struct lu_env *env,
3973 struct mgs_device *mgs, char *logname,
3974 struct fs_db *fsdb, char *tgtname,
3975 enum lcfg_command_type cmd,
3976 char *fsname, char *poolname,
3977 char *ostname, char *comment)
3979 struct llog_handle *llh = NULL;
3982 rc = record_start_log(env, mgs, &llh, logname);
3985 rc = record_marker(env, llh, fsdb, CM_START, tgtname, comment);
3988 rc = record_base(env, llh, tgtname, 0, cmd,
3989 fsname, poolname, ostname, NULL);
3992 rc = record_marker(env, llh, fsdb, CM_END, tgtname, comment);
3994 record_end_log(env, &llh);
3998 int mgs_nodemap_cmd(const struct lu_env *env, struct mgs_device *mgs,
3999 enum lcfg_command_type cmd, const char *nodemap_name,
4010 case LCFG_NODEMAP_ADD:
4011 rc = nodemap_add(nodemap_name);
4013 case LCFG_NODEMAP_DEL:
4014 rc = nodemap_del(nodemap_name);
4016 case LCFG_NODEMAP_ADD_RANGE:
4017 rc = nodemap_parse_range(param, nid);
4020 rc = nodemap_add_range(nodemap_name, nid);
4022 case LCFG_NODEMAP_DEL_RANGE:
4023 rc = nodemap_parse_range(param, nid);
4026 rc = nodemap_del_range(nodemap_name, nid);
4028 case LCFG_NODEMAP_ADMIN:
4029 bool_switch = simple_strtoul(param, NULL, 10);
4030 rc = nodemap_set_allow_root(nodemap_name, bool_switch);
4032 case LCFG_NODEMAP_TRUSTED:
4033 bool_switch = simple_strtoul(param, NULL, 10);
4034 rc = nodemap_set_trust_client_ids(nodemap_name, bool_switch);
4036 case LCFG_NODEMAP_SQUASH_UID:
4037 int_id = simple_strtoul(param, NULL, 10);
4038 rc = nodemap_set_squash_uid(nodemap_name, int_id);
4040 case LCFG_NODEMAP_SQUASH_GID:
4041 int_id = simple_strtoul(param, NULL, 10);
4042 rc = nodemap_set_squash_gid(nodemap_name, int_id);
4044 case LCFG_NODEMAP_ADD_UIDMAP:
4045 case LCFG_NODEMAP_ADD_GIDMAP:
4046 rc = nodemap_parse_idmap(param, idmap);
4049 if (cmd == LCFG_NODEMAP_ADD_UIDMAP)
4050 rc = nodemap_add_idmap(nodemap_name, NODEMAP_UID,
4053 rc = nodemap_add_idmap(nodemap_name, NODEMAP_GID,
4056 case LCFG_NODEMAP_DEL_UIDMAP:
4057 case LCFG_NODEMAP_DEL_GIDMAP:
4058 rc = nodemap_parse_idmap(param, idmap);
4061 if (cmd == LCFG_NODEMAP_DEL_UIDMAP)
4062 rc = nodemap_del_idmap(nodemap_name, NODEMAP_UID,
4065 rc = nodemap_del_idmap(nodemap_name, NODEMAP_GID,
4075 int mgs_pool_cmd(const struct lu_env *env, struct mgs_device *mgs,
4076 enum lcfg_command_type cmd, char *fsname,
4077 char *poolname, char *ostname)
4082 char *label = NULL, *canceled_label = NULL;
4084 struct mgs_target_info *mti = NULL;
4088 rc = mgs_find_or_make_fsdb(env, mgs, fsname, &fsdb);
4090 CERROR("Can't get db for %s\n", fsname);
4093 if (test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
4094 CERROR("%s is not defined\n", fsname);
4095 mgs_free_fsdb(mgs, fsdb);
4099 label_sz = 10 + strlen(fsname) + strlen(poolname);
4101 /* check if ostname match fsname */
4102 if (ostname != NULL) {
4105 ptr = strrchr(ostname, '-');
4106 if ((ptr == NULL) ||
4107 (strncmp(fsname, ostname, ptr-ostname) != 0))
4109 label_sz += strlen(ostname);
4112 OBD_ALLOC(label, label_sz);
4119 "new %s.%s", fsname, poolname);
4123 "add %s.%s.%s", fsname, poolname, ostname);
4126 OBD_ALLOC(canceled_label, label_sz);
4127 if (canceled_label == NULL)
4128 GOTO(out_label, rc = -ENOMEM);
4130 "rem %s.%s.%s", fsname, poolname, ostname);
4131 sprintf(canceled_label,
4132 "add %s.%s.%s", fsname, poolname, ostname);
4135 OBD_ALLOC(canceled_label, label_sz);
4136 if (canceled_label == NULL)
4137 GOTO(out_label, rc = -ENOMEM);
4139 "del %s.%s", fsname, poolname);
4140 sprintf(canceled_label,
4141 "new %s.%s", fsname, poolname);
4147 if (canceled_label != NULL) {
4150 GOTO(out_cancel, rc = -ENOMEM);
4153 mutex_lock(&fsdb->fsdb_mutex);
4154 /* write pool def to all MDT logs */
4155 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
4156 if (test_bit(i, fsdb->fsdb_mdt_index_map)) {
4157 rc = name_create_mdt_and_lov(&logname, &lovname,
4160 mutex_unlock(&fsdb->fsdb_mutex);
4163 if (canceled_label != NULL) {
4164 strcpy(mti->mti_svname, "lov pool");
4165 rc = mgs_modify(env, mgs, fsdb, mti, logname,
4166 lovname, canceled_label,
4171 rc = mgs_write_log_pool(env, mgs, logname,
4175 name_destroy(&logname);
4176 name_destroy(&lovname);
4178 mutex_unlock(&fsdb->fsdb_mutex);
4184 rc = name_create(&logname, fsname, "-client");
4186 mutex_unlock(&fsdb->fsdb_mutex);
4189 if (canceled_label != NULL) {
4190 rc = mgs_modify(env, mgs, fsdb, mti, logname,
4191 fsdb->fsdb_clilov, canceled_label, CM_SKIP);
4193 mutex_unlock(&fsdb->fsdb_mutex);
4194 name_destroy(&logname);
4199 rc = mgs_write_log_pool(env, mgs, logname, fsdb, fsdb->fsdb_clilov,
4200 cmd, fsname, poolname, ostname, label);
4201 mutex_unlock(&fsdb->fsdb_mutex);
4202 name_destroy(&logname);
4203 /* request for update */
4204 mgs_revoke_lock(mgs, fsdb, CONFIG_T_CONFIG);
4211 if (canceled_label != NULL)
4212 OBD_FREE(canceled_label, label_sz);
4214 OBD_FREE(label, label_sz);