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 (c) 2007, 2010, Oracle and/or its affiliates. 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 = ll_dentry_open(dentry, mnt, O_RDONLY, current_cred());
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 cfs_set_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags);
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 cfs_set_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags);
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 (!cfs_test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags) &&
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 cfs_set_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags);
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 cfs_set_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags);
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 cfs_set_bit(FSDB_UDESC, &fsdb->fsdb_flags);
362 if (strcmp(fsname, MGSSELF_NAME) == 0) {
363 cfs_set_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags);
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 (!cfs_test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
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 (cfs_test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags))
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 cfs_clear_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags);
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 *);
1076 static int mgs_write_log_osc_to_lov(struct obd_device *obd, struct fs_db *fsdb,
1077 struct mgs_target_info *mti,
1078 char *logname, char *suffix, char *lovname,
1079 enum lustre_sec_part sec_part, int flags);
1080 static void name_create_mdt_and_lov(char **logname, char **lovname,
1081 struct fs_db *fsdb, int i);
1083 static int mgs_steal_llog_handler(struct llog_handle *llh,
1084 struct llog_rec_hdr *rec,
1087 struct obd_device * obd;
1088 struct mgs_target_info *mti, *tmti;
1090 int cfg_len = rec->lrh_len;
1091 char *cfg_buf = (char*) (rec + 1);
1092 struct lustre_cfg *lcfg;
1094 struct llog_handle *mdt_llh = NULL;
1095 static int got_an_osc_or_mdc = 0;
1096 /* 0: not found any osc/mdc;
1100 static int last_step = -1;
1104 mti = ((struct temp_comp*)data)->comp_mti;
1105 tmti = ((struct temp_comp*)data)->comp_tmti;
1106 fsdb = ((struct temp_comp*)data)->comp_fsdb;
1107 obd = ((struct temp_comp*)data)->comp_obd;
1109 if (rec->lrh_type != OBD_CFG_REC) {
1110 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
1114 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
1116 CERROR("Insane cfg\n");
1120 lcfg = (struct lustre_cfg *)cfg_buf;
1122 if (lcfg->lcfg_command == LCFG_MARKER) {
1123 struct cfg_marker *marker;
1124 marker = lustre_cfg_buf(lcfg, 1);
1125 if (!strncmp(marker->cm_comment,"add osc",7) &&
1126 (marker->cm_flags & CM_START)){
1127 got_an_osc_or_mdc = 1;
1128 rc = record_start_log(obd, &mdt_llh, mti->mti_svname);
1129 rc = record_marker(obd, mdt_llh, fsdb, CM_START,
1130 mti->mti_svname,"add osc(copied)");
1131 rc = record_end_log(obd, &mdt_llh);
1132 last_step = marker->cm_step;
1135 if (!strncmp(marker->cm_comment,"add osc",7) &&
1136 (marker->cm_flags & CM_END)){
1137 LASSERT(last_step == marker->cm_step);
1139 got_an_osc_or_mdc = 0;
1140 rc = record_start_log(obd, &mdt_llh, mti->mti_svname);
1141 rc = record_marker(obd, mdt_llh, fsdb, CM_END,
1142 mti->mti_svname,"add osc(copied)");
1143 rc = record_end_log(obd, &mdt_llh);
1146 if (!strncmp(marker->cm_comment,"add mdc",7) &&
1147 (marker->cm_flags & CM_START)){
1148 got_an_osc_or_mdc = 2;
1149 last_step = marker->cm_step;
1150 memcpy(tmti->mti_svname, marker->cm_tgtname,
1151 strlen(marker->cm_tgtname));
1155 if (!strncmp(marker->cm_comment,"add mdc",7) &&
1156 (marker->cm_flags & CM_END)){
1157 LASSERT(last_step == marker->cm_step);
1159 got_an_osc_or_mdc = 0;
1164 if (got_an_osc_or_mdc == 0 || last_step < 0)
1167 if (lcfg->lcfg_command == LCFG_ADD_UUID) {
1169 nodenid = lcfg->lcfg_nid;
1171 tmti->mti_nids[tmti->mti_nid_count] = nodenid;
1172 tmti->mti_nid_count++;
1177 if (lcfg->lcfg_command == LCFG_SETUP) {
1180 target = lustre_cfg_string(lcfg, 1);
1181 memcpy(tmti->mti_uuid, target, strlen(target));
1185 /* ignore client side sptlrpc_conf_log */
1186 if (lcfg->lcfg_command == LCFG_SPTLRPC_CONF)
1189 if (lcfg->lcfg_command == LCFG_ADD_MDC) {
1192 if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1)
1195 memcpy(tmti->mti_fsname, mti->mti_fsname,
1196 strlen(mti->mti_fsname));
1197 tmti->mti_stripe_index = index;
1199 mgs_write_log_mdc_to_mdt(obd, fsdb, tmti, mti->mti_svname);
1200 memset(tmti, 0, sizeof(*tmti));
1204 if (lcfg->lcfg_command == LCFG_LOV_ADD_OBD) {
1206 char *logname, *lovname;
1208 name_create_mdt_and_lov(&logname, &lovname, fsdb, mti->mti_stripe_index);
1209 sprintf(mdt_index, "-MDT%04x", mti->mti_stripe_index);
1211 mgs_write_log_osc_to_lov(obd, fsdb, tmti, logname,
1214 name_destroy(&logname);
1215 name_destroy(&lovname);
1221 /* fsdb->fsdb_sem is already held in mgs_write_log_target*/
1222 /* stealed from mgs_get_fsdb_from_llog*/
1223 static int mgs_steal_llog_for_mdt_from_client(struct obd_device *obd,
1225 struct temp_comp* comp)
1227 struct llog_handle *loghandle;
1228 struct lvfs_run_ctxt saved;
1229 struct mgs_target_info *tmti;
1230 struct llog_ctxt *ctxt;
1234 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
1235 LASSERT(ctxt != NULL);
1237 OBD_ALLOC_PTR(tmti);
1241 comp->comp_tmti = tmti;
1242 comp->comp_obd = obd;
1244 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
1246 rc = llog_create(ctxt, &loghandle, NULL, client_name);
1250 rc = llog_init_handle(loghandle, LLOG_F_IS_PLAIN, NULL);
1252 GOTO(out_close, rc);
1254 rc = llog_process(loghandle, mgs_steal_llog_handler, (void *)comp, NULL);
1255 CDEBUG(D_MGS, "steal llog re = %d\n", rc);
1257 rc2 = llog_close(loghandle);
1261 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
1263 llog_ctxt_put(ctxt);
1267 /* lmv is the second thing for client logs */
1268 /* copied from mgs_write_log_lov. Please refer to that. */
1269 static int mgs_write_log_lmv(struct obd_device *obd, struct fs_db *fsdb,
1270 struct mgs_target_info *mti,
1271 char *logname, char *lmvname)
1273 struct llog_handle *llh = NULL;
1274 struct lmv_desc *lmvdesc;
1279 CDEBUG(D_MGS, "Writing lmv(%s) log for %s\n", lmvname,logname);
1281 OBD_ALLOC_PTR(lmvdesc);
1282 if (lmvdesc == NULL)
1284 lmvdesc->ld_active_tgt_count = 0;
1285 lmvdesc->ld_tgt_count = 0;
1286 sprintf((char*)lmvdesc->ld_uuid.uuid, "%s_UUID", lmvname);
1287 uuid = (char *)lmvdesc->ld_uuid.uuid;
1289 rc = record_start_log(obd, &llh, logname);
1290 rc = record_marker(obd, llh, fsdb, CM_START, lmvname, "lmv setup");
1291 rc = record_attach(obd, llh, lmvname, "lmv", uuid);
1292 rc = record_lmv_setup(obd, llh, lmvname, lmvdesc);
1293 rc = record_marker(obd, llh, fsdb, CM_END, lmvname, "lmv setup");
1294 rc = record_end_log(obd, &llh);
1296 OBD_FREE_PTR(lmvdesc);
1300 /* lov is the first thing in the mdt and client logs */
1301 static int mgs_write_log_lov(struct obd_device *obd, struct fs_db *fsdb,
1302 struct mgs_target_info *mti,
1303 char *logname, char *lovname)
1305 struct llog_handle *llh = NULL;
1306 struct lov_desc *lovdesc;
1311 CDEBUG(D_MGS, "Writing lov(%s) log for %s\n", lovname, logname);
1314 #01 L attach 0:lov_mdsA 1:lov 2:71ccb_lov_mdsA_19f961a9e1
1315 #02 L lov_setup 0:lov_mdsA 1:(struct lov_desc)
1316 uuid=lov1_UUID, stripe count=1, size=1048576, offset=0, pattern=0
1319 /* FIXME just make lov_setup accept empty desc (put uuid in buf 2) */
1320 OBD_ALLOC_PTR(lovdesc);
1321 if (lovdesc == NULL)
1323 lovdesc->ld_magic = LOV_DESC_MAGIC;
1324 lovdesc->ld_tgt_count = 0;
1325 /* Defaults. Can be changed later by lcfg config_param */
1326 lovdesc->ld_default_stripe_count = 1;
1327 lovdesc->ld_pattern = LOV_PATTERN_RAID0;
1328 lovdesc->ld_default_stripe_size = 1024 * 1024;
1329 lovdesc->ld_default_stripe_offset = -1;
1330 lovdesc->ld_qos_maxage = QOS_DEFAULT_MAXAGE;
1331 sprintf((char*)lovdesc->ld_uuid.uuid, "%s_UUID", lovname);
1332 /* can these be the same? */
1333 uuid = (char *)lovdesc->ld_uuid.uuid;
1335 /* This should always be the first entry in a log.
1336 rc = mgs_clear_log(obd, logname); */
1337 rc = record_start_log(obd, &llh, logname);
1340 /* FIXME these should be a single journal transaction */
1341 rc = record_marker(obd, llh, fsdb, CM_START, lovname, "lov setup");
1342 rc = record_attach(obd, llh, lovname, "lov", uuid);
1343 rc = record_lov_setup(obd, llh, lovname, lovdesc);
1344 rc = record_marker(obd, llh, fsdb, CM_END, lovname, "lov setup");
1345 rc = record_end_log(obd, &llh);
1349 OBD_FREE_PTR(lovdesc);
1353 /* add failnids to open log */
1354 static int mgs_write_log_failnids(struct obd_device *obd,
1355 struct mgs_target_info *mti,
1356 struct llog_handle *llh,
1359 char *failnodeuuid = NULL;
1360 char *ptr = mti->mti_params;
1365 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) nal=90 0: 1:uml1_UUID
1366 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
1367 #05 L setup 0:OSC_uml1_ost1_mdsA 1:ost1_UUID 2:uml1_UUID
1368 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) nal=90 0: 1:uml2_UUID
1369 #0x L add_uuid nid=2@elan(0x1000000000002) nal=90 0: 1:uml2_UUID
1370 #07 L add_conn 0:OSC_uml1_ost1_mdsA 1:uml2_UUID
1373 /* Pull failnid info out of params string */
1374 while (class_find_param(ptr, PARAM_FAILNODE, &ptr) == 0) {
1375 while (class_parse_nid(ptr, &nid, &ptr) == 0) {
1376 if (failnodeuuid == NULL) {
1377 /* We don't know the failover node name,
1378 so just use the first nid as the uuid */
1379 rc = name_create(&failnodeuuid,
1380 libcfs_nid2str(nid), "");
1384 CDEBUG(D_MGS, "add nid %s for failover uuid %s, "
1385 "client %s\n", libcfs_nid2str(nid),
1386 failnodeuuid, cliname);
1387 rc = record_add_uuid(obd, llh, nid, failnodeuuid);
1390 rc = record_add_conn(obd, llh, cliname, failnodeuuid);
1391 name_destroy(&failnodeuuid);
1392 failnodeuuid = NULL;
1399 static int mgs_write_log_mdc_to_lmv(struct obd_device *obd, struct fs_db *fsdb,
1400 struct mgs_target_info *mti,
1401 char *logname, char *lmvname)
1403 struct llog_handle *llh = NULL;
1404 char *mdcname, *nodeuuid, *mdcuuid, *lmvuuid;
1409 if (mgs_log_is_empty(obd, logname)) {
1410 CERROR("log is empty! Logical error\n");
1414 CDEBUG(D_MGS, "adding mdc for %s to log %s:lmv(%s)\n",
1415 mti->mti_svname, logname, lmvname);
1417 name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
1418 name_create(&mdcname, mti->mti_svname, "-mdc");
1419 name_create(&mdcuuid, mdcname, "_UUID");
1420 name_create(&lmvuuid, lmvname, "_UUID");
1422 rc = record_start_log(obd, &llh, logname);
1423 rc = record_marker(obd, llh, fsdb, CM_START, mti->mti_svname,
1426 for (i = 0; i < mti->mti_nid_count; i++) {
1427 CDEBUG(D_MGS, "add nid %s for mdt\n",
1428 libcfs_nid2str(mti->mti_nids[i]));
1430 rc = record_add_uuid(obd, llh, mti->mti_nids[i], nodeuuid);
1433 rc = record_attach(obd, llh, mdcname, LUSTRE_MDC_NAME, lmvuuid);
1434 rc = record_setup(obd, llh, mdcname, mti->mti_uuid, nodeuuid, 0, 0);
1435 rc = mgs_write_log_failnids(obd, mti, llh, mdcname);
1436 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
1437 rc = record_mdc_add(obd, llh, lmvname, mdcuuid, mti->mti_uuid,
1439 rc = record_marker(obd, llh, fsdb, CM_END, mti->mti_svname,
1441 rc = record_end_log(obd, &llh);
1443 name_destroy(&lmvuuid);
1444 name_destroy(&mdcuuid);
1445 name_destroy(&mdcname);
1446 name_destroy(&nodeuuid);
1450 /* add new mdc to already existent MDS */
1451 static int mgs_write_log_mdc_to_mdt(struct obd_device *obd, struct fs_db *fsdb,
1452 struct mgs_target_info *mti, char *logname)
1454 struct llog_handle *llh = NULL;
1455 char *nodeuuid, *mdcname, *mdcuuid, *mdtuuid;
1456 int idx = mti->mti_stripe_index;
1461 if (mgs_log_is_empty(obd, logname)) {
1462 CERROR("log is empty! Logical error\n");
1466 CDEBUG(D_MGS, "adding mdc index %d to %s\n", idx, logname);
1468 name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
1469 snprintf(index, sizeof(index), "-mdc%04x", idx);
1470 name_create(&mdcname, logname, index);
1471 name_create(&mdcuuid, mdcname, "_UUID");
1472 name_create(&mdtuuid, logname, "_UUID");
1474 rc = record_start_log(obd, &llh, logname);
1475 rc = record_marker(obd, llh, fsdb, CM_START, mti->mti_svname, "add mdc");
1476 for (i = 0; i < mti->mti_nid_count; i++) {
1477 CDEBUG(D_MGS, "add nid %s for mdt\n",
1478 libcfs_nid2str(mti->mti_nids[i]));
1479 rc = record_add_uuid(obd, llh, mti->mti_nids[i], nodeuuid);
1481 rc = record_attach(obd, llh, mdcname, LUSTRE_MDC_NAME, mdcuuid);
1482 rc = record_setup(obd, llh, mdcname, mti->mti_uuid, nodeuuid, 0, 0);
1483 rc = mgs_write_log_failnids(obd, mti, llh, mdcname);
1484 snprintf(index, sizeof(index), "%d", idx);
1486 rc = record_mdc_add(obd, llh, logname, mdcuuid, mti->mti_uuid,
1488 rc = record_marker(obd, llh, fsdb, CM_END, mti->mti_svname, "add mdc");
1489 rc = record_end_log(obd, &llh);
1491 name_destroy(&mdcuuid);
1492 name_destroy(&mdcname);
1493 name_destroy(&nodeuuid);
1494 name_destroy(&mdtuuid);
1498 static int mgs_write_log_mdt0(struct obd_device *obd, struct fs_db *fsdb,
1499 struct mgs_target_info *mti)
1501 char *log = mti->mti_svname;
1502 struct llog_handle *llh = NULL;
1503 char *uuid, *lovname;
1505 char *ptr = mti->mti_params;
1506 int rc = 0, failout = 0;
1509 OBD_ALLOC(uuid, sizeof(struct obd_uuid));
1513 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
1514 failout = (strncmp(ptr, "failout", 7) == 0);
1516 name_create(&lovname, log, "-mdtlov");
1517 if (mgs_log_is_empty(obd, log))
1518 rc = mgs_write_log_lov(obd, fsdb, mti, log, lovname);
1520 sprintf(uuid, "%s_UUID", log);
1521 sprintf(mdt_index, "%d", mti->mti_stripe_index);
1523 /* add MDT itself */
1524 rc = record_start_log(obd, &llh, log);
1528 /* FIXME this whole fn should be a single journal transaction */
1529 rc = record_marker(obd, llh, fsdb, CM_START, log, "add mdt");
1530 rc = record_attach(obd, llh, log, LUSTRE_MDT_NAME, uuid);
1531 rc = record_mount_opt(obd, llh, log, lovname, NULL);
1532 rc = record_setup(obd, llh, log, uuid, mdt_index, lovname,
1533 failout ? "n" : "f");
1534 rc = record_marker(obd, llh, fsdb, CM_END, log, "add mdt");
1535 rc = record_end_log(obd, &llh);
1537 name_destroy(&lovname);
1538 OBD_FREE(uuid, sizeof(struct obd_uuid));
1542 static inline void name_create_mdt(char **logname, char *fsname, int i)
1546 sprintf(mdt_index, "-MDT%04x", i);
1547 name_create(logname, fsname, mdt_index);
1550 static void name_create_mdt_and_lov(char **logname, char **lovname,
1551 struct fs_db *fsdb, int i)
1553 name_create_mdt(logname, fsdb->fsdb_name, i);
1555 if (i == 0 && cfs_test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
1556 name_create(lovname, fsdb->fsdb_name, "-mdtlov");
1558 name_create(lovname, *logname, "-mdtlov");
1561 static inline void name_create_mdt_osc(char **oscname, char *ostname,
1562 struct fs_db *fsdb, int i)
1566 if (i == 0 && cfs_test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
1567 sprintf(suffix, "-osc");
1569 sprintf(suffix, "-osc-MDT%04x", i);
1570 name_create(oscname, ostname, suffix);
1573 /* envelope method for all layers log */
1574 static int mgs_write_log_mdt(struct obd_device *obd, struct fs_db *fsdb,
1575 struct mgs_target_info *mti)
1577 struct llog_handle *llh = NULL;
1579 struct temp_comp comp = { 0 };
1583 CDEBUG(D_MGS, "writing new mdt %s\n", mti->mti_svname);
1587 if (mti->mti_flags & LDD_F_UPGRADE14) {
1588 /* We're starting with an old uuid. Assume old name for lov
1589 as well since the lov entry already exists in the log. */
1590 CDEBUG(D_MGS, "old mds uuid %s\n", mti->mti_uuid);
1591 if (strncmp(mti->mti_uuid, fsdb->fsdb_mdtlov + 4,
1592 strlen(fsdb->fsdb_mdtlov) - 4) != 0) {
1593 CERROR("old mds uuid %s doesn't match log %s (%s)\n",
1594 mti->mti_uuid, fsdb->fsdb_mdtlov,
1595 fsdb->fsdb_mdtlov + 4);
1599 /* end COMPAT_146 */
1601 if (mti->mti_uuid[0] == '\0') {
1602 /* Make up our own uuid */
1603 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
1604 "%s_UUID", mti->mti_svname);
1608 rc = mgs_write_log_mdt0(obd, fsdb, mti);
1610 /* Append the mdt info to the client log */
1611 name_create(&cliname, mti->mti_fsname, "-client");
1613 if (mgs_log_is_empty(obd, cliname)) {
1614 /* Start client log */
1615 rc = mgs_write_log_lov(obd, fsdb, mti, cliname,
1617 rc = mgs_write_log_lmv(obd, fsdb, mti, cliname,
1622 #09 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
1623 #10 L attach 0:MDC_uml1_mdsA_MNT_client 1:mdc 2:1d834_MNT_client_03f
1624 #11 L setup 0:MDC_uml1_mdsA_MNT_client 1:mdsA_UUID 2:uml1_UUID
1625 #12 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
1626 #13 L add_conn 0:MDC_uml1_mdsA_MNT_client 1:uml2_UUID
1627 #14 L mount_option 0: 1:client 2:lov1 3:MDC_uml1_mdsA_MNT_client
1632 if (mti->mti_flags & LDD_F_UPGRADE14) {
1633 rc = record_start_log(obd, &llh, cliname);
1637 rc = record_marker(obd, llh, fsdb, CM_START,
1638 mti->mti_svname,"add mdc");
1640 /* Old client log already has MDC entry, but needs mount opt
1641 for new client name (lustre-client) */
1642 /* FIXME Old MDT log already has an old mount opt
1643 which we should remove (currently handled by
1644 class_del_profiles()) */
1645 rc = record_mount_opt(obd, llh, cliname, fsdb->fsdb_clilov,
1647 /* end COMPAT_146 */
1649 rc = record_marker(obd, llh, fsdb, CM_END,
1650 mti->mti_svname, "add mdc");
1654 /* copy client info about lov/lmv */
1655 comp.comp_mti = mti;
1656 comp.comp_fsdb = fsdb;
1658 rc = mgs_steal_llog_for_mdt_from_client(obd, cliname,
1661 rc = mgs_write_log_mdc_to_lmv(obd, fsdb, mti, cliname,
1664 rc = record_start_log(obd, &llh, cliname);
1668 rc = record_marker(obd, llh, fsdb, CM_START, cliname,
1670 rc = record_mount_opt(obd, llh, cliname, fsdb->fsdb_clilov,
1672 rc = record_marker(obd, llh, fsdb, CM_END, cliname,
1676 rc = record_end_log(obd, &llh);
1678 name_destroy(&cliname);
1680 // for_all_existing_mdt except current one
1681 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
1683 if (i != mti->mti_stripe_index &&
1684 cfs_test_bit(i, fsdb->fsdb_mdt_index_map)) {
1685 name_create_mdt(&mdtname, mti->mti_fsname, i);
1686 rc = mgs_write_log_mdc_to_mdt(obd, fsdb, mti, mdtname);
1687 name_destroy(&mdtname);
1694 /* Add the ost info to the client/mdt lov */
1695 static int mgs_write_log_osc_to_lov(struct obd_device *obd, struct fs_db *fsdb,
1696 struct mgs_target_info *mti,
1697 char *logname, char *suffix, char *lovname,
1698 enum lustre_sec_part sec_part, int flags)
1700 struct llog_handle *llh = NULL;
1701 char *nodeuuid, *oscname, *oscuuid, *lovuuid, *svname;
1706 CDEBUG(D_INFO, "adding osc for %s to log %s\n",
1707 mti->mti_svname, logname);
1709 if (mgs_log_is_empty(obd, logname)) {
1710 CERROR("log is empty! Logical error\n");
1714 name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
1715 name_create(&svname, mti->mti_svname, "-osc");
1716 name_create(&oscname, svname, suffix);
1717 name_create(&oscuuid, oscname, "_UUID");
1718 name_create(&lovuuid, lovname, "_UUID");
1721 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
1723 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
1724 #04 L attach 0:OSC_uml1_ost1_MNT_client 1:osc 2:89070_lov1_a41dff51a
1725 #05 L setup 0:OSC_uml1_ost1_MNT_client 1:ost1_UUID 2:uml1_UUID
1727 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
1728 #07 L add_conn 0:OSC_uml1_ost1_MNT_client 1:uml2_UUID
1729 #08 L lov_modify_tgts add 0:lov1 1:ost1_UUID 2(index):0 3(gen):1
1732 rc = record_start_log(obd, &llh, logname);
1735 /* FIXME these should be a single journal transaction */
1736 rc = record_marker(obd, llh, fsdb, CM_START | flags, mti->mti_svname,
1738 for (i = 0; i < mti->mti_nid_count; i++) {
1739 CDEBUG(D_MGS, "add nid %s\n", libcfs_nid2str(mti->mti_nids[i]));
1740 rc = record_add_uuid(obd, llh, mti->mti_nids[i], nodeuuid);
1742 rc = record_attach(obd, llh, oscname, LUSTRE_OSC_NAME, lovuuid);
1743 rc = record_setup(obd, llh, oscname, mti->mti_uuid, nodeuuid, 0, 0);
1744 rc = mgs_write_log_failnids(obd, mti, llh, oscname);
1745 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
1746 rc = record_lov_add(obd, llh, lovname, mti->mti_uuid, index, "1");
1747 rc = record_marker(obd, llh, fsdb, CM_END | flags, mti->mti_svname,
1749 rc = record_end_log(obd, &llh);
1751 name_destroy(&lovuuid);
1752 name_destroy(&oscuuid);
1753 name_destroy(&oscname);
1754 name_destroy(&svname);
1755 name_destroy(&nodeuuid);
1759 static int mgs_write_log_ost(struct obd_device *obd, struct fs_db *fsdb,
1760 struct mgs_target_info *mti)
1762 struct llog_handle *llh = NULL;
1763 char *logname, *lovname;
1764 char *ptr = mti->mti_params;
1765 int rc, flags = 0, failout = 0, i;
1768 CDEBUG(D_MGS, "writing new ost %s\n", mti->mti_svname);
1770 /* The ost startup log */
1772 /* If the ost log already exists, that means that someone reformatted
1773 the ost and it called target_add again. */
1774 if (!mgs_log_is_empty(obd, mti->mti_svname)) {
1775 LCONSOLE_ERROR_MSG(0x141, "The config log for %s already "
1776 "exists, yet the server claims it never "
1777 "registered. It may have been reformatted, "
1778 "or the index changed. writeconf the MDT to "
1779 "regenerate all logs.\n", mti->mti_svname);
1784 attach obdfilter ost1 ost1_UUID
1785 setup /dev/loop2 ldiskfs f|n errors=remount-ro,user_xattr
1787 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
1788 failout = (strncmp(ptr, "failout", 7) == 0);
1789 rc = record_start_log(obd, &llh, mti->mti_svname);
1792 /* FIXME these should be a single journal transaction */
1793 rc = record_marker(obd, llh, fsdb, CM_START, mti->mti_svname,"add ost");
1794 if (*mti->mti_uuid == '\0')
1795 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
1796 "%s_UUID", mti->mti_svname);
1797 rc = record_attach(obd, llh, mti->mti_svname,
1798 "obdfilter"/*LUSTRE_OST_NAME*/, mti->mti_uuid);
1799 rc = record_setup(obd, llh, mti->mti_svname,
1800 "dev"/*ignored*/, "type"/*ignored*/,
1801 failout ? "n" : "f", 0/*options*/);
1802 rc = record_marker(obd, llh, fsdb, CM_END, mti->mti_svname, "add ost");
1803 rc = record_end_log(obd, &llh);
1805 /* We also have to update the other logs where this osc is part of
1808 if (cfs_test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
1809 /* If we're upgrading, the old mdt log already has our
1810 entry. Let's do a fake one for fun. */
1811 /* Note that we can't add any new failnids, since we don't
1812 know the old osc names. */
1813 flags = CM_SKIP | CM_UPGRADE146;
1815 } else if ((mti->mti_flags & LDD_F_UPDATE) != LDD_F_UPDATE) {
1816 /* If the update flag isn't set, don't update client/mdt
1819 LCONSOLE_WARN("Client log for %s was not updated; writeconf "
1820 "the MDT first to regenerate it.\n",
1824 /* Add ost to all MDT lov defs */
1825 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
1826 if (cfs_test_bit(i, fsdb->fsdb_mdt_index_map)) {
1829 name_create_mdt_and_lov(&logname, &lovname, fsdb, i);
1830 sprintf(mdt_index, "-MDT%04x", i);
1831 mgs_write_log_osc_to_lov(obd, fsdb, mti, logname,
1833 LUSTRE_SP_MDT, flags);
1834 name_destroy(&logname);
1835 name_destroy(&lovname);
1839 /* Append ost info to the client log */
1840 name_create(&logname, mti->mti_fsname, "-client");
1841 if (mgs_log_is_empty(obd, logname)) {
1842 /* Start client log */
1843 rc = mgs_write_log_lov(obd, fsdb, mti, logname,
1845 rc = mgs_write_log_lmv(obd, fsdb, mti, logname,
1848 mgs_write_log_osc_to_lov(obd, fsdb, mti, logname, "",
1849 fsdb->fsdb_clilov, LUSTRE_SP_CLI, 0);
1850 name_destroy(&logname);
1854 static __inline__ int mgs_param_empty(char *ptr)
1858 if ((tmp = strchr(ptr, '=')) && (*(++tmp) == '\0'))
1863 static int mgs_write_log_failnid_internal(struct obd_device *obd,
1865 struct mgs_target_info *mti,
1866 char *logname, char *cliname)
1869 struct llog_handle *llh = NULL;
1871 if (mgs_param_empty(mti->mti_params)) {
1872 /* Remove _all_ failnids */
1873 rc = mgs_modify(obd, fsdb, mti, logname,
1874 mti->mti_svname, "add failnid", CM_SKIP);
1878 /* Otherwise failover nids are additive */
1879 rc = record_start_log(obd, &llh, logname);
1881 /* FIXME this should be a single journal transaction */
1882 rc = record_marker(obd, llh, fsdb, CM_START,
1883 mti->mti_svname, "add failnid");
1884 rc = mgs_write_log_failnids(obd, mti, llh, cliname);
1885 rc = record_marker(obd, llh, fsdb, CM_END,
1886 mti->mti_svname, "add failnid");
1887 rc = record_end_log(obd, &llh);
1894 /* Add additional failnids to an existing log.
1895 The mdc/osc must have been added to logs first */
1896 /* tcp nids must be in dotted-quad ascii -
1897 we can't resolve hostnames from the kernel. */
1898 static int mgs_write_log_add_failnid(struct obd_device *obd, struct fs_db *fsdb,
1899 struct mgs_target_info *mti)
1901 char *logname, *cliname;
1905 /* FIXME we currently can't erase the failnids
1906 * given when a target first registers, since they aren't part of
1907 * an "add uuid" stanza */
1909 /* Verify that we know about this target */
1910 if (mgs_log_is_empty(obd, mti->mti_svname)) {
1911 LCONSOLE_ERROR_MSG(0x142, "The target %s has not registered "
1912 "yet. It must be started before failnids "
1913 "can be added.\n", mti->mti_svname);
1917 /* Create mdc/osc client name (e.g. lustre-OST0001-osc) */
1918 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
1919 name_create(&cliname, mti->mti_svname, "-mdc");
1920 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
1921 name_create(&cliname, mti->mti_svname, "-osc");
1926 /* Add failover nids to the client log */
1927 name_create(&logname, mti->mti_fsname, "-client");
1928 rc = mgs_write_log_failnid_internal(obd, fsdb, mti, logname, cliname);
1929 name_destroy(&logname);
1930 name_destroy(&cliname);
1932 if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
1933 /* Add OST failover nids to the MDT logs as well */
1936 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
1937 if (!cfs_test_bit(i, fsdb->fsdb_mdt_index_map))
1939 name_create_mdt(&logname, mti->mti_fsname, i);
1940 name_create_mdt_osc(&cliname, mti->mti_svname, fsdb, i);
1941 rc = mgs_write_log_failnid_internal(obd, fsdb, mti,
1943 name_destroy(&cliname);
1944 name_destroy(&logname);
1951 static int mgs_wlp_lcfg(struct obd_device *obd, struct fs_db *fsdb,
1952 struct mgs_target_info *mti,
1953 char *logname, struct lustre_cfg_bufs *bufs,
1954 char *tgtname, char *ptr)
1956 char comment[MTI_NAME_MAXLEN];
1958 struct lustre_cfg *lcfg;
1961 /* Erase any old settings of this same parameter */
1962 memcpy(comment, ptr, MTI_NAME_MAXLEN);
1963 comment[MTI_NAME_MAXLEN - 1] = 0;
1964 /* But don't try to match the value. */
1965 if ((tmp = strchr(comment, '=')))
1967 /* FIXME we should skip settings that are the same as old values */
1968 rc = mgs_modify(obd, fsdb, mti, logname, tgtname, comment, CM_SKIP);
1969 del = mgs_param_empty(ptr);
1971 LCONSOLE_INFO("%sing parameter %s.%s in log %s\n", del ? "Disabl" : rc ?
1972 "Sett" : "Modify", tgtname, comment, logname);
1976 lustre_cfg_bufs_reset(bufs, tgtname);
1977 lustre_cfg_bufs_set_string(bufs, 1, ptr);
1978 lcfg = lustre_cfg_new(LCFG_PARAM, bufs);
1981 rc = mgs_write_log_direct(obd, fsdb, logname, lcfg, tgtname, comment);
1982 lustre_cfg_free(lcfg);
1986 /* write global variable settings into log */
1987 static int mgs_write_log_sys(struct obd_device *obd, struct fs_db *fsdb,
1988 struct mgs_target_info *mti, char *sys, char *ptr)
1990 struct lustre_cfg_bufs bufs;
1991 struct lustre_cfg *lcfg;
1997 if (class_match_param(ptr, PARAM_TIMEOUT, &tmp) == 0)
1998 cmd = LCFG_SET_TIMEOUT;
1999 else if (class_match_param(ptr, PARAM_LDLM_TIMEOUT, &tmp) == 0)
2000 cmd = LCFG_SET_LDLM_TIMEOUT;
2001 /* Check for known params here so we can return error to lctl */
2002 else if ((class_match_param(ptr, PARAM_AT_MIN, &tmp) == 0)
2003 || (class_match_param(ptr, PARAM_AT_MAX, &tmp) == 0)
2004 || (class_match_param(ptr, PARAM_AT_EXTRA, &tmp) == 0)
2005 || (class_match_param(ptr, PARAM_AT_EARLY_MARGIN, &tmp) == 0)
2006 || (class_match_param(ptr, PARAM_AT_HISTORY, &tmp) == 0))
2011 /* separate the value */
2012 val = simple_strtoul(tmp, NULL, 0);
2014 CDEBUG(D_MGS, "global '%s' removed\n", sys);
2016 CDEBUG(D_MGS, "global '%s' val=%d\n", sys, val);
2018 lustre_cfg_bufs_reset(&bufs, NULL);
2019 lustre_cfg_bufs_set_string(&bufs, 1, sys);
2020 lcfg = lustre_cfg_new(cmd, &bufs);
2021 lcfg->lcfg_num = val;
2022 /* truncate the comment to the parameter name */
2026 /* modify all servers and clients */
2027 rc = mgs_write_log_direct_all(obd, fsdb, mti,
2028 *tmp == '\0' ? NULL : lcfg,
2029 mti->mti_fsname, sys);
2031 lustre_cfg_free(lcfg);
2035 static int mgs_srpc_set_param_disk(struct obd_device *obd,
2037 struct mgs_target_info *mti,
2040 struct llog_handle *llh = NULL;
2042 char *comment, *ptr;
2043 struct lustre_cfg_bufs bufs;
2044 struct lustre_cfg *lcfg;
2049 ptr = strchr(param, '=');
2053 OBD_ALLOC(comment, len + 1);
2054 if (comment == NULL)
2056 strncpy(comment, param, len);
2057 comment[len] = '\0';
2060 lustre_cfg_bufs_reset(&bufs, mti->mti_svname);
2061 lustre_cfg_bufs_set_string(&bufs, 1, param);
2062 lcfg = lustre_cfg_new(LCFG_SPTLRPC_CONF, &bufs);
2064 GOTO(out_comment, rc = -ENOMEM);
2066 /* construct log name */
2067 rc = name_create(&logname, mti->mti_fsname, "-sptlrpc");
2071 if (mgs_log_is_empty(obd, logname)) {
2072 rc = record_start_log(obd, &llh, logname);
2073 record_end_log(obd, &llh);
2078 /* obsolete old one */
2079 mgs_modify(obd, fsdb, mti, logname, mti->mti_svname, comment, CM_SKIP);
2081 /* write the new one */
2082 rc = mgs_write_log_direct(obd, fsdb, logname, lcfg,
2083 mti->mti_svname, comment);
2085 CERROR("err %d writing log %s\n", rc, logname);
2088 name_destroy(&logname);
2090 lustre_cfg_free(lcfg);
2092 OBD_FREE(comment, len + 1);
2096 static int mgs_srpc_set_param_udesc_mem(struct fs_db *fsdb,
2101 /* disable the adjustable udesc parameter for now, i.e. use default
2102 * setting that client always ship udesc to MDT if possible. to enable
2103 * it simply remove the following line */
2106 ptr = strchr(param, '=');
2111 if (strcmp(param, PARAM_SRPC_UDESC))
2114 if (strcmp(ptr, "yes") == 0) {
2115 cfs_set_bit(FSDB_UDESC, &fsdb->fsdb_flags);
2116 CWARN("Enable user descriptor shipping from client to MDT\n");
2117 } else if (strcmp(ptr, "no") == 0) {
2118 cfs_clear_bit(FSDB_UDESC, &fsdb->fsdb_flags);
2119 CWARN("Disable user descriptor shipping from client to MDT\n");
2127 CERROR("Invalid param: %s\n", param);
2131 static int mgs_srpc_set_param_mem(struct fs_db *fsdb,
2135 struct sptlrpc_rule rule;
2136 struct sptlrpc_rule_set *rset;
2140 if (strncmp(param, PARAM_SRPC, sizeof(PARAM_SRPC) - 1) != 0) {
2141 CERROR("Invalid sptlrpc parameter: %s\n", param);
2145 if (strncmp(param, PARAM_SRPC_UDESC,
2146 sizeof(PARAM_SRPC_UDESC) - 1) == 0) {
2147 RETURN(mgs_srpc_set_param_udesc_mem(fsdb, param));
2150 if (strncmp(param, PARAM_SRPC_FLVR, sizeof(PARAM_SRPC_FLVR) - 1) != 0) {
2151 CERROR("Invalid sptlrpc flavor parameter: %s\n", param);
2155 param += sizeof(PARAM_SRPC_FLVR) - 1;
2157 rc = sptlrpc_parse_rule(param, &rule);
2161 /* mgs rules implies must be mgc->mgs */
2162 if (cfs_test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
2163 if ((rule.sr_from != LUSTRE_SP_MGC &&
2164 rule.sr_from != LUSTRE_SP_ANY) ||
2165 (rule.sr_to != LUSTRE_SP_MGS &&
2166 rule.sr_to != LUSTRE_SP_ANY))
2170 /* preapre room for this coming rule. svcname format should be:
2171 * - fsname: general rule
2172 * - fsname-tgtname: target-specific rule
2174 if (strchr(svname, '-')) {
2175 struct mgs_tgt_srpc_conf *tgtconf;
2178 for (tgtconf = fsdb->fsdb_srpc_tgt; tgtconf != NULL;
2179 tgtconf = tgtconf->mtsc_next) {
2180 if (!strcmp(tgtconf->mtsc_tgt, svname)) {
2189 OBD_ALLOC_PTR(tgtconf);
2190 if (tgtconf == NULL)
2193 name_len = strlen(svname);
2195 OBD_ALLOC(tgtconf->mtsc_tgt, name_len + 1);
2196 if (tgtconf->mtsc_tgt == NULL) {
2197 OBD_FREE_PTR(tgtconf);
2200 memcpy(tgtconf->mtsc_tgt, svname, name_len);
2202 tgtconf->mtsc_next = fsdb->fsdb_srpc_tgt;
2203 fsdb->fsdb_srpc_tgt = tgtconf;
2206 rset = &tgtconf->mtsc_rset;
2208 rset = &fsdb->fsdb_srpc_gen;
2211 rc = sptlrpc_rule_set_merge(rset, &rule);
2216 static int mgs_srpc_set_param(struct obd_device *obd,
2218 struct mgs_target_info *mti,
2228 /* keep a copy of original param, which could be destroied
2230 copy_size = strlen(param) + 1;
2231 OBD_ALLOC(copy, copy_size);
2234 memcpy(copy, param, copy_size);
2236 rc = mgs_srpc_set_param_mem(fsdb, mti->mti_svname, param);
2240 /* previous steps guaranteed the syntax is correct */
2241 rc = mgs_srpc_set_param_disk(obd, fsdb, mti, copy);
2245 if (cfs_test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
2247 * for mgs rules, make them effective immediately.
2249 LASSERT(fsdb->fsdb_srpc_tgt == NULL);
2250 sptlrpc_target_update_exp_flavor(obd, &fsdb->fsdb_srpc_gen);
2254 OBD_FREE(copy, copy_size);
2258 struct mgs_srpc_read_data {
2259 struct fs_db *msrd_fsdb;
2263 static int mgs_srpc_read_handler(struct llog_handle *llh,
2264 struct llog_rec_hdr *rec,
2267 struct mgs_srpc_read_data *msrd = (struct mgs_srpc_read_data *) data;
2268 struct cfg_marker *marker;
2269 struct lustre_cfg *lcfg = (struct lustre_cfg *)(rec + 1);
2270 char *svname, *param;
2274 if (rec->lrh_type != OBD_CFG_REC) {
2275 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
2279 cfg_len = rec->lrh_len - sizeof(struct llog_rec_hdr) -
2280 sizeof(struct llog_rec_tail);
2282 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
2284 CERROR("Insane cfg\n");
2288 if (lcfg->lcfg_command == LCFG_MARKER) {
2289 marker = lustre_cfg_buf(lcfg, 1);
2291 if (marker->cm_flags & CM_START &&
2292 marker->cm_flags & CM_SKIP)
2293 msrd->msrd_skip = 1;
2294 if (marker->cm_flags & CM_END)
2295 msrd->msrd_skip = 0;
2300 if (msrd->msrd_skip)
2303 if (lcfg->lcfg_command != LCFG_SPTLRPC_CONF) {
2304 CERROR("invalid command (%x)\n", lcfg->lcfg_command);
2308 svname = lustre_cfg_string(lcfg, 0);
2309 if (svname == NULL) {
2310 CERROR("svname is empty\n");
2314 param = lustre_cfg_string(lcfg, 1);
2315 if (param == NULL) {
2316 CERROR("param is empty\n");
2320 rc = mgs_srpc_set_param_mem(msrd->msrd_fsdb, svname, param);
2322 CERROR("read sptlrpc record error (%d): %s\n", rc, param);
2327 int mgs_get_fsdb_srpc_from_llog(struct obd_device *obd,
2330 struct llog_handle *llh = NULL;
2331 struct lvfs_run_ctxt saved;
2332 struct llog_ctxt *ctxt;
2334 struct mgs_srpc_read_data msrd;
2338 /* construct log name */
2339 rc = name_create(&logname, fsdb->fsdb_name, "-sptlrpc");
2343 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
2344 LASSERT(ctxt != NULL);
2346 if (mgs_log_is_empty(obd, logname))
2349 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
2351 rc = llog_create(ctxt, &llh, NULL, logname);
2355 rc = llog_init_handle(llh, LLOG_F_IS_PLAIN, NULL);
2357 GOTO(out_close, rc);
2359 if (llog_get_size(llh) <= 1)
2360 GOTO(out_close, rc = 0);
2362 msrd.msrd_fsdb = fsdb;
2365 rc = llog_process(llh, mgs_srpc_read_handler, (void *) &msrd, NULL);
2370 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
2372 llog_ctxt_put(ctxt);
2373 name_destroy(&logname);
2376 CERROR("failed to read sptlrpc config database: %d\n", rc);
2380 /* Permanent settings of all parameters by writing into the appropriate
2381 * configuration logs.
2382 * A parameter with null value ("<param>='\0'") means to erase it out of
2385 static int mgs_write_log_param(struct obd_device *obd, struct fs_db *fsdb,
2386 struct mgs_target_info *mti, char *ptr)
2388 struct lustre_cfg_bufs bufs;
2391 int rc = 0, rc2 = 0;
2394 /* For various parameter settings, we have to figure out which logs
2395 care about them (e.g. both mdt and client for lov settings) */
2396 CDEBUG(D_MGS, "next param '%s'\n", ptr);
2398 /* The params are stored in MOUNT_DATA_FILE and modified via
2399 tunefs.lustre, or set using lctl conf_param */
2401 /* Processed in lustre_start_mgc */
2402 if (class_match_param(ptr, PARAM_MGSNODE, NULL) == 0)
2405 /* Processed in mgs_write_log_ost */
2406 if (class_match_param(ptr, PARAM_FAILMODE, NULL) == 0) {
2407 if (mti->mti_flags & LDD_F_PARAM) {
2408 LCONSOLE_ERROR_MSG(0x169, "%s can only be "
2409 "changed with tunefs.lustre"
2410 "and --writeconf\n", ptr);
2416 if (class_match_param(ptr, PARAM_SRPC, NULL) == 0) {
2417 rc = mgs_srpc_set_param(obd, fsdb, mti, ptr);
2421 if (class_match_param(ptr, PARAM_FAILNODE, NULL) == 0) {
2422 /* Add a failover nidlist */
2424 /* We already processed failovers params for new
2425 targets in mgs_write_log_target */
2426 if (mti->mti_flags & LDD_F_PARAM) {
2427 CDEBUG(D_MGS, "Adding failnode\n");
2428 rc = mgs_write_log_add_failnid(obd, fsdb, mti);
2433 if (class_match_param(ptr, PARAM_SYS, &tmp) == 0) {
2434 rc = mgs_write_log_sys(obd, fsdb, mti, ptr, tmp);
2438 if (class_match_param(ptr, PARAM_OSC""PARAM_ACTIVE, &tmp) == 0) {
2439 /* active=0 means off, anything else means on */
2440 int flag = (*tmp == '0') ? CM_EXCLUDE : 0;
2443 if (!(mti->mti_flags & LDD_F_SV_TYPE_OST)) {
2444 LCONSOLE_ERROR_MSG(0x144, "%s: Only OSCs can "
2445 "be (de)activated.\n",
2447 GOTO(end, rc = -EINVAL);
2449 LCONSOLE_WARN("Permanently %sactivating %s\n",
2450 flag ? "de": "re", mti->mti_svname);
2452 name_create(&logname, mti->mti_fsname, "-client");
2453 rc = mgs_modify(obd, fsdb, mti, logname,
2454 mti->mti_svname, "add osc", flag);
2455 name_destroy(&logname);
2459 /* Add to all MDT logs for CMD */
2460 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2461 if (!cfs_test_bit(i, fsdb->fsdb_mdt_index_map))
2463 name_create_mdt(&logname, mti->mti_fsname, i);
2464 rc = mgs_modify(obd, fsdb, mti, logname,
2465 mti->mti_svname, "add osc", flag);
2466 name_destroy(&logname);
2472 LCONSOLE_ERROR_MSG(0x145, "Couldn't find %s in"
2473 "log (%d). No permanent "
2474 "changes were made to the "
2476 mti->mti_svname, rc);
2477 if (cfs_test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags))
2478 LCONSOLE_ERROR_MSG(0x146, "This may be"
2483 "update the logs.\n");
2486 /* Fall through to osc proc for deactivating live OSC
2487 on running MDT / clients. */
2489 /* Below here, let obd's XXX_process_config methods handle it */
2491 /* All lov. in proc */
2492 if (class_match_param(ptr, PARAM_LOV, NULL) == 0) {
2495 CDEBUG(D_MGS, "lov param %s\n", ptr);
2496 if (!(mti->mti_flags & LDD_F_SV_TYPE_MDT)) {
2497 LCONSOLE_ERROR_MSG(0x147, "LOV params must be "
2498 "set on the MDT, not %s. "
2505 if (mgs_log_is_empty(obd, mti->mti_svname))
2506 GOTO(end, rc = -ENODEV);
2508 name_create_mdt_and_lov(&logname, &mdtlovname, fsdb,
2509 mti->mti_stripe_index);
2510 rc = mgs_wlp_lcfg(obd, fsdb, mti, mti->mti_svname,
2511 &bufs, mdtlovname, ptr);
2512 name_destroy(&logname);
2513 name_destroy(&mdtlovname);
2518 name_create(&logname, mti->mti_fsname, "-client");
2519 rc = mgs_wlp_lcfg(obd, fsdb, mti, logname, &bufs,
2520 fsdb->fsdb_clilov, ptr);
2521 name_destroy(&logname);
2525 /* All osc., mdc., llite. params in proc */
2526 if ((class_match_param(ptr, PARAM_OSC, NULL) == 0) ||
2527 (class_match_param(ptr, PARAM_MDC, NULL) == 0) ||
2528 (class_match_param(ptr, PARAM_LLITE, NULL) == 0)) {
2530 if (memcmp(ptr, PARAM_LLITE, strlen(PARAM_LLITE)) == 0) {
2531 name_create(&cname, mti->mti_fsname, "-client");
2532 /* Add the client type to match the obdname in
2533 class_config_llog_handler */
2534 } else if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
2537 name_create(&cname, fsdb->fsdb_mdc, "");
2539 name_create(&cname, mti->mti_svname,
2541 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2543 if (cfs_test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
2544 LCONSOLE_ERROR_MSG(0x148, "Upgraded "
2545 "client logs for %s"
2547 "modified. Consider"
2549 "configuration with"
2552 /* We don't know the names of all the
2554 GOTO(end, rc = -EINVAL);
2556 name_create(&cname, mti->mti_svname, "-osc");
2558 GOTO(end, rc = -EINVAL);
2561 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
2564 name_create(&logname, mti->mti_fsname, "-client");
2565 rc = mgs_wlp_lcfg(obd, fsdb, mti, logname, &bufs,
2568 /* osc params affect the MDT as well */
2569 if (!rc && (mti->mti_flags & LDD_F_SV_TYPE_OST)) {
2572 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
2573 if (!cfs_test_bit(i, fsdb->fsdb_mdt_index_map))
2575 name_destroy(&cname);
2576 name_create_mdt_osc(&cname, mti->mti_svname,
2578 name_destroy(&logname);
2579 name_create_mdt(&logname, mti->mti_fsname, i);
2580 if (!mgs_log_is_empty(obd, logname))
2581 rc = mgs_wlp_lcfg(obd, fsdb,mti,logname,
2587 name_destroy(&logname);
2588 name_destroy(&cname);
2592 /* All mdt. params in proc */
2593 if (class_match_param(ptr, PARAM_MDT, NULL) == 0) {
2597 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
2598 if (strncmp(mti->mti_svname, mti->mti_fsname,
2599 MTI_NAME_MAXLEN) == 0)
2600 /* device is unspecified completely? */
2601 rc = LDD_F_SV_TYPE_MDT | LDD_F_SV_ALL;
2603 rc = server_name2index(mti->mti_svname, &idx, NULL);
2606 if ((rc & LDD_F_SV_TYPE_MDT) == 0)
2608 if (rc & LDD_F_SV_ALL) {
2609 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2610 if (!cfs_test_bit(i,
2611 fsdb->fsdb_mdt_index_map))
2613 name_create_mdt(&logname, mti->mti_fsname, i);
2614 rc = mgs_wlp_lcfg(obd, fsdb, mti,
2617 name_destroy(&logname);
2622 rc = mgs_wlp_lcfg(obd, fsdb, mti,
2623 mti->mti_svname, &bufs,
2624 mti->mti_svname, ptr);
2631 /* All mdd., ost. params in proc */
2632 if ((class_match_param(ptr, PARAM_MDD, NULL) == 0) ||
2633 (class_match_param(ptr, PARAM_OST, NULL) == 0)) {
2634 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
2635 if (mgs_log_is_empty(obd, mti->mti_svname))
2636 GOTO(end, rc = -ENODEV);
2638 rc = mgs_wlp_lcfg(obd, fsdb, mti, mti->mti_svname,
2639 &bufs, mti->mti_svname, ptr);
2643 LCONSOLE_WARN("Ignoring unrecognized param '%s'\n", ptr);
2648 CERROR("err %d on param '%s'\n", rc, ptr);
2653 /* Not implementing automatic failover nid addition at this time. */
2654 int mgs_check_failnid(struct obd_device *obd, struct mgs_target_info *mti)
2661 rc = mgs_find_or_make_fsdb(obd, fsname, &fsdb);
2665 if (mgs_log_is_empty(obd, mti->mti_svname))
2666 /* should never happen */
2669 CDEBUG(D_MGS, "Checking for new failnids for %s\n", mti->mti_svname);
2671 /* FIXME We can just check mti->params to see if we're already in
2672 the failover list. Modify mti->params for rewriting back at
2673 server_register_target(). */
2675 cfs_down(&fsdb->fsdb_sem);
2676 rc = mgs_write_log_add_failnid(obd, fsdb, mti);
2677 cfs_up(&fsdb->fsdb_sem);
2684 int mgs_write_log_target(struct obd_device *obd,
2685 struct mgs_target_info *mti,
2692 /* set/check the new target index */
2693 rc = mgs_set_index(obd, mti);
2695 CERROR("Can't get index (%d)\n", rc);
2700 if (mti->mti_flags & LDD_F_UPGRADE14) {
2701 if (rc == EALREADY) {
2702 LCONSOLE_INFO("Found index %d for %s 1.4 log, "
2703 "upgrading\n", mti->mti_stripe_index,
2706 LCONSOLE_ERROR_MSG(0x149, "Failed to find %s in the old"
2707 " client log. Apparently it is not "
2708 "part of this filesystem, or the old"
2709 " log is wrong.\nUse 'writeconf' on "
2710 "the MDT to force log regeneration."
2711 "\n", mti->mti_svname);
2712 /* Not in client log? Upgrade anyhow...*/
2713 /* Argument against upgrading: reformat MDT,
2714 upgrade OST, then OST will start but will be SKIPped
2715 in client logs. Maybe error now is better. */
2716 /* RETURN(-EINVAL); */
2718 /* end COMPAT_146 */
2720 if (rc == EALREADY) {
2721 LCONSOLE_WARN("Found index %d for %s, updating log\n",
2722 mti->mti_stripe_index, mti->mti_svname);
2723 /* We would like to mark old log sections as invalid
2724 and add new log sections in the client and mdt logs.
2725 But if we add new sections, then live clients will
2726 get repeat setup instructions for already running
2727 osc's. So don't update the client/mdt logs. */
2728 mti->mti_flags &= ~LDD_F_UPDATE;
2732 cfs_down(&fsdb->fsdb_sem);
2734 if (mti->mti_flags &
2735 (LDD_F_VIRGIN | LDD_F_UPGRADE14 | LDD_F_WRITECONF)) {
2736 /* Generate a log from scratch */
2737 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
2738 rc = mgs_write_log_mdt(obd, fsdb, mti);
2739 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2740 rc = mgs_write_log_ost(obd, fsdb, mti);
2742 CERROR("Unknown target type %#x, can't create log for "
2743 "%s\n", mti->mti_flags, mti->mti_svname);
2746 CERROR("Can't write logs for %s (%d)\n",
2747 mti->mti_svname, rc);
2751 /* Just update the params from tunefs in mgs_write_log_params */
2752 CDEBUG(D_MGS, "Update params for %s\n", mti->mti_svname);
2753 mti->mti_flags |= LDD_F_PARAM;
2756 /* allocate temporary buffer, where class_get_next_param will
2757 make copy of a current parameter */
2758 OBD_ALLOC(buf, strlen(mti->mti_params) + 1);
2760 GOTO(out_up, rc = -ENOMEM);
2761 params = mti->mti_params;
2762 while (params != NULL) {
2763 rc = class_get_next_param(¶ms, buf);
2766 /* there is no next parameter, that is
2771 CDEBUG(D_MGS, "remaining string: '%s', param: '%s'\n",
2773 rc = mgs_write_log_param(obd, fsdb, mti, buf);
2778 OBD_FREE(buf, strlen(mti->mti_params) + 1);
2781 cfs_up(&fsdb->fsdb_sem);
2786 /* verify that we can handle the old config logs */
2787 int mgs_upgrade_sv_14(struct obd_device *obd, struct mgs_target_info *mti,
2793 /* Create ost log normally, as servers register. Servers
2794 register with their old uuids (from last_rcvd), so old
2795 (MDT and client) logs should work.
2796 - new MDT won't know about old OSTs, only the ones that have
2797 registered, so we need the old MDT log to get the LOV right
2798 in order for old clients to work.
2799 - Old clients connect to the MDT, not the MGS, for their logs, and
2800 will therefore receive the old client log from the MDT /LOGS dir.
2801 - Old clients can continue to use and connect to old or new OSTs
2802 - New clients will contact the MGS for their log
2805 LCONSOLE_INFO("upgrading server %s from pre-1.6\n", mti->mti_svname);
2806 server_mti_print("upgrade", mti);
2808 if (cfs_test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
2809 LCONSOLE_ERROR_MSG(0x14a, "The old client log %s-client is "
2810 "missing. Was tunefs.lustre successful?\n",
2815 if (fsdb->fsdb_gen == 0) {
2816 /* There were no markers in the client log, meaning we have
2817 not updated the logs for this fs */
2818 CDEBUG(D_MGS, "found old, unupdated client log\n");
2821 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
2822 if (mgs_log_is_empty(obd, mti->mti_svname)) {
2823 LCONSOLE_ERROR_MSG(0x14b, "The old MDT log %s is "
2824 "missing. Was tunefs.lustre "
2829 /* We're starting with an old uuid. Assume old name for lov
2830 as well since the lov entry already exists in the log. */
2831 CDEBUG(D_MGS, "old mds uuid %s\n", mti->mti_uuid);
2832 if (strncmp(mti->mti_uuid, fsdb->fsdb_mdtlov + 4,
2833 strlen(fsdb->fsdb_mdtlov) - 4) != 0) {
2834 CERROR("old mds uuid %s doesn't match log %s (%s)\n",
2835 mti->mti_uuid, fsdb->fsdb_mdtlov,
2836 fsdb->fsdb_mdtlov + 4);
2841 if (!cfs_test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
2842 LCONSOLE_ERROR_MSG(0x14c, "%s-client is supposedly an old "
2843 "log, but no old LOV or MDT was found. "
2844 "Consider updating the configuration with"
2845 " --writeconf.\n", mti->mti_fsname);
2850 /* end COMPAT_146 */
2852 int mgs_erase_log(struct obd_device *obd, char *name)
2854 struct lvfs_run_ctxt saved;
2855 struct llog_ctxt *ctxt;
2856 struct llog_handle *llh;
2859 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
2860 LASSERT(ctxt != NULL);
2862 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
2863 rc = llog_create(ctxt, &llh, NULL, name);
2865 llog_init_handle(llh, LLOG_F_IS_PLAIN, NULL);
2866 rc = llog_destroy(llh);
2867 llog_free_handle(llh);
2869 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
2870 llog_ctxt_put(ctxt);
2873 CERROR("failed to clear log %s: %d\n", name, rc);
2878 /* erase all logs for the given fs */
2879 int mgs_erase_logs(struct obd_device *obd, char *fsname)
2881 struct mgs_obd *mgs = &obd->u.mgs;
2882 static struct fs_db *fsdb;
2883 cfs_list_t dentry_list;
2884 struct l_linux_dirent *dirent, *n;
2885 int rc, len = strlen(fsname);
2889 /* Find all the logs in the CONFIGS directory */
2890 rc = class_dentry_readdir(obd, mgs->mgs_configs_dir,
2891 mgs->mgs_vfsmnt, &dentry_list);
2893 CERROR("Can't read %s dir\n", MOUNT_CONFIGS_DIR);
2897 cfs_down(&mgs->mgs_sem);
2899 /* Delete the fs db */
2900 fsdb = mgs_find_fsdb(obd, fsname);
2902 mgs_free_fsdb(obd, fsdb);
2904 cfs_list_for_each_entry_safe(dirent, n, &dentry_list, lld_list) {
2905 cfs_list_del(&dirent->lld_list);
2906 suffix = strrchr(dirent->lld_name, '-');
2907 if (suffix != NULL) {
2908 if ((len == suffix - dirent->lld_name) &&
2909 (strncmp(fsname, dirent->lld_name, len) == 0)) {
2910 CDEBUG(D_MGS, "Removing log %s\n",
2912 mgs_erase_log(obd, dirent->lld_name);
2915 OBD_FREE(dirent, sizeof(*dirent));
2918 cfs_up(&mgs->mgs_sem);
2923 /* from llog_swab */
2924 static void print_lustre_cfg(struct lustre_cfg *lcfg)
2929 CDEBUG(D_MGS, "lustre_cfg: %p\n", lcfg);
2930 CDEBUG(D_MGS, "\tlcfg->lcfg_version: %#x\n", lcfg->lcfg_version);
2932 CDEBUG(D_MGS, "\tlcfg->lcfg_command: %#x\n", lcfg->lcfg_command);
2933 CDEBUG(D_MGS, "\tlcfg->lcfg_num: %#x\n", lcfg->lcfg_num);
2934 CDEBUG(D_MGS, "\tlcfg->lcfg_flags: %#x\n", lcfg->lcfg_flags);
2935 CDEBUG(D_MGS, "\tlcfg->lcfg_nid: %s\n", libcfs_nid2str(lcfg->lcfg_nid));
2937 CDEBUG(D_MGS, "\tlcfg->lcfg_bufcount: %d\n", lcfg->lcfg_bufcount);
2938 if (lcfg->lcfg_bufcount < LUSTRE_CFG_MAX_BUFCOUNT)
2939 for (i = 0; i < lcfg->lcfg_bufcount; i++) {
2940 CDEBUG(D_MGS, "\tlcfg->lcfg_buflens[%d]: %d %s\n",
2941 i, lcfg->lcfg_buflens[i],
2942 lustre_cfg_string(lcfg, i));
2947 /* Set a permanent (config log) param for a target or fs
2948 * \param lcfg buf0 may contain the device (testfs-MDT0000) name
2949 * buf1 contains the single parameter
2951 int mgs_setparam(struct obd_device *obd, struct lustre_cfg *lcfg, char *fsname)
2954 struct mgs_target_info *mti;
2955 char *devname, *param;
2961 print_lustre_cfg(lcfg);
2963 /* lustre, lustre-mdtlov, lustre-client, lustre-MDT0000 */
2964 devname = lustre_cfg_string(lcfg, 0);
2965 param = lustre_cfg_string(lcfg, 1);
2967 /* Assume device name embedded in param:
2968 lustre-OST0000.osc.max_dirty_mb=32 */
2969 ptr = strchr(param, '.');
2977 LCONSOLE_ERROR_MSG(0x14d, "No target specified: %s\n", param);
2981 /* Extract fsname */
2982 ptr = strrchr(devname, '-');
2983 memset(fsname, 0, MTI_NAME_MAXLEN);
2984 if (ptr && (server_name2index(ptr, &index, NULL) >= 0)) {
2985 /* param related to llite isn't allowed to set by OST or MDT */
2986 if (strncmp(param, PARAM_LLITE, sizeof(PARAM_LLITE)) == 0)
2989 strncpy(fsname, devname, ptr - devname);
2991 /* assume devname is the fsname */
2992 strncpy(fsname, devname, MTI_NAME_MAXLEN);
2994 fsname[MTI_NAME_MAXLEN - 1] = 0;
2995 CDEBUG(D_MGS, "setparam fs='%s' device='%s'\n", fsname, devname);
2997 rc = mgs_find_or_make_fsdb(obd, fsname, &fsdb);
3000 if (!cfs_test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags) &&
3001 cfs_test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
3002 CERROR("No filesystem targets for %s. cfg_device from lctl "
3003 "is '%s'\n", fsname, devname);
3004 mgs_free_fsdb(obd, fsdb);
3008 /* Create a fake mti to hold everything */
3011 GOTO(out, rc = -ENOMEM);
3012 strncpy(mti->mti_fsname, fsname, MTI_NAME_MAXLEN);
3013 strncpy(mti->mti_svname, devname, MTI_NAME_MAXLEN);
3014 strncpy(mti->mti_params, param, sizeof(mti->mti_params));
3015 rc = server_name2index(mti->mti_svname, &mti->mti_stripe_index, &tmp);
3017 /* Not a valid server; may be only fsname */
3020 /* Strip -osc or -mdc suffix from svname */
3021 if (server_make_name(rc, mti->mti_stripe_index, mti->mti_fsname,
3023 GOTO(out, rc = -EINVAL);
3025 mti->mti_flags = rc | LDD_F_PARAM;
3027 cfs_down(&fsdb->fsdb_sem);
3028 rc = mgs_write_log_param(obd, fsdb, mti, mti->mti_params);
3029 cfs_up(&fsdb->fsdb_sem);
3032 * Revoke lock so everyone updates. Should be alright if
3033 * someone was already reading while we were updating the logs,
3034 * so we don't really need to hold the lock while we're
3037 mgs_revoke_lock(obd, fsdb);
3043 static int mgs_write_log_pool(struct obd_device *obd, char *logname,
3044 struct fs_db *fsdb, char *lovname,
3045 enum lcfg_command_type cmd,
3046 char *poolname, char *fsname,
3047 char *ostname, char *comment)
3049 struct llog_handle *llh = NULL;
3052 rc = record_start_log(obd, &llh, logname);
3055 rc = record_marker(obd, llh, fsdb, CM_START, lovname, comment);
3056 record_base(obd, llh, lovname, 0, cmd, poolname, fsname, ostname, 0);
3057 rc = record_marker(obd, llh, fsdb, CM_END, lovname, comment);
3058 rc = record_end_log(obd, &llh);
3063 int mgs_pool_cmd(struct obd_device *obd, enum lcfg_command_type cmd,
3064 char *fsname, char *poolname, char *ostname)
3069 char *label = NULL, *canceled_label = NULL;
3071 struct mgs_target_info *mti = NULL;
3075 rc = mgs_find_or_make_fsdb(obd, fsname, &fsdb);
3077 CERROR("Can't get db for %s\n", fsname);
3080 if (cfs_test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
3081 CERROR("%s is not defined\n", fsname);
3082 mgs_free_fsdb(obd, fsdb);
3086 label_sz = 10 + strlen(fsname) + strlen(poolname);
3088 /* check if ostname match fsname */
3089 if (ostname != NULL) {
3092 ptr = strrchr(ostname, '-');
3093 if ((ptr == NULL) ||
3094 (strncmp(fsname, ostname, ptr-ostname) != 0))
3096 label_sz += strlen(ostname);
3099 OBD_ALLOC(label, label_sz);
3101 GOTO(out, rc = -ENOMEM);
3104 case LCFG_POOL_NEW: {
3106 "new %s.%s", fsname, poolname);
3109 case LCFG_POOL_ADD: {
3111 "add %s.%s.%s", fsname, poolname, ostname);
3114 case LCFG_POOL_REM: {
3115 OBD_ALLOC(canceled_label, label_sz);
3116 if (canceled_label == NULL)
3117 GOTO(out, rc = -ENOMEM);
3119 "rem %s.%s.%s", fsname, poolname, ostname);
3120 sprintf(canceled_label,
3121 "add %s.%s.%s", fsname, poolname, ostname);
3124 case LCFG_POOL_DEL: {
3125 OBD_ALLOC(canceled_label, label_sz);
3126 if (canceled_label == NULL)
3127 GOTO(out, rc = -ENOMEM);
3129 "del %s.%s", fsname, poolname);
3130 sprintf(canceled_label,
3131 "new %s.%s", fsname, poolname);
3139 cfs_down(&fsdb->fsdb_sem);
3141 if (canceled_label != NULL) {
3144 GOTO(out, rc = -ENOMEM);
3147 /* write pool def to all MDT logs */
3148 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3149 if (cfs_test_bit(i, fsdb->fsdb_mdt_index_map)) {
3150 name_create_mdt_and_lov(&logname, &lovname, fsdb, i);
3152 if (canceled_label != NULL) {
3153 strcpy(mti->mti_svname, "lov pool");
3154 mgs_modify(obd, fsdb, mti, logname, lovname,
3155 canceled_label, CM_SKIP);
3158 mgs_write_log_pool(obd, logname, fsdb, lovname,
3159 cmd, fsname, poolname, ostname,
3161 name_destroy(&logname);
3162 name_destroy(&lovname);
3166 name_create(&logname, fsname, "-client");
3167 if (canceled_label != NULL)
3168 mgs_modify(obd, fsdb, mti, logname, fsdb->fsdb_clilov,
3169 canceled_label, CM_SKIP);
3171 mgs_write_log_pool(obd, logname, fsdb, fsdb->fsdb_clilov,
3172 cmd, fsname, poolname, ostname, label);
3173 name_destroy(&logname);
3175 cfs_up(&fsdb->fsdb_sem);
3176 /* request for update */
3177 mgs_revoke_lock(obd, fsdb);
3182 OBD_FREE(label, label_sz);
3184 if (canceled_label != NULL)
3185 OBD_FREE(canceled_label, label_sz);
3194 /******************** unused *********************/
3195 static int mgs_backup_llog(struct obd_device *obd, char* fsname)
3197 struct file *filp, *bak_filp;
3198 struct lvfs_run_ctxt saved;
3199 char *logname, *buf;
3200 loff_t soff = 0 , doff = 0;
3201 int count = 4096, len;
3204 OBD_ALLOC(logname, PATH_MAX);
3205 if (logname == NULL)
3208 OBD_ALLOC(buf, count);
3210 GOTO(out , rc = -ENOMEM);
3212 len = snprintf(logname, PATH_MAX, "%s/%s.bak",
3213 MOUNT_CONFIGS_DIR, fsname);
3215 if (len >= PATH_MAX - 1) {
3216 GOTO(out, -ENAMETOOLONG);
3219 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
3221 bak_filp = l_filp_open(logname, O_RDWR|O_CREAT|O_TRUNC, 0660);
3222 if (IS_ERR(bak_filp)) {
3223 rc = PTR_ERR(bak_filp);
3224 CERROR("backup logfile open %s: %d\n", logname, rc);
3227 sprintf(logname, "%s/%s", MOUNT_CONFIGS_DIR, fsname);
3228 filp = l_filp_open(logname, O_RDONLY, 0);
3231 CERROR("logfile open %s: %d\n", logname, rc);
3235 while ((rc = lustre_fread(filp, buf, count, &soff)) > 0) {
3236 rc = lustre_fwrite(bak_filp, buf, count, &doff);
3240 filp_close(filp, 0);
3242 filp_close(bak_filp, 0);
3244 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
3247 OBD_FREE(buf, count);
3248 OBD_FREE(logname, PATH_MAX);