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 strncpy(tmti->mti_svname, marker->cm_tgtname,
1129 sizeof(tmti->mti_svname));
1130 rc = record_start_log(obd, &mdt_llh, mti->mti_svname);
1131 rc = record_marker(obd, mdt_llh, fsdb, CM_START,
1132 mti->mti_svname,"add osc(copied)");
1133 rc = record_end_log(obd, &mdt_llh);
1134 last_step = marker->cm_step;
1137 if (!strncmp(marker->cm_comment,"add osc",7) &&
1138 (marker->cm_flags & CM_END)){
1139 LASSERT(last_step == marker->cm_step);
1141 got_an_osc_or_mdc = 0;
1142 rc = record_start_log(obd, &mdt_llh, mti->mti_svname);
1143 rc = record_marker(obd, mdt_llh, fsdb, CM_END,
1144 mti->mti_svname,"add osc(copied)");
1145 rc = record_end_log(obd, &mdt_llh);
1148 if (!strncmp(marker->cm_comment,"add mdc",7) &&
1149 (marker->cm_flags & CM_START)){
1150 got_an_osc_or_mdc = 2;
1151 last_step = marker->cm_step;
1152 memcpy(tmti->mti_svname, marker->cm_tgtname,
1153 strlen(marker->cm_tgtname));
1157 if (!strncmp(marker->cm_comment,"add mdc",7) &&
1158 (marker->cm_flags & CM_END)){
1159 LASSERT(last_step == marker->cm_step);
1161 got_an_osc_or_mdc = 0;
1166 if (got_an_osc_or_mdc == 0 || last_step < 0)
1169 if (lcfg->lcfg_command == LCFG_ADD_UUID) {
1171 nodenid = lcfg->lcfg_nid;
1173 tmti->mti_nids[tmti->mti_nid_count] = nodenid;
1174 tmti->mti_nid_count++;
1179 if (lcfg->lcfg_command == LCFG_SETUP) {
1182 target = lustre_cfg_string(lcfg, 1);
1183 memcpy(tmti->mti_uuid, target, strlen(target));
1187 /* ignore client side sptlrpc_conf_log */
1188 if (lcfg->lcfg_command == LCFG_SPTLRPC_CONF)
1191 if (lcfg->lcfg_command == LCFG_ADD_MDC) {
1194 if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1)
1197 memcpy(tmti->mti_fsname, mti->mti_fsname,
1198 strlen(mti->mti_fsname));
1199 tmti->mti_stripe_index = index;
1201 mgs_write_log_mdc_to_mdt(obd, fsdb, tmti, mti->mti_svname);
1202 memset(tmti, 0, sizeof(*tmti));
1206 if (lcfg->lcfg_command == LCFG_LOV_ADD_OBD) {
1209 char *logname, *lovname;
1211 name_create_mdt_and_lov(&logname, &lovname, fsdb,
1212 mti->mti_stripe_index);
1213 sprintf(mdt_index, "-MDT%04x", mti->mti_stripe_index);
1215 if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1) {
1216 name_destroy(&logname);
1217 name_destroy(&lovname);
1221 tmti->mti_stripe_index = index;
1222 mgs_write_log_osc_to_lov(obd, fsdb, tmti, logname,
1225 name_destroy(&logname);
1226 name_destroy(&lovname);
1232 /* fsdb->fsdb_sem is already held in mgs_write_log_target*/
1233 /* stealed from mgs_get_fsdb_from_llog*/
1234 static int mgs_steal_llog_for_mdt_from_client(struct obd_device *obd,
1236 struct temp_comp* comp)
1238 struct llog_handle *loghandle;
1239 struct lvfs_run_ctxt saved;
1240 struct mgs_target_info *tmti;
1241 struct llog_ctxt *ctxt;
1245 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
1246 LASSERT(ctxt != NULL);
1248 OBD_ALLOC_PTR(tmti);
1252 comp->comp_tmti = tmti;
1253 comp->comp_obd = obd;
1255 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
1257 rc = llog_create(ctxt, &loghandle, NULL, client_name);
1261 rc = llog_init_handle(loghandle, LLOG_F_IS_PLAIN, NULL);
1263 GOTO(out_close, rc);
1265 rc = llog_process(loghandle, mgs_steal_llog_handler, (void *)comp, NULL);
1266 CDEBUG(D_MGS, "steal llog re = %d\n", rc);
1268 rc2 = llog_close(loghandle);
1272 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
1274 llog_ctxt_put(ctxt);
1278 /* lmv is the second thing for client logs */
1279 /* copied from mgs_write_log_lov. Please refer to that. */
1280 static int mgs_write_log_lmv(struct obd_device *obd, struct fs_db *fsdb,
1281 struct mgs_target_info *mti,
1282 char *logname, char *lmvname)
1284 struct llog_handle *llh = NULL;
1285 struct lmv_desc *lmvdesc;
1290 CDEBUG(D_MGS, "Writing lmv(%s) log for %s\n", lmvname,logname);
1292 OBD_ALLOC_PTR(lmvdesc);
1293 if (lmvdesc == NULL)
1295 lmvdesc->ld_active_tgt_count = 0;
1296 lmvdesc->ld_tgt_count = 0;
1297 sprintf((char*)lmvdesc->ld_uuid.uuid, "%s_UUID", lmvname);
1298 uuid = (char *)lmvdesc->ld_uuid.uuid;
1300 rc = record_start_log(obd, &llh, logname);
1301 rc = record_marker(obd, llh, fsdb, CM_START, lmvname, "lmv setup");
1302 rc = record_attach(obd, llh, lmvname, "lmv", uuid);
1303 rc = record_lmv_setup(obd, llh, lmvname, lmvdesc);
1304 rc = record_marker(obd, llh, fsdb, CM_END, lmvname, "lmv setup");
1305 rc = record_end_log(obd, &llh);
1307 OBD_FREE_PTR(lmvdesc);
1311 /* lov is the first thing in the mdt and client logs */
1312 static int mgs_write_log_lov(struct obd_device *obd, struct fs_db *fsdb,
1313 struct mgs_target_info *mti,
1314 char *logname, char *lovname)
1316 struct llog_handle *llh = NULL;
1317 struct lov_desc *lovdesc;
1322 CDEBUG(D_MGS, "Writing lov(%s) log for %s\n", lovname, logname);
1325 #01 L attach 0:lov_mdsA 1:lov 2:71ccb_lov_mdsA_19f961a9e1
1326 #02 L lov_setup 0:lov_mdsA 1:(struct lov_desc)
1327 uuid=lov1_UUID, stripe count=1, size=1048576, offset=0, pattern=0
1330 /* FIXME just make lov_setup accept empty desc (put uuid in buf 2) */
1331 OBD_ALLOC_PTR(lovdesc);
1332 if (lovdesc == NULL)
1334 lovdesc->ld_magic = LOV_DESC_MAGIC;
1335 lovdesc->ld_tgt_count = 0;
1336 /* Defaults. Can be changed later by lcfg config_param */
1337 lovdesc->ld_default_stripe_count = 1;
1338 lovdesc->ld_pattern = LOV_PATTERN_RAID0;
1339 lovdesc->ld_default_stripe_size = 1024 * 1024;
1340 lovdesc->ld_default_stripe_offset = -1;
1341 lovdesc->ld_qos_maxage = QOS_DEFAULT_MAXAGE;
1342 sprintf((char*)lovdesc->ld_uuid.uuid, "%s_UUID", lovname);
1343 /* can these be the same? */
1344 uuid = (char *)lovdesc->ld_uuid.uuid;
1346 /* This should always be the first entry in a log.
1347 rc = mgs_clear_log(obd, logname); */
1348 rc = record_start_log(obd, &llh, logname);
1351 /* FIXME these should be a single journal transaction */
1352 rc = record_marker(obd, llh, fsdb, CM_START, lovname, "lov setup");
1353 rc = record_attach(obd, llh, lovname, "lov", uuid);
1354 rc = record_lov_setup(obd, llh, lovname, lovdesc);
1355 rc = record_marker(obd, llh, fsdb, CM_END, lovname, "lov setup");
1356 rc = record_end_log(obd, &llh);
1360 OBD_FREE_PTR(lovdesc);
1364 /* add failnids to open log */
1365 static int mgs_write_log_failnids(struct obd_device *obd,
1366 struct mgs_target_info *mti,
1367 struct llog_handle *llh,
1370 char *failnodeuuid = NULL;
1371 char *ptr = mti->mti_params;
1376 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) nal=90 0: 1:uml1_UUID
1377 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
1378 #05 L setup 0:OSC_uml1_ost1_mdsA 1:ost1_UUID 2:uml1_UUID
1379 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) nal=90 0: 1:uml2_UUID
1380 #0x L add_uuid nid=2@elan(0x1000000000002) nal=90 0: 1:uml2_UUID
1381 #07 L add_conn 0:OSC_uml1_ost1_mdsA 1:uml2_UUID
1384 /* Pull failnid info out of params string */
1385 while (class_find_param(ptr, PARAM_FAILNODE, &ptr) == 0) {
1386 while (class_parse_nid(ptr, &nid, &ptr) == 0) {
1387 if (failnodeuuid == NULL) {
1388 /* We don't know the failover node name,
1389 so just use the first nid as the uuid */
1390 rc = name_create(&failnodeuuid,
1391 libcfs_nid2str(nid), "");
1395 CDEBUG(D_MGS, "add nid %s for failover uuid %s, "
1396 "client %s\n", libcfs_nid2str(nid),
1397 failnodeuuid, cliname);
1398 rc = record_add_uuid(obd, llh, nid, failnodeuuid);
1401 rc = record_add_conn(obd, llh, cliname, failnodeuuid);
1402 name_destroy(&failnodeuuid);
1403 failnodeuuid = NULL;
1410 static int mgs_write_log_mdc_to_lmv(struct obd_device *obd, struct fs_db *fsdb,
1411 struct mgs_target_info *mti,
1412 char *logname, char *lmvname)
1414 struct llog_handle *llh = NULL;
1415 char *mdcname, *nodeuuid, *mdcuuid, *lmvuuid;
1420 if (mgs_log_is_empty(obd, logname)) {
1421 CERROR("log is empty! Logical error\n");
1425 CDEBUG(D_MGS, "adding mdc for %s to log %s:lmv(%s)\n",
1426 mti->mti_svname, logname, lmvname);
1428 name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
1429 name_create(&mdcname, mti->mti_svname, "-mdc");
1430 name_create(&mdcuuid, mdcname, "_UUID");
1431 name_create(&lmvuuid, lmvname, "_UUID");
1433 rc = record_start_log(obd, &llh, logname);
1434 rc = record_marker(obd, llh, fsdb, CM_START, mti->mti_svname,
1437 for (i = 0; i < mti->mti_nid_count; i++) {
1438 CDEBUG(D_MGS, "add nid %s for mdt\n",
1439 libcfs_nid2str(mti->mti_nids[i]));
1441 rc = record_add_uuid(obd, llh, mti->mti_nids[i], nodeuuid);
1444 rc = record_attach(obd, llh, mdcname, LUSTRE_MDC_NAME, lmvuuid);
1445 rc = record_setup(obd, llh, mdcname, mti->mti_uuid, nodeuuid, 0, 0);
1446 rc = mgs_write_log_failnids(obd, mti, llh, mdcname);
1447 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
1448 rc = record_mdc_add(obd, llh, lmvname, mdcuuid, mti->mti_uuid,
1450 rc = record_marker(obd, llh, fsdb, CM_END, mti->mti_svname,
1452 rc = record_end_log(obd, &llh);
1454 name_destroy(&lmvuuid);
1455 name_destroy(&mdcuuid);
1456 name_destroy(&mdcname);
1457 name_destroy(&nodeuuid);
1461 /* add new mdc to already existent MDS */
1462 static int mgs_write_log_mdc_to_mdt(struct obd_device *obd, struct fs_db *fsdb,
1463 struct mgs_target_info *mti, char *logname)
1465 struct llog_handle *llh = NULL;
1466 char *nodeuuid, *mdcname, *mdcuuid, *mdtuuid;
1467 int idx = mti->mti_stripe_index;
1472 if (mgs_log_is_empty(obd, logname)) {
1473 CERROR("log is empty! Logical error\n");
1477 CDEBUG(D_MGS, "adding mdc index %d to %s\n", idx, logname);
1479 name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
1480 snprintf(index, sizeof(index), "-mdc%04x", idx);
1481 name_create(&mdcname, logname, index);
1482 name_create(&mdcuuid, mdcname, "_UUID");
1483 name_create(&mdtuuid, logname, "_UUID");
1485 rc = record_start_log(obd, &llh, logname);
1486 rc = record_marker(obd, llh, fsdb, CM_START, mti->mti_svname, "add mdc");
1487 for (i = 0; i < mti->mti_nid_count; i++) {
1488 CDEBUG(D_MGS, "add nid %s for mdt\n",
1489 libcfs_nid2str(mti->mti_nids[i]));
1490 rc = record_add_uuid(obd, llh, mti->mti_nids[i], nodeuuid);
1492 rc = record_attach(obd, llh, mdcname, LUSTRE_MDC_NAME, mdcuuid);
1493 rc = record_setup(obd, llh, mdcname, mti->mti_uuid, nodeuuid, 0, 0);
1494 rc = mgs_write_log_failnids(obd, mti, llh, mdcname);
1495 snprintf(index, sizeof(index), "%d", idx);
1497 rc = record_mdc_add(obd, llh, logname, mdcuuid, mti->mti_uuid,
1499 rc = record_marker(obd, llh, fsdb, CM_END, mti->mti_svname, "add mdc");
1500 rc = record_end_log(obd, &llh);
1502 name_destroy(&mdcuuid);
1503 name_destroy(&mdcname);
1504 name_destroy(&nodeuuid);
1505 name_destroy(&mdtuuid);
1509 static int mgs_write_log_mdt0(struct obd_device *obd, struct fs_db *fsdb,
1510 struct mgs_target_info *mti)
1512 char *log = mti->mti_svname;
1513 struct llog_handle *llh = NULL;
1514 char *uuid, *lovname;
1516 char *ptr = mti->mti_params;
1517 int rc = 0, failout = 0;
1520 OBD_ALLOC(uuid, sizeof(struct obd_uuid));
1524 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
1525 failout = (strncmp(ptr, "failout", 7) == 0);
1527 name_create(&lovname, log, "-mdtlov");
1528 if (mgs_log_is_empty(obd, log))
1529 rc = mgs_write_log_lov(obd, fsdb, mti, log, lovname);
1531 sprintf(uuid, "%s_UUID", log);
1532 sprintf(mdt_index, "%d", mti->mti_stripe_index);
1534 /* add MDT itself */
1535 rc = record_start_log(obd, &llh, log);
1539 /* FIXME this whole fn should be a single journal transaction */
1540 rc = record_marker(obd, llh, fsdb, CM_START, log, "add mdt");
1541 rc = record_attach(obd, llh, log, LUSTRE_MDT_NAME, uuid);
1542 rc = record_mount_opt(obd, llh, log, lovname, NULL);
1543 rc = record_setup(obd, llh, log, uuid, mdt_index, lovname,
1544 failout ? "n" : "f");
1545 rc = record_marker(obd, llh, fsdb, CM_END, log, "add mdt");
1546 rc = record_end_log(obd, &llh);
1548 name_destroy(&lovname);
1549 OBD_FREE(uuid, sizeof(struct obd_uuid));
1553 static inline void name_create_mdt(char **logname, char *fsname, int i)
1557 sprintf(mdt_index, "-MDT%04x", i);
1558 name_create(logname, fsname, mdt_index);
1561 static void name_create_mdt_and_lov(char **logname, char **lovname,
1562 struct fs_db *fsdb, int i)
1564 name_create_mdt(logname, fsdb->fsdb_name, i);
1566 if (i == 0 && cfs_test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
1567 name_create(lovname, fsdb->fsdb_name, "-mdtlov");
1569 name_create(lovname, *logname, "-mdtlov");
1572 static inline void name_create_mdt_osc(char **oscname, char *ostname,
1573 struct fs_db *fsdb, int i)
1577 if (i == 0 && cfs_test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
1578 sprintf(suffix, "-osc");
1580 sprintf(suffix, "-osc-MDT%04x", i);
1581 name_create(oscname, ostname, suffix);
1584 /* envelope method for all layers log */
1585 static int mgs_write_log_mdt(struct obd_device *obd, struct fs_db *fsdb,
1586 struct mgs_target_info *mti)
1588 struct llog_handle *llh = NULL;
1590 struct temp_comp comp = { 0 };
1594 CDEBUG(D_MGS, "writing new mdt %s\n", mti->mti_svname);
1598 if (mti->mti_flags & LDD_F_UPGRADE14) {
1599 /* We're starting with an old uuid. Assume old name for lov
1600 as well since the lov entry already exists in the log. */
1601 CDEBUG(D_MGS, "old mds uuid %s\n", mti->mti_uuid);
1602 if (strncmp(mti->mti_uuid, fsdb->fsdb_mdtlov + 4,
1603 strlen(fsdb->fsdb_mdtlov) - 4) != 0) {
1604 CERROR("old mds uuid %s doesn't match log %s (%s)\n",
1605 mti->mti_uuid, fsdb->fsdb_mdtlov,
1606 fsdb->fsdb_mdtlov + 4);
1610 /* end COMPAT_146 */
1612 if (mti->mti_uuid[0] == '\0') {
1613 /* Make up our own uuid */
1614 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
1615 "%s_UUID", mti->mti_svname);
1619 rc = mgs_write_log_mdt0(obd, fsdb, mti);
1621 /* Append the mdt info to the client log */
1622 name_create(&cliname, mti->mti_fsname, "-client");
1624 if (mgs_log_is_empty(obd, cliname)) {
1625 /* Start client log */
1626 rc = mgs_write_log_lov(obd, fsdb, mti, cliname,
1628 rc = mgs_write_log_lmv(obd, fsdb, mti, cliname,
1633 #09 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
1634 #10 L attach 0:MDC_uml1_mdsA_MNT_client 1:mdc 2:1d834_MNT_client_03f
1635 #11 L setup 0:MDC_uml1_mdsA_MNT_client 1:mdsA_UUID 2:uml1_UUID
1636 #12 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
1637 #13 L add_conn 0:MDC_uml1_mdsA_MNT_client 1:uml2_UUID
1638 #14 L mount_option 0: 1:client 2:lov1 3:MDC_uml1_mdsA_MNT_client
1643 if (mti->mti_flags & LDD_F_UPGRADE14) {
1644 rc = record_start_log(obd, &llh, cliname);
1648 rc = record_marker(obd, llh, fsdb, CM_START,
1649 mti->mti_svname,"add mdc");
1651 /* Old client log already has MDC entry, but needs mount opt
1652 for new client name (lustre-client) */
1653 /* FIXME Old MDT log already has an old mount opt
1654 which we should remove (currently handled by
1655 class_del_profiles()) */
1656 rc = record_mount_opt(obd, llh, cliname, fsdb->fsdb_clilov,
1658 /* end COMPAT_146 */
1660 rc = record_marker(obd, llh, fsdb, CM_END,
1661 mti->mti_svname, "add mdc");
1665 /* copy client info about lov/lmv */
1666 comp.comp_mti = mti;
1667 comp.comp_fsdb = fsdb;
1669 rc = mgs_steal_llog_for_mdt_from_client(obd, cliname,
1672 rc = mgs_write_log_mdc_to_lmv(obd, fsdb, mti, cliname,
1675 rc = record_start_log(obd, &llh, cliname);
1679 rc = record_marker(obd, llh, fsdb, CM_START, cliname,
1681 rc = record_mount_opt(obd, llh, cliname, fsdb->fsdb_clilov,
1683 rc = record_marker(obd, llh, fsdb, CM_END, cliname,
1687 rc = record_end_log(obd, &llh);
1689 name_destroy(&cliname);
1691 // for_all_existing_mdt except current one
1692 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
1694 if (i != mti->mti_stripe_index &&
1695 cfs_test_bit(i, fsdb->fsdb_mdt_index_map)) {
1696 name_create_mdt(&mdtname, mti->mti_fsname, i);
1697 rc = mgs_write_log_mdc_to_mdt(obd, fsdb, mti, mdtname);
1698 name_destroy(&mdtname);
1705 /* Add the ost info to the client/mdt lov */
1706 static int mgs_write_log_osc_to_lov(struct obd_device *obd, struct fs_db *fsdb,
1707 struct mgs_target_info *mti,
1708 char *logname, char *suffix, char *lovname,
1709 enum lustre_sec_part sec_part, int flags)
1711 struct llog_handle *llh = NULL;
1712 char *nodeuuid, *oscname, *oscuuid, *lovuuid, *svname;
1717 CDEBUG(D_INFO, "adding osc for %s to log %s\n",
1718 mti->mti_svname, logname);
1720 if (mgs_log_is_empty(obd, logname)) {
1721 CERROR("log is empty! Logical error\n");
1725 name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
1726 name_create(&svname, mti->mti_svname, "-osc");
1727 name_create(&oscname, svname, suffix);
1728 name_create(&oscuuid, oscname, "_UUID");
1729 name_create(&lovuuid, lovname, "_UUID");
1732 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
1734 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
1735 #04 L attach 0:OSC_uml1_ost1_MNT_client 1:osc 2:89070_lov1_a41dff51a
1736 #05 L setup 0:OSC_uml1_ost1_MNT_client 1:ost1_UUID 2:uml1_UUID
1738 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
1739 #07 L add_conn 0:OSC_uml1_ost1_MNT_client 1:uml2_UUID
1740 #08 L lov_modify_tgts add 0:lov1 1:ost1_UUID 2(index):0 3(gen):1
1743 rc = record_start_log(obd, &llh, logname);
1746 /* FIXME these should be a single journal transaction */
1747 rc = record_marker(obd, llh, fsdb, CM_START | flags, mti->mti_svname,
1749 for (i = 0; i < mti->mti_nid_count; i++) {
1750 CDEBUG(D_MGS, "add nid %s\n", libcfs_nid2str(mti->mti_nids[i]));
1751 rc = record_add_uuid(obd, llh, mti->mti_nids[i], nodeuuid);
1753 rc = record_attach(obd, llh, oscname, LUSTRE_OSC_NAME, lovuuid);
1754 rc = record_setup(obd, llh, oscname, mti->mti_uuid, nodeuuid, 0, 0);
1755 rc = mgs_write_log_failnids(obd, mti, llh, oscname);
1756 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
1757 rc = record_lov_add(obd, llh, lovname, mti->mti_uuid, index, "1");
1758 rc = record_marker(obd, llh, fsdb, CM_END | flags, mti->mti_svname,
1760 rc = record_end_log(obd, &llh);
1762 name_destroy(&lovuuid);
1763 name_destroy(&oscuuid);
1764 name_destroy(&oscname);
1765 name_destroy(&svname);
1766 name_destroy(&nodeuuid);
1770 static int mgs_write_log_ost(struct obd_device *obd, struct fs_db *fsdb,
1771 struct mgs_target_info *mti)
1773 struct llog_handle *llh = NULL;
1774 char *logname, *lovname;
1775 char *ptr = mti->mti_params;
1776 int rc, flags = 0, failout = 0, i;
1779 CDEBUG(D_MGS, "writing new ost %s\n", mti->mti_svname);
1781 /* The ost startup log */
1783 /* If the ost log already exists, that means that someone reformatted
1784 the ost and it called target_add again. */
1785 if (!mgs_log_is_empty(obd, mti->mti_svname)) {
1786 LCONSOLE_ERROR_MSG(0x141, "The config log for %s already "
1787 "exists, yet the server claims it never "
1788 "registered. It may have been reformatted, "
1789 "or the index changed. writeconf the MDT to "
1790 "regenerate all logs.\n", mti->mti_svname);
1795 attach obdfilter ost1 ost1_UUID
1796 setup /dev/loop2 ldiskfs f|n errors=remount-ro,user_xattr
1798 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
1799 failout = (strncmp(ptr, "failout", 7) == 0);
1800 rc = record_start_log(obd, &llh, mti->mti_svname);
1803 /* FIXME these should be a single journal transaction */
1804 rc = record_marker(obd, llh, fsdb, CM_START, mti->mti_svname,"add ost");
1805 if (*mti->mti_uuid == '\0')
1806 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
1807 "%s_UUID", mti->mti_svname);
1808 rc = record_attach(obd, llh, mti->mti_svname,
1809 "obdfilter"/*LUSTRE_OST_NAME*/, mti->mti_uuid);
1810 rc = record_setup(obd, llh, mti->mti_svname,
1811 "dev"/*ignored*/, "type"/*ignored*/,
1812 failout ? "n" : "f", 0/*options*/);
1813 rc = record_marker(obd, llh, fsdb, CM_END, mti->mti_svname, "add ost");
1814 rc = record_end_log(obd, &llh);
1816 /* We also have to update the other logs where this osc is part of
1819 if (cfs_test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
1820 /* If we're upgrading, the old mdt log already has our
1821 entry. Let's do a fake one for fun. */
1822 /* Note that we can't add any new failnids, since we don't
1823 know the old osc names. */
1824 flags = CM_SKIP | CM_UPGRADE146;
1826 } else if ((mti->mti_flags & LDD_F_UPDATE) != LDD_F_UPDATE) {
1827 /* If the update flag isn't set, don't update client/mdt
1830 LCONSOLE_WARN("Client log for %s was not updated; writeconf "
1831 "the MDT first to regenerate it.\n",
1835 /* Add ost to all MDT lov defs */
1836 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
1837 if (cfs_test_bit(i, fsdb->fsdb_mdt_index_map)) {
1840 name_create_mdt_and_lov(&logname, &lovname, fsdb, i);
1841 sprintf(mdt_index, "-MDT%04x", i);
1842 mgs_write_log_osc_to_lov(obd, fsdb, mti, logname,
1844 LUSTRE_SP_MDT, flags);
1845 name_destroy(&logname);
1846 name_destroy(&lovname);
1850 /* Append ost info to the client log */
1851 name_create(&logname, mti->mti_fsname, "-client");
1852 if (mgs_log_is_empty(obd, logname)) {
1853 /* Start client log */
1854 rc = mgs_write_log_lov(obd, fsdb, mti, logname,
1856 rc = mgs_write_log_lmv(obd, fsdb, mti, logname,
1859 mgs_write_log_osc_to_lov(obd, fsdb, mti, logname, "",
1860 fsdb->fsdb_clilov, LUSTRE_SP_CLI, flags);
1861 name_destroy(&logname);
1865 static __inline__ int mgs_param_empty(char *ptr)
1869 if ((tmp = strchr(ptr, '=')) && (*(++tmp) == '\0'))
1874 static int mgs_write_log_failnid_internal(struct obd_device *obd,
1876 struct mgs_target_info *mti,
1877 char *logname, char *cliname)
1880 struct llog_handle *llh = NULL;
1882 if (mgs_param_empty(mti->mti_params)) {
1883 /* Remove _all_ failnids */
1884 rc = mgs_modify(obd, fsdb, mti, logname,
1885 mti->mti_svname, "add failnid", CM_SKIP);
1889 /* Otherwise failover nids are additive */
1890 rc = record_start_log(obd, &llh, logname);
1892 /* FIXME this should be a single journal transaction */
1893 rc = record_marker(obd, llh, fsdb, CM_START,
1894 mti->mti_svname, "add failnid");
1895 rc = mgs_write_log_failnids(obd, mti, llh, cliname);
1896 rc = record_marker(obd, llh, fsdb, CM_END,
1897 mti->mti_svname, "add failnid");
1898 rc = record_end_log(obd, &llh);
1905 /* Add additional failnids to an existing log.
1906 The mdc/osc must have been added to logs first */
1907 /* tcp nids must be in dotted-quad ascii -
1908 we can't resolve hostnames from the kernel. */
1909 static int mgs_write_log_add_failnid(struct obd_device *obd, struct fs_db *fsdb,
1910 struct mgs_target_info *mti)
1912 char *logname, *cliname;
1916 /* FIXME we currently can't erase the failnids
1917 * given when a target first registers, since they aren't part of
1918 * an "add uuid" stanza */
1920 /* Verify that we know about this target */
1921 if (mgs_log_is_empty(obd, mti->mti_svname)) {
1922 LCONSOLE_ERROR_MSG(0x142, "The target %s has not registered "
1923 "yet. It must be started before failnids "
1924 "can be added.\n", mti->mti_svname);
1928 /* Create mdc/osc client name (e.g. lustre-OST0001-osc) */
1929 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
1930 name_create(&cliname, mti->mti_svname, "-mdc");
1931 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
1932 name_create(&cliname, mti->mti_svname, "-osc");
1937 /* Add failover nids to the client log */
1938 name_create(&logname, mti->mti_fsname, "-client");
1939 rc = mgs_write_log_failnid_internal(obd, fsdb, mti, logname, cliname);
1940 name_destroy(&logname);
1941 name_destroy(&cliname);
1943 if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
1944 /* Add OST failover nids to the MDT logs as well */
1947 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
1948 if (!cfs_test_bit(i, fsdb->fsdb_mdt_index_map))
1950 name_create_mdt(&logname, mti->mti_fsname, i);
1951 name_create_mdt_osc(&cliname, mti->mti_svname, fsdb, i);
1952 rc = mgs_write_log_failnid_internal(obd, fsdb, mti,
1954 name_destroy(&cliname);
1955 name_destroy(&logname);
1962 static int mgs_wlp_lcfg(struct obd_device *obd, struct fs_db *fsdb,
1963 struct mgs_target_info *mti,
1964 char *logname, struct lustre_cfg_bufs *bufs,
1965 char *tgtname, char *ptr)
1967 char comment[MTI_NAME_MAXLEN];
1969 struct lustre_cfg *lcfg;
1972 /* Erase any old settings of this same parameter */
1973 memcpy(comment, ptr, MTI_NAME_MAXLEN);
1974 comment[MTI_NAME_MAXLEN - 1] = 0;
1975 /* But don't try to match the value. */
1976 if ((tmp = strchr(comment, '=')))
1978 /* FIXME we should skip settings that are the same as old values */
1979 rc = mgs_modify(obd, fsdb, mti, logname, tgtname, comment, CM_SKIP);
1980 del = mgs_param_empty(ptr);
1982 LCONSOLE_INFO("%sing parameter %s.%s in log %s\n", del ? "Disabl" : rc ?
1983 "Sett" : "Modify", tgtname, comment, logname);
1987 lustre_cfg_bufs_reset(bufs, tgtname);
1988 lustre_cfg_bufs_set_string(bufs, 1, ptr);
1989 lcfg = lustre_cfg_new(LCFG_PARAM, bufs);
1992 rc = mgs_write_log_direct(obd, fsdb, logname, lcfg, tgtname, comment);
1993 lustre_cfg_free(lcfg);
1997 /* write global variable settings into log */
1998 static int mgs_write_log_sys(struct obd_device *obd, struct fs_db *fsdb,
1999 struct mgs_target_info *mti, char *sys, char *ptr)
2001 struct lustre_cfg_bufs bufs;
2002 struct lustre_cfg *lcfg;
2008 if (class_match_param(ptr, PARAM_TIMEOUT, &tmp) == 0)
2009 cmd = LCFG_SET_TIMEOUT;
2010 else if (class_match_param(ptr, PARAM_LDLM_TIMEOUT, &tmp) == 0)
2011 cmd = LCFG_SET_LDLM_TIMEOUT;
2012 /* Check for known params here so we can return error to lctl */
2013 else if ((class_match_param(ptr, PARAM_AT_MIN, &tmp) == 0)
2014 || (class_match_param(ptr, PARAM_AT_MAX, &tmp) == 0)
2015 || (class_match_param(ptr, PARAM_AT_EXTRA, &tmp) == 0)
2016 || (class_match_param(ptr, PARAM_AT_EARLY_MARGIN, &tmp) == 0)
2017 || (class_match_param(ptr, PARAM_AT_HISTORY, &tmp) == 0))
2022 /* separate the value */
2023 val = simple_strtoul(tmp, NULL, 0);
2025 CDEBUG(D_MGS, "global '%s' removed\n", sys);
2027 CDEBUG(D_MGS, "global '%s' val=%d\n", sys, val);
2029 lustre_cfg_bufs_reset(&bufs, NULL);
2030 lustre_cfg_bufs_set_string(&bufs, 1, sys);
2031 lcfg = lustre_cfg_new(cmd, &bufs);
2032 lcfg->lcfg_num = val;
2033 /* truncate the comment to the parameter name */
2037 /* modify all servers and clients */
2038 rc = mgs_write_log_direct_all(obd, fsdb, mti,
2039 *tmp == '\0' ? NULL : lcfg,
2040 mti->mti_fsname, sys);
2042 lustre_cfg_free(lcfg);
2046 static int mgs_srpc_set_param_disk(struct obd_device *obd,
2048 struct mgs_target_info *mti,
2051 struct llog_handle *llh = NULL;
2053 char *comment, *ptr;
2054 struct lustre_cfg_bufs bufs;
2055 struct lustre_cfg *lcfg;
2060 ptr = strchr(param, '=');
2064 OBD_ALLOC(comment, len + 1);
2065 if (comment == NULL)
2067 strncpy(comment, param, len);
2068 comment[len] = '\0';
2071 lustre_cfg_bufs_reset(&bufs, mti->mti_svname);
2072 lustre_cfg_bufs_set_string(&bufs, 1, param);
2073 lcfg = lustre_cfg_new(LCFG_SPTLRPC_CONF, &bufs);
2075 GOTO(out_comment, rc = -ENOMEM);
2077 /* construct log name */
2078 rc = name_create(&logname, mti->mti_fsname, "-sptlrpc");
2082 if (mgs_log_is_empty(obd, logname)) {
2083 rc = record_start_log(obd, &llh, logname);
2084 record_end_log(obd, &llh);
2089 /* obsolete old one */
2090 mgs_modify(obd, fsdb, mti, logname, mti->mti_svname, comment, CM_SKIP);
2092 /* write the new one */
2093 rc = mgs_write_log_direct(obd, fsdb, logname, lcfg,
2094 mti->mti_svname, comment);
2096 CERROR("err %d writing log %s\n", rc, logname);
2099 name_destroy(&logname);
2101 lustre_cfg_free(lcfg);
2103 OBD_FREE(comment, len + 1);
2107 static int mgs_srpc_set_param_udesc_mem(struct fs_db *fsdb,
2112 /* disable the adjustable udesc parameter for now, i.e. use default
2113 * setting that client always ship udesc to MDT if possible. to enable
2114 * it simply remove the following line */
2117 ptr = strchr(param, '=');
2122 if (strcmp(param, PARAM_SRPC_UDESC))
2125 if (strcmp(ptr, "yes") == 0) {
2126 cfs_set_bit(FSDB_UDESC, &fsdb->fsdb_flags);
2127 CWARN("Enable user descriptor shipping from client to MDT\n");
2128 } else if (strcmp(ptr, "no") == 0) {
2129 cfs_clear_bit(FSDB_UDESC, &fsdb->fsdb_flags);
2130 CWARN("Disable user descriptor shipping from client to MDT\n");
2138 CERROR("Invalid param: %s\n", param);
2142 static int mgs_srpc_set_param_mem(struct fs_db *fsdb,
2146 struct sptlrpc_rule rule;
2147 struct sptlrpc_rule_set *rset;
2151 if (strncmp(param, PARAM_SRPC, sizeof(PARAM_SRPC) - 1) != 0) {
2152 CERROR("Invalid sptlrpc parameter: %s\n", param);
2156 if (strncmp(param, PARAM_SRPC_UDESC,
2157 sizeof(PARAM_SRPC_UDESC) - 1) == 0) {
2158 RETURN(mgs_srpc_set_param_udesc_mem(fsdb, param));
2161 if (strncmp(param, PARAM_SRPC_FLVR, sizeof(PARAM_SRPC_FLVR) - 1) != 0) {
2162 CERROR("Invalid sptlrpc flavor parameter: %s\n", param);
2166 param += sizeof(PARAM_SRPC_FLVR) - 1;
2168 rc = sptlrpc_parse_rule(param, &rule);
2172 /* mgs rules implies must be mgc->mgs */
2173 if (cfs_test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
2174 if ((rule.sr_from != LUSTRE_SP_MGC &&
2175 rule.sr_from != LUSTRE_SP_ANY) ||
2176 (rule.sr_to != LUSTRE_SP_MGS &&
2177 rule.sr_to != LUSTRE_SP_ANY))
2181 /* preapre room for this coming rule. svcname format should be:
2182 * - fsname: general rule
2183 * - fsname-tgtname: target-specific rule
2185 if (strchr(svname, '-')) {
2186 struct mgs_tgt_srpc_conf *tgtconf;
2189 for (tgtconf = fsdb->fsdb_srpc_tgt; tgtconf != NULL;
2190 tgtconf = tgtconf->mtsc_next) {
2191 if (!strcmp(tgtconf->mtsc_tgt, svname)) {
2200 OBD_ALLOC_PTR(tgtconf);
2201 if (tgtconf == NULL)
2204 name_len = strlen(svname);
2206 OBD_ALLOC(tgtconf->mtsc_tgt, name_len + 1);
2207 if (tgtconf->mtsc_tgt == NULL) {
2208 OBD_FREE_PTR(tgtconf);
2211 memcpy(tgtconf->mtsc_tgt, svname, name_len);
2213 tgtconf->mtsc_next = fsdb->fsdb_srpc_tgt;
2214 fsdb->fsdb_srpc_tgt = tgtconf;
2217 rset = &tgtconf->mtsc_rset;
2219 rset = &fsdb->fsdb_srpc_gen;
2222 rc = sptlrpc_rule_set_merge(rset, &rule);
2227 static int mgs_srpc_set_param(struct obd_device *obd,
2229 struct mgs_target_info *mti,
2239 /* keep a copy of original param, which could be destroied
2241 copy_size = strlen(param) + 1;
2242 OBD_ALLOC(copy, copy_size);
2245 memcpy(copy, param, copy_size);
2247 rc = mgs_srpc_set_param_mem(fsdb, mti->mti_svname, param);
2251 /* previous steps guaranteed the syntax is correct */
2252 rc = mgs_srpc_set_param_disk(obd, fsdb, mti, copy);
2256 if (cfs_test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
2258 * for mgs rules, make them effective immediately.
2260 LASSERT(fsdb->fsdb_srpc_tgt == NULL);
2261 sptlrpc_target_update_exp_flavor(obd, &fsdb->fsdb_srpc_gen);
2265 OBD_FREE(copy, copy_size);
2269 struct mgs_srpc_read_data {
2270 struct fs_db *msrd_fsdb;
2274 static int mgs_srpc_read_handler(struct llog_handle *llh,
2275 struct llog_rec_hdr *rec,
2278 struct mgs_srpc_read_data *msrd = (struct mgs_srpc_read_data *) data;
2279 struct cfg_marker *marker;
2280 struct lustre_cfg *lcfg = (struct lustre_cfg *)(rec + 1);
2281 char *svname, *param;
2285 if (rec->lrh_type != OBD_CFG_REC) {
2286 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
2290 cfg_len = rec->lrh_len - sizeof(struct llog_rec_hdr) -
2291 sizeof(struct llog_rec_tail);
2293 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
2295 CERROR("Insane cfg\n");
2299 if (lcfg->lcfg_command == LCFG_MARKER) {
2300 marker = lustre_cfg_buf(lcfg, 1);
2302 if (marker->cm_flags & CM_START &&
2303 marker->cm_flags & CM_SKIP)
2304 msrd->msrd_skip = 1;
2305 if (marker->cm_flags & CM_END)
2306 msrd->msrd_skip = 0;
2311 if (msrd->msrd_skip)
2314 if (lcfg->lcfg_command != LCFG_SPTLRPC_CONF) {
2315 CERROR("invalid command (%x)\n", lcfg->lcfg_command);
2319 svname = lustre_cfg_string(lcfg, 0);
2320 if (svname == NULL) {
2321 CERROR("svname is empty\n");
2325 param = lustre_cfg_string(lcfg, 1);
2326 if (param == NULL) {
2327 CERROR("param is empty\n");
2331 rc = mgs_srpc_set_param_mem(msrd->msrd_fsdb, svname, param);
2333 CERROR("read sptlrpc record error (%d): %s\n", rc, param);
2338 int mgs_get_fsdb_srpc_from_llog(struct obd_device *obd,
2341 struct llog_handle *llh = NULL;
2342 struct lvfs_run_ctxt saved;
2343 struct llog_ctxt *ctxt;
2345 struct mgs_srpc_read_data msrd;
2349 /* construct log name */
2350 rc = name_create(&logname, fsdb->fsdb_name, "-sptlrpc");
2354 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
2355 LASSERT(ctxt != NULL);
2357 if (mgs_log_is_empty(obd, logname))
2360 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
2362 rc = llog_create(ctxt, &llh, NULL, logname);
2366 rc = llog_init_handle(llh, LLOG_F_IS_PLAIN, NULL);
2368 GOTO(out_close, rc);
2370 if (llog_get_size(llh) <= 1)
2371 GOTO(out_close, rc = 0);
2373 msrd.msrd_fsdb = fsdb;
2376 rc = llog_process(llh, mgs_srpc_read_handler, (void *) &msrd, NULL);
2381 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
2383 llog_ctxt_put(ctxt);
2384 name_destroy(&logname);
2387 CERROR("failed to read sptlrpc config database: %d\n", rc);
2391 /* Permanent settings of all parameters by writing into the appropriate
2392 * configuration logs.
2393 * A parameter with null value ("<param>='\0'") means to erase it out of
2396 static int mgs_write_log_param(struct obd_device *obd, struct fs_db *fsdb,
2397 struct mgs_target_info *mti, char *ptr)
2399 struct lustre_cfg_bufs bufs;
2402 int rc = 0, rc2 = 0;
2405 /* For various parameter settings, we have to figure out which logs
2406 care about them (e.g. both mdt and client for lov settings) */
2407 CDEBUG(D_MGS, "next param '%s'\n", ptr);
2409 /* The params are stored in MOUNT_DATA_FILE and modified via
2410 tunefs.lustre, or set using lctl conf_param */
2412 /* Processed in lustre_start_mgc */
2413 if (class_match_param(ptr, PARAM_MGSNODE, NULL) == 0)
2416 /* Processed in ost/mdt */
2417 if (class_match_param(ptr, PARAM_NETWORK, NULL) == 0)
2420 /* Processed in mgs_write_log_ost */
2421 if (class_match_param(ptr, PARAM_FAILMODE, NULL) == 0) {
2422 if (mti->mti_flags & LDD_F_PARAM) {
2423 LCONSOLE_ERROR_MSG(0x169, "%s can only be "
2424 "changed with tunefs.lustre"
2425 "and --writeconf\n", ptr);
2431 if (class_match_param(ptr, PARAM_SRPC, NULL) == 0) {
2432 rc = mgs_srpc_set_param(obd, fsdb, mti, ptr);
2436 if (class_match_param(ptr, PARAM_FAILNODE, NULL) == 0) {
2437 /* Add a failover nidlist */
2439 /* We already processed failovers params for new
2440 targets in mgs_write_log_target */
2441 if (mti->mti_flags & LDD_F_PARAM) {
2442 CDEBUG(D_MGS, "Adding failnode\n");
2443 rc = mgs_write_log_add_failnid(obd, fsdb, mti);
2448 if (class_match_param(ptr, PARAM_SYS, &tmp) == 0) {
2449 rc = mgs_write_log_sys(obd, fsdb, mti, ptr, tmp);
2453 if (class_match_param(ptr, PARAM_OSC""PARAM_ACTIVE, &tmp) == 0) {
2454 /* active=0 means off, anything else means on */
2455 int flag = (*tmp == '0') ? CM_EXCLUDE : 0;
2458 if (!(mti->mti_flags & LDD_F_SV_TYPE_OST)) {
2459 LCONSOLE_ERROR_MSG(0x144, "%s: Only OSCs can "
2460 "be (de)activated.\n",
2462 GOTO(end, rc = -EINVAL);
2464 LCONSOLE_WARN("Permanently %sactivating %s\n",
2465 flag ? "de": "re", mti->mti_svname);
2467 name_create(&logname, mti->mti_fsname, "-client");
2468 rc = mgs_modify(obd, fsdb, mti, logname,
2469 mti->mti_svname, "add osc", flag);
2470 name_destroy(&logname);
2474 /* Add to all MDT logs for CMD */
2475 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2476 if (!cfs_test_bit(i, fsdb->fsdb_mdt_index_map))
2478 name_create_mdt(&logname, mti->mti_fsname, i);
2479 rc = mgs_modify(obd, fsdb, mti, logname,
2480 mti->mti_svname, "add osc", flag);
2481 name_destroy(&logname);
2487 LCONSOLE_ERROR_MSG(0x145, "Couldn't find %s in"
2488 "log (%d). No permanent "
2489 "changes were made to the "
2491 mti->mti_svname, rc);
2492 if (cfs_test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags))
2493 LCONSOLE_ERROR_MSG(0x146, "This may be"
2498 "update the logs.\n");
2501 /* Fall through to osc proc for deactivating live OSC
2502 on running MDT / clients. */
2504 /* Below here, let obd's XXX_process_config methods handle it */
2506 /* All lov. in proc */
2507 if (class_match_param(ptr, PARAM_LOV, NULL) == 0) {
2510 CDEBUG(D_MGS, "lov param %s\n", ptr);
2511 if (!(mti->mti_flags & LDD_F_SV_TYPE_MDT)) {
2512 LCONSOLE_ERROR_MSG(0x147, "LOV params must be "
2513 "set on the MDT, not %s. "
2520 if (mgs_log_is_empty(obd, mti->mti_svname))
2521 GOTO(end, rc = -ENODEV);
2523 name_create_mdt_and_lov(&logname, &mdtlovname, fsdb,
2524 mti->mti_stripe_index);
2525 rc = mgs_wlp_lcfg(obd, fsdb, mti, mti->mti_svname,
2526 &bufs, mdtlovname, ptr);
2527 name_destroy(&logname);
2528 name_destroy(&mdtlovname);
2533 name_create(&logname, mti->mti_fsname, "-client");
2534 rc = mgs_wlp_lcfg(obd, fsdb, mti, logname, &bufs,
2535 fsdb->fsdb_clilov, ptr);
2536 name_destroy(&logname);
2540 /* All osc., mdc., llite. params in proc */
2541 if ((class_match_param(ptr, PARAM_OSC, NULL) == 0) ||
2542 (class_match_param(ptr, PARAM_MDC, NULL) == 0) ||
2543 (class_match_param(ptr, PARAM_LLITE, NULL) == 0)) {
2545 if (memcmp(ptr, PARAM_LLITE, strlen(PARAM_LLITE)) == 0) {
2546 name_create(&cname, mti->mti_fsname, "-client");
2547 /* Add the client type to match the obdname in
2548 class_config_llog_handler */
2549 } else if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
2552 name_create(&cname, fsdb->fsdb_mdc, "");
2554 name_create(&cname, mti->mti_svname,
2556 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2558 if (cfs_test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
2559 LCONSOLE_ERROR_MSG(0x148, "Upgraded "
2560 "client logs for %s"
2562 "modified. Consider"
2564 "configuration with"
2567 /* We don't know the names of all the
2569 GOTO(end, rc = -EINVAL);
2571 name_create(&cname, mti->mti_svname, "-osc");
2573 GOTO(end, rc = -EINVAL);
2576 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
2579 name_create(&logname, mti->mti_fsname, "-client");
2580 rc = mgs_wlp_lcfg(obd, fsdb, mti, logname, &bufs,
2583 /* osc params affect the MDT as well */
2584 if (!rc && (mti->mti_flags & LDD_F_SV_TYPE_OST)) {
2587 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
2588 if (!cfs_test_bit(i, fsdb->fsdb_mdt_index_map))
2590 name_destroy(&cname);
2591 name_create_mdt_osc(&cname, mti->mti_svname,
2593 name_destroy(&logname);
2594 name_create_mdt(&logname, mti->mti_fsname, i);
2595 if (!mgs_log_is_empty(obd, logname))
2596 rc = mgs_wlp_lcfg(obd, fsdb,mti,logname,
2602 name_destroy(&logname);
2603 name_destroy(&cname);
2607 /* All mdt. params in proc */
2608 if (class_match_param(ptr, PARAM_MDT, NULL) == 0) {
2612 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
2613 if (strncmp(mti->mti_svname, mti->mti_fsname,
2614 MTI_NAME_MAXLEN) == 0)
2615 /* device is unspecified completely? */
2616 rc = LDD_F_SV_TYPE_MDT | LDD_F_SV_ALL;
2618 rc = server_name2index(mti->mti_svname, &idx, NULL);
2621 if ((rc & LDD_F_SV_TYPE_MDT) == 0)
2623 if (rc & LDD_F_SV_ALL) {
2624 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2625 if (!cfs_test_bit(i,
2626 fsdb->fsdb_mdt_index_map))
2628 name_create_mdt(&logname, mti->mti_fsname, i);
2629 rc = mgs_wlp_lcfg(obd, fsdb, mti,
2632 name_destroy(&logname);
2637 rc = mgs_wlp_lcfg(obd, fsdb, mti,
2638 mti->mti_svname, &bufs,
2639 mti->mti_svname, ptr);
2646 /* All mdd., ost. params in proc */
2647 if ((class_match_param(ptr, PARAM_MDD, NULL) == 0) ||
2648 (class_match_param(ptr, PARAM_OST, NULL) == 0)) {
2649 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
2650 if (mgs_log_is_empty(obd, mti->mti_svname))
2651 GOTO(end, rc = -ENODEV);
2653 rc = mgs_wlp_lcfg(obd, fsdb, mti, mti->mti_svname,
2654 &bufs, mti->mti_svname, ptr);
2658 LCONSOLE_WARN("Ignoring unrecognized param '%s'\n", ptr);
2663 CERROR("err %d on param '%s'\n", rc, ptr);
2668 /* Not implementing automatic failover nid addition at this time. */
2669 int mgs_check_failnid(struct obd_device *obd, struct mgs_target_info *mti)
2676 rc = mgs_find_or_make_fsdb(obd, fsname, &fsdb);
2680 if (mgs_log_is_empty(obd, mti->mti_svname))
2681 /* should never happen */
2684 CDEBUG(D_MGS, "Checking for new failnids for %s\n", mti->mti_svname);
2686 /* FIXME We can just check mti->params to see if we're already in
2687 the failover list. Modify mti->params for rewriting back at
2688 server_register_target(). */
2690 cfs_down(&fsdb->fsdb_sem);
2691 rc = mgs_write_log_add_failnid(obd, fsdb, mti);
2692 cfs_up(&fsdb->fsdb_sem);
2699 int mgs_write_log_target(struct obd_device *obd,
2700 struct mgs_target_info *mti,
2707 /* set/check the new target index */
2708 rc = mgs_set_index(obd, mti);
2710 CERROR("Can't get index (%d)\n", rc);
2715 if (mti->mti_flags & LDD_F_UPGRADE14) {
2716 if (rc == EALREADY) {
2717 LCONSOLE_INFO("Found index %d for %s 1.4 log, "
2718 "upgrading\n", mti->mti_stripe_index,
2721 LCONSOLE_ERROR_MSG(0x149, "Failed to find %s in the old"
2722 " client log. Apparently it is not "
2723 "part of this filesystem, or the old"
2724 " log is wrong.\nUse 'writeconf' on "
2725 "the MDT to force log regeneration."
2726 "\n", mti->mti_svname);
2727 /* Not in client log? Upgrade anyhow...*/
2728 /* Argument against upgrading: reformat MDT,
2729 upgrade OST, then OST will start but will be SKIPped
2730 in client logs. Maybe error now is better. */
2731 /* RETURN(-EINVAL); */
2733 /* end COMPAT_146 */
2735 if (rc == EALREADY) {
2736 LCONSOLE_WARN("Found index %d for %s, updating log\n",
2737 mti->mti_stripe_index, mti->mti_svname);
2738 /* We would like to mark old log sections as invalid
2739 and add new log sections in the client and mdt logs.
2740 But if we add new sections, then live clients will
2741 get repeat setup instructions for already running
2742 osc's. So don't update the client/mdt logs. */
2743 mti->mti_flags &= ~LDD_F_UPDATE;
2747 cfs_down(&fsdb->fsdb_sem);
2749 if (mti->mti_flags &
2750 (LDD_F_VIRGIN | LDD_F_UPGRADE14 | LDD_F_WRITECONF)) {
2751 /* Generate a log from scratch */
2752 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
2753 rc = mgs_write_log_mdt(obd, fsdb, mti);
2754 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2755 rc = mgs_write_log_ost(obd, fsdb, mti);
2757 CERROR("Unknown target type %#x, can't create log for "
2758 "%s\n", mti->mti_flags, mti->mti_svname);
2761 CERROR("Can't write logs for %s (%d)\n",
2762 mti->mti_svname, rc);
2766 /* Just update the params from tunefs in mgs_write_log_params */
2767 CDEBUG(D_MGS, "Update params for %s\n", mti->mti_svname);
2768 mti->mti_flags |= LDD_F_PARAM;
2771 /* allocate temporary buffer, where class_get_next_param will
2772 make copy of a current parameter */
2773 OBD_ALLOC(buf, strlen(mti->mti_params) + 1);
2775 GOTO(out_up, rc = -ENOMEM);
2776 params = mti->mti_params;
2777 while (params != NULL) {
2778 rc = class_get_next_param(¶ms, buf);
2781 /* there is no next parameter, that is
2786 CDEBUG(D_MGS, "remaining string: '%s', param: '%s'\n",
2788 rc = mgs_write_log_param(obd, fsdb, mti, buf);
2793 OBD_FREE(buf, strlen(mti->mti_params) + 1);
2796 cfs_up(&fsdb->fsdb_sem);
2801 /* verify that we can handle the old config logs */
2802 int mgs_upgrade_sv_14(struct obd_device *obd, struct mgs_target_info *mti,
2808 /* Create ost log normally, as servers register. Servers
2809 register with their old uuids (from last_rcvd), so old
2810 (MDT and client) logs should work.
2811 - new MDT won't know about old OSTs, only the ones that have
2812 registered, so we need the old MDT log to get the LOV right
2813 in order for old clients to work.
2814 - Old clients connect to the MDT, not the MGS, for their logs, and
2815 will therefore receive the old client log from the MDT /LOGS dir.
2816 - Old clients can continue to use and connect to old or new OSTs
2817 - New clients will contact the MGS for their log
2820 LCONSOLE_INFO("upgrading server %s from pre-1.6\n", mti->mti_svname);
2821 server_mti_print("upgrade", mti);
2823 if (cfs_test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
2824 LCONSOLE_ERROR_MSG(0x14a, "The old client log %s-client is "
2825 "missing. Was tunefs.lustre successful?\n",
2830 if (fsdb->fsdb_gen == 0) {
2831 /* There were no markers in the client log, meaning we have
2832 not updated the logs for this fs */
2833 CDEBUG(D_MGS, "found old, unupdated client log\n");
2836 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
2837 if (mgs_log_is_empty(obd, mti->mti_svname)) {
2838 LCONSOLE_ERROR_MSG(0x14b, "The old MDT log %s is "
2839 "missing. Was tunefs.lustre "
2844 /* We're starting with an old uuid. Assume old name for lov
2845 as well since the lov entry already exists in the log. */
2846 CDEBUG(D_MGS, "old mds uuid %s\n", mti->mti_uuid);
2847 if (strncmp(mti->mti_uuid, fsdb->fsdb_mdtlov + 4,
2848 strlen(fsdb->fsdb_mdtlov) - 4) != 0) {
2849 CERROR("old mds uuid %s doesn't match log %s (%s)\n",
2850 mti->mti_uuid, fsdb->fsdb_mdtlov,
2851 fsdb->fsdb_mdtlov + 4);
2856 if (!cfs_test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
2857 LCONSOLE_ERROR_MSG(0x14c, "%s-client is supposedly an old "
2858 "log, but no old LOV or MDT was found. "
2859 "Consider updating the configuration with"
2860 " --writeconf.\n", mti->mti_fsname);
2865 /* end COMPAT_146 */
2867 int mgs_erase_log(struct obd_device *obd, char *name)
2869 struct lvfs_run_ctxt saved;
2870 struct llog_ctxt *ctxt;
2871 struct llog_handle *llh;
2874 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
2875 LASSERT(ctxt != NULL);
2877 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
2878 rc = llog_create(ctxt, &llh, NULL, name);
2880 llog_init_handle(llh, LLOG_F_IS_PLAIN, NULL);
2881 rc = llog_destroy(llh);
2882 llog_free_handle(llh);
2884 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
2885 llog_ctxt_put(ctxt);
2888 CERROR("failed to clear log %s: %d\n", name, rc);
2893 /* erase all logs for the given fs */
2894 int mgs_erase_logs(struct obd_device *obd, char *fsname)
2896 struct mgs_obd *mgs = &obd->u.mgs;
2897 static struct fs_db *fsdb;
2898 cfs_list_t dentry_list;
2899 struct l_linux_dirent *dirent, *n;
2900 int rc, len = strlen(fsname);
2904 /* Find all the logs in the CONFIGS directory */
2905 rc = class_dentry_readdir(obd, mgs->mgs_configs_dir,
2906 mgs->mgs_vfsmnt, &dentry_list);
2908 CERROR("Can't read %s dir\n", MOUNT_CONFIGS_DIR);
2912 cfs_down(&mgs->mgs_sem);
2914 /* Delete the fs db */
2915 fsdb = mgs_find_fsdb(obd, fsname);
2917 mgs_free_fsdb(obd, fsdb);
2919 cfs_list_for_each_entry_safe(dirent, n, &dentry_list, lld_list) {
2920 cfs_list_del(&dirent->lld_list);
2921 suffix = strrchr(dirent->lld_name, '-');
2922 if (suffix != NULL) {
2923 if ((len == suffix - dirent->lld_name) &&
2924 (strncmp(fsname, dirent->lld_name, len) == 0)) {
2925 CDEBUG(D_MGS, "Removing log %s\n",
2927 mgs_erase_log(obd, dirent->lld_name);
2930 OBD_FREE(dirent, sizeof(*dirent));
2933 cfs_up(&mgs->mgs_sem);
2938 /* from llog_swab */
2939 static void print_lustre_cfg(struct lustre_cfg *lcfg)
2944 CDEBUG(D_MGS, "lustre_cfg: %p\n", lcfg);
2945 CDEBUG(D_MGS, "\tlcfg->lcfg_version: %#x\n", lcfg->lcfg_version);
2947 CDEBUG(D_MGS, "\tlcfg->lcfg_command: %#x\n", lcfg->lcfg_command);
2948 CDEBUG(D_MGS, "\tlcfg->lcfg_num: %#x\n", lcfg->lcfg_num);
2949 CDEBUG(D_MGS, "\tlcfg->lcfg_flags: %#x\n", lcfg->lcfg_flags);
2950 CDEBUG(D_MGS, "\tlcfg->lcfg_nid: %s\n", libcfs_nid2str(lcfg->lcfg_nid));
2952 CDEBUG(D_MGS, "\tlcfg->lcfg_bufcount: %d\n", lcfg->lcfg_bufcount);
2953 if (lcfg->lcfg_bufcount < LUSTRE_CFG_MAX_BUFCOUNT)
2954 for (i = 0; i < lcfg->lcfg_bufcount; i++) {
2955 CDEBUG(D_MGS, "\tlcfg->lcfg_buflens[%d]: %d %s\n",
2956 i, lcfg->lcfg_buflens[i],
2957 lustre_cfg_string(lcfg, i));
2962 /* Set a permanent (config log) param for a target or fs
2963 * \param lcfg buf0 may contain the device (testfs-MDT0000) name
2964 * buf1 contains the single parameter
2966 int mgs_setparam(struct obd_device *obd, struct lustre_cfg *lcfg, char *fsname)
2969 struct mgs_target_info *mti;
2970 char *devname, *param;
2976 print_lustre_cfg(lcfg);
2978 /* lustre, lustre-mdtlov, lustre-client, lustre-MDT0000 */
2979 devname = lustre_cfg_string(lcfg, 0);
2980 param = lustre_cfg_string(lcfg, 1);
2982 /* Assume device name embedded in param:
2983 lustre-OST0000.osc.max_dirty_mb=32 */
2984 ptr = strchr(param, '.');
2992 LCONSOLE_ERROR_MSG(0x14d, "No target specified: %s\n", param);
2996 /* Extract fsname */
2997 ptr = strrchr(devname, '-');
2998 memset(fsname, 0, MTI_NAME_MAXLEN);
2999 if (ptr && (server_name2index(ptr, &index, NULL) >= 0)) {
3000 /* param related to llite isn't allowed to set by OST or MDT */
3001 if (strncmp(param, PARAM_LLITE, sizeof(PARAM_LLITE)) == 0)
3004 strncpy(fsname, devname, ptr - devname);
3006 /* assume devname is the fsname */
3007 strncpy(fsname, devname, MTI_NAME_MAXLEN);
3009 fsname[MTI_NAME_MAXLEN - 1] = 0;
3010 CDEBUG(D_MGS, "setparam fs='%s' device='%s'\n", fsname, devname);
3012 rc = mgs_find_or_make_fsdb(obd, fsname, &fsdb);
3015 if (!cfs_test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags) &&
3016 cfs_test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
3017 CERROR("No filesystem targets for %s. cfg_device from lctl "
3018 "is '%s'\n", fsname, devname);
3019 mgs_free_fsdb(obd, fsdb);
3023 /* Create a fake mti to hold everything */
3026 GOTO(out, rc = -ENOMEM);
3027 strncpy(mti->mti_fsname, fsname, MTI_NAME_MAXLEN);
3028 strncpy(mti->mti_svname, devname, MTI_NAME_MAXLEN);
3029 strncpy(mti->mti_params, param, sizeof(mti->mti_params));
3030 rc = server_name2index(mti->mti_svname, &mti->mti_stripe_index, &tmp);
3032 /* Not a valid server; may be only fsname */
3035 /* Strip -osc or -mdc suffix from svname */
3036 if (server_make_name(rc, mti->mti_stripe_index, mti->mti_fsname,
3038 GOTO(out, rc = -EINVAL);
3040 mti->mti_flags = rc | LDD_F_PARAM;
3042 cfs_down(&fsdb->fsdb_sem);
3043 rc = mgs_write_log_param(obd, fsdb, mti, mti->mti_params);
3044 cfs_up(&fsdb->fsdb_sem);
3047 * Revoke lock so everyone updates. Should be alright if
3048 * someone was already reading while we were updating the logs,
3049 * so we don't really need to hold the lock while we're
3052 mgs_revoke_lock(obd, fsdb);
3058 static int mgs_write_log_pool(struct obd_device *obd, char *logname,
3059 struct fs_db *fsdb, char *lovname,
3060 enum lcfg_command_type cmd,
3061 char *poolname, char *fsname,
3062 char *ostname, char *comment)
3064 struct llog_handle *llh = NULL;
3067 rc = record_start_log(obd, &llh, logname);
3070 rc = record_marker(obd, llh, fsdb, CM_START, lovname, comment);
3071 record_base(obd, llh, lovname, 0, cmd, poolname, fsname, ostname, 0);
3072 rc = record_marker(obd, llh, fsdb, CM_END, lovname, comment);
3073 rc = record_end_log(obd, &llh);
3078 int mgs_pool_cmd(struct obd_device *obd, enum lcfg_command_type cmd,
3079 char *fsname, char *poolname, char *ostname)
3084 char *label = NULL, *canceled_label = NULL;
3086 struct mgs_target_info *mti = NULL;
3090 rc = mgs_find_or_make_fsdb(obd, fsname, &fsdb);
3092 CERROR("Can't get db for %s\n", fsname);
3095 if (cfs_test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
3096 CERROR("%s is not defined\n", fsname);
3097 mgs_free_fsdb(obd, fsdb);
3101 label_sz = 10 + strlen(fsname) + strlen(poolname);
3103 /* check if ostname match fsname */
3104 if (ostname != NULL) {
3107 ptr = strrchr(ostname, '-');
3108 if ((ptr == NULL) ||
3109 (strncmp(fsname, ostname, ptr-ostname) != 0))
3111 label_sz += strlen(ostname);
3114 OBD_ALLOC(label, label_sz);
3116 GOTO(out, rc = -ENOMEM);
3119 case LCFG_POOL_NEW: {
3121 "new %s.%s", fsname, poolname);
3124 case LCFG_POOL_ADD: {
3126 "add %s.%s.%s", fsname, poolname, ostname);
3129 case LCFG_POOL_REM: {
3130 OBD_ALLOC(canceled_label, label_sz);
3131 if (canceled_label == NULL)
3132 GOTO(out, rc = -ENOMEM);
3134 "rem %s.%s.%s", fsname, poolname, ostname);
3135 sprintf(canceled_label,
3136 "add %s.%s.%s", fsname, poolname, ostname);
3139 case LCFG_POOL_DEL: {
3140 OBD_ALLOC(canceled_label, label_sz);
3141 if (canceled_label == NULL)
3142 GOTO(out, rc = -ENOMEM);
3144 "del %s.%s", fsname, poolname);
3145 sprintf(canceled_label,
3146 "new %s.%s", fsname, poolname);
3154 cfs_down(&fsdb->fsdb_sem);
3156 if (canceled_label != NULL) {
3159 GOTO(out, rc = -ENOMEM);
3162 /* write pool def to all MDT logs */
3163 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3164 if (cfs_test_bit(i, fsdb->fsdb_mdt_index_map)) {
3165 name_create_mdt_and_lov(&logname, &lovname, fsdb, i);
3167 if (canceled_label != NULL) {
3168 strcpy(mti->mti_svname, "lov pool");
3169 mgs_modify(obd, fsdb, mti, logname, lovname,
3170 canceled_label, CM_SKIP);
3173 mgs_write_log_pool(obd, logname, fsdb, lovname,
3174 cmd, fsname, poolname, ostname,
3176 name_destroy(&logname);
3177 name_destroy(&lovname);
3181 name_create(&logname, fsname, "-client");
3182 if (canceled_label != NULL)
3183 mgs_modify(obd, fsdb, mti, logname, fsdb->fsdb_clilov,
3184 canceled_label, CM_SKIP);
3186 mgs_write_log_pool(obd, logname, fsdb, fsdb->fsdb_clilov,
3187 cmd, fsname, poolname, ostname, label);
3188 name_destroy(&logname);
3190 cfs_up(&fsdb->fsdb_sem);
3191 /* request for update */
3192 mgs_revoke_lock(obd, fsdb);
3197 OBD_FREE(label, label_sz);
3199 if (canceled_label != NULL)
3200 OBD_FREE(canceled_label, label_sz);
3209 /******************** unused *********************/
3210 static int mgs_backup_llog(struct obd_device *obd, char* fsname)
3212 struct file *filp, *bak_filp;
3213 struct lvfs_run_ctxt saved;
3214 char *logname, *buf;
3215 loff_t soff = 0 , doff = 0;
3216 int count = 4096, len;
3219 OBD_ALLOC(logname, PATH_MAX);
3220 if (logname == NULL)
3223 OBD_ALLOC(buf, count);
3225 GOTO(out , rc = -ENOMEM);
3227 len = snprintf(logname, PATH_MAX, "%s/%s.bak",
3228 MOUNT_CONFIGS_DIR, fsname);
3230 if (len >= PATH_MAX - 1) {
3231 GOTO(out, -ENAMETOOLONG);
3234 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
3236 bak_filp = l_filp_open(logname, O_RDWR|O_CREAT|O_TRUNC, 0660);
3237 if (IS_ERR(bak_filp)) {
3238 rc = PTR_ERR(bak_filp);
3239 CERROR("backup logfile open %s: %d\n", logname, rc);
3242 sprintf(logname, "%s/%s", MOUNT_CONFIGS_DIR, fsname);
3243 filp = l_filp_open(logname, O_RDONLY, 0);
3246 CERROR("logfile open %s: %d\n", logname, rc);
3250 while ((rc = lustre_fread(filp, buf, count, &soff)) > 0) {
3251 rc = lustre_fwrite(bak_filp, buf, count, &doff);
3255 filp_close(filp, 0);
3257 filp_close(bak_filp, 0);
3259 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
3262 OBD_FREE(buf, count);
3263 OBD_FREE(logname, PATH_MAX);