4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 only,
8 * as published by the Free Software Foundation.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License version 2 for more details (a copy is included
14 * in the LICENSE file that accompanied this code).
16 * You should have received a copy of the GNU General Public License
17 * version 2 along with this program; If not, see
18 * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
20 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
21 * CA 95054 USA or visit www.sun.com if you need additional information or
27 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
28 * Use is subject to license terms.
30 * Copyright (c) 2011, 2013, Intel Corporation.
33 * This file is part of Lustre, http://www.lustre.org/
34 * Lustre is a trademark of Sun Microsystems, Inc.
36 * lustre/mgs/mgs_llog.c
38 * Lustre Management Server (mgs) config llog creation
40 * Author: Nathan Rutman <nathan@clusterfs.com>
41 * Author: Alex Zhuravlev <bzzz@whamcloud.com>
42 * Author: Mikhail Pershin <tappro@whamcloud.com>
45 #define DEBUG_SUBSYSTEM S_MGS
46 #define D_MGS D_CONFIG
49 #include <lustre_ioctl.h>
50 #include <lustre_param.h>
51 #include <lustre_sec.h>
52 #include <lustre_quota.h>
54 #include "mgs_internal.h"
56 /********************** Class functions ********************/
58 /* Find all logs in CONFIG directory and link then into list */
59 int class_dentry_readdir(const struct lu_env *env,
60 struct mgs_device *mgs, struct list_head *log_list)
62 struct dt_object *dir = mgs->mgs_configs_dir;
63 const struct dt_it_ops *iops;
65 struct mgs_direntry *de;
69 INIT_LIST_HEAD(log_list);
72 LASSERT(dir->do_index_ops);
74 iops = &dir->do_index_ops->dio_it;
75 it = iops->init(env, dir, LUDA_64BITHASH, BYPASS_CAPA);
79 rc = iops->load(env, it, 0);
85 key = (void *)iops->key(env, it);
87 CERROR("%s: key failed when listing %s: rc = %d\n",
88 mgs->mgs_obd->obd_name, MOUNT_CONFIGS_DIR,
92 key_sz = iops->key_size(env, it);
95 /* filter out "." and ".." entries */
99 if (key_sz == 2 && key[1] == '.')
103 de = mgs_direntry_alloc(key_sz + 1);
109 memcpy(de->mde_name, key, key_sz);
110 de->mde_name[key_sz] = 0;
112 list_add(&de->mde_list, log_list);
115 rc = iops->next(env, it);
124 CERROR("%s: key failed when listing %s: rc = %d\n",
125 mgs->mgs_obd->obd_name, MOUNT_CONFIGS_DIR, rc);
129 /******************** DB functions *********************/
131 static inline int name_create(char **newname, char *prefix, char *suffix)
134 OBD_ALLOC(*newname, strlen(prefix) + strlen(suffix) + 1);
137 sprintf(*newname, "%s%s", prefix, suffix);
141 static inline void name_destroy(char **name)
144 OBD_FREE(*name, strlen(*name) + 1);
148 struct mgs_fsdb_handler_data
154 /* from the (client) config log, figure out:
155 1. which ost's/mdt's are configured (by index)
156 2. what the last config step is
157 3. COMPAT_18 osc name
159 /* It might be better to have a separate db file, instead of parsing the info
160 out of the client log. This is slow and potentially error-prone. */
161 static int mgs_fsdb_handler(const struct lu_env *env, struct llog_handle *llh,
162 struct llog_rec_hdr *rec, void *data)
164 struct mgs_fsdb_handler_data *d = data;
165 struct fs_db *fsdb = d->fsdb;
166 int cfg_len = rec->lrh_len;
167 char *cfg_buf = (char*) (rec + 1);
168 struct lustre_cfg *lcfg;
173 if (rec->lrh_type != OBD_CFG_REC) {
174 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
178 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
180 CERROR("Insane cfg\n");
184 lcfg = (struct lustre_cfg *)cfg_buf;
186 CDEBUG(D_INFO, "cmd %x %s %s\n", lcfg->lcfg_command,
187 lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));
189 /* Figure out ost indicies */
190 /* lov_modify_tgts add 0:lov1 1:ost1_UUID 2(index):0 3(gen):1 */
191 if (lcfg->lcfg_command == LCFG_LOV_ADD_OBD ||
192 lcfg->lcfg_command == LCFG_LOV_DEL_OBD) {
193 index = simple_strtoul(lustre_cfg_string(lcfg, 2),
195 CDEBUG(D_MGS, "OST index for %s is %u (%s)\n",
196 lustre_cfg_string(lcfg, 1), index,
197 lustre_cfg_string(lcfg, 2));
198 set_bit(index, fsdb->fsdb_ost_index_map);
201 /* Figure out mdt indicies */
202 /* attach 0:MDC_uml1_mdsA_MNT_client 1:mdc 2:1d834_MNT_client_03f */
203 if ((lcfg->lcfg_command == LCFG_ATTACH) &&
204 (strcmp(lustre_cfg_string(lcfg, 1), LUSTRE_MDC_NAME) == 0)) {
205 rc = server_name2index(lustre_cfg_string(lcfg, 0),
207 if (rc != LDD_F_SV_TYPE_MDT) {
208 CWARN("Unparsable MDC name %s, assuming index 0\n",
209 lustre_cfg_string(lcfg, 0));
213 CDEBUG(D_MGS, "MDT index is %u\n", index);
214 set_bit(index, fsdb->fsdb_mdt_index_map);
215 fsdb->fsdb_mdt_count ++;
219 * figure out the old config. fsdb_gen = 0 means old log
220 * It is obsoleted and not supported anymore
222 if (fsdb->fsdb_gen == 0) {
223 CERROR("Old config format is not supported\n");
228 * compat to 1.8, check osc name used by MDT0 to OSTs, bz18548.
230 if (!test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags) &&
231 lcfg->lcfg_command == LCFG_ATTACH &&
232 strcmp(lustre_cfg_string(lcfg, 1), LUSTRE_OSC_NAME) == 0) {
233 if (OBD_OCD_VERSION_MAJOR(d->ver) == 1 &&
234 OBD_OCD_VERSION_MINOR(d->ver) <= 8) {
235 CWARN("MDT using 1.8 OSC name scheme\n");
236 set_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags);
240 if (lcfg->lcfg_command == LCFG_MARKER) {
241 struct cfg_marker *marker;
242 marker = lustre_cfg_buf(lcfg, 1);
244 d->ver = marker->cm_vers;
246 /* Keep track of the latest marker step */
247 fsdb->fsdb_gen = max(fsdb->fsdb_gen, marker->cm_step);
253 /* fsdb->fsdb_mutex is already held in mgs_find_or_make_fsdb*/
254 static int mgs_get_fsdb_from_llog(const struct lu_env *env,
255 struct mgs_device *mgs,
259 struct llog_handle *loghandle;
260 struct llog_ctxt *ctxt;
261 struct mgs_fsdb_handler_data d = { fsdb, 0 };
266 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
267 LASSERT(ctxt != NULL);
268 rc = name_create(&logname, fsdb->fsdb_name, "-client");
271 rc = llog_open_create(env, ctxt, &loghandle, NULL, logname);
275 rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL);
279 if (llog_get_size(loghandle) <= 1)
280 set_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags);
282 rc = llog_process(env, loghandle, mgs_fsdb_handler, (void *)&d, NULL);
283 CDEBUG(D_INFO, "get_db = %d\n", rc);
285 llog_close(env, loghandle);
287 name_destroy(&logname);
294 static void mgs_free_fsdb_srpc(struct fs_db *fsdb)
296 struct mgs_tgt_srpc_conf *tgtconf;
298 /* free target-specific rules */
299 while (fsdb->fsdb_srpc_tgt) {
300 tgtconf = fsdb->fsdb_srpc_tgt;
301 fsdb->fsdb_srpc_tgt = tgtconf->mtsc_next;
303 LASSERT(tgtconf->mtsc_tgt);
305 sptlrpc_rule_set_free(&tgtconf->mtsc_rset);
306 OBD_FREE(tgtconf->mtsc_tgt, strlen(tgtconf->mtsc_tgt) + 1);
307 OBD_FREE_PTR(tgtconf);
310 /* free general rules */
311 sptlrpc_rule_set_free(&fsdb->fsdb_srpc_gen);
314 struct fs_db *mgs_find_fsdb(struct mgs_device *mgs, char *fsname)
319 cfs_list_for_each(tmp, &mgs->mgs_fs_db_list) {
320 fsdb = cfs_list_entry(tmp, struct fs_db, fsdb_list);
321 if (strcmp(fsdb->fsdb_name, fsname) == 0)
327 /* caller must hold the mgs->mgs_fs_db_lock */
328 static struct fs_db *mgs_new_fsdb(const struct lu_env *env,
329 struct mgs_device *mgs, char *fsname)
335 if (strlen(fsname) >= sizeof(fsdb->fsdb_name)) {
336 CERROR("fsname %s is too long\n", fsname);
344 strcpy(fsdb->fsdb_name, fsname);
345 mutex_init(&fsdb->fsdb_mutex);
346 set_bit(FSDB_UDESC, &fsdb->fsdb_flags);
349 if (strcmp(fsname, MGSSELF_NAME) == 0) {
350 set_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags);
352 OBD_ALLOC(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
353 OBD_ALLOC(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
354 if (!fsdb->fsdb_ost_index_map || !fsdb->fsdb_mdt_index_map) {
355 CERROR("No memory for index maps\n");
356 GOTO(err, rc = -ENOMEM);
359 rc = name_create(&fsdb->fsdb_clilov, fsname, "-clilov");
362 rc = name_create(&fsdb->fsdb_clilmv, fsname, "-clilmv");
366 /* initialise data for NID table */
367 mgs_ir_init_fs(env, mgs, fsdb);
369 lproc_mgs_add_live(mgs, fsdb);
372 cfs_list_add(&fsdb->fsdb_list, &mgs->mgs_fs_db_list);
376 if (fsdb->fsdb_ost_index_map)
377 OBD_FREE(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
378 if (fsdb->fsdb_mdt_index_map)
379 OBD_FREE(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
380 name_destroy(&fsdb->fsdb_clilov);
381 name_destroy(&fsdb->fsdb_clilmv);
386 static void mgs_free_fsdb(struct mgs_device *mgs, struct fs_db *fsdb)
388 /* wait for anyone with the sem */
389 mutex_lock(&fsdb->fsdb_mutex);
390 lproc_mgs_del_live(mgs, fsdb);
391 cfs_list_del(&fsdb->fsdb_list);
393 /* deinitialize fsr */
394 mgs_ir_fini_fs(mgs, fsdb);
396 if (fsdb->fsdb_ost_index_map)
397 OBD_FREE(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
398 if (fsdb->fsdb_mdt_index_map)
399 OBD_FREE(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
400 name_destroy(&fsdb->fsdb_clilov);
401 name_destroy(&fsdb->fsdb_clilmv);
402 mgs_free_fsdb_srpc(fsdb);
403 mutex_unlock(&fsdb->fsdb_mutex);
407 int mgs_init_fsdb_list(struct mgs_device *mgs)
409 CFS_INIT_LIST_HEAD(&mgs->mgs_fs_db_list);
413 int mgs_cleanup_fsdb_list(struct mgs_device *mgs)
416 cfs_list_t *tmp, *tmp2;
417 mutex_lock(&mgs->mgs_mutex);
418 cfs_list_for_each_safe(tmp, tmp2, &mgs->mgs_fs_db_list) {
419 fsdb = cfs_list_entry(tmp, struct fs_db, fsdb_list);
420 mgs_free_fsdb(mgs, fsdb);
422 mutex_unlock(&mgs->mgs_mutex);
426 int mgs_find_or_make_fsdb(const struct lu_env *env,
427 struct mgs_device *mgs, char *name,
434 mutex_lock(&mgs->mgs_mutex);
435 fsdb = mgs_find_fsdb(mgs, name);
437 mutex_unlock(&mgs->mgs_mutex);
442 CDEBUG(D_MGS, "Creating new db\n");
443 fsdb = mgs_new_fsdb(env, mgs, name);
444 /* lock fsdb_mutex until the db is loaded from llogs */
446 mutex_lock(&fsdb->fsdb_mutex);
447 mutex_unlock(&mgs->mgs_mutex);
451 if (!test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
452 /* populate the db from the client llog */
453 rc = mgs_get_fsdb_from_llog(env, mgs, fsdb);
455 CERROR("Can't get db from client log %d\n", rc);
460 /* populate srpc rules from params llog */
461 rc = mgs_get_fsdb_srpc_from_llog(env, mgs, fsdb);
463 CERROR("Can't get db from params log %d\n", rc);
467 mutex_unlock(&fsdb->fsdb_mutex);
473 mutex_unlock(&fsdb->fsdb_mutex);
474 mgs_free_fsdb(mgs, fsdb);
480 -1= empty client log */
481 int mgs_check_index(const struct lu_env *env,
482 struct mgs_device *mgs,
483 struct mgs_target_info *mti)
490 LASSERT(!(mti->mti_flags & LDD_F_NEED_INDEX));
492 rc = mgs_find_or_make_fsdb(env, mgs, mti->mti_fsname, &fsdb);
494 CERROR("Can't get db for %s\n", mti->mti_fsname);
498 if (test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags))
501 if (mti->mti_flags & LDD_F_SV_TYPE_OST)
502 imap = fsdb->fsdb_ost_index_map;
503 else if (mti->mti_flags & LDD_F_SV_TYPE_MDT)
504 imap = fsdb->fsdb_mdt_index_map;
508 if (test_bit(mti->mti_stripe_index, imap))
513 static __inline__ int next_index(void *index_map, int map_len)
516 for (i = 0; i < map_len * 8; i++)
517 if (!test_bit(i, index_map)) {
520 CERROR("max index %d exceeded.\n", i);
525 0 newly marked as in use
527 +EALREADY for update of an old index */
528 static int mgs_set_index(const struct lu_env *env,
529 struct mgs_device *mgs,
530 struct mgs_target_info *mti)
537 rc = mgs_find_or_make_fsdb(env, mgs, mti->mti_fsname, &fsdb);
539 CERROR("Can't get db for %s\n", mti->mti_fsname);
543 mutex_lock(&fsdb->fsdb_mutex);
544 if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
545 imap = fsdb->fsdb_ost_index_map;
546 } else if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
547 imap = fsdb->fsdb_mdt_index_map;
549 GOTO(out_up, rc = -EINVAL);
552 if (mti->mti_flags & LDD_F_NEED_INDEX) {
553 rc = next_index(imap, INDEX_MAP_SIZE);
555 GOTO(out_up, rc = -ERANGE);
556 mti->mti_stripe_index = rc;
557 if (mti->mti_flags & LDD_F_SV_TYPE_MDT)
558 fsdb->fsdb_mdt_count ++;
561 if (mti->mti_stripe_index >= INDEX_MAP_SIZE * 8) {
562 LCONSOLE_ERROR_MSG(0x13f, "Server %s requested index %d, "
563 "but the max index is %d.\n",
564 mti->mti_svname, mti->mti_stripe_index,
566 GOTO(out_up, rc = -ERANGE);
569 if (test_bit(mti->mti_stripe_index, imap)) {
570 if ((mti->mti_flags & LDD_F_VIRGIN) &&
571 !(mti->mti_flags & LDD_F_WRITECONF)) {
572 LCONSOLE_ERROR_MSG(0x140, "Server %s requested index "
573 "%d, but that index is already in "
574 "use. Use --writeconf to force\n",
576 mti->mti_stripe_index);
577 GOTO(out_up, rc = -EADDRINUSE);
579 CDEBUG(D_MGS, "Server %s updating index %d\n",
580 mti->mti_svname, mti->mti_stripe_index);
581 GOTO(out_up, rc = EALREADY);
585 set_bit(mti->mti_stripe_index, imap);
586 clear_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags);
587 mutex_unlock(&fsdb->fsdb_mutex);
588 server_make_name(mti->mti_flags & ~(LDD_F_VIRGIN | LDD_F_WRITECONF),
589 mti->mti_stripe_index, mti->mti_fsname, mti->mti_svname);
591 CDEBUG(D_MGS, "Set index for %s to %d\n", mti->mti_svname,
592 mti->mti_stripe_index);
596 mutex_unlock(&fsdb->fsdb_mutex);
600 struct mgs_modify_lookup {
601 struct cfg_marker mml_marker;
605 static int mgs_modify_handler(const struct lu_env *env,
606 struct llog_handle *llh,
607 struct llog_rec_hdr *rec, void *data)
609 struct mgs_modify_lookup *mml = data;
610 struct cfg_marker *marker;
611 struct lustre_cfg *lcfg = REC_DATA(rec);
612 int cfg_len = REC_DATA_LEN(rec);
616 if (rec->lrh_type != OBD_CFG_REC) {
617 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
621 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
623 CERROR("Insane cfg\n");
627 /* We only care about markers */
628 if (lcfg->lcfg_command != LCFG_MARKER)
631 marker = lustre_cfg_buf(lcfg, 1);
632 if ((strcmp(mml->mml_marker.cm_comment, marker->cm_comment) == 0) &&
633 (strcmp(mml->mml_marker.cm_tgtname, marker->cm_tgtname) == 0) &&
634 !(marker->cm_flags & CM_SKIP)) {
635 /* Found a non-skipped marker match */
636 CDEBUG(D_MGS, "Changing rec %u marker %d %x->%x: %s %s\n",
637 rec->lrh_index, marker->cm_step,
638 marker->cm_flags, mml->mml_marker.cm_flags,
639 marker->cm_tgtname, marker->cm_comment);
640 /* Overwrite the old marker llog entry */
641 marker->cm_flags &= ~CM_EXCLUDE; /* in case we're unexcluding */
642 marker->cm_flags |= mml->mml_marker.cm_flags;
643 marker->cm_canceltime = mml->mml_marker.cm_canceltime;
644 rc = llog_write(env, llh, rec, rec->lrh_index);
653 * Modify an existing config log record (for CM_SKIP or CM_EXCLUDE)
655 * 0 - modified successfully,
656 * 1 - no modification was done
659 static int mgs_modify(const struct lu_env *env, struct mgs_device *mgs,
660 struct fs_db *fsdb, struct mgs_target_info *mti,
661 char *logname, char *devname, char *comment, int flags)
663 struct llog_handle *loghandle;
664 struct llog_ctxt *ctxt;
665 struct mgs_modify_lookup *mml;
670 LASSERT(mutex_is_locked(&fsdb->fsdb_mutex));
671 CDEBUG(D_MGS, "modify %s/%s/%s fl=%x\n", logname, devname, comment,
674 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
675 LASSERT(ctxt != NULL);
676 rc = llog_open(env, ctxt, &loghandle, NULL, logname, LLOG_OPEN_EXISTS);
683 rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL);
687 if (llog_get_size(loghandle) <= 1)
688 GOTO(out_close, rc = 0);
692 GOTO(out_close, rc = -ENOMEM);
693 if (strlcpy(mml->mml_marker.cm_comment, comment,
694 sizeof(mml->mml_marker.cm_comment)) >=
695 sizeof(mml->mml_marker.cm_comment))
696 GOTO(out_free, rc = -E2BIG);
697 if (strlcpy(mml->mml_marker.cm_tgtname, devname,
698 sizeof(mml->mml_marker.cm_tgtname)) >=
699 sizeof(mml->mml_marker.cm_tgtname))
700 GOTO(out_free, rc = -E2BIG);
701 /* Modify mostly means cancel */
702 mml->mml_marker.cm_flags = flags;
703 mml->mml_marker.cm_canceltime = flags ? cfs_time_current_sec() : 0;
704 mml->mml_modified = 0;
705 rc = llog_process(env, loghandle, mgs_modify_handler, (void *)mml,
707 if (!rc && !mml->mml_modified)
714 llog_close(env, loghandle);
717 CERROR("%s: modify %s/%s failed: rc = %d\n",
718 mgs->mgs_obd->obd_name, mti->mti_svname, comment, rc);
723 /** This structure is passed to mgs_replace_handler */
724 struct mgs_replace_uuid_lookup {
725 /* Nids are replaced for this target device */
726 struct mgs_target_info target;
727 /* Temporary modified llog */
728 struct llog_handle *temp_llh;
729 /* Flag is set if in target block*/
730 int in_target_device;
731 /* Nids already added. Just skip (multiple nids) */
732 int device_nids_added;
733 /* Flag is set if this block should not be copied */
738 * Check: a) if block should be skipped
739 * b) is it target block
744 * \retval 0 should not to be skipped
745 * \retval 1 should to be skipped
747 static int check_markers(struct lustre_cfg *lcfg,
748 struct mgs_replace_uuid_lookup *mrul)
750 struct cfg_marker *marker;
752 /* Track markers. Find given device */
753 if (lcfg->lcfg_command == LCFG_MARKER) {
754 marker = lustre_cfg_buf(lcfg, 1);
755 /* Clean llog from records marked as CM_EXCLUDE.
756 CM_SKIP records are used for "active" command
757 and can be restored if needed */
758 if ((marker->cm_flags & (CM_EXCLUDE | CM_START)) ==
759 (CM_EXCLUDE | CM_START)) {
764 if ((marker->cm_flags & (CM_EXCLUDE | CM_END)) ==
765 (CM_EXCLUDE | CM_END)) {
770 if (strcmp(mrul->target.mti_svname, marker->cm_tgtname) == 0) {
771 LASSERT(!(marker->cm_flags & CM_START) ||
772 !(marker->cm_flags & CM_END));
773 if (marker->cm_flags & CM_START) {
774 mrul->in_target_device = 1;
775 mrul->device_nids_added = 0;
776 } else if (marker->cm_flags & CM_END)
777 mrul->in_target_device = 0;
784 static int record_base(const struct lu_env *env, struct llog_handle *llh,
785 char *cfgname, lnet_nid_t nid, int cmd,
786 char *s1, char *s2, char *s3, char *s4)
788 struct mgs_thread_info *mgi = mgs_env_info(env);
789 struct llog_cfg_rec *lcr;
792 CDEBUG(D_MGS, "lcfg %s %#x %s %s %s %s\n", cfgname,
793 cmd, s1, s2, s3, s4);
795 lustre_cfg_bufs_reset(&mgi->mgi_bufs, cfgname);
797 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, s1);
799 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 2, s2);
801 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 3, s3);
803 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 4, s4);
805 lcr = lustre_cfg_rec_new(cmd, &mgi->mgi_bufs);
809 lcr->lcr_cfg.lcfg_nid = nid;
810 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
812 lustre_cfg_rec_free(lcr);
816 "failed to write lcfg %s %#x %s %s %s %s: rc = %d\n",
817 cfgname, cmd, s1, s2, s3, s4, rc);
821 static inline int record_add_uuid(const struct lu_env *env,
822 struct llog_handle *llh,
823 uint64_t nid, char *uuid)
825 return record_base(env, llh, NULL, nid, LCFG_ADD_UUID, uuid, 0, 0, 0);
828 static inline int record_add_conn(const struct lu_env *env,
829 struct llog_handle *llh,
830 char *devname, char *uuid)
832 return record_base(env, llh, devname, 0, LCFG_ADD_CONN, uuid, 0, 0, 0);
835 static inline int record_attach(const struct lu_env *env,
836 struct llog_handle *llh, char *devname,
837 char *type, char *uuid)
839 return record_base(env, llh,devname, 0, LCFG_ATTACH, type, uuid, 0, 0);
842 static inline int record_setup(const struct lu_env *env,
843 struct llog_handle *llh, char *devname,
844 char *s1, char *s2, char *s3, char *s4)
846 return record_base(env, llh, devname, 0, LCFG_SETUP, s1, s2, s3, s4);
850 * \retval <0 record processing error
851 * \retval n record is processed. No need copy original one.
852 * \retval 0 record is not processed.
854 static int process_command(const struct lu_env *env, struct lustre_cfg *lcfg,
855 struct mgs_replace_uuid_lookup *mrul)
862 if (lcfg->lcfg_command == LCFG_ADD_UUID) {
863 /* LCFG_ADD_UUID command found. Let's skip original command
864 and add passed nids */
865 ptr = mrul->target.mti_params;
866 while (class_parse_nid(ptr, &nid, &ptr) == 0) {
867 CDEBUG(D_MGS, "add nid %s with uuid %s, "
868 "device %s\n", libcfs_nid2str(nid),
869 mrul->target.mti_params,
870 mrul->target.mti_svname);
871 rc = record_add_uuid(env,
873 mrul->target.mti_params);
878 if (nids_added == 0) {
879 CERROR("No new nids were added, nid %s with uuid %s, "
880 "device %s\n", libcfs_nid2str(nid),
881 mrul->target.mti_params,
882 mrul->target.mti_svname);
885 mrul->device_nids_added = 1;
891 if (mrul->device_nids_added && lcfg->lcfg_command == LCFG_SETUP) {
892 /* LCFG_SETUP command found. UUID should be changed */
893 rc = record_setup(env,
895 /* devname the same */
896 lustre_cfg_string(lcfg, 0),
897 /* s1 is not changed */
898 lustre_cfg_string(lcfg, 1),
899 /* new uuid should be
901 mrul->target.mti_params,
902 /* s3 is not changed */
903 lustre_cfg_string(lcfg, 3),
904 /* s4 is not changed */
905 lustre_cfg_string(lcfg, 4));
909 /* Another commands in target device block */
914 * Handler that called for every record in llog.
915 * Records are processed in order they placed in llog.
917 * \param[in] llh log to be processed
918 * \param[in] rec current record
919 * \param[in] data mgs_replace_uuid_lookup structure
923 static int mgs_replace_handler(const struct lu_env *env,
924 struct llog_handle *llh,
925 struct llog_rec_hdr *rec,
928 struct mgs_replace_uuid_lookup *mrul;
929 struct lustre_cfg *lcfg = REC_DATA(rec);
930 int cfg_len = REC_DATA_LEN(rec);
934 mrul = (struct mgs_replace_uuid_lookup *)data;
936 if (rec->lrh_type != OBD_CFG_REC) {
937 CERROR("unhandled lrh_type: %#x, cmd %x %s %s\n",
938 rec->lrh_type, lcfg->lcfg_command,
939 lustre_cfg_string(lcfg, 0),
940 lustre_cfg_string(lcfg, 1));
944 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
946 /* Do not copy any invalidated records */
947 GOTO(skip_out, rc = 0);
950 rc = check_markers(lcfg, mrul);
951 if (rc || mrul->skip_it)
952 GOTO(skip_out, rc = 0);
954 /* Write to new log all commands outside target device block */
955 if (!mrul->in_target_device)
956 GOTO(copy_out, rc = 0);
958 /* Skip all other LCFG_ADD_UUID and LCFG_ADD_CONN records
959 (failover nids) for this target, assuming that if then
960 primary is changing then so is the failover */
961 if (mrul->device_nids_added &&
962 (lcfg->lcfg_command == LCFG_ADD_UUID ||
963 lcfg->lcfg_command == LCFG_ADD_CONN))
964 GOTO(skip_out, rc = 0);
966 rc = process_command(env, lcfg, mrul);
973 /* Record is placed in temporary llog as is */
974 rc = llog_write(env, mrul->temp_llh, rec, LLOG_NEXT_IDX);
976 CDEBUG(D_MGS, "Copied idx=%d, rc=%d, len=%d, cmd %x %s %s\n",
977 rec->lrh_index, rc, rec->lrh_len, lcfg->lcfg_command,
978 lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));
982 CDEBUG(D_MGS, "Skipped idx=%d, rc=%d, len=%d, cmd %x %s %s\n",
983 rec->lrh_index, rc, rec->lrh_len, lcfg->lcfg_command,
984 lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));
988 static int mgs_log_is_empty(const struct lu_env *env,
989 struct mgs_device *mgs, char *name)
991 struct llog_ctxt *ctxt;
994 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
995 LASSERT(ctxt != NULL);
997 rc = llog_is_empty(env, ctxt, name);
1002 static int mgs_replace_nids_log(const struct lu_env *env,
1003 struct obd_device *mgs, struct fs_db *fsdb,
1004 char *logname, char *devname, char *nids)
1006 struct llog_handle *orig_llh, *backup_llh;
1007 struct llog_ctxt *ctxt;
1008 struct mgs_replace_uuid_lookup *mrul;
1009 struct mgs_device *mgs_dev = lu2mgs_dev(mgs->obd_lu_dev);
1010 static struct obd_uuid cfg_uuid = { .uuid = "config_uuid" };
1015 CDEBUG(D_MGS, "Replace nids for %s in %s\n", devname, logname);
1017 ctxt = llog_get_context(mgs, LLOG_CONFIG_ORIG_CTXT);
1018 LASSERT(ctxt != NULL);
1020 if (mgs_log_is_empty(env, mgs_dev, logname)) {
1021 /* Log is empty. Nothing to replace */
1022 GOTO(out_put, rc = 0);
1025 OBD_ALLOC(backup, strlen(logname) + strlen(".bak") + 1);
1027 GOTO(out_put, rc = -ENOMEM);
1029 sprintf(backup, "%s.bak", logname);
1031 rc = llog_backup(env, mgs, ctxt, ctxt, logname, backup);
1033 /* Now erase original log file. Connections are not allowed.
1034 Backup is already saved */
1035 rc = llog_erase(env, ctxt, NULL, logname);
1038 } else if (rc != -ENOENT) {
1039 CERROR("%s: can't make backup for %s: rc = %d\n",
1040 mgs->obd_name, logname, rc);
1044 /* open local log */
1045 rc = llog_open_create(env, ctxt, &orig_llh, NULL, logname);
1047 GOTO(out_restore, rc);
1049 rc = llog_init_handle(env, orig_llh, LLOG_F_IS_PLAIN, &cfg_uuid);
1051 GOTO(out_closel, rc);
1053 /* open backup llog */
1054 rc = llog_open(env, ctxt, &backup_llh, NULL, backup,
1057 GOTO(out_closel, rc);
1059 rc = llog_init_handle(env, backup_llh, LLOG_F_IS_PLAIN, NULL);
1061 GOTO(out_close, rc);
1063 if (llog_get_size(backup_llh) <= 1)
1064 GOTO(out_close, rc = 0);
1066 OBD_ALLOC_PTR(mrul);
1068 GOTO(out_close, rc = -ENOMEM);
1069 /* devname is only needed information to replace UUID records */
1070 strncpy(mrul->target.mti_svname, devname, MTI_NAME_MAXLEN);
1071 /* parse nids later */
1072 strncpy(mrul->target.mti_params, nids, MTI_PARAM_MAXLEN);
1073 /* Copy records to this temporary llog */
1074 mrul->temp_llh = orig_llh;
1076 rc = llog_process(env, backup_llh, mgs_replace_handler,
1077 (void *)mrul, NULL);
1080 rc2 = llog_close(NULL, backup_llh);
1084 rc2 = llog_close(NULL, orig_llh);
1090 CERROR("%s: llog should be restored: rc = %d\n",
1092 rc2 = llog_backup(env, mgs, ctxt, ctxt, backup,
1095 CERROR("%s: can't restore backup %s: rc = %d\n",
1096 mgs->obd_name, logname, rc2);
1100 OBD_FREE(backup, strlen(backup) + 1);
1103 llog_ctxt_put(ctxt);
1106 CERROR("%s: failed to replace nids in log %s: rc = %d\n",
1107 mgs->obd_name, logname, rc);
1113 * Parse device name and get file system name and/or device index
1115 * \param[in] devname device name (ex. lustre-MDT0000)
1116 * \param[out] fsname file system name(optional)
1117 * \param[out] index device index(optional)
1121 static int mgs_parse_devname(char *devname, char *fsname, __u32 *index)
1126 /* Extract fsname */
1128 rc = server_name2fsname(devname, fsname, NULL);
1130 CDEBUG(D_MGS, "Device name %s without fsname\n",
1137 rc = server_name2index(devname, index, NULL);
1139 CDEBUG(D_MGS, "Device name %s with wrong index\n",
1148 /* This is only called during replace_nids */
1149 static int only_mgs_is_running(struct obd_device *mgs_obd)
1151 /* TDB: Is global variable with devices count exists? */
1152 int num_devices = get_devices_count();
1153 int num_exports = 0;
1154 struct obd_export *exp;
1156 spin_lock(&mgs_obd->obd_dev_lock);
1157 list_for_each_entry(exp, &mgs_obd->obd_exports, exp_obd_chain) {
1158 /* skip self export */
1159 if (exp == mgs_obd->obd_self_export)
1161 if (exp_connect_flags(exp) & OBD_CONNECT_MDS_MDS)
1166 CERROR("%s: node %s still connected during replace_nids "
1167 "connect_flags:%llx\n",
1169 libcfs_nid2str(exp->exp_nid_stats->nid),
1170 exp_connect_flags(exp));
1173 spin_unlock(&mgs_obd->obd_dev_lock);
1175 /* osd, MGS and MGC + self_export
1176 (wc -l /proc/fs/lustre/devices <= 2) && (non self exports == 0) */
1177 return (num_devices <= 3) && (num_exports == 0);
1180 static int name_create_mdt(char **logname, char *fsname, int i)
1184 sprintf(mdt_index, "-MDT%04x", i);
1185 return name_create(logname, fsname, mdt_index);
1189 * Replace nids for \a device to \a nids values
1191 * \param obd MGS obd device
1192 * \param devname nids need to be replaced for this device
1193 * (ex. lustre-OST0000)
1194 * \param nids nids list (ex. nid1,nid2,nid3)
1198 int mgs_replace_nids(const struct lu_env *env,
1199 struct mgs_device *mgs,
1200 char *devname, char *nids)
1202 /* Assume fsname is part of device name */
1203 char fsname[MTI_NAME_MAXLEN];
1210 struct obd_device *mgs_obd = mgs->mgs_obd;
1213 /* We can only change NIDs if no other nodes are connected */
1214 spin_lock(&mgs_obd->obd_dev_lock);
1215 conn_state = mgs_obd->obd_no_conn;
1216 mgs_obd->obd_no_conn = 1;
1217 spin_unlock(&mgs_obd->obd_dev_lock);
1219 /* We can not change nids if not only MGS is started */
1220 if (!only_mgs_is_running(mgs_obd)) {
1221 CERROR("Only MGS is allowed to be started\n");
1222 GOTO(out, rc = -EINPROGRESS);
1225 /* Get fsname and index*/
1226 rc = mgs_parse_devname(devname, fsname, &index);
1230 rc = mgs_find_or_make_fsdb(env, mgs, fsname, &fsdb);
1232 CERROR("%s: can't find fsdb: rc = %d\n", fsname, rc);
1236 /* Process client llogs */
1237 name_create(&logname, fsname, "-client");
1238 rc = mgs_replace_nids_log(env, mgs_obd, fsdb, logname, devname, nids);
1239 name_destroy(&logname);
1241 CERROR("%s: error while replacing NIDs for %s: rc = %d\n",
1242 fsname, devname, rc);
1246 /* Process MDT llogs */
1247 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
1248 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
1250 name_create_mdt(&logname, fsname, i);
1251 rc = mgs_replace_nids_log(env, mgs_obd, fsdb, logname, devname, nids);
1252 name_destroy(&logname);
1258 spin_lock(&mgs_obd->obd_dev_lock);
1259 mgs_obd->obd_no_conn = conn_state;
1260 spin_unlock(&mgs_obd->obd_dev_lock);
1265 static int record_lov_setup(const struct lu_env *env, struct llog_handle *llh,
1266 char *devname, struct lov_desc *desc)
1268 struct mgs_thread_info *mgi = mgs_env_info(env);
1269 struct llog_cfg_rec *lcr;
1272 lustre_cfg_bufs_reset(&mgi->mgi_bufs, devname);
1273 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, desc, sizeof(*desc));
1274 lcr = lustre_cfg_rec_new(LCFG_SETUP, &mgi->mgi_bufs);
1278 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1279 lustre_cfg_rec_free(lcr);
1283 static int record_lmv_setup(const struct lu_env *env, struct llog_handle *llh,
1284 char *devname, struct lmv_desc *desc)
1286 struct mgs_thread_info *mgi = mgs_env_info(env);
1287 struct llog_cfg_rec *lcr;
1290 lustre_cfg_bufs_reset(&mgi->mgi_bufs, devname);
1291 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, desc, sizeof(*desc));
1292 lcr = lustre_cfg_rec_new(LCFG_SETUP, &mgi->mgi_bufs);
1296 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1297 lustre_cfg_rec_free(lcr);
1301 static inline int record_mdc_add(const struct lu_env *env,
1302 struct llog_handle *llh,
1303 char *logname, char *mdcuuid,
1304 char *mdtuuid, char *index,
1307 return record_base(env,llh,logname,0,LCFG_ADD_MDC,
1308 mdtuuid,index,gen,mdcuuid);
1311 static inline int record_lov_add(const struct lu_env *env,
1312 struct llog_handle *llh,
1313 char *lov_name, char *ost_uuid,
1314 char *index, char *gen)
1316 return record_base(env,llh,lov_name,0,LCFG_LOV_ADD_OBD,
1317 ost_uuid, index, gen, 0);
1320 static inline int record_mount_opt(const struct lu_env *env,
1321 struct llog_handle *llh,
1322 char *profile, char *lov_name,
1325 return record_base(env,llh,NULL,0,LCFG_MOUNTOPT,
1326 profile,lov_name,mdc_name,0);
1329 static int record_marker(const struct lu_env *env,
1330 struct llog_handle *llh,
1331 struct fs_db *fsdb, __u32 flags,
1332 char *tgtname, char *comment)
1334 struct mgs_thread_info *mgi = mgs_env_info(env);
1335 struct llog_cfg_rec *lcr;
1339 if (flags & CM_START)
1341 mgi->mgi_marker.cm_step = fsdb->fsdb_gen;
1342 mgi->mgi_marker.cm_flags = flags;
1343 mgi->mgi_marker.cm_vers = LUSTRE_VERSION_CODE;
1344 cplen = strlcpy(mgi->mgi_marker.cm_tgtname, tgtname,
1345 sizeof(mgi->mgi_marker.cm_tgtname));
1346 if (cplen >= sizeof(mgi->mgi_marker.cm_tgtname))
1348 cplen = strlcpy(mgi->mgi_marker.cm_comment, comment,
1349 sizeof(mgi->mgi_marker.cm_comment));
1350 if (cplen >= sizeof(mgi->mgi_marker.cm_comment))
1352 mgi->mgi_marker.cm_createtime = cfs_time_current_sec();
1353 mgi->mgi_marker.cm_canceltime = 0;
1354 lustre_cfg_bufs_reset(&mgi->mgi_bufs, NULL);
1355 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, &mgi->mgi_marker,
1356 sizeof(mgi->mgi_marker));
1357 lcr = lustre_cfg_rec_new(LCFG_MARKER, &mgi->mgi_bufs);
1361 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1362 lustre_cfg_rec_free(lcr);
1366 static int record_start_log(const struct lu_env *env, struct mgs_device *mgs,
1367 struct llog_handle **llh, char *name)
1369 static struct obd_uuid cfg_uuid = { .uuid = "config_uuid" };
1370 struct llog_ctxt *ctxt;
1375 GOTO(out, rc = -EBUSY);
1377 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
1379 GOTO(out, rc = -ENODEV);
1380 LASSERT(ctxt->loc_obd == mgs->mgs_obd);
1382 rc = llog_open_create(env, ctxt, llh, NULL, name);
1385 rc = llog_init_handle(env, *llh, LLOG_F_IS_PLAIN, &cfg_uuid);
1387 llog_close(env, *llh);
1389 llog_ctxt_put(ctxt);
1392 CERROR("%s: can't start log %s: rc = %d\n",
1393 mgs->mgs_obd->obd_name, name, rc);
1399 static int record_end_log(const struct lu_env *env, struct llog_handle **llh)
1403 rc = llog_close(env, *llh);
1409 /******************** config "macros" *********************/
1411 /* write an lcfg directly into a log (with markers) */
1412 static int mgs_write_log_direct(const struct lu_env *env,
1413 struct mgs_device *mgs, struct fs_db *fsdb,
1414 char *logname, struct llog_cfg_rec *lcr,
1415 char *devname, char *comment)
1417 struct llog_handle *llh = NULL;
1422 rc = record_start_log(env, mgs, &llh, logname);
1426 /* FIXME These should be a single journal transaction */
1427 rc = record_marker(env, llh, fsdb, CM_START, devname, comment);
1430 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1433 rc = record_marker(env, llh, fsdb, CM_END, devname, comment);
1437 record_end_log(env, &llh);
1441 /* write the lcfg in all logs for the given fs */
1442 int mgs_write_log_direct_all(const struct lu_env *env, struct mgs_device *mgs,
1443 struct fs_db *fsdb, struct mgs_target_info *mti,
1444 struct llog_cfg_rec *lcr, char *devname,
1445 char *comment, int server_only)
1447 struct list_head log_list;
1448 struct mgs_direntry *dirent, *n;
1449 char *fsname = mti->mti_fsname;
1451 int rc = 0, len = strlen(fsname);
1454 /* We need to set params for any future logs
1456 * FIXME Append this file to every new log.
1457 * Actually, we should store as params (text), not llogs,
1458 * or in a database. */
1459 rc = name_create(&logname, fsname, "-params");
1462 if (mgs_log_is_empty(env, mgs, logname)) {
1463 struct llog_handle *llh = NULL;
1465 rc = record_start_log(env, mgs, &llh, logname);
1467 record_end_log(env, &llh);
1469 name_destroy(&logname);
1473 /* Find all the logs in the CONFIGS directory */
1474 rc = class_dentry_readdir(env, mgs, &log_list);
1478 /* Could use fsdb index maps instead of directory listing */
1479 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
1480 list_del_init(&dirent->mde_list);
1481 /* don't write to sptlrpc rule log */
1482 if (strstr(dirent->mde_name, "-sptlrpc") != NULL)
1485 /* caller wants write server logs only */
1486 if (server_only && strstr(dirent->mde_name, "-client") != NULL)
1489 if (strncmp(fsname, dirent->mde_name, len) != 0)
1492 CDEBUG(D_MGS, "Changing log %s\n", dirent->mde_name);
1493 /* Erase any old settings of this same parameter */
1494 rc = mgs_modify(env, mgs, fsdb, mti, dirent->mde_name,
1495 devname, comment, CM_SKIP);
1497 CERROR("%s: Can't modify llog %s: rc = %d\n",
1498 mgs->mgs_obd->obd_name, dirent->mde_name, rc);
1501 /* Write the new one */
1502 rc = mgs_write_log_direct(env, mgs, fsdb, dirent->mde_name,
1503 lcr, devname, comment);
1505 CERROR("%s: writing log %s: rc = %d\n",
1506 mgs->mgs_obd->obd_name, dirent->mde_name, rc);
1508 mgs_direntry_free(dirent);
1514 static int mgs_write_log_osp_to_mdt(const struct lu_env *env,
1515 struct mgs_device *mgs,
1517 struct mgs_target_info *mti,
1518 int index, char *logname);
1519 static int mgs_write_log_osc_to_lov(const struct lu_env *env,
1520 struct mgs_device *mgs,
1522 struct mgs_target_info *mti,
1523 char *logname, char *suffix, char *lovname,
1524 enum lustre_sec_part sec_part, int flags);
1525 static int name_create_mdt_and_lov(char **logname, char **lovname,
1526 struct fs_db *fsdb, int i);
1528 static int add_param(char *params, char *key, char *val)
1530 char *start = params + strlen(params);
1531 char *end = params + sizeof(((struct mgs_target_info *)0)->mti_params);
1535 keylen = strlen(key);
1536 if (start + 1 + keylen + strlen(val) >= end) {
1537 CERROR("params are too long: %s %s%s\n",
1538 params, key != NULL ? key : "", val);
1542 sprintf(start, " %s%s", key != NULL ? key : "", val);
1547 * Walk through client config log record and convert the related records
1550 static int mgs_steal_client_llog_handler(const struct lu_env *env,
1551 struct llog_handle *llh,
1552 struct llog_rec_hdr *rec, void *data)
1554 struct mgs_device *mgs;
1555 struct obd_device *obd;
1556 struct mgs_target_info *mti, *tmti;
1558 int cfg_len = rec->lrh_len;
1559 char *cfg_buf = (char*) (rec + 1);
1560 struct lustre_cfg *lcfg;
1562 struct llog_handle *mdt_llh = NULL;
1563 static int got_an_osc_or_mdc = 0;
1564 /* 0: not found any osc/mdc;
1568 static int last_step = -1;
1573 mti = ((struct temp_comp*)data)->comp_mti;
1574 tmti = ((struct temp_comp*)data)->comp_tmti;
1575 fsdb = ((struct temp_comp*)data)->comp_fsdb;
1576 obd = ((struct temp_comp *)data)->comp_obd;
1577 mgs = lu2mgs_dev(obd->obd_lu_dev);
1580 if (rec->lrh_type != OBD_CFG_REC) {
1581 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
1585 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
1587 CERROR("Insane cfg\n");
1591 lcfg = (struct lustre_cfg *)cfg_buf;
1593 if (lcfg->lcfg_command == LCFG_MARKER) {
1594 struct cfg_marker *marker;
1595 marker = lustre_cfg_buf(lcfg, 1);
1596 if (!strncmp(marker->cm_comment, "add osc", 7) &&
1597 (marker->cm_flags & CM_START) &&
1598 !(marker->cm_flags & CM_SKIP)) {
1599 got_an_osc_or_mdc = 1;
1600 cplen = strlcpy(tmti->mti_svname, marker->cm_tgtname,
1601 sizeof(tmti->mti_svname));
1602 if (cplen >= sizeof(tmti->mti_svname))
1604 rc = record_start_log(env, mgs, &mdt_llh,
1608 rc = record_marker(env, mdt_llh, fsdb, CM_START,
1609 mti->mti_svname, "add osc(copied)");
1610 record_end_log(env, &mdt_llh);
1611 last_step = marker->cm_step;
1614 if (!strncmp(marker->cm_comment, "add osc", 7) &&
1615 (marker->cm_flags & CM_END) &&
1616 !(marker->cm_flags & CM_SKIP)) {
1617 LASSERT(last_step == marker->cm_step);
1619 got_an_osc_or_mdc = 0;
1620 memset(tmti, 0, sizeof(*tmti));
1621 rc = record_start_log(env, mgs, &mdt_llh,
1625 rc = record_marker(env, mdt_llh, fsdb, CM_END,
1626 mti->mti_svname, "add osc(copied)");
1627 record_end_log(env, &mdt_llh);
1630 if (!strncmp(marker->cm_comment, "add mdc", 7) &&
1631 (marker->cm_flags & CM_START) &&
1632 !(marker->cm_flags & CM_SKIP)) {
1633 got_an_osc_or_mdc = 2;
1634 last_step = marker->cm_step;
1635 memcpy(tmti->mti_svname, marker->cm_tgtname,
1636 strlen(marker->cm_tgtname));
1640 if (!strncmp(marker->cm_comment, "add mdc", 7) &&
1641 (marker->cm_flags & CM_END) &&
1642 !(marker->cm_flags & CM_SKIP)) {
1643 LASSERT(last_step == marker->cm_step);
1645 got_an_osc_or_mdc = 0;
1646 memset(tmti, 0, sizeof(*tmti));
1651 if (got_an_osc_or_mdc == 0 || last_step < 0)
1654 if (lcfg->lcfg_command == LCFG_ADD_UUID) {
1655 uint64_t nodenid = lcfg->lcfg_nid;
1657 if (strlen(tmti->mti_uuid) == 0) {
1658 /* target uuid not set, this config record is before
1659 * LCFG_SETUP, this nid is one of target node nid.
1661 tmti->mti_nids[tmti->mti_nid_count] = nodenid;
1662 tmti->mti_nid_count++;
1664 /* failover node nid */
1665 rc = add_param(tmti->mti_params, PARAM_FAILNODE,
1666 libcfs_nid2str(nodenid));
1672 if (lcfg->lcfg_command == LCFG_SETUP) {
1675 target = lustre_cfg_string(lcfg, 1);
1676 memcpy(tmti->mti_uuid, target, strlen(target));
1680 /* ignore client side sptlrpc_conf_log */
1681 if (lcfg->lcfg_command == LCFG_SPTLRPC_CONF)
1684 if (lcfg->lcfg_command == LCFG_ADD_MDC) {
1687 if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1)
1690 memcpy(tmti->mti_fsname, mti->mti_fsname,
1691 strlen(mti->mti_fsname));
1692 tmti->mti_stripe_index = index;
1694 rc = mgs_write_log_osp_to_mdt(env, mgs, fsdb, tmti,
1695 mti->mti_stripe_index,
1697 memset(tmti, 0, sizeof(*tmti));
1701 if (lcfg->lcfg_command == LCFG_LOV_ADD_OBD) {
1704 char *logname, *lovname;
1706 rc = name_create_mdt_and_lov(&logname, &lovname, fsdb,
1707 mti->mti_stripe_index);
1710 sprintf(mdt_index, "-MDT%04x", mti->mti_stripe_index);
1712 if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1) {
1713 name_destroy(&logname);
1714 name_destroy(&lovname);
1718 tmti->mti_stripe_index = index;
1719 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, tmti, logname,
1722 name_destroy(&logname);
1723 name_destroy(&lovname);
1729 /* fsdb->fsdb_mutex is already held in mgs_write_log_target*/
1730 /* stealed from mgs_get_fsdb_from_llog*/
1731 static int mgs_steal_llog_for_mdt_from_client(const struct lu_env *env,
1732 struct mgs_device *mgs,
1734 struct temp_comp* comp)
1736 struct llog_handle *loghandle;
1737 struct mgs_target_info *tmti;
1738 struct llog_ctxt *ctxt;
1743 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
1744 LASSERT(ctxt != NULL);
1746 OBD_ALLOC_PTR(tmti);
1748 GOTO(out_ctxt, rc = -ENOMEM);
1750 comp->comp_tmti = tmti;
1751 comp->comp_obd = mgs->mgs_obd;
1753 rc = llog_open(env, ctxt, &loghandle, NULL, client_name,
1761 rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL);
1763 GOTO(out_close, rc);
1765 rc = llog_process_or_fork(env, loghandle, mgs_steal_client_llog_handler,
1766 (void *)comp, NULL, false);
1767 CDEBUG(D_MGS, "steal llog re = %d\n", rc);
1769 llog_close(env, loghandle);
1773 llog_ctxt_put(ctxt);
1777 /* lmv is the second thing for client logs */
1778 /* copied from mgs_write_log_lov. Please refer to that. */
1779 static int mgs_write_log_lmv(const struct lu_env *env,
1780 struct mgs_device *mgs,
1782 struct mgs_target_info *mti,
1783 char *logname, char *lmvname)
1785 struct llog_handle *llh = NULL;
1786 struct lmv_desc *lmvdesc;
1791 CDEBUG(D_MGS, "Writing lmv(%s) log for %s\n", lmvname,logname);
1793 OBD_ALLOC_PTR(lmvdesc);
1794 if (lmvdesc == NULL)
1796 lmvdesc->ld_active_tgt_count = 0;
1797 lmvdesc->ld_tgt_count = 0;
1798 sprintf((char*)lmvdesc->ld_uuid.uuid, "%s_UUID", lmvname);
1799 uuid = (char *)lmvdesc->ld_uuid.uuid;
1801 rc = record_start_log(env, mgs, &llh, logname);
1804 rc = record_marker(env, llh, fsdb, CM_START, lmvname, "lmv setup");
1807 rc = record_attach(env, llh, lmvname, "lmv", uuid);
1810 rc = record_lmv_setup(env, llh, lmvname, lmvdesc);
1813 rc = record_marker(env, llh, fsdb, CM_END, lmvname, "lmv setup");
1817 record_end_log(env, &llh);
1819 OBD_FREE_PTR(lmvdesc);
1823 /* lov is the first thing in the mdt and client logs */
1824 static int mgs_write_log_lov(const struct lu_env *env, struct mgs_device *mgs,
1825 struct fs_db *fsdb, struct mgs_target_info *mti,
1826 char *logname, char *lovname)
1828 struct llog_handle *llh = NULL;
1829 struct lov_desc *lovdesc;
1834 CDEBUG(D_MGS, "Writing lov(%s) log for %s\n", lovname, logname);
1837 #01 L attach 0:lov_mdsA 1:lov 2:71ccb_lov_mdsA_19f961a9e1
1838 #02 L lov_setup 0:lov_mdsA 1:(struct lov_desc)
1839 uuid=lov1_UUID, stripe count=1, size=1048576, offset=0, pattern=0
1842 /* FIXME just make lov_setup accept empty desc (put uuid in buf 2) */
1843 OBD_ALLOC_PTR(lovdesc);
1844 if (lovdesc == NULL)
1846 lovdesc->ld_magic = LOV_DESC_MAGIC;
1847 lovdesc->ld_tgt_count = 0;
1848 /* Defaults. Can be changed later by lcfg config_param */
1849 lovdesc->ld_default_stripe_count = 1;
1850 lovdesc->ld_pattern = LOV_PATTERN_RAID0;
1851 lovdesc->ld_default_stripe_size = LOV_DESC_STRIPE_SIZE_DEFAULT;
1852 lovdesc->ld_default_stripe_offset = -1;
1853 lovdesc->ld_qos_maxage = LOV_DESC_QOS_MAXAGE_DEFAULT;
1854 sprintf((char*)lovdesc->ld_uuid.uuid, "%s_UUID", lovname);
1855 /* can these be the same? */
1856 uuid = (char *)lovdesc->ld_uuid.uuid;
1858 /* This should always be the first entry in a log.
1859 rc = mgs_clear_log(obd, logname); */
1860 rc = record_start_log(env, mgs, &llh, logname);
1863 /* FIXME these should be a single journal transaction */
1864 rc = record_marker(env, llh, fsdb, CM_START, lovname, "lov setup");
1867 rc = record_attach(env, llh, lovname, "lov", uuid);
1870 rc = record_lov_setup(env, llh, lovname, lovdesc);
1873 rc = record_marker(env, llh, fsdb, CM_END, lovname, "lov setup");
1878 record_end_log(env, &llh);
1880 OBD_FREE_PTR(lovdesc);
1884 /* add failnids to open log */
1885 static int mgs_write_log_failnids(const struct lu_env *env,
1886 struct mgs_target_info *mti,
1887 struct llog_handle *llh,
1890 char *failnodeuuid = NULL;
1891 char *ptr = mti->mti_params;
1896 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) nal=90 0: 1:uml1_UUID
1897 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
1898 #05 L setup 0:OSC_uml1_ost1_mdsA 1:ost1_UUID 2:uml1_UUID
1899 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) nal=90 0: 1:uml2_UUID
1900 #0x L add_uuid nid=2@elan(0x1000000000002) nal=90 0: 1:uml2_UUID
1901 #07 L add_conn 0:OSC_uml1_ost1_mdsA 1:uml2_UUID
1904 /* Pull failnid info out of params string */
1905 while (class_find_param(ptr, PARAM_FAILNODE, &ptr) == 0) {
1906 while (class_parse_nid(ptr, &nid, &ptr) == 0) {
1907 if (failnodeuuid == NULL) {
1908 /* We don't know the failover node name,
1909 so just use the first nid as the uuid */
1910 rc = name_create(&failnodeuuid,
1911 libcfs_nid2str(nid), "");
1915 CDEBUG(D_MGS, "add nid %s for failover uuid %s, "
1916 "client %s\n", libcfs_nid2str(nid),
1917 failnodeuuid, cliname);
1918 rc = record_add_uuid(env, llh, nid, failnodeuuid);
1921 rc = record_add_conn(env, llh, cliname, failnodeuuid);
1922 name_destroy(&failnodeuuid);
1923 failnodeuuid = NULL;
1930 static int mgs_write_log_mdc_to_lmv(const struct lu_env *env,
1931 struct mgs_device *mgs,
1933 struct mgs_target_info *mti,
1934 char *logname, char *lmvname)
1936 struct llog_handle *llh = NULL;
1937 char *mdcname = NULL;
1938 char *nodeuuid = NULL;
1939 char *mdcuuid = NULL;
1940 char *lmvuuid = NULL;
1945 if (mgs_log_is_empty(env, mgs, logname)) {
1946 CERROR("log is empty! Logical error\n");
1950 CDEBUG(D_MGS, "adding mdc for %s to log %s:lmv(%s)\n",
1951 mti->mti_svname, logname, lmvname);
1953 rc = name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
1956 rc = name_create(&mdcname, mti->mti_svname, "-mdc");
1959 rc = name_create(&mdcuuid, mdcname, "_UUID");
1962 rc = name_create(&lmvuuid, lmvname, "_UUID");
1966 rc = record_start_log(env, mgs, &llh, logname);
1969 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
1973 for (i = 0; i < mti->mti_nid_count; i++) {
1974 CDEBUG(D_MGS, "add nid %s for mdt\n",
1975 libcfs_nid2str(mti->mti_nids[i]));
1977 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
1982 rc = record_attach(env, llh, mdcname, LUSTRE_MDC_NAME, lmvuuid);
1985 rc = record_setup(env, llh, mdcname, mti->mti_uuid, nodeuuid, 0, 0);
1988 rc = mgs_write_log_failnids(env, mti, llh, mdcname);
1991 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
1992 rc = record_mdc_add(env, llh, lmvname, mdcuuid, mti->mti_uuid,
1996 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname,
2001 record_end_log(env, &llh);
2003 name_destroy(&lmvuuid);
2004 name_destroy(&mdcuuid);
2005 name_destroy(&mdcname);
2006 name_destroy(&nodeuuid);
2010 static inline int name_create_lov(char **lovname, char *mdtname,
2011 struct fs_db *fsdb, int index)
2014 if (index == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2015 return name_create(lovname, fsdb->fsdb_name, "-mdtlov");
2017 return name_create(lovname, mdtname, "-mdtlov");
2020 static int name_create_mdt_and_lov(char **logname, char **lovname,
2021 struct fs_db *fsdb, int i)
2025 rc = name_create_mdt(logname, fsdb->fsdb_name, i);
2029 if (i == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2030 rc = name_create(lovname, fsdb->fsdb_name, "-mdtlov");
2032 rc = name_create(lovname, *logname, "-mdtlov");
2034 name_destroy(logname);
2040 static inline int name_create_mdt_osc(char **oscname, char *ostname,
2041 struct fs_db *fsdb, int i)
2045 if (i == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2046 sprintf(suffix, "-osc");
2048 sprintf(suffix, "-osc-MDT%04x", i);
2049 return name_create(oscname, ostname, suffix);
2052 /* add new mdc to already existent MDS */
2053 static int mgs_write_log_osp_to_mdt(const struct lu_env *env,
2054 struct mgs_device *mgs,
2056 struct mgs_target_info *mti,
2057 int mdt_index, char *logname)
2059 struct llog_handle *llh = NULL;
2060 char *nodeuuid = NULL;
2061 char *ospname = NULL;
2062 char *lovuuid = NULL;
2063 char *mdtuuid = NULL;
2064 char *svname = NULL;
2065 char *mdtname = NULL;
2066 char *lovname = NULL;
2071 if (mgs_log_is_empty(env, mgs, mti->mti_svname)) {
2072 CERROR("log is empty! Logical error\n");
2076 CDEBUG(D_MGS, "adding osp index %d to %s\n", mti->mti_stripe_index,
2079 rc = name_create_mdt(&mdtname, fsdb->fsdb_name, mti->mti_stripe_index);
2083 rc = name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
2085 GOTO(out_destory, rc);
2087 rc = name_create(&svname, mdtname, "-osp");
2089 GOTO(out_destory, rc);
2091 sprintf(index_str, "-MDT%04x", mdt_index);
2092 rc = name_create(&ospname, svname, index_str);
2094 GOTO(out_destory, rc);
2096 rc = name_create_lov(&lovname, logname, fsdb, mdt_index);
2098 GOTO(out_destory, rc);
2100 rc = name_create(&lovuuid, lovname, "_UUID");
2102 GOTO(out_destory, rc);
2104 rc = name_create(&mdtuuid, mdtname, "_UUID");
2106 GOTO(out_destory, rc);
2108 rc = record_start_log(env, mgs, &llh, logname);
2110 GOTO(out_destory, rc);
2112 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
2115 GOTO(out_destory, rc);
2117 for (i = 0; i < mti->mti_nid_count; i++) {
2118 CDEBUG(D_MGS, "add nid %s for mdt\n",
2119 libcfs_nid2str(mti->mti_nids[i]));
2120 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
2125 rc = record_attach(env, llh, ospname, LUSTRE_OSP_NAME, lovuuid);
2129 rc = record_setup(env, llh, ospname, mti->mti_uuid, nodeuuid,
2134 rc = mgs_write_log_failnids(env, mti, llh, ospname);
2138 /* Add mdc(osp) to lod */
2139 snprintf(index_str, sizeof(mti->mti_stripe_index), "%d",
2140 mti->mti_stripe_index);
2141 rc = record_base(env, llh, lovname, 0, LCFG_ADD_MDC, mti->mti_uuid,
2142 index_str, "1", NULL);
2146 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname, "add osp");
2151 record_end_log(env, &llh);
2154 name_destroy(&mdtuuid);
2155 name_destroy(&lovuuid);
2156 name_destroy(&lovname);
2157 name_destroy(&ospname);
2158 name_destroy(&svname);
2159 name_destroy(&nodeuuid);
2160 name_destroy(&mdtname);
2164 static int mgs_write_log_mdt0(const struct lu_env *env,
2165 struct mgs_device *mgs,
2167 struct mgs_target_info *mti)
2169 char *log = mti->mti_svname;
2170 struct llog_handle *llh = NULL;
2171 char *uuid, *lovname;
2173 char *ptr = mti->mti_params;
2174 int rc = 0, failout = 0;
2177 OBD_ALLOC(uuid, sizeof(struct obd_uuid));
2181 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
2182 failout = (strncmp(ptr, "failout", 7) == 0);
2184 rc = name_create(&lovname, log, "-mdtlov");
2187 if (mgs_log_is_empty(env, mgs, log)) {
2188 rc = mgs_write_log_lov(env, mgs, fsdb, mti, log, lovname);
2193 sprintf(mdt_index, "%d", mti->mti_stripe_index);
2195 rc = record_start_log(env, mgs, &llh, log);
2199 /* add MDT itself */
2201 /* FIXME this whole fn should be a single journal transaction */
2202 sprintf(uuid, "%s_UUID", log);
2203 rc = record_marker(env, llh, fsdb, CM_START, log, "add mdt");
2206 rc = record_attach(env, llh, log, LUSTRE_MDT_NAME, uuid);
2209 rc = record_mount_opt(env, llh, log, lovname, NULL);
2212 rc = record_setup(env, llh, log, uuid, mdt_index, lovname,
2213 failout ? "n" : "f");
2216 rc = record_marker(env, llh, fsdb, CM_END, log, "add mdt");
2220 record_end_log(env, &llh);
2222 name_destroy(&lovname);
2224 OBD_FREE(uuid, sizeof(struct obd_uuid));
2228 /* envelope method for all layers log */
2229 static int mgs_write_log_mdt(const struct lu_env *env,
2230 struct mgs_device *mgs,
2232 struct mgs_target_info *mti)
2234 struct mgs_thread_info *mgi = mgs_env_info(env);
2235 struct llog_handle *llh = NULL;
2240 CDEBUG(D_MGS, "writing new mdt %s\n", mti->mti_svname);
2242 if (mti->mti_uuid[0] == '\0') {
2243 /* Make up our own uuid */
2244 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
2245 "%s_UUID", mti->mti_svname);
2249 rc = mgs_write_log_mdt0(env, mgs, fsdb, mti);
2252 /* Append the mdt info to the client log */
2253 rc = name_create(&cliname, mti->mti_fsname, "-client");
2257 if (mgs_log_is_empty(env, mgs, cliname)) {
2258 /* Start client log */
2259 rc = mgs_write_log_lov(env, mgs, fsdb, mti, cliname,
2263 rc = mgs_write_log_lmv(env, mgs, fsdb, mti, cliname,
2270 #09 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
2271 #10 L attach 0:MDC_uml1_mdsA_MNT_client 1:mdc 2:1d834_MNT_client_03f
2272 #11 L setup 0:MDC_uml1_mdsA_MNT_client 1:mdsA_UUID 2:uml1_UUID
2273 #12 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
2274 #13 L add_conn 0:MDC_uml1_mdsA_MNT_client 1:uml2_UUID
2275 #14 L mount_option 0: 1:client 2:lov1 3:MDC_uml1_mdsA_MNT_client
2278 /* copy client info about lov/lmv */
2279 mgi->mgi_comp.comp_mti = mti;
2280 mgi->mgi_comp.comp_fsdb = fsdb;
2282 rc = mgs_steal_llog_for_mdt_from_client(env, mgs, cliname,
2286 rc = mgs_write_log_mdc_to_lmv(env, mgs, fsdb, mti, cliname,
2292 rc = record_start_log(env, mgs, &llh, cliname);
2296 rc = record_marker(env, llh, fsdb, CM_START, cliname,
2300 rc = record_mount_opt(env, llh, cliname, fsdb->fsdb_clilov,
2304 rc = record_marker(env, llh, fsdb, CM_END, cliname,
2310 /* for_all_existing_mdt except current one */
2311 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2312 if (i != mti->mti_stripe_index &&
2313 test_bit(i, fsdb->fsdb_mdt_index_map)) {
2316 rc = name_create_mdt(&logname, fsdb->fsdb_name, i);
2320 rc = mgs_write_log_osp_to_mdt(env, mgs, fsdb, mti,
2322 name_destroy(&logname);
2328 record_end_log(env, &llh);
2330 name_destroy(&cliname);
2334 /* Add the ost info to the client/mdt lov */
2335 static int mgs_write_log_osc_to_lov(const struct lu_env *env,
2336 struct mgs_device *mgs, struct fs_db *fsdb,
2337 struct mgs_target_info *mti,
2338 char *logname, char *suffix, char *lovname,
2339 enum lustre_sec_part sec_part, int flags)
2341 struct llog_handle *llh = NULL;
2342 char *nodeuuid = NULL;
2343 char *oscname = NULL;
2344 char *oscuuid = NULL;
2345 char *lovuuid = NULL;
2346 char *svname = NULL;
2351 CDEBUG(D_INFO, "adding osc for %s to log %s\n",
2352 mti->mti_svname, logname);
2354 if (mgs_log_is_empty(env, mgs, logname)) {
2355 CERROR("log is empty! Logical error\n");
2359 rc = name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
2362 rc = name_create(&svname, mti->mti_svname, "-osc");
2366 /* for the system upgraded from old 1.8, keep using the old osc naming
2367 * style for mdt, see name_create_mdt_osc(). LU-1257 */
2368 if (test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2369 rc = name_create(&oscname, svname, "");
2371 rc = name_create(&oscname, svname, suffix);
2375 rc = name_create(&oscuuid, oscname, "_UUID");
2378 rc = name_create(&lovuuid, lovname, "_UUID");
2384 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
2386 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
2387 #04 L attach 0:OSC_uml1_ost1_MNT_client 1:osc 2:89070_lov1_a41dff51a
2388 #05 L setup 0:OSC_uml1_ost1_MNT_client 1:ost1_UUID 2:uml1_UUID
2390 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
2391 #07 L add_conn 0:OSC_uml1_ost1_MNT_client 1:uml2_UUID
2392 #08 L lov_modify_tgts add 0:lov1 1:ost1_UUID 2(index):0 3(gen):1
2395 rc = record_start_log(env, mgs, &llh, logname);
2399 /* FIXME these should be a single journal transaction */
2400 rc = record_marker(env, llh, fsdb, CM_START | flags, mti->mti_svname,
2405 /* NB: don't change record order, because upon MDT steal OSC config
2406 * from client, it treats all nids before LCFG_SETUP as target nids
2407 * (multiple interfaces), while nids after as failover node nids.
2408 * See mgs_steal_client_llog_handler() LCFG_ADD_UUID.
2410 for (i = 0; i < mti->mti_nid_count; i++) {
2411 CDEBUG(D_MGS, "add nid %s\n", libcfs_nid2str(mti->mti_nids[i]));
2412 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
2416 rc = record_attach(env, llh, oscname, LUSTRE_OSC_NAME, lovuuid);
2419 rc = record_setup(env, llh, oscname, mti->mti_uuid, nodeuuid, 0, 0);
2422 rc = mgs_write_log_failnids(env, mti, llh, oscname);
2426 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
2428 rc = record_lov_add(env, llh, lovname, mti->mti_uuid, index, "1");
2431 rc = record_marker(env, llh, fsdb, CM_END | flags, mti->mti_svname,
2436 record_end_log(env, &llh);
2438 name_destroy(&lovuuid);
2439 name_destroy(&oscuuid);
2440 name_destroy(&oscname);
2441 name_destroy(&svname);
2442 name_destroy(&nodeuuid);
2446 static int mgs_write_log_ost(const struct lu_env *env,
2447 struct mgs_device *mgs, struct fs_db *fsdb,
2448 struct mgs_target_info *mti)
2450 struct llog_handle *llh = NULL;
2451 char *logname, *lovname;
2452 char *ptr = mti->mti_params;
2453 int rc, flags = 0, failout = 0, i;
2456 CDEBUG(D_MGS, "writing new ost %s\n", mti->mti_svname);
2458 /* The ost startup log */
2460 /* If the ost log already exists, that means that someone reformatted
2461 the ost and it called target_add again. */
2462 if (!mgs_log_is_empty(env, mgs, mti->mti_svname)) {
2463 LCONSOLE_ERROR_MSG(0x141, "The config log for %s already "
2464 "exists, yet the server claims it never "
2465 "registered. It may have been reformatted, "
2466 "or the index changed. writeconf the MDT to "
2467 "regenerate all logs.\n", mti->mti_svname);
2472 attach obdfilter ost1 ost1_UUID
2473 setup /dev/loop2 ldiskfs f|n errors=remount-ro,user_xattr
2475 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
2476 failout = (strncmp(ptr, "failout", 7) == 0);
2477 rc = record_start_log(env, mgs, &llh, mti->mti_svname);
2480 /* FIXME these should be a single journal transaction */
2481 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,"add ost");
2484 if (*mti->mti_uuid == '\0')
2485 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
2486 "%s_UUID", mti->mti_svname);
2487 rc = record_attach(env, llh, mti->mti_svname,
2488 "obdfilter"/*LUSTRE_OST_NAME*/, mti->mti_uuid);
2491 rc = record_setup(env, llh, mti->mti_svname,
2492 "dev"/*ignored*/, "type"/*ignored*/,
2493 failout ? "n" : "f", 0/*options*/);
2496 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname, "add ost");
2500 record_end_log(env, &llh);
2503 /* We also have to update the other logs where this osc is part of
2506 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
2507 /* If we're upgrading, the old mdt log already has our
2508 entry. Let's do a fake one for fun. */
2509 /* Note that we can't add any new failnids, since we don't
2510 know the old osc names. */
2511 flags = CM_SKIP | CM_UPGRADE146;
2513 } else if ((mti->mti_flags & LDD_F_UPDATE) != LDD_F_UPDATE) {
2514 /* If the update flag isn't set, don't update client/mdt
2517 LCONSOLE_WARN("Client log for %s was not updated; writeconf "
2518 "the MDT first to regenerate it.\n",
2522 /* Add ost to all MDT lov defs */
2523 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
2524 if (test_bit(i, fsdb->fsdb_mdt_index_map)) {
2527 rc = name_create_mdt_and_lov(&logname, &lovname, fsdb,
2531 sprintf(mdt_index, "-MDT%04x", i);
2532 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, mti,
2534 lovname, LUSTRE_SP_MDT,
2536 name_destroy(&logname);
2537 name_destroy(&lovname);
2543 /* Append ost info to the client log */
2544 rc = name_create(&logname, mti->mti_fsname, "-client");
2547 if (mgs_log_is_empty(env, mgs, logname)) {
2548 /* Start client log */
2549 rc = mgs_write_log_lov(env, mgs, fsdb, mti, logname,
2553 rc = mgs_write_log_lmv(env, mgs, fsdb, mti, logname,
2558 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, mti, logname, "",
2559 fsdb->fsdb_clilov, LUSTRE_SP_CLI, 0);
2561 name_destroy(&logname);
2565 static __inline__ int mgs_param_empty(char *ptr)
2569 if ((tmp = strchr(ptr, '=')) && (*(++tmp) == '\0'))
2574 static int mgs_write_log_failnid_internal(const struct lu_env *env,
2575 struct mgs_device *mgs,
2577 struct mgs_target_info *mti,
2578 char *logname, char *cliname)
2581 struct llog_handle *llh = NULL;
2583 if (mgs_param_empty(mti->mti_params)) {
2584 /* Remove _all_ failnids */
2585 rc = mgs_modify(env, mgs, fsdb, mti, logname,
2586 mti->mti_svname, "add failnid", CM_SKIP);
2587 return rc < 0 ? rc : 0;
2590 /* Otherwise failover nids are additive */
2591 rc = record_start_log(env, mgs, &llh, logname);
2594 /* FIXME this should be a single journal transaction */
2595 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
2599 rc = mgs_write_log_failnids(env, mti, llh, cliname);
2602 rc = record_marker(env, llh, fsdb, CM_END,
2603 mti->mti_svname, "add failnid");
2605 record_end_log(env, &llh);
2610 /* Add additional failnids to an existing log.
2611 The mdc/osc must have been added to logs first */
2612 /* tcp nids must be in dotted-quad ascii -
2613 we can't resolve hostnames from the kernel. */
2614 static int mgs_write_log_add_failnid(const struct lu_env *env,
2615 struct mgs_device *mgs,
2617 struct mgs_target_info *mti)
2619 char *logname, *cliname;
2623 /* FIXME we currently can't erase the failnids
2624 * given when a target first registers, since they aren't part of
2625 * an "add uuid" stanza */
2627 /* Verify that we know about this target */
2628 if (mgs_log_is_empty(env, mgs, mti->mti_svname)) {
2629 LCONSOLE_ERROR_MSG(0x142, "The target %s has not registered "
2630 "yet. It must be started before failnids "
2631 "can be added.\n", mti->mti_svname);
2635 /* Create mdc/osc client name (e.g. lustre-OST0001-osc) */
2636 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
2637 rc = name_create(&cliname, mti->mti_svname, "-mdc");
2638 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2639 rc = name_create(&cliname, mti->mti_svname, "-osc");
2645 /* Add failover nids to the client log */
2646 rc = name_create(&logname, mti->mti_fsname, "-client");
2648 name_destroy(&cliname);
2651 rc = mgs_write_log_failnid_internal(env, mgs, fsdb,mti,logname,cliname);
2652 name_destroy(&logname);
2653 name_destroy(&cliname);
2657 if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2658 /* Add OST failover nids to the MDT logs as well */
2661 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2662 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
2664 rc = name_create_mdt(&logname, mti->mti_fsname, i);
2667 rc = name_create_mdt_osc(&cliname, mti->mti_svname,
2670 name_destroy(&logname);
2673 rc = mgs_write_log_failnid_internal(env, mgs, fsdb,
2676 name_destroy(&cliname);
2677 name_destroy(&logname);
2686 static int mgs_wlp_lcfg(const struct lu_env *env,
2687 struct mgs_device *mgs, struct fs_db *fsdb,
2688 struct mgs_target_info *mti,
2689 char *logname, struct lustre_cfg_bufs *bufs,
2690 char *tgtname, char *ptr)
2692 char comment[MTI_NAME_MAXLEN];
2694 struct llog_cfg_rec *lcr;
2697 /* Erase any old settings of this same parameter */
2698 memcpy(comment, ptr, MTI_NAME_MAXLEN);
2699 comment[MTI_NAME_MAXLEN - 1] = 0;
2700 /* But don't try to match the value. */
2701 tmp = strchr(comment, '=');
2704 /* FIXME we should skip settings that are the same as old values */
2705 rc = mgs_modify(env, mgs, fsdb, mti, logname, tgtname, comment,CM_SKIP);
2708 del = mgs_param_empty(ptr);
2710 LCONSOLE_INFO("%s parameter %s.%s in log %s\n", del ? "Disabling" : rc ?
2711 "Setting" : "Modifying", tgtname, comment, logname);
2713 /* mgs_modify() will return 1 if nothing had to be done */
2719 lustre_cfg_bufs_reset(bufs, tgtname);
2720 lustre_cfg_bufs_set_string(bufs, 1, ptr);
2721 if (mti->mti_flags & LDD_F_PARAM2)
2722 lustre_cfg_bufs_set_string(bufs, 2, LCTL_UPCALL);
2724 lcr = lustre_cfg_rec_new((mti->mti_flags & LDD_F_PARAM2) ?
2725 LCFG_SET_PARAM : LCFG_PARAM, bufs);
2729 rc = mgs_write_log_direct(env, mgs, fsdb, logname, lcr, tgtname,
2731 lustre_cfg_rec_free(lcr);
2735 static int mgs_write_log_param2(const struct lu_env *env,
2736 struct mgs_device *mgs,
2738 struct mgs_target_info *mti, char *ptr)
2740 struct lustre_cfg_bufs bufs;
2744 CDEBUG(D_MGS, "next param '%s'\n", ptr);
2745 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, PARAMS_FILENAME, &bufs,
2746 mti->mti_svname, ptr);
2751 /* write global variable settings into log */
2752 static int mgs_write_log_sys(const struct lu_env *env,
2753 struct mgs_device *mgs, struct fs_db *fsdb,
2754 struct mgs_target_info *mti, char *sys, char *ptr)
2756 struct mgs_thread_info *mgi = mgs_env_info(env);
2757 struct lustre_cfg *lcfg;
2758 struct llog_cfg_rec *lcr;
2760 int rc, cmd, convert = 1;
2762 if (class_match_param(ptr, PARAM_TIMEOUT, &tmp) == 0) {
2763 cmd = LCFG_SET_TIMEOUT;
2764 } else if (class_match_param(ptr, PARAM_LDLM_TIMEOUT, &tmp) == 0) {
2765 cmd = LCFG_SET_LDLM_TIMEOUT;
2766 /* Check for known params here so we can return error to lctl */
2767 } else if ((class_match_param(ptr, PARAM_AT_MIN, &tmp) == 0) ||
2768 (class_match_param(ptr, PARAM_AT_MAX, &tmp) == 0) ||
2769 (class_match_param(ptr, PARAM_AT_EXTRA, &tmp) == 0) ||
2770 (class_match_param(ptr, PARAM_AT_EARLY_MARGIN, &tmp) == 0) ||
2771 (class_match_param(ptr, PARAM_AT_HISTORY, &tmp) == 0)) {
2773 } else if (class_match_param(ptr, PARAM_JOBID_VAR, &tmp) == 0) {
2774 convert = 0; /* Don't convert string value to integer */
2780 if (mgs_param_empty(ptr))
2781 CDEBUG(D_MGS, "global '%s' removed\n", sys);
2783 CDEBUG(D_MGS, "global '%s' val=%s\n", sys, tmp);
2785 lustre_cfg_bufs_reset(&mgi->mgi_bufs, NULL);
2786 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, sys);
2787 if (!convert && *tmp != '\0')
2788 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 2, tmp);
2789 lcr = lustre_cfg_rec_new(cmd, &mgi->mgi_bufs);
2793 lcfg = &lcr->lcr_cfg;
2794 lcfg->lcfg_num = convert ? simple_strtoul(tmp, NULL, 0) : 0;
2795 /* truncate the comment to the parameter name */
2799 /* modify all servers and clients */
2800 rc = mgs_write_log_direct_all(env, mgs, fsdb, mti,
2801 *tmp == '\0' ? NULL : lcr,
2802 mti->mti_fsname, sys, 0);
2803 if (rc == 0 && *tmp != '\0') {
2805 case LCFG_SET_TIMEOUT:
2806 if (!obd_timeout_set || lcfg->lcfg_num > obd_timeout)
2807 class_process_config(lcfg);
2809 case LCFG_SET_LDLM_TIMEOUT:
2810 if (!ldlm_timeout_set || lcfg->lcfg_num > ldlm_timeout)
2811 class_process_config(lcfg);
2818 lustre_cfg_rec_free(lcr);
2822 /* write quota settings into log */
2823 static int mgs_write_log_quota(const struct lu_env *env, struct mgs_device *mgs,
2824 struct fs_db *fsdb, struct mgs_target_info *mti,
2825 char *quota, char *ptr)
2827 struct mgs_thread_info *mgi = mgs_env_info(env);
2828 struct llog_cfg_rec *lcr;
2831 int rc, cmd = LCFG_PARAM;
2833 /* support only 'meta' and 'data' pools so far */
2834 if (class_match_param(ptr, QUOTA_METAPOOL_NAME, &tmp) != 0 &&
2835 class_match_param(ptr, QUOTA_DATAPOOL_NAME, &tmp) != 0) {
2836 CERROR("parameter quota.%s isn't supported (only quota.mdt "
2837 "& quota.ost are)\n", ptr);
2842 CDEBUG(D_MGS, "global '%s' removed\n", quota);
2844 CDEBUG(D_MGS, "global '%s'\n", quota);
2846 if (strchr(tmp, 'u') == NULL && strchr(tmp, 'g') == NULL &&
2847 strcmp(tmp, "none") != 0) {
2848 CERROR("enable option(%s) isn't supported\n", tmp);
2853 lustre_cfg_bufs_reset(&mgi->mgi_bufs, mti->mti_fsname);
2854 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, quota);
2855 lcr = lustre_cfg_rec_new(cmd, &mgi->mgi_bufs);
2859 /* truncate the comment to the parameter name */
2864 /* XXX we duplicated quota enable information in all server
2865 * config logs, it should be moved to a separate config
2866 * log once we cleanup the config log for global param. */
2867 /* modify all servers */
2868 rc = mgs_write_log_direct_all(env, mgs, fsdb, mti,
2869 *tmp == '\0' ? NULL : lcr,
2870 mti->mti_fsname, quota, 1);
2872 lustre_cfg_rec_free(lcr);
2873 return rc < 0 ? rc : 0;
2876 static int mgs_srpc_set_param_disk(const struct lu_env *env,
2877 struct mgs_device *mgs,
2879 struct mgs_target_info *mti,
2882 struct mgs_thread_info *mgi = mgs_env_info(env);
2883 struct llog_cfg_rec *lcr;
2884 struct llog_handle *llh = NULL;
2886 char *comment, *ptr;
2892 ptr = strchr(param, '=');
2893 LASSERT(ptr != NULL);
2896 OBD_ALLOC(comment, len + 1);
2897 if (comment == NULL)
2899 strncpy(comment, param, len);
2900 comment[len] = '\0';
2903 lustre_cfg_bufs_reset(&mgi->mgi_bufs, mti->mti_svname);
2904 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, param);
2905 lcr = lustre_cfg_rec_new(LCFG_SPTLRPC_CONF, &mgi->mgi_bufs);
2907 GOTO(out_comment, rc = -ENOMEM);
2909 /* construct log name */
2910 rc = name_create(&logname, mti->mti_fsname, "-sptlrpc");
2914 if (mgs_log_is_empty(env, mgs, logname)) {
2915 rc = record_start_log(env, mgs, &llh, logname);
2918 record_end_log(env, &llh);
2921 /* obsolete old one */
2922 rc = mgs_modify(env, mgs, fsdb, mti, logname, mti->mti_svname,
2926 /* write the new one */
2927 rc = mgs_write_log_direct(env, mgs, fsdb, logname, lcr,
2928 mti->mti_svname, comment);
2930 CERROR("%s: error writing log %s: rc = %d\n",
2931 mgs->mgs_obd->obd_name, logname, rc);
2933 name_destroy(&logname);
2935 lustre_cfg_rec_free(lcr);
2937 OBD_FREE(comment, len + 1);
2941 static int mgs_srpc_set_param_udesc_mem(struct fs_db *fsdb,
2946 /* disable the adjustable udesc parameter for now, i.e. use default
2947 * setting that client always ship udesc to MDT if possible. to enable
2948 * it simply remove the following line */
2951 ptr = strchr(param, '=');
2956 if (strcmp(param, PARAM_SRPC_UDESC))
2959 if (strcmp(ptr, "yes") == 0) {
2960 set_bit(FSDB_UDESC, &fsdb->fsdb_flags);
2961 CWARN("Enable user descriptor shipping from client to MDT\n");
2962 } else if (strcmp(ptr, "no") == 0) {
2963 clear_bit(FSDB_UDESC, &fsdb->fsdb_flags);
2964 CWARN("Disable user descriptor shipping from client to MDT\n");
2972 CERROR("Invalid param: %s\n", param);
2976 static int mgs_srpc_set_param_mem(struct fs_db *fsdb,
2980 struct sptlrpc_rule rule;
2981 struct sptlrpc_rule_set *rset;
2985 if (strncmp(param, PARAM_SRPC, sizeof(PARAM_SRPC) - 1) != 0) {
2986 CERROR("Invalid sptlrpc parameter: %s\n", param);
2990 if (strncmp(param, PARAM_SRPC_UDESC,
2991 sizeof(PARAM_SRPC_UDESC) - 1) == 0) {
2992 RETURN(mgs_srpc_set_param_udesc_mem(fsdb, param));
2995 if (strncmp(param, PARAM_SRPC_FLVR, sizeof(PARAM_SRPC_FLVR) - 1) != 0) {
2996 CERROR("Invalid sptlrpc flavor parameter: %s\n", param);
3000 param += sizeof(PARAM_SRPC_FLVR) - 1;
3002 rc = sptlrpc_parse_rule(param, &rule);
3006 /* mgs rules implies must be mgc->mgs */
3007 if (test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
3008 if ((rule.sr_from != LUSTRE_SP_MGC &&
3009 rule.sr_from != LUSTRE_SP_ANY) ||
3010 (rule.sr_to != LUSTRE_SP_MGS &&
3011 rule.sr_to != LUSTRE_SP_ANY))
3015 /* preapre room for this coming rule. svcname format should be:
3016 * - fsname: general rule
3017 * - fsname-tgtname: target-specific rule
3019 if (strchr(svname, '-')) {
3020 struct mgs_tgt_srpc_conf *tgtconf;
3023 for (tgtconf = fsdb->fsdb_srpc_tgt; tgtconf != NULL;
3024 tgtconf = tgtconf->mtsc_next) {
3025 if (!strcmp(tgtconf->mtsc_tgt, svname)) {
3034 OBD_ALLOC_PTR(tgtconf);
3035 if (tgtconf == NULL)
3038 name_len = strlen(svname);
3040 OBD_ALLOC(tgtconf->mtsc_tgt, name_len + 1);
3041 if (tgtconf->mtsc_tgt == NULL) {
3042 OBD_FREE_PTR(tgtconf);
3045 memcpy(tgtconf->mtsc_tgt, svname, name_len);
3047 tgtconf->mtsc_next = fsdb->fsdb_srpc_tgt;
3048 fsdb->fsdb_srpc_tgt = tgtconf;
3051 rset = &tgtconf->mtsc_rset;
3053 rset = &fsdb->fsdb_srpc_gen;
3056 rc = sptlrpc_rule_set_merge(rset, &rule);
3061 static int mgs_srpc_set_param(const struct lu_env *env,
3062 struct mgs_device *mgs,
3064 struct mgs_target_info *mti,
3074 /* keep a copy of original param, which could be destroied
3076 copy_size = strlen(param) + 1;
3077 OBD_ALLOC(copy, copy_size);
3080 memcpy(copy, param, copy_size);
3082 rc = mgs_srpc_set_param_mem(fsdb, mti->mti_svname, param);
3086 /* previous steps guaranteed the syntax is correct */
3087 rc = mgs_srpc_set_param_disk(env, mgs, fsdb, mti, copy);
3091 if (test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
3093 * for mgs rules, make them effective immediately.
3095 LASSERT(fsdb->fsdb_srpc_tgt == NULL);
3096 sptlrpc_target_update_exp_flavor(mgs->mgs_obd,
3097 &fsdb->fsdb_srpc_gen);
3101 OBD_FREE(copy, copy_size);
3105 struct mgs_srpc_read_data {
3106 struct fs_db *msrd_fsdb;
3110 static int mgs_srpc_read_handler(const struct lu_env *env,
3111 struct llog_handle *llh,
3112 struct llog_rec_hdr *rec, void *data)
3114 struct mgs_srpc_read_data *msrd = data;
3115 struct cfg_marker *marker;
3116 struct lustre_cfg *lcfg = REC_DATA(rec);
3117 char *svname, *param;
3121 if (rec->lrh_type != OBD_CFG_REC) {
3122 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
3126 cfg_len = REC_DATA_LEN(rec);
3128 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
3130 CERROR("Insane cfg\n");
3134 if (lcfg->lcfg_command == LCFG_MARKER) {
3135 marker = lustre_cfg_buf(lcfg, 1);
3137 if (marker->cm_flags & CM_START &&
3138 marker->cm_flags & CM_SKIP)
3139 msrd->msrd_skip = 1;
3140 if (marker->cm_flags & CM_END)
3141 msrd->msrd_skip = 0;
3146 if (msrd->msrd_skip)
3149 if (lcfg->lcfg_command != LCFG_SPTLRPC_CONF) {
3150 CERROR("invalid command (%x)\n", lcfg->lcfg_command);
3154 svname = lustre_cfg_string(lcfg, 0);
3155 if (svname == NULL) {
3156 CERROR("svname is empty\n");
3160 param = lustre_cfg_string(lcfg, 1);
3161 if (param == NULL) {
3162 CERROR("param is empty\n");
3166 rc = mgs_srpc_set_param_mem(msrd->msrd_fsdb, svname, param);
3168 CERROR("read sptlrpc record error (%d): %s\n", rc, param);
3173 int mgs_get_fsdb_srpc_from_llog(const struct lu_env *env,
3174 struct mgs_device *mgs,
3177 struct llog_handle *llh = NULL;
3178 struct llog_ctxt *ctxt;
3180 struct mgs_srpc_read_data msrd;
3184 /* construct log name */
3185 rc = name_create(&logname, fsdb->fsdb_name, "-sptlrpc");
3189 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
3190 LASSERT(ctxt != NULL);
3192 if (mgs_log_is_empty(env, mgs, logname))
3195 rc = llog_open(env, ctxt, &llh, NULL, logname,
3203 rc = llog_init_handle(env, llh, LLOG_F_IS_PLAIN, NULL);
3205 GOTO(out_close, rc);
3207 if (llog_get_size(llh) <= 1)
3208 GOTO(out_close, rc = 0);
3210 msrd.msrd_fsdb = fsdb;
3213 rc = llog_process(env, llh, mgs_srpc_read_handler, (void *)&msrd,
3217 llog_close(env, llh);
3219 llog_ctxt_put(ctxt);
3220 name_destroy(&logname);
3223 CERROR("failed to read sptlrpc config database: %d\n", rc);
3227 /* Permanent settings of all parameters by writing into the appropriate
3228 * configuration logs.
3229 * A parameter with null value ("<param>='\0'") means to erase it out of
3232 static int mgs_write_log_param(const struct lu_env *env,
3233 struct mgs_device *mgs, struct fs_db *fsdb,
3234 struct mgs_target_info *mti, char *ptr)
3236 struct mgs_thread_info *mgi = mgs_env_info(env);
3239 int rc = 0, rc2 = 0;
3242 /* For various parameter settings, we have to figure out which logs
3243 care about them (e.g. both mdt and client for lov settings) */
3244 CDEBUG(D_MGS, "next param '%s'\n", ptr);
3246 /* The params are stored in MOUNT_DATA_FILE and modified via
3247 tunefs.lustre, or set using lctl conf_param */
3249 /* Processed in lustre_start_mgc */
3250 if (class_match_param(ptr, PARAM_MGSNODE, NULL) == 0)
3253 /* Processed in ost/mdt */
3254 if (class_match_param(ptr, PARAM_NETWORK, NULL) == 0)
3257 /* Processed in mgs_write_log_ost */
3258 if (class_match_param(ptr, PARAM_FAILMODE, NULL) == 0) {
3259 if (mti->mti_flags & LDD_F_PARAM) {
3260 LCONSOLE_ERROR_MSG(0x169, "%s can only be "
3261 "changed with tunefs.lustre"
3262 "and --writeconf\n", ptr);
3268 if (class_match_param(ptr, PARAM_SRPC, NULL) == 0) {
3269 rc = mgs_srpc_set_param(env, mgs, fsdb, mti, ptr);
3273 if (class_match_param(ptr, PARAM_FAILNODE, NULL) == 0) {
3274 /* Add a failover nidlist */
3276 /* We already processed failovers params for new
3277 targets in mgs_write_log_target */
3278 if (mti->mti_flags & LDD_F_PARAM) {
3279 CDEBUG(D_MGS, "Adding failnode\n");
3280 rc = mgs_write_log_add_failnid(env, mgs, fsdb, mti);
3285 if (class_match_param(ptr, PARAM_SYS, &tmp) == 0) {
3286 rc = mgs_write_log_sys(env, mgs, fsdb, mti, ptr, tmp);
3290 if (class_match_param(ptr, PARAM_QUOTA, &tmp) == 0) {
3291 rc = mgs_write_log_quota(env, mgs, fsdb, mti, ptr, tmp);
3295 if (class_match_param(ptr, PARAM_OSC""PARAM_ACTIVE, &tmp) == 0) {
3296 /* active=0 means off, anything else means on */
3297 int flag = (*tmp == '0') ? CM_EXCLUDE : 0;
3300 if (!(mti->mti_flags & LDD_F_SV_TYPE_OST)) {
3301 LCONSOLE_ERROR_MSG(0x144, "%s: Only OSCs can "
3302 "be (de)activated.\n",
3304 GOTO(end, rc = -EINVAL);
3306 LCONSOLE_WARN("Permanently %sactivating %s\n",
3307 flag ? "de": "re", mti->mti_svname);
3309 rc = name_create(&logname, mti->mti_fsname, "-client");
3312 rc = mgs_modify(env, mgs, fsdb, mti, logname,
3313 mti->mti_svname, "add osc", flag);
3314 name_destroy(&logname);
3318 /* Add to all MDT logs for CMD */
3319 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3320 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
3322 rc = name_create_mdt(&logname, mti->mti_fsname, i);
3325 rc = mgs_modify(env, mgs, fsdb, mti, logname,
3326 mti->mti_svname, "add osc", flag);
3327 name_destroy(&logname);
3333 LCONSOLE_ERROR_MSG(0x145, "Couldn't find %s in"
3334 "log (%d). No permanent "
3335 "changes were made to the "
3337 mti->mti_svname, rc);
3338 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags))
3339 LCONSOLE_ERROR_MSG(0x146, "This may be"
3344 "update the logs.\n");
3347 /* Fall through to osc proc for deactivating live OSC
3348 on running MDT / clients. */
3350 /* Below here, let obd's XXX_process_config methods handle it */
3352 /* All lov. in proc */
3353 if (class_match_param(ptr, PARAM_LOV, NULL) == 0) {
3356 CDEBUG(D_MGS, "lov param %s\n", ptr);
3357 if (!(mti->mti_flags & LDD_F_SV_TYPE_MDT)) {
3358 LCONSOLE_ERROR_MSG(0x147, "LOV params must be "
3359 "set on the MDT, not %s. "
3366 if (mgs_log_is_empty(env, mgs, mti->mti_svname))
3367 GOTO(end, rc = -ENODEV);
3369 rc = name_create_mdt_and_lov(&logname, &mdtlovname, fsdb,
3370 mti->mti_stripe_index);
3373 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, mti->mti_svname,
3374 &mgi->mgi_bufs, mdtlovname, ptr);
3375 name_destroy(&logname);
3376 name_destroy(&mdtlovname);
3381 rc = name_create(&logname, mti->mti_fsname, "-client");
3384 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname, &mgi->mgi_bufs,
3385 fsdb->fsdb_clilov, ptr);
3386 name_destroy(&logname);
3390 /* All osc., mdc., llite. params in proc */
3391 if ((class_match_param(ptr, PARAM_OSC, NULL) == 0) ||
3392 (class_match_param(ptr, PARAM_MDC, NULL) == 0) ||
3393 (class_match_param(ptr, PARAM_LLITE, NULL) == 0)) {
3396 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
3397 LCONSOLE_ERROR_MSG(0x148, "Upgraded client logs for %s"
3398 " cannot be modified. Consider"
3399 " updating the configuration with"
3402 GOTO(end, rc = -EINVAL);
3404 if (memcmp(ptr, PARAM_LLITE, strlen(PARAM_LLITE)) == 0) {
3405 rc = name_create(&cname, mti->mti_fsname, "-client");
3406 /* Add the client type to match the obdname in
3407 class_config_llog_handler */
3408 } else if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
3409 rc = name_create(&cname, mti->mti_svname, "-mdc");
3410 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
3411 rc = name_create(&cname, mti->mti_svname, "-osc");
3413 GOTO(end, rc = -EINVAL);
3418 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
3421 rc = name_create(&logname, mti->mti_fsname, "-client");
3423 name_destroy(&cname);
3426 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname, &mgi->mgi_bufs,
3429 /* osc params affect the MDT as well */
3430 if (!rc && (mti->mti_flags & LDD_F_SV_TYPE_OST)) {
3433 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
3434 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
3436 name_destroy(&cname);
3437 rc = name_create_mdt_osc(&cname, mti->mti_svname,
3439 name_destroy(&logname);
3442 rc = name_create_mdt(&logname,
3443 mti->mti_fsname, i);
3446 if (!mgs_log_is_empty(env, mgs, logname)) {
3447 rc = mgs_wlp_lcfg(env, mgs, fsdb,
3456 name_destroy(&logname);
3457 name_destroy(&cname);
3461 /* All mdt. params in proc */
3462 if (class_match_param(ptr, PARAM_MDT, NULL) == 0) {
3466 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
3467 if (strncmp(mti->mti_svname, mti->mti_fsname,
3468 MTI_NAME_MAXLEN) == 0)
3469 /* device is unspecified completely? */
3470 rc = LDD_F_SV_TYPE_MDT | LDD_F_SV_ALL;
3472 rc = server_name2index(mti->mti_svname, &idx, NULL);
3475 if ((rc & LDD_F_SV_TYPE_MDT) == 0)
3477 if (rc & LDD_F_SV_ALL) {
3478 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3480 fsdb->fsdb_mdt_index_map))
3482 rc = name_create_mdt(&logname,
3483 mti->mti_fsname, i);
3486 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti,
3487 logname, &mgi->mgi_bufs,
3489 name_destroy(&logname);
3494 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti,
3495 mti->mti_svname, &mgi->mgi_bufs,
3496 mti->mti_svname, ptr);
3503 /* All mdd., ost. and osd. params in proc */
3504 if ((class_match_param(ptr, PARAM_MDD, NULL) == 0) ||
3505 (class_match_param(ptr, PARAM_OST, NULL) == 0) ||
3506 (class_match_param(ptr, PARAM_OSD, NULL) == 0)) {
3507 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
3508 if (mgs_log_is_empty(env, mgs, mti->mti_svname))
3509 GOTO(end, rc = -ENODEV);
3511 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, mti->mti_svname,
3512 &mgi->mgi_bufs, mti->mti_svname, ptr);
3516 LCONSOLE_WARN("Ignoring unrecognized param '%s'\n", ptr);
3521 CERROR("err %d on param '%s'\n", rc, ptr);
3526 /* Not implementing automatic failover nid addition at this time. */
3527 int mgs_check_failnid(const struct lu_env *env, struct mgs_device *mgs,
3528 struct mgs_target_info *mti)
3535 rc = mgs_find_or_make_fsdb(obd, fsname, &fsdb);
3539 if (mgs_log_is_empty(obd, mti->mti_svname))
3540 /* should never happen */
3543 CDEBUG(D_MGS, "Checking for new failnids for %s\n", mti->mti_svname);
3545 /* FIXME We can just check mti->params to see if we're already in
3546 the failover list. Modify mti->params for rewriting back at
3547 server_register_target(). */
3549 mutex_lock(&fsdb->fsdb_mutex);
3550 rc = mgs_write_log_add_failnid(obd, fsdb, mti);
3551 mutex_unlock(&fsdb->fsdb_mutex);
3560 int mgs_write_log_target(const struct lu_env *env, struct mgs_device *mgs,
3561 struct mgs_target_info *mti, struct fs_db *fsdb)
3568 /* set/check the new target index */
3569 rc = mgs_set_index(env, mgs, mti);
3573 if (rc == EALREADY) {
3574 LCONSOLE_WARN("Found index %d for %s, updating log\n",
3575 mti->mti_stripe_index, mti->mti_svname);
3576 /* We would like to mark old log sections as invalid
3577 and add new log sections in the client and mdt logs.
3578 But if we add new sections, then live clients will
3579 get repeat setup instructions for already running
3580 osc's. So don't update the client/mdt logs. */
3581 mti->mti_flags &= ~LDD_F_UPDATE;
3585 mutex_lock(&fsdb->fsdb_mutex);
3587 if (mti->mti_flags &
3588 (LDD_F_VIRGIN | LDD_F_UPGRADE14 | LDD_F_WRITECONF)) {
3589 /* Generate a log from scratch */
3590 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
3591 rc = mgs_write_log_mdt(env, mgs, fsdb, mti);
3592 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
3593 rc = mgs_write_log_ost(env, mgs, fsdb, mti);
3595 CERROR("Unknown target type %#x, can't create log for "
3596 "%s\n", mti->mti_flags, mti->mti_svname);
3599 CERROR("Can't write logs for %s (%d)\n",
3600 mti->mti_svname, rc);
3604 /* Just update the params from tunefs in mgs_write_log_params */
3605 CDEBUG(D_MGS, "Update params for %s\n", mti->mti_svname);
3606 mti->mti_flags |= LDD_F_PARAM;
3609 /* allocate temporary buffer, where class_get_next_param will
3610 make copy of a current parameter */
3611 OBD_ALLOC(buf, strlen(mti->mti_params) + 1);
3613 GOTO(out_up, rc = -ENOMEM);
3614 params = mti->mti_params;
3615 while (params != NULL) {
3616 rc = class_get_next_param(¶ms, buf);
3619 /* there is no next parameter, that is
3624 CDEBUG(D_MGS, "remaining string: '%s', param: '%s'\n",
3626 rc = mgs_write_log_param(env, mgs, fsdb, mti, buf);
3631 OBD_FREE(buf, strlen(mti->mti_params) + 1);
3634 mutex_unlock(&fsdb->fsdb_mutex);
3638 int mgs_erase_log(const struct lu_env *env, struct mgs_device *mgs, char *name)
3640 struct llog_ctxt *ctxt;
3643 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
3645 CERROR("%s: MGS config context doesn't exist\n",
3646 mgs->mgs_obd->obd_name);
3649 rc = llog_erase(env, ctxt, NULL, name);
3650 /* llog may not exist */
3653 llog_ctxt_put(ctxt);
3657 CERROR("%s: failed to clear log %s: %d\n",
3658 mgs->mgs_obd->obd_name, name, rc);
3663 /* erase all logs for the given fs */
3664 int mgs_erase_logs(const struct lu_env *env, struct mgs_device *mgs, char *fsname)
3667 struct list_head log_list;
3668 struct mgs_direntry *dirent, *n;
3669 int rc, len = strlen(fsname);
3673 /* Find all the logs in the CONFIGS directory */
3674 rc = class_dentry_readdir(env, mgs, &log_list);
3678 mutex_lock(&mgs->mgs_mutex);
3680 /* Delete the fs db */
3681 fsdb = mgs_find_fsdb(mgs, fsname);
3683 mgs_free_fsdb(mgs, fsdb);
3685 mutex_unlock(&mgs->mgs_mutex);
3687 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
3688 list_del_init(&dirent->mde_list);
3689 suffix = strrchr(dirent->mde_name, '-');
3690 if (suffix != NULL) {
3691 if ((len == suffix - dirent->mde_name) &&
3692 (strncmp(fsname, dirent->mde_name, len) == 0)) {
3693 CDEBUG(D_MGS, "Removing log %s\n",
3695 mgs_erase_log(env, mgs, dirent->mde_name);
3698 mgs_direntry_free(dirent);
3704 /* list all logs for the given fs */
3705 int mgs_list_logs(const struct lu_env *env, struct mgs_device *mgs,
3706 struct obd_ioctl_data *data)
3708 struct list_head log_list;
3709 struct mgs_direntry *dirent, *n;
3715 /* Find all the logs in the CONFIGS directory */
3716 rc = class_dentry_readdir(env, mgs, &log_list);
3720 out = data->ioc_bulk;
3721 remains = data->ioc_inllen1;
3722 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
3723 list_del_init(&dirent->mde_list);
3724 suffix = strrchr(dirent->mde_name, '-');
3725 if (suffix != NULL) {
3726 l = snprintf(out, remains, "config log: $%s\n",
3731 mgs_direntry_free(dirent);
3738 /* from llog_swab */
3739 static void print_lustre_cfg(struct lustre_cfg *lcfg)
3744 CDEBUG(D_MGS, "lustre_cfg: %p\n", lcfg);
3745 CDEBUG(D_MGS, "\tlcfg->lcfg_version: %#x\n", lcfg->lcfg_version);
3747 CDEBUG(D_MGS, "\tlcfg->lcfg_command: %#x\n", lcfg->lcfg_command);
3748 CDEBUG(D_MGS, "\tlcfg->lcfg_num: %#x\n", lcfg->lcfg_num);
3749 CDEBUG(D_MGS, "\tlcfg->lcfg_flags: %#x\n", lcfg->lcfg_flags);
3750 CDEBUG(D_MGS, "\tlcfg->lcfg_nid: %s\n", libcfs_nid2str(lcfg->lcfg_nid));
3752 CDEBUG(D_MGS, "\tlcfg->lcfg_bufcount: %d\n", lcfg->lcfg_bufcount);
3753 if (lcfg->lcfg_bufcount < LUSTRE_CFG_MAX_BUFCOUNT)
3754 for (i = 0; i < lcfg->lcfg_bufcount; i++) {
3755 CDEBUG(D_MGS, "\tlcfg->lcfg_buflens[%d]: %d %s\n",
3756 i, lcfg->lcfg_buflens[i],
3757 lustre_cfg_string(lcfg, i));
3762 /* Setup params fsdb and log
3764 int mgs_params_fsdb_setup(const struct lu_env *env, struct mgs_device *mgs,
3767 struct llog_handle *params_llh = NULL;
3771 rc = mgs_find_or_make_fsdb(env, mgs, PARAMS_FILENAME, &fsdb);
3773 mutex_lock(&fsdb->fsdb_mutex);
3774 rc = record_start_log(env, mgs, ¶ms_llh, PARAMS_FILENAME);
3776 rc = record_end_log(env, ¶ms_llh);
3777 mutex_unlock(&fsdb->fsdb_mutex);
3783 /* Cleanup params fsdb and log
3785 int mgs_params_fsdb_cleanup(const struct lu_env *env, struct mgs_device *mgs)
3787 return mgs_erase_logs(env, mgs, PARAMS_FILENAME);
3790 /* Set a permanent (config log) param for a target or fs
3791 * \param lcfg buf0 may contain the device (testfs-MDT0000) name
3792 * buf1 contains the single parameter
3794 int mgs_setparam(const struct lu_env *env, struct mgs_device *mgs,
3795 struct lustre_cfg *lcfg, char *fsname)
3798 struct mgs_target_info *mti;
3799 char *devname, *param;
3806 print_lustre_cfg(lcfg);
3808 /* lustre, lustre-mdtlov, lustre-client, lustre-MDT0000 */
3809 devname = lustre_cfg_string(lcfg, 0);
3810 param = lustre_cfg_string(lcfg, 1);
3812 /* Assume device name embedded in param:
3813 lustre-OST0000.osc.max_dirty_mb=32 */
3814 ptr = strchr(param, '.');
3822 LCONSOLE_ERROR_MSG(0x14d, "No target specified: %s\n", param);
3826 rc = mgs_parse_devname(devname, fsname, NULL);
3827 if (rc == 0 && !mgs_parse_devname(devname, NULL, &index)) {
3828 /* param related to llite isn't allowed to set by OST or MDT */
3829 if (rc == 0 && strncmp(param, PARAM_LLITE,
3830 sizeof(PARAM_LLITE) - 1) == 0)
3833 /* assume devname is the fsname */
3834 memset(fsname, 0, MTI_NAME_MAXLEN);
3835 strncpy(fsname, devname, MTI_NAME_MAXLEN);
3836 fsname[MTI_NAME_MAXLEN - 1] = 0;
3838 CDEBUG(D_MGS, "setparam fs='%s' device='%s'\n", fsname, devname);
3840 rc = mgs_find_or_make_fsdb(env, mgs,
3841 lcfg->lcfg_command == LCFG_SET_PARAM ?
3842 PARAMS_FILENAME : fsname, &fsdb);
3846 if (lcfg->lcfg_command != LCFG_SET_PARAM &&
3847 !test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags) &&
3848 test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
3849 CERROR("No filesystem targets for %s. cfg_device from lctl "
3850 "is '%s'\n", fsname, devname);
3851 mgs_free_fsdb(mgs, fsdb);
3855 /* Create a fake mti to hold everything */
3858 GOTO(out, rc = -ENOMEM);
3859 if (strlcpy(mti->mti_fsname, fsname, sizeof(mti->mti_fsname))
3860 >= sizeof(mti->mti_fsname))
3861 GOTO(out, rc = -E2BIG);
3862 if (strlcpy(mti->mti_svname, devname, sizeof(mti->mti_svname))
3863 >= sizeof(mti->mti_svname))
3864 GOTO(out, rc = -E2BIG);
3865 if (strlcpy(mti->mti_params, param, sizeof(mti->mti_params))
3866 >= sizeof(mti->mti_params))
3867 GOTO(out, rc = -E2BIG);
3868 rc = server_name2index(mti->mti_svname, &mti->mti_stripe_index, &tmp);
3870 /* Not a valid server; may be only fsname */
3873 /* Strip -osc or -mdc suffix from svname */
3874 if (server_make_name(rc, mti->mti_stripe_index, mti->mti_fsname,
3876 GOTO(out, rc = -EINVAL);
3878 * Revoke lock so everyone updates. Should be alright if
3879 * someone was already reading while we were updating the logs,
3880 * so we don't really need to hold the lock while we're
3883 if (lcfg->lcfg_command == LCFG_SET_PARAM) {
3884 mti->mti_flags = rc | LDD_F_PARAM2;
3885 mutex_lock(&fsdb->fsdb_mutex);
3886 rc = mgs_write_log_param2(env, mgs, fsdb, mti, mti->mti_params);
3887 mutex_unlock(&fsdb->fsdb_mutex);
3888 mgs_revoke_lock(mgs, fsdb, CONFIG_T_PARAMS);
3890 mti->mti_flags = rc | LDD_F_PARAM;
3891 mutex_lock(&fsdb->fsdb_mutex);
3892 rc = mgs_write_log_param(env, mgs, fsdb, mti, mti->mti_params);
3893 mutex_unlock(&fsdb->fsdb_mutex);
3894 mgs_revoke_lock(mgs, fsdb, CONFIG_T_CONFIG);
3902 static int mgs_write_log_pool(const struct lu_env *env,
3903 struct mgs_device *mgs, char *logname,
3904 struct fs_db *fsdb, char *tgtname,
3905 enum lcfg_command_type cmd,
3906 char *fsname, char *poolname,
3907 char *ostname, char *comment)
3909 struct llog_handle *llh = NULL;
3912 rc = record_start_log(env, mgs, &llh, logname);
3915 rc = record_marker(env, llh, fsdb, CM_START, tgtname, comment);
3918 rc = record_base(env, llh, tgtname, 0, cmd,
3919 fsname, poolname, ostname, 0);
3922 rc = record_marker(env, llh, fsdb, CM_END, tgtname, comment);
3924 record_end_log(env, &llh);
3928 int mgs_nodemap_cmd(const struct lu_env *env, struct mgs_device *mgs,
3929 enum lcfg_command_type cmd, const char *nodemap_name,
3940 case LCFG_NODEMAP_ADD:
3941 rc = nodemap_add(nodemap_name);
3943 case LCFG_NODEMAP_DEL:
3944 rc = nodemap_del(nodemap_name);
3946 case LCFG_NODEMAP_ADD_RANGE:
3947 rc = nodemap_parse_range(param, nid);
3950 rc = nodemap_add_range(nodemap_name, nid);
3952 case LCFG_NODEMAP_DEL_RANGE:
3953 rc = nodemap_parse_range(param, nid);
3956 rc = nodemap_del_range(nodemap_name, nid);
3958 case LCFG_NODEMAP_ADMIN:
3959 bool_switch = simple_strtoul(param, NULL, 10);
3960 rc = nodemap_set_allow_root(nodemap_name, bool_switch);
3962 case LCFG_NODEMAP_TRUSTED:
3963 bool_switch = simple_strtoul(param, NULL, 10);
3964 rc = nodemap_set_trust_client_ids(nodemap_name, bool_switch);
3966 case LCFG_NODEMAP_SQUASH_UID:
3967 int_id = simple_strtoul(param, NULL, 10);
3968 rc = nodemap_set_squash_uid(nodemap_name, int_id);
3970 case LCFG_NODEMAP_SQUASH_GID:
3971 int_id = simple_strtoul(param, NULL, 10);
3972 rc = nodemap_set_squash_gid(nodemap_name, int_id);
3974 case LCFG_NODEMAP_ADD_UIDMAP:
3975 case LCFG_NODEMAP_ADD_GIDMAP:
3976 rc = nodemap_parse_idmap(param, idmap);
3979 if (cmd == LCFG_NODEMAP_ADD_UIDMAP)
3980 rc = nodemap_add_idmap(nodemap_name, NODEMAP_UID,
3983 rc = nodemap_add_idmap(nodemap_name, NODEMAP_GID,
3986 case LCFG_NODEMAP_DEL_UIDMAP:
3987 case LCFG_NODEMAP_DEL_GIDMAP:
3988 rc = nodemap_parse_idmap(param, idmap);
3991 if (cmd == LCFG_NODEMAP_DEL_UIDMAP)
3992 rc = nodemap_del_idmap(nodemap_name, NODEMAP_UID,
3995 rc = nodemap_del_idmap(nodemap_name, NODEMAP_GID,
4005 int mgs_pool_cmd(const struct lu_env *env, struct mgs_device *mgs,
4006 enum lcfg_command_type cmd, char *fsname,
4007 char *poolname, char *ostname)
4012 char *label = NULL, *canceled_label = NULL;
4014 struct mgs_target_info *mti = NULL;
4018 rc = mgs_find_or_make_fsdb(env, mgs, fsname, &fsdb);
4020 CERROR("Can't get db for %s\n", fsname);
4023 if (test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
4024 CERROR("%s is not defined\n", fsname);
4025 mgs_free_fsdb(mgs, fsdb);
4029 label_sz = 10 + strlen(fsname) + strlen(poolname);
4031 /* check if ostname match fsname */
4032 if (ostname != NULL) {
4035 ptr = strrchr(ostname, '-');
4036 if ((ptr == NULL) ||
4037 (strncmp(fsname, ostname, ptr-ostname) != 0))
4039 label_sz += strlen(ostname);
4042 OBD_ALLOC(label, label_sz);
4049 "new %s.%s", fsname, poolname);
4053 "add %s.%s.%s", fsname, poolname, ostname);
4056 OBD_ALLOC(canceled_label, label_sz);
4057 if (canceled_label == NULL)
4058 GOTO(out_label, rc = -ENOMEM);
4060 "rem %s.%s.%s", fsname, poolname, ostname);
4061 sprintf(canceled_label,
4062 "add %s.%s.%s", fsname, poolname, ostname);
4065 OBD_ALLOC(canceled_label, label_sz);
4066 if (canceled_label == NULL)
4067 GOTO(out_label, rc = -ENOMEM);
4069 "del %s.%s", fsname, poolname);
4070 sprintf(canceled_label,
4071 "new %s.%s", fsname, poolname);
4077 if (canceled_label != NULL) {
4080 GOTO(out_cancel, rc = -ENOMEM);
4083 mutex_lock(&fsdb->fsdb_mutex);
4084 /* write pool def to all MDT logs */
4085 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
4086 if (test_bit(i, fsdb->fsdb_mdt_index_map)) {
4087 rc = name_create_mdt_and_lov(&logname, &lovname,
4090 mutex_unlock(&fsdb->fsdb_mutex);
4093 if (canceled_label != NULL) {
4094 strcpy(mti->mti_svname, "lov pool");
4095 rc = mgs_modify(env, mgs, fsdb, mti, logname,
4096 lovname, canceled_label,
4101 rc = mgs_write_log_pool(env, mgs, logname,
4105 name_destroy(&logname);
4106 name_destroy(&lovname);
4108 mutex_unlock(&fsdb->fsdb_mutex);
4114 rc = name_create(&logname, fsname, "-client");
4116 mutex_unlock(&fsdb->fsdb_mutex);
4119 if (canceled_label != NULL) {
4120 rc = mgs_modify(env, mgs, fsdb, mti, logname,
4121 fsdb->fsdb_clilov, canceled_label, CM_SKIP);
4123 mutex_unlock(&fsdb->fsdb_mutex);
4124 name_destroy(&logname);
4129 rc = mgs_write_log_pool(env, mgs, logname, fsdb, fsdb->fsdb_clilov,
4130 cmd, fsname, poolname, ostname, label);
4131 mutex_unlock(&fsdb->fsdb_mutex);
4132 name_destroy(&logname);
4133 /* request for update */
4134 mgs_revoke_lock(mgs, fsdb, CONFIG_T_CONFIG);
4141 if (canceled_label != NULL)
4142 OBD_FREE(canceled_label, label_sz);
4144 OBD_FREE(label, label_sz);