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.gnu.org/licenses/gpl-2.0.html
23 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
24 * Use is subject to license terms.
26 * Copyright (c) 2011, 2015, Intel Corporation.
29 * This file is part of Lustre, http://www.lustre.org/
30 * Lustre is a trademark of Sun Microsystems, Inc.
32 * lustre/mgs/mgs_llog.c
34 * Lustre Management Server (mgs) config llog creation
36 * Author: Nathan Rutman <nathan@clusterfs.com>
37 * Author: Alex Zhuravlev <bzzz@whamcloud.com>
38 * Author: Mikhail Pershin <tappro@whamcloud.com>
41 #define DEBUG_SUBSYSTEM S_MGS
42 #define D_MGS D_CONFIG
45 #include <lustre_ioctl.h>
46 #include <lustre_param.h>
47 #include <lustre_sec.h>
48 #include <lustre_quota.h>
50 #include "mgs_internal.h"
52 /********************** Class functions ********************/
54 /* Find all logs in CONFIG directory and link then into list */
55 int class_dentry_readdir(const struct lu_env *env,
56 struct mgs_device *mgs, struct list_head *log_list)
58 struct dt_object *dir = mgs->mgs_configs_dir;
59 const struct dt_it_ops *iops;
61 struct mgs_direntry *de;
65 INIT_LIST_HEAD(log_list);
68 LASSERT(dir->do_index_ops);
70 iops = &dir->do_index_ops->dio_it;
71 it = iops->init(env, dir, LUDA_64BITHASH);
75 rc = iops->load(env, it, 0);
81 key = (void *)iops->key(env, it);
83 CERROR("%s: key failed when listing %s: rc = %d\n",
84 mgs->mgs_obd->obd_name, MOUNT_CONFIGS_DIR,
88 key_sz = iops->key_size(env, it);
91 /* filter out "." and ".." entries */
95 if (key_sz == 2 && key[1] == '.')
99 /* filter out ".bak" files */
100 /* sizeof(".bak") - 1 == 3 */
102 !memcmp(".bak", key + key_sz - 3, 3)) {
103 CDEBUG(D_MGS, "Skipping backup file %.*s\n",
108 de = mgs_direntry_alloc(key_sz + 1);
114 memcpy(de->mde_name, key, key_sz);
115 de->mde_name[key_sz] = 0;
117 list_add(&de->mde_list, log_list);
120 rc = iops->next(env, it);
130 CERROR("%s: key failed when listing %s: rc = %d\n",
131 mgs->mgs_obd->obd_name, MOUNT_CONFIGS_DIR, rc);
135 /******************** DB functions *********************/
137 static inline int name_create(char **newname, char *prefix, char *suffix)
140 OBD_ALLOC(*newname, strlen(prefix) + strlen(suffix) + 1);
143 sprintf(*newname, "%s%s", prefix, suffix);
147 static inline void name_destroy(char **name)
150 OBD_FREE(*name, strlen(*name) + 1);
154 struct mgs_fsdb_handler_data
160 /* from the (client) config log, figure out:
161 1. which ost's/mdt's are configured (by index)
162 2. what the last config step is
163 3. COMPAT_18 osc name
165 /* It might be better to have a separate db file, instead of parsing the info
166 out of the client log. This is slow and potentially error-prone. */
167 static int mgs_fsdb_handler(const struct lu_env *env, struct llog_handle *llh,
168 struct llog_rec_hdr *rec, void *data)
170 struct mgs_fsdb_handler_data *d = data;
171 struct fs_db *fsdb = d->fsdb;
172 int cfg_len = rec->lrh_len;
173 char *cfg_buf = (char*) (rec + 1);
174 struct lustre_cfg *lcfg;
179 if (rec->lrh_type != OBD_CFG_REC) {
180 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
184 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
186 CERROR("Insane cfg\n");
190 lcfg = (struct lustre_cfg *)cfg_buf;
192 CDEBUG(D_INFO, "cmd %x %s %s\n", lcfg->lcfg_command,
193 lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));
195 /* Figure out ost indicies */
196 /* lov_modify_tgts add 0:lov1 1:ost1_UUID 2(index):0 3(gen):1 */
197 if (lcfg->lcfg_command == LCFG_LOV_ADD_OBD ||
198 lcfg->lcfg_command == LCFG_LOV_DEL_OBD) {
199 index = simple_strtoul(lustre_cfg_string(lcfg, 2),
201 CDEBUG(D_MGS, "OST index for %s is %u (%s)\n",
202 lustre_cfg_string(lcfg, 1), index,
203 lustre_cfg_string(lcfg, 2));
204 set_bit(index, fsdb->fsdb_ost_index_map);
207 /* Figure out mdt indicies */
208 /* attach 0:MDC_uml1_mdsA_MNT_client 1:mdc 2:1d834_MNT_client_03f */
209 if ((lcfg->lcfg_command == LCFG_ATTACH) &&
210 (strcmp(lustre_cfg_string(lcfg, 1), LUSTRE_MDC_NAME) == 0)) {
211 rc = server_name2index(lustre_cfg_string(lcfg, 0),
213 if (rc != LDD_F_SV_TYPE_MDT) {
214 CWARN("Unparsable MDC name %s, assuming index 0\n",
215 lustre_cfg_string(lcfg, 0));
219 CDEBUG(D_MGS, "MDT index is %u\n", index);
220 set_bit(index, fsdb->fsdb_mdt_index_map);
221 fsdb->fsdb_mdt_count ++;
225 * figure out the old config. fsdb_gen = 0 means old log
226 * It is obsoleted and not supported anymore
228 if (fsdb->fsdb_gen == 0) {
229 CERROR("Old config format is not supported\n");
234 * compat to 1.8, check osc name used by MDT0 to OSTs, bz18548.
236 if (!test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags) &&
237 lcfg->lcfg_command == LCFG_ATTACH &&
238 strcmp(lustre_cfg_string(lcfg, 1), LUSTRE_OSC_NAME) == 0) {
239 if (OBD_OCD_VERSION_MAJOR(d->ver) == 1 &&
240 OBD_OCD_VERSION_MINOR(d->ver) <= 8) {
241 CWARN("MDT using 1.8 OSC name scheme\n");
242 set_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags);
246 if (lcfg->lcfg_command == LCFG_MARKER) {
247 struct cfg_marker *marker;
248 marker = lustre_cfg_buf(lcfg, 1);
250 d->ver = marker->cm_vers;
252 /* Keep track of the latest marker step */
253 fsdb->fsdb_gen = max(fsdb->fsdb_gen, marker->cm_step);
259 /* fsdb->fsdb_mutex is already held in mgs_find_or_make_fsdb*/
260 static int mgs_get_fsdb_from_llog(const struct lu_env *env,
261 struct mgs_device *mgs,
265 struct llog_handle *loghandle;
266 struct llog_ctxt *ctxt;
267 struct mgs_fsdb_handler_data d = { fsdb, 0 };
272 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
273 LASSERT(ctxt != NULL);
274 rc = name_create(&logname, fsdb->fsdb_name, "-client");
277 rc = llog_open_create(env, ctxt, &loghandle, NULL, logname);
281 rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL);
285 if (llog_get_size(loghandle) <= 1)
286 set_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags);
288 rc = llog_process(env, loghandle, mgs_fsdb_handler, (void *)&d, NULL);
289 CDEBUG(D_INFO, "get_db = %d\n", rc);
291 llog_close(env, loghandle);
293 name_destroy(&logname);
300 static void mgs_free_fsdb_srpc(struct fs_db *fsdb)
302 struct mgs_tgt_srpc_conf *tgtconf;
304 /* free target-specific rules */
305 while (fsdb->fsdb_srpc_tgt) {
306 tgtconf = fsdb->fsdb_srpc_tgt;
307 fsdb->fsdb_srpc_tgt = tgtconf->mtsc_next;
309 LASSERT(tgtconf->mtsc_tgt);
311 sptlrpc_rule_set_free(&tgtconf->mtsc_rset);
312 OBD_FREE(tgtconf->mtsc_tgt, strlen(tgtconf->mtsc_tgt) + 1);
313 OBD_FREE_PTR(tgtconf);
316 /* free general rules */
317 sptlrpc_rule_set_free(&fsdb->fsdb_srpc_gen);
320 struct fs_db *mgs_find_fsdb(struct mgs_device *mgs, char *fsname)
323 struct list_head *tmp;
325 list_for_each(tmp, &mgs->mgs_fs_db_list) {
326 fsdb = list_entry(tmp, struct fs_db, fsdb_list);
327 if (strcmp(fsdb->fsdb_name, fsname) == 0)
333 /* caller must hold the mgs->mgs_fs_db_lock */
334 static struct fs_db *mgs_new_fsdb(const struct lu_env *env,
335 struct mgs_device *mgs, char *fsname)
341 if (strlen(fsname) >= sizeof(fsdb->fsdb_name)) {
342 CERROR("fsname %s is too long\n", fsname);
343 RETURN(ERR_PTR(-EINVAL));
348 RETURN(ERR_PTR(-ENOMEM));
350 strcpy(fsdb->fsdb_name, fsname);
351 mutex_init(&fsdb->fsdb_mutex);
352 set_bit(FSDB_UDESC, &fsdb->fsdb_flags);
355 if (strcmp(fsname, MGSSELF_NAME) == 0) {
356 set_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags);
357 fsdb->fsdb_mgs = mgs;
359 OBD_ALLOC(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
360 OBD_ALLOC(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
361 if (!fsdb->fsdb_ost_index_map || !fsdb->fsdb_mdt_index_map) {
362 CERROR("No memory for index maps\n");
363 GOTO(err, rc = -ENOMEM);
366 rc = name_create(&fsdb->fsdb_clilov, fsname, "-clilov");
369 rc = name_create(&fsdb->fsdb_clilmv, fsname, "-clilmv");
373 /* initialise data for NID table */
374 mgs_ir_init_fs(env, mgs, fsdb);
376 lproc_mgs_add_live(mgs, fsdb);
379 list_add(&fsdb->fsdb_list, &mgs->mgs_fs_db_list);
383 if (fsdb->fsdb_ost_index_map)
384 OBD_FREE(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
385 if (fsdb->fsdb_mdt_index_map)
386 OBD_FREE(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
387 name_destroy(&fsdb->fsdb_clilov);
388 name_destroy(&fsdb->fsdb_clilmv);
393 static void mgs_free_fsdb(struct mgs_device *mgs, struct fs_db *fsdb)
395 /* wait for anyone with the sem */
396 mutex_lock(&fsdb->fsdb_mutex);
397 lproc_mgs_del_live(mgs, fsdb);
398 list_del(&fsdb->fsdb_list);
400 /* deinitialize fsr */
401 mgs_ir_fini_fs(mgs, fsdb);
403 if (fsdb->fsdb_ost_index_map)
404 OBD_FREE(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
405 if (fsdb->fsdb_mdt_index_map)
406 OBD_FREE(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
407 name_destroy(&fsdb->fsdb_clilov);
408 name_destroy(&fsdb->fsdb_clilmv);
409 mgs_free_fsdb_srpc(fsdb);
410 mutex_unlock(&fsdb->fsdb_mutex);
414 int mgs_init_fsdb_list(struct mgs_device *mgs)
416 INIT_LIST_HEAD(&mgs->mgs_fs_db_list);
420 int mgs_cleanup_fsdb_list(struct mgs_device *mgs)
423 struct list_head *tmp, *tmp2;
425 mutex_lock(&mgs->mgs_mutex);
426 list_for_each_safe(tmp, tmp2, &mgs->mgs_fs_db_list) {
427 fsdb = list_entry(tmp, struct fs_db, fsdb_list);
428 mgs_free_fsdb(mgs, fsdb);
430 mutex_unlock(&mgs->mgs_mutex);
434 int mgs_find_or_make_fsdb(const struct lu_env *env,
435 struct mgs_device *mgs, char *name,
442 mutex_lock(&mgs->mgs_mutex);
443 fsdb = mgs_find_fsdb(mgs, name);
445 mutex_unlock(&mgs->mgs_mutex);
450 CDEBUG(D_MGS, "Creating new db\n");
451 fsdb = mgs_new_fsdb(env, mgs, name);
452 /* lock fsdb_mutex until the db is loaded from llogs */
454 mutex_lock(&fsdb->fsdb_mutex);
455 mutex_unlock(&mgs->mgs_mutex);
457 RETURN(PTR_ERR(fsdb));
459 if (!test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
460 /* populate the db from the client llog */
461 rc = mgs_get_fsdb_from_llog(env, mgs, fsdb);
463 CERROR("Can't get db from client log %d\n", rc);
468 /* populate srpc rules from params llog */
469 rc = mgs_get_fsdb_srpc_from_llog(env, mgs, fsdb);
471 CERROR("Can't get db from params log %d\n", rc);
475 mutex_unlock(&fsdb->fsdb_mutex);
481 mutex_unlock(&fsdb->fsdb_mutex);
482 mgs_free_fsdb(mgs, fsdb);
488 -1= empty client log */
489 int mgs_check_index(const struct lu_env *env,
490 struct mgs_device *mgs,
491 struct mgs_target_info *mti)
498 LASSERT(!(mti->mti_flags & LDD_F_NEED_INDEX));
500 rc = mgs_find_or_make_fsdb(env, mgs, mti->mti_fsname, &fsdb);
502 CERROR("Can't get db for %s\n", mti->mti_fsname);
506 if (test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags))
509 if (mti->mti_flags & LDD_F_SV_TYPE_OST)
510 imap = fsdb->fsdb_ost_index_map;
511 else if (mti->mti_flags & LDD_F_SV_TYPE_MDT)
512 imap = fsdb->fsdb_mdt_index_map;
516 if (test_bit(mti->mti_stripe_index, imap))
521 static __inline__ int next_index(void *index_map, int map_len)
524 for (i = 0; i < map_len * 8; i++)
525 if (!test_bit(i, index_map)) {
528 CERROR("max index %d exceeded.\n", i);
533 0 newly marked as in use
535 +EALREADY for update of an old index */
536 static int mgs_set_index(const struct lu_env *env,
537 struct mgs_device *mgs,
538 struct mgs_target_info *mti)
545 rc = mgs_find_or_make_fsdb(env, mgs, mti->mti_fsname, &fsdb);
547 CERROR("Can't get db for %s\n", mti->mti_fsname);
551 mutex_lock(&fsdb->fsdb_mutex);
552 if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
553 imap = fsdb->fsdb_ost_index_map;
554 } else if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
555 imap = fsdb->fsdb_mdt_index_map;
557 GOTO(out_up, rc = -EINVAL);
560 if (mti->mti_flags & LDD_F_NEED_INDEX) {
561 rc = next_index(imap, INDEX_MAP_SIZE);
563 GOTO(out_up, rc = -ERANGE);
564 mti->mti_stripe_index = rc;
565 if (mti->mti_flags & LDD_F_SV_TYPE_MDT)
566 fsdb->fsdb_mdt_count ++;
569 /* the last index(0xffff) is reserved for default value. */
570 if (mti->mti_stripe_index >= INDEX_MAP_SIZE * 8 - 1) {
571 LCONSOLE_ERROR_MSG(0x13f, "Server %s requested index %u, "
572 "but index must be less than %u.\n",
573 mti->mti_svname, mti->mti_stripe_index,
574 INDEX_MAP_SIZE * 8 - 1);
575 GOTO(out_up, rc = -ERANGE);
578 if (test_bit(mti->mti_stripe_index, imap)) {
579 if ((mti->mti_flags & LDD_F_VIRGIN) &&
580 !(mti->mti_flags & LDD_F_WRITECONF)) {
581 LCONSOLE_ERROR_MSG(0x140, "Server %s requested index "
582 "%d, but that index is already in "
583 "use. Use --writeconf to force\n",
585 mti->mti_stripe_index);
586 GOTO(out_up, rc = -EADDRINUSE);
588 CDEBUG(D_MGS, "Server %s updating index %d\n",
589 mti->mti_svname, mti->mti_stripe_index);
590 GOTO(out_up, rc = EALREADY);
594 set_bit(mti->mti_stripe_index, imap);
595 clear_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags);
596 mutex_unlock(&fsdb->fsdb_mutex);
597 if (server_make_name(mti->mti_flags & ~(LDD_F_VIRGIN | LDD_F_WRITECONF),
598 mti->mti_stripe_index, mti->mti_fsname,
600 CERROR("unknown server type %#x\n", mti->mti_flags);
604 CDEBUG(D_MGS, "Set index for %s to %d\n", mti->mti_svname,
605 mti->mti_stripe_index);
609 mutex_unlock(&fsdb->fsdb_mutex);
613 struct mgs_modify_lookup {
614 struct cfg_marker mml_marker;
618 static int mgs_modify_handler(const struct lu_env *env,
619 struct llog_handle *llh,
620 struct llog_rec_hdr *rec, void *data)
622 struct mgs_modify_lookup *mml = data;
623 struct cfg_marker *marker;
624 struct lustre_cfg *lcfg = REC_DATA(rec);
625 int cfg_len = REC_DATA_LEN(rec);
629 if (rec->lrh_type != OBD_CFG_REC) {
630 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
634 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
636 CERROR("Insane cfg\n");
640 /* We only care about markers */
641 if (lcfg->lcfg_command != LCFG_MARKER)
644 marker = lustre_cfg_buf(lcfg, 1);
645 if ((strcmp(mml->mml_marker.cm_comment, marker->cm_comment) == 0) &&
646 (strcmp(mml->mml_marker.cm_tgtname, marker->cm_tgtname) == 0) &&
647 !(marker->cm_flags & CM_SKIP)) {
648 /* Found a non-skipped marker match */
649 CDEBUG(D_MGS, "Changing rec %u marker %d %x->%x: %s %s\n",
650 rec->lrh_index, marker->cm_step,
651 marker->cm_flags, mml->mml_marker.cm_flags,
652 marker->cm_tgtname, marker->cm_comment);
653 /* Overwrite the old marker llog entry */
654 marker->cm_flags &= ~CM_EXCLUDE; /* in case we're unexcluding */
655 marker->cm_flags |= mml->mml_marker.cm_flags;
656 marker->cm_canceltime = mml->mml_marker.cm_canceltime;
657 rc = llog_write(env, llh, rec, rec->lrh_index);
666 * Modify an existing config log record (for CM_SKIP or CM_EXCLUDE)
668 * 0 - modified successfully,
669 * 1 - no modification was done
672 static int mgs_modify(const struct lu_env *env, struct mgs_device *mgs,
673 struct fs_db *fsdb, struct mgs_target_info *mti,
674 char *logname, char *devname, char *comment, int flags)
676 struct llog_handle *loghandle;
677 struct llog_ctxt *ctxt;
678 struct mgs_modify_lookup *mml;
683 LASSERT(mutex_is_locked(&fsdb->fsdb_mutex));
684 CDEBUG(D_MGS, "modify %s/%s/%s fl=%x\n", logname, devname, comment,
687 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
688 LASSERT(ctxt != NULL);
689 rc = llog_open(env, ctxt, &loghandle, NULL, logname, LLOG_OPEN_EXISTS);
696 rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL);
700 if (llog_get_size(loghandle) <= 1)
701 GOTO(out_close, rc = 0);
705 GOTO(out_close, rc = -ENOMEM);
706 if (strlcpy(mml->mml_marker.cm_comment, comment,
707 sizeof(mml->mml_marker.cm_comment)) >=
708 sizeof(mml->mml_marker.cm_comment))
709 GOTO(out_free, rc = -E2BIG);
710 if (strlcpy(mml->mml_marker.cm_tgtname, devname,
711 sizeof(mml->mml_marker.cm_tgtname)) >=
712 sizeof(mml->mml_marker.cm_tgtname))
713 GOTO(out_free, rc = -E2BIG);
714 /* Modify mostly means cancel */
715 mml->mml_marker.cm_flags = flags;
716 mml->mml_marker.cm_canceltime = flags ? cfs_time_current_sec() : 0;
717 mml->mml_modified = 0;
718 rc = llog_process(env, loghandle, mgs_modify_handler, (void *)mml,
720 if (!rc && !mml->mml_modified)
727 llog_close(env, loghandle);
730 CERROR("%s: modify %s/%s failed: rc = %d\n",
731 mgs->mgs_obd->obd_name, mti->mti_svname, comment, rc);
736 /** This structure is passed to mgs_replace_handler */
737 struct mgs_replace_uuid_lookup {
738 /* Nids are replaced for this target device */
739 struct mgs_target_info target;
740 /* Temporary modified llog */
741 struct llog_handle *temp_llh;
742 /* Flag is set if in target block*/
743 int in_target_device;
744 /* Nids already added. Just skip (multiple nids) */
745 int device_nids_added;
746 /* Flag is set if this block should not be copied */
751 * Check: a) if block should be skipped
752 * b) is it target block
757 * \retval 0 should not to be skipped
758 * \retval 1 should to be skipped
760 static int check_markers(struct lustre_cfg *lcfg,
761 struct mgs_replace_uuid_lookup *mrul)
763 struct cfg_marker *marker;
765 /* Track markers. Find given device */
766 if (lcfg->lcfg_command == LCFG_MARKER) {
767 marker = lustre_cfg_buf(lcfg, 1);
768 /* Clean llog from records marked as CM_EXCLUDE.
769 CM_SKIP records are used for "active" command
770 and can be restored if needed */
771 if ((marker->cm_flags & (CM_EXCLUDE | CM_START)) ==
772 (CM_EXCLUDE | CM_START)) {
777 if ((marker->cm_flags & (CM_EXCLUDE | CM_END)) ==
778 (CM_EXCLUDE | CM_END)) {
783 if (strcmp(mrul->target.mti_svname, marker->cm_tgtname) == 0) {
784 LASSERT(!(marker->cm_flags & CM_START) ||
785 !(marker->cm_flags & CM_END));
786 if (marker->cm_flags & CM_START) {
787 mrul->in_target_device = 1;
788 mrul->device_nids_added = 0;
789 } else if (marker->cm_flags & CM_END)
790 mrul->in_target_device = 0;
797 static int record_base(const struct lu_env *env, struct llog_handle *llh,
798 char *cfgname, lnet_nid_t nid, int cmd,
799 char *s1, char *s2, char *s3, char *s4)
801 struct mgs_thread_info *mgi = mgs_env_info(env);
802 struct llog_cfg_rec *lcr;
805 CDEBUG(D_MGS, "lcfg %s %#x %s %s %s %s\n", cfgname,
806 cmd, s1, s2, s3, s4);
808 lustre_cfg_bufs_reset(&mgi->mgi_bufs, cfgname);
810 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, s1);
812 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 2, s2);
814 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 3, s3);
816 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 4, s4);
818 lcr = lustre_cfg_rec_new(cmd, &mgi->mgi_bufs);
822 lcr->lcr_cfg.lcfg_nid = nid;
823 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
825 lustre_cfg_rec_free(lcr);
829 "failed to write lcfg %s %#x %s %s %s %s: rc = %d\n",
830 cfgname, cmd, s1, s2, s3, s4, rc);
834 static inline int record_add_uuid(const struct lu_env *env,
835 struct llog_handle *llh,
836 uint64_t nid, char *uuid)
838 return record_base(env, llh, NULL, nid, LCFG_ADD_UUID, uuid,
842 static inline int record_add_conn(const struct lu_env *env,
843 struct llog_handle *llh,
844 char *devname, char *uuid)
846 return record_base(env, llh, devname, 0, LCFG_ADD_CONN, uuid,
850 static inline int record_attach(const struct lu_env *env,
851 struct llog_handle *llh, char *devname,
852 char *type, char *uuid)
854 return record_base(env, llh, devname, 0, LCFG_ATTACH, type, uuid,
858 static inline int record_setup(const struct lu_env *env,
859 struct llog_handle *llh, char *devname,
860 char *s1, char *s2, char *s3, char *s4)
862 return record_base(env, llh, devname, 0, LCFG_SETUP, s1, s2, s3, s4);
866 * \retval <0 record processing error
867 * \retval n record is processed. No need copy original one.
868 * \retval 0 record is not processed.
870 static int process_command(const struct lu_env *env, struct lustre_cfg *lcfg,
871 struct mgs_replace_uuid_lookup *mrul)
878 if (lcfg->lcfg_command == LCFG_ADD_UUID) {
879 /* LCFG_ADD_UUID command found. Let's skip original command
880 and add passed nids */
881 ptr = mrul->target.mti_params;
882 while (class_parse_nid(ptr, &nid, &ptr) == 0) {
883 CDEBUG(D_MGS, "add nid %s with uuid %s, "
884 "device %s\n", libcfs_nid2str(nid),
885 mrul->target.mti_params,
886 mrul->target.mti_svname);
887 rc = record_add_uuid(env,
889 mrul->target.mti_params);
894 if (nids_added == 0) {
895 CERROR("No new nids were added, nid %s with uuid %s, "
896 "device %s\n", libcfs_nid2str(nid),
897 mrul->target.mti_params,
898 mrul->target.mti_svname);
901 mrul->device_nids_added = 1;
907 if (mrul->device_nids_added && lcfg->lcfg_command == LCFG_SETUP) {
908 /* LCFG_SETUP command found. UUID should be changed */
909 rc = record_setup(env,
911 /* devname the same */
912 lustre_cfg_string(lcfg, 0),
913 /* s1 is not changed */
914 lustre_cfg_string(lcfg, 1),
915 /* new uuid should be
917 mrul->target.mti_params,
918 /* s3 is not changed */
919 lustre_cfg_string(lcfg, 3),
920 /* s4 is not changed */
921 lustre_cfg_string(lcfg, 4));
925 /* Another commands in target device block */
930 * Handler that called for every record in llog.
931 * Records are processed in order they placed in llog.
933 * \param[in] llh log to be processed
934 * \param[in] rec current record
935 * \param[in] data mgs_replace_uuid_lookup structure
939 static int mgs_replace_handler(const struct lu_env *env,
940 struct llog_handle *llh,
941 struct llog_rec_hdr *rec,
944 struct mgs_replace_uuid_lookup *mrul;
945 struct lustre_cfg *lcfg = REC_DATA(rec);
946 int cfg_len = REC_DATA_LEN(rec);
950 mrul = (struct mgs_replace_uuid_lookup *)data;
952 if (rec->lrh_type != OBD_CFG_REC) {
953 CERROR("unhandled lrh_type: %#x, cmd %x %s %s\n",
954 rec->lrh_type, lcfg->lcfg_command,
955 lustre_cfg_string(lcfg, 0),
956 lustre_cfg_string(lcfg, 1));
960 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
962 /* Do not copy any invalidated records */
963 GOTO(skip_out, rc = 0);
966 rc = check_markers(lcfg, mrul);
967 if (rc || mrul->skip_it)
968 GOTO(skip_out, rc = 0);
970 /* Write to new log all commands outside target device block */
971 if (!mrul->in_target_device)
972 GOTO(copy_out, rc = 0);
974 /* Skip all other LCFG_ADD_UUID and LCFG_ADD_CONN records
975 (failover nids) for this target, assuming that if then
976 primary is changing then so is the failover */
977 if (mrul->device_nids_added &&
978 (lcfg->lcfg_command == LCFG_ADD_UUID ||
979 lcfg->lcfg_command == LCFG_ADD_CONN))
980 GOTO(skip_out, rc = 0);
982 rc = process_command(env, lcfg, mrul);
989 /* Record is placed in temporary llog as is */
990 rc = llog_write(env, mrul->temp_llh, rec, LLOG_NEXT_IDX);
992 CDEBUG(D_MGS, "Copied idx=%d, rc=%d, len=%d, cmd %x %s %s\n",
993 rec->lrh_index, rc, rec->lrh_len, lcfg->lcfg_command,
994 lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));
998 CDEBUG(D_MGS, "Skipped idx=%d, rc=%d, len=%d, cmd %x %s %s\n",
999 rec->lrh_index, rc, rec->lrh_len, lcfg->lcfg_command,
1000 lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));
1004 static int mgs_log_is_empty(const struct lu_env *env,
1005 struct mgs_device *mgs, char *name)
1007 struct llog_ctxt *ctxt;
1010 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
1011 LASSERT(ctxt != NULL);
1013 rc = llog_is_empty(env, ctxt, name);
1014 llog_ctxt_put(ctxt);
1018 static int mgs_replace_nids_log(const struct lu_env *env,
1019 struct obd_device *mgs, struct fs_db *fsdb,
1020 char *logname, char *devname, char *nids)
1022 struct llog_handle *orig_llh, *backup_llh;
1023 struct llog_ctxt *ctxt;
1024 struct mgs_replace_uuid_lookup *mrul;
1025 struct mgs_device *mgs_dev = lu2mgs_dev(mgs->obd_lu_dev);
1026 static struct obd_uuid cfg_uuid = { .uuid = "config_uuid" };
1031 CDEBUG(D_MGS, "Replace nids for %s in %s\n", devname, logname);
1033 ctxt = llog_get_context(mgs, LLOG_CONFIG_ORIG_CTXT);
1034 LASSERT(ctxt != NULL);
1036 if (mgs_log_is_empty(env, mgs_dev, logname)) {
1037 /* Log is empty. Nothing to replace */
1038 GOTO(out_put, rc = 0);
1041 OBD_ALLOC(backup, strlen(logname) + strlen(".bak") + 1);
1043 GOTO(out_put, rc = -ENOMEM);
1045 sprintf(backup, "%s.bak", logname);
1047 rc = llog_backup(env, mgs, ctxt, ctxt, logname, backup);
1049 /* Now erase original log file. Connections are not allowed.
1050 Backup is already saved */
1051 rc = llog_erase(env, ctxt, NULL, logname);
1054 } else if (rc != -ENOENT) {
1055 CERROR("%s: can't make backup for %s: rc = %d\n",
1056 mgs->obd_name, logname, rc);
1060 /* open local log */
1061 rc = llog_open_create(env, ctxt, &orig_llh, NULL, logname);
1063 GOTO(out_restore, rc);
1065 rc = llog_init_handle(env, orig_llh, LLOG_F_IS_PLAIN, &cfg_uuid);
1067 GOTO(out_closel, rc);
1069 /* open backup llog */
1070 rc = llog_open(env, ctxt, &backup_llh, NULL, backup,
1073 GOTO(out_closel, rc);
1075 rc = llog_init_handle(env, backup_llh, LLOG_F_IS_PLAIN, NULL);
1077 GOTO(out_close, rc);
1079 if (llog_get_size(backup_llh) <= 1)
1080 GOTO(out_close, rc = 0);
1082 OBD_ALLOC_PTR(mrul);
1084 GOTO(out_close, rc = -ENOMEM);
1085 /* devname is only needed information to replace UUID records */
1086 strlcpy(mrul->target.mti_svname, devname,
1087 sizeof(mrul->target.mti_svname));
1088 /* parse nids later */
1089 strlcpy(mrul->target.mti_params, nids, sizeof(mrul->target.mti_params));
1090 /* Copy records to this temporary llog */
1091 mrul->temp_llh = orig_llh;
1093 rc = llog_process(env, backup_llh, mgs_replace_handler,
1094 (void *)mrul, NULL);
1097 rc2 = llog_close(NULL, backup_llh);
1101 rc2 = llog_close(NULL, orig_llh);
1107 CERROR("%s: llog should be restored: rc = %d\n",
1109 rc2 = llog_backup(env, mgs, ctxt, ctxt, backup,
1112 CERROR("%s: can't restore backup %s: rc = %d\n",
1113 mgs->obd_name, logname, rc2);
1117 OBD_FREE(backup, strlen(backup) + 1);
1120 llog_ctxt_put(ctxt);
1123 CERROR("%s: failed to replace nids in log %s: rc = %d\n",
1124 mgs->obd_name, logname, rc);
1130 * Parse device name and get file system name and/or device index
1132 * \param[in] devname device name (ex. lustre-MDT0000)
1133 * \param[out] fsname file system name(optional)
1134 * \param[out] index device index(optional)
1138 static int mgs_parse_devname(char *devname, char *fsname, __u32 *index)
1143 /* Extract fsname */
1145 rc = server_name2fsname(devname, fsname, NULL);
1147 CDEBUG(D_MGS, "Device name %s without fsname\n",
1154 rc = server_name2index(devname, index, NULL);
1156 CDEBUG(D_MGS, "Device name %s with wrong index\n",
1165 /* This is only called during replace_nids */
1166 static int only_mgs_is_running(struct obd_device *mgs_obd)
1168 /* TDB: Is global variable with devices count exists? */
1169 int num_devices = get_devices_count();
1170 int num_exports = 0;
1171 struct obd_export *exp;
1173 spin_lock(&mgs_obd->obd_dev_lock);
1174 list_for_each_entry(exp, &mgs_obd->obd_exports, exp_obd_chain) {
1175 /* skip self export */
1176 if (exp == mgs_obd->obd_self_export)
1178 if (exp_connect_flags(exp) & OBD_CONNECT_MDS_MDS)
1183 CERROR("%s: node %s still connected during replace_nids "
1184 "connect_flags:%llx\n",
1186 libcfs_nid2str(exp->exp_nid_stats->nid),
1187 exp_connect_flags(exp));
1190 spin_unlock(&mgs_obd->obd_dev_lock);
1192 /* osd, MGS and MGC + self_export
1193 (wc -l /proc/fs/lustre/devices <= 2) && (non self exports == 0) */
1194 return (num_devices <= 3) && (num_exports == 0);
1197 static int name_create_mdt(char **logname, char *fsname, int i)
1201 sprintf(mdt_index, "-MDT%04x", i);
1202 return name_create(logname, fsname, mdt_index);
1206 * Replace nids for \a device to \a nids values
1208 * \param obd MGS obd device
1209 * \param devname nids need to be replaced for this device
1210 * (ex. lustre-OST0000)
1211 * \param nids nids list (ex. nid1,nid2,nid3)
1215 int mgs_replace_nids(const struct lu_env *env,
1216 struct mgs_device *mgs,
1217 char *devname, char *nids)
1219 /* Assume fsname is part of device name */
1220 char fsname[MTI_NAME_MAXLEN];
1227 struct obd_device *mgs_obd = mgs->mgs_obd;
1230 /* We can only change NIDs if no other nodes are connected */
1231 spin_lock(&mgs_obd->obd_dev_lock);
1232 conn_state = mgs_obd->obd_no_conn;
1233 mgs_obd->obd_no_conn = 1;
1234 spin_unlock(&mgs_obd->obd_dev_lock);
1236 /* We can not change nids if not only MGS is started */
1237 if (!only_mgs_is_running(mgs_obd)) {
1238 CERROR("Only MGS is allowed to be started\n");
1239 GOTO(out, rc = -EINPROGRESS);
1242 /* Get fsname and index*/
1243 rc = mgs_parse_devname(devname, fsname, &index);
1247 rc = mgs_find_or_make_fsdb(env, mgs, fsname, &fsdb);
1249 CERROR("%s: can't find fsdb: rc = %d\n", fsname, rc);
1253 /* Process client llogs */
1254 name_create(&logname, fsname, "-client");
1255 rc = mgs_replace_nids_log(env, mgs_obd, fsdb, logname, devname, nids);
1256 name_destroy(&logname);
1258 CERROR("%s: error while replacing NIDs for %s: rc = %d\n",
1259 fsname, devname, rc);
1263 /* Process MDT llogs */
1264 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
1265 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
1267 name_create_mdt(&logname, fsname, i);
1268 rc = mgs_replace_nids_log(env, mgs_obd, fsdb, logname, devname, nids);
1269 name_destroy(&logname);
1275 spin_lock(&mgs_obd->obd_dev_lock);
1276 mgs_obd->obd_no_conn = conn_state;
1277 spin_unlock(&mgs_obd->obd_dev_lock);
1282 static int record_lov_setup(const struct lu_env *env, struct llog_handle *llh,
1283 char *devname, struct lov_desc *desc)
1285 struct mgs_thread_info *mgi = mgs_env_info(env);
1286 struct llog_cfg_rec *lcr;
1289 lustre_cfg_bufs_reset(&mgi->mgi_bufs, devname);
1290 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, desc, sizeof(*desc));
1291 lcr = lustre_cfg_rec_new(LCFG_SETUP, &mgi->mgi_bufs);
1295 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1296 lustre_cfg_rec_free(lcr);
1300 static int record_lmv_setup(const struct lu_env *env, struct llog_handle *llh,
1301 char *devname, struct lmv_desc *desc)
1303 struct mgs_thread_info *mgi = mgs_env_info(env);
1304 struct llog_cfg_rec *lcr;
1307 lustre_cfg_bufs_reset(&mgi->mgi_bufs, devname);
1308 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, desc, sizeof(*desc));
1309 lcr = lustre_cfg_rec_new(LCFG_SETUP, &mgi->mgi_bufs);
1313 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1314 lustre_cfg_rec_free(lcr);
1318 static inline int record_mdc_add(const struct lu_env *env,
1319 struct llog_handle *llh,
1320 char *logname, char *mdcuuid,
1321 char *mdtuuid, char *index,
1324 return record_base(env,llh,logname,0,LCFG_ADD_MDC,
1325 mdtuuid,index,gen,mdcuuid);
1328 static inline int record_lov_add(const struct lu_env *env,
1329 struct llog_handle *llh,
1330 char *lov_name, char *ost_uuid,
1331 char *index, char *gen)
1333 return record_base(env, llh, lov_name, 0, LCFG_LOV_ADD_OBD,
1334 ost_uuid, index, gen, NULL);
1337 static inline int record_mount_opt(const struct lu_env *env,
1338 struct llog_handle *llh,
1339 char *profile, char *lov_name,
1342 return record_base(env, llh, NULL, 0, LCFG_MOUNTOPT,
1343 profile, lov_name, mdc_name, NULL);
1346 static int record_marker(const struct lu_env *env,
1347 struct llog_handle *llh,
1348 struct fs_db *fsdb, __u32 flags,
1349 char *tgtname, char *comment)
1351 struct mgs_thread_info *mgi = mgs_env_info(env);
1352 struct llog_cfg_rec *lcr;
1356 if (flags & CM_START)
1358 mgi->mgi_marker.cm_step = fsdb->fsdb_gen;
1359 mgi->mgi_marker.cm_flags = flags;
1360 mgi->mgi_marker.cm_vers = LUSTRE_VERSION_CODE;
1361 cplen = strlcpy(mgi->mgi_marker.cm_tgtname, tgtname,
1362 sizeof(mgi->mgi_marker.cm_tgtname));
1363 if (cplen >= sizeof(mgi->mgi_marker.cm_tgtname))
1365 cplen = strlcpy(mgi->mgi_marker.cm_comment, comment,
1366 sizeof(mgi->mgi_marker.cm_comment));
1367 if (cplen >= sizeof(mgi->mgi_marker.cm_comment))
1369 mgi->mgi_marker.cm_createtime = cfs_time_current_sec();
1370 mgi->mgi_marker.cm_canceltime = 0;
1371 lustre_cfg_bufs_reset(&mgi->mgi_bufs, NULL);
1372 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, &mgi->mgi_marker,
1373 sizeof(mgi->mgi_marker));
1374 lcr = lustre_cfg_rec_new(LCFG_MARKER, &mgi->mgi_bufs);
1378 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1379 lustre_cfg_rec_free(lcr);
1383 static int record_start_log(const struct lu_env *env, struct mgs_device *mgs,
1384 struct llog_handle **llh, char *name)
1386 static struct obd_uuid cfg_uuid = { .uuid = "config_uuid" };
1387 struct llog_ctxt *ctxt;
1392 GOTO(out, rc = -EBUSY);
1394 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
1396 GOTO(out, rc = -ENODEV);
1397 LASSERT(ctxt->loc_obd == mgs->mgs_obd);
1399 rc = llog_open_create(env, ctxt, llh, NULL, name);
1402 rc = llog_init_handle(env, *llh, LLOG_F_IS_PLAIN, &cfg_uuid);
1404 llog_close(env, *llh);
1406 llog_ctxt_put(ctxt);
1409 CERROR("%s: can't start log %s: rc = %d\n",
1410 mgs->mgs_obd->obd_name, name, rc);
1416 static int record_end_log(const struct lu_env *env, struct llog_handle **llh)
1420 rc = llog_close(env, *llh);
1426 /******************** config "macros" *********************/
1428 /* write an lcfg directly into a log (with markers) */
1429 static int mgs_write_log_direct(const struct lu_env *env,
1430 struct mgs_device *mgs, struct fs_db *fsdb,
1431 char *logname, struct llog_cfg_rec *lcr,
1432 char *devname, char *comment)
1434 struct llog_handle *llh = NULL;
1439 rc = record_start_log(env, mgs, &llh, logname);
1443 /* FIXME These should be a single journal transaction */
1444 rc = record_marker(env, llh, fsdb, CM_START, devname, comment);
1447 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1450 rc = record_marker(env, llh, fsdb, CM_END, devname, comment);
1454 record_end_log(env, &llh);
1458 /* write the lcfg in all logs for the given fs */
1459 static int mgs_write_log_direct_all(const struct lu_env *env,
1460 struct mgs_device *mgs,
1462 struct mgs_target_info *mti,
1463 struct llog_cfg_rec *lcr, char *devname,
1464 char *comment, int server_only)
1466 struct list_head log_list;
1467 struct mgs_direntry *dirent, *n;
1468 char *fsname = mti->mti_fsname;
1469 int rc = 0, len = strlen(fsname);
1472 /* Find all the logs in the CONFIGS directory */
1473 rc = class_dentry_readdir(env, mgs, &log_list);
1477 /* Could use fsdb index maps instead of directory listing */
1478 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
1479 list_del_init(&dirent->mde_list);
1480 /* don't write to sptlrpc rule log */
1481 if (strstr(dirent->mde_name, "-sptlrpc") != NULL)
1484 /* caller wants write server logs only */
1485 if (server_only && strstr(dirent->mde_name, "-client") != NULL)
1488 if (strlen(dirent->mde_name) <= len ||
1489 strncmp(fsname, dirent->mde_name, len) != 0 ||
1490 dirent->mde_name[len] != '-')
1493 CDEBUG(D_MGS, "Changing log %s\n", dirent->mde_name);
1494 /* Erase any old settings of this same parameter */
1495 rc = mgs_modify(env, mgs, fsdb, mti, dirent->mde_name,
1496 devname, comment, CM_SKIP);
1498 CERROR("%s: Can't modify llog %s: rc = %d\n",
1499 mgs->mgs_obd->obd_name, dirent->mde_name, rc);
1502 /* Write the new one */
1503 rc = mgs_write_log_direct(env, mgs, fsdb, dirent->mde_name,
1504 lcr, devname, comment);
1506 CERROR("%s: writing log %s: rc = %d\n",
1507 mgs->mgs_obd->obd_name, dirent->mde_name, rc);
1509 mgs_direntry_free(dirent);
1515 static int mgs_write_log_osp_to_mdt(const struct lu_env *env,
1516 struct mgs_device *mgs,
1518 struct mgs_target_info *mti,
1519 int index, char *logname);
1520 static int mgs_write_log_osc_to_lov(const struct lu_env *env,
1521 struct mgs_device *mgs,
1523 struct mgs_target_info *mti,
1524 char *logname, char *suffix, char *lovname,
1525 enum lustre_sec_part sec_part, int flags);
1526 static int name_create_mdt_and_lov(char **logname, char **lovname,
1527 struct fs_db *fsdb, int i);
1529 static int add_param(char *params, char *key, char *val)
1531 char *start = params + strlen(params);
1532 char *end = params + sizeof(((struct mgs_target_info *)0)->mti_params);
1536 keylen = strlen(key);
1537 if (start + 1 + keylen + strlen(val) >= end) {
1538 CERROR("params are too long: %s %s%s\n",
1539 params, key != NULL ? key : "", val);
1543 sprintf(start, " %s%s", key != NULL ? key : "", val);
1548 * Walk through client config log record and convert the related records
1551 static int mgs_steal_client_llog_handler(const struct lu_env *env,
1552 struct llog_handle *llh,
1553 struct llog_rec_hdr *rec, void *data)
1555 struct mgs_device *mgs;
1556 struct obd_device *obd;
1557 struct mgs_target_info *mti, *tmti;
1559 int cfg_len = rec->lrh_len;
1560 char *cfg_buf = (char*) (rec + 1);
1561 struct lustre_cfg *lcfg;
1563 struct llog_handle *mdt_llh = NULL;
1564 static int got_an_osc_or_mdc = 0;
1565 /* 0: not found any osc/mdc;
1569 static int last_step = -1;
1574 mti = ((struct temp_comp*)data)->comp_mti;
1575 tmti = ((struct temp_comp*)data)->comp_tmti;
1576 fsdb = ((struct temp_comp*)data)->comp_fsdb;
1577 obd = ((struct temp_comp *)data)->comp_obd;
1578 mgs = lu2mgs_dev(obd->obd_lu_dev);
1581 if (rec->lrh_type != OBD_CFG_REC) {
1582 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
1586 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
1588 CERROR("Insane cfg\n");
1592 lcfg = (struct lustre_cfg *)cfg_buf;
1594 if (lcfg->lcfg_command == LCFG_MARKER) {
1595 struct cfg_marker *marker;
1596 marker = lustre_cfg_buf(lcfg, 1);
1597 if (!strncmp(marker->cm_comment, "add osc", 7) &&
1598 (marker->cm_flags & CM_START) &&
1599 !(marker->cm_flags & CM_SKIP)) {
1600 got_an_osc_or_mdc = 1;
1601 cplen = strlcpy(tmti->mti_svname, marker->cm_tgtname,
1602 sizeof(tmti->mti_svname));
1603 if (cplen >= sizeof(tmti->mti_svname))
1605 rc = record_start_log(env, mgs, &mdt_llh,
1609 rc = record_marker(env, mdt_llh, fsdb, CM_START,
1610 mti->mti_svname, "add osc(copied)");
1611 record_end_log(env, &mdt_llh);
1612 last_step = marker->cm_step;
1615 if (!strncmp(marker->cm_comment, "add osc", 7) &&
1616 (marker->cm_flags & CM_END) &&
1617 !(marker->cm_flags & CM_SKIP)) {
1618 LASSERT(last_step == marker->cm_step);
1620 got_an_osc_or_mdc = 0;
1621 memset(tmti, 0, sizeof(*tmti));
1622 rc = record_start_log(env, mgs, &mdt_llh,
1626 rc = record_marker(env, mdt_llh, fsdb, CM_END,
1627 mti->mti_svname, "add osc(copied)");
1628 record_end_log(env, &mdt_llh);
1631 if (!strncmp(marker->cm_comment, "add mdc", 7) &&
1632 (marker->cm_flags & CM_START) &&
1633 !(marker->cm_flags & CM_SKIP)) {
1634 got_an_osc_or_mdc = 2;
1635 last_step = marker->cm_step;
1636 memcpy(tmti->mti_svname, marker->cm_tgtname,
1637 strlen(marker->cm_tgtname));
1641 if (!strncmp(marker->cm_comment, "add mdc", 7) &&
1642 (marker->cm_flags & CM_END) &&
1643 !(marker->cm_flags & CM_SKIP)) {
1644 LASSERT(last_step == marker->cm_step);
1646 got_an_osc_or_mdc = 0;
1647 memset(tmti, 0, sizeof(*tmti));
1652 if (got_an_osc_or_mdc == 0 || last_step < 0)
1655 if (lcfg->lcfg_command == LCFG_ADD_UUID) {
1656 __u64 nodenid = lcfg->lcfg_nid;
1658 if (strlen(tmti->mti_uuid) == 0) {
1659 /* target uuid not set, this config record is before
1660 * LCFG_SETUP, this nid is one of target node nid.
1662 tmti->mti_nids[tmti->mti_nid_count] = nodenid;
1663 tmti->mti_nid_count++;
1665 char nidstr[LNET_NIDSTR_SIZE];
1667 /* failover node nid */
1668 libcfs_nid2str_r(nodenid, nidstr, sizeof(nidstr));
1669 rc = add_param(tmti->mti_params, PARAM_FAILNODE,
1676 if (lcfg->lcfg_command == LCFG_SETUP) {
1679 target = lustre_cfg_string(lcfg, 1);
1680 memcpy(tmti->mti_uuid, target, strlen(target));
1684 /* ignore client side sptlrpc_conf_log */
1685 if (lcfg->lcfg_command == LCFG_SPTLRPC_CONF)
1688 if (lcfg->lcfg_command == LCFG_ADD_MDC) {
1691 if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1)
1694 memcpy(tmti->mti_fsname, mti->mti_fsname,
1695 strlen(mti->mti_fsname));
1696 tmti->mti_stripe_index = index;
1698 rc = mgs_write_log_osp_to_mdt(env, mgs, fsdb, tmti,
1699 mti->mti_stripe_index,
1701 memset(tmti, 0, sizeof(*tmti));
1705 if (lcfg->lcfg_command == LCFG_LOV_ADD_OBD) {
1708 char *logname, *lovname;
1710 rc = name_create_mdt_and_lov(&logname, &lovname, fsdb,
1711 mti->mti_stripe_index);
1714 sprintf(mdt_index, "-MDT%04x", mti->mti_stripe_index);
1716 if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1) {
1717 name_destroy(&logname);
1718 name_destroy(&lovname);
1722 tmti->mti_stripe_index = index;
1723 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, tmti, logname,
1726 name_destroy(&logname);
1727 name_destroy(&lovname);
1733 /* fsdb->fsdb_mutex is already held in mgs_write_log_target*/
1734 /* stealed from mgs_get_fsdb_from_llog*/
1735 static int mgs_steal_llog_for_mdt_from_client(const struct lu_env *env,
1736 struct mgs_device *mgs,
1738 struct temp_comp* comp)
1740 struct llog_handle *loghandle;
1741 struct mgs_target_info *tmti;
1742 struct llog_ctxt *ctxt;
1747 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
1748 LASSERT(ctxt != NULL);
1750 OBD_ALLOC_PTR(tmti);
1752 GOTO(out_ctxt, rc = -ENOMEM);
1754 comp->comp_tmti = tmti;
1755 comp->comp_obd = mgs->mgs_obd;
1757 rc = llog_open(env, ctxt, &loghandle, NULL, client_name,
1765 rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL);
1767 GOTO(out_close, rc);
1769 rc = llog_process_or_fork(env, loghandle, mgs_steal_client_llog_handler,
1770 (void *)comp, NULL, false);
1771 CDEBUG(D_MGS, "steal llog re = %d\n", rc);
1773 llog_close(env, loghandle);
1777 llog_ctxt_put(ctxt);
1781 /* lmv is the second thing for client logs */
1782 /* copied from mgs_write_log_lov. Please refer to that. */
1783 static int mgs_write_log_lmv(const struct lu_env *env,
1784 struct mgs_device *mgs,
1786 struct mgs_target_info *mti,
1787 char *logname, char *lmvname)
1789 struct llog_handle *llh = NULL;
1790 struct lmv_desc *lmvdesc;
1795 CDEBUG(D_MGS, "Writing lmv(%s) log for %s\n", lmvname,logname);
1797 OBD_ALLOC_PTR(lmvdesc);
1798 if (lmvdesc == NULL)
1800 lmvdesc->ld_active_tgt_count = 0;
1801 lmvdesc->ld_tgt_count = 0;
1802 sprintf((char*)lmvdesc->ld_uuid.uuid, "%s_UUID", lmvname);
1803 uuid = (char *)lmvdesc->ld_uuid.uuid;
1805 rc = record_start_log(env, mgs, &llh, logname);
1808 rc = record_marker(env, llh, fsdb, CM_START, lmvname, "lmv setup");
1811 rc = record_attach(env, llh, lmvname, "lmv", uuid);
1814 rc = record_lmv_setup(env, llh, lmvname, lmvdesc);
1817 rc = record_marker(env, llh, fsdb, CM_END, lmvname, "lmv setup");
1821 record_end_log(env, &llh);
1823 OBD_FREE_PTR(lmvdesc);
1827 /* lov is the first thing in the mdt and client logs */
1828 static int mgs_write_log_lov(const struct lu_env *env, struct mgs_device *mgs,
1829 struct fs_db *fsdb, struct mgs_target_info *mti,
1830 char *logname, char *lovname)
1832 struct llog_handle *llh = NULL;
1833 struct lov_desc *lovdesc;
1838 CDEBUG(D_MGS, "Writing lov(%s) log for %s\n", lovname, logname);
1841 #01 L attach 0:lov_mdsA 1:lov 2:71ccb_lov_mdsA_19f961a9e1
1842 #02 L lov_setup 0:lov_mdsA 1:(struct lov_desc)
1843 uuid=lov1_UUID, stripe count=1, size=1048576, offset=0, pattern=0
1846 /* FIXME just make lov_setup accept empty desc (put uuid in buf 2) */
1847 OBD_ALLOC_PTR(lovdesc);
1848 if (lovdesc == NULL)
1850 lovdesc->ld_magic = LOV_DESC_MAGIC;
1851 lovdesc->ld_tgt_count = 0;
1852 /* Defaults. Can be changed later by lcfg config_param */
1853 lovdesc->ld_default_stripe_count = 1;
1854 lovdesc->ld_pattern = LOV_PATTERN_RAID0;
1855 lovdesc->ld_default_stripe_size = LOV_DESC_STRIPE_SIZE_DEFAULT;
1856 lovdesc->ld_default_stripe_offset = -1;
1857 lovdesc->ld_qos_maxage = LOV_DESC_QOS_MAXAGE_DEFAULT;
1858 sprintf((char*)lovdesc->ld_uuid.uuid, "%s_UUID", lovname);
1859 /* can these be the same? */
1860 uuid = (char *)lovdesc->ld_uuid.uuid;
1862 /* This should always be the first entry in a log.
1863 rc = mgs_clear_log(obd, logname); */
1864 rc = record_start_log(env, mgs, &llh, logname);
1867 /* FIXME these should be a single journal transaction */
1868 rc = record_marker(env, llh, fsdb, CM_START, lovname, "lov setup");
1871 rc = record_attach(env, llh, lovname, "lov", uuid);
1874 rc = record_lov_setup(env, llh, lovname, lovdesc);
1877 rc = record_marker(env, llh, fsdb, CM_END, lovname, "lov setup");
1882 record_end_log(env, &llh);
1884 OBD_FREE_PTR(lovdesc);
1888 /* add failnids to open log */
1889 static int mgs_write_log_failnids(const struct lu_env *env,
1890 struct mgs_target_info *mti,
1891 struct llog_handle *llh,
1894 char *failnodeuuid = NULL;
1895 char *ptr = mti->mti_params;
1900 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) nal=90 0: 1:uml1_UUID
1901 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
1902 #05 L setup 0:OSC_uml1_ost1_mdsA 1:ost1_UUID 2:uml1_UUID
1903 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) nal=90 0: 1:uml2_UUID
1904 #0x L add_uuid nid=2@elan(0x1000000000002) nal=90 0: 1:uml2_UUID
1905 #07 L add_conn 0:OSC_uml1_ost1_mdsA 1:uml2_UUID
1909 * Pull failnid info out of params string, which may contain something
1910 * like "<nid1>,<nid2>:<nid3>,<nid4>". class_parse_nid() does not
1911 * complain about abnormal inputs like ",:<nid1>", "<nid1>:,<nid2>",
1912 * etc. However, convert_hostnames() should have caught those.
1914 while (class_find_param(ptr, PARAM_FAILNODE, &ptr) == 0) {
1915 while (class_parse_nid(ptr, &nid, &ptr) == 0) {
1916 char nidstr[LNET_NIDSTR_SIZE];
1918 if (failnodeuuid == NULL) {
1919 /* We don't know the failover node name,
1920 * so just use the first nid as the uuid */
1921 libcfs_nid2str_r(nid, nidstr, sizeof(nidstr));
1922 rc = name_create(&failnodeuuid, nidstr, "");
1926 CDEBUG(D_MGS, "add nid %s for failover uuid %s, "
1928 libcfs_nid2str_r(nid, nidstr, sizeof(nidstr)),
1929 failnodeuuid, cliname);
1930 rc = record_add_uuid(env, llh, nid, failnodeuuid);
1932 * If *ptr is ':', we have added all NIDs for
1936 rc = record_add_conn(env, llh, cliname,
1938 name_destroy(&failnodeuuid);
1939 failnodeuuid = NULL;
1943 rc = record_add_conn(env, llh, cliname, failnodeuuid);
1944 name_destroy(&failnodeuuid);
1945 failnodeuuid = NULL;
1952 static int mgs_write_log_mdc_to_lmv(const struct lu_env *env,
1953 struct mgs_device *mgs,
1955 struct mgs_target_info *mti,
1956 char *logname, char *lmvname)
1958 struct llog_handle *llh = NULL;
1959 char *mdcname = NULL;
1960 char *nodeuuid = NULL;
1961 char *mdcuuid = NULL;
1962 char *lmvuuid = NULL;
1964 char nidstr[LNET_NIDSTR_SIZE];
1968 if (mgs_log_is_empty(env, mgs, logname)) {
1969 CERROR("log is empty! Logical error\n");
1973 CDEBUG(D_MGS, "adding mdc for %s to log %s:lmv(%s)\n",
1974 mti->mti_svname, logname, lmvname);
1976 libcfs_nid2str_r(mti->mti_nids[0], nidstr, sizeof(nidstr));
1977 rc = name_create(&nodeuuid, nidstr, "");
1980 rc = name_create(&mdcname, mti->mti_svname, "-mdc");
1983 rc = name_create(&mdcuuid, mdcname, "_UUID");
1986 rc = name_create(&lmvuuid, lmvname, "_UUID");
1990 rc = record_start_log(env, mgs, &llh, logname);
1993 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
1997 for (i = 0; i < mti->mti_nid_count; i++) {
1998 CDEBUG(D_MGS, "add nid %s for mdt\n",
1999 libcfs_nid2str_r(mti->mti_nids[i],
2000 nidstr, sizeof(nidstr)));
2002 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
2007 rc = record_attach(env, llh, mdcname, LUSTRE_MDC_NAME, lmvuuid);
2010 rc = record_setup(env, llh, mdcname, mti->mti_uuid, nodeuuid,
2014 rc = mgs_write_log_failnids(env, mti, llh, mdcname);
2017 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
2018 rc = record_mdc_add(env, llh, lmvname, mdcuuid, mti->mti_uuid,
2022 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname,
2027 record_end_log(env, &llh);
2029 name_destroy(&lmvuuid);
2030 name_destroy(&mdcuuid);
2031 name_destroy(&mdcname);
2032 name_destroy(&nodeuuid);
2036 static inline int name_create_lov(char **lovname, char *mdtname,
2037 struct fs_db *fsdb, int index)
2040 if (index == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2041 return name_create(lovname, fsdb->fsdb_name, "-mdtlov");
2043 return name_create(lovname, mdtname, "-mdtlov");
2046 static int name_create_mdt_and_lov(char **logname, char **lovname,
2047 struct fs_db *fsdb, int i)
2051 rc = name_create_mdt(logname, fsdb->fsdb_name, i);
2055 if (i == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2056 rc = name_create(lovname, fsdb->fsdb_name, "-mdtlov");
2058 rc = name_create(lovname, *logname, "-mdtlov");
2060 name_destroy(logname);
2066 static inline int name_create_mdt_osc(char **oscname, char *ostname,
2067 struct fs_db *fsdb, int i)
2071 if (i == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2072 sprintf(suffix, "-osc");
2074 sprintf(suffix, "-osc-MDT%04x", i);
2075 return name_create(oscname, ostname, suffix);
2078 /* add new mdc to already existent MDS */
2079 static int mgs_write_log_osp_to_mdt(const struct lu_env *env,
2080 struct mgs_device *mgs,
2082 struct mgs_target_info *mti,
2083 int mdt_index, char *logname)
2085 struct llog_handle *llh = NULL;
2086 char *nodeuuid = NULL;
2087 char *ospname = NULL;
2088 char *lovuuid = NULL;
2089 char *mdtuuid = NULL;
2090 char *svname = NULL;
2091 char *mdtname = NULL;
2092 char *lovname = NULL;
2094 char nidstr[LNET_NIDSTR_SIZE];
2098 if (mgs_log_is_empty(env, mgs, mti->mti_svname)) {
2099 CERROR("log is empty! Logical error\n");
2103 CDEBUG(D_MGS, "adding osp index %d to %s\n", mti->mti_stripe_index,
2106 rc = name_create_mdt(&mdtname, fsdb->fsdb_name, mti->mti_stripe_index);
2110 libcfs_nid2str_r(mti->mti_nids[0], nidstr, sizeof(nidstr));
2111 rc = name_create(&nodeuuid, nidstr, "");
2113 GOTO(out_destory, rc);
2115 rc = name_create(&svname, mdtname, "-osp");
2117 GOTO(out_destory, rc);
2119 sprintf(index_str, "-MDT%04x", mdt_index);
2120 rc = name_create(&ospname, svname, index_str);
2122 GOTO(out_destory, rc);
2124 rc = name_create_lov(&lovname, logname, fsdb, mdt_index);
2126 GOTO(out_destory, rc);
2128 rc = name_create(&lovuuid, lovname, "_UUID");
2130 GOTO(out_destory, rc);
2132 rc = name_create(&mdtuuid, mdtname, "_UUID");
2134 GOTO(out_destory, rc);
2136 rc = record_start_log(env, mgs, &llh, logname);
2138 GOTO(out_destory, rc);
2140 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
2143 GOTO(out_destory, rc);
2145 for (i = 0; i < mti->mti_nid_count; i++) {
2146 CDEBUG(D_MGS, "add nid %s for mdt\n",
2147 libcfs_nid2str_r(mti->mti_nids[i],
2148 nidstr, sizeof(nidstr)));
2149 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
2154 rc = record_attach(env, llh, ospname, LUSTRE_OSP_NAME, lovuuid);
2158 rc = record_setup(env, llh, ospname, mti->mti_uuid, nodeuuid,
2163 rc = mgs_write_log_failnids(env, mti, llh, ospname);
2167 /* Add mdc(osp) to lod */
2168 snprintf(index_str, sizeof(index_str), "%d", mti->mti_stripe_index);
2169 rc = record_base(env, llh, lovname, 0, LCFG_ADD_MDC, mti->mti_uuid,
2170 index_str, "1", NULL);
2174 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname, "add osp");
2179 record_end_log(env, &llh);
2182 name_destroy(&mdtuuid);
2183 name_destroy(&lovuuid);
2184 name_destroy(&lovname);
2185 name_destroy(&ospname);
2186 name_destroy(&svname);
2187 name_destroy(&nodeuuid);
2188 name_destroy(&mdtname);
2192 static int mgs_write_log_mdt0(const struct lu_env *env,
2193 struct mgs_device *mgs,
2195 struct mgs_target_info *mti)
2197 char *log = mti->mti_svname;
2198 struct llog_handle *llh = NULL;
2199 char *uuid, *lovname;
2201 char *ptr = mti->mti_params;
2202 int rc = 0, failout = 0;
2205 OBD_ALLOC(uuid, sizeof(struct obd_uuid));
2209 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
2210 failout = (strncmp(ptr, "failout", 7) == 0);
2212 rc = name_create(&lovname, log, "-mdtlov");
2215 if (mgs_log_is_empty(env, mgs, log)) {
2216 rc = mgs_write_log_lov(env, mgs, fsdb, mti, log, lovname);
2221 sprintf(mdt_index, "%d", mti->mti_stripe_index);
2223 rc = record_start_log(env, mgs, &llh, log);
2227 /* add MDT itself */
2229 /* FIXME this whole fn should be a single journal transaction */
2230 sprintf(uuid, "%s_UUID", log);
2231 rc = record_marker(env, llh, fsdb, CM_START, log, "add mdt");
2234 rc = record_attach(env, llh, log, LUSTRE_MDT_NAME, uuid);
2237 rc = record_mount_opt(env, llh, log, lovname, NULL);
2240 rc = record_setup(env, llh, log, uuid, mdt_index, lovname,
2241 failout ? "n" : "f");
2244 rc = record_marker(env, llh, fsdb, CM_END, log, "add mdt");
2248 record_end_log(env, &llh);
2250 name_destroy(&lovname);
2252 OBD_FREE(uuid, sizeof(struct obd_uuid));
2256 /* envelope method for all layers log */
2257 static int mgs_write_log_mdt(const struct lu_env *env,
2258 struct mgs_device *mgs,
2260 struct mgs_target_info *mti)
2262 struct mgs_thread_info *mgi = mgs_env_info(env);
2263 struct llog_handle *llh = NULL;
2268 CDEBUG(D_MGS, "writing new mdt %s\n", mti->mti_svname);
2270 if (mti->mti_uuid[0] == '\0') {
2271 /* Make up our own uuid */
2272 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
2273 "%s_UUID", mti->mti_svname);
2277 rc = mgs_write_log_mdt0(env, mgs, fsdb, mti);
2280 /* Append the mdt info to the client log */
2281 rc = name_create(&cliname, mti->mti_fsname, "-client");
2285 if (mgs_log_is_empty(env, mgs, cliname)) {
2286 /* Start client log */
2287 rc = mgs_write_log_lov(env, mgs, fsdb, mti, cliname,
2291 rc = mgs_write_log_lmv(env, mgs, fsdb, mti, cliname,
2298 #09 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
2299 #10 L attach 0:MDC_uml1_mdsA_MNT_client 1:mdc 2:1d834_MNT_client_03f
2300 #11 L setup 0:MDC_uml1_mdsA_MNT_client 1:mdsA_UUID 2:uml1_UUID
2301 #12 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
2302 #13 L add_conn 0:MDC_uml1_mdsA_MNT_client 1:uml2_UUID
2303 #14 L mount_option 0: 1:client 2:lov1 3:MDC_uml1_mdsA_MNT_client
2306 /* copy client info about lov/lmv */
2307 mgi->mgi_comp.comp_mti = mti;
2308 mgi->mgi_comp.comp_fsdb = fsdb;
2310 rc = mgs_steal_llog_for_mdt_from_client(env, mgs, cliname,
2314 rc = mgs_write_log_mdc_to_lmv(env, mgs, fsdb, mti, cliname,
2320 rc = record_start_log(env, mgs, &llh, cliname);
2324 rc = record_marker(env, llh, fsdb, CM_START, cliname,
2328 rc = record_mount_opt(env, llh, cliname, fsdb->fsdb_clilov,
2332 rc = record_marker(env, llh, fsdb, CM_END, cliname,
2338 /* for_all_existing_mdt except current one */
2339 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2340 if (i != mti->mti_stripe_index &&
2341 test_bit(i, fsdb->fsdb_mdt_index_map)) {
2344 rc = name_create_mdt(&logname, fsdb->fsdb_name, i);
2348 /* NB: If the log for the MDT is empty, it means
2349 * the MDT is only added to the index
2350 * map, and not being process yet, i.e. this
2351 * is an unregistered MDT, see mgs_write_log_target().
2352 * so we should skip it. Otherwise
2354 * 1. MGS get register request for MDT1 and MDT2.
2356 * 2. Then both MDT1 and MDT2 are added into
2357 * fsdb_mdt_index_map. (see mgs_set_index()).
2359 * 3. Then MDT1 get the lock of fsdb_mutex, then
2360 * generate the config log, here, it will regard MDT2
2361 * as an existent MDT, and generate "add osp" for
2362 * lustre-MDT0001-osp-MDT0002. Note: at the moment
2363 * MDT0002 config log is still empty, so it will
2364 * add "add osp" even before "lov setup", which
2365 * will definitly cause trouble.
2367 * 4. MDT1 registeration finished, fsdb_mutex is
2368 * released, then MDT2 get in, then in above
2369 * mgs_steal_llog_for_mdt_from_client(), it will
2370 * add another osp log for lustre-MDT0001-osp-MDT0002,
2371 * which will cause another trouble.*/
2372 if (!mgs_log_is_empty(env, mgs, logname))
2373 rc = mgs_write_log_osp_to_mdt(env, mgs, fsdb,
2376 name_destroy(&logname);
2382 record_end_log(env, &llh);
2384 name_destroy(&cliname);
2388 /* Add the ost info to the client/mdt lov */
2389 static int mgs_write_log_osc_to_lov(const struct lu_env *env,
2390 struct mgs_device *mgs, struct fs_db *fsdb,
2391 struct mgs_target_info *mti,
2392 char *logname, char *suffix, char *lovname,
2393 enum lustre_sec_part sec_part, int flags)
2395 struct llog_handle *llh = NULL;
2396 char *nodeuuid = NULL;
2397 char *oscname = NULL;
2398 char *oscuuid = NULL;
2399 char *lovuuid = NULL;
2400 char *svname = NULL;
2402 char nidstr[LNET_NIDSTR_SIZE];
2406 CDEBUG(D_INFO, "adding osc for %s to log %s\n",
2407 mti->mti_svname, logname);
2409 if (mgs_log_is_empty(env, mgs, logname)) {
2410 CERROR("log is empty! Logical error\n");
2414 libcfs_nid2str_r(mti->mti_nids[0], nidstr, sizeof(nidstr));
2415 rc = name_create(&nodeuuid, nidstr, "");
2418 rc = name_create(&svname, mti->mti_svname, "-osc");
2422 /* for the system upgraded from old 1.8, keep using the old osc naming
2423 * style for mdt, see name_create_mdt_osc(). LU-1257 */
2424 if (test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2425 rc = name_create(&oscname, svname, "");
2427 rc = name_create(&oscname, svname, suffix);
2431 rc = name_create(&oscuuid, oscname, "_UUID");
2434 rc = name_create(&lovuuid, lovname, "_UUID");
2440 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
2442 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
2443 #04 L attach 0:OSC_uml1_ost1_MNT_client 1:osc 2:89070_lov1_a41dff51a
2444 #05 L setup 0:OSC_uml1_ost1_MNT_client 1:ost1_UUID 2:uml1_UUID
2446 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
2447 #07 L add_conn 0:OSC_uml1_ost1_MNT_client 1:uml2_UUID
2448 #08 L lov_modify_tgts add 0:lov1 1:ost1_UUID 2(index):0 3(gen):1
2451 rc = record_start_log(env, mgs, &llh, logname);
2455 /* FIXME these should be a single journal transaction */
2456 rc = record_marker(env, llh, fsdb, CM_START | flags, mti->mti_svname,
2461 /* NB: don't change record order, because upon MDT steal OSC config
2462 * from client, it treats all nids before LCFG_SETUP as target nids
2463 * (multiple interfaces), while nids after as failover node nids.
2464 * See mgs_steal_client_llog_handler() LCFG_ADD_UUID.
2466 for (i = 0; i < mti->mti_nid_count; i++) {
2467 CDEBUG(D_MGS, "add nid %s\n",
2468 libcfs_nid2str_r(mti->mti_nids[i],
2469 nidstr, sizeof(nidstr)));
2470 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
2474 rc = record_attach(env, llh, oscname, LUSTRE_OSC_NAME, lovuuid);
2477 rc = record_setup(env, llh, oscname, mti->mti_uuid, nodeuuid,
2481 rc = mgs_write_log_failnids(env, mti, llh, oscname);
2485 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
2487 rc = record_lov_add(env, llh, lovname, mti->mti_uuid, index, "1");
2490 rc = record_marker(env, llh, fsdb, CM_END | flags, mti->mti_svname,
2495 record_end_log(env, &llh);
2497 name_destroy(&lovuuid);
2498 name_destroy(&oscuuid);
2499 name_destroy(&oscname);
2500 name_destroy(&svname);
2501 name_destroy(&nodeuuid);
2505 static int mgs_write_log_ost(const struct lu_env *env,
2506 struct mgs_device *mgs, struct fs_db *fsdb,
2507 struct mgs_target_info *mti)
2509 struct llog_handle *llh = NULL;
2510 char *logname, *lovname;
2511 char *ptr = mti->mti_params;
2512 int rc, flags = 0, failout = 0, i;
2515 CDEBUG(D_MGS, "writing new ost %s\n", mti->mti_svname);
2517 /* The ost startup log */
2519 /* If the ost log already exists, that means that someone reformatted
2520 the ost and it called target_add again. */
2521 if (!mgs_log_is_empty(env, mgs, mti->mti_svname)) {
2522 LCONSOLE_ERROR_MSG(0x141, "The config log for %s already "
2523 "exists, yet the server claims it never "
2524 "registered. It may have been reformatted, "
2525 "or the index changed. writeconf the MDT to "
2526 "regenerate all logs.\n", mti->mti_svname);
2531 attach obdfilter ost1 ost1_UUID
2532 setup /dev/loop2 ldiskfs f|n errors=remount-ro,user_xattr
2534 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
2535 failout = (strncmp(ptr, "failout", 7) == 0);
2536 rc = record_start_log(env, mgs, &llh, mti->mti_svname);
2539 /* FIXME these should be a single journal transaction */
2540 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,"add ost");
2543 if (*mti->mti_uuid == '\0')
2544 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
2545 "%s_UUID", mti->mti_svname);
2546 rc = record_attach(env, llh, mti->mti_svname,
2547 "obdfilter"/*LUSTRE_OST_NAME*/, mti->mti_uuid);
2550 rc = record_setup(env, llh, mti->mti_svname,
2551 "dev"/*ignored*/, "type"/*ignored*/,
2552 failout ? "n" : "f", NULL/*options*/);
2555 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname, "add ost");
2559 record_end_log(env, &llh);
2562 /* We also have to update the other logs where this osc is part of
2565 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
2566 /* If we're upgrading, the old mdt log already has our
2567 entry. Let's do a fake one for fun. */
2568 /* Note that we can't add any new failnids, since we don't
2569 know the old osc names. */
2570 flags = CM_SKIP | CM_UPGRADE146;
2572 } else if ((mti->mti_flags & LDD_F_UPDATE) != LDD_F_UPDATE) {
2573 /* If the update flag isn't set, don't update client/mdt
2576 LCONSOLE_WARN("Client log for %s was not updated; writeconf "
2577 "the MDT first to regenerate it.\n",
2581 /* Add ost to all MDT lov defs */
2582 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
2583 if (test_bit(i, fsdb->fsdb_mdt_index_map)) {
2586 rc = name_create_mdt_and_lov(&logname, &lovname, fsdb,
2590 sprintf(mdt_index, "-MDT%04x", i);
2591 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, mti,
2593 lovname, LUSTRE_SP_MDT,
2595 name_destroy(&logname);
2596 name_destroy(&lovname);
2602 /* Append ost info to the client log */
2603 rc = name_create(&logname, mti->mti_fsname, "-client");
2606 if (mgs_log_is_empty(env, mgs, logname)) {
2607 /* Start client log */
2608 rc = mgs_write_log_lov(env, mgs, fsdb, mti, logname,
2612 rc = mgs_write_log_lmv(env, mgs, fsdb, mti, logname,
2617 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, mti, logname, "",
2618 fsdb->fsdb_clilov, LUSTRE_SP_CLI, flags);
2620 name_destroy(&logname);
2624 static __inline__ int mgs_param_empty(char *ptr)
2628 if ((tmp = strchr(ptr, '=')) && (*(++tmp) == '\0'))
2633 static int mgs_write_log_failnid_internal(const struct lu_env *env,
2634 struct mgs_device *mgs,
2636 struct mgs_target_info *mti,
2637 char *logname, char *cliname)
2640 struct llog_handle *llh = NULL;
2642 if (mgs_param_empty(mti->mti_params)) {
2643 /* Remove _all_ failnids */
2644 rc = mgs_modify(env, mgs, fsdb, mti, logname,
2645 mti->mti_svname, "add failnid", CM_SKIP);
2646 return rc < 0 ? rc : 0;
2649 /* Otherwise failover nids are additive */
2650 rc = record_start_log(env, mgs, &llh, logname);
2653 /* FIXME this should be a single journal transaction */
2654 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
2658 rc = mgs_write_log_failnids(env, mti, llh, cliname);
2661 rc = record_marker(env, llh, fsdb, CM_END,
2662 mti->mti_svname, "add failnid");
2664 record_end_log(env, &llh);
2669 /* Add additional failnids to an existing log.
2670 The mdc/osc must have been added to logs first */
2671 /* tcp nids must be in dotted-quad ascii -
2672 we can't resolve hostnames from the kernel. */
2673 static int mgs_write_log_add_failnid(const struct lu_env *env,
2674 struct mgs_device *mgs,
2676 struct mgs_target_info *mti)
2678 char *logname, *cliname;
2682 /* FIXME we currently can't erase the failnids
2683 * given when a target first registers, since they aren't part of
2684 * an "add uuid" stanza */
2686 /* Verify that we know about this target */
2687 if (mgs_log_is_empty(env, mgs, mti->mti_svname)) {
2688 LCONSOLE_ERROR_MSG(0x142, "The target %s has not registered "
2689 "yet. It must be started before failnids "
2690 "can be added.\n", mti->mti_svname);
2694 /* Create mdc/osc client name (e.g. lustre-OST0001-osc) */
2695 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
2696 rc = name_create(&cliname, mti->mti_svname, "-mdc");
2697 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2698 rc = name_create(&cliname, mti->mti_svname, "-osc");
2704 /* Add failover nids to the client log */
2705 rc = name_create(&logname, mti->mti_fsname, "-client");
2707 name_destroy(&cliname);
2710 rc = mgs_write_log_failnid_internal(env, mgs, fsdb,mti,logname,cliname);
2711 name_destroy(&logname);
2712 name_destroy(&cliname);
2716 if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2717 /* Add OST failover nids to the MDT logs as well */
2720 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2721 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
2723 rc = name_create_mdt(&logname, mti->mti_fsname, i);
2726 rc = name_create_mdt_osc(&cliname, mti->mti_svname,
2729 name_destroy(&logname);
2732 rc = mgs_write_log_failnid_internal(env, mgs, fsdb,
2735 name_destroy(&cliname);
2736 name_destroy(&logname);
2745 static int mgs_wlp_lcfg(const struct lu_env *env,
2746 struct mgs_device *mgs, struct fs_db *fsdb,
2747 struct mgs_target_info *mti,
2748 char *logname, struct lustre_cfg_bufs *bufs,
2749 char *tgtname, char *ptr)
2751 char comment[MTI_NAME_MAXLEN];
2753 struct llog_cfg_rec *lcr;
2756 /* Erase any old settings of this same parameter */
2757 memcpy(comment, ptr, MTI_NAME_MAXLEN);
2758 comment[MTI_NAME_MAXLEN - 1] = 0;
2759 /* But don't try to match the value. */
2760 tmp = strchr(comment, '=');
2763 /* FIXME we should skip settings that are the same as old values */
2764 rc = mgs_modify(env, mgs, fsdb, mti, logname, tgtname, comment,CM_SKIP);
2767 del = mgs_param_empty(ptr);
2769 LCONSOLE_INFO("%s parameter %s.%s in log %s\n", del ? "Disabling" : rc ?
2770 "Setting" : "Modifying", tgtname, comment, logname);
2772 /* mgs_modify() will return 1 if nothing had to be done */
2778 lustre_cfg_bufs_reset(bufs, tgtname);
2779 lustre_cfg_bufs_set_string(bufs, 1, ptr);
2780 if (mti->mti_flags & LDD_F_PARAM2)
2781 lustre_cfg_bufs_set_string(bufs, 2, LCTL_UPCALL);
2783 lcr = lustre_cfg_rec_new((mti->mti_flags & LDD_F_PARAM2) ?
2784 LCFG_SET_PARAM : LCFG_PARAM, bufs);
2788 rc = mgs_write_log_direct(env, mgs, fsdb, logname, lcr, tgtname,
2790 lustre_cfg_rec_free(lcr);
2794 static int mgs_write_log_param2(const struct lu_env *env,
2795 struct mgs_device *mgs,
2797 struct mgs_target_info *mti, char *ptr)
2799 struct lustre_cfg_bufs bufs;
2803 CDEBUG(D_MGS, "next param '%s'\n", ptr);
2804 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, PARAMS_FILENAME, &bufs,
2805 mti->mti_svname, ptr);
2810 /* write global variable settings into log */
2811 static int mgs_write_log_sys(const struct lu_env *env,
2812 struct mgs_device *mgs, struct fs_db *fsdb,
2813 struct mgs_target_info *mti, char *sys, char *ptr)
2815 struct mgs_thread_info *mgi = mgs_env_info(env);
2816 struct lustre_cfg *lcfg;
2817 struct llog_cfg_rec *lcr;
2819 int rc, cmd, convert = 1;
2821 if (class_match_param(ptr, PARAM_TIMEOUT, &tmp) == 0) {
2822 cmd = LCFG_SET_TIMEOUT;
2823 } else if (class_match_param(ptr, PARAM_LDLM_TIMEOUT, &tmp) == 0) {
2824 cmd = LCFG_SET_LDLM_TIMEOUT;
2825 /* Check for known params here so we can return error to lctl */
2826 } else if ((class_match_param(ptr, PARAM_AT_MIN, &tmp) == 0) ||
2827 (class_match_param(ptr, PARAM_AT_MAX, &tmp) == 0) ||
2828 (class_match_param(ptr, PARAM_AT_EXTRA, &tmp) == 0) ||
2829 (class_match_param(ptr, PARAM_AT_EARLY_MARGIN, &tmp) == 0) ||
2830 (class_match_param(ptr, PARAM_AT_HISTORY, &tmp) == 0)) {
2832 } else if (class_match_param(ptr, PARAM_JOBID_VAR, &tmp) == 0) {
2833 convert = 0; /* Don't convert string value to integer */
2839 if (mgs_param_empty(ptr))
2840 CDEBUG(D_MGS, "global '%s' removed\n", sys);
2842 CDEBUG(D_MGS, "global '%s' val=%s\n", sys, tmp);
2844 lustre_cfg_bufs_reset(&mgi->mgi_bufs, NULL);
2845 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, sys);
2846 if (!convert && *tmp != '\0')
2847 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 2, tmp);
2848 lcr = lustre_cfg_rec_new(cmd, &mgi->mgi_bufs);
2852 lcfg = &lcr->lcr_cfg;
2853 lcfg->lcfg_num = convert ? simple_strtoul(tmp, NULL, 0) : 0;
2854 /* truncate the comment to the parameter name */
2858 /* modify all servers and clients */
2859 rc = mgs_write_log_direct_all(env, mgs, fsdb, mti,
2860 *tmp == '\0' ? NULL : lcr,
2861 mti->mti_fsname, sys, 0);
2862 if (rc == 0 && *tmp != '\0') {
2864 case LCFG_SET_TIMEOUT:
2865 if (!obd_timeout_set || lcfg->lcfg_num > obd_timeout)
2866 class_process_config(lcfg);
2868 case LCFG_SET_LDLM_TIMEOUT:
2869 if (!ldlm_timeout_set || lcfg->lcfg_num > ldlm_timeout)
2870 class_process_config(lcfg);
2877 lustre_cfg_rec_free(lcr);
2881 /* write quota settings into log */
2882 static int mgs_write_log_quota(const struct lu_env *env, struct mgs_device *mgs,
2883 struct fs_db *fsdb, struct mgs_target_info *mti,
2884 char *quota, char *ptr)
2886 struct mgs_thread_info *mgi = mgs_env_info(env);
2887 struct llog_cfg_rec *lcr;
2890 int rc, cmd = LCFG_PARAM;
2892 /* support only 'meta' and 'data' pools so far */
2893 if (class_match_param(ptr, QUOTA_METAPOOL_NAME, &tmp) != 0 &&
2894 class_match_param(ptr, QUOTA_DATAPOOL_NAME, &tmp) != 0) {
2895 CERROR("parameter quota.%s isn't supported (only quota.mdt "
2896 "& quota.ost are)\n", ptr);
2901 CDEBUG(D_MGS, "global '%s' removed\n", quota);
2903 CDEBUG(D_MGS, "global '%s'\n", quota);
2905 if (strchr(tmp, 'u') == NULL && strchr(tmp, 'g') == NULL &&
2906 strcmp(tmp, "none") != 0) {
2907 CERROR("enable option(%s) isn't supported\n", tmp);
2912 lustre_cfg_bufs_reset(&mgi->mgi_bufs, mti->mti_fsname);
2913 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, quota);
2914 lcr = lustre_cfg_rec_new(cmd, &mgi->mgi_bufs);
2918 /* truncate the comment to the parameter name */
2923 /* XXX we duplicated quota enable information in all server
2924 * config logs, it should be moved to a separate config
2925 * log once we cleanup the config log for global param. */
2926 /* modify all servers */
2927 rc = mgs_write_log_direct_all(env, mgs, fsdb, mti,
2928 *tmp == '\0' ? NULL : lcr,
2929 mti->mti_fsname, quota, 1);
2931 lustre_cfg_rec_free(lcr);
2932 return rc < 0 ? rc : 0;
2935 static int mgs_srpc_set_param_disk(const struct lu_env *env,
2936 struct mgs_device *mgs,
2938 struct mgs_target_info *mti,
2941 struct mgs_thread_info *mgi = mgs_env_info(env);
2942 struct llog_cfg_rec *lcr;
2943 struct llog_handle *llh = NULL;
2945 char *comment, *ptr;
2951 ptr = strchr(param, '=');
2952 LASSERT(ptr != NULL);
2955 OBD_ALLOC(comment, len + 1);
2956 if (comment == NULL)
2958 strncpy(comment, param, len);
2959 comment[len] = '\0';
2962 lustre_cfg_bufs_reset(&mgi->mgi_bufs, mti->mti_svname);
2963 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, param);
2964 lcr = lustre_cfg_rec_new(LCFG_SPTLRPC_CONF, &mgi->mgi_bufs);
2966 GOTO(out_comment, rc = -ENOMEM);
2968 /* construct log name */
2969 rc = name_create(&logname, mti->mti_fsname, "-sptlrpc");
2973 if (mgs_log_is_empty(env, mgs, logname)) {
2974 rc = record_start_log(env, mgs, &llh, logname);
2977 record_end_log(env, &llh);
2980 /* obsolete old one */
2981 rc = mgs_modify(env, mgs, fsdb, mti, logname, mti->mti_svname,
2985 /* write the new one */
2986 rc = mgs_write_log_direct(env, mgs, fsdb, logname, lcr,
2987 mti->mti_svname, comment);
2989 CERROR("%s: error writing log %s: rc = %d\n",
2990 mgs->mgs_obd->obd_name, logname, rc);
2992 name_destroy(&logname);
2994 lustre_cfg_rec_free(lcr);
2996 OBD_FREE(comment, len + 1);
3000 static int mgs_srpc_set_param_udesc_mem(struct fs_db *fsdb,
3005 /* disable the adjustable udesc parameter for now, i.e. use default
3006 * setting that client always ship udesc to MDT if possible. to enable
3007 * it simply remove the following line */
3010 ptr = strchr(param, '=');
3015 if (strcmp(param, PARAM_SRPC_UDESC))
3018 if (strcmp(ptr, "yes") == 0) {
3019 set_bit(FSDB_UDESC, &fsdb->fsdb_flags);
3020 CWARN("Enable user descriptor shipping from client to MDT\n");
3021 } else if (strcmp(ptr, "no") == 0) {
3022 clear_bit(FSDB_UDESC, &fsdb->fsdb_flags);
3023 CWARN("Disable user descriptor shipping from client to MDT\n");
3031 CERROR("Invalid param: %s\n", param);
3035 static int mgs_srpc_set_param_mem(struct fs_db *fsdb,
3039 struct sptlrpc_rule rule;
3040 struct sptlrpc_rule_set *rset;
3044 if (strncmp(param, PARAM_SRPC, sizeof(PARAM_SRPC) - 1) != 0) {
3045 CERROR("Invalid sptlrpc parameter: %s\n", param);
3049 if (strncmp(param, PARAM_SRPC_UDESC,
3050 sizeof(PARAM_SRPC_UDESC) - 1) == 0) {
3051 RETURN(mgs_srpc_set_param_udesc_mem(fsdb, param));
3054 if (strncmp(param, PARAM_SRPC_FLVR, sizeof(PARAM_SRPC_FLVR) - 1) != 0) {
3055 CERROR("Invalid sptlrpc flavor parameter: %s\n", param);
3059 param += sizeof(PARAM_SRPC_FLVR) - 1;
3061 rc = sptlrpc_parse_rule(param, &rule);
3065 /* mgs rules implies must be mgc->mgs */
3066 if (test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
3067 if ((rule.sr_from != LUSTRE_SP_MGC &&
3068 rule.sr_from != LUSTRE_SP_ANY) ||
3069 (rule.sr_to != LUSTRE_SP_MGS &&
3070 rule.sr_to != LUSTRE_SP_ANY))
3074 /* preapre room for this coming rule. svcname format should be:
3075 * - fsname: general rule
3076 * - fsname-tgtname: target-specific rule
3078 if (strchr(svname, '-')) {
3079 struct mgs_tgt_srpc_conf *tgtconf;
3082 for (tgtconf = fsdb->fsdb_srpc_tgt; tgtconf != NULL;
3083 tgtconf = tgtconf->mtsc_next) {
3084 if (!strcmp(tgtconf->mtsc_tgt, svname)) {
3093 OBD_ALLOC_PTR(tgtconf);
3094 if (tgtconf == NULL)
3097 name_len = strlen(svname);
3099 OBD_ALLOC(tgtconf->mtsc_tgt, name_len + 1);
3100 if (tgtconf->mtsc_tgt == NULL) {
3101 OBD_FREE_PTR(tgtconf);
3104 memcpy(tgtconf->mtsc_tgt, svname, name_len);
3106 tgtconf->mtsc_next = fsdb->fsdb_srpc_tgt;
3107 fsdb->fsdb_srpc_tgt = tgtconf;
3110 rset = &tgtconf->mtsc_rset;
3111 } else if (strcmp(svname, MGSSELF_NAME) == 0) {
3112 /* put _mgs related srpc rule directly in mgs ruleset */
3113 rset = &fsdb->fsdb_mgs->mgs_lut.lut_sptlrpc_rset;
3115 rset = &fsdb->fsdb_srpc_gen;
3118 rc = sptlrpc_rule_set_merge(rset, &rule);
3123 static int mgs_srpc_set_param(const struct lu_env *env,
3124 struct mgs_device *mgs,
3126 struct mgs_target_info *mti,
3136 /* keep a copy of original param, which could be destroied
3138 copy_size = strlen(param) + 1;
3139 OBD_ALLOC(copy, copy_size);
3142 memcpy(copy, param, copy_size);
3144 rc = mgs_srpc_set_param_mem(fsdb, mti->mti_svname, param);
3148 /* previous steps guaranteed the syntax is correct */
3149 rc = mgs_srpc_set_param_disk(env, mgs, fsdb, mti, copy);
3153 if (test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
3155 * for mgs rules, make them effective immediately.
3157 LASSERT(fsdb->fsdb_srpc_tgt == NULL);
3158 sptlrpc_target_update_exp_flavor(mgs->mgs_obd,
3159 &fsdb->fsdb_srpc_gen);
3163 OBD_FREE(copy, copy_size);
3167 struct mgs_srpc_read_data {
3168 struct fs_db *msrd_fsdb;
3172 static int mgs_srpc_read_handler(const struct lu_env *env,
3173 struct llog_handle *llh,
3174 struct llog_rec_hdr *rec, void *data)
3176 struct mgs_srpc_read_data *msrd = data;
3177 struct cfg_marker *marker;
3178 struct lustre_cfg *lcfg = REC_DATA(rec);
3179 char *svname, *param;
3183 if (rec->lrh_type != OBD_CFG_REC) {
3184 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
3188 cfg_len = REC_DATA_LEN(rec);
3190 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
3192 CERROR("Insane cfg\n");
3196 if (lcfg->lcfg_command == LCFG_MARKER) {
3197 marker = lustre_cfg_buf(lcfg, 1);
3199 if (marker->cm_flags & CM_START &&
3200 marker->cm_flags & CM_SKIP)
3201 msrd->msrd_skip = 1;
3202 if (marker->cm_flags & CM_END)
3203 msrd->msrd_skip = 0;
3208 if (msrd->msrd_skip)
3211 if (lcfg->lcfg_command != LCFG_SPTLRPC_CONF) {
3212 CERROR("invalid command (%x)\n", lcfg->lcfg_command);
3216 svname = lustre_cfg_string(lcfg, 0);
3217 if (svname == NULL) {
3218 CERROR("svname is empty\n");
3222 param = lustre_cfg_string(lcfg, 1);
3223 if (param == NULL) {
3224 CERROR("param is empty\n");
3228 rc = mgs_srpc_set_param_mem(msrd->msrd_fsdb, svname, param);
3230 CERROR("read sptlrpc record error (%d): %s\n", rc, param);
3235 int mgs_get_fsdb_srpc_from_llog(const struct lu_env *env,
3236 struct mgs_device *mgs,
3239 struct llog_handle *llh = NULL;
3240 struct llog_ctxt *ctxt;
3242 struct mgs_srpc_read_data msrd;
3246 /* construct log name */
3247 rc = name_create(&logname, fsdb->fsdb_name, "-sptlrpc");
3251 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
3252 LASSERT(ctxt != NULL);
3254 if (mgs_log_is_empty(env, mgs, logname))
3257 rc = llog_open(env, ctxt, &llh, NULL, logname,
3265 rc = llog_init_handle(env, llh, LLOG_F_IS_PLAIN, NULL);
3267 GOTO(out_close, rc);
3269 if (llog_get_size(llh) <= 1)
3270 GOTO(out_close, rc = 0);
3272 msrd.msrd_fsdb = fsdb;
3275 rc = llog_process(env, llh, mgs_srpc_read_handler, (void *)&msrd,
3279 llog_close(env, llh);
3281 llog_ctxt_put(ctxt);
3282 name_destroy(&logname);
3285 CERROR("failed to read sptlrpc config database: %d\n", rc);
3289 /* Permanent settings of all parameters by writing into the appropriate
3290 * configuration logs.
3291 * A parameter with null value ("<param>='\0'") means to erase it out of
3294 static int mgs_write_log_param(const struct lu_env *env,
3295 struct mgs_device *mgs, struct fs_db *fsdb,
3296 struct mgs_target_info *mti, char *ptr)
3298 struct mgs_thread_info *mgi = mgs_env_info(env);
3304 /* For various parameter settings, we have to figure out which logs
3305 care about them (e.g. both mdt and client for lov settings) */
3306 CDEBUG(D_MGS, "next param '%s'\n", ptr);
3308 /* The params are stored in MOUNT_DATA_FILE and modified via
3309 tunefs.lustre, or set using lctl conf_param */
3311 /* Processed in lustre_start_mgc */
3312 if (class_match_param(ptr, PARAM_MGSNODE, NULL) == 0)
3315 /* Processed in ost/mdt */
3316 if (class_match_param(ptr, PARAM_NETWORK, NULL) == 0)
3319 /* Processed in mgs_write_log_ost */
3320 if (class_match_param(ptr, PARAM_FAILMODE, NULL) == 0) {
3321 if (mti->mti_flags & LDD_F_PARAM) {
3322 LCONSOLE_ERROR_MSG(0x169, "%s can only be "
3323 "changed with tunefs.lustre"
3324 "and --writeconf\n", ptr);
3330 if (class_match_param(ptr, PARAM_SRPC, NULL) == 0) {
3331 rc = mgs_srpc_set_param(env, mgs, fsdb, mti, ptr);
3335 if (class_match_param(ptr, PARAM_FAILNODE, NULL) == 0) {
3336 /* Add a failover nidlist */
3338 /* We already processed failovers params for new
3339 targets in mgs_write_log_target */
3340 if (mti->mti_flags & LDD_F_PARAM) {
3341 CDEBUG(D_MGS, "Adding failnode\n");
3342 rc = mgs_write_log_add_failnid(env, mgs, fsdb, mti);
3347 if (class_match_param(ptr, PARAM_SYS, &tmp) == 0) {
3348 rc = mgs_write_log_sys(env, mgs, fsdb, mti, ptr, tmp);
3352 if (class_match_param(ptr, PARAM_QUOTA, &tmp) == 0) {
3353 rc = mgs_write_log_quota(env, mgs, fsdb, mti, ptr, tmp);
3357 if (class_match_param(ptr, PARAM_OSC PARAM_ACTIVE, &tmp) == 0 ||
3358 class_match_param(ptr, PARAM_MDC PARAM_ACTIVE, &tmp) == 0) {
3359 /* active=0 means off, anything else means on */
3360 int flag = (*tmp == '0') ? CM_EXCLUDE : 0;
3361 bool deactive_osc = memcmp(ptr, PARAM_OSC PARAM_ACTIVE,
3362 strlen(PARAM_OSC PARAM_ACTIVE)) == 0;
3365 if (!deactive_osc) {
3368 rc = server_name2index(mti->mti_svname, &index, NULL);
3373 LCONSOLE_ERROR_MSG(0x144, "%s: MDC0 can not be"
3374 " (de)activated.\n",
3376 GOTO(end, rc = -EINVAL);
3380 LCONSOLE_WARN("Permanently %sactivating %s\n",
3381 flag ? "de" : "re", mti->mti_svname);
3383 rc = name_create(&logname, mti->mti_fsname, "-client");
3386 rc = mgs_modify(env, mgs, fsdb, mti, logname,
3388 deactive_osc ? "add osc" : "add mdc", flag);
3389 name_destroy(&logname);
3394 /* Add to all MDT logs for DNE */
3395 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3396 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
3398 rc = name_create_mdt(&logname, mti->mti_fsname, i);
3401 rc = mgs_modify(env, mgs, fsdb, mti, logname,
3403 deactive_osc ? "add osc" : "add osp",
3405 name_destroy(&logname);
3411 LCONSOLE_ERROR_MSG(0x145, "Couldn't find %s in"
3412 "log (%d). No permanent "
3413 "changes were made to the "
3415 mti->mti_svname, rc);
3416 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags))
3417 LCONSOLE_ERROR_MSG(0x146, "This may be"
3422 "update the logs.\n");
3425 /* Fall through to osc/mdc proc for deactivating live
3426 OSC/OSP on running MDT / clients. */
3428 /* Below here, let obd's XXX_process_config methods handle it */
3430 /* All lov. in proc */
3431 if (class_match_param(ptr, PARAM_LOV, NULL) == 0) {
3434 CDEBUG(D_MGS, "lov param %s\n", ptr);
3435 if (!(mti->mti_flags & LDD_F_SV_TYPE_MDT)) {
3436 LCONSOLE_ERROR_MSG(0x147, "LOV params must be "
3437 "set on the MDT, not %s. "
3444 if (mgs_log_is_empty(env, mgs, mti->mti_svname))
3445 GOTO(end, rc = -ENODEV);
3447 rc = name_create_mdt_and_lov(&logname, &mdtlovname, fsdb,
3448 mti->mti_stripe_index);
3451 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, mti->mti_svname,
3452 &mgi->mgi_bufs, mdtlovname, ptr);
3453 name_destroy(&logname);
3454 name_destroy(&mdtlovname);
3459 rc = name_create(&logname, mti->mti_fsname, "-client");
3462 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname, &mgi->mgi_bufs,
3463 fsdb->fsdb_clilov, ptr);
3464 name_destroy(&logname);
3468 /* All osc., mdc., llite. params in proc */
3469 if ((class_match_param(ptr, PARAM_OSC, NULL) == 0) ||
3470 (class_match_param(ptr, PARAM_MDC, NULL) == 0) ||
3471 (class_match_param(ptr, PARAM_LLITE, NULL) == 0)) {
3474 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
3475 LCONSOLE_ERROR_MSG(0x148, "Upgraded client logs for %s"
3476 " cannot be modified. Consider"
3477 " updating the configuration with"
3480 GOTO(end, rc = -EINVAL);
3482 if (memcmp(ptr, PARAM_LLITE, strlen(PARAM_LLITE)) == 0) {
3483 rc = name_create(&cname, mti->mti_fsname, "-client");
3484 /* Add the client type to match the obdname in
3485 class_config_llog_handler */
3486 } else if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
3487 rc = name_create(&cname, mti->mti_svname, "-mdc");
3488 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
3489 rc = name_create(&cname, mti->mti_svname, "-osc");
3491 GOTO(end, rc = -EINVAL);
3496 /* Forbid direct update of llite root squash parameters.
3497 * These parameters are indirectly set via the MDT settings.
3499 if ((class_match_param(ptr, PARAM_LLITE, &tmp) == 0) &&
3500 ((memcmp(tmp, "root_squash=", 12) == 0) ||
3501 (memcmp(tmp, "nosquash_nids=", 14) == 0))) {
3502 LCONSOLE_ERROR("%s: root squash parameters can only "
3503 "be updated through MDT component\n",
3505 name_destroy(&cname);
3506 GOTO(end, rc = -EINVAL);
3509 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
3512 rc = name_create(&logname, mti->mti_fsname, "-client");
3514 name_destroy(&cname);
3517 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname, &mgi->mgi_bufs,
3520 /* osc params affect the MDT as well */
3521 if (!rc && (mti->mti_flags & LDD_F_SV_TYPE_OST)) {
3524 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
3525 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
3527 name_destroy(&cname);
3528 rc = name_create_mdt_osc(&cname, mti->mti_svname,
3530 name_destroy(&logname);
3533 rc = name_create_mdt(&logname,
3534 mti->mti_fsname, i);
3537 if (!mgs_log_is_empty(env, mgs, logname)) {
3538 rc = mgs_wlp_lcfg(env, mgs, fsdb,
3548 /* For mdc activate/deactivate, it affects OSP on MDT as well */
3549 if (class_match_param(ptr, PARAM_MDC PARAM_ACTIVE, &tmp) == 0 &&
3552 char *lodname = NULL;
3553 char *param_str = NULL;
3557 /* replace mdc with osp */
3558 memcpy(ptr, PARAM_OSP, strlen(PARAM_OSP));
3559 rc = server_name2index(mti->mti_svname, &index, NULL);
3561 memcpy(ptr, PARAM_MDC, strlen(PARAM_MDC));
3565 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3566 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
3572 name_destroy(&logname);
3573 rc = name_create_mdt(&logname, mti->mti_fsname,
3578 if (mgs_log_is_empty(env, mgs, logname))
3581 snprintf(suffix, sizeof(suffix), "-osp-MDT%04x",
3583 name_destroy(&cname);
3584 rc = name_create(&cname, mti->mti_svname,
3589 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname,
3590 &mgi->mgi_bufs, cname, ptr);
3594 /* Add configuration log for noitfying LOD
3595 * to active/deactive the OSP. */
3596 name_destroy(¶m_str);
3597 rc = name_create(¶m_str, cname,
3598 (*tmp == '0') ? ".active=0" :
3603 name_destroy(&lodname);
3604 rc = name_create(&lodname, logname, "-mdtlov");
3608 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname,
3609 &mgi->mgi_bufs, lodname,
3614 memcpy(ptr, PARAM_MDC, strlen(PARAM_MDC));
3615 name_destroy(&lodname);
3616 name_destroy(¶m_str);
3619 name_destroy(&logname);
3620 name_destroy(&cname);
3624 /* All mdt. params in proc */
3625 if (class_match_param(ptr, PARAM_MDT, &tmp) == 0) {
3629 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
3630 if (strncmp(mti->mti_svname, mti->mti_fsname,
3631 MTI_NAME_MAXLEN) == 0)
3632 /* device is unspecified completely? */
3633 rc = LDD_F_SV_TYPE_MDT | LDD_F_SV_ALL;
3635 rc = server_name2index(mti->mti_svname, &idx, NULL);
3638 if ((rc & LDD_F_SV_TYPE_MDT) == 0)
3640 if (rc & LDD_F_SV_ALL) {
3641 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3643 fsdb->fsdb_mdt_index_map))
3645 rc = name_create_mdt(&logname,
3646 mti->mti_fsname, i);
3649 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti,
3650 logname, &mgi->mgi_bufs,
3652 name_destroy(&logname);
3657 if ((memcmp(tmp, "root_squash=", 12) == 0) ||
3658 (memcmp(tmp, "nosquash_nids=", 14) == 0)) {
3659 LCONSOLE_ERROR("%s: root squash parameters "
3660 "cannot be applied to a single MDT\n",
3662 GOTO(end, rc = -EINVAL);
3664 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti,
3665 mti->mti_svname, &mgi->mgi_bufs,
3666 mti->mti_svname, ptr);
3671 /* root squash settings are also applied to llite
3672 * config log (see LU-1778) */
3674 ((memcmp(tmp, "root_squash=", 12) == 0) ||
3675 (memcmp(tmp, "nosquash_nids=", 14) == 0))) {
3679 rc = name_create(&cname, mti->mti_fsname, "-client");
3682 rc = name_create(&logname, mti->mti_fsname, "-client");
3684 name_destroy(&cname);
3687 rc = name_create(&ptr2, PARAM_LLITE, tmp);
3689 name_destroy(&cname);
3690 name_destroy(&logname);
3693 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname,
3694 &mgi->mgi_bufs, cname, ptr2);
3695 name_destroy(&ptr2);
3696 name_destroy(&logname);
3697 name_destroy(&cname);
3702 /* All mdd., ost. and osd. params in proc */
3703 if ((class_match_param(ptr, PARAM_MDD, NULL) == 0) ||
3704 (class_match_param(ptr, PARAM_OST, NULL) == 0) ||
3705 (class_match_param(ptr, PARAM_OSD, NULL) == 0)) {
3706 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
3707 if (mgs_log_is_empty(env, mgs, mti->mti_svname))
3708 GOTO(end, rc = -ENODEV);
3710 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, mti->mti_svname,
3711 &mgi->mgi_bufs, mti->mti_svname, ptr);
3715 LCONSOLE_WARN("Ignoring unrecognized param '%s'\n", ptr);
3719 CERROR("err %d on param '%s'\n", rc, ptr);
3724 int mgs_write_log_target(const struct lu_env *env, struct mgs_device *mgs,
3725 struct mgs_target_info *mti, struct fs_db *fsdb)
3732 /* set/check the new target index */
3733 rc = mgs_set_index(env, mgs, mti);
3737 if (rc == EALREADY) {
3738 LCONSOLE_WARN("Found index %d for %s, updating log\n",
3739 mti->mti_stripe_index, mti->mti_svname);
3740 /* We would like to mark old log sections as invalid
3741 and add new log sections in the client and mdt logs.
3742 But if we add new sections, then live clients will
3743 get repeat setup instructions for already running
3744 osc's. So don't update the client/mdt logs. */
3745 mti->mti_flags &= ~LDD_F_UPDATE;
3749 OBD_FAIL_TIMEOUT(OBD_FAIL_MGS_WRITE_TARGET_DELAY, cfs_fail_val > 0 ?
3752 mutex_lock(&fsdb->fsdb_mutex);
3754 if (mti->mti_flags &
3755 (LDD_F_VIRGIN | LDD_F_UPGRADE14 | LDD_F_WRITECONF)) {
3756 /* Generate a log from scratch */
3757 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
3758 rc = mgs_write_log_mdt(env, mgs, fsdb, mti);
3759 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
3760 rc = mgs_write_log_ost(env, mgs, fsdb, mti);
3762 CERROR("Unknown target type %#x, can't create log for "
3763 "%s\n", mti->mti_flags, mti->mti_svname);
3766 CERROR("Can't write logs for %s (%d)\n",
3767 mti->mti_svname, rc);
3771 /* Just update the params from tunefs in mgs_write_log_params */
3772 CDEBUG(D_MGS, "Update params for %s\n", mti->mti_svname);
3773 mti->mti_flags |= LDD_F_PARAM;
3776 /* allocate temporary buffer, where class_get_next_param will
3777 make copy of a current parameter */
3778 OBD_ALLOC(buf, strlen(mti->mti_params) + 1);
3780 GOTO(out_up, rc = -ENOMEM);
3781 params = mti->mti_params;
3782 while (params != NULL) {
3783 rc = class_get_next_param(¶ms, buf);
3786 /* there is no next parameter, that is
3791 CDEBUG(D_MGS, "remaining string: '%s', param: '%s'\n",
3793 rc = mgs_write_log_param(env, mgs, fsdb, mti, buf);
3798 OBD_FREE(buf, strlen(mti->mti_params) + 1);
3801 mutex_unlock(&fsdb->fsdb_mutex);
3805 int mgs_erase_log(const struct lu_env *env, struct mgs_device *mgs, char *name)
3807 struct llog_ctxt *ctxt;
3810 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
3812 CERROR("%s: MGS config context doesn't exist\n",
3813 mgs->mgs_obd->obd_name);
3816 rc = llog_erase(env, ctxt, NULL, name);
3817 /* llog may not exist */
3820 llog_ctxt_put(ctxt);
3824 CERROR("%s: failed to clear log %s: %d\n",
3825 mgs->mgs_obd->obd_name, name, rc);
3830 /* erase all logs for the given fs */
3831 int mgs_erase_logs(const struct lu_env *env, struct mgs_device *mgs, char *fsname)
3834 struct list_head log_list;
3835 struct mgs_direntry *dirent, *n;
3836 int rc, len = strlen(fsname);
3840 /* Find all the logs in the CONFIGS directory */
3841 rc = class_dentry_readdir(env, mgs, &log_list);
3845 mutex_lock(&mgs->mgs_mutex);
3847 /* Delete the fs db */
3848 fsdb = mgs_find_fsdb(mgs, fsname);
3850 mgs_free_fsdb(mgs, fsdb);
3852 mutex_unlock(&mgs->mgs_mutex);
3854 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
3855 list_del_init(&dirent->mde_list);
3856 suffix = strrchr(dirent->mde_name, '-');
3857 if (suffix != NULL) {
3858 if ((len == suffix - dirent->mde_name) &&
3859 (strncmp(fsname, dirent->mde_name, len) == 0)) {
3860 CDEBUG(D_MGS, "Removing log %s\n",
3862 mgs_erase_log(env, mgs, dirent->mde_name);
3865 mgs_direntry_free(dirent);
3871 /* list all logs for the given fs */
3872 int mgs_list_logs(const struct lu_env *env, struct mgs_device *mgs,
3873 struct obd_ioctl_data *data)
3875 struct list_head log_list;
3876 struct mgs_direntry *dirent, *n;
3882 /* Find all the logs in the CONFIGS directory */
3883 rc = class_dentry_readdir(env, mgs, &log_list);
3887 out = data->ioc_bulk;
3888 remains = data->ioc_inllen1;
3889 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
3890 list_del_init(&dirent->mde_list);
3891 suffix = strrchr(dirent->mde_name, '-');
3892 if (suffix != NULL) {
3893 l = snprintf(out, remains, "config log: $%s\n",
3898 mgs_direntry_free(dirent);
3905 /* from llog_swab */
3906 static void print_lustre_cfg(struct lustre_cfg *lcfg)
3911 CDEBUG(D_MGS, "lustre_cfg: %p\n", lcfg);
3912 CDEBUG(D_MGS, "\tlcfg->lcfg_version: %#x\n", lcfg->lcfg_version);
3914 CDEBUG(D_MGS, "\tlcfg->lcfg_command: %#x\n", lcfg->lcfg_command);
3915 CDEBUG(D_MGS, "\tlcfg->lcfg_num: %#x\n", lcfg->lcfg_num);
3916 CDEBUG(D_MGS, "\tlcfg->lcfg_flags: %#x\n", lcfg->lcfg_flags);
3917 CDEBUG(D_MGS, "\tlcfg->lcfg_nid: %s\n", libcfs_nid2str(lcfg->lcfg_nid));
3919 CDEBUG(D_MGS, "\tlcfg->lcfg_bufcount: %d\n", lcfg->lcfg_bufcount);
3920 if (lcfg->lcfg_bufcount < LUSTRE_CFG_MAX_BUFCOUNT)
3921 for (i = 0; i < lcfg->lcfg_bufcount; i++) {
3922 CDEBUG(D_MGS, "\tlcfg->lcfg_buflens[%d]: %d %s\n",
3923 i, lcfg->lcfg_buflens[i],
3924 lustre_cfg_string(lcfg, i));
3929 /* Setup _mgs fsdb and log
3931 int mgs__mgs_fsdb_setup(const struct lu_env *env, struct mgs_device *mgs,
3937 rc = mgs_find_or_make_fsdb(env, mgs, MGSSELF_NAME, &fsdb);
3942 /* Setup params fsdb and log
3944 int mgs_params_fsdb_setup(const struct lu_env *env, struct mgs_device *mgs,
3947 struct llog_handle *params_llh = NULL;
3951 rc = mgs_find_or_make_fsdb(env, mgs, PARAMS_FILENAME, &fsdb);
3953 mutex_lock(&fsdb->fsdb_mutex);
3954 rc = record_start_log(env, mgs, ¶ms_llh, PARAMS_FILENAME);
3956 rc = record_end_log(env, ¶ms_llh);
3957 mutex_unlock(&fsdb->fsdb_mutex);
3963 /* Cleanup params fsdb and log
3965 int mgs_params_fsdb_cleanup(const struct lu_env *env, struct mgs_device *mgs)
3967 return mgs_erase_logs(env, mgs, PARAMS_FILENAME);
3970 /* Set a permanent (config log) param for a target or fs
3971 * \param lcfg buf0 may contain the device (testfs-MDT0000) name
3972 * buf1 contains the single parameter
3974 int mgs_setparam(const struct lu_env *env, struct mgs_device *mgs,
3975 struct lustre_cfg *lcfg, char *fsname)
3978 struct mgs_target_info *mti;
3979 char *devname, *param;
3986 print_lustre_cfg(lcfg);
3988 /* lustre, lustre-mdtlov, lustre-client, lustre-MDT0000 */
3989 devname = lustre_cfg_string(lcfg, 0);
3990 param = lustre_cfg_string(lcfg, 1);
3992 /* Assume device name embedded in param:
3993 lustre-OST0000.osc.max_dirty_mb=32 */
3994 ptr = strchr(param, '.');
4002 LCONSOLE_ERROR_MSG(0x14d, "No target specified: %s\n", param);
4006 rc = mgs_parse_devname(devname, fsname, NULL);
4007 if (rc == 0 && !mgs_parse_devname(devname, NULL, &index)) {
4008 /* param related to llite isn't allowed to set by OST or MDT */
4009 if (rc == 0 && strncmp(param, PARAM_LLITE,
4010 sizeof(PARAM_LLITE) - 1) == 0)
4013 /* assume devname is the fsname */
4014 strlcpy(fsname, devname, MTI_NAME_MAXLEN);
4016 CDEBUG(D_MGS, "setparam fs='%s' device='%s'\n", fsname, devname);
4018 rc = mgs_find_or_make_fsdb(env, mgs,
4019 lcfg->lcfg_command == LCFG_SET_PARAM ?
4020 PARAMS_FILENAME : fsname, &fsdb);
4024 if (lcfg->lcfg_command != LCFG_SET_PARAM &&
4025 !test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags) &&
4026 test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
4027 CERROR("No filesystem targets for %s. cfg_device from lctl "
4028 "is '%s'\n", fsname, devname);
4029 mgs_free_fsdb(mgs, fsdb);
4033 /* Create a fake mti to hold everything */
4036 GOTO(out, rc = -ENOMEM);
4037 if (strlcpy(mti->mti_fsname, fsname, sizeof(mti->mti_fsname))
4038 >= sizeof(mti->mti_fsname))
4039 GOTO(out, rc = -E2BIG);
4040 if (strlcpy(mti->mti_svname, devname, sizeof(mti->mti_svname))
4041 >= sizeof(mti->mti_svname))
4042 GOTO(out, rc = -E2BIG);
4043 if (strlcpy(mti->mti_params, param, sizeof(mti->mti_params))
4044 >= sizeof(mti->mti_params))
4045 GOTO(out, rc = -E2BIG);
4046 rc = server_name2index(mti->mti_svname, &mti->mti_stripe_index, &tmp);
4048 /* Not a valid server; may be only fsname */
4051 /* Strip -osc or -mdc suffix from svname */
4052 if (server_make_name(rc, mti->mti_stripe_index, mti->mti_fsname,
4054 GOTO(out, rc = -EINVAL);
4056 * Revoke lock so everyone updates. Should be alright if
4057 * someone was already reading while we were updating the logs,
4058 * so we don't really need to hold the lock while we're
4061 if (lcfg->lcfg_command == LCFG_SET_PARAM) {
4062 mti->mti_flags = rc | LDD_F_PARAM2;
4063 mutex_lock(&fsdb->fsdb_mutex);
4064 rc = mgs_write_log_param2(env, mgs, fsdb, mti, mti->mti_params);
4065 mutex_unlock(&fsdb->fsdb_mutex);
4066 mgs_revoke_lock(mgs, fsdb, CONFIG_T_PARAMS);
4068 mti->mti_flags = rc | LDD_F_PARAM;
4069 mutex_lock(&fsdb->fsdb_mutex);
4070 rc = mgs_write_log_param(env, mgs, fsdb, mti, mti->mti_params);
4071 mutex_unlock(&fsdb->fsdb_mutex);
4072 mgs_revoke_lock(mgs, fsdb, CONFIG_T_CONFIG);
4080 static int mgs_write_log_pool(const struct lu_env *env,
4081 struct mgs_device *mgs, char *logname,
4082 struct fs_db *fsdb, char *tgtname,
4083 enum lcfg_command_type cmd,
4084 char *fsname, char *poolname,
4085 char *ostname, char *comment)
4087 struct llog_handle *llh = NULL;
4090 rc = record_start_log(env, mgs, &llh, logname);
4093 rc = record_marker(env, llh, fsdb, CM_START, tgtname, comment);
4096 rc = record_base(env, llh, tgtname, 0, cmd,
4097 fsname, poolname, ostname, NULL);
4100 rc = record_marker(env, llh, fsdb, CM_END, tgtname, comment);
4102 record_end_log(env, &llh);
4106 int mgs_nodemap_cmd(const struct lu_env *env, struct mgs_device *mgs,
4107 enum lcfg_command_type cmd, const char *nodemap_name,
4118 case LCFG_NODEMAP_ADD:
4119 rc = nodemap_add(nodemap_name);
4121 case LCFG_NODEMAP_DEL:
4122 rc = nodemap_del(nodemap_name);
4124 case LCFG_NODEMAP_ADD_RANGE:
4125 rc = nodemap_parse_range(param, nid);
4128 rc = nodemap_add_range(nodemap_name, nid);
4130 case LCFG_NODEMAP_DEL_RANGE:
4131 rc = nodemap_parse_range(param, nid);
4134 rc = nodemap_del_range(nodemap_name, nid);
4136 case LCFG_NODEMAP_ADMIN:
4137 bool_switch = simple_strtoul(param, NULL, 10);
4138 rc = nodemap_set_allow_root(nodemap_name, bool_switch);
4140 case LCFG_NODEMAP_DENY_UNKNOWN:
4141 bool_switch = simple_strtoul(param, NULL, 10);
4142 rc = nodemap_set_deny_unknown(nodemap_name, bool_switch);
4144 case LCFG_NODEMAP_TRUSTED:
4145 bool_switch = simple_strtoul(param, NULL, 10);
4146 rc = nodemap_set_trust_client_ids(nodemap_name, bool_switch);
4148 case LCFG_NODEMAP_SQUASH_UID:
4149 int_id = simple_strtoul(param, NULL, 10);
4150 rc = nodemap_set_squash_uid(nodemap_name, int_id);
4152 case LCFG_NODEMAP_SQUASH_GID:
4153 int_id = simple_strtoul(param, NULL, 10);
4154 rc = nodemap_set_squash_gid(nodemap_name, int_id);
4156 case LCFG_NODEMAP_ADD_UIDMAP:
4157 case LCFG_NODEMAP_ADD_GIDMAP:
4158 rc = nodemap_parse_idmap(param, idmap);
4161 if (cmd == LCFG_NODEMAP_ADD_UIDMAP)
4162 rc = nodemap_add_idmap(nodemap_name, NODEMAP_UID,
4165 rc = nodemap_add_idmap(nodemap_name, NODEMAP_GID,
4168 case LCFG_NODEMAP_DEL_UIDMAP:
4169 case LCFG_NODEMAP_DEL_GIDMAP:
4170 rc = nodemap_parse_idmap(param, idmap);
4173 if (cmd == LCFG_NODEMAP_DEL_UIDMAP)
4174 rc = nodemap_del_idmap(nodemap_name, NODEMAP_UID,
4177 rc = nodemap_del_idmap(nodemap_name, NODEMAP_GID,
4180 case LCFG_NODEMAP_SET_FILESET:
4181 rc = nodemap_set_fileset(nodemap_name, param);
4190 int mgs_pool_cmd(const struct lu_env *env, struct mgs_device *mgs,
4191 enum lcfg_command_type cmd, char *fsname,
4192 char *poolname, char *ostname)
4197 char *label = NULL, *canceled_label = NULL;
4199 struct mgs_target_info *mti = NULL;
4203 rc = mgs_find_or_make_fsdb(env, mgs, fsname, &fsdb);
4205 CERROR("Can't get db for %s\n", fsname);
4208 if (test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
4209 CERROR("%s is not defined\n", fsname);
4210 mgs_free_fsdb(mgs, fsdb);
4214 label_sz = 10 + strlen(fsname) + strlen(poolname);
4216 /* check if ostname match fsname */
4217 if (ostname != NULL) {
4220 ptr = strrchr(ostname, '-');
4221 if ((ptr == NULL) ||
4222 (strncmp(fsname, ostname, ptr-ostname) != 0))
4224 label_sz += strlen(ostname);
4227 OBD_ALLOC(label, label_sz);
4234 "new %s.%s", fsname, poolname);
4238 "add %s.%s.%s", fsname, poolname, ostname);
4241 OBD_ALLOC(canceled_label, label_sz);
4242 if (canceled_label == NULL)
4243 GOTO(out_label, rc = -ENOMEM);
4245 "rem %s.%s.%s", fsname, poolname, ostname);
4246 sprintf(canceled_label,
4247 "add %s.%s.%s", fsname, poolname, ostname);
4250 OBD_ALLOC(canceled_label, label_sz);
4251 if (canceled_label == NULL)
4252 GOTO(out_label, rc = -ENOMEM);
4254 "del %s.%s", fsname, poolname);
4255 sprintf(canceled_label,
4256 "new %s.%s", fsname, poolname);
4262 if (canceled_label != NULL) {
4265 GOTO(out_cancel, rc = -ENOMEM);
4268 mutex_lock(&fsdb->fsdb_mutex);
4269 /* write pool def to all MDT logs */
4270 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
4271 if (test_bit(i, fsdb->fsdb_mdt_index_map)) {
4272 rc = name_create_mdt_and_lov(&logname, &lovname,
4275 mutex_unlock(&fsdb->fsdb_mutex);
4278 if (canceled_label != NULL) {
4279 strcpy(mti->mti_svname, "lov pool");
4280 rc = mgs_modify(env, mgs, fsdb, mti, logname,
4281 lovname, canceled_label,
4286 rc = mgs_write_log_pool(env, mgs, logname,
4290 name_destroy(&logname);
4291 name_destroy(&lovname);
4293 mutex_unlock(&fsdb->fsdb_mutex);
4299 rc = name_create(&logname, fsname, "-client");
4301 mutex_unlock(&fsdb->fsdb_mutex);
4304 if (canceled_label != NULL) {
4305 rc = mgs_modify(env, mgs, fsdb, mti, logname,
4306 fsdb->fsdb_clilov, canceled_label, CM_SKIP);
4308 mutex_unlock(&fsdb->fsdb_mutex);
4309 name_destroy(&logname);
4314 rc = mgs_write_log_pool(env, mgs, logname, fsdb, fsdb->fsdb_clilov,
4315 cmd, fsname, poolname, ostname, label);
4316 mutex_unlock(&fsdb->fsdb_mutex);
4317 name_destroy(&logname);
4318 /* request for update */
4319 mgs_revoke_lock(mgs, fsdb, CONFIG_T_CONFIG);
4326 if (canceled_label != NULL)
4327 OBD_FREE(canceled_label, label_sz);
4329 OBD_FREE(label, label_sz);