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, Whamcloud, Inc.
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
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);
70 if (!dt_try_as_dir(env, dir))
71 GOTO(out, rc = -ENOTDIR);
74 LASSERT(dir->do_index_ops);
76 iops = &dir->do_index_ops->dio_it;
77 it = iops->init(env, dir, LUDA_64BITHASH, BYPASS_CAPA);
81 rc = iops->load(env, it, 0);
87 key = (void *)iops->key(env, it);
89 CERROR("%s: key failed when listing %s: rc = %d\n",
90 mgs->mgs_obd->obd_name, MOUNT_CONFIGS_DIR,
94 key_sz = iops->key_size(env, it);
97 /* filter out "." and ".." entries */
101 if (key_sz == 2 && key[1] == '.')
105 de = mgs_direntry_alloc(key_sz + 1);
111 memcpy(de->name, key, key_sz);
112 de->name[key_sz] = 0;
114 cfs_list_add(&de->list, list);
117 rc = iops->next(env, it);
127 CERROR("%s: key failed when listing %s: rc = %d\n",
128 mgs->mgs_obd->obd_name, MOUNT_CONFIGS_DIR, rc);
132 /******************** DB functions *********************/
134 static inline int name_create(char **newname, char *prefix, char *suffix)
137 OBD_ALLOC(*newname, strlen(prefix) + strlen(suffix) + 1);
140 sprintf(*newname, "%s%s", prefix, suffix);
144 static inline void name_destroy(char **name)
147 OBD_FREE(*name, strlen(*name) + 1);
151 struct mgs_fsdb_handler_data
157 /* from the (client) config log, figure out:
158 1. which ost's/mdt's are configured (by index)
159 2. what the last config step is
160 3. COMPAT_18 osc name
162 /* It might be better to have a separate db file, instead of parsing the info
163 out of the client log. This is slow and potentially error-prone. */
164 static int mgs_fsdb_handler(const struct lu_env *env, struct llog_handle *llh,
165 struct llog_rec_hdr *rec, void *data)
167 struct mgs_fsdb_handler_data *d = data;
168 struct fs_db *fsdb = d->fsdb;
169 int cfg_len = rec->lrh_len;
170 char *cfg_buf = (char*) (rec + 1);
171 struct lustre_cfg *lcfg;
176 if (rec->lrh_type != OBD_CFG_REC) {
177 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
181 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
183 CERROR("Insane cfg\n");
187 lcfg = (struct lustre_cfg *)cfg_buf;
189 CDEBUG(D_INFO, "cmd %x %s %s\n", lcfg->lcfg_command,
190 lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));
192 /* Figure out ost indicies */
193 /* lov_modify_tgts add 0:lov1 1:ost1_UUID 2(index):0 3(gen):1 */
194 if (lcfg->lcfg_command == LCFG_LOV_ADD_OBD ||
195 lcfg->lcfg_command == LCFG_LOV_DEL_OBD) {
196 index = simple_strtoul(lustre_cfg_string(lcfg, 2),
198 CDEBUG(D_MGS, "OST index for %s is %u (%s)\n",
199 lustre_cfg_string(lcfg, 1), index,
200 lustre_cfg_string(lcfg, 2));
201 cfs_set_bit(index, fsdb->fsdb_ost_index_map);
204 /* Figure out mdt indicies */
205 /* attach 0:MDC_uml1_mdsA_MNT_client 1:mdc 2:1d834_MNT_client_03f */
206 if ((lcfg->lcfg_command == LCFG_ATTACH) &&
207 (strcmp(lustre_cfg_string(lcfg, 1), LUSTRE_MDC_NAME) == 0)) {
208 rc = server_name2index(lustre_cfg_string(lcfg, 0),
210 if (rc != LDD_F_SV_TYPE_MDT) {
211 CWARN("Unparsable MDC name %s, assuming index 0\n",
212 lustre_cfg_string(lcfg, 0));
216 CDEBUG(D_MGS, "MDT index is %u\n", index);
217 cfs_set_bit(index, fsdb->fsdb_mdt_index_map);
218 fsdb->fsdb_mdt_count ++;
222 * figure out the old config. fsdb_gen = 0 means old log
223 * It is obsoleted and not supported anymore
225 if (fsdb->fsdb_gen == 0) {
226 CERROR("Old config format is not supported\n");
231 * compat to 1.8, check osc name used by MDT0 to OSTs, bz18548.
233 if (!cfs_test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags) &&
234 lcfg->lcfg_command == LCFG_ATTACH &&
235 strcmp(lustre_cfg_string(lcfg, 1), LUSTRE_OSC_NAME) == 0) {
236 if (OBD_OCD_VERSION_MAJOR(d->ver) == 1 &&
237 OBD_OCD_VERSION_MINOR(d->ver) <= 8) {
238 CWARN("MDT using 1.8 OSC name scheme\n");
239 cfs_set_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags);
243 if (lcfg->lcfg_command == LCFG_MARKER) {
244 struct cfg_marker *marker;
245 marker = lustre_cfg_buf(lcfg, 1);
247 d->ver = marker->cm_vers;
249 /* Keep track of the latest marker step */
250 fsdb->fsdb_gen = max(fsdb->fsdb_gen, marker->cm_step);
256 /* fsdb->fsdb_mutex is already held in mgs_find_or_make_fsdb*/
257 static int mgs_get_fsdb_from_llog(const struct lu_env *env,
258 struct mgs_device *mgs,
262 struct llog_handle *loghandle;
263 struct llog_ctxt *ctxt;
264 struct mgs_fsdb_handler_data d = { fsdb, 0 };
269 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
270 LASSERT(ctxt != NULL);
271 rc = name_create(&logname, fsdb->fsdb_name, "-client");
274 cfs_mutex_lock(&fsdb->fsdb_mutex);
275 rc = llog_open_create(env, ctxt, &loghandle, NULL, logname);
279 rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL);
283 if (llog_get_size(loghandle) <= 1)
284 cfs_set_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags);
286 rc = llog_process(env, loghandle, mgs_fsdb_handler, (void *)&d, NULL);
287 CDEBUG(D_INFO, "get_db = %d\n", rc);
289 llog_close(env, loghandle);
291 cfs_mutex_unlock(&fsdb->fsdb_mutex);
292 name_destroy(&logname);
299 static void mgs_free_fsdb_srpc(struct fs_db *fsdb)
301 struct mgs_tgt_srpc_conf *tgtconf;
303 /* free target-specific rules */
304 while (fsdb->fsdb_srpc_tgt) {
305 tgtconf = fsdb->fsdb_srpc_tgt;
306 fsdb->fsdb_srpc_tgt = tgtconf->mtsc_next;
308 LASSERT(tgtconf->mtsc_tgt);
310 sptlrpc_rule_set_free(&tgtconf->mtsc_rset);
311 OBD_FREE(tgtconf->mtsc_tgt, strlen(tgtconf->mtsc_tgt) + 1);
312 OBD_FREE_PTR(tgtconf);
315 /* free general rules */
316 sptlrpc_rule_set_free(&fsdb->fsdb_srpc_gen);
319 struct fs_db *mgs_find_fsdb(struct mgs_device *mgs, char *fsname)
324 cfs_list_for_each(tmp, &mgs->mgs_fs_db_list) {
325 fsdb = cfs_list_entry(tmp, struct fs_db, fsdb_list);
326 if (strcmp(fsdb->fsdb_name, fsname) == 0)
332 /* caller must hold the mgs->mgs_fs_db_lock */
333 static struct fs_db *mgs_new_fsdb(const struct lu_env *env,
334 struct mgs_device *mgs, char *fsname)
340 if (strlen(fsname) >= sizeof(fsdb->fsdb_name)) {
341 CERROR("fsname %s is too long\n", fsname);
349 strcpy(fsdb->fsdb_name, fsname);
350 cfs_mutex_init(&fsdb->fsdb_mutex);
351 cfs_set_bit(FSDB_UDESC, &fsdb->fsdb_flags);
354 if (strcmp(fsname, MGSSELF_NAME) == 0) {
355 cfs_set_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags);
357 OBD_ALLOC(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
358 OBD_ALLOC(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
359 if (!fsdb->fsdb_ost_index_map || !fsdb->fsdb_mdt_index_map) {
360 CERROR("No memory for index maps\n");
361 GOTO(err, rc = -ENOMEM);
364 rc = name_create(&fsdb->fsdb_clilov, fsname, "-clilov");
367 rc = name_create(&fsdb->fsdb_clilmv, fsname, "-clilmv");
371 /* initialise data for NID table */
372 mgs_ir_init_fs(env, mgs, fsdb);
374 lproc_mgs_add_live(mgs, fsdb);
377 cfs_list_add(&fsdb->fsdb_list, &mgs->mgs_fs_db_list);
381 if (fsdb->fsdb_ost_index_map)
382 OBD_FREE(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
383 if (fsdb->fsdb_mdt_index_map)
384 OBD_FREE(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
385 name_destroy(&fsdb->fsdb_clilov);
386 name_destroy(&fsdb->fsdb_clilmv);
391 static void mgs_free_fsdb(struct mgs_device *mgs, struct fs_db *fsdb)
393 /* wait for anyone with the sem */
394 cfs_mutex_lock(&fsdb->fsdb_mutex);
395 lproc_mgs_del_live(mgs, fsdb);
396 cfs_list_del(&fsdb->fsdb_list);
398 /* deinitialize fsr */
399 mgs_ir_fini_fs(mgs, fsdb);
401 if (fsdb->fsdb_ost_index_map)
402 OBD_FREE(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
403 if (fsdb->fsdb_mdt_index_map)
404 OBD_FREE(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
405 name_destroy(&fsdb->fsdb_clilov);
406 name_destroy(&fsdb->fsdb_clilmv);
407 mgs_free_fsdb_srpc(fsdb);
408 cfs_mutex_unlock(&fsdb->fsdb_mutex);
412 int mgs_init_fsdb_list(struct mgs_device *mgs)
414 CFS_INIT_LIST_HEAD(&mgs->mgs_fs_db_list);
418 int mgs_cleanup_fsdb_list(struct mgs_device *mgs)
421 cfs_list_t *tmp, *tmp2;
422 cfs_mutex_lock(&mgs->mgs_mutex);
423 cfs_list_for_each_safe(tmp, tmp2, &mgs->mgs_fs_db_list) {
424 fsdb = cfs_list_entry(tmp, struct fs_db, fsdb_list);
425 mgs_free_fsdb(mgs, fsdb);
427 cfs_mutex_unlock(&mgs->mgs_mutex);
431 int mgs_find_or_make_fsdb(const struct lu_env *env,
432 struct mgs_device *mgs, char *name,
438 cfs_mutex_lock(&mgs->mgs_mutex);
439 fsdb = mgs_find_fsdb(mgs, name);
441 cfs_mutex_unlock(&mgs->mgs_mutex);
446 CDEBUG(D_MGS, "Creating new db\n");
447 fsdb = mgs_new_fsdb(env, mgs, name);
448 cfs_mutex_unlock(&mgs->mgs_mutex);
452 if (!cfs_test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
453 /* populate the db from the client llog */
454 rc = mgs_get_fsdb_from_llog(env, mgs, fsdb);
456 CERROR("Can't get db from client log %d\n", rc);
457 mgs_free_fsdb(mgs, fsdb);
462 /* populate srpc rules from params llog */
463 rc = mgs_get_fsdb_srpc_from_llog(env, mgs, fsdb);
465 CERROR("Can't get db from params log %d\n", rc);
466 mgs_free_fsdb(mgs, fsdb);
477 -1= empty client log */
478 int mgs_check_index(const struct lu_env *env,
479 struct mgs_device *mgs,
480 struct mgs_target_info *mti)
487 LASSERT(!(mti->mti_flags & LDD_F_NEED_INDEX));
489 rc = mgs_find_or_make_fsdb(env, mgs, mti->mti_fsname, &fsdb);
491 CERROR("Can't get db for %s\n", mti->mti_fsname);
495 if (cfs_test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags))
498 if (mti->mti_flags & LDD_F_SV_TYPE_OST)
499 imap = fsdb->fsdb_ost_index_map;
500 else if (mti->mti_flags & LDD_F_SV_TYPE_MDT)
501 imap = fsdb->fsdb_mdt_index_map;
505 if (cfs_test_bit(mti->mti_stripe_index, imap))
510 static __inline__ int next_index(void *index_map, int map_len)
513 for (i = 0; i < map_len * 8; i++)
514 if (!cfs_test_bit(i, index_map)) {
517 CERROR("max index %d exceeded.\n", i);
522 0 newly marked as in use
524 +EALREADY for update of an old index */
525 static int mgs_set_index(const struct lu_env *env,
526 struct mgs_device *mgs,
527 struct mgs_target_info *mti)
534 rc = mgs_find_or_make_fsdb(env, mgs, mti->mti_fsname, &fsdb);
536 CERROR("Can't get db for %s\n", mti->mti_fsname);
540 if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
541 imap = fsdb->fsdb_ost_index_map;
542 } else if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
543 imap = fsdb->fsdb_mdt_index_map;
544 if (fsdb->fsdb_mdt_count >= MAX_MDT_COUNT) {
545 LCONSOLE_ERROR_MSG(0x13f, "The max mdt count"
546 "is %d\n", (int)MAX_MDT_COUNT);
553 if (mti->mti_flags & LDD_F_NEED_INDEX) {
554 rc = next_index(imap, INDEX_MAP_SIZE);
557 mti->mti_stripe_index = rc;
558 if (mti->mti_flags & LDD_F_SV_TYPE_MDT)
559 fsdb->fsdb_mdt_count ++;
562 if (mti->mti_stripe_index >= INDEX_MAP_SIZE * 8) {
563 LCONSOLE_ERROR_MSG(0x13f, "Server %s requested index %d, "
564 "but the max index is %d.\n",
565 mti->mti_svname, mti->mti_stripe_index,
570 if (cfs_test_bit(mti->mti_stripe_index, imap)) {
571 if ((mti->mti_flags & LDD_F_VIRGIN) &&
572 !(mti->mti_flags & LDD_F_WRITECONF)) {
573 LCONSOLE_ERROR_MSG(0x140, "Server %s requested index "
574 "%d, but that index is already in "
575 "use. Use --writeconf to force\n",
577 mti->mti_stripe_index);
580 CDEBUG(D_MGS, "Server %s updating index %d\n",
581 mti->mti_svname, mti->mti_stripe_index);
586 cfs_set_bit(mti->mti_stripe_index, imap);
587 cfs_clear_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags);
588 server_make_name(mti->mti_flags & ~(LDD_F_VIRGIN | LDD_F_WRITECONF),
589 mti->mti_stripe_index, mti->mti_fsname, mti->mti_svname);
591 CDEBUG(D_MGS, "Set index for %s to %d\n", mti->mti_svname,
592 mti->mti_stripe_index);
597 struct mgs_modify_lookup {
598 struct cfg_marker mml_marker;
602 static int mgs_modify_handler(const struct lu_env *env,
603 struct llog_handle *llh,
604 struct llog_rec_hdr *rec, void *data)
606 struct mgs_modify_lookup *mml = data;
607 struct cfg_marker *marker;
608 struct lustre_cfg *lcfg = (struct lustre_cfg *)(rec + 1);
609 int cfg_len = rec->lrh_len - sizeof(struct llog_rec_hdr) -
610 sizeof(struct llog_rec_tail);
614 if (rec->lrh_type != OBD_CFG_REC) {
615 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
619 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
621 CERROR("Insane cfg\n");
625 /* We only care about markers */
626 if (lcfg->lcfg_command != LCFG_MARKER)
629 marker = lustre_cfg_buf(lcfg, 1);
630 if ((strcmp(mml->mml_marker.cm_comment, marker->cm_comment) == 0) &&
631 (strcmp(mml->mml_marker.cm_tgtname, marker->cm_tgtname) == 0) &&
632 !(marker->cm_flags & CM_SKIP)) {
633 /* Found a non-skipped marker match */
634 CDEBUG(D_MGS, "Changing rec %u marker %d %x->%x: %s %s\n",
635 rec->lrh_index, marker->cm_step,
636 marker->cm_flags, mml->mml_marker.cm_flags,
637 marker->cm_tgtname, marker->cm_comment);
638 /* Overwrite the old marker llog entry */
639 marker->cm_flags &= ~CM_EXCLUDE; /* in case we're unexcluding */
640 marker->cm_flags |= mml->mml_marker.cm_flags;
641 marker->cm_canceltime = mml->mml_marker.cm_canceltime;
642 /* Header and tail are added back to lrh_len in
643 llog_lvfs_write_rec */
644 rec->lrh_len = cfg_len;
645 rc = llog_write(env, llh, rec, NULL, 0, (void *)lcfg,
655 * Modify an existing config log record (for CM_SKIP or CM_EXCLUDE)
657 * 0 - modified successfully,
658 * 1 - no modification was done
661 static int mgs_modify(const struct lu_env *env, struct mgs_device *mgs,
662 struct fs_db *fsdb, struct mgs_target_info *mti,
663 char *logname, char *devname, char *comment, int flags)
665 struct llog_handle *loghandle;
666 struct llog_ctxt *ctxt;
667 struct mgs_modify_lookup *mml;
672 LASSERT(cfs_mutex_is_locked(&fsdb->fsdb_mutex));
673 CDEBUG(D_MGS, "modify %s/%s/%s fl=%x\n", logname, devname, comment,
676 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
677 LASSERT(ctxt != NULL);
678 rc = llog_open(env, ctxt, &loghandle, NULL, logname, LLOG_OPEN_EXISTS);
685 rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL);
689 if (llog_get_size(loghandle) <= 1)
690 GOTO(out_close, rc = 0);
694 GOTO(out_close, rc = -ENOMEM);
695 strcpy(mml->mml_marker.cm_comment, comment);
696 strcpy(mml->mml_marker.cm_tgtname, devname);
697 /* Modify mostly means cancel */
698 mml->mml_marker.cm_flags = flags;
699 mml->mml_marker.cm_canceltime = flags ? cfs_time_current_sec() : 0;
700 mml->mml_modified = 0;
701 rc = llog_process(env, loghandle, mgs_modify_handler, (void *)mml,
703 if (!rc && !mml->mml_modified)
708 llog_close(env, loghandle);
711 CERROR("%s: modify %s/%s failed: rc = %d\n",
712 mgs->mgs_obd->obd_name, mti->mti_svname, comment, rc);
717 /******************** config log recording functions *********************/
719 static int record_lcfg(const struct lu_env *env, struct llog_handle *llh,
720 struct lustre_cfg *lcfg)
722 struct llog_rec_hdr rec;
728 LASSERT(llh->lgh_ctxt);
730 buflen = lustre_cfg_len(lcfg->lcfg_bufcount,
732 rec.lrh_len = llog_data_len(buflen);
733 rec.lrh_type = OBD_CFG_REC;
735 /* idx = -1 means append */
736 rc = llog_write(env, llh, &rec, NULL, 0, (void *)lcfg, -1);
738 CERROR("failed %d\n", rc);
742 static int record_base(const struct lu_env *env, struct llog_handle *llh,
743 char *cfgname, lnet_nid_t nid, int cmd,
744 char *s1, char *s2, char *s3, char *s4)
746 struct mgs_thread_info *mgi = mgs_env_info(env);
747 struct lustre_cfg *lcfg;
750 CDEBUG(D_MGS, "lcfg %s %#x %s %s %s %s\n", cfgname,
751 cmd, s1, s2, s3, s4);
753 lustre_cfg_bufs_reset(&mgi->mgi_bufs, cfgname);
755 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, s1);
757 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 2, s2);
759 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 3, s3);
761 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 4, s4);
763 lcfg = lustre_cfg_new(cmd, &mgi->mgi_bufs);
766 lcfg->lcfg_nid = nid;
768 rc = record_lcfg(env, llh, lcfg);
770 lustre_cfg_free(lcfg);
773 CERROR("error %d: lcfg %s %#x %s %s %s %s\n", rc, cfgname,
774 cmd, s1, s2, s3, s4);
780 static inline int record_add_uuid(const struct lu_env *env,
781 struct llog_handle *llh,
782 uint64_t nid, char *uuid)
784 return record_base(env, llh, NULL, nid, LCFG_ADD_UUID, uuid, 0, 0, 0);
788 static inline int record_add_conn(const struct lu_env *env,
789 struct llog_handle *llh,
790 char *devname, char *uuid)
792 return record_base(env, llh, devname, 0, LCFG_ADD_CONN, uuid, 0, 0, 0);
795 static inline int record_attach(const struct lu_env *env,
796 struct llog_handle *llh, char *devname,
797 char *type, char *uuid)
799 return record_base(env, llh,devname, 0, LCFG_ATTACH, type, uuid, 0, 0);
802 static inline int record_setup(const struct lu_env *env,
803 struct llog_handle *llh, char *devname,
804 char *s1, char *s2, char *s3, char *s4)
806 return record_base(env, llh, devname, 0, LCFG_SETUP, s1, s2, s3, s4);
809 static int record_lov_setup(const struct lu_env *env, struct llog_handle *llh,
810 char *devname, struct lov_desc *desc)
812 struct mgs_thread_info *mgi = mgs_env_info(env);
813 struct lustre_cfg *lcfg;
816 lustre_cfg_bufs_reset(&mgi->mgi_bufs, devname);
817 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, desc, sizeof(*desc));
818 lcfg = lustre_cfg_new(LCFG_SETUP, &mgi->mgi_bufs);
821 rc = record_lcfg(env, llh, lcfg);
823 lustre_cfg_free(lcfg);
827 static int record_lmv_setup(const struct lu_env *env, struct llog_handle *llh,
828 char *devname, struct lmv_desc *desc)
830 struct mgs_thread_info *mgi = mgs_env_info(env);
831 struct lustre_cfg *lcfg;
834 lustre_cfg_bufs_reset(&mgi->mgi_bufs, devname);
835 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, desc, sizeof(*desc));
836 lcfg = lustre_cfg_new(LCFG_SETUP, &mgi->mgi_bufs);
838 rc = record_lcfg(env, llh, lcfg);
840 lustre_cfg_free(lcfg);
844 static inline int record_mdc_add(const struct lu_env *env,
845 struct llog_handle *llh,
846 char *logname, char *mdcuuid,
847 char *mdtuuid, char *index,
850 return record_base(env,llh,logname,0,LCFG_ADD_MDC,
851 mdtuuid,index,gen,mdcuuid);
854 static inline int record_lov_add(const struct lu_env *env,
855 struct llog_handle *llh,
856 char *lov_name, char *ost_uuid,
857 char *index, char *gen)
859 return record_base(env,llh,lov_name,0,LCFG_LOV_ADD_OBD,
860 ost_uuid,index,gen,0);
863 static inline int record_mount_opt(const struct lu_env *env,
864 struct llog_handle *llh,
865 char *profile, char *lov_name,
868 return record_base(env,llh,NULL,0,LCFG_MOUNTOPT,
869 profile,lov_name,mdc_name,0);
872 static int record_marker(const struct lu_env *env,
873 struct llog_handle *llh,
874 struct fs_db *fsdb, __u32 flags,
875 char *tgtname, char *comment)
877 struct mgs_thread_info *mgi = mgs_env_info(env);
878 struct lustre_cfg *lcfg;
881 if (flags & CM_START)
883 mgi->mgi_marker.cm_step = fsdb->fsdb_gen;
884 mgi->mgi_marker.cm_flags = flags;
885 mgi->mgi_marker.cm_vers = LUSTRE_VERSION_CODE;
886 strncpy(mgi->mgi_marker.cm_tgtname, tgtname,
887 sizeof(mgi->mgi_marker.cm_tgtname));
888 strncpy(mgi->mgi_marker.cm_comment, comment,
889 sizeof(mgi->mgi_marker.cm_comment));
890 mgi->mgi_marker.cm_createtime = cfs_time_current_sec();
891 mgi->mgi_marker.cm_canceltime = 0;
892 lustre_cfg_bufs_reset(&mgi->mgi_bufs, NULL);
893 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, &mgi->mgi_marker,
894 sizeof(mgi->mgi_marker));
895 lcfg = lustre_cfg_new(LCFG_MARKER, &mgi->mgi_bufs);
898 rc = record_lcfg(env, llh, lcfg);
900 lustre_cfg_free(lcfg);
904 static int record_start_log(const struct lu_env *env, struct mgs_device *mgs,
905 struct llog_handle **llh, char *name)
907 static struct obd_uuid cfg_uuid = { .uuid = "config_uuid" };
908 struct llog_ctxt *ctxt;
912 GOTO(out, rc = -EBUSY);
914 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
916 GOTO(out, rc = -ENODEV);
917 LASSERT(ctxt->loc_obd == mgs->mgs_obd);
919 rc = llog_open_create(env, ctxt, llh, NULL, name);
922 rc = llog_init_handle(env, *llh, LLOG_F_IS_PLAIN, &cfg_uuid);
924 llog_close(env, *llh);
929 CERROR("%s: can't start log %s: rc = %d\n",
930 mgs->mgs_obd->obd_name, name, rc);
936 static int record_end_log(const struct lu_env *env, struct llog_handle **llh)
940 rc = llog_close(env, *llh);
946 static int mgs_log_is_empty(const struct lu_env *env,
947 struct mgs_device *mgs, char *name)
949 struct llog_handle *llh;
950 struct llog_ctxt *ctxt;
953 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
954 LASSERT(ctxt != NULL);
955 rc = llog_open(env, ctxt, &llh, NULL, name, LLOG_OPEN_EXISTS);
962 llog_init_handle(env, llh, LLOG_F_IS_PLAIN, NULL);
965 rc = llog_get_size(llh);
968 llog_close(env, llh);
971 /* header is record 1 */
975 /******************** config "macros" *********************/
977 /* write an lcfg directly into a log (with markers) */
978 static int mgs_write_log_direct(const struct lu_env *env,
979 struct mgs_device *mgs, struct fs_db *fsdb,
980 char *logname, struct lustre_cfg *lcfg,
981 char *devname, char *comment)
983 struct llog_handle *llh = NULL;
990 rc = record_start_log(env, mgs, &llh, logname);
994 /* FIXME These should be a single journal transaction */
995 rc = record_marker(env, llh, fsdb, CM_START, devname, comment);
998 rc = record_lcfg(env, llh, lcfg);
1001 rc = record_marker(env, llh, fsdb, CM_END, devname, comment);
1005 record_end_log(env, &llh);
1009 /* write the lcfg in all logs for the given fs */
1010 int mgs_write_log_direct_all(const struct lu_env *env,
1011 struct mgs_device *mgs,
1013 struct mgs_target_info *mti,
1014 struct lustre_cfg *lcfg,
1015 char *devname, char *comment,
1019 struct mgs_direntry *dirent, *n;
1020 char *fsname = mti->mti_fsname;
1022 int rc = 0, len = strlen(fsname);
1025 /* We need to set params for any future logs
1026 as well. FIXME Append this file to every new log.
1027 Actually, we should store as params (text), not llogs. Or
1029 rc = name_create(&logname, fsname, "-params");
1032 if (mgs_log_is_empty(env, mgs, logname)) {
1033 struct llog_handle *llh = NULL;
1034 rc = record_start_log(env, mgs, &llh, logname);
1035 record_end_log(env, &llh);
1037 name_destroy(&logname);
1041 /* Find all the logs in the CONFIGS directory */
1042 rc = class_dentry_readdir(env, mgs, &list);
1046 /* Could use fsdb index maps instead of directory listing */
1047 cfs_list_for_each_entry_safe(dirent, n, &list, list) {
1048 cfs_list_del(&dirent->list);
1049 /* don't write to sptlrpc rule log */
1050 if (strstr(dirent->name, "-sptlrpc") != NULL)
1053 /* caller wants write server logs only */
1054 if (server_only && strstr(dirent->name, "-client") != NULL)
1057 if (strncmp(fsname, dirent->name, len) == 0) {
1058 CDEBUG(D_MGS, "Changing log %s\n", dirent->name);
1059 /* Erase any old settings of this same parameter */
1060 rc = mgs_modify(env, mgs, fsdb, mti, dirent->name,
1061 devname, comment, CM_SKIP);
1063 CERROR("%s: Can't modify llog %s: rc = %d\n",
1064 mgs->mgs_obd->obd_name, dirent->name,rc);
1065 /* Write the new one */
1067 rc = mgs_write_log_direct(env, mgs, fsdb,
1072 CERROR("%s: writing log %s: rc = %d\n",
1073 mgs->mgs_obd->obd_name,
1078 mgs_direntry_free(dirent);
1084 static int mgs_write_log_mdc_to_mdt(const struct lu_env *env,
1085 struct mgs_device *mgs,
1087 struct mgs_target_info *mti,
1089 static int mgs_write_log_osc_to_lov(const struct lu_env *env,
1090 struct mgs_device *mgs,
1092 struct mgs_target_info *mti,
1093 char *logname, char *suffix, char *lovname,
1094 enum lustre_sec_part sec_part, int flags);
1095 static int name_create_mdt_and_lov(char **logname, char **lovname,
1096 struct fs_db *fsdb, int i);
1098 static int mgs_steal_llog_handler(const struct lu_env *env,
1099 struct llog_handle *llh,
1100 struct llog_rec_hdr *rec, void *data)
1102 struct mgs_device *mgs;
1103 struct obd_device *obd;
1104 struct mgs_target_info *mti, *tmti;
1106 int cfg_len = rec->lrh_len;
1107 char *cfg_buf = (char*) (rec + 1);
1108 struct lustre_cfg *lcfg;
1110 struct llog_handle *mdt_llh = NULL;
1111 static int got_an_osc_or_mdc = 0;
1112 /* 0: not found any osc/mdc;
1116 static int last_step = -1;
1120 mti = ((struct temp_comp*)data)->comp_mti;
1121 tmti = ((struct temp_comp*)data)->comp_tmti;
1122 fsdb = ((struct temp_comp*)data)->comp_fsdb;
1123 obd = ((struct temp_comp *)data)->comp_obd;
1124 mgs = lu2mgs_dev(obd->obd_lu_dev);
1127 if (rec->lrh_type != OBD_CFG_REC) {
1128 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
1132 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
1134 CERROR("Insane cfg\n");
1138 lcfg = (struct lustre_cfg *)cfg_buf;
1140 if (lcfg->lcfg_command == LCFG_MARKER) {
1141 struct cfg_marker *marker;
1142 marker = lustre_cfg_buf(lcfg, 1);
1143 if (!strncmp(marker->cm_comment,"add osc",7) &&
1144 (marker->cm_flags & CM_START)){
1145 got_an_osc_or_mdc = 1;
1146 strncpy(tmti->mti_svname, marker->cm_tgtname,
1147 sizeof(tmti->mti_svname));
1148 rc = record_start_log(env, mgs, &mdt_llh,
1152 rc = record_marker(env, mdt_llh, fsdb, CM_START,
1153 mti->mti_svname,"add osc(copied)");
1154 record_end_log(env, &mdt_llh);
1155 last_step = marker->cm_step;
1158 if (!strncmp(marker->cm_comment,"add osc",7) &&
1159 (marker->cm_flags & CM_END)){
1160 LASSERT(last_step == marker->cm_step);
1162 got_an_osc_or_mdc = 0;
1163 rc = record_start_log(env, mgs, &mdt_llh,
1167 rc = record_marker(env, mdt_llh, fsdb, CM_END,
1168 mti->mti_svname,"add osc(copied)");
1169 record_end_log(env, &mdt_llh);
1172 if (!strncmp(marker->cm_comment,"add mdc",7) &&
1173 (marker->cm_flags & CM_START)){
1174 got_an_osc_or_mdc = 2;
1175 last_step = marker->cm_step;
1176 memcpy(tmti->mti_svname, marker->cm_tgtname,
1177 strlen(marker->cm_tgtname));
1181 if (!strncmp(marker->cm_comment,"add mdc",7) &&
1182 (marker->cm_flags & CM_END)){
1183 LASSERT(last_step == marker->cm_step);
1185 got_an_osc_or_mdc = 0;
1190 if (got_an_osc_or_mdc == 0 || last_step < 0)
1193 if (lcfg->lcfg_command == LCFG_ADD_UUID) {
1195 nodenid = lcfg->lcfg_nid;
1197 tmti->mti_nids[tmti->mti_nid_count] = nodenid;
1198 tmti->mti_nid_count++;
1203 if (lcfg->lcfg_command == LCFG_SETUP) {
1206 target = lustre_cfg_string(lcfg, 1);
1207 memcpy(tmti->mti_uuid, target, strlen(target));
1211 /* ignore client side sptlrpc_conf_log */
1212 if (lcfg->lcfg_command == LCFG_SPTLRPC_CONF)
1215 if (lcfg->lcfg_command == LCFG_ADD_MDC) {
1218 if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1)
1221 memcpy(tmti->mti_fsname, mti->mti_fsname,
1222 strlen(mti->mti_fsname));
1223 tmti->mti_stripe_index = index;
1225 rc = mgs_write_log_mdc_to_mdt(env, mgs, fsdb, tmti,
1227 memset(tmti, 0, sizeof(*tmti));
1231 if (lcfg->lcfg_command == LCFG_LOV_ADD_OBD) {
1234 char *logname, *lovname;
1236 rc = name_create_mdt_and_lov(&logname, &lovname, fsdb,
1237 mti->mti_stripe_index);
1240 sprintf(mdt_index, "-MDT%04x", mti->mti_stripe_index);
1242 if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1) {
1243 name_destroy(&logname);
1244 name_destroy(&lovname);
1248 tmti->mti_stripe_index = index;
1249 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, tmti, logname,
1252 name_destroy(&logname);
1253 name_destroy(&lovname);
1259 /* fsdb->fsdb_mutex is already held in mgs_write_log_target*/
1260 /* stealed from mgs_get_fsdb_from_llog*/
1261 static int mgs_steal_llog_for_mdt_from_client(const struct lu_env *env,
1262 struct mgs_device *mgs,
1264 struct temp_comp* comp)
1266 struct llog_handle *loghandle;
1267 struct mgs_target_info *tmti;
1268 struct llog_ctxt *ctxt;
1273 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
1274 LASSERT(ctxt != NULL);
1276 OBD_ALLOC_PTR(tmti);
1278 GOTO(out_ctxt, rc = -ENOMEM);
1280 comp->comp_tmti = tmti;
1281 comp->comp_obd = mgs->mgs_obd;
1283 rc = llog_open(env, ctxt, &loghandle, NULL, client_name,
1291 rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL);
1293 GOTO(out_close, rc);
1295 rc = llog_process_or_fork(env, loghandle, mgs_steal_llog_handler,
1296 (void *)comp, NULL, false);
1297 CDEBUG(D_MGS, "steal llog re = %d\n", rc);
1299 llog_close(env, loghandle);
1303 llog_ctxt_put(ctxt);
1307 /* lmv is the second thing for client logs */
1308 /* copied from mgs_write_log_lov. Please refer to that. */
1309 static int mgs_write_log_lmv(const struct lu_env *env,
1310 struct mgs_device *mgs,
1312 struct mgs_target_info *mti,
1313 char *logname, char *lmvname)
1315 struct llog_handle *llh = NULL;
1316 struct lmv_desc *lmvdesc;
1321 CDEBUG(D_MGS, "Writing lmv(%s) log for %s\n", lmvname,logname);
1323 OBD_ALLOC_PTR(lmvdesc);
1324 if (lmvdesc == NULL)
1326 lmvdesc->ld_active_tgt_count = 0;
1327 lmvdesc->ld_tgt_count = 0;
1328 sprintf((char*)lmvdesc->ld_uuid.uuid, "%s_UUID", lmvname);
1329 uuid = (char *)lmvdesc->ld_uuid.uuid;
1331 rc = record_start_log(env, mgs, &llh, logname);
1334 rc = record_marker(env, llh, fsdb, CM_START, lmvname, "lmv setup");
1337 rc = record_attach(env, llh, lmvname, "lmv", uuid);
1340 rc = record_lmv_setup(env, llh, lmvname, lmvdesc);
1343 rc = record_marker(env, llh, fsdb, CM_END, lmvname, "lmv setup");
1347 record_end_log(env, &llh);
1349 OBD_FREE_PTR(lmvdesc);
1353 /* lov is the first thing in the mdt and client logs */
1354 static int mgs_write_log_lov(const struct lu_env *env, struct mgs_device *mgs,
1355 struct fs_db *fsdb, struct mgs_target_info *mti,
1356 char *logname, char *lovname)
1358 struct llog_handle *llh = NULL;
1359 struct lov_desc *lovdesc;
1364 CDEBUG(D_MGS, "Writing lov(%s) log for %s\n", lovname, logname);
1367 #01 L attach 0:lov_mdsA 1:lov 2:71ccb_lov_mdsA_19f961a9e1
1368 #02 L lov_setup 0:lov_mdsA 1:(struct lov_desc)
1369 uuid=lov1_UUID, stripe count=1, size=1048576, offset=0, pattern=0
1372 /* FIXME just make lov_setup accept empty desc (put uuid in buf 2) */
1373 OBD_ALLOC_PTR(lovdesc);
1374 if (lovdesc == NULL)
1376 lovdesc->ld_magic = LOV_DESC_MAGIC;
1377 lovdesc->ld_tgt_count = 0;
1378 /* Defaults. Can be changed later by lcfg config_param */
1379 lovdesc->ld_default_stripe_count = 1;
1380 lovdesc->ld_pattern = LOV_PATTERN_RAID0;
1381 lovdesc->ld_default_stripe_size = 1024 * 1024;
1382 lovdesc->ld_default_stripe_offset = -1;
1383 lovdesc->ld_qos_maxage = QOS_DEFAULT_MAXAGE;
1384 sprintf((char*)lovdesc->ld_uuid.uuid, "%s_UUID", lovname);
1385 /* can these be the same? */
1386 uuid = (char *)lovdesc->ld_uuid.uuid;
1388 /* This should always be the first entry in a log.
1389 rc = mgs_clear_log(obd, logname); */
1390 rc = record_start_log(env, mgs, &llh, logname);
1393 /* FIXME these should be a single journal transaction */
1394 rc = record_marker(env, llh, fsdb, CM_START, lovname, "lov setup");
1397 rc = record_attach(env, llh, lovname, "lov", uuid);
1400 rc = record_lov_setup(env, llh, lovname, lovdesc);
1403 rc = record_marker(env, llh, fsdb, CM_END, lovname, "lov setup");
1408 record_end_log(env, &llh);
1410 OBD_FREE_PTR(lovdesc);
1414 /* add failnids to open log */
1415 static int mgs_write_log_failnids(const struct lu_env *env,
1416 struct mgs_target_info *mti,
1417 struct llog_handle *llh,
1420 char *failnodeuuid = NULL;
1421 char *ptr = mti->mti_params;
1426 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) nal=90 0: 1:uml1_UUID
1427 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
1428 #05 L setup 0:OSC_uml1_ost1_mdsA 1:ost1_UUID 2:uml1_UUID
1429 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) nal=90 0: 1:uml2_UUID
1430 #0x L add_uuid nid=2@elan(0x1000000000002) nal=90 0: 1:uml2_UUID
1431 #07 L add_conn 0:OSC_uml1_ost1_mdsA 1:uml2_UUID
1434 /* Pull failnid info out of params string */
1435 while (class_find_param(ptr, PARAM_FAILNODE, &ptr) == 0) {
1436 while (class_parse_nid(ptr, &nid, &ptr) == 0) {
1437 if (failnodeuuid == NULL) {
1438 /* We don't know the failover node name,
1439 so just use the first nid as the uuid */
1440 rc = name_create(&failnodeuuid,
1441 libcfs_nid2str(nid), "");
1445 CDEBUG(D_MGS, "add nid %s for failover uuid %s, "
1446 "client %s\n", libcfs_nid2str(nid),
1447 failnodeuuid, cliname);
1448 rc = record_add_uuid(env, llh, nid, failnodeuuid);
1451 rc = record_add_conn(env, llh, cliname, failnodeuuid);
1454 name_destroy(&failnodeuuid);
1458 static int mgs_write_log_mdc_to_lmv(const struct lu_env *env,
1459 struct mgs_device *mgs,
1461 struct mgs_target_info *mti,
1462 char *logname, char *lmvname)
1464 struct llog_handle *llh = NULL;
1465 char *mdcname = NULL;
1466 char *nodeuuid = NULL;
1467 char *mdcuuid = NULL;
1468 char *lmvuuid = NULL;
1473 if (mgs_log_is_empty(env, mgs, logname)) {
1474 CERROR("log is empty! Logical error\n");
1478 CDEBUG(D_MGS, "adding mdc for %s to log %s:lmv(%s)\n",
1479 mti->mti_svname, logname, lmvname);
1481 rc = name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
1484 rc = name_create(&mdcname, mti->mti_svname, "-mdc");
1487 rc = name_create(&mdcuuid, mdcname, "_UUID");
1490 rc = name_create(&lmvuuid, lmvname, "_UUID");
1494 rc = record_start_log(env, mgs, &llh, logname);
1497 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
1501 for (i = 0; i < mti->mti_nid_count; i++) {
1502 CDEBUG(D_MGS, "add nid %s for mdt\n",
1503 libcfs_nid2str(mti->mti_nids[i]));
1505 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
1510 rc = record_attach(env, llh, mdcname, LUSTRE_MDC_NAME, lmvuuid);
1513 rc = record_setup(env, llh, mdcname, mti->mti_uuid, nodeuuid, 0, 0);
1516 rc = mgs_write_log_failnids(env, mti, llh, mdcname);
1519 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
1520 rc = record_mdc_add(env, llh, lmvname, mdcuuid, mti->mti_uuid,
1524 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname,
1529 record_end_log(env, &llh);
1531 name_destroy(&lmvuuid);
1532 name_destroy(&mdcuuid);
1533 name_destroy(&mdcname);
1534 name_destroy(&nodeuuid);
1538 /* add new mdc to already existent MDS */
1539 static int mgs_write_log_mdc_to_mdt(const struct lu_env *env,
1540 struct mgs_device *mgs,
1542 struct mgs_target_info *mti,
1545 struct llog_handle *llh = NULL;
1546 char *nodeuuid = NULL;
1547 char *mdcname = NULL;
1548 char *mdcuuid = NULL;
1549 char *mdtuuid = NULL;
1550 int idx = mti->mti_stripe_index;
1555 if (mgs_log_is_empty(env, mgs, logname)) {
1556 CERROR("log is empty! Logical error\n");
1560 CDEBUG(D_MGS, "adding mdc index %d to %s\n", idx, logname);
1562 rc = name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
1565 snprintf(index, sizeof(index), "-mdc%04x", idx);
1566 rc = name_create(&mdcname, logname, index);
1569 rc = name_create(&mdcuuid, mdcname, "_UUID");
1572 rc = name_create(&mdtuuid, logname, "_UUID");
1576 rc = record_start_log(env, mgs, &llh, logname);
1579 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname, "add mdc");
1582 for (i = 0; i < mti->mti_nid_count; i++) {
1583 CDEBUG(D_MGS, "add nid %s for mdt\n",
1584 libcfs_nid2str(mti->mti_nids[i]));
1585 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
1589 rc = record_attach(env, llh, mdcname, LUSTRE_MDC_NAME, mdcuuid);
1592 rc = record_setup(env, llh, mdcname, mti->mti_uuid, nodeuuid, 0, 0);
1595 rc = mgs_write_log_failnids(env, mti, llh, mdcname);
1598 snprintf(index, sizeof(index), "%d", idx);
1600 rc = record_mdc_add(env, llh, logname, mdcuuid, mti->mti_uuid,
1604 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname, "add mdc");
1608 record_end_log(env, &llh);
1610 name_destroy(&mdtuuid);
1611 name_destroy(&mdcuuid);
1612 name_destroy(&mdcname);
1613 name_destroy(&nodeuuid);
1617 static int mgs_write_log_mdt0(const struct lu_env *env,
1618 struct mgs_device *mgs,
1620 struct mgs_target_info *mti)
1622 char *log = mti->mti_svname;
1623 struct llog_handle *llh = NULL;
1624 char *uuid, *lovname;
1626 char *ptr = mti->mti_params;
1627 int rc = 0, failout = 0;
1630 OBD_ALLOC(uuid, sizeof(struct obd_uuid));
1634 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
1635 failout = (strncmp(ptr, "failout", 7) == 0);
1637 rc = name_create(&lovname, log, "-mdtlov");
1640 if (mgs_log_is_empty(env, mgs, log)) {
1641 rc = mgs_write_log_lov(env, mgs, fsdb, mti, log, lovname);
1646 sprintf(mdt_index, "%d", mti->mti_stripe_index);
1648 rc = record_start_log(env, mgs, &llh, log);
1652 /* add MDT itself */
1654 /* FIXME this whole fn should be a single journal transaction */
1655 sprintf(uuid, "%s_UUID", log);
1656 rc = record_marker(env, llh, fsdb, CM_START, log, "add mdt");
1659 rc = record_attach(env, llh, log, LUSTRE_MDT_NAME, uuid);
1662 rc = record_mount_opt(env, llh, log, lovname, NULL);
1665 rc = record_setup(env, llh, log, uuid, mdt_index, lovname,
1666 failout ? "n" : "f");
1669 rc = record_marker(env, llh, fsdb, CM_END, log, "add mdt");
1673 record_end_log(env, &llh);
1675 name_destroy(&lovname);
1677 OBD_FREE(uuid, sizeof(struct obd_uuid));
1681 static inline int name_create_mdt(char **logname, char *fsname, int i)
1685 sprintf(mdt_index, "-MDT%04x", i);
1686 return name_create(logname, fsname, mdt_index);
1689 static int name_create_mdt_and_lov(char **logname, char **lovname,
1690 struct fs_db *fsdb, int i)
1694 rc = name_create_mdt(logname, fsdb->fsdb_name, i);
1698 if (i == 0 && cfs_test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
1699 rc = name_create(lovname, fsdb->fsdb_name, "-mdtlov");
1701 rc = name_create(lovname, *logname, "-mdtlov");
1703 name_destroy(logname);
1709 static inline int name_create_mdt_osc(char **oscname, char *ostname,
1710 struct fs_db *fsdb, int i)
1714 if (i == 0 && cfs_test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
1715 sprintf(suffix, "-osc");
1717 sprintf(suffix, "-osc-MDT%04x", i);
1718 return name_create(oscname, ostname, suffix);
1721 /* envelope method for all layers log */
1722 static int mgs_write_log_mdt(const struct lu_env *env,
1723 struct mgs_device *mgs,
1725 struct mgs_target_info *mti)
1727 struct mgs_thread_info *mgi = mgs_env_info(env);
1728 struct llog_handle *llh = NULL;
1733 CDEBUG(D_MGS, "writing new mdt %s\n", mti->mti_svname);
1735 if (mti->mti_uuid[0] == '\0') {
1736 /* Make up our own uuid */
1737 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
1738 "%s_UUID", mti->mti_svname);
1742 rc = mgs_write_log_mdt0(env, mgs, fsdb, mti);
1745 /* Append the mdt info to the client log */
1746 rc = name_create(&cliname, mti->mti_fsname, "-client");
1750 if (mgs_log_is_empty(env, mgs, cliname)) {
1751 /* Start client log */
1752 rc = mgs_write_log_lov(env, mgs, fsdb, mti, cliname,
1756 rc = mgs_write_log_lmv(env, mgs, fsdb, mti, cliname,
1763 #09 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
1764 #10 L attach 0:MDC_uml1_mdsA_MNT_client 1:mdc 2:1d834_MNT_client_03f
1765 #11 L setup 0:MDC_uml1_mdsA_MNT_client 1:mdsA_UUID 2:uml1_UUID
1766 #12 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
1767 #13 L add_conn 0:MDC_uml1_mdsA_MNT_client 1:uml2_UUID
1768 #14 L mount_option 0: 1:client 2:lov1 3:MDC_uml1_mdsA_MNT_client
1771 /* copy client info about lov/lmv */
1772 mgi->mgi_comp.comp_mti = mti;
1773 mgi->mgi_comp.comp_fsdb = fsdb;
1775 rc = mgs_steal_llog_for_mdt_from_client(env, mgs, cliname,
1779 rc = mgs_write_log_mdc_to_lmv(env, mgs, fsdb, mti, cliname,
1785 rc = record_start_log(env, mgs, &llh, cliname);
1789 rc = record_marker(env, llh, fsdb, CM_START, cliname,
1793 rc = record_mount_opt(env, llh, cliname, fsdb->fsdb_clilov,
1797 rc = record_marker(env, llh, fsdb, CM_END, cliname,
1802 /* for_all_existing_mdt except current one */
1803 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
1805 if (i != mti->mti_stripe_index &&
1806 cfs_test_bit(i, fsdb->fsdb_mdt_index_map)) {
1807 rc = name_create_mdt(&mdtname, mti->mti_fsname, i);
1810 rc = mgs_write_log_mdc_to_mdt(env, mgs, fsdb, mti, mdtname);
1811 name_destroy(&mdtname);
1817 record_end_log(env, &llh);
1819 name_destroy(&cliname);
1823 /* Add the ost info to the client/mdt lov */
1824 static int mgs_write_log_osc_to_lov(const struct lu_env *env,
1825 struct mgs_device *mgs, struct fs_db *fsdb,
1826 struct mgs_target_info *mti,
1827 char *logname, char *suffix, char *lovname,
1828 enum lustre_sec_part sec_part, int flags)
1830 struct llog_handle *llh = NULL;
1831 char *nodeuuid = NULL;
1832 char *oscname = NULL;
1833 char *oscuuid = NULL;
1834 char *lovuuid = NULL;
1835 char *svname = NULL;
1840 CDEBUG(D_INFO, "adding osc for %s to log %s\n",
1841 mti->mti_svname, logname);
1843 if (mgs_log_is_empty(env, mgs, logname)) {
1844 CERROR("log is empty! Logical error\n");
1848 rc = name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
1851 rc = name_create(&svname, mti->mti_svname, "-osc");
1854 rc = name_create(&oscname, svname, suffix);
1857 rc = name_create(&oscuuid, oscname, "_UUID");
1860 rc = name_create(&lovuuid, lovname, "_UUID");
1865 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
1867 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
1868 #04 L attach 0:OSC_uml1_ost1_MNT_client 1:osc 2:89070_lov1_a41dff51a
1869 #05 L setup 0:OSC_uml1_ost1_MNT_client 1:ost1_UUID 2:uml1_UUID
1871 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
1872 #07 L add_conn 0:OSC_uml1_ost1_MNT_client 1:uml2_UUID
1873 #08 L lov_modify_tgts add 0:lov1 1:ost1_UUID 2(index):0 3(gen):1
1876 rc = record_start_log(env, mgs, &llh, logname);
1879 /* FIXME these should be a single journal transaction */
1880 rc = record_marker(env, llh, fsdb, CM_START | flags, mti->mti_svname,
1884 for (i = 0; i < mti->mti_nid_count; i++) {
1885 CDEBUG(D_MGS, "add nid %s\n", libcfs_nid2str(mti->mti_nids[i]));
1886 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
1890 rc = record_attach(env, llh, oscname, LUSTRE_OSC_NAME, lovuuid);
1893 rc = record_setup(env, llh, oscname, mti->mti_uuid, nodeuuid, 0, 0);
1896 rc = mgs_write_log_failnids(env, mti, llh, oscname);
1899 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
1900 rc = record_lov_add(env, llh, lovname, mti->mti_uuid, index, "1");
1903 rc = record_marker(env, llh, fsdb, CM_END | flags, mti->mti_svname,
1908 record_end_log(env, &llh);
1910 name_destroy(&lovuuid);
1911 name_destroy(&oscuuid);
1912 name_destroy(&oscname);
1913 name_destroy(&svname);
1914 name_destroy(&nodeuuid);
1918 static int mgs_write_log_ost(const struct lu_env *env,
1919 struct mgs_device *mgs, struct fs_db *fsdb,
1920 struct mgs_target_info *mti)
1922 struct llog_handle *llh = NULL;
1923 char *logname, *lovname;
1924 char *ptr = mti->mti_params;
1925 int rc, flags = 0, failout = 0, i;
1928 CDEBUG(D_MGS, "writing new ost %s\n", mti->mti_svname);
1930 /* The ost startup log */
1932 /* If the ost log already exists, that means that someone reformatted
1933 the ost and it called target_add again. */
1934 if (!mgs_log_is_empty(env, mgs, mti->mti_svname)) {
1935 LCONSOLE_ERROR_MSG(0x141, "The config log for %s already "
1936 "exists, yet the server claims it never "
1937 "registered. It may have been reformatted, "
1938 "or the index changed. writeconf the MDT to "
1939 "regenerate all logs.\n", mti->mti_svname);
1944 attach obdfilter ost1 ost1_UUID
1945 setup /dev/loop2 ldiskfs f|n errors=remount-ro,user_xattr
1947 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
1948 failout = (strncmp(ptr, "failout", 7) == 0);
1949 rc = record_start_log(env, mgs, &llh, mti->mti_svname);
1952 /* FIXME these should be a single journal transaction */
1953 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,"add ost");
1956 if (*mti->mti_uuid == '\0')
1957 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
1958 "%s_UUID", mti->mti_svname);
1959 rc = record_attach(env, llh, mti->mti_svname,
1960 "obdfilter"/*LUSTRE_OST_NAME*/, mti->mti_uuid);
1963 rc = record_setup(env, llh, mti->mti_svname,
1964 "dev"/*ignored*/, "type"/*ignored*/,
1965 failout ? "n" : "f", 0/*options*/);
1968 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname, "add ost");
1972 record_end_log(env, &llh);
1975 /* We also have to update the other logs where this osc is part of
1978 if (cfs_test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
1979 /* If we're upgrading, the old mdt log already has our
1980 entry. Let's do a fake one for fun. */
1981 /* Note that we can't add any new failnids, since we don't
1982 know the old osc names. */
1983 flags = CM_SKIP | CM_UPGRADE146;
1985 } else if ((mti->mti_flags & LDD_F_UPDATE) != LDD_F_UPDATE) {
1986 /* If the update flag isn't set, don't update client/mdt
1989 LCONSOLE_WARN("Client log for %s was not updated; writeconf "
1990 "the MDT first to regenerate it.\n",
1994 /* Add ost to all MDT lov defs */
1995 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
1996 if (cfs_test_bit(i, fsdb->fsdb_mdt_index_map)) {
1999 rc = name_create_mdt_and_lov(&logname, &lovname, fsdb,
2003 sprintf(mdt_index, "-MDT%04x", i);
2004 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, mti,
2006 lovname, LUSTRE_SP_MDT,
2008 name_destroy(&logname);
2009 name_destroy(&lovname);
2015 /* Append ost info to the client log */
2016 rc = name_create(&logname, mti->mti_fsname, "-client");
2019 if (mgs_log_is_empty(env, mgs, logname)) {
2020 /* Start client log */
2021 rc = mgs_write_log_lov(env, mgs, fsdb, mti, logname,
2025 rc = mgs_write_log_lmv(env, mgs, fsdb, mti, logname,
2030 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, mti, logname, "",
2031 fsdb->fsdb_clilov, LUSTRE_SP_CLI, 0);
2033 name_destroy(&logname);
2037 static __inline__ int mgs_param_empty(char *ptr)
2041 if ((tmp = strchr(ptr, '=')) && (*(++tmp) == '\0'))
2046 static int mgs_write_log_failnid_internal(const struct lu_env *env,
2047 struct mgs_device *mgs,
2049 struct mgs_target_info *mti,
2050 char *logname, char *cliname)
2053 struct llog_handle *llh = NULL;
2055 if (mgs_param_empty(mti->mti_params)) {
2056 /* Remove _all_ failnids */
2057 rc = mgs_modify(env, mgs, fsdb, mti, logname,
2058 mti->mti_svname, "add failnid", CM_SKIP);
2059 return rc < 0 ? rc : 0;
2062 /* Otherwise failover nids are additive */
2063 rc = record_start_log(env, mgs, &llh, logname);
2066 /* FIXME this should be a single journal transaction */
2067 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
2071 rc = mgs_write_log_failnids(env, mti, llh, cliname);
2074 rc = record_marker(env, llh, fsdb, CM_END,
2075 mti->mti_svname, "add failnid");
2077 record_end_log(env, &llh);
2082 /* Add additional failnids to an existing log.
2083 The mdc/osc must have been added to logs first */
2084 /* tcp nids must be in dotted-quad ascii -
2085 we can't resolve hostnames from the kernel. */
2086 static int mgs_write_log_add_failnid(const struct lu_env *env,
2087 struct mgs_device *mgs,
2089 struct mgs_target_info *mti)
2091 char *logname, *cliname;
2095 /* FIXME we currently can't erase the failnids
2096 * given when a target first registers, since they aren't part of
2097 * an "add uuid" stanza */
2099 /* Verify that we know about this target */
2100 if (mgs_log_is_empty(env, mgs, mti->mti_svname)) {
2101 LCONSOLE_ERROR_MSG(0x142, "The target %s has not registered "
2102 "yet. It must be started before failnids "
2103 "can be added.\n", mti->mti_svname);
2107 /* Create mdc/osc client name (e.g. lustre-OST0001-osc) */
2108 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
2109 rc = name_create(&cliname, mti->mti_svname, "-mdc");
2110 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2111 rc = name_create(&cliname, mti->mti_svname, "-osc");
2117 /* Add failover nids to the client log */
2118 rc = name_create(&logname, mti->mti_fsname, "-client");
2120 name_destroy(&cliname);
2123 rc = mgs_write_log_failnid_internal(env, mgs, fsdb,mti,logname,cliname);
2124 name_destroy(&logname);
2125 name_destroy(&cliname);
2129 if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2130 /* Add OST failover nids to the MDT logs as well */
2133 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2134 if (!cfs_test_bit(i, fsdb->fsdb_mdt_index_map))
2136 rc = name_create_mdt(&logname, mti->mti_fsname, i);
2139 rc = name_create_mdt_osc(&cliname, mti->mti_svname,
2142 name_destroy(&logname);
2145 rc = mgs_write_log_failnid_internal(env, mgs, fsdb,
2148 name_destroy(&cliname);
2149 name_destroy(&logname);
2158 static int mgs_wlp_lcfg(const struct lu_env *env,
2159 struct mgs_device *mgs, struct fs_db *fsdb,
2160 struct mgs_target_info *mti,
2161 char *logname, struct lustre_cfg_bufs *bufs,
2162 char *tgtname, char *ptr)
2164 char comment[MTI_NAME_MAXLEN];
2166 struct lustre_cfg *lcfg;
2169 /* Erase any old settings of this same parameter */
2170 memcpy(comment, ptr, MTI_NAME_MAXLEN);
2171 comment[MTI_NAME_MAXLEN - 1] = 0;
2172 /* But don't try to match the value. */
2173 if ((tmp = strchr(comment, '=')))
2175 /* FIXME we should skip settings that are the same as old values */
2176 rc = mgs_modify(env, mgs, fsdb, mti, logname, tgtname, comment,CM_SKIP);
2179 del = mgs_param_empty(ptr);
2181 LCONSOLE_INFO("%sing parameter %s.%s in log %s\n", del ? "Disabl" : rc ?
2182 "Sett" : "Modify", tgtname, comment, logname);
2186 lustre_cfg_bufs_reset(bufs, tgtname);
2187 lustre_cfg_bufs_set_string(bufs, 1, ptr);
2188 lcfg = lustre_cfg_new(LCFG_PARAM, bufs);
2191 rc = mgs_write_log_direct(env, mgs, fsdb, logname,lcfg,tgtname,comment);
2192 lustre_cfg_free(lcfg);
2196 /* write global variable settings into log */
2197 static int mgs_write_log_sys(const struct lu_env *env,
2198 struct mgs_device *mgs, struct fs_db *fsdb,
2199 struct mgs_target_info *mti, char *sys, char *ptr)
2201 struct mgs_thread_info *mgi = mgs_env_info(env);
2202 struct lustre_cfg *lcfg;
2204 int rc, cmd, convert = 1;
2206 if (class_match_param(ptr, PARAM_TIMEOUT, &tmp) == 0) {
2207 cmd = LCFG_SET_TIMEOUT;
2208 } else if (class_match_param(ptr, PARAM_LDLM_TIMEOUT, &tmp) == 0) {
2209 cmd = LCFG_SET_LDLM_TIMEOUT;
2210 /* Check for known params here so we can return error to lctl */
2211 } else if ((class_match_param(ptr, PARAM_AT_MIN, &tmp) == 0) ||
2212 (class_match_param(ptr, PARAM_AT_MAX, &tmp) == 0) ||
2213 (class_match_param(ptr, PARAM_AT_EXTRA, &tmp) == 0) ||
2214 (class_match_param(ptr, PARAM_AT_EARLY_MARGIN, &tmp) == 0) ||
2215 (class_match_param(ptr, PARAM_AT_HISTORY, &tmp) == 0)) {
2217 } else if (class_match_param(ptr, PARAM_JOBID_VAR, &tmp) == 0) {
2218 convert = 0; /* Don't convert string value to integer */
2224 if (mgs_param_empty(ptr))
2225 CDEBUG(D_MGS, "global '%s' removed\n", sys);
2227 CDEBUG(D_MGS, "global '%s' val=%s\n", sys, tmp);
2229 lustre_cfg_bufs_reset(&mgi->mgi_bufs, NULL);
2230 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, sys);
2231 if (!convert && *tmp != '\0')
2232 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 2, tmp);
2233 lcfg = lustre_cfg_new(cmd, &mgi->mgi_bufs);
2234 lcfg->lcfg_num = convert ? simple_strtoul(tmp, NULL, 0) : 0;
2235 /* truncate the comment to the parameter name */
2239 /* modify all servers and clients */
2240 rc = mgs_write_log_direct_all(env, mgs, fsdb, mti,
2241 *tmp == '\0' ? NULL : lcfg,
2242 mti->mti_fsname, sys, 0);
2243 if (rc == 0 && *tmp != '\0') {
2245 case LCFG_SET_TIMEOUT:
2246 if (!obd_timeout_set || lcfg->lcfg_num > obd_timeout)
2247 class_process_config(lcfg);
2249 case LCFG_SET_LDLM_TIMEOUT:
2250 if (!ldlm_timeout_set || lcfg->lcfg_num > ldlm_timeout)
2251 class_process_config(lcfg);
2258 lustre_cfg_free(lcfg);
2262 /* write quota settings into log */
2263 static int mgs_write_log_quota(const struct lu_env *env, struct mgs_device *mgs,
2264 struct fs_db *fsdb, struct mgs_target_info *mti,
2265 char *quota, char *ptr)
2267 struct mgs_thread_info *mgi = mgs_env_info(env);
2268 struct lustre_cfg *lcfg;
2271 int rc, cmd = LCFG_PARAM;
2273 /* support only 'meta' and 'data' pools so far */
2274 if (class_match_param(ptr, QUOTA_METAPOOL_NAME, &tmp) != 0 &&
2275 class_match_param(ptr, QUOTA_DATAPOOL_NAME, &tmp) != 0) {
2276 CERROR("parameter quota.%s isn't supported (only quota.mdt "
2277 "& quota.ost are)\n", ptr);
2282 CDEBUG(D_MGS, "global '%s' removed\n", quota);
2284 CDEBUG(D_MGS, "global '%s'\n", quota);
2286 if (strchr(tmp, 'u') == NULL && strchr(tmp, 'g') == NULL &&
2287 strcmp(tmp, "none") != 0) {
2288 CERROR("enable option(%s) isn't supported\n", tmp);
2293 lustre_cfg_bufs_reset(&mgi->mgi_bufs, mti->mti_fsname);
2294 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, quota);
2295 lcfg = lustre_cfg_new(cmd, &mgi->mgi_bufs);
2296 /* truncate the comment to the parameter name */
2301 /* XXX we duplicated quota enable information in all server
2302 * config logs, it should be moved to a separate config
2303 * log once we cleanup the config log for global param. */
2304 /* modify all servers */
2305 rc = mgs_write_log_direct_all(env, mgs, fsdb, mti,
2306 *tmp == '\0' ? NULL : lcfg,
2307 mti->mti_fsname, quota, 1);
2309 lustre_cfg_free(lcfg);
2313 static int mgs_srpc_set_param_disk(const struct lu_env *env,
2314 struct mgs_device *mgs,
2316 struct mgs_target_info *mti,
2319 struct mgs_thread_info *mgi = mgs_env_info(env);
2320 struct llog_handle *llh = NULL;
2322 char *comment, *ptr;
2323 struct lustre_cfg *lcfg;
2328 ptr = strchr(param, '=');
2332 OBD_ALLOC(comment, len + 1);
2333 if (comment == NULL)
2335 strncpy(comment, param, len);
2336 comment[len] = '\0';
2339 lustre_cfg_bufs_reset(&mgi->mgi_bufs, mti->mti_svname);
2340 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, param);
2341 lcfg = lustre_cfg_new(LCFG_SPTLRPC_CONF, &mgi->mgi_bufs);
2343 GOTO(out_comment, rc = -ENOMEM);
2345 /* construct log name */
2346 rc = name_create(&logname, mti->mti_fsname, "-sptlrpc");
2350 if (mgs_log_is_empty(env, mgs, logname)) {
2351 rc = record_start_log(env, mgs, &llh, logname);
2354 record_end_log(env, &llh);
2357 /* obsolete old one */
2358 rc = mgs_modify(env, mgs, fsdb, mti, logname, mti->mti_svname,
2362 /* write the new one */
2363 rc = mgs_write_log_direct(env, mgs, fsdb, logname, lcfg,
2364 mti->mti_svname, comment);
2366 CERROR("err %d writing log %s\n", rc, logname);
2368 name_destroy(&logname);
2370 lustre_cfg_free(lcfg);
2372 OBD_FREE(comment, len + 1);
2376 static int mgs_srpc_set_param_udesc_mem(struct fs_db *fsdb,
2381 /* disable the adjustable udesc parameter for now, i.e. use default
2382 * setting that client always ship udesc to MDT if possible. to enable
2383 * it simply remove the following line */
2386 ptr = strchr(param, '=');
2391 if (strcmp(param, PARAM_SRPC_UDESC))
2394 if (strcmp(ptr, "yes") == 0) {
2395 cfs_set_bit(FSDB_UDESC, &fsdb->fsdb_flags);
2396 CWARN("Enable user descriptor shipping from client to MDT\n");
2397 } else if (strcmp(ptr, "no") == 0) {
2398 cfs_clear_bit(FSDB_UDESC, &fsdb->fsdb_flags);
2399 CWARN("Disable user descriptor shipping from client to MDT\n");
2407 CERROR("Invalid param: %s\n", param);
2411 static int mgs_srpc_set_param_mem(struct fs_db *fsdb,
2415 struct sptlrpc_rule rule;
2416 struct sptlrpc_rule_set *rset;
2420 if (strncmp(param, PARAM_SRPC, sizeof(PARAM_SRPC) - 1) != 0) {
2421 CERROR("Invalid sptlrpc parameter: %s\n", param);
2425 if (strncmp(param, PARAM_SRPC_UDESC,
2426 sizeof(PARAM_SRPC_UDESC) - 1) == 0) {
2427 RETURN(mgs_srpc_set_param_udesc_mem(fsdb, param));
2430 if (strncmp(param, PARAM_SRPC_FLVR, sizeof(PARAM_SRPC_FLVR) - 1) != 0) {
2431 CERROR("Invalid sptlrpc flavor parameter: %s\n", param);
2435 param += sizeof(PARAM_SRPC_FLVR) - 1;
2437 rc = sptlrpc_parse_rule(param, &rule);
2441 /* mgs rules implies must be mgc->mgs */
2442 if (cfs_test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
2443 if ((rule.sr_from != LUSTRE_SP_MGC &&
2444 rule.sr_from != LUSTRE_SP_ANY) ||
2445 (rule.sr_to != LUSTRE_SP_MGS &&
2446 rule.sr_to != LUSTRE_SP_ANY))
2450 /* preapre room for this coming rule. svcname format should be:
2451 * - fsname: general rule
2452 * - fsname-tgtname: target-specific rule
2454 if (strchr(svname, '-')) {
2455 struct mgs_tgt_srpc_conf *tgtconf;
2458 for (tgtconf = fsdb->fsdb_srpc_tgt; tgtconf != NULL;
2459 tgtconf = tgtconf->mtsc_next) {
2460 if (!strcmp(tgtconf->mtsc_tgt, svname)) {
2469 OBD_ALLOC_PTR(tgtconf);
2470 if (tgtconf == NULL)
2473 name_len = strlen(svname);
2475 OBD_ALLOC(tgtconf->mtsc_tgt, name_len + 1);
2476 if (tgtconf->mtsc_tgt == NULL) {
2477 OBD_FREE_PTR(tgtconf);
2480 memcpy(tgtconf->mtsc_tgt, svname, name_len);
2482 tgtconf->mtsc_next = fsdb->fsdb_srpc_tgt;
2483 fsdb->fsdb_srpc_tgt = tgtconf;
2486 rset = &tgtconf->mtsc_rset;
2488 rset = &fsdb->fsdb_srpc_gen;
2491 rc = sptlrpc_rule_set_merge(rset, &rule);
2496 static int mgs_srpc_set_param(const struct lu_env *env,
2497 struct mgs_device *mgs,
2499 struct mgs_target_info *mti,
2509 /* keep a copy of original param, which could be destroied
2511 copy_size = strlen(param) + 1;
2512 OBD_ALLOC(copy, copy_size);
2515 memcpy(copy, param, copy_size);
2517 rc = mgs_srpc_set_param_mem(fsdb, mti->mti_svname, param);
2521 /* previous steps guaranteed the syntax is correct */
2522 rc = mgs_srpc_set_param_disk(env, mgs, fsdb, mti, copy);
2526 if (cfs_test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
2528 * for mgs rules, make them effective immediately.
2530 LASSERT(fsdb->fsdb_srpc_tgt == NULL);
2531 sptlrpc_target_update_exp_flavor(mgs->mgs_obd,
2532 &fsdb->fsdb_srpc_gen);
2536 OBD_FREE(copy, copy_size);
2540 struct mgs_srpc_read_data {
2541 struct fs_db *msrd_fsdb;
2545 static int mgs_srpc_read_handler(const struct lu_env *env,
2546 struct llog_handle *llh,
2547 struct llog_rec_hdr *rec, void *data)
2549 struct mgs_srpc_read_data *msrd = data;
2550 struct cfg_marker *marker;
2551 struct lustre_cfg *lcfg = (struct lustre_cfg *)(rec + 1);
2552 char *svname, *param;
2556 if (rec->lrh_type != OBD_CFG_REC) {
2557 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
2561 cfg_len = rec->lrh_len - sizeof(struct llog_rec_hdr) -
2562 sizeof(struct llog_rec_tail);
2564 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
2566 CERROR("Insane cfg\n");
2570 if (lcfg->lcfg_command == LCFG_MARKER) {
2571 marker = lustre_cfg_buf(lcfg, 1);
2573 if (marker->cm_flags & CM_START &&
2574 marker->cm_flags & CM_SKIP)
2575 msrd->msrd_skip = 1;
2576 if (marker->cm_flags & CM_END)
2577 msrd->msrd_skip = 0;
2582 if (msrd->msrd_skip)
2585 if (lcfg->lcfg_command != LCFG_SPTLRPC_CONF) {
2586 CERROR("invalid command (%x)\n", lcfg->lcfg_command);
2590 svname = lustre_cfg_string(lcfg, 0);
2591 if (svname == NULL) {
2592 CERROR("svname is empty\n");
2596 param = lustre_cfg_string(lcfg, 1);
2597 if (param == NULL) {
2598 CERROR("param is empty\n");
2602 rc = mgs_srpc_set_param_mem(msrd->msrd_fsdb, svname, param);
2604 CERROR("read sptlrpc record error (%d): %s\n", rc, param);
2609 int mgs_get_fsdb_srpc_from_llog(const struct lu_env *env,
2610 struct mgs_device *mgs,
2613 struct llog_handle *llh = NULL;
2614 struct llog_ctxt *ctxt;
2616 struct mgs_srpc_read_data msrd;
2620 /* construct log name */
2621 rc = name_create(&logname, fsdb->fsdb_name, "-sptlrpc");
2625 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
2626 LASSERT(ctxt != NULL);
2628 if (mgs_log_is_empty(env, mgs, logname))
2631 rc = llog_open(env, ctxt, &llh, NULL, logname,
2639 rc = llog_init_handle(env, llh, LLOG_F_IS_PLAIN, NULL);
2641 GOTO(out_close, rc);
2643 if (llog_get_size(llh) <= 1)
2644 GOTO(out_close, rc = 0);
2646 msrd.msrd_fsdb = fsdb;
2649 rc = llog_process(env, llh, mgs_srpc_read_handler, (void *)&msrd,
2653 llog_close(env, llh);
2655 llog_ctxt_put(ctxt);
2656 name_destroy(&logname);
2659 CERROR("failed to read sptlrpc config database: %d\n", rc);
2663 /* Permanent settings of all parameters by writing into the appropriate
2664 * configuration logs.
2665 * A parameter with null value ("<param>='\0'") means to erase it out of
2668 static int mgs_write_log_param(const struct lu_env *env,
2669 struct mgs_device *mgs, struct fs_db *fsdb,
2670 struct mgs_target_info *mti, char *ptr)
2672 struct mgs_thread_info *mgi = mgs_env_info(env);
2675 int rc = 0, rc2 = 0;
2678 /* For various parameter settings, we have to figure out which logs
2679 care about them (e.g. both mdt and client for lov settings) */
2680 CDEBUG(D_MGS, "next param '%s'\n", ptr);
2682 /* The params are stored in MOUNT_DATA_FILE and modified via
2683 tunefs.lustre, or set using lctl conf_param */
2685 /* Processed in lustre_start_mgc */
2686 if (class_match_param(ptr, PARAM_MGSNODE, NULL) == 0)
2689 /* Processed in ost/mdt */
2690 if (class_match_param(ptr, PARAM_NETWORK, NULL) == 0)
2693 /* Processed in mgs_write_log_ost */
2694 if (class_match_param(ptr, PARAM_FAILMODE, NULL) == 0) {
2695 if (mti->mti_flags & LDD_F_PARAM) {
2696 LCONSOLE_ERROR_MSG(0x169, "%s can only be "
2697 "changed with tunefs.lustre"
2698 "and --writeconf\n", ptr);
2704 if (class_match_param(ptr, PARAM_SRPC, NULL) == 0) {
2705 rc = mgs_srpc_set_param(env, mgs, fsdb, mti, ptr);
2709 if (class_match_param(ptr, PARAM_FAILNODE, NULL) == 0) {
2710 /* Add a failover nidlist */
2712 /* We already processed failovers params for new
2713 targets in mgs_write_log_target */
2714 if (mti->mti_flags & LDD_F_PARAM) {
2715 CDEBUG(D_MGS, "Adding failnode\n");
2716 rc = mgs_write_log_add_failnid(env, mgs, fsdb, mti);
2721 if (class_match_param(ptr, PARAM_SYS, &tmp) == 0) {
2722 rc = mgs_write_log_sys(env, mgs, fsdb, mti, ptr, tmp);
2726 if (class_match_param(ptr, PARAM_QUOTA, &tmp) == 0) {
2727 rc = mgs_write_log_quota(env, mgs, fsdb, mti, ptr, tmp);
2731 if (class_match_param(ptr, PARAM_OSC""PARAM_ACTIVE, &tmp) == 0) {
2732 /* active=0 means off, anything else means on */
2733 int flag = (*tmp == '0') ? CM_EXCLUDE : 0;
2736 if (!(mti->mti_flags & LDD_F_SV_TYPE_OST)) {
2737 LCONSOLE_ERROR_MSG(0x144, "%s: Only OSCs can "
2738 "be (de)activated.\n",
2740 GOTO(end, rc = -EINVAL);
2742 LCONSOLE_WARN("Permanently %sactivating %s\n",
2743 flag ? "de": "re", mti->mti_svname);
2745 rc = name_create(&logname, mti->mti_fsname, "-client");
2748 rc = mgs_modify(env, mgs, fsdb, mti, logname,
2749 mti->mti_svname, "add osc", flag);
2750 name_destroy(&logname);
2754 /* Add to all MDT logs for CMD */
2755 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2756 if (!cfs_test_bit(i, fsdb->fsdb_mdt_index_map))
2758 rc = name_create_mdt(&logname, mti->mti_fsname, i);
2761 rc = mgs_modify(env, mgs, fsdb, mti, logname,
2762 mti->mti_svname, "add osc", flag);
2763 name_destroy(&logname);
2769 LCONSOLE_ERROR_MSG(0x145, "Couldn't find %s in"
2770 "log (%d). No permanent "
2771 "changes were made to the "
2773 mti->mti_svname, rc);
2774 if (cfs_test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags))
2775 LCONSOLE_ERROR_MSG(0x146, "This may be"
2780 "update the logs.\n");
2783 /* Fall through to osc proc for deactivating live OSC
2784 on running MDT / clients. */
2786 /* Below here, let obd's XXX_process_config methods handle it */
2788 /* All lov. in proc */
2789 if (class_match_param(ptr, PARAM_LOV, NULL) == 0) {
2792 CDEBUG(D_MGS, "lov param %s\n", ptr);
2793 if (!(mti->mti_flags & LDD_F_SV_TYPE_MDT)) {
2794 LCONSOLE_ERROR_MSG(0x147, "LOV params must be "
2795 "set on the MDT, not %s. "
2802 if (mgs_log_is_empty(env, mgs, mti->mti_svname))
2803 GOTO(end, rc = -ENODEV);
2805 rc = name_create_mdt_and_lov(&logname, &mdtlovname, fsdb,
2806 mti->mti_stripe_index);
2809 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, mti->mti_svname,
2810 &mgi->mgi_bufs, mdtlovname, ptr);
2811 name_destroy(&logname);
2812 name_destroy(&mdtlovname);
2817 rc = name_create(&logname, mti->mti_fsname, "-client");
2820 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname, &mgi->mgi_bufs,
2821 fsdb->fsdb_clilov, ptr);
2822 name_destroy(&logname);
2826 /* All osc., mdc., llite. params in proc */
2827 if ((class_match_param(ptr, PARAM_OSC, NULL) == 0) ||
2828 (class_match_param(ptr, PARAM_MDC, NULL) == 0) ||
2829 (class_match_param(ptr, PARAM_LLITE, NULL) == 0)) {
2832 if (cfs_test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
2833 LCONSOLE_ERROR_MSG(0x148, "Upgraded client logs for %s"
2834 " cannot be modified. Consider"
2835 " updating the configuration with"
2838 GOTO(end, rc = -EINVAL);
2840 if (memcmp(ptr, PARAM_LLITE, strlen(PARAM_LLITE)) == 0) {
2841 rc = name_create(&cname, mti->mti_fsname, "-client");
2842 /* Add the client type to match the obdname in
2843 class_config_llog_handler */
2844 } else if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
2845 rc = name_create(&cname, mti->mti_svname, "-mdc");
2846 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2847 rc = name_create(&cname, mti->mti_svname, "-osc");
2849 GOTO(end, rc = -EINVAL);
2854 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
2857 rc = name_create(&logname, mti->mti_fsname, "-client");
2859 name_destroy(&cname);
2862 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname, &mgi->mgi_bufs,
2865 /* osc params affect the MDT as well */
2866 if (!rc && (mti->mti_flags & LDD_F_SV_TYPE_OST)) {
2869 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
2870 if (!cfs_test_bit(i, fsdb->fsdb_mdt_index_map))
2872 name_destroy(&cname);
2873 rc = name_create_mdt_osc(&cname, mti->mti_svname,
2875 name_destroy(&logname);
2878 rc = name_create_mdt(&logname,
2879 mti->mti_fsname, i);
2882 if (!mgs_log_is_empty(env, mgs, logname)) {
2883 rc = mgs_wlp_lcfg(env, mgs, fsdb,
2892 name_destroy(&logname);
2893 name_destroy(&cname);
2897 /* All mdt. params in proc */
2898 if (class_match_param(ptr, PARAM_MDT, NULL) == 0) {
2902 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
2903 if (strncmp(mti->mti_svname, mti->mti_fsname,
2904 MTI_NAME_MAXLEN) == 0)
2905 /* device is unspecified completely? */
2906 rc = LDD_F_SV_TYPE_MDT | LDD_F_SV_ALL;
2908 rc = server_name2index(mti->mti_svname, &idx, NULL);
2911 if ((rc & LDD_F_SV_TYPE_MDT) == 0)
2913 if (rc & LDD_F_SV_ALL) {
2914 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2915 if (!cfs_test_bit(i,
2916 fsdb->fsdb_mdt_index_map))
2918 rc = name_create_mdt(&logname,
2919 mti->mti_fsname, i);
2922 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti,
2923 logname, &mgi->mgi_bufs,
2925 name_destroy(&logname);
2930 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti,
2931 mti->mti_svname, &mgi->mgi_bufs,
2932 mti->mti_svname, ptr);
2939 /* All mdd., ost. params in proc */
2940 if ((class_match_param(ptr, PARAM_MDD, NULL) == 0) ||
2941 (class_match_param(ptr, PARAM_OST, NULL) == 0)) {
2942 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
2943 if (mgs_log_is_empty(env, mgs, mti->mti_svname))
2944 GOTO(end, rc = -ENODEV);
2946 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, mti->mti_svname,
2947 &mgi->mgi_bufs, mti->mti_svname, ptr);
2951 LCONSOLE_WARN("Ignoring unrecognized param '%s'\n", ptr);
2956 CERROR("err %d on param '%s'\n", rc, ptr);
2961 /* Not implementing automatic failover nid addition at this time. */
2962 int mgs_check_failnid(const struct lu_env *env, struct mgs_device *mgs,
2963 struct mgs_target_info *mti)
2970 rc = mgs_find_or_make_fsdb(obd, fsname, &fsdb);
2974 if (mgs_log_is_empty(obd, mti->mti_svname))
2975 /* should never happen */
2978 CDEBUG(D_MGS, "Checking for new failnids for %s\n", mti->mti_svname);
2980 /* FIXME We can just check mti->params to see if we're already in
2981 the failover list. Modify mti->params for rewriting back at
2982 server_register_target(). */
2984 cfs_mutex_lock(&fsdb->fsdb_mutex);
2985 rc = mgs_write_log_add_failnid(obd, fsdb, mti);
2986 cfs_mutex_unlock(&fsdb->fsdb_mutex);
2993 int mgs_write_log_target(const struct lu_env *env,
2994 struct mgs_device *mgs,
2995 struct mgs_target_info *mti,
3002 /* set/check the new target index */
3003 rc = mgs_set_index(env, mgs, mti);
3005 CERROR("Can't get index (%d)\n", rc);
3009 if (rc == EALREADY) {
3010 LCONSOLE_WARN("Found index %d for %s, updating log\n",
3011 mti->mti_stripe_index, mti->mti_svname);
3012 /* We would like to mark old log sections as invalid
3013 and add new log sections in the client and mdt logs.
3014 But if we add new sections, then live clients will
3015 get repeat setup instructions for already running
3016 osc's. So don't update the client/mdt logs. */
3017 mti->mti_flags &= ~LDD_F_UPDATE;
3020 cfs_mutex_lock(&fsdb->fsdb_mutex);
3022 if (mti->mti_flags &
3023 (LDD_F_VIRGIN | LDD_F_UPGRADE14 | LDD_F_WRITECONF)) {
3024 /* Generate a log from scratch */
3025 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
3026 rc = mgs_write_log_mdt(env, mgs, fsdb, mti);
3027 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
3028 rc = mgs_write_log_ost(env, mgs, fsdb, mti);
3030 CERROR("Unknown target type %#x, can't create log for "
3031 "%s\n", mti->mti_flags, mti->mti_svname);
3034 CERROR("Can't write logs for %s (%d)\n",
3035 mti->mti_svname, rc);
3039 /* Just update the params from tunefs in mgs_write_log_params */
3040 CDEBUG(D_MGS, "Update params for %s\n", mti->mti_svname);
3041 mti->mti_flags |= LDD_F_PARAM;
3044 /* allocate temporary buffer, where class_get_next_param will
3045 make copy of a current parameter */
3046 OBD_ALLOC(buf, strlen(mti->mti_params) + 1);
3048 GOTO(out_up, rc = -ENOMEM);
3049 params = mti->mti_params;
3050 while (params != NULL) {
3051 rc = class_get_next_param(¶ms, buf);
3054 /* there is no next parameter, that is
3059 CDEBUG(D_MGS, "remaining string: '%s', param: '%s'\n",
3061 rc = mgs_write_log_param(env, mgs, fsdb, mti, buf);
3066 OBD_FREE(buf, strlen(mti->mti_params) + 1);
3069 cfs_mutex_unlock(&fsdb->fsdb_mutex);
3073 int mgs_erase_log(const struct lu_env *env, struct mgs_device *mgs, char *name)
3075 struct llog_ctxt *ctxt;
3078 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
3080 CERROR("%s: MGS config context doesn't exist\n",
3081 mgs->mgs_obd->obd_name);
3084 rc = llog_erase(env, ctxt, NULL, name);
3085 /* llog may not exist */
3088 llog_ctxt_put(ctxt);
3092 CERROR("%s: failed to clear log %s: %d\n",
3093 mgs->mgs_obd->obd_name, name, rc);
3098 /* erase all logs for the given fs */
3099 int mgs_erase_logs(const struct lu_env *env, struct mgs_device *mgs, char *fsname)
3103 struct mgs_direntry *dirent, *n;
3104 int rc, len = strlen(fsname);
3108 /* Find all the logs in the CONFIGS directory */
3109 rc = class_dentry_readdir(env, mgs, &list);
3113 cfs_mutex_lock(&mgs->mgs_mutex);
3115 /* Delete the fs db */
3116 fsdb = mgs_find_fsdb(mgs, fsname);
3118 mgs_free_fsdb(mgs, fsdb);
3120 cfs_mutex_unlock(&mgs->mgs_mutex);
3122 cfs_list_for_each_entry_safe(dirent, n, &list, list) {
3123 cfs_list_del(&dirent->list);
3124 suffix = strrchr(dirent->name, '-');
3125 if (suffix != NULL) {
3126 if ((len == suffix - dirent->name) &&
3127 (strncmp(fsname, dirent->name, len) == 0)) {
3128 CDEBUG(D_MGS, "Removing log %s\n",
3130 mgs_erase_log(env, mgs, dirent->name);
3133 mgs_direntry_free(dirent);
3139 /* from llog_swab */
3140 static void print_lustre_cfg(struct lustre_cfg *lcfg)
3145 CDEBUG(D_MGS, "lustre_cfg: %p\n", lcfg);
3146 CDEBUG(D_MGS, "\tlcfg->lcfg_version: %#x\n", lcfg->lcfg_version);
3148 CDEBUG(D_MGS, "\tlcfg->lcfg_command: %#x\n", lcfg->lcfg_command);
3149 CDEBUG(D_MGS, "\tlcfg->lcfg_num: %#x\n", lcfg->lcfg_num);
3150 CDEBUG(D_MGS, "\tlcfg->lcfg_flags: %#x\n", lcfg->lcfg_flags);
3151 CDEBUG(D_MGS, "\tlcfg->lcfg_nid: %s\n", libcfs_nid2str(lcfg->lcfg_nid));
3153 CDEBUG(D_MGS, "\tlcfg->lcfg_bufcount: %d\n", lcfg->lcfg_bufcount);
3154 if (lcfg->lcfg_bufcount < LUSTRE_CFG_MAX_BUFCOUNT)
3155 for (i = 0; i < lcfg->lcfg_bufcount; i++) {
3156 CDEBUG(D_MGS, "\tlcfg->lcfg_buflens[%d]: %d %s\n",
3157 i, lcfg->lcfg_buflens[i],
3158 lustre_cfg_string(lcfg, i));
3163 /* Set a permanent (config log) param for a target or fs
3164 * \param lcfg buf0 may contain the device (testfs-MDT0000) name
3165 * buf1 contains the single parameter
3167 int mgs_setparam(const struct lu_env *env, struct mgs_device *mgs,
3168 struct lustre_cfg *lcfg, char *fsname)
3171 struct mgs_target_info *mti;
3172 char *devname, *param;
3178 print_lustre_cfg(lcfg);
3180 /* lustre, lustre-mdtlov, lustre-client, lustre-MDT0000 */
3181 devname = lustre_cfg_string(lcfg, 0);
3182 param = lustre_cfg_string(lcfg, 1);
3184 /* Assume device name embedded in param:
3185 lustre-OST0000.osc.max_dirty_mb=32 */
3186 ptr = strchr(param, '.');
3194 LCONSOLE_ERROR_MSG(0x14d, "No target specified: %s\n", param);
3198 /* Extract fsname */
3199 ptr = strrchr(devname, '-');
3200 memset(fsname, 0, MTI_NAME_MAXLEN);
3201 if (ptr && (server_name2index(ptr, &index, NULL) >= 0)) {
3202 /* param related to llite isn't allowed to set by OST or MDT */
3203 if (strncmp(param, PARAM_LLITE, sizeof(PARAM_LLITE)) == 0)
3206 strncpy(fsname, devname, ptr - devname);
3208 /* assume devname is the fsname */
3209 strncpy(fsname, devname, MTI_NAME_MAXLEN);
3211 fsname[MTI_NAME_MAXLEN - 1] = 0;
3212 CDEBUG(D_MGS, "setparam fs='%s' device='%s'\n", fsname, devname);
3214 rc = mgs_find_or_make_fsdb(env, mgs, fsname, &fsdb);
3217 if (!cfs_test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags) &&
3218 cfs_test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
3219 CERROR("No filesystem targets for %s. cfg_device from lctl "
3220 "is '%s'\n", fsname, devname);
3221 mgs_free_fsdb(mgs, fsdb);
3225 /* Create a fake mti to hold everything */
3228 GOTO(out, rc = -ENOMEM);
3229 strncpy(mti->mti_fsname, fsname, MTI_NAME_MAXLEN);
3230 strncpy(mti->mti_svname, devname, MTI_NAME_MAXLEN);
3231 strncpy(mti->mti_params, param, sizeof(mti->mti_params));
3232 rc = server_name2index(mti->mti_svname, &mti->mti_stripe_index, &tmp);
3234 /* Not a valid server; may be only fsname */
3237 /* Strip -osc or -mdc suffix from svname */
3238 if (server_make_name(rc, mti->mti_stripe_index, mti->mti_fsname,
3240 GOTO(out, rc = -EINVAL);
3242 mti->mti_flags = rc | LDD_F_PARAM;
3244 cfs_mutex_lock(&fsdb->fsdb_mutex);
3245 rc = mgs_write_log_param(env, mgs, fsdb, mti, mti->mti_params);
3246 cfs_mutex_unlock(&fsdb->fsdb_mutex);
3249 * Revoke lock so everyone updates. Should be alright if
3250 * someone was already reading while we were updating the logs,
3251 * so we don't really need to hold the lock while we're
3254 mgs_revoke_lock(mgs, fsdb, CONFIG_T_CONFIG);
3260 static int mgs_write_log_pool(const struct lu_env *env,
3261 struct mgs_device *mgs, char *logname,
3262 struct fs_db *fsdb, char *lovname,
3263 enum lcfg_command_type cmd,
3264 char *poolname, char *fsname,
3265 char *ostname, char *comment)
3267 struct llog_handle *llh = NULL;
3270 rc = record_start_log(env, mgs, &llh, logname);
3273 rc = record_marker(env, llh, fsdb, CM_START, lovname, comment);
3276 rc = record_base(env, llh, lovname, 0, cmd, poolname, fsname, ostname, 0);
3279 rc = record_marker(env, llh, fsdb, CM_END, lovname, comment);
3281 record_end_log(env, &llh);
3285 int mgs_pool_cmd(const struct lu_env *env, struct mgs_device *mgs,
3286 enum lcfg_command_type cmd, char *fsname,
3287 char *poolname, char *ostname)
3292 char *label = NULL, *canceled_label = NULL;
3294 struct mgs_target_info *mti = NULL;
3298 rc = mgs_find_or_make_fsdb(env, mgs, fsname, &fsdb);
3300 CERROR("Can't get db for %s\n", fsname);
3303 if (cfs_test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
3304 CERROR("%s is not defined\n", fsname);
3305 mgs_free_fsdb(mgs, fsdb);
3309 label_sz = 10 + strlen(fsname) + strlen(poolname);
3311 /* check if ostname match fsname */
3312 if (ostname != NULL) {
3315 ptr = strrchr(ostname, '-');
3316 if ((ptr == NULL) ||
3317 (strncmp(fsname, ostname, ptr-ostname) != 0))
3319 label_sz += strlen(ostname);
3322 OBD_ALLOC(label, label_sz);
3329 "new %s.%s", fsname, poolname);
3333 "add %s.%s.%s", fsname, poolname, ostname);
3336 OBD_ALLOC(canceled_label, label_sz);
3337 if (canceled_label == NULL)
3338 GOTO(out_label, rc = -ENOMEM);
3340 "rem %s.%s.%s", fsname, poolname, ostname);
3341 sprintf(canceled_label,
3342 "add %s.%s.%s", fsname, poolname, ostname);
3345 OBD_ALLOC(canceled_label, label_sz);
3346 if (canceled_label == NULL)
3347 GOTO(out_label, rc = -ENOMEM);
3349 "del %s.%s", fsname, poolname);
3350 sprintf(canceled_label,
3351 "new %s.%s", fsname, poolname);
3357 cfs_mutex_lock(&fsdb->fsdb_mutex);
3359 if (canceled_label != NULL) {
3362 GOTO(out_cancel, rc = -ENOMEM);
3365 /* write pool def to all MDT logs */
3366 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3367 if (cfs_test_bit(i, fsdb->fsdb_mdt_index_map)) {
3368 rc = name_create_mdt_and_lov(&logname, &lovname,
3371 cfs_mutex_unlock(&fsdb->fsdb_mutex);
3374 if (canceled_label != NULL) {
3375 strcpy(mti->mti_svname, "lov pool");
3376 rc = mgs_modify(env, mgs, fsdb, mti, logname,
3377 lovname, canceled_label,
3382 rc = mgs_write_log_pool(env, mgs, logname,
3386 name_destroy(&logname);
3387 name_destroy(&lovname);
3389 cfs_mutex_unlock(&fsdb->fsdb_mutex);
3395 rc = name_create(&logname, fsname, "-client");
3397 cfs_mutex_unlock(&fsdb->fsdb_mutex);
3400 if (canceled_label != NULL) {
3401 rc = mgs_modify(env, mgs, fsdb, mti, logname,
3402 fsdb->fsdb_clilov, canceled_label, CM_SKIP);
3404 cfs_mutex_unlock(&fsdb->fsdb_mutex);
3405 name_destroy(&logname);
3410 rc = mgs_write_log_pool(env, mgs, logname, fsdb, fsdb->fsdb_clilov,
3411 cmd, fsname, poolname, ostname, label);
3412 cfs_mutex_unlock(&fsdb->fsdb_mutex);
3413 name_destroy(&logname);
3414 /* request for update */
3415 mgs_revoke_lock(mgs, fsdb, CONFIG_T_CONFIG);
3422 if (canceled_label != NULL)
3423 OBD_FREE(canceled_label, label_sz);
3425 OBD_FREE(label, label_sz);
3430 /******************** unused *********************/
3431 static int mgs_backup_llog(struct obd_device *obd, char* fsname)
3433 struct file *filp, *bak_filp;
3434 struct lvfs_run_ctxt saved;
3435 char *logname, *buf;
3436 loff_t soff = 0 , doff = 0;
3437 int count = 4096, len;
3440 OBD_ALLOC(logname, PATH_MAX);
3441 if (logname == NULL)
3444 OBD_ALLOC(buf, count);
3446 GOTO(out , rc = -ENOMEM);
3448 len = snprintf(logname, PATH_MAX, "%s/%s.bak",
3449 MOUNT_CONFIGS_DIR, fsname);
3451 if (len >= PATH_MAX - 1) {
3452 GOTO(out, -ENAMETOOLONG);
3455 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
3457 bak_filp = l_filp_open(logname, O_RDWR|O_CREAT|O_TRUNC, 0660);
3458 if (IS_ERR(bak_filp)) {
3459 rc = PTR_ERR(bak_filp);
3460 CERROR("backup logfile open %s: %d\n", logname, rc);
3463 sprintf(logname, "%s/%s", MOUNT_CONFIGS_DIR, fsname);
3464 filp = l_filp_open(logname, O_RDONLY, 0);
3467 CERROR("logfile open %s: %d\n", logname, rc);
3471 while ((rc = lustre_fread(filp, buf, count, &soff)) > 0) {
3472 rc = lustre_fwrite(bak_filp, buf, count, &doff);
3476 filp_close(filp, 0);
3478 filp_close(bak_filp, 0);
3480 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
3483 OBD_FREE(buf, count);
3484 OBD_FREE(logname, PATH_MAX);