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 int class_dentry_readdir(const struct lu_env *env,
59 struct mgs_device *mgs, cfs_list_t *list)
61 struct dt_object *dir = mgs->mgs_configs_dir;
62 const struct dt_it_ops *iops;
64 struct mgs_direntry *de;
68 CFS_INIT_LIST_HEAD(list);
71 LASSERT(dir->do_index_ops);
73 iops = &dir->do_index_ops->dio_it;
74 it = iops->init(env, dir, LUDA_64BITHASH, BYPASS_CAPA);
78 rc = iops->load(env, it, 0);
84 key = (void *)iops->key(env, it);
86 CERROR("%s: key failed when listing %s: rc = %d\n",
87 mgs->mgs_obd->obd_name, MOUNT_CONFIGS_DIR,
91 key_sz = iops->key_size(env, it);
94 /* filter out "." and ".." entries */
98 if (key_sz == 2 && key[1] == '.')
102 de = mgs_direntry_alloc(key_sz + 1);
108 memcpy(de->name, key, key_sz);
109 de->name[key_sz] = 0;
111 cfs_list_add(&de->list, list);
114 rc = iops->next(env, it);
123 CERROR("%s: key failed when listing %s: rc = %d\n",
124 mgs->mgs_obd->obd_name, MOUNT_CONFIGS_DIR, rc);
128 /******************** DB functions *********************/
130 static inline int name_create(char **newname, char *prefix, char *suffix)
133 OBD_ALLOC(*newname, strlen(prefix) + strlen(suffix) + 1);
136 sprintf(*newname, "%s%s", prefix, suffix);
140 static inline void name_destroy(char **name)
143 OBD_FREE(*name, strlen(*name) + 1);
147 struct mgs_fsdb_handler_data
153 /* from the (client) config log, figure out:
154 1. which ost's/mdt's are configured (by index)
155 2. what the last config step is
156 3. COMPAT_18 osc name
158 /* It might be better to have a separate db file, instead of parsing the info
159 out of the client log. This is slow and potentially error-prone. */
160 static int mgs_fsdb_handler(const struct lu_env *env, struct llog_handle *llh,
161 struct llog_rec_hdr *rec, void *data)
163 struct mgs_fsdb_handler_data *d = data;
164 struct fs_db *fsdb = d->fsdb;
165 int cfg_len = rec->lrh_len;
166 char *cfg_buf = (char*) (rec + 1);
167 struct lustre_cfg *lcfg;
172 if (rec->lrh_type != OBD_CFG_REC) {
173 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
177 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
179 CERROR("Insane cfg\n");
183 lcfg = (struct lustre_cfg *)cfg_buf;
185 CDEBUG(D_INFO, "cmd %x %s %s\n", lcfg->lcfg_command,
186 lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));
188 /* Figure out ost indicies */
189 /* lov_modify_tgts add 0:lov1 1:ost1_UUID 2(index):0 3(gen):1 */
190 if (lcfg->lcfg_command == LCFG_LOV_ADD_OBD ||
191 lcfg->lcfg_command == LCFG_LOV_DEL_OBD) {
192 index = simple_strtoul(lustre_cfg_string(lcfg, 2),
194 CDEBUG(D_MGS, "OST index for %s is %u (%s)\n",
195 lustre_cfg_string(lcfg, 1), index,
196 lustre_cfg_string(lcfg, 2));
197 set_bit(index, fsdb->fsdb_ost_index_map);
200 /* Figure out mdt indicies */
201 /* attach 0:MDC_uml1_mdsA_MNT_client 1:mdc 2:1d834_MNT_client_03f */
202 if ((lcfg->lcfg_command == LCFG_ATTACH) &&
203 (strcmp(lustre_cfg_string(lcfg, 1), LUSTRE_MDC_NAME) == 0)) {
204 rc = server_name2index(lustre_cfg_string(lcfg, 0),
206 if (rc != LDD_F_SV_TYPE_MDT) {
207 CWARN("Unparsable MDC name %s, assuming index 0\n",
208 lustre_cfg_string(lcfg, 0));
212 CDEBUG(D_MGS, "MDT index is %u\n", index);
213 set_bit(index, fsdb->fsdb_mdt_index_map);
214 fsdb->fsdb_mdt_count ++;
218 * figure out the old config. fsdb_gen = 0 means old log
219 * It is obsoleted and not supported anymore
221 if (fsdb->fsdb_gen == 0) {
222 CERROR("Old config format is not supported\n");
227 * compat to 1.8, check osc name used by MDT0 to OSTs, bz18548.
229 if (!test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags) &&
230 lcfg->lcfg_command == LCFG_ATTACH &&
231 strcmp(lustre_cfg_string(lcfg, 1), LUSTRE_OSC_NAME) == 0) {
232 if (OBD_OCD_VERSION_MAJOR(d->ver) == 1 &&
233 OBD_OCD_VERSION_MINOR(d->ver) <= 8) {
234 CWARN("MDT using 1.8 OSC name scheme\n");
235 set_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags);
239 if (lcfg->lcfg_command == LCFG_MARKER) {
240 struct cfg_marker *marker;
241 marker = lustre_cfg_buf(lcfg, 1);
243 d->ver = marker->cm_vers;
245 /* Keep track of the latest marker step */
246 fsdb->fsdb_gen = max(fsdb->fsdb_gen, marker->cm_step);
252 /* fsdb->fsdb_mutex is already held in mgs_find_or_make_fsdb*/
253 static int mgs_get_fsdb_from_llog(const struct lu_env *env,
254 struct mgs_device *mgs,
258 struct llog_handle *loghandle;
259 struct llog_ctxt *ctxt;
260 struct mgs_fsdb_handler_data d = { fsdb, 0 };
265 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
266 LASSERT(ctxt != NULL);
267 rc = name_create(&logname, fsdb->fsdb_name, "-client");
270 rc = llog_open_create(env, ctxt, &loghandle, NULL, logname);
274 rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL);
278 if (llog_get_size(loghandle) <= 1)
279 set_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags);
281 rc = llog_process(env, loghandle, mgs_fsdb_handler, (void *)&d, NULL);
282 CDEBUG(D_INFO, "get_db = %d\n", rc);
284 llog_close(env, loghandle);
286 name_destroy(&logname);
293 static void mgs_free_fsdb_srpc(struct fs_db *fsdb)
295 struct mgs_tgt_srpc_conf *tgtconf;
297 /* free target-specific rules */
298 while (fsdb->fsdb_srpc_tgt) {
299 tgtconf = fsdb->fsdb_srpc_tgt;
300 fsdb->fsdb_srpc_tgt = tgtconf->mtsc_next;
302 LASSERT(tgtconf->mtsc_tgt);
304 sptlrpc_rule_set_free(&tgtconf->mtsc_rset);
305 OBD_FREE(tgtconf->mtsc_tgt, strlen(tgtconf->mtsc_tgt) + 1);
306 OBD_FREE_PTR(tgtconf);
309 /* free general rules */
310 sptlrpc_rule_set_free(&fsdb->fsdb_srpc_gen);
313 struct fs_db *mgs_find_fsdb(struct mgs_device *mgs, char *fsname)
318 cfs_list_for_each(tmp, &mgs->mgs_fs_db_list) {
319 fsdb = cfs_list_entry(tmp, struct fs_db, fsdb_list);
320 if (strcmp(fsdb->fsdb_name, fsname) == 0)
326 /* caller must hold the mgs->mgs_fs_db_lock */
327 static struct fs_db *mgs_new_fsdb(const struct lu_env *env,
328 struct mgs_device *mgs, char *fsname)
334 if (strlen(fsname) >= sizeof(fsdb->fsdb_name)) {
335 CERROR("fsname %s is too long\n", fsname);
343 strcpy(fsdb->fsdb_name, fsname);
344 mutex_init(&fsdb->fsdb_mutex);
345 set_bit(FSDB_UDESC, &fsdb->fsdb_flags);
348 if (strcmp(fsname, MGSSELF_NAME) == 0) {
349 set_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags);
351 OBD_ALLOC(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
352 OBD_ALLOC(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
353 if (!fsdb->fsdb_ost_index_map || !fsdb->fsdb_mdt_index_map) {
354 CERROR("No memory for index maps\n");
355 GOTO(err, rc = -ENOMEM);
358 rc = name_create(&fsdb->fsdb_clilov, fsname, "-clilov");
361 rc = name_create(&fsdb->fsdb_clilmv, fsname, "-clilmv");
365 /* initialise data for NID table */
366 mgs_ir_init_fs(env, mgs, fsdb);
368 lproc_mgs_add_live(mgs, fsdb);
371 cfs_list_add(&fsdb->fsdb_list, &mgs->mgs_fs_db_list);
375 if (fsdb->fsdb_ost_index_map)
376 OBD_FREE(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
377 if (fsdb->fsdb_mdt_index_map)
378 OBD_FREE(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
379 name_destroy(&fsdb->fsdb_clilov);
380 name_destroy(&fsdb->fsdb_clilmv);
385 static void mgs_free_fsdb(struct mgs_device *mgs, struct fs_db *fsdb)
387 /* wait for anyone with the sem */
388 mutex_lock(&fsdb->fsdb_mutex);
389 lproc_mgs_del_live(mgs, fsdb);
390 cfs_list_del(&fsdb->fsdb_list);
392 /* deinitialize fsr */
393 mgs_ir_fini_fs(mgs, fsdb);
395 if (fsdb->fsdb_ost_index_map)
396 OBD_FREE(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
397 if (fsdb->fsdb_mdt_index_map)
398 OBD_FREE(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
399 name_destroy(&fsdb->fsdb_clilov);
400 name_destroy(&fsdb->fsdb_clilmv);
401 mgs_free_fsdb_srpc(fsdb);
402 mutex_unlock(&fsdb->fsdb_mutex);
406 int mgs_init_fsdb_list(struct mgs_device *mgs)
408 CFS_INIT_LIST_HEAD(&mgs->mgs_fs_db_list);
412 int mgs_cleanup_fsdb_list(struct mgs_device *mgs)
415 cfs_list_t *tmp, *tmp2;
416 mutex_lock(&mgs->mgs_mutex);
417 cfs_list_for_each_safe(tmp, tmp2, &mgs->mgs_fs_db_list) {
418 fsdb = cfs_list_entry(tmp, struct fs_db, fsdb_list);
419 mgs_free_fsdb(mgs, fsdb);
421 mutex_unlock(&mgs->mgs_mutex);
425 int mgs_find_or_make_fsdb(const struct lu_env *env,
426 struct mgs_device *mgs, char *name,
433 mutex_lock(&mgs->mgs_mutex);
434 fsdb = mgs_find_fsdb(mgs, name);
436 mutex_unlock(&mgs->mgs_mutex);
441 CDEBUG(D_MGS, "Creating new db\n");
442 fsdb = mgs_new_fsdb(env, mgs, name);
443 /* lock fsdb_mutex until the db is loaded from llogs */
445 mutex_lock(&fsdb->fsdb_mutex);
446 mutex_unlock(&mgs->mgs_mutex);
450 if (!test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
451 /* populate the db from the client llog */
452 rc = mgs_get_fsdb_from_llog(env, mgs, fsdb);
454 CERROR("Can't get db from client log %d\n", rc);
459 /* populate srpc rules from params llog */
460 rc = mgs_get_fsdb_srpc_from_llog(env, mgs, fsdb);
462 CERROR("Can't get db from params log %d\n", rc);
466 mutex_unlock(&fsdb->fsdb_mutex);
472 mutex_unlock(&fsdb->fsdb_mutex);
473 mgs_free_fsdb(mgs, fsdb);
479 -1= empty client log */
480 int mgs_check_index(const struct lu_env *env,
481 struct mgs_device *mgs,
482 struct mgs_target_info *mti)
489 LASSERT(!(mti->mti_flags & LDD_F_NEED_INDEX));
491 rc = mgs_find_or_make_fsdb(env, mgs, mti->mti_fsname, &fsdb);
493 CERROR("Can't get db for %s\n", mti->mti_fsname);
497 if (test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags))
500 if (mti->mti_flags & LDD_F_SV_TYPE_OST)
501 imap = fsdb->fsdb_ost_index_map;
502 else if (mti->mti_flags & LDD_F_SV_TYPE_MDT)
503 imap = fsdb->fsdb_mdt_index_map;
507 if (test_bit(mti->mti_stripe_index, imap))
512 static __inline__ int next_index(void *index_map, int map_len)
515 for (i = 0; i < map_len * 8; i++)
516 if (!test_bit(i, index_map)) {
519 CERROR("max index %d exceeded.\n", i);
524 0 newly marked as in use
526 +EALREADY for update of an old index */
527 static int mgs_set_index(const struct lu_env *env,
528 struct mgs_device *mgs,
529 struct mgs_target_info *mti)
536 rc = mgs_find_or_make_fsdb(env, mgs, mti->mti_fsname, &fsdb);
538 CERROR("Can't get db for %s\n", mti->mti_fsname);
542 mutex_lock(&fsdb->fsdb_mutex);
543 if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
544 imap = fsdb->fsdb_ost_index_map;
545 } else if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
546 imap = fsdb->fsdb_mdt_index_map;
548 GOTO(out_up, rc = -EINVAL);
551 if (mti->mti_flags & LDD_F_NEED_INDEX) {
552 rc = next_index(imap, INDEX_MAP_SIZE);
554 GOTO(out_up, rc = -ERANGE);
555 mti->mti_stripe_index = rc;
556 if (mti->mti_flags & LDD_F_SV_TYPE_MDT)
557 fsdb->fsdb_mdt_count ++;
560 if (mti->mti_stripe_index >= INDEX_MAP_SIZE * 8) {
561 LCONSOLE_ERROR_MSG(0x13f, "Server %s requested index %d, "
562 "but the max index is %d.\n",
563 mti->mti_svname, mti->mti_stripe_index,
565 GOTO(out_up, rc = -ERANGE);
568 if (test_bit(mti->mti_stripe_index, imap)) {
569 if ((mti->mti_flags & LDD_F_VIRGIN) &&
570 !(mti->mti_flags & LDD_F_WRITECONF)) {
571 LCONSOLE_ERROR_MSG(0x140, "Server %s requested index "
572 "%d, but that index is already in "
573 "use. Use --writeconf to force\n",
575 mti->mti_stripe_index);
576 GOTO(out_up, rc = -EADDRINUSE);
578 CDEBUG(D_MGS, "Server %s updating index %d\n",
579 mti->mti_svname, mti->mti_stripe_index);
580 GOTO(out_up, rc = EALREADY);
584 set_bit(mti->mti_stripe_index, imap);
585 clear_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags);
586 mutex_unlock(&fsdb->fsdb_mutex);
587 server_make_name(mti->mti_flags & ~(LDD_F_VIRGIN | LDD_F_WRITECONF),
588 mti->mti_stripe_index, mti->mti_fsname, mti->mti_svname);
590 CDEBUG(D_MGS, "Set index for %s to %d\n", mti->mti_svname,
591 mti->mti_stripe_index);
595 mutex_unlock(&fsdb->fsdb_mutex);
599 struct mgs_modify_lookup {
600 struct cfg_marker mml_marker;
604 static int mgs_modify_handler(const struct lu_env *env,
605 struct llog_handle *llh,
606 struct llog_rec_hdr *rec, void *data)
608 struct mgs_modify_lookup *mml = data;
609 struct cfg_marker *marker;
610 struct lustre_cfg *lcfg = REC_DATA(rec);
611 int cfg_len = REC_DATA_LEN(rec);
615 if (rec->lrh_type != OBD_CFG_REC) {
616 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
620 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
622 CERROR("Insane cfg\n");
626 /* We only care about markers */
627 if (lcfg->lcfg_command != LCFG_MARKER)
630 marker = lustre_cfg_buf(lcfg, 1);
631 if ((strcmp(mml->mml_marker.cm_comment, marker->cm_comment) == 0) &&
632 (strcmp(mml->mml_marker.cm_tgtname, marker->cm_tgtname) == 0) &&
633 !(marker->cm_flags & CM_SKIP)) {
634 /* Found a non-skipped marker match */
635 CDEBUG(D_MGS, "Changing rec %u marker %d %x->%x: %s %s\n",
636 rec->lrh_index, marker->cm_step,
637 marker->cm_flags, mml->mml_marker.cm_flags,
638 marker->cm_tgtname, marker->cm_comment);
639 /* Overwrite the old marker llog entry */
640 marker->cm_flags &= ~CM_EXCLUDE; /* in case we're unexcluding */
641 marker->cm_flags |= mml->mml_marker.cm_flags;
642 marker->cm_canceltime = mml->mml_marker.cm_canceltime;
643 /* Header and tail are added back to lrh_len in
644 llog_lvfs_write_rec */
645 rec->lrh_len = cfg_len;
646 rc = llog_write(env, llh, rec, NULL, 0, (void *)lcfg,
656 * Modify an existing config log record (for CM_SKIP or CM_EXCLUDE)
658 * 0 - modified successfully,
659 * 1 - no modification was done
662 static int mgs_modify(const struct lu_env *env, struct mgs_device *mgs,
663 struct fs_db *fsdb, struct mgs_target_info *mti,
664 char *logname, char *devname, char *comment, int flags)
666 struct llog_handle *loghandle;
667 struct llog_ctxt *ctxt;
668 struct mgs_modify_lookup *mml;
673 LASSERT(mutex_is_locked(&fsdb->fsdb_mutex));
674 CDEBUG(D_MGS, "modify %s/%s/%s fl=%x\n", logname, devname, comment,
677 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
678 LASSERT(ctxt != NULL);
679 rc = llog_open(env, ctxt, &loghandle, NULL, logname, LLOG_OPEN_EXISTS);
686 rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL);
690 if (llog_get_size(loghandle) <= 1)
691 GOTO(out_close, rc = 0);
695 GOTO(out_close, rc = -ENOMEM);
696 if (strlcpy(mml->mml_marker.cm_comment, comment,
697 sizeof(mml->mml_marker.cm_comment)) >=
698 sizeof(mml->mml_marker.cm_comment))
699 GOTO(out_free, rc = -E2BIG);
700 if (strlcpy(mml->mml_marker.cm_tgtname, devname,
701 sizeof(mml->mml_marker.cm_tgtname)) >=
702 sizeof(mml->mml_marker.cm_tgtname))
703 GOTO(out_free, rc = -E2BIG);
704 /* Modify mostly means cancel */
705 mml->mml_marker.cm_flags = flags;
706 mml->mml_marker.cm_canceltime = flags ? cfs_time_current_sec() : 0;
707 mml->mml_modified = 0;
708 rc = llog_process(env, loghandle, mgs_modify_handler, (void *)mml,
710 if (!rc && !mml->mml_modified)
717 llog_close(env, loghandle);
720 CERROR("%s: modify %s/%s failed: rc = %d\n",
721 mgs->mgs_obd->obd_name, mti->mti_svname, comment, rc);
726 /** This structure is passed to mgs_replace_handler */
727 struct mgs_replace_uuid_lookup {
728 /* Nids are replaced for this target device */
729 struct mgs_target_info target;
730 /* Temporary modified llog */
731 struct llog_handle *temp_llh;
732 /* Flag is set if in target block*/
733 int in_target_device;
734 /* Nids already added. Just skip (multiple nids) */
735 int device_nids_added;
736 /* Flag is set if this block should not be copied */
741 * Check: a) if block should be skipped
742 * b) is it target block
747 * \retval 0 should not to be skipped
748 * \retval 1 should to be skipped
750 static int check_markers(struct lustre_cfg *lcfg,
751 struct mgs_replace_uuid_lookup *mrul)
753 struct cfg_marker *marker;
755 /* Track markers. Find given device */
756 if (lcfg->lcfg_command == LCFG_MARKER) {
757 marker = lustre_cfg_buf(lcfg, 1);
758 /* Clean llog from records marked as CM_EXCLUDE.
759 CM_SKIP records are used for "active" command
760 and can be restored if needed */
761 if ((marker->cm_flags & (CM_EXCLUDE | CM_START)) ==
762 (CM_EXCLUDE | CM_START)) {
767 if ((marker->cm_flags & (CM_EXCLUDE | CM_END)) ==
768 (CM_EXCLUDE | CM_END)) {
773 if (strcmp(mrul->target.mti_svname, marker->cm_tgtname) == 0) {
774 LASSERT(!(marker->cm_flags & CM_START) ||
775 !(marker->cm_flags & CM_END));
776 if (marker->cm_flags & CM_START) {
777 mrul->in_target_device = 1;
778 mrul->device_nids_added = 0;
779 } else if (marker->cm_flags & CM_END)
780 mrul->in_target_device = 0;
787 static int record_lcfg(const struct lu_env *env, struct llog_handle *llh,
788 struct lustre_cfg *lcfg)
790 struct llog_rec_hdr rec;
796 LASSERT(llh->lgh_ctxt);
798 buflen = lustre_cfg_len(lcfg->lcfg_bufcount,
800 rec.lrh_len = llog_data_len(buflen);
801 rec.lrh_type = OBD_CFG_REC;
803 /* idx = -1 means append */
804 rc = llog_write(env, llh, &rec, NULL, 0, (void *)lcfg, -1);
806 CERROR("failed %d\n", rc);
810 static int record_base(const struct lu_env *env, struct llog_handle *llh,
811 char *cfgname, lnet_nid_t nid, int cmd,
812 char *s1, char *s2, char *s3, char *s4)
814 struct mgs_thread_info *mgi = mgs_env_info(env);
815 struct lustre_cfg *lcfg;
818 CDEBUG(D_MGS, "lcfg %s %#x %s %s %s %s\n", cfgname,
819 cmd, s1, s2, s3, s4);
821 lustre_cfg_bufs_reset(&mgi->mgi_bufs, cfgname);
823 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, s1);
825 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 2, s2);
827 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 3, s3);
829 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 4, s4);
831 lcfg = lustre_cfg_new(cmd, &mgi->mgi_bufs);
834 lcfg->lcfg_nid = nid;
836 rc = record_lcfg(env, llh, lcfg);
838 lustre_cfg_free(lcfg);
841 CERROR("error %d: lcfg %s %#x %s %s %s %s\n", rc, cfgname,
842 cmd, s1, s2, s3, s4);
847 static inline int record_add_uuid(const struct lu_env *env,
848 struct llog_handle *llh,
849 uint64_t nid, char *uuid)
851 return record_base(env, llh, NULL, nid, LCFG_ADD_UUID, uuid, 0, 0, 0);
854 static inline int record_add_conn(const struct lu_env *env,
855 struct llog_handle *llh,
856 char *devname, char *uuid)
858 return record_base(env, llh, devname, 0, LCFG_ADD_CONN, uuid, 0, 0, 0);
861 static inline int record_attach(const struct lu_env *env,
862 struct llog_handle *llh, char *devname,
863 char *type, char *uuid)
865 return record_base(env, llh,devname, 0, LCFG_ATTACH, type, uuid, 0, 0);
868 static inline int record_setup(const struct lu_env *env,
869 struct llog_handle *llh, char *devname,
870 char *s1, char *s2, char *s3, char *s4)
872 return record_base(env, llh, devname, 0, LCFG_SETUP, s1, s2, s3, s4);
876 * \retval <0 record processing error
877 * \retval n record is processed. No need copy original one.
878 * \retval 0 record is not processed.
880 static int process_command(const struct lu_env *env, struct lustre_cfg *lcfg,
881 struct mgs_replace_uuid_lookup *mrul)
888 if (lcfg->lcfg_command == LCFG_ADD_UUID) {
889 /* LCFG_ADD_UUID command found. Let's skip original command
890 and add passed nids */
891 ptr = mrul->target.mti_params;
892 while (class_parse_nid(ptr, &nid, &ptr) == 0) {
893 CDEBUG(D_MGS, "add nid %s with uuid %s, "
894 "device %s\n", libcfs_nid2str(nid),
895 mrul->target.mti_params,
896 mrul->target.mti_svname);
897 rc = record_add_uuid(env,
899 mrul->target.mti_params);
904 if (nids_added == 0) {
905 CERROR("No new nids were added, nid %s with uuid %s, "
906 "device %s\n", libcfs_nid2str(nid),
907 mrul->target.mti_params,
908 mrul->target.mti_svname);
911 mrul->device_nids_added = 1;
917 if (mrul->device_nids_added && lcfg->lcfg_command == LCFG_SETUP) {
918 /* LCFG_SETUP command found. UUID should be changed */
919 rc = record_setup(env,
921 /* devname the same */
922 lustre_cfg_string(lcfg, 0),
923 /* s1 is not changed */
924 lustre_cfg_string(lcfg, 1),
925 /* new uuid should be
927 mrul->target.mti_params,
928 /* s3 is not changed */
929 lustre_cfg_string(lcfg, 3),
930 /* s4 is not changed */
931 lustre_cfg_string(lcfg, 4));
935 /* Another commands in target device block */
940 * Handler that called for every record in llog.
941 * Records are processed in order they placed in llog.
943 * \param[in] llh log to be processed
944 * \param[in] rec current record
945 * \param[in] data mgs_replace_uuid_lookup structure
949 static int mgs_replace_handler(const struct lu_env *env,
950 struct llog_handle *llh,
951 struct llog_rec_hdr *rec,
954 struct mgs_replace_uuid_lookup *mrul;
955 struct lustre_cfg *lcfg = REC_DATA(rec);
956 int cfg_len = REC_DATA_LEN(rec);
960 mrul = (struct mgs_replace_uuid_lookup *)data;
962 if (rec->lrh_type != OBD_CFG_REC) {
963 CERROR("unhandled lrh_type: %#x, cmd %x %s %s\n",
964 rec->lrh_type, lcfg->lcfg_command,
965 lustre_cfg_string(lcfg, 0),
966 lustre_cfg_string(lcfg, 1));
970 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
972 /* Do not copy any invalidated records */
973 GOTO(skip_out, rc = 0);
976 rc = check_markers(lcfg, mrul);
977 if (rc || mrul->skip_it)
978 GOTO(skip_out, rc = 0);
980 /* Write to new log all commands outside target device block */
981 if (!mrul->in_target_device)
982 GOTO(copy_out, rc = 0);
984 /* Skip all other LCFG_ADD_UUID and LCFG_ADD_CONN records
985 (failover nids) for this target, assuming that if then
986 primary is changing then so is the failover */
987 if (mrul->device_nids_added &&
988 (lcfg->lcfg_command == LCFG_ADD_UUID ||
989 lcfg->lcfg_command == LCFG_ADD_CONN))
990 GOTO(skip_out, rc = 0);
992 rc = process_command(env, lcfg, mrul);
999 /* Record is placed in temporary llog as is */
1000 rc = llog_write(env, mrul->temp_llh, rec, NULL, 0, NULL, -1);
1002 CDEBUG(D_MGS, "Copied idx=%d, rc=%d, len=%d, cmd %x %s %s\n",
1003 rec->lrh_index, rc, rec->lrh_len, lcfg->lcfg_command,
1004 lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));
1008 CDEBUG(D_MGS, "Skipped idx=%d, rc=%d, len=%d, cmd %x %s %s\n",
1009 rec->lrh_index, rc, rec->lrh_len, lcfg->lcfg_command,
1010 lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));
1014 static int mgs_log_is_empty(const struct lu_env *env,
1015 struct mgs_device *mgs, char *name)
1017 struct llog_ctxt *ctxt;
1020 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
1021 LASSERT(ctxt != NULL);
1023 rc = llog_is_empty(env, ctxt, name);
1024 llog_ctxt_put(ctxt);
1028 static int mgs_replace_nids_log(const struct lu_env *env,
1029 struct obd_device *mgs, struct fs_db *fsdb,
1030 char *logname, char *devname, char *nids)
1032 struct llog_handle *orig_llh, *backup_llh;
1033 struct llog_ctxt *ctxt;
1034 struct mgs_replace_uuid_lookup *mrul;
1035 struct mgs_device *mgs_dev = lu2mgs_dev(mgs->obd_lu_dev);
1036 static struct obd_uuid cfg_uuid = { .uuid = "config_uuid" };
1041 CDEBUG(D_MGS, "Replace nids for %s in %s\n", devname, logname);
1043 ctxt = llog_get_context(mgs, LLOG_CONFIG_ORIG_CTXT);
1044 LASSERT(ctxt != NULL);
1046 if (mgs_log_is_empty(env, mgs_dev, logname)) {
1047 /* Log is empty. Nothing to replace */
1048 GOTO(out_put, rc = 0);
1051 OBD_ALLOC(backup, strlen(logname) + strlen(".bak") + 1);
1053 GOTO(out_put, rc = -ENOMEM);
1055 sprintf(backup, "%s.bak", logname);
1057 rc = llog_backup(env, mgs, ctxt, ctxt, logname, backup);
1059 /* Now erase original log file. Connections are not allowed.
1060 Backup is already saved */
1061 rc = llog_erase(env, ctxt, NULL, logname);
1064 } else if (rc != -ENOENT) {
1065 CERROR("%s: can't make backup for %s: rc = %d\n",
1066 mgs->obd_name, logname, rc);
1070 /* open local log */
1071 rc = llog_open_create(env, ctxt, &orig_llh, NULL, logname);
1073 GOTO(out_restore, rc);
1075 rc = llog_init_handle(env, orig_llh, LLOG_F_IS_PLAIN, &cfg_uuid);
1077 GOTO(out_closel, rc);
1079 /* open backup llog */
1080 rc = llog_open(env, ctxt, &backup_llh, NULL, backup,
1083 GOTO(out_closel, rc);
1085 rc = llog_init_handle(env, backup_llh, LLOG_F_IS_PLAIN, NULL);
1087 GOTO(out_close, rc);
1089 if (llog_get_size(backup_llh) <= 1)
1090 GOTO(out_close, rc = 0);
1092 OBD_ALLOC_PTR(mrul);
1094 GOTO(out_close, rc = -ENOMEM);
1095 /* devname is only needed information to replace UUID records */
1096 strncpy(mrul->target.mti_svname, devname, MTI_NAME_MAXLEN);
1097 /* parse nids later */
1098 strncpy(mrul->target.mti_params, nids, MTI_PARAM_MAXLEN);
1099 /* Copy records to this temporary llog */
1100 mrul->temp_llh = orig_llh;
1102 rc = llog_process(env, backup_llh, mgs_replace_handler,
1103 (void *)mrul, NULL);
1106 rc2 = llog_close(NULL, backup_llh);
1110 rc2 = llog_close(NULL, orig_llh);
1116 CERROR("%s: llog should be restored: rc = %d\n",
1118 rc2 = llog_backup(env, mgs, ctxt, ctxt, backup,
1121 CERROR("%s: can't restore backup %s: rc = %d\n",
1122 mgs->obd_name, logname, rc2);
1126 OBD_FREE(backup, strlen(backup) + 1);
1129 llog_ctxt_put(ctxt);
1132 CERROR("%s: failed to replace nids in log %s: rc = %d\n",
1133 mgs->obd_name, logname, rc);
1139 * Parse device name and get file system name and/or device index
1141 * \param[in] devname device name (ex. lustre-MDT0000)
1142 * \param[out] fsname file system name(optional)
1143 * \param[out] index device index(optional)
1147 static int mgs_parse_devname(char *devname, char *fsname, __u32 *index)
1152 /* Extract fsname */
1154 rc = server_name2fsname(devname, fsname, NULL);
1156 CDEBUG(D_MGS, "Device name %s without fsname\n",
1163 rc = server_name2index(devname, index, NULL);
1165 CDEBUG(D_MGS, "Device name %s with wrong index\n",
1174 /* This is only called during replace_nids */
1175 static int only_mgs_is_running(struct obd_device *mgs_obd)
1177 /* TDB: Is global variable with devices count exists? */
1178 int num_devices = get_devices_count();
1179 int num_exports = 0;
1180 struct obd_export *exp;
1182 spin_lock(&mgs_obd->obd_dev_lock);
1183 list_for_each_entry(exp, &mgs_obd->obd_exports, exp_obd_chain) {
1184 /* skip self export */
1185 if (exp == mgs_obd->obd_self_export)
1187 if (exp_connect_flags(exp) & OBD_CONNECT_MDS_MDS)
1192 CERROR("%s: node %s still connected during replace_nids "
1193 "connect_flags:%llx\n",
1195 libcfs_nid2str(exp->exp_nid_stats->nid),
1196 exp_connect_flags(exp));
1199 spin_unlock(&mgs_obd->obd_dev_lock);
1201 /* osd, MGS and MGC + self_export
1202 (wc -l /proc/fs/lustre/devices <= 2) && (non self exports == 0) */
1203 return (num_devices <= 3) && (num_exports == 0);
1206 static int name_create_mdt(char **logname, char *fsname, int i)
1210 sprintf(mdt_index, "-MDT%04x", i);
1211 return name_create(logname, fsname, mdt_index);
1215 * Replace nids for \a device to \a nids values
1217 * \param obd MGS obd device
1218 * \param devname nids need to be replaced for this device
1219 * (ex. lustre-OST0000)
1220 * \param nids nids list (ex. nid1,nid2,nid3)
1224 int mgs_replace_nids(const struct lu_env *env,
1225 struct mgs_device *mgs,
1226 char *devname, char *nids)
1228 /* Assume fsname is part of device name */
1229 char fsname[MTI_NAME_MAXLEN];
1236 struct obd_device *mgs_obd = mgs->mgs_obd;
1239 /* We can only change NIDs if no other nodes are connected */
1240 spin_lock(&mgs_obd->obd_dev_lock);
1241 conn_state = mgs_obd->obd_no_conn;
1242 mgs_obd->obd_no_conn = 1;
1243 spin_unlock(&mgs_obd->obd_dev_lock);
1245 /* We can not change nids if not only MGS is started */
1246 if (!only_mgs_is_running(mgs_obd)) {
1247 CERROR("Only MGS is allowed to be started\n");
1248 GOTO(out, rc = -EINPROGRESS);
1251 /* Get fsname and index*/
1252 rc = mgs_parse_devname(devname, fsname, &index);
1256 rc = mgs_find_or_make_fsdb(env, mgs, fsname, &fsdb);
1258 CERROR("%s: can't find fsdb: rc = %d\n", fsname, rc);
1262 /* Process client llogs */
1263 name_create(&logname, fsname, "-client");
1264 rc = mgs_replace_nids_log(env, mgs_obd, fsdb, logname, devname, nids);
1265 name_destroy(&logname);
1267 CERROR("%s: error while replacing NIDs for %s: rc = %d\n",
1268 fsname, devname, rc);
1272 /* Process MDT llogs */
1273 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
1274 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
1276 name_create_mdt(&logname, fsname, i);
1277 rc = mgs_replace_nids_log(env, mgs_obd, fsdb, logname, devname, nids);
1278 name_destroy(&logname);
1284 spin_lock(&mgs_obd->obd_dev_lock);
1285 mgs_obd->obd_no_conn = conn_state;
1286 spin_unlock(&mgs_obd->obd_dev_lock);
1291 static int record_lov_setup(const struct lu_env *env, struct llog_handle *llh,
1292 char *devname, struct lov_desc *desc)
1294 struct mgs_thread_info *mgi = mgs_env_info(env);
1295 struct lustre_cfg *lcfg;
1298 lustre_cfg_bufs_reset(&mgi->mgi_bufs, devname);
1299 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, desc, sizeof(*desc));
1300 lcfg = lustre_cfg_new(LCFG_SETUP, &mgi->mgi_bufs);
1303 rc = record_lcfg(env, llh, lcfg);
1305 lustre_cfg_free(lcfg);
1309 static int record_lmv_setup(const struct lu_env *env, struct llog_handle *llh,
1310 char *devname, struct lmv_desc *desc)
1312 struct mgs_thread_info *mgi = mgs_env_info(env);
1313 struct lustre_cfg *lcfg;
1316 lustre_cfg_bufs_reset(&mgi->mgi_bufs, devname);
1317 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, desc, sizeof(*desc));
1318 lcfg = lustre_cfg_new(LCFG_SETUP, &mgi->mgi_bufs);
1320 rc = record_lcfg(env, llh, lcfg);
1322 lustre_cfg_free(lcfg);
1326 static inline int record_mdc_add(const struct lu_env *env,
1327 struct llog_handle *llh,
1328 char *logname, char *mdcuuid,
1329 char *mdtuuid, char *index,
1332 return record_base(env,llh,logname,0,LCFG_ADD_MDC,
1333 mdtuuid,index,gen,mdcuuid);
1336 static inline int record_lov_add(const struct lu_env *env,
1337 struct llog_handle *llh,
1338 char *lov_name, char *ost_uuid,
1339 char *index, char *gen)
1341 return record_base(env,llh,lov_name,0,LCFG_LOV_ADD_OBD,
1342 ost_uuid, index, gen, 0);
1345 static inline int record_mount_opt(const struct lu_env *env,
1346 struct llog_handle *llh,
1347 char *profile, char *lov_name,
1350 return record_base(env,llh,NULL,0,LCFG_MOUNTOPT,
1351 profile,lov_name,mdc_name,0);
1354 static int record_marker(const struct lu_env *env,
1355 struct llog_handle *llh,
1356 struct fs_db *fsdb, __u32 flags,
1357 char *tgtname, char *comment)
1359 struct mgs_thread_info *mgi = mgs_env_info(env);
1360 struct lustre_cfg *lcfg;
1364 if (flags & CM_START)
1366 mgi->mgi_marker.cm_step = fsdb->fsdb_gen;
1367 mgi->mgi_marker.cm_flags = flags;
1368 mgi->mgi_marker.cm_vers = LUSTRE_VERSION_CODE;
1369 cplen = strlcpy(mgi->mgi_marker.cm_tgtname, tgtname,
1370 sizeof(mgi->mgi_marker.cm_tgtname));
1371 if (cplen >= sizeof(mgi->mgi_marker.cm_tgtname))
1373 cplen = strlcpy(mgi->mgi_marker.cm_comment, comment,
1374 sizeof(mgi->mgi_marker.cm_comment));
1375 if (cplen >= sizeof(mgi->mgi_marker.cm_comment))
1377 mgi->mgi_marker.cm_createtime = cfs_time_current_sec();
1378 mgi->mgi_marker.cm_canceltime = 0;
1379 lustre_cfg_bufs_reset(&mgi->mgi_bufs, NULL);
1380 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, &mgi->mgi_marker,
1381 sizeof(mgi->mgi_marker));
1382 lcfg = lustre_cfg_new(LCFG_MARKER, &mgi->mgi_bufs);
1385 rc = record_lcfg(env, llh, lcfg);
1387 lustre_cfg_free(lcfg);
1391 static int record_start_log(const struct lu_env *env, struct mgs_device *mgs,
1392 struct llog_handle **llh, char *name)
1394 static struct obd_uuid cfg_uuid = { .uuid = "config_uuid" };
1395 struct llog_ctxt *ctxt;
1400 GOTO(out, rc = -EBUSY);
1402 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
1404 GOTO(out, rc = -ENODEV);
1405 LASSERT(ctxt->loc_obd == mgs->mgs_obd);
1407 rc = llog_open_create(env, ctxt, llh, NULL, name);
1410 rc = llog_init_handle(env, *llh, LLOG_F_IS_PLAIN, &cfg_uuid);
1412 llog_close(env, *llh);
1414 llog_ctxt_put(ctxt);
1417 CERROR("%s: can't start log %s: rc = %d\n",
1418 mgs->mgs_obd->obd_name, name, rc);
1424 static int record_end_log(const struct lu_env *env, struct llog_handle **llh)
1428 rc = llog_close(env, *llh);
1434 /******************** config "macros" *********************/
1436 /* write an lcfg directly into a log (with markers) */
1437 static int mgs_write_log_direct(const struct lu_env *env,
1438 struct mgs_device *mgs, struct fs_db *fsdb,
1439 char *logname, struct lustre_cfg *lcfg,
1440 char *devname, char *comment)
1442 struct llog_handle *llh = NULL;
1449 rc = record_start_log(env, mgs, &llh, logname);
1453 /* FIXME These should be a single journal transaction */
1454 rc = record_marker(env, llh, fsdb, CM_START, devname, comment);
1457 rc = record_lcfg(env, llh, lcfg);
1460 rc = record_marker(env, llh, fsdb, CM_END, devname, comment);
1464 record_end_log(env, &llh);
1468 /* write the lcfg in all logs for the given fs */
1469 int mgs_write_log_direct_all(const struct lu_env *env,
1470 struct mgs_device *mgs,
1472 struct mgs_target_info *mti,
1473 struct lustre_cfg *lcfg,
1474 char *devname, char *comment,
1478 struct mgs_direntry *dirent, *n;
1479 char *fsname = mti->mti_fsname;
1481 int rc = 0, len = strlen(fsname);
1484 /* We need to set params for any future logs
1485 as well. FIXME Append this file to every new log.
1486 Actually, we should store as params (text), not llogs. Or
1488 rc = name_create(&logname, fsname, "-params");
1491 if (mgs_log_is_empty(env, mgs, logname)) {
1492 struct llog_handle *llh = NULL;
1493 rc = record_start_log(env, mgs, &llh, logname);
1495 record_end_log(env, &llh);
1497 name_destroy(&logname);
1501 /* Find all the logs in the CONFIGS directory */
1502 rc = class_dentry_readdir(env, mgs, &list);
1506 /* Could use fsdb index maps instead of directory listing */
1507 cfs_list_for_each_entry_safe(dirent, n, &list, list) {
1508 cfs_list_del(&dirent->list);
1509 /* don't write to sptlrpc rule log */
1510 if (strstr(dirent->name, "-sptlrpc") != NULL)
1513 /* caller wants write server logs only */
1514 if (server_only && strstr(dirent->name, "-client") != NULL)
1517 if (strncmp(fsname, dirent->name, len) == 0) {
1518 CDEBUG(D_MGS, "Changing log %s\n", dirent->name);
1519 /* Erase any old settings of this same parameter */
1520 rc = mgs_modify(env, mgs, fsdb, mti, dirent->name,
1521 devname, comment, CM_SKIP);
1523 CERROR("%s: Can't modify llog %s: rc = %d\n",
1524 mgs->mgs_obd->obd_name, dirent->name,rc);
1525 /* Write the new one */
1527 rc = mgs_write_log_direct(env, mgs, fsdb,
1532 CERROR("%s: writing log %s: rc = %d\n",
1533 mgs->mgs_obd->obd_name,
1538 mgs_direntry_free(dirent);
1544 static int mgs_write_log_osp_to_mdt(const struct lu_env *env,
1545 struct mgs_device *mgs,
1547 struct mgs_target_info *mti,
1548 int index, char *logname);
1549 static int mgs_write_log_osc_to_lov(const struct lu_env *env,
1550 struct mgs_device *mgs,
1552 struct mgs_target_info *mti,
1553 char *logname, char *suffix, char *lovname,
1554 enum lustre_sec_part sec_part, int flags);
1555 static int name_create_mdt_and_lov(char **logname, char **lovname,
1556 struct fs_db *fsdb, int i);
1558 static int add_param(char *params, char *key, char *val)
1560 char *start = params + strlen(params);
1561 char *end = params + sizeof(((struct mgs_target_info *)0)->mti_params);
1565 keylen = strlen(key);
1566 if (start + 1 + keylen + strlen(val) >= end) {
1567 CERROR("params are too long: %s %s%s\n",
1568 params, key != NULL ? key : "", val);
1572 sprintf(start, " %s%s", key != NULL ? key : "", val);
1577 * Walk through client config log record and convert the related records
1580 static int mgs_steal_client_llog_handler(const struct lu_env *env,
1581 struct llog_handle *llh,
1582 struct llog_rec_hdr *rec, void *data)
1584 struct mgs_device *mgs;
1585 struct obd_device *obd;
1586 struct mgs_target_info *mti, *tmti;
1588 int cfg_len = rec->lrh_len;
1589 char *cfg_buf = (char*) (rec + 1);
1590 struct lustre_cfg *lcfg;
1592 struct llog_handle *mdt_llh = NULL;
1593 static int got_an_osc_or_mdc = 0;
1594 /* 0: not found any osc/mdc;
1598 static int last_step = -1;
1603 mti = ((struct temp_comp*)data)->comp_mti;
1604 tmti = ((struct temp_comp*)data)->comp_tmti;
1605 fsdb = ((struct temp_comp*)data)->comp_fsdb;
1606 obd = ((struct temp_comp *)data)->comp_obd;
1607 mgs = lu2mgs_dev(obd->obd_lu_dev);
1610 if (rec->lrh_type != OBD_CFG_REC) {
1611 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
1615 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
1617 CERROR("Insane cfg\n");
1621 lcfg = (struct lustre_cfg *)cfg_buf;
1623 if (lcfg->lcfg_command == LCFG_MARKER) {
1624 struct cfg_marker *marker;
1625 marker = lustre_cfg_buf(lcfg, 1);
1626 if (!strncmp(marker->cm_comment, "add osc", 7) &&
1627 (marker->cm_flags & CM_START) &&
1628 !(marker->cm_flags & CM_SKIP)) {
1629 got_an_osc_or_mdc = 1;
1630 cplen = strlcpy(tmti->mti_svname, marker->cm_tgtname,
1631 sizeof(tmti->mti_svname));
1632 if (cplen >= sizeof(tmti->mti_svname))
1634 rc = record_start_log(env, mgs, &mdt_llh,
1638 rc = record_marker(env, mdt_llh, fsdb, CM_START,
1639 mti->mti_svname, "add osc(copied)");
1640 record_end_log(env, &mdt_llh);
1641 last_step = marker->cm_step;
1644 if (!strncmp(marker->cm_comment, "add osc", 7) &&
1645 (marker->cm_flags & CM_END) &&
1646 !(marker->cm_flags & CM_SKIP)) {
1647 LASSERT(last_step == marker->cm_step);
1649 got_an_osc_or_mdc = 0;
1650 memset(tmti, 0, sizeof(*tmti));
1651 rc = record_start_log(env, mgs, &mdt_llh,
1655 rc = record_marker(env, mdt_llh, fsdb, CM_END,
1656 mti->mti_svname, "add osc(copied)");
1657 record_end_log(env, &mdt_llh);
1660 if (!strncmp(marker->cm_comment, "add mdc", 7) &&
1661 (marker->cm_flags & CM_START) &&
1662 !(marker->cm_flags & CM_SKIP)) {
1663 got_an_osc_or_mdc = 2;
1664 last_step = marker->cm_step;
1665 memcpy(tmti->mti_svname, marker->cm_tgtname,
1666 strlen(marker->cm_tgtname));
1670 if (!strncmp(marker->cm_comment, "add mdc", 7) &&
1671 (marker->cm_flags & CM_END) &&
1672 !(marker->cm_flags & CM_SKIP)) {
1673 LASSERT(last_step == marker->cm_step);
1675 got_an_osc_or_mdc = 0;
1676 memset(tmti, 0, sizeof(*tmti));
1681 if (got_an_osc_or_mdc == 0 || last_step < 0)
1684 if (lcfg->lcfg_command == LCFG_ADD_UUID) {
1685 uint64_t nodenid = lcfg->lcfg_nid;
1687 if (strlen(tmti->mti_uuid) == 0) {
1688 /* target uuid not set, this config record is before
1689 * LCFG_SETUP, this nid is one of target node nid.
1691 tmti->mti_nids[tmti->mti_nid_count] = nodenid;
1692 tmti->mti_nid_count++;
1694 /* failover node nid */
1695 rc = add_param(tmti->mti_params, PARAM_FAILNODE,
1696 libcfs_nid2str(nodenid));
1702 if (lcfg->lcfg_command == LCFG_SETUP) {
1705 target = lustre_cfg_string(lcfg, 1);
1706 memcpy(tmti->mti_uuid, target, strlen(target));
1710 /* ignore client side sptlrpc_conf_log */
1711 if (lcfg->lcfg_command == LCFG_SPTLRPC_CONF)
1714 if (lcfg->lcfg_command == LCFG_ADD_MDC) {
1717 if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1)
1720 memcpy(tmti->mti_fsname, mti->mti_fsname,
1721 strlen(mti->mti_fsname));
1722 tmti->mti_stripe_index = index;
1724 rc = mgs_write_log_osp_to_mdt(env, mgs, fsdb, tmti,
1725 mti->mti_stripe_index,
1727 memset(tmti, 0, sizeof(*tmti));
1731 if (lcfg->lcfg_command == LCFG_LOV_ADD_OBD) {
1734 char *logname, *lovname;
1736 rc = name_create_mdt_and_lov(&logname, &lovname, fsdb,
1737 mti->mti_stripe_index);
1740 sprintf(mdt_index, "-MDT%04x", mti->mti_stripe_index);
1742 if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1) {
1743 name_destroy(&logname);
1744 name_destroy(&lovname);
1748 tmti->mti_stripe_index = index;
1749 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, tmti, logname,
1752 name_destroy(&logname);
1753 name_destroy(&lovname);
1759 /* fsdb->fsdb_mutex is already held in mgs_write_log_target*/
1760 /* stealed from mgs_get_fsdb_from_llog*/
1761 static int mgs_steal_llog_for_mdt_from_client(const struct lu_env *env,
1762 struct mgs_device *mgs,
1764 struct temp_comp* comp)
1766 struct llog_handle *loghandle;
1767 struct mgs_target_info *tmti;
1768 struct llog_ctxt *ctxt;
1773 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
1774 LASSERT(ctxt != NULL);
1776 OBD_ALLOC_PTR(tmti);
1778 GOTO(out_ctxt, rc = -ENOMEM);
1780 comp->comp_tmti = tmti;
1781 comp->comp_obd = mgs->mgs_obd;
1783 rc = llog_open(env, ctxt, &loghandle, NULL, client_name,
1791 rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL);
1793 GOTO(out_close, rc);
1795 rc = llog_process_or_fork(env, loghandle, mgs_steal_client_llog_handler,
1796 (void *)comp, NULL, false);
1797 CDEBUG(D_MGS, "steal llog re = %d\n", rc);
1799 llog_close(env, loghandle);
1803 llog_ctxt_put(ctxt);
1807 /* lmv is the second thing for client logs */
1808 /* copied from mgs_write_log_lov. Please refer to that. */
1809 static int mgs_write_log_lmv(const struct lu_env *env,
1810 struct mgs_device *mgs,
1812 struct mgs_target_info *mti,
1813 char *logname, char *lmvname)
1815 struct llog_handle *llh = NULL;
1816 struct lmv_desc *lmvdesc;
1821 CDEBUG(D_MGS, "Writing lmv(%s) log for %s\n", lmvname,logname);
1823 OBD_ALLOC_PTR(lmvdesc);
1824 if (lmvdesc == NULL)
1826 lmvdesc->ld_active_tgt_count = 0;
1827 lmvdesc->ld_tgt_count = 0;
1828 sprintf((char*)lmvdesc->ld_uuid.uuid, "%s_UUID", lmvname);
1829 uuid = (char *)lmvdesc->ld_uuid.uuid;
1831 rc = record_start_log(env, mgs, &llh, logname);
1834 rc = record_marker(env, llh, fsdb, CM_START, lmvname, "lmv setup");
1837 rc = record_attach(env, llh, lmvname, "lmv", uuid);
1840 rc = record_lmv_setup(env, llh, lmvname, lmvdesc);
1843 rc = record_marker(env, llh, fsdb, CM_END, lmvname, "lmv setup");
1847 record_end_log(env, &llh);
1849 OBD_FREE_PTR(lmvdesc);
1853 /* lov is the first thing in the mdt and client logs */
1854 static int mgs_write_log_lov(const struct lu_env *env, struct mgs_device *mgs,
1855 struct fs_db *fsdb, struct mgs_target_info *mti,
1856 char *logname, char *lovname)
1858 struct llog_handle *llh = NULL;
1859 struct lov_desc *lovdesc;
1864 CDEBUG(D_MGS, "Writing lov(%s) log for %s\n", lovname, logname);
1867 #01 L attach 0:lov_mdsA 1:lov 2:71ccb_lov_mdsA_19f961a9e1
1868 #02 L lov_setup 0:lov_mdsA 1:(struct lov_desc)
1869 uuid=lov1_UUID, stripe count=1, size=1048576, offset=0, pattern=0
1872 /* FIXME just make lov_setup accept empty desc (put uuid in buf 2) */
1873 OBD_ALLOC_PTR(lovdesc);
1874 if (lovdesc == NULL)
1876 lovdesc->ld_magic = LOV_DESC_MAGIC;
1877 lovdesc->ld_tgt_count = 0;
1878 /* Defaults. Can be changed later by lcfg config_param */
1879 lovdesc->ld_default_stripe_count = 1;
1880 lovdesc->ld_pattern = LOV_PATTERN_RAID0;
1881 lovdesc->ld_default_stripe_size = LOV_DESC_STRIPE_SIZE_DEFAULT;
1882 lovdesc->ld_default_stripe_offset = -1;
1883 lovdesc->ld_qos_maxage = LOV_DESC_QOS_MAXAGE_DEFAULT;
1884 sprintf((char*)lovdesc->ld_uuid.uuid, "%s_UUID", lovname);
1885 /* can these be the same? */
1886 uuid = (char *)lovdesc->ld_uuid.uuid;
1888 /* This should always be the first entry in a log.
1889 rc = mgs_clear_log(obd, logname); */
1890 rc = record_start_log(env, mgs, &llh, logname);
1893 /* FIXME these should be a single journal transaction */
1894 rc = record_marker(env, llh, fsdb, CM_START, lovname, "lov setup");
1897 rc = record_attach(env, llh, lovname, "lov", uuid);
1900 rc = record_lov_setup(env, llh, lovname, lovdesc);
1903 rc = record_marker(env, llh, fsdb, CM_END, lovname, "lov setup");
1908 record_end_log(env, &llh);
1910 OBD_FREE_PTR(lovdesc);
1914 /* add failnids to open log */
1915 static int mgs_write_log_failnids(const struct lu_env *env,
1916 struct mgs_target_info *mti,
1917 struct llog_handle *llh,
1920 char *failnodeuuid = NULL;
1921 char *ptr = mti->mti_params;
1926 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) nal=90 0: 1:uml1_UUID
1927 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
1928 #05 L setup 0:OSC_uml1_ost1_mdsA 1:ost1_UUID 2:uml1_UUID
1929 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) nal=90 0: 1:uml2_UUID
1930 #0x L add_uuid nid=2@elan(0x1000000000002) nal=90 0: 1:uml2_UUID
1931 #07 L add_conn 0:OSC_uml1_ost1_mdsA 1:uml2_UUID
1934 /* Pull failnid info out of params string */
1935 while (class_find_param(ptr, PARAM_FAILNODE, &ptr) == 0) {
1936 while (class_parse_nid(ptr, &nid, &ptr) == 0) {
1937 if (failnodeuuid == NULL) {
1938 /* We don't know the failover node name,
1939 so just use the first nid as the uuid */
1940 rc = name_create(&failnodeuuid,
1941 libcfs_nid2str(nid), "");
1945 CDEBUG(D_MGS, "add nid %s for failover uuid %s, "
1946 "client %s\n", libcfs_nid2str(nid),
1947 failnodeuuid, cliname);
1948 rc = record_add_uuid(env, llh, nid, failnodeuuid);
1951 rc = record_add_conn(env, llh, cliname, failnodeuuid);
1952 name_destroy(&failnodeuuid);
1953 failnodeuuid = NULL;
1960 static int mgs_write_log_mdc_to_lmv(const struct lu_env *env,
1961 struct mgs_device *mgs,
1963 struct mgs_target_info *mti,
1964 char *logname, char *lmvname)
1966 struct llog_handle *llh = NULL;
1967 char *mdcname = NULL;
1968 char *nodeuuid = NULL;
1969 char *mdcuuid = NULL;
1970 char *lmvuuid = NULL;
1975 if (mgs_log_is_empty(env, mgs, logname)) {
1976 CERROR("log is empty! Logical error\n");
1980 CDEBUG(D_MGS, "adding mdc for %s to log %s:lmv(%s)\n",
1981 mti->mti_svname, logname, lmvname);
1983 rc = name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
1986 rc = name_create(&mdcname, mti->mti_svname, "-mdc");
1989 rc = name_create(&mdcuuid, mdcname, "_UUID");
1992 rc = name_create(&lmvuuid, lmvname, "_UUID");
1996 rc = record_start_log(env, mgs, &llh, logname);
1999 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
2003 for (i = 0; i < mti->mti_nid_count; i++) {
2004 CDEBUG(D_MGS, "add nid %s for mdt\n",
2005 libcfs_nid2str(mti->mti_nids[i]));
2007 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
2012 rc = record_attach(env, llh, mdcname, LUSTRE_MDC_NAME, lmvuuid);
2015 rc = record_setup(env, llh, mdcname, mti->mti_uuid, nodeuuid, 0, 0);
2018 rc = mgs_write_log_failnids(env, mti, llh, mdcname);
2021 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
2022 rc = record_mdc_add(env, llh, lmvname, mdcuuid, mti->mti_uuid,
2026 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname,
2031 record_end_log(env, &llh);
2033 name_destroy(&lmvuuid);
2034 name_destroy(&mdcuuid);
2035 name_destroy(&mdcname);
2036 name_destroy(&nodeuuid);
2040 static inline int name_create_lov(char **lovname, char *mdtname,
2041 struct fs_db *fsdb, int index)
2044 if (index == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2045 return name_create(lovname, fsdb->fsdb_name, "-mdtlov");
2047 return name_create(lovname, mdtname, "-mdtlov");
2050 static int name_create_mdt_and_lov(char **logname, char **lovname,
2051 struct fs_db *fsdb, int i)
2055 rc = name_create_mdt(logname, fsdb->fsdb_name, i);
2059 if (i == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2060 rc = name_create(lovname, fsdb->fsdb_name, "-mdtlov");
2062 rc = name_create(lovname, *logname, "-mdtlov");
2064 name_destroy(logname);
2070 static inline int name_create_mdt_osc(char **oscname, char *ostname,
2071 struct fs_db *fsdb, int i)
2075 if (i == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2076 sprintf(suffix, "-osc");
2078 sprintf(suffix, "-osc-MDT%04x", i);
2079 return name_create(oscname, ostname, suffix);
2082 /* add new mdc to already existent MDS */
2083 static int mgs_write_log_osp_to_mdt(const struct lu_env *env,
2084 struct mgs_device *mgs,
2086 struct mgs_target_info *mti,
2087 int mdt_index, char *logname)
2089 struct llog_handle *llh = NULL;
2090 char *nodeuuid = NULL;
2091 char *ospname = NULL;
2092 char *lovuuid = NULL;
2093 char *mdtuuid = NULL;
2094 char *svname = NULL;
2095 char *mdtname = NULL;
2096 char *lovname = NULL;
2101 if (mgs_log_is_empty(env, mgs, mti->mti_svname)) {
2102 CERROR("log is empty! Logical error\n");
2106 CDEBUG(D_MGS, "adding osp index %d to %s\n", mti->mti_stripe_index,
2109 rc = name_create_mdt(&mdtname, fsdb->fsdb_name, mti->mti_stripe_index);
2113 rc = name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
2115 GOTO(out_destory, rc);
2117 rc = name_create(&svname, mdtname, "-osp");
2119 GOTO(out_destory, rc);
2121 sprintf(index_str, "-MDT%04x", mdt_index);
2122 rc = name_create(&ospname, svname, index_str);
2124 GOTO(out_destory, rc);
2126 rc = name_create_lov(&lovname, logname, fsdb, mdt_index);
2128 GOTO(out_destory, rc);
2130 rc = name_create(&lovuuid, lovname, "_UUID");
2132 GOTO(out_destory, rc);
2134 rc = name_create(&mdtuuid, mdtname, "_UUID");
2136 GOTO(out_destory, rc);
2138 rc = record_start_log(env, mgs, &llh, logname);
2140 GOTO(out_destory, rc);
2142 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
2145 GOTO(out_destory, rc);
2147 for (i = 0; i < mti->mti_nid_count; i++) {
2148 CDEBUG(D_MGS, "add nid %s for mdt\n",
2149 libcfs_nid2str(mti->mti_nids[i]));
2150 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
2155 rc = record_attach(env, llh, ospname, LUSTRE_OSP_NAME, lovuuid);
2159 rc = record_setup(env, llh, ospname, mti->mti_uuid, nodeuuid,
2164 rc = mgs_write_log_failnids(env, mti, llh, ospname);
2168 /* Add mdc(osp) to lod */
2169 snprintf(index_str, sizeof(mti->mti_stripe_index), "%d",
2170 mti->mti_stripe_index);
2171 rc = record_base(env, llh, lovname, 0, LCFG_ADD_MDC, mti->mti_uuid,
2172 index_str, "1", NULL);
2176 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname, "add osp");
2181 record_end_log(env, &llh);
2184 name_destroy(&mdtuuid);
2185 name_destroy(&lovuuid);
2186 name_destroy(&lovname);
2187 name_destroy(&ospname);
2188 name_destroy(&svname);
2189 name_destroy(&nodeuuid);
2190 name_destroy(&mdtname);
2194 static int mgs_write_log_mdt0(const struct lu_env *env,
2195 struct mgs_device *mgs,
2197 struct mgs_target_info *mti)
2199 char *log = mti->mti_svname;
2200 struct llog_handle *llh = NULL;
2201 char *uuid, *lovname;
2203 char *ptr = mti->mti_params;
2204 int rc = 0, failout = 0;
2207 OBD_ALLOC(uuid, sizeof(struct obd_uuid));
2211 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
2212 failout = (strncmp(ptr, "failout", 7) == 0);
2214 rc = name_create(&lovname, log, "-mdtlov");
2217 if (mgs_log_is_empty(env, mgs, log)) {
2218 rc = mgs_write_log_lov(env, mgs, fsdb, mti, log, lovname);
2223 sprintf(mdt_index, "%d", mti->mti_stripe_index);
2225 rc = record_start_log(env, mgs, &llh, log);
2229 /* add MDT itself */
2231 /* FIXME this whole fn should be a single journal transaction */
2232 sprintf(uuid, "%s_UUID", log);
2233 rc = record_marker(env, llh, fsdb, CM_START, log, "add mdt");
2236 rc = record_attach(env, llh, log, LUSTRE_MDT_NAME, uuid);
2239 rc = record_mount_opt(env, llh, log, lovname, NULL);
2242 rc = record_setup(env, llh, log, uuid, mdt_index, lovname,
2243 failout ? "n" : "f");
2246 rc = record_marker(env, llh, fsdb, CM_END, log, "add mdt");
2250 record_end_log(env, &llh);
2252 name_destroy(&lovname);
2254 OBD_FREE(uuid, sizeof(struct obd_uuid));
2258 /* envelope method for all layers log */
2259 static int mgs_write_log_mdt(const struct lu_env *env,
2260 struct mgs_device *mgs,
2262 struct mgs_target_info *mti)
2264 struct mgs_thread_info *mgi = mgs_env_info(env);
2265 struct llog_handle *llh = NULL;
2270 CDEBUG(D_MGS, "writing new mdt %s\n", mti->mti_svname);
2272 if (mti->mti_uuid[0] == '\0') {
2273 /* Make up our own uuid */
2274 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
2275 "%s_UUID", mti->mti_svname);
2279 rc = mgs_write_log_mdt0(env, mgs, fsdb, mti);
2282 /* Append the mdt info to the client log */
2283 rc = name_create(&cliname, mti->mti_fsname, "-client");
2287 if (mgs_log_is_empty(env, mgs, cliname)) {
2288 /* Start client log */
2289 rc = mgs_write_log_lov(env, mgs, fsdb, mti, cliname,
2293 rc = mgs_write_log_lmv(env, mgs, fsdb, mti, cliname,
2300 #09 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
2301 #10 L attach 0:MDC_uml1_mdsA_MNT_client 1:mdc 2:1d834_MNT_client_03f
2302 #11 L setup 0:MDC_uml1_mdsA_MNT_client 1:mdsA_UUID 2:uml1_UUID
2303 #12 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
2304 #13 L add_conn 0:MDC_uml1_mdsA_MNT_client 1:uml2_UUID
2305 #14 L mount_option 0: 1:client 2:lov1 3:MDC_uml1_mdsA_MNT_client
2308 /* copy client info about lov/lmv */
2309 mgi->mgi_comp.comp_mti = mti;
2310 mgi->mgi_comp.comp_fsdb = fsdb;
2312 rc = mgs_steal_llog_for_mdt_from_client(env, mgs, cliname,
2316 rc = mgs_write_log_mdc_to_lmv(env, mgs, fsdb, mti, cliname,
2322 rc = record_start_log(env, mgs, &llh, cliname);
2326 rc = record_marker(env, llh, fsdb, CM_START, cliname,
2330 rc = record_mount_opt(env, llh, cliname, fsdb->fsdb_clilov,
2334 rc = record_marker(env, llh, fsdb, CM_END, cliname,
2340 /* for_all_existing_mdt except current one */
2341 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2342 if (i != mti->mti_stripe_index &&
2343 test_bit(i, fsdb->fsdb_mdt_index_map)) {
2346 rc = name_create_mdt(&logname, fsdb->fsdb_name, i);
2350 rc = mgs_write_log_osp_to_mdt(env, mgs, fsdb, mti,
2352 name_destroy(&logname);
2358 record_end_log(env, &llh);
2360 name_destroy(&cliname);
2364 /* Add the ost info to the client/mdt lov */
2365 static int mgs_write_log_osc_to_lov(const struct lu_env *env,
2366 struct mgs_device *mgs, struct fs_db *fsdb,
2367 struct mgs_target_info *mti,
2368 char *logname, char *suffix, char *lovname,
2369 enum lustre_sec_part sec_part, int flags)
2371 struct llog_handle *llh = NULL;
2372 char *nodeuuid = NULL;
2373 char *oscname = NULL;
2374 char *oscuuid = NULL;
2375 char *lovuuid = NULL;
2376 char *svname = NULL;
2381 CDEBUG(D_INFO, "adding osc for %s to log %s\n",
2382 mti->mti_svname, logname);
2384 if (mgs_log_is_empty(env, mgs, logname)) {
2385 CERROR("log is empty! Logical error\n");
2389 rc = name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
2392 rc = name_create(&svname, mti->mti_svname, "-osc");
2396 /* for the system upgraded from old 1.8, keep using the old osc naming
2397 * style for mdt, see name_create_mdt_osc(). LU-1257 */
2398 if (test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2399 rc = name_create(&oscname, svname, "");
2401 rc = name_create(&oscname, svname, suffix);
2405 rc = name_create(&oscuuid, oscname, "_UUID");
2408 rc = name_create(&lovuuid, lovname, "_UUID");
2414 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
2416 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
2417 #04 L attach 0:OSC_uml1_ost1_MNT_client 1:osc 2:89070_lov1_a41dff51a
2418 #05 L setup 0:OSC_uml1_ost1_MNT_client 1:ost1_UUID 2:uml1_UUID
2420 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
2421 #07 L add_conn 0:OSC_uml1_ost1_MNT_client 1:uml2_UUID
2422 #08 L lov_modify_tgts add 0:lov1 1:ost1_UUID 2(index):0 3(gen):1
2425 rc = record_start_log(env, mgs, &llh, logname);
2429 /* FIXME these should be a single journal transaction */
2430 rc = record_marker(env, llh, fsdb, CM_START | flags, mti->mti_svname,
2435 /* NB: don't change record order, because upon MDT steal OSC config
2436 * from client, it treats all nids before LCFG_SETUP as target nids
2437 * (multiple interfaces), while nids after as failover node nids.
2438 * See mgs_steal_client_llog_handler() LCFG_ADD_UUID.
2440 for (i = 0; i < mti->mti_nid_count; i++) {
2441 CDEBUG(D_MGS, "add nid %s\n", libcfs_nid2str(mti->mti_nids[i]));
2442 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
2446 rc = record_attach(env, llh, oscname, LUSTRE_OSC_NAME, lovuuid);
2449 rc = record_setup(env, llh, oscname, mti->mti_uuid, nodeuuid, 0, 0);
2452 rc = mgs_write_log_failnids(env, mti, llh, oscname);
2456 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
2458 rc = record_lov_add(env, llh, lovname, mti->mti_uuid, index, "1");
2461 rc = record_marker(env, llh, fsdb, CM_END | flags, mti->mti_svname,
2466 record_end_log(env, &llh);
2468 name_destroy(&lovuuid);
2469 name_destroy(&oscuuid);
2470 name_destroy(&oscname);
2471 name_destroy(&svname);
2472 name_destroy(&nodeuuid);
2476 static int mgs_write_log_ost(const struct lu_env *env,
2477 struct mgs_device *mgs, struct fs_db *fsdb,
2478 struct mgs_target_info *mti)
2480 struct llog_handle *llh = NULL;
2481 char *logname, *lovname;
2482 char *ptr = mti->mti_params;
2483 int rc, flags = 0, failout = 0, i;
2486 CDEBUG(D_MGS, "writing new ost %s\n", mti->mti_svname);
2488 /* The ost startup log */
2490 /* If the ost log already exists, that means that someone reformatted
2491 the ost and it called target_add again. */
2492 if (!mgs_log_is_empty(env, mgs, mti->mti_svname)) {
2493 LCONSOLE_ERROR_MSG(0x141, "The config log for %s already "
2494 "exists, yet the server claims it never "
2495 "registered. It may have been reformatted, "
2496 "or the index changed. writeconf the MDT to "
2497 "regenerate all logs.\n", mti->mti_svname);
2502 attach obdfilter ost1 ost1_UUID
2503 setup /dev/loop2 ldiskfs f|n errors=remount-ro,user_xattr
2505 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
2506 failout = (strncmp(ptr, "failout", 7) == 0);
2507 rc = record_start_log(env, mgs, &llh, mti->mti_svname);
2510 /* FIXME these should be a single journal transaction */
2511 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,"add ost");
2514 if (*mti->mti_uuid == '\0')
2515 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
2516 "%s_UUID", mti->mti_svname);
2517 rc = record_attach(env, llh, mti->mti_svname,
2518 "obdfilter"/*LUSTRE_OST_NAME*/, mti->mti_uuid);
2521 rc = record_setup(env, llh, mti->mti_svname,
2522 "dev"/*ignored*/, "type"/*ignored*/,
2523 failout ? "n" : "f", 0/*options*/);
2526 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname, "add ost");
2530 record_end_log(env, &llh);
2533 /* We also have to update the other logs where this osc is part of
2536 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
2537 /* If we're upgrading, the old mdt log already has our
2538 entry. Let's do a fake one for fun. */
2539 /* Note that we can't add any new failnids, since we don't
2540 know the old osc names. */
2541 flags = CM_SKIP | CM_UPGRADE146;
2543 } else if ((mti->mti_flags & LDD_F_UPDATE) != LDD_F_UPDATE) {
2544 /* If the update flag isn't set, don't update client/mdt
2547 LCONSOLE_WARN("Client log for %s was not updated; writeconf "
2548 "the MDT first to regenerate it.\n",
2552 /* Add ost to all MDT lov defs */
2553 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
2554 if (test_bit(i, fsdb->fsdb_mdt_index_map)) {
2557 rc = name_create_mdt_and_lov(&logname, &lovname, fsdb,
2561 sprintf(mdt_index, "-MDT%04x", i);
2562 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, mti,
2564 lovname, LUSTRE_SP_MDT,
2566 name_destroy(&logname);
2567 name_destroy(&lovname);
2573 /* Append ost info to the client log */
2574 rc = name_create(&logname, mti->mti_fsname, "-client");
2577 if (mgs_log_is_empty(env, mgs, logname)) {
2578 /* Start client log */
2579 rc = mgs_write_log_lov(env, mgs, fsdb, mti, logname,
2583 rc = mgs_write_log_lmv(env, mgs, fsdb, mti, logname,
2588 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, mti, logname, "",
2589 fsdb->fsdb_clilov, LUSTRE_SP_CLI, 0);
2591 name_destroy(&logname);
2595 static __inline__ int mgs_param_empty(char *ptr)
2599 if ((tmp = strchr(ptr, '=')) && (*(++tmp) == '\0'))
2604 static int mgs_write_log_failnid_internal(const struct lu_env *env,
2605 struct mgs_device *mgs,
2607 struct mgs_target_info *mti,
2608 char *logname, char *cliname)
2611 struct llog_handle *llh = NULL;
2613 if (mgs_param_empty(mti->mti_params)) {
2614 /* Remove _all_ failnids */
2615 rc = mgs_modify(env, mgs, fsdb, mti, logname,
2616 mti->mti_svname, "add failnid", CM_SKIP);
2617 return rc < 0 ? rc : 0;
2620 /* Otherwise failover nids are additive */
2621 rc = record_start_log(env, mgs, &llh, logname);
2624 /* FIXME this should be a single journal transaction */
2625 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
2629 rc = mgs_write_log_failnids(env, mti, llh, cliname);
2632 rc = record_marker(env, llh, fsdb, CM_END,
2633 mti->mti_svname, "add failnid");
2635 record_end_log(env, &llh);
2640 /* Add additional failnids to an existing log.
2641 The mdc/osc must have been added to logs first */
2642 /* tcp nids must be in dotted-quad ascii -
2643 we can't resolve hostnames from the kernel. */
2644 static int mgs_write_log_add_failnid(const struct lu_env *env,
2645 struct mgs_device *mgs,
2647 struct mgs_target_info *mti)
2649 char *logname, *cliname;
2653 /* FIXME we currently can't erase the failnids
2654 * given when a target first registers, since they aren't part of
2655 * an "add uuid" stanza */
2657 /* Verify that we know about this target */
2658 if (mgs_log_is_empty(env, mgs, mti->mti_svname)) {
2659 LCONSOLE_ERROR_MSG(0x142, "The target %s has not registered "
2660 "yet. It must be started before failnids "
2661 "can be added.\n", mti->mti_svname);
2665 /* Create mdc/osc client name (e.g. lustre-OST0001-osc) */
2666 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
2667 rc = name_create(&cliname, mti->mti_svname, "-mdc");
2668 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2669 rc = name_create(&cliname, mti->mti_svname, "-osc");
2675 /* Add failover nids to the client log */
2676 rc = name_create(&logname, mti->mti_fsname, "-client");
2678 name_destroy(&cliname);
2681 rc = mgs_write_log_failnid_internal(env, mgs, fsdb,mti,logname,cliname);
2682 name_destroy(&logname);
2683 name_destroy(&cliname);
2687 if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2688 /* Add OST failover nids to the MDT logs as well */
2691 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2692 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
2694 rc = name_create_mdt(&logname, mti->mti_fsname, i);
2697 rc = name_create_mdt_osc(&cliname, mti->mti_svname,
2700 name_destroy(&logname);
2703 rc = mgs_write_log_failnid_internal(env, mgs, fsdb,
2706 name_destroy(&cliname);
2707 name_destroy(&logname);
2716 static int mgs_wlp_lcfg(const struct lu_env *env,
2717 struct mgs_device *mgs, struct fs_db *fsdb,
2718 struct mgs_target_info *mti,
2719 char *logname, struct lustre_cfg_bufs *bufs,
2720 char *tgtname, char *ptr)
2722 char comment[MTI_NAME_MAXLEN];
2724 struct lustre_cfg *lcfg;
2727 /* Erase any old settings of this same parameter */
2728 memcpy(comment, ptr, MTI_NAME_MAXLEN);
2729 comment[MTI_NAME_MAXLEN - 1] = 0;
2730 /* But don't try to match the value. */
2731 tmp = strchr(comment, '=');
2734 /* FIXME we should skip settings that are the same as old values */
2735 rc = mgs_modify(env, mgs, fsdb, mti, logname, tgtname, comment,CM_SKIP);
2738 del = mgs_param_empty(ptr);
2740 LCONSOLE_INFO("%s parameter %s.%s in log %s\n", del ? "Disabling" : rc ?
2741 "Setting" : "Modifying", tgtname, comment, logname);
2743 /* mgs_modify() will return 1 if nothing had to be done */
2749 lustre_cfg_bufs_reset(bufs, tgtname);
2750 lustre_cfg_bufs_set_string(bufs, 1, ptr);
2751 if (mti->mti_flags & LDD_F_PARAM2)
2752 lustre_cfg_bufs_set_string(bufs, 2, LCTL_UPCALL);
2754 lcfg = lustre_cfg_new((mti->mti_flags & LDD_F_PARAM2) ?
2755 LCFG_SET_PARAM : LCFG_PARAM, bufs);
2759 rc = mgs_write_log_direct(env, mgs, fsdb, logname,lcfg,tgtname,comment);
2760 lustre_cfg_free(lcfg);
2764 static int mgs_write_log_param2(const struct lu_env *env,
2765 struct mgs_device *mgs,
2767 struct mgs_target_info *mti, char *ptr)
2769 struct lustre_cfg_bufs bufs;
2773 CDEBUG(D_MGS, "next param '%s'\n", ptr);
2774 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, PARAMS_FILENAME, &bufs,
2775 mti->mti_svname, ptr);
2780 /* write global variable settings into log */
2781 static int mgs_write_log_sys(const struct lu_env *env,
2782 struct mgs_device *mgs, struct fs_db *fsdb,
2783 struct mgs_target_info *mti, char *sys, char *ptr)
2785 struct mgs_thread_info *mgi = mgs_env_info(env);
2786 struct lustre_cfg *lcfg;
2788 int rc, cmd, convert = 1;
2790 if (class_match_param(ptr, PARAM_TIMEOUT, &tmp) == 0) {
2791 cmd = LCFG_SET_TIMEOUT;
2792 } else if (class_match_param(ptr, PARAM_LDLM_TIMEOUT, &tmp) == 0) {
2793 cmd = LCFG_SET_LDLM_TIMEOUT;
2794 /* Check for known params here so we can return error to lctl */
2795 } else if ((class_match_param(ptr, PARAM_AT_MIN, &tmp) == 0) ||
2796 (class_match_param(ptr, PARAM_AT_MAX, &tmp) == 0) ||
2797 (class_match_param(ptr, PARAM_AT_EXTRA, &tmp) == 0) ||
2798 (class_match_param(ptr, PARAM_AT_EARLY_MARGIN, &tmp) == 0) ||
2799 (class_match_param(ptr, PARAM_AT_HISTORY, &tmp) == 0)) {
2801 } else if (class_match_param(ptr, PARAM_JOBID_VAR, &tmp) == 0) {
2802 convert = 0; /* Don't convert string value to integer */
2808 if (mgs_param_empty(ptr))
2809 CDEBUG(D_MGS, "global '%s' removed\n", sys);
2811 CDEBUG(D_MGS, "global '%s' val=%s\n", sys, tmp);
2813 lustre_cfg_bufs_reset(&mgi->mgi_bufs, NULL);
2814 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, sys);
2815 if (!convert && *tmp != '\0')
2816 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 2, tmp);
2817 lcfg = lustre_cfg_new(cmd, &mgi->mgi_bufs);
2818 lcfg->lcfg_num = convert ? simple_strtoul(tmp, NULL, 0) : 0;
2819 /* truncate the comment to the parameter name */
2823 /* modify all servers and clients */
2824 rc = mgs_write_log_direct_all(env, mgs, fsdb, mti,
2825 *tmp == '\0' ? NULL : lcfg,
2826 mti->mti_fsname, sys, 0);
2827 if (rc == 0 && *tmp != '\0') {
2829 case LCFG_SET_TIMEOUT:
2830 if (!obd_timeout_set || lcfg->lcfg_num > obd_timeout)
2831 class_process_config(lcfg);
2833 case LCFG_SET_LDLM_TIMEOUT:
2834 if (!ldlm_timeout_set || lcfg->lcfg_num > ldlm_timeout)
2835 class_process_config(lcfg);
2842 lustre_cfg_free(lcfg);
2846 /* write quota settings into log */
2847 static int mgs_write_log_quota(const struct lu_env *env, struct mgs_device *mgs,
2848 struct fs_db *fsdb, struct mgs_target_info *mti,
2849 char *quota, char *ptr)
2851 struct mgs_thread_info *mgi = mgs_env_info(env);
2852 struct lustre_cfg *lcfg;
2855 int rc, cmd = LCFG_PARAM;
2857 /* support only 'meta' and 'data' pools so far */
2858 if (class_match_param(ptr, QUOTA_METAPOOL_NAME, &tmp) != 0 &&
2859 class_match_param(ptr, QUOTA_DATAPOOL_NAME, &tmp) != 0) {
2860 CERROR("parameter quota.%s isn't supported (only quota.mdt "
2861 "& quota.ost are)\n", ptr);
2866 CDEBUG(D_MGS, "global '%s' removed\n", quota);
2868 CDEBUG(D_MGS, "global '%s'\n", quota);
2870 if (strchr(tmp, 'u') == NULL && strchr(tmp, 'g') == NULL &&
2871 strcmp(tmp, "none") != 0) {
2872 CERROR("enable option(%s) isn't supported\n", tmp);
2877 lustre_cfg_bufs_reset(&mgi->mgi_bufs, mti->mti_fsname);
2878 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, quota);
2879 lcfg = lustre_cfg_new(cmd, &mgi->mgi_bufs);
2880 /* truncate the comment to the parameter name */
2885 /* XXX we duplicated quota enable information in all server
2886 * config logs, it should be moved to a separate config
2887 * log once we cleanup the config log for global param. */
2888 /* modify all servers */
2889 rc = mgs_write_log_direct_all(env, mgs, fsdb, mti,
2890 *tmp == '\0' ? NULL : lcfg,
2891 mti->mti_fsname, quota, 1);
2893 lustre_cfg_free(lcfg);
2894 return rc < 0 ? rc : 0;
2897 static int mgs_srpc_set_param_disk(const struct lu_env *env,
2898 struct mgs_device *mgs,
2900 struct mgs_target_info *mti,
2903 struct mgs_thread_info *mgi = mgs_env_info(env);
2904 struct llog_handle *llh = NULL;
2906 char *comment, *ptr;
2907 struct lustre_cfg *lcfg;
2912 ptr = strchr(param, '=');
2916 OBD_ALLOC(comment, len + 1);
2917 if (comment == NULL)
2919 strncpy(comment, param, len);
2920 comment[len] = '\0';
2923 lustre_cfg_bufs_reset(&mgi->mgi_bufs, mti->mti_svname);
2924 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, param);
2925 lcfg = lustre_cfg_new(LCFG_SPTLRPC_CONF, &mgi->mgi_bufs);
2927 GOTO(out_comment, rc = -ENOMEM);
2929 /* construct log name */
2930 rc = name_create(&logname, mti->mti_fsname, "-sptlrpc");
2934 if (mgs_log_is_empty(env, mgs, logname)) {
2935 rc = record_start_log(env, mgs, &llh, logname);
2938 record_end_log(env, &llh);
2941 /* obsolete old one */
2942 rc = mgs_modify(env, mgs, fsdb, mti, logname, mti->mti_svname,
2946 /* write the new one */
2947 rc = mgs_write_log_direct(env, mgs, fsdb, logname, lcfg,
2948 mti->mti_svname, comment);
2950 CERROR("err %d writing log %s\n", rc, logname);
2952 name_destroy(&logname);
2954 lustre_cfg_free(lcfg);
2956 OBD_FREE(comment, len + 1);
2960 static int mgs_srpc_set_param_udesc_mem(struct fs_db *fsdb,
2965 /* disable the adjustable udesc parameter for now, i.e. use default
2966 * setting that client always ship udesc to MDT if possible. to enable
2967 * it simply remove the following line */
2970 ptr = strchr(param, '=');
2975 if (strcmp(param, PARAM_SRPC_UDESC))
2978 if (strcmp(ptr, "yes") == 0) {
2979 set_bit(FSDB_UDESC, &fsdb->fsdb_flags);
2980 CWARN("Enable user descriptor shipping from client to MDT\n");
2981 } else if (strcmp(ptr, "no") == 0) {
2982 clear_bit(FSDB_UDESC, &fsdb->fsdb_flags);
2983 CWARN("Disable user descriptor shipping from client to MDT\n");
2991 CERROR("Invalid param: %s\n", param);
2995 static int mgs_srpc_set_param_mem(struct fs_db *fsdb,
2999 struct sptlrpc_rule rule;
3000 struct sptlrpc_rule_set *rset;
3004 if (strncmp(param, PARAM_SRPC, sizeof(PARAM_SRPC) - 1) != 0) {
3005 CERROR("Invalid sptlrpc parameter: %s\n", param);
3009 if (strncmp(param, PARAM_SRPC_UDESC,
3010 sizeof(PARAM_SRPC_UDESC) - 1) == 0) {
3011 RETURN(mgs_srpc_set_param_udesc_mem(fsdb, param));
3014 if (strncmp(param, PARAM_SRPC_FLVR, sizeof(PARAM_SRPC_FLVR) - 1) != 0) {
3015 CERROR("Invalid sptlrpc flavor parameter: %s\n", param);
3019 param += sizeof(PARAM_SRPC_FLVR) - 1;
3021 rc = sptlrpc_parse_rule(param, &rule);
3025 /* mgs rules implies must be mgc->mgs */
3026 if (test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
3027 if ((rule.sr_from != LUSTRE_SP_MGC &&
3028 rule.sr_from != LUSTRE_SP_ANY) ||
3029 (rule.sr_to != LUSTRE_SP_MGS &&
3030 rule.sr_to != LUSTRE_SP_ANY))
3034 /* preapre room for this coming rule. svcname format should be:
3035 * - fsname: general rule
3036 * - fsname-tgtname: target-specific rule
3038 if (strchr(svname, '-')) {
3039 struct mgs_tgt_srpc_conf *tgtconf;
3042 for (tgtconf = fsdb->fsdb_srpc_tgt; tgtconf != NULL;
3043 tgtconf = tgtconf->mtsc_next) {
3044 if (!strcmp(tgtconf->mtsc_tgt, svname)) {
3053 OBD_ALLOC_PTR(tgtconf);
3054 if (tgtconf == NULL)
3057 name_len = strlen(svname);
3059 OBD_ALLOC(tgtconf->mtsc_tgt, name_len + 1);
3060 if (tgtconf->mtsc_tgt == NULL) {
3061 OBD_FREE_PTR(tgtconf);
3064 memcpy(tgtconf->mtsc_tgt, svname, name_len);
3066 tgtconf->mtsc_next = fsdb->fsdb_srpc_tgt;
3067 fsdb->fsdb_srpc_tgt = tgtconf;
3070 rset = &tgtconf->mtsc_rset;
3072 rset = &fsdb->fsdb_srpc_gen;
3075 rc = sptlrpc_rule_set_merge(rset, &rule);
3080 static int mgs_srpc_set_param(const struct lu_env *env,
3081 struct mgs_device *mgs,
3083 struct mgs_target_info *mti,
3093 /* keep a copy of original param, which could be destroied
3095 copy_size = strlen(param) + 1;
3096 OBD_ALLOC(copy, copy_size);
3099 memcpy(copy, param, copy_size);
3101 rc = mgs_srpc_set_param_mem(fsdb, mti->mti_svname, param);
3105 /* previous steps guaranteed the syntax is correct */
3106 rc = mgs_srpc_set_param_disk(env, mgs, fsdb, mti, copy);
3110 if (test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
3112 * for mgs rules, make them effective immediately.
3114 LASSERT(fsdb->fsdb_srpc_tgt == NULL);
3115 sptlrpc_target_update_exp_flavor(mgs->mgs_obd,
3116 &fsdb->fsdb_srpc_gen);
3120 OBD_FREE(copy, copy_size);
3124 struct mgs_srpc_read_data {
3125 struct fs_db *msrd_fsdb;
3129 static int mgs_srpc_read_handler(const struct lu_env *env,
3130 struct llog_handle *llh,
3131 struct llog_rec_hdr *rec, void *data)
3133 struct mgs_srpc_read_data *msrd = data;
3134 struct cfg_marker *marker;
3135 struct lustre_cfg *lcfg = REC_DATA(rec);
3136 char *svname, *param;
3140 if (rec->lrh_type != OBD_CFG_REC) {
3141 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
3145 cfg_len = rec->lrh_len - sizeof(struct llog_rec_hdr) -
3146 sizeof(struct llog_rec_tail);
3148 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
3150 CERROR("Insane cfg\n");
3154 if (lcfg->lcfg_command == LCFG_MARKER) {
3155 marker = lustre_cfg_buf(lcfg, 1);
3157 if (marker->cm_flags & CM_START &&
3158 marker->cm_flags & CM_SKIP)
3159 msrd->msrd_skip = 1;
3160 if (marker->cm_flags & CM_END)
3161 msrd->msrd_skip = 0;
3166 if (msrd->msrd_skip)
3169 if (lcfg->lcfg_command != LCFG_SPTLRPC_CONF) {
3170 CERROR("invalid command (%x)\n", lcfg->lcfg_command);
3174 svname = lustre_cfg_string(lcfg, 0);
3175 if (svname == NULL) {
3176 CERROR("svname is empty\n");
3180 param = lustre_cfg_string(lcfg, 1);
3181 if (param == NULL) {
3182 CERROR("param is empty\n");
3186 rc = mgs_srpc_set_param_mem(msrd->msrd_fsdb, svname, param);
3188 CERROR("read sptlrpc record error (%d): %s\n", rc, param);
3193 int mgs_get_fsdb_srpc_from_llog(const struct lu_env *env,
3194 struct mgs_device *mgs,
3197 struct llog_handle *llh = NULL;
3198 struct llog_ctxt *ctxt;
3200 struct mgs_srpc_read_data msrd;
3204 /* construct log name */
3205 rc = name_create(&logname, fsdb->fsdb_name, "-sptlrpc");
3209 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
3210 LASSERT(ctxt != NULL);
3212 if (mgs_log_is_empty(env, mgs, logname))
3215 rc = llog_open(env, ctxt, &llh, NULL, logname,
3223 rc = llog_init_handle(env, llh, LLOG_F_IS_PLAIN, NULL);
3225 GOTO(out_close, rc);
3227 if (llog_get_size(llh) <= 1)
3228 GOTO(out_close, rc = 0);
3230 msrd.msrd_fsdb = fsdb;
3233 rc = llog_process(env, llh, mgs_srpc_read_handler, (void *)&msrd,
3237 llog_close(env, llh);
3239 llog_ctxt_put(ctxt);
3240 name_destroy(&logname);
3243 CERROR("failed to read sptlrpc config database: %d\n", rc);
3247 /* Permanent settings of all parameters by writing into the appropriate
3248 * configuration logs.
3249 * A parameter with null value ("<param>='\0'") means to erase it out of
3252 static int mgs_write_log_param(const struct lu_env *env,
3253 struct mgs_device *mgs, struct fs_db *fsdb,
3254 struct mgs_target_info *mti, char *ptr)
3256 struct mgs_thread_info *mgi = mgs_env_info(env);
3259 int rc = 0, rc2 = 0;
3262 /* For various parameter settings, we have to figure out which logs
3263 care about them (e.g. both mdt and client for lov settings) */
3264 CDEBUG(D_MGS, "next param '%s'\n", ptr);
3266 /* The params are stored in MOUNT_DATA_FILE and modified via
3267 tunefs.lustre, or set using lctl conf_param */
3269 /* Processed in lustre_start_mgc */
3270 if (class_match_param(ptr, PARAM_MGSNODE, NULL) == 0)
3273 /* Processed in ost/mdt */
3274 if (class_match_param(ptr, PARAM_NETWORK, NULL) == 0)
3277 /* Processed in mgs_write_log_ost */
3278 if (class_match_param(ptr, PARAM_FAILMODE, NULL) == 0) {
3279 if (mti->mti_flags & LDD_F_PARAM) {
3280 LCONSOLE_ERROR_MSG(0x169, "%s can only be "
3281 "changed with tunefs.lustre"
3282 "and --writeconf\n", ptr);
3288 if (class_match_param(ptr, PARAM_SRPC, NULL) == 0) {
3289 rc = mgs_srpc_set_param(env, mgs, fsdb, mti, ptr);
3293 if (class_match_param(ptr, PARAM_FAILNODE, NULL) == 0) {
3294 /* Add a failover nidlist */
3296 /* We already processed failovers params for new
3297 targets in mgs_write_log_target */
3298 if (mti->mti_flags & LDD_F_PARAM) {
3299 CDEBUG(D_MGS, "Adding failnode\n");
3300 rc = mgs_write_log_add_failnid(env, mgs, fsdb, mti);
3305 if (class_match_param(ptr, PARAM_SYS, &tmp) == 0) {
3306 rc = mgs_write_log_sys(env, mgs, fsdb, mti, ptr, tmp);
3310 if (class_match_param(ptr, PARAM_QUOTA, &tmp) == 0) {
3311 rc = mgs_write_log_quota(env, mgs, fsdb, mti, ptr, tmp);
3315 if (class_match_param(ptr, PARAM_OSC""PARAM_ACTIVE, &tmp) == 0) {
3316 /* active=0 means off, anything else means on */
3317 int flag = (*tmp == '0') ? CM_EXCLUDE : 0;
3320 if (!(mti->mti_flags & LDD_F_SV_TYPE_OST)) {
3321 LCONSOLE_ERROR_MSG(0x144, "%s: Only OSCs can "
3322 "be (de)activated.\n",
3324 GOTO(end, rc = -EINVAL);
3326 LCONSOLE_WARN("Permanently %sactivating %s\n",
3327 flag ? "de": "re", mti->mti_svname);
3329 rc = name_create(&logname, mti->mti_fsname, "-client");
3332 rc = mgs_modify(env, mgs, fsdb, mti, logname,
3333 mti->mti_svname, "add osc", flag);
3334 name_destroy(&logname);
3338 /* Add to all MDT logs for CMD */
3339 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3340 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
3342 rc = name_create_mdt(&logname, mti->mti_fsname, i);
3345 rc = mgs_modify(env, mgs, fsdb, mti, logname,
3346 mti->mti_svname, "add osc", flag);
3347 name_destroy(&logname);
3353 LCONSOLE_ERROR_MSG(0x145, "Couldn't find %s in"
3354 "log (%d). No permanent "
3355 "changes were made to the "
3357 mti->mti_svname, rc);
3358 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags))
3359 LCONSOLE_ERROR_MSG(0x146, "This may be"
3364 "update the logs.\n");
3367 /* Fall through to osc proc for deactivating live OSC
3368 on running MDT / clients. */
3370 /* Below here, let obd's XXX_process_config methods handle it */
3372 /* All lov. in proc */
3373 if (class_match_param(ptr, PARAM_LOV, NULL) == 0) {
3376 CDEBUG(D_MGS, "lov param %s\n", ptr);
3377 if (!(mti->mti_flags & LDD_F_SV_TYPE_MDT)) {
3378 LCONSOLE_ERROR_MSG(0x147, "LOV params must be "
3379 "set on the MDT, not %s. "
3386 if (mgs_log_is_empty(env, mgs, mti->mti_svname))
3387 GOTO(end, rc = -ENODEV);
3389 rc = name_create_mdt_and_lov(&logname, &mdtlovname, fsdb,
3390 mti->mti_stripe_index);
3393 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, mti->mti_svname,
3394 &mgi->mgi_bufs, mdtlovname, ptr);
3395 name_destroy(&logname);
3396 name_destroy(&mdtlovname);
3401 rc = name_create(&logname, mti->mti_fsname, "-client");
3404 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname, &mgi->mgi_bufs,
3405 fsdb->fsdb_clilov, ptr);
3406 name_destroy(&logname);
3410 /* All osc., mdc., llite. params in proc */
3411 if ((class_match_param(ptr, PARAM_OSC, NULL) == 0) ||
3412 (class_match_param(ptr, PARAM_MDC, NULL) == 0) ||
3413 (class_match_param(ptr, PARAM_LLITE, NULL) == 0)) {
3416 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
3417 LCONSOLE_ERROR_MSG(0x148, "Upgraded client logs for %s"
3418 " cannot be modified. Consider"
3419 " updating the configuration with"
3422 GOTO(end, rc = -EINVAL);
3424 if (memcmp(ptr, PARAM_LLITE, strlen(PARAM_LLITE)) == 0) {
3425 rc = name_create(&cname, mti->mti_fsname, "-client");
3426 /* Add the client type to match the obdname in
3427 class_config_llog_handler */
3428 } else if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
3429 rc = name_create(&cname, mti->mti_svname, "-mdc");
3430 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
3431 rc = name_create(&cname, mti->mti_svname, "-osc");
3433 GOTO(end, rc = -EINVAL);
3438 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
3441 rc = name_create(&logname, mti->mti_fsname, "-client");
3443 name_destroy(&cname);
3446 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname, &mgi->mgi_bufs,
3449 /* osc params affect the MDT as well */
3450 if (!rc && (mti->mti_flags & LDD_F_SV_TYPE_OST)) {
3453 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
3454 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
3456 name_destroy(&cname);
3457 rc = name_create_mdt_osc(&cname, mti->mti_svname,
3459 name_destroy(&logname);
3462 rc = name_create_mdt(&logname,
3463 mti->mti_fsname, i);
3466 if (!mgs_log_is_empty(env, mgs, logname)) {
3467 rc = mgs_wlp_lcfg(env, mgs, fsdb,
3476 name_destroy(&logname);
3477 name_destroy(&cname);
3481 /* All mdt. params in proc */
3482 if (class_match_param(ptr, PARAM_MDT, NULL) == 0) {
3486 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
3487 if (strncmp(mti->mti_svname, mti->mti_fsname,
3488 MTI_NAME_MAXLEN) == 0)
3489 /* device is unspecified completely? */
3490 rc = LDD_F_SV_TYPE_MDT | LDD_F_SV_ALL;
3492 rc = server_name2index(mti->mti_svname, &idx, NULL);
3495 if ((rc & LDD_F_SV_TYPE_MDT) == 0)
3497 if (rc & LDD_F_SV_ALL) {
3498 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3500 fsdb->fsdb_mdt_index_map))
3502 rc = name_create_mdt(&logname,
3503 mti->mti_fsname, i);
3506 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti,
3507 logname, &mgi->mgi_bufs,
3509 name_destroy(&logname);
3514 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti,
3515 mti->mti_svname, &mgi->mgi_bufs,
3516 mti->mti_svname, ptr);
3523 /* All mdd., ost. and osd. params in proc */
3524 if ((class_match_param(ptr, PARAM_MDD, NULL) == 0) ||
3525 (class_match_param(ptr, PARAM_OST, NULL) == 0) ||
3526 (class_match_param(ptr, PARAM_OSD, NULL) == 0)) {
3527 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
3528 if (mgs_log_is_empty(env, mgs, mti->mti_svname))
3529 GOTO(end, rc = -ENODEV);
3531 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, mti->mti_svname,
3532 &mgi->mgi_bufs, mti->mti_svname, ptr);
3536 LCONSOLE_WARN("Ignoring unrecognized param '%s'\n", ptr);
3541 CERROR("err %d on param '%s'\n", rc, ptr);
3546 /* Not implementing automatic failover nid addition at this time. */
3547 int mgs_check_failnid(const struct lu_env *env, struct mgs_device *mgs,
3548 struct mgs_target_info *mti)
3555 rc = mgs_find_or_make_fsdb(obd, fsname, &fsdb);
3559 if (mgs_log_is_empty(obd, mti->mti_svname))
3560 /* should never happen */
3563 CDEBUG(D_MGS, "Checking for new failnids for %s\n", mti->mti_svname);
3565 /* FIXME We can just check mti->params to see if we're already in
3566 the failover list. Modify mti->params for rewriting back at
3567 server_register_target(). */
3569 mutex_lock(&fsdb->fsdb_mutex);
3570 rc = mgs_write_log_add_failnid(obd, fsdb, mti);
3571 mutex_unlock(&fsdb->fsdb_mutex);
3578 int mgs_write_log_target(const struct lu_env *env,
3579 struct mgs_device *mgs,
3580 struct mgs_target_info *mti,
3587 /* set/check the new target index */
3588 rc = mgs_set_index(env, mgs, mti);
3590 CERROR("Can't get index (%d)\n", rc);
3594 if (rc == EALREADY) {
3595 LCONSOLE_WARN("Found index %d for %s, updating log\n",
3596 mti->mti_stripe_index, mti->mti_svname);
3597 /* We would like to mark old log sections as invalid
3598 and add new log sections in the client and mdt logs.
3599 But if we add new sections, then live clients will
3600 get repeat setup instructions for already running
3601 osc's. So don't update the client/mdt logs. */
3602 mti->mti_flags &= ~LDD_F_UPDATE;
3606 mutex_lock(&fsdb->fsdb_mutex);
3608 if (mti->mti_flags &
3609 (LDD_F_VIRGIN | LDD_F_UPGRADE14 | LDD_F_WRITECONF)) {
3610 /* Generate a log from scratch */
3611 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
3612 rc = mgs_write_log_mdt(env, mgs, fsdb, mti);
3613 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
3614 rc = mgs_write_log_ost(env, mgs, fsdb, mti);
3616 CERROR("Unknown target type %#x, can't create log for "
3617 "%s\n", mti->mti_flags, mti->mti_svname);
3620 CERROR("Can't write logs for %s (%d)\n",
3621 mti->mti_svname, rc);
3625 /* Just update the params from tunefs in mgs_write_log_params */
3626 CDEBUG(D_MGS, "Update params for %s\n", mti->mti_svname);
3627 mti->mti_flags |= LDD_F_PARAM;
3630 /* allocate temporary buffer, where class_get_next_param will
3631 make copy of a current parameter */
3632 OBD_ALLOC(buf, strlen(mti->mti_params) + 1);
3634 GOTO(out_up, rc = -ENOMEM);
3635 params = mti->mti_params;
3636 while (params != NULL) {
3637 rc = class_get_next_param(¶ms, buf);
3640 /* there is no next parameter, that is
3645 CDEBUG(D_MGS, "remaining string: '%s', param: '%s'\n",
3647 rc = mgs_write_log_param(env, mgs, fsdb, mti, buf);
3652 OBD_FREE(buf, strlen(mti->mti_params) + 1);
3655 mutex_unlock(&fsdb->fsdb_mutex);
3659 int mgs_erase_log(const struct lu_env *env, struct mgs_device *mgs, char *name)
3661 struct llog_ctxt *ctxt;
3664 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
3666 CERROR("%s: MGS config context doesn't exist\n",
3667 mgs->mgs_obd->obd_name);
3670 rc = llog_erase(env, ctxt, NULL, name);
3671 /* llog may not exist */
3674 llog_ctxt_put(ctxt);
3678 CERROR("%s: failed to clear log %s: %d\n",
3679 mgs->mgs_obd->obd_name, name, rc);
3684 /* erase all logs for the given fs */
3685 int mgs_erase_logs(const struct lu_env *env, struct mgs_device *mgs, char *fsname)
3689 struct mgs_direntry *dirent, *n;
3690 int rc, len = strlen(fsname);
3694 /* Find all the logs in the CONFIGS directory */
3695 rc = class_dentry_readdir(env, mgs, &list);
3699 mutex_lock(&mgs->mgs_mutex);
3701 /* Delete the fs db */
3702 fsdb = mgs_find_fsdb(mgs, fsname);
3704 mgs_free_fsdb(mgs, fsdb);
3706 mutex_unlock(&mgs->mgs_mutex);
3708 cfs_list_for_each_entry_safe(dirent, n, &list, list) {
3709 cfs_list_del(&dirent->list);
3710 suffix = strrchr(dirent->name, '-');
3711 if (suffix != NULL) {
3712 if ((len == suffix - dirent->name) &&
3713 (strncmp(fsname, dirent->name, len) == 0)) {
3714 CDEBUG(D_MGS, "Removing log %s\n",
3716 mgs_erase_log(env, mgs, dirent->name);
3719 mgs_direntry_free(dirent);
3725 /* list all logs for the given fs */
3726 int mgs_list_logs(const struct lu_env *env, struct mgs_device *mgs,
3727 struct obd_ioctl_data *data)
3730 struct mgs_direntry *dirent, *n;
3736 /* Find all the logs in the CONFIGS directory */
3737 rc = class_dentry_readdir(env, mgs, &list);
3739 CERROR("%s: can't read %s dir = %d\n",
3740 mgs->mgs_obd->obd_name, MOUNT_CONFIGS_DIR, rc);
3744 out = data->ioc_bulk;
3745 remains = data->ioc_inllen1;
3746 cfs_list_for_each_entry_safe(dirent, n, &list, list) {
3747 cfs_list_del(&dirent->list);
3748 suffix = strrchr(dirent->name, '-');
3749 if (suffix != NULL) {
3750 l = snprintf(out, remains, "config log: $%s\n",
3755 mgs_direntry_free(dirent);
3762 /* from llog_swab */
3763 static void print_lustre_cfg(struct lustre_cfg *lcfg)
3768 CDEBUG(D_MGS, "lustre_cfg: %p\n", lcfg);
3769 CDEBUG(D_MGS, "\tlcfg->lcfg_version: %#x\n", lcfg->lcfg_version);
3771 CDEBUG(D_MGS, "\tlcfg->lcfg_command: %#x\n", lcfg->lcfg_command);
3772 CDEBUG(D_MGS, "\tlcfg->lcfg_num: %#x\n", lcfg->lcfg_num);
3773 CDEBUG(D_MGS, "\tlcfg->lcfg_flags: %#x\n", lcfg->lcfg_flags);
3774 CDEBUG(D_MGS, "\tlcfg->lcfg_nid: %s\n", libcfs_nid2str(lcfg->lcfg_nid));
3776 CDEBUG(D_MGS, "\tlcfg->lcfg_bufcount: %d\n", lcfg->lcfg_bufcount);
3777 if (lcfg->lcfg_bufcount < LUSTRE_CFG_MAX_BUFCOUNT)
3778 for (i = 0; i < lcfg->lcfg_bufcount; i++) {
3779 CDEBUG(D_MGS, "\tlcfg->lcfg_buflens[%d]: %d %s\n",
3780 i, lcfg->lcfg_buflens[i],
3781 lustre_cfg_string(lcfg, i));
3786 /* Setup params fsdb and log
3788 int mgs_params_fsdb_setup(const struct lu_env *env, struct mgs_device *mgs,
3791 struct llog_handle *params_llh = NULL;
3795 rc = mgs_find_or_make_fsdb(env, mgs, PARAMS_FILENAME, &fsdb);
3797 mutex_lock(&fsdb->fsdb_mutex);
3798 rc = record_start_log(env, mgs, ¶ms_llh, PARAMS_FILENAME);
3800 rc = record_end_log(env, ¶ms_llh);
3801 mutex_unlock(&fsdb->fsdb_mutex);
3807 /* Cleanup params fsdb and log
3809 int mgs_params_fsdb_cleanup(const struct lu_env *env, struct mgs_device *mgs)
3811 return mgs_erase_logs(env, mgs, PARAMS_FILENAME);
3814 /* Set a permanent (config log) param for a target or fs
3815 * \param lcfg buf0 may contain the device (testfs-MDT0000) name
3816 * buf1 contains the single parameter
3818 int mgs_setparam(const struct lu_env *env, struct mgs_device *mgs,
3819 struct lustre_cfg *lcfg, char *fsname)
3822 struct mgs_target_info *mti;
3823 char *devname, *param;
3830 print_lustre_cfg(lcfg);
3832 /* lustre, lustre-mdtlov, lustre-client, lustre-MDT0000 */
3833 devname = lustre_cfg_string(lcfg, 0);
3834 param = lustre_cfg_string(lcfg, 1);
3836 /* Assume device name embedded in param:
3837 lustre-OST0000.osc.max_dirty_mb=32 */
3838 ptr = strchr(param, '.');
3846 LCONSOLE_ERROR_MSG(0x14d, "No target specified: %s\n", param);
3850 rc = mgs_parse_devname(devname, fsname, NULL);
3851 if (rc == 0 && !mgs_parse_devname(devname, NULL, &index)) {
3852 /* param related to llite isn't allowed to set by OST or MDT */
3853 if (rc == 0 && strncmp(param, PARAM_LLITE,
3854 sizeof(PARAM_LLITE) - 1) == 0)
3857 /* assume devname is the fsname */
3858 memset(fsname, 0, MTI_NAME_MAXLEN);
3859 strncpy(fsname, devname, MTI_NAME_MAXLEN);
3860 fsname[MTI_NAME_MAXLEN - 1] = 0;
3862 CDEBUG(D_MGS, "setparam fs='%s' device='%s'\n", fsname, devname);
3864 rc = mgs_find_or_make_fsdb(env, mgs,
3865 lcfg->lcfg_command == LCFG_SET_PARAM ?
3866 PARAMS_FILENAME : fsname, &fsdb);
3870 if (lcfg->lcfg_command != LCFG_SET_PARAM &&
3871 !test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags) &&
3872 test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
3873 CERROR("No filesystem targets for %s. cfg_device from lctl "
3874 "is '%s'\n", fsname, devname);
3875 mgs_free_fsdb(mgs, fsdb);
3879 /* Create a fake mti to hold everything */
3882 GOTO(out, rc = -ENOMEM);
3883 if (strlcpy(mti->mti_fsname, fsname, sizeof(mti->mti_fsname))
3884 >= sizeof(mti->mti_fsname))
3885 GOTO(out, rc = -E2BIG);
3886 if (strlcpy(mti->mti_svname, devname, sizeof(mti->mti_svname))
3887 >= sizeof(mti->mti_svname))
3888 GOTO(out, rc = -E2BIG);
3889 if (strlcpy(mti->mti_params, param, sizeof(mti->mti_params))
3890 >= sizeof(mti->mti_params))
3891 GOTO(out, rc = -E2BIG);
3892 rc = server_name2index(mti->mti_svname, &mti->mti_stripe_index, &tmp);
3894 /* Not a valid server; may be only fsname */
3897 /* Strip -osc or -mdc suffix from svname */
3898 if (server_make_name(rc, mti->mti_stripe_index, mti->mti_fsname,
3900 GOTO(out, rc = -EINVAL);
3902 * Revoke lock so everyone updates. Should be alright if
3903 * someone was already reading while we were updating the logs,
3904 * so we don't really need to hold the lock while we're
3907 if (lcfg->lcfg_command == LCFG_SET_PARAM) {
3908 mti->mti_flags = rc | LDD_F_PARAM2;
3909 mutex_lock(&fsdb->fsdb_mutex);
3910 rc = mgs_write_log_param2(env, mgs, fsdb, mti, mti->mti_params);
3911 mutex_unlock(&fsdb->fsdb_mutex);
3912 mgs_revoke_lock(mgs, fsdb, CONFIG_T_PARAMS);
3914 mti->mti_flags = rc | LDD_F_PARAM;
3915 mutex_lock(&fsdb->fsdb_mutex);
3916 rc = mgs_write_log_param(env, mgs, fsdb, mti, mti->mti_params);
3917 mutex_unlock(&fsdb->fsdb_mutex);
3918 mgs_revoke_lock(mgs, fsdb, CONFIG_T_CONFIG);
3926 static int mgs_write_log_pool(const struct lu_env *env,
3927 struct mgs_device *mgs, char *logname,
3928 struct fs_db *fsdb, char *tgtname,
3929 enum lcfg_command_type cmd,
3930 char *fsname, char *poolname,
3931 char *ostname, char *comment)
3933 struct llog_handle *llh = NULL;
3936 rc = record_start_log(env, mgs, &llh, logname);
3939 rc = record_marker(env, llh, fsdb, CM_START, tgtname, comment);
3942 rc = record_base(env, llh, tgtname, 0, cmd,
3943 fsname, poolname, ostname, 0);
3946 rc = record_marker(env, llh, fsdb, CM_END, tgtname, comment);
3948 record_end_log(env, &llh);
3952 int mgs_nodemap_cmd(const struct lu_env *env, struct mgs_device *mgs,
3953 enum lcfg_command_type cmd, const char *nodemap_name,
3964 case LCFG_NODEMAP_ADD:
3965 rc = nodemap_add(nodemap_name);
3967 case LCFG_NODEMAP_DEL:
3968 rc = nodemap_del(nodemap_name);
3970 case LCFG_NODEMAP_ADD_RANGE:
3971 rc = nodemap_parse_range(param, nid);
3974 rc = nodemap_add_range(nodemap_name, nid);
3976 case LCFG_NODEMAP_DEL_RANGE:
3977 rc = nodemap_parse_range(param, nid);
3980 rc = nodemap_del_range(nodemap_name, nid);
3982 case LCFG_NODEMAP_ADMIN:
3983 bool_switch = simple_strtoul(param, NULL, 10);
3984 rc = nodemap_set_allow_root(nodemap_name, bool_switch);
3986 case LCFG_NODEMAP_TRUSTED:
3987 bool_switch = simple_strtoul(param, NULL, 10);
3988 rc = nodemap_set_trust_client_ids(nodemap_name, bool_switch);
3990 case LCFG_NODEMAP_SQUASH_UID:
3991 int_id = simple_strtoul(param, NULL, 10);
3992 rc = nodemap_set_squash_uid(nodemap_name, int_id);
3994 case LCFG_NODEMAP_SQUASH_GID:
3995 int_id = simple_strtoul(param, NULL, 10);
3996 rc = nodemap_set_squash_gid(nodemap_name, int_id);
3998 case LCFG_NODEMAP_ADD_UIDMAP:
3999 case LCFG_NODEMAP_ADD_GIDMAP:
4000 rc = nodemap_parse_idmap(param, idmap);
4003 if (cmd == LCFG_NODEMAP_ADD_UIDMAP)
4004 rc = nodemap_add_idmap(nodemap_name, NODEMAP_UID,
4007 rc = nodemap_add_idmap(nodemap_name, NODEMAP_GID,
4010 case LCFG_NODEMAP_DEL_UIDMAP:
4011 case LCFG_NODEMAP_DEL_GIDMAP:
4012 rc = nodemap_parse_idmap(param, idmap);
4015 if (cmd == LCFG_NODEMAP_DEL_UIDMAP)
4016 rc = nodemap_del_idmap(nodemap_name, NODEMAP_UID,
4019 rc = nodemap_del_idmap(nodemap_name, NODEMAP_GID,
4029 int mgs_pool_cmd(const struct lu_env *env, struct mgs_device *mgs,
4030 enum lcfg_command_type cmd, char *fsname,
4031 char *poolname, char *ostname)
4036 char *label = NULL, *canceled_label = NULL;
4038 struct mgs_target_info *mti = NULL;
4042 rc = mgs_find_or_make_fsdb(env, mgs, fsname, &fsdb);
4044 CERROR("Can't get db for %s\n", fsname);
4047 if (test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
4048 CERROR("%s is not defined\n", fsname);
4049 mgs_free_fsdb(mgs, fsdb);
4053 label_sz = 10 + strlen(fsname) + strlen(poolname);
4055 /* check if ostname match fsname */
4056 if (ostname != NULL) {
4059 ptr = strrchr(ostname, '-');
4060 if ((ptr == NULL) ||
4061 (strncmp(fsname, ostname, ptr-ostname) != 0))
4063 label_sz += strlen(ostname);
4066 OBD_ALLOC(label, label_sz);
4073 "new %s.%s", fsname, poolname);
4077 "add %s.%s.%s", fsname, poolname, ostname);
4080 OBD_ALLOC(canceled_label, label_sz);
4081 if (canceled_label == NULL)
4082 GOTO(out_label, rc = -ENOMEM);
4084 "rem %s.%s.%s", fsname, poolname, ostname);
4085 sprintf(canceled_label,
4086 "add %s.%s.%s", fsname, poolname, ostname);
4089 OBD_ALLOC(canceled_label, label_sz);
4090 if (canceled_label == NULL)
4091 GOTO(out_label, rc = -ENOMEM);
4093 "del %s.%s", fsname, poolname);
4094 sprintf(canceled_label,
4095 "new %s.%s", fsname, poolname);
4101 if (canceled_label != NULL) {
4104 GOTO(out_cancel, rc = -ENOMEM);
4107 mutex_lock(&fsdb->fsdb_mutex);
4108 /* write pool def to all MDT logs */
4109 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
4110 if (test_bit(i, fsdb->fsdb_mdt_index_map)) {
4111 rc = name_create_mdt_and_lov(&logname, &lovname,
4114 mutex_unlock(&fsdb->fsdb_mutex);
4117 if (canceled_label != NULL) {
4118 strcpy(mti->mti_svname, "lov pool");
4119 rc = mgs_modify(env, mgs, fsdb, mti, logname,
4120 lovname, canceled_label,
4125 rc = mgs_write_log_pool(env, mgs, logname,
4129 name_destroy(&logname);
4130 name_destroy(&lovname);
4132 mutex_unlock(&fsdb->fsdb_mutex);
4138 rc = name_create(&logname, fsname, "-client");
4140 mutex_unlock(&fsdb->fsdb_mutex);
4143 if (canceled_label != NULL) {
4144 rc = mgs_modify(env, mgs, fsdb, mti, logname,
4145 fsdb->fsdb_clilov, canceled_label, CM_SKIP);
4147 mutex_unlock(&fsdb->fsdb_mutex);
4148 name_destroy(&logname);
4153 rc = mgs_write_log_pool(env, mgs, logname, fsdb, fsdb->fsdb_clilov,
4154 cmd, fsname, poolname, ostname, label);
4155 mutex_unlock(&fsdb->fsdb_mutex);
4156 name_destroy(&logname);
4157 /* request for update */
4158 mgs_revoke_lock(mgs, fsdb, CONFIG_T_CONFIG);
4165 if (canceled_label != NULL)
4166 OBD_FREE(canceled_label, label_sz);
4168 OBD_FREE(label, label_sz);