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 = 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 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 *);
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 = -1;
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 && cfs_test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
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 && cfs_test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
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 (cfs_test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
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 /* write the new one */
2055 rc = mgs_write_log_direct(obd, fsdb, logname, lcfg,
2056 mti->mti_svname, comment);
2058 CERROR("err %d writing log %s\n", rc, logname);
2061 name_destroy(&logname);
2063 lustre_cfg_free(lcfg);
2065 OBD_FREE(comment, len + 1);
2069 static int mgs_srpc_set_param_udesc_mem(struct fs_db *fsdb,
2074 /* disable the adjustable udesc parameter for now, i.e. use default
2075 * setting that client always ship udesc to MDT if possible. to enable
2076 * it simply remove the following line */
2079 ptr = strchr(param, '=');
2084 if (strcmp(param, PARAM_SRPC_UDESC))
2087 if (strcmp(ptr, "yes") == 0) {
2088 cfs_set_bit(FSDB_UDESC, &fsdb->fsdb_flags);
2089 CWARN("Enable user descriptor shipping from client to MDT\n");
2090 } else if (strcmp(ptr, "no") == 0) {
2091 cfs_clear_bit(FSDB_UDESC, &fsdb->fsdb_flags);
2092 CWARN("Disable user descriptor shipping from client to MDT\n");
2100 CERROR("Invalid param: %s\n", param);
2104 static int mgs_srpc_set_param_mem(struct fs_db *fsdb,
2108 struct sptlrpc_rule rule;
2109 struct sptlrpc_rule_set *rset;
2113 if (strncmp(param, PARAM_SRPC, sizeof(PARAM_SRPC) - 1) != 0) {
2114 CERROR("Invalid sptlrpc parameter: %s\n", param);
2118 if (strncmp(param, PARAM_SRPC_UDESC,
2119 sizeof(PARAM_SRPC_UDESC) - 1) == 0) {
2120 RETURN(mgs_srpc_set_param_udesc_mem(fsdb, param));
2123 if (strncmp(param, PARAM_SRPC_FLVR, sizeof(PARAM_SRPC_FLVR) - 1) != 0) {
2124 CERROR("Invalid sptlrpc flavor parameter: %s\n", param);
2128 param += sizeof(PARAM_SRPC_FLVR) - 1;
2130 rc = sptlrpc_parse_rule(param, &rule);
2134 /* mgs rules implies must be mgc->mgs */
2135 if (cfs_test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
2136 if ((rule.sr_from != LUSTRE_SP_MGC &&
2137 rule.sr_from != LUSTRE_SP_ANY) ||
2138 (rule.sr_to != LUSTRE_SP_MGS &&
2139 rule.sr_to != LUSTRE_SP_ANY))
2143 /* preapre room for this coming rule. svcname format should be:
2144 * - fsname: general rule
2145 * - fsname-tgtname: target-specific rule
2147 if (strchr(svname, '-')) {
2148 struct mgs_tgt_srpc_conf *tgtconf;
2151 for (tgtconf = fsdb->fsdb_srpc_tgt; tgtconf != NULL;
2152 tgtconf = tgtconf->mtsc_next) {
2153 if (!strcmp(tgtconf->mtsc_tgt, svname)) {
2162 OBD_ALLOC_PTR(tgtconf);
2163 if (tgtconf == NULL)
2166 name_len = strlen(svname);
2168 OBD_ALLOC(tgtconf->mtsc_tgt, name_len + 1);
2169 if (tgtconf->mtsc_tgt == NULL) {
2170 OBD_FREE_PTR(tgtconf);
2173 memcpy(tgtconf->mtsc_tgt, svname, name_len);
2175 tgtconf->mtsc_next = fsdb->fsdb_srpc_tgt;
2176 fsdb->fsdb_srpc_tgt = tgtconf;
2179 rset = &tgtconf->mtsc_rset;
2181 rset = &fsdb->fsdb_srpc_gen;
2184 rc = sptlrpc_rule_set_merge(rset, &rule);
2189 static int mgs_srpc_set_param(struct obd_device *obd,
2191 struct mgs_target_info *mti,
2201 /* keep a copy of original param, which could be destroied
2203 copy_size = strlen(param) + 1;
2204 OBD_ALLOC(copy, copy_size);
2207 memcpy(copy, param, copy_size);
2209 rc = mgs_srpc_set_param_mem(fsdb, mti->mti_svname, param);
2213 /* previous steps guaranteed the syntax is correct */
2214 rc = mgs_srpc_set_param_disk(obd, fsdb, mti, copy);
2218 if (cfs_test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
2220 * for mgs rules, make them effective immediately.
2222 LASSERT(fsdb->fsdb_srpc_tgt == NULL);
2223 sptlrpc_target_update_exp_flavor(obd, &fsdb->fsdb_srpc_gen);
2227 OBD_FREE(copy, copy_size);
2231 struct mgs_srpc_read_data {
2232 struct fs_db *msrd_fsdb;
2236 static int mgs_srpc_read_handler(struct llog_handle *llh,
2237 struct llog_rec_hdr *rec,
2240 struct mgs_srpc_read_data *msrd = (struct mgs_srpc_read_data *) data;
2241 struct cfg_marker *marker;
2242 struct lustre_cfg *lcfg = (struct lustre_cfg *)(rec + 1);
2243 char *svname, *param;
2247 if (rec->lrh_type != OBD_CFG_REC) {
2248 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
2252 cfg_len = rec->lrh_len - sizeof(struct llog_rec_hdr) -
2253 sizeof(struct llog_rec_tail);
2255 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
2257 CERROR("Insane cfg\n");
2261 if (lcfg->lcfg_command == LCFG_MARKER) {
2262 marker = lustre_cfg_buf(lcfg, 1);
2264 if (marker->cm_flags & CM_START &&
2265 marker->cm_flags & CM_SKIP)
2266 msrd->msrd_skip = 1;
2267 if (marker->cm_flags & CM_END)
2268 msrd->msrd_skip = 0;
2273 if (msrd->msrd_skip)
2276 if (lcfg->lcfg_command != LCFG_SPTLRPC_CONF) {
2277 CERROR("invalid command (%x)\n", lcfg->lcfg_command);
2281 svname = lustre_cfg_string(lcfg, 0);
2282 if (svname == NULL) {
2283 CERROR("svname is empty\n");
2287 param = lustre_cfg_string(lcfg, 1);
2288 if (param == NULL) {
2289 CERROR("param is empty\n");
2293 rc = mgs_srpc_set_param_mem(msrd->msrd_fsdb, svname, param);
2295 CERROR("read sptlrpc record error (%d): %s\n", rc, param);
2300 int mgs_get_fsdb_srpc_from_llog(struct obd_device *obd,
2303 struct llog_handle *llh = NULL;
2304 struct lvfs_run_ctxt saved;
2305 struct llog_ctxt *ctxt;
2307 struct mgs_srpc_read_data msrd;
2311 /* construct log name */
2312 rc = name_create(&logname, fsdb->fsdb_name, "-sptlrpc");
2316 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
2317 LASSERT(ctxt != NULL);
2319 if (mgs_log_is_empty(obd, logname))
2322 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
2324 rc = llog_create(ctxt, &llh, NULL, logname);
2328 rc = llog_init_handle(llh, LLOG_F_IS_PLAIN, NULL);
2330 GOTO(out_close, rc);
2332 if (llog_get_size(llh) <= 1)
2333 GOTO(out_close, rc = 0);
2335 msrd.msrd_fsdb = fsdb;
2338 rc = llog_process(llh, mgs_srpc_read_handler, (void *) &msrd, NULL);
2343 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
2345 llog_ctxt_put(ctxt);
2346 name_destroy(&logname);
2349 CERROR("failed to read sptlrpc config database: %d\n", rc);
2353 /* Permanent settings of all parameters by writing into the appropriate
2354 * configuration logs.
2355 * A parameter with null value ("<param>='\0'") means to erase it out of
2358 static int mgs_write_log_param(struct obd_device *obd, struct fs_db *fsdb,
2359 struct mgs_target_info *mti, char *ptr)
2361 struct lustre_cfg_bufs bufs;
2367 /* For various parameter settings, we have to figure out which logs
2368 care about them (e.g. both mdt and client for lov settings) */
2369 CDEBUG(D_MGS, "next param '%s'\n", ptr);
2371 /* The params are stored in MOUNT_DATA_FILE and modified via
2372 tunefs.lustre, or set using lctl conf_param */
2374 /* Processed in lustre_start_mgc */
2375 if (class_match_param(ptr, PARAM_MGSNODE, NULL) == 0)
2378 /* Processed in mgs_write_log_ost */
2379 if (class_match_param(ptr, PARAM_FAILMODE, NULL) == 0) {
2380 if (mti->mti_flags & LDD_F_PARAM) {
2381 LCONSOLE_ERROR_MSG(0x169, "%s can only be "
2382 "changed with tunefs.lustre"
2383 "and --writeconf\n", ptr);
2389 if (class_match_param(ptr, PARAM_SRPC, NULL) == 0) {
2390 rc = mgs_srpc_set_param(obd, fsdb, mti, ptr);
2394 if (class_match_param(ptr, PARAM_FAILNODE, NULL) == 0) {
2395 /* Add a failover nidlist */
2397 /* We already processed failovers params for new
2398 targets in mgs_write_log_target */
2399 if (mti->mti_flags & LDD_F_PARAM) {
2400 CDEBUG(D_MGS, "Adding failnode\n");
2401 rc = mgs_write_log_add_failnid(obd, fsdb, mti);
2406 if (class_match_param(ptr, PARAM_SYS, &tmp) == 0) {
2407 rc = mgs_write_log_sys(obd, fsdb, mti, ptr, tmp);
2411 if (class_match_param(ptr, PARAM_OSC""PARAM_ACTIVE, &tmp) == 0) {
2412 /* active=0 means off, anything else means on */
2413 int flag = (*tmp == '0') ? CM_EXCLUDE : 0;
2416 if (!(mti->mti_flags & LDD_F_SV_TYPE_OST)) {
2417 LCONSOLE_ERROR_MSG(0x144, "%s: Only OSCs can "
2418 "be (de)activated.\n",
2420 GOTO(end, rc = -EINVAL);
2422 LCONSOLE_WARN("Permanently %sactivating %s\n",
2423 flag ? "de": "re", mti->mti_svname);
2425 name_create(&logname, mti->mti_fsname, "-client");
2426 rc = mgs_modify(obd, fsdb, mti, logname,
2427 mti->mti_svname, "add osc", flag);
2428 name_destroy(&logname);
2432 /* Add to all MDT logs for CMD */
2433 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2434 if (!cfs_test_bit(i, fsdb->fsdb_mdt_index_map))
2436 name_create_mdt(&logname, mti->mti_fsname, i);
2437 rc = mgs_modify(obd, fsdb, mti, logname,
2438 mti->mti_svname, "add osc", flag);
2439 name_destroy(&logname);
2445 LCONSOLE_ERROR_MSG(0x145, "Couldn't find %s in"
2446 "log (%d). No permanent "
2447 "changes were made to the "
2449 mti->mti_svname, rc);
2450 if (cfs_test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags))
2451 LCONSOLE_ERROR_MSG(0x146, "This may be"
2456 "update the logs.\n");
2459 /* Fall through to osc proc for deactivating live OSC
2460 on running MDT / clients. */
2462 /* Below here, let obd's XXX_process_config methods handle it */
2464 /* All lov. in proc */
2465 if (class_match_param(ptr, PARAM_LOV, NULL) == 0) {
2468 CDEBUG(D_MGS, "lov param %s\n", ptr);
2469 if (!(mti->mti_flags & LDD_F_SV_TYPE_MDT)) {
2470 LCONSOLE_ERROR_MSG(0x147, "LOV params must be "
2471 "set on the MDT, not %s. "
2478 if (mgs_log_is_empty(obd, mti->mti_svname))
2479 GOTO(end, rc = -ENODEV);
2481 name_create_mdt_and_lov(&logname, &mdtlovname, fsdb,
2482 mti->mti_stripe_index);
2483 rc = mgs_wlp_lcfg(obd, fsdb, mti, mti->mti_svname,
2484 &bufs, mdtlovname, ptr);
2485 name_destroy(&logname);
2486 name_destroy(&mdtlovname);
2491 name_create(&logname, mti->mti_fsname, "-client");
2492 rc = mgs_wlp_lcfg(obd, fsdb, mti, logname, &bufs,
2493 fsdb->fsdb_clilov, ptr);
2494 name_destroy(&logname);
2498 /* All osc., mdc., llite. params in proc */
2499 if ((class_match_param(ptr, PARAM_OSC, NULL) == 0) ||
2500 (class_match_param(ptr, PARAM_MDC, NULL) == 0) ||
2501 (class_match_param(ptr, PARAM_LLITE, NULL) == 0)) {
2503 if (memcmp(ptr, PARAM_LLITE, strlen(PARAM_LLITE)) == 0) {
2504 name_create(&cname, mti->mti_fsname, "-client");
2505 /* Add the client type to match the obdname in
2506 class_config_llog_handler */
2507 } else if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
2510 name_create(&cname, fsdb->fsdb_mdc, "");
2512 name_create(&cname, mti->mti_svname,
2514 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2516 if (cfs_test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
2517 LCONSOLE_ERROR_MSG(0x148, "Upgraded "
2518 "client logs for %s"
2520 "modified. Consider"
2522 "configuration with"
2525 /* We don't know the names of all the
2527 GOTO(end, rc = -EINVAL);
2529 name_create(&cname, mti->mti_svname, "-osc");
2531 GOTO(end, rc = -EINVAL);
2534 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
2537 name_create(&logname, mti->mti_fsname, "-client");
2538 rc = mgs_wlp_lcfg(obd, fsdb, mti, logname, &bufs,
2541 /* osc params affect the MDT as well */
2542 if (!rc && (mti->mti_flags & LDD_F_SV_TYPE_OST)) {
2545 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
2546 if (!cfs_test_bit(i, fsdb->fsdb_mdt_index_map))
2548 name_destroy(&cname);
2549 name_create_mdt_osc(&cname, mti->mti_svname,
2551 name_destroy(&logname);
2552 name_create_mdt(&logname, mti->mti_fsname, i);
2553 if (!mgs_log_is_empty(obd, logname))
2554 rc = mgs_wlp_lcfg(obd, fsdb,mti,logname,
2560 name_destroy(&logname);
2561 name_destroy(&cname);
2565 /* All mdt. params in proc */
2566 if (class_match_param(ptr, PARAM_MDT, NULL) == 0) {
2570 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
2571 if (strncmp(mti->mti_svname, mti->mti_fsname,
2572 MTI_NAME_MAXLEN) == 0)
2573 /* device is unspecified completely? */
2574 rc = LDD_F_SV_TYPE_MDT | LDD_F_SV_ALL;
2576 rc = server_name2index(mti->mti_svname, &idx, NULL);
2579 if ((rc & LDD_F_SV_TYPE_MDT) == 0)
2581 if (rc & LDD_F_SV_ALL) {
2582 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2583 if (!cfs_test_bit(i,
2584 fsdb->fsdb_mdt_index_map))
2586 name_create_mdt(&logname, mti->mti_fsname, i);
2587 rc = mgs_wlp_lcfg(obd, fsdb, mti,
2590 name_destroy(&logname);
2595 rc = mgs_wlp_lcfg(obd, fsdb, mti,
2596 mti->mti_svname, &bufs,
2597 mti->mti_svname, ptr);
2604 /* All mdd., ost. params in proc */
2605 if ((class_match_param(ptr, PARAM_MDD, NULL) == 0) ||
2606 (class_match_param(ptr, PARAM_OST, NULL) == 0)) {
2607 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
2608 if (mgs_log_is_empty(obd, mti->mti_svname))
2609 GOTO(end, rc = -ENODEV);
2611 rc = mgs_wlp_lcfg(obd, fsdb, mti, mti->mti_svname,
2612 &bufs, mti->mti_svname, ptr);
2616 LCONSOLE_WARN("Ignoring unrecognized param '%s'\n", ptr);
2620 CERROR("err %d on param '%s'\n", rc, ptr);
2625 /* Not implementing automatic failover nid addition at this time. */
2626 int mgs_check_failnid(struct obd_device *obd, struct mgs_target_info *mti)
2633 rc = mgs_find_or_make_fsdb(obd, fsname, &fsdb);
2637 if (mgs_log_is_empty(obd, mti->mti_svname))
2638 /* should never happen */
2641 CDEBUG(D_MGS, "Checking for new failnids for %s\n", mti->mti_svname);
2643 /* FIXME We can just check mti->params to see if we're already in
2644 the failover list. Modify mti->params for rewriting back at
2645 server_register_target(). */
2647 cfs_down(&fsdb->fsdb_sem);
2648 rc = mgs_write_log_add_failnid(obd, fsdb, mti);
2649 cfs_up(&fsdb->fsdb_sem);
2656 int mgs_write_log_target(struct obd_device *obd,
2657 struct mgs_target_info *mti,
2664 /* set/check the new target index */
2665 rc = mgs_set_index(obd, mti);
2667 CERROR("Can't get index (%d)\n", rc);
2672 if (mti->mti_flags & LDD_F_UPGRADE14) {
2673 if (rc == EALREADY) {
2674 LCONSOLE_INFO("Found index %d for %s 1.4 log, "
2675 "upgrading\n", mti->mti_stripe_index,
2678 LCONSOLE_ERROR_MSG(0x149, "Failed to find %s in the old"
2679 " client log. Apparently it is not "
2680 "part of this filesystem, or the old"
2681 " log is wrong.\nUse 'writeconf' on "
2682 "the MDT to force log regeneration."
2683 "\n", mti->mti_svname);
2684 /* Not in client log? Upgrade anyhow...*/
2685 /* Argument against upgrading: reformat MDT,
2686 upgrade OST, then OST will start but will be SKIPped
2687 in client logs. Maybe error now is better. */
2688 /* RETURN(-EINVAL); */
2690 /* end COMPAT_146 */
2692 if (rc == EALREADY) {
2693 LCONSOLE_WARN("Found index %d for %s, updating log\n",
2694 mti->mti_stripe_index, mti->mti_svname);
2695 /* We would like to mark old log sections as invalid
2696 and add new log sections in the client and mdt logs.
2697 But if we add new sections, then live clients will
2698 get repeat setup instructions for already running
2699 osc's. So don't update the client/mdt logs. */
2700 mti->mti_flags &= ~LDD_F_UPDATE;
2704 cfs_down(&fsdb->fsdb_sem);
2706 if (mti->mti_flags &
2707 (LDD_F_VIRGIN | LDD_F_UPGRADE14 | LDD_F_WRITECONF)) {
2708 /* Generate a log from scratch */
2709 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
2710 rc = mgs_write_log_mdt(obd, fsdb, mti);
2711 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2712 rc = mgs_write_log_ost(obd, fsdb, mti);
2714 CERROR("Unknown target type %#x, can't create log for "
2715 "%s\n", mti->mti_flags, mti->mti_svname);
2718 CERROR("Can't write logs for %s (%d)\n",
2719 mti->mti_svname, rc);
2723 /* Just update the params from tunefs in mgs_write_log_params */
2724 CDEBUG(D_MGS, "Update params for %s\n", mti->mti_svname);
2725 mti->mti_flags |= LDD_F_PARAM;
2728 /* allocate temporary buffer, where class_get_next_param will
2729 make copy of a current parameter */
2730 OBD_ALLOC(buf, strlen(mti->mti_params) + 1);
2732 GOTO(out_up, rc = -ENOMEM);
2733 params = mti->mti_params;
2734 while (params != NULL) {
2735 rc = class_get_next_param(¶ms, buf);
2738 /* there is no next parameter, that is
2743 CDEBUG(D_MGS, "remaining string: '%s', param: '%s'\n",
2745 rc = mgs_write_log_param(obd, fsdb, mti, buf);
2750 OBD_FREE(buf, strlen(mti->mti_params) + 1);
2753 cfs_up(&fsdb->fsdb_sem);
2758 /* verify that we can handle the old config logs */
2759 int mgs_upgrade_sv_14(struct obd_device *obd, struct mgs_target_info *mti,
2765 /* Create ost log normally, as servers register. Servers
2766 register with their old uuids (from last_rcvd), so old
2767 (MDT and client) logs should work.
2768 - new MDT won't know about old OSTs, only the ones that have
2769 registered, so we need the old MDT log to get the LOV right
2770 in order for old clients to work.
2771 - Old clients connect to the MDT, not the MGS, for their logs, and
2772 will therefore receive the old client log from the MDT /LOGS dir.
2773 - Old clients can continue to use and connect to old or new OSTs
2774 - New clients will contact the MGS for their log
2777 LCONSOLE_INFO("upgrading server %s from pre-1.6\n", mti->mti_svname);
2778 server_mti_print("upgrade", mti);
2780 if (cfs_test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
2781 LCONSOLE_ERROR_MSG(0x14a, "The old client log %s-client is "
2782 "missing. Was tunefs.lustre successful?\n",
2787 if (fsdb->fsdb_gen == 0) {
2788 /* There were no markers in the client log, meaning we have
2789 not updated the logs for this fs */
2790 CDEBUG(D_MGS, "found old, unupdated client log\n");
2793 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
2794 if (mgs_log_is_empty(obd, mti->mti_svname)) {
2795 LCONSOLE_ERROR_MSG(0x14b, "The old MDT log %s is "
2796 "missing. Was tunefs.lustre "
2801 /* We're starting with an old uuid. Assume old name for lov
2802 as well since the lov entry already exists in the log. */
2803 CDEBUG(D_MGS, "old mds uuid %s\n", mti->mti_uuid);
2804 if (strncmp(mti->mti_uuid, fsdb->fsdb_mdtlov + 4,
2805 strlen(fsdb->fsdb_mdtlov) - 4) != 0) {
2806 CERROR("old mds uuid %s doesn't match log %s (%s)\n",
2807 mti->mti_uuid, fsdb->fsdb_mdtlov,
2808 fsdb->fsdb_mdtlov + 4);
2813 if (!cfs_test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
2814 LCONSOLE_ERROR_MSG(0x14c, "%s-client is supposedly an old "
2815 "log, but no old LOV or MDT was found. "
2816 "Consider updating the configuration with"
2817 " --writeconf.\n", mti->mti_fsname);
2822 /* end COMPAT_146 */
2824 int mgs_erase_log(struct obd_device *obd, char *name)
2826 struct lvfs_run_ctxt saved;
2827 struct llog_ctxt *ctxt;
2828 struct llog_handle *llh;
2831 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
2832 LASSERT(ctxt != NULL);
2834 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
2835 rc = llog_create(ctxt, &llh, NULL, name);
2837 llog_init_handle(llh, LLOG_F_IS_PLAIN, NULL);
2838 rc = llog_destroy(llh);
2839 llog_free_handle(llh);
2841 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
2842 llog_ctxt_put(ctxt);
2845 CERROR("failed to clear log %s: %d\n", name, rc);
2850 /* erase all logs for the given fs */
2851 int mgs_erase_logs(struct obd_device *obd, char *fsname)
2853 struct mgs_obd *mgs = &obd->u.mgs;
2854 static struct fs_db *fsdb;
2855 cfs_list_t dentry_list;
2856 struct l_linux_dirent *dirent, *n;
2857 int rc, len = strlen(fsname);
2861 /* Find all the logs in the CONFIGS directory */
2862 rc = class_dentry_readdir(obd, mgs->mgs_configs_dir,
2863 mgs->mgs_vfsmnt, &dentry_list);
2865 CERROR("Can't read %s dir\n", MOUNT_CONFIGS_DIR);
2869 cfs_down(&mgs->mgs_sem);
2871 /* Delete the fs db */
2872 fsdb = mgs_find_fsdb(obd, fsname);
2874 mgs_free_fsdb(obd, fsdb);
2876 cfs_list_for_each_entry_safe(dirent, n, &dentry_list, lld_list) {
2877 cfs_list_del(&dirent->lld_list);
2878 suffix = strrchr(dirent->lld_name, '-');
2879 if (suffix != NULL) {
2880 if ((len == suffix - dirent->lld_name) &&
2881 (strncmp(fsname, dirent->lld_name, len) == 0)) {
2882 CDEBUG(D_MGS, "Removing log %s\n",
2884 mgs_erase_log(obd, dirent->lld_name);
2887 OBD_FREE(dirent, sizeof(*dirent));
2890 cfs_up(&mgs->mgs_sem);
2895 /* from llog_swab */
2896 static void print_lustre_cfg(struct lustre_cfg *lcfg)
2901 CDEBUG(D_MGS, "lustre_cfg: %p\n", lcfg);
2902 CDEBUG(D_MGS, "\tlcfg->lcfg_version: %#x\n", lcfg->lcfg_version);
2904 CDEBUG(D_MGS, "\tlcfg->lcfg_command: %#x\n", lcfg->lcfg_command);
2905 CDEBUG(D_MGS, "\tlcfg->lcfg_num: %#x\n", lcfg->lcfg_num);
2906 CDEBUG(D_MGS, "\tlcfg->lcfg_flags: %#x\n", lcfg->lcfg_flags);
2907 CDEBUG(D_MGS, "\tlcfg->lcfg_nid: %s\n", libcfs_nid2str(lcfg->lcfg_nid));
2909 CDEBUG(D_MGS, "\tlcfg->lcfg_bufcount: %d\n", lcfg->lcfg_bufcount);
2910 if (lcfg->lcfg_bufcount < LUSTRE_CFG_MAX_BUFCOUNT)
2911 for (i = 0; i < lcfg->lcfg_bufcount; i++) {
2912 CDEBUG(D_MGS, "\tlcfg->lcfg_buflens[%d]: %d %s\n",
2913 i, lcfg->lcfg_buflens[i],
2914 lustre_cfg_string(lcfg, i));
2919 /* Set a permanent (config log) param for a target or fs
2920 * \param lcfg buf0 may contain the device (testfs-MDT0000) name
2921 * buf1 contains the single parameter
2923 int mgs_setparam(struct obd_device *obd, struct lustre_cfg *lcfg, char *fsname)
2926 struct mgs_target_info *mti;
2927 char *devname, *param;
2933 print_lustre_cfg(lcfg);
2935 /* lustre, lustre-mdtlov, lustre-client, lustre-MDT0000 */
2936 devname = lustre_cfg_string(lcfg, 0);
2937 param = lustre_cfg_string(lcfg, 1);
2939 /* Assume device name embedded in param:
2940 lustre-OST0000.osc.max_dirty_mb=32 */
2941 ptr = strchr(param, '.');
2949 LCONSOLE_ERROR_MSG(0x14d, "No target specified: %s\n", param);
2953 /* Extract fsname */
2954 ptr = strrchr(devname, '-');
2955 memset(fsname, 0, MTI_NAME_MAXLEN);
2956 if (ptr && (server_name2index(ptr, &index, NULL) >= 0)) {
2957 /* param related to llite isn't allowed to set by OST or MDT */
2958 if (strncmp(param, PARAM_LLITE, sizeof(PARAM_LLITE)) == 0)
2961 strncpy(fsname, devname, ptr - devname);
2963 /* assume devname is the fsname */
2964 strncpy(fsname, devname, MTI_NAME_MAXLEN);
2966 fsname[MTI_NAME_MAXLEN - 1] = 0;
2967 CDEBUG(D_MGS, "setparam fs='%s' device='%s'\n", fsname, devname);
2969 rc = mgs_find_or_make_fsdb(obd, fsname, &fsdb);
2972 if (!cfs_test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags) &&
2973 cfs_test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
2974 CERROR("No filesystem targets for %s. cfg_device from lctl "
2975 "is '%s'\n", fsname, devname);
2976 mgs_free_fsdb(obd, fsdb);
2980 /* Create a fake mti to hold everything */
2983 GOTO(out, rc = -ENOMEM);
2984 strncpy(mti->mti_fsname, fsname, MTI_NAME_MAXLEN);
2985 strncpy(mti->mti_svname, devname, MTI_NAME_MAXLEN);
2986 strncpy(mti->mti_params, param, sizeof(mti->mti_params));
2987 rc = server_name2index(mti->mti_svname, &mti->mti_stripe_index, &tmp);
2989 /* Not a valid server; may be only fsname */
2992 /* Strip -osc or -mdc suffix from svname */
2993 if (server_make_name(rc, mti->mti_stripe_index, mti->mti_fsname,
2995 GOTO(out, rc = -EINVAL);
2997 mti->mti_flags = rc | LDD_F_PARAM;
2999 cfs_down(&fsdb->fsdb_sem);
3000 rc = mgs_write_log_param(obd, fsdb, mti, mti->mti_params);
3001 cfs_up(&fsdb->fsdb_sem);
3004 * Revoke lock so everyone updates. Should be alright if
3005 * someone was already reading while we were updating the logs,
3006 * so we don't really need to hold the lock while we're
3009 mgs_revoke_lock(obd, fsdb);
3015 static int mgs_write_log_pool(struct obd_device *obd, char *logname,
3016 struct fs_db *fsdb, char *lovname,
3017 enum lcfg_command_type cmd,
3018 char *poolname, char *fsname,
3019 char *ostname, char *comment)
3021 struct llog_handle *llh = NULL;
3024 rc = record_start_log(obd, &llh, logname);
3027 rc = record_marker(obd, llh, fsdb, CM_START, lovname, comment);
3028 record_base(obd, llh, lovname, 0, cmd, poolname, fsname, ostname, 0);
3029 rc = record_marker(obd, llh, fsdb, CM_END, lovname, comment);
3030 rc = record_end_log(obd, &llh);
3035 int mgs_pool_cmd(struct obd_device *obd, enum lcfg_command_type cmd,
3036 char *fsname, char *poolname, char *ostname)
3041 char *label = NULL, *canceled_label = NULL;
3043 struct mgs_target_info *mti = NULL;
3047 rc = mgs_find_or_make_fsdb(obd, fsname, &fsdb);
3049 CERROR("Can't get db for %s\n", fsname);
3052 if (cfs_test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
3053 CERROR("%s is not defined\n", fsname);
3054 mgs_free_fsdb(obd, fsdb);
3058 label_sz = 10 + strlen(fsname) + strlen(poolname);
3060 /* check if ostname match fsname */
3061 if (ostname != NULL) {
3064 ptr = strrchr(ostname, '-');
3065 if ((ptr == NULL) ||
3066 (strncmp(fsname, ostname, ptr-ostname) != 0))
3068 label_sz += strlen(ostname);
3071 OBD_ALLOC(label, label_sz);
3073 GOTO(out, rc = -ENOMEM);
3076 case LCFG_POOL_NEW: {
3078 "new %s.%s", fsname, poolname);
3081 case LCFG_POOL_ADD: {
3083 "add %s.%s.%s", fsname, poolname, ostname);
3086 case LCFG_POOL_REM: {
3087 OBD_ALLOC(canceled_label, label_sz);
3088 if (canceled_label == NULL)
3089 GOTO(out, rc = -ENOMEM);
3091 "rem %s.%s.%s", fsname, poolname, ostname);
3092 sprintf(canceled_label,
3093 "add %s.%s.%s", fsname, poolname, ostname);
3096 case LCFG_POOL_DEL: {
3097 OBD_ALLOC(canceled_label, label_sz);
3098 if (canceled_label == NULL)
3099 GOTO(out, rc = -ENOMEM);
3101 "del %s.%s", fsname, poolname);
3102 sprintf(canceled_label,
3103 "new %s.%s", fsname, poolname);
3111 cfs_down(&fsdb->fsdb_sem);
3113 if (canceled_label != NULL) {
3116 GOTO(out, rc = -ENOMEM);
3119 /* write pool def to all MDT logs */
3120 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3121 if (cfs_test_bit(i, fsdb->fsdb_mdt_index_map)) {
3122 name_create_mdt_and_lov(&logname, &lovname, fsdb, i);
3124 if (canceled_label != NULL) {
3125 strcpy(mti->mti_svname, "lov pool");
3126 mgs_modify(obd, fsdb, mti, logname, lovname,
3127 canceled_label, CM_SKIP);
3130 mgs_write_log_pool(obd, logname, fsdb, lovname,
3131 cmd, fsname, poolname, ostname,
3133 name_destroy(&logname);
3134 name_destroy(&lovname);
3138 name_create(&logname, fsname, "-client");
3139 if (canceled_label != NULL)
3140 mgs_modify(obd, fsdb, mti, logname, fsdb->fsdb_clilov,
3141 canceled_label, CM_SKIP);
3143 mgs_write_log_pool(obd, logname, fsdb, fsdb->fsdb_clilov,
3144 cmd, fsname, poolname, ostname, label);
3145 name_destroy(&logname);
3147 cfs_up(&fsdb->fsdb_sem);
3148 /* request for update */
3149 mgs_revoke_lock(obd, fsdb);
3154 OBD_FREE(label, label_sz);
3156 if (canceled_label != NULL)
3157 OBD_FREE(canceled_label, label_sz);
3166 /******************** unused *********************/
3167 static int mgs_backup_llog(struct obd_device *obd, char* fsname)
3169 struct file *filp, *bak_filp;
3170 struct lvfs_run_ctxt saved;
3171 char *logname, *buf;
3172 loff_t soff = 0 , doff = 0;
3173 int count = 4096, len;
3176 OBD_ALLOC(logname, PATH_MAX);
3177 if (logname == NULL)
3180 OBD_ALLOC(buf, count);
3182 GOTO(out , rc = -ENOMEM);
3184 len = snprintf(logname, PATH_MAX, "%s/%s.bak",
3185 MOUNT_CONFIGS_DIR, fsname);
3187 if (len >= PATH_MAX - 1) {
3188 GOTO(out, -ENAMETOOLONG);
3191 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
3193 bak_filp = l_filp_open(logname, O_RDWR|O_CREAT|O_TRUNC, 0660);
3194 if (IS_ERR(bak_filp)) {
3195 rc = PTR_ERR(bak_filp);
3196 CERROR("backup logfile open %s: %d\n", logname, rc);
3199 sprintf(logname, "%s/%s", MOUNT_CONFIGS_DIR, fsname);
3200 filp = l_filp_open(logname, O_RDONLY, 0);
3203 CERROR("logfile open %s: %d\n", logname, rc);
3207 while ((rc = lustre_fread(filp, buf, count, &soff)) > 0) {
3208 rc = lustre_fwrite(bak_filp, buf, count, &doff);
3212 filp_close(filp, 0);
3214 filp_close(bak_filp, 0);
3216 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
3219 OBD_FREE(buf, count);
3220 OBD_FREE(logname, PATH_MAX);