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 strlcpy(mrul->target.mti_svname, devname,
1072 sizeof(mrul->target.mti_svname));
1073 /* parse nids later */
1074 strlcpy(mrul->target.mti_params, nids, sizeof(mrul->target.mti_params));
1075 /* Copy records to this temporary llog */
1076 mrul->temp_llh = orig_llh;
1078 rc = llog_process(env, backup_llh, mgs_replace_handler,
1079 (void *)mrul, NULL);
1082 rc2 = llog_close(NULL, backup_llh);
1086 rc2 = llog_close(NULL, orig_llh);
1092 CERROR("%s: llog should be restored: rc = %d\n",
1094 rc2 = llog_backup(env, mgs, ctxt, ctxt, backup,
1097 CERROR("%s: can't restore backup %s: rc = %d\n",
1098 mgs->obd_name, logname, rc2);
1102 OBD_FREE(backup, strlen(backup) + 1);
1105 llog_ctxt_put(ctxt);
1108 CERROR("%s: failed to replace nids in log %s: rc = %d\n",
1109 mgs->obd_name, logname, rc);
1115 * Parse device name and get file system name and/or device index
1117 * \param[in] devname device name (ex. lustre-MDT0000)
1118 * \param[out] fsname file system name(optional)
1119 * \param[out] index device index(optional)
1123 static int mgs_parse_devname(char *devname, char *fsname, __u32 *index)
1128 /* Extract fsname */
1130 rc = server_name2fsname(devname, fsname, NULL);
1132 CDEBUG(D_MGS, "Device name %s without fsname\n",
1139 rc = server_name2index(devname, index, NULL);
1141 CDEBUG(D_MGS, "Device name %s with wrong index\n",
1150 /* This is only called during replace_nids */
1151 static int only_mgs_is_running(struct obd_device *mgs_obd)
1153 /* TDB: Is global variable with devices count exists? */
1154 int num_devices = get_devices_count();
1155 int num_exports = 0;
1156 struct obd_export *exp;
1158 spin_lock(&mgs_obd->obd_dev_lock);
1159 list_for_each_entry(exp, &mgs_obd->obd_exports, exp_obd_chain) {
1160 /* skip self export */
1161 if (exp == mgs_obd->obd_self_export)
1163 if (exp_connect_flags(exp) & OBD_CONNECT_MDS_MDS)
1168 CERROR("%s: node %s still connected during replace_nids "
1169 "connect_flags:%llx\n",
1171 libcfs_nid2str(exp->exp_nid_stats->nid),
1172 exp_connect_flags(exp));
1175 spin_unlock(&mgs_obd->obd_dev_lock);
1177 /* osd, MGS and MGC + self_export
1178 (wc -l /proc/fs/lustre/devices <= 2) && (non self exports == 0) */
1179 return (num_devices <= 3) && (num_exports == 0);
1182 static int name_create_mdt(char **logname, char *fsname, int i)
1186 sprintf(mdt_index, "-MDT%04x", i);
1187 return name_create(logname, fsname, mdt_index);
1191 * Replace nids for \a device to \a nids values
1193 * \param obd MGS obd device
1194 * \param devname nids need to be replaced for this device
1195 * (ex. lustre-OST0000)
1196 * \param nids nids list (ex. nid1,nid2,nid3)
1200 int mgs_replace_nids(const struct lu_env *env,
1201 struct mgs_device *mgs,
1202 char *devname, char *nids)
1204 /* Assume fsname is part of device name */
1205 char fsname[MTI_NAME_MAXLEN];
1212 struct obd_device *mgs_obd = mgs->mgs_obd;
1215 /* We can only change NIDs if no other nodes are connected */
1216 spin_lock(&mgs_obd->obd_dev_lock);
1217 conn_state = mgs_obd->obd_no_conn;
1218 mgs_obd->obd_no_conn = 1;
1219 spin_unlock(&mgs_obd->obd_dev_lock);
1221 /* We can not change nids if not only MGS is started */
1222 if (!only_mgs_is_running(mgs_obd)) {
1223 CERROR("Only MGS is allowed to be started\n");
1224 GOTO(out, rc = -EINPROGRESS);
1227 /* Get fsname and index*/
1228 rc = mgs_parse_devname(devname, fsname, &index);
1232 rc = mgs_find_or_make_fsdb(env, mgs, fsname, &fsdb);
1234 CERROR("%s: can't find fsdb: rc = %d\n", fsname, rc);
1238 /* Process client llogs */
1239 name_create(&logname, fsname, "-client");
1240 rc = mgs_replace_nids_log(env, mgs_obd, fsdb, logname, devname, nids);
1241 name_destroy(&logname);
1243 CERROR("%s: error while replacing NIDs for %s: rc = %d\n",
1244 fsname, devname, rc);
1248 /* Process MDT llogs */
1249 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
1250 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
1252 name_create_mdt(&logname, fsname, i);
1253 rc = mgs_replace_nids_log(env, mgs_obd, fsdb, logname, devname, nids);
1254 name_destroy(&logname);
1260 spin_lock(&mgs_obd->obd_dev_lock);
1261 mgs_obd->obd_no_conn = conn_state;
1262 spin_unlock(&mgs_obd->obd_dev_lock);
1267 static int record_lov_setup(const struct lu_env *env, struct llog_handle *llh,
1268 char *devname, struct lov_desc *desc)
1270 struct mgs_thread_info *mgi = mgs_env_info(env);
1271 struct llog_cfg_rec *lcr;
1274 lustre_cfg_bufs_reset(&mgi->mgi_bufs, devname);
1275 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, desc, sizeof(*desc));
1276 lcr = lustre_cfg_rec_new(LCFG_SETUP, &mgi->mgi_bufs);
1280 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1281 lustre_cfg_rec_free(lcr);
1285 static int record_lmv_setup(const struct lu_env *env, struct llog_handle *llh,
1286 char *devname, struct lmv_desc *desc)
1288 struct mgs_thread_info *mgi = mgs_env_info(env);
1289 struct llog_cfg_rec *lcr;
1292 lustre_cfg_bufs_reset(&mgi->mgi_bufs, devname);
1293 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, desc, sizeof(*desc));
1294 lcr = lustre_cfg_rec_new(LCFG_SETUP, &mgi->mgi_bufs);
1298 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1299 lustre_cfg_rec_free(lcr);
1303 static inline int record_mdc_add(const struct lu_env *env,
1304 struct llog_handle *llh,
1305 char *logname, char *mdcuuid,
1306 char *mdtuuid, char *index,
1309 return record_base(env,llh,logname,0,LCFG_ADD_MDC,
1310 mdtuuid,index,gen,mdcuuid);
1313 static inline int record_lov_add(const struct lu_env *env,
1314 struct llog_handle *llh,
1315 char *lov_name, char *ost_uuid,
1316 char *index, char *gen)
1318 return record_base(env,llh,lov_name,0,LCFG_LOV_ADD_OBD,
1319 ost_uuid, index, gen, 0);
1322 static inline int record_mount_opt(const struct lu_env *env,
1323 struct llog_handle *llh,
1324 char *profile, char *lov_name,
1327 return record_base(env,llh,NULL,0,LCFG_MOUNTOPT,
1328 profile,lov_name,mdc_name,0);
1331 static int record_marker(const struct lu_env *env,
1332 struct llog_handle *llh,
1333 struct fs_db *fsdb, __u32 flags,
1334 char *tgtname, char *comment)
1336 struct mgs_thread_info *mgi = mgs_env_info(env);
1337 struct llog_cfg_rec *lcr;
1341 if (flags & CM_START)
1343 mgi->mgi_marker.cm_step = fsdb->fsdb_gen;
1344 mgi->mgi_marker.cm_flags = flags;
1345 mgi->mgi_marker.cm_vers = LUSTRE_VERSION_CODE;
1346 cplen = strlcpy(mgi->mgi_marker.cm_tgtname, tgtname,
1347 sizeof(mgi->mgi_marker.cm_tgtname));
1348 if (cplen >= sizeof(mgi->mgi_marker.cm_tgtname))
1350 cplen = strlcpy(mgi->mgi_marker.cm_comment, comment,
1351 sizeof(mgi->mgi_marker.cm_comment));
1352 if (cplen >= sizeof(mgi->mgi_marker.cm_comment))
1354 mgi->mgi_marker.cm_createtime = cfs_time_current_sec();
1355 mgi->mgi_marker.cm_canceltime = 0;
1356 lustre_cfg_bufs_reset(&mgi->mgi_bufs, NULL);
1357 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, &mgi->mgi_marker,
1358 sizeof(mgi->mgi_marker));
1359 lcr = lustre_cfg_rec_new(LCFG_MARKER, &mgi->mgi_bufs);
1363 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1364 lustre_cfg_rec_free(lcr);
1368 static int record_start_log(const struct lu_env *env, struct mgs_device *mgs,
1369 struct llog_handle **llh, char *name)
1371 static struct obd_uuid cfg_uuid = { .uuid = "config_uuid" };
1372 struct llog_ctxt *ctxt;
1377 GOTO(out, rc = -EBUSY);
1379 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
1381 GOTO(out, rc = -ENODEV);
1382 LASSERT(ctxt->loc_obd == mgs->mgs_obd);
1384 rc = llog_open_create(env, ctxt, llh, NULL, name);
1387 rc = llog_init_handle(env, *llh, LLOG_F_IS_PLAIN, &cfg_uuid);
1389 llog_close(env, *llh);
1391 llog_ctxt_put(ctxt);
1394 CERROR("%s: can't start log %s: rc = %d\n",
1395 mgs->mgs_obd->obd_name, name, rc);
1401 static int record_end_log(const struct lu_env *env, struct llog_handle **llh)
1405 rc = llog_close(env, *llh);
1411 /******************** config "macros" *********************/
1413 /* write an lcfg directly into a log (with markers) */
1414 static int mgs_write_log_direct(const struct lu_env *env,
1415 struct mgs_device *mgs, struct fs_db *fsdb,
1416 char *logname, struct llog_cfg_rec *lcr,
1417 char *devname, char *comment)
1419 struct llog_handle *llh = NULL;
1424 rc = record_start_log(env, mgs, &llh, logname);
1428 /* FIXME These should be a single journal transaction */
1429 rc = record_marker(env, llh, fsdb, CM_START, devname, comment);
1432 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1435 rc = record_marker(env, llh, fsdb, CM_END, devname, comment);
1439 record_end_log(env, &llh);
1443 /* write the lcfg in all logs for the given fs */
1444 int mgs_write_log_direct_all(const struct lu_env *env, struct mgs_device *mgs,
1445 struct fs_db *fsdb, struct mgs_target_info *mti,
1446 struct llog_cfg_rec *lcr, char *devname,
1447 char *comment, int server_only)
1449 struct list_head log_list;
1450 struct mgs_direntry *dirent, *n;
1451 char *fsname = mti->mti_fsname;
1452 int rc = 0, len = strlen(fsname);
1455 /* Find all the logs in the CONFIGS directory */
1456 rc = class_dentry_readdir(env, mgs, &log_list);
1460 /* Could use fsdb index maps instead of directory listing */
1461 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
1462 list_del_init(&dirent->mde_list);
1463 /* don't write to sptlrpc rule log */
1464 if (strstr(dirent->mde_name, "-sptlrpc") != NULL)
1467 /* caller wants write server logs only */
1468 if (server_only && strstr(dirent->mde_name, "-client") != NULL)
1471 if (strncmp(fsname, dirent->mde_name, len) != 0)
1474 CDEBUG(D_MGS, "Changing log %s\n", dirent->mde_name);
1475 /* Erase any old settings of this same parameter */
1476 rc = mgs_modify(env, mgs, fsdb, mti, dirent->mde_name,
1477 devname, comment, CM_SKIP);
1479 CERROR("%s: Can't modify llog %s: rc = %d\n",
1480 mgs->mgs_obd->obd_name, dirent->mde_name, rc);
1483 /* Write the new one */
1484 rc = mgs_write_log_direct(env, mgs, fsdb, dirent->mde_name,
1485 lcr, devname, comment);
1487 CERROR("%s: writing log %s: rc = %d\n",
1488 mgs->mgs_obd->obd_name, dirent->mde_name, rc);
1490 mgs_direntry_free(dirent);
1496 static int mgs_write_log_osp_to_mdt(const struct lu_env *env,
1497 struct mgs_device *mgs,
1499 struct mgs_target_info *mti,
1500 int index, char *logname);
1501 static int mgs_write_log_osc_to_lov(const struct lu_env *env,
1502 struct mgs_device *mgs,
1504 struct mgs_target_info *mti,
1505 char *logname, char *suffix, char *lovname,
1506 enum lustre_sec_part sec_part, int flags);
1507 static int name_create_mdt_and_lov(char **logname, char **lovname,
1508 struct fs_db *fsdb, int i);
1510 static int add_param(char *params, char *key, char *val)
1512 char *start = params + strlen(params);
1513 char *end = params + sizeof(((struct mgs_target_info *)0)->mti_params);
1517 keylen = strlen(key);
1518 if (start + 1 + keylen + strlen(val) >= end) {
1519 CERROR("params are too long: %s %s%s\n",
1520 params, key != NULL ? key : "", val);
1524 sprintf(start, " %s%s", key != NULL ? key : "", val);
1529 * Walk through client config log record and convert the related records
1532 static int mgs_steal_client_llog_handler(const struct lu_env *env,
1533 struct llog_handle *llh,
1534 struct llog_rec_hdr *rec, void *data)
1536 struct mgs_device *mgs;
1537 struct obd_device *obd;
1538 struct mgs_target_info *mti, *tmti;
1540 int cfg_len = rec->lrh_len;
1541 char *cfg_buf = (char*) (rec + 1);
1542 struct lustre_cfg *lcfg;
1544 struct llog_handle *mdt_llh = NULL;
1545 static int got_an_osc_or_mdc = 0;
1546 /* 0: not found any osc/mdc;
1550 static int last_step = -1;
1555 mti = ((struct temp_comp*)data)->comp_mti;
1556 tmti = ((struct temp_comp*)data)->comp_tmti;
1557 fsdb = ((struct temp_comp*)data)->comp_fsdb;
1558 obd = ((struct temp_comp *)data)->comp_obd;
1559 mgs = lu2mgs_dev(obd->obd_lu_dev);
1562 if (rec->lrh_type != OBD_CFG_REC) {
1563 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
1567 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
1569 CERROR("Insane cfg\n");
1573 lcfg = (struct lustre_cfg *)cfg_buf;
1575 if (lcfg->lcfg_command == LCFG_MARKER) {
1576 struct cfg_marker *marker;
1577 marker = lustre_cfg_buf(lcfg, 1);
1578 if (!strncmp(marker->cm_comment, "add osc", 7) &&
1579 (marker->cm_flags & CM_START) &&
1580 !(marker->cm_flags & CM_SKIP)) {
1581 got_an_osc_or_mdc = 1;
1582 cplen = strlcpy(tmti->mti_svname, marker->cm_tgtname,
1583 sizeof(tmti->mti_svname));
1584 if (cplen >= sizeof(tmti->mti_svname))
1586 rc = record_start_log(env, mgs, &mdt_llh,
1590 rc = record_marker(env, mdt_llh, fsdb, CM_START,
1591 mti->mti_svname, "add osc(copied)");
1592 record_end_log(env, &mdt_llh);
1593 last_step = marker->cm_step;
1596 if (!strncmp(marker->cm_comment, "add osc", 7) &&
1597 (marker->cm_flags & CM_END) &&
1598 !(marker->cm_flags & CM_SKIP)) {
1599 LASSERT(last_step == marker->cm_step);
1601 got_an_osc_or_mdc = 0;
1602 memset(tmti, 0, sizeof(*tmti));
1603 rc = record_start_log(env, mgs, &mdt_llh,
1607 rc = record_marker(env, mdt_llh, fsdb, CM_END,
1608 mti->mti_svname, "add osc(copied)");
1609 record_end_log(env, &mdt_llh);
1612 if (!strncmp(marker->cm_comment, "add mdc", 7) &&
1613 (marker->cm_flags & CM_START) &&
1614 !(marker->cm_flags & CM_SKIP)) {
1615 got_an_osc_or_mdc = 2;
1616 last_step = marker->cm_step;
1617 memcpy(tmti->mti_svname, marker->cm_tgtname,
1618 strlen(marker->cm_tgtname));
1622 if (!strncmp(marker->cm_comment, "add mdc", 7) &&
1623 (marker->cm_flags & CM_END) &&
1624 !(marker->cm_flags & CM_SKIP)) {
1625 LASSERT(last_step == marker->cm_step);
1627 got_an_osc_or_mdc = 0;
1628 memset(tmti, 0, sizeof(*tmti));
1633 if (got_an_osc_or_mdc == 0 || last_step < 0)
1636 if (lcfg->lcfg_command == LCFG_ADD_UUID) {
1637 uint64_t nodenid = lcfg->lcfg_nid;
1639 if (strlen(tmti->mti_uuid) == 0) {
1640 /* target uuid not set, this config record is before
1641 * LCFG_SETUP, this nid is one of target node nid.
1643 tmti->mti_nids[tmti->mti_nid_count] = nodenid;
1644 tmti->mti_nid_count++;
1646 /* failover node nid */
1647 rc = add_param(tmti->mti_params, PARAM_FAILNODE,
1648 libcfs_nid2str(nodenid));
1654 if (lcfg->lcfg_command == LCFG_SETUP) {
1657 target = lustre_cfg_string(lcfg, 1);
1658 memcpy(tmti->mti_uuid, target, strlen(target));
1662 /* ignore client side sptlrpc_conf_log */
1663 if (lcfg->lcfg_command == LCFG_SPTLRPC_CONF)
1666 if (lcfg->lcfg_command == LCFG_ADD_MDC) {
1669 if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1)
1672 memcpy(tmti->mti_fsname, mti->mti_fsname,
1673 strlen(mti->mti_fsname));
1674 tmti->mti_stripe_index = index;
1676 rc = mgs_write_log_osp_to_mdt(env, mgs, fsdb, tmti,
1677 mti->mti_stripe_index,
1679 memset(tmti, 0, sizeof(*tmti));
1683 if (lcfg->lcfg_command == LCFG_LOV_ADD_OBD) {
1686 char *logname, *lovname;
1688 rc = name_create_mdt_and_lov(&logname, &lovname, fsdb,
1689 mti->mti_stripe_index);
1692 sprintf(mdt_index, "-MDT%04x", mti->mti_stripe_index);
1694 if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1) {
1695 name_destroy(&logname);
1696 name_destroy(&lovname);
1700 tmti->mti_stripe_index = index;
1701 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, tmti, logname,
1704 name_destroy(&logname);
1705 name_destroy(&lovname);
1711 /* fsdb->fsdb_mutex is already held in mgs_write_log_target*/
1712 /* stealed from mgs_get_fsdb_from_llog*/
1713 static int mgs_steal_llog_for_mdt_from_client(const struct lu_env *env,
1714 struct mgs_device *mgs,
1716 struct temp_comp* comp)
1718 struct llog_handle *loghandle;
1719 struct mgs_target_info *tmti;
1720 struct llog_ctxt *ctxt;
1725 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
1726 LASSERT(ctxt != NULL);
1728 OBD_ALLOC_PTR(tmti);
1730 GOTO(out_ctxt, rc = -ENOMEM);
1732 comp->comp_tmti = tmti;
1733 comp->comp_obd = mgs->mgs_obd;
1735 rc = llog_open(env, ctxt, &loghandle, NULL, client_name,
1743 rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL);
1745 GOTO(out_close, rc);
1747 rc = llog_process_or_fork(env, loghandle, mgs_steal_client_llog_handler,
1748 (void *)comp, NULL, false);
1749 CDEBUG(D_MGS, "steal llog re = %d\n", rc);
1751 llog_close(env, loghandle);
1755 llog_ctxt_put(ctxt);
1759 /* lmv is the second thing for client logs */
1760 /* copied from mgs_write_log_lov. Please refer to that. */
1761 static int mgs_write_log_lmv(const struct lu_env *env,
1762 struct mgs_device *mgs,
1764 struct mgs_target_info *mti,
1765 char *logname, char *lmvname)
1767 struct llog_handle *llh = NULL;
1768 struct lmv_desc *lmvdesc;
1773 CDEBUG(D_MGS, "Writing lmv(%s) log for %s\n", lmvname,logname);
1775 OBD_ALLOC_PTR(lmvdesc);
1776 if (lmvdesc == NULL)
1778 lmvdesc->ld_active_tgt_count = 0;
1779 lmvdesc->ld_tgt_count = 0;
1780 sprintf((char*)lmvdesc->ld_uuid.uuid, "%s_UUID", lmvname);
1781 uuid = (char *)lmvdesc->ld_uuid.uuid;
1783 rc = record_start_log(env, mgs, &llh, logname);
1786 rc = record_marker(env, llh, fsdb, CM_START, lmvname, "lmv setup");
1789 rc = record_attach(env, llh, lmvname, "lmv", uuid);
1792 rc = record_lmv_setup(env, llh, lmvname, lmvdesc);
1795 rc = record_marker(env, llh, fsdb, CM_END, lmvname, "lmv setup");
1799 record_end_log(env, &llh);
1801 OBD_FREE_PTR(lmvdesc);
1805 /* lov is the first thing in the mdt and client logs */
1806 static int mgs_write_log_lov(const struct lu_env *env, struct mgs_device *mgs,
1807 struct fs_db *fsdb, struct mgs_target_info *mti,
1808 char *logname, char *lovname)
1810 struct llog_handle *llh = NULL;
1811 struct lov_desc *lovdesc;
1816 CDEBUG(D_MGS, "Writing lov(%s) log for %s\n", lovname, logname);
1819 #01 L attach 0:lov_mdsA 1:lov 2:71ccb_lov_mdsA_19f961a9e1
1820 #02 L lov_setup 0:lov_mdsA 1:(struct lov_desc)
1821 uuid=lov1_UUID, stripe count=1, size=1048576, offset=0, pattern=0
1824 /* FIXME just make lov_setup accept empty desc (put uuid in buf 2) */
1825 OBD_ALLOC_PTR(lovdesc);
1826 if (lovdesc == NULL)
1828 lovdesc->ld_magic = LOV_DESC_MAGIC;
1829 lovdesc->ld_tgt_count = 0;
1830 /* Defaults. Can be changed later by lcfg config_param */
1831 lovdesc->ld_default_stripe_count = 1;
1832 lovdesc->ld_pattern = LOV_PATTERN_RAID0;
1833 lovdesc->ld_default_stripe_size = LOV_DESC_STRIPE_SIZE_DEFAULT;
1834 lovdesc->ld_default_stripe_offset = -1;
1835 lovdesc->ld_qos_maxage = LOV_DESC_QOS_MAXAGE_DEFAULT;
1836 sprintf((char*)lovdesc->ld_uuid.uuid, "%s_UUID", lovname);
1837 /* can these be the same? */
1838 uuid = (char *)lovdesc->ld_uuid.uuid;
1840 /* This should always be the first entry in a log.
1841 rc = mgs_clear_log(obd, logname); */
1842 rc = record_start_log(env, mgs, &llh, logname);
1845 /* FIXME these should be a single journal transaction */
1846 rc = record_marker(env, llh, fsdb, CM_START, lovname, "lov setup");
1849 rc = record_attach(env, llh, lovname, "lov", uuid);
1852 rc = record_lov_setup(env, llh, lovname, lovdesc);
1855 rc = record_marker(env, llh, fsdb, CM_END, lovname, "lov setup");
1860 record_end_log(env, &llh);
1862 OBD_FREE_PTR(lovdesc);
1866 /* add failnids to open log */
1867 static int mgs_write_log_failnids(const struct lu_env *env,
1868 struct mgs_target_info *mti,
1869 struct llog_handle *llh,
1872 char *failnodeuuid = NULL;
1873 char *ptr = mti->mti_params;
1878 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) nal=90 0: 1:uml1_UUID
1879 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
1880 #05 L setup 0:OSC_uml1_ost1_mdsA 1:ost1_UUID 2:uml1_UUID
1881 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) nal=90 0: 1:uml2_UUID
1882 #0x L add_uuid nid=2@elan(0x1000000000002) nal=90 0: 1:uml2_UUID
1883 #07 L add_conn 0:OSC_uml1_ost1_mdsA 1:uml2_UUID
1887 * Pull failnid info out of params string, which may contain something
1888 * like "<nid1>,<nid2>:<nid3>,<nid4>". class_parse_nid() does not
1889 * complain about abnormal inputs like ",:<nid1>", "<nid1>:,<nid2>",
1890 * etc. However, convert_hostnames() should have caught those.
1892 while (class_find_param(ptr, PARAM_FAILNODE, &ptr) == 0) {
1893 while (class_parse_nid(ptr, &nid, &ptr) == 0) {
1894 if (failnodeuuid == NULL) {
1895 /* We don't know the failover node name,
1896 so just use the first nid as the uuid */
1897 rc = name_create(&failnodeuuid,
1898 libcfs_nid2str(nid), "");
1902 CDEBUG(D_MGS, "add nid %s for failover uuid %s, "
1903 "client %s\n", libcfs_nid2str(nid),
1904 failnodeuuid, cliname);
1905 rc = record_add_uuid(env, llh, nid, failnodeuuid);
1907 * If *ptr is ':', we have added all NIDs for
1911 rc = record_add_conn(env, llh, cliname,
1913 name_destroy(&failnodeuuid);
1914 failnodeuuid = NULL;
1918 rc = record_add_conn(env, llh, cliname, failnodeuuid);
1919 name_destroy(&failnodeuuid);
1920 failnodeuuid = NULL;
1927 static int mgs_write_log_mdc_to_lmv(const struct lu_env *env,
1928 struct mgs_device *mgs,
1930 struct mgs_target_info *mti,
1931 char *logname, char *lmvname)
1933 struct llog_handle *llh = NULL;
1934 char *mdcname = NULL;
1935 char *nodeuuid = NULL;
1936 char *mdcuuid = NULL;
1937 char *lmvuuid = NULL;
1942 if (mgs_log_is_empty(env, mgs, logname)) {
1943 CERROR("log is empty! Logical error\n");
1947 CDEBUG(D_MGS, "adding mdc for %s to log %s:lmv(%s)\n",
1948 mti->mti_svname, logname, lmvname);
1950 rc = name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
1953 rc = name_create(&mdcname, mti->mti_svname, "-mdc");
1956 rc = name_create(&mdcuuid, mdcname, "_UUID");
1959 rc = name_create(&lmvuuid, lmvname, "_UUID");
1963 rc = record_start_log(env, mgs, &llh, logname);
1966 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
1970 for (i = 0; i < mti->mti_nid_count; i++) {
1971 CDEBUG(D_MGS, "add nid %s for mdt\n",
1972 libcfs_nid2str(mti->mti_nids[i]));
1974 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
1979 rc = record_attach(env, llh, mdcname, LUSTRE_MDC_NAME, lmvuuid);
1982 rc = record_setup(env, llh, mdcname, mti->mti_uuid, nodeuuid, 0, 0);
1985 rc = mgs_write_log_failnids(env, mti, llh, mdcname);
1988 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
1989 rc = record_mdc_add(env, llh, lmvname, mdcuuid, mti->mti_uuid,
1993 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname,
1998 record_end_log(env, &llh);
2000 name_destroy(&lmvuuid);
2001 name_destroy(&mdcuuid);
2002 name_destroy(&mdcname);
2003 name_destroy(&nodeuuid);
2007 static inline int name_create_lov(char **lovname, char *mdtname,
2008 struct fs_db *fsdb, int index)
2011 if (index == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2012 return name_create(lovname, fsdb->fsdb_name, "-mdtlov");
2014 return name_create(lovname, mdtname, "-mdtlov");
2017 static int name_create_mdt_and_lov(char **logname, char **lovname,
2018 struct fs_db *fsdb, int i)
2022 rc = name_create_mdt(logname, fsdb->fsdb_name, i);
2026 if (i == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2027 rc = name_create(lovname, fsdb->fsdb_name, "-mdtlov");
2029 rc = name_create(lovname, *logname, "-mdtlov");
2031 name_destroy(logname);
2037 static inline int name_create_mdt_osc(char **oscname, char *ostname,
2038 struct fs_db *fsdb, int i)
2042 if (i == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2043 sprintf(suffix, "-osc");
2045 sprintf(suffix, "-osc-MDT%04x", i);
2046 return name_create(oscname, ostname, suffix);
2049 /* add new mdc to already existent MDS */
2050 static int mgs_write_log_osp_to_mdt(const struct lu_env *env,
2051 struct mgs_device *mgs,
2053 struct mgs_target_info *mti,
2054 int mdt_index, char *logname)
2056 struct llog_handle *llh = NULL;
2057 char *nodeuuid = NULL;
2058 char *ospname = NULL;
2059 char *lovuuid = NULL;
2060 char *mdtuuid = NULL;
2061 char *svname = NULL;
2062 char *mdtname = NULL;
2063 char *lovname = NULL;
2068 if (mgs_log_is_empty(env, mgs, mti->mti_svname)) {
2069 CERROR("log is empty! Logical error\n");
2073 CDEBUG(D_MGS, "adding osp index %d to %s\n", mti->mti_stripe_index,
2076 rc = name_create_mdt(&mdtname, fsdb->fsdb_name, mti->mti_stripe_index);
2080 rc = name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
2082 GOTO(out_destory, rc);
2084 rc = name_create(&svname, mdtname, "-osp");
2086 GOTO(out_destory, rc);
2088 sprintf(index_str, "-MDT%04x", mdt_index);
2089 rc = name_create(&ospname, svname, index_str);
2091 GOTO(out_destory, rc);
2093 rc = name_create_lov(&lovname, logname, fsdb, mdt_index);
2095 GOTO(out_destory, rc);
2097 rc = name_create(&lovuuid, lovname, "_UUID");
2099 GOTO(out_destory, rc);
2101 rc = name_create(&mdtuuid, mdtname, "_UUID");
2103 GOTO(out_destory, rc);
2105 rc = record_start_log(env, mgs, &llh, logname);
2107 GOTO(out_destory, rc);
2109 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
2112 GOTO(out_destory, rc);
2114 for (i = 0; i < mti->mti_nid_count; i++) {
2115 CDEBUG(D_MGS, "add nid %s for mdt\n",
2116 libcfs_nid2str(mti->mti_nids[i]));
2117 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
2122 rc = record_attach(env, llh, ospname, LUSTRE_OSP_NAME, lovuuid);
2126 rc = record_setup(env, llh, ospname, mti->mti_uuid, nodeuuid,
2131 rc = mgs_write_log_failnids(env, mti, llh, ospname);
2135 /* Add mdc(osp) to lod */
2136 snprintf(index_str, sizeof(mti->mti_stripe_index), "%d",
2137 mti->mti_stripe_index);
2138 rc = record_base(env, llh, lovname, 0, LCFG_ADD_MDC, mti->mti_uuid,
2139 index_str, "1", NULL);
2143 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname, "add osp");
2148 record_end_log(env, &llh);
2151 name_destroy(&mdtuuid);
2152 name_destroy(&lovuuid);
2153 name_destroy(&lovname);
2154 name_destroy(&ospname);
2155 name_destroy(&svname);
2156 name_destroy(&nodeuuid);
2157 name_destroy(&mdtname);
2161 static int mgs_write_log_mdt0(const struct lu_env *env,
2162 struct mgs_device *mgs,
2164 struct mgs_target_info *mti)
2166 char *log = mti->mti_svname;
2167 struct llog_handle *llh = NULL;
2168 char *uuid, *lovname;
2170 char *ptr = mti->mti_params;
2171 int rc = 0, failout = 0;
2174 OBD_ALLOC(uuid, sizeof(struct obd_uuid));
2178 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
2179 failout = (strncmp(ptr, "failout", 7) == 0);
2181 rc = name_create(&lovname, log, "-mdtlov");
2184 if (mgs_log_is_empty(env, mgs, log)) {
2185 rc = mgs_write_log_lov(env, mgs, fsdb, mti, log, lovname);
2190 sprintf(mdt_index, "%d", mti->mti_stripe_index);
2192 rc = record_start_log(env, mgs, &llh, log);
2196 /* add MDT itself */
2198 /* FIXME this whole fn should be a single journal transaction */
2199 sprintf(uuid, "%s_UUID", log);
2200 rc = record_marker(env, llh, fsdb, CM_START, log, "add mdt");
2203 rc = record_attach(env, llh, log, LUSTRE_MDT_NAME, uuid);
2206 rc = record_mount_opt(env, llh, log, lovname, NULL);
2209 rc = record_setup(env, llh, log, uuid, mdt_index, lovname,
2210 failout ? "n" : "f");
2213 rc = record_marker(env, llh, fsdb, CM_END, log, "add mdt");
2217 record_end_log(env, &llh);
2219 name_destroy(&lovname);
2221 OBD_FREE(uuid, sizeof(struct obd_uuid));
2225 /* envelope method for all layers log */
2226 static int mgs_write_log_mdt(const struct lu_env *env,
2227 struct mgs_device *mgs,
2229 struct mgs_target_info *mti)
2231 struct mgs_thread_info *mgi = mgs_env_info(env);
2232 struct llog_handle *llh = NULL;
2237 CDEBUG(D_MGS, "writing new mdt %s\n", mti->mti_svname);
2239 if (mti->mti_uuid[0] == '\0') {
2240 /* Make up our own uuid */
2241 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
2242 "%s_UUID", mti->mti_svname);
2246 rc = mgs_write_log_mdt0(env, mgs, fsdb, mti);
2249 /* Append the mdt info to the client log */
2250 rc = name_create(&cliname, mti->mti_fsname, "-client");
2254 if (mgs_log_is_empty(env, mgs, cliname)) {
2255 /* Start client log */
2256 rc = mgs_write_log_lov(env, mgs, fsdb, mti, cliname,
2260 rc = mgs_write_log_lmv(env, mgs, fsdb, mti, cliname,
2267 #09 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
2268 #10 L attach 0:MDC_uml1_mdsA_MNT_client 1:mdc 2:1d834_MNT_client_03f
2269 #11 L setup 0:MDC_uml1_mdsA_MNT_client 1:mdsA_UUID 2:uml1_UUID
2270 #12 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
2271 #13 L add_conn 0:MDC_uml1_mdsA_MNT_client 1:uml2_UUID
2272 #14 L mount_option 0: 1:client 2:lov1 3:MDC_uml1_mdsA_MNT_client
2275 /* copy client info about lov/lmv */
2276 mgi->mgi_comp.comp_mti = mti;
2277 mgi->mgi_comp.comp_fsdb = fsdb;
2279 rc = mgs_steal_llog_for_mdt_from_client(env, mgs, cliname,
2283 rc = mgs_write_log_mdc_to_lmv(env, mgs, fsdb, mti, cliname,
2289 rc = record_start_log(env, mgs, &llh, cliname);
2293 rc = record_marker(env, llh, fsdb, CM_START, cliname,
2297 rc = record_mount_opt(env, llh, cliname, fsdb->fsdb_clilov,
2301 rc = record_marker(env, llh, fsdb, CM_END, cliname,
2307 /* for_all_existing_mdt except current one */
2308 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2309 if (i != mti->mti_stripe_index &&
2310 test_bit(i, fsdb->fsdb_mdt_index_map)) {
2313 rc = name_create_mdt(&logname, fsdb->fsdb_name, i);
2317 rc = mgs_write_log_osp_to_mdt(env, mgs, fsdb, mti,
2319 name_destroy(&logname);
2325 record_end_log(env, &llh);
2327 name_destroy(&cliname);
2331 /* Add the ost info to the client/mdt lov */
2332 static int mgs_write_log_osc_to_lov(const struct lu_env *env,
2333 struct mgs_device *mgs, struct fs_db *fsdb,
2334 struct mgs_target_info *mti,
2335 char *logname, char *suffix, char *lovname,
2336 enum lustre_sec_part sec_part, int flags)
2338 struct llog_handle *llh = NULL;
2339 char *nodeuuid = NULL;
2340 char *oscname = NULL;
2341 char *oscuuid = NULL;
2342 char *lovuuid = NULL;
2343 char *svname = NULL;
2348 CDEBUG(D_INFO, "adding osc for %s to log %s\n",
2349 mti->mti_svname, logname);
2351 if (mgs_log_is_empty(env, mgs, logname)) {
2352 CERROR("log is empty! Logical error\n");
2356 rc = name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
2359 rc = name_create(&svname, mti->mti_svname, "-osc");
2363 /* for the system upgraded from old 1.8, keep using the old osc naming
2364 * style for mdt, see name_create_mdt_osc(). LU-1257 */
2365 if (test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2366 rc = name_create(&oscname, svname, "");
2368 rc = name_create(&oscname, svname, suffix);
2372 rc = name_create(&oscuuid, oscname, "_UUID");
2375 rc = name_create(&lovuuid, lovname, "_UUID");
2381 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
2383 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
2384 #04 L attach 0:OSC_uml1_ost1_MNT_client 1:osc 2:89070_lov1_a41dff51a
2385 #05 L setup 0:OSC_uml1_ost1_MNT_client 1:ost1_UUID 2:uml1_UUID
2387 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
2388 #07 L add_conn 0:OSC_uml1_ost1_MNT_client 1:uml2_UUID
2389 #08 L lov_modify_tgts add 0:lov1 1:ost1_UUID 2(index):0 3(gen):1
2392 rc = record_start_log(env, mgs, &llh, logname);
2396 /* FIXME these should be a single journal transaction */
2397 rc = record_marker(env, llh, fsdb, CM_START | flags, mti->mti_svname,
2402 /* NB: don't change record order, because upon MDT steal OSC config
2403 * from client, it treats all nids before LCFG_SETUP as target nids
2404 * (multiple interfaces), while nids after as failover node nids.
2405 * See mgs_steal_client_llog_handler() LCFG_ADD_UUID.
2407 for (i = 0; i < mti->mti_nid_count; i++) {
2408 CDEBUG(D_MGS, "add nid %s\n", libcfs_nid2str(mti->mti_nids[i]));
2409 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
2413 rc = record_attach(env, llh, oscname, LUSTRE_OSC_NAME, lovuuid);
2416 rc = record_setup(env, llh, oscname, mti->mti_uuid, nodeuuid, 0, 0);
2419 rc = mgs_write_log_failnids(env, mti, llh, oscname);
2423 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
2425 rc = record_lov_add(env, llh, lovname, mti->mti_uuid, index, "1");
2428 rc = record_marker(env, llh, fsdb, CM_END | flags, mti->mti_svname,
2433 record_end_log(env, &llh);
2435 name_destroy(&lovuuid);
2436 name_destroy(&oscuuid);
2437 name_destroy(&oscname);
2438 name_destroy(&svname);
2439 name_destroy(&nodeuuid);
2443 static int mgs_write_log_ost(const struct lu_env *env,
2444 struct mgs_device *mgs, struct fs_db *fsdb,
2445 struct mgs_target_info *mti)
2447 struct llog_handle *llh = NULL;
2448 char *logname, *lovname;
2449 char *ptr = mti->mti_params;
2450 int rc, flags = 0, failout = 0, i;
2453 CDEBUG(D_MGS, "writing new ost %s\n", mti->mti_svname);
2455 /* The ost startup log */
2457 /* If the ost log already exists, that means that someone reformatted
2458 the ost and it called target_add again. */
2459 if (!mgs_log_is_empty(env, mgs, mti->mti_svname)) {
2460 LCONSOLE_ERROR_MSG(0x141, "The config log for %s already "
2461 "exists, yet the server claims it never "
2462 "registered. It may have been reformatted, "
2463 "or the index changed. writeconf the MDT to "
2464 "regenerate all logs.\n", mti->mti_svname);
2469 attach obdfilter ost1 ost1_UUID
2470 setup /dev/loop2 ldiskfs f|n errors=remount-ro,user_xattr
2472 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
2473 failout = (strncmp(ptr, "failout", 7) == 0);
2474 rc = record_start_log(env, mgs, &llh, mti->mti_svname);
2477 /* FIXME these should be a single journal transaction */
2478 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,"add ost");
2481 if (*mti->mti_uuid == '\0')
2482 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
2483 "%s_UUID", mti->mti_svname);
2484 rc = record_attach(env, llh, mti->mti_svname,
2485 "obdfilter"/*LUSTRE_OST_NAME*/, mti->mti_uuid);
2488 rc = record_setup(env, llh, mti->mti_svname,
2489 "dev"/*ignored*/, "type"/*ignored*/,
2490 failout ? "n" : "f", 0/*options*/);
2493 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname, "add ost");
2497 record_end_log(env, &llh);
2500 /* We also have to update the other logs where this osc is part of
2503 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
2504 /* If we're upgrading, the old mdt log already has our
2505 entry. Let's do a fake one for fun. */
2506 /* Note that we can't add any new failnids, since we don't
2507 know the old osc names. */
2508 flags = CM_SKIP | CM_UPGRADE146;
2510 } else if ((mti->mti_flags & LDD_F_UPDATE) != LDD_F_UPDATE) {
2511 /* If the update flag isn't set, don't update client/mdt
2514 LCONSOLE_WARN("Client log for %s was not updated; writeconf "
2515 "the MDT first to regenerate it.\n",
2519 /* Add ost to all MDT lov defs */
2520 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
2521 if (test_bit(i, fsdb->fsdb_mdt_index_map)) {
2524 rc = name_create_mdt_and_lov(&logname, &lovname, fsdb,
2528 sprintf(mdt_index, "-MDT%04x", i);
2529 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, mti,
2531 lovname, LUSTRE_SP_MDT,
2533 name_destroy(&logname);
2534 name_destroy(&lovname);
2540 /* Append ost info to the client log */
2541 rc = name_create(&logname, mti->mti_fsname, "-client");
2544 if (mgs_log_is_empty(env, mgs, logname)) {
2545 /* Start client log */
2546 rc = mgs_write_log_lov(env, mgs, fsdb, mti, logname,
2550 rc = mgs_write_log_lmv(env, mgs, fsdb, mti, logname,
2555 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, mti, logname, "",
2556 fsdb->fsdb_clilov, LUSTRE_SP_CLI, 0);
2558 name_destroy(&logname);
2562 static __inline__ int mgs_param_empty(char *ptr)
2566 if ((tmp = strchr(ptr, '=')) && (*(++tmp) == '\0'))
2571 static int mgs_write_log_failnid_internal(const struct lu_env *env,
2572 struct mgs_device *mgs,
2574 struct mgs_target_info *mti,
2575 char *logname, char *cliname)
2578 struct llog_handle *llh = NULL;
2580 if (mgs_param_empty(mti->mti_params)) {
2581 /* Remove _all_ failnids */
2582 rc = mgs_modify(env, mgs, fsdb, mti, logname,
2583 mti->mti_svname, "add failnid", CM_SKIP);
2584 return rc < 0 ? rc : 0;
2587 /* Otherwise failover nids are additive */
2588 rc = record_start_log(env, mgs, &llh, logname);
2591 /* FIXME this should be a single journal transaction */
2592 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
2596 rc = mgs_write_log_failnids(env, mti, llh, cliname);
2599 rc = record_marker(env, llh, fsdb, CM_END,
2600 mti->mti_svname, "add failnid");
2602 record_end_log(env, &llh);
2607 /* Add additional failnids to an existing log.
2608 The mdc/osc must have been added to logs first */
2609 /* tcp nids must be in dotted-quad ascii -
2610 we can't resolve hostnames from the kernel. */
2611 static int mgs_write_log_add_failnid(const struct lu_env *env,
2612 struct mgs_device *mgs,
2614 struct mgs_target_info *mti)
2616 char *logname, *cliname;
2620 /* FIXME we currently can't erase the failnids
2621 * given when a target first registers, since they aren't part of
2622 * an "add uuid" stanza */
2624 /* Verify that we know about this target */
2625 if (mgs_log_is_empty(env, mgs, mti->mti_svname)) {
2626 LCONSOLE_ERROR_MSG(0x142, "The target %s has not registered "
2627 "yet. It must be started before failnids "
2628 "can be added.\n", mti->mti_svname);
2632 /* Create mdc/osc client name (e.g. lustre-OST0001-osc) */
2633 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
2634 rc = name_create(&cliname, mti->mti_svname, "-mdc");
2635 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2636 rc = name_create(&cliname, mti->mti_svname, "-osc");
2642 /* Add failover nids to the client log */
2643 rc = name_create(&logname, mti->mti_fsname, "-client");
2645 name_destroy(&cliname);
2648 rc = mgs_write_log_failnid_internal(env, mgs, fsdb,mti,logname,cliname);
2649 name_destroy(&logname);
2650 name_destroy(&cliname);
2654 if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2655 /* Add OST failover nids to the MDT logs as well */
2658 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2659 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
2661 rc = name_create_mdt(&logname, mti->mti_fsname, i);
2664 rc = name_create_mdt_osc(&cliname, mti->mti_svname,
2667 name_destroy(&logname);
2670 rc = mgs_write_log_failnid_internal(env, mgs, fsdb,
2673 name_destroy(&cliname);
2674 name_destroy(&logname);
2683 static int mgs_wlp_lcfg(const struct lu_env *env,
2684 struct mgs_device *mgs, struct fs_db *fsdb,
2685 struct mgs_target_info *mti,
2686 char *logname, struct lustre_cfg_bufs *bufs,
2687 char *tgtname, char *ptr)
2689 char comment[MTI_NAME_MAXLEN];
2691 struct llog_cfg_rec *lcr;
2694 /* Erase any old settings of this same parameter */
2695 memcpy(comment, ptr, MTI_NAME_MAXLEN);
2696 comment[MTI_NAME_MAXLEN - 1] = 0;
2697 /* But don't try to match the value. */
2698 tmp = strchr(comment, '=');
2701 /* FIXME we should skip settings that are the same as old values */
2702 rc = mgs_modify(env, mgs, fsdb, mti, logname, tgtname, comment,CM_SKIP);
2705 del = mgs_param_empty(ptr);
2707 LCONSOLE_INFO("%s parameter %s.%s in log %s\n", del ? "Disabling" : rc ?
2708 "Setting" : "Modifying", tgtname, comment, logname);
2710 /* mgs_modify() will return 1 if nothing had to be done */
2716 lustre_cfg_bufs_reset(bufs, tgtname);
2717 lustre_cfg_bufs_set_string(bufs, 1, ptr);
2718 if (mti->mti_flags & LDD_F_PARAM2)
2719 lustre_cfg_bufs_set_string(bufs, 2, LCTL_UPCALL);
2721 lcr = lustre_cfg_rec_new((mti->mti_flags & LDD_F_PARAM2) ?
2722 LCFG_SET_PARAM : LCFG_PARAM, bufs);
2726 rc = mgs_write_log_direct(env, mgs, fsdb, logname, lcr, tgtname,
2728 lustre_cfg_rec_free(lcr);
2732 static int mgs_write_log_param2(const struct lu_env *env,
2733 struct mgs_device *mgs,
2735 struct mgs_target_info *mti, char *ptr)
2737 struct lustre_cfg_bufs bufs;
2741 CDEBUG(D_MGS, "next param '%s'\n", ptr);
2742 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, PARAMS_FILENAME, &bufs,
2743 mti->mti_svname, ptr);
2748 /* write global variable settings into log */
2749 static int mgs_write_log_sys(const struct lu_env *env,
2750 struct mgs_device *mgs, struct fs_db *fsdb,
2751 struct mgs_target_info *mti, char *sys, char *ptr)
2753 struct mgs_thread_info *mgi = mgs_env_info(env);
2754 struct lustre_cfg *lcfg;
2755 struct llog_cfg_rec *lcr;
2757 int rc, cmd, convert = 1;
2759 if (class_match_param(ptr, PARAM_TIMEOUT, &tmp) == 0) {
2760 cmd = LCFG_SET_TIMEOUT;
2761 } else if (class_match_param(ptr, PARAM_LDLM_TIMEOUT, &tmp) == 0) {
2762 cmd = LCFG_SET_LDLM_TIMEOUT;
2763 /* Check for known params here so we can return error to lctl */
2764 } else if ((class_match_param(ptr, PARAM_AT_MIN, &tmp) == 0) ||
2765 (class_match_param(ptr, PARAM_AT_MAX, &tmp) == 0) ||
2766 (class_match_param(ptr, PARAM_AT_EXTRA, &tmp) == 0) ||
2767 (class_match_param(ptr, PARAM_AT_EARLY_MARGIN, &tmp) == 0) ||
2768 (class_match_param(ptr, PARAM_AT_HISTORY, &tmp) == 0)) {
2770 } else if (class_match_param(ptr, PARAM_JOBID_VAR, &tmp) == 0) {
2771 convert = 0; /* Don't convert string value to integer */
2777 if (mgs_param_empty(ptr))
2778 CDEBUG(D_MGS, "global '%s' removed\n", sys);
2780 CDEBUG(D_MGS, "global '%s' val=%s\n", sys, tmp);
2782 lustre_cfg_bufs_reset(&mgi->mgi_bufs, NULL);
2783 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, sys);
2784 if (!convert && *tmp != '\0')
2785 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 2, tmp);
2786 lcr = lustre_cfg_rec_new(cmd, &mgi->mgi_bufs);
2790 lcfg = &lcr->lcr_cfg;
2791 lcfg->lcfg_num = convert ? simple_strtoul(tmp, NULL, 0) : 0;
2792 /* truncate the comment to the parameter name */
2796 /* modify all servers and clients */
2797 rc = mgs_write_log_direct_all(env, mgs, fsdb, mti,
2798 *tmp == '\0' ? NULL : lcr,
2799 mti->mti_fsname, sys, 0);
2800 if (rc == 0 && *tmp != '\0') {
2802 case LCFG_SET_TIMEOUT:
2803 if (!obd_timeout_set || lcfg->lcfg_num > obd_timeout)
2804 class_process_config(lcfg);
2806 case LCFG_SET_LDLM_TIMEOUT:
2807 if (!ldlm_timeout_set || lcfg->lcfg_num > ldlm_timeout)
2808 class_process_config(lcfg);
2815 lustre_cfg_rec_free(lcr);
2819 /* write quota settings into log */
2820 static int mgs_write_log_quota(const struct lu_env *env, struct mgs_device *mgs,
2821 struct fs_db *fsdb, struct mgs_target_info *mti,
2822 char *quota, char *ptr)
2824 struct mgs_thread_info *mgi = mgs_env_info(env);
2825 struct llog_cfg_rec *lcr;
2828 int rc, cmd = LCFG_PARAM;
2830 /* support only 'meta' and 'data' pools so far */
2831 if (class_match_param(ptr, QUOTA_METAPOOL_NAME, &tmp) != 0 &&
2832 class_match_param(ptr, QUOTA_DATAPOOL_NAME, &tmp) != 0) {
2833 CERROR("parameter quota.%s isn't supported (only quota.mdt "
2834 "& quota.ost are)\n", ptr);
2839 CDEBUG(D_MGS, "global '%s' removed\n", quota);
2841 CDEBUG(D_MGS, "global '%s'\n", quota);
2843 if (strchr(tmp, 'u') == NULL && strchr(tmp, 'g') == NULL &&
2844 strcmp(tmp, "none") != 0) {
2845 CERROR("enable option(%s) isn't supported\n", tmp);
2850 lustre_cfg_bufs_reset(&mgi->mgi_bufs, mti->mti_fsname);
2851 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, quota);
2852 lcr = lustre_cfg_rec_new(cmd, &mgi->mgi_bufs);
2856 /* truncate the comment to the parameter name */
2861 /* XXX we duplicated quota enable information in all server
2862 * config logs, it should be moved to a separate config
2863 * log once we cleanup the config log for global param. */
2864 /* modify all servers */
2865 rc = mgs_write_log_direct_all(env, mgs, fsdb, mti,
2866 *tmp == '\0' ? NULL : lcr,
2867 mti->mti_fsname, quota, 1);
2869 lustre_cfg_rec_free(lcr);
2870 return rc < 0 ? rc : 0;
2873 static int mgs_srpc_set_param_disk(const struct lu_env *env,
2874 struct mgs_device *mgs,
2876 struct mgs_target_info *mti,
2879 struct mgs_thread_info *mgi = mgs_env_info(env);
2880 struct llog_cfg_rec *lcr;
2881 struct llog_handle *llh = NULL;
2883 char *comment, *ptr;
2889 ptr = strchr(param, '=');
2890 LASSERT(ptr != NULL);
2893 OBD_ALLOC(comment, len + 1);
2894 if (comment == NULL)
2896 strncpy(comment, param, len);
2897 comment[len] = '\0';
2900 lustre_cfg_bufs_reset(&mgi->mgi_bufs, mti->mti_svname);
2901 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, param);
2902 lcr = lustre_cfg_rec_new(LCFG_SPTLRPC_CONF, &mgi->mgi_bufs);
2904 GOTO(out_comment, rc = -ENOMEM);
2906 /* construct log name */
2907 rc = name_create(&logname, mti->mti_fsname, "-sptlrpc");
2911 if (mgs_log_is_empty(env, mgs, logname)) {
2912 rc = record_start_log(env, mgs, &llh, logname);
2915 record_end_log(env, &llh);
2918 /* obsolete old one */
2919 rc = mgs_modify(env, mgs, fsdb, mti, logname, mti->mti_svname,
2923 /* write the new one */
2924 rc = mgs_write_log_direct(env, mgs, fsdb, logname, lcr,
2925 mti->mti_svname, comment);
2927 CERROR("%s: error writing log %s: rc = %d\n",
2928 mgs->mgs_obd->obd_name, logname, rc);
2930 name_destroy(&logname);
2932 lustre_cfg_rec_free(lcr);
2934 OBD_FREE(comment, len + 1);
2938 static int mgs_srpc_set_param_udesc_mem(struct fs_db *fsdb,
2943 /* disable the adjustable udesc parameter for now, i.e. use default
2944 * setting that client always ship udesc to MDT if possible. to enable
2945 * it simply remove the following line */
2948 ptr = strchr(param, '=');
2953 if (strcmp(param, PARAM_SRPC_UDESC))
2956 if (strcmp(ptr, "yes") == 0) {
2957 set_bit(FSDB_UDESC, &fsdb->fsdb_flags);
2958 CWARN("Enable user descriptor shipping from client to MDT\n");
2959 } else if (strcmp(ptr, "no") == 0) {
2960 clear_bit(FSDB_UDESC, &fsdb->fsdb_flags);
2961 CWARN("Disable user descriptor shipping from client to MDT\n");
2969 CERROR("Invalid param: %s\n", param);
2973 static int mgs_srpc_set_param_mem(struct fs_db *fsdb,
2977 struct sptlrpc_rule rule;
2978 struct sptlrpc_rule_set *rset;
2982 if (strncmp(param, PARAM_SRPC, sizeof(PARAM_SRPC) - 1) != 0) {
2983 CERROR("Invalid sptlrpc parameter: %s\n", param);
2987 if (strncmp(param, PARAM_SRPC_UDESC,
2988 sizeof(PARAM_SRPC_UDESC) - 1) == 0) {
2989 RETURN(mgs_srpc_set_param_udesc_mem(fsdb, param));
2992 if (strncmp(param, PARAM_SRPC_FLVR, sizeof(PARAM_SRPC_FLVR) - 1) != 0) {
2993 CERROR("Invalid sptlrpc flavor parameter: %s\n", param);
2997 param += sizeof(PARAM_SRPC_FLVR) - 1;
2999 rc = sptlrpc_parse_rule(param, &rule);
3003 /* mgs rules implies must be mgc->mgs */
3004 if (test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
3005 if ((rule.sr_from != LUSTRE_SP_MGC &&
3006 rule.sr_from != LUSTRE_SP_ANY) ||
3007 (rule.sr_to != LUSTRE_SP_MGS &&
3008 rule.sr_to != LUSTRE_SP_ANY))
3012 /* preapre room for this coming rule. svcname format should be:
3013 * - fsname: general rule
3014 * - fsname-tgtname: target-specific rule
3016 if (strchr(svname, '-')) {
3017 struct mgs_tgt_srpc_conf *tgtconf;
3020 for (tgtconf = fsdb->fsdb_srpc_tgt; tgtconf != NULL;
3021 tgtconf = tgtconf->mtsc_next) {
3022 if (!strcmp(tgtconf->mtsc_tgt, svname)) {
3031 OBD_ALLOC_PTR(tgtconf);
3032 if (tgtconf == NULL)
3035 name_len = strlen(svname);
3037 OBD_ALLOC(tgtconf->mtsc_tgt, name_len + 1);
3038 if (tgtconf->mtsc_tgt == NULL) {
3039 OBD_FREE_PTR(tgtconf);
3042 memcpy(tgtconf->mtsc_tgt, svname, name_len);
3044 tgtconf->mtsc_next = fsdb->fsdb_srpc_tgt;
3045 fsdb->fsdb_srpc_tgt = tgtconf;
3048 rset = &tgtconf->mtsc_rset;
3050 rset = &fsdb->fsdb_srpc_gen;
3053 rc = sptlrpc_rule_set_merge(rset, &rule);
3058 static int mgs_srpc_set_param(const struct lu_env *env,
3059 struct mgs_device *mgs,
3061 struct mgs_target_info *mti,
3071 /* keep a copy of original param, which could be destroied
3073 copy_size = strlen(param) + 1;
3074 OBD_ALLOC(copy, copy_size);
3077 memcpy(copy, param, copy_size);
3079 rc = mgs_srpc_set_param_mem(fsdb, mti->mti_svname, param);
3083 /* previous steps guaranteed the syntax is correct */
3084 rc = mgs_srpc_set_param_disk(env, mgs, fsdb, mti, copy);
3088 if (test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
3090 * for mgs rules, make them effective immediately.
3092 LASSERT(fsdb->fsdb_srpc_tgt == NULL);
3093 sptlrpc_target_update_exp_flavor(mgs->mgs_obd,
3094 &fsdb->fsdb_srpc_gen);
3098 OBD_FREE(copy, copy_size);
3102 struct mgs_srpc_read_data {
3103 struct fs_db *msrd_fsdb;
3107 static int mgs_srpc_read_handler(const struct lu_env *env,
3108 struct llog_handle *llh,
3109 struct llog_rec_hdr *rec, void *data)
3111 struct mgs_srpc_read_data *msrd = data;
3112 struct cfg_marker *marker;
3113 struct lustre_cfg *lcfg = REC_DATA(rec);
3114 char *svname, *param;
3118 if (rec->lrh_type != OBD_CFG_REC) {
3119 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
3123 cfg_len = REC_DATA_LEN(rec);
3125 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
3127 CERROR("Insane cfg\n");
3131 if (lcfg->lcfg_command == LCFG_MARKER) {
3132 marker = lustre_cfg_buf(lcfg, 1);
3134 if (marker->cm_flags & CM_START &&
3135 marker->cm_flags & CM_SKIP)
3136 msrd->msrd_skip = 1;
3137 if (marker->cm_flags & CM_END)
3138 msrd->msrd_skip = 0;
3143 if (msrd->msrd_skip)
3146 if (lcfg->lcfg_command != LCFG_SPTLRPC_CONF) {
3147 CERROR("invalid command (%x)\n", lcfg->lcfg_command);
3151 svname = lustre_cfg_string(lcfg, 0);
3152 if (svname == NULL) {
3153 CERROR("svname is empty\n");
3157 param = lustre_cfg_string(lcfg, 1);
3158 if (param == NULL) {
3159 CERROR("param is empty\n");
3163 rc = mgs_srpc_set_param_mem(msrd->msrd_fsdb, svname, param);
3165 CERROR("read sptlrpc record error (%d): %s\n", rc, param);
3170 int mgs_get_fsdb_srpc_from_llog(const struct lu_env *env,
3171 struct mgs_device *mgs,
3174 struct llog_handle *llh = NULL;
3175 struct llog_ctxt *ctxt;
3177 struct mgs_srpc_read_data msrd;
3181 /* construct log name */
3182 rc = name_create(&logname, fsdb->fsdb_name, "-sptlrpc");
3186 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
3187 LASSERT(ctxt != NULL);
3189 if (mgs_log_is_empty(env, mgs, logname))
3192 rc = llog_open(env, ctxt, &llh, NULL, logname,
3200 rc = llog_init_handle(env, llh, LLOG_F_IS_PLAIN, NULL);
3202 GOTO(out_close, rc);
3204 if (llog_get_size(llh) <= 1)
3205 GOTO(out_close, rc = 0);
3207 msrd.msrd_fsdb = fsdb;
3210 rc = llog_process(env, llh, mgs_srpc_read_handler, (void *)&msrd,
3214 llog_close(env, llh);
3216 llog_ctxt_put(ctxt);
3217 name_destroy(&logname);
3220 CERROR("failed to read sptlrpc config database: %d\n", rc);
3224 /* Permanent settings of all parameters by writing into the appropriate
3225 * configuration logs.
3226 * A parameter with null value ("<param>='\0'") means to erase it out of
3229 static int mgs_write_log_param(const struct lu_env *env,
3230 struct mgs_device *mgs, struct fs_db *fsdb,
3231 struct mgs_target_info *mti, char *ptr)
3233 struct mgs_thread_info *mgi = mgs_env_info(env);
3236 int rc = 0, rc2 = 0;
3239 /* For various parameter settings, we have to figure out which logs
3240 care about them (e.g. both mdt and client for lov settings) */
3241 CDEBUG(D_MGS, "next param '%s'\n", ptr);
3243 /* The params are stored in MOUNT_DATA_FILE and modified via
3244 tunefs.lustre, or set using lctl conf_param */
3246 /* Processed in lustre_start_mgc */
3247 if (class_match_param(ptr, PARAM_MGSNODE, NULL) == 0)
3250 /* Processed in ost/mdt */
3251 if (class_match_param(ptr, PARAM_NETWORK, NULL) == 0)
3254 /* Processed in mgs_write_log_ost */
3255 if (class_match_param(ptr, PARAM_FAILMODE, NULL) == 0) {
3256 if (mti->mti_flags & LDD_F_PARAM) {
3257 LCONSOLE_ERROR_MSG(0x169, "%s can only be "
3258 "changed with tunefs.lustre"
3259 "and --writeconf\n", ptr);
3265 if (class_match_param(ptr, PARAM_SRPC, NULL) == 0) {
3266 rc = mgs_srpc_set_param(env, mgs, fsdb, mti, ptr);
3270 if (class_match_param(ptr, PARAM_FAILNODE, NULL) == 0) {
3271 /* Add a failover nidlist */
3273 /* We already processed failovers params for new
3274 targets in mgs_write_log_target */
3275 if (mti->mti_flags & LDD_F_PARAM) {
3276 CDEBUG(D_MGS, "Adding failnode\n");
3277 rc = mgs_write_log_add_failnid(env, mgs, fsdb, mti);
3282 if (class_match_param(ptr, PARAM_SYS, &tmp) == 0) {
3283 rc = mgs_write_log_sys(env, mgs, fsdb, mti, ptr, tmp);
3287 if (class_match_param(ptr, PARAM_QUOTA, &tmp) == 0) {
3288 rc = mgs_write_log_quota(env, mgs, fsdb, mti, ptr, tmp);
3292 if (class_match_param(ptr, PARAM_OSC""PARAM_ACTIVE, &tmp) == 0) {
3293 /* active=0 means off, anything else means on */
3294 int flag = (*tmp == '0') ? CM_EXCLUDE : 0;
3297 if (!(mti->mti_flags & LDD_F_SV_TYPE_OST)) {
3298 LCONSOLE_ERROR_MSG(0x144, "%s: Only OSCs can "
3299 "be (de)activated.\n",
3301 GOTO(end, rc = -EINVAL);
3303 LCONSOLE_WARN("Permanently %sactivating %s\n",
3304 flag ? "de": "re", mti->mti_svname);
3306 rc = name_create(&logname, mti->mti_fsname, "-client");
3309 rc = mgs_modify(env, mgs, fsdb, mti, logname,
3310 mti->mti_svname, "add osc", flag);
3311 name_destroy(&logname);
3315 /* Add to all MDT logs for CMD */
3316 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3317 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
3319 rc = name_create_mdt(&logname, mti->mti_fsname, i);
3322 rc = mgs_modify(env, mgs, fsdb, mti, logname,
3323 mti->mti_svname, "add osc", flag);
3324 name_destroy(&logname);
3330 LCONSOLE_ERROR_MSG(0x145, "Couldn't find %s in"
3331 "log (%d). No permanent "
3332 "changes were made to the "
3334 mti->mti_svname, rc);
3335 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags))
3336 LCONSOLE_ERROR_MSG(0x146, "This may be"
3341 "update the logs.\n");
3344 /* Fall through to osc proc for deactivating live OSC
3345 on running MDT / clients. */
3347 /* Below here, let obd's XXX_process_config methods handle it */
3349 /* All lov. in proc */
3350 if (class_match_param(ptr, PARAM_LOV, NULL) == 0) {
3353 CDEBUG(D_MGS, "lov param %s\n", ptr);
3354 if (!(mti->mti_flags & LDD_F_SV_TYPE_MDT)) {
3355 LCONSOLE_ERROR_MSG(0x147, "LOV params must be "
3356 "set on the MDT, not %s. "
3363 if (mgs_log_is_empty(env, mgs, mti->mti_svname))
3364 GOTO(end, rc = -ENODEV);
3366 rc = name_create_mdt_and_lov(&logname, &mdtlovname, fsdb,
3367 mti->mti_stripe_index);
3370 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, mti->mti_svname,
3371 &mgi->mgi_bufs, mdtlovname, ptr);
3372 name_destroy(&logname);
3373 name_destroy(&mdtlovname);
3378 rc = name_create(&logname, mti->mti_fsname, "-client");
3381 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname, &mgi->mgi_bufs,
3382 fsdb->fsdb_clilov, ptr);
3383 name_destroy(&logname);
3387 /* All osc., mdc., llite. params in proc */
3388 if ((class_match_param(ptr, PARAM_OSC, NULL) == 0) ||
3389 (class_match_param(ptr, PARAM_MDC, NULL) == 0) ||
3390 (class_match_param(ptr, PARAM_LLITE, NULL) == 0)) {
3393 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
3394 LCONSOLE_ERROR_MSG(0x148, "Upgraded client logs for %s"
3395 " cannot be modified. Consider"
3396 " updating the configuration with"
3399 GOTO(end, rc = -EINVAL);
3401 if (memcmp(ptr, PARAM_LLITE, strlen(PARAM_LLITE)) == 0) {
3402 rc = name_create(&cname, mti->mti_fsname, "-client");
3403 /* Add the client type to match the obdname in
3404 class_config_llog_handler */
3405 } else if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
3406 rc = name_create(&cname, mti->mti_svname, "-mdc");
3407 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
3408 rc = name_create(&cname, mti->mti_svname, "-osc");
3410 GOTO(end, rc = -EINVAL);
3415 /* Forbid direct update of llite root squash parameters.
3416 * These parameters are indirectly set via the MDT settings.
3418 if ((class_match_param(ptr, PARAM_LLITE, &tmp) == 0) &&
3419 ((memcmp(tmp, "root_squash=", 12) == 0) ||
3420 (memcmp(tmp, "nosquash_nids=", 14) == 0))) {
3421 LCONSOLE_ERROR("%s: root squash parameters can only "
3422 "be updated through MDT component\n",
3424 name_destroy(&cname);
3425 GOTO(end, rc = -EINVAL);
3428 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
3431 rc = name_create(&logname, mti->mti_fsname, "-client");
3433 name_destroy(&cname);
3436 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname, &mgi->mgi_bufs,
3439 /* osc params affect the MDT as well */
3440 if (!rc && (mti->mti_flags & LDD_F_SV_TYPE_OST)) {
3443 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
3444 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
3446 name_destroy(&cname);
3447 rc = name_create_mdt_osc(&cname, mti->mti_svname,
3449 name_destroy(&logname);
3452 rc = name_create_mdt(&logname,
3453 mti->mti_fsname, i);
3456 if (!mgs_log_is_empty(env, mgs, logname)) {
3457 rc = mgs_wlp_lcfg(env, mgs, fsdb,
3466 name_destroy(&logname);
3467 name_destroy(&cname);
3471 /* All mdt. params in proc */
3472 if (class_match_param(ptr, PARAM_MDT, &tmp) == 0) {
3476 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
3477 if (strncmp(mti->mti_svname, mti->mti_fsname,
3478 MTI_NAME_MAXLEN) == 0)
3479 /* device is unspecified completely? */
3480 rc = LDD_F_SV_TYPE_MDT | LDD_F_SV_ALL;
3482 rc = server_name2index(mti->mti_svname, &idx, NULL);
3485 if ((rc & LDD_F_SV_TYPE_MDT) == 0)
3487 if (rc & LDD_F_SV_ALL) {
3488 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3490 fsdb->fsdb_mdt_index_map))
3492 rc = name_create_mdt(&logname,
3493 mti->mti_fsname, i);
3496 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti,
3497 logname, &mgi->mgi_bufs,
3499 name_destroy(&logname);
3504 if ((memcmp(tmp, "root_squash=", 12) == 0) ||
3505 (memcmp(tmp, "nosquash_nids=", 14) == 0)) {
3506 LCONSOLE_ERROR("%s: root squash parameters "
3507 "cannot be applied to a single MDT\n",
3509 GOTO(end, rc = -EINVAL);
3511 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti,
3512 mti->mti_svname, &mgi->mgi_bufs,
3513 mti->mti_svname, ptr);
3518 /* root squash settings are also applied to llite
3519 * config log (see LU-1778) */
3521 ((memcmp(tmp, "root_squash=", 12) == 0) ||
3522 (memcmp(tmp, "nosquash_nids=", 14) == 0))) {
3526 rc = name_create(&cname, mti->mti_fsname, "-client");
3529 rc = name_create(&logname, mti->mti_fsname, "-client");
3531 name_destroy(&cname);
3534 rc = name_create(&ptr2, PARAM_LLITE, tmp);
3536 name_destroy(&cname);
3537 name_destroy(&logname);
3540 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname,
3541 &mgi->mgi_bufs, cname, ptr2);
3542 name_destroy(&ptr2);
3543 name_destroy(&logname);
3544 name_destroy(&cname);
3549 /* All mdd., ost. and osd. params in proc */
3550 if ((class_match_param(ptr, PARAM_MDD, NULL) == 0) ||
3551 (class_match_param(ptr, PARAM_OST, NULL) == 0) ||
3552 (class_match_param(ptr, PARAM_OSD, NULL) == 0)) {
3553 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
3554 if (mgs_log_is_empty(env, mgs, mti->mti_svname))
3555 GOTO(end, rc = -ENODEV);
3557 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, mti->mti_svname,
3558 &mgi->mgi_bufs, mti->mti_svname, ptr);
3562 LCONSOLE_WARN("Ignoring unrecognized param '%s'\n", ptr);
3567 CERROR("err %d on param '%s'\n", rc, ptr);
3572 /* Not implementing automatic failover nid addition at this time. */
3573 int mgs_check_failnid(const struct lu_env *env, struct mgs_device *mgs,
3574 struct mgs_target_info *mti)
3581 rc = mgs_find_or_make_fsdb(obd, fsname, &fsdb);
3585 if (mgs_log_is_empty(obd, mti->mti_svname))
3586 /* should never happen */
3589 CDEBUG(D_MGS, "Checking for new failnids for %s\n", mti->mti_svname);
3591 /* FIXME We can just check mti->params to see if we're already in
3592 the failover list. Modify mti->params for rewriting back at
3593 server_register_target(). */
3595 mutex_lock(&fsdb->fsdb_mutex);
3596 rc = mgs_write_log_add_failnid(obd, fsdb, mti);
3597 mutex_unlock(&fsdb->fsdb_mutex);
3606 int mgs_write_log_target(const struct lu_env *env, struct mgs_device *mgs,
3607 struct mgs_target_info *mti, struct fs_db *fsdb)
3614 /* set/check the new target index */
3615 rc = mgs_set_index(env, mgs, mti);
3619 if (rc == EALREADY) {
3620 LCONSOLE_WARN("Found index %d for %s, updating log\n",
3621 mti->mti_stripe_index, mti->mti_svname);
3622 /* We would like to mark old log sections as invalid
3623 and add new log sections in the client and mdt logs.
3624 But if we add new sections, then live clients will
3625 get repeat setup instructions for already running
3626 osc's. So don't update the client/mdt logs. */
3627 mti->mti_flags &= ~LDD_F_UPDATE;
3631 mutex_lock(&fsdb->fsdb_mutex);
3633 if (mti->mti_flags &
3634 (LDD_F_VIRGIN | LDD_F_UPGRADE14 | LDD_F_WRITECONF)) {
3635 /* Generate a log from scratch */
3636 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
3637 rc = mgs_write_log_mdt(env, mgs, fsdb, mti);
3638 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
3639 rc = mgs_write_log_ost(env, mgs, fsdb, mti);
3641 CERROR("Unknown target type %#x, can't create log for "
3642 "%s\n", mti->mti_flags, mti->mti_svname);
3645 CERROR("Can't write logs for %s (%d)\n",
3646 mti->mti_svname, rc);
3650 /* Just update the params from tunefs in mgs_write_log_params */
3651 CDEBUG(D_MGS, "Update params for %s\n", mti->mti_svname);
3652 mti->mti_flags |= LDD_F_PARAM;
3655 /* allocate temporary buffer, where class_get_next_param will
3656 make copy of a current parameter */
3657 OBD_ALLOC(buf, strlen(mti->mti_params) + 1);
3659 GOTO(out_up, rc = -ENOMEM);
3660 params = mti->mti_params;
3661 while (params != NULL) {
3662 rc = class_get_next_param(¶ms, buf);
3665 /* there is no next parameter, that is
3670 CDEBUG(D_MGS, "remaining string: '%s', param: '%s'\n",
3672 rc = mgs_write_log_param(env, mgs, fsdb, mti, buf);
3677 OBD_FREE(buf, strlen(mti->mti_params) + 1);
3680 mutex_unlock(&fsdb->fsdb_mutex);
3684 int mgs_erase_log(const struct lu_env *env, struct mgs_device *mgs, char *name)
3686 struct llog_ctxt *ctxt;
3689 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
3691 CERROR("%s: MGS config context doesn't exist\n",
3692 mgs->mgs_obd->obd_name);
3695 rc = llog_erase(env, ctxt, NULL, name);
3696 /* llog may not exist */
3699 llog_ctxt_put(ctxt);
3703 CERROR("%s: failed to clear log %s: %d\n",
3704 mgs->mgs_obd->obd_name, name, rc);
3709 /* erase all logs for the given fs */
3710 int mgs_erase_logs(const struct lu_env *env, struct mgs_device *mgs, char *fsname)
3713 struct list_head log_list;
3714 struct mgs_direntry *dirent, *n;
3715 int rc, len = strlen(fsname);
3719 /* Find all the logs in the CONFIGS directory */
3720 rc = class_dentry_readdir(env, mgs, &log_list);
3724 mutex_lock(&mgs->mgs_mutex);
3726 /* Delete the fs db */
3727 fsdb = mgs_find_fsdb(mgs, fsname);
3729 mgs_free_fsdb(mgs, fsdb);
3731 mutex_unlock(&mgs->mgs_mutex);
3733 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
3734 list_del_init(&dirent->mde_list);
3735 suffix = strrchr(dirent->mde_name, '-');
3736 if (suffix != NULL) {
3737 if ((len == suffix - dirent->mde_name) &&
3738 (strncmp(fsname, dirent->mde_name, len) == 0)) {
3739 CDEBUG(D_MGS, "Removing log %s\n",
3741 mgs_erase_log(env, mgs, dirent->mde_name);
3744 mgs_direntry_free(dirent);
3750 /* list all logs for the given fs */
3751 int mgs_list_logs(const struct lu_env *env, struct mgs_device *mgs,
3752 struct obd_ioctl_data *data)
3754 struct list_head log_list;
3755 struct mgs_direntry *dirent, *n;
3761 /* Find all the logs in the CONFIGS directory */
3762 rc = class_dentry_readdir(env, mgs, &log_list);
3766 out = data->ioc_bulk;
3767 remains = data->ioc_inllen1;
3768 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
3769 list_del_init(&dirent->mde_list);
3770 suffix = strrchr(dirent->mde_name, '-');
3771 if (suffix != NULL) {
3772 l = snprintf(out, remains, "config log: $%s\n",
3777 mgs_direntry_free(dirent);
3784 /* from llog_swab */
3785 static void print_lustre_cfg(struct lustre_cfg *lcfg)
3790 CDEBUG(D_MGS, "lustre_cfg: %p\n", lcfg);
3791 CDEBUG(D_MGS, "\tlcfg->lcfg_version: %#x\n", lcfg->lcfg_version);
3793 CDEBUG(D_MGS, "\tlcfg->lcfg_command: %#x\n", lcfg->lcfg_command);
3794 CDEBUG(D_MGS, "\tlcfg->lcfg_num: %#x\n", lcfg->lcfg_num);
3795 CDEBUG(D_MGS, "\tlcfg->lcfg_flags: %#x\n", lcfg->lcfg_flags);
3796 CDEBUG(D_MGS, "\tlcfg->lcfg_nid: %s\n", libcfs_nid2str(lcfg->lcfg_nid));
3798 CDEBUG(D_MGS, "\tlcfg->lcfg_bufcount: %d\n", lcfg->lcfg_bufcount);
3799 if (lcfg->lcfg_bufcount < LUSTRE_CFG_MAX_BUFCOUNT)
3800 for (i = 0; i < lcfg->lcfg_bufcount; i++) {
3801 CDEBUG(D_MGS, "\tlcfg->lcfg_buflens[%d]: %d %s\n",
3802 i, lcfg->lcfg_buflens[i],
3803 lustre_cfg_string(lcfg, i));
3808 /* Setup params fsdb and log
3810 int mgs_params_fsdb_setup(const struct lu_env *env, struct mgs_device *mgs,
3813 struct llog_handle *params_llh = NULL;
3817 rc = mgs_find_or_make_fsdb(env, mgs, PARAMS_FILENAME, &fsdb);
3819 mutex_lock(&fsdb->fsdb_mutex);
3820 rc = record_start_log(env, mgs, ¶ms_llh, PARAMS_FILENAME);
3822 rc = record_end_log(env, ¶ms_llh);
3823 mutex_unlock(&fsdb->fsdb_mutex);
3829 /* Cleanup params fsdb and log
3831 int mgs_params_fsdb_cleanup(const struct lu_env *env, struct mgs_device *mgs)
3833 return mgs_erase_logs(env, mgs, PARAMS_FILENAME);
3836 /* Set a permanent (config log) param for a target or fs
3837 * \param lcfg buf0 may contain the device (testfs-MDT0000) name
3838 * buf1 contains the single parameter
3840 int mgs_setparam(const struct lu_env *env, struct mgs_device *mgs,
3841 struct lustre_cfg *lcfg, char *fsname)
3844 struct mgs_target_info *mti;
3845 char *devname, *param;
3852 print_lustre_cfg(lcfg);
3854 /* lustre, lustre-mdtlov, lustre-client, lustre-MDT0000 */
3855 devname = lustre_cfg_string(lcfg, 0);
3856 param = lustre_cfg_string(lcfg, 1);
3858 /* Assume device name embedded in param:
3859 lustre-OST0000.osc.max_dirty_mb=32 */
3860 ptr = strchr(param, '.');
3868 LCONSOLE_ERROR_MSG(0x14d, "No target specified: %s\n", param);
3872 rc = mgs_parse_devname(devname, fsname, NULL);
3873 if (rc == 0 && !mgs_parse_devname(devname, NULL, &index)) {
3874 /* param related to llite isn't allowed to set by OST or MDT */
3875 if (rc == 0 && strncmp(param, PARAM_LLITE,
3876 sizeof(PARAM_LLITE) - 1) == 0)
3879 /* assume devname is the fsname */
3880 strlcpy(fsname, devname, MTI_NAME_MAXLEN);
3882 CDEBUG(D_MGS, "setparam fs='%s' device='%s'\n", fsname, devname);
3884 rc = mgs_find_or_make_fsdb(env, mgs,
3885 lcfg->lcfg_command == LCFG_SET_PARAM ?
3886 PARAMS_FILENAME : fsname, &fsdb);
3890 if (lcfg->lcfg_command != LCFG_SET_PARAM &&
3891 !test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags) &&
3892 test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
3893 CERROR("No filesystem targets for %s. cfg_device from lctl "
3894 "is '%s'\n", fsname, devname);
3895 mgs_free_fsdb(mgs, fsdb);
3899 /* Create a fake mti to hold everything */
3902 GOTO(out, rc = -ENOMEM);
3903 if (strlcpy(mti->mti_fsname, fsname, sizeof(mti->mti_fsname))
3904 >= sizeof(mti->mti_fsname))
3905 GOTO(out, rc = -E2BIG);
3906 if (strlcpy(mti->mti_svname, devname, sizeof(mti->mti_svname))
3907 >= sizeof(mti->mti_svname))
3908 GOTO(out, rc = -E2BIG);
3909 if (strlcpy(mti->mti_params, param, sizeof(mti->mti_params))
3910 >= sizeof(mti->mti_params))
3911 GOTO(out, rc = -E2BIG);
3912 rc = server_name2index(mti->mti_svname, &mti->mti_stripe_index, &tmp);
3914 /* Not a valid server; may be only fsname */
3917 /* Strip -osc or -mdc suffix from svname */
3918 if (server_make_name(rc, mti->mti_stripe_index, mti->mti_fsname,
3920 GOTO(out, rc = -EINVAL);
3922 * Revoke lock so everyone updates. Should be alright if
3923 * someone was already reading while we were updating the logs,
3924 * so we don't really need to hold the lock while we're
3927 if (lcfg->lcfg_command == LCFG_SET_PARAM) {
3928 mti->mti_flags = rc | LDD_F_PARAM2;
3929 mutex_lock(&fsdb->fsdb_mutex);
3930 rc = mgs_write_log_param2(env, mgs, fsdb, mti, mti->mti_params);
3931 mutex_unlock(&fsdb->fsdb_mutex);
3932 mgs_revoke_lock(mgs, fsdb, CONFIG_T_PARAMS);
3934 mti->mti_flags = rc | LDD_F_PARAM;
3935 mutex_lock(&fsdb->fsdb_mutex);
3936 rc = mgs_write_log_param(env, mgs, fsdb, mti, mti->mti_params);
3937 mutex_unlock(&fsdb->fsdb_mutex);
3938 mgs_revoke_lock(mgs, fsdb, CONFIG_T_CONFIG);
3946 static int mgs_write_log_pool(const struct lu_env *env,
3947 struct mgs_device *mgs, char *logname,
3948 struct fs_db *fsdb, char *tgtname,
3949 enum lcfg_command_type cmd,
3950 char *fsname, char *poolname,
3951 char *ostname, char *comment)
3953 struct llog_handle *llh = NULL;
3956 rc = record_start_log(env, mgs, &llh, logname);
3959 rc = record_marker(env, llh, fsdb, CM_START, tgtname, comment);
3962 rc = record_base(env, llh, tgtname, 0, cmd,
3963 fsname, poolname, ostname, 0);
3966 rc = record_marker(env, llh, fsdb, CM_END, tgtname, comment);
3968 record_end_log(env, &llh);
3972 int mgs_nodemap_cmd(const struct lu_env *env, struct mgs_device *mgs,
3973 enum lcfg_command_type cmd, const char *nodemap_name,
3984 case LCFG_NODEMAP_ADD:
3985 rc = nodemap_add(nodemap_name);
3987 case LCFG_NODEMAP_DEL:
3988 rc = nodemap_del(nodemap_name);
3990 case LCFG_NODEMAP_ADD_RANGE:
3991 rc = nodemap_parse_range(param, nid);
3994 rc = nodemap_add_range(nodemap_name, nid);
3996 case LCFG_NODEMAP_DEL_RANGE:
3997 rc = nodemap_parse_range(param, nid);
4000 rc = nodemap_del_range(nodemap_name, nid);
4002 case LCFG_NODEMAP_ADMIN:
4003 bool_switch = simple_strtoul(param, NULL, 10);
4004 rc = nodemap_set_allow_root(nodemap_name, bool_switch);
4006 case LCFG_NODEMAP_TRUSTED:
4007 bool_switch = simple_strtoul(param, NULL, 10);
4008 rc = nodemap_set_trust_client_ids(nodemap_name, bool_switch);
4010 case LCFG_NODEMAP_SQUASH_UID:
4011 int_id = simple_strtoul(param, NULL, 10);
4012 rc = nodemap_set_squash_uid(nodemap_name, int_id);
4014 case LCFG_NODEMAP_SQUASH_GID:
4015 int_id = simple_strtoul(param, NULL, 10);
4016 rc = nodemap_set_squash_gid(nodemap_name, int_id);
4018 case LCFG_NODEMAP_ADD_UIDMAP:
4019 case LCFG_NODEMAP_ADD_GIDMAP:
4020 rc = nodemap_parse_idmap(param, idmap);
4023 if (cmd == LCFG_NODEMAP_ADD_UIDMAP)
4024 rc = nodemap_add_idmap(nodemap_name, NODEMAP_UID,
4027 rc = nodemap_add_idmap(nodemap_name, NODEMAP_GID,
4030 case LCFG_NODEMAP_DEL_UIDMAP:
4031 case LCFG_NODEMAP_DEL_GIDMAP:
4032 rc = nodemap_parse_idmap(param, idmap);
4035 if (cmd == LCFG_NODEMAP_DEL_UIDMAP)
4036 rc = nodemap_del_idmap(nodemap_name, NODEMAP_UID,
4039 rc = nodemap_del_idmap(nodemap_name, NODEMAP_GID,
4049 int mgs_pool_cmd(const struct lu_env *env, struct mgs_device *mgs,
4050 enum lcfg_command_type cmd, char *fsname,
4051 char *poolname, char *ostname)
4056 char *label = NULL, *canceled_label = NULL;
4058 struct mgs_target_info *mti = NULL;
4062 rc = mgs_find_or_make_fsdb(env, mgs, fsname, &fsdb);
4064 CERROR("Can't get db for %s\n", fsname);
4067 if (test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
4068 CERROR("%s is not defined\n", fsname);
4069 mgs_free_fsdb(mgs, fsdb);
4073 label_sz = 10 + strlen(fsname) + strlen(poolname);
4075 /* check if ostname match fsname */
4076 if (ostname != NULL) {
4079 ptr = strrchr(ostname, '-');
4080 if ((ptr == NULL) ||
4081 (strncmp(fsname, ostname, ptr-ostname) != 0))
4083 label_sz += strlen(ostname);
4086 OBD_ALLOC(label, label_sz);
4093 "new %s.%s", fsname, poolname);
4097 "add %s.%s.%s", fsname, poolname, ostname);
4100 OBD_ALLOC(canceled_label, label_sz);
4101 if (canceled_label == NULL)
4102 GOTO(out_label, rc = -ENOMEM);
4104 "rem %s.%s.%s", fsname, poolname, ostname);
4105 sprintf(canceled_label,
4106 "add %s.%s.%s", fsname, poolname, ostname);
4109 OBD_ALLOC(canceled_label, label_sz);
4110 if (canceled_label == NULL)
4111 GOTO(out_label, rc = -ENOMEM);
4113 "del %s.%s", fsname, poolname);
4114 sprintf(canceled_label,
4115 "new %s.%s", fsname, poolname);
4121 if (canceled_label != NULL) {
4124 GOTO(out_cancel, rc = -ENOMEM);
4127 mutex_lock(&fsdb->fsdb_mutex);
4128 /* write pool def to all MDT logs */
4129 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
4130 if (test_bit(i, fsdb->fsdb_mdt_index_map)) {
4131 rc = name_create_mdt_and_lov(&logname, &lovname,
4134 mutex_unlock(&fsdb->fsdb_mutex);
4137 if (canceled_label != NULL) {
4138 strcpy(mti->mti_svname, "lov pool");
4139 rc = mgs_modify(env, mgs, fsdb, mti, logname,
4140 lovname, canceled_label,
4145 rc = mgs_write_log_pool(env, mgs, logname,
4149 name_destroy(&logname);
4150 name_destroy(&lovname);
4152 mutex_unlock(&fsdb->fsdb_mutex);
4158 rc = name_create(&logname, fsname, "-client");
4160 mutex_unlock(&fsdb->fsdb_mutex);
4163 if (canceled_label != NULL) {
4164 rc = mgs_modify(env, mgs, fsdb, mti, logname,
4165 fsdb->fsdb_clilov, canceled_label, CM_SKIP);
4167 mutex_unlock(&fsdb->fsdb_mutex);
4168 name_destroy(&logname);
4173 rc = mgs_write_log_pool(env, mgs, logname, fsdb, fsdb->fsdb_clilov,
4174 cmd, fsname, poolname, ostname, label);
4175 mutex_unlock(&fsdb->fsdb_mutex);
4176 name_destroy(&logname);
4177 /* request for update */
4178 mgs_revoke_lock(mgs, fsdb, CONFIG_T_CONFIG);
4185 if (canceled_label != NULL)
4186 OBD_FREE(canceled_label, label_sz);
4188 OBD_FREE(label, label_sz);