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>
53 #include <lustre_log.h>
55 #include "mgs_internal.h"
57 /********************** Class functions ********************/
59 /* Caller must list_del and mgs_dirent_free() each dentry from the list */
60 int class_dentry_readdir(const struct lu_env *env,
61 struct mgs_device *mgs, cfs_list_t *list)
63 struct dt_object *dir = mgs->mgs_configs_dir;
64 const struct dt_it_ops *iops;
66 struct mgs_direntry *de;
70 CFS_INIT_LIST_HEAD(list);
72 if (!dt_try_as_dir(env, dir))
73 GOTO(out, rc = -ENOTDIR);
76 LASSERT(dir->do_index_ops);
78 iops = &dir->do_index_ops->dio_it;
79 it = iops->init(env, dir, LUDA_64BITHASH, BYPASS_CAPA);
83 rc = iops->load(env, it, 0);
89 key = (void *)iops->key(env, it);
91 CERROR("%s: key failed when listing %s: rc = %d\n",
92 mgs->mgs_obd->obd_name, MOUNT_CONFIGS_DIR,
96 key_sz = iops->key_size(env, it);
99 /* filter out "." and ".." entries */
103 if (key_sz == 2 && key[1] == '.')
107 de = mgs_direntry_alloc(key_sz + 1);
113 memcpy(de->name, key, key_sz);
114 de->name[key_sz] = 0;
116 cfs_list_add(&de->list, list);
119 rc = iops->next(env, it);
129 CERROR("%s: key failed when listing %s: rc = %d\n",
130 mgs->mgs_obd->obd_name, MOUNT_CONFIGS_DIR, rc);
134 /******************** DB functions *********************/
136 static inline int name_create(char **newname, char *prefix, char *suffix)
139 OBD_ALLOC(*newname, strlen(prefix) + strlen(suffix) + 1);
142 sprintf(*newname, "%s%s", prefix, suffix);
146 static inline void name_destroy(char **name)
149 OBD_FREE(*name, strlen(*name) + 1);
153 struct mgs_fsdb_handler_data
159 /* from the (client) config log, figure out:
160 1. which ost's/mdt's are configured (by index)
161 2. what the last config step is
162 3. COMPAT_18 osc name
164 /* It might be better to have a separate db file, instead of parsing the info
165 out of the client log. This is slow and potentially error-prone. */
166 static int mgs_fsdb_handler(const struct lu_env *env, struct llog_handle *llh,
167 struct llog_rec_hdr *rec, void *data)
169 struct mgs_fsdb_handler_data *d = data;
170 struct fs_db *fsdb = d->fsdb;
171 int cfg_len = rec->lrh_len;
172 char *cfg_buf = (char*) (rec + 1);
173 struct lustre_cfg *lcfg;
178 if (rec->lrh_type != OBD_CFG_REC) {
179 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
183 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
185 CERROR("Insane cfg\n");
189 lcfg = (struct lustre_cfg *)cfg_buf;
191 CDEBUG(D_INFO, "cmd %x %s %s\n", lcfg->lcfg_command,
192 lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));
194 /* Figure out ost indicies */
195 /* lov_modify_tgts add 0:lov1 1:ost1_UUID 2(index):0 3(gen):1 */
196 if (lcfg->lcfg_command == LCFG_LOV_ADD_OBD ||
197 lcfg->lcfg_command == LCFG_LOV_DEL_OBD) {
198 index = simple_strtoul(lustre_cfg_string(lcfg, 2),
200 CDEBUG(D_MGS, "OST index for %s is %u (%s)\n",
201 lustre_cfg_string(lcfg, 1), index,
202 lustre_cfg_string(lcfg, 2));
203 cfs_set_bit(index, fsdb->fsdb_ost_index_map);
206 /* Figure out mdt indicies */
207 /* attach 0:MDC_uml1_mdsA_MNT_client 1:mdc 2:1d834_MNT_client_03f */
208 if ((lcfg->lcfg_command == LCFG_ATTACH) &&
209 (strcmp(lustre_cfg_string(lcfg, 1), LUSTRE_MDC_NAME) == 0)) {
210 rc = server_name2index(lustre_cfg_string(lcfg, 0),
212 if (rc != LDD_F_SV_TYPE_MDT) {
213 CWARN("Unparsable MDC name %s, assuming index 0\n",
214 lustre_cfg_string(lcfg, 0));
218 CDEBUG(D_MGS, "MDT index is %u\n", index);
219 cfs_set_bit(index, fsdb->fsdb_mdt_index_map);
220 fsdb->fsdb_mdt_count ++;
224 * figure out the old config. fsdb_gen = 0 means old log
225 * It is obsoleted and not supported anymore
227 if (fsdb->fsdb_gen == 0) {
228 CERROR("Old config format is not supported\n");
233 * compat to 1.8, check osc name used by MDT0 to OSTs, bz18548.
235 if (!cfs_test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags) &&
236 lcfg->lcfg_command == LCFG_ATTACH &&
237 strcmp(lustre_cfg_string(lcfg, 1), LUSTRE_OSC_NAME) == 0) {
238 if (OBD_OCD_VERSION_MAJOR(d->ver) == 1 &&
239 OBD_OCD_VERSION_MINOR(d->ver) <= 8) {
240 CWARN("MDT using 1.8 OSC name scheme\n");
241 cfs_set_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags);
245 if (lcfg->lcfg_command == LCFG_MARKER) {
246 struct cfg_marker *marker;
247 marker = lustre_cfg_buf(lcfg, 1);
249 d->ver = marker->cm_vers;
251 /* Keep track of the latest marker step */
252 fsdb->fsdb_gen = max(fsdb->fsdb_gen, marker->cm_step);
258 /* fsdb->fsdb_mutex is already held in mgs_find_or_make_fsdb*/
259 static int mgs_get_fsdb_from_llog(const struct lu_env *env,
260 struct mgs_device *mgs,
264 struct llog_handle *loghandle;
265 struct lvfs_run_ctxt saved;
266 struct llog_ctxt *ctxt;
267 struct mgs_fsdb_handler_data d = { fsdb, 0 };
271 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
272 LASSERT(ctxt != NULL);
273 rc = name_create(&logname, fsdb->fsdb_name, "-client");
276 cfs_mutex_lock(&fsdb->fsdb_mutex);
277 push_ctxt(&saved, &mgs->mgs_obd->obd_lvfs_ctxt, NULL);
278 rc = llog_open_create(NULL, ctxt, &loghandle, NULL, logname);
282 rc = llog_init_handle(NULL, loghandle, LLOG_F_IS_PLAIN, NULL);
286 if (llog_get_size(loghandle) <= 1)
287 cfs_set_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags);
289 rc = llog_process_or_fork(env, loghandle, mgs_fsdb_handler, (void *)&d,
291 CDEBUG(D_INFO, "get_db = %d\n", rc);
293 rc2 = llog_close(NULL, loghandle);
297 pop_ctxt(&saved, &mgs->mgs_obd->obd_lvfs_ctxt, NULL);
298 cfs_mutex_unlock(&fsdb->fsdb_mutex);
299 name_destroy(&logname);
306 static void mgs_free_fsdb_srpc(struct fs_db *fsdb)
308 struct mgs_tgt_srpc_conf *tgtconf;
310 /* free target-specific rules */
311 while (fsdb->fsdb_srpc_tgt) {
312 tgtconf = fsdb->fsdb_srpc_tgt;
313 fsdb->fsdb_srpc_tgt = tgtconf->mtsc_next;
315 LASSERT(tgtconf->mtsc_tgt);
317 sptlrpc_rule_set_free(&tgtconf->mtsc_rset);
318 OBD_FREE(tgtconf->mtsc_tgt, strlen(tgtconf->mtsc_tgt) + 1);
319 OBD_FREE_PTR(tgtconf);
322 /* free general rules */
323 sptlrpc_rule_set_free(&fsdb->fsdb_srpc_gen);
326 struct fs_db *mgs_find_fsdb(struct mgs_device *mgs, char *fsname)
331 cfs_list_for_each(tmp, &mgs->mgs_fs_db_list) {
332 fsdb = cfs_list_entry(tmp, struct fs_db, fsdb_list);
333 if (strcmp(fsdb->fsdb_name, fsname) == 0)
339 /* caller must hold the mgs->mgs_fs_db_lock */
340 static struct fs_db *mgs_new_fsdb(const struct lu_env *env,
341 struct mgs_device *mgs, char *fsname)
347 if (strlen(fsname) >= sizeof(fsdb->fsdb_name)) {
348 CERROR("fsname %s is too long\n", fsname);
356 strcpy(fsdb->fsdb_name, fsname);
357 cfs_mutex_init(&fsdb->fsdb_mutex);
358 cfs_set_bit(FSDB_UDESC, &fsdb->fsdb_flags);
361 if (strcmp(fsname, MGSSELF_NAME) == 0) {
362 cfs_set_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags);
364 OBD_ALLOC(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
365 OBD_ALLOC(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
366 if (!fsdb->fsdb_ost_index_map || !fsdb->fsdb_mdt_index_map) {
367 CERROR("No memory for index maps\n");
368 GOTO(err, rc = -ENOMEM);
371 rc = name_create(&fsdb->fsdb_clilov, fsname, "-clilov");
374 rc = name_create(&fsdb->fsdb_clilmv, fsname, "-clilmv");
378 /* initialise data for NID table */
379 mgs_ir_init_fs(env, mgs, fsdb);
381 lproc_mgs_add_live(mgs, fsdb);
384 cfs_list_add(&fsdb->fsdb_list, &mgs->mgs_fs_db_list);
388 if (fsdb->fsdb_ost_index_map)
389 OBD_FREE(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
390 if (fsdb->fsdb_mdt_index_map)
391 OBD_FREE(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
392 name_destroy(&fsdb->fsdb_clilov);
393 name_destroy(&fsdb->fsdb_clilmv);
398 static void mgs_free_fsdb(struct mgs_device *mgs, struct fs_db *fsdb)
400 /* wait for anyone with the sem */
401 cfs_mutex_lock(&fsdb->fsdb_mutex);
402 lproc_mgs_del_live(mgs, fsdb);
403 cfs_list_del(&fsdb->fsdb_list);
405 /* deinitialize fsr */
406 mgs_ir_fini_fs(mgs, fsdb);
408 if (fsdb->fsdb_ost_index_map)
409 OBD_FREE(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
410 if (fsdb->fsdb_mdt_index_map)
411 OBD_FREE(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
412 name_destroy(&fsdb->fsdb_clilov);
413 name_destroy(&fsdb->fsdb_clilmv);
414 mgs_free_fsdb_srpc(fsdb);
415 cfs_mutex_unlock(&fsdb->fsdb_mutex);
419 int mgs_init_fsdb_list(struct mgs_device *mgs)
421 CFS_INIT_LIST_HEAD(&mgs->mgs_fs_db_list);
425 int mgs_cleanup_fsdb_list(struct mgs_device *mgs)
428 cfs_list_t *tmp, *tmp2;
429 cfs_mutex_lock(&mgs->mgs_mutex);
430 cfs_list_for_each_safe(tmp, tmp2, &mgs->mgs_fs_db_list) {
431 fsdb = cfs_list_entry(tmp, struct fs_db, fsdb_list);
432 mgs_free_fsdb(mgs, fsdb);
434 cfs_mutex_unlock(&mgs->mgs_mutex);
438 int mgs_find_or_make_fsdb(const struct lu_env *env,
439 struct mgs_device *mgs, char *name,
445 cfs_mutex_lock(&mgs->mgs_mutex);
446 fsdb = mgs_find_fsdb(mgs, name);
448 cfs_mutex_unlock(&mgs->mgs_mutex);
453 CDEBUG(D_MGS, "Creating new db\n");
454 fsdb = mgs_new_fsdb(env, mgs, name);
455 cfs_mutex_unlock(&mgs->mgs_mutex);
459 if (!cfs_test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
460 /* populate the db from the client llog */
461 rc = mgs_get_fsdb_from_llog(env, mgs, fsdb);
463 CERROR("Can't get db from client log %d\n", rc);
464 mgs_free_fsdb(mgs, fsdb);
469 /* populate srpc rules from params llog */
470 rc = mgs_get_fsdb_srpc_from_llog(env, mgs, fsdb);
472 CERROR("Can't get db from params log %d\n", rc);
473 mgs_free_fsdb(mgs, fsdb);
484 -1= empty client log */
485 int mgs_check_index(const struct lu_env *env,
486 struct mgs_device *mgs,
487 struct mgs_target_info *mti)
494 LASSERT(!(mti->mti_flags & LDD_F_NEED_INDEX));
496 rc = mgs_find_or_make_fsdb(env, mgs, mti->mti_fsname, &fsdb);
498 CERROR("Can't get db for %s\n", mti->mti_fsname);
502 if (cfs_test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags))
505 if (mti->mti_flags & LDD_F_SV_TYPE_OST)
506 imap = fsdb->fsdb_ost_index_map;
507 else if (mti->mti_flags & LDD_F_SV_TYPE_MDT)
508 imap = fsdb->fsdb_mdt_index_map;
512 if (cfs_test_bit(mti->mti_stripe_index, imap))
517 static __inline__ int next_index(void *index_map, int map_len)
520 for (i = 0; i < map_len * 8; i++)
521 if (!cfs_test_bit(i, index_map)) {
524 CERROR("max index %d exceeded.\n", i);
529 0 newly marked as in use
531 +EALREADY for update of an old index */
532 static int mgs_set_index(const struct lu_env *env,
533 struct mgs_device *mgs,
534 struct mgs_target_info *mti)
541 rc = mgs_find_or_make_fsdb(env, mgs, mti->mti_fsname, &fsdb);
543 CERROR("Can't get db for %s\n", mti->mti_fsname);
547 if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
548 imap = fsdb->fsdb_ost_index_map;
549 } else if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
550 imap = fsdb->fsdb_mdt_index_map;
551 if (fsdb->fsdb_mdt_count >= MAX_MDT_COUNT) {
552 LCONSOLE_ERROR_MSG(0x13f, "The max mdt count"
553 "is %d\n", (int)MAX_MDT_COUNT);
560 if (mti->mti_flags & LDD_F_NEED_INDEX) {
561 rc = next_index(imap, INDEX_MAP_SIZE);
564 mti->mti_stripe_index = rc;
565 if (mti->mti_flags & LDD_F_SV_TYPE_MDT)
566 fsdb->fsdb_mdt_count ++;
569 if (mti->mti_stripe_index >= INDEX_MAP_SIZE * 8) {
570 LCONSOLE_ERROR_MSG(0x13f, "Server %s requested index %d, "
571 "but the max index is %d.\n",
572 mti->mti_svname, mti->mti_stripe_index,
577 if (cfs_test_bit(mti->mti_stripe_index, imap)) {
578 if ((mti->mti_flags & LDD_F_VIRGIN) &&
579 !(mti->mti_flags & LDD_F_WRITECONF)) {
580 LCONSOLE_ERROR_MSG(0x140, "Server %s requested index "
581 "%d, but that index is already in "
582 "use. Use --writeconf to force\n",
584 mti->mti_stripe_index);
587 CDEBUG(D_MGS, "Server %s updating index %d\n",
588 mti->mti_svname, mti->mti_stripe_index);
593 cfs_set_bit(mti->mti_stripe_index, imap);
594 cfs_clear_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags);
595 server_make_name(mti->mti_flags & ~(LDD_F_VIRGIN | LDD_F_WRITECONF),
596 mti->mti_stripe_index, mti->mti_fsname, mti->mti_svname);
598 CDEBUG(D_MGS, "Set index for %s to %d\n", mti->mti_svname,
599 mti->mti_stripe_index);
604 struct mgs_modify_lookup {
605 struct cfg_marker mml_marker;
609 static int mgs_modify_handler(const struct lu_env *env,
610 struct llog_handle *llh,
611 struct llog_rec_hdr *rec, void *data)
613 struct mgs_modify_lookup *mml = data;
614 struct cfg_marker *marker;
615 struct lustre_cfg *lcfg = (struct lustre_cfg *)(rec + 1);
616 int cfg_len = rec->lrh_len - sizeof(struct llog_rec_hdr) -
617 sizeof(struct llog_rec_tail);
621 if (rec->lrh_type != OBD_CFG_REC) {
622 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
626 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
628 CERROR("Insane cfg\n");
632 /* We only care about markers */
633 if (lcfg->lcfg_command != LCFG_MARKER)
636 marker = lustre_cfg_buf(lcfg, 1);
637 if ((strcmp(mml->mml_marker.cm_comment, marker->cm_comment) == 0) &&
638 (strcmp(mml->mml_marker.cm_tgtname, marker->cm_tgtname) == 0) &&
639 !(marker->cm_flags & CM_SKIP)) {
640 /* Found a non-skipped marker match */
641 CDEBUG(D_MGS, "Changing rec %u marker %d %x->%x: %s %s\n",
642 rec->lrh_index, marker->cm_step,
643 marker->cm_flags, mml->mml_marker.cm_flags,
644 marker->cm_tgtname, marker->cm_comment);
645 /* Overwrite the old marker llog entry */
646 marker->cm_flags &= ~CM_EXCLUDE; /* in case we're unexcluding */
647 marker->cm_flags |= mml->mml_marker.cm_flags;
648 marker->cm_canceltime = mml->mml_marker.cm_canceltime;
649 /* Header and tail are added back to lrh_len in
650 llog_lvfs_write_rec */
651 rec->lrh_len = cfg_len;
652 rc = llog_write_rec(NULL, llh, rec, NULL, 0, (void *)lcfg,
661 /* Modify an existing config log record (for CM_SKIP or CM_EXCLUDE) */
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 lvfs_run_ctxt saved;
668 struct llog_ctxt *ctxt;
669 struct mgs_modify_lookup *mml;
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 push_ctxt(&saved, &mgs->mgs_obd->obd_lvfs_ctxt, NULL);
679 rc = llog_open(NULL, ctxt, &loghandle, NULL, logname,
687 rc = llog_init_handle(NULL, loghandle, LLOG_F_IS_PLAIN, NULL);
691 if (llog_get_size(loghandle) <= 1)
692 GOTO(out_close, rc = 0);
696 GOTO(out_close, rc = -ENOMEM);
697 strcpy(mml->mml_marker.cm_comment, comment);
698 strcpy(mml->mml_marker.cm_tgtname, devname);
699 /* Modify mostly means cancel */
700 mml->mml_marker.cm_flags = flags;
701 mml->mml_marker.cm_canceltime = flags ? cfs_time_current_sec() : 0;
702 mml->mml_modified = 0;
703 rc = llog_process_or_fork(env, loghandle, mgs_modify_handler,
704 (void *)mml, NULL, false);
705 if (!rc && !mml->mml_modified)
710 rc2 = llog_close(NULL, loghandle);
714 pop_ctxt(&saved, &mgs->mgs_obd->obd_lvfs_ctxt, NULL);
716 CERROR("modify %s/%s failed %d\n",
717 mti->mti_svname, comment, rc);
722 /******************** config log recording functions *********************/
724 static int record_lcfg(const struct lu_env *env, struct llog_handle *llh,
725 struct lustre_cfg *lcfg)
727 struct lvfs_run_ctxt saved;
728 struct llog_rec_hdr rec;
730 struct obd_device *obd = llh->lgh_ctxt->loc_obd;
735 LASSERT(llh->lgh_ctxt);
737 buflen = lustre_cfg_len(lcfg->lcfg_bufcount,
739 rec.lrh_len = llog_data_len(buflen);
740 rec.lrh_type = OBD_CFG_REC;
742 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
743 /* idx = -1 means append */
744 rc = llog_write_rec(NULL, llh, &rec, NULL, 0, (void *)lcfg, -1);
745 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
747 CERROR("failed %d\n", rc);
751 static int record_base(const struct lu_env *env, struct llog_handle *llh,
752 char *cfgname, lnet_nid_t nid, int cmd,
753 char *s1, char *s2, char *s3, char *s4)
755 struct mgs_thread_info *mgi = mgs_env_info(env);
756 struct lustre_cfg *lcfg;
759 CDEBUG(D_MGS, "lcfg %s %#x %s %s %s %s\n", cfgname,
760 cmd, s1, s2, s3, s4);
762 lustre_cfg_bufs_reset(&mgi->mgi_bufs, cfgname);
764 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, s1);
766 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 2, s2);
768 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 3, s3);
770 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 4, s4);
772 lcfg = lustre_cfg_new(cmd, &mgi->mgi_bufs);
775 lcfg->lcfg_nid = nid;
777 rc = record_lcfg(env, llh, lcfg);
779 lustre_cfg_free(lcfg);
782 CERROR("error %d: lcfg %s %#x %s %s %s %s\n", rc, cfgname,
783 cmd, s1, s2, s3, s4);
789 static inline int record_add_uuid(const struct lu_env *env,
790 struct llog_handle *llh,
791 uint64_t nid, char *uuid)
793 return record_base(env, llh, NULL, nid, LCFG_ADD_UUID, uuid, 0, 0, 0);
797 static inline int record_add_conn(const struct lu_env *env,
798 struct llog_handle *llh,
799 char *devname, char *uuid)
801 return record_base(env, llh, devname, 0, LCFG_ADD_CONN, uuid, 0, 0, 0);
804 static inline int record_attach(const struct lu_env *env,
805 struct llog_handle *llh, char *devname,
806 char *type, char *uuid)
808 return record_base(env, llh,devname, 0, LCFG_ATTACH, type, uuid, 0, 0);
811 static inline int record_setup(const struct lu_env *env,
812 struct llog_handle *llh, char *devname,
813 char *s1, char *s2, char *s3, char *s4)
815 return record_base(env, llh, devname, 0, LCFG_SETUP, s1, s2, s3, s4);
818 static int record_lov_setup(const struct lu_env *env, struct llog_handle *llh,
819 char *devname, struct lov_desc *desc)
821 struct mgs_thread_info *mgi = mgs_env_info(env);
822 struct lustre_cfg *lcfg;
825 lustre_cfg_bufs_reset(&mgi->mgi_bufs, devname);
826 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, desc, sizeof(*desc));
827 lcfg = lustre_cfg_new(LCFG_SETUP, &mgi->mgi_bufs);
830 rc = record_lcfg(env, llh, lcfg);
832 lustre_cfg_free(lcfg);
836 static int record_lmv_setup(const struct lu_env *env, struct llog_handle *llh,
837 char *devname, struct lmv_desc *desc)
839 struct mgs_thread_info *mgi = mgs_env_info(env);
840 struct lustre_cfg *lcfg;
843 lustre_cfg_bufs_reset(&mgi->mgi_bufs, devname);
844 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, desc, sizeof(*desc));
845 lcfg = lustre_cfg_new(LCFG_SETUP, &mgi->mgi_bufs);
847 rc = record_lcfg(env, llh, lcfg);
849 lustre_cfg_free(lcfg);
853 static inline int record_mdc_add(const struct lu_env *env,
854 struct llog_handle *llh,
855 char *logname, char *mdcuuid,
856 char *mdtuuid, char *index,
859 return record_base(env,llh,logname,0,LCFG_ADD_MDC,
860 mdtuuid,index,gen,mdcuuid);
863 static inline int record_lov_add(const struct lu_env *env,
864 struct llog_handle *llh,
865 char *lov_name, char *ost_uuid,
866 char *index, char *gen)
868 return record_base(env,llh,lov_name,0,LCFG_LOV_ADD_OBD,
869 ost_uuid,index,gen,0);
872 static inline int record_mount_opt(const struct lu_env *env,
873 struct llog_handle *llh,
874 char *profile, char *lov_name,
877 return record_base(env,llh,NULL,0,LCFG_MOUNTOPT,
878 profile,lov_name,mdc_name,0);
881 static int record_marker(const struct lu_env *env,
882 struct llog_handle *llh,
883 struct fs_db *fsdb, __u32 flags,
884 char *tgtname, char *comment)
886 struct mgs_thread_info *mgi = mgs_env_info(env);
887 struct lustre_cfg *lcfg;
890 if (flags & CM_START)
892 mgi->mgi_marker.cm_step = fsdb->fsdb_gen;
893 mgi->mgi_marker.cm_flags = flags;
894 mgi->mgi_marker.cm_vers = LUSTRE_VERSION_CODE;
895 strncpy(mgi->mgi_marker.cm_tgtname, tgtname,
896 sizeof(mgi->mgi_marker.cm_tgtname));
897 strncpy(mgi->mgi_marker.cm_comment, comment,
898 sizeof(mgi->mgi_marker.cm_comment));
899 mgi->mgi_marker.cm_createtime = cfs_time_current_sec();
900 mgi->mgi_marker.cm_canceltime = 0;
901 lustre_cfg_bufs_reset(&mgi->mgi_bufs, NULL);
902 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, &mgi->mgi_marker,
903 sizeof(mgi->mgi_marker));
904 lcfg = lustre_cfg_new(LCFG_MARKER, &mgi->mgi_bufs);
907 rc = record_lcfg(env, llh, lcfg);
909 lustre_cfg_free(lcfg);
913 static int record_start_log(const struct lu_env *env,
914 struct mgs_device *mgs,
915 struct llog_handle **llh, char *name)
917 static struct obd_uuid cfg_uuid = { .uuid = "config_uuid" };
918 struct lvfs_run_ctxt saved;
919 struct llog_ctxt *ctxt;
923 GOTO(out, rc = -EBUSY);
925 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
927 GOTO(out, rc = -ENODEV);
928 LASSERT(ctxt->loc_obd == mgs->mgs_obd);
930 push_ctxt(&saved, &mgs->mgs_obd->obd_lvfs_ctxt, NULL);
931 rc = llog_open_create(NULL, ctxt, llh, NULL, name);
934 rc = llog_init_handle(NULL, *llh, LLOG_F_IS_PLAIN, &cfg_uuid);
936 llog_close(NULL, *llh);
940 pop_ctxt(&saved, &mgs->mgs_obd->obd_lvfs_ctxt, NULL);
944 CERROR("Can't start log %s: %d\n", name, rc);
948 static int record_end_log(const struct lu_env *env, struct llog_handle **llh)
950 struct lvfs_run_ctxt saved;
951 struct obd_device *obd = (*llh)->lgh_ctxt->loc_obd;
954 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
956 rc = llog_close(NULL, *llh);
959 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
963 static int mgs_log_is_empty(const struct lu_env *env,
964 struct mgs_device *mgs, char *name)
966 struct lvfs_run_ctxt saved;
967 struct llog_handle *llh;
968 struct llog_ctxt *ctxt;
971 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
972 LASSERT(ctxt != NULL);
973 push_ctxt(&saved, &mgs->mgs_obd->obd_lvfs_ctxt, NULL);
974 rc = llog_open(NULL, ctxt, &llh, NULL, name, LLOG_OPEN_EXISTS);
981 llog_init_handle(NULL, llh, LLOG_F_IS_PLAIN, NULL);
984 rc = llog_get_size(llh);
987 llog_close(NULL, llh);
989 pop_ctxt(&saved, &mgs->mgs_obd->obd_lvfs_ctxt, NULL);
991 /* header is record 1 */
995 /******************** config "macros" *********************/
997 /* write an lcfg directly into a log (with markers) */
998 static int mgs_write_log_direct(const struct lu_env *env,
999 struct mgs_device *mgs, struct fs_db *fsdb,
1000 char *logname, struct lustre_cfg *lcfg,
1001 char *devname, char *comment)
1003 struct llog_handle *llh = NULL;
1010 rc = record_start_log(env, mgs, &llh, logname);
1014 /* FIXME These should be a single journal transaction */
1015 rc = record_marker(env, llh, fsdb, CM_START, devname, comment);
1018 rc = record_lcfg(env, llh, lcfg);
1021 rc = record_marker(env, llh, fsdb, CM_END, devname, comment);
1025 record_end_log(env, &llh);
1029 /* write the lcfg in all logs for the given fs */
1030 int mgs_write_log_direct_all(const struct lu_env *env,
1031 struct mgs_device *mgs,
1033 struct mgs_target_info *mti,
1034 struct lustre_cfg *lcfg,
1035 char *devname, char *comment,
1039 struct mgs_direntry *dirent, *n;
1040 char *fsname = mti->mti_fsname;
1042 int rc = 0, len = strlen(fsname);
1045 /* We need to set params for any future logs
1046 as well. FIXME Append this file to every new log.
1047 Actually, we should store as params (text), not llogs. Or
1049 rc = name_create(&logname, fsname, "-params");
1052 if (mgs_log_is_empty(env, mgs, logname)) {
1053 struct llog_handle *llh = NULL;
1054 rc = record_start_log(env, mgs, &llh, logname);
1055 record_end_log(env, &llh);
1057 name_destroy(&logname);
1061 /* Find all the logs in the CONFIGS directory */
1062 rc = class_dentry_readdir(env, mgs, &list);
1066 /* Could use fsdb index maps instead of directory listing */
1067 cfs_list_for_each_entry_safe(dirent, n, &list, list) {
1068 cfs_list_del(&dirent->list);
1069 /* don't write to sptlrpc rule log */
1070 if (strstr(dirent->name, "-sptlrpc") != NULL)
1073 /* caller wants write server logs only */
1074 if (server_only && strstr(dirent->name, "-client") != NULL)
1077 if (strncmp(fsname, dirent->name, len) == 0) {
1078 CDEBUG(D_MGS, "Changing log %s\n", dirent->name);
1079 /* Erase any old settings of this same parameter */
1080 rc = mgs_modify(env, mgs, fsdb, mti, dirent->name,
1081 devname, comment, CM_SKIP);
1083 CERROR("%s: Can't modify llog %s: rc = %d\n",
1084 mgs->mgs_obd->obd_name, dirent->name,rc);
1085 /* Write the new one */
1087 rc = mgs_write_log_direct(env, mgs, fsdb,
1092 CERROR("%s: writing log %s: rc = %d\n",
1093 mgs->mgs_obd->obd_name,
1098 mgs_direntry_free(dirent);
1104 static int mgs_write_log_mdc_to_mdt(const struct lu_env *env,
1105 struct mgs_device *mgs,
1107 struct mgs_target_info *mti,
1109 static int mgs_write_log_osc_to_lov(const struct lu_env *env,
1110 struct mgs_device *mgs,
1112 struct mgs_target_info *mti,
1113 char *logname, char *suffix, char *lovname,
1114 enum lustre_sec_part sec_part, int flags);
1115 static int name_create_mdt_and_lov(char **logname, char **lovname,
1116 struct fs_db *fsdb, int i);
1118 static int mgs_steal_llog_handler(const struct lu_env *env,
1119 struct llog_handle *llh,
1120 struct llog_rec_hdr *rec, void *data)
1122 struct mgs_device *mgs;
1123 struct mgs_target_info *mti, *tmti;
1125 int cfg_len = rec->lrh_len;
1126 char *cfg_buf = (char*) (rec + 1);
1127 struct lustre_cfg *lcfg;
1129 struct llog_handle *mdt_llh = NULL;
1130 static int got_an_osc_or_mdc = 0;
1131 /* 0: not found any osc/mdc;
1135 static int last_step = -1;
1139 mti = ((struct temp_comp*)data)->comp_mti;
1140 tmti = ((struct temp_comp*)data)->comp_tmti;
1141 fsdb = ((struct temp_comp*)data)->comp_fsdb;
1142 mgs = ((struct temp_comp*)data)->comp_mgs;
1144 if (rec->lrh_type != OBD_CFG_REC) {
1145 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
1149 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
1151 CERROR("Insane cfg\n");
1155 lcfg = (struct lustre_cfg *)cfg_buf;
1157 if (lcfg->lcfg_command == LCFG_MARKER) {
1158 struct cfg_marker *marker;
1159 marker = lustre_cfg_buf(lcfg, 1);
1160 if (!strncmp(marker->cm_comment,"add osc",7) &&
1161 (marker->cm_flags & CM_START)){
1162 got_an_osc_or_mdc = 1;
1163 strncpy(tmti->mti_svname, marker->cm_tgtname,
1164 sizeof(tmti->mti_svname));
1165 rc = record_start_log(env, mgs, &mdt_llh,
1169 rc = record_marker(env, mdt_llh, fsdb, CM_START,
1170 mti->mti_svname,"add osc(copied)");
1171 record_end_log(env, &mdt_llh);
1172 last_step = marker->cm_step;
1175 if (!strncmp(marker->cm_comment,"add osc",7) &&
1176 (marker->cm_flags & CM_END)){
1177 LASSERT(last_step == marker->cm_step);
1179 got_an_osc_or_mdc = 0;
1180 rc = record_start_log(env, mgs, &mdt_llh,
1184 rc = record_marker(env, mdt_llh, fsdb, CM_END,
1185 mti->mti_svname,"add osc(copied)");
1186 record_end_log(env, &mdt_llh);
1189 if (!strncmp(marker->cm_comment,"add mdc",7) &&
1190 (marker->cm_flags & CM_START)){
1191 got_an_osc_or_mdc = 2;
1192 last_step = marker->cm_step;
1193 memcpy(tmti->mti_svname, marker->cm_tgtname,
1194 strlen(marker->cm_tgtname));
1198 if (!strncmp(marker->cm_comment,"add mdc",7) &&
1199 (marker->cm_flags & CM_END)){
1200 LASSERT(last_step == marker->cm_step);
1202 got_an_osc_or_mdc = 0;
1207 if (got_an_osc_or_mdc == 0 || last_step < 0)
1210 if (lcfg->lcfg_command == LCFG_ADD_UUID) {
1212 nodenid = lcfg->lcfg_nid;
1214 tmti->mti_nids[tmti->mti_nid_count] = nodenid;
1215 tmti->mti_nid_count++;
1220 if (lcfg->lcfg_command == LCFG_SETUP) {
1223 target = lustre_cfg_string(lcfg, 1);
1224 memcpy(tmti->mti_uuid, target, strlen(target));
1228 /* ignore client side sptlrpc_conf_log */
1229 if (lcfg->lcfg_command == LCFG_SPTLRPC_CONF)
1232 if (lcfg->lcfg_command == LCFG_ADD_MDC) {
1235 if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1)
1238 memcpy(tmti->mti_fsname, mti->mti_fsname,
1239 strlen(mti->mti_fsname));
1240 tmti->mti_stripe_index = index;
1242 rc = mgs_write_log_mdc_to_mdt(env, mgs, fsdb, tmti,
1244 memset(tmti, 0, sizeof(*tmti));
1248 if (lcfg->lcfg_command == LCFG_LOV_ADD_OBD) {
1251 char *logname, *lovname;
1253 rc = name_create_mdt_and_lov(&logname, &lovname, fsdb,
1254 mti->mti_stripe_index);
1257 sprintf(mdt_index, "-MDT%04x", mti->mti_stripe_index);
1259 if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1) {
1260 name_destroy(&logname);
1261 name_destroy(&lovname);
1265 tmti->mti_stripe_index = index;
1266 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, tmti, logname,
1269 name_destroy(&logname);
1270 name_destroy(&lovname);
1276 /* fsdb->fsdb_mutex is already held in mgs_write_log_target*/
1277 /* stealed from mgs_get_fsdb_from_llog*/
1278 static int mgs_steal_llog_for_mdt_from_client(const struct lu_env *env,
1279 struct mgs_device *mgs,
1281 struct temp_comp* comp)
1283 struct llog_handle *loghandle;
1284 struct lvfs_run_ctxt saved;
1285 struct mgs_target_info *tmti;
1286 struct llog_ctxt *ctxt;
1291 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
1292 LASSERT(ctxt != NULL);
1294 OBD_ALLOC_PTR(tmti);
1296 GOTO(out_ctxt, rc = -ENOMEM);
1298 comp->comp_tmti = tmti;
1299 comp->comp_mgs = mgs;
1301 push_ctxt(&saved, &mgs->mgs_obd->obd_lvfs_ctxt, NULL);
1303 rc = llog_open(NULL, ctxt, &loghandle, NULL, client_name,
1311 rc = llog_init_handle(NULL, loghandle, LLOG_F_IS_PLAIN, NULL);
1313 GOTO(out_close, rc);
1315 rc = llog_process_or_fork(env, loghandle, mgs_steal_llog_handler,
1316 (void *)comp, NULL, false);
1317 CDEBUG(D_MGS, "steal llog re = %d\n", rc);
1319 llog_close(NULL, loghandle);
1321 pop_ctxt(&saved, &mgs->mgs_obd->obd_lvfs_ctxt, NULL);
1324 llog_ctxt_put(ctxt);
1328 /* lmv is the second thing for client logs */
1329 /* copied from mgs_write_log_lov. Please refer to that. */
1330 static int mgs_write_log_lmv(const struct lu_env *env,
1331 struct mgs_device *mgs,
1333 struct mgs_target_info *mti,
1334 char *logname, char *lmvname)
1336 struct llog_handle *llh = NULL;
1337 struct lmv_desc *lmvdesc;
1342 CDEBUG(D_MGS, "Writing lmv(%s) log for %s\n", lmvname,logname);
1344 OBD_ALLOC_PTR(lmvdesc);
1345 if (lmvdesc == NULL)
1347 lmvdesc->ld_active_tgt_count = 0;
1348 lmvdesc->ld_tgt_count = 0;
1349 sprintf((char*)lmvdesc->ld_uuid.uuid, "%s_UUID", lmvname);
1350 uuid = (char *)lmvdesc->ld_uuid.uuid;
1352 rc = record_start_log(env, mgs, &llh, logname);
1355 rc = record_marker(env, llh, fsdb, CM_START, lmvname, "lmv setup");
1358 rc = record_attach(env, llh, lmvname, "lmv", uuid);
1361 rc = record_lmv_setup(env, llh, lmvname, lmvdesc);
1364 rc = record_marker(env, llh, fsdb, CM_END, lmvname, "lmv setup");
1368 record_end_log(env, &llh);
1370 OBD_FREE_PTR(lmvdesc);
1374 /* lov is the first thing in the mdt and client logs */
1375 static int mgs_write_log_lov(const struct lu_env *env, struct mgs_device *mgs,
1376 struct fs_db *fsdb, struct mgs_target_info *mti,
1377 char *logname, char *lovname)
1379 struct llog_handle *llh = NULL;
1380 struct lov_desc *lovdesc;
1385 CDEBUG(D_MGS, "Writing lov(%s) log for %s\n", lovname, logname);
1388 #01 L attach 0:lov_mdsA 1:lov 2:71ccb_lov_mdsA_19f961a9e1
1389 #02 L lov_setup 0:lov_mdsA 1:(struct lov_desc)
1390 uuid=lov1_UUID, stripe count=1, size=1048576, offset=0, pattern=0
1393 /* FIXME just make lov_setup accept empty desc (put uuid in buf 2) */
1394 OBD_ALLOC_PTR(lovdesc);
1395 if (lovdesc == NULL)
1397 lovdesc->ld_magic = LOV_DESC_MAGIC;
1398 lovdesc->ld_tgt_count = 0;
1399 /* Defaults. Can be changed later by lcfg config_param */
1400 lovdesc->ld_default_stripe_count = 1;
1401 lovdesc->ld_pattern = LOV_PATTERN_RAID0;
1402 lovdesc->ld_default_stripe_size = 1024 * 1024;
1403 lovdesc->ld_default_stripe_offset = -1;
1404 lovdesc->ld_qos_maxage = QOS_DEFAULT_MAXAGE;
1405 sprintf((char*)lovdesc->ld_uuid.uuid, "%s_UUID", lovname);
1406 /* can these be the same? */
1407 uuid = (char *)lovdesc->ld_uuid.uuid;
1409 /* This should always be the first entry in a log.
1410 rc = mgs_clear_log(obd, logname); */
1411 rc = record_start_log(env, mgs, &llh, logname);
1414 /* FIXME these should be a single journal transaction */
1415 rc = record_marker(env, llh, fsdb, CM_START, lovname, "lov setup");
1418 rc = record_attach(env, llh, lovname, "lov", uuid);
1421 rc = record_lov_setup(env, llh, lovname, lovdesc);
1424 rc = record_marker(env, llh, fsdb, CM_END, lovname, "lov setup");
1429 record_end_log(env, &llh);
1431 OBD_FREE_PTR(lovdesc);
1435 /* add failnids to open log */
1436 static int mgs_write_log_failnids(const struct lu_env *env,
1437 struct mgs_target_info *mti,
1438 struct llog_handle *llh,
1441 char *failnodeuuid = NULL;
1442 char *ptr = mti->mti_params;
1447 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) nal=90 0: 1:uml1_UUID
1448 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
1449 #05 L setup 0:OSC_uml1_ost1_mdsA 1:ost1_UUID 2:uml1_UUID
1450 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) nal=90 0: 1:uml2_UUID
1451 #0x L add_uuid nid=2@elan(0x1000000000002) nal=90 0: 1:uml2_UUID
1452 #07 L add_conn 0:OSC_uml1_ost1_mdsA 1:uml2_UUID
1455 /* Pull failnid info out of params string */
1456 while (class_find_param(ptr, PARAM_FAILNODE, &ptr) == 0) {
1457 while (class_parse_nid(ptr, &nid, &ptr) == 0) {
1458 if (failnodeuuid == NULL) {
1459 /* We don't know the failover node name,
1460 so just use the first nid as the uuid */
1461 rc = name_create(&failnodeuuid,
1462 libcfs_nid2str(nid), "");
1466 CDEBUG(D_MGS, "add nid %s for failover uuid %s, "
1467 "client %s\n", libcfs_nid2str(nid),
1468 failnodeuuid, cliname);
1469 rc = record_add_uuid(env, llh, nid, failnodeuuid);
1472 rc = record_add_conn(env, llh, cliname, failnodeuuid);
1475 name_destroy(&failnodeuuid);
1479 static int mgs_write_log_mdc_to_lmv(const struct lu_env *env,
1480 struct mgs_device *mgs,
1482 struct mgs_target_info *mti,
1483 char *logname, char *lmvname)
1485 struct llog_handle *llh = NULL;
1486 char *mdcname = NULL;
1487 char *nodeuuid = NULL;
1488 char *mdcuuid = NULL;
1489 char *lmvuuid = NULL;
1494 if (mgs_log_is_empty(env, mgs, logname)) {
1495 CERROR("log is empty! Logical error\n");
1499 CDEBUG(D_MGS, "adding mdc for %s to log %s:lmv(%s)\n",
1500 mti->mti_svname, logname, lmvname);
1502 rc = name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
1505 rc = name_create(&mdcname, mti->mti_svname, "-mdc");
1508 rc = name_create(&mdcuuid, mdcname, "_UUID");
1511 rc = name_create(&lmvuuid, lmvname, "_UUID");
1515 rc = record_start_log(env, mgs, &llh, logname);
1518 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
1522 for (i = 0; i < mti->mti_nid_count; i++) {
1523 CDEBUG(D_MGS, "add nid %s for mdt\n",
1524 libcfs_nid2str(mti->mti_nids[i]));
1526 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
1531 rc = record_attach(env, llh, mdcname, LUSTRE_MDC_NAME, lmvuuid);
1534 rc = record_setup(env, llh, mdcname, mti->mti_uuid, nodeuuid, 0, 0);
1537 rc = mgs_write_log_failnids(env, mti, llh, mdcname);
1540 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
1541 rc = record_mdc_add(env, llh, lmvname, mdcuuid, mti->mti_uuid,
1545 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname,
1550 record_end_log(env, &llh);
1552 name_destroy(&lmvuuid);
1553 name_destroy(&mdcuuid);
1554 name_destroy(&mdcname);
1555 name_destroy(&nodeuuid);
1559 /* add new mdc to already existent MDS */
1560 static int mgs_write_log_mdc_to_mdt(const struct lu_env *env,
1561 struct mgs_device *mgs,
1563 struct mgs_target_info *mti,
1566 struct llog_handle *llh = NULL;
1567 char *nodeuuid = NULL;
1568 char *mdcname = NULL;
1569 char *mdcuuid = NULL;
1570 char *mdtuuid = NULL;
1571 int idx = mti->mti_stripe_index;
1576 if (mgs_log_is_empty(env, mgs, logname)) {
1577 CERROR("log is empty! Logical error\n");
1581 CDEBUG(D_MGS, "adding mdc index %d to %s\n", idx, logname);
1583 rc = name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
1586 snprintf(index, sizeof(index), "-mdc%04x", idx);
1587 rc = name_create(&mdcname, logname, index);
1590 rc = name_create(&mdcuuid, mdcname, "_UUID");
1593 rc = name_create(&mdtuuid, logname, "_UUID");
1597 rc = record_start_log(env, mgs, &llh, logname);
1600 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname, "add mdc");
1603 for (i = 0; i < mti->mti_nid_count; i++) {
1604 CDEBUG(D_MGS, "add nid %s for mdt\n",
1605 libcfs_nid2str(mti->mti_nids[i]));
1606 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
1610 rc = record_attach(env, llh, mdcname, LUSTRE_MDC_NAME, mdcuuid);
1613 rc = record_setup(env, llh, mdcname, mti->mti_uuid, nodeuuid, 0, 0);
1616 rc = mgs_write_log_failnids(env, mti, llh, mdcname);
1619 snprintf(index, sizeof(index), "%d", idx);
1621 rc = record_mdc_add(env, llh, logname, mdcuuid, mti->mti_uuid,
1625 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname, "add mdc");
1629 record_end_log(env, &llh);
1631 name_destroy(&mdtuuid);
1632 name_destroy(&mdcuuid);
1633 name_destroy(&mdcname);
1634 name_destroy(&nodeuuid);
1638 static int mgs_write_log_mdt0(const struct lu_env *env,
1639 struct mgs_device *mgs,
1641 struct mgs_target_info *mti)
1643 char *log = mti->mti_svname;
1644 struct llog_handle *llh = NULL;
1645 char *uuid, *lovname;
1647 char *ptr = mti->mti_params;
1648 int rc = 0, failout = 0;
1651 OBD_ALLOC(uuid, sizeof(struct obd_uuid));
1655 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
1656 failout = (strncmp(ptr, "failout", 7) == 0);
1658 rc = name_create(&lovname, log, "-mdtlov");
1661 if (mgs_log_is_empty(env, mgs, log)) {
1662 rc = mgs_write_log_lov(env, mgs, fsdb, mti, log, lovname);
1667 sprintf(mdt_index, "%d", mti->mti_stripe_index);
1669 rc = record_start_log(env, mgs, &llh, log);
1673 /* add MDT itself */
1675 /* FIXME this whole fn should be a single journal transaction */
1676 sprintf(uuid, "%s_UUID", log);
1677 rc = record_marker(env, llh, fsdb, CM_START, log, "add mdt");
1680 rc = record_attach(env, llh, log, LUSTRE_MDT_NAME, uuid);
1683 rc = record_mount_opt(env, llh, log, lovname, NULL);
1686 rc = record_setup(env, llh, log, uuid, mdt_index, lovname,
1687 failout ? "n" : "f");
1690 rc = record_marker(env, llh, fsdb, CM_END, log, "add mdt");
1694 record_end_log(env, &llh);
1696 name_destroy(&lovname);
1698 OBD_FREE(uuid, sizeof(struct obd_uuid));
1702 static inline int name_create_mdt(char **logname, char *fsname, int i)
1706 sprintf(mdt_index, "-MDT%04x", i);
1707 return name_create(logname, fsname, mdt_index);
1710 static int name_create_mdt_and_lov(char **logname, char **lovname,
1711 struct fs_db *fsdb, int i)
1715 rc = name_create_mdt(logname, fsdb->fsdb_name, i);
1719 if (i == 0 && cfs_test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
1720 rc = name_create(lovname, fsdb->fsdb_name, "-mdtlov");
1722 rc = name_create(lovname, *logname, "-mdtlov");
1724 name_destroy(logname);
1730 static inline int name_create_mdt_osc(char **oscname, char *ostname,
1731 struct fs_db *fsdb, int i)
1735 if (i == 0 && cfs_test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
1736 sprintf(suffix, "-osc");
1738 sprintf(suffix, "-osc-MDT%04x", i);
1739 return name_create(oscname, ostname, suffix);
1742 /* envelope method for all layers log */
1743 static int mgs_write_log_mdt(const struct lu_env *env,
1744 struct mgs_device *mgs,
1746 struct mgs_target_info *mti)
1748 struct mgs_thread_info *mgi = mgs_env_info(env);
1749 struct llog_handle *llh = NULL;
1754 CDEBUG(D_MGS, "writing new mdt %s\n", mti->mti_svname);
1756 if (mti->mti_uuid[0] == '\0') {
1757 /* Make up our own uuid */
1758 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
1759 "%s_UUID", mti->mti_svname);
1763 rc = mgs_write_log_mdt0(env, mgs, fsdb, mti);
1766 /* Append the mdt info to the client log */
1767 rc = name_create(&cliname, mti->mti_fsname, "-client");
1771 if (mgs_log_is_empty(env, mgs, cliname)) {
1772 /* Start client log */
1773 rc = mgs_write_log_lov(env, mgs, fsdb, mti, cliname,
1777 rc = mgs_write_log_lmv(env, mgs, fsdb, mti, cliname,
1784 #09 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
1785 #10 L attach 0:MDC_uml1_mdsA_MNT_client 1:mdc 2:1d834_MNT_client_03f
1786 #11 L setup 0:MDC_uml1_mdsA_MNT_client 1:mdsA_UUID 2:uml1_UUID
1787 #12 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
1788 #13 L add_conn 0:MDC_uml1_mdsA_MNT_client 1:uml2_UUID
1789 #14 L mount_option 0: 1:client 2:lov1 3:MDC_uml1_mdsA_MNT_client
1792 /* copy client info about lov/lmv */
1793 mgi->mgi_comp.comp_mti = mti;
1794 mgi->mgi_comp.comp_fsdb = fsdb;
1796 rc = mgs_steal_llog_for_mdt_from_client(env, mgs, cliname,
1800 rc = mgs_write_log_mdc_to_lmv(env, mgs, fsdb, mti, cliname,
1806 rc = record_start_log(env, mgs, &llh, cliname);
1810 rc = record_marker(env, llh, fsdb, CM_START, cliname,
1814 rc = record_mount_opt(env, llh, cliname, fsdb->fsdb_clilov,
1818 rc = record_marker(env, llh, fsdb, CM_END, cliname,
1823 /* for_all_existing_mdt except current one */
1824 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
1826 if (i != mti->mti_stripe_index &&
1827 cfs_test_bit(i, fsdb->fsdb_mdt_index_map)) {
1828 rc = name_create_mdt(&mdtname, mti->mti_fsname, i);
1831 rc = mgs_write_log_mdc_to_mdt(env, mgs, fsdb, mti, mdtname);
1832 name_destroy(&mdtname);
1838 record_end_log(env, &llh);
1840 name_destroy(&cliname);
1844 /* Add the ost info to the client/mdt lov */
1845 static int mgs_write_log_osc_to_lov(const struct lu_env *env,
1846 struct mgs_device *mgs, struct fs_db *fsdb,
1847 struct mgs_target_info *mti,
1848 char *logname, char *suffix, char *lovname,
1849 enum lustre_sec_part sec_part, int flags)
1851 struct llog_handle *llh = NULL;
1852 char *nodeuuid = NULL;
1853 char *oscname = NULL;
1854 char *oscuuid = NULL;
1855 char *lovuuid = NULL;
1856 char *svname = NULL;
1861 CDEBUG(D_INFO, "adding osc for %s to log %s\n",
1862 mti->mti_svname, logname);
1864 if (mgs_log_is_empty(env, mgs, logname)) {
1865 CERROR("log is empty! Logical error\n");
1869 rc = name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
1872 rc = name_create(&svname, mti->mti_svname, "-osc");
1875 rc = name_create(&oscname, svname, suffix);
1878 rc = name_create(&oscuuid, oscname, "_UUID");
1881 rc = name_create(&lovuuid, lovname, "_UUID");
1886 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
1888 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
1889 #04 L attach 0:OSC_uml1_ost1_MNT_client 1:osc 2:89070_lov1_a41dff51a
1890 #05 L setup 0:OSC_uml1_ost1_MNT_client 1:ost1_UUID 2:uml1_UUID
1892 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
1893 #07 L add_conn 0:OSC_uml1_ost1_MNT_client 1:uml2_UUID
1894 #08 L lov_modify_tgts add 0:lov1 1:ost1_UUID 2(index):0 3(gen):1
1897 rc = record_start_log(env, mgs, &llh, logname);
1900 /* FIXME these should be a single journal transaction */
1901 rc = record_marker(env, llh, fsdb, CM_START | flags, mti->mti_svname,
1905 for (i = 0; i < mti->mti_nid_count; i++) {
1906 CDEBUG(D_MGS, "add nid %s\n", libcfs_nid2str(mti->mti_nids[i]));
1907 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
1911 rc = record_attach(env, llh, oscname, LUSTRE_OSC_NAME, lovuuid);
1914 rc = record_setup(env, llh, oscname, mti->mti_uuid, nodeuuid, 0, 0);
1917 rc = mgs_write_log_failnids(env, mti, llh, oscname);
1920 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
1921 rc = record_lov_add(env, llh, lovname, mti->mti_uuid, index, "1");
1924 rc = record_marker(env, llh, fsdb, CM_END | flags, mti->mti_svname,
1929 record_end_log(env, &llh);
1931 name_destroy(&lovuuid);
1932 name_destroy(&oscuuid);
1933 name_destroy(&oscname);
1934 name_destroy(&svname);
1935 name_destroy(&nodeuuid);
1939 static int mgs_write_log_ost(const struct lu_env *env,
1940 struct mgs_device *mgs, struct fs_db *fsdb,
1941 struct mgs_target_info *mti)
1943 struct llog_handle *llh = NULL;
1944 char *logname, *lovname;
1945 char *ptr = mti->mti_params;
1946 int rc, flags = 0, failout = 0, i;
1949 CDEBUG(D_MGS, "writing new ost %s\n", mti->mti_svname);
1951 /* The ost startup log */
1953 /* If the ost log already exists, that means that someone reformatted
1954 the ost and it called target_add again. */
1955 if (!mgs_log_is_empty(env, mgs, mti->mti_svname)) {
1956 LCONSOLE_ERROR_MSG(0x141, "The config log for %s already "
1957 "exists, yet the server claims it never "
1958 "registered. It may have been reformatted, "
1959 "or the index changed. writeconf the MDT to "
1960 "regenerate all logs.\n", mti->mti_svname);
1965 attach obdfilter ost1 ost1_UUID
1966 setup /dev/loop2 ldiskfs f|n errors=remount-ro,user_xattr
1968 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
1969 failout = (strncmp(ptr, "failout", 7) == 0);
1970 rc = record_start_log(env, mgs, &llh, mti->mti_svname);
1973 /* FIXME these should be a single journal transaction */
1974 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,"add ost");
1977 if (*mti->mti_uuid == '\0')
1978 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
1979 "%s_UUID", mti->mti_svname);
1980 rc = record_attach(env, llh, mti->mti_svname,
1981 "obdfilter"/*LUSTRE_OST_NAME*/, mti->mti_uuid);
1984 rc = record_setup(env, llh, mti->mti_svname,
1985 "dev"/*ignored*/, "type"/*ignored*/,
1986 failout ? "n" : "f", 0/*options*/);
1989 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname, "add ost");
1993 record_end_log(env, &llh);
1996 /* We also have to update the other logs where this osc is part of
1999 if (cfs_test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
2000 /* If we're upgrading, the old mdt log already has our
2001 entry. Let's do a fake one for fun. */
2002 /* Note that we can't add any new failnids, since we don't
2003 know the old osc names. */
2004 flags = CM_SKIP | CM_UPGRADE146;
2006 } else if ((mti->mti_flags & LDD_F_UPDATE) != LDD_F_UPDATE) {
2007 /* If the update flag isn't set, don't update client/mdt
2010 LCONSOLE_WARN("Client log for %s was not updated; writeconf "
2011 "the MDT first to regenerate it.\n",
2015 /* Add ost to all MDT lov defs */
2016 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
2017 if (cfs_test_bit(i, fsdb->fsdb_mdt_index_map)) {
2020 rc = name_create_mdt_and_lov(&logname, &lovname, fsdb,
2024 sprintf(mdt_index, "-MDT%04x", i);
2025 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, mti,
2027 lovname, LUSTRE_SP_MDT,
2029 name_destroy(&logname);
2030 name_destroy(&lovname);
2036 /* Append ost info to the client log */
2037 rc = name_create(&logname, mti->mti_fsname, "-client");
2040 if (mgs_log_is_empty(env, mgs, logname)) {
2041 /* Start client log */
2042 rc = mgs_write_log_lov(env, mgs, fsdb, mti, logname,
2046 rc = mgs_write_log_lmv(env, mgs, fsdb, mti, logname,
2051 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, mti, logname, "",
2052 fsdb->fsdb_clilov, LUSTRE_SP_CLI, 0);
2054 name_destroy(&logname);
2058 static __inline__ int mgs_param_empty(char *ptr)
2062 if ((tmp = strchr(ptr, '=')) && (*(++tmp) == '\0'))
2067 static int mgs_write_log_failnid_internal(const struct lu_env *env,
2068 struct mgs_device *mgs,
2070 struct mgs_target_info *mti,
2071 char *logname, char *cliname)
2074 struct llog_handle *llh = NULL;
2076 if (mgs_param_empty(mti->mti_params)) {
2077 /* Remove _all_ failnids */
2078 rc = mgs_modify(env, mgs, fsdb, mti, logname,
2079 mti->mti_svname, "add failnid", CM_SKIP);
2080 return rc < 0 ? rc : 0;
2083 /* Otherwise failover nids are additive */
2084 rc = record_start_log(env, mgs, &llh, logname);
2087 /* FIXME this should be a single journal transaction */
2088 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
2092 rc = mgs_write_log_failnids(env, mti, llh, cliname);
2095 rc = record_marker(env, llh, fsdb, CM_END,
2096 mti->mti_svname, "add failnid");
2098 record_end_log(env, &llh);
2103 /* Add additional failnids to an existing log.
2104 The mdc/osc must have been added to logs first */
2105 /* tcp nids must be in dotted-quad ascii -
2106 we can't resolve hostnames from the kernel. */
2107 static int mgs_write_log_add_failnid(const struct lu_env *env,
2108 struct mgs_device *mgs,
2110 struct mgs_target_info *mti)
2112 char *logname, *cliname;
2116 /* FIXME we currently can't erase the failnids
2117 * given when a target first registers, since they aren't part of
2118 * an "add uuid" stanza */
2120 /* Verify that we know about this target */
2121 if (mgs_log_is_empty(env, mgs, mti->mti_svname)) {
2122 LCONSOLE_ERROR_MSG(0x142, "The target %s has not registered "
2123 "yet. It must be started before failnids "
2124 "can be added.\n", mti->mti_svname);
2128 /* Create mdc/osc client name (e.g. lustre-OST0001-osc) */
2129 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
2130 rc = name_create(&cliname, mti->mti_svname, "-mdc");
2131 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2132 rc = name_create(&cliname, mti->mti_svname, "-osc");
2138 /* Add failover nids to the client log */
2139 rc = name_create(&logname, mti->mti_fsname, "-client");
2141 name_destroy(&cliname);
2144 rc = mgs_write_log_failnid_internal(env, mgs, fsdb,mti,logname,cliname);
2145 name_destroy(&logname);
2146 name_destroy(&cliname);
2150 if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2151 /* Add OST failover nids to the MDT logs as well */
2154 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2155 if (!cfs_test_bit(i, fsdb->fsdb_mdt_index_map))
2157 rc = name_create_mdt(&logname, mti->mti_fsname, i);
2160 rc = name_create_mdt_osc(&cliname, mti->mti_svname,
2163 name_destroy(&logname);
2166 rc = mgs_write_log_failnid_internal(env, mgs, fsdb,
2169 name_destroy(&cliname);
2170 name_destroy(&logname);
2179 static int mgs_wlp_lcfg(const struct lu_env *env,
2180 struct mgs_device *mgs, struct fs_db *fsdb,
2181 struct mgs_target_info *mti,
2182 char *logname, struct lustre_cfg_bufs *bufs,
2183 char *tgtname, char *ptr)
2185 char comment[MTI_NAME_MAXLEN];
2187 struct lustre_cfg *lcfg;
2190 /* Erase any old settings of this same parameter */
2191 memcpy(comment, ptr, MTI_NAME_MAXLEN);
2192 comment[MTI_NAME_MAXLEN - 1] = 0;
2193 /* But don't try to match the value. */
2194 if ((tmp = strchr(comment, '=')))
2196 /* FIXME we should skip settings that are the same as old values */
2197 rc = mgs_modify(env, mgs, fsdb, mti, logname, tgtname, comment,CM_SKIP);
2200 del = mgs_param_empty(ptr);
2202 LCONSOLE_INFO("%sing parameter %s.%s in log %s\n", del ? "Disabl" : rc ?
2203 "Sett" : "Modify", tgtname, comment, logname);
2207 lustre_cfg_bufs_reset(bufs, tgtname);
2208 lustre_cfg_bufs_set_string(bufs, 1, ptr);
2209 lcfg = lustre_cfg_new(LCFG_PARAM, bufs);
2212 rc = mgs_write_log_direct(env, mgs, fsdb, logname,lcfg,tgtname,comment);
2213 lustre_cfg_free(lcfg);
2217 /* write global variable settings into log */
2218 static int mgs_write_log_sys(const struct lu_env *env,
2219 struct mgs_device *mgs, struct fs_db *fsdb,
2220 struct mgs_target_info *mti, char *sys, char *ptr)
2222 struct mgs_thread_info *mgi = mgs_env_info(env);
2223 struct lustre_cfg *lcfg;
2225 int rc, cmd, convert = 1;
2227 if (class_match_param(ptr, PARAM_TIMEOUT, &tmp) == 0) {
2228 cmd = LCFG_SET_TIMEOUT;
2229 } else if (class_match_param(ptr, PARAM_LDLM_TIMEOUT, &tmp) == 0) {
2230 cmd = LCFG_SET_LDLM_TIMEOUT;
2231 /* Check for known params here so we can return error to lctl */
2232 } else if ((class_match_param(ptr, PARAM_AT_MIN, &tmp) == 0) ||
2233 (class_match_param(ptr, PARAM_AT_MAX, &tmp) == 0) ||
2234 (class_match_param(ptr, PARAM_AT_EXTRA, &tmp) == 0) ||
2235 (class_match_param(ptr, PARAM_AT_EARLY_MARGIN, &tmp) == 0) ||
2236 (class_match_param(ptr, PARAM_AT_HISTORY, &tmp) == 0)) {
2238 } else if (class_match_param(ptr, PARAM_JOBID_VAR, &tmp) == 0) {
2239 convert = 0; /* Don't convert string value to integer */
2245 if (mgs_param_empty(ptr))
2246 CDEBUG(D_MGS, "global '%s' removed\n", sys);
2248 CDEBUG(D_MGS, "global '%s' val=%s\n", sys, tmp);
2250 lustre_cfg_bufs_reset(&mgi->mgi_bufs, NULL);
2251 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, sys);
2252 if (!convert && *tmp != '\0')
2253 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 2, tmp);
2254 lcfg = lustre_cfg_new(cmd, &mgi->mgi_bufs);
2255 lcfg->lcfg_num = convert ? simple_strtoul(tmp, NULL, 0) : 0;
2256 /* truncate the comment to the parameter name */
2260 /* modify all servers and clients */
2261 rc = mgs_write_log_direct_all(env, mgs, fsdb, mti,
2262 *tmp == '\0' ? NULL : lcfg,
2263 mti->mti_fsname, sys, 0);
2264 if (rc == 0 && *tmp != '\0') {
2266 case LCFG_SET_TIMEOUT:
2267 if (!obd_timeout_set || lcfg->lcfg_num > obd_timeout)
2268 class_process_config(lcfg);
2270 case LCFG_SET_LDLM_TIMEOUT:
2271 if (!ldlm_timeout_set || lcfg->lcfg_num > ldlm_timeout)
2272 class_process_config(lcfg);
2279 lustre_cfg_free(lcfg);
2283 /* write quota settings into log */
2284 static int mgs_write_log_quota(const struct lu_env *env, struct mgs_device *mgs,
2285 struct fs_db *fsdb, struct mgs_target_info *mti,
2286 char *quota, char *ptr)
2288 struct lustre_cfg_bufs bufs;
2289 struct lustre_cfg *lcfg;
2292 int cmd = LCFG_PARAM;
2295 /* support only 'meta' and 'data' pools so far */
2296 if (class_match_param(ptr, QUOTA_METAPOOL_NAME, &tmp) != 0 &&
2297 class_match_param(ptr, QUOTA_DATAPOOL_NAME, &tmp) != 0) {
2298 CERROR("parameter quota.%s isn't supported (only quota.mdt "
2299 "& quota.ost are)\n", ptr);
2304 CDEBUG(D_MGS, "global '%s' removed\n", quota);
2306 CDEBUG(D_MGS, "global '%s'\n", quota);
2308 if (strchr(tmp, 'u') == NULL && strchr(tmp, 'g') == NULL &&
2309 strcmp(tmp, "none") != 0) {
2310 CERROR("enable option(%s) isn't supported\n", tmp);
2315 lustre_cfg_bufs_reset(&bufs, NULL);
2316 lustre_cfg_bufs_set_string(&bufs, 1, quota);
2317 lcfg = lustre_cfg_new(cmd, &bufs);
2318 /* truncate the comment to the parameter name */
2323 /* XXX we duplicated quota enable information in all server
2324 * config logs, it should be moved to a separate config
2325 * log once we cleanup the config log for global param. */
2326 /* modify all servers */
2327 rc = mgs_write_log_direct_all(env, mgs, fsdb, mti,
2328 *tmp == '\0' ? NULL : lcfg,
2329 mti->mti_fsname, quota, 1);
2331 lustre_cfg_free(lcfg);
2335 static int mgs_srpc_set_param_disk(const struct lu_env *env,
2336 struct mgs_device *mgs,
2338 struct mgs_target_info *mti,
2341 struct mgs_thread_info *mgi = mgs_env_info(env);
2342 struct llog_handle *llh = NULL;
2344 char *comment, *ptr;
2345 struct lustre_cfg *lcfg;
2350 ptr = strchr(param, '=');
2354 OBD_ALLOC(comment, len + 1);
2355 if (comment == NULL)
2357 strncpy(comment, param, len);
2358 comment[len] = '\0';
2361 lustre_cfg_bufs_reset(&mgi->mgi_bufs, mti->mti_svname);
2362 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, param);
2363 lcfg = lustre_cfg_new(LCFG_SPTLRPC_CONF, &mgi->mgi_bufs);
2365 GOTO(out_comment, rc = -ENOMEM);
2367 /* construct log name */
2368 rc = name_create(&logname, mti->mti_fsname, "-sptlrpc");
2372 if (mgs_log_is_empty(env, mgs, logname)) {
2373 rc = record_start_log(env, mgs, &llh, logname);
2376 record_end_log(env, &llh);
2379 /* obsolete old one */
2380 rc = mgs_modify(env, mgs, fsdb, mti, logname, mti->mti_svname,
2384 /* write the new one */
2385 rc = mgs_write_log_direct(env, mgs, fsdb, logname, lcfg,
2386 mti->mti_svname, comment);
2388 CERROR("err %d writing log %s\n", rc, logname);
2390 name_destroy(&logname);
2392 lustre_cfg_free(lcfg);
2394 OBD_FREE(comment, len + 1);
2398 static int mgs_srpc_set_param_udesc_mem(struct fs_db *fsdb,
2403 /* disable the adjustable udesc parameter for now, i.e. use default
2404 * setting that client always ship udesc to MDT if possible. to enable
2405 * it simply remove the following line */
2408 ptr = strchr(param, '=');
2413 if (strcmp(param, PARAM_SRPC_UDESC))
2416 if (strcmp(ptr, "yes") == 0) {
2417 cfs_set_bit(FSDB_UDESC, &fsdb->fsdb_flags);
2418 CWARN("Enable user descriptor shipping from client to MDT\n");
2419 } else if (strcmp(ptr, "no") == 0) {
2420 cfs_clear_bit(FSDB_UDESC, &fsdb->fsdb_flags);
2421 CWARN("Disable user descriptor shipping from client to MDT\n");
2429 CERROR("Invalid param: %s\n", param);
2433 static int mgs_srpc_set_param_mem(struct fs_db *fsdb,
2437 struct sptlrpc_rule rule;
2438 struct sptlrpc_rule_set *rset;
2442 if (strncmp(param, PARAM_SRPC, sizeof(PARAM_SRPC) - 1) != 0) {
2443 CERROR("Invalid sptlrpc parameter: %s\n", param);
2447 if (strncmp(param, PARAM_SRPC_UDESC,
2448 sizeof(PARAM_SRPC_UDESC) - 1) == 0) {
2449 RETURN(mgs_srpc_set_param_udesc_mem(fsdb, param));
2452 if (strncmp(param, PARAM_SRPC_FLVR, sizeof(PARAM_SRPC_FLVR) - 1) != 0) {
2453 CERROR("Invalid sptlrpc flavor parameter: %s\n", param);
2457 param += sizeof(PARAM_SRPC_FLVR) - 1;
2459 rc = sptlrpc_parse_rule(param, &rule);
2463 /* mgs rules implies must be mgc->mgs */
2464 if (cfs_test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
2465 if ((rule.sr_from != LUSTRE_SP_MGC &&
2466 rule.sr_from != LUSTRE_SP_ANY) ||
2467 (rule.sr_to != LUSTRE_SP_MGS &&
2468 rule.sr_to != LUSTRE_SP_ANY))
2472 /* preapre room for this coming rule. svcname format should be:
2473 * - fsname: general rule
2474 * - fsname-tgtname: target-specific rule
2476 if (strchr(svname, '-')) {
2477 struct mgs_tgt_srpc_conf *tgtconf;
2480 for (tgtconf = fsdb->fsdb_srpc_tgt; tgtconf != NULL;
2481 tgtconf = tgtconf->mtsc_next) {
2482 if (!strcmp(tgtconf->mtsc_tgt, svname)) {
2491 OBD_ALLOC_PTR(tgtconf);
2492 if (tgtconf == NULL)
2495 name_len = strlen(svname);
2497 OBD_ALLOC(tgtconf->mtsc_tgt, name_len + 1);
2498 if (tgtconf->mtsc_tgt == NULL) {
2499 OBD_FREE_PTR(tgtconf);
2502 memcpy(tgtconf->mtsc_tgt, svname, name_len);
2504 tgtconf->mtsc_next = fsdb->fsdb_srpc_tgt;
2505 fsdb->fsdb_srpc_tgt = tgtconf;
2508 rset = &tgtconf->mtsc_rset;
2510 rset = &fsdb->fsdb_srpc_gen;
2513 rc = sptlrpc_rule_set_merge(rset, &rule);
2518 static int mgs_srpc_set_param(const struct lu_env *env,
2519 struct mgs_device *mgs,
2521 struct mgs_target_info *mti,
2531 /* keep a copy of original param, which could be destroied
2533 copy_size = strlen(param) + 1;
2534 OBD_ALLOC(copy, copy_size);
2537 memcpy(copy, param, copy_size);
2539 rc = mgs_srpc_set_param_mem(fsdb, mti->mti_svname, param);
2543 /* previous steps guaranteed the syntax is correct */
2544 rc = mgs_srpc_set_param_disk(env, mgs, fsdb, mti, copy);
2548 if (cfs_test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
2550 * for mgs rules, make them effective immediately.
2552 LASSERT(fsdb->fsdb_srpc_tgt == NULL);
2553 sptlrpc_target_update_exp_flavor(mgs->mgs_obd,
2554 &fsdb->fsdb_srpc_gen);
2558 OBD_FREE(copy, copy_size);
2562 struct mgs_srpc_read_data {
2563 struct fs_db *msrd_fsdb;
2567 static int mgs_srpc_read_handler(const struct lu_env *env,
2568 struct llog_handle *llh,
2569 struct llog_rec_hdr *rec, void *data)
2571 struct mgs_srpc_read_data *msrd = data;
2572 struct cfg_marker *marker;
2573 struct lustre_cfg *lcfg = (struct lustre_cfg *)(rec + 1);
2574 char *svname, *param;
2578 if (rec->lrh_type != OBD_CFG_REC) {
2579 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
2583 cfg_len = rec->lrh_len - sizeof(struct llog_rec_hdr) -
2584 sizeof(struct llog_rec_tail);
2586 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
2588 CERROR("Insane cfg\n");
2592 if (lcfg->lcfg_command == LCFG_MARKER) {
2593 marker = lustre_cfg_buf(lcfg, 1);
2595 if (marker->cm_flags & CM_START &&
2596 marker->cm_flags & CM_SKIP)
2597 msrd->msrd_skip = 1;
2598 if (marker->cm_flags & CM_END)
2599 msrd->msrd_skip = 0;
2604 if (msrd->msrd_skip)
2607 if (lcfg->lcfg_command != LCFG_SPTLRPC_CONF) {
2608 CERROR("invalid command (%x)\n", lcfg->lcfg_command);
2612 svname = lustre_cfg_string(lcfg, 0);
2613 if (svname == NULL) {
2614 CERROR("svname is empty\n");
2618 param = lustre_cfg_string(lcfg, 1);
2619 if (param == NULL) {
2620 CERROR("param is empty\n");
2624 rc = mgs_srpc_set_param_mem(msrd->msrd_fsdb, svname, param);
2626 CERROR("read sptlrpc record error (%d): %s\n", rc, param);
2631 int mgs_get_fsdb_srpc_from_llog(const struct lu_env *env,
2632 struct mgs_device *mgs,
2635 struct llog_handle *llh = NULL;
2636 struct lvfs_run_ctxt saved;
2637 struct llog_ctxt *ctxt;
2639 struct mgs_srpc_read_data msrd;
2643 /* construct log name */
2644 rc = name_create(&logname, fsdb->fsdb_name, "-sptlrpc");
2648 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
2649 LASSERT(ctxt != NULL);
2651 if (mgs_log_is_empty(env, mgs, logname))
2654 push_ctxt(&saved, &mgs->mgs_obd->obd_lvfs_ctxt, NULL);
2656 rc = llog_open(NULL, ctxt, &llh, NULL, logname,
2664 rc = llog_init_handle(NULL, llh, LLOG_F_IS_PLAIN, NULL);
2666 GOTO(out_close, rc);
2668 if (llog_get_size(llh) <= 1)
2669 GOTO(out_close, rc = 0);
2671 msrd.msrd_fsdb = fsdb;
2674 rc = llog_process_or_fork(env, llh, mgs_srpc_read_handler,
2675 (void *)&msrd, NULL, false);
2678 llog_close(NULL, llh);
2680 pop_ctxt(&saved, &mgs->mgs_obd->obd_lvfs_ctxt, NULL);
2682 llog_ctxt_put(ctxt);
2683 name_destroy(&logname);
2686 CERROR("failed to read sptlrpc config database: %d\n", rc);
2690 /* Permanent settings of all parameters by writing into the appropriate
2691 * configuration logs.
2692 * A parameter with null value ("<param>='\0'") means to erase it out of
2695 static int mgs_write_log_param(const struct lu_env *env,
2696 struct mgs_device *mgs, struct fs_db *fsdb,
2697 struct mgs_target_info *mti, char *ptr)
2699 struct mgs_thread_info *mgi = mgs_env_info(env);
2702 int rc = 0, rc2 = 0;
2705 /* For various parameter settings, we have to figure out which logs
2706 care about them (e.g. both mdt and client for lov settings) */
2707 CDEBUG(D_MGS, "next param '%s'\n", ptr);
2709 /* The params are stored in MOUNT_DATA_FILE and modified via
2710 tunefs.lustre, or set using lctl conf_param */
2712 /* Processed in lustre_start_mgc */
2713 if (class_match_param(ptr, PARAM_MGSNODE, NULL) == 0)
2716 /* Processed in ost/mdt */
2717 if (class_match_param(ptr, PARAM_NETWORK, NULL) == 0)
2720 /* Processed in mgs_write_log_ost */
2721 if (class_match_param(ptr, PARAM_FAILMODE, NULL) == 0) {
2722 if (mti->mti_flags & LDD_F_PARAM) {
2723 LCONSOLE_ERROR_MSG(0x169, "%s can only be "
2724 "changed with tunefs.lustre"
2725 "and --writeconf\n", ptr);
2731 if (class_match_param(ptr, PARAM_SRPC, NULL) == 0) {
2732 rc = mgs_srpc_set_param(env, mgs, fsdb, mti, ptr);
2736 if (class_match_param(ptr, PARAM_FAILNODE, NULL) == 0) {
2737 /* Add a failover nidlist */
2739 /* We already processed failovers params for new
2740 targets in mgs_write_log_target */
2741 if (mti->mti_flags & LDD_F_PARAM) {
2742 CDEBUG(D_MGS, "Adding failnode\n");
2743 rc = mgs_write_log_add_failnid(env, mgs, fsdb, mti);
2748 if (class_match_param(ptr, PARAM_SYS, &tmp) == 0) {
2749 rc = mgs_write_log_sys(env, mgs, fsdb, mti, ptr, tmp);
2753 if (class_match_param(ptr, PARAM_QUOTA, &tmp) == 0) {
2754 rc = mgs_write_log_quota(env, mgs, fsdb, mti, ptr, tmp);
2758 if (class_match_param(ptr, PARAM_OSC""PARAM_ACTIVE, &tmp) == 0) {
2759 /* active=0 means off, anything else means on */
2760 int flag = (*tmp == '0') ? CM_EXCLUDE : 0;
2763 if (!(mti->mti_flags & LDD_F_SV_TYPE_OST)) {
2764 LCONSOLE_ERROR_MSG(0x144, "%s: Only OSCs can "
2765 "be (de)activated.\n",
2767 GOTO(end, rc = -EINVAL);
2769 LCONSOLE_WARN("Permanently %sactivating %s\n",
2770 flag ? "de": "re", mti->mti_svname);
2772 rc = name_create(&logname, mti->mti_fsname, "-client");
2775 rc = mgs_modify(env, mgs, fsdb, mti, logname,
2776 mti->mti_svname, "add osc", flag);
2777 name_destroy(&logname);
2781 /* Add to all MDT logs for CMD */
2782 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2783 if (!cfs_test_bit(i, fsdb->fsdb_mdt_index_map))
2785 rc = name_create_mdt(&logname, mti->mti_fsname, i);
2788 rc = mgs_modify(env, mgs, fsdb, mti, logname,
2789 mti->mti_svname, "add osc", flag);
2790 name_destroy(&logname);
2796 LCONSOLE_ERROR_MSG(0x145, "Couldn't find %s in"
2797 "log (%d). No permanent "
2798 "changes were made to the "
2800 mti->mti_svname, rc);
2801 if (cfs_test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags))
2802 LCONSOLE_ERROR_MSG(0x146, "This may be"
2807 "update the logs.\n");
2810 /* Fall through to osc proc for deactivating live OSC
2811 on running MDT / clients. */
2813 /* Below here, let obd's XXX_process_config methods handle it */
2815 /* All lov. in proc */
2816 if (class_match_param(ptr, PARAM_LOV, NULL) == 0) {
2819 CDEBUG(D_MGS, "lov param %s\n", ptr);
2820 if (!(mti->mti_flags & LDD_F_SV_TYPE_MDT)) {
2821 LCONSOLE_ERROR_MSG(0x147, "LOV params must be "
2822 "set on the MDT, not %s. "
2829 if (mgs_log_is_empty(env, mgs, mti->mti_svname))
2830 GOTO(end, rc = -ENODEV);
2832 rc = name_create_mdt_and_lov(&logname, &mdtlovname, fsdb,
2833 mti->mti_stripe_index);
2836 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, mti->mti_svname,
2837 &mgi->mgi_bufs, mdtlovname, ptr);
2838 name_destroy(&logname);
2839 name_destroy(&mdtlovname);
2844 rc = name_create(&logname, mti->mti_fsname, "-client");
2847 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname, &mgi->mgi_bufs,
2848 fsdb->fsdb_clilov, ptr);
2849 name_destroy(&logname);
2853 /* All osc., mdc., llite. params in proc */
2854 if ((class_match_param(ptr, PARAM_OSC, NULL) == 0) ||
2855 (class_match_param(ptr, PARAM_MDC, NULL) == 0) ||
2856 (class_match_param(ptr, PARAM_LLITE, NULL) == 0)) {
2859 if (cfs_test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
2860 LCONSOLE_ERROR_MSG(0x148, "Upgraded client logs for %s"
2861 " cannot be modified. Consider"
2862 " updating the configuration with"
2865 GOTO(end, rc = -EINVAL);
2867 if (memcmp(ptr, PARAM_LLITE, strlen(PARAM_LLITE)) == 0) {
2868 rc = name_create(&cname, mti->mti_fsname, "-client");
2869 /* Add the client type to match the obdname in
2870 class_config_llog_handler */
2871 } else if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
2872 rc = name_create(&cname, mti->mti_svname, "-mdc");
2873 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2874 rc = name_create(&cname, mti->mti_svname, "-osc");
2876 GOTO(end, rc = -EINVAL);
2881 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
2884 rc = name_create(&logname, mti->mti_fsname, "-client");
2886 name_destroy(&cname);
2889 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname, &mgi->mgi_bufs,
2892 /* osc params affect the MDT as well */
2893 if (!rc && (mti->mti_flags & LDD_F_SV_TYPE_OST)) {
2896 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
2897 if (!cfs_test_bit(i, fsdb->fsdb_mdt_index_map))
2899 name_destroy(&cname);
2900 rc = name_create_mdt_osc(&cname, mti->mti_svname,
2902 name_destroy(&logname);
2905 rc = name_create_mdt(&logname,
2906 mti->mti_fsname, i);
2909 if (!mgs_log_is_empty(env, mgs, logname)) {
2910 rc = mgs_wlp_lcfg(env, mgs, fsdb,
2919 name_destroy(&logname);
2920 name_destroy(&cname);
2924 /* All mdt. params in proc */
2925 if (class_match_param(ptr, PARAM_MDT, NULL) == 0) {
2929 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
2930 if (strncmp(mti->mti_svname, mti->mti_fsname,
2931 MTI_NAME_MAXLEN) == 0)
2932 /* device is unspecified completely? */
2933 rc = LDD_F_SV_TYPE_MDT | LDD_F_SV_ALL;
2935 rc = server_name2index(mti->mti_svname, &idx, NULL);
2938 if ((rc & LDD_F_SV_TYPE_MDT) == 0)
2940 if (rc & LDD_F_SV_ALL) {
2941 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2942 if (!cfs_test_bit(i,
2943 fsdb->fsdb_mdt_index_map))
2945 rc = name_create_mdt(&logname,
2946 mti->mti_fsname, i);
2949 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti,
2950 logname, &mgi->mgi_bufs,
2952 name_destroy(&logname);
2957 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti,
2958 mti->mti_svname, &mgi->mgi_bufs,
2959 mti->mti_svname, ptr);
2966 /* All mdd., ost. params in proc */
2967 if ((class_match_param(ptr, PARAM_MDD, NULL) == 0) ||
2968 (class_match_param(ptr, PARAM_OST, NULL) == 0)) {
2969 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
2970 if (mgs_log_is_empty(env, mgs, mti->mti_svname))
2971 GOTO(end, rc = -ENODEV);
2973 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, mti->mti_svname,
2974 &mgi->mgi_bufs, mti->mti_svname, ptr);
2978 LCONSOLE_WARN("Ignoring unrecognized param '%s'\n", ptr);
2983 CERROR("err %d on param '%s'\n", rc, ptr);
2988 /* Not implementing automatic failover nid addition at this time. */
2989 int mgs_check_failnid(const struct lu_env *env, struct mgs_device *mgs,
2990 struct mgs_target_info *mti)
2997 rc = mgs_find_or_make_fsdb(obd, fsname, &fsdb);
3001 if (mgs_log_is_empty(obd, mti->mti_svname))
3002 /* should never happen */
3005 CDEBUG(D_MGS, "Checking for new failnids for %s\n", mti->mti_svname);
3007 /* FIXME We can just check mti->params to see if we're already in
3008 the failover list. Modify mti->params for rewriting back at
3009 server_register_target(). */
3011 cfs_mutex_lock(&fsdb->fsdb_mutex);
3012 rc = mgs_write_log_add_failnid(obd, fsdb, mti);
3013 cfs_mutex_unlock(&fsdb->fsdb_mutex);
3020 int mgs_write_log_target(const struct lu_env *env,
3021 struct mgs_device *mgs,
3022 struct mgs_target_info *mti,
3029 /* set/check the new target index */
3030 rc = mgs_set_index(env, mgs, mti);
3032 CERROR("Can't get index (%d)\n", rc);
3036 if (rc == EALREADY) {
3037 LCONSOLE_WARN("Found index %d for %s, updating log\n",
3038 mti->mti_stripe_index, mti->mti_svname);
3039 /* We would like to mark old log sections as invalid
3040 and add new log sections in the client and mdt logs.
3041 But if we add new sections, then live clients will
3042 get repeat setup instructions for already running
3043 osc's. So don't update the client/mdt logs. */
3044 mti->mti_flags &= ~LDD_F_UPDATE;
3047 cfs_mutex_lock(&fsdb->fsdb_mutex);
3049 if (mti->mti_flags &
3050 (LDD_F_VIRGIN | LDD_F_UPGRADE14 | LDD_F_WRITECONF)) {
3051 /* Generate a log from scratch */
3052 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
3053 rc = mgs_write_log_mdt(env, mgs, fsdb, mti);
3054 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
3055 rc = mgs_write_log_ost(env, mgs, fsdb, mti);
3057 CERROR("Unknown target type %#x, can't create log for "
3058 "%s\n", mti->mti_flags, mti->mti_svname);
3061 CERROR("Can't write logs for %s (%d)\n",
3062 mti->mti_svname, rc);
3066 /* Just update the params from tunefs in mgs_write_log_params */
3067 CDEBUG(D_MGS, "Update params for %s\n", mti->mti_svname);
3068 mti->mti_flags |= LDD_F_PARAM;
3071 /* allocate temporary buffer, where class_get_next_param will
3072 make copy of a current parameter */
3073 OBD_ALLOC(buf, strlen(mti->mti_params) + 1);
3075 GOTO(out_up, rc = -ENOMEM);
3076 params = mti->mti_params;
3077 while (params != NULL) {
3078 rc = class_get_next_param(¶ms, buf);
3081 /* there is no next parameter, that is
3086 CDEBUG(D_MGS, "remaining string: '%s', param: '%s'\n",
3088 rc = mgs_write_log_param(env, mgs, fsdb, mti, buf);
3093 OBD_FREE(buf, strlen(mti->mti_params) + 1);
3096 cfs_mutex_unlock(&fsdb->fsdb_mutex);
3100 int mgs_erase_log(const struct lu_env *env, struct mgs_device *mgs, char *name)
3102 struct lvfs_run_ctxt saved;
3103 struct llog_ctxt *ctxt;
3105 struct obd_device *obd = mgs->mgs_obd;
3107 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
3109 CERROR("%s: MGS config context doesn't exist\n",
3113 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
3114 rc = llog_erase(NULL, ctxt, NULL, name);
3115 /* llog may not exist */
3118 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
3119 llog_ctxt_put(ctxt);
3123 CERROR("%s: failed to clear log %s: %d\n", obd->obd_name,
3129 /* erase all logs for the given fs */
3130 int mgs_erase_logs(const struct lu_env *env, struct mgs_device *mgs, char *fsname)
3134 struct mgs_direntry *dirent, *n;
3135 int rc, len = strlen(fsname);
3139 /* Find all the logs in the CONFIGS directory */
3140 rc = class_dentry_readdir(env, mgs, &list);
3144 cfs_mutex_lock(&mgs->mgs_mutex);
3146 /* Delete the fs db */
3147 fsdb = mgs_find_fsdb(mgs, fsname);
3149 mgs_free_fsdb(mgs, fsdb);
3151 cfs_mutex_unlock(&mgs->mgs_mutex);
3153 cfs_list_for_each_entry_safe(dirent, n, &list, list) {
3154 cfs_list_del(&dirent->list);
3155 suffix = strrchr(dirent->name, '-');
3156 if (suffix != NULL) {
3157 if ((len == suffix - dirent->name) &&
3158 (strncmp(fsname, dirent->name, len) == 0)) {
3159 CDEBUG(D_MGS, "Removing log %s\n",
3161 mgs_erase_log(env, mgs, dirent->name);
3164 mgs_direntry_free(dirent);
3170 /* from llog_swab */
3171 static void print_lustre_cfg(struct lustre_cfg *lcfg)
3176 CDEBUG(D_MGS, "lustre_cfg: %p\n", lcfg);
3177 CDEBUG(D_MGS, "\tlcfg->lcfg_version: %#x\n", lcfg->lcfg_version);
3179 CDEBUG(D_MGS, "\tlcfg->lcfg_command: %#x\n", lcfg->lcfg_command);
3180 CDEBUG(D_MGS, "\tlcfg->lcfg_num: %#x\n", lcfg->lcfg_num);
3181 CDEBUG(D_MGS, "\tlcfg->lcfg_flags: %#x\n", lcfg->lcfg_flags);
3182 CDEBUG(D_MGS, "\tlcfg->lcfg_nid: %s\n", libcfs_nid2str(lcfg->lcfg_nid));
3184 CDEBUG(D_MGS, "\tlcfg->lcfg_bufcount: %d\n", lcfg->lcfg_bufcount);
3185 if (lcfg->lcfg_bufcount < LUSTRE_CFG_MAX_BUFCOUNT)
3186 for (i = 0; i < lcfg->lcfg_bufcount; i++) {
3187 CDEBUG(D_MGS, "\tlcfg->lcfg_buflens[%d]: %d %s\n",
3188 i, lcfg->lcfg_buflens[i],
3189 lustre_cfg_string(lcfg, i));
3194 /* Set a permanent (config log) param for a target or fs
3195 * \param lcfg buf0 may contain the device (testfs-MDT0000) name
3196 * buf1 contains the single parameter
3198 int mgs_setparam(const struct lu_env *env, struct mgs_device *mgs,
3199 struct lustre_cfg *lcfg, char *fsname)
3202 struct mgs_target_info *mti;
3203 char *devname, *param;
3209 print_lustre_cfg(lcfg);
3211 /* lustre, lustre-mdtlov, lustre-client, lustre-MDT0000 */
3212 devname = lustre_cfg_string(lcfg, 0);
3213 param = lustre_cfg_string(lcfg, 1);
3215 /* Assume device name embedded in param:
3216 lustre-OST0000.osc.max_dirty_mb=32 */
3217 ptr = strchr(param, '.');
3225 LCONSOLE_ERROR_MSG(0x14d, "No target specified: %s\n", param);
3229 /* Extract fsname */
3230 ptr = strrchr(devname, '-');
3231 memset(fsname, 0, MTI_NAME_MAXLEN);
3232 if (ptr && (server_name2index(ptr, &index, NULL) >= 0)) {
3233 /* param related to llite isn't allowed to set by OST or MDT */
3234 if (strncmp(param, PARAM_LLITE, sizeof(PARAM_LLITE)) == 0)
3237 strncpy(fsname, devname, ptr - devname);
3239 /* assume devname is the fsname */
3240 strncpy(fsname, devname, MTI_NAME_MAXLEN);
3242 fsname[MTI_NAME_MAXLEN - 1] = 0;
3243 CDEBUG(D_MGS, "setparam fs='%s' device='%s'\n", fsname, devname);
3245 rc = mgs_find_or_make_fsdb(env, mgs, fsname, &fsdb);
3248 if (!cfs_test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags) &&
3249 cfs_test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
3250 CERROR("No filesystem targets for %s. cfg_device from lctl "
3251 "is '%s'\n", fsname, devname);
3252 mgs_free_fsdb(mgs, fsdb);
3256 /* Create a fake mti to hold everything */
3259 GOTO(out, rc = -ENOMEM);
3260 strncpy(mti->mti_fsname, fsname, MTI_NAME_MAXLEN);
3261 strncpy(mti->mti_svname, devname, MTI_NAME_MAXLEN);
3262 strncpy(mti->mti_params, param, sizeof(mti->mti_params));
3263 rc = server_name2index(mti->mti_svname, &mti->mti_stripe_index, &tmp);
3265 /* Not a valid server; may be only fsname */
3268 /* Strip -osc or -mdc suffix from svname */
3269 if (server_make_name(rc, mti->mti_stripe_index, mti->mti_fsname,
3271 GOTO(out, rc = -EINVAL);
3273 mti->mti_flags = rc | LDD_F_PARAM;
3275 cfs_mutex_lock(&fsdb->fsdb_mutex);
3276 rc = mgs_write_log_param(env, mgs, fsdb, mti, mti->mti_params);
3277 cfs_mutex_unlock(&fsdb->fsdb_mutex);
3280 * Revoke lock so everyone updates. Should be alright if
3281 * someone was already reading while we were updating the logs,
3282 * so we don't really need to hold the lock while we're
3285 mgs_revoke_lock(mgs, fsdb, CONFIG_T_CONFIG);
3291 static int mgs_write_log_pool(const struct lu_env *env,
3292 struct mgs_device *mgs, char *logname,
3293 struct fs_db *fsdb, char *lovname,
3294 enum lcfg_command_type cmd,
3295 char *poolname, char *fsname,
3296 char *ostname, char *comment)
3298 struct llog_handle *llh = NULL;
3301 rc = record_start_log(env, mgs, &llh, logname);
3304 rc = record_marker(env, llh, fsdb, CM_START, lovname, comment);
3307 rc = record_base(env, llh, lovname, 0, cmd, poolname, fsname, ostname, 0);
3310 rc = record_marker(env, llh, fsdb, CM_END, lovname, comment);
3312 record_end_log(env, &llh);
3316 int mgs_pool_cmd(const struct lu_env *env, struct mgs_device *mgs,
3317 enum lcfg_command_type cmd, char *fsname,
3318 char *poolname, char *ostname)
3323 char *label = NULL, *canceled_label = NULL;
3325 struct mgs_target_info *mti = NULL;
3329 rc = mgs_find_or_make_fsdb(env, mgs, fsname, &fsdb);
3331 CERROR("Can't get db for %s\n", fsname);
3334 if (cfs_test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
3335 CERROR("%s is not defined\n", fsname);
3336 mgs_free_fsdb(mgs, fsdb);
3340 label_sz = 10 + strlen(fsname) + strlen(poolname);
3342 /* check if ostname match fsname */
3343 if (ostname != NULL) {
3346 ptr = strrchr(ostname, '-');
3347 if ((ptr == NULL) ||
3348 (strncmp(fsname, ostname, ptr-ostname) != 0))
3350 label_sz += strlen(ostname);
3353 OBD_ALLOC(label, label_sz);
3360 "new %s.%s", fsname, poolname);
3364 "add %s.%s.%s", fsname, poolname, ostname);
3367 OBD_ALLOC(canceled_label, label_sz);
3368 if (canceled_label == NULL)
3369 GOTO(out_label, rc = -ENOMEM);
3371 "rem %s.%s.%s", fsname, poolname, ostname);
3372 sprintf(canceled_label,
3373 "add %s.%s.%s", fsname, poolname, ostname);
3376 OBD_ALLOC(canceled_label, label_sz);
3377 if (canceled_label == NULL)
3378 GOTO(out_label, rc = -ENOMEM);
3380 "del %s.%s", fsname, poolname);
3381 sprintf(canceled_label,
3382 "new %s.%s", fsname, poolname);
3388 cfs_mutex_lock(&fsdb->fsdb_mutex);
3390 if (canceled_label != NULL) {
3393 GOTO(out_cancel, rc = -ENOMEM);
3396 /* write pool def to all MDT logs */
3397 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3398 if (cfs_test_bit(i, fsdb->fsdb_mdt_index_map)) {
3399 rc = name_create_mdt_and_lov(&logname, &lovname,
3402 cfs_mutex_unlock(&fsdb->fsdb_mutex);
3405 if (canceled_label != NULL) {
3406 strcpy(mti->mti_svname, "lov pool");
3407 rc = mgs_modify(env, mgs, fsdb, mti, logname,
3408 lovname, canceled_label,
3413 rc = mgs_write_log_pool(env, mgs, logname,
3417 name_destroy(&logname);
3418 name_destroy(&lovname);
3420 cfs_mutex_unlock(&fsdb->fsdb_mutex);
3426 rc = name_create(&logname, fsname, "-client");
3428 cfs_mutex_unlock(&fsdb->fsdb_mutex);
3431 if (canceled_label != NULL) {
3432 rc = mgs_modify(env, mgs, fsdb, mti, logname,
3433 fsdb->fsdb_clilov, canceled_label, CM_SKIP);
3435 cfs_mutex_unlock(&fsdb->fsdb_mutex);
3436 name_destroy(&logname);
3441 rc = mgs_write_log_pool(env, mgs, logname, fsdb, fsdb->fsdb_clilov,
3442 cmd, fsname, poolname, ostname, label);
3443 cfs_mutex_unlock(&fsdb->fsdb_mutex);
3444 name_destroy(&logname);
3445 /* request for update */
3446 mgs_revoke_lock(mgs, fsdb, CONFIG_T_CONFIG);
3453 if (canceled_label != NULL)
3454 OBD_FREE(canceled_label, label_sz);
3456 OBD_FREE(label, label_sz);
3461 /******************** unused *********************/
3462 static int mgs_backup_llog(struct obd_device *obd, char* fsname)
3464 struct file *filp, *bak_filp;
3465 struct lvfs_run_ctxt saved;
3466 char *logname, *buf;
3467 loff_t soff = 0 , doff = 0;
3468 int count = 4096, len;
3471 OBD_ALLOC(logname, PATH_MAX);
3472 if (logname == NULL)
3475 OBD_ALLOC(buf, count);
3477 GOTO(out , rc = -ENOMEM);
3479 len = snprintf(logname, PATH_MAX, "%s/%s.bak",
3480 MOUNT_CONFIGS_DIR, fsname);
3482 if (len >= PATH_MAX - 1) {
3483 GOTO(out, -ENAMETOOLONG);
3486 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
3488 bak_filp = l_filp_open(logname, O_RDWR|O_CREAT|O_TRUNC, 0660);
3489 if (IS_ERR(bak_filp)) {
3490 rc = PTR_ERR(bak_filp);
3491 CERROR("backup logfile open %s: %d\n", logname, rc);
3494 sprintf(logname, "%s/%s", MOUNT_CONFIGS_DIR, fsname);
3495 filp = l_filp_open(logname, O_RDONLY, 0);
3498 CERROR("logfile open %s: %d\n", logname, rc);
3502 while ((rc = lustre_fread(filp, buf, count, &soff)) > 0) {
3503 rc = lustre_fwrite(bak_filp, buf, count, &doff);
3507 filp_close(filp, 0);
3509 filp_close(bak_filp, 0);
3511 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
3514 OBD_FREE(buf, count);
3515 OBD_FREE(logname, PATH_MAX);