1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
6 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 only,
10 * as published by the Free Software Foundation.
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License version 2 for more details (a copy is included
16 * in the LICENSE file that accompanied this code).
18 * You should have received a copy of the GNU General Public License
19 * version 2 along with this program; If not, see
20 * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
22 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
23 * CA 95054 USA or visit www.sun.com if you need additional information or
29 * Copyright 2008 Sun Microsystems, Inc. All rights reserved
30 * Use is subject to license terms.
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>
46 #define DEBUG_SUBSYSTEM S_MGS
47 #define D_MGS D_CONFIG /*|D_WARNING*/
50 #include <linux/module.h>
51 #include <linux/pagemap.h>
57 #include <obd_class.h>
58 #include <lustre_log.h>
60 #include <libcfs/list.h>
61 #include <linux/lvfs.h>
62 #include <lustre_fsfilt.h>
63 #include <lustre_disk.h>
64 #include <lustre_param.h>
65 #include <lustre_sec.h>
66 #include "mgs_internal.h"
68 /********************** Class functions ********************/
70 /* Caller must list_del and OBD_FREE each dentry from the list */
71 int class_dentry_readdir(struct obd_device *obd, struct dentry *dir,
72 struct vfsmount *inmnt,
73 cfs_list_t *dentry_list){
74 /* see mds_cleanup_pending */
75 struct lvfs_run_ctxt saved;
77 struct dentry *dentry;
82 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
85 GOTO(out_pop, rc = PTR_ERR(dentry));
89 GOTO(out_pop, rc = PTR_ERR(mnt));
92 file = dentry_open(dentry, mnt, O_RDONLY);
94 /* dentry_open_it() drops the dentry, mnt refs */
95 GOTO(out_pop, rc = PTR_ERR(file));
97 CFS_INIT_LIST_HEAD(dentry_list);
98 rc = l_readdir(file, dentry_list);
100 /* filp_close->fput() drops the dentry, mnt refs */
103 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
107 /******************** DB functions *********************/
109 static inline int name_create(char **newname, char *prefix, char *suffix)
112 OBD_ALLOC(*newname, strlen(prefix) + strlen(suffix) + 1);
115 sprintf(*newname, "%s%s", prefix, suffix);
119 static inline void name_destroy(char **name)
122 OBD_FREE(*name, strlen(*name) + 1);
126 struct mgs_fsdb_handler_data
132 /* from the (client) config log, figure out:
133 1. which ost's/mdt's are configured (by index)
134 2. what the last config step is
135 3. COMPAT_146 lov name
136 4. COMPAT_146 mdt lov name
137 5. COMPAT_146 mdc name
138 6. COMPAT_18 osc name
140 /* It might be better to have a separate db file, instead of parsing the info
141 out of the client log. This is slow and potentially error-prone. */
142 static int mgs_fsdb_handler(struct llog_handle *llh, struct llog_rec_hdr *rec,
145 struct mgs_fsdb_handler_data *d = (struct mgs_fsdb_handler_data *) data;
146 struct fs_db *fsdb = d->fsdb;
147 int cfg_len = rec->lrh_len;
148 char *cfg_buf = (char*) (rec + 1);
149 struct lustre_cfg *lcfg;
154 if (rec->lrh_type != OBD_CFG_REC) {
155 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
159 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
161 CERROR("Insane cfg\n");
165 lcfg = (struct lustre_cfg *)cfg_buf;
167 CDEBUG(D_INFO, "cmd %x %s %s\n", lcfg->lcfg_command,
168 lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));
170 /* Figure out ost indicies */
171 /* lov_modify_tgts add 0:lov1 1:ost1_UUID 2(index):0 3(gen):1 */
172 if (lcfg->lcfg_command == LCFG_LOV_ADD_OBD ||
173 lcfg->lcfg_command == LCFG_LOV_DEL_OBD) {
174 index = simple_strtoul(lustre_cfg_string(lcfg, 2),
176 CDEBUG(D_MGS, "OST index for %s is %u (%s)\n",
177 lustre_cfg_string(lcfg, 1), index,
178 lustre_cfg_string(lcfg, 2));
179 cfs_set_bit(index, fsdb->fsdb_ost_index_map);
182 /* Figure out mdt indicies */
183 /* attach 0:MDC_uml1_mdsA_MNT_client 1:mdc 2:1d834_MNT_client_03f */
184 if ((lcfg->lcfg_command == LCFG_ATTACH) &&
185 (strcmp(lustre_cfg_string(lcfg, 1), LUSTRE_MDC_NAME) == 0)) {
186 rc = server_name2index(lustre_cfg_string(lcfg, 0),
188 if (rc != LDD_F_SV_TYPE_MDT) {
189 CWARN("Unparsable MDC name %s, assuming index 0\n",
190 lustre_cfg_string(lcfg, 0));
194 CDEBUG(D_MGS, "MDT index is %u\n", index);
195 cfs_set_bit(index, fsdb->fsdb_mdt_index_map);
196 fsdb->fsdb_mdt_count ++;
200 /* figure out the old LOV name. fsdb_gen = 0 means old log */
201 /* #01 L attach 0:lov_mdsA 1:lov 2:cdbe9_lov_mdsA_dc8cf7f3bb */
202 if ((fsdb->fsdb_gen == 0) && (lcfg->lcfg_command == LCFG_ATTACH) &&
203 (strcmp(lustre_cfg_string(lcfg, 1), LUSTRE_LOV_NAME) == 0)) {
204 fsdb->fsdb_flags |= FSDB_OLDLOG14;
205 name_destroy(&fsdb->fsdb_clilov);
206 rc = name_create(&fsdb->fsdb_clilov,
207 lustre_cfg_string(lcfg, 0), "");
210 CDEBUG(D_MGS, "client lov name is %s\n", fsdb->fsdb_clilov);
213 /* figure out the old MDT lov name from the MDT uuid */
214 if ((fsdb->fsdb_gen == 0) && (lcfg->lcfg_command == LCFG_SETUP) &&
215 (strncmp(lustre_cfg_string(lcfg, 0), "MDC_", 4) == 0)) {
217 fsdb->fsdb_flags |= FSDB_OLDLOG14;
218 ptr = strstr(lustre_cfg_string(lcfg, 1), "_UUID");
220 CERROR("Can't parse MDT uuid %s\n",
221 lustre_cfg_string(lcfg, 1));
225 name_destroy(&fsdb->fsdb_mdtlov);
226 rc = name_create(&fsdb->fsdb_mdtlov,
227 "lov_", lustre_cfg_string(lcfg, 1));
230 name_destroy(&fsdb->fsdb_mdc);
231 rc = name_create(&fsdb->fsdb_mdc,
232 lustre_cfg_string(lcfg, 0), "");
235 CDEBUG(D_MGS, "MDT lov name is %s\n", fsdb->fsdb_mdtlov);
240 * compat to 1.8, check osc name used by MDT0 to OSTs, bz18548.
242 if (fsdb->fsdb_fl_oscname_18 == 0 &&
243 lcfg->lcfg_command == LCFG_ATTACH &&
244 strcmp(lustre_cfg_string(lcfg, 1), LUSTRE_OSC_NAME) == 0) {
245 if (OBD_OCD_VERSION_MAJOR(d->ver) == 1 &&
246 OBD_OCD_VERSION_MINOR(d->ver) <= 8) {
247 CWARN("MDT using 1.8 OSC name scheme\n");
248 fsdb->fsdb_fl_oscname_18 = 1;
252 if (lcfg->lcfg_command == LCFG_MARKER) {
253 struct cfg_marker *marker;
254 marker = lustre_cfg_buf(lcfg, 1);
256 d->ver = marker->cm_vers;
258 /* Keep track of the latest marker step */
259 fsdb->fsdb_gen = max(fsdb->fsdb_gen, marker->cm_step);
265 /* fsdb->fsdb_sem is already held in mgs_find_or_make_fsdb*/
266 static int mgs_get_fsdb_from_llog(struct obd_device *obd, struct fs_db *fsdb)
269 struct llog_handle *loghandle;
270 struct lvfs_run_ctxt saved;
271 struct llog_ctxt *ctxt;
272 struct mgs_fsdb_handler_data d = { fsdb, 0 };
276 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
277 LASSERT(ctxt != NULL);
278 name_create(&logname, fsdb->fsdb_name, "-client");
279 cfs_down(&fsdb->fsdb_sem);
280 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
281 rc = llog_create(ctxt, &loghandle, NULL, logname);
285 rc = llog_init_handle(loghandle, LLOG_F_IS_PLAIN, NULL);
289 if (llog_get_size(loghandle) <= 1)
290 fsdb->fsdb_flags |= FSDB_LOG_EMPTY;
292 rc = llog_process(loghandle, mgs_fsdb_handler, (void *) &d, NULL);
293 CDEBUG(D_INFO, "get_db = %d\n", rc);
295 rc2 = llog_close(loghandle);
299 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
300 cfs_up(&fsdb->fsdb_sem);
301 name_destroy(&logname);
307 static void mgs_free_fsdb_srpc(struct fs_db *fsdb)
309 struct mgs_tgt_srpc_conf *tgtconf;
311 /* free target-specific rules */
312 while (fsdb->fsdb_srpc_tgt) {
313 tgtconf = fsdb->fsdb_srpc_tgt;
314 fsdb->fsdb_srpc_tgt = tgtconf->mtsc_next;
316 LASSERT(tgtconf->mtsc_tgt);
318 sptlrpc_rule_set_free(&tgtconf->mtsc_rset);
319 OBD_FREE(tgtconf->mtsc_tgt, strlen(tgtconf->mtsc_tgt) + 1);
320 OBD_FREE_PTR(tgtconf);
323 /* free general rules */
324 sptlrpc_rule_set_free(&fsdb->fsdb_srpc_gen);
327 static struct fs_db *mgs_find_fsdb(struct obd_device *obd, char *fsname)
329 struct mgs_obd *mgs = &obd->u.mgs;
333 cfs_list_for_each(tmp, &mgs->mgs_fs_db_list) {
334 fsdb = cfs_list_entry(tmp, struct fs_db, fsdb_list);
335 if (strcmp(fsdb->fsdb_name, fsname) == 0)
341 /* caller must hold the mgs->mgs_fs_db_lock */
342 static struct fs_db *mgs_new_fsdb(struct obd_device *obd, char *fsname)
344 struct mgs_obd *mgs = &obd->u.mgs;
349 if (strlen(fsname) >= sizeof(fsdb->fsdb_name)) {
350 CERROR("fsname %s is too long\n", fsname);
358 strcpy(fsdb->fsdb_name, fsname);
359 cfs_sema_init(&fsdb->fsdb_sem, 1);
360 fsdb->fsdb_fl_udesc = 1;
362 if (strcmp(fsname, MGSSELF_NAME) == 0) {
363 fsdb->fsdb_fl_mgsself = 1;
365 OBD_ALLOC(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
366 OBD_ALLOC(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
367 if (!fsdb->fsdb_ost_index_map || !fsdb->fsdb_mdt_index_map) {
368 CERROR("No memory for index maps\n");
372 rc = name_create(&fsdb->fsdb_mdtlov, fsname, "-mdtlov");
375 rc = name_create(&fsdb->fsdb_mdtlmv, fsname, "-mdtlmv");
378 rc = name_create(&fsdb->fsdb_clilov, fsname, "-clilov");
381 rc = name_create(&fsdb->fsdb_clilmv, fsname, "-clilmv");
385 lproc_mgs_add_live(obd, fsdb);
388 cfs_list_add(&fsdb->fsdb_list, &mgs->mgs_fs_db_list);
392 if (fsdb->fsdb_ost_index_map)
393 OBD_FREE(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
394 if (fsdb->fsdb_mdt_index_map)
395 OBD_FREE(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
396 name_destroy(&fsdb->fsdb_clilov);
397 name_destroy(&fsdb->fsdb_clilmv);
398 name_destroy(&fsdb->fsdb_mdtlov);
399 name_destroy(&fsdb->fsdb_mdtlmv);
404 static void mgs_free_fsdb(struct obd_device *obd, struct fs_db *fsdb)
406 /* wait for anyone with the sem */
407 cfs_down(&fsdb->fsdb_sem);
408 lproc_mgs_del_live(obd, fsdb);
409 cfs_list_del(&fsdb->fsdb_list);
410 if (fsdb->fsdb_ost_index_map)
411 OBD_FREE(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
412 if (fsdb->fsdb_mdt_index_map)
413 OBD_FREE(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
414 name_destroy(&fsdb->fsdb_clilov);
415 name_destroy(&fsdb->fsdb_clilmv);
416 name_destroy(&fsdb->fsdb_mdtlov);
417 name_destroy(&fsdb->fsdb_mdtlmv);
418 name_destroy(&fsdb->fsdb_mdc);
419 mgs_free_fsdb_srpc(fsdb);
423 int mgs_init_fsdb_list(struct obd_device *obd)
425 struct mgs_obd *mgs = &obd->u.mgs;
426 CFS_INIT_LIST_HEAD(&mgs->mgs_fs_db_list);
430 int mgs_cleanup_fsdb_list(struct obd_device *obd)
432 struct mgs_obd *mgs = &obd->u.mgs;
434 cfs_list_t *tmp, *tmp2;
435 cfs_down(&mgs->mgs_sem);
436 cfs_list_for_each_safe(tmp, tmp2, &mgs->mgs_fs_db_list) {
437 fsdb = cfs_list_entry(tmp, struct fs_db, fsdb_list);
438 mgs_free_fsdb(obd, fsdb);
440 cfs_up(&mgs->mgs_sem);
444 int mgs_find_or_make_fsdb(struct obd_device *obd, char *name,
447 struct mgs_obd *mgs = &obd->u.mgs;
451 cfs_down(&mgs->mgs_sem);
452 fsdb = mgs_find_fsdb(obd, name);
454 cfs_up(&mgs->mgs_sem);
459 CDEBUG(D_MGS, "Creating new db\n");
460 fsdb = mgs_new_fsdb(obd, name);
461 cfs_up(&mgs->mgs_sem);
465 if (!fsdb->fsdb_fl_mgsself) {
466 /* populate the db from the client llog */
467 rc = mgs_get_fsdb_from_llog(obd, fsdb);
469 CERROR("Can't get db from client log %d\n", rc);
470 mgs_free_fsdb(obd, fsdb);
475 /* populate srpc rules from params llog */
476 rc = mgs_get_fsdb_srpc_from_llog(obd, fsdb);
478 CERROR("Can't get db from params log %d\n", rc);
479 mgs_free_fsdb(obd, fsdb);
490 -1= empty client log */
491 int mgs_check_index(struct obd_device *obd, struct mgs_target_info *mti)
498 LASSERT(!(mti->mti_flags & LDD_F_NEED_INDEX));
500 rc = mgs_find_or_make_fsdb(obd, mti->mti_fsname, &fsdb);
502 CERROR("Can't get db for %s\n", mti->mti_fsname);
506 if (fsdb->fsdb_flags & FSDB_LOG_EMPTY)
509 if (mti->mti_flags & LDD_F_SV_TYPE_OST)
510 imap = fsdb->fsdb_ost_index_map;
511 else if (mti->mti_flags & LDD_F_SV_TYPE_MDT)
512 imap = fsdb->fsdb_mdt_index_map;
516 if (cfs_test_bit(mti->mti_stripe_index, imap))
521 static __inline__ int next_index(void *index_map, int map_len)
524 for (i = 0; i < map_len * 8; i++)
525 if (!cfs_test_bit(i, index_map)) {
528 CERROR("max index %d exceeded.\n", i);
533 0 newly marked as in use
535 +EALREADY for update of an old index */
536 static int mgs_set_index(struct obd_device *obd, struct mgs_target_info *mti)
543 rc = mgs_find_or_make_fsdb(obd, mti->mti_fsname, &fsdb);
545 CERROR("Can't get db for %s\n", mti->mti_fsname);
549 if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
550 imap = fsdb->fsdb_ost_index_map;
551 } else if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
552 imap = fsdb->fsdb_mdt_index_map;
553 if (fsdb->fsdb_mdt_count >= MAX_MDT_COUNT) {
554 LCONSOLE_ERROR_MSG(0x13f, "The max mdt count"
555 "is %d\n", (int)MAX_MDT_COUNT);
562 if (mti->mti_flags & LDD_F_NEED_INDEX) {
563 rc = next_index(imap, INDEX_MAP_SIZE);
566 mti->mti_stripe_index = rc;
567 if (mti->mti_flags & LDD_F_SV_TYPE_MDT)
568 fsdb->fsdb_mdt_count ++;
571 if (mti->mti_stripe_index >= INDEX_MAP_SIZE * 8) {
572 LCONSOLE_ERROR_MSG(0x13f, "Server %s requested index %d, "
573 "but the max index is %d.\n",
574 mti->mti_svname, mti->mti_stripe_index,
579 if (cfs_test_bit(mti->mti_stripe_index, imap)) {
580 if ((mti->mti_flags & LDD_F_VIRGIN) &&
581 !(mti->mti_flags & LDD_F_WRITECONF)) {
582 LCONSOLE_ERROR_MSG(0x140, "Server %s requested index "
583 "%d, but that index is already in "
584 "use. Use --writeconf to force\n",
586 mti->mti_stripe_index);
589 CDEBUG(D_MGS, "Server %s updating index %d\n",
590 mti->mti_svname, mti->mti_stripe_index);
595 cfs_set_bit(mti->mti_stripe_index, imap);
596 fsdb->fsdb_flags &= ~FSDB_LOG_EMPTY;
597 server_make_name(mti->mti_flags, mti->mti_stripe_index,
598 mti->mti_fsname, mti->mti_svname);
600 CDEBUG(D_MGS, "Set index for %s to %d\n", mti->mti_svname,
601 mti->mti_stripe_index);
606 struct mgs_modify_lookup {
607 struct cfg_marker mml_marker;
611 static int mgs_modify_handler(struct llog_handle *llh, struct llog_rec_hdr *rec,
614 struct mgs_modify_lookup *mml = (struct mgs_modify_lookup *)data;
615 struct cfg_marker *marker;
616 struct lustre_cfg *lcfg = (struct lustre_cfg *)(rec + 1);
617 int cfg_len = rec->lrh_len - sizeof(struct llog_rec_hdr) -
618 sizeof(struct llog_rec_tail);
622 if (rec->lrh_type != OBD_CFG_REC) {
623 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
627 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
629 CERROR("Insane cfg\n");
633 /* We only care about markers */
634 if (lcfg->lcfg_command != LCFG_MARKER)
637 marker = lustre_cfg_buf(lcfg, 1);
638 if ((strcmp(mml->mml_marker.cm_comment, marker->cm_comment) == 0) &&
639 (strcmp(mml->mml_marker.cm_tgtname, marker->cm_tgtname) == 0) &&
640 !(marker->cm_flags & CM_SKIP)) {
641 /* Found a non-skipped marker match */
642 CDEBUG(D_MGS, "Changing rec %u marker %d %x->%x: %s %s\n",
643 rec->lrh_index, marker->cm_step,
644 marker->cm_flags, mml->mml_marker.cm_flags,
645 marker->cm_tgtname, marker->cm_comment);
646 /* Overwrite the old marker llog entry */
647 marker->cm_flags &= ~CM_EXCLUDE; /* in case we're unexcluding */
648 marker->cm_flags |= mml->mml_marker.cm_flags;
649 marker->cm_canceltime = mml->mml_marker.cm_canceltime;
650 /* Header and tail are added back to lrh_len in
651 llog_lvfs_write_rec */
652 rec->lrh_len = cfg_len;
653 rc = llog_write_rec(llh, rec, NULL, 0, (void *)lcfg,
662 /* Modify an existing config log record (for CM_SKIP or CM_EXCLUDE) */
663 static int mgs_modify(struct obd_device *obd, struct fs_db *fsdb,
664 struct mgs_target_info *mti, char *logname,
665 char *devname, char *comment, int flags)
667 struct llog_handle *loghandle;
668 struct lvfs_run_ctxt saved;
669 struct llog_ctxt *ctxt;
670 struct mgs_modify_lookup *mml;
674 CDEBUG(D_MGS, "modify %s/%s/%s\n", logname, devname, comment);
676 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
678 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
679 LASSERT(ctxt != NULL);
680 rc = llog_create(ctxt, &loghandle, NULL, logname);
684 rc = llog_init_handle(loghandle, LLOG_F_IS_PLAIN, NULL);
688 if (llog_get_size(loghandle) <= 1)
689 GOTO(out_close, rc = 0);
693 GOTO(out_close, rc = -ENOMEM);
694 strcpy(mml->mml_marker.cm_comment, comment);
695 strcpy(mml->mml_marker.cm_tgtname, devname);
696 /* Modify mostly means cancel */
697 mml->mml_marker.cm_flags = flags;
698 mml->mml_marker.cm_canceltime = flags ? cfs_time_current_sec() : 0;
699 mml->mml_modified = 0;
700 rc = llog_process(loghandle, mgs_modify_handler, (void *)mml, NULL);
701 if (!rc && !mml->mml_modified)
706 rc2 = llog_close(loghandle);
710 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
711 if (rc && rc != -ENODEV)
712 CERROR("modify %s/%s failed %d\n",
713 mti->mti_svname, comment, rc);
718 /******************** config log recording functions *********************/
720 static int record_lcfg(struct obd_device *obd, struct llog_handle *llh,
721 struct lustre_cfg *lcfg)
723 struct lvfs_run_ctxt saved;
724 struct llog_rec_hdr rec;
730 LASSERT(llh->lgh_ctxt);
732 buflen = lustre_cfg_len(lcfg->lcfg_bufcount,
734 rec.lrh_len = llog_data_len(buflen);
735 rec.lrh_type = OBD_CFG_REC;
737 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
738 /* idx = -1 means append */
739 rc = llog_write_rec(llh, &rec, NULL, 0, (void *)lcfg, -1);
740 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
742 CERROR("failed %d\n", rc);
746 static int record_base(struct obd_device *obd, struct llog_handle *llh,
747 char *cfgname, lnet_nid_t nid, int cmd,
748 char *s1, char *s2, char *s3, char *s4)
750 struct lustre_cfg_bufs bufs;
751 struct lustre_cfg *lcfg;
754 CDEBUG(D_MGS, "lcfg %s %#x %s %s %s %s\n", cfgname,
755 cmd, s1, s2, s3, s4);
757 lustre_cfg_bufs_reset(&bufs, cfgname);
759 lustre_cfg_bufs_set_string(&bufs, 1, s1);
761 lustre_cfg_bufs_set_string(&bufs, 2, s2);
763 lustre_cfg_bufs_set_string(&bufs, 3, s3);
765 lustre_cfg_bufs_set_string(&bufs, 4, s4);
767 lcfg = lustre_cfg_new(cmd, &bufs);
770 lcfg->lcfg_nid = nid;
772 rc = record_lcfg(obd, llh, lcfg);
774 lustre_cfg_free(lcfg);
777 CERROR("error %d: lcfg %s %#x %s %s %s %s\n", rc, cfgname,
778 cmd, s1, s2, s3, s4);
784 static inline int record_add_uuid(struct obd_device *obd,
785 struct llog_handle *llh,
786 uint64_t nid, char *uuid)
788 return record_base(obd,llh,NULL,nid,LCFG_ADD_UUID,uuid,0,0,0);
792 static inline int record_add_conn(struct obd_device *obd,
793 struct llog_handle *llh,
797 return record_base(obd,llh,devname,0,LCFG_ADD_CONN,uuid,0,0,0);
800 static inline int record_attach(struct obd_device *obd, struct llog_handle *llh,
801 char *devname, char *type, char *uuid)
803 return record_base(obd,llh,devname,0,LCFG_ATTACH,type,uuid,0,0);
806 static inline int record_setup(struct obd_device *obd, struct llog_handle *llh,
808 char *s1, char *s2, char *s3, char *s4)
810 return record_base(obd,llh,devname,0,LCFG_SETUP,s1,s2,s3,s4);
813 static int record_lov_setup(struct obd_device *obd, struct llog_handle *llh,
814 char *devname, struct lov_desc *desc)
816 struct lustre_cfg_bufs bufs;
817 struct lustre_cfg *lcfg;
820 lustre_cfg_bufs_reset(&bufs, devname);
821 lustre_cfg_bufs_set(&bufs, 1, desc, sizeof(*desc));
822 lcfg = lustre_cfg_new(LCFG_SETUP, &bufs);
825 rc = record_lcfg(obd, llh, lcfg);
827 lustre_cfg_free(lcfg);
831 static int record_lmv_setup(struct obd_device *obd, struct llog_handle *llh,
832 char *devname, struct lmv_desc *desc)
834 struct lustre_cfg_bufs bufs;
835 struct lustre_cfg *lcfg;
838 lustre_cfg_bufs_reset(&bufs, devname);
839 lustre_cfg_bufs_set(&bufs, 1, desc, sizeof(*desc));
840 lcfg = lustre_cfg_new(LCFG_SETUP, &bufs);
842 rc = record_lcfg(obd, llh, lcfg);
844 lustre_cfg_free(lcfg);
848 static inline int record_mdc_add(struct obd_device *obd,
849 struct llog_handle *llh,
850 char *logname, char *mdcuuid,
851 char *mdtuuid, char *index,
854 return record_base(obd,llh,logname,0,LCFG_ADD_MDC,
855 mdtuuid,index,gen,mdcuuid);
858 static inline int record_lov_add(struct obd_device *obd,
859 struct llog_handle *llh,
860 char *lov_name, char *ost_uuid,
861 char *index, char *gen)
863 return record_base(obd,llh,lov_name,0,LCFG_LOV_ADD_OBD,
864 ost_uuid,index,gen,0);
867 static inline int record_mount_opt(struct obd_device *obd,
868 struct llog_handle *llh,
869 char *profile, char *lov_name,
872 return record_base(obd,llh,NULL,0,LCFG_MOUNTOPT,
873 profile,lov_name,mdc_name,0);
876 static int record_marker(struct obd_device *obd, struct llog_handle *llh,
877 struct fs_db *fsdb, __u32 flags,
878 char *tgtname, char *comment)
880 struct cfg_marker marker;
881 struct lustre_cfg_bufs bufs;
882 struct lustre_cfg *lcfg;
885 if (flags & CM_START)
887 marker.cm_step = fsdb->fsdb_gen;
888 marker.cm_flags = flags;
889 marker.cm_vers = LUSTRE_VERSION_CODE;
890 strncpy(marker.cm_tgtname, tgtname, sizeof(marker.cm_tgtname));
891 strncpy(marker.cm_comment, comment, sizeof(marker.cm_comment));
892 marker.cm_createtime = cfs_time_current_sec();
893 marker.cm_canceltime = 0;
894 lustre_cfg_bufs_reset(&bufs, NULL);
895 lustre_cfg_bufs_set(&bufs, 1, &marker, sizeof(marker));
896 lcfg = lustre_cfg_new(LCFG_MARKER, &bufs);
899 rc = record_lcfg(obd, llh, lcfg);
901 lustre_cfg_free(lcfg);
905 static int record_start_log(struct obd_device *obd,
906 struct llog_handle **llh, char *name)
908 static struct obd_uuid cfg_uuid = { .uuid = "config_uuid" };
909 struct lvfs_run_ctxt saved;
910 struct llog_ctxt *ctxt;
914 GOTO(out, rc = -EBUSY);
916 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
918 GOTO(out, rc = -ENODEV);
920 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
921 rc = llog_create(ctxt, llh, NULL, name);
923 llog_init_handle(*llh, LLOG_F_IS_PLAIN, &cfg_uuid);
927 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
932 CERROR("Can't start log %s: %d\n", name, rc);
937 static int record_end_log(struct obd_device *obd, struct llog_handle **llh)
939 struct lvfs_run_ctxt saved;
942 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
944 rc = llog_close(*llh);
947 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
951 static int mgs_log_is_empty(struct obd_device *obd, char *name)
953 struct lvfs_run_ctxt saved;
954 struct llog_handle *llh;
955 struct llog_ctxt *ctxt;
958 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
959 LASSERT(ctxt != NULL);
960 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
961 rc = llog_create(ctxt, &llh, NULL, name);
963 llog_init_handle(llh, LLOG_F_IS_PLAIN, NULL);
964 rc = llog_get_size(llh);
967 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
969 /* header is record 1 */
973 /******************** config "macros" *********************/
975 /* write an lcfg directly into a log (with markers) */
976 static int mgs_write_log_direct(struct obd_device *obd, struct fs_db *fsdb,
977 char *logname, struct lustre_cfg *lcfg,
978 char *devname, char *comment)
980 struct llog_handle *llh = NULL;
987 rc = record_start_log(obd, &llh, logname);
991 /* FIXME These should be a single journal transaction */
992 rc = record_marker(obd, llh, fsdb, CM_START, devname, comment);
994 rc = record_lcfg(obd, llh, lcfg);
996 rc = record_marker(obd, llh, fsdb, CM_END, devname, comment);
997 rc = record_end_log(obd, &llh);
1002 /* write the lcfg in all logs for the given fs */
1003 int mgs_write_log_direct_all(struct obd_device *obd, struct fs_db *fsdb,
1004 struct mgs_target_info *mti,
1005 struct lustre_cfg *lcfg,
1006 char *devname, char *comment)
1008 struct mgs_obd *mgs = &obd->u.mgs;
1009 cfs_list_t dentry_list;
1010 struct l_linux_dirent *dirent, *n;
1011 char *fsname = mti->mti_fsname;
1013 int rc = 0, len = strlen(fsname);
1016 /* We need to set params for any future logs
1017 as well. FIXME Append this file to every new log.
1018 Actually, we should store as params (text), not llogs. Or
1020 name_create(&logname, fsname, "-params");
1021 if (mgs_log_is_empty(obd, logname)) {
1022 struct llog_handle *llh = NULL;
1023 rc = record_start_log(obd, &llh, logname);
1024 record_end_log(obd, &llh);
1026 name_destroy(&logname);
1030 /* Find all the logs in the CONFIGS directory */
1031 rc = class_dentry_readdir(obd, mgs->mgs_configs_dir,
1032 mgs->mgs_vfsmnt, &dentry_list);
1034 CERROR("Can't read %s dir\n", MOUNT_CONFIGS_DIR);
1038 /* Could use fsdb index maps instead of directory listing */
1039 cfs_list_for_each_entry_safe(dirent, n, &dentry_list, lld_list) {
1040 cfs_list_del(&dirent->lld_list);
1041 /* don't write to sptlrpc rule log */
1042 if (strncmp(fsname, dirent->lld_name, len) == 0 &&
1043 strstr(dirent->lld_name, "-sptlrpc") == NULL) {
1044 CDEBUG(D_MGS, "Changing log %s\n", dirent->lld_name);
1045 /* Erase any old settings of this same parameter */
1046 mgs_modify(obd, fsdb, mti, dirent->lld_name, devname,
1048 /* Write the new one */
1049 rc = mgs_write_log_direct(obd, fsdb, dirent->lld_name,
1050 lcfg, devname, comment);
1052 CERROR("err %d writing log %s\n", rc,
1055 OBD_FREE(dirent, sizeof(*dirent));
1063 struct mgs_target_info *comp_tmti;
1064 struct mgs_target_info *comp_mti;
1065 struct fs_db *comp_fsdb;
1066 struct obd_device *comp_obd;
1069 static int mgs_write_log_mdc_to_mdt(struct obd_device *, struct fs_db *,
1070 struct mgs_target_info *, char *);
1072 static int mgs_steal_llog_handler(struct llog_handle *llh,
1073 struct llog_rec_hdr *rec,
1076 struct obd_device * obd;
1077 struct mgs_target_info *mti, *tmti;
1079 int cfg_len = rec->lrh_len;
1080 char *cfg_buf = (char*) (rec + 1);
1081 struct lustre_cfg *lcfg;
1083 struct llog_handle *mdt_llh = NULL;
1084 static int got_an_osc_or_mdc = 0;
1085 /* 0: not found any osc/mdc;
1089 static int last_step = -1;
1093 mti = ((struct temp_comp*)data)->comp_mti;
1094 tmti = ((struct temp_comp*)data)->comp_tmti;
1095 fsdb = ((struct temp_comp*)data)->comp_fsdb;
1096 obd = ((struct temp_comp*)data)->comp_obd;
1098 if (rec->lrh_type != OBD_CFG_REC) {
1099 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
1103 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
1105 CERROR("Insane cfg\n");
1109 lcfg = (struct lustre_cfg *)cfg_buf;
1111 if (lcfg->lcfg_command == LCFG_MARKER) {
1112 struct cfg_marker *marker;
1113 marker = lustre_cfg_buf(lcfg, 1);
1114 if (!strncmp(marker->cm_comment,"add osc",7) &&
1115 (marker->cm_flags & CM_START)){
1116 got_an_osc_or_mdc = 1;
1117 rc = record_start_log(obd, &mdt_llh, mti->mti_svname);
1118 rc = record_marker(obd, mdt_llh, fsdb, CM_START,
1119 mti->mti_svname,"add osc(copied)");
1120 rc = record_end_log(obd, &mdt_llh);
1121 last_step = marker->cm_step;
1124 if (!strncmp(marker->cm_comment,"add osc",7) &&
1125 (marker->cm_flags & CM_END)){
1126 LASSERT(last_step == marker->cm_step);
1128 got_an_osc_or_mdc = 0;
1129 rc = record_start_log(obd, &mdt_llh, mti->mti_svname);
1130 rc = record_marker(obd, mdt_llh, fsdb, CM_END,
1131 mti->mti_svname,"add osc(copied)");
1132 rc = record_end_log(obd, &mdt_llh);
1135 if (!strncmp(marker->cm_comment,"add mdc",7) &&
1136 (marker->cm_flags & CM_START)){
1137 got_an_osc_or_mdc = 2;
1138 last_step = marker->cm_step;
1139 memcpy(tmti->mti_svname, marker->cm_tgtname,
1140 strlen(marker->cm_tgtname));
1144 if (!strncmp(marker->cm_comment,"add mdc",7) &&
1145 (marker->cm_flags & CM_END)){
1146 LASSERT(last_step == marker->cm_step);
1148 got_an_osc_or_mdc = 0;
1153 if (got_an_osc_or_mdc == 0 || last_step < 0)
1156 if (lcfg->lcfg_command == LCFG_ADD_UUID) {
1158 nodenid = lcfg->lcfg_nid;
1160 tmti->mti_nids[tmti->mti_nid_count] = nodenid;
1161 tmti->mti_nid_count++;
1166 if (lcfg->lcfg_command == LCFG_SETUP) {
1169 target = lustre_cfg_string(lcfg, 1);
1170 memcpy(tmti->mti_uuid, target, strlen(target));
1174 /* ignore client side sptlrpc_conf_log */
1175 if (lcfg->lcfg_command == LCFG_SPTLRPC_CONF)
1178 if (lcfg->lcfg_command == LCFG_ADD_MDC) {
1181 if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1)
1184 memcpy(tmti->mti_fsname, mti->mti_fsname,
1185 strlen(mti->mti_fsname));
1186 tmti->mti_stripe_index = index;
1188 mgs_write_log_mdc_to_mdt(obd, fsdb, tmti, mti->mti_svname);
1189 memset(tmti, 0, sizeof(*tmti));
1195 /* fsdb->fsdb_sem is already held in mgs_write_log_target*/
1196 /* stealed from mgs_get_fsdb_from_llog*/
1197 static int mgs_steal_llog_for_mdt_from_client(struct obd_device *obd,
1199 struct temp_comp* comp)
1201 struct llog_handle *loghandle;
1202 struct lvfs_run_ctxt saved;
1203 struct mgs_target_info *tmti;
1204 struct llog_ctxt *ctxt;
1208 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
1209 LASSERT(ctxt != NULL);
1211 OBD_ALLOC_PTR(tmti);
1215 comp->comp_tmti = tmti;
1216 comp->comp_obd = obd;
1218 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
1220 rc = llog_create(ctxt, &loghandle, NULL, client_name);
1224 rc = llog_init_handle(loghandle, LLOG_F_IS_PLAIN, NULL);
1226 GOTO(out_close, rc);
1228 rc = llog_process(loghandle, mgs_steal_llog_handler, (void *)comp, NULL);
1229 CDEBUG(D_MGS, "steal llog re = %d\n", rc);
1231 rc2 = llog_close(loghandle);
1235 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
1237 llog_ctxt_put(ctxt);
1241 /* lmv is the second thing for client logs */
1242 /* copied from mgs_write_log_lov. Please refer to that. */
1243 static int mgs_write_log_lmv(struct obd_device *obd, struct fs_db *fsdb,
1244 struct mgs_target_info *mti,
1245 char *logname, char *lmvname)
1247 struct llog_handle *llh = NULL;
1248 struct lmv_desc *lmvdesc;
1253 CDEBUG(D_MGS, "Writing lmv(%s) log for %s\n", lmvname,logname);
1255 OBD_ALLOC_PTR(lmvdesc);
1256 if (lmvdesc == NULL)
1258 lmvdesc->ld_active_tgt_count = 0;
1259 lmvdesc->ld_tgt_count = 0;
1260 sprintf((char*)lmvdesc->ld_uuid.uuid, "%s_UUID", lmvname);
1261 uuid = (char *)lmvdesc->ld_uuid.uuid;
1263 rc = record_start_log(obd, &llh, logname);
1264 rc = record_marker(obd, llh, fsdb, CM_START, lmvname, "lmv setup");
1265 rc = record_attach(obd, llh, lmvname, "lmv", uuid);
1266 rc = record_lmv_setup(obd, llh, lmvname, lmvdesc);
1267 rc = record_marker(obd, llh, fsdb, CM_END, lmvname, "lmv setup");
1268 rc = record_end_log(obd, &llh);
1270 OBD_FREE_PTR(lmvdesc);
1274 /* lov is the first thing in the mdt and client logs */
1275 static int mgs_write_log_lov(struct obd_device *obd, struct fs_db *fsdb,
1276 struct mgs_target_info *mti,
1277 char *logname, char *lovname)
1279 struct llog_handle *llh = NULL;
1280 struct lov_desc *lovdesc;
1285 CDEBUG(D_MGS, "Writing lov(%s) log for %s\n", lovname, logname);
1288 #01 L attach 0:lov_mdsA 1:lov 2:71ccb_lov_mdsA_19f961a9e1
1289 #02 L lov_setup 0:lov_mdsA 1:(struct lov_desc)
1290 uuid=lov1_UUID, stripe count=1, size=1048576, offset=0, pattern=0
1293 /* FIXME just make lov_setup accept empty desc (put uuid in buf 2) */
1294 OBD_ALLOC_PTR(lovdesc);
1295 if (lovdesc == NULL)
1297 lovdesc->ld_magic = LOV_DESC_MAGIC;
1298 lovdesc->ld_tgt_count = 0;
1299 /* Defaults. Can be changed later by lcfg config_param */
1300 lovdesc->ld_default_stripe_count = 1;
1301 lovdesc->ld_pattern = LOV_PATTERN_RAID0;
1302 lovdesc->ld_default_stripe_size = 1024 * 1024;
1303 lovdesc->ld_default_stripe_offset = 0;
1304 lovdesc->ld_qos_maxage = QOS_DEFAULT_MAXAGE;
1305 sprintf((char*)lovdesc->ld_uuid.uuid, "%s_UUID", lovname);
1306 /* can these be the same? */
1307 uuid = (char *)lovdesc->ld_uuid.uuid;
1309 /* This should always be the first entry in a log.
1310 rc = mgs_clear_log(obd, logname); */
1311 rc = record_start_log(obd, &llh, logname);
1314 /* FIXME these should be a single journal transaction */
1315 rc = record_marker(obd, llh, fsdb, CM_START, lovname, "lov setup");
1316 rc = record_attach(obd, llh, lovname, "lov", uuid);
1317 rc = record_lov_setup(obd, llh, lovname, lovdesc);
1318 rc = record_marker(obd, llh, fsdb, CM_END, lovname, "lov setup");
1319 rc = record_end_log(obd, &llh);
1323 OBD_FREE_PTR(lovdesc);
1327 /* add failnids to open log */
1328 static int mgs_write_log_failnids(struct obd_device *obd,
1329 struct mgs_target_info *mti,
1330 struct llog_handle *llh,
1333 char *failnodeuuid = NULL;
1334 char *ptr = mti->mti_params;
1339 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) nal=90 0: 1:uml1_UUID
1340 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
1341 #05 L setup 0:OSC_uml1_ost1_mdsA 1:ost1_UUID 2:uml1_UUID
1342 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) nal=90 0: 1:uml2_UUID
1343 #0x L add_uuid nid=2@elan(0x1000000000002) nal=90 0: 1:uml2_UUID
1344 #07 L add_conn 0:OSC_uml1_ost1_mdsA 1:uml2_UUID
1347 /* Pull failnid info out of params string */
1348 while (class_find_param(ptr, PARAM_FAILNODE, &ptr) == 0) {
1349 while (class_parse_nid(ptr, &nid, &ptr) == 0) {
1350 if (failnodeuuid == NULL) {
1351 /* We don't know the failover node name,
1352 so just use the first nid as the uuid */
1353 rc = name_create(&failnodeuuid,
1354 libcfs_nid2str(nid), "");
1358 CDEBUG(D_MGS, "add nid %s for failover uuid %s, "
1359 "client %s\n", libcfs_nid2str(nid),
1360 failnodeuuid, cliname);
1361 rc = record_add_uuid(obd, llh, nid, failnodeuuid);
1364 rc = record_add_conn(obd, llh, cliname, failnodeuuid);
1365 name_destroy(&failnodeuuid);
1366 failnodeuuid = NULL;
1373 static int mgs_write_log_mdc_to_lmv(struct obd_device *obd, struct fs_db *fsdb,
1374 struct mgs_target_info *mti,
1375 char *logname, char *lmvname)
1377 struct llog_handle *llh = NULL;
1378 char *mdcname, *nodeuuid, *mdcuuid, *lmvuuid;
1383 if (mgs_log_is_empty(obd, logname)) {
1384 CERROR("log is empty! Logical error\n");
1388 CDEBUG(D_MGS, "adding mdc for %s to log %s:lmv(%s)\n",
1389 mti->mti_svname, logname, lmvname);
1391 name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
1392 name_create(&mdcname, mti->mti_svname, "-mdc");
1393 name_create(&mdcuuid, mdcname, "_UUID");
1394 name_create(&lmvuuid, lmvname, "_UUID");
1396 rc = record_start_log(obd, &llh, logname);
1397 rc = record_marker(obd, llh, fsdb, CM_START, mti->mti_svname,
1400 for (i = 0; i < mti->mti_nid_count; i++) {
1401 CDEBUG(D_MGS, "add nid %s for mdt\n",
1402 libcfs_nid2str(mti->mti_nids[i]));
1404 rc = record_add_uuid(obd, llh, mti->mti_nids[i], nodeuuid);
1407 rc = record_attach(obd, llh, mdcname, LUSTRE_MDC_NAME, lmvuuid);
1408 rc = record_setup(obd, llh, mdcname, mti->mti_uuid, nodeuuid, 0, 0);
1409 rc = mgs_write_log_failnids(obd, mti, llh, mdcname);
1410 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
1411 rc = record_mdc_add(obd, llh, lmvname, mdcuuid, mti->mti_uuid,
1413 rc = record_marker(obd, llh, fsdb, CM_END, mti->mti_svname,
1415 rc = record_end_log(obd, &llh);
1417 name_destroy(&lmvuuid);
1418 name_destroy(&mdcuuid);
1419 name_destroy(&mdcname);
1420 name_destroy(&nodeuuid);
1424 /* add new mdc to already existent MDS */
1425 static int mgs_write_log_mdc_to_mdt(struct obd_device *obd, struct fs_db *fsdb,
1426 struct mgs_target_info *mti, char *logname)
1428 struct llog_handle *llh = NULL;
1429 char *nodeuuid, *mdcname, *mdcuuid, *mdtuuid;
1430 int idx = mti->mti_stripe_index;
1435 if (mgs_log_is_empty(obd, mti->mti_svname)) {
1436 CERROR("log is empty! Logical error\n");
1440 CDEBUG(D_MGS, "adding mdc index %d to %s\n", idx, logname);
1442 name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
1443 snprintf(index, sizeof(index), "-mdc%04x", idx);
1444 name_create(&mdcname, logname, index);
1445 name_create(&mdcuuid, mdcname, "_UUID");
1446 name_create(&mdtuuid, logname, "_UUID");
1448 rc = record_start_log(obd, &llh, logname);
1449 rc = record_marker(obd, llh, fsdb, CM_START, mti->mti_svname, "add mdc");
1450 for (i = 0; i < mti->mti_nid_count; i++) {
1451 CDEBUG(D_MGS, "add nid %s for mdt\n",
1452 libcfs_nid2str(mti->mti_nids[i]));
1453 rc = record_add_uuid(obd, llh, mti->mti_nids[i], nodeuuid);
1455 rc = record_attach(obd, llh, mdcname, LUSTRE_MDC_NAME, mdcuuid);
1456 rc = record_setup(obd, llh, mdcname, mti->mti_uuid, nodeuuid, 0, 0);
1457 rc = mgs_write_log_failnids(obd, mti, llh, mdcname);
1458 snprintf(index, sizeof(index), "%d", idx);
1460 rc = record_mdc_add(obd, llh, logname, mdcuuid, mti->mti_uuid,
1462 rc = record_marker(obd, llh, fsdb, CM_END, mti->mti_svname, "add mdc");
1463 rc = record_end_log(obd, &llh);
1465 name_destroy(&mdcuuid);
1466 name_destroy(&mdcname);
1467 name_destroy(&nodeuuid);
1468 name_destroy(&mdtuuid);
1472 static int mgs_write_log_mdt0(struct obd_device *obd, struct fs_db *fsdb,
1473 struct mgs_target_info *mti)
1475 char *log = mti->mti_svname;
1476 struct llog_handle *llh = NULL;
1477 char *uuid, *lovname;
1479 char *ptr = mti->mti_params;
1480 int rc = 0, failout = 0;
1483 OBD_ALLOC(uuid, sizeof(struct obd_uuid));
1487 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
1488 failout = (strncmp(ptr, "failout", 7) == 0);
1490 name_create(&lovname, log, "-mdtlov");
1491 if (mgs_log_is_empty(obd, log))
1492 rc = mgs_write_log_lov(obd, fsdb, mti, log, lovname);
1494 sprintf(uuid, "%s_UUID", log);
1495 sprintf(mdt_index, "%d", mti->mti_stripe_index);
1497 /* add MDT itself */
1498 rc = record_start_log(obd, &llh, log);
1502 /* FIXME this whole fn should be a single journal transaction */
1503 rc = record_marker(obd, llh, fsdb, CM_START, log, "add mdt");
1504 rc = record_attach(obd, llh, log, LUSTRE_MDT_NAME, uuid);
1505 rc = record_mount_opt(obd, llh, log, lovname, NULL);
1506 rc = record_setup(obd, llh, log, uuid, mdt_index, lovname,
1507 failout ? "n" : "f");
1508 rc = record_marker(obd, llh, fsdb, CM_END, log, "add mdt");
1509 rc = record_end_log(obd, &llh);
1511 name_destroy(&lovname);
1512 OBD_FREE(uuid, sizeof(struct obd_uuid));
1516 static inline void name_create_mdt(char **logname, char *fsname, int i)
1520 sprintf(mdt_index, "-MDT%04x", i);
1521 name_create(logname, fsname, mdt_index);
1524 static void name_create_mdt_and_lov(char **logname, char **lovname,
1525 struct fs_db *fsdb, int i)
1527 name_create_mdt(logname, fsdb->fsdb_name, i);
1529 if (i == 0 && fsdb->fsdb_fl_oscname_18)
1530 name_create(lovname, fsdb->fsdb_name, "-mdtlov");
1532 name_create(lovname, *logname, "-mdtlov");
1535 static inline void name_create_mdt_osc(char **oscname, char *ostname,
1536 struct fs_db *fsdb, int i)
1540 if (i == 0 && fsdb->fsdb_fl_oscname_18)
1541 sprintf(suffix, "-osc");
1543 sprintf(suffix, "-osc-MDT%04x", i);
1544 name_create(oscname, ostname, suffix);
1547 /* envelope method for all layers log */
1548 static int mgs_write_log_mdt(struct obd_device *obd, struct fs_db *fsdb,
1549 struct mgs_target_info *mti)
1551 struct llog_handle *llh = NULL;
1553 struct temp_comp comp = { 0 };
1557 CDEBUG(D_MGS, "writing new mdt %s\n", mti->mti_svname);
1561 if (mti->mti_flags & LDD_F_UPGRADE14) {
1562 /* We're starting with an old uuid. Assume old name for lov
1563 as well since the lov entry already exists in the log. */
1564 CDEBUG(D_MGS, "old mds uuid %s\n", mti->mti_uuid);
1565 if (strncmp(mti->mti_uuid, fsdb->fsdb_mdtlov + 4,
1566 strlen(fsdb->fsdb_mdtlov) - 4) != 0) {
1567 CERROR("old mds uuid %s doesn't match log %s (%s)\n",
1568 mti->mti_uuid, fsdb->fsdb_mdtlov,
1569 fsdb->fsdb_mdtlov + 4);
1573 /* end COMPAT_146 */
1575 if (mti->mti_uuid[0] == '\0') {
1576 /* Make up our own uuid */
1577 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
1578 "%s_UUID", mti->mti_svname);
1582 rc = mgs_write_log_mdt0(obd, fsdb, mti);
1584 /* Append the mdt info to the client log */
1585 name_create(&cliname, mti->mti_fsname, "-client");
1587 if (mgs_log_is_empty(obd, cliname)) {
1588 /* Start client log */
1589 rc = mgs_write_log_lov(obd, fsdb, mti, cliname,
1591 rc = mgs_write_log_lmv(obd, fsdb, mti, cliname,
1596 #09 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
1597 #10 L attach 0:MDC_uml1_mdsA_MNT_client 1:mdc 2:1d834_MNT_client_03f
1598 #11 L setup 0:MDC_uml1_mdsA_MNT_client 1:mdsA_UUID 2:uml1_UUID
1599 #12 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
1600 #13 L add_conn 0:MDC_uml1_mdsA_MNT_client 1:uml2_UUID
1601 #14 L mount_option 0: 1:client 2:lov1 3:MDC_uml1_mdsA_MNT_client
1606 if (mti->mti_flags & LDD_F_UPGRADE14) {
1607 rc = record_start_log(obd, &llh, cliname);
1611 rc = record_marker(obd, llh, fsdb, CM_START,
1612 mti->mti_svname,"add mdc");
1614 /* Old client log already has MDC entry, but needs mount opt
1615 for new client name (lustre-client) */
1616 /* FIXME Old MDT log already has an old mount opt
1617 which we should remove (currently handled by
1618 class_del_profiles()) */
1619 rc = record_mount_opt(obd, llh, cliname, fsdb->fsdb_clilov,
1621 /* end COMPAT_146 */
1623 rc = record_marker(obd, llh, fsdb, CM_END,
1624 mti->mti_svname, "add mdc");
1628 /* copy client info about lov/lmv */
1629 comp.comp_mti = mti;
1630 comp.comp_fsdb = fsdb;
1632 rc = mgs_steal_llog_for_mdt_from_client(obd, cliname,
1635 rc = mgs_write_log_mdc_to_lmv(obd, fsdb, mti, cliname,
1638 rc = record_start_log(obd, &llh, cliname);
1642 rc = record_marker(obd, llh, fsdb, CM_START, cliname,
1644 rc = record_mount_opt(obd, llh, cliname, fsdb->fsdb_clilov,
1646 rc = record_marker(obd, llh, fsdb, CM_END, cliname,
1650 rc = record_end_log(obd, &llh);
1652 name_destroy(&cliname);
1654 // for_all_existing_mdt except current one
1655 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
1657 if (i != mti->mti_stripe_index &&
1658 cfs_test_bit(i, fsdb->fsdb_mdt_index_map)) {
1659 name_create_mdt(&mdtname, mti->mti_fsname, i);
1660 rc = mgs_write_log_mdc_to_mdt(obd, fsdb, mti, mdtname);
1661 name_destroy(&mdtname);
1668 /* Add the ost info to the client/mdt lov */
1669 static int mgs_write_log_osc_to_lov(struct obd_device *obd, struct fs_db *fsdb,
1670 struct mgs_target_info *mti,
1671 char *logname, char *suffix, char *lovname,
1672 enum lustre_sec_part sec_part, int flags)
1674 struct llog_handle *llh = NULL;
1675 char *nodeuuid, *oscname, *oscuuid, *lovuuid, *svname;
1680 CDEBUG(D_INFO, "adding osc for %s to log %s\n",
1681 mti->mti_svname, logname);
1683 if (mgs_log_is_empty(obd, logname)) {
1684 /* The first item in the log must be the lov, so we have
1685 somewhere to add our osc. */
1686 rc = mgs_write_log_lov(obd, fsdb, mti, logname, lovname);
1689 name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
1690 name_create(&svname, mti->mti_svname, "-osc");
1691 name_create(&oscname, svname, suffix);
1692 name_create(&oscuuid, oscname, "_UUID");
1693 name_create(&lovuuid, lovname, "_UUID");
1696 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
1698 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
1699 #04 L attach 0:OSC_uml1_ost1_MNT_client 1:osc 2:89070_lov1_a41dff51a
1700 #05 L setup 0:OSC_uml1_ost1_MNT_client 1:ost1_UUID 2:uml1_UUID
1702 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
1703 #07 L add_conn 0:OSC_uml1_ost1_MNT_client 1:uml2_UUID
1704 #08 L lov_modify_tgts add 0:lov1 1:ost1_UUID 2(index):0 3(gen):1
1707 rc = record_start_log(obd, &llh, logname);
1710 /* FIXME these should be a single journal transaction */
1711 rc = record_marker(obd, llh, fsdb, CM_START | flags, mti->mti_svname,
1713 for (i = 0; i < mti->mti_nid_count; i++) {
1714 CDEBUG(D_MGS, "add nid %s\n", libcfs_nid2str(mti->mti_nids[i]));
1715 rc = record_add_uuid(obd, llh, mti->mti_nids[i], nodeuuid);
1717 rc = record_attach(obd, llh, oscname, LUSTRE_OSC_NAME, lovuuid);
1718 rc = record_setup(obd, llh, oscname, mti->mti_uuid, nodeuuid, 0, 0);
1719 rc = mgs_write_log_failnids(obd, mti, llh, oscname);
1720 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
1721 rc = record_lov_add(obd, llh, lovname, mti->mti_uuid, index, "1");
1722 rc = record_marker(obd, llh, fsdb, CM_END | flags, mti->mti_svname,
1724 rc = record_end_log(obd, &llh);
1726 name_destroy(&lovuuid);
1727 name_destroy(&oscuuid);
1728 name_destroy(&oscname);
1729 name_destroy(&svname);
1730 name_destroy(&nodeuuid);
1734 static int mgs_write_log_ost(struct obd_device *obd, struct fs_db *fsdb,
1735 struct mgs_target_info *mti)
1737 struct llog_handle *llh = NULL;
1738 char *logname, *lovname;
1739 char *ptr = mti->mti_params;
1740 int rc, flags = 0, failout = 0, i;
1743 CDEBUG(D_MGS, "writing new ost %s\n", mti->mti_svname);
1745 /* The ost startup log */
1747 /* If the ost log already exists, that means that someone reformatted
1748 the ost and it called target_add again. */
1749 if (!mgs_log_is_empty(obd, mti->mti_svname)) {
1750 LCONSOLE_ERROR_MSG(0x141, "The config log for %s already "
1751 "exists, yet the server claims it never "
1752 "registered. It may have been reformatted, "
1753 "or the index changed. writeconf the MDT to "
1754 "regenerate all logs.\n", mti->mti_svname);
1759 attach obdfilter ost1 ost1_UUID
1760 setup /dev/loop2 ldiskfs f|n errors=remount-ro,user_xattr
1762 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
1763 failout = (strncmp(ptr, "failout", 7) == 0);
1764 rc = record_start_log(obd, &llh, mti->mti_svname);
1767 /* FIXME these should be a single journal transaction */
1768 rc = record_marker(obd, llh, fsdb, CM_START, mti->mti_svname,"add ost");
1769 if (*mti->mti_uuid == '\0')
1770 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
1771 "%s_UUID", mti->mti_svname);
1772 rc = record_attach(obd, llh, mti->mti_svname,
1773 "obdfilter"/*LUSTRE_OST_NAME*/, mti->mti_uuid);
1774 rc = record_setup(obd, llh, mti->mti_svname,
1775 "dev"/*ignored*/, "type"/*ignored*/,
1776 failout ? "n" : "f", 0/*options*/);
1777 rc = record_marker(obd, llh, fsdb, CM_END, mti->mti_svname, "add ost");
1778 rc = record_end_log(obd, &llh);
1780 /* We also have to update the other logs where this osc is part of
1783 if (fsdb->fsdb_flags & FSDB_OLDLOG14) {
1784 /* If we're upgrading, the old mdt log already has our
1785 entry. Let's do a fake one for fun. */
1786 /* Note that we can't add any new failnids, since we don't
1787 know the old osc names. */
1788 flags = CM_SKIP | CM_UPGRADE146;
1790 } else if ((mti->mti_flags & LDD_F_UPDATE) != LDD_F_UPDATE) {
1791 /* If the update flag isn't set, don't update client/mdt
1794 LCONSOLE_WARN("Client log for %s was not updated; writeconf "
1795 "the MDT first to regenerate it.\n",
1799 /* Add ost to all MDT lov defs */
1800 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
1801 if (cfs_test_bit(i, fsdb->fsdb_mdt_index_map)) {
1804 name_create_mdt_and_lov(&logname, &lovname, fsdb, i);
1805 sprintf(mdt_index, "-MDT%04x", i);
1806 mgs_write_log_osc_to_lov(obd, fsdb, mti, logname,
1808 LUSTRE_SP_MDT, flags);
1809 name_destroy(&logname);
1810 name_destroy(&lovname);
1814 /* Append ost info to the client log */
1815 name_create(&logname, mti->mti_fsname, "-client");
1816 mgs_write_log_osc_to_lov(obd, fsdb, mti, logname, "",
1817 fsdb->fsdb_clilov, LUSTRE_SP_CLI, 0);
1818 name_destroy(&logname);
1822 /* Add additional failnids to an existing log.
1823 The mdc/osc must have been added to logs first */
1824 /* tcp nids must be in dotted-quad ascii -
1825 we can't resolve hostnames from the kernel. */
1826 static int mgs_write_log_add_failnid(struct obd_device *obd, struct fs_db *fsdb,
1827 struct mgs_target_info *mti)
1829 char *logname, *cliname;
1830 struct llog_handle *llh = NULL;
1834 /* FIXME how do we delete a failnid? Currently --writeconf is the
1835 only way. Maybe make --erase-params pass a flag to really
1836 erase all params from logs - except it can't erase the failnids
1837 given when a target first registers, since they aren't processed
1840 /* Verify that we know about this target */
1841 if (mgs_log_is_empty(obd, mti->mti_svname)) {
1842 LCONSOLE_ERROR_MSG(0x142, "The target %s has not registered "
1843 "yet. It must be started before failnids "
1844 "can be added.\n", mti->mti_svname);
1848 /* Create mdc/osc client name (e.g. lustre-OST0001-osc) */
1849 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
1850 name_create(&cliname, mti->mti_svname, "-mdc");
1851 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
1852 name_create(&cliname, mti->mti_svname, "-osc");
1857 /* Add failover nids to client log */
1858 name_create(&logname, mti->mti_fsname, "-client");
1859 rc = record_start_log(obd, &llh, logname);
1861 /* FIXME this fn should be a single journal transaction */
1862 rc = record_marker(obd, llh, fsdb, CM_START, mti->mti_svname,
1864 rc = mgs_write_log_failnids(obd, mti, llh, cliname);
1865 rc = record_marker(obd, llh, fsdb, CM_END, mti->mti_svname,
1867 rc = record_end_log(obd, &llh);
1869 name_destroy(&logname);
1870 name_destroy(&cliname);
1872 if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
1873 /* Add OST failover nids to the MDT logs as well */
1876 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
1877 if (!cfs_test_bit(i, fsdb->fsdb_mdt_index_map))
1879 name_create_mdt(&logname, mti->mti_fsname, i);
1880 name_create_mdt_osc(&cliname, mti->mti_svname, fsdb, i);
1882 rc = record_start_log(obd, &llh, logname);
1884 rc = record_marker(obd, llh, fsdb, CM_START,
1887 rc = mgs_write_log_failnids(obd, mti, llh,
1889 rc = record_marker(obd, llh, fsdb, CM_END,
1892 rc = record_end_log(obd, &llh);
1894 name_destroy(&cliname);
1895 name_destroy(&logname);
1902 static int mgs_wlp_lcfg(struct obd_device *obd, struct fs_db *fsdb,
1903 struct mgs_target_info *mti,
1904 char *logname, struct lustre_cfg_bufs *bufs,
1905 char *tgtname, char *ptr)
1907 char comment[MTI_NAME_MAXLEN];
1909 struct lustre_cfg *lcfg;
1912 /* Erase any old settings of this same parameter */
1913 memcpy(comment, ptr, MTI_NAME_MAXLEN);
1914 comment[MTI_NAME_MAXLEN - 1] = 0;
1915 /* But don't try to match the value. */
1916 if ((tmp = strchr(comment, '=')))
1918 /* FIXME we should skip settings that are the same as old values */
1919 rc = mgs_modify(obd, fsdb, mti, logname, tgtname, comment, CM_SKIP);
1920 LCONSOLE_INFO("%sing parameter %s.%s in log %s\n", rc ?
1921 "Sett" : "Modify", tgtname, comment, logname);
1923 lustre_cfg_bufs_reset(bufs, tgtname);
1924 lustre_cfg_bufs_set_string(bufs, 1, ptr);
1925 lcfg = lustre_cfg_new(LCFG_PARAM, bufs);
1928 rc = mgs_write_log_direct(obd, fsdb, logname, lcfg, tgtname, comment);
1929 lustre_cfg_free(lcfg);
1933 /* write global variable settings into log */
1934 static int mgs_write_log_sys(struct obd_device *obd, struct fs_db *fsdb,
1935 struct mgs_target_info *mti, char *sys, char *ptr)
1937 struct lustre_cfg_bufs bufs;
1938 struct lustre_cfg *lcfg;
1943 if (class_match_param(ptr, PARAM_TIMEOUT, &tmp) == 0)
1944 cmd = LCFG_SET_TIMEOUT;
1945 else if (class_match_param(ptr, PARAM_LDLM_TIMEOUT, &tmp) == 0)
1946 cmd = LCFG_SET_LDLM_TIMEOUT;
1947 /* Check for known params here so we can return error to lctl */
1948 else if ((class_match_param(ptr, PARAM_AT_MIN, &tmp) == 0)
1949 || (class_match_param(ptr, PARAM_AT_MAX, &tmp) == 0)
1950 || (class_match_param(ptr, PARAM_AT_EXTRA, &tmp) == 0)
1951 || (class_match_param(ptr, PARAM_AT_EARLY_MARGIN, &tmp) == 0)
1952 || (class_match_param(ptr, PARAM_AT_HISTORY, &tmp) == 0))
1957 val = simple_strtoul(tmp, NULL, 0);
1958 CDEBUG(D_MGS, "global %s = %d\n", ptr, val);
1960 lustre_cfg_bufs_reset(&bufs, NULL);
1961 lustre_cfg_bufs_set_string(&bufs, 1, sys);
1962 lcfg = lustre_cfg_new(cmd, &bufs);
1963 lcfg->lcfg_num = val;
1964 /* modify all servers and clients */
1965 rc = mgs_write_log_direct_all(obd, fsdb, mti, lcfg, mti->mti_fsname,
1967 lustre_cfg_free(lcfg);
1971 static int mgs_srpc_set_param_disk(struct obd_device *obd,
1973 struct mgs_target_info *mti,
1976 struct llog_handle *llh = NULL;
1978 char *comment, *ptr;
1979 struct lustre_cfg_bufs bufs;
1980 struct lustre_cfg *lcfg;
1985 ptr = strchr(param, '=');
1989 OBD_ALLOC(comment, len + 1);
1990 if (comment == NULL)
1992 strncpy(comment, param, len);
1993 comment[len] = '\0';
1996 lustre_cfg_bufs_reset(&bufs, mti->mti_svname);
1997 lustre_cfg_bufs_set_string(&bufs, 1, param);
1998 lcfg = lustre_cfg_new(LCFG_SPTLRPC_CONF, &bufs);
2000 GOTO(out_comment, rc = -ENOMEM);
2002 /* construct log name */
2003 rc = name_create(&logname, mti->mti_fsname, "-sptlrpc");
2007 if (mgs_log_is_empty(obd, logname)) {
2008 rc = record_start_log(obd, &llh, logname);
2009 record_end_log(obd, &llh);
2014 /* obsolete old one */
2015 mgs_modify(obd, fsdb, mti, logname, mti->mti_svname, comment, CM_SKIP);
2017 /* write the new one */
2018 rc = mgs_write_log_direct(obd, fsdb, logname, lcfg,
2019 mti->mti_svname, comment);
2021 CERROR("err %d writing log %s\n", rc, logname);
2024 name_destroy(&logname);
2026 lustre_cfg_free(lcfg);
2028 OBD_FREE(comment, len + 1);
2032 static int mgs_srpc_set_param_udesc_mem(struct fs_db *fsdb,
2037 /* disable the adjustable udesc parameter for now, i.e. use default
2038 * setting that client always ship udesc to MDT if possible. to enable
2039 * it simply remove the following line */
2042 ptr = strchr(param, '=');
2047 if (strcmp(param, PARAM_SRPC_UDESC))
2050 if (strcmp(ptr, "yes") == 0) {
2051 fsdb->fsdb_fl_udesc = 1;
2052 CWARN("Enable user descriptor shipping from client to MDT\n");
2053 } else if (strcmp(ptr, "no") == 0) {
2054 fsdb->fsdb_fl_udesc = 0;
2055 CWARN("Disable user descriptor shipping from client to MDT\n");
2063 CERROR("Invalid param: %s\n", param);
2067 static int mgs_srpc_set_param_mem(struct fs_db *fsdb,
2071 struct sptlrpc_rule rule;
2072 struct sptlrpc_rule_set *rset;
2076 if (strncmp(param, PARAM_SRPC, sizeof(PARAM_SRPC) - 1) != 0) {
2077 CERROR("Invalid sptlrpc parameter: %s\n", param);
2081 if (strncmp(param, PARAM_SRPC_UDESC,
2082 sizeof(PARAM_SRPC_UDESC) - 1) == 0) {
2083 RETURN(mgs_srpc_set_param_udesc_mem(fsdb, param));
2086 if (strncmp(param, PARAM_SRPC_FLVR, sizeof(PARAM_SRPC_FLVR) - 1) != 0) {
2087 CERROR("Invalid sptlrpc flavor parameter: %s\n", param);
2091 param += sizeof(PARAM_SRPC_FLVR) - 1;
2093 rc = sptlrpc_parse_rule(param, &rule);
2097 /* mgs rules implies must be mgc->mgs */
2098 if (fsdb->fsdb_fl_mgsself) {
2099 if ((rule.sr_from != LUSTRE_SP_MGC &&
2100 rule.sr_from != LUSTRE_SP_ANY) ||
2101 (rule.sr_to != LUSTRE_SP_MGS &&
2102 rule.sr_to != LUSTRE_SP_ANY))
2106 /* preapre room for this coming rule. svcname format should be:
2107 * - fsname: general rule
2108 * - fsname-tgtname: target-specific rule
2110 if (strchr(svname, '-')) {
2111 struct mgs_tgt_srpc_conf *tgtconf;
2114 for (tgtconf = fsdb->fsdb_srpc_tgt; tgtconf != NULL;
2115 tgtconf = tgtconf->mtsc_next) {
2116 if (!strcmp(tgtconf->mtsc_tgt, svname)) {
2125 OBD_ALLOC_PTR(tgtconf);
2126 if (tgtconf == NULL)
2129 name_len = strlen(svname);
2131 OBD_ALLOC(tgtconf->mtsc_tgt, name_len + 1);
2132 if (tgtconf->mtsc_tgt == NULL) {
2133 OBD_FREE_PTR(tgtconf);
2136 memcpy(tgtconf->mtsc_tgt, svname, name_len);
2138 tgtconf->mtsc_next = fsdb->fsdb_srpc_tgt;
2139 fsdb->fsdb_srpc_tgt = tgtconf;
2142 rset = &tgtconf->mtsc_rset;
2144 rset = &fsdb->fsdb_srpc_gen;
2147 rc = sptlrpc_rule_set_merge(rset, &rule);
2152 static int mgs_srpc_set_param(struct obd_device *obd,
2154 struct mgs_target_info *mti,
2164 /* keep a copy of original param, which could be destroied
2166 copy_size = strlen(param) + 1;
2167 OBD_ALLOC(copy, copy_size);
2170 memcpy(copy, param, copy_size);
2172 rc = mgs_srpc_set_param_mem(fsdb, mti->mti_svname, param);
2176 /* previous steps guaranteed the syntax is correct */
2177 rc = mgs_srpc_set_param_disk(obd, fsdb, mti, copy);
2181 if (fsdb->fsdb_fl_mgsself) {
2183 * for mgs rules, make them effective immediately.
2185 LASSERT(fsdb->fsdb_srpc_tgt == NULL);
2186 sptlrpc_target_update_exp_flavor(obd, &fsdb->fsdb_srpc_gen);
2190 OBD_FREE(copy, copy_size);
2194 struct mgs_srpc_read_data {
2195 struct fs_db *msrd_fsdb;
2199 static int mgs_srpc_read_handler(struct llog_handle *llh,
2200 struct llog_rec_hdr *rec,
2203 struct mgs_srpc_read_data *msrd = (struct mgs_srpc_read_data *) data;
2204 struct cfg_marker *marker;
2205 struct lustre_cfg *lcfg = (struct lustre_cfg *)(rec + 1);
2206 char *svname, *param;
2210 if (rec->lrh_type != OBD_CFG_REC) {
2211 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
2215 cfg_len = rec->lrh_len - sizeof(struct llog_rec_hdr) -
2216 sizeof(struct llog_rec_tail);
2218 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
2220 CERROR("Insane cfg\n");
2224 if (lcfg->lcfg_command == LCFG_MARKER) {
2225 marker = lustre_cfg_buf(lcfg, 1);
2227 if (marker->cm_flags & CM_START &&
2228 marker->cm_flags & CM_SKIP)
2229 msrd->msrd_skip = 1;
2230 if (marker->cm_flags & CM_END)
2231 msrd->msrd_skip = 0;
2236 if (msrd->msrd_skip)
2239 if (lcfg->lcfg_command != LCFG_SPTLRPC_CONF) {
2240 CERROR("invalid command (%x)\n", lcfg->lcfg_command);
2244 svname = lustre_cfg_string(lcfg, 0);
2245 if (svname == NULL) {
2246 CERROR("svname is empty\n");
2250 param = lustre_cfg_string(lcfg, 1);
2251 if (param == NULL) {
2252 CERROR("param is empty\n");
2256 rc = mgs_srpc_set_param_mem(msrd->msrd_fsdb, svname, param);
2258 CERROR("read sptlrpc record error (%d): %s\n", rc, param);
2263 int mgs_get_fsdb_srpc_from_llog(struct obd_device *obd,
2266 struct llog_handle *llh = NULL;
2267 struct lvfs_run_ctxt saved;
2268 struct llog_ctxt *ctxt;
2270 struct mgs_srpc_read_data msrd;
2274 /* construct log name */
2275 rc = name_create(&logname, fsdb->fsdb_name, "-sptlrpc");
2279 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
2280 LASSERT(ctxt != NULL);
2282 if (mgs_log_is_empty(obd, logname))
2285 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
2287 rc = llog_create(ctxt, &llh, NULL, logname);
2291 rc = llog_init_handle(llh, LLOG_F_IS_PLAIN, NULL);
2293 GOTO(out_close, rc);
2295 if (llog_get_size(llh) <= 1)
2296 GOTO(out_close, rc = 0);
2298 msrd.msrd_fsdb = fsdb;
2301 rc = llog_process(llh, mgs_srpc_read_handler, (void *) &msrd, NULL);
2306 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
2308 llog_ctxt_put(ctxt);
2309 name_destroy(&logname);
2312 CERROR("failed to read sptlrpc config database: %d\n", rc);
2316 static int mgs_write_log_param(struct obd_device *obd, struct fs_db *fsdb,
2317 struct mgs_target_info *mti, char *ptr)
2319 struct lustre_cfg_bufs bufs;
2325 /* For various parameter settings, we have to figure out which logs
2326 care about them (e.g. both mdt and client for lov settings) */
2327 CDEBUG(D_MGS, "next param '%s'\n", ptr);
2329 /* The params are stored in MOUNT_DATA_FILE and modified via
2330 tunefs.lustre, or set using lctl conf_param */
2332 /* Processed in lustre_start_mgc */
2333 if (class_match_param(ptr, PARAM_MGSNODE, NULL) == 0)
2336 /* Processed in mgs_write_log_ost */
2337 if (class_match_param(ptr, PARAM_FAILMODE, NULL) == 0) {
2338 if (mti->mti_flags & LDD_F_PARAM) {
2339 LCONSOLE_ERROR_MSG(0x169, "%s can only be "
2340 "changed with tunefs.lustre"
2341 "and --writeconf\n", ptr);
2347 if (class_match_param(ptr, PARAM_SRPC, NULL) == 0) {
2348 rc = mgs_srpc_set_param(obd, fsdb, mti, ptr);
2352 if (class_match_param(ptr, PARAM_FAILNODE, NULL) == 0) {
2353 /* Add a failover nidlist */
2355 /* We already processed failovers params for new
2356 targets in mgs_write_log_target */
2357 if (mti->mti_flags & LDD_F_PARAM) {
2358 CDEBUG(D_MGS, "Adding failnode\n");
2359 rc = mgs_write_log_add_failnid(obd, fsdb, mti);
2364 if (class_match_param(ptr, PARAM_SYS, &tmp) == 0) {
2365 rc = mgs_write_log_sys(obd, fsdb, mti, ptr, tmp);
2369 if (class_match_param(ptr, PARAM_OSC""PARAM_ACTIVE, &tmp) == 0) {
2370 /* active=0 means off, anything else means on */
2371 int flag = (*tmp == '0') ? CM_EXCLUDE : 0;
2374 if (!(mti->mti_flags & LDD_F_SV_TYPE_OST)) {
2375 LCONSOLE_ERROR_MSG(0x144, "%s: Only OSCs can "
2376 "be (de)activated.\n",
2378 GOTO(end, rc = -EINVAL);
2380 LCONSOLE_WARN("Permanently %sactivating %s\n",
2381 flag ? "de": "re", mti->mti_svname);
2383 name_create(&logname, mti->mti_fsname, "-client");
2384 rc = mgs_modify(obd, fsdb, mti, logname,
2385 mti->mti_svname, "add osc", flag);
2386 name_destroy(&logname);
2390 /* Add to all MDT logs for CMD */
2391 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2392 if (!cfs_test_bit(i, fsdb->fsdb_mdt_index_map))
2394 name_create_mdt(&logname, mti->mti_fsname, i);
2395 rc = mgs_modify(obd, fsdb, mti, logname,
2396 mti->mti_svname, "add osc", flag);
2397 name_destroy(&logname);
2403 LCONSOLE_ERROR_MSG(0x145, "Couldn't find %s in"
2404 "log (%d). No permanent "
2405 "changes were made to the "
2407 mti->mti_svname, rc);
2408 if (fsdb->fsdb_flags & FSDB_OLDLOG14)
2409 LCONSOLE_ERROR_MSG(0x146, "This may be"
2414 "update the logs.\n");
2417 /* Fall through to osc proc for deactivating live OSC
2418 on running MDT / clients. */
2420 /* Below here, let obd's XXX_process_config methods handle it */
2422 /* All lov. in proc */
2423 if (class_match_param(ptr, PARAM_LOV, NULL) == 0) {
2426 CDEBUG(D_MGS, "lov param %s\n", ptr);
2427 if (!(mti->mti_flags & LDD_F_SV_TYPE_MDT)) {
2428 LCONSOLE_ERROR_MSG(0x147, "LOV params must be "
2429 "set on the MDT, not %s. "
2436 if (mgs_log_is_empty(obd, mti->mti_svname))
2437 GOTO(end, rc = -ENODEV);
2439 name_create_mdt_and_lov(&logname, &mdtlovname, fsdb,
2440 mti->mti_stripe_index);
2441 rc = mgs_wlp_lcfg(obd, fsdb, mti, mti->mti_svname,
2442 &bufs, mdtlovname, ptr);
2443 name_destroy(&logname);
2444 name_destroy(&mdtlovname);
2449 name_create(&logname, mti->mti_fsname, "-client");
2450 rc = mgs_wlp_lcfg(obd, fsdb, mti, logname, &bufs,
2451 fsdb->fsdb_clilov, ptr);
2452 name_destroy(&logname);
2456 /* All osc., mdc., llite. params in proc */
2457 if ((class_match_param(ptr, PARAM_OSC, NULL) == 0) ||
2458 (class_match_param(ptr, PARAM_MDC, NULL) == 0) ||
2459 (class_match_param(ptr, PARAM_LLITE, NULL) == 0)) {
2461 if (memcmp(ptr, PARAM_LLITE, strlen(PARAM_LLITE)) == 0) {
2462 name_create(&cname, mti->mti_fsname, "-client");
2463 /* Add the client type to match the obdname in
2464 class_config_llog_handler */
2465 } else if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
2468 name_create(&cname, fsdb->fsdb_mdc, "");
2470 name_create(&cname, mti->mti_svname,
2472 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2474 if (fsdb->fsdb_flags & FSDB_OLDLOG14) {
2475 LCONSOLE_ERROR_MSG(0x148, "Upgraded "
2476 "client logs for %s"
2478 "modified. Consider"
2480 "configuration with"
2483 /* We don't know the names of all the
2485 GOTO(end, rc = -EINVAL);
2487 name_create(&cname, mti->mti_svname, "-osc");
2489 GOTO(end, rc = -EINVAL);
2492 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
2495 name_create(&logname, mti->mti_fsname, "-client");
2496 rc = mgs_wlp_lcfg(obd, fsdb, mti, logname, &bufs,
2499 /* osc params affect the MDT as well */
2500 if (!rc && (mti->mti_flags & LDD_F_SV_TYPE_OST)) {
2503 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
2504 if (!cfs_test_bit(i, fsdb->fsdb_mdt_index_map))
2506 name_destroy(&cname);
2507 name_create_mdt_osc(&cname, mti->mti_svname,
2509 name_destroy(&logname);
2510 name_create_mdt(&logname, mti->mti_fsname, i);
2511 if (!mgs_log_is_empty(obd, logname))
2512 rc = mgs_wlp_lcfg(obd, fsdb,mti,logname,
2518 name_destroy(&logname);
2519 name_destroy(&cname);
2523 /* All mdt. params in proc */
2524 if (class_match_param(ptr, PARAM_MDT, NULL) == 0) {
2528 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
2529 if (strncmp(mti->mti_svname, mti->mti_fsname,
2530 MTI_NAME_MAXLEN) == 0)
2531 /* device is unspecified completely? */
2532 rc = LDD_F_SV_TYPE_MDT | LDD_F_SV_ALL;
2534 rc = server_name2index(mti->mti_svname, &idx, NULL);
2537 if ((rc & LDD_F_SV_TYPE_MDT) == 0)
2539 if (rc & LDD_F_SV_ALL) {
2540 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2541 if (!cfs_test_bit(i,
2542 fsdb->fsdb_mdt_index_map))
2544 name_create_mdt(&logname, mti->mti_fsname, i);
2545 rc = mgs_wlp_lcfg(obd, fsdb, mti,
2548 name_destroy(&logname);
2553 rc = mgs_wlp_lcfg(obd, fsdb, mti,
2554 mti->mti_svname, &bufs,
2555 mti->mti_svname, ptr);
2562 /* All mdd., ost. params in proc */
2563 if ((class_match_param(ptr, PARAM_MDD, NULL) == 0) ||
2564 (class_match_param(ptr, PARAM_OST, NULL) == 0)) {
2565 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
2566 if (mgs_log_is_empty(obd, mti->mti_svname))
2567 GOTO(end, rc = -ENODEV);
2569 rc = mgs_wlp_lcfg(obd, fsdb, mti, mti->mti_svname,
2570 &bufs, mti->mti_svname, ptr);
2574 LCONSOLE_WARN("Ignoring unrecognized param '%s'\n", ptr);
2578 CERROR("err %d on param '%s'\n", rc, ptr);
2583 /* Not implementing automatic failover nid addition at this time. */
2584 int mgs_check_failnid(struct obd_device *obd, struct mgs_target_info *mti)
2591 rc = mgs_find_or_make_fsdb(obd, fsname, &fsdb);
2595 if (mgs_log_is_empty(obd, mti->mti_svname))
2596 /* should never happen */
2599 CDEBUG(D_MGS, "Checking for new failnids for %s\n", mti->mti_svname);
2601 /* FIXME We can just check mti->params to see if we're already in
2602 the failover list. Modify mti->params for rewriting back at
2603 server_register_target(). */
2605 cfs_down(&fsdb->fsdb_sem);
2606 rc = mgs_write_log_add_failnid(obd, fsdb, mti);
2607 cfs_up(&fsdb->fsdb_sem);
2614 int mgs_write_log_target(struct obd_device *obd,
2615 struct mgs_target_info *mti)
2622 /* set/check the new target index */
2623 rc = mgs_set_index(obd, mti);
2625 CERROR("Can't get index (%d)\n", rc);
2630 if (mti->mti_flags & LDD_F_UPGRADE14) {
2631 if (rc == EALREADY) {
2632 LCONSOLE_INFO("Found index %d for %s 1.4 log, "
2633 "upgrading\n", mti->mti_stripe_index,
2636 LCONSOLE_ERROR_MSG(0x149, "Failed to find %s in the old"
2637 " client log. Apparently it is not "
2638 "part of this filesystem, or the old"
2639 " log is wrong.\nUse 'writeconf' on "
2640 "the MDT to force log regeneration."
2641 "\n", mti->mti_svname);
2642 /* Not in client log? Upgrade anyhow...*/
2643 /* Argument against upgrading: reformat MDT,
2644 upgrade OST, then OST will start but will be SKIPped
2645 in client logs. Maybe error now is better. */
2646 /* RETURN(-EINVAL); */
2648 /* end COMPAT_146 */
2650 if (rc == EALREADY) {
2651 LCONSOLE_WARN("Found index %d for %s, updating log\n",
2652 mti->mti_stripe_index, mti->mti_svname);
2653 /* We would like to mark old log sections as invalid
2654 and add new log sections in the client and mdt logs.
2655 But if we add new sections, then live clients will
2656 get repeat setup instructions for already running
2657 osc's. So don't update the client/mdt logs. */
2658 mti->mti_flags &= ~LDD_F_UPDATE;
2662 rc = mgs_find_or_make_fsdb(obd, mti->mti_fsname, &fsdb);
2664 CERROR("Can't get db for %s\n", mti->mti_fsname);
2668 cfs_down(&fsdb->fsdb_sem);
2670 if (mti->mti_flags &
2671 (LDD_F_VIRGIN | LDD_F_UPGRADE14 | LDD_F_WRITECONF)) {
2672 /* Generate a log from scratch */
2673 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
2674 rc = mgs_write_log_mdt(obd, fsdb, mti);
2675 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2676 rc = mgs_write_log_ost(obd, fsdb, mti);
2678 CERROR("Unknown target type %#x, can't create log for "
2679 "%s\n", mti->mti_flags, mti->mti_svname);
2682 CERROR("Can't write logs for %s (%d)\n",
2683 mti->mti_svname, rc);
2687 /* Just update the params from tunefs in mgs_write_log_params */
2688 CDEBUG(D_MGS, "Update params for %s\n", mti->mti_svname);
2689 mti->mti_flags |= LDD_F_PARAM;
2692 /* allocate temporary buffer, where class_get_next_param will
2693 make copy of a current parameter */
2694 OBD_ALLOC(buf, strlen(mti->mti_params) + 1);
2696 GOTO(out_up, rc = -ENOMEM);
2697 params = mti->mti_params;
2698 while (params != NULL) {
2699 rc = class_get_next_param(¶ms, buf);
2702 /* there is no next parameter, that is
2707 CDEBUG(D_MGS, "remaining string: '%s', param: '%s'\n",
2709 rc = mgs_write_log_param(obd, fsdb, mti, buf);
2714 OBD_FREE(buf, strlen(mti->mti_params) + 1);
2717 cfs_up(&fsdb->fsdb_sem);
2722 /* verify that we can handle the old config logs */
2723 int mgs_upgrade_sv_14(struct obd_device *obd, struct mgs_target_info *mti)
2729 /* Create ost log normally, as servers register. Servers
2730 register with their old uuids (from last_rcvd), so old
2731 (MDT and client) logs should work.
2732 - new MDT won't know about old OSTs, only the ones that have
2733 registered, so we need the old MDT log to get the LOV right
2734 in order for old clients to work.
2735 - Old clients connect to the MDT, not the MGS, for their logs, and
2736 will therefore receive the old client log from the MDT /LOGS dir.
2737 - Old clients can continue to use and connect to old or new OSTs
2738 - New clients will contact the MGS for their log
2741 LCONSOLE_INFO("upgrading server %s from pre-1.6\n", mti->mti_svname);
2742 server_mti_print("upgrade", mti);
2744 rc = mgs_find_or_make_fsdb(obd, mti->mti_fsname, &fsdb);
2748 if (fsdb->fsdb_flags & FSDB_LOG_EMPTY) {
2749 LCONSOLE_ERROR_MSG(0x14a, "The old client log %s-client is "
2750 "missing. Was tunefs.lustre successful?\n",
2755 if (fsdb->fsdb_gen == 0) {
2756 /* There were no markers in the client log, meaning we have
2757 not updated the logs for this fs */
2758 CDEBUG(D_MGS, "found old, unupdated client log\n");
2761 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
2762 if (mgs_log_is_empty(obd, mti->mti_svname)) {
2763 LCONSOLE_ERROR_MSG(0x14b, "The old MDT log %s is "
2764 "missing. Was tunefs.lustre "
2769 /* We're starting with an old uuid. Assume old name for lov
2770 as well since the lov entry already exists in the log. */
2771 CDEBUG(D_MGS, "old mds uuid %s\n", mti->mti_uuid);
2772 if (strncmp(mti->mti_uuid, fsdb->fsdb_mdtlov + 4,
2773 strlen(fsdb->fsdb_mdtlov) - 4) != 0) {
2774 CERROR("old mds uuid %s doesn't match log %s (%s)\n",
2775 mti->mti_uuid, fsdb->fsdb_mdtlov,
2776 fsdb->fsdb_mdtlov + 4);
2781 if (!(fsdb->fsdb_flags & FSDB_OLDLOG14)) {
2782 LCONSOLE_ERROR_MSG(0x14c, "%s-client is supposedly an old "
2783 "log, but no old LOV or MDT was found. "
2784 "Consider updating the configuration with"
2785 " --writeconf.\n", mti->mti_fsname);
2790 /* end COMPAT_146 */
2792 int mgs_erase_log(struct obd_device *obd, char *name)
2794 struct lvfs_run_ctxt saved;
2795 struct llog_ctxt *ctxt;
2796 struct llog_handle *llh;
2799 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
2800 LASSERT(ctxt != NULL);
2802 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
2803 rc = llog_create(ctxt, &llh, NULL, name);
2805 llog_init_handle(llh, LLOG_F_IS_PLAIN, NULL);
2806 rc = llog_destroy(llh);
2807 llog_free_handle(llh);
2809 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
2810 llog_ctxt_put(ctxt);
2813 CERROR("failed to clear log %s: %d\n", name, rc);
2818 /* erase all logs for the given fs */
2819 int mgs_erase_logs(struct obd_device *obd, char *fsname)
2821 struct mgs_obd *mgs = &obd->u.mgs;
2822 static struct fs_db *fsdb;
2823 cfs_list_t dentry_list;
2824 struct l_linux_dirent *dirent, *n;
2825 int rc, len = strlen(fsname);
2829 /* Find all the logs in the CONFIGS directory */
2830 rc = class_dentry_readdir(obd, mgs->mgs_configs_dir,
2831 mgs->mgs_vfsmnt, &dentry_list);
2833 CERROR("Can't read %s dir\n", MOUNT_CONFIGS_DIR);
2837 cfs_down(&mgs->mgs_sem);
2839 /* Delete the fs db */
2840 fsdb = mgs_find_fsdb(obd, fsname);
2842 mgs_free_fsdb(obd, fsdb);
2844 cfs_list_for_each_entry_safe(dirent, n, &dentry_list, lld_list) {
2845 cfs_list_del(&dirent->lld_list);
2846 suffix = strrchr(dirent->lld_name, '-');
2847 if (suffix != NULL) {
2848 if ((len == suffix - dirent->lld_name) &&
2849 (strncmp(fsname, dirent->lld_name, len) == 0)) {
2850 CDEBUG(D_MGS, "Removing log %s\n",
2852 mgs_erase_log(obd, dirent->lld_name);
2855 OBD_FREE(dirent, sizeof(*dirent));
2858 cfs_up(&mgs->mgs_sem);
2863 /* from llog_swab */
2864 static void print_lustre_cfg(struct lustre_cfg *lcfg)
2869 CDEBUG(D_MGS, "lustre_cfg: %p\n", lcfg);
2870 CDEBUG(D_MGS, "\tlcfg->lcfg_version: %#x\n", lcfg->lcfg_version);
2872 CDEBUG(D_MGS, "\tlcfg->lcfg_command: %#x\n", lcfg->lcfg_command);
2873 CDEBUG(D_MGS, "\tlcfg->lcfg_num: %#x\n", lcfg->lcfg_num);
2874 CDEBUG(D_MGS, "\tlcfg->lcfg_flags: %#x\n", lcfg->lcfg_flags);
2875 CDEBUG(D_MGS, "\tlcfg->lcfg_nid: %s\n", libcfs_nid2str(lcfg->lcfg_nid));
2877 CDEBUG(D_MGS, "\tlcfg->lcfg_bufcount: %d\n", lcfg->lcfg_bufcount);
2878 if (lcfg->lcfg_bufcount < LUSTRE_CFG_MAX_BUFCOUNT)
2879 for (i = 0; i < lcfg->lcfg_bufcount; i++) {
2880 CDEBUG(D_MGS, "\tlcfg->lcfg_buflens[%d]: %d %s\n",
2881 i, lcfg->lcfg_buflens[i],
2882 lustre_cfg_string(lcfg, i));
2887 /* Set a permanent (config log) param for a target or fs */
2888 int mgs_setparam(struct obd_device *obd, struct lustre_cfg *lcfg, char *fsname)
2891 struct mgs_target_info *mti;
2892 char *devname, *param;
2898 print_lustre_cfg(lcfg);
2900 /* lustre, lustre-mdtlov, lustre-client, lustre-MDT0000 */
2901 devname = lustre_cfg_string(lcfg, 0);
2902 param = lustre_cfg_string(lcfg, 1);
2904 /* Assume device name embedded in param:
2905 lustre-OST0000.osc.max_dirty_mb=32 */
2906 ptr = strchr(param, '.');
2914 LCONSOLE_ERROR_MSG(0x14d, "No target specified: %s\n", param);
2918 /* Extract fsname */
2919 ptr = strrchr(devname, '-');
2920 memset(fsname, 0, MTI_NAME_MAXLEN);
2921 if (ptr && (server_name2index(ptr, &index, NULL) >= 0)) {
2922 /* param related to llite isn't allowed to set by OST or MDT */
2923 if (strncmp(param, PARAM_LLITE, sizeof(PARAM_LLITE)) == 0)
2926 strncpy(fsname, devname, ptr - devname);
2928 /* assume devname is the fsname */
2929 strncpy(fsname, devname, MTI_NAME_MAXLEN);
2931 fsname[MTI_NAME_MAXLEN - 1] = 0;
2932 CDEBUG(D_MGS, "setparam on fs %s device %s\n", fsname, devname);
2934 rc = mgs_find_or_make_fsdb(obd, fsname, &fsdb);
2937 if (!fsdb->fsdb_fl_mgsself && fsdb->fsdb_flags & FSDB_LOG_EMPTY) {
2938 CERROR("No filesystem targets for %s. cfg_device from lctl "
2939 "is '%s'\n", fsname, devname);
2940 mgs_free_fsdb(obd, fsdb);
2944 /* Create a fake mti to hold everything */
2947 GOTO(out, rc = -ENOMEM);
2948 strncpy(mti->mti_fsname, fsname, MTI_NAME_MAXLEN);
2949 strncpy(mti->mti_svname, devname, MTI_NAME_MAXLEN);
2950 strncpy(mti->mti_params, param, sizeof(mti->mti_params));
2951 rc = server_name2index(mti->mti_svname, &mti->mti_stripe_index, &tmp);
2953 /* Not a valid server; may be only fsname */
2956 /* Strip -osc or -mdc suffix from svname */
2957 if (server_make_name(rc, mti->mti_stripe_index, mti->mti_fsname,
2959 GOTO(out, rc = -EINVAL);
2961 mti->mti_flags = rc | LDD_F_PARAM;
2963 cfs_down(&fsdb->fsdb_sem);
2964 /* this is lctl conf_param's single param path, there is not
2965 need to loop through parameters */
2966 rc = mgs_write_log_param(obd, fsdb, mti, mti->mti_params);
2967 cfs_up(&fsdb->fsdb_sem);
2974 static int mgs_write_log_pool(struct obd_device *obd, char *logname,
2975 struct fs_db *fsdb, char *lovname,
2976 enum lcfg_command_type cmd,
2977 char *poolname, char *fsname,
2978 char *ostname, char *comment)
2980 struct llog_handle *llh = NULL;
2983 rc = record_start_log(obd, &llh, logname);
2986 rc = record_marker(obd, llh, fsdb, CM_START, lovname, comment);
2987 record_base(obd, llh, lovname, 0, cmd, poolname, fsname, ostname, 0);
2988 rc = record_marker(obd, llh, fsdb, CM_END, lovname, comment);
2989 rc = record_end_log(obd, &llh);
2994 int mgs_pool_cmd(struct obd_device *obd, enum lcfg_command_type cmd,
2995 char *fsname, char *poolname, char *ostname)
3000 char *label = NULL, *canceled_label = NULL;
3002 struct mgs_target_info *mti = NULL;
3006 rc = mgs_find_or_make_fsdb(obd, fsname, &fsdb);
3008 CERROR("Can't get db for %s\n", fsname);
3011 if (fsdb->fsdb_flags & FSDB_LOG_EMPTY) {
3012 CERROR("%s is not defined\n", fsname);
3013 mgs_free_fsdb(obd, fsdb);
3017 label_sz = 10 + strlen(fsname) + strlen(poolname);
3019 /* check if ostname match fsname */
3020 if (ostname != NULL) {
3023 ptr = strrchr(ostname, '-');
3024 if ((ptr == NULL) ||
3025 (strncmp(fsname, ostname, ptr-ostname) != 0))
3027 label_sz += strlen(ostname);
3030 OBD_ALLOC(label, label_sz);
3032 GOTO(out, rc = -ENOMEM);
3035 case LCFG_POOL_NEW: {
3037 "new %s.%s", fsname, poolname);
3040 case LCFG_POOL_ADD: {
3042 "add %s.%s.%s", fsname, poolname, ostname);
3045 case LCFG_POOL_REM: {
3046 OBD_ALLOC(canceled_label, label_sz);
3047 if (canceled_label == NULL)
3048 GOTO(out, rc = -ENOMEM);
3050 "rem %s.%s.%s", fsname, poolname, ostname);
3051 sprintf(canceled_label,
3052 "add %s.%s.%s", fsname, poolname, ostname);
3055 case LCFG_POOL_DEL: {
3056 OBD_ALLOC(canceled_label, label_sz);
3057 if (canceled_label == NULL)
3058 GOTO(out, rc = -ENOMEM);
3060 "del %s.%s", fsname, poolname);
3061 sprintf(canceled_label,
3062 "new %s.%s", fsname, poolname);
3070 cfs_down(&fsdb->fsdb_sem);
3072 if (canceled_label != NULL) {
3075 GOTO(out, rc = -ENOMEM);
3078 /* write pool def to all MDT logs */
3079 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3080 if (cfs_test_bit(i, fsdb->fsdb_mdt_index_map)) {
3081 name_create_mdt_and_lov(&logname, &lovname, fsdb, i);
3083 if (canceled_label != NULL) {
3084 strcpy(mti->mti_svname, "lov pool");
3085 mgs_modify(obd, fsdb, mti, logname, lovname,
3086 canceled_label, CM_SKIP);
3089 mgs_write_log_pool(obd, logname, fsdb, lovname,
3090 cmd, fsname, poolname, ostname,
3092 name_destroy(&logname);
3093 name_destroy(&lovname);
3097 name_create(&logname, fsname, "-client");
3098 if (canceled_label != NULL)
3099 mgs_modify(obd, fsdb, mti, logname, fsdb->fsdb_clilov,
3100 canceled_label, CM_SKIP);
3102 mgs_write_log_pool(obd, logname, fsdb, fsdb->fsdb_clilov,
3103 cmd, fsname, poolname, ostname, label);
3104 name_destroy(&logname);
3106 cfs_up(&fsdb->fsdb_sem);
3111 OBD_FREE(label, label_sz);
3113 if (canceled_label != NULL)
3114 OBD_FREE(canceled_label, label_sz);
3123 /******************** unused *********************/
3124 static int mgs_backup_llog(struct obd_device *obd, char* fsname)
3126 struct file *filp, *bak_filp;
3127 struct lvfs_run_ctxt saved;
3128 char *logname, *buf;
3129 loff_t soff = 0 , doff = 0;
3130 int count = 4096, len;
3133 OBD_ALLOC(logname, PATH_MAX);
3134 if (logname == NULL)
3137 OBD_ALLOC(buf, count);
3139 GOTO(out , rc = -ENOMEM);
3141 len = snprintf(logname, PATH_MAX, "%s/%s.bak",
3142 MOUNT_CONFIGS_DIR, fsname);
3144 if (len >= PATH_MAX - 1) {
3145 GOTO(out, -ENAMETOOLONG);
3148 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
3150 bak_filp = l_filp_open(logname, O_RDWR|O_CREAT|O_TRUNC, 0660);
3151 if (IS_ERR(bak_filp)) {
3152 rc = PTR_ERR(bak_filp);
3153 CERROR("backup logfile open %s: %d\n", logname, rc);
3156 sprintf(logname, "%s/%s", MOUNT_CONFIGS_DIR, fsname);
3157 filp = l_filp_open(logname, O_RDONLY, 0);
3160 CERROR("logfile open %s: %d\n", logname, rc);
3164 while ((rc = lustre_fread(filp, buf, count, &soff)) > 0) {
3165 rc = lustre_fwrite(bak_filp, buf, count, &doff);
3169 filp_close(filp, 0);
3171 filp_close(bak_filp, 0);
3173 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
3176 OBD_FREE(buf, count);
3177 OBD_FREE(logname, PATH_MAX);