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)
317 struct list_head *tmp;
319 list_for_each(tmp, &mgs->mgs_fs_db_list) {
320 fsdb = list_entry(tmp, struct fs_db, fsdb_list);
321 if (strcmp(fsdb->fsdb_name, fsname) == 0)
327 /* caller must hold the mgs->mgs_fs_db_lock */
328 static struct fs_db *mgs_new_fsdb(const struct lu_env *env,
329 struct mgs_device *mgs, char *fsname)
335 if (strlen(fsname) >= sizeof(fsdb->fsdb_name)) {
336 CERROR("fsname %s is too long\n", fsname);
344 strcpy(fsdb->fsdb_name, fsname);
345 mutex_init(&fsdb->fsdb_mutex);
346 set_bit(FSDB_UDESC, &fsdb->fsdb_flags);
349 if (strcmp(fsname, MGSSELF_NAME) == 0) {
350 set_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags);
352 OBD_ALLOC(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
353 OBD_ALLOC(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
354 if (!fsdb->fsdb_ost_index_map || !fsdb->fsdb_mdt_index_map) {
355 CERROR("No memory for index maps\n");
356 GOTO(err, rc = -ENOMEM);
359 rc = name_create(&fsdb->fsdb_clilov, fsname, "-clilov");
362 rc = name_create(&fsdb->fsdb_clilmv, fsname, "-clilmv");
366 /* initialise data for NID table */
367 mgs_ir_init_fs(env, mgs, fsdb);
369 lproc_mgs_add_live(mgs, fsdb);
372 list_add(&fsdb->fsdb_list, &mgs->mgs_fs_db_list);
376 if (fsdb->fsdb_ost_index_map)
377 OBD_FREE(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
378 if (fsdb->fsdb_mdt_index_map)
379 OBD_FREE(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
380 name_destroy(&fsdb->fsdb_clilov);
381 name_destroy(&fsdb->fsdb_clilmv);
386 static void mgs_free_fsdb(struct mgs_device *mgs, struct fs_db *fsdb)
388 /* wait for anyone with the sem */
389 mutex_lock(&fsdb->fsdb_mutex);
390 lproc_mgs_del_live(mgs, fsdb);
391 list_del(&fsdb->fsdb_list);
393 /* deinitialize fsr */
394 mgs_ir_fini_fs(mgs, fsdb);
396 if (fsdb->fsdb_ost_index_map)
397 OBD_FREE(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
398 if (fsdb->fsdb_mdt_index_map)
399 OBD_FREE(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
400 name_destroy(&fsdb->fsdb_clilov);
401 name_destroy(&fsdb->fsdb_clilmv);
402 mgs_free_fsdb_srpc(fsdb);
403 mutex_unlock(&fsdb->fsdb_mutex);
407 int mgs_init_fsdb_list(struct mgs_device *mgs)
409 INIT_LIST_HEAD(&mgs->mgs_fs_db_list);
413 int mgs_cleanup_fsdb_list(struct mgs_device *mgs)
416 struct list_head *tmp, *tmp2;
418 mutex_lock(&mgs->mgs_mutex);
419 list_for_each_safe(tmp, tmp2, &mgs->mgs_fs_db_list) {
420 fsdb = list_entry(tmp, struct fs_db, fsdb_list);
421 mgs_free_fsdb(mgs, fsdb);
423 mutex_unlock(&mgs->mgs_mutex);
427 int mgs_find_or_make_fsdb(const struct lu_env *env,
428 struct mgs_device *mgs, char *name,
435 mutex_lock(&mgs->mgs_mutex);
436 fsdb = mgs_find_fsdb(mgs, name);
438 mutex_unlock(&mgs->mgs_mutex);
443 CDEBUG(D_MGS, "Creating new db\n");
444 fsdb = mgs_new_fsdb(env, mgs, name);
445 /* lock fsdb_mutex until the db is loaded from llogs */
447 mutex_lock(&fsdb->fsdb_mutex);
448 mutex_unlock(&mgs->mgs_mutex);
452 if (!test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
453 /* populate the db from the client llog */
454 rc = mgs_get_fsdb_from_llog(env, mgs, fsdb);
456 CERROR("Can't get db from client log %d\n", rc);
461 /* populate srpc rules from params llog */
462 rc = mgs_get_fsdb_srpc_from_llog(env, mgs, fsdb);
464 CERROR("Can't get db from params log %d\n", rc);
468 mutex_unlock(&fsdb->fsdb_mutex);
474 mutex_unlock(&fsdb->fsdb_mutex);
475 mgs_free_fsdb(mgs, fsdb);
481 -1= empty client log */
482 int mgs_check_index(const struct lu_env *env,
483 struct mgs_device *mgs,
484 struct mgs_target_info *mti)
491 LASSERT(!(mti->mti_flags & LDD_F_NEED_INDEX));
493 rc = mgs_find_or_make_fsdb(env, mgs, mti->mti_fsname, &fsdb);
495 CERROR("Can't get db for %s\n", mti->mti_fsname);
499 if (test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags))
502 if (mti->mti_flags & LDD_F_SV_TYPE_OST)
503 imap = fsdb->fsdb_ost_index_map;
504 else if (mti->mti_flags & LDD_F_SV_TYPE_MDT)
505 imap = fsdb->fsdb_mdt_index_map;
509 if (test_bit(mti->mti_stripe_index, imap))
514 static __inline__ int next_index(void *index_map, int map_len)
517 for (i = 0; i < map_len * 8; i++)
518 if (!test_bit(i, index_map)) {
521 CERROR("max index %d exceeded.\n", i);
526 0 newly marked as in use
528 +EALREADY for update of an old index */
529 static int mgs_set_index(const struct lu_env *env,
530 struct mgs_device *mgs,
531 struct mgs_target_info *mti)
538 rc = mgs_find_or_make_fsdb(env, mgs, mti->mti_fsname, &fsdb);
540 CERROR("Can't get db for %s\n", mti->mti_fsname);
544 mutex_lock(&fsdb->fsdb_mutex);
545 if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
546 imap = fsdb->fsdb_ost_index_map;
547 } else if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
548 imap = fsdb->fsdb_mdt_index_map;
550 GOTO(out_up, rc = -EINVAL);
553 if (mti->mti_flags & LDD_F_NEED_INDEX) {
554 rc = next_index(imap, INDEX_MAP_SIZE);
556 GOTO(out_up, rc = -ERANGE);
557 mti->mti_stripe_index = rc;
558 if (mti->mti_flags & LDD_F_SV_TYPE_MDT)
559 fsdb->fsdb_mdt_count ++;
562 if (mti->mti_stripe_index >= INDEX_MAP_SIZE * 8) {
563 LCONSOLE_ERROR_MSG(0x13f, "Server %s requested index %d, "
564 "but the max index is %d.\n",
565 mti->mti_svname, mti->mti_stripe_index,
567 GOTO(out_up, rc = -ERANGE);
570 if (test_bit(mti->mti_stripe_index, imap)) {
571 if ((mti->mti_flags & LDD_F_VIRGIN) &&
572 !(mti->mti_flags & LDD_F_WRITECONF)) {
573 LCONSOLE_ERROR_MSG(0x140, "Server %s requested index "
574 "%d, but that index is already in "
575 "use. Use --writeconf to force\n",
577 mti->mti_stripe_index);
578 GOTO(out_up, rc = -EADDRINUSE);
580 CDEBUG(D_MGS, "Server %s updating index %d\n",
581 mti->mti_svname, mti->mti_stripe_index);
582 GOTO(out_up, rc = EALREADY);
586 set_bit(mti->mti_stripe_index, imap);
587 clear_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags);
588 mutex_unlock(&fsdb->fsdb_mutex);
589 server_make_name(mti->mti_flags & ~(LDD_F_VIRGIN | LDD_F_WRITECONF),
590 mti->mti_stripe_index, mti->mti_fsname, mti->mti_svname);
592 CDEBUG(D_MGS, "Set index for %s to %d\n", mti->mti_svname,
593 mti->mti_stripe_index);
597 mutex_unlock(&fsdb->fsdb_mutex);
601 struct mgs_modify_lookup {
602 struct cfg_marker mml_marker;
606 static int mgs_modify_handler(const struct lu_env *env,
607 struct llog_handle *llh,
608 struct llog_rec_hdr *rec, void *data)
610 struct mgs_modify_lookup *mml = data;
611 struct cfg_marker *marker;
612 struct lustre_cfg *lcfg = REC_DATA(rec);
613 int cfg_len = REC_DATA_LEN(rec);
617 if (rec->lrh_type != OBD_CFG_REC) {
618 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
622 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
624 CERROR("Insane cfg\n");
628 /* We only care about markers */
629 if (lcfg->lcfg_command != LCFG_MARKER)
632 marker = lustre_cfg_buf(lcfg, 1);
633 if ((strcmp(mml->mml_marker.cm_comment, marker->cm_comment) == 0) &&
634 (strcmp(mml->mml_marker.cm_tgtname, marker->cm_tgtname) == 0) &&
635 !(marker->cm_flags & CM_SKIP)) {
636 /* Found a non-skipped marker match */
637 CDEBUG(D_MGS, "Changing rec %u marker %d %x->%x: %s %s\n",
638 rec->lrh_index, marker->cm_step,
639 marker->cm_flags, mml->mml_marker.cm_flags,
640 marker->cm_tgtname, marker->cm_comment);
641 /* Overwrite the old marker llog entry */
642 marker->cm_flags &= ~CM_EXCLUDE; /* in case we're unexcluding */
643 marker->cm_flags |= mml->mml_marker.cm_flags;
644 marker->cm_canceltime = mml->mml_marker.cm_canceltime;
645 rc = llog_write(env, llh, rec, rec->lrh_index);
654 * Modify an existing config log record (for CM_SKIP or CM_EXCLUDE)
656 * 0 - modified successfully,
657 * 1 - no modification was done
660 static int mgs_modify(const struct lu_env *env, struct mgs_device *mgs,
661 struct fs_db *fsdb, struct mgs_target_info *mti,
662 char *logname, char *devname, char *comment, int flags)
664 struct llog_handle *loghandle;
665 struct llog_ctxt *ctxt;
666 struct mgs_modify_lookup *mml;
671 LASSERT(mutex_is_locked(&fsdb->fsdb_mutex));
672 CDEBUG(D_MGS, "modify %s/%s/%s fl=%x\n", logname, devname, comment,
675 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
676 LASSERT(ctxt != NULL);
677 rc = llog_open(env, ctxt, &loghandle, NULL, logname, LLOG_OPEN_EXISTS);
684 rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL);
688 if (llog_get_size(loghandle) <= 1)
689 GOTO(out_close, rc = 0);
693 GOTO(out_close, rc = -ENOMEM);
694 if (strlcpy(mml->mml_marker.cm_comment, comment,
695 sizeof(mml->mml_marker.cm_comment)) >=
696 sizeof(mml->mml_marker.cm_comment))
697 GOTO(out_free, rc = -E2BIG);
698 if (strlcpy(mml->mml_marker.cm_tgtname, devname,
699 sizeof(mml->mml_marker.cm_tgtname)) >=
700 sizeof(mml->mml_marker.cm_tgtname))
701 GOTO(out_free, rc = -E2BIG);
702 /* Modify mostly means cancel */
703 mml->mml_marker.cm_flags = flags;
704 mml->mml_marker.cm_canceltime = flags ? cfs_time_current_sec() : 0;
705 mml->mml_modified = 0;
706 rc = llog_process(env, loghandle, mgs_modify_handler, (void *)mml,
708 if (!rc && !mml->mml_modified)
715 llog_close(env, loghandle);
718 CERROR("%s: modify %s/%s failed: rc = %d\n",
719 mgs->mgs_obd->obd_name, mti->mti_svname, comment, rc);
724 /** This structure is passed to mgs_replace_handler */
725 struct mgs_replace_uuid_lookup {
726 /* Nids are replaced for this target device */
727 struct mgs_target_info target;
728 /* Temporary modified llog */
729 struct llog_handle *temp_llh;
730 /* Flag is set if in target block*/
731 int in_target_device;
732 /* Nids already added. Just skip (multiple nids) */
733 int device_nids_added;
734 /* Flag is set if this block should not be copied */
739 * Check: a) if block should be skipped
740 * b) is it target block
745 * \retval 0 should not to be skipped
746 * \retval 1 should to be skipped
748 static int check_markers(struct lustre_cfg *lcfg,
749 struct mgs_replace_uuid_lookup *mrul)
751 struct cfg_marker *marker;
753 /* Track markers. Find given device */
754 if (lcfg->lcfg_command == LCFG_MARKER) {
755 marker = lustre_cfg_buf(lcfg, 1);
756 /* Clean llog from records marked as CM_EXCLUDE.
757 CM_SKIP records are used for "active" command
758 and can be restored if needed */
759 if ((marker->cm_flags & (CM_EXCLUDE | CM_START)) ==
760 (CM_EXCLUDE | CM_START)) {
765 if ((marker->cm_flags & (CM_EXCLUDE | CM_END)) ==
766 (CM_EXCLUDE | CM_END)) {
771 if (strcmp(mrul->target.mti_svname, marker->cm_tgtname) == 0) {
772 LASSERT(!(marker->cm_flags & CM_START) ||
773 !(marker->cm_flags & CM_END));
774 if (marker->cm_flags & CM_START) {
775 mrul->in_target_device = 1;
776 mrul->device_nids_added = 0;
777 } else if (marker->cm_flags & CM_END)
778 mrul->in_target_device = 0;
785 static int record_base(const struct lu_env *env, struct llog_handle *llh,
786 char *cfgname, lnet_nid_t nid, int cmd,
787 char *s1, char *s2, char *s3, char *s4)
789 struct mgs_thread_info *mgi = mgs_env_info(env);
790 struct llog_cfg_rec *lcr;
793 CDEBUG(D_MGS, "lcfg %s %#x %s %s %s %s\n", cfgname,
794 cmd, s1, s2, s3, s4);
796 lustre_cfg_bufs_reset(&mgi->mgi_bufs, cfgname);
798 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, s1);
800 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 2, s2);
802 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 3, s3);
804 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 4, s4);
806 lcr = lustre_cfg_rec_new(cmd, &mgi->mgi_bufs);
810 lcr->lcr_cfg.lcfg_nid = nid;
811 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
813 lustre_cfg_rec_free(lcr);
817 "failed to write lcfg %s %#x %s %s %s %s: rc = %d\n",
818 cfgname, cmd, s1, s2, s3, s4, rc);
822 static inline int record_add_uuid(const struct lu_env *env,
823 struct llog_handle *llh,
824 uint64_t nid, char *uuid)
826 return record_base(env, llh, NULL, nid, LCFG_ADD_UUID, uuid, 0, 0, 0);
829 static inline int record_add_conn(const struct lu_env *env,
830 struct llog_handle *llh,
831 char *devname, char *uuid)
833 return record_base(env, llh, devname, 0, LCFG_ADD_CONN, uuid, 0, 0, 0);
836 static inline int record_attach(const struct lu_env *env,
837 struct llog_handle *llh, char *devname,
838 char *type, char *uuid)
840 return record_base(env, llh,devname, 0, LCFG_ATTACH, type, uuid, 0, 0);
843 static inline int record_setup(const struct lu_env *env,
844 struct llog_handle *llh, char *devname,
845 char *s1, char *s2, char *s3, char *s4)
847 return record_base(env, llh, devname, 0, LCFG_SETUP, s1, s2, s3, s4);
851 * \retval <0 record processing error
852 * \retval n record is processed. No need copy original one.
853 * \retval 0 record is not processed.
855 static int process_command(const struct lu_env *env, struct lustre_cfg *lcfg,
856 struct mgs_replace_uuid_lookup *mrul)
863 if (lcfg->lcfg_command == LCFG_ADD_UUID) {
864 /* LCFG_ADD_UUID command found. Let's skip original command
865 and add passed nids */
866 ptr = mrul->target.mti_params;
867 while (class_parse_nid(ptr, &nid, &ptr) == 0) {
868 CDEBUG(D_MGS, "add nid %s with uuid %s, "
869 "device %s\n", libcfs_nid2str(nid),
870 mrul->target.mti_params,
871 mrul->target.mti_svname);
872 rc = record_add_uuid(env,
874 mrul->target.mti_params);
879 if (nids_added == 0) {
880 CERROR("No new nids were added, nid %s with uuid %s, "
881 "device %s\n", libcfs_nid2str(nid),
882 mrul->target.mti_params,
883 mrul->target.mti_svname);
886 mrul->device_nids_added = 1;
892 if (mrul->device_nids_added && lcfg->lcfg_command == LCFG_SETUP) {
893 /* LCFG_SETUP command found. UUID should be changed */
894 rc = record_setup(env,
896 /* devname the same */
897 lustre_cfg_string(lcfg, 0),
898 /* s1 is not changed */
899 lustre_cfg_string(lcfg, 1),
900 /* new uuid should be
902 mrul->target.mti_params,
903 /* s3 is not changed */
904 lustre_cfg_string(lcfg, 3),
905 /* s4 is not changed */
906 lustre_cfg_string(lcfg, 4));
910 /* Another commands in target device block */
915 * Handler that called for every record in llog.
916 * Records are processed in order they placed in llog.
918 * \param[in] llh log to be processed
919 * \param[in] rec current record
920 * \param[in] data mgs_replace_uuid_lookup structure
924 static int mgs_replace_handler(const struct lu_env *env,
925 struct llog_handle *llh,
926 struct llog_rec_hdr *rec,
929 struct mgs_replace_uuid_lookup *mrul;
930 struct lustre_cfg *lcfg = REC_DATA(rec);
931 int cfg_len = REC_DATA_LEN(rec);
935 mrul = (struct mgs_replace_uuid_lookup *)data;
937 if (rec->lrh_type != OBD_CFG_REC) {
938 CERROR("unhandled lrh_type: %#x, cmd %x %s %s\n",
939 rec->lrh_type, lcfg->lcfg_command,
940 lustre_cfg_string(lcfg, 0),
941 lustre_cfg_string(lcfg, 1));
945 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
947 /* Do not copy any invalidated records */
948 GOTO(skip_out, rc = 0);
951 rc = check_markers(lcfg, mrul);
952 if (rc || mrul->skip_it)
953 GOTO(skip_out, rc = 0);
955 /* Write to new log all commands outside target device block */
956 if (!mrul->in_target_device)
957 GOTO(copy_out, rc = 0);
959 /* Skip all other LCFG_ADD_UUID and LCFG_ADD_CONN records
960 (failover nids) for this target, assuming that if then
961 primary is changing then so is the failover */
962 if (mrul->device_nids_added &&
963 (lcfg->lcfg_command == LCFG_ADD_UUID ||
964 lcfg->lcfg_command == LCFG_ADD_CONN))
965 GOTO(skip_out, rc = 0);
967 rc = process_command(env, lcfg, mrul);
974 /* Record is placed in temporary llog as is */
975 rc = llog_write(env, mrul->temp_llh, rec, LLOG_NEXT_IDX);
977 CDEBUG(D_MGS, "Copied idx=%d, rc=%d, len=%d, cmd %x %s %s\n",
978 rec->lrh_index, rc, rec->lrh_len, lcfg->lcfg_command,
979 lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));
983 CDEBUG(D_MGS, "Skipped idx=%d, rc=%d, len=%d, cmd %x %s %s\n",
984 rec->lrh_index, rc, rec->lrh_len, lcfg->lcfg_command,
985 lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));
989 static int mgs_log_is_empty(const struct lu_env *env,
990 struct mgs_device *mgs, char *name)
992 struct llog_ctxt *ctxt;
995 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
996 LASSERT(ctxt != NULL);
998 rc = llog_is_empty(env, ctxt, name);
1003 static int mgs_replace_nids_log(const struct lu_env *env,
1004 struct obd_device *mgs, struct fs_db *fsdb,
1005 char *logname, char *devname, char *nids)
1007 struct llog_handle *orig_llh, *backup_llh;
1008 struct llog_ctxt *ctxt;
1009 struct mgs_replace_uuid_lookup *mrul;
1010 struct mgs_device *mgs_dev = lu2mgs_dev(mgs->obd_lu_dev);
1011 static struct obd_uuid cfg_uuid = { .uuid = "config_uuid" };
1016 CDEBUG(D_MGS, "Replace nids for %s in %s\n", devname, logname);
1018 ctxt = llog_get_context(mgs, LLOG_CONFIG_ORIG_CTXT);
1019 LASSERT(ctxt != NULL);
1021 if (mgs_log_is_empty(env, mgs_dev, logname)) {
1022 /* Log is empty. Nothing to replace */
1023 GOTO(out_put, rc = 0);
1026 OBD_ALLOC(backup, strlen(logname) + strlen(".bak") + 1);
1028 GOTO(out_put, rc = -ENOMEM);
1030 sprintf(backup, "%s.bak", logname);
1032 rc = llog_backup(env, mgs, ctxt, ctxt, logname, backup);
1034 /* Now erase original log file. Connections are not allowed.
1035 Backup is already saved */
1036 rc = llog_erase(env, ctxt, NULL, logname);
1039 } else if (rc != -ENOENT) {
1040 CERROR("%s: can't make backup for %s: rc = %d\n",
1041 mgs->obd_name, logname, rc);
1045 /* open local log */
1046 rc = llog_open_create(env, ctxt, &orig_llh, NULL, logname);
1048 GOTO(out_restore, rc);
1050 rc = llog_init_handle(env, orig_llh, LLOG_F_IS_PLAIN, &cfg_uuid);
1052 GOTO(out_closel, rc);
1054 /* open backup llog */
1055 rc = llog_open(env, ctxt, &backup_llh, NULL, backup,
1058 GOTO(out_closel, rc);
1060 rc = llog_init_handle(env, backup_llh, LLOG_F_IS_PLAIN, NULL);
1062 GOTO(out_close, rc);
1064 if (llog_get_size(backup_llh) <= 1)
1065 GOTO(out_close, rc = 0);
1067 OBD_ALLOC_PTR(mrul);
1069 GOTO(out_close, rc = -ENOMEM);
1070 /* devname is only needed information to replace UUID records */
1071 strncpy(mrul->target.mti_svname, devname, MTI_NAME_MAXLEN);
1072 /* parse nids later */
1073 strncpy(mrul->target.mti_params, nids, MTI_PARAM_MAXLEN);
1074 /* Copy records to this temporary llog */
1075 mrul->temp_llh = orig_llh;
1077 rc = llog_process(env, backup_llh, mgs_replace_handler,
1078 (void *)mrul, NULL);
1081 rc2 = llog_close(NULL, backup_llh);
1085 rc2 = llog_close(NULL, orig_llh);
1091 CERROR("%s: llog should be restored: rc = %d\n",
1093 rc2 = llog_backup(env, mgs, ctxt, ctxt, backup,
1096 CERROR("%s: can't restore backup %s: rc = %d\n",
1097 mgs->obd_name, logname, rc2);
1101 OBD_FREE(backup, strlen(backup) + 1);
1104 llog_ctxt_put(ctxt);
1107 CERROR("%s: failed to replace nids in log %s: rc = %d\n",
1108 mgs->obd_name, logname, rc);
1114 * Parse device name and get file system name and/or device index
1116 * \param[in] devname device name (ex. lustre-MDT0000)
1117 * \param[out] fsname file system name(optional)
1118 * \param[out] index device index(optional)
1122 static int mgs_parse_devname(char *devname, char *fsname, __u32 *index)
1127 /* Extract fsname */
1129 rc = server_name2fsname(devname, fsname, NULL);
1131 CDEBUG(D_MGS, "Device name %s without fsname\n",
1138 rc = server_name2index(devname, index, NULL);
1140 CDEBUG(D_MGS, "Device name %s with wrong index\n",
1149 /* This is only called during replace_nids */
1150 static int only_mgs_is_running(struct obd_device *mgs_obd)
1152 /* TDB: Is global variable with devices count exists? */
1153 int num_devices = get_devices_count();
1154 int num_exports = 0;
1155 struct obd_export *exp;
1157 spin_lock(&mgs_obd->obd_dev_lock);
1158 list_for_each_entry(exp, &mgs_obd->obd_exports, exp_obd_chain) {
1159 /* skip self export */
1160 if (exp == mgs_obd->obd_self_export)
1162 if (exp_connect_flags(exp) & OBD_CONNECT_MDS_MDS)
1167 CERROR("%s: node %s still connected during replace_nids "
1168 "connect_flags:%llx\n",
1170 libcfs_nid2str(exp->exp_nid_stats->nid),
1171 exp_connect_flags(exp));
1174 spin_unlock(&mgs_obd->obd_dev_lock);
1176 /* osd, MGS and MGC + self_export
1177 (wc -l /proc/fs/lustre/devices <= 2) && (non self exports == 0) */
1178 return (num_devices <= 3) && (num_exports == 0);
1181 static int name_create_mdt(char **logname, char *fsname, int i)
1185 sprintf(mdt_index, "-MDT%04x", i);
1186 return name_create(logname, fsname, mdt_index);
1190 * Replace nids for \a device to \a nids values
1192 * \param obd MGS obd device
1193 * \param devname nids need to be replaced for this device
1194 * (ex. lustre-OST0000)
1195 * \param nids nids list (ex. nid1,nid2,nid3)
1199 int mgs_replace_nids(const struct lu_env *env,
1200 struct mgs_device *mgs,
1201 char *devname, char *nids)
1203 /* Assume fsname is part of device name */
1204 char fsname[MTI_NAME_MAXLEN];
1211 struct obd_device *mgs_obd = mgs->mgs_obd;
1214 /* We can only change NIDs if no other nodes are connected */
1215 spin_lock(&mgs_obd->obd_dev_lock);
1216 conn_state = mgs_obd->obd_no_conn;
1217 mgs_obd->obd_no_conn = 1;
1218 spin_unlock(&mgs_obd->obd_dev_lock);
1220 /* We can not change nids if not only MGS is started */
1221 if (!only_mgs_is_running(mgs_obd)) {
1222 CERROR("Only MGS is allowed to be started\n");
1223 GOTO(out, rc = -EINPROGRESS);
1226 /* Get fsname and index*/
1227 rc = mgs_parse_devname(devname, fsname, &index);
1231 rc = mgs_find_or_make_fsdb(env, mgs, fsname, &fsdb);
1233 CERROR("%s: can't find fsdb: rc = %d\n", fsname, rc);
1237 /* Process client llogs */
1238 name_create(&logname, fsname, "-client");
1239 rc = mgs_replace_nids_log(env, mgs_obd, fsdb, logname, devname, nids);
1240 name_destroy(&logname);
1242 CERROR("%s: error while replacing NIDs for %s: rc = %d\n",
1243 fsname, devname, rc);
1247 /* Process MDT llogs */
1248 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
1249 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
1251 name_create_mdt(&logname, fsname, i);
1252 rc = mgs_replace_nids_log(env, mgs_obd, fsdb, logname, devname, nids);
1253 name_destroy(&logname);
1259 spin_lock(&mgs_obd->obd_dev_lock);
1260 mgs_obd->obd_no_conn = conn_state;
1261 spin_unlock(&mgs_obd->obd_dev_lock);
1266 static int record_lov_setup(const struct lu_env *env, struct llog_handle *llh,
1267 char *devname, struct lov_desc *desc)
1269 struct mgs_thread_info *mgi = mgs_env_info(env);
1270 struct llog_cfg_rec *lcr;
1273 lustre_cfg_bufs_reset(&mgi->mgi_bufs, devname);
1274 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, desc, sizeof(*desc));
1275 lcr = lustre_cfg_rec_new(LCFG_SETUP, &mgi->mgi_bufs);
1279 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1280 lustre_cfg_rec_free(lcr);
1284 static int record_lmv_setup(const struct lu_env *env, struct llog_handle *llh,
1285 char *devname, struct lmv_desc *desc)
1287 struct mgs_thread_info *mgi = mgs_env_info(env);
1288 struct llog_cfg_rec *lcr;
1291 lustre_cfg_bufs_reset(&mgi->mgi_bufs, devname);
1292 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, desc, sizeof(*desc));
1293 lcr = lustre_cfg_rec_new(LCFG_SETUP, &mgi->mgi_bufs);
1297 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1298 lustre_cfg_rec_free(lcr);
1302 static inline int record_mdc_add(const struct lu_env *env,
1303 struct llog_handle *llh,
1304 char *logname, char *mdcuuid,
1305 char *mdtuuid, char *index,
1308 return record_base(env,llh,logname,0,LCFG_ADD_MDC,
1309 mdtuuid,index,gen,mdcuuid);
1312 static inline int record_lov_add(const struct lu_env *env,
1313 struct llog_handle *llh,
1314 char *lov_name, char *ost_uuid,
1315 char *index, char *gen)
1317 return record_base(env,llh,lov_name,0,LCFG_LOV_ADD_OBD,
1318 ost_uuid, index, gen, 0);
1321 static inline int record_mount_opt(const struct lu_env *env,
1322 struct llog_handle *llh,
1323 char *profile, char *lov_name,
1326 return record_base(env,llh,NULL,0,LCFG_MOUNTOPT,
1327 profile,lov_name,mdc_name,0);
1330 static int record_marker(const struct lu_env *env,
1331 struct llog_handle *llh,
1332 struct fs_db *fsdb, __u32 flags,
1333 char *tgtname, char *comment)
1335 struct mgs_thread_info *mgi = mgs_env_info(env);
1336 struct llog_cfg_rec *lcr;
1340 if (flags & CM_START)
1342 mgi->mgi_marker.cm_step = fsdb->fsdb_gen;
1343 mgi->mgi_marker.cm_flags = flags;
1344 mgi->mgi_marker.cm_vers = LUSTRE_VERSION_CODE;
1345 cplen = strlcpy(mgi->mgi_marker.cm_tgtname, tgtname,
1346 sizeof(mgi->mgi_marker.cm_tgtname));
1347 if (cplen >= sizeof(mgi->mgi_marker.cm_tgtname))
1349 cplen = strlcpy(mgi->mgi_marker.cm_comment, comment,
1350 sizeof(mgi->mgi_marker.cm_comment));
1351 if (cplen >= sizeof(mgi->mgi_marker.cm_comment))
1353 mgi->mgi_marker.cm_createtime = cfs_time_current_sec();
1354 mgi->mgi_marker.cm_canceltime = 0;
1355 lustre_cfg_bufs_reset(&mgi->mgi_bufs, NULL);
1356 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, &mgi->mgi_marker,
1357 sizeof(mgi->mgi_marker));
1358 lcr = lustre_cfg_rec_new(LCFG_MARKER, &mgi->mgi_bufs);
1362 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1363 lustre_cfg_rec_free(lcr);
1367 static int record_start_log(const struct lu_env *env, struct mgs_device *mgs,
1368 struct llog_handle **llh, char *name)
1370 static struct obd_uuid cfg_uuid = { .uuid = "config_uuid" };
1371 struct llog_ctxt *ctxt;
1376 GOTO(out, rc = -EBUSY);
1378 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
1380 GOTO(out, rc = -ENODEV);
1381 LASSERT(ctxt->loc_obd == mgs->mgs_obd);
1383 rc = llog_open_create(env, ctxt, llh, NULL, name);
1386 rc = llog_init_handle(env, *llh, LLOG_F_IS_PLAIN, &cfg_uuid);
1388 llog_close(env, *llh);
1390 llog_ctxt_put(ctxt);
1393 CERROR("%s: can't start log %s: rc = %d\n",
1394 mgs->mgs_obd->obd_name, name, rc);
1400 static int record_end_log(const struct lu_env *env, struct llog_handle **llh)
1404 rc = llog_close(env, *llh);
1410 /******************** config "macros" *********************/
1412 /* write an lcfg directly into a log (with markers) */
1413 static int mgs_write_log_direct(const struct lu_env *env,
1414 struct mgs_device *mgs, struct fs_db *fsdb,
1415 char *logname, struct llog_cfg_rec *lcr,
1416 char *devname, char *comment)
1418 struct llog_handle *llh = NULL;
1423 rc = record_start_log(env, mgs, &llh, logname);
1427 /* FIXME These should be a single journal transaction */
1428 rc = record_marker(env, llh, fsdb, CM_START, devname, comment);
1431 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1434 rc = record_marker(env, llh, fsdb, CM_END, devname, comment);
1438 record_end_log(env, &llh);
1442 /* write the lcfg in all logs for the given fs */
1443 int mgs_write_log_direct_all(const struct lu_env *env, struct mgs_device *mgs,
1444 struct fs_db *fsdb, struct mgs_target_info *mti,
1445 struct llog_cfg_rec *lcr, char *devname,
1446 char *comment, int server_only)
1448 struct list_head log_list;
1449 struct mgs_direntry *dirent, *n;
1450 char *fsname = mti->mti_fsname;
1451 int rc = 0, len = strlen(fsname);
1454 /* Find all the logs in the CONFIGS directory */
1455 rc = class_dentry_readdir(env, mgs, &log_list);
1459 /* Could use fsdb index maps instead of directory listing */
1460 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
1461 list_del_init(&dirent->mde_list);
1462 /* don't write to sptlrpc rule log */
1463 if (strstr(dirent->mde_name, "-sptlrpc") != NULL)
1466 /* caller wants write server logs only */
1467 if (server_only && strstr(dirent->mde_name, "-client") != NULL)
1470 if (strncmp(fsname, dirent->mde_name, len) != 0)
1473 CDEBUG(D_MGS, "Changing log %s\n", dirent->mde_name);
1474 /* Erase any old settings of this same parameter */
1475 rc = mgs_modify(env, mgs, fsdb, mti, dirent->mde_name,
1476 devname, comment, CM_SKIP);
1478 CERROR("%s: Can't modify llog %s: rc = %d\n",
1479 mgs->mgs_obd->obd_name, dirent->mde_name, rc);
1482 /* Write the new one */
1483 rc = mgs_write_log_direct(env, mgs, fsdb, dirent->mde_name,
1484 lcr, devname, comment);
1486 CERROR("%s: writing log %s: rc = %d\n",
1487 mgs->mgs_obd->obd_name, dirent->mde_name, rc);
1489 mgs_direntry_free(dirent);
1495 static int mgs_write_log_osp_to_mdt(const struct lu_env *env,
1496 struct mgs_device *mgs,
1498 struct mgs_target_info *mti,
1499 int index, char *logname);
1500 static int mgs_write_log_osc_to_lov(const struct lu_env *env,
1501 struct mgs_device *mgs,
1503 struct mgs_target_info *mti,
1504 char *logname, char *suffix, char *lovname,
1505 enum lustre_sec_part sec_part, int flags);
1506 static int name_create_mdt_and_lov(char **logname, char **lovname,
1507 struct fs_db *fsdb, int i);
1509 static int add_param(char *params, char *key, char *val)
1511 char *start = params + strlen(params);
1512 char *end = params + sizeof(((struct mgs_target_info *)0)->mti_params);
1516 keylen = strlen(key);
1517 if (start + 1 + keylen + strlen(val) >= end) {
1518 CERROR("params are too long: %s %s%s\n",
1519 params, key != NULL ? key : "", val);
1523 sprintf(start, " %s%s", key != NULL ? key : "", val);
1528 * Walk through client config log record and convert the related records
1531 static int mgs_steal_client_llog_handler(const struct lu_env *env,
1532 struct llog_handle *llh,
1533 struct llog_rec_hdr *rec, void *data)
1535 struct mgs_device *mgs;
1536 struct obd_device *obd;
1537 struct mgs_target_info *mti, *tmti;
1539 int cfg_len = rec->lrh_len;
1540 char *cfg_buf = (char*) (rec + 1);
1541 struct lustre_cfg *lcfg;
1543 struct llog_handle *mdt_llh = NULL;
1544 static int got_an_osc_or_mdc = 0;
1545 /* 0: not found any osc/mdc;
1549 static int last_step = -1;
1554 mti = ((struct temp_comp*)data)->comp_mti;
1555 tmti = ((struct temp_comp*)data)->comp_tmti;
1556 fsdb = ((struct temp_comp*)data)->comp_fsdb;
1557 obd = ((struct temp_comp *)data)->comp_obd;
1558 mgs = lu2mgs_dev(obd->obd_lu_dev);
1561 if (rec->lrh_type != OBD_CFG_REC) {
1562 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
1566 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
1568 CERROR("Insane cfg\n");
1572 lcfg = (struct lustre_cfg *)cfg_buf;
1574 if (lcfg->lcfg_command == LCFG_MARKER) {
1575 struct cfg_marker *marker;
1576 marker = lustre_cfg_buf(lcfg, 1);
1577 if (!strncmp(marker->cm_comment, "add osc", 7) &&
1578 (marker->cm_flags & CM_START) &&
1579 !(marker->cm_flags & CM_SKIP)) {
1580 got_an_osc_or_mdc = 1;
1581 cplen = strlcpy(tmti->mti_svname, marker->cm_tgtname,
1582 sizeof(tmti->mti_svname));
1583 if (cplen >= sizeof(tmti->mti_svname))
1585 rc = record_start_log(env, mgs, &mdt_llh,
1589 rc = record_marker(env, mdt_llh, fsdb, CM_START,
1590 mti->mti_svname, "add osc(copied)");
1591 record_end_log(env, &mdt_llh);
1592 last_step = marker->cm_step;
1595 if (!strncmp(marker->cm_comment, "add osc", 7) &&
1596 (marker->cm_flags & CM_END) &&
1597 !(marker->cm_flags & CM_SKIP)) {
1598 LASSERT(last_step == marker->cm_step);
1600 got_an_osc_or_mdc = 0;
1601 memset(tmti, 0, sizeof(*tmti));
1602 rc = record_start_log(env, mgs, &mdt_llh,
1606 rc = record_marker(env, mdt_llh, fsdb, CM_END,
1607 mti->mti_svname, "add osc(copied)");
1608 record_end_log(env, &mdt_llh);
1611 if (!strncmp(marker->cm_comment, "add mdc", 7) &&
1612 (marker->cm_flags & CM_START) &&
1613 !(marker->cm_flags & CM_SKIP)) {
1614 got_an_osc_or_mdc = 2;
1615 last_step = marker->cm_step;
1616 memcpy(tmti->mti_svname, marker->cm_tgtname,
1617 strlen(marker->cm_tgtname));
1621 if (!strncmp(marker->cm_comment, "add mdc", 7) &&
1622 (marker->cm_flags & CM_END) &&
1623 !(marker->cm_flags & CM_SKIP)) {
1624 LASSERT(last_step == marker->cm_step);
1626 got_an_osc_or_mdc = 0;
1627 memset(tmti, 0, sizeof(*tmti));
1632 if (got_an_osc_or_mdc == 0 || last_step < 0)
1635 if (lcfg->lcfg_command == LCFG_ADD_UUID) {
1636 uint64_t nodenid = lcfg->lcfg_nid;
1638 if (strlen(tmti->mti_uuid) == 0) {
1639 /* target uuid not set, this config record is before
1640 * LCFG_SETUP, this nid is one of target node nid.
1642 tmti->mti_nids[tmti->mti_nid_count] = nodenid;
1643 tmti->mti_nid_count++;
1645 /* failover node nid */
1646 rc = add_param(tmti->mti_params, PARAM_FAILNODE,
1647 libcfs_nid2str(nodenid));
1653 if (lcfg->lcfg_command == LCFG_SETUP) {
1656 target = lustre_cfg_string(lcfg, 1);
1657 memcpy(tmti->mti_uuid, target, strlen(target));
1661 /* ignore client side sptlrpc_conf_log */
1662 if (lcfg->lcfg_command == LCFG_SPTLRPC_CONF)
1665 if (lcfg->lcfg_command == LCFG_ADD_MDC) {
1668 if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1)
1671 memcpy(tmti->mti_fsname, mti->mti_fsname,
1672 strlen(mti->mti_fsname));
1673 tmti->mti_stripe_index = index;
1675 rc = mgs_write_log_osp_to_mdt(env, mgs, fsdb, tmti,
1676 mti->mti_stripe_index,
1678 memset(tmti, 0, sizeof(*tmti));
1682 if (lcfg->lcfg_command == LCFG_LOV_ADD_OBD) {
1685 char *logname, *lovname;
1687 rc = name_create_mdt_and_lov(&logname, &lovname, fsdb,
1688 mti->mti_stripe_index);
1691 sprintf(mdt_index, "-MDT%04x", mti->mti_stripe_index);
1693 if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1) {
1694 name_destroy(&logname);
1695 name_destroy(&lovname);
1699 tmti->mti_stripe_index = index;
1700 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, tmti, logname,
1703 name_destroy(&logname);
1704 name_destroy(&lovname);
1710 /* fsdb->fsdb_mutex is already held in mgs_write_log_target*/
1711 /* stealed from mgs_get_fsdb_from_llog*/
1712 static int mgs_steal_llog_for_mdt_from_client(const struct lu_env *env,
1713 struct mgs_device *mgs,
1715 struct temp_comp* comp)
1717 struct llog_handle *loghandle;
1718 struct mgs_target_info *tmti;
1719 struct llog_ctxt *ctxt;
1724 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
1725 LASSERT(ctxt != NULL);
1727 OBD_ALLOC_PTR(tmti);
1729 GOTO(out_ctxt, rc = -ENOMEM);
1731 comp->comp_tmti = tmti;
1732 comp->comp_obd = mgs->mgs_obd;
1734 rc = llog_open(env, ctxt, &loghandle, NULL, client_name,
1742 rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL);
1744 GOTO(out_close, rc);
1746 rc = llog_process_or_fork(env, loghandle, mgs_steal_client_llog_handler,
1747 (void *)comp, NULL, false);
1748 CDEBUG(D_MGS, "steal llog re = %d\n", rc);
1750 llog_close(env, loghandle);
1754 llog_ctxt_put(ctxt);
1758 /* lmv is the second thing for client logs */
1759 /* copied from mgs_write_log_lov. Please refer to that. */
1760 static int mgs_write_log_lmv(const struct lu_env *env,
1761 struct mgs_device *mgs,
1763 struct mgs_target_info *mti,
1764 char *logname, char *lmvname)
1766 struct llog_handle *llh = NULL;
1767 struct lmv_desc *lmvdesc;
1772 CDEBUG(D_MGS, "Writing lmv(%s) log for %s\n", lmvname,logname);
1774 OBD_ALLOC_PTR(lmvdesc);
1775 if (lmvdesc == NULL)
1777 lmvdesc->ld_active_tgt_count = 0;
1778 lmvdesc->ld_tgt_count = 0;
1779 sprintf((char*)lmvdesc->ld_uuid.uuid, "%s_UUID", lmvname);
1780 uuid = (char *)lmvdesc->ld_uuid.uuid;
1782 rc = record_start_log(env, mgs, &llh, logname);
1785 rc = record_marker(env, llh, fsdb, CM_START, lmvname, "lmv setup");
1788 rc = record_attach(env, llh, lmvname, "lmv", uuid);
1791 rc = record_lmv_setup(env, llh, lmvname, lmvdesc);
1794 rc = record_marker(env, llh, fsdb, CM_END, lmvname, "lmv setup");
1798 record_end_log(env, &llh);
1800 OBD_FREE_PTR(lmvdesc);
1804 /* lov is the first thing in the mdt and client logs */
1805 static int mgs_write_log_lov(const struct lu_env *env, struct mgs_device *mgs,
1806 struct fs_db *fsdb, struct mgs_target_info *mti,
1807 char *logname, char *lovname)
1809 struct llog_handle *llh = NULL;
1810 struct lov_desc *lovdesc;
1815 CDEBUG(D_MGS, "Writing lov(%s) log for %s\n", lovname, logname);
1818 #01 L attach 0:lov_mdsA 1:lov 2:71ccb_lov_mdsA_19f961a9e1
1819 #02 L lov_setup 0:lov_mdsA 1:(struct lov_desc)
1820 uuid=lov1_UUID, stripe count=1, size=1048576, offset=0, pattern=0
1823 /* FIXME just make lov_setup accept empty desc (put uuid in buf 2) */
1824 OBD_ALLOC_PTR(lovdesc);
1825 if (lovdesc == NULL)
1827 lovdesc->ld_magic = LOV_DESC_MAGIC;
1828 lovdesc->ld_tgt_count = 0;
1829 /* Defaults. Can be changed later by lcfg config_param */
1830 lovdesc->ld_default_stripe_count = 1;
1831 lovdesc->ld_pattern = LOV_PATTERN_RAID0;
1832 lovdesc->ld_default_stripe_size = LOV_DESC_STRIPE_SIZE_DEFAULT;
1833 lovdesc->ld_default_stripe_offset = -1;
1834 lovdesc->ld_qos_maxage = LOV_DESC_QOS_MAXAGE_DEFAULT;
1835 sprintf((char*)lovdesc->ld_uuid.uuid, "%s_UUID", lovname);
1836 /* can these be the same? */
1837 uuid = (char *)lovdesc->ld_uuid.uuid;
1839 /* This should always be the first entry in a log.
1840 rc = mgs_clear_log(obd, logname); */
1841 rc = record_start_log(env, mgs, &llh, logname);
1844 /* FIXME these should be a single journal transaction */
1845 rc = record_marker(env, llh, fsdb, CM_START, lovname, "lov setup");
1848 rc = record_attach(env, llh, lovname, "lov", uuid);
1851 rc = record_lov_setup(env, llh, lovname, lovdesc);
1854 rc = record_marker(env, llh, fsdb, CM_END, lovname, "lov setup");
1859 record_end_log(env, &llh);
1861 OBD_FREE_PTR(lovdesc);
1865 /* add failnids to open log */
1866 static int mgs_write_log_failnids(const struct lu_env *env,
1867 struct mgs_target_info *mti,
1868 struct llog_handle *llh,
1871 char *failnodeuuid = NULL;
1872 char *ptr = mti->mti_params;
1877 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) nal=90 0: 1:uml1_UUID
1878 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
1879 #05 L setup 0:OSC_uml1_ost1_mdsA 1:ost1_UUID 2:uml1_UUID
1880 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) nal=90 0: 1:uml2_UUID
1881 #0x L add_uuid nid=2@elan(0x1000000000002) nal=90 0: 1:uml2_UUID
1882 #07 L add_conn 0:OSC_uml1_ost1_mdsA 1:uml2_UUID
1885 /* Pull failnid info out of params string */
1886 while (class_find_param(ptr, PARAM_FAILNODE, &ptr) == 0) {
1887 while (class_parse_nid(ptr, &nid, &ptr) == 0) {
1888 if (failnodeuuid == NULL) {
1889 /* We don't know the failover node name,
1890 so just use the first nid as the uuid */
1891 rc = name_create(&failnodeuuid,
1892 libcfs_nid2str(nid), "");
1896 CDEBUG(D_MGS, "add nid %s for failover uuid %s, "
1897 "client %s\n", libcfs_nid2str(nid),
1898 failnodeuuid, cliname);
1899 rc = record_add_uuid(env, llh, nid, failnodeuuid);
1902 rc = record_add_conn(env, llh, cliname, failnodeuuid);
1903 name_destroy(&failnodeuuid);
1904 failnodeuuid = NULL;
1911 static int mgs_write_log_mdc_to_lmv(const struct lu_env *env,
1912 struct mgs_device *mgs,
1914 struct mgs_target_info *mti,
1915 char *logname, char *lmvname)
1917 struct llog_handle *llh = NULL;
1918 char *mdcname = NULL;
1919 char *nodeuuid = NULL;
1920 char *mdcuuid = NULL;
1921 char *lmvuuid = NULL;
1926 if (mgs_log_is_empty(env, mgs, logname)) {
1927 CERROR("log is empty! Logical error\n");
1931 CDEBUG(D_MGS, "adding mdc for %s to log %s:lmv(%s)\n",
1932 mti->mti_svname, logname, lmvname);
1934 rc = name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
1937 rc = name_create(&mdcname, mti->mti_svname, "-mdc");
1940 rc = name_create(&mdcuuid, mdcname, "_UUID");
1943 rc = name_create(&lmvuuid, lmvname, "_UUID");
1947 rc = record_start_log(env, mgs, &llh, logname);
1950 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
1954 for (i = 0; i < mti->mti_nid_count; i++) {
1955 CDEBUG(D_MGS, "add nid %s for mdt\n",
1956 libcfs_nid2str(mti->mti_nids[i]));
1958 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
1963 rc = record_attach(env, llh, mdcname, LUSTRE_MDC_NAME, lmvuuid);
1966 rc = record_setup(env, llh, mdcname, mti->mti_uuid, nodeuuid, 0, 0);
1969 rc = mgs_write_log_failnids(env, mti, llh, mdcname);
1972 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
1973 rc = record_mdc_add(env, llh, lmvname, mdcuuid, mti->mti_uuid,
1977 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname,
1982 record_end_log(env, &llh);
1984 name_destroy(&lmvuuid);
1985 name_destroy(&mdcuuid);
1986 name_destroy(&mdcname);
1987 name_destroy(&nodeuuid);
1991 static inline int name_create_lov(char **lovname, char *mdtname,
1992 struct fs_db *fsdb, int index)
1995 if (index == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
1996 return name_create(lovname, fsdb->fsdb_name, "-mdtlov");
1998 return name_create(lovname, mdtname, "-mdtlov");
2001 static int name_create_mdt_and_lov(char **logname, char **lovname,
2002 struct fs_db *fsdb, int i)
2006 rc = name_create_mdt(logname, fsdb->fsdb_name, i);
2010 if (i == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2011 rc = name_create(lovname, fsdb->fsdb_name, "-mdtlov");
2013 rc = name_create(lovname, *logname, "-mdtlov");
2015 name_destroy(logname);
2021 static inline int name_create_mdt_osc(char **oscname, char *ostname,
2022 struct fs_db *fsdb, int i)
2026 if (i == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2027 sprintf(suffix, "-osc");
2029 sprintf(suffix, "-osc-MDT%04x", i);
2030 return name_create(oscname, ostname, suffix);
2033 /* add new mdc to already existent MDS */
2034 static int mgs_write_log_osp_to_mdt(const struct lu_env *env,
2035 struct mgs_device *mgs,
2037 struct mgs_target_info *mti,
2038 int mdt_index, char *logname)
2040 struct llog_handle *llh = NULL;
2041 char *nodeuuid = NULL;
2042 char *ospname = NULL;
2043 char *lovuuid = NULL;
2044 char *mdtuuid = NULL;
2045 char *svname = NULL;
2046 char *mdtname = NULL;
2047 char *lovname = NULL;
2052 if (mgs_log_is_empty(env, mgs, mti->mti_svname)) {
2053 CERROR("log is empty! Logical error\n");
2057 CDEBUG(D_MGS, "adding osp index %d to %s\n", mti->mti_stripe_index,
2060 rc = name_create_mdt(&mdtname, fsdb->fsdb_name, mti->mti_stripe_index);
2064 rc = name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
2066 GOTO(out_destory, rc);
2068 rc = name_create(&svname, mdtname, "-osp");
2070 GOTO(out_destory, rc);
2072 sprintf(index_str, "-MDT%04x", mdt_index);
2073 rc = name_create(&ospname, svname, index_str);
2075 GOTO(out_destory, rc);
2077 rc = name_create_lov(&lovname, logname, fsdb, mdt_index);
2079 GOTO(out_destory, rc);
2081 rc = name_create(&lovuuid, lovname, "_UUID");
2083 GOTO(out_destory, rc);
2085 rc = name_create(&mdtuuid, mdtname, "_UUID");
2087 GOTO(out_destory, rc);
2089 rc = record_start_log(env, mgs, &llh, logname);
2091 GOTO(out_destory, rc);
2093 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
2096 GOTO(out_destory, rc);
2098 for (i = 0; i < mti->mti_nid_count; i++) {
2099 CDEBUG(D_MGS, "add nid %s for mdt\n",
2100 libcfs_nid2str(mti->mti_nids[i]));
2101 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
2106 rc = record_attach(env, llh, ospname, LUSTRE_OSP_NAME, lovuuid);
2110 rc = record_setup(env, llh, ospname, mti->mti_uuid, nodeuuid,
2115 rc = mgs_write_log_failnids(env, mti, llh, ospname);
2119 /* Add mdc(osp) to lod */
2120 snprintf(index_str, sizeof(mti->mti_stripe_index), "%d",
2121 mti->mti_stripe_index);
2122 rc = record_base(env, llh, lovname, 0, LCFG_ADD_MDC, mti->mti_uuid,
2123 index_str, "1", NULL);
2127 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname, "add osp");
2132 record_end_log(env, &llh);
2135 name_destroy(&mdtuuid);
2136 name_destroy(&lovuuid);
2137 name_destroy(&lovname);
2138 name_destroy(&ospname);
2139 name_destroy(&svname);
2140 name_destroy(&nodeuuid);
2141 name_destroy(&mdtname);
2145 static int mgs_write_log_mdt0(const struct lu_env *env,
2146 struct mgs_device *mgs,
2148 struct mgs_target_info *mti)
2150 char *log = mti->mti_svname;
2151 struct llog_handle *llh = NULL;
2152 char *uuid, *lovname;
2154 char *ptr = mti->mti_params;
2155 int rc = 0, failout = 0;
2158 OBD_ALLOC(uuid, sizeof(struct obd_uuid));
2162 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
2163 failout = (strncmp(ptr, "failout", 7) == 0);
2165 rc = name_create(&lovname, log, "-mdtlov");
2168 if (mgs_log_is_empty(env, mgs, log)) {
2169 rc = mgs_write_log_lov(env, mgs, fsdb, mti, log, lovname);
2174 sprintf(mdt_index, "%d", mti->mti_stripe_index);
2176 rc = record_start_log(env, mgs, &llh, log);
2180 /* add MDT itself */
2182 /* FIXME this whole fn should be a single journal transaction */
2183 sprintf(uuid, "%s_UUID", log);
2184 rc = record_marker(env, llh, fsdb, CM_START, log, "add mdt");
2187 rc = record_attach(env, llh, log, LUSTRE_MDT_NAME, uuid);
2190 rc = record_mount_opt(env, llh, log, lovname, NULL);
2193 rc = record_setup(env, llh, log, uuid, mdt_index, lovname,
2194 failout ? "n" : "f");
2197 rc = record_marker(env, llh, fsdb, CM_END, log, "add mdt");
2201 record_end_log(env, &llh);
2203 name_destroy(&lovname);
2205 OBD_FREE(uuid, sizeof(struct obd_uuid));
2209 /* envelope method for all layers log */
2210 static int mgs_write_log_mdt(const struct lu_env *env,
2211 struct mgs_device *mgs,
2213 struct mgs_target_info *mti)
2215 struct mgs_thread_info *mgi = mgs_env_info(env);
2216 struct llog_handle *llh = NULL;
2221 CDEBUG(D_MGS, "writing new mdt %s\n", mti->mti_svname);
2223 if (mti->mti_uuid[0] == '\0') {
2224 /* Make up our own uuid */
2225 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
2226 "%s_UUID", mti->mti_svname);
2230 rc = mgs_write_log_mdt0(env, mgs, fsdb, mti);
2233 /* Append the mdt info to the client log */
2234 rc = name_create(&cliname, mti->mti_fsname, "-client");
2238 if (mgs_log_is_empty(env, mgs, cliname)) {
2239 /* Start client log */
2240 rc = mgs_write_log_lov(env, mgs, fsdb, mti, cliname,
2244 rc = mgs_write_log_lmv(env, mgs, fsdb, mti, cliname,
2251 #09 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
2252 #10 L attach 0:MDC_uml1_mdsA_MNT_client 1:mdc 2:1d834_MNT_client_03f
2253 #11 L setup 0:MDC_uml1_mdsA_MNT_client 1:mdsA_UUID 2:uml1_UUID
2254 #12 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
2255 #13 L add_conn 0:MDC_uml1_mdsA_MNT_client 1:uml2_UUID
2256 #14 L mount_option 0: 1:client 2:lov1 3:MDC_uml1_mdsA_MNT_client
2259 /* copy client info about lov/lmv */
2260 mgi->mgi_comp.comp_mti = mti;
2261 mgi->mgi_comp.comp_fsdb = fsdb;
2263 rc = mgs_steal_llog_for_mdt_from_client(env, mgs, cliname,
2267 rc = mgs_write_log_mdc_to_lmv(env, mgs, fsdb, mti, cliname,
2273 rc = record_start_log(env, mgs, &llh, cliname);
2277 rc = record_marker(env, llh, fsdb, CM_START, cliname,
2281 rc = record_mount_opt(env, llh, cliname, fsdb->fsdb_clilov,
2285 rc = record_marker(env, llh, fsdb, CM_END, cliname,
2291 /* for_all_existing_mdt except current one */
2292 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2293 if (i != mti->mti_stripe_index &&
2294 test_bit(i, fsdb->fsdb_mdt_index_map)) {
2297 rc = name_create_mdt(&logname, fsdb->fsdb_name, i);
2301 rc = mgs_write_log_osp_to_mdt(env, mgs, fsdb, mti,
2303 name_destroy(&logname);
2309 record_end_log(env, &llh);
2311 name_destroy(&cliname);
2315 /* Add the ost info to the client/mdt lov */
2316 static int mgs_write_log_osc_to_lov(const struct lu_env *env,
2317 struct mgs_device *mgs, struct fs_db *fsdb,
2318 struct mgs_target_info *mti,
2319 char *logname, char *suffix, char *lovname,
2320 enum lustre_sec_part sec_part, int flags)
2322 struct llog_handle *llh = NULL;
2323 char *nodeuuid = NULL;
2324 char *oscname = NULL;
2325 char *oscuuid = NULL;
2326 char *lovuuid = NULL;
2327 char *svname = NULL;
2332 CDEBUG(D_INFO, "adding osc for %s to log %s\n",
2333 mti->mti_svname, logname);
2335 if (mgs_log_is_empty(env, mgs, logname)) {
2336 CERROR("log is empty! Logical error\n");
2340 rc = name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
2343 rc = name_create(&svname, mti->mti_svname, "-osc");
2347 /* for the system upgraded from old 1.8, keep using the old osc naming
2348 * style for mdt, see name_create_mdt_osc(). LU-1257 */
2349 if (test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2350 rc = name_create(&oscname, svname, "");
2352 rc = name_create(&oscname, svname, suffix);
2356 rc = name_create(&oscuuid, oscname, "_UUID");
2359 rc = name_create(&lovuuid, lovname, "_UUID");
2365 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
2367 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
2368 #04 L attach 0:OSC_uml1_ost1_MNT_client 1:osc 2:89070_lov1_a41dff51a
2369 #05 L setup 0:OSC_uml1_ost1_MNT_client 1:ost1_UUID 2:uml1_UUID
2371 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
2372 #07 L add_conn 0:OSC_uml1_ost1_MNT_client 1:uml2_UUID
2373 #08 L lov_modify_tgts add 0:lov1 1:ost1_UUID 2(index):0 3(gen):1
2376 rc = record_start_log(env, mgs, &llh, logname);
2380 /* FIXME these should be a single journal transaction */
2381 rc = record_marker(env, llh, fsdb, CM_START | flags, mti->mti_svname,
2386 /* NB: don't change record order, because upon MDT steal OSC config
2387 * from client, it treats all nids before LCFG_SETUP as target nids
2388 * (multiple interfaces), while nids after as failover node nids.
2389 * See mgs_steal_client_llog_handler() LCFG_ADD_UUID.
2391 for (i = 0; i < mti->mti_nid_count; i++) {
2392 CDEBUG(D_MGS, "add nid %s\n", libcfs_nid2str(mti->mti_nids[i]));
2393 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
2397 rc = record_attach(env, llh, oscname, LUSTRE_OSC_NAME, lovuuid);
2400 rc = record_setup(env, llh, oscname, mti->mti_uuid, nodeuuid, 0, 0);
2403 rc = mgs_write_log_failnids(env, mti, llh, oscname);
2407 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
2409 rc = record_lov_add(env, llh, lovname, mti->mti_uuid, index, "1");
2412 rc = record_marker(env, llh, fsdb, CM_END | flags, mti->mti_svname,
2417 record_end_log(env, &llh);
2419 name_destroy(&lovuuid);
2420 name_destroy(&oscuuid);
2421 name_destroy(&oscname);
2422 name_destroy(&svname);
2423 name_destroy(&nodeuuid);
2427 static int mgs_write_log_ost(const struct lu_env *env,
2428 struct mgs_device *mgs, struct fs_db *fsdb,
2429 struct mgs_target_info *mti)
2431 struct llog_handle *llh = NULL;
2432 char *logname, *lovname;
2433 char *ptr = mti->mti_params;
2434 int rc, flags = 0, failout = 0, i;
2437 CDEBUG(D_MGS, "writing new ost %s\n", mti->mti_svname);
2439 /* The ost startup log */
2441 /* If the ost log already exists, that means that someone reformatted
2442 the ost and it called target_add again. */
2443 if (!mgs_log_is_empty(env, mgs, mti->mti_svname)) {
2444 LCONSOLE_ERROR_MSG(0x141, "The config log for %s already "
2445 "exists, yet the server claims it never "
2446 "registered. It may have been reformatted, "
2447 "or the index changed. writeconf the MDT to "
2448 "regenerate all logs.\n", mti->mti_svname);
2453 attach obdfilter ost1 ost1_UUID
2454 setup /dev/loop2 ldiskfs f|n errors=remount-ro,user_xattr
2456 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
2457 failout = (strncmp(ptr, "failout", 7) == 0);
2458 rc = record_start_log(env, mgs, &llh, mti->mti_svname);
2461 /* FIXME these should be a single journal transaction */
2462 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,"add ost");
2465 if (*mti->mti_uuid == '\0')
2466 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
2467 "%s_UUID", mti->mti_svname);
2468 rc = record_attach(env, llh, mti->mti_svname,
2469 "obdfilter"/*LUSTRE_OST_NAME*/, mti->mti_uuid);
2472 rc = record_setup(env, llh, mti->mti_svname,
2473 "dev"/*ignored*/, "type"/*ignored*/,
2474 failout ? "n" : "f", 0/*options*/);
2477 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname, "add ost");
2481 record_end_log(env, &llh);
2484 /* We also have to update the other logs where this osc is part of
2487 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
2488 /* If we're upgrading, the old mdt log already has our
2489 entry. Let's do a fake one for fun. */
2490 /* Note that we can't add any new failnids, since we don't
2491 know the old osc names. */
2492 flags = CM_SKIP | CM_UPGRADE146;
2494 } else if ((mti->mti_flags & LDD_F_UPDATE) != LDD_F_UPDATE) {
2495 /* If the update flag isn't set, don't update client/mdt
2498 LCONSOLE_WARN("Client log for %s was not updated; writeconf "
2499 "the MDT first to regenerate it.\n",
2503 /* Add ost to all MDT lov defs */
2504 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
2505 if (test_bit(i, fsdb->fsdb_mdt_index_map)) {
2508 rc = name_create_mdt_and_lov(&logname, &lovname, fsdb,
2512 sprintf(mdt_index, "-MDT%04x", i);
2513 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, mti,
2515 lovname, LUSTRE_SP_MDT,
2517 name_destroy(&logname);
2518 name_destroy(&lovname);
2524 /* Append ost info to the client log */
2525 rc = name_create(&logname, mti->mti_fsname, "-client");
2528 if (mgs_log_is_empty(env, mgs, logname)) {
2529 /* Start client log */
2530 rc = mgs_write_log_lov(env, mgs, fsdb, mti, logname,
2534 rc = mgs_write_log_lmv(env, mgs, fsdb, mti, logname,
2539 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, mti, logname, "",
2540 fsdb->fsdb_clilov, LUSTRE_SP_CLI, 0);
2542 name_destroy(&logname);
2546 static __inline__ int mgs_param_empty(char *ptr)
2550 if ((tmp = strchr(ptr, '=')) && (*(++tmp) == '\0'))
2555 static int mgs_write_log_failnid_internal(const struct lu_env *env,
2556 struct mgs_device *mgs,
2558 struct mgs_target_info *mti,
2559 char *logname, char *cliname)
2562 struct llog_handle *llh = NULL;
2564 if (mgs_param_empty(mti->mti_params)) {
2565 /* Remove _all_ failnids */
2566 rc = mgs_modify(env, mgs, fsdb, mti, logname,
2567 mti->mti_svname, "add failnid", CM_SKIP);
2568 return rc < 0 ? rc : 0;
2571 /* Otherwise failover nids are additive */
2572 rc = record_start_log(env, mgs, &llh, logname);
2575 /* FIXME this should be a single journal transaction */
2576 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
2580 rc = mgs_write_log_failnids(env, mti, llh, cliname);
2583 rc = record_marker(env, llh, fsdb, CM_END,
2584 mti->mti_svname, "add failnid");
2586 record_end_log(env, &llh);
2591 /* Add additional failnids to an existing log.
2592 The mdc/osc must have been added to logs first */
2593 /* tcp nids must be in dotted-quad ascii -
2594 we can't resolve hostnames from the kernel. */
2595 static int mgs_write_log_add_failnid(const struct lu_env *env,
2596 struct mgs_device *mgs,
2598 struct mgs_target_info *mti)
2600 char *logname, *cliname;
2604 /* FIXME we currently can't erase the failnids
2605 * given when a target first registers, since they aren't part of
2606 * an "add uuid" stanza */
2608 /* Verify that we know about this target */
2609 if (mgs_log_is_empty(env, mgs, mti->mti_svname)) {
2610 LCONSOLE_ERROR_MSG(0x142, "The target %s has not registered "
2611 "yet. It must be started before failnids "
2612 "can be added.\n", mti->mti_svname);
2616 /* Create mdc/osc client name (e.g. lustre-OST0001-osc) */
2617 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
2618 rc = name_create(&cliname, mti->mti_svname, "-mdc");
2619 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2620 rc = name_create(&cliname, mti->mti_svname, "-osc");
2626 /* Add failover nids to the client log */
2627 rc = name_create(&logname, mti->mti_fsname, "-client");
2629 name_destroy(&cliname);
2632 rc = mgs_write_log_failnid_internal(env, mgs, fsdb,mti,logname,cliname);
2633 name_destroy(&logname);
2634 name_destroy(&cliname);
2638 if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2639 /* Add OST failover nids to the MDT logs as well */
2642 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2643 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
2645 rc = name_create_mdt(&logname, mti->mti_fsname, i);
2648 rc = name_create_mdt_osc(&cliname, mti->mti_svname,
2651 name_destroy(&logname);
2654 rc = mgs_write_log_failnid_internal(env, mgs, fsdb,
2657 name_destroy(&cliname);
2658 name_destroy(&logname);
2667 static int mgs_wlp_lcfg(const struct lu_env *env,
2668 struct mgs_device *mgs, struct fs_db *fsdb,
2669 struct mgs_target_info *mti,
2670 char *logname, struct lustre_cfg_bufs *bufs,
2671 char *tgtname, char *ptr)
2673 char comment[MTI_NAME_MAXLEN];
2675 struct llog_cfg_rec *lcr;
2678 /* Erase any old settings of this same parameter */
2679 memcpy(comment, ptr, MTI_NAME_MAXLEN);
2680 comment[MTI_NAME_MAXLEN - 1] = 0;
2681 /* But don't try to match the value. */
2682 tmp = strchr(comment, '=');
2685 /* FIXME we should skip settings that are the same as old values */
2686 rc = mgs_modify(env, mgs, fsdb, mti, logname, tgtname, comment,CM_SKIP);
2689 del = mgs_param_empty(ptr);
2691 LCONSOLE_INFO("%s parameter %s.%s in log %s\n", del ? "Disabling" : rc ?
2692 "Setting" : "Modifying", tgtname, comment, logname);
2694 /* mgs_modify() will return 1 if nothing had to be done */
2700 lustre_cfg_bufs_reset(bufs, tgtname);
2701 lustre_cfg_bufs_set_string(bufs, 1, ptr);
2702 if (mti->mti_flags & LDD_F_PARAM2)
2703 lustre_cfg_bufs_set_string(bufs, 2, LCTL_UPCALL);
2705 lcr = lustre_cfg_rec_new((mti->mti_flags & LDD_F_PARAM2) ?
2706 LCFG_SET_PARAM : LCFG_PARAM, bufs);
2710 rc = mgs_write_log_direct(env, mgs, fsdb, logname, lcr, tgtname,
2712 lustre_cfg_rec_free(lcr);
2716 static int mgs_write_log_param2(const struct lu_env *env,
2717 struct mgs_device *mgs,
2719 struct mgs_target_info *mti, char *ptr)
2721 struct lustre_cfg_bufs bufs;
2725 CDEBUG(D_MGS, "next param '%s'\n", ptr);
2726 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, PARAMS_FILENAME, &bufs,
2727 mti->mti_svname, ptr);
2732 /* write global variable settings into log */
2733 static int mgs_write_log_sys(const struct lu_env *env,
2734 struct mgs_device *mgs, struct fs_db *fsdb,
2735 struct mgs_target_info *mti, char *sys, char *ptr)
2737 struct mgs_thread_info *mgi = mgs_env_info(env);
2738 struct lustre_cfg *lcfg;
2739 struct llog_cfg_rec *lcr;
2741 int rc, cmd, convert = 1;
2743 if (class_match_param(ptr, PARAM_TIMEOUT, &tmp) == 0) {
2744 cmd = LCFG_SET_TIMEOUT;
2745 } else if (class_match_param(ptr, PARAM_LDLM_TIMEOUT, &tmp) == 0) {
2746 cmd = LCFG_SET_LDLM_TIMEOUT;
2747 /* Check for known params here so we can return error to lctl */
2748 } else if ((class_match_param(ptr, PARAM_AT_MIN, &tmp) == 0) ||
2749 (class_match_param(ptr, PARAM_AT_MAX, &tmp) == 0) ||
2750 (class_match_param(ptr, PARAM_AT_EXTRA, &tmp) == 0) ||
2751 (class_match_param(ptr, PARAM_AT_EARLY_MARGIN, &tmp) == 0) ||
2752 (class_match_param(ptr, PARAM_AT_HISTORY, &tmp) == 0)) {
2754 } else if (class_match_param(ptr, PARAM_JOBID_VAR, &tmp) == 0) {
2755 convert = 0; /* Don't convert string value to integer */
2761 if (mgs_param_empty(ptr))
2762 CDEBUG(D_MGS, "global '%s' removed\n", sys);
2764 CDEBUG(D_MGS, "global '%s' val=%s\n", sys, tmp);
2766 lustre_cfg_bufs_reset(&mgi->mgi_bufs, NULL);
2767 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, sys);
2768 if (!convert && *tmp != '\0')
2769 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 2, tmp);
2770 lcr = lustre_cfg_rec_new(cmd, &mgi->mgi_bufs);
2774 lcfg = &lcr->lcr_cfg;
2775 lcfg->lcfg_num = convert ? simple_strtoul(tmp, NULL, 0) : 0;
2776 /* truncate the comment to the parameter name */
2780 /* modify all servers and clients */
2781 rc = mgs_write_log_direct_all(env, mgs, fsdb, mti,
2782 *tmp == '\0' ? NULL : lcr,
2783 mti->mti_fsname, sys, 0);
2784 if (rc == 0 && *tmp != '\0') {
2786 case LCFG_SET_TIMEOUT:
2787 if (!obd_timeout_set || lcfg->lcfg_num > obd_timeout)
2788 class_process_config(lcfg);
2790 case LCFG_SET_LDLM_TIMEOUT:
2791 if (!ldlm_timeout_set || lcfg->lcfg_num > ldlm_timeout)
2792 class_process_config(lcfg);
2799 lustre_cfg_rec_free(lcr);
2803 /* write quota settings into log */
2804 static int mgs_write_log_quota(const struct lu_env *env, struct mgs_device *mgs,
2805 struct fs_db *fsdb, struct mgs_target_info *mti,
2806 char *quota, char *ptr)
2808 struct mgs_thread_info *mgi = mgs_env_info(env);
2809 struct llog_cfg_rec *lcr;
2812 int rc, cmd = LCFG_PARAM;
2814 /* support only 'meta' and 'data' pools so far */
2815 if (class_match_param(ptr, QUOTA_METAPOOL_NAME, &tmp) != 0 &&
2816 class_match_param(ptr, QUOTA_DATAPOOL_NAME, &tmp) != 0) {
2817 CERROR("parameter quota.%s isn't supported (only quota.mdt "
2818 "& quota.ost are)\n", ptr);
2823 CDEBUG(D_MGS, "global '%s' removed\n", quota);
2825 CDEBUG(D_MGS, "global '%s'\n", quota);
2827 if (strchr(tmp, 'u') == NULL && strchr(tmp, 'g') == NULL &&
2828 strcmp(tmp, "none") != 0) {
2829 CERROR("enable option(%s) isn't supported\n", tmp);
2834 lustre_cfg_bufs_reset(&mgi->mgi_bufs, mti->mti_fsname);
2835 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, quota);
2836 lcr = lustre_cfg_rec_new(cmd, &mgi->mgi_bufs);
2840 /* truncate the comment to the parameter name */
2845 /* XXX we duplicated quota enable information in all server
2846 * config logs, it should be moved to a separate config
2847 * log once we cleanup the config log for global param. */
2848 /* modify all servers */
2849 rc = mgs_write_log_direct_all(env, mgs, fsdb, mti,
2850 *tmp == '\0' ? NULL : lcr,
2851 mti->mti_fsname, quota, 1);
2853 lustre_cfg_rec_free(lcr);
2854 return rc < 0 ? rc : 0;
2857 static int mgs_srpc_set_param_disk(const struct lu_env *env,
2858 struct mgs_device *mgs,
2860 struct mgs_target_info *mti,
2863 struct mgs_thread_info *mgi = mgs_env_info(env);
2864 struct llog_cfg_rec *lcr;
2865 struct llog_handle *llh = NULL;
2867 char *comment, *ptr;
2873 ptr = strchr(param, '=');
2874 LASSERT(ptr != NULL);
2877 OBD_ALLOC(comment, len + 1);
2878 if (comment == NULL)
2880 strncpy(comment, param, len);
2881 comment[len] = '\0';
2884 lustre_cfg_bufs_reset(&mgi->mgi_bufs, mti->mti_svname);
2885 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, param);
2886 lcr = lustre_cfg_rec_new(LCFG_SPTLRPC_CONF, &mgi->mgi_bufs);
2888 GOTO(out_comment, rc = -ENOMEM);
2890 /* construct log name */
2891 rc = name_create(&logname, mti->mti_fsname, "-sptlrpc");
2895 if (mgs_log_is_empty(env, mgs, logname)) {
2896 rc = record_start_log(env, mgs, &llh, logname);
2899 record_end_log(env, &llh);
2902 /* obsolete old one */
2903 rc = mgs_modify(env, mgs, fsdb, mti, logname, mti->mti_svname,
2907 /* write the new one */
2908 rc = mgs_write_log_direct(env, mgs, fsdb, logname, lcr,
2909 mti->mti_svname, comment);
2911 CERROR("%s: error writing log %s: rc = %d\n",
2912 mgs->mgs_obd->obd_name, logname, rc);
2914 name_destroy(&logname);
2916 lustre_cfg_rec_free(lcr);
2918 OBD_FREE(comment, len + 1);
2922 static int mgs_srpc_set_param_udesc_mem(struct fs_db *fsdb,
2927 /* disable the adjustable udesc parameter for now, i.e. use default
2928 * setting that client always ship udesc to MDT if possible. to enable
2929 * it simply remove the following line */
2932 ptr = strchr(param, '=');
2937 if (strcmp(param, PARAM_SRPC_UDESC))
2940 if (strcmp(ptr, "yes") == 0) {
2941 set_bit(FSDB_UDESC, &fsdb->fsdb_flags);
2942 CWARN("Enable user descriptor shipping from client to MDT\n");
2943 } else if (strcmp(ptr, "no") == 0) {
2944 clear_bit(FSDB_UDESC, &fsdb->fsdb_flags);
2945 CWARN("Disable user descriptor shipping from client to MDT\n");
2953 CERROR("Invalid param: %s\n", param);
2957 static int mgs_srpc_set_param_mem(struct fs_db *fsdb,
2961 struct sptlrpc_rule rule;
2962 struct sptlrpc_rule_set *rset;
2966 if (strncmp(param, PARAM_SRPC, sizeof(PARAM_SRPC) - 1) != 0) {
2967 CERROR("Invalid sptlrpc parameter: %s\n", param);
2971 if (strncmp(param, PARAM_SRPC_UDESC,
2972 sizeof(PARAM_SRPC_UDESC) - 1) == 0) {
2973 RETURN(mgs_srpc_set_param_udesc_mem(fsdb, param));
2976 if (strncmp(param, PARAM_SRPC_FLVR, sizeof(PARAM_SRPC_FLVR) - 1) != 0) {
2977 CERROR("Invalid sptlrpc flavor parameter: %s\n", param);
2981 param += sizeof(PARAM_SRPC_FLVR) - 1;
2983 rc = sptlrpc_parse_rule(param, &rule);
2987 /* mgs rules implies must be mgc->mgs */
2988 if (test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
2989 if ((rule.sr_from != LUSTRE_SP_MGC &&
2990 rule.sr_from != LUSTRE_SP_ANY) ||
2991 (rule.sr_to != LUSTRE_SP_MGS &&
2992 rule.sr_to != LUSTRE_SP_ANY))
2996 /* preapre room for this coming rule. svcname format should be:
2997 * - fsname: general rule
2998 * - fsname-tgtname: target-specific rule
3000 if (strchr(svname, '-')) {
3001 struct mgs_tgt_srpc_conf *tgtconf;
3004 for (tgtconf = fsdb->fsdb_srpc_tgt; tgtconf != NULL;
3005 tgtconf = tgtconf->mtsc_next) {
3006 if (!strcmp(tgtconf->mtsc_tgt, svname)) {
3015 OBD_ALLOC_PTR(tgtconf);
3016 if (tgtconf == NULL)
3019 name_len = strlen(svname);
3021 OBD_ALLOC(tgtconf->mtsc_tgt, name_len + 1);
3022 if (tgtconf->mtsc_tgt == NULL) {
3023 OBD_FREE_PTR(tgtconf);
3026 memcpy(tgtconf->mtsc_tgt, svname, name_len);
3028 tgtconf->mtsc_next = fsdb->fsdb_srpc_tgt;
3029 fsdb->fsdb_srpc_tgt = tgtconf;
3032 rset = &tgtconf->mtsc_rset;
3034 rset = &fsdb->fsdb_srpc_gen;
3037 rc = sptlrpc_rule_set_merge(rset, &rule);
3042 static int mgs_srpc_set_param(const struct lu_env *env,
3043 struct mgs_device *mgs,
3045 struct mgs_target_info *mti,
3055 /* keep a copy of original param, which could be destroied
3057 copy_size = strlen(param) + 1;
3058 OBD_ALLOC(copy, copy_size);
3061 memcpy(copy, param, copy_size);
3063 rc = mgs_srpc_set_param_mem(fsdb, mti->mti_svname, param);
3067 /* previous steps guaranteed the syntax is correct */
3068 rc = mgs_srpc_set_param_disk(env, mgs, fsdb, mti, copy);
3072 if (test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
3074 * for mgs rules, make them effective immediately.
3076 LASSERT(fsdb->fsdb_srpc_tgt == NULL);
3077 sptlrpc_target_update_exp_flavor(mgs->mgs_obd,
3078 &fsdb->fsdb_srpc_gen);
3082 OBD_FREE(copy, copy_size);
3086 struct mgs_srpc_read_data {
3087 struct fs_db *msrd_fsdb;
3091 static int mgs_srpc_read_handler(const struct lu_env *env,
3092 struct llog_handle *llh,
3093 struct llog_rec_hdr *rec, void *data)
3095 struct mgs_srpc_read_data *msrd = data;
3096 struct cfg_marker *marker;
3097 struct lustre_cfg *lcfg = REC_DATA(rec);
3098 char *svname, *param;
3102 if (rec->lrh_type != OBD_CFG_REC) {
3103 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
3107 cfg_len = REC_DATA_LEN(rec);
3109 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
3111 CERROR("Insane cfg\n");
3115 if (lcfg->lcfg_command == LCFG_MARKER) {
3116 marker = lustre_cfg_buf(lcfg, 1);
3118 if (marker->cm_flags & CM_START &&
3119 marker->cm_flags & CM_SKIP)
3120 msrd->msrd_skip = 1;
3121 if (marker->cm_flags & CM_END)
3122 msrd->msrd_skip = 0;
3127 if (msrd->msrd_skip)
3130 if (lcfg->lcfg_command != LCFG_SPTLRPC_CONF) {
3131 CERROR("invalid command (%x)\n", lcfg->lcfg_command);
3135 svname = lustre_cfg_string(lcfg, 0);
3136 if (svname == NULL) {
3137 CERROR("svname is empty\n");
3141 param = lustre_cfg_string(lcfg, 1);
3142 if (param == NULL) {
3143 CERROR("param is empty\n");
3147 rc = mgs_srpc_set_param_mem(msrd->msrd_fsdb, svname, param);
3149 CERROR("read sptlrpc record error (%d): %s\n", rc, param);
3154 int mgs_get_fsdb_srpc_from_llog(const struct lu_env *env,
3155 struct mgs_device *mgs,
3158 struct llog_handle *llh = NULL;
3159 struct llog_ctxt *ctxt;
3161 struct mgs_srpc_read_data msrd;
3165 /* construct log name */
3166 rc = name_create(&logname, fsdb->fsdb_name, "-sptlrpc");
3170 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
3171 LASSERT(ctxt != NULL);
3173 if (mgs_log_is_empty(env, mgs, logname))
3176 rc = llog_open(env, ctxt, &llh, NULL, logname,
3184 rc = llog_init_handle(env, llh, LLOG_F_IS_PLAIN, NULL);
3186 GOTO(out_close, rc);
3188 if (llog_get_size(llh) <= 1)
3189 GOTO(out_close, rc = 0);
3191 msrd.msrd_fsdb = fsdb;
3194 rc = llog_process(env, llh, mgs_srpc_read_handler, (void *)&msrd,
3198 llog_close(env, llh);
3200 llog_ctxt_put(ctxt);
3201 name_destroy(&logname);
3204 CERROR("failed to read sptlrpc config database: %d\n", rc);
3208 /* Permanent settings of all parameters by writing into the appropriate
3209 * configuration logs.
3210 * A parameter with null value ("<param>='\0'") means to erase it out of
3213 static int mgs_write_log_param(const struct lu_env *env,
3214 struct mgs_device *mgs, struct fs_db *fsdb,
3215 struct mgs_target_info *mti, char *ptr)
3217 struct mgs_thread_info *mgi = mgs_env_info(env);
3220 int rc = 0, rc2 = 0;
3223 /* For various parameter settings, we have to figure out which logs
3224 care about them (e.g. both mdt and client for lov settings) */
3225 CDEBUG(D_MGS, "next param '%s'\n", ptr);
3227 /* The params are stored in MOUNT_DATA_FILE and modified via
3228 tunefs.lustre, or set using lctl conf_param */
3230 /* Processed in lustre_start_mgc */
3231 if (class_match_param(ptr, PARAM_MGSNODE, NULL) == 0)
3234 /* Processed in ost/mdt */
3235 if (class_match_param(ptr, PARAM_NETWORK, NULL) == 0)
3238 /* Processed in mgs_write_log_ost */
3239 if (class_match_param(ptr, PARAM_FAILMODE, NULL) == 0) {
3240 if (mti->mti_flags & LDD_F_PARAM) {
3241 LCONSOLE_ERROR_MSG(0x169, "%s can only be "
3242 "changed with tunefs.lustre"
3243 "and --writeconf\n", ptr);
3249 if (class_match_param(ptr, PARAM_SRPC, NULL) == 0) {
3250 rc = mgs_srpc_set_param(env, mgs, fsdb, mti, ptr);
3254 if (class_match_param(ptr, PARAM_FAILNODE, NULL) == 0) {
3255 /* Add a failover nidlist */
3257 /* We already processed failovers params for new
3258 targets in mgs_write_log_target */
3259 if (mti->mti_flags & LDD_F_PARAM) {
3260 CDEBUG(D_MGS, "Adding failnode\n");
3261 rc = mgs_write_log_add_failnid(env, mgs, fsdb, mti);
3266 if (class_match_param(ptr, PARAM_SYS, &tmp) == 0) {
3267 rc = mgs_write_log_sys(env, mgs, fsdb, mti, ptr, tmp);
3271 if (class_match_param(ptr, PARAM_QUOTA, &tmp) == 0) {
3272 rc = mgs_write_log_quota(env, mgs, fsdb, mti, ptr, tmp);
3276 if (class_match_param(ptr, PARAM_OSC""PARAM_ACTIVE, &tmp) == 0) {
3277 /* active=0 means off, anything else means on */
3278 int flag = (*tmp == '0') ? CM_EXCLUDE : 0;
3281 if (!(mti->mti_flags & LDD_F_SV_TYPE_OST)) {
3282 LCONSOLE_ERROR_MSG(0x144, "%s: Only OSCs can "
3283 "be (de)activated.\n",
3285 GOTO(end, rc = -EINVAL);
3287 LCONSOLE_WARN("Permanently %sactivating %s\n",
3288 flag ? "de": "re", mti->mti_svname);
3290 rc = name_create(&logname, mti->mti_fsname, "-client");
3293 rc = mgs_modify(env, mgs, fsdb, mti, logname,
3294 mti->mti_svname, "add osc", flag);
3295 name_destroy(&logname);
3299 /* Add to all MDT logs for CMD */
3300 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3301 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
3303 rc = name_create_mdt(&logname, mti->mti_fsname, i);
3306 rc = mgs_modify(env, mgs, fsdb, mti, logname,
3307 mti->mti_svname, "add osc", flag);
3308 name_destroy(&logname);
3314 LCONSOLE_ERROR_MSG(0x145, "Couldn't find %s in"
3315 "log (%d). No permanent "
3316 "changes were made to the "
3318 mti->mti_svname, rc);
3319 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags))
3320 LCONSOLE_ERROR_MSG(0x146, "This may be"
3325 "update the logs.\n");
3328 /* Fall through to osc proc for deactivating live OSC
3329 on running MDT / clients. */
3331 /* Below here, let obd's XXX_process_config methods handle it */
3333 /* All lov. in proc */
3334 if (class_match_param(ptr, PARAM_LOV, NULL) == 0) {
3337 CDEBUG(D_MGS, "lov param %s\n", ptr);
3338 if (!(mti->mti_flags & LDD_F_SV_TYPE_MDT)) {
3339 LCONSOLE_ERROR_MSG(0x147, "LOV params must be "
3340 "set on the MDT, not %s. "
3347 if (mgs_log_is_empty(env, mgs, mti->mti_svname))
3348 GOTO(end, rc = -ENODEV);
3350 rc = name_create_mdt_and_lov(&logname, &mdtlovname, fsdb,
3351 mti->mti_stripe_index);
3354 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, mti->mti_svname,
3355 &mgi->mgi_bufs, mdtlovname, ptr);
3356 name_destroy(&logname);
3357 name_destroy(&mdtlovname);
3362 rc = name_create(&logname, mti->mti_fsname, "-client");
3365 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname, &mgi->mgi_bufs,
3366 fsdb->fsdb_clilov, ptr);
3367 name_destroy(&logname);
3371 /* All osc., mdc., llite. params in proc */
3372 if ((class_match_param(ptr, PARAM_OSC, NULL) == 0) ||
3373 (class_match_param(ptr, PARAM_MDC, NULL) == 0) ||
3374 (class_match_param(ptr, PARAM_LLITE, NULL) == 0)) {
3377 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
3378 LCONSOLE_ERROR_MSG(0x148, "Upgraded client logs for %s"
3379 " cannot be modified. Consider"
3380 " updating the configuration with"
3383 GOTO(end, rc = -EINVAL);
3385 if (memcmp(ptr, PARAM_LLITE, strlen(PARAM_LLITE)) == 0) {
3386 rc = name_create(&cname, mti->mti_fsname, "-client");
3387 /* Add the client type to match the obdname in
3388 class_config_llog_handler */
3389 } else if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
3390 rc = name_create(&cname, mti->mti_svname, "-mdc");
3391 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
3392 rc = name_create(&cname, mti->mti_svname, "-osc");
3394 GOTO(end, rc = -EINVAL);
3399 /* Forbid direct update of llite root squash parameters.
3400 * These parameters are indirectly set via the MDT settings.
3402 if ((class_match_param(ptr, PARAM_LLITE, &tmp) == 0) &&
3403 ((memcmp(tmp, "root_squash=", 12) == 0) ||
3404 (memcmp(tmp, "nosquash_nids=", 14) == 0))) {
3405 LCONSOLE_ERROR("%s: root squash parameters can only "
3406 "be updated through MDT component\n",
3408 name_destroy(&cname);
3409 GOTO(end, rc = -EINVAL);
3412 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
3415 rc = name_create(&logname, mti->mti_fsname, "-client");
3417 name_destroy(&cname);
3420 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname, &mgi->mgi_bufs,
3423 /* osc params affect the MDT as well */
3424 if (!rc && (mti->mti_flags & LDD_F_SV_TYPE_OST)) {
3427 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
3428 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
3430 name_destroy(&cname);
3431 rc = name_create_mdt_osc(&cname, mti->mti_svname,
3433 name_destroy(&logname);
3436 rc = name_create_mdt(&logname,
3437 mti->mti_fsname, i);
3440 if (!mgs_log_is_empty(env, mgs, logname)) {
3441 rc = mgs_wlp_lcfg(env, mgs, fsdb,
3450 name_destroy(&logname);
3451 name_destroy(&cname);
3455 /* All mdt. params in proc */
3456 if (class_match_param(ptr, PARAM_MDT, &tmp) == 0) {
3460 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
3461 if (strncmp(mti->mti_svname, mti->mti_fsname,
3462 MTI_NAME_MAXLEN) == 0)
3463 /* device is unspecified completely? */
3464 rc = LDD_F_SV_TYPE_MDT | LDD_F_SV_ALL;
3466 rc = server_name2index(mti->mti_svname, &idx, NULL);
3469 if ((rc & LDD_F_SV_TYPE_MDT) == 0)
3471 if (rc & LDD_F_SV_ALL) {
3472 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3474 fsdb->fsdb_mdt_index_map))
3476 rc = name_create_mdt(&logname,
3477 mti->mti_fsname, i);
3480 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti,
3481 logname, &mgi->mgi_bufs,
3483 name_destroy(&logname);
3488 if ((memcmp(tmp, "root_squash=", 12) == 0) ||
3489 (memcmp(tmp, "nosquash_nids=", 14) == 0)) {
3490 LCONSOLE_ERROR("%s: root squash parameters "
3491 "cannot be applied to a single MDT\n",
3493 GOTO(end, rc = -EINVAL);
3495 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti,
3496 mti->mti_svname, &mgi->mgi_bufs,
3497 mti->mti_svname, ptr);
3502 /* root squash settings are also applied to llite
3503 * config log (see LU-1778) */
3505 ((memcmp(tmp, "root_squash=", 12) == 0) ||
3506 (memcmp(tmp, "nosquash_nids=", 14) == 0))) {
3510 rc = name_create(&cname, mti->mti_fsname, "-client");
3513 rc = name_create(&logname, mti->mti_fsname, "-client");
3515 name_destroy(&cname);
3518 rc = name_create(&ptr2, PARAM_LLITE, tmp);
3520 name_destroy(&cname);
3521 name_destroy(&logname);
3524 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname,
3525 &mgi->mgi_bufs, cname, ptr2);
3526 name_destroy(&ptr2);
3527 name_destroy(&logname);
3528 name_destroy(&cname);
3533 /* All mdd., ost. and osd. params in proc */
3534 if ((class_match_param(ptr, PARAM_MDD, NULL) == 0) ||
3535 (class_match_param(ptr, PARAM_OST, NULL) == 0) ||
3536 (class_match_param(ptr, PARAM_OSD, NULL) == 0)) {
3537 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
3538 if (mgs_log_is_empty(env, mgs, mti->mti_svname))
3539 GOTO(end, rc = -ENODEV);
3541 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, mti->mti_svname,
3542 &mgi->mgi_bufs, mti->mti_svname, ptr);
3546 LCONSOLE_WARN("Ignoring unrecognized param '%s'\n", ptr);
3551 CERROR("err %d on param '%s'\n", rc, ptr);
3556 /* Not implementing automatic failover nid addition at this time. */
3557 int mgs_check_failnid(const struct lu_env *env, struct mgs_device *mgs,
3558 struct mgs_target_info *mti)
3565 rc = mgs_find_or_make_fsdb(obd, fsname, &fsdb);
3569 if (mgs_log_is_empty(obd, mti->mti_svname))
3570 /* should never happen */
3573 CDEBUG(D_MGS, "Checking for new failnids for %s\n", mti->mti_svname);
3575 /* FIXME We can just check mti->params to see if we're already in
3576 the failover list. Modify mti->params for rewriting back at
3577 server_register_target(). */
3579 mutex_lock(&fsdb->fsdb_mutex);
3580 rc = mgs_write_log_add_failnid(obd, fsdb, mti);
3581 mutex_unlock(&fsdb->fsdb_mutex);
3590 int mgs_write_log_target(const struct lu_env *env, struct mgs_device *mgs,
3591 struct mgs_target_info *mti, struct fs_db *fsdb)
3598 /* set/check the new target index */
3599 rc = mgs_set_index(env, mgs, mti);
3603 if (rc == EALREADY) {
3604 LCONSOLE_WARN("Found index %d for %s, updating log\n",
3605 mti->mti_stripe_index, mti->mti_svname);
3606 /* We would like to mark old log sections as invalid
3607 and add new log sections in the client and mdt logs.
3608 But if we add new sections, then live clients will
3609 get repeat setup instructions for already running
3610 osc's. So don't update the client/mdt logs. */
3611 mti->mti_flags &= ~LDD_F_UPDATE;
3615 mutex_lock(&fsdb->fsdb_mutex);
3617 if (mti->mti_flags &
3618 (LDD_F_VIRGIN | LDD_F_UPGRADE14 | LDD_F_WRITECONF)) {
3619 /* Generate a log from scratch */
3620 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
3621 rc = mgs_write_log_mdt(env, mgs, fsdb, mti);
3622 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
3623 rc = mgs_write_log_ost(env, mgs, fsdb, mti);
3625 CERROR("Unknown target type %#x, can't create log for "
3626 "%s\n", mti->mti_flags, mti->mti_svname);
3629 CERROR("Can't write logs for %s (%d)\n",
3630 mti->mti_svname, rc);
3634 /* Just update the params from tunefs in mgs_write_log_params */
3635 CDEBUG(D_MGS, "Update params for %s\n", mti->mti_svname);
3636 mti->mti_flags |= LDD_F_PARAM;
3639 /* allocate temporary buffer, where class_get_next_param will
3640 make copy of a current parameter */
3641 OBD_ALLOC(buf, strlen(mti->mti_params) + 1);
3643 GOTO(out_up, rc = -ENOMEM);
3644 params = mti->mti_params;
3645 while (params != NULL) {
3646 rc = class_get_next_param(¶ms, buf);
3649 /* there is no next parameter, that is
3654 CDEBUG(D_MGS, "remaining string: '%s', param: '%s'\n",
3656 rc = mgs_write_log_param(env, mgs, fsdb, mti, buf);
3661 OBD_FREE(buf, strlen(mti->mti_params) + 1);
3664 mutex_unlock(&fsdb->fsdb_mutex);
3668 int mgs_erase_log(const struct lu_env *env, struct mgs_device *mgs, char *name)
3670 struct llog_ctxt *ctxt;
3673 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
3675 CERROR("%s: MGS config context doesn't exist\n",
3676 mgs->mgs_obd->obd_name);
3679 rc = llog_erase(env, ctxt, NULL, name);
3680 /* llog may not exist */
3683 llog_ctxt_put(ctxt);
3687 CERROR("%s: failed to clear log %s: %d\n",
3688 mgs->mgs_obd->obd_name, name, rc);
3693 /* erase all logs for the given fs */
3694 int mgs_erase_logs(const struct lu_env *env, struct mgs_device *mgs, char *fsname)
3697 struct list_head log_list;
3698 struct mgs_direntry *dirent, *n;
3699 int rc, len = strlen(fsname);
3703 /* Find all the logs in the CONFIGS directory */
3704 rc = class_dentry_readdir(env, mgs, &log_list);
3708 mutex_lock(&mgs->mgs_mutex);
3710 /* Delete the fs db */
3711 fsdb = mgs_find_fsdb(mgs, fsname);
3713 mgs_free_fsdb(mgs, fsdb);
3715 mutex_unlock(&mgs->mgs_mutex);
3717 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
3718 list_del_init(&dirent->mde_list);
3719 suffix = strrchr(dirent->mde_name, '-');
3720 if (suffix != NULL) {
3721 if ((len == suffix - dirent->mde_name) &&
3722 (strncmp(fsname, dirent->mde_name, len) == 0)) {
3723 CDEBUG(D_MGS, "Removing log %s\n",
3725 mgs_erase_log(env, mgs, dirent->mde_name);
3728 mgs_direntry_free(dirent);
3734 /* list all logs for the given fs */
3735 int mgs_list_logs(const struct lu_env *env, struct mgs_device *mgs,
3736 struct obd_ioctl_data *data)
3738 struct list_head log_list;
3739 struct mgs_direntry *dirent, *n;
3745 /* Find all the logs in the CONFIGS directory */
3746 rc = class_dentry_readdir(env, mgs, &log_list);
3750 out = data->ioc_bulk;
3751 remains = data->ioc_inllen1;
3752 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
3753 list_del_init(&dirent->mde_list);
3754 suffix = strrchr(dirent->mde_name, '-');
3755 if (suffix != NULL) {
3756 l = snprintf(out, remains, "config log: $%s\n",
3761 mgs_direntry_free(dirent);
3768 /* from llog_swab */
3769 static void print_lustre_cfg(struct lustre_cfg *lcfg)
3774 CDEBUG(D_MGS, "lustre_cfg: %p\n", lcfg);
3775 CDEBUG(D_MGS, "\tlcfg->lcfg_version: %#x\n", lcfg->lcfg_version);
3777 CDEBUG(D_MGS, "\tlcfg->lcfg_command: %#x\n", lcfg->lcfg_command);
3778 CDEBUG(D_MGS, "\tlcfg->lcfg_num: %#x\n", lcfg->lcfg_num);
3779 CDEBUG(D_MGS, "\tlcfg->lcfg_flags: %#x\n", lcfg->lcfg_flags);
3780 CDEBUG(D_MGS, "\tlcfg->lcfg_nid: %s\n", libcfs_nid2str(lcfg->lcfg_nid));
3782 CDEBUG(D_MGS, "\tlcfg->lcfg_bufcount: %d\n", lcfg->lcfg_bufcount);
3783 if (lcfg->lcfg_bufcount < LUSTRE_CFG_MAX_BUFCOUNT)
3784 for (i = 0; i < lcfg->lcfg_bufcount; i++) {
3785 CDEBUG(D_MGS, "\tlcfg->lcfg_buflens[%d]: %d %s\n",
3786 i, lcfg->lcfg_buflens[i],
3787 lustre_cfg_string(lcfg, i));
3792 /* Setup params fsdb and log
3794 int mgs_params_fsdb_setup(const struct lu_env *env, struct mgs_device *mgs,
3797 struct llog_handle *params_llh = NULL;
3801 rc = mgs_find_or_make_fsdb(env, mgs, PARAMS_FILENAME, &fsdb);
3803 mutex_lock(&fsdb->fsdb_mutex);
3804 rc = record_start_log(env, mgs, ¶ms_llh, PARAMS_FILENAME);
3806 rc = record_end_log(env, ¶ms_llh);
3807 mutex_unlock(&fsdb->fsdb_mutex);
3813 /* Cleanup params fsdb and log
3815 int mgs_params_fsdb_cleanup(const struct lu_env *env, struct mgs_device *mgs)
3817 return mgs_erase_logs(env, mgs, PARAMS_FILENAME);
3820 /* Set a permanent (config log) param for a target or fs
3821 * \param lcfg buf0 may contain the device (testfs-MDT0000) name
3822 * buf1 contains the single parameter
3824 int mgs_setparam(const struct lu_env *env, struct mgs_device *mgs,
3825 struct lustre_cfg *lcfg, char *fsname)
3828 struct mgs_target_info *mti;
3829 char *devname, *param;
3836 print_lustre_cfg(lcfg);
3838 /* lustre, lustre-mdtlov, lustre-client, lustre-MDT0000 */
3839 devname = lustre_cfg_string(lcfg, 0);
3840 param = lustre_cfg_string(lcfg, 1);
3842 /* Assume device name embedded in param:
3843 lustre-OST0000.osc.max_dirty_mb=32 */
3844 ptr = strchr(param, '.');
3852 LCONSOLE_ERROR_MSG(0x14d, "No target specified: %s\n", param);
3856 rc = mgs_parse_devname(devname, fsname, NULL);
3857 if (rc == 0 && !mgs_parse_devname(devname, NULL, &index)) {
3858 /* param related to llite isn't allowed to set by OST or MDT */
3859 if (rc == 0 && strncmp(param, PARAM_LLITE,
3860 sizeof(PARAM_LLITE) - 1) == 0)
3863 /* assume devname is the fsname */
3864 memset(fsname, 0, MTI_NAME_MAXLEN);
3865 strncpy(fsname, devname, MTI_NAME_MAXLEN);
3866 fsname[MTI_NAME_MAXLEN - 1] = 0;
3868 CDEBUG(D_MGS, "setparam fs='%s' device='%s'\n", fsname, devname);
3870 rc = mgs_find_or_make_fsdb(env, mgs,
3871 lcfg->lcfg_command == LCFG_SET_PARAM ?
3872 PARAMS_FILENAME : fsname, &fsdb);
3876 if (lcfg->lcfg_command != LCFG_SET_PARAM &&
3877 !test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags) &&
3878 test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
3879 CERROR("No filesystem targets for %s. cfg_device from lctl "
3880 "is '%s'\n", fsname, devname);
3881 mgs_free_fsdb(mgs, fsdb);
3885 /* Create a fake mti to hold everything */
3888 GOTO(out, rc = -ENOMEM);
3889 if (strlcpy(mti->mti_fsname, fsname, sizeof(mti->mti_fsname))
3890 >= sizeof(mti->mti_fsname))
3891 GOTO(out, rc = -E2BIG);
3892 if (strlcpy(mti->mti_svname, devname, sizeof(mti->mti_svname))
3893 >= sizeof(mti->mti_svname))
3894 GOTO(out, rc = -E2BIG);
3895 if (strlcpy(mti->mti_params, param, sizeof(mti->mti_params))
3896 >= sizeof(mti->mti_params))
3897 GOTO(out, rc = -E2BIG);
3898 rc = server_name2index(mti->mti_svname, &mti->mti_stripe_index, &tmp);
3900 /* Not a valid server; may be only fsname */
3903 /* Strip -osc or -mdc suffix from svname */
3904 if (server_make_name(rc, mti->mti_stripe_index, mti->mti_fsname,
3906 GOTO(out, rc = -EINVAL);
3908 * Revoke lock so everyone updates. Should be alright if
3909 * someone was already reading while we were updating the logs,
3910 * so we don't really need to hold the lock while we're
3913 if (lcfg->lcfg_command == LCFG_SET_PARAM) {
3914 mti->mti_flags = rc | LDD_F_PARAM2;
3915 mutex_lock(&fsdb->fsdb_mutex);
3916 rc = mgs_write_log_param2(env, mgs, fsdb, mti, mti->mti_params);
3917 mutex_unlock(&fsdb->fsdb_mutex);
3918 mgs_revoke_lock(mgs, fsdb, CONFIG_T_PARAMS);
3920 mti->mti_flags = rc | LDD_F_PARAM;
3921 mutex_lock(&fsdb->fsdb_mutex);
3922 rc = mgs_write_log_param(env, mgs, fsdb, mti, mti->mti_params);
3923 mutex_unlock(&fsdb->fsdb_mutex);
3924 mgs_revoke_lock(mgs, fsdb, CONFIG_T_CONFIG);
3932 static int mgs_write_log_pool(const struct lu_env *env,
3933 struct mgs_device *mgs, char *logname,
3934 struct fs_db *fsdb, char *tgtname,
3935 enum lcfg_command_type cmd,
3936 char *fsname, char *poolname,
3937 char *ostname, char *comment)
3939 struct llog_handle *llh = NULL;
3942 rc = record_start_log(env, mgs, &llh, logname);
3945 rc = record_marker(env, llh, fsdb, CM_START, tgtname, comment);
3948 rc = record_base(env, llh, tgtname, 0, cmd,
3949 fsname, poolname, ostname, 0);
3952 rc = record_marker(env, llh, fsdb, CM_END, tgtname, comment);
3954 record_end_log(env, &llh);
3958 int mgs_nodemap_cmd(const struct lu_env *env, struct mgs_device *mgs,
3959 enum lcfg_command_type cmd, const char *nodemap_name,
3970 case LCFG_NODEMAP_ADD:
3971 rc = nodemap_add(nodemap_name);
3973 case LCFG_NODEMAP_DEL:
3974 rc = nodemap_del(nodemap_name);
3976 case LCFG_NODEMAP_ADD_RANGE:
3977 rc = nodemap_parse_range(param, nid);
3980 rc = nodemap_add_range(nodemap_name, nid);
3982 case LCFG_NODEMAP_DEL_RANGE:
3983 rc = nodemap_parse_range(param, nid);
3986 rc = nodemap_del_range(nodemap_name, nid);
3988 case LCFG_NODEMAP_ADMIN:
3989 bool_switch = simple_strtoul(param, NULL, 10);
3990 rc = nodemap_set_allow_root(nodemap_name, bool_switch);
3992 case LCFG_NODEMAP_TRUSTED:
3993 bool_switch = simple_strtoul(param, NULL, 10);
3994 rc = nodemap_set_trust_client_ids(nodemap_name, bool_switch);
3996 case LCFG_NODEMAP_SQUASH_UID:
3997 int_id = simple_strtoul(param, NULL, 10);
3998 rc = nodemap_set_squash_uid(nodemap_name, int_id);
4000 case LCFG_NODEMAP_SQUASH_GID:
4001 int_id = simple_strtoul(param, NULL, 10);
4002 rc = nodemap_set_squash_gid(nodemap_name, int_id);
4004 case LCFG_NODEMAP_ADD_UIDMAP:
4005 case LCFG_NODEMAP_ADD_GIDMAP:
4006 rc = nodemap_parse_idmap(param, idmap);
4009 if (cmd == LCFG_NODEMAP_ADD_UIDMAP)
4010 rc = nodemap_add_idmap(nodemap_name, NODEMAP_UID,
4013 rc = nodemap_add_idmap(nodemap_name, NODEMAP_GID,
4016 case LCFG_NODEMAP_DEL_UIDMAP:
4017 case LCFG_NODEMAP_DEL_GIDMAP:
4018 rc = nodemap_parse_idmap(param, idmap);
4021 if (cmd == LCFG_NODEMAP_DEL_UIDMAP)
4022 rc = nodemap_del_idmap(nodemap_name, NODEMAP_UID,
4025 rc = nodemap_del_idmap(nodemap_name, NODEMAP_GID,
4035 int mgs_pool_cmd(const struct lu_env *env, struct mgs_device *mgs,
4036 enum lcfg_command_type cmd, char *fsname,
4037 char *poolname, char *ostname)
4042 char *label = NULL, *canceled_label = NULL;
4044 struct mgs_target_info *mti = NULL;
4048 rc = mgs_find_or_make_fsdb(env, mgs, fsname, &fsdb);
4050 CERROR("Can't get db for %s\n", fsname);
4053 if (test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
4054 CERROR("%s is not defined\n", fsname);
4055 mgs_free_fsdb(mgs, fsdb);
4059 label_sz = 10 + strlen(fsname) + strlen(poolname);
4061 /* check if ostname match fsname */
4062 if (ostname != NULL) {
4065 ptr = strrchr(ostname, '-');
4066 if ((ptr == NULL) ||
4067 (strncmp(fsname, ostname, ptr-ostname) != 0))
4069 label_sz += strlen(ostname);
4072 OBD_ALLOC(label, label_sz);
4079 "new %s.%s", fsname, poolname);
4083 "add %s.%s.%s", fsname, poolname, ostname);
4086 OBD_ALLOC(canceled_label, label_sz);
4087 if (canceled_label == NULL)
4088 GOTO(out_label, rc = -ENOMEM);
4090 "rem %s.%s.%s", fsname, poolname, ostname);
4091 sprintf(canceled_label,
4092 "add %s.%s.%s", fsname, poolname, ostname);
4095 OBD_ALLOC(canceled_label, label_sz);
4096 if (canceled_label == NULL)
4097 GOTO(out_label, rc = -ENOMEM);
4099 "del %s.%s", fsname, poolname);
4100 sprintf(canceled_label,
4101 "new %s.%s", fsname, poolname);
4107 if (canceled_label != NULL) {
4110 GOTO(out_cancel, rc = -ENOMEM);
4113 mutex_lock(&fsdb->fsdb_mutex);
4114 /* write pool def to all MDT logs */
4115 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
4116 if (test_bit(i, fsdb->fsdb_mdt_index_map)) {
4117 rc = name_create_mdt_and_lov(&logname, &lovname,
4120 mutex_unlock(&fsdb->fsdb_mutex);
4123 if (canceled_label != NULL) {
4124 strcpy(mti->mti_svname, "lov pool");
4125 rc = mgs_modify(env, mgs, fsdb, mti, logname,
4126 lovname, canceled_label,
4131 rc = mgs_write_log_pool(env, mgs, logname,
4135 name_destroy(&logname);
4136 name_destroy(&lovname);
4138 mutex_unlock(&fsdb->fsdb_mutex);
4144 rc = name_create(&logname, fsname, "-client");
4146 mutex_unlock(&fsdb->fsdb_mutex);
4149 if (canceled_label != NULL) {
4150 rc = mgs_modify(env, mgs, fsdb, mti, logname,
4151 fsdb->fsdb_clilov, canceled_label, CM_SKIP);
4153 mutex_unlock(&fsdb->fsdb_mutex);
4154 name_destroy(&logname);
4159 rc = mgs_write_log_pool(env, mgs, logname, fsdb, fsdb->fsdb_clilov,
4160 cmd, fsname, poolname, ostname, label);
4161 mutex_unlock(&fsdb->fsdb_mutex);
4162 name_destroy(&logname);
4163 /* request for update */
4164 mgs_revoke_lock(mgs, fsdb, CONFIG_T_CONFIG);
4171 if (canceled_label != NULL)
4172 OBD_FREE(canceled_label, label_sz);
4174 OBD_FREE(label, label_sz);