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
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 fl=%x\n", logname, devname, comment,
677 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
679 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
680 LASSERT(ctxt != NULL);
681 rc = llog_create(ctxt, &loghandle, NULL, logname);
685 rc = llog_init_handle(loghandle, LLOG_F_IS_PLAIN, NULL);
689 if (llog_get_size(loghandle) <= 1)
690 GOTO(out_close, rc = 0);
694 GOTO(out_close, rc = -ENOMEM);
695 strcpy(mml->mml_marker.cm_comment, comment);
696 strcpy(mml->mml_marker.cm_tgtname, devname);
697 /* Modify mostly means cancel */
698 mml->mml_marker.cm_flags = flags;
699 mml->mml_marker.cm_canceltime = flags ? cfs_time_current_sec() : 0;
700 mml->mml_modified = 0;
701 rc = llog_process(loghandle, mgs_modify_handler, (void *)mml, NULL);
702 if (!rc && !mml->mml_modified)
707 rc2 = llog_close(loghandle);
711 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
712 if (rc && rc != -ENODEV)
713 CERROR("modify %s/%s failed %d\n",
714 mti->mti_svname, comment, rc);
719 /******************** config log recording functions *********************/
721 static int record_lcfg(struct obd_device *obd, struct llog_handle *llh,
722 struct lustre_cfg *lcfg)
724 struct lvfs_run_ctxt saved;
725 struct llog_rec_hdr rec;
731 LASSERT(llh->lgh_ctxt);
733 buflen = lustre_cfg_len(lcfg->lcfg_bufcount,
735 rec.lrh_len = llog_data_len(buflen);
736 rec.lrh_type = OBD_CFG_REC;
738 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
739 /* idx = -1 means append */
740 rc = llog_write_rec(llh, &rec, NULL, 0, (void *)lcfg, -1);
741 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
743 CERROR("failed %d\n", rc);
747 static int record_base(struct obd_device *obd, struct llog_handle *llh,
748 char *cfgname, lnet_nid_t nid, int cmd,
749 char *s1, char *s2, char *s3, char *s4)
751 struct lustre_cfg_bufs bufs;
752 struct lustre_cfg *lcfg;
755 CDEBUG(D_MGS, "lcfg %s %#x %s %s %s %s\n", cfgname,
756 cmd, s1, s2, s3, s4);
758 lustre_cfg_bufs_reset(&bufs, cfgname);
760 lustre_cfg_bufs_set_string(&bufs, 1, s1);
762 lustre_cfg_bufs_set_string(&bufs, 2, s2);
764 lustre_cfg_bufs_set_string(&bufs, 3, s3);
766 lustre_cfg_bufs_set_string(&bufs, 4, s4);
768 lcfg = lustre_cfg_new(cmd, &bufs);
771 lcfg->lcfg_nid = nid;
773 rc = record_lcfg(obd, llh, lcfg);
775 lustre_cfg_free(lcfg);
778 CERROR("error %d: lcfg %s %#x %s %s %s %s\n", rc, cfgname,
779 cmd, s1, s2, s3, s4);
785 static inline int record_add_uuid(struct obd_device *obd,
786 struct llog_handle *llh,
787 uint64_t nid, char *uuid)
789 return record_base(obd,llh,NULL,nid,LCFG_ADD_UUID,uuid,0,0,0);
793 static inline int record_add_conn(struct obd_device *obd,
794 struct llog_handle *llh,
798 return record_base(obd,llh,devname,0,LCFG_ADD_CONN,uuid,0,0,0);
801 static inline int record_attach(struct obd_device *obd, struct llog_handle *llh,
802 char *devname, char *type, char *uuid)
804 return record_base(obd,llh,devname,0,LCFG_ATTACH,type,uuid,0,0);
807 static inline int record_setup(struct obd_device *obd, struct llog_handle *llh,
809 char *s1, char *s2, char *s3, char *s4)
811 return record_base(obd,llh,devname,0,LCFG_SETUP,s1,s2,s3,s4);
814 static int record_lov_setup(struct obd_device *obd, struct llog_handle *llh,
815 char *devname, struct lov_desc *desc)
817 struct lustre_cfg_bufs bufs;
818 struct lustre_cfg *lcfg;
821 lustre_cfg_bufs_reset(&bufs, devname);
822 lustre_cfg_bufs_set(&bufs, 1, desc, sizeof(*desc));
823 lcfg = lustre_cfg_new(LCFG_SETUP, &bufs);
826 rc = record_lcfg(obd, llh, lcfg);
828 lustre_cfg_free(lcfg);
832 static int record_lmv_setup(struct obd_device *obd, struct llog_handle *llh,
833 char *devname, struct lmv_desc *desc)
835 struct lustre_cfg_bufs bufs;
836 struct lustre_cfg *lcfg;
839 lustre_cfg_bufs_reset(&bufs, devname);
840 lustre_cfg_bufs_set(&bufs, 1, desc, sizeof(*desc));
841 lcfg = lustre_cfg_new(LCFG_SETUP, &bufs);
843 rc = record_lcfg(obd, llh, lcfg);
845 lustre_cfg_free(lcfg);
849 static inline int record_mdc_add(struct obd_device *obd,
850 struct llog_handle *llh,
851 char *logname, char *mdcuuid,
852 char *mdtuuid, char *index,
855 return record_base(obd,llh,logname,0,LCFG_ADD_MDC,
856 mdtuuid,index,gen,mdcuuid);
859 static inline int record_lov_add(struct obd_device *obd,
860 struct llog_handle *llh,
861 char *lov_name, char *ost_uuid,
862 char *index, char *gen)
864 return record_base(obd,llh,lov_name,0,LCFG_LOV_ADD_OBD,
865 ost_uuid,index,gen,0);
868 static inline int record_mount_opt(struct obd_device *obd,
869 struct llog_handle *llh,
870 char *profile, char *lov_name,
873 return record_base(obd,llh,NULL,0,LCFG_MOUNTOPT,
874 profile,lov_name,mdc_name,0);
877 static int record_marker(struct obd_device *obd, struct llog_handle *llh,
878 struct fs_db *fsdb, __u32 flags,
879 char *tgtname, char *comment)
881 struct cfg_marker marker;
882 struct lustre_cfg_bufs bufs;
883 struct lustre_cfg *lcfg;
886 if (flags & CM_START)
888 marker.cm_step = fsdb->fsdb_gen;
889 marker.cm_flags = flags;
890 marker.cm_vers = LUSTRE_VERSION_CODE;
891 strncpy(marker.cm_tgtname, tgtname, sizeof(marker.cm_tgtname));
892 strncpy(marker.cm_comment, comment, sizeof(marker.cm_comment));
893 marker.cm_createtime = cfs_time_current_sec();
894 marker.cm_canceltime = 0;
895 lustre_cfg_bufs_reset(&bufs, NULL);
896 lustre_cfg_bufs_set(&bufs, 1, &marker, sizeof(marker));
897 lcfg = lustre_cfg_new(LCFG_MARKER, &bufs);
900 rc = record_lcfg(obd, llh, lcfg);
902 lustre_cfg_free(lcfg);
906 static int record_start_log(struct obd_device *obd,
907 struct llog_handle **llh, char *name)
909 static struct obd_uuid cfg_uuid = { .uuid = "config_uuid" };
910 struct lvfs_run_ctxt saved;
911 struct llog_ctxt *ctxt;
915 GOTO(out, rc = -EBUSY);
917 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
919 GOTO(out, rc = -ENODEV);
921 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
922 rc = llog_create(ctxt, llh, NULL, name);
924 llog_init_handle(*llh, LLOG_F_IS_PLAIN, &cfg_uuid);
928 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
933 CERROR("Can't start log %s: %d\n", name, rc);
938 static int record_end_log(struct obd_device *obd, struct llog_handle **llh)
940 struct lvfs_run_ctxt saved;
943 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
945 rc = llog_close(*llh);
948 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
952 static int mgs_log_is_empty(struct obd_device *obd, char *name)
954 struct lvfs_run_ctxt saved;
955 struct llog_handle *llh;
956 struct llog_ctxt *ctxt;
959 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
960 LASSERT(ctxt != NULL);
961 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
962 rc = llog_create(ctxt, &llh, NULL, name);
964 llog_init_handle(llh, LLOG_F_IS_PLAIN, NULL);
965 rc = llog_get_size(llh);
968 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
970 /* header is record 1 */
974 /******************** config "macros" *********************/
976 /* write an lcfg directly into a log (with markers) */
977 static int mgs_write_log_direct(struct obd_device *obd, struct fs_db *fsdb,
978 char *logname, struct lustre_cfg *lcfg,
979 char *devname, char *comment)
981 struct llog_handle *llh = NULL;
988 rc = record_start_log(obd, &llh, logname);
992 /* FIXME These should be a single journal transaction */
993 rc = record_marker(obd, llh, fsdb, CM_START, devname, comment);
995 rc = record_lcfg(obd, llh, lcfg);
997 rc = record_marker(obd, llh, fsdb, CM_END, devname, comment);
998 rc = record_end_log(obd, &llh);
1003 /* write the lcfg in all logs for the given fs */
1004 int mgs_write_log_direct_all(struct obd_device *obd, struct fs_db *fsdb,
1005 struct mgs_target_info *mti,
1006 struct lustre_cfg *lcfg,
1007 char *devname, char *comment)
1009 struct mgs_obd *mgs = &obd->u.mgs;
1010 cfs_list_t dentry_list;
1011 struct l_linux_dirent *dirent, *n;
1012 char *fsname = mti->mti_fsname;
1014 int rc = 0, len = strlen(fsname);
1017 /* We need to set params for any future logs
1018 as well. FIXME Append this file to every new log.
1019 Actually, we should store as params (text), not llogs. Or
1021 name_create(&logname, fsname, "-params");
1022 if (mgs_log_is_empty(obd, logname)) {
1023 struct llog_handle *llh = NULL;
1024 rc = record_start_log(obd, &llh, logname);
1025 record_end_log(obd, &llh);
1027 name_destroy(&logname);
1031 /* Find all the logs in the CONFIGS directory */
1032 rc = class_dentry_readdir(obd, mgs->mgs_configs_dir,
1033 mgs->mgs_vfsmnt, &dentry_list);
1035 CERROR("Can't read %s dir\n", MOUNT_CONFIGS_DIR);
1039 /* Could use fsdb index maps instead of directory listing */
1040 cfs_list_for_each_entry_safe(dirent, n, &dentry_list, lld_list) {
1041 cfs_list_del(&dirent->lld_list);
1042 /* don't write to sptlrpc rule log */
1043 if (strncmp(fsname, dirent->lld_name, len) == 0 &&
1044 strstr(dirent->lld_name, "-sptlrpc") == NULL) {
1045 CDEBUG(D_MGS, "Changing log %s\n", dirent->lld_name);
1046 /* Erase any old settings of this same parameter */
1047 mgs_modify(obd, fsdb, mti, dirent->lld_name, devname,
1049 /* Write the new one */
1051 rc = mgs_write_log_direct(obd, fsdb,
1056 CERROR("err %d writing log %s\n", rc,
1060 OBD_FREE(dirent, sizeof(*dirent));
1068 struct mgs_target_info *comp_tmti;
1069 struct mgs_target_info *comp_mti;
1070 struct fs_db *comp_fsdb;
1071 struct obd_device *comp_obd;
1074 static int mgs_write_log_mdc_to_mdt(struct obd_device *, struct fs_db *,
1075 struct mgs_target_info *, char *);
1077 static int mgs_steal_llog_handler(struct llog_handle *llh,
1078 struct llog_rec_hdr *rec,
1081 struct obd_device * obd;
1082 struct mgs_target_info *mti, *tmti;
1084 int cfg_len = rec->lrh_len;
1085 char *cfg_buf = (char*) (rec + 1);
1086 struct lustre_cfg *lcfg;
1088 struct llog_handle *mdt_llh = NULL;
1089 static int got_an_osc_or_mdc = 0;
1090 /* 0: not found any osc/mdc;
1094 static int last_step = -1;
1098 mti = ((struct temp_comp*)data)->comp_mti;
1099 tmti = ((struct temp_comp*)data)->comp_tmti;
1100 fsdb = ((struct temp_comp*)data)->comp_fsdb;
1101 obd = ((struct temp_comp*)data)->comp_obd;
1103 if (rec->lrh_type != OBD_CFG_REC) {
1104 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
1108 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
1110 CERROR("Insane cfg\n");
1114 lcfg = (struct lustre_cfg *)cfg_buf;
1116 if (lcfg->lcfg_command == LCFG_MARKER) {
1117 struct cfg_marker *marker;
1118 marker = lustre_cfg_buf(lcfg, 1);
1119 if (!strncmp(marker->cm_comment,"add osc",7) &&
1120 (marker->cm_flags & CM_START)){
1121 got_an_osc_or_mdc = 1;
1122 rc = record_start_log(obd, &mdt_llh, mti->mti_svname);
1123 rc = record_marker(obd, mdt_llh, fsdb, CM_START,
1124 mti->mti_svname,"add osc(copied)");
1125 rc = record_end_log(obd, &mdt_llh);
1126 last_step = marker->cm_step;
1129 if (!strncmp(marker->cm_comment,"add osc",7) &&
1130 (marker->cm_flags & CM_END)){
1131 LASSERT(last_step == marker->cm_step);
1133 got_an_osc_or_mdc = 0;
1134 rc = record_start_log(obd, &mdt_llh, mti->mti_svname);
1135 rc = record_marker(obd, mdt_llh, fsdb, CM_END,
1136 mti->mti_svname,"add osc(copied)");
1137 rc = record_end_log(obd, &mdt_llh);
1140 if (!strncmp(marker->cm_comment,"add mdc",7) &&
1141 (marker->cm_flags & CM_START)){
1142 got_an_osc_or_mdc = 2;
1143 last_step = marker->cm_step;
1144 memcpy(tmti->mti_svname, marker->cm_tgtname,
1145 strlen(marker->cm_tgtname));
1149 if (!strncmp(marker->cm_comment,"add mdc",7) &&
1150 (marker->cm_flags & CM_END)){
1151 LASSERT(last_step == marker->cm_step);
1153 got_an_osc_or_mdc = 0;
1158 if (got_an_osc_or_mdc == 0 || last_step < 0)
1161 if (lcfg->lcfg_command == LCFG_ADD_UUID) {
1163 nodenid = lcfg->lcfg_nid;
1165 tmti->mti_nids[tmti->mti_nid_count] = nodenid;
1166 tmti->mti_nid_count++;
1171 if (lcfg->lcfg_command == LCFG_SETUP) {
1174 target = lustre_cfg_string(lcfg, 1);
1175 memcpy(tmti->mti_uuid, target, strlen(target));
1179 /* ignore client side sptlrpc_conf_log */
1180 if (lcfg->lcfg_command == LCFG_SPTLRPC_CONF)
1183 if (lcfg->lcfg_command == LCFG_ADD_MDC) {
1186 if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1)
1189 memcpy(tmti->mti_fsname, mti->mti_fsname,
1190 strlen(mti->mti_fsname));
1191 tmti->mti_stripe_index = index;
1193 mgs_write_log_mdc_to_mdt(obd, fsdb, tmti, mti->mti_svname);
1194 memset(tmti, 0, sizeof(*tmti));
1200 /* fsdb->fsdb_sem is already held in mgs_write_log_target*/
1201 /* stealed from mgs_get_fsdb_from_llog*/
1202 static int mgs_steal_llog_for_mdt_from_client(struct obd_device *obd,
1204 struct temp_comp* comp)
1206 struct llog_handle *loghandle;
1207 struct lvfs_run_ctxt saved;
1208 struct mgs_target_info *tmti;
1209 struct llog_ctxt *ctxt;
1213 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
1214 LASSERT(ctxt != NULL);
1216 OBD_ALLOC_PTR(tmti);
1220 comp->comp_tmti = tmti;
1221 comp->comp_obd = obd;
1223 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
1225 rc = llog_create(ctxt, &loghandle, NULL, client_name);
1229 rc = llog_init_handle(loghandle, LLOG_F_IS_PLAIN, NULL);
1231 GOTO(out_close, rc);
1233 rc = llog_process(loghandle, mgs_steal_llog_handler, (void *)comp, NULL);
1234 CDEBUG(D_MGS, "steal llog re = %d\n", rc);
1236 rc2 = llog_close(loghandle);
1240 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
1242 llog_ctxt_put(ctxt);
1246 /* lmv is the second thing for client logs */
1247 /* copied from mgs_write_log_lov. Please refer to that. */
1248 static int mgs_write_log_lmv(struct obd_device *obd, struct fs_db *fsdb,
1249 struct mgs_target_info *mti,
1250 char *logname, char *lmvname)
1252 struct llog_handle *llh = NULL;
1253 struct lmv_desc *lmvdesc;
1258 CDEBUG(D_MGS, "Writing lmv(%s) log for %s\n", lmvname,logname);
1260 OBD_ALLOC_PTR(lmvdesc);
1261 if (lmvdesc == NULL)
1263 lmvdesc->ld_active_tgt_count = 0;
1264 lmvdesc->ld_tgt_count = 0;
1265 sprintf((char*)lmvdesc->ld_uuid.uuid, "%s_UUID", lmvname);
1266 uuid = (char *)lmvdesc->ld_uuid.uuid;
1268 rc = record_start_log(obd, &llh, logname);
1269 rc = record_marker(obd, llh, fsdb, CM_START, lmvname, "lmv setup");
1270 rc = record_attach(obd, llh, lmvname, "lmv", uuid);
1271 rc = record_lmv_setup(obd, llh, lmvname, lmvdesc);
1272 rc = record_marker(obd, llh, fsdb, CM_END, lmvname, "lmv setup");
1273 rc = record_end_log(obd, &llh);
1275 OBD_FREE_PTR(lmvdesc);
1279 /* lov is the first thing in the mdt and client logs */
1280 static int mgs_write_log_lov(struct obd_device *obd, struct fs_db *fsdb,
1281 struct mgs_target_info *mti,
1282 char *logname, char *lovname)
1284 struct llog_handle *llh = NULL;
1285 struct lov_desc *lovdesc;
1290 CDEBUG(D_MGS, "Writing lov(%s) log for %s\n", lovname, logname);
1293 #01 L attach 0:lov_mdsA 1:lov 2:71ccb_lov_mdsA_19f961a9e1
1294 #02 L lov_setup 0:lov_mdsA 1:(struct lov_desc)
1295 uuid=lov1_UUID, stripe count=1, size=1048576, offset=0, pattern=0
1298 /* FIXME just make lov_setup accept empty desc (put uuid in buf 2) */
1299 OBD_ALLOC_PTR(lovdesc);
1300 if (lovdesc == NULL)
1302 lovdesc->ld_magic = LOV_DESC_MAGIC;
1303 lovdesc->ld_tgt_count = 0;
1304 /* Defaults. Can be changed later by lcfg config_param */
1305 lovdesc->ld_default_stripe_count = 1;
1306 lovdesc->ld_pattern = LOV_PATTERN_RAID0;
1307 lovdesc->ld_default_stripe_size = 1024 * 1024;
1308 lovdesc->ld_default_stripe_offset = 0;
1309 lovdesc->ld_qos_maxage = QOS_DEFAULT_MAXAGE;
1310 sprintf((char*)lovdesc->ld_uuid.uuid, "%s_UUID", lovname);
1311 /* can these be the same? */
1312 uuid = (char *)lovdesc->ld_uuid.uuid;
1314 /* This should always be the first entry in a log.
1315 rc = mgs_clear_log(obd, logname); */
1316 rc = record_start_log(obd, &llh, logname);
1319 /* FIXME these should be a single journal transaction */
1320 rc = record_marker(obd, llh, fsdb, CM_START, lovname, "lov setup");
1321 rc = record_attach(obd, llh, lovname, "lov", uuid);
1322 rc = record_lov_setup(obd, llh, lovname, lovdesc);
1323 rc = record_marker(obd, llh, fsdb, CM_END, lovname, "lov setup");
1324 rc = record_end_log(obd, &llh);
1328 OBD_FREE_PTR(lovdesc);
1332 /* add failnids to open log */
1333 static int mgs_write_log_failnids(struct obd_device *obd,
1334 struct mgs_target_info *mti,
1335 struct llog_handle *llh,
1338 char *failnodeuuid = NULL;
1339 char *ptr = mti->mti_params;
1344 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) nal=90 0: 1:uml1_UUID
1345 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
1346 #05 L setup 0:OSC_uml1_ost1_mdsA 1:ost1_UUID 2:uml1_UUID
1347 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) nal=90 0: 1:uml2_UUID
1348 #0x L add_uuid nid=2@elan(0x1000000000002) nal=90 0: 1:uml2_UUID
1349 #07 L add_conn 0:OSC_uml1_ost1_mdsA 1:uml2_UUID
1352 /* Pull failnid info out of params string */
1353 while (class_find_param(ptr, PARAM_FAILNODE, &ptr) == 0) {
1354 while (class_parse_nid(ptr, &nid, &ptr) == 0) {
1355 if (failnodeuuid == NULL) {
1356 /* We don't know the failover node name,
1357 so just use the first nid as the uuid */
1358 rc = name_create(&failnodeuuid,
1359 libcfs_nid2str(nid), "");
1363 CDEBUG(D_MGS, "add nid %s for failover uuid %s, "
1364 "client %s\n", libcfs_nid2str(nid),
1365 failnodeuuid, cliname);
1366 rc = record_add_uuid(obd, llh, nid, failnodeuuid);
1369 rc = record_add_conn(obd, llh, cliname, failnodeuuid);
1370 name_destroy(&failnodeuuid);
1371 failnodeuuid = NULL;
1378 static int mgs_write_log_mdc_to_lmv(struct obd_device *obd, struct fs_db *fsdb,
1379 struct mgs_target_info *mti,
1380 char *logname, char *lmvname)
1382 struct llog_handle *llh = NULL;
1383 char *mdcname, *nodeuuid, *mdcuuid, *lmvuuid;
1388 if (mgs_log_is_empty(obd, logname)) {
1389 CERROR("log is empty! Logical error\n");
1393 CDEBUG(D_MGS, "adding mdc for %s to log %s:lmv(%s)\n",
1394 mti->mti_svname, logname, lmvname);
1396 name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
1397 name_create(&mdcname, mti->mti_svname, "-mdc");
1398 name_create(&mdcuuid, mdcname, "_UUID");
1399 name_create(&lmvuuid, lmvname, "_UUID");
1401 rc = record_start_log(obd, &llh, logname);
1402 rc = record_marker(obd, llh, fsdb, CM_START, mti->mti_svname,
1405 for (i = 0; i < mti->mti_nid_count; i++) {
1406 CDEBUG(D_MGS, "add nid %s for mdt\n",
1407 libcfs_nid2str(mti->mti_nids[i]));
1409 rc = record_add_uuid(obd, llh, mti->mti_nids[i], nodeuuid);
1412 rc = record_attach(obd, llh, mdcname, LUSTRE_MDC_NAME, lmvuuid);
1413 rc = record_setup(obd, llh, mdcname, mti->mti_uuid, nodeuuid, 0, 0);
1414 rc = mgs_write_log_failnids(obd, mti, llh, mdcname);
1415 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
1416 rc = record_mdc_add(obd, llh, lmvname, mdcuuid, mti->mti_uuid,
1418 rc = record_marker(obd, llh, fsdb, CM_END, mti->mti_svname,
1420 rc = record_end_log(obd, &llh);
1422 name_destroy(&lmvuuid);
1423 name_destroy(&mdcuuid);
1424 name_destroy(&mdcname);
1425 name_destroy(&nodeuuid);
1429 /* add new mdc to already existent MDS */
1430 static int mgs_write_log_mdc_to_mdt(struct obd_device *obd, struct fs_db *fsdb,
1431 struct mgs_target_info *mti, char *logname)
1433 struct llog_handle *llh = NULL;
1434 char *nodeuuid, *mdcname, *mdcuuid, *mdtuuid;
1435 int idx = mti->mti_stripe_index;
1440 if (mgs_log_is_empty(obd, mti->mti_svname)) {
1441 CERROR("log is empty! Logical error\n");
1445 CDEBUG(D_MGS, "adding mdc index %d to %s\n", idx, logname);
1447 name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
1448 snprintf(index, sizeof(index), "-mdc%04x", idx);
1449 name_create(&mdcname, logname, index);
1450 name_create(&mdcuuid, mdcname, "_UUID");
1451 name_create(&mdtuuid, logname, "_UUID");
1453 rc = record_start_log(obd, &llh, logname);
1454 rc = record_marker(obd, llh, fsdb, CM_START, mti->mti_svname, "add mdc");
1455 for (i = 0; i < mti->mti_nid_count; i++) {
1456 CDEBUG(D_MGS, "add nid %s for mdt\n",
1457 libcfs_nid2str(mti->mti_nids[i]));
1458 rc = record_add_uuid(obd, llh, mti->mti_nids[i], nodeuuid);
1460 rc = record_attach(obd, llh, mdcname, LUSTRE_MDC_NAME, mdcuuid);
1461 rc = record_setup(obd, llh, mdcname, mti->mti_uuid, nodeuuid, 0, 0);
1462 rc = mgs_write_log_failnids(obd, mti, llh, mdcname);
1463 snprintf(index, sizeof(index), "%d", idx);
1465 rc = record_mdc_add(obd, llh, logname, mdcuuid, mti->mti_uuid,
1467 rc = record_marker(obd, llh, fsdb, CM_END, mti->mti_svname, "add mdc");
1468 rc = record_end_log(obd, &llh);
1470 name_destroy(&mdcuuid);
1471 name_destroy(&mdcname);
1472 name_destroy(&nodeuuid);
1473 name_destroy(&mdtuuid);
1477 static int mgs_write_log_mdt0(struct obd_device *obd, struct fs_db *fsdb,
1478 struct mgs_target_info *mti)
1480 char *log = mti->mti_svname;
1481 struct llog_handle *llh = NULL;
1482 char *uuid, *lovname;
1484 char *ptr = mti->mti_params;
1485 int rc = 0, failout = 0;
1488 OBD_ALLOC(uuid, sizeof(struct obd_uuid));
1492 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
1493 failout = (strncmp(ptr, "failout", 7) == 0);
1495 name_create(&lovname, log, "-mdtlov");
1496 if (mgs_log_is_empty(obd, log))
1497 rc = mgs_write_log_lov(obd, fsdb, mti, log, lovname);
1499 sprintf(uuid, "%s_UUID", log);
1500 sprintf(mdt_index, "%d", mti->mti_stripe_index);
1502 /* add MDT itself */
1503 rc = record_start_log(obd, &llh, log);
1507 /* FIXME this whole fn should be a single journal transaction */
1508 rc = record_marker(obd, llh, fsdb, CM_START, log, "add mdt");
1509 rc = record_attach(obd, llh, log, LUSTRE_MDT_NAME, uuid);
1510 rc = record_mount_opt(obd, llh, log, lovname, NULL);
1511 rc = record_setup(obd, llh, log, uuid, mdt_index, lovname,
1512 failout ? "n" : "f");
1513 rc = record_marker(obd, llh, fsdb, CM_END, log, "add mdt");
1514 rc = record_end_log(obd, &llh);
1516 name_destroy(&lovname);
1517 OBD_FREE(uuid, sizeof(struct obd_uuid));
1521 static inline void name_create_mdt(char **logname, char *fsname, int i)
1525 sprintf(mdt_index, "-MDT%04x", i);
1526 name_create(logname, fsname, mdt_index);
1529 static void name_create_mdt_and_lov(char **logname, char **lovname,
1530 struct fs_db *fsdb, int i)
1532 name_create_mdt(logname, fsdb->fsdb_name, i);
1534 if (i == 0 && fsdb->fsdb_fl_oscname_18)
1535 name_create(lovname, fsdb->fsdb_name, "-mdtlov");
1537 name_create(lovname, *logname, "-mdtlov");
1540 static inline void name_create_mdt_osc(char **oscname, char *ostname,
1541 struct fs_db *fsdb, int i)
1545 if (i == 0 && fsdb->fsdb_fl_oscname_18)
1546 sprintf(suffix, "-osc");
1548 sprintf(suffix, "-osc-MDT%04x", i);
1549 name_create(oscname, ostname, suffix);
1552 /* envelope method for all layers log */
1553 static int mgs_write_log_mdt(struct obd_device *obd, struct fs_db *fsdb,
1554 struct mgs_target_info *mti)
1556 struct llog_handle *llh = NULL;
1558 struct temp_comp comp = { 0 };
1562 CDEBUG(D_MGS, "writing new mdt %s\n", mti->mti_svname);
1566 if (mti->mti_flags & LDD_F_UPGRADE14) {
1567 /* We're starting with an old uuid. Assume old name for lov
1568 as well since the lov entry already exists in the log. */
1569 CDEBUG(D_MGS, "old mds uuid %s\n", mti->mti_uuid);
1570 if (strncmp(mti->mti_uuid, fsdb->fsdb_mdtlov + 4,
1571 strlen(fsdb->fsdb_mdtlov) - 4) != 0) {
1572 CERROR("old mds uuid %s doesn't match log %s (%s)\n",
1573 mti->mti_uuid, fsdb->fsdb_mdtlov,
1574 fsdb->fsdb_mdtlov + 4);
1578 /* end COMPAT_146 */
1580 if (mti->mti_uuid[0] == '\0') {
1581 /* Make up our own uuid */
1582 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
1583 "%s_UUID", mti->mti_svname);
1587 rc = mgs_write_log_mdt0(obd, fsdb, mti);
1589 /* Append the mdt info to the client log */
1590 name_create(&cliname, mti->mti_fsname, "-client");
1592 if (mgs_log_is_empty(obd, cliname)) {
1593 /* Start client log */
1594 rc = mgs_write_log_lov(obd, fsdb, mti, cliname,
1596 rc = mgs_write_log_lmv(obd, fsdb, mti, cliname,
1601 #09 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
1602 #10 L attach 0:MDC_uml1_mdsA_MNT_client 1:mdc 2:1d834_MNT_client_03f
1603 #11 L setup 0:MDC_uml1_mdsA_MNT_client 1:mdsA_UUID 2:uml1_UUID
1604 #12 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
1605 #13 L add_conn 0:MDC_uml1_mdsA_MNT_client 1:uml2_UUID
1606 #14 L mount_option 0: 1:client 2:lov1 3:MDC_uml1_mdsA_MNT_client
1611 if (mti->mti_flags & LDD_F_UPGRADE14) {
1612 rc = record_start_log(obd, &llh, cliname);
1616 rc = record_marker(obd, llh, fsdb, CM_START,
1617 mti->mti_svname,"add mdc");
1619 /* Old client log already has MDC entry, but needs mount opt
1620 for new client name (lustre-client) */
1621 /* FIXME Old MDT log already has an old mount opt
1622 which we should remove (currently handled by
1623 class_del_profiles()) */
1624 rc = record_mount_opt(obd, llh, cliname, fsdb->fsdb_clilov,
1626 /* end COMPAT_146 */
1628 rc = record_marker(obd, llh, fsdb, CM_END,
1629 mti->mti_svname, "add mdc");
1633 /* copy client info about lov/lmv */
1634 comp.comp_mti = mti;
1635 comp.comp_fsdb = fsdb;
1637 rc = mgs_steal_llog_for_mdt_from_client(obd, cliname,
1640 rc = mgs_write_log_mdc_to_lmv(obd, fsdb, mti, cliname,
1643 rc = record_start_log(obd, &llh, cliname);
1647 rc = record_marker(obd, llh, fsdb, CM_START, cliname,
1649 rc = record_mount_opt(obd, llh, cliname, fsdb->fsdb_clilov,
1651 rc = record_marker(obd, llh, fsdb, CM_END, cliname,
1655 rc = record_end_log(obd, &llh);
1657 name_destroy(&cliname);
1659 // for_all_existing_mdt except current one
1660 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
1662 if (i != mti->mti_stripe_index &&
1663 cfs_test_bit(i, fsdb->fsdb_mdt_index_map)) {
1664 name_create_mdt(&mdtname, mti->mti_fsname, i);
1665 rc = mgs_write_log_mdc_to_mdt(obd, fsdb, mti, mdtname);
1666 name_destroy(&mdtname);
1673 /* Add the ost info to the client/mdt lov */
1674 static int mgs_write_log_osc_to_lov(struct obd_device *obd, struct fs_db *fsdb,
1675 struct mgs_target_info *mti,
1676 char *logname, char *suffix, char *lovname,
1677 enum lustre_sec_part sec_part, int flags)
1679 struct llog_handle *llh = NULL;
1680 char *nodeuuid, *oscname, *oscuuid, *lovuuid, *svname;
1685 CDEBUG(D_INFO, "adding osc for %s to log %s\n",
1686 mti->mti_svname, logname);
1688 if (mgs_log_is_empty(obd, logname)) {
1689 /* The first item in the log must be the lov, so we have
1690 somewhere to add our osc. */
1691 rc = mgs_write_log_lov(obd, fsdb, mti, logname, lovname);
1694 name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
1695 name_create(&svname, mti->mti_svname, "-osc");
1696 name_create(&oscname, svname, suffix);
1697 name_create(&oscuuid, oscname, "_UUID");
1698 name_create(&lovuuid, lovname, "_UUID");
1701 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
1703 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
1704 #04 L attach 0:OSC_uml1_ost1_MNT_client 1:osc 2:89070_lov1_a41dff51a
1705 #05 L setup 0:OSC_uml1_ost1_MNT_client 1:ost1_UUID 2:uml1_UUID
1707 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
1708 #07 L add_conn 0:OSC_uml1_ost1_MNT_client 1:uml2_UUID
1709 #08 L lov_modify_tgts add 0:lov1 1:ost1_UUID 2(index):0 3(gen):1
1712 rc = record_start_log(obd, &llh, logname);
1715 /* FIXME these should be a single journal transaction */
1716 rc = record_marker(obd, llh, fsdb, CM_START | flags, mti->mti_svname,
1718 for (i = 0; i < mti->mti_nid_count; i++) {
1719 CDEBUG(D_MGS, "add nid %s\n", libcfs_nid2str(mti->mti_nids[i]));
1720 rc = record_add_uuid(obd, llh, mti->mti_nids[i], nodeuuid);
1722 rc = record_attach(obd, llh, oscname, LUSTRE_OSC_NAME, lovuuid);
1723 rc = record_setup(obd, llh, oscname, mti->mti_uuid, nodeuuid, 0, 0);
1724 rc = mgs_write_log_failnids(obd, mti, llh, oscname);
1725 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
1726 rc = record_lov_add(obd, llh, lovname, mti->mti_uuid, index, "1");
1727 rc = record_marker(obd, llh, fsdb, CM_END | flags, mti->mti_svname,
1729 rc = record_end_log(obd, &llh);
1731 name_destroy(&lovuuid);
1732 name_destroy(&oscuuid);
1733 name_destroy(&oscname);
1734 name_destroy(&svname);
1735 name_destroy(&nodeuuid);
1739 static int mgs_write_log_ost(struct obd_device *obd, struct fs_db *fsdb,
1740 struct mgs_target_info *mti)
1742 struct llog_handle *llh = NULL;
1743 char *logname, *lovname;
1744 char *ptr = mti->mti_params;
1745 int rc, flags = 0, failout = 0, i;
1748 CDEBUG(D_MGS, "writing new ost %s\n", mti->mti_svname);
1750 /* The ost startup log */
1752 /* If the ost log already exists, that means that someone reformatted
1753 the ost and it called target_add again. */
1754 if (!mgs_log_is_empty(obd, mti->mti_svname)) {
1755 LCONSOLE_ERROR_MSG(0x141, "The config log for %s already "
1756 "exists, yet the server claims it never "
1757 "registered. It may have been reformatted, "
1758 "or the index changed. writeconf the MDT to "
1759 "regenerate all logs.\n", mti->mti_svname);
1764 attach obdfilter ost1 ost1_UUID
1765 setup /dev/loop2 ldiskfs f|n errors=remount-ro,user_xattr
1767 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
1768 failout = (strncmp(ptr, "failout", 7) == 0);
1769 rc = record_start_log(obd, &llh, mti->mti_svname);
1772 /* FIXME these should be a single journal transaction */
1773 rc = record_marker(obd, llh, fsdb, CM_START, mti->mti_svname,"add ost");
1774 if (*mti->mti_uuid == '\0')
1775 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
1776 "%s_UUID", mti->mti_svname);
1777 rc = record_attach(obd, llh, mti->mti_svname,
1778 "obdfilter"/*LUSTRE_OST_NAME*/, mti->mti_uuid);
1779 rc = record_setup(obd, llh, mti->mti_svname,
1780 "dev"/*ignored*/, "type"/*ignored*/,
1781 failout ? "n" : "f", 0/*options*/);
1782 rc = record_marker(obd, llh, fsdb, CM_END, mti->mti_svname, "add ost");
1783 rc = record_end_log(obd, &llh);
1785 /* We also have to update the other logs where this osc is part of
1788 if (fsdb->fsdb_flags & FSDB_OLDLOG14) {
1789 /* If we're upgrading, the old mdt log already has our
1790 entry. Let's do a fake one for fun. */
1791 /* Note that we can't add any new failnids, since we don't
1792 know the old osc names. */
1793 flags = CM_SKIP | CM_UPGRADE146;
1795 } else if ((mti->mti_flags & LDD_F_UPDATE) != LDD_F_UPDATE) {
1796 /* If the update flag isn't set, don't update client/mdt
1799 LCONSOLE_WARN("Client log for %s was not updated; writeconf "
1800 "the MDT first to regenerate it.\n",
1804 /* Add ost to all MDT lov defs */
1805 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
1806 if (cfs_test_bit(i, fsdb->fsdb_mdt_index_map)) {
1809 name_create_mdt_and_lov(&logname, &lovname, fsdb, i);
1810 sprintf(mdt_index, "-MDT%04x", i);
1811 mgs_write_log_osc_to_lov(obd, fsdb, mti, logname,
1813 LUSTRE_SP_MDT, flags);
1814 name_destroy(&logname);
1815 name_destroy(&lovname);
1819 /* Append ost info to the client log */
1820 name_create(&logname, mti->mti_fsname, "-client");
1821 mgs_write_log_osc_to_lov(obd, fsdb, mti, logname, "",
1822 fsdb->fsdb_clilov, LUSTRE_SP_CLI, 0);
1823 name_destroy(&logname);
1827 static __inline__ int mgs_param_empty(char *ptr)
1831 if ((tmp = strchr(ptr, '=')) && (*(++tmp) == '\0'))
1836 static int mgs_write_log_failnid_internal(struct obd_device *obd,
1838 struct mgs_target_info *mti,
1839 char *logname, char *cliname)
1842 struct llog_handle *llh = NULL;
1844 if (mgs_param_empty(mti->mti_params)) {
1845 /* Remove _all_ failnids */
1846 rc = mgs_modify(obd, fsdb, mti, logname,
1847 mti->mti_svname, "add failnid", CM_SKIP);
1851 /* Otherwise failover nids are additive */
1852 rc = record_start_log(obd, &llh, logname);
1854 /* FIXME this should be a single journal transaction */
1855 rc = record_marker(obd, llh, fsdb, CM_START,
1856 mti->mti_svname, "add failnid");
1857 rc = mgs_write_log_failnids(obd, mti, llh, cliname);
1858 rc = record_marker(obd, llh, fsdb, CM_END,
1859 mti->mti_svname, "add failnid");
1860 rc = record_end_log(obd, &llh);
1867 /* Add additional failnids to an existing log.
1868 The mdc/osc must have been added to logs first */
1869 /* tcp nids must be in dotted-quad ascii -
1870 we can't resolve hostnames from the kernel. */
1871 static int mgs_write_log_add_failnid(struct obd_device *obd, struct fs_db *fsdb,
1872 struct mgs_target_info *mti)
1874 char *logname, *cliname;
1878 /* FIXME we currently can't erase the failnids
1879 * given when a target first registers, since they aren't part of
1880 * an "add uuid" stanza */
1882 /* Verify that we know about this target */
1883 if (mgs_log_is_empty(obd, mti->mti_svname)) {
1884 LCONSOLE_ERROR_MSG(0x142, "The target %s has not registered "
1885 "yet. It must be started before failnids "
1886 "can be added.\n", mti->mti_svname);
1890 /* Create mdc/osc client name (e.g. lustre-OST0001-osc) */
1891 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
1892 name_create(&cliname, mti->mti_svname, "-mdc");
1893 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
1894 name_create(&cliname, mti->mti_svname, "-osc");
1899 /* Add failover nids to the client log */
1900 name_create(&logname, mti->mti_fsname, "-client");
1901 rc = mgs_write_log_failnid_internal(obd, fsdb, mti, logname, cliname);
1902 name_destroy(&logname);
1903 name_destroy(&cliname);
1905 if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
1906 /* Add OST failover nids to the MDT logs as well */
1909 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
1910 if (!cfs_test_bit(i, fsdb->fsdb_mdt_index_map))
1912 name_create_mdt(&logname, mti->mti_fsname, i);
1913 name_create_mdt_osc(&cliname, mti->mti_svname, fsdb, i);
1914 rc = mgs_write_log_failnid_internal(obd, fsdb, mti,
1916 name_destroy(&cliname);
1917 name_destroy(&logname);
1924 static int mgs_wlp_lcfg(struct obd_device *obd, struct fs_db *fsdb,
1925 struct mgs_target_info *mti,
1926 char *logname, struct lustre_cfg_bufs *bufs,
1927 char *tgtname, char *ptr)
1929 char comment[MTI_NAME_MAXLEN];
1931 struct lustre_cfg *lcfg;
1934 /* Erase any old settings of this same parameter */
1935 memcpy(comment, ptr, MTI_NAME_MAXLEN);
1936 comment[MTI_NAME_MAXLEN - 1] = 0;
1937 /* But don't try to match the value. */
1938 if ((tmp = strchr(comment, '=')))
1940 /* FIXME we should skip settings that are the same as old values */
1941 rc = mgs_modify(obd, fsdb, mti, logname, tgtname, comment, CM_SKIP);
1942 del = mgs_param_empty(ptr);
1944 LCONSOLE_INFO("%sing parameter %s.%s in log %s\n", del ? "Disabl" : rc ?
1945 "Sett" : "Modify", tgtname, comment, logname);
1949 lustre_cfg_bufs_reset(bufs, tgtname);
1950 lustre_cfg_bufs_set_string(bufs, 1, ptr);
1951 lcfg = lustre_cfg_new(LCFG_PARAM, bufs);
1954 rc = mgs_write_log_direct(obd, fsdb, logname, lcfg, tgtname, comment);
1955 lustre_cfg_free(lcfg);
1959 /* write global variable settings into log */
1960 static int mgs_write_log_sys(struct obd_device *obd, struct fs_db *fsdb,
1961 struct mgs_target_info *mti, char *sys, char *ptr)
1963 struct lustre_cfg_bufs bufs;
1964 struct lustre_cfg *lcfg;
1970 if (class_match_param(ptr, PARAM_TIMEOUT, &tmp) == 0)
1971 cmd = LCFG_SET_TIMEOUT;
1972 else if (class_match_param(ptr, PARAM_LDLM_TIMEOUT, &tmp) == 0)
1973 cmd = LCFG_SET_LDLM_TIMEOUT;
1974 /* Check for known params here so we can return error to lctl */
1975 else if ((class_match_param(ptr, PARAM_AT_MIN, &tmp) == 0)
1976 || (class_match_param(ptr, PARAM_AT_MAX, &tmp) == 0)
1977 || (class_match_param(ptr, PARAM_AT_EXTRA, &tmp) == 0)
1978 || (class_match_param(ptr, PARAM_AT_EARLY_MARGIN, &tmp) == 0)
1979 || (class_match_param(ptr, PARAM_AT_HISTORY, &tmp) == 0))
1984 /* separate the value */
1985 val = simple_strtoul(tmp, NULL, 0);
1987 CDEBUG(D_MGS, "global '%s' removed\n", sys);
1989 CDEBUG(D_MGS, "global '%s' val=%d\n", sys, val);
1991 lustre_cfg_bufs_reset(&bufs, NULL);
1992 lustre_cfg_bufs_set_string(&bufs, 1, sys);
1993 lcfg = lustre_cfg_new(cmd, &bufs);
1994 lcfg->lcfg_num = val;
1995 /* truncate the comment to the parameter name */
1999 /* modify all servers and clients */
2000 rc = mgs_write_log_direct_all(obd, fsdb, mti,
2001 *tmp == '\0' ? NULL : lcfg,
2002 mti->mti_fsname, sys);
2004 lustre_cfg_free(lcfg);
2008 static int mgs_srpc_set_param_disk(struct obd_device *obd,
2010 struct mgs_target_info *mti,
2013 struct llog_handle *llh = NULL;
2015 char *comment, *ptr;
2016 struct lustre_cfg_bufs bufs;
2017 struct lustre_cfg *lcfg;
2022 ptr = strchr(param, '=');
2026 OBD_ALLOC(comment, len + 1);
2027 if (comment == NULL)
2029 strncpy(comment, param, len);
2030 comment[len] = '\0';
2033 lustre_cfg_bufs_reset(&bufs, mti->mti_svname);
2034 lustre_cfg_bufs_set_string(&bufs, 1, param);
2035 lcfg = lustre_cfg_new(LCFG_SPTLRPC_CONF, &bufs);
2037 GOTO(out_comment, rc = -ENOMEM);
2039 /* construct log name */
2040 rc = name_create(&logname, mti->mti_fsname, "-sptlrpc");
2044 if (mgs_log_is_empty(obd, logname)) {
2045 rc = record_start_log(obd, &llh, logname);
2046 record_end_log(obd, &llh);
2051 /* obsolete old one */
2052 mgs_modify(obd, fsdb, mti, logname, mti->mti_svname, comment, CM_SKIP);
2054 if (!mgs_param_empty(param)) {
2055 /* write the new one */
2056 rc = mgs_write_log_direct(obd, fsdb, logname, lcfg,
2057 mti->mti_svname, comment);
2059 CERROR("err %d writing log %s\n", rc, logname);
2062 name_destroy(&logname);
2064 lustre_cfg_free(lcfg);
2066 OBD_FREE(comment, len + 1);
2070 static int mgs_srpc_set_param_udesc_mem(struct fs_db *fsdb,
2075 /* disable the adjustable udesc parameter for now, i.e. use default
2076 * setting that client always ship udesc to MDT if possible. to enable
2077 * it simply remove the following line */
2080 ptr = strchr(param, '=');
2085 if (strcmp(param, PARAM_SRPC_UDESC))
2088 if (strcmp(ptr, "yes") == 0) {
2089 fsdb->fsdb_fl_udesc = 1;
2090 CWARN("Enable user descriptor shipping from client to MDT\n");
2091 } else if (strcmp(ptr, "no") == 0) {
2092 fsdb->fsdb_fl_udesc = 0;
2093 CWARN("Disable user descriptor shipping from client to MDT\n");
2101 CERROR("Invalid param: %s\n", param);
2105 static int mgs_srpc_set_param_mem(struct fs_db *fsdb,
2109 struct sptlrpc_rule rule;
2110 struct sptlrpc_rule_set *rset;
2114 if (strncmp(param, PARAM_SRPC, sizeof(PARAM_SRPC) - 1) != 0) {
2115 CERROR("Invalid sptlrpc parameter: %s\n", param);
2119 if (strncmp(param, PARAM_SRPC_UDESC,
2120 sizeof(PARAM_SRPC_UDESC) - 1) == 0) {
2121 RETURN(mgs_srpc_set_param_udesc_mem(fsdb, param));
2124 if (strncmp(param, PARAM_SRPC_FLVR, sizeof(PARAM_SRPC_FLVR) - 1) != 0) {
2125 CERROR("Invalid sptlrpc flavor parameter: %s\n", param);
2129 param += sizeof(PARAM_SRPC_FLVR) - 1;
2131 rc = sptlrpc_parse_rule(param, &rule);
2135 /* mgs rules implies must be mgc->mgs */
2136 if (fsdb->fsdb_fl_mgsself) {
2137 if ((rule.sr_from != LUSTRE_SP_MGC &&
2138 rule.sr_from != LUSTRE_SP_ANY) ||
2139 (rule.sr_to != LUSTRE_SP_MGS &&
2140 rule.sr_to != LUSTRE_SP_ANY))
2144 /* preapre room for this coming rule. svcname format should be:
2145 * - fsname: general rule
2146 * - fsname-tgtname: target-specific rule
2148 if (strchr(svname, '-')) {
2149 struct mgs_tgt_srpc_conf *tgtconf;
2152 for (tgtconf = fsdb->fsdb_srpc_tgt; tgtconf != NULL;
2153 tgtconf = tgtconf->mtsc_next) {
2154 if (!strcmp(tgtconf->mtsc_tgt, svname)) {
2163 OBD_ALLOC_PTR(tgtconf);
2164 if (tgtconf == NULL)
2167 name_len = strlen(svname);
2169 OBD_ALLOC(tgtconf->mtsc_tgt, name_len + 1);
2170 if (tgtconf->mtsc_tgt == NULL) {
2171 OBD_FREE_PTR(tgtconf);
2174 memcpy(tgtconf->mtsc_tgt, svname, name_len);
2176 tgtconf->mtsc_next = fsdb->fsdb_srpc_tgt;
2177 fsdb->fsdb_srpc_tgt = tgtconf;
2180 rset = &tgtconf->mtsc_rset;
2182 rset = &fsdb->fsdb_srpc_gen;
2185 rc = sptlrpc_rule_set_merge(rset, &rule);
2190 static int mgs_srpc_set_param(struct obd_device *obd,
2192 struct mgs_target_info *mti,
2196 int rc, copy_size, del;
2202 /* keep a copy of original param, which could be destroied
2204 copy_size = strlen(param) + 1;
2205 OBD_ALLOC(copy, copy_size);
2208 memcpy(copy, param, copy_size);
2210 del = mgs_param_empty(param);
2212 rc = mgs_srpc_set_param_mem(fsdb, mti->mti_svname, param);
2217 /* previous steps guaranteed the syntax is correct */
2218 rc = mgs_srpc_set_param_disk(obd, fsdb, mti, copy);
2222 if (fsdb->fsdb_fl_mgsself) {
2224 * for mgs rules, make them effective immediately.
2226 LASSERT(fsdb->fsdb_srpc_tgt == NULL);
2227 sptlrpc_target_update_exp_flavor(obd, &fsdb->fsdb_srpc_gen);
2231 OBD_FREE(copy, copy_size);
2235 struct mgs_srpc_read_data {
2236 struct fs_db *msrd_fsdb;
2240 static int mgs_srpc_read_handler(struct llog_handle *llh,
2241 struct llog_rec_hdr *rec,
2244 struct mgs_srpc_read_data *msrd = (struct mgs_srpc_read_data *) data;
2245 struct cfg_marker *marker;
2246 struct lustre_cfg *lcfg = (struct lustre_cfg *)(rec + 1);
2247 char *svname, *param;
2251 if (rec->lrh_type != OBD_CFG_REC) {
2252 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
2256 cfg_len = rec->lrh_len - sizeof(struct llog_rec_hdr) -
2257 sizeof(struct llog_rec_tail);
2259 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
2261 CERROR("Insane cfg\n");
2265 if (lcfg->lcfg_command == LCFG_MARKER) {
2266 marker = lustre_cfg_buf(lcfg, 1);
2268 if (marker->cm_flags & CM_START &&
2269 marker->cm_flags & CM_SKIP)
2270 msrd->msrd_skip = 1;
2271 if (marker->cm_flags & CM_END)
2272 msrd->msrd_skip = 0;
2277 if (msrd->msrd_skip)
2280 if (lcfg->lcfg_command != LCFG_SPTLRPC_CONF) {
2281 CERROR("invalid command (%x)\n", lcfg->lcfg_command);
2285 svname = lustre_cfg_string(lcfg, 0);
2286 if (svname == NULL) {
2287 CERROR("svname is empty\n");
2291 param = lustre_cfg_string(lcfg, 1);
2292 if (param == NULL) {
2293 CERROR("param is empty\n");
2297 rc = mgs_srpc_set_param_mem(msrd->msrd_fsdb, svname, param);
2299 CERROR("read sptlrpc record error (%d): %s\n", rc, param);
2304 int mgs_get_fsdb_srpc_from_llog(struct obd_device *obd,
2307 struct llog_handle *llh = NULL;
2308 struct lvfs_run_ctxt saved;
2309 struct llog_ctxt *ctxt;
2311 struct mgs_srpc_read_data msrd;
2315 /* construct log name */
2316 rc = name_create(&logname, fsdb->fsdb_name, "-sptlrpc");
2320 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
2321 LASSERT(ctxt != NULL);
2323 if (mgs_log_is_empty(obd, logname))
2326 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
2328 rc = llog_create(ctxt, &llh, NULL, logname);
2332 rc = llog_init_handle(llh, LLOG_F_IS_PLAIN, NULL);
2334 GOTO(out_close, rc);
2336 if (llog_get_size(llh) <= 1)
2337 GOTO(out_close, rc = 0);
2339 msrd.msrd_fsdb = fsdb;
2342 rc = llog_process(llh, mgs_srpc_read_handler, (void *) &msrd, NULL);
2347 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
2349 llog_ctxt_put(ctxt);
2350 name_destroy(&logname);
2353 CERROR("failed to read sptlrpc config database: %d\n", rc);
2357 /* Permanent settings of all parameters by writing into the appropriate
2358 * configuration logs.
2359 * A parameter with null value ("<param>='\0'") means to erase it out of
2362 static int mgs_write_log_param(struct obd_device *obd, struct fs_db *fsdb,
2363 struct mgs_target_info *mti, char *ptr)
2365 struct lustre_cfg_bufs bufs;
2371 /* For various parameter settings, we have to figure out which logs
2372 care about them (e.g. both mdt and client for lov settings) */
2373 CDEBUG(D_MGS, "next param '%s'\n", ptr);
2375 /* The params are stored in MOUNT_DATA_FILE and modified via
2376 tunefs.lustre, or set using lctl conf_param */
2378 /* Processed in lustre_start_mgc */
2379 if (class_match_param(ptr, PARAM_MGSNODE, NULL) == 0)
2382 /* Processed in mgs_write_log_ost */
2383 if (class_match_param(ptr, PARAM_FAILMODE, NULL) == 0) {
2384 if (mti->mti_flags & LDD_F_PARAM) {
2385 LCONSOLE_ERROR_MSG(0x169, "%s can only be "
2386 "changed with tunefs.lustre"
2387 "and --writeconf\n", ptr);
2393 if (class_match_param(ptr, PARAM_SRPC, NULL) == 0) {
2394 rc = mgs_srpc_set_param(obd, fsdb, mti, ptr);
2398 if (class_match_param(ptr, PARAM_FAILNODE, NULL) == 0) {
2399 /* Add a failover nidlist */
2401 /* We already processed failovers params for new
2402 targets in mgs_write_log_target */
2403 if (mti->mti_flags & LDD_F_PARAM) {
2404 CDEBUG(D_MGS, "Adding failnode\n");
2405 rc = mgs_write_log_add_failnid(obd, fsdb, mti);
2410 if (class_match_param(ptr, PARAM_SYS, &tmp) == 0) {
2411 rc = mgs_write_log_sys(obd, fsdb, mti, ptr, tmp);
2415 if (class_match_param(ptr, PARAM_OSC""PARAM_ACTIVE, &tmp) == 0) {
2416 /* active=0 means off, anything else means on */
2417 int flag = (*tmp == '0') ? CM_EXCLUDE : 0;
2420 if (!(mti->mti_flags & LDD_F_SV_TYPE_OST)) {
2421 LCONSOLE_ERROR_MSG(0x144, "%s: Only OSCs can "
2422 "be (de)activated.\n",
2424 GOTO(end, rc = -EINVAL);
2426 LCONSOLE_WARN("Permanently %sactivating %s\n",
2427 flag ? "de": "re", mti->mti_svname);
2429 name_create(&logname, mti->mti_fsname, "-client");
2430 rc = mgs_modify(obd, fsdb, mti, logname,
2431 mti->mti_svname, "add osc", flag);
2432 name_destroy(&logname);
2436 /* Add to all MDT logs for CMD */
2437 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2438 if (!cfs_test_bit(i, fsdb->fsdb_mdt_index_map))
2440 name_create_mdt(&logname, mti->mti_fsname, i);
2441 rc = mgs_modify(obd, fsdb, mti, logname,
2442 mti->mti_svname, "add osc", flag);
2443 name_destroy(&logname);
2449 LCONSOLE_ERROR_MSG(0x145, "Couldn't find %s in"
2450 "log (%d). No permanent "
2451 "changes were made to the "
2453 mti->mti_svname, rc);
2454 if (fsdb->fsdb_flags & FSDB_OLDLOG14)
2455 LCONSOLE_ERROR_MSG(0x146, "This may be"
2460 "update the logs.\n");
2463 /* Fall through to osc proc for deactivating live OSC
2464 on running MDT / clients. */
2466 /* Below here, let obd's XXX_process_config methods handle it */
2468 /* All lov. in proc */
2469 if (class_match_param(ptr, PARAM_LOV, NULL) == 0) {
2472 CDEBUG(D_MGS, "lov param %s\n", ptr);
2473 if (!(mti->mti_flags & LDD_F_SV_TYPE_MDT)) {
2474 LCONSOLE_ERROR_MSG(0x147, "LOV params must be "
2475 "set on the MDT, not %s. "
2482 if (mgs_log_is_empty(obd, mti->mti_svname))
2483 GOTO(end, rc = -ENODEV);
2485 name_create_mdt_and_lov(&logname, &mdtlovname, fsdb,
2486 mti->mti_stripe_index);
2487 rc = mgs_wlp_lcfg(obd, fsdb, mti, mti->mti_svname,
2488 &bufs, mdtlovname, ptr);
2489 name_destroy(&logname);
2490 name_destroy(&mdtlovname);
2495 name_create(&logname, mti->mti_fsname, "-client");
2496 rc = mgs_wlp_lcfg(obd, fsdb, mti, logname, &bufs,
2497 fsdb->fsdb_clilov, ptr);
2498 name_destroy(&logname);
2502 /* All osc., mdc., llite. params in proc */
2503 if ((class_match_param(ptr, PARAM_OSC, NULL) == 0) ||
2504 (class_match_param(ptr, PARAM_MDC, NULL) == 0) ||
2505 (class_match_param(ptr, PARAM_LLITE, NULL) == 0)) {
2507 if (memcmp(ptr, PARAM_LLITE, strlen(PARAM_LLITE)) == 0) {
2508 name_create(&cname, mti->mti_fsname, "-client");
2509 /* Add the client type to match the obdname in
2510 class_config_llog_handler */
2511 } else if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
2514 name_create(&cname, fsdb->fsdb_mdc, "");
2516 name_create(&cname, mti->mti_svname,
2518 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2520 if (fsdb->fsdb_flags & FSDB_OLDLOG14) {
2521 LCONSOLE_ERROR_MSG(0x148, "Upgraded "
2522 "client logs for %s"
2524 "modified. Consider"
2526 "configuration with"
2529 /* We don't know the names of all the
2531 GOTO(end, rc = -EINVAL);
2533 name_create(&cname, mti->mti_svname, "-osc");
2535 GOTO(end, rc = -EINVAL);
2538 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
2541 name_create(&logname, mti->mti_fsname, "-client");
2542 rc = mgs_wlp_lcfg(obd, fsdb, mti, logname, &bufs,
2545 /* osc params affect the MDT as well */
2546 if (!rc && (mti->mti_flags & LDD_F_SV_TYPE_OST)) {
2549 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
2550 if (!cfs_test_bit(i, fsdb->fsdb_mdt_index_map))
2552 name_destroy(&cname);
2553 name_create_mdt_osc(&cname, mti->mti_svname,
2555 name_destroy(&logname);
2556 name_create_mdt(&logname, mti->mti_fsname, i);
2557 if (!mgs_log_is_empty(obd, logname))
2558 rc = mgs_wlp_lcfg(obd, fsdb,mti,logname,
2564 name_destroy(&logname);
2565 name_destroy(&cname);
2569 /* All mdt. params in proc */
2570 if (class_match_param(ptr, PARAM_MDT, NULL) == 0) {
2574 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
2575 if (strncmp(mti->mti_svname, mti->mti_fsname,
2576 MTI_NAME_MAXLEN) == 0)
2577 /* device is unspecified completely? */
2578 rc = LDD_F_SV_TYPE_MDT | LDD_F_SV_ALL;
2580 rc = server_name2index(mti->mti_svname, &idx, NULL);
2583 if ((rc & LDD_F_SV_TYPE_MDT) == 0)
2585 if (rc & LDD_F_SV_ALL) {
2586 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2587 if (!cfs_test_bit(i,
2588 fsdb->fsdb_mdt_index_map))
2590 name_create_mdt(&logname, mti->mti_fsname, i);
2591 rc = mgs_wlp_lcfg(obd, fsdb, mti,
2594 name_destroy(&logname);
2599 rc = mgs_wlp_lcfg(obd, fsdb, mti,
2600 mti->mti_svname, &bufs,
2601 mti->mti_svname, ptr);
2608 /* All mdd., ost. params in proc */
2609 if ((class_match_param(ptr, PARAM_MDD, NULL) == 0) ||
2610 (class_match_param(ptr, PARAM_OST, NULL) == 0)) {
2611 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
2612 if (mgs_log_is_empty(obd, mti->mti_svname))
2613 GOTO(end, rc = -ENODEV);
2615 rc = mgs_wlp_lcfg(obd, fsdb, mti, mti->mti_svname,
2616 &bufs, mti->mti_svname, ptr);
2620 LCONSOLE_WARN("Ignoring unrecognized param '%s'\n", ptr);
2624 CERROR("err %d on param '%s'\n", rc, ptr);
2629 /* Not implementing automatic failover nid addition at this time. */
2630 int mgs_check_failnid(struct obd_device *obd, struct mgs_target_info *mti)
2637 rc = mgs_find_or_make_fsdb(obd, fsname, &fsdb);
2641 if (mgs_log_is_empty(obd, mti->mti_svname))
2642 /* should never happen */
2645 CDEBUG(D_MGS, "Checking for new failnids for %s\n", mti->mti_svname);
2647 /* FIXME We can just check mti->params to see if we're already in
2648 the failover list. Modify mti->params for rewriting back at
2649 server_register_target(). */
2651 cfs_down(&fsdb->fsdb_sem);
2652 rc = mgs_write_log_add_failnid(obd, fsdb, mti);
2653 cfs_up(&fsdb->fsdb_sem);
2660 int mgs_write_log_target(struct obd_device *obd,
2661 struct mgs_target_info *mti,
2668 /* set/check the new target index */
2669 rc = mgs_set_index(obd, mti);
2671 CERROR("Can't get index (%d)\n", rc);
2676 if (mti->mti_flags & LDD_F_UPGRADE14) {
2677 if (rc == EALREADY) {
2678 LCONSOLE_INFO("Found index %d for %s 1.4 log, "
2679 "upgrading\n", mti->mti_stripe_index,
2682 LCONSOLE_ERROR_MSG(0x149, "Failed to find %s in the old"
2683 " client log. Apparently it is not "
2684 "part of this filesystem, or the old"
2685 " log is wrong.\nUse 'writeconf' on "
2686 "the MDT to force log regeneration."
2687 "\n", mti->mti_svname);
2688 /* Not in client log? Upgrade anyhow...*/
2689 /* Argument against upgrading: reformat MDT,
2690 upgrade OST, then OST will start but will be SKIPped
2691 in client logs. Maybe error now is better. */
2692 /* RETURN(-EINVAL); */
2694 /* end COMPAT_146 */
2696 if (rc == EALREADY) {
2697 LCONSOLE_WARN("Found index %d for %s, updating log\n",
2698 mti->mti_stripe_index, mti->mti_svname);
2699 /* We would like to mark old log sections as invalid
2700 and add new log sections in the client and mdt logs.
2701 But if we add new sections, then live clients will
2702 get repeat setup instructions for already running
2703 osc's. So don't update the client/mdt logs. */
2704 mti->mti_flags &= ~LDD_F_UPDATE;
2708 cfs_down(&fsdb->fsdb_sem);
2710 if (mti->mti_flags &
2711 (LDD_F_VIRGIN | LDD_F_UPGRADE14 | LDD_F_WRITECONF)) {
2712 /* Generate a log from scratch */
2713 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
2714 rc = mgs_write_log_mdt(obd, fsdb, mti);
2715 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2716 rc = mgs_write_log_ost(obd, fsdb, mti);
2718 CERROR("Unknown target type %#x, can't create log for "
2719 "%s\n", mti->mti_flags, mti->mti_svname);
2722 CERROR("Can't write logs for %s (%d)\n",
2723 mti->mti_svname, rc);
2727 /* Just update the params from tunefs in mgs_write_log_params */
2728 CDEBUG(D_MGS, "Update params for %s\n", mti->mti_svname);
2729 mti->mti_flags |= LDD_F_PARAM;
2732 /* allocate temporary buffer, where class_get_next_param will
2733 make copy of a current parameter */
2734 OBD_ALLOC(buf, strlen(mti->mti_params) + 1);
2736 GOTO(out_up, rc = -ENOMEM);
2737 params = mti->mti_params;
2738 while (params != NULL) {
2739 rc = class_get_next_param(¶ms, buf);
2742 /* there is no next parameter, that is
2747 CDEBUG(D_MGS, "remaining string: '%s', param: '%s'\n",
2749 rc = mgs_write_log_param(obd, fsdb, mti, buf);
2754 OBD_FREE(buf, strlen(mti->mti_params) + 1);
2757 cfs_up(&fsdb->fsdb_sem);
2762 /* verify that we can handle the old config logs */
2763 int mgs_upgrade_sv_14(struct obd_device *obd, struct mgs_target_info *mti,
2769 /* Create ost log normally, as servers register. Servers
2770 register with their old uuids (from last_rcvd), so old
2771 (MDT and client) logs should work.
2772 - new MDT won't know about old OSTs, only the ones that have
2773 registered, so we need the old MDT log to get the LOV right
2774 in order for old clients to work.
2775 - Old clients connect to the MDT, not the MGS, for their logs, and
2776 will therefore receive the old client log from the MDT /LOGS dir.
2777 - Old clients can continue to use and connect to old or new OSTs
2778 - New clients will contact the MGS for their log
2781 LCONSOLE_INFO("upgrading server %s from pre-1.6\n", mti->mti_svname);
2782 server_mti_print("upgrade", mti);
2784 if (fsdb->fsdb_flags & FSDB_LOG_EMPTY) {
2785 LCONSOLE_ERROR_MSG(0x14a, "The old client log %s-client is "
2786 "missing. Was tunefs.lustre successful?\n",
2791 if (fsdb->fsdb_gen == 0) {
2792 /* There were no markers in the client log, meaning we have
2793 not updated the logs for this fs */
2794 CDEBUG(D_MGS, "found old, unupdated client log\n");
2797 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
2798 if (mgs_log_is_empty(obd, mti->mti_svname)) {
2799 LCONSOLE_ERROR_MSG(0x14b, "The old MDT log %s is "
2800 "missing. Was tunefs.lustre "
2805 /* We're starting with an old uuid. Assume old name for lov
2806 as well since the lov entry already exists in the log. */
2807 CDEBUG(D_MGS, "old mds uuid %s\n", mti->mti_uuid);
2808 if (strncmp(mti->mti_uuid, fsdb->fsdb_mdtlov + 4,
2809 strlen(fsdb->fsdb_mdtlov) - 4) != 0) {
2810 CERROR("old mds uuid %s doesn't match log %s (%s)\n",
2811 mti->mti_uuid, fsdb->fsdb_mdtlov,
2812 fsdb->fsdb_mdtlov + 4);
2817 if (!(fsdb->fsdb_flags & FSDB_OLDLOG14)) {
2818 LCONSOLE_ERROR_MSG(0x14c, "%s-client is supposedly an old "
2819 "log, but no old LOV or MDT was found. "
2820 "Consider updating the configuration with"
2821 " --writeconf.\n", mti->mti_fsname);
2826 /* end COMPAT_146 */
2828 int mgs_erase_log(struct obd_device *obd, char *name)
2830 struct lvfs_run_ctxt saved;
2831 struct llog_ctxt *ctxt;
2832 struct llog_handle *llh;
2835 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
2836 LASSERT(ctxt != NULL);
2838 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
2839 rc = llog_create(ctxt, &llh, NULL, name);
2841 llog_init_handle(llh, LLOG_F_IS_PLAIN, NULL);
2842 rc = llog_destroy(llh);
2843 llog_free_handle(llh);
2845 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
2846 llog_ctxt_put(ctxt);
2849 CERROR("failed to clear log %s: %d\n", name, rc);
2854 /* erase all logs for the given fs */
2855 int mgs_erase_logs(struct obd_device *obd, char *fsname)
2857 struct mgs_obd *mgs = &obd->u.mgs;
2858 static struct fs_db *fsdb;
2859 cfs_list_t dentry_list;
2860 struct l_linux_dirent *dirent, *n;
2861 int rc, len = strlen(fsname);
2865 /* Find all the logs in the CONFIGS directory */
2866 rc = class_dentry_readdir(obd, mgs->mgs_configs_dir,
2867 mgs->mgs_vfsmnt, &dentry_list);
2869 CERROR("Can't read %s dir\n", MOUNT_CONFIGS_DIR);
2873 cfs_down(&mgs->mgs_sem);
2875 /* Delete the fs db */
2876 fsdb = mgs_find_fsdb(obd, fsname);
2878 mgs_free_fsdb(obd, fsdb);
2880 cfs_list_for_each_entry_safe(dirent, n, &dentry_list, lld_list) {
2881 cfs_list_del(&dirent->lld_list);
2882 suffix = strrchr(dirent->lld_name, '-');
2883 if (suffix != NULL) {
2884 if ((len == suffix - dirent->lld_name) &&
2885 (strncmp(fsname, dirent->lld_name, len) == 0)) {
2886 CDEBUG(D_MGS, "Removing log %s\n",
2888 mgs_erase_log(obd, dirent->lld_name);
2891 OBD_FREE(dirent, sizeof(*dirent));
2894 cfs_up(&mgs->mgs_sem);
2899 /* from llog_swab */
2900 static void print_lustre_cfg(struct lustre_cfg *lcfg)
2905 CDEBUG(D_MGS, "lustre_cfg: %p\n", lcfg);
2906 CDEBUG(D_MGS, "\tlcfg->lcfg_version: %#x\n", lcfg->lcfg_version);
2908 CDEBUG(D_MGS, "\tlcfg->lcfg_command: %#x\n", lcfg->lcfg_command);
2909 CDEBUG(D_MGS, "\tlcfg->lcfg_num: %#x\n", lcfg->lcfg_num);
2910 CDEBUG(D_MGS, "\tlcfg->lcfg_flags: %#x\n", lcfg->lcfg_flags);
2911 CDEBUG(D_MGS, "\tlcfg->lcfg_nid: %s\n", libcfs_nid2str(lcfg->lcfg_nid));
2913 CDEBUG(D_MGS, "\tlcfg->lcfg_bufcount: %d\n", lcfg->lcfg_bufcount);
2914 if (lcfg->lcfg_bufcount < LUSTRE_CFG_MAX_BUFCOUNT)
2915 for (i = 0; i < lcfg->lcfg_bufcount; i++) {
2916 CDEBUG(D_MGS, "\tlcfg->lcfg_buflens[%d]: %d %s\n",
2917 i, lcfg->lcfg_buflens[i],
2918 lustre_cfg_string(lcfg, i));
2923 /* Set a permanent (config log) param for a target or fs
2924 * \param lcfg buf0 may contain the device (testfs-MDT0000) name
2925 * buf1 contains the single parameter
2927 int mgs_setparam(struct obd_device *obd, struct lustre_cfg *lcfg, char *fsname)
2930 struct mgs_target_info *mti;
2931 char *devname, *param;
2937 print_lustre_cfg(lcfg);
2939 /* lustre, lustre-mdtlov, lustre-client, lustre-MDT0000 */
2940 devname = lustre_cfg_string(lcfg, 0);
2941 param = lustre_cfg_string(lcfg, 1);
2943 /* Assume device name embedded in param:
2944 lustre-OST0000.osc.max_dirty_mb=32 */
2945 ptr = strchr(param, '.');
2953 LCONSOLE_ERROR_MSG(0x14d, "No target specified: %s\n", param);
2957 /* Extract fsname */
2958 ptr = strrchr(devname, '-');
2959 memset(fsname, 0, MTI_NAME_MAXLEN);
2960 if (ptr && (server_name2index(ptr, &index, NULL) >= 0)) {
2961 /* param related to llite isn't allowed to set by OST or MDT */
2962 if (strncmp(param, PARAM_LLITE, sizeof(PARAM_LLITE)) == 0)
2965 strncpy(fsname, devname, ptr - devname);
2967 /* assume devname is the fsname */
2968 strncpy(fsname, devname, MTI_NAME_MAXLEN);
2970 fsname[MTI_NAME_MAXLEN - 1] = 0;
2971 CDEBUG(D_MGS, "setparam fs='%s' device='%s'\n", fsname, devname);
2973 rc = mgs_find_or_make_fsdb(obd, fsname, &fsdb);
2976 if (!fsdb->fsdb_fl_mgsself && fsdb->fsdb_flags & FSDB_LOG_EMPTY) {
2977 CERROR("No filesystem targets for %s. cfg_device from lctl "
2978 "is '%s'\n", fsname, devname);
2979 mgs_free_fsdb(obd, fsdb);
2983 /* Create a fake mti to hold everything */
2986 GOTO(out, rc = -ENOMEM);
2987 strncpy(mti->mti_fsname, fsname, MTI_NAME_MAXLEN);
2988 strncpy(mti->mti_svname, devname, MTI_NAME_MAXLEN);
2989 strncpy(mti->mti_params, param, sizeof(mti->mti_params));
2990 rc = server_name2index(mti->mti_svname, &mti->mti_stripe_index, &tmp);
2992 /* Not a valid server; may be only fsname */
2995 /* Strip -osc or -mdc suffix from svname */
2996 if (server_make_name(rc, mti->mti_stripe_index, mti->mti_fsname,
2998 GOTO(out, rc = -EINVAL);
3000 mti->mti_flags = rc | LDD_F_PARAM;
3002 cfs_down(&fsdb->fsdb_sem);
3003 rc = mgs_write_log_param(obd, fsdb, mti, mti->mti_params);
3004 cfs_up(&fsdb->fsdb_sem);
3007 * Revoke lock so everyone updates. Should be alright if
3008 * someone was already reading while we were updating the logs,
3009 * so we don't really need to hold the lock while we're
3012 mgs_revoke_lock(obd, fsdb);
3018 static int mgs_write_log_pool(struct obd_device *obd, char *logname,
3019 struct fs_db *fsdb, char *lovname,
3020 enum lcfg_command_type cmd,
3021 char *poolname, char *fsname,
3022 char *ostname, char *comment)
3024 struct llog_handle *llh = NULL;
3027 rc = record_start_log(obd, &llh, logname);
3030 rc = record_marker(obd, llh, fsdb, CM_START, lovname, comment);
3031 record_base(obd, llh, lovname, 0, cmd, poolname, fsname, ostname, 0);
3032 rc = record_marker(obd, llh, fsdb, CM_END, lovname, comment);
3033 rc = record_end_log(obd, &llh);
3038 int mgs_pool_cmd(struct obd_device *obd, enum lcfg_command_type cmd,
3039 char *fsname, char *poolname, char *ostname)
3044 char *label = NULL, *canceled_label = NULL;
3046 struct mgs_target_info *mti = NULL;
3050 rc = mgs_find_or_make_fsdb(obd, fsname, &fsdb);
3052 CERROR("Can't get db for %s\n", fsname);
3055 if (fsdb->fsdb_flags & FSDB_LOG_EMPTY) {
3056 CERROR("%s is not defined\n", fsname);
3057 mgs_free_fsdb(obd, fsdb);
3061 label_sz = 10 + strlen(fsname) + strlen(poolname);
3063 /* check if ostname match fsname */
3064 if (ostname != NULL) {
3067 ptr = strrchr(ostname, '-');
3068 if ((ptr == NULL) ||
3069 (strncmp(fsname, ostname, ptr-ostname) != 0))
3071 label_sz += strlen(ostname);
3074 OBD_ALLOC(label, label_sz);
3076 GOTO(out, rc = -ENOMEM);
3079 case LCFG_POOL_NEW: {
3081 "new %s.%s", fsname, poolname);
3084 case LCFG_POOL_ADD: {
3086 "add %s.%s.%s", fsname, poolname, ostname);
3089 case LCFG_POOL_REM: {
3090 OBD_ALLOC(canceled_label, label_sz);
3091 if (canceled_label == NULL)
3092 GOTO(out, rc = -ENOMEM);
3094 "rem %s.%s.%s", fsname, poolname, ostname);
3095 sprintf(canceled_label,
3096 "add %s.%s.%s", fsname, poolname, ostname);
3099 case LCFG_POOL_DEL: {
3100 OBD_ALLOC(canceled_label, label_sz);
3101 if (canceled_label == NULL)
3102 GOTO(out, rc = -ENOMEM);
3104 "del %s.%s", fsname, poolname);
3105 sprintf(canceled_label,
3106 "new %s.%s", fsname, poolname);
3114 cfs_down(&fsdb->fsdb_sem);
3116 if (canceled_label != NULL) {
3119 GOTO(out, rc = -ENOMEM);
3122 /* write pool def to all MDT logs */
3123 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3124 if (cfs_test_bit(i, fsdb->fsdb_mdt_index_map)) {
3125 name_create_mdt_and_lov(&logname, &lovname, fsdb, i);
3127 if (canceled_label != NULL) {
3128 strcpy(mti->mti_svname, "lov pool");
3129 mgs_modify(obd, fsdb, mti, logname, lovname,
3130 canceled_label, CM_SKIP);
3133 mgs_write_log_pool(obd, logname, fsdb, lovname,
3134 cmd, fsname, poolname, ostname,
3136 name_destroy(&logname);
3137 name_destroy(&lovname);
3141 name_create(&logname, fsname, "-client");
3142 if (canceled_label != NULL)
3143 mgs_modify(obd, fsdb, mti, logname, fsdb->fsdb_clilov,
3144 canceled_label, CM_SKIP);
3146 mgs_write_log_pool(obd, logname, fsdb, fsdb->fsdb_clilov,
3147 cmd, fsname, poolname, ostname, label);
3148 name_destroy(&logname);
3150 cfs_up(&fsdb->fsdb_sem);
3151 /* request for update */
3152 mgs_revoke_lock(obd, fsdb);
3157 OBD_FREE(label, label_sz);
3159 if (canceled_label != NULL)
3160 OBD_FREE(canceled_label, label_sz);
3169 /******************** unused *********************/
3170 static int mgs_backup_llog(struct obd_device *obd, char* fsname)
3172 struct file *filp, *bak_filp;
3173 struct lvfs_run_ctxt saved;
3174 char *logname, *buf;
3175 loff_t soff = 0 , doff = 0;
3176 int count = 4096, len;
3179 OBD_ALLOC(logname, PATH_MAX);
3180 if (logname == NULL)
3183 OBD_ALLOC(buf, count);
3185 GOTO(out , rc = -ENOMEM);
3187 len = snprintf(logname, PATH_MAX, "%s/%s.bak",
3188 MOUNT_CONFIGS_DIR, fsname);
3190 if (len >= PATH_MAX - 1) {
3191 GOTO(out, -ENAMETOOLONG);
3194 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
3196 bak_filp = l_filp_open(logname, O_RDWR|O_CREAT|O_TRUNC, 0660);
3197 if (IS_ERR(bak_filp)) {
3198 rc = PTR_ERR(bak_filp);
3199 CERROR("backup logfile open %s: %d\n", logname, rc);
3202 sprintf(logname, "%s/%s", MOUNT_CONFIGS_DIR, fsname);
3203 filp = l_filp_open(logname, O_RDONLY, 0);
3206 CERROR("logfile open %s: %d\n", logname, rc);
3210 while ((rc = lustre_fread(filp, buf, count, &soff)) > 0) {
3211 rc = lustre_fwrite(bak_filp, buf, count, &doff);
3215 filp_close(filp, 0);
3217 filp_close(bak_filp, 0);
3219 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
3222 OBD_FREE(buf, count);
3223 OBD_FREE(logname, PATH_MAX);