4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 only,
8 * as published by the Free Software Foundation.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License version 2 for more details (a copy is included
14 * in the LICENSE file that accompanied this code).
16 * You should have received a copy of the GNU General Public License
17 * version 2 along with this program; If not, see
18 * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
20 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
21 * CA 95054 USA or visit www.sun.com if you need additional information or
27 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
28 * Use is subject to license terms.
30 * Copyright (c) 2011, 2013, Intel Corporation.
33 * This file is part of Lustre, http://www.lustre.org/
34 * Lustre is a trademark of Sun Microsystems, Inc.
36 * lustre/mgs/mgs_llog.c
38 * Lustre Management Server (mgs) config llog creation
40 * Author: Nathan Rutman <nathan@clusterfs.com>
41 * Author: Alex Zhuravlev <bzzz@whamcloud.com>
42 * Author: Mikhail Pershin <tappro@whamcloud.com>
45 #define DEBUG_SUBSYSTEM S_MGS
46 #define D_MGS D_CONFIG
49 #include <lustre_ioctl.h>
50 #include <lustre_param.h>
51 #include <lustre_sec.h>
52 #include <lustre_quota.h>
54 #include "mgs_internal.h"
56 /********************** Class functions ********************/
58 /* Find all logs in CONFIG directory and link then into list */
59 int class_dentry_readdir(const struct lu_env *env,
60 struct mgs_device *mgs, struct list_head *log_list)
62 struct dt_object *dir = mgs->mgs_configs_dir;
63 const struct dt_it_ops *iops;
65 struct mgs_direntry *de;
69 INIT_LIST_HEAD(log_list);
72 LASSERT(dir->do_index_ops);
74 iops = &dir->do_index_ops->dio_it;
75 it = iops->init(env, dir, LUDA_64BITHASH, BYPASS_CAPA);
79 rc = iops->load(env, it, 0);
85 key = (void *)iops->key(env, it);
87 CERROR("%s: key failed when listing %s: rc = %d\n",
88 mgs->mgs_obd->obd_name, MOUNT_CONFIGS_DIR,
92 key_sz = iops->key_size(env, it);
95 /* filter out "." and ".." entries */
99 if (key_sz == 2 && key[1] == '.')
103 de = mgs_direntry_alloc(key_sz + 1);
109 memcpy(de->mde_name, key, key_sz);
110 de->mde_name[key_sz] = 0;
112 list_add(&de->mde_list, log_list);
115 rc = iops->next(env, it);
124 CERROR("%s: key failed when listing %s: rc = %d\n",
125 mgs->mgs_obd->obd_name, MOUNT_CONFIGS_DIR, rc);
129 /******************** DB functions *********************/
131 static inline int name_create(char **newname, char *prefix, char *suffix)
134 OBD_ALLOC(*newname, strlen(prefix) + strlen(suffix) + 1);
137 sprintf(*newname, "%s%s", prefix, suffix);
141 static inline void name_destroy(char **name)
144 OBD_FREE(*name, strlen(*name) + 1);
148 struct mgs_fsdb_handler_data
154 /* from the (client) config log, figure out:
155 1. which ost's/mdt's are configured (by index)
156 2. what the last config step is
157 3. COMPAT_18 osc name
159 /* It might be better to have a separate db file, instead of parsing the info
160 out of the client log. This is slow and potentially error-prone. */
161 static int mgs_fsdb_handler(const struct lu_env *env, struct llog_handle *llh,
162 struct llog_rec_hdr *rec, void *data)
164 struct mgs_fsdb_handler_data *d = data;
165 struct fs_db *fsdb = d->fsdb;
166 int cfg_len = rec->lrh_len;
167 char *cfg_buf = (char*) (rec + 1);
168 struct lustre_cfg *lcfg;
173 if (rec->lrh_type != OBD_CFG_REC) {
174 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
178 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
180 CERROR("Insane cfg\n");
184 lcfg = (struct lustre_cfg *)cfg_buf;
186 CDEBUG(D_INFO, "cmd %x %s %s\n", lcfg->lcfg_command,
187 lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));
189 /* Figure out ost indicies */
190 /* lov_modify_tgts add 0:lov1 1:ost1_UUID 2(index):0 3(gen):1 */
191 if (lcfg->lcfg_command == LCFG_LOV_ADD_OBD ||
192 lcfg->lcfg_command == LCFG_LOV_DEL_OBD) {
193 index = simple_strtoul(lustre_cfg_string(lcfg, 2),
195 CDEBUG(D_MGS, "OST index for %s is %u (%s)\n",
196 lustre_cfg_string(lcfg, 1), index,
197 lustre_cfg_string(lcfg, 2));
198 set_bit(index, fsdb->fsdb_ost_index_map);
201 /* Figure out mdt indicies */
202 /* attach 0:MDC_uml1_mdsA_MNT_client 1:mdc 2:1d834_MNT_client_03f */
203 if ((lcfg->lcfg_command == LCFG_ATTACH) &&
204 (strcmp(lustre_cfg_string(lcfg, 1), LUSTRE_MDC_NAME) == 0)) {
205 rc = server_name2index(lustre_cfg_string(lcfg, 0),
207 if (rc != LDD_F_SV_TYPE_MDT) {
208 CWARN("Unparsable MDC name %s, assuming index 0\n",
209 lustre_cfg_string(lcfg, 0));
213 CDEBUG(D_MGS, "MDT index is %u\n", index);
214 set_bit(index, fsdb->fsdb_mdt_index_map);
215 fsdb->fsdb_mdt_count ++;
219 * figure out the old config. fsdb_gen = 0 means old log
220 * It is obsoleted and not supported anymore
222 if (fsdb->fsdb_gen == 0) {
223 CERROR("Old config format is not supported\n");
228 * compat to 1.8, check osc name used by MDT0 to OSTs, bz18548.
230 if (!test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags) &&
231 lcfg->lcfg_command == LCFG_ATTACH &&
232 strcmp(lustre_cfg_string(lcfg, 1), LUSTRE_OSC_NAME) == 0) {
233 if (OBD_OCD_VERSION_MAJOR(d->ver) == 1 &&
234 OBD_OCD_VERSION_MINOR(d->ver) <= 8) {
235 CWARN("MDT using 1.8 OSC name scheme\n");
236 set_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags);
240 if (lcfg->lcfg_command == LCFG_MARKER) {
241 struct cfg_marker *marker;
242 marker = lustre_cfg_buf(lcfg, 1);
244 d->ver = marker->cm_vers;
246 /* Keep track of the latest marker step */
247 fsdb->fsdb_gen = max(fsdb->fsdb_gen, marker->cm_step);
253 /* fsdb->fsdb_mutex is already held in mgs_find_or_make_fsdb*/
254 static int mgs_get_fsdb_from_llog(const struct lu_env *env,
255 struct mgs_device *mgs,
259 struct llog_handle *loghandle;
260 struct llog_ctxt *ctxt;
261 struct mgs_fsdb_handler_data d = { fsdb, 0 };
266 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
267 LASSERT(ctxt != NULL);
268 rc = name_create(&logname, fsdb->fsdb_name, "-client");
271 rc = llog_open_create(env, ctxt, &loghandle, NULL, logname);
275 rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL);
279 if (llog_get_size(loghandle) <= 1)
280 set_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags);
282 rc = llog_process(env, loghandle, mgs_fsdb_handler, (void *)&d, NULL);
283 CDEBUG(D_INFO, "get_db = %d\n", rc);
285 llog_close(env, loghandle);
287 name_destroy(&logname);
294 static void mgs_free_fsdb_srpc(struct fs_db *fsdb)
296 struct mgs_tgt_srpc_conf *tgtconf;
298 /* free target-specific rules */
299 while (fsdb->fsdb_srpc_tgt) {
300 tgtconf = fsdb->fsdb_srpc_tgt;
301 fsdb->fsdb_srpc_tgt = tgtconf->mtsc_next;
303 LASSERT(tgtconf->mtsc_tgt);
305 sptlrpc_rule_set_free(&tgtconf->mtsc_rset);
306 OBD_FREE(tgtconf->mtsc_tgt, strlen(tgtconf->mtsc_tgt) + 1);
307 OBD_FREE_PTR(tgtconf);
310 /* free general rules */
311 sptlrpc_rule_set_free(&fsdb->fsdb_srpc_gen);
314 struct fs_db *mgs_find_fsdb(struct mgs_device *mgs, char *fsname)
319 cfs_list_for_each(tmp, &mgs->mgs_fs_db_list) {
320 fsdb = cfs_list_entry(tmp, struct fs_db, fsdb_list);
321 if (strcmp(fsdb->fsdb_name, fsname) == 0)
327 /* caller must hold the mgs->mgs_fs_db_lock */
328 static struct fs_db *mgs_new_fsdb(const struct lu_env *env,
329 struct mgs_device *mgs, char *fsname)
335 if (strlen(fsname) >= sizeof(fsdb->fsdb_name)) {
336 CERROR("fsname %s is too long\n", fsname);
344 strcpy(fsdb->fsdb_name, fsname);
345 mutex_init(&fsdb->fsdb_mutex);
346 set_bit(FSDB_UDESC, &fsdb->fsdb_flags);
349 if (strcmp(fsname, MGSSELF_NAME) == 0) {
350 set_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags);
352 OBD_ALLOC(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
353 OBD_ALLOC(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
354 if (!fsdb->fsdb_ost_index_map || !fsdb->fsdb_mdt_index_map) {
355 CERROR("No memory for index maps\n");
356 GOTO(err, rc = -ENOMEM);
359 rc = name_create(&fsdb->fsdb_clilov, fsname, "-clilov");
362 rc = name_create(&fsdb->fsdb_clilmv, fsname, "-clilmv");
366 /* initialise data for NID table */
367 mgs_ir_init_fs(env, mgs, fsdb);
369 lproc_mgs_add_live(mgs, fsdb);
372 cfs_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 cfs_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 CFS_INIT_LIST_HEAD(&mgs->mgs_fs_db_list);
413 int mgs_cleanup_fsdb_list(struct mgs_device *mgs)
416 cfs_list_t *tmp, *tmp2;
417 mutex_lock(&mgs->mgs_mutex);
418 cfs_list_for_each_safe(tmp, tmp2, &mgs->mgs_fs_db_list) {
419 fsdb = cfs_list_entry(tmp, struct fs_db, fsdb_list);
420 mgs_free_fsdb(mgs, fsdb);
422 mutex_unlock(&mgs->mgs_mutex);
426 int mgs_find_or_make_fsdb(const struct lu_env *env,
427 struct mgs_device *mgs, char *name,
434 mutex_lock(&mgs->mgs_mutex);
435 fsdb = mgs_find_fsdb(mgs, name);
437 mutex_unlock(&mgs->mgs_mutex);
442 CDEBUG(D_MGS, "Creating new db\n");
443 fsdb = mgs_new_fsdb(env, mgs, name);
444 /* lock fsdb_mutex until the db is loaded from llogs */
446 mutex_lock(&fsdb->fsdb_mutex);
447 mutex_unlock(&mgs->mgs_mutex);
451 if (!test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
452 /* populate the db from the client llog */
453 rc = mgs_get_fsdb_from_llog(env, mgs, fsdb);
455 CERROR("Can't get db from client log %d\n", rc);
460 /* populate srpc rules from params llog */
461 rc = mgs_get_fsdb_srpc_from_llog(env, mgs, fsdb);
463 CERROR("Can't get db from params log %d\n", rc);
467 mutex_unlock(&fsdb->fsdb_mutex);
473 mutex_unlock(&fsdb->fsdb_mutex);
474 mgs_free_fsdb(mgs, fsdb);
480 -1= empty client log */
481 int mgs_check_index(const struct lu_env *env,
482 struct mgs_device *mgs,
483 struct mgs_target_info *mti)
490 LASSERT(!(mti->mti_flags & LDD_F_NEED_INDEX));
492 rc = mgs_find_or_make_fsdb(env, mgs, mti->mti_fsname, &fsdb);
494 CERROR("Can't get db for %s\n", mti->mti_fsname);
498 if (test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags))
501 if (mti->mti_flags & LDD_F_SV_TYPE_OST)
502 imap = fsdb->fsdb_ost_index_map;
503 else if (mti->mti_flags & LDD_F_SV_TYPE_MDT)
504 imap = fsdb->fsdb_mdt_index_map;
508 if (test_bit(mti->mti_stripe_index, imap))
513 static __inline__ int next_index(void *index_map, int map_len)
516 for (i = 0; i < map_len * 8; i++)
517 if (!test_bit(i, index_map)) {
520 CERROR("max index %d exceeded.\n", i);
525 0 newly marked as in use
527 +EALREADY for update of an old index */
528 static int mgs_set_index(const struct lu_env *env,
529 struct mgs_device *mgs,
530 struct mgs_target_info *mti)
537 rc = mgs_find_or_make_fsdb(env, mgs, mti->mti_fsname, &fsdb);
539 CERROR("Can't get db for %s\n", mti->mti_fsname);
543 mutex_lock(&fsdb->fsdb_mutex);
544 if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
545 imap = fsdb->fsdb_ost_index_map;
546 } else if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
547 imap = fsdb->fsdb_mdt_index_map;
549 GOTO(out_up, rc = -EINVAL);
552 if (mti->mti_flags & LDD_F_NEED_INDEX) {
553 rc = next_index(imap, INDEX_MAP_SIZE);
555 GOTO(out_up, rc = -ERANGE);
556 mti->mti_stripe_index = rc;
557 if (mti->mti_flags & LDD_F_SV_TYPE_MDT)
558 fsdb->fsdb_mdt_count ++;
561 if (mti->mti_stripe_index >= INDEX_MAP_SIZE * 8) {
562 LCONSOLE_ERROR_MSG(0x13f, "Server %s requested index %d, "
563 "but the max index is %d.\n",
564 mti->mti_svname, mti->mti_stripe_index,
566 GOTO(out_up, rc = -ERANGE);
569 if (test_bit(mti->mti_stripe_index, imap)) {
570 if ((mti->mti_flags & LDD_F_VIRGIN) &&
571 !(mti->mti_flags & LDD_F_WRITECONF)) {
572 LCONSOLE_ERROR_MSG(0x140, "Server %s requested index "
573 "%d, but that index is already in "
574 "use. Use --writeconf to force\n",
576 mti->mti_stripe_index);
577 GOTO(out_up, rc = -EADDRINUSE);
579 CDEBUG(D_MGS, "Server %s updating index %d\n",
580 mti->mti_svname, mti->mti_stripe_index);
581 GOTO(out_up, rc = EALREADY);
585 set_bit(mti->mti_stripe_index, imap);
586 clear_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags);
587 mutex_unlock(&fsdb->fsdb_mutex);
588 server_make_name(mti->mti_flags & ~(LDD_F_VIRGIN | LDD_F_WRITECONF),
589 mti->mti_stripe_index, mti->mti_fsname, mti->mti_svname);
591 CDEBUG(D_MGS, "Set index for %s to %d\n", mti->mti_svname,
592 mti->mti_stripe_index);
596 mutex_unlock(&fsdb->fsdb_mutex);
600 struct mgs_modify_lookup {
601 struct cfg_marker mml_marker;
605 static int mgs_modify_handler(const struct lu_env *env,
606 struct llog_handle *llh,
607 struct llog_rec_hdr *rec, void *data)
609 struct mgs_modify_lookup *mml = data;
610 struct cfg_marker *marker;
611 struct lustre_cfg *lcfg = REC_DATA(rec);
612 int cfg_len = REC_DATA_LEN(rec);
616 if (rec->lrh_type != OBD_CFG_REC) {
617 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
621 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
623 CERROR("Insane cfg\n");
627 /* We only care about markers */
628 if (lcfg->lcfg_command != LCFG_MARKER)
631 marker = lustre_cfg_buf(lcfg, 1);
632 if ((strcmp(mml->mml_marker.cm_comment, marker->cm_comment) == 0) &&
633 (strcmp(mml->mml_marker.cm_tgtname, marker->cm_tgtname) == 0) &&
634 !(marker->cm_flags & CM_SKIP)) {
635 /* Found a non-skipped marker match */
636 CDEBUG(D_MGS, "Changing rec %u marker %d %x->%x: %s %s\n",
637 rec->lrh_index, marker->cm_step,
638 marker->cm_flags, mml->mml_marker.cm_flags,
639 marker->cm_tgtname, marker->cm_comment);
640 /* Overwrite the old marker llog entry */
641 marker->cm_flags &= ~CM_EXCLUDE; /* in case we're unexcluding */
642 marker->cm_flags |= mml->mml_marker.cm_flags;
643 marker->cm_canceltime = mml->mml_marker.cm_canceltime;
644 rc = llog_write(env, llh, rec, rec->lrh_index);
653 * Modify an existing config log record (for CM_SKIP or CM_EXCLUDE)
655 * 0 - modified successfully,
656 * 1 - no modification was done
659 static int mgs_modify(const struct lu_env *env, struct mgs_device *mgs,
660 struct fs_db *fsdb, struct mgs_target_info *mti,
661 char *logname, char *devname, char *comment, int flags)
663 struct llog_handle *loghandle;
664 struct llog_ctxt *ctxt;
665 struct mgs_modify_lookup *mml;
670 LASSERT(mutex_is_locked(&fsdb->fsdb_mutex));
671 CDEBUG(D_MGS, "modify %s/%s/%s fl=%x\n", logname, devname, comment,
674 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
675 LASSERT(ctxt != NULL);
676 rc = llog_open(env, ctxt, &loghandle, NULL, logname, LLOG_OPEN_EXISTS);
683 rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL);
687 if (llog_get_size(loghandle) <= 1)
688 GOTO(out_close, rc = 0);
692 GOTO(out_close, rc = -ENOMEM);
693 if (strlcpy(mml->mml_marker.cm_comment, comment,
694 sizeof(mml->mml_marker.cm_comment)) >=
695 sizeof(mml->mml_marker.cm_comment))
696 GOTO(out_free, rc = -E2BIG);
697 if (strlcpy(mml->mml_marker.cm_tgtname, devname,
698 sizeof(mml->mml_marker.cm_tgtname)) >=
699 sizeof(mml->mml_marker.cm_tgtname))
700 GOTO(out_free, rc = -E2BIG);
701 /* Modify mostly means cancel */
702 mml->mml_marker.cm_flags = flags;
703 mml->mml_marker.cm_canceltime = flags ? cfs_time_current_sec() : 0;
704 mml->mml_modified = 0;
705 rc = llog_process(env, loghandle, mgs_modify_handler, (void *)mml,
707 if (!rc && !mml->mml_modified)
714 llog_close(env, loghandle);
717 CERROR("%s: modify %s/%s failed: rc = %d\n",
718 mgs->mgs_obd->obd_name, mti->mti_svname, comment, rc);
723 /** This structure is passed to mgs_replace_handler */
724 struct mgs_replace_uuid_lookup {
725 /* Nids are replaced for this target device */
726 struct mgs_target_info target;
727 /* Temporary modified llog */
728 struct llog_handle *temp_llh;
729 /* Flag is set if in target block*/
730 int in_target_device;
731 /* Nids already added. Just skip (multiple nids) */
732 int device_nids_added;
733 /* Flag is set if this block should not be copied */
738 * Check: a) if block should be skipped
739 * b) is it target block
744 * \retval 0 should not to be skipped
745 * \retval 1 should to be skipped
747 static int check_markers(struct lustre_cfg *lcfg,
748 struct mgs_replace_uuid_lookup *mrul)
750 struct cfg_marker *marker;
752 /* Track markers. Find given device */
753 if (lcfg->lcfg_command == LCFG_MARKER) {
754 marker = lustre_cfg_buf(lcfg, 1);
755 /* Clean llog from records marked as CM_EXCLUDE.
756 CM_SKIP records are used for "active" command
757 and can be restored if needed */
758 if ((marker->cm_flags & (CM_EXCLUDE | CM_START)) ==
759 (CM_EXCLUDE | CM_START)) {
764 if ((marker->cm_flags & (CM_EXCLUDE | CM_END)) ==
765 (CM_EXCLUDE | CM_END)) {
770 if (strcmp(mrul->target.mti_svname, marker->cm_tgtname) == 0) {
771 LASSERT(!(marker->cm_flags & CM_START) ||
772 !(marker->cm_flags & CM_END));
773 if (marker->cm_flags & CM_START) {
774 mrul->in_target_device = 1;
775 mrul->device_nids_added = 0;
776 } else if (marker->cm_flags & CM_END)
777 mrul->in_target_device = 0;
784 static int record_base(const struct lu_env *env, struct llog_handle *llh,
785 char *cfgname, lnet_nid_t nid, int cmd,
786 char *s1, char *s2, char *s3, char *s4)
788 struct mgs_thread_info *mgi = mgs_env_info(env);
789 struct llog_cfg_rec *lcr;
792 CDEBUG(D_MGS, "lcfg %s %#x %s %s %s %s\n", cfgname,
793 cmd, s1, s2, s3, s4);
795 lustre_cfg_bufs_reset(&mgi->mgi_bufs, cfgname);
797 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, s1);
799 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 2, s2);
801 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 3, s3);
803 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 4, s4);
805 lcr = lustre_cfg_rec_new(cmd, &mgi->mgi_bufs);
809 lcr->lcr_cfg.lcfg_nid = nid;
810 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
812 lustre_cfg_rec_free(lcr);
816 "failed to write lcfg %s %#x %s %s %s %s: rc = %d\n",
817 cfgname, cmd, s1, s2, s3, s4, rc);
821 static inline int record_add_uuid(const struct lu_env *env,
822 struct llog_handle *llh,
823 uint64_t nid, char *uuid)
825 return record_base(env, llh, NULL, nid, LCFG_ADD_UUID, uuid, 0, 0, 0);
828 static inline int record_add_conn(const struct lu_env *env,
829 struct llog_handle *llh,
830 char *devname, char *uuid)
832 return record_base(env, llh, devname, 0, LCFG_ADD_CONN, uuid, 0, 0, 0);
835 static inline int record_attach(const struct lu_env *env,
836 struct llog_handle *llh, char *devname,
837 char *type, char *uuid)
839 return record_base(env, llh,devname, 0, LCFG_ATTACH, type, uuid, 0, 0);
842 static inline int record_setup(const struct lu_env *env,
843 struct llog_handle *llh, char *devname,
844 char *s1, char *s2, char *s3, char *s4)
846 return record_base(env, llh, devname, 0, LCFG_SETUP, s1, s2, s3, s4);
850 * \retval <0 record processing error
851 * \retval n record is processed. No need copy original one.
852 * \retval 0 record is not processed.
854 static int process_command(const struct lu_env *env, struct lustre_cfg *lcfg,
855 struct mgs_replace_uuid_lookup *mrul)
862 if (lcfg->lcfg_command == LCFG_ADD_UUID) {
863 /* LCFG_ADD_UUID command found. Let's skip original command
864 and add passed nids */
865 ptr = mrul->target.mti_params;
866 while (class_parse_nid(ptr, &nid, &ptr) == 0) {
867 CDEBUG(D_MGS, "add nid %s with uuid %s, "
868 "device %s\n", libcfs_nid2str(nid),
869 mrul->target.mti_params,
870 mrul->target.mti_svname);
871 rc = record_add_uuid(env,
873 mrul->target.mti_params);
878 if (nids_added == 0) {
879 CERROR("No new nids were added, nid %s with uuid %s, "
880 "device %s\n", libcfs_nid2str(nid),
881 mrul->target.mti_params,
882 mrul->target.mti_svname);
885 mrul->device_nids_added = 1;
891 if (mrul->device_nids_added && lcfg->lcfg_command == LCFG_SETUP) {
892 /* LCFG_SETUP command found. UUID should be changed */
893 rc = record_setup(env,
895 /* devname the same */
896 lustre_cfg_string(lcfg, 0),
897 /* s1 is not changed */
898 lustre_cfg_string(lcfg, 1),
899 /* new uuid should be
901 mrul->target.mti_params,
902 /* s3 is not changed */
903 lustre_cfg_string(lcfg, 3),
904 /* s4 is not changed */
905 lustre_cfg_string(lcfg, 4));
909 /* Another commands in target device block */
914 * Handler that called for every record in llog.
915 * Records are processed in order they placed in llog.
917 * \param[in] llh log to be processed
918 * \param[in] rec current record
919 * \param[in] data mgs_replace_uuid_lookup structure
923 static int mgs_replace_handler(const struct lu_env *env,
924 struct llog_handle *llh,
925 struct llog_rec_hdr *rec,
928 struct mgs_replace_uuid_lookup *mrul;
929 struct lustre_cfg *lcfg = REC_DATA(rec);
930 int cfg_len = REC_DATA_LEN(rec);
934 mrul = (struct mgs_replace_uuid_lookup *)data;
936 if (rec->lrh_type != OBD_CFG_REC) {
937 CERROR("unhandled lrh_type: %#x, cmd %x %s %s\n",
938 rec->lrh_type, lcfg->lcfg_command,
939 lustre_cfg_string(lcfg, 0),
940 lustre_cfg_string(lcfg, 1));
944 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
946 /* Do not copy any invalidated records */
947 GOTO(skip_out, rc = 0);
950 rc = check_markers(lcfg, mrul);
951 if (rc || mrul->skip_it)
952 GOTO(skip_out, rc = 0);
954 /* Write to new log all commands outside target device block */
955 if (!mrul->in_target_device)
956 GOTO(copy_out, rc = 0);
958 /* Skip all other LCFG_ADD_UUID and LCFG_ADD_CONN records
959 (failover nids) for this target, assuming that if then
960 primary is changing then so is the failover */
961 if (mrul->device_nids_added &&
962 (lcfg->lcfg_command == LCFG_ADD_UUID ||
963 lcfg->lcfg_command == LCFG_ADD_CONN))
964 GOTO(skip_out, rc = 0);
966 rc = process_command(env, lcfg, mrul);
973 /* Record is placed in temporary llog as is */
974 rc = llog_write(env, mrul->temp_llh, rec, LLOG_NEXT_IDX);
976 CDEBUG(D_MGS, "Copied idx=%d, rc=%d, len=%d, cmd %x %s %s\n",
977 rec->lrh_index, rc, rec->lrh_len, lcfg->lcfg_command,
978 lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));
982 CDEBUG(D_MGS, "Skipped idx=%d, rc=%d, len=%d, cmd %x %s %s\n",
983 rec->lrh_index, rc, rec->lrh_len, lcfg->lcfg_command,
984 lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));
988 static int mgs_log_is_empty(const struct lu_env *env,
989 struct mgs_device *mgs, char *name)
991 struct llog_ctxt *ctxt;
994 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
995 LASSERT(ctxt != NULL);
997 rc = llog_is_empty(env, ctxt, name);
1002 static int mgs_replace_nids_log(const struct lu_env *env,
1003 struct obd_device *mgs, struct fs_db *fsdb,
1004 char *logname, char *devname, char *nids)
1006 struct llog_handle *orig_llh, *backup_llh;
1007 struct llog_ctxt *ctxt;
1008 struct mgs_replace_uuid_lookup *mrul;
1009 struct mgs_device *mgs_dev = lu2mgs_dev(mgs->obd_lu_dev);
1010 static struct obd_uuid cfg_uuid = { .uuid = "config_uuid" };
1015 CDEBUG(D_MGS, "Replace nids for %s in %s\n", devname, logname);
1017 ctxt = llog_get_context(mgs, LLOG_CONFIG_ORIG_CTXT);
1018 LASSERT(ctxt != NULL);
1020 if (mgs_log_is_empty(env, mgs_dev, logname)) {
1021 /* Log is empty. Nothing to replace */
1022 GOTO(out_put, rc = 0);
1025 OBD_ALLOC(backup, strlen(logname) + strlen(".bak") + 1);
1027 GOTO(out_put, rc = -ENOMEM);
1029 sprintf(backup, "%s.bak", logname);
1031 rc = llog_backup(env, mgs, ctxt, ctxt, logname, backup);
1033 /* Now erase original log file. Connections are not allowed.
1034 Backup is already saved */
1035 rc = llog_erase(env, ctxt, NULL, logname);
1038 } else if (rc != -ENOENT) {
1039 CERROR("%s: can't make backup for %s: rc = %d\n",
1040 mgs->obd_name, logname, rc);
1044 /* open local log */
1045 rc = llog_open_create(env, ctxt, &orig_llh, NULL, logname);
1047 GOTO(out_restore, rc);
1049 rc = llog_init_handle(env, orig_llh, LLOG_F_IS_PLAIN, &cfg_uuid);
1051 GOTO(out_closel, rc);
1053 /* open backup llog */
1054 rc = llog_open(env, ctxt, &backup_llh, NULL, backup,
1057 GOTO(out_closel, rc);
1059 rc = llog_init_handle(env, backup_llh, LLOG_F_IS_PLAIN, NULL);
1061 GOTO(out_close, rc);
1063 if (llog_get_size(backup_llh) <= 1)
1064 GOTO(out_close, rc = 0);
1066 OBD_ALLOC_PTR(mrul);
1068 GOTO(out_close, rc = -ENOMEM);
1069 /* devname is only needed information to replace UUID records */
1070 strncpy(mrul->target.mti_svname, devname, MTI_NAME_MAXLEN);
1071 /* parse nids later */
1072 strncpy(mrul->target.mti_params, nids, MTI_PARAM_MAXLEN);
1073 /* Copy records to this temporary llog */
1074 mrul->temp_llh = orig_llh;
1076 rc = llog_process(env, backup_llh, mgs_replace_handler,
1077 (void *)mrul, NULL);
1080 rc2 = llog_close(NULL, backup_llh);
1084 rc2 = llog_close(NULL, orig_llh);
1090 CERROR("%s: llog should be restored: rc = %d\n",
1092 rc2 = llog_backup(env, mgs, ctxt, ctxt, backup,
1095 CERROR("%s: can't restore backup %s: rc = %d\n",
1096 mgs->obd_name, logname, rc2);
1100 OBD_FREE(backup, strlen(backup) + 1);
1103 llog_ctxt_put(ctxt);
1106 CERROR("%s: failed to replace nids in log %s: rc = %d\n",
1107 mgs->obd_name, logname, rc);
1113 * Parse device name and get file system name and/or device index
1115 * \param[in] devname device name (ex. lustre-MDT0000)
1116 * \param[out] fsname file system name(optional)
1117 * \param[out] index device index(optional)
1121 static int mgs_parse_devname(char *devname, char *fsname, __u32 *index)
1126 /* Extract fsname */
1128 rc = server_name2fsname(devname, fsname, NULL);
1130 CDEBUG(D_MGS, "Device name %s without fsname\n",
1137 rc = server_name2index(devname, index, NULL);
1139 CDEBUG(D_MGS, "Device name %s with wrong index\n",
1148 /* This is only called during replace_nids */
1149 static int only_mgs_is_running(struct obd_device *mgs_obd)
1151 /* TDB: Is global variable with devices count exists? */
1152 int num_devices = get_devices_count();
1153 int num_exports = 0;
1154 struct obd_export *exp;
1156 spin_lock(&mgs_obd->obd_dev_lock);
1157 list_for_each_entry(exp, &mgs_obd->obd_exports, exp_obd_chain) {
1158 /* skip self export */
1159 if (exp == mgs_obd->obd_self_export)
1161 if (exp_connect_flags(exp) & OBD_CONNECT_MDS_MDS)
1166 CERROR("%s: node %s still connected during replace_nids "
1167 "connect_flags:%llx\n",
1169 libcfs_nid2str(exp->exp_nid_stats->nid),
1170 exp_connect_flags(exp));
1173 spin_unlock(&mgs_obd->obd_dev_lock);
1175 /* osd, MGS and MGC + self_export
1176 (wc -l /proc/fs/lustre/devices <= 2) && (non self exports == 0) */
1177 return (num_devices <= 3) && (num_exports == 0);
1180 static int name_create_mdt(char **logname, char *fsname, int i)
1184 sprintf(mdt_index, "-MDT%04x", i);
1185 return name_create(logname, fsname, mdt_index);
1189 * Replace nids for \a device to \a nids values
1191 * \param obd MGS obd device
1192 * \param devname nids need to be replaced for this device
1193 * (ex. lustre-OST0000)
1194 * \param nids nids list (ex. nid1,nid2,nid3)
1198 int mgs_replace_nids(const struct lu_env *env,
1199 struct mgs_device *mgs,
1200 char *devname, char *nids)
1202 /* Assume fsname is part of device name */
1203 char fsname[MTI_NAME_MAXLEN];
1210 struct obd_device *mgs_obd = mgs->mgs_obd;
1213 /* We can only change NIDs if no other nodes are connected */
1214 spin_lock(&mgs_obd->obd_dev_lock);
1215 conn_state = mgs_obd->obd_no_conn;
1216 mgs_obd->obd_no_conn = 1;
1217 spin_unlock(&mgs_obd->obd_dev_lock);
1219 /* We can not change nids if not only MGS is started */
1220 if (!only_mgs_is_running(mgs_obd)) {
1221 CERROR("Only MGS is allowed to be started\n");
1222 GOTO(out, rc = -EINPROGRESS);
1225 /* Get fsname and index*/
1226 rc = mgs_parse_devname(devname, fsname, &index);
1230 rc = mgs_find_or_make_fsdb(env, mgs, fsname, &fsdb);
1232 CERROR("%s: can't find fsdb: rc = %d\n", fsname, rc);
1236 /* Process client llogs */
1237 name_create(&logname, fsname, "-client");
1238 rc = mgs_replace_nids_log(env, mgs_obd, fsdb, logname, devname, nids);
1239 name_destroy(&logname);
1241 CERROR("%s: error while replacing NIDs for %s: rc = %d\n",
1242 fsname, devname, rc);
1246 /* Process MDT llogs */
1247 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
1248 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
1250 name_create_mdt(&logname, fsname, i);
1251 rc = mgs_replace_nids_log(env, mgs_obd, fsdb, logname, devname, nids);
1252 name_destroy(&logname);
1258 spin_lock(&mgs_obd->obd_dev_lock);
1259 mgs_obd->obd_no_conn = conn_state;
1260 spin_unlock(&mgs_obd->obd_dev_lock);
1265 static int record_lov_setup(const struct lu_env *env, struct llog_handle *llh,
1266 char *devname, struct lov_desc *desc)
1268 struct mgs_thread_info *mgi = mgs_env_info(env);
1269 struct llog_cfg_rec *lcr;
1272 lustre_cfg_bufs_reset(&mgi->mgi_bufs, devname);
1273 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, desc, sizeof(*desc));
1274 lcr = lustre_cfg_rec_new(LCFG_SETUP, &mgi->mgi_bufs);
1278 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1279 lustre_cfg_rec_free(lcr);
1283 static int record_lmv_setup(const struct lu_env *env, struct llog_handle *llh,
1284 char *devname, struct lmv_desc *desc)
1286 struct mgs_thread_info *mgi = mgs_env_info(env);
1287 struct llog_cfg_rec *lcr;
1290 lustre_cfg_bufs_reset(&mgi->mgi_bufs, devname);
1291 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, desc, sizeof(*desc));
1292 lcr = lustre_cfg_rec_new(LCFG_SETUP, &mgi->mgi_bufs);
1296 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1297 lustre_cfg_rec_free(lcr);
1301 static inline int record_mdc_add(const struct lu_env *env,
1302 struct llog_handle *llh,
1303 char *logname, char *mdcuuid,
1304 char *mdtuuid, char *index,
1307 return record_base(env,llh,logname,0,LCFG_ADD_MDC,
1308 mdtuuid,index,gen,mdcuuid);
1311 static inline int record_lov_add(const struct lu_env *env,
1312 struct llog_handle *llh,
1313 char *lov_name, char *ost_uuid,
1314 char *index, char *gen)
1316 return record_base(env,llh,lov_name,0,LCFG_LOV_ADD_OBD,
1317 ost_uuid, index, gen, 0);
1320 static inline int record_mount_opt(const struct lu_env *env,
1321 struct llog_handle *llh,
1322 char *profile, char *lov_name,
1325 return record_base(env,llh,NULL,0,LCFG_MOUNTOPT,
1326 profile,lov_name,mdc_name,0);
1329 static int record_marker(const struct lu_env *env,
1330 struct llog_handle *llh,
1331 struct fs_db *fsdb, __u32 flags,
1332 char *tgtname, char *comment)
1334 struct mgs_thread_info *mgi = mgs_env_info(env);
1335 struct llog_cfg_rec *lcr;
1339 if (flags & CM_START)
1341 mgi->mgi_marker.cm_step = fsdb->fsdb_gen;
1342 mgi->mgi_marker.cm_flags = flags;
1343 mgi->mgi_marker.cm_vers = LUSTRE_VERSION_CODE;
1344 cplen = strlcpy(mgi->mgi_marker.cm_tgtname, tgtname,
1345 sizeof(mgi->mgi_marker.cm_tgtname));
1346 if (cplen >= sizeof(mgi->mgi_marker.cm_tgtname))
1348 cplen = strlcpy(mgi->mgi_marker.cm_comment, comment,
1349 sizeof(mgi->mgi_marker.cm_comment));
1350 if (cplen >= sizeof(mgi->mgi_marker.cm_comment))
1352 mgi->mgi_marker.cm_createtime = cfs_time_current_sec();
1353 mgi->mgi_marker.cm_canceltime = 0;
1354 lustre_cfg_bufs_reset(&mgi->mgi_bufs, NULL);
1355 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, &mgi->mgi_marker,
1356 sizeof(mgi->mgi_marker));
1357 lcr = lustre_cfg_rec_new(LCFG_MARKER, &mgi->mgi_bufs);
1361 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1362 lustre_cfg_rec_free(lcr);
1366 static int record_start_log(const struct lu_env *env, struct mgs_device *mgs,
1367 struct llog_handle **llh, char *name)
1369 static struct obd_uuid cfg_uuid = { .uuid = "config_uuid" };
1370 struct llog_ctxt *ctxt;
1375 GOTO(out, rc = -EBUSY);
1377 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
1379 GOTO(out, rc = -ENODEV);
1380 LASSERT(ctxt->loc_obd == mgs->mgs_obd);
1382 rc = llog_open_create(env, ctxt, llh, NULL, name);
1385 rc = llog_init_handle(env, *llh, LLOG_F_IS_PLAIN, &cfg_uuid);
1387 llog_close(env, *llh);
1389 llog_ctxt_put(ctxt);
1392 CERROR("%s: can't start log %s: rc = %d\n",
1393 mgs->mgs_obd->obd_name, name, rc);
1399 static int record_end_log(const struct lu_env *env, struct llog_handle **llh)
1403 rc = llog_close(env, *llh);
1409 /******************** config "macros" *********************/
1411 /* write an lcfg directly into a log (with markers) */
1412 static int mgs_write_log_direct(const struct lu_env *env,
1413 struct mgs_device *mgs, struct fs_db *fsdb,
1414 char *logname, struct llog_cfg_rec *lcr,
1415 char *devname, char *comment)
1417 struct llog_handle *llh = NULL;
1422 rc = record_start_log(env, mgs, &llh, logname);
1426 /* FIXME These should be a single journal transaction */
1427 rc = record_marker(env, llh, fsdb, CM_START, devname, comment);
1430 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1433 rc = record_marker(env, llh, fsdb, CM_END, devname, comment);
1437 record_end_log(env, &llh);
1441 /* write the lcfg in all logs for the given fs */
1442 int mgs_write_log_direct_all(const struct lu_env *env, struct mgs_device *mgs,
1443 struct fs_db *fsdb, struct mgs_target_info *mti,
1444 struct llog_cfg_rec *lcr, char *devname,
1445 char *comment, int server_only)
1447 struct list_head log_list;
1448 struct mgs_direntry *dirent, *n;
1449 char *fsname = mti->mti_fsname;
1450 int rc = 0, len = strlen(fsname);
1453 /* Find all the logs in the CONFIGS directory */
1454 rc = class_dentry_readdir(env, mgs, &log_list);
1458 /* Could use fsdb index maps instead of directory listing */
1459 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
1460 list_del_init(&dirent->mde_list);
1461 /* don't write to sptlrpc rule log */
1462 if (strstr(dirent->mde_name, "-sptlrpc") != NULL)
1465 /* caller wants write server logs only */
1466 if (server_only && strstr(dirent->mde_name, "-client") != NULL)
1469 if (strncmp(fsname, dirent->mde_name, len) != 0)
1472 CDEBUG(D_MGS, "Changing log %s\n", dirent->mde_name);
1473 /* Erase any old settings of this same parameter */
1474 rc = mgs_modify(env, mgs, fsdb, mti, dirent->mde_name,
1475 devname, comment, CM_SKIP);
1477 CERROR("%s: Can't modify llog %s: rc = %d\n",
1478 mgs->mgs_obd->obd_name, dirent->mde_name, rc);
1481 /* Write the new one */
1482 rc = mgs_write_log_direct(env, mgs, fsdb, dirent->mde_name,
1483 lcr, devname, comment);
1485 CERROR("%s: writing log %s: rc = %d\n",
1486 mgs->mgs_obd->obd_name, dirent->mde_name, rc);
1488 mgs_direntry_free(dirent);
1494 static int mgs_write_log_osp_to_mdt(const struct lu_env *env,
1495 struct mgs_device *mgs,
1497 struct mgs_target_info *mti,
1498 int index, char *logname);
1499 static int mgs_write_log_osc_to_lov(const struct lu_env *env,
1500 struct mgs_device *mgs,
1502 struct mgs_target_info *mti,
1503 char *logname, char *suffix, char *lovname,
1504 enum lustre_sec_part sec_part, int flags);
1505 static int name_create_mdt_and_lov(char **logname, char **lovname,
1506 struct fs_db *fsdb, int i);
1508 static int add_param(char *params, char *key, char *val)
1510 char *start = params + strlen(params);
1511 char *end = params + sizeof(((struct mgs_target_info *)0)->mti_params);
1515 keylen = strlen(key);
1516 if (start + 1 + keylen + strlen(val) >= end) {
1517 CERROR("params are too long: %s %s%s\n",
1518 params, key != NULL ? key : "", val);
1522 sprintf(start, " %s%s", key != NULL ? key : "", val);
1527 * Walk through client config log record and convert the related records
1530 static int mgs_steal_client_llog_handler(const struct lu_env *env,
1531 struct llog_handle *llh,
1532 struct llog_rec_hdr *rec, void *data)
1534 struct mgs_device *mgs;
1535 struct obd_device *obd;
1536 struct mgs_target_info *mti, *tmti;
1538 int cfg_len = rec->lrh_len;
1539 char *cfg_buf = (char*) (rec + 1);
1540 struct lustre_cfg *lcfg;
1542 struct llog_handle *mdt_llh = NULL;
1543 static int got_an_osc_or_mdc = 0;
1544 /* 0: not found any osc/mdc;
1548 static int last_step = -1;
1553 mti = ((struct temp_comp*)data)->comp_mti;
1554 tmti = ((struct temp_comp*)data)->comp_tmti;
1555 fsdb = ((struct temp_comp*)data)->comp_fsdb;
1556 obd = ((struct temp_comp *)data)->comp_obd;
1557 mgs = lu2mgs_dev(obd->obd_lu_dev);
1560 if (rec->lrh_type != OBD_CFG_REC) {
1561 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
1565 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
1567 CERROR("Insane cfg\n");
1571 lcfg = (struct lustre_cfg *)cfg_buf;
1573 if (lcfg->lcfg_command == LCFG_MARKER) {
1574 struct cfg_marker *marker;
1575 marker = lustre_cfg_buf(lcfg, 1);
1576 if (!strncmp(marker->cm_comment, "add osc", 7) &&
1577 (marker->cm_flags & CM_START) &&
1578 !(marker->cm_flags & CM_SKIP)) {
1579 got_an_osc_or_mdc = 1;
1580 cplen = strlcpy(tmti->mti_svname, marker->cm_tgtname,
1581 sizeof(tmti->mti_svname));
1582 if (cplen >= sizeof(tmti->mti_svname))
1584 rc = record_start_log(env, mgs, &mdt_llh,
1588 rc = record_marker(env, mdt_llh, fsdb, CM_START,
1589 mti->mti_svname, "add osc(copied)");
1590 record_end_log(env, &mdt_llh);
1591 last_step = marker->cm_step;
1594 if (!strncmp(marker->cm_comment, "add osc", 7) &&
1595 (marker->cm_flags & CM_END) &&
1596 !(marker->cm_flags & CM_SKIP)) {
1597 LASSERT(last_step == marker->cm_step);
1599 got_an_osc_or_mdc = 0;
1600 memset(tmti, 0, sizeof(*tmti));
1601 rc = record_start_log(env, mgs, &mdt_llh,
1605 rc = record_marker(env, mdt_llh, fsdb, CM_END,
1606 mti->mti_svname, "add osc(copied)");
1607 record_end_log(env, &mdt_llh);
1610 if (!strncmp(marker->cm_comment, "add mdc", 7) &&
1611 (marker->cm_flags & CM_START) &&
1612 !(marker->cm_flags & CM_SKIP)) {
1613 got_an_osc_or_mdc = 2;
1614 last_step = marker->cm_step;
1615 memcpy(tmti->mti_svname, marker->cm_tgtname,
1616 strlen(marker->cm_tgtname));
1620 if (!strncmp(marker->cm_comment, "add mdc", 7) &&
1621 (marker->cm_flags & CM_END) &&
1622 !(marker->cm_flags & CM_SKIP)) {
1623 LASSERT(last_step == marker->cm_step);
1625 got_an_osc_or_mdc = 0;
1626 memset(tmti, 0, sizeof(*tmti));
1631 if (got_an_osc_or_mdc == 0 || last_step < 0)
1634 if (lcfg->lcfg_command == LCFG_ADD_UUID) {
1635 uint64_t nodenid = lcfg->lcfg_nid;
1637 if (strlen(tmti->mti_uuid) == 0) {
1638 /* target uuid not set, this config record is before
1639 * LCFG_SETUP, this nid is one of target node nid.
1641 tmti->mti_nids[tmti->mti_nid_count] = nodenid;
1642 tmti->mti_nid_count++;
1644 /* failover node nid */
1645 rc = add_param(tmti->mti_params, PARAM_FAILNODE,
1646 libcfs_nid2str(nodenid));
1652 if (lcfg->lcfg_command == LCFG_SETUP) {
1655 target = lustre_cfg_string(lcfg, 1);
1656 memcpy(tmti->mti_uuid, target, strlen(target));
1660 /* ignore client side sptlrpc_conf_log */
1661 if (lcfg->lcfg_command == LCFG_SPTLRPC_CONF)
1664 if (lcfg->lcfg_command == LCFG_ADD_MDC) {
1667 if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1)
1670 memcpy(tmti->mti_fsname, mti->mti_fsname,
1671 strlen(mti->mti_fsname));
1672 tmti->mti_stripe_index = index;
1674 rc = mgs_write_log_osp_to_mdt(env, mgs, fsdb, tmti,
1675 mti->mti_stripe_index,
1677 memset(tmti, 0, sizeof(*tmti));
1681 if (lcfg->lcfg_command == LCFG_LOV_ADD_OBD) {
1684 char *logname, *lovname;
1686 rc = name_create_mdt_and_lov(&logname, &lovname, fsdb,
1687 mti->mti_stripe_index);
1690 sprintf(mdt_index, "-MDT%04x", mti->mti_stripe_index);
1692 if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1) {
1693 name_destroy(&logname);
1694 name_destroy(&lovname);
1698 tmti->mti_stripe_index = index;
1699 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, tmti, logname,
1702 name_destroy(&logname);
1703 name_destroy(&lovname);
1709 /* fsdb->fsdb_mutex is already held in mgs_write_log_target*/
1710 /* stealed from mgs_get_fsdb_from_llog*/
1711 static int mgs_steal_llog_for_mdt_from_client(const struct lu_env *env,
1712 struct mgs_device *mgs,
1714 struct temp_comp* comp)
1716 struct llog_handle *loghandle;
1717 struct mgs_target_info *tmti;
1718 struct llog_ctxt *ctxt;
1723 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
1724 LASSERT(ctxt != NULL);
1726 OBD_ALLOC_PTR(tmti);
1728 GOTO(out_ctxt, rc = -ENOMEM);
1730 comp->comp_tmti = tmti;
1731 comp->comp_obd = mgs->mgs_obd;
1733 rc = llog_open(env, ctxt, &loghandle, NULL, client_name,
1741 rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL);
1743 GOTO(out_close, rc);
1745 rc = llog_process_or_fork(env, loghandle, mgs_steal_client_llog_handler,
1746 (void *)comp, NULL, false);
1747 CDEBUG(D_MGS, "steal llog re = %d\n", rc);
1749 llog_close(env, loghandle);
1753 llog_ctxt_put(ctxt);
1757 /* lmv is the second thing for client logs */
1758 /* copied from mgs_write_log_lov. Please refer to that. */
1759 static int mgs_write_log_lmv(const struct lu_env *env,
1760 struct mgs_device *mgs,
1762 struct mgs_target_info *mti,
1763 char *logname, char *lmvname)
1765 struct llog_handle *llh = NULL;
1766 struct lmv_desc *lmvdesc;
1771 CDEBUG(D_MGS, "Writing lmv(%s) log for %s\n", lmvname,logname);
1773 OBD_ALLOC_PTR(lmvdesc);
1774 if (lmvdesc == NULL)
1776 lmvdesc->ld_active_tgt_count = 0;
1777 lmvdesc->ld_tgt_count = 0;
1778 sprintf((char*)lmvdesc->ld_uuid.uuid, "%s_UUID", lmvname);
1779 uuid = (char *)lmvdesc->ld_uuid.uuid;
1781 rc = record_start_log(env, mgs, &llh, logname);
1784 rc = record_marker(env, llh, fsdb, CM_START, lmvname, "lmv setup");
1787 rc = record_attach(env, llh, lmvname, "lmv", uuid);
1790 rc = record_lmv_setup(env, llh, lmvname, lmvdesc);
1793 rc = record_marker(env, llh, fsdb, CM_END, lmvname, "lmv setup");
1797 record_end_log(env, &llh);
1799 OBD_FREE_PTR(lmvdesc);
1803 /* lov is the first thing in the mdt and client logs */
1804 static int mgs_write_log_lov(const struct lu_env *env, struct mgs_device *mgs,
1805 struct fs_db *fsdb, struct mgs_target_info *mti,
1806 char *logname, char *lovname)
1808 struct llog_handle *llh = NULL;
1809 struct lov_desc *lovdesc;
1814 CDEBUG(D_MGS, "Writing lov(%s) log for %s\n", lovname, logname);
1817 #01 L attach 0:lov_mdsA 1:lov 2:71ccb_lov_mdsA_19f961a9e1
1818 #02 L lov_setup 0:lov_mdsA 1:(struct lov_desc)
1819 uuid=lov1_UUID, stripe count=1, size=1048576, offset=0, pattern=0
1822 /* FIXME just make lov_setup accept empty desc (put uuid in buf 2) */
1823 OBD_ALLOC_PTR(lovdesc);
1824 if (lovdesc == NULL)
1826 lovdesc->ld_magic = LOV_DESC_MAGIC;
1827 lovdesc->ld_tgt_count = 0;
1828 /* Defaults. Can be changed later by lcfg config_param */
1829 lovdesc->ld_default_stripe_count = 1;
1830 lovdesc->ld_pattern = LOV_PATTERN_RAID0;
1831 lovdesc->ld_default_stripe_size = LOV_DESC_STRIPE_SIZE_DEFAULT;
1832 lovdesc->ld_default_stripe_offset = -1;
1833 lovdesc->ld_qos_maxage = LOV_DESC_QOS_MAXAGE_DEFAULT;
1834 sprintf((char*)lovdesc->ld_uuid.uuid, "%s_UUID", lovname);
1835 /* can these be the same? */
1836 uuid = (char *)lovdesc->ld_uuid.uuid;
1838 /* This should always be the first entry in a log.
1839 rc = mgs_clear_log(obd, logname); */
1840 rc = record_start_log(env, mgs, &llh, logname);
1843 /* FIXME these should be a single journal transaction */
1844 rc = record_marker(env, llh, fsdb, CM_START, lovname, "lov setup");
1847 rc = record_attach(env, llh, lovname, "lov", uuid);
1850 rc = record_lov_setup(env, llh, lovname, lovdesc);
1853 rc = record_marker(env, llh, fsdb, CM_END, lovname, "lov setup");
1858 record_end_log(env, &llh);
1860 OBD_FREE_PTR(lovdesc);
1864 /* add failnids to open log */
1865 static int mgs_write_log_failnids(const struct lu_env *env,
1866 struct mgs_target_info *mti,
1867 struct llog_handle *llh,
1870 char *failnodeuuid = NULL;
1871 char *ptr = mti->mti_params;
1876 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) nal=90 0: 1:uml1_UUID
1877 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
1878 #05 L setup 0:OSC_uml1_ost1_mdsA 1:ost1_UUID 2:uml1_UUID
1879 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) nal=90 0: 1:uml2_UUID
1880 #0x L add_uuid nid=2@elan(0x1000000000002) nal=90 0: 1:uml2_UUID
1881 #07 L add_conn 0:OSC_uml1_ost1_mdsA 1:uml2_UUID
1884 /* Pull failnid info out of params string */
1885 while (class_find_param(ptr, PARAM_FAILNODE, &ptr) == 0) {
1886 while (class_parse_nid(ptr, &nid, &ptr) == 0) {
1887 if (failnodeuuid == NULL) {
1888 /* We don't know the failover node name,
1889 so just use the first nid as the uuid */
1890 rc = name_create(&failnodeuuid,
1891 libcfs_nid2str(nid), "");
1895 CDEBUG(D_MGS, "add nid %s for failover uuid %s, "
1896 "client %s\n", libcfs_nid2str(nid),
1897 failnodeuuid, cliname);
1898 rc = record_add_uuid(env, llh, nid, failnodeuuid);
1901 rc = record_add_conn(env, llh, cliname, failnodeuuid);
1902 name_destroy(&failnodeuuid);
1903 failnodeuuid = NULL;
1910 static int mgs_write_log_mdc_to_lmv(const struct lu_env *env,
1911 struct mgs_device *mgs,
1913 struct mgs_target_info *mti,
1914 char *logname, char *lmvname)
1916 struct llog_handle *llh = NULL;
1917 char *mdcname = NULL;
1918 char *nodeuuid = NULL;
1919 char *mdcuuid = NULL;
1920 char *lmvuuid = NULL;
1925 if (mgs_log_is_empty(env, mgs, logname)) {
1926 CERROR("log is empty! Logical error\n");
1930 CDEBUG(D_MGS, "adding mdc for %s to log %s:lmv(%s)\n",
1931 mti->mti_svname, logname, lmvname);
1933 rc = name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
1936 rc = name_create(&mdcname, mti->mti_svname, "-mdc");
1939 rc = name_create(&mdcuuid, mdcname, "_UUID");
1942 rc = name_create(&lmvuuid, lmvname, "_UUID");
1946 rc = record_start_log(env, mgs, &llh, logname);
1949 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
1953 for (i = 0; i < mti->mti_nid_count; i++) {
1954 CDEBUG(D_MGS, "add nid %s for mdt\n",
1955 libcfs_nid2str(mti->mti_nids[i]));
1957 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
1962 rc = record_attach(env, llh, mdcname, LUSTRE_MDC_NAME, lmvuuid);
1965 rc = record_setup(env, llh, mdcname, mti->mti_uuid, nodeuuid, 0, 0);
1968 rc = mgs_write_log_failnids(env, mti, llh, mdcname);
1971 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
1972 rc = record_mdc_add(env, llh, lmvname, mdcuuid, mti->mti_uuid,
1976 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname,
1981 record_end_log(env, &llh);
1983 name_destroy(&lmvuuid);
1984 name_destroy(&mdcuuid);
1985 name_destroy(&mdcname);
1986 name_destroy(&nodeuuid);
1990 static inline int name_create_lov(char **lovname, char *mdtname,
1991 struct fs_db *fsdb, int index)
1994 if (index == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
1995 return name_create(lovname, fsdb->fsdb_name, "-mdtlov");
1997 return name_create(lovname, mdtname, "-mdtlov");
2000 static int name_create_mdt_and_lov(char **logname, char **lovname,
2001 struct fs_db *fsdb, int i)
2005 rc = name_create_mdt(logname, fsdb->fsdb_name, i);
2009 if (i == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2010 rc = name_create(lovname, fsdb->fsdb_name, "-mdtlov");
2012 rc = name_create(lovname, *logname, "-mdtlov");
2014 name_destroy(logname);
2020 static inline int name_create_mdt_osc(char **oscname, char *ostname,
2021 struct fs_db *fsdb, int i)
2025 if (i == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2026 sprintf(suffix, "-osc");
2028 sprintf(suffix, "-osc-MDT%04x", i);
2029 return name_create(oscname, ostname, suffix);
2032 /* add new mdc to already existent MDS */
2033 static int mgs_write_log_osp_to_mdt(const struct lu_env *env,
2034 struct mgs_device *mgs,
2036 struct mgs_target_info *mti,
2037 int mdt_index, char *logname)
2039 struct llog_handle *llh = NULL;
2040 char *nodeuuid = NULL;
2041 char *ospname = NULL;
2042 char *lovuuid = NULL;
2043 char *mdtuuid = NULL;
2044 char *svname = NULL;
2045 char *mdtname = NULL;
2046 char *lovname = NULL;
2051 if (mgs_log_is_empty(env, mgs, mti->mti_svname)) {
2052 CERROR("log is empty! Logical error\n");
2056 CDEBUG(D_MGS, "adding osp index %d to %s\n", mti->mti_stripe_index,
2059 rc = name_create_mdt(&mdtname, fsdb->fsdb_name, mti->mti_stripe_index);
2063 rc = name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
2065 GOTO(out_destory, rc);
2067 rc = name_create(&svname, mdtname, "-osp");
2069 GOTO(out_destory, rc);
2071 sprintf(index_str, "-MDT%04x", mdt_index);
2072 rc = name_create(&ospname, svname, index_str);
2074 GOTO(out_destory, rc);
2076 rc = name_create_lov(&lovname, logname, fsdb, mdt_index);
2078 GOTO(out_destory, rc);
2080 rc = name_create(&lovuuid, lovname, "_UUID");
2082 GOTO(out_destory, rc);
2084 rc = name_create(&mdtuuid, mdtname, "_UUID");
2086 GOTO(out_destory, rc);
2088 rc = record_start_log(env, mgs, &llh, logname);
2090 GOTO(out_destory, rc);
2092 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
2095 GOTO(out_destory, rc);
2097 for (i = 0; i < mti->mti_nid_count; i++) {
2098 CDEBUG(D_MGS, "add nid %s for mdt\n",
2099 libcfs_nid2str(mti->mti_nids[i]));
2100 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
2105 rc = record_attach(env, llh, ospname, LUSTRE_OSP_NAME, lovuuid);
2109 rc = record_setup(env, llh, ospname, mti->mti_uuid, nodeuuid,
2114 rc = mgs_write_log_failnids(env, mti, llh, ospname);
2118 /* Add mdc(osp) to lod */
2119 snprintf(index_str, sizeof(mti->mti_stripe_index), "%d",
2120 mti->mti_stripe_index);
2121 rc = record_base(env, llh, lovname, 0, LCFG_ADD_MDC, mti->mti_uuid,
2122 index_str, "1", NULL);
2126 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname, "add osp");
2131 record_end_log(env, &llh);
2134 name_destroy(&mdtuuid);
2135 name_destroy(&lovuuid);
2136 name_destroy(&lovname);
2137 name_destroy(&ospname);
2138 name_destroy(&svname);
2139 name_destroy(&nodeuuid);
2140 name_destroy(&mdtname);
2144 static int mgs_write_log_mdt0(const struct lu_env *env,
2145 struct mgs_device *mgs,
2147 struct mgs_target_info *mti)
2149 char *log = mti->mti_svname;
2150 struct llog_handle *llh = NULL;
2151 char *uuid, *lovname;
2153 char *ptr = mti->mti_params;
2154 int rc = 0, failout = 0;
2157 OBD_ALLOC(uuid, sizeof(struct obd_uuid));
2161 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
2162 failout = (strncmp(ptr, "failout", 7) == 0);
2164 rc = name_create(&lovname, log, "-mdtlov");
2167 if (mgs_log_is_empty(env, mgs, log)) {
2168 rc = mgs_write_log_lov(env, mgs, fsdb, mti, log, lovname);
2173 sprintf(mdt_index, "%d", mti->mti_stripe_index);
2175 rc = record_start_log(env, mgs, &llh, log);
2179 /* add MDT itself */
2181 /* FIXME this whole fn should be a single journal transaction */
2182 sprintf(uuid, "%s_UUID", log);
2183 rc = record_marker(env, llh, fsdb, CM_START, log, "add mdt");
2186 rc = record_attach(env, llh, log, LUSTRE_MDT_NAME, uuid);
2189 rc = record_mount_opt(env, llh, log, lovname, NULL);
2192 rc = record_setup(env, llh, log, uuid, mdt_index, lovname,
2193 failout ? "n" : "f");
2196 rc = record_marker(env, llh, fsdb, CM_END, log, "add mdt");
2200 record_end_log(env, &llh);
2202 name_destroy(&lovname);
2204 OBD_FREE(uuid, sizeof(struct obd_uuid));
2208 /* envelope method for all layers log */
2209 static int mgs_write_log_mdt(const struct lu_env *env,
2210 struct mgs_device *mgs,
2212 struct mgs_target_info *mti)
2214 struct mgs_thread_info *mgi = mgs_env_info(env);
2215 struct llog_handle *llh = NULL;
2220 CDEBUG(D_MGS, "writing new mdt %s\n", mti->mti_svname);
2222 if (mti->mti_uuid[0] == '\0') {
2223 /* Make up our own uuid */
2224 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
2225 "%s_UUID", mti->mti_svname);
2229 rc = mgs_write_log_mdt0(env, mgs, fsdb, mti);
2232 /* Append the mdt info to the client log */
2233 rc = name_create(&cliname, mti->mti_fsname, "-client");
2237 if (mgs_log_is_empty(env, mgs, cliname)) {
2238 /* Start client log */
2239 rc = mgs_write_log_lov(env, mgs, fsdb, mti, cliname,
2243 rc = mgs_write_log_lmv(env, mgs, fsdb, mti, cliname,
2250 #09 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
2251 #10 L attach 0:MDC_uml1_mdsA_MNT_client 1:mdc 2:1d834_MNT_client_03f
2252 #11 L setup 0:MDC_uml1_mdsA_MNT_client 1:mdsA_UUID 2:uml1_UUID
2253 #12 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
2254 #13 L add_conn 0:MDC_uml1_mdsA_MNT_client 1:uml2_UUID
2255 #14 L mount_option 0: 1:client 2:lov1 3:MDC_uml1_mdsA_MNT_client
2258 /* copy client info about lov/lmv */
2259 mgi->mgi_comp.comp_mti = mti;
2260 mgi->mgi_comp.comp_fsdb = fsdb;
2262 rc = mgs_steal_llog_for_mdt_from_client(env, mgs, cliname,
2266 rc = mgs_write_log_mdc_to_lmv(env, mgs, fsdb, mti, cliname,
2272 rc = record_start_log(env, mgs, &llh, cliname);
2276 rc = record_marker(env, llh, fsdb, CM_START, cliname,
2280 rc = record_mount_opt(env, llh, cliname, fsdb->fsdb_clilov,
2284 rc = record_marker(env, llh, fsdb, CM_END, cliname,
2290 /* for_all_existing_mdt except current one */
2291 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2292 if (i != mti->mti_stripe_index &&
2293 test_bit(i, fsdb->fsdb_mdt_index_map)) {
2296 rc = name_create_mdt(&logname, fsdb->fsdb_name, i);
2300 rc = mgs_write_log_osp_to_mdt(env, mgs, fsdb, mti,
2302 name_destroy(&logname);
2308 record_end_log(env, &llh);
2310 name_destroy(&cliname);
2314 /* Add the ost info to the client/mdt lov */
2315 static int mgs_write_log_osc_to_lov(const struct lu_env *env,
2316 struct mgs_device *mgs, struct fs_db *fsdb,
2317 struct mgs_target_info *mti,
2318 char *logname, char *suffix, char *lovname,
2319 enum lustre_sec_part sec_part, int flags)
2321 struct llog_handle *llh = NULL;
2322 char *nodeuuid = NULL;
2323 char *oscname = NULL;
2324 char *oscuuid = NULL;
2325 char *lovuuid = NULL;
2326 char *svname = NULL;
2331 CDEBUG(D_INFO, "adding osc for %s to log %s\n",
2332 mti->mti_svname, logname);
2334 if (mgs_log_is_empty(env, mgs, logname)) {
2335 CERROR("log is empty! Logical error\n");
2339 rc = name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
2342 rc = name_create(&svname, mti->mti_svname, "-osc");
2346 /* for the system upgraded from old 1.8, keep using the old osc naming
2347 * style for mdt, see name_create_mdt_osc(). LU-1257 */
2348 if (test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2349 rc = name_create(&oscname, svname, "");
2351 rc = name_create(&oscname, svname, suffix);
2355 rc = name_create(&oscuuid, oscname, "_UUID");
2358 rc = name_create(&lovuuid, lovname, "_UUID");
2364 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
2366 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
2367 #04 L attach 0:OSC_uml1_ost1_MNT_client 1:osc 2:89070_lov1_a41dff51a
2368 #05 L setup 0:OSC_uml1_ost1_MNT_client 1:ost1_UUID 2:uml1_UUID
2370 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
2371 #07 L add_conn 0:OSC_uml1_ost1_MNT_client 1:uml2_UUID
2372 #08 L lov_modify_tgts add 0:lov1 1:ost1_UUID 2(index):0 3(gen):1
2375 rc = record_start_log(env, mgs, &llh, logname);
2379 /* FIXME these should be a single journal transaction */
2380 rc = record_marker(env, llh, fsdb, CM_START | flags, mti->mti_svname,
2385 /* NB: don't change record order, because upon MDT steal OSC config
2386 * from client, it treats all nids before LCFG_SETUP as target nids
2387 * (multiple interfaces), while nids after as failover node nids.
2388 * See mgs_steal_client_llog_handler() LCFG_ADD_UUID.
2390 for (i = 0; i < mti->mti_nid_count; i++) {
2391 CDEBUG(D_MGS, "add nid %s\n", libcfs_nid2str(mti->mti_nids[i]));
2392 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
2396 rc = record_attach(env, llh, oscname, LUSTRE_OSC_NAME, lovuuid);
2399 rc = record_setup(env, llh, oscname, mti->mti_uuid, nodeuuid, 0, 0);
2402 rc = mgs_write_log_failnids(env, mti, llh, oscname);
2406 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
2408 rc = record_lov_add(env, llh, lovname, mti->mti_uuid, index, "1");
2411 rc = record_marker(env, llh, fsdb, CM_END | flags, mti->mti_svname,
2416 record_end_log(env, &llh);
2418 name_destroy(&lovuuid);
2419 name_destroy(&oscuuid);
2420 name_destroy(&oscname);
2421 name_destroy(&svname);
2422 name_destroy(&nodeuuid);
2426 static int mgs_write_log_ost(const struct lu_env *env,
2427 struct mgs_device *mgs, struct fs_db *fsdb,
2428 struct mgs_target_info *mti)
2430 struct llog_handle *llh = NULL;
2431 char *logname, *lovname;
2432 char *ptr = mti->mti_params;
2433 int rc, flags = 0, failout = 0, i;
2436 CDEBUG(D_MGS, "writing new ost %s\n", mti->mti_svname);
2438 /* The ost startup log */
2440 /* If the ost log already exists, that means that someone reformatted
2441 the ost and it called target_add again. */
2442 if (!mgs_log_is_empty(env, mgs, mti->mti_svname)) {
2443 LCONSOLE_ERROR_MSG(0x141, "The config log for %s already "
2444 "exists, yet the server claims it never "
2445 "registered. It may have been reformatted, "
2446 "or the index changed. writeconf the MDT to "
2447 "regenerate all logs.\n", mti->mti_svname);
2452 attach obdfilter ost1 ost1_UUID
2453 setup /dev/loop2 ldiskfs f|n errors=remount-ro,user_xattr
2455 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
2456 failout = (strncmp(ptr, "failout", 7) == 0);
2457 rc = record_start_log(env, mgs, &llh, mti->mti_svname);
2460 /* FIXME these should be a single journal transaction */
2461 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,"add ost");
2464 if (*mti->mti_uuid == '\0')
2465 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
2466 "%s_UUID", mti->mti_svname);
2467 rc = record_attach(env, llh, mti->mti_svname,
2468 "obdfilter"/*LUSTRE_OST_NAME*/, mti->mti_uuid);
2471 rc = record_setup(env, llh, mti->mti_svname,
2472 "dev"/*ignored*/, "type"/*ignored*/,
2473 failout ? "n" : "f", 0/*options*/);
2476 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname, "add ost");
2480 record_end_log(env, &llh);
2483 /* We also have to update the other logs where this osc is part of
2486 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
2487 /* If we're upgrading, the old mdt log already has our
2488 entry. Let's do a fake one for fun. */
2489 /* Note that we can't add any new failnids, since we don't
2490 know the old osc names. */
2491 flags = CM_SKIP | CM_UPGRADE146;
2493 } else if ((mti->mti_flags & LDD_F_UPDATE) != LDD_F_UPDATE) {
2494 /* If the update flag isn't set, don't update client/mdt
2497 LCONSOLE_WARN("Client log for %s was not updated; writeconf "
2498 "the MDT first to regenerate it.\n",
2502 /* Add ost to all MDT lov defs */
2503 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
2504 if (test_bit(i, fsdb->fsdb_mdt_index_map)) {
2507 rc = name_create_mdt_and_lov(&logname, &lovname, fsdb,
2511 sprintf(mdt_index, "-MDT%04x", i);
2512 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, mti,
2514 lovname, LUSTRE_SP_MDT,
2516 name_destroy(&logname);
2517 name_destroy(&lovname);
2523 /* Append ost info to the client log */
2524 rc = name_create(&logname, mti->mti_fsname, "-client");
2527 if (mgs_log_is_empty(env, mgs, logname)) {
2528 /* Start client log */
2529 rc = mgs_write_log_lov(env, mgs, fsdb, mti, logname,
2533 rc = mgs_write_log_lmv(env, mgs, fsdb, mti, logname,
2538 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, mti, logname, "",
2539 fsdb->fsdb_clilov, LUSTRE_SP_CLI, 0);
2541 name_destroy(&logname);
2545 static __inline__ int mgs_param_empty(char *ptr)
2549 if ((tmp = strchr(ptr, '=')) && (*(++tmp) == '\0'))
2554 static int mgs_write_log_failnid_internal(const struct lu_env *env,
2555 struct mgs_device *mgs,
2557 struct mgs_target_info *mti,
2558 char *logname, char *cliname)
2561 struct llog_handle *llh = NULL;
2563 if (mgs_param_empty(mti->mti_params)) {
2564 /* Remove _all_ failnids */
2565 rc = mgs_modify(env, mgs, fsdb, mti, logname,
2566 mti->mti_svname, "add failnid", CM_SKIP);
2567 return rc < 0 ? rc : 0;
2570 /* Otherwise failover nids are additive */
2571 rc = record_start_log(env, mgs, &llh, logname);
2574 /* FIXME this should be a single journal transaction */
2575 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
2579 rc = mgs_write_log_failnids(env, mti, llh, cliname);
2582 rc = record_marker(env, llh, fsdb, CM_END,
2583 mti->mti_svname, "add failnid");
2585 record_end_log(env, &llh);
2590 /* Add additional failnids to an existing log.
2591 The mdc/osc must have been added to logs first */
2592 /* tcp nids must be in dotted-quad ascii -
2593 we can't resolve hostnames from the kernel. */
2594 static int mgs_write_log_add_failnid(const struct lu_env *env,
2595 struct mgs_device *mgs,
2597 struct mgs_target_info *mti)
2599 char *logname, *cliname;
2603 /* FIXME we currently can't erase the failnids
2604 * given when a target first registers, since they aren't part of
2605 * an "add uuid" stanza */
2607 /* Verify that we know about this target */
2608 if (mgs_log_is_empty(env, mgs, mti->mti_svname)) {
2609 LCONSOLE_ERROR_MSG(0x142, "The target %s has not registered "
2610 "yet. It must be started before failnids "
2611 "can be added.\n", mti->mti_svname);
2615 /* Create mdc/osc client name (e.g. lustre-OST0001-osc) */
2616 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
2617 rc = name_create(&cliname, mti->mti_svname, "-mdc");
2618 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2619 rc = name_create(&cliname, mti->mti_svname, "-osc");
2625 /* Add failover nids to the client log */
2626 rc = name_create(&logname, mti->mti_fsname, "-client");
2628 name_destroy(&cliname);
2631 rc = mgs_write_log_failnid_internal(env, mgs, fsdb,mti,logname,cliname);
2632 name_destroy(&logname);
2633 name_destroy(&cliname);
2637 if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2638 /* Add OST failover nids to the MDT logs as well */
2641 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2642 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
2644 rc = name_create_mdt(&logname, mti->mti_fsname, i);
2647 rc = name_create_mdt_osc(&cliname, mti->mti_svname,
2650 name_destroy(&logname);
2653 rc = mgs_write_log_failnid_internal(env, mgs, fsdb,
2656 name_destroy(&cliname);
2657 name_destroy(&logname);
2666 static int mgs_wlp_lcfg(const struct lu_env *env,
2667 struct mgs_device *mgs, struct fs_db *fsdb,
2668 struct mgs_target_info *mti,
2669 char *logname, struct lustre_cfg_bufs *bufs,
2670 char *tgtname, char *ptr)
2672 char comment[MTI_NAME_MAXLEN];
2674 struct llog_cfg_rec *lcr;
2677 /* Erase any old settings of this same parameter */
2678 memcpy(comment, ptr, MTI_NAME_MAXLEN);
2679 comment[MTI_NAME_MAXLEN - 1] = 0;
2680 /* But don't try to match the value. */
2681 tmp = strchr(comment, '=');
2684 /* FIXME we should skip settings that are the same as old values */
2685 rc = mgs_modify(env, mgs, fsdb, mti, logname, tgtname, comment,CM_SKIP);
2688 del = mgs_param_empty(ptr);
2690 LCONSOLE_INFO("%s parameter %s.%s in log %s\n", del ? "Disabling" : rc ?
2691 "Setting" : "Modifying", tgtname, comment, logname);
2693 /* mgs_modify() will return 1 if nothing had to be done */
2699 lustre_cfg_bufs_reset(bufs, tgtname);
2700 lustre_cfg_bufs_set_string(bufs, 1, ptr);
2701 if (mti->mti_flags & LDD_F_PARAM2)
2702 lustre_cfg_bufs_set_string(bufs, 2, LCTL_UPCALL);
2704 lcr = lustre_cfg_rec_new((mti->mti_flags & LDD_F_PARAM2) ?
2705 LCFG_SET_PARAM : LCFG_PARAM, bufs);
2709 rc = mgs_write_log_direct(env, mgs, fsdb, logname, lcr, tgtname,
2711 lustre_cfg_rec_free(lcr);
2715 static int mgs_write_log_param2(const struct lu_env *env,
2716 struct mgs_device *mgs,
2718 struct mgs_target_info *mti, char *ptr)
2720 struct lustre_cfg_bufs bufs;
2724 CDEBUG(D_MGS, "next param '%s'\n", ptr);
2725 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, PARAMS_FILENAME, &bufs,
2726 mti->mti_svname, ptr);
2731 /* write global variable settings into log */
2732 static int mgs_write_log_sys(const struct lu_env *env,
2733 struct mgs_device *mgs, struct fs_db *fsdb,
2734 struct mgs_target_info *mti, char *sys, char *ptr)
2736 struct mgs_thread_info *mgi = mgs_env_info(env);
2737 struct lustre_cfg *lcfg;
2738 struct llog_cfg_rec *lcr;
2740 int rc, cmd, convert = 1;
2742 if (class_match_param(ptr, PARAM_TIMEOUT, &tmp) == 0) {
2743 cmd = LCFG_SET_TIMEOUT;
2744 } else if (class_match_param(ptr, PARAM_LDLM_TIMEOUT, &tmp) == 0) {
2745 cmd = LCFG_SET_LDLM_TIMEOUT;
2746 /* Check for known params here so we can return error to lctl */
2747 } else if ((class_match_param(ptr, PARAM_AT_MIN, &tmp) == 0) ||
2748 (class_match_param(ptr, PARAM_AT_MAX, &tmp) == 0) ||
2749 (class_match_param(ptr, PARAM_AT_EXTRA, &tmp) == 0) ||
2750 (class_match_param(ptr, PARAM_AT_EARLY_MARGIN, &tmp) == 0) ||
2751 (class_match_param(ptr, PARAM_AT_HISTORY, &tmp) == 0)) {
2753 } else if (class_match_param(ptr, PARAM_JOBID_VAR, &tmp) == 0) {
2754 convert = 0; /* Don't convert string value to integer */
2760 if (mgs_param_empty(ptr))
2761 CDEBUG(D_MGS, "global '%s' removed\n", sys);
2763 CDEBUG(D_MGS, "global '%s' val=%s\n", sys, tmp);
2765 lustre_cfg_bufs_reset(&mgi->mgi_bufs, NULL);
2766 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, sys);
2767 if (!convert && *tmp != '\0')
2768 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 2, tmp);
2769 lcr = lustre_cfg_rec_new(cmd, &mgi->mgi_bufs);
2773 lcfg = &lcr->lcr_cfg;
2774 lcfg->lcfg_num = convert ? simple_strtoul(tmp, NULL, 0) : 0;
2775 /* truncate the comment to the parameter name */
2779 /* modify all servers and clients */
2780 rc = mgs_write_log_direct_all(env, mgs, fsdb, mti,
2781 *tmp == '\0' ? NULL : lcr,
2782 mti->mti_fsname, sys, 0);
2783 if (rc == 0 && *tmp != '\0') {
2785 case LCFG_SET_TIMEOUT:
2786 if (!obd_timeout_set || lcfg->lcfg_num > obd_timeout)
2787 class_process_config(lcfg);
2789 case LCFG_SET_LDLM_TIMEOUT:
2790 if (!ldlm_timeout_set || lcfg->lcfg_num > ldlm_timeout)
2791 class_process_config(lcfg);
2798 lustre_cfg_rec_free(lcr);
2802 /* write quota settings into log */
2803 static int mgs_write_log_quota(const struct lu_env *env, struct mgs_device *mgs,
2804 struct fs_db *fsdb, struct mgs_target_info *mti,
2805 char *quota, char *ptr)
2807 struct mgs_thread_info *mgi = mgs_env_info(env);
2808 struct llog_cfg_rec *lcr;
2811 int rc, cmd = LCFG_PARAM;
2813 /* support only 'meta' and 'data' pools so far */
2814 if (class_match_param(ptr, QUOTA_METAPOOL_NAME, &tmp) != 0 &&
2815 class_match_param(ptr, QUOTA_DATAPOOL_NAME, &tmp) != 0) {
2816 CERROR("parameter quota.%s isn't supported (only quota.mdt "
2817 "& quota.ost are)\n", ptr);
2822 CDEBUG(D_MGS, "global '%s' removed\n", quota);
2824 CDEBUG(D_MGS, "global '%s'\n", quota);
2826 if (strchr(tmp, 'u') == NULL && strchr(tmp, 'g') == NULL &&
2827 strcmp(tmp, "none") != 0) {
2828 CERROR("enable option(%s) isn't supported\n", tmp);
2833 lustre_cfg_bufs_reset(&mgi->mgi_bufs, mti->mti_fsname);
2834 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, quota);
2835 lcr = lustre_cfg_rec_new(cmd, &mgi->mgi_bufs);
2839 /* truncate the comment to the parameter name */
2844 /* XXX we duplicated quota enable information in all server
2845 * config logs, it should be moved to a separate config
2846 * log once we cleanup the config log for global param. */
2847 /* modify all servers */
2848 rc = mgs_write_log_direct_all(env, mgs, fsdb, mti,
2849 *tmp == '\0' ? NULL : lcr,
2850 mti->mti_fsname, quota, 1);
2852 lustre_cfg_rec_free(lcr);
2853 return rc < 0 ? rc : 0;
2856 static int mgs_srpc_set_param_disk(const struct lu_env *env,
2857 struct mgs_device *mgs,
2859 struct mgs_target_info *mti,
2862 struct mgs_thread_info *mgi = mgs_env_info(env);
2863 struct llog_cfg_rec *lcr;
2864 struct llog_handle *llh = NULL;
2866 char *comment, *ptr;
2872 ptr = strchr(param, '=');
2873 LASSERT(ptr != NULL);
2876 OBD_ALLOC(comment, len + 1);
2877 if (comment == NULL)
2879 strncpy(comment, param, len);
2880 comment[len] = '\0';
2883 lustre_cfg_bufs_reset(&mgi->mgi_bufs, mti->mti_svname);
2884 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, param);
2885 lcr = lustre_cfg_rec_new(LCFG_SPTLRPC_CONF, &mgi->mgi_bufs);
2887 GOTO(out_comment, rc = -ENOMEM);
2889 /* construct log name */
2890 rc = name_create(&logname, mti->mti_fsname, "-sptlrpc");
2894 if (mgs_log_is_empty(env, mgs, logname)) {
2895 rc = record_start_log(env, mgs, &llh, logname);
2898 record_end_log(env, &llh);
2901 /* obsolete old one */
2902 rc = mgs_modify(env, mgs, fsdb, mti, logname, mti->mti_svname,
2906 /* write the new one */
2907 rc = mgs_write_log_direct(env, mgs, fsdb, logname, lcr,
2908 mti->mti_svname, comment);
2910 CERROR("%s: error writing log %s: rc = %d\n",
2911 mgs->mgs_obd->obd_name, logname, rc);
2913 name_destroy(&logname);
2915 lustre_cfg_rec_free(lcr);
2917 OBD_FREE(comment, len + 1);
2921 static int mgs_srpc_set_param_udesc_mem(struct fs_db *fsdb,
2926 /* disable the adjustable udesc parameter for now, i.e. use default
2927 * setting that client always ship udesc to MDT if possible. to enable
2928 * it simply remove the following line */
2931 ptr = strchr(param, '=');
2936 if (strcmp(param, PARAM_SRPC_UDESC))
2939 if (strcmp(ptr, "yes") == 0) {
2940 set_bit(FSDB_UDESC, &fsdb->fsdb_flags);
2941 CWARN("Enable user descriptor shipping from client to MDT\n");
2942 } else if (strcmp(ptr, "no") == 0) {
2943 clear_bit(FSDB_UDESC, &fsdb->fsdb_flags);
2944 CWARN("Disable user descriptor shipping from client to MDT\n");
2952 CERROR("Invalid param: %s\n", param);
2956 static int mgs_srpc_set_param_mem(struct fs_db *fsdb,
2960 struct sptlrpc_rule rule;
2961 struct sptlrpc_rule_set *rset;
2965 if (strncmp(param, PARAM_SRPC, sizeof(PARAM_SRPC) - 1) != 0) {
2966 CERROR("Invalid sptlrpc parameter: %s\n", param);
2970 if (strncmp(param, PARAM_SRPC_UDESC,
2971 sizeof(PARAM_SRPC_UDESC) - 1) == 0) {
2972 RETURN(mgs_srpc_set_param_udesc_mem(fsdb, param));
2975 if (strncmp(param, PARAM_SRPC_FLVR, sizeof(PARAM_SRPC_FLVR) - 1) != 0) {
2976 CERROR("Invalid sptlrpc flavor parameter: %s\n", param);
2980 param += sizeof(PARAM_SRPC_FLVR) - 1;
2982 rc = sptlrpc_parse_rule(param, &rule);
2986 /* mgs rules implies must be mgc->mgs */
2987 if (test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
2988 if ((rule.sr_from != LUSTRE_SP_MGC &&
2989 rule.sr_from != LUSTRE_SP_ANY) ||
2990 (rule.sr_to != LUSTRE_SP_MGS &&
2991 rule.sr_to != LUSTRE_SP_ANY))
2995 /* preapre room for this coming rule. svcname format should be:
2996 * - fsname: general rule
2997 * - fsname-tgtname: target-specific rule
2999 if (strchr(svname, '-')) {
3000 struct mgs_tgt_srpc_conf *tgtconf;
3003 for (tgtconf = fsdb->fsdb_srpc_tgt; tgtconf != NULL;
3004 tgtconf = tgtconf->mtsc_next) {
3005 if (!strcmp(tgtconf->mtsc_tgt, svname)) {
3014 OBD_ALLOC_PTR(tgtconf);
3015 if (tgtconf == NULL)
3018 name_len = strlen(svname);
3020 OBD_ALLOC(tgtconf->mtsc_tgt, name_len + 1);
3021 if (tgtconf->mtsc_tgt == NULL) {
3022 OBD_FREE_PTR(tgtconf);
3025 memcpy(tgtconf->mtsc_tgt, svname, name_len);
3027 tgtconf->mtsc_next = fsdb->fsdb_srpc_tgt;
3028 fsdb->fsdb_srpc_tgt = tgtconf;
3031 rset = &tgtconf->mtsc_rset;
3033 rset = &fsdb->fsdb_srpc_gen;
3036 rc = sptlrpc_rule_set_merge(rset, &rule);
3041 static int mgs_srpc_set_param(const struct lu_env *env,
3042 struct mgs_device *mgs,
3044 struct mgs_target_info *mti,
3054 /* keep a copy of original param, which could be destroied
3056 copy_size = strlen(param) + 1;
3057 OBD_ALLOC(copy, copy_size);
3060 memcpy(copy, param, copy_size);
3062 rc = mgs_srpc_set_param_mem(fsdb, mti->mti_svname, param);
3066 /* previous steps guaranteed the syntax is correct */
3067 rc = mgs_srpc_set_param_disk(env, mgs, fsdb, mti, copy);
3071 if (test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
3073 * for mgs rules, make them effective immediately.
3075 LASSERT(fsdb->fsdb_srpc_tgt == NULL);
3076 sptlrpc_target_update_exp_flavor(mgs->mgs_obd,
3077 &fsdb->fsdb_srpc_gen);
3081 OBD_FREE(copy, copy_size);
3085 struct mgs_srpc_read_data {
3086 struct fs_db *msrd_fsdb;
3090 static int mgs_srpc_read_handler(const struct lu_env *env,
3091 struct llog_handle *llh,
3092 struct llog_rec_hdr *rec, void *data)
3094 struct mgs_srpc_read_data *msrd = data;
3095 struct cfg_marker *marker;
3096 struct lustre_cfg *lcfg = REC_DATA(rec);
3097 char *svname, *param;
3101 if (rec->lrh_type != OBD_CFG_REC) {
3102 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
3106 cfg_len = REC_DATA_LEN(rec);
3108 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
3110 CERROR("Insane cfg\n");
3114 if (lcfg->lcfg_command == LCFG_MARKER) {
3115 marker = lustre_cfg_buf(lcfg, 1);
3117 if (marker->cm_flags & CM_START &&
3118 marker->cm_flags & CM_SKIP)
3119 msrd->msrd_skip = 1;
3120 if (marker->cm_flags & CM_END)
3121 msrd->msrd_skip = 0;
3126 if (msrd->msrd_skip)
3129 if (lcfg->lcfg_command != LCFG_SPTLRPC_CONF) {
3130 CERROR("invalid command (%x)\n", lcfg->lcfg_command);
3134 svname = lustre_cfg_string(lcfg, 0);
3135 if (svname == NULL) {
3136 CERROR("svname is empty\n");
3140 param = lustre_cfg_string(lcfg, 1);
3141 if (param == NULL) {
3142 CERROR("param is empty\n");
3146 rc = mgs_srpc_set_param_mem(msrd->msrd_fsdb, svname, param);
3148 CERROR("read sptlrpc record error (%d): %s\n", rc, param);
3153 int mgs_get_fsdb_srpc_from_llog(const struct lu_env *env,
3154 struct mgs_device *mgs,
3157 struct llog_handle *llh = NULL;
3158 struct llog_ctxt *ctxt;
3160 struct mgs_srpc_read_data msrd;
3164 /* construct log name */
3165 rc = name_create(&logname, fsdb->fsdb_name, "-sptlrpc");
3169 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
3170 LASSERT(ctxt != NULL);
3172 if (mgs_log_is_empty(env, mgs, logname))
3175 rc = llog_open(env, ctxt, &llh, NULL, logname,
3183 rc = llog_init_handle(env, llh, LLOG_F_IS_PLAIN, NULL);
3185 GOTO(out_close, rc);
3187 if (llog_get_size(llh) <= 1)
3188 GOTO(out_close, rc = 0);
3190 msrd.msrd_fsdb = fsdb;
3193 rc = llog_process(env, llh, mgs_srpc_read_handler, (void *)&msrd,
3197 llog_close(env, llh);
3199 llog_ctxt_put(ctxt);
3200 name_destroy(&logname);
3203 CERROR("failed to read sptlrpc config database: %d\n", rc);
3207 /* Permanent settings of all parameters by writing into the appropriate
3208 * configuration logs.
3209 * A parameter with null value ("<param>='\0'") means to erase it out of
3212 static int mgs_write_log_param(const struct lu_env *env,
3213 struct mgs_device *mgs, struct fs_db *fsdb,
3214 struct mgs_target_info *mti, char *ptr)
3216 struct mgs_thread_info *mgi = mgs_env_info(env);
3219 int rc = 0, rc2 = 0;
3222 /* For various parameter settings, we have to figure out which logs
3223 care about them (e.g. both mdt and client for lov settings) */
3224 CDEBUG(D_MGS, "next param '%s'\n", ptr);
3226 /* The params are stored in MOUNT_DATA_FILE and modified via
3227 tunefs.lustre, or set using lctl conf_param */
3229 /* Processed in lustre_start_mgc */
3230 if (class_match_param(ptr, PARAM_MGSNODE, NULL) == 0)
3233 /* Processed in ost/mdt */
3234 if (class_match_param(ptr, PARAM_NETWORK, NULL) == 0)
3237 /* Processed in mgs_write_log_ost */
3238 if (class_match_param(ptr, PARAM_FAILMODE, NULL) == 0) {
3239 if (mti->mti_flags & LDD_F_PARAM) {
3240 LCONSOLE_ERROR_MSG(0x169, "%s can only be "
3241 "changed with tunefs.lustre"
3242 "and --writeconf\n", ptr);
3248 if (class_match_param(ptr, PARAM_SRPC, NULL) == 0) {
3249 rc = mgs_srpc_set_param(env, mgs, fsdb, mti, ptr);
3253 if (class_match_param(ptr, PARAM_FAILNODE, NULL) == 0) {
3254 /* Add a failover nidlist */
3256 /* We already processed failovers params for new
3257 targets in mgs_write_log_target */
3258 if (mti->mti_flags & LDD_F_PARAM) {
3259 CDEBUG(D_MGS, "Adding failnode\n");
3260 rc = mgs_write_log_add_failnid(env, mgs, fsdb, mti);
3265 if (class_match_param(ptr, PARAM_SYS, &tmp) == 0) {
3266 rc = mgs_write_log_sys(env, mgs, fsdb, mti, ptr, tmp);
3270 if (class_match_param(ptr, PARAM_QUOTA, &tmp) == 0) {
3271 rc = mgs_write_log_quota(env, mgs, fsdb, mti, ptr, tmp);
3275 if (class_match_param(ptr, PARAM_OSC""PARAM_ACTIVE, &tmp) == 0) {
3276 /* active=0 means off, anything else means on */
3277 int flag = (*tmp == '0') ? CM_EXCLUDE : 0;
3280 if (!(mti->mti_flags & LDD_F_SV_TYPE_OST)) {
3281 LCONSOLE_ERROR_MSG(0x144, "%s: Only OSCs can "
3282 "be (de)activated.\n",
3284 GOTO(end, rc = -EINVAL);
3286 LCONSOLE_WARN("Permanently %sactivating %s\n",
3287 flag ? "de": "re", mti->mti_svname);
3289 rc = name_create(&logname, mti->mti_fsname, "-client");
3292 rc = mgs_modify(env, mgs, fsdb, mti, logname,
3293 mti->mti_svname, "add osc", flag);
3294 name_destroy(&logname);
3298 /* Add to all MDT logs for CMD */
3299 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3300 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
3302 rc = name_create_mdt(&logname, mti->mti_fsname, i);
3305 rc = mgs_modify(env, mgs, fsdb, mti, logname,
3306 mti->mti_svname, "add osc", flag);
3307 name_destroy(&logname);
3313 LCONSOLE_ERROR_MSG(0x145, "Couldn't find %s in"
3314 "log (%d). No permanent "
3315 "changes were made to the "
3317 mti->mti_svname, rc);
3318 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags))
3319 LCONSOLE_ERROR_MSG(0x146, "This may be"
3324 "update the logs.\n");
3327 /* Fall through to osc proc for deactivating live OSC
3328 on running MDT / clients. */
3330 /* Below here, let obd's XXX_process_config methods handle it */
3332 /* All lov. in proc */
3333 if (class_match_param(ptr, PARAM_LOV, NULL) == 0) {
3336 CDEBUG(D_MGS, "lov param %s\n", ptr);
3337 if (!(mti->mti_flags & LDD_F_SV_TYPE_MDT)) {
3338 LCONSOLE_ERROR_MSG(0x147, "LOV params must be "
3339 "set on the MDT, not %s. "
3346 if (mgs_log_is_empty(env, mgs, mti->mti_svname))
3347 GOTO(end, rc = -ENODEV);
3349 rc = name_create_mdt_and_lov(&logname, &mdtlovname, fsdb,
3350 mti->mti_stripe_index);
3353 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, mti->mti_svname,
3354 &mgi->mgi_bufs, mdtlovname, ptr);
3355 name_destroy(&logname);
3356 name_destroy(&mdtlovname);
3361 rc = name_create(&logname, mti->mti_fsname, "-client");
3364 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname, &mgi->mgi_bufs,
3365 fsdb->fsdb_clilov, ptr);
3366 name_destroy(&logname);
3370 /* All osc., mdc., llite. params in proc */
3371 if ((class_match_param(ptr, PARAM_OSC, NULL) == 0) ||
3372 (class_match_param(ptr, PARAM_MDC, NULL) == 0) ||
3373 (class_match_param(ptr, PARAM_LLITE, NULL) == 0)) {
3376 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
3377 LCONSOLE_ERROR_MSG(0x148, "Upgraded client logs for %s"
3378 " cannot be modified. Consider"
3379 " updating the configuration with"
3382 GOTO(end, rc = -EINVAL);
3384 if (memcmp(ptr, PARAM_LLITE, strlen(PARAM_LLITE)) == 0) {
3385 rc = name_create(&cname, mti->mti_fsname, "-client");
3386 /* Add the client type to match the obdname in
3387 class_config_llog_handler */
3388 } else if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
3389 rc = name_create(&cname, mti->mti_svname, "-mdc");
3390 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
3391 rc = name_create(&cname, mti->mti_svname, "-osc");
3393 GOTO(end, rc = -EINVAL);
3398 /* Forbid direct update of llite root squash parameters.
3399 * These parameters are indirectly set via the MDT settings.
3401 if ((class_match_param(ptr, PARAM_LLITE, &tmp) == 0) &&
3402 ((memcmp(tmp, "root_squash=", 12) == 0) ||
3403 (memcmp(tmp, "nosquash_nids=", 14) == 0))) {
3404 LCONSOLE_ERROR("%s: root squash parameters can only "
3405 "be updated through MDT component\n",
3407 name_destroy(&cname);
3408 GOTO(end, rc = -EINVAL);
3411 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
3414 rc = name_create(&logname, mti->mti_fsname, "-client");
3416 name_destroy(&cname);
3419 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname, &mgi->mgi_bufs,
3422 /* osc params affect the MDT as well */
3423 if (!rc && (mti->mti_flags & LDD_F_SV_TYPE_OST)) {
3426 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
3427 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
3429 name_destroy(&cname);
3430 rc = name_create_mdt_osc(&cname, mti->mti_svname,
3432 name_destroy(&logname);
3435 rc = name_create_mdt(&logname,
3436 mti->mti_fsname, i);
3439 if (!mgs_log_is_empty(env, mgs, logname)) {
3440 rc = mgs_wlp_lcfg(env, mgs, fsdb,
3449 name_destroy(&logname);
3450 name_destroy(&cname);
3454 /* All mdt. params in proc */
3455 if (class_match_param(ptr, PARAM_MDT, &tmp) == 0) {
3459 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
3460 if (strncmp(mti->mti_svname, mti->mti_fsname,
3461 MTI_NAME_MAXLEN) == 0)
3462 /* device is unspecified completely? */
3463 rc = LDD_F_SV_TYPE_MDT | LDD_F_SV_ALL;
3465 rc = server_name2index(mti->mti_svname, &idx, NULL);
3468 if ((rc & LDD_F_SV_TYPE_MDT) == 0)
3470 if (rc & LDD_F_SV_ALL) {
3471 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3473 fsdb->fsdb_mdt_index_map))
3475 rc = name_create_mdt(&logname,
3476 mti->mti_fsname, i);
3479 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti,
3480 logname, &mgi->mgi_bufs,
3482 name_destroy(&logname);
3487 if ((memcmp(tmp, "root_squash=", 12) == 0) ||
3488 (memcmp(tmp, "nosquash_nids=", 14) == 0)) {
3489 LCONSOLE_ERROR("%s: root squash parameters "
3490 "cannot be applied to a single MDT\n",
3492 GOTO(end, rc = -EINVAL);
3494 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti,
3495 mti->mti_svname, &mgi->mgi_bufs,
3496 mti->mti_svname, ptr);
3501 /* root squash settings are also applied to llite
3502 * config log (see LU-1778) */
3504 ((memcmp(tmp, "root_squash=", 12) == 0) ||
3505 (memcmp(tmp, "nosquash_nids=", 14) == 0))) {
3509 rc = name_create(&cname, mti->mti_fsname, "-client");
3512 rc = name_create(&logname, mti->mti_fsname, "-client");
3514 name_destroy(&cname);
3517 rc = name_create(&ptr2, PARAM_LLITE, tmp);
3519 name_destroy(&cname);
3520 name_destroy(&logname);
3523 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname,
3524 &mgi->mgi_bufs, cname, ptr2);
3525 name_destroy(&ptr2);
3526 name_destroy(&logname);
3527 name_destroy(&cname);
3532 /* All mdd., ost. and osd. params in proc */
3533 if ((class_match_param(ptr, PARAM_MDD, NULL) == 0) ||
3534 (class_match_param(ptr, PARAM_OST, NULL) == 0) ||
3535 (class_match_param(ptr, PARAM_OSD, NULL) == 0)) {
3536 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
3537 if (mgs_log_is_empty(env, mgs, mti->mti_svname))
3538 GOTO(end, rc = -ENODEV);
3540 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, mti->mti_svname,
3541 &mgi->mgi_bufs, mti->mti_svname, ptr);
3545 LCONSOLE_WARN("Ignoring unrecognized param '%s'\n", ptr);
3550 CERROR("err %d on param '%s'\n", rc, ptr);
3555 /* Not implementing automatic failover nid addition at this time. */
3556 int mgs_check_failnid(const struct lu_env *env, struct mgs_device *mgs,
3557 struct mgs_target_info *mti)
3564 rc = mgs_find_or_make_fsdb(obd, fsname, &fsdb);
3568 if (mgs_log_is_empty(obd, mti->mti_svname))
3569 /* should never happen */
3572 CDEBUG(D_MGS, "Checking for new failnids for %s\n", mti->mti_svname);
3574 /* FIXME We can just check mti->params to see if we're already in
3575 the failover list. Modify mti->params for rewriting back at
3576 server_register_target(). */
3578 mutex_lock(&fsdb->fsdb_mutex);
3579 rc = mgs_write_log_add_failnid(obd, fsdb, mti);
3580 mutex_unlock(&fsdb->fsdb_mutex);
3589 int mgs_write_log_target(const struct lu_env *env, struct mgs_device *mgs,
3590 struct mgs_target_info *mti, struct fs_db *fsdb)
3597 /* set/check the new target index */
3598 rc = mgs_set_index(env, mgs, mti);
3602 if (rc == EALREADY) {
3603 LCONSOLE_WARN("Found index %d for %s, updating log\n",
3604 mti->mti_stripe_index, mti->mti_svname);
3605 /* We would like to mark old log sections as invalid
3606 and add new log sections in the client and mdt logs.
3607 But if we add new sections, then live clients will
3608 get repeat setup instructions for already running
3609 osc's. So don't update the client/mdt logs. */
3610 mti->mti_flags &= ~LDD_F_UPDATE;
3614 mutex_lock(&fsdb->fsdb_mutex);
3616 if (mti->mti_flags &
3617 (LDD_F_VIRGIN | LDD_F_UPGRADE14 | LDD_F_WRITECONF)) {
3618 /* Generate a log from scratch */
3619 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
3620 rc = mgs_write_log_mdt(env, mgs, fsdb, mti);
3621 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
3622 rc = mgs_write_log_ost(env, mgs, fsdb, mti);
3624 CERROR("Unknown target type %#x, can't create log for "
3625 "%s\n", mti->mti_flags, mti->mti_svname);
3628 CERROR("Can't write logs for %s (%d)\n",
3629 mti->mti_svname, rc);
3633 /* Just update the params from tunefs in mgs_write_log_params */
3634 CDEBUG(D_MGS, "Update params for %s\n", mti->mti_svname);
3635 mti->mti_flags |= LDD_F_PARAM;
3638 /* allocate temporary buffer, where class_get_next_param will
3639 make copy of a current parameter */
3640 OBD_ALLOC(buf, strlen(mti->mti_params) + 1);
3642 GOTO(out_up, rc = -ENOMEM);
3643 params = mti->mti_params;
3644 while (params != NULL) {
3645 rc = class_get_next_param(¶ms, buf);
3648 /* there is no next parameter, that is
3653 CDEBUG(D_MGS, "remaining string: '%s', param: '%s'\n",
3655 rc = mgs_write_log_param(env, mgs, fsdb, mti, buf);
3660 OBD_FREE(buf, strlen(mti->mti_params) + 1);
3663 mutex_unlock(&fsdb->fsdb_mutex);
3667 int mgs_erase_log(const struct lu_env *env, struct mgs_device *mgs, char *name)
3669 struct llog_ctxt *ctxt;
3672 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
3674 CERROR("%s: MGS config context doesn't exist\n",
3675 mgs->mgs_obd->obd_name);
3678 rc = llog_erase(env, ctxt, NULL, name);
3679 /* llog may not exist */
3682 llog_ctxt_put(ctxt);
3686 CERROR("%s: failed to clear log %s: %d\n",
3687 mgs->mgs_obd->obd_name, name, rc);
3692 /* erase all logs for the given fs */
3693 int mgs_erase_logs(const struct lu_env *env, struct mgs_device *mgs, char *fsname)
3696 struct list_head log_list;
3697 struct mgs_direntry *dirent, *n;
3698 int rc, len = strlen(fsname);
3702 /* Find all the logs in the CONFIGS directory */
3703 rc = class_dentry_readdir(env, mgs, &log_list);
3707 mutex_lock(&mgs->mgs_mutex);
3709 /* Delete the fs db */
3710 fsdb = mgs_find_fsdb(mgs, fsname);
3712 mgs_free_fsdb(mgs, fsdb);
3714 mutex_unlock(&mgs->mgs_mutex);
3716 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
3717 list_del_init(&dirent->mde_list);
3718 suffix = strrchr(dirent->mde_name, '-');
3719 if (suffix != NULL) {
3720 if ((len == suffix - dirent->mde_name) &&
3721 (strncmp(fsname, dirent->mde_name, len) == 0)) {
3722 CDEBUG(D_MGS, "Removing log %s\n",
3724 mgs_erase_log(env, mgs, dirent->mde_name);
3727 mgs_direntry_free(dirent);
3733 /* list all logs for the given fs */
3734 int mgs_list_logs(const struct lu_env *env, struct mgs_device *mgs,
3735 struct obd_ioctl_data *data)
3737 struct list_head log_list;
3738 struct mgs_direntry *dirent, *n;
3744 /* Find all the logs in the CONFIGS directory */
3745 rc = class_dentry_readdir(env, mgs, &log_list);
3749 out = data->ioc_bulk;
3750 remains = data->ioc_inllen1;
3751 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
3752 list_del_init(&dirent->mde_list);
3753 suffix = strrchr(dirent->mde_name, '-');
3754 if (suffix != NULL) {
3755 l = snprintf(out, remains, "config log: $%s\n",
3760 mgs_direntry_free(dirent);
3767 /* from llog_swab */
3768 static void print_lustre_cfg(struct lustre_cfg *lcfg)
3773 CDEBUG(D_MGS, "lustre_cfg: %p\n", lcfg);
3774 CDEBUG(D_MGS, "\tlcfg->lcfg_version: %#x\n", lcfg->lcfg_version);
3776 CDEBUG(D_MGS, "\tlcfg->lcfg_command: %#x\n", lcfg->lcfg_command);
3777 CDEBUG(D_MGS, "\tlcfg->lcfg_num: %#x\n", lcfg->lcfg_num);
3778 CDEBUG(D_MGS, "\tlcfg->lcfg_flags: %#x\n", lcfg->lcfg_flags);
3779 CDEBUG(D_MGS, "\tlcfg->lcfg_nid: %s\n", libcfs_nid2str(lcfg->lcfg_nid));
3781 CDEBUG(D_MGS, "\tlcfg->lcfg_bufcount: %d\n", lcfg->lcfg_bufcount);
3782 if (lcfg->lcfg_bufcount < LUSTRE_CFG_MAX_BUFCOUNT)
3783 for (i = 0; i < lcfg->lcfg_bufcount; i++) {
3784 CDEBUG(D_MGS, "\tlcfg->lcfg_buflens[%d]: %d %s\n",
3785 i, lcfg->lcfg_buflens[i],
3786 lustre_cfg_string(lcfg, i));
3791 /* Setup params fsdb and log
3793 int mgs_params_fsdb_setup(const struct lu_env *env, struct mgs_device *mgs,
3796 struct llog_handle *params_llh = NULL;
3800 rc = mgs_find_or_make_fsdb(env, mgs, PARAMS_FILENAME, &fsdb);
3802 mutex_lock(&fsdb->fsdb_mutex);
3803 rc = record_start_log(env, mgs, ¶ms_llh, PARAMS_FILENAME);
3805 rc = record_end_log(env, ¶ms_llh);
3806 mutex_unlock(&fsdb->fsdb_mutex);
3812 /* Cleanup params fsdb and log
3814 int mgs_params_fsdb_cleanup(const struct lu_env *env, struct mgs_device *mgs)
3816 return mgs_erase_logs(env, mgs, PARAMS_FILENAME);
3819 /* Set a permanent (config log) param for a target or fs
3820 * \param lcfg buf0 may contain the device (testfs-MDT0000) name
3821 * buf1 contains the single parameter
3823 int mgs_setparam(const struct lu_env *env, struct mgs_device *mgs,
3824 struct lustre_cfg *lcfg, char *fsname)
3827 struct mgs_target_info *mti;
3828 char *devname, *param;
3835 print_lustre_cfg(lcfg);
3837 /* lustre, lustre-mdtlov, lustre-client, lustre-MDT0000 */
3838 devname = lustre_cfg_string(lcfg, 0);
3839 param = lustre_cfg_string(lcfg, 1);
3841 /* Assume device name embedded in param:
3842 lustre-OST0000.osc.max_dirty_mb=32 */
3843 ptr = strchr(param, '.');
3851 LCONSOLE_ERROR_MSG(0x14d, "No target specified: %s\n", param);
3855 rc = mgs_parse_devname(devname, fsname, NULL);
3856 if (rc == 0 && !mgs_parse_devname(devname, NULL, &index)) {
3857 /* param related to llite isn't allowed to set by OST or MDT */
3858 if (rc == 0 && strncmp(param, PARAM_LLITE,
3859 sizeof(PARAM_LLITE) - 1) == 0)
3862 /* assume devname is the fsname */
3863 memset(fsname, 0, MTI_NAME_MAXLEN);
3864 strncpy(fsname, devname, MTI_NAME_MAXLEN);
3865 fsname[MTI_NAME_MAXLEN - 1] = 0;
3867 CDEBUG(D_MGS, "setparam fs='%s' device='%s'\n", fsname, devname);
3869 rc = mgs_find_or_make_fsdb(env, mgs,
3870 lcfg->lcfg_command == LCFG_SET_PARAM ?
3871 PARAMS_FILENAME : fsname, &fsdb);
3875 if (lcfg->lcfg_command != LCFG_SET_PARAM &&
3876 !test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags) &&
3877 test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
3878 CERROR("No filesystem targets for %s. cfg_device from lctl "
3879 "is '%s'\n", fsname, devname);
3880 mgs_free_fsdb(mgs, fsdb);
3884 /* Create a fake mti to hold everything */
3887 GOTO(out, rc = -ENOMEM);
3888 if (strlcpy(mti->mti_fsname, fsname, sizeof(mti->mti_fsname))
3889 >= sizeof(mti->mti_fsname))
3890 GOTO(out, rc = -E2BIG);
3891 if (strlcpy(mti->mti_svname, devname, sizeof(mti->mti_svname))
3892 >= sizeof(mti->mti_svname))
3893 GOTO(out, rc = -E2BIG);
3894 if (strlcpy(mti->mti_params, param, sizeof(mti->mti_params))
3895 >= sizeof(mti->mti_params))
3896 GOTO(out, rc = -E2BIG);
3897 rc = server_name2index(mti->mti_svname, &mti->mti_stripe_index, &tmp);
3899 /* Not a valid server; may be only fsname */
3902 /* Strip -osc or -mdc suffix from svname */
3903 if (server_make_name(rc, mti->mti_stripe_index, mti->mti_fsname,
3905 GOTO(out, rc = -EINVAL);
3907 * Revoke lock so everyone updates. Should be alright if
3908 * someone was already reading while we were updating the logs,
3909 * so we don't really need to hold the lock while we're
3912 if (lcfg->lcfg_command == LCFG_SET_PARAM) {
3913 mti->mti_flags = rc | LDD_F_PARAM2;
3914 mutex_lock(&fsdb->fsdb_mutex);
3915 rc = mgs_write_log_param2(env, mgs, fsdb, mti, mti->mti_params);
3916 mutex_unlock(&fsdb->fsdb_mutex);
3917 mgs_revoke_lock(mgs, fsdb, CONFIG_T_PARAMS);
3919 mti->mti_flags = rc | LDD_F_PARAM;
3920 mutex_lock(&fsdb->fsdb_mutex);
3921 rc = mgs_write_log_param(env, mgs, fsdb, mti, mti->mti_params);
3922 mutex_unlock(&fsdb->fsdb_mutex);
3923 mgs_revoke_lock(mgs, fsdb, CONFIG_T_CONFIG);
3931 static int mgs_write_log_pool(const struct lu_env *env,
3932 struct mgs_device *mgs, char *logname,
3933 struct fs_db *fsdb, char *tgtname,
3934 enum lcfg_command_type cmd,
3935 char *fsname, char *poolname,
3936 char *ostname, char *comment)
3938 struct llog_handle *llh = NULL;
3941 rc = record_start_log(env, mgs, &llh, logname);
3944 rc = record_marker(env, llh, fsdb, CM_START, tgtname, comment);
3947 rc = record_base(env, llh, tgtname, 0, cmd,
3948 fsname, poolname, ostname, 0);
3951 rc = record_marker(env, llh, fsdb, CM_END, tgtname, comment);
3953 record_end_log(env, &llh);
3957 int mgs_nodemap_cmd(const struct lu_env *env, struct mgs_device *mgs,
3958 enum lcfg_command_type cmd, const char *nodemap_name,
3969 case LCFG_NODEMAP_ADD:
3970 rc = nodemap_add(nodemap_name);
3972 case LCFG_NODEMAP_DEL:
3973 rc = nodemap_del(nodemap_name);
3975 case LCFG_NODEMAP_ADD_RANGE:
3976 rc = nodemap_parse_range(param, nid);
3979 rc = nodemap_add_range(nodemap_name, nid);
3981 case LCFG_NODEMAP_DEL_RANGE:
3982 rc = nodemap_parse_range(param, nid);
3985 rc = nodemap_del_range(nodemap_name, nid);
3987 case LCFG_NODEMAP_ADMIN:
3988 bool_switch = simple_strtoul(param, NULL, 10);
3989 rc = nodemap_set_allow_root(nodemap_name, bool_switch);
3991 case LCFG_NODEMAP_TRUSTED:
3992 bool_switch = simple_strtoul(param, NULL, 10);
3993 rc = nodemap_set_trust_client_ids(nodemap_name, bool_switch);
3995 case LCFG_NODEMAP_SQUASH_UID:
3996 int_id = simple_strtoul(param, NULL, 10);
3997 rc = nodemap_set_squash_uid(nodemap_name, int_id);
3999 case LCFG_NODEMAP_SQUASH_GID:
4000 int_id = simple_strtoul(param, NULL, 10);
4001 rc = nodemap_set_squash_gid(nodemap_name, int_id);
4003 case LCFG_NODEMAP_ADD_UIDMAP:
4004 case LCFG_NODEMAP_ADD_GIDMAP:
4005 rc = nodemap_parse_idmap(param, idmap);
4008 if (cmd == LCFG_NODEMAP_ADD_UIDMAP)
4009 rc = nodemap_add_idmap(nodemap_name, NODEMAP_UID,
4012 rc = nodemap_add_idmap(nodemap_name, NODEMAP_GID,
4015 case LCFG_NODEMAP_DEL_UIDMAP:
4016 case LCFG_NODEMAP_DEL_GIDMAP:
4017 rc = nodemap_parse_idmap(param, idmap);
4020 if (cmd == LCFG_NODEMAP_DEL_UIDMAP)
4021 rc = nodemap_del_idmap(nodemap_name, NODEMAP_UID,
4024 rc = nodemap_del_idmap(nodemap_name, NODEMAP_GID,
4034 int mgs_pool_cmd(const struct lu_env *env, struct mgs_device *mgs,
4035 enum lcfg_command_type cmd, char *fsname,
4036 char *poolname, char *ostname)
4041 char *label = NULL, *canceled_label = NULL;
4043 struct mgs_target_info *mti = NULL;
4047 rc = mgs_find_or_make_fsdb(env, mgs, fsname, &fsdb);
4049 CERROR("Can't get db for %s\n", fsname);
4052 if (test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
4053 CERROR("%s is not defined\n", fsname);
4054 mgs_free_fsdb(mgs, fsdb);
4058 label_sz = 10 + strlen(fsname) + strlen(poolname);
4060 /* check if ostname match fsname */
4061 if (ostname != NULL) {
4064 ptr = strrchr(ostname, '-');
4065 if ((ptr == NULL) ||
4066 (strncmp(fsname, ostname, ptr-ostname) != 0))
4068 label_sz += strlen(ostname);
4071 OBD_ALLOC(label, label_sz);
4078 "new %s.%s", fsname, poolname);
4082 "add %s.%s.%s", fsname, poolname, ostname);
4085 OBD_ALLOC(canceled_label, label_sz);
4086 if (canceled_label == NULL)
4087 GOTO(out_label, rc = -ENOMEM);
4089 "rem %s.%s.%s", fsname, poolname, ostname);
4090 sprintf(canceled_label,
4091 "add %s.%s.%s", fsname, poolname, ostname);
4094 OBD_ALLOC(canceled_label, label_sz);
4095 if (canceled_label == NULL)
4096 GOTO(out_label, rc = -ENOMEM);
4098 "del %s.%s", fsname, poolname);
4099 sprintf(canceled_label,
4100 "new %s.%s", fsname, poolname);
4106 if (canceled_label != NULL) {
4109 GOTO(out_cancel, rc = -ENOMEM);
4112 mutex_lock(&fsdb->fsdb_mutex);
4113 /* write pool def to all MDT logs */
4114 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
4115 if (test_bit(i, fsdb->fsdb_mdt_index_map)) {
4116 rc = name_create_mdt_and_lov(&logname, &lovname,
4119 mutex_unlock(&fsdb->fsdb_mutex);
4122 if (canceled_label != NULL) {
4123 strcpy(mti->mti_svname, "lov pool");
4124 rc = mgs_modify(env, mgs, fsdb, mti, logname,
4125 lovname, canceled_label,
4130 rc = mgs_write_log_pool(env, mgs, logname,
4134 name_destroy(&logname);
4135 name_destroy(&lovname);
4137 mutex_unlock(&fsdb->fsdb_mutex);
4143 rc = name_create(&logname, fsname, "-client");
4145 mutex_unlock(&fsdb->fsdb_mutex);
4148 if (canceled_label != NULL) {
4149 rc = mgs_modify(env, mgs, fsdb, mti, logname,
4150 fsdb->fsdb_clilov, canceled_label, CM_SKIP);
4152 mutex_unlock(&fsdb->fsdb_mutex);
4153 name_destroy(&logname);
4158 rc = mgs_write_log_pool(env, mgs, logname, fsdb, fsdb->fsdb_clilov,
4159 cmd, fsname, poolname, ostname, label);
4160 mutex_unlock(&fsdb->fsdb_mutex);
4161 name_destroy(&logname);
4162 /* request for update */
4163 mgs_revoke_lock(mgs, fsdb, CONFIG_T_CONFIG);
4170 if (canceled_label != NULL)
4171 OBD_FREE(canceled_label, label_sz);
4173 OBD_FREE(label, label_sz);