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)) {
187 rc = libcfs_str2server(lustre_cfg_string(lcfg, 0), &type,
189 if (rc || type != SVTYPE_MDT) {
190 CWARN("Unparsable MDC name %s, assuming index 0\n",
191 lustre_cfg_string(lcfg, 0));
195 CDEBUG(D_MGS, "MDT index is %u\n", index);
196 cfs_set_bit(index, fsdb->fsdb_mdt_index_map);
197 fsdb->fsdb_mdt_count ++;
201 /* figure out the old LOV name. fsdb_gen = 0 means old log */
202 /* #01 L attach 0:lov_mdsA 1:lov 2:cdbe9_lov_mdsA_dc8cf7f3bb */
203 if ((fsdb->fsdb_gen == 0) && (lcfg->lcfg_command == LCFG_ATTACH) &&
204 (strcmp(lustre_cfg_string(lcfg, 1), LUSTRE_LOV_NAME) == 0)) {
205 cfs_set_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags);
206 name_destroy(&fsdb->fsdb_clilov);
207 rc = name_create(&fsdb->fsdb_clilov,
208 lustre_cfg_string(lcfg, 0), "");
211 CDEBUG(D_MGS, "client lov name is %s\n", fsdb->fsdb_clilov);
214 /* figure out the old MDT lov name from the MDT uuid */
215 if ((fsdb->fsdb_gen == 0) && (lcfg->lcfg_command == LCFG_SETUP) &&
216 (strncmp(lustre_cfg_string(lcfg, 0), "MDC_", 4) == 0)) {
218 cfs_set_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags);
219 ptr = strstr(lustre_cfg_string(lcfg, 1), "_UUID");
221 CERROR("Can't parse MDT uuid %s\n",
222 lustre_cfg_string(lcfg, 1));
226 name_destroy(&fsdb->fsdb_mdtlov);
227 rc = name_create(&fsdb->fsdb_mdtlov,
228 "lov_", lustre_cfg_string(lcfg, 1));
231 name_destroy(&fsdb->fsdb_mdc);
232 rc = name_create(&fsdb->fsdb_mdc,
233 lustre_cfg_string(lcfg, 0), "");
236 CDEBUG(D_MGS, "MDT lov name is %s\n", fsdb->fsdb_mdtlov);
241 * compat to 1.8, check osc name used by MDT0 to OSTs, bz18548.
243 if (!cfs_test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags) &&
244 lcfg->lcfg_command == LCFG_ATTACH &&
245 strcmp(lustre_cfg_string(lcfg, 1), LUSTRE_OSC_NAME) == 0) {
246 if (OBD_OCD_VERSION_MAJOR(d->ver) == 1 &&
247 OBD_OCD_VERSION_MINOR(d->ver) <= 8) {
248 CWARN("MDT using 1.8 OSC name scheme\n");
249 cfs_set_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags);
253 if (lcfg->lcfg_command == LCFG_MARKER) {
254 struct cfg_marker *marker;
255 marker = lustre_cfg_buf(lcfg, 1);
257 d->ver = marker->cm_vers;
259 /* Keep track of the latest marker step */
260 fsdb->fsdb_gen = max(fsdb->fsdb_gen, marker->cm_step);
266 /* fsdb->fsdb_sem is already held in mgs_find_or_make_fsdb*/
267 static int mgs_get_fsdb_from_llog(struct obd_device *obd, struct fs_db *fsdb)
270 struct llog_handle *loghandle;
271 struct lvfs_run_ctxt saved;
272 struct llog_ctxt *ctxt;
273 struct mgs_fsdb_handler_data d = { fsdb, 0 };
277 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
278 LASSERT(ctxt != NULL);
279 name_create(&logname, fsdb->fsdb_name, "-client");
280 cfs_down(&fsdb->fsdb_sem);
281 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
282 rc = llog_create(ctxt, &loghandle, NULL, logname);
286 rc = llog_init_handle(loghandle, LLOG_F_IS_PLAIN, NULL);
290 if (llog_get_size(loghandle) <= 1)
291 cfs_set_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags);
293 rc = llog_process(loghandle, mgs_fsdb_handler, (void *) &d, NULL);
294 CDEBUG(D_INFO, "get_db = %d\n", rc);
296 rc2 = llog_close(loghandle);
300 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
301 cfs_up(&fsdb->fsdb_sem);
302 name_destroy(&logname);
308 static void mgs_free_fsdb_srpc(struct fs_db *fsdb)
310 struct mgs_tgt_srpc_conf *tgtconf;
312 /* free target-specific rules */
313 while (fsdb->fsdb_srpc_tgt) {
314 tgtconf = fsdb->fsdb_srpc_tgt;
315 fsdb->fsdb_srpc_tgt = tgtconf->mtsc_next;
317 LASSERT(tgtconf->mtsc_tgt);
319 sptlrpc_rule_set_free(&tgtconf->mtsc_rset);
320 OBD_FREE(tgtconf->mtsc_tgt, strlen(tgtconf->mtsc_tgt) + 1);
321 OBD_FREE_PTR(tgtconf);
324 /* free general rules */
325 sptlrpc_rule_set_free(&fsdb->fsdb_srpc_gen);
328 static struct fs_db *mgs_find_fsdb(struct obd_device *obd, char *fsname)
330 struct mgs_obd *mgs = &obd->u.mgs;
334 cfs_list_for_each(tmp, &mgs->mgs_fs_db_list) {
335 fsdb = cfs_list_entry(tmp, struct fs_db, fsdb_list);
336 if (strcmp(fsdb->fsdb_name, fsname) == 0)
342 /* caller must hold the mgs->mgs_fs_db_lock */
343 static struct fs_db *mgs_new_fsdb(struct obd_device *obd, char *fsname)
345 struct mgs_obd *mgs = &obd->u.mgs;
350 if (strlen(fsname) >= sizeof(fsdb->fsdb_name)) {
351 CERROR("fsname %s is too long\n", fsname);
359 strcpy(fsdb->fsdb_name, fsname);
360 cfs_sema_init(&fsdb->fsdb_sem, 1);
361 cfs_set_bit(FSDB_UDESC, &fsdb->fsdb_flags);
363 if (strcmp(fsname, MGSSELF_NAME) == 0) {
364 cfs_set_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags);
366 OBD_ALLOC(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
367 OBD_ALLOC(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
368 if (!fsdb->fsdb_ost_index_map || !fsdb->fsdb_mdt_index_map) {
369 CERROR("No memory for index maps\n");
373 rc = name_create(&fsdb->fsdb_mdtlov, fsname, "-mdtlov");
376 rc = name_create(&fsdb->fsdb_mdtlmv, fsname, "-mdtlmv");
379 rc = name_create(&fsdb->fsdb_clilov, fsname, "-clilov");
382 rc = name_create(&fsdb->fsdb_clilmv, fsname, "-clilmv");
386 lproc_mgs_add_live(obd, fsdb);
389 cfs_list_add(&fsdb->fsdb_list, &mgs->mgs_fs_db_list);
393 if (fsdb->fsdb_ost_index_map)
394 OBD_FREE(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
395 if (fsdb->fsdb_mdt_index_map)
396 OBD_FREE(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
397 name_destroy(&fsdb->fsdb_clilov);
398 name_destroy(&fsdb->fsdb_clilmv);
399 name_destroy(&fsdb->fsdb_mdtlov);
400 name_destroy(&fsdb->fsdb_mdtlmv);
405 static void mgs_free_fsdb(struct obd_device *obd, struct fs_db *fsdb)
407 /* wait for anyone with the sem */
408 cfs_down(&fsdb->fsdb_sem);
409 lproc_mgs_del_live(obd, fsdb);
410 cfs_list_del(&fsdb->fsdb_list);
411 if (fsdb->fsdb_ost_index_map)
412 OBD_FREE(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
413 if (fsdb->fsdb_mdt_index_map)
414 OBD_FREE(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
415 name_destroy(&fsdb->fsdb_clilov);
416 name_destroy(&fsdb->fsdb_clilmv);
417 name_destroy(&fsdb->fsdb_mdtlov);
418 name_destroy(&fsdb->fsdb_mdtlmv);
419 name_destroy(&fsdb->fsdb_mdc);
420 mgs_free_fsdb_srpc(fsdb);
424 int mgs_init_fsdb_list(struct obd_device *obd)
426 struct mgs_obd *mgs = &obd->u.mgs;
427 CFS_INIT_LIST_HEAD(&mgs->mgs_fs_db_list);
431 int mgs_cleanup_fsdb_list(struct obd_device *obd)
433 struct mgs_obd *mgs = &obd->u.mgs;
435 cfs_list_t *tmp, *tmp2;
436 cfs_down(&mgs->mgs_sem);
437 cfs_list_for_each_safe(tmp, tmp2, &mgs->mgs_fs_db_list) {
438 fsdb = cfs_list_entry(tmp, struct fs_db, fsdb_list);
439 mgs_free_fsdb(obd, fsdb);
441 cfs_up(&mgs->mgs_sem);
445 int mgs_find_or_make_fsdb(struct obd_device *obd, char *name,
448 struct mgs_obd *mgs = &obd->u.mgs;
452 cfs_down(&mgs->mgs_sem);
453 fsdb = mgs_find_fsdb(obd, name);
455 cfs_up(&mgs->mgs_sem);
460 CDEBUG(D_MGS, "Creating new db\n");
461 fsdb = mgs_new_fsdb(obd, name);
462 cfs_up(&mgs->mgs_sem);
466 if (!cfs_test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
467 /* populate the db from the client llog */
468 rc = mgs_get_fsdb_from_llog(obd, fsdb);
470 CERROR("Can't get db from client log %d\n", rc);
471 mgs_free_fsdb(obd, fsdb);
476 /* populate srpc rules from params llog */
477 rc = mgs_get_fsdb_srpc_from_llog(obd, fsdb);
479 CERROR("Can't get db from params log %d\n", rc);
480 mgs_free_fsdb(obd, fsdb);
491 -1= empty client log */
492 int mgs_check_index(struct obd_device *obd, struct mgs_target_info *mti)
499 LASSERT(!(mti->mti_flags & LDD_F_NEED_INDEX));
501 rc = mgs_find_or_make_fsdb(obd, mti->mti_fsname, &fsdb);
503 CERROR("Can't get db for %s\n", mti->mti_fsname);
507 if (cfs_test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags))
510 if (mti->mti_flags & SVTYPE_OST)
511 imap = fsdb->fsdb_ost_index_map;
512 else if (mti->mti_flags & SVTYPE_MDT)
513 imap = fsdb->fsdb_mdt_index_map;
517 if (cfs_test_bit(mti->mti_stripe_index, imap))
522 static __inline__ int next_index(void *index_map, int map_len)
525 for (i = 0; i < map_len * 8; i++)
526 if (!cfs_test_bit(i, index_map)) {
529 CERROR("max index %d exceeded.\n", i);
534 0 newly marked as in use
536 +EALREADY for update of an old index */
537 static int mgs_set_index(struct obd_device *obd, struct mgs_target_info *mti)
544 rc = mgs_find_or_make_fsdb(obd, mti->mti_fsname, &fsdb);
546 CERROR("Can't get db for %s\n", mti->mti_fsname);
550 if (mti->mti_flags & SVTYPE_OST) {
551 imap = fsdb->fsdb_ost_index_map;
552 } else if (mti->mti_flags & SVTYPE_MDT) {
553 imap = fsdb->fsdb_mdt_index_map;
554 if (fsdb->fsdb_mdt_count >= MAX_MDT_COUNT) {
555 LCONSOLE_ERROR_MSG(0x13f, "The max mdt count"
556 "is %d\n", (int)MAX_MDT_COUNT);
563 if (mti->mti_flags & LDD_F_NEED_INDEX) {
564 rc = next_index(imap, INDEX_MAP_SIZE);
567 mti->mti_stripe_index = rc;
568 if (mti->mti_flags & SVTYPE_MDT)
569 fsdb->fsdb_mdt_count ++;
572 if (mti->mti_stripe_index >= INDEX_MAP_SIZE * 8) {
573 LCONSOLE_ERROR_MSG(0x13f, "Server %s requested index %d, "
574 "but the max index is %d.\n",
575 mti->mti_svname, mti->mti_stripe_index,
580 if (cfs_test_bit(mti->mti_stripe_index, imap)) {
581 if ((mti->mti_flags & LDD_F_VIRGIN) &&
582 !(mti->mti_flags & LDD_F_WRITECONF)) {
583 LCONSOLE_ERROR_MSG(0x140, "Server %s requested index "
584 "%d, but that index is already in "
585 "use. Use --writeconf to force\n",
587 mti->mti_stripe_index);
590 CDEBUG(D_MGS, "Server %s updating index %d\n",
591 mti->mti_svname, mti->mti_stripe_index);
596 cfs_set_bit(mti->mti_stripe_index, imap);
597 cfs_clear_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags);
598 server_make_name(mti->mti_flags, mti->mti_stripe_index,
599 mti->mti_fsname, mti->mti_svname);
601 CDEBUG(D_MGS, "Set index for %s to %d\n", mti->mti_svname,
602 mti->mti_stripe_index);
607 struct mgs_modify_lookup {
608 struct cfg_marker mml_marker;
612 static int mgs_modify_handler(struct llog_handle *llh, struct llog_rec_hdr *rec,
615 struct mgs_modify_lookup *mml = (struct mgs_modify_lookup *)data;
616 struct cfg_marker *marker;
617 struct lustre_cfg *lcfg = (struct lustre_cfg *)(rec + 1);
618 int cfg_len = rec->lrh_len - sizeof(struct llog_rec_hdr) -
619 sizeof(struct llog_rec_tail);
623 if (rec->lrh_type != OBD_CFG_REC) {
624 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
628 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
630 CERROR("Insane cfg\n");
634 /* We only care about markers */
635 if (lcfg->lcfg_command != LCFG_MARKER)
638 marker = lustre_cfg_buf(lcfg, 1);
639 if ((strcmp(mml->mml_marker.cm_comment, marker->cm_comment) == 0) &&
640 (strcmp(mml->mml_marker.cm_tgtname, marker->cm_tgtname) == 0) &&
641 !(marker->cm_flags & CM_SKIP)) {
642 /* Found a non-skipped marker match */
643 CDEBUG(D_MGS, "Changing rec %u marker %d %x->%x: %s %s\n",
644 rec->lrh_index, marker->cm_step,
645 marker->cm_flags, mml->mml_marker.cm_flags,
646 marker->cm_tgtname, marker->cm_comment);
647 /* Overwrite the old marker llog entry */
648 marker->cm_flags &= ~CM_EXCLUDE; /* in case we're unexcluding */
649 marker->cm_flags |= mml->mml_marker.cm_flags;
650 marker->cm_canceltime = mml->mml_marker.cm_canceltime;
651 /* Header and tail are added back to lrh_len in
652 llog_lvfs_write_rec */
653 rec->lrh_len = cfg_len;
654 rc = llog_write_rec(llh, rec, NULL, 0, (void *)lcfg,
663 /* Modify an existing config log record (for CM_SKIP or CM_EXCLUDE) */
664 static int mgs_modify(struct obd_device *obd, struct fs_db *fsdb,
665 struct mgs_target_info *mti, char *logname,
666 char *devname, char *comment, int flags)
668 struct llog_handle *loghandle;
669 struct lvfs_run_ctxt saved;
670 struct llog_ctxt *ctxt;
671 struct mgs_modify_lookup *mml;
675 CDEBUG(D_MGS, "modify %s/%s/%s fl=%x\n", logname, devname, comment,
678 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
680 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
681 LASSERT(ctxt != NULL);
682 rc = llog_create(ctxt, &loghandle, NULL, logname);
686 rc = llog_init_handle(loghandle, LLOG_F_IS_PLAIN, NULL);
690 if (llog_get_size(loghandle) <= 1)
691 GOTO(out_close, rc = 0);
695 GOTO(out_close, rc = -ENOMEM);
696 strcpy(mml->mml_marker.cm_comment, comment);
697 strcpy(mml->mml_marker.cm_tgtname, devname);
698 /* Modify mostly means cancel */
699 mml->mml_marker.cm_flags = flags;
700 mml->mml_marker.cm_canceltime = flags ? cfs_time_current_sec() : 0;
701 mml->mml_modified = 0;
702 rc = llog_process(loghandle, mgs_modify_handler, (void *)mml, NULL);
703 if (!rc && !mml->mml_modified)
708 rc2 = llog_close(loghandle);
712 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
713 if (rc && rc != -ENODEV)
714 CERROR("modify %s/%s failed %d\n",
715 mti->mti_svname, comment, rc);
720 /******************** config log recording functions *********************/
722 static int record_lcfg(struct obd_device *obd, struct llog_handle *llh,
723 struct lustre_cfg *lcfg)
725 struct lvfs_run_ctxt saved;
726 struct llog_rec_hdr rec;
732 LASSERT(llh->lgh_ctxt);
734 buflen = lustre_cfg_len(lcfg->lcfg_bufcount,
736 rec.lrh_len = llog_data_len(buflen);
737 rec.lrh_type = OBD_CFG_REC;
739 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
740 /* idx = -1 means append */
741 rc = llog_write_rec(llh, &rec, NULL, 0, (void *)lcfg, -1);
742 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
744 CERROR("failed %d\n", rc);
748 static int record_base(struct obd_device *obd, struct llog_handle *llh,
749 char *cfgname, lnet_nid_t nid, int cmd,
750 char *s1, char *s2, char *s3, char *s4)
752 struct lustre_cfg_bufs bufs;
753 struct lustre_cfg *lcfg;
756 CDEBUG(D_MGS, "lcfg %s %#x %s %s %s %s\n", cfgname,
757 cmd, s1, s2, s3, s4);
759 lustre_cfg_bufs_reset(&bufs, cfgname);
761 lustre_cfg_bufs_set_string(&bufs, 1, s1);
763 lustre_cfg_bufs_set_string(&bufs, 2, s2);
765 lustre_cfg_bufs_set_string(&bufs, 3, s3);
767 lustre_cfg_bufs_set_string(&bufs, 4, s4);
769 lcfg = lustre_cfg_new(cmd, &bufs);
772 lcfg->lcfg_nid = nid;
774 rc = record_lcfg(obd, llh, lcfg);
776 lustre_cfg_free(lcfg);
779 CERROR("error %d: lcfg %s %#x %s %s %s %s\n", rc, cfgname,
780 cmd, s1, s2, s3, s4);
786 static inline int record_add_uuid(struct obd_device *obd,
787 struct llog_handle *llh,
788 uint64_t nid, char *uuid)
790 return record_base(obd,llh,NULL,nid,LCFG_ADD_UUID,uuid,0,0,0);
794 static inline int record_add_conn(struct obd_device *obd,
795 struct llog_handle *llh,
799 return record_base(obd,llh,devname,0,LCFG_ADD_CONN,uuid,0,0,0);
802 static inline int record_attach(struct obd_device *obd, struct llog_handle *llh,
803 char *devname, char *type, char *uuid)
805 return record_base(obd,llh,devname,0,LCFG_ATTACH,type,uuid,0,0);
808 static inline int record_setup(struct obd_device *obd, struct llog_handle *llh,
810 char *s1, char *s2, char *s3, char *s4)
812 return record_base(obd,llh,devname,0,LCFG_SETUP,s1,s2,s3,s4);
815 static int record_lov_setup(struct obd_device *obd, struct llog_handle *llh,
816 char *devname, struct lov_desc *desc)
818 struct lustre_cfg_bufs bufs;
819 struct lustre_cfg *lcfg;
822 lustre_cfg_bufs_reset(&bufs, devname);
823 lustre_cfg_bufs_set(&bufs, 1, desc, sizeof(*desc));
824 lcfg = lustre_cfg_new(LCFG_SETUP, &bufs);
827 rc = record_lcfg(obd, llh, lcfg);
829 lustre_cfg_free(lcfg);
833 static int record_lmv_setup(struct obd_device *obd, struct llog_handle *llh,
834 char *devname, struct lmv_desc *desc)
836 struct lustre_cfg_bufs bufs;
837 struct lustre_cfg *lcfg;
840 lustre_cfg_bufs_reset(&bufs, devname);
841 lustre_cfg_bufs_set(&bufs, 1, desc, sizeof(*desc));
842 lcfg = lustre_cfg_new(LCFG_SETUP, &bufs);
844 rc = record_lcfg(obd, llh, lcfg);
846 lustre_cfg_free(lcfg);
850 static inline int record_mdc_add(struct obd_device *obd,
851 struct llog_handle *llh,
852 char *logname, char *mdcuuid,
853 char *mdtuuid, char *index,
856 return record_base(obd,llh,logname,0,LCFG_ADD_MDC,
857 mdtuuid,index,gen,mdcuuid);
860 static inline int record_lov_add(struct obd_device *obd,
861 struct llog_handle *llh,
862 char *lov_name, char *ost_uuid,
863 char *index, char *gen)
865 return record_base(obd,llh,lov_name,0,LCFG_LOV_ADD_OBD,
866 ost_uuid,index,gen,0);
869 static inline int record_mount_opt(struct obd_device *obd,
870 struct llog_handle *llh,
871 char *profile, char *lov_name,
874 return record_base(obd,llh,NULL,0,LCFG_MOUNTOPT,
875 profile,lov_name,mdc_name,0);
878 static int record_marker(struct obd_device *obd, struct llog_handle *llh,
879 struct fs_db *fsdb, __u32 flags,
880 char *tgtname, char *comment)
882 struct cfg_marker marker;
883 struct lustre_cfg_bufs bufs;
884 struct lustre_cfg *lcfg;
887 if (flags & CM_START)
889 marker.cm_step = fsdb->fsdb_gen;
890 marker.cm_flags = flags;
891 marker.cm_vers = LUSTRE_VERSION_CODE;
892 strncpy(marker.cm_tgtname, tgtname, sizeof(marker.cm_tgtname));
893 strncpy(marker.cm_comment, comment, sizeof(marker.cm_comment));
894 marker.cm_createtime = cfs_time_current_sec();
895 marker.cm_canceltime = 0;
896 lustre_cfg_bufs_reset(&bufs, NULL);
897 lustre_cfg_bufs_set(&bufs, 1, &marker, sizeof(marker));
898 lcfg = lustre_cfg_new(LCFG_MARKER, &bufs);
901 rc = record_lcfg(obd, llh, lcfg);
903 lustre_cfg_free(lcfg);
907 static int record_start_log(struct obd_device *obd,
908 struct llog_handle **llh, char *name)
910 static struct obd_uuid cfg_uuid = { .uuid = "config_uuid" };
911 struct lvfs_run_ctxt saved;
912 struct llog_ctxt *ctxt;
916 GOTO(out, rc = -EBUSY);
918 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
920 GOTO(out, rc = -ENODEV);
922 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
923 rc = llog_create(ctxt, llh, NULL, name);
925 llog_init_handle(*llh, LLOG_F_IS_PLAIN, &cfg_uuid);
929 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
934 CERROR("Can't start log %s: %d\n", name, rc);
939 static int record_end_log(struct obd_device *obd, struct llog_handle **llh)
941 struct lvfs_run_ctxt saved;
944 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
946 rc = llog_close(*llh);
949 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
953 static int mgs_log_is_empty(struct obd_device *obd, char *name)
955 struct lvfs_run_ctxt saved;
956 struct llog_handle *llh;
957 struct llog_ctxt *ctxt;
960 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
961 LASSERT(ctxt != NULL);
962 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
963 rc = llog_create(ctxt, &llh, NULL, name);
965 llog_init_handle(llh, LLOG_F_IS_PLAIN, NULL);
966 rc = llog_get_size(llh);
969 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
971 /* header is record 1 */
975 /******************** config "macros" *********************/
977 /* write an lcfg directly into a log (with markers) */
978 static int mgs_write_log_direct(struct obd_device *obd, struct fs_db *fsdb,
979 char *logname, struct lustre_cfg *lcfg,
980 char *devname, char *comment)
982 struct llog_handle *llh = NULL;
989 rc = record_start_log(obd, &llh, logname);
993 /* FIXME These should be a single journal transaction */
994 rc = record_marker(obd, llh, fsdb, CM_START, devname, comment);
996 rc = record_lcfg(obd, llh, lcfg);
998 rc = record_marker(obd, llh, fsdb, CM_END, devname, comment);
999 rc = record_end_log(obd, &llh);
1004 /* write the lcfg in all logs for the given fs */
1005 int mgs_write_log_direct_all(struct obd_device *obd, struct fs_db *fsdb,
1006 struct mgs_target_info *mti,
1007 struct lustre_cfg *lcfg,
1008 char *devname, char *comment)
1010 struct mgs_obd *mgs = &obd->u.mgs;
1011 cfs_list_t dentry_list;
1012 struct l_linux_dirent *dirent, *n;
1013 char *fsname = mti->mti_fsname;
1015 int rc = 0, len = strlen(fsname);
1018 /* We need to set params for any future logs
1019 as well. FIXME Append this file to every new log.
1020 Actually, we should store as params (text), not llogs. Or
1022 name_create(&logname, fsname, "-params");
1023 if (mgs_log_is_empty(obd, logname)) {
1024 struct llog_handle *llh = NULL;
1025 rc = record_start_log(obd, &llh, logname);
1026 record_end_log(obd, &llh);
1028 name_destroy(&logname);
1032 /* Find all the logs in the CONFIGS directory */
1033 rc = class_dentry_readdir(obd, mgs->mgs_configs_dir,
1034 mgs->mgs_vfsmnt, &dentry_list);
1036 CERROR("Can't read %s dir\n", MOUNT_CONFIGS_DIR);
1040 /* Could use fsdb index maps instead of directory listing */
1041 cfs_list_for_each_entry_safe(dirent, n, &dentry_list, lld_list) {
1042 cfs_list_del(&dirent->lld_list);
1043 /* don't write to sptlrpc rule log */
1044 if (strncmp(fsname, dirent->lld_name, len) == 0 &&
1045 strstr(dirent->lld_name, "-sptlrpc") == NULL) {
1046 CDEBUG(D_MGS, "Changing log %s\n", dirent->lld_name);
1047 /* Erase any old settings of this same parameter */
1048 mgs_modify(obd, fsdb, mti, dirent->lld_name, devname,
1050 /* Write the new one */
1052 rc = mgs_write_log_direct(obd, fsdb,
1057 CERROR("err %d writing log %s\n", rc,
1061 OBD_FREE(dirent, sizeof(*dirent));
1069 struct mgs_target_info *comp_tmti;
1070 struct mgs_target_info *comp_mti;
1071 struct fs_db *comp_fsdb;
1072 struct obd_device *comp_obd;
1075 static int mgs_write_log_mdc_to_mdt(struct obd_device *, struct fs_db *,
1076 struct mgs_target_info *, char *);
1078 static int mgs_steal_llog_handler(struct llog_handle *llh,
1079 struct llog_rec_hdr *rec,
1082 struct obd_device * obd;
1083 struct mgs_target_info *mti, *tmti;
1085 int cfg_len = rec->lrh_len;
1086 char *cfg_buf = (char*) (rec + 1);
1087 struct lustre_cfg *lcfg;
1089 struct llog_handle *mdt_llh = NULL;
1090 static int got_an_osc_or_mdc = 0;
1091 /* 0: not found any osc/mdc;
1095 static int last_step = -1;
1099 mti = ((struct temp_comp*)data)->comp_mti;
1100 tmti = ((struct temp_comp*)data)->comp_tmti;
1101 fsdb = ((struct temp_comp*)data)->comp_fsdb;
1102 obd = ((struct temp_comp*)data)->comp_obd;
1104 if (rec->lrh_type != OBD_CFG_REC) {
1105 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
1109 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
1111 CERROR("Insane cfg\n");
1115 lcfg = (struct lustre_cfg *)cfg_buf;
1117 if (lcfg->lcfg_command == LCFG_MARKER) {
1118 struct cfg_marker *marker;
1119 marker = lustre_cfg_buf(lcfg, 1);
1120 if (!strncmp(marker->cm_comment,"add osc",7) &&
1121 (marker->cm_flags & CM_START)){
1122 got_an_osc_or_mdc = 1;
1123 rc = record_start_log(obd, &mdt_llh, mti->mti_svname);
1124 rc = record_marker(obd, mdt_llh, fsdb, CM_START,
1125 mti->mti_svname,"add osc(copied)");
1126 rc = record_end_log(obd, &mdt_llh);
1127 last_step = marker->cm_step;
1130 if (!strncmp(marker->cm_comment,"add osc",7) &&
1131 (marker->cm_flags & CM_END)){
1132 LASSERT(last_step == marker->cm_step);
1134 got_an_osc_or_mdc = 0;
1135 rc = record_start_log(obd, &mdt_llh, mti->mti_svname);
1136 rc = record_marker(obd, mdt_llh, fsdb, CM_END,
1137 mti->mti_svname,"add osc(copied)");
1138 rc = record_end_log(obd, &mdt_llh);
1141 if (!strncmp(marker->cm_comment,"add mdc",7) &&
1142 (marker->cm_flags & CM_START)){
1143 got_an_osc_or_mdc = 2;
1144 last_step = marker->cm_step;
1145 memcpy(tmti->mti_svname, marker->cm_tgtname,
1146 strlen(marker->cm_tgtname));
1150 if (!strncmp(marker->cm_comment,"add mdc",7) &&
1151 (marker->cm_flags & CM_END)){
1152 LASSERT(last_step == marker->cm_step);
1154 got_an_osc_or_mdc = 0;
1159 if (got_an_osc_or_mdc == 0 || last_step < 0)
1162 if (lcfg->lcfg_command == LCFG_ADD_UUID) {
1164 nodenid = lcfg->lcfg_nid;
1166 tmti->mti_nids[tmti->mti_nid_count] = nodenid;
1167 tmti->mti_nid_count++;
1172 if (lcfg->lcfg_command == LCFG_SETUP) {
1175 target = lustre_cfg_string(lcfg, 1);
1176 memcpy(tmti->mti_uuid, target, strlen(target));
1180 /* ignore client side sptlrpc_conf_log */
1181 if (lcfg->lcfg_command == LCFG_SPTLRPC_CONF)
1184 if (lcfg->lcfg_command == LCFG_ADD_MDC) {
1187 if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1)
1190 memcpy(tmti->mti_fsname, mti->mti_fsname,
1191 strlen(mti->mti_fsname));
1192 tmti->mti_stripe_index = index;
1194 mgs_write_log_mdc_to_mdt(obd, fsdb, tmti, mti->mti_svname);
1195 memset(tmti, 0, sizeof(*tmti));
1201 /* fsdb->fsdb_sem is already held in mgs_write_log_target*/
1202 /* stealed from mgs_get_fsdb_from_llog*/
1203 static int mgs_steal_llog_for_mdt_from_client(struct obd_device *obd,
1205 struct temp_comp* comp)
1207 struct llog_handle *loghandle;
1208 struct lvfs_run_ctxt saved;
1209 struct mgs_target_info *tmti;
1210 struct llog_ctxt *ctxt;
1214 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
1215 LASSERT(ctxt != NULL);
1217 OBD_ALLOC_PTR(tmti);
1221 comp->comp_tmti = tmti;
1222 comp->comp_obd = obd;
1224 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
1226 rc = llog_create(ctxt, &loghandle, NULL, client_name);
1230 rc = llog_init_handle(loghandle, LLOG_F_IS_PLAIN, NULL);
1232 GOTO(out_close, rc);
1234 rc = llog_process(loghandle, mgs_steal_llog_handler, (void *)comp, NULL);
1235 CDEBUG(D_MGS, "steal llog re = %d\n", rc);
1237 rc2 = llog_close(loghandle);
1241 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
1243 llog_ctxt_put(ctxt);
1247 /* lmv is the second thing for client logs */
1248 /* copied from mgs_write_log_lov. Please refer to that. */
1249 static int mgs_write_log_lmv(struct obd_device *obd, struct fs_db *fsdb,
1250 struct mgs_target_info *mti,
1251 char *logname, char *lmvname)
1253 struct llog_handle *llh = NULL;
1254 struct lmv_desc *lmvdesc;
1259 CDEBUG(D_MGS, "Writing lmv(%s) log for %s\n", lmvname,logname);
1261 OBD_ALLOC_PTR(lmvdesc);
1262 if (lmvdesc == NULL)
1264 lmvdesc->ld_active_tgt_count = 0;
1265 lmvdesc->ld_tgt_count = 0;
1266 sprintf((char*)lmvdesc->ld_uuid.uuid, "%s_UUID", lmvname);
1267 uuid = (char *)lmvdesc->ld_uuid.uuid;
1269 rc = record_start_log(obd, &llh, logname);
1270 rc = record_marker(obd, llh, fsdb, CM_START, lmvname, "lmv setup");
1271 rc = record_attach(obd, llh, lmvname, "lmv", uuid);
1272 rc = record_lmv_setup(obd, llh, lmvname, lmvdesc);
1273 rc = record_marker(obd, llh, fsdb, CM_END, lmvname, "lmv setup");
1274 rc = record_end_log(obd, &llh);
1276 OBD_FREE_PTR(lmvdesc);
1280 /* lov is the first thing in the mdt and client logs */
1281 static int mgs_write_log_lov(struct obd_device *obd, struct fs_db *fsdb,
1282 struct mgs_target_info *mti,
1283 char *logname, char *lovname)
1285 struct llog_handle *llh = NULL;
1286 struct lov_desc *lovdesc;
1291 CDEBUG(D_MGS, "Writing lov(%s) log for %s\n", lovname, logname);
1294 #01 L attach 0:lov_mdsA 1:lov 2:71ccb_lov_mdsA_19f961a9e1
1295 #02 L lov_setup 0:lov_mdsA 1:(struct lov_desc)
1296 uuid=lov1_UUID, stripe count=1, size=1048576, offset=0, pattern=0
1299 /* FIXME just make lov_setup accept empty desc (put uuid in buf 2) */
1300 OBD_ALLOC_PTR(lovdesc);
1301 if (lovdesc == NULL)
1303 lovdesc->ld_magic = LOV_DESC_MAGIC;
1304 lovdesc->ld_tgt_count = 0;
1305 /* Defaults. Can be changed later by lcfg config_param */
1306 lovdesc->ld_default_stripe_count = 1;
1307 lovdesc->ld_pattern = LOV_PATTERN_RAID0;
1308 lovdesc->ld_default_stripe_size = 1024 * 1024;
1309 lovdesc->ld_default_stripe_offset = 0;
1310 lovdesc->ld_qos_maxage = QOS_DEFAULT_MAXAGE;
1311 sprintf((char*)lovdesc->ld_uuid.uuid, "%s_UUID", lovname);
1312 /* can these be the same? */
1313 uuid = (char *)lovdesc->ld_uuid.uuid;
1315 /* This should always be the first entry in a log.
1316 rc = mgs_clear_log(obd, logname); */
1317 rc = record_start_log(obd, &llh, logname);
1320 /* FIXME these should be a single journal transaction */
1321 rc = record_marker(obd, llh, fsdb, CM_START, lovname, "lov setup");
1322 rc = record_attach(obd, llh, lovname, "lov", uuid);
1323 rc = record_lov_setup(obd, llh, lovname, lovdesc);
1324 rc = record_marker(obd, llh, fsdb, CM_END, lovname, "lov setup");
1325 rc = record_end_log(obd, &llh);
1329 OBD_FREE_PTR(lovdesc);
1333 /* add failnids to open log */
1334 static int mgs_write_log_failnids(struct obd_device *obd,
1335 struct mgs_target_info *mti,
1336 struct llog_handle *llh,
1339 char *failnodeuuid = NULL;
1340 char *ptr = mti->mti_params;
1345 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) nal=90 0: 1:uml1_UUID
1346 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
1347 #05 L setup 0:OSC_uml1_ost1_mdsA 1:ost1_UUID 2:uml1_UUID
1348 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) nal=90 0: 1:uml2_UUID
1349 #0x L add_uuid nid=2@elan(0x1000000000002) nal=90 0: 1:uml2_UUID
1350 #07 L add_conn 0:OSC_uml1_ost1_mdsA 1:uml2_UUID
1353 /* Pull failnid info out of params string */
1354 while (class_find_param(ptr, PARAM_FAILNODE, &ptr) == 0) {
1355 while (class_parse_nid(ptr, &nid, &ptr) == 0) {
1356 if (failnodeuuid == NULL) {
1357 /* We don't know the failover node name,
1358 so just use the first nid as the uuid */
1359 rc = name_create(&failnodeuuid,
1360 libcfs_nid2str(nid), "");
1364 CDEBUG(D_MGS, "add nid %s for failover uuid %s, "
1365 "client %s\n", libcfs_nid2str(nid),
1366 failnodeuuid, cliname);
1367 rc = record_add_uuid(obd, llh, nid, failnodeuuid);
1370 rc = record_add_conn(obd, llh, cliname, failnodeuuid);
1371 name_destroy(&failnodeuuid);
1372 failnodeuuid = NULL;
1379 static int mgs_write_log_mdc_to_lmv(struct obd_device *obd, struct fs_db *fsdb,
1380 struct mgs_target_info *mti,
1381 char *logname, char *lmvname)
1383 struct llog_handle *llh = NULL;
1384 char *mdcname, *nodeuuid, *mdcuuid, *lmvuuid;
1389 if (mgs_log_is_empty(obd, logname)) {
1390 CERROR("log is empty! Logical error\n");
1394 CDEBUG(D_MGS, "adding mdc for %s to log %s:lmv(%s)\n",
1395 mti->mti_svname, logname, lmvname);
1397 name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
1398 name_create(&mdcname, mti->mti_svname, "-mdc");
1399 name_create(&mdcuuid, mdcname, "_UUID");
1400 name_create(&lmvuuid, lmvname, "_UUID");
1402 rc = record_start_log(obd, &llh, logname);
1403 rc = record_marker(obd, llh, fsdb, CM_START, mti->mti_svname,
1406 for (i = 0; i < mti->mti_nid_count; i++) {
1407 CDEBUG(D_MGS, "add nid %s for mdt\n",
1408 libcfs_nid2str(mti->mti_nids[i]));
1410 rc = record_add_uuid(obd, llh, mti->mti_nids[i], nodeuuid);
1413 rc = record_attach(obd, llh, mdcname, LUSTRE_MDC_NAME, lmvuuid);
1414 rc = record_setup(obd, llh, mdcname, mti->mti_uuid, nodeuuid, 0, 0);
1415 rc = mgs_write_log_failnids(obd, mti, llh, mdcname);
1416 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
1417 rc = record_mdc_add(obd, llh, lmvname, mdcuuid, mti->mti_uuid,
1419 rc = record_marker(obd, llh, fsdb, CM_END, mti->mti_svname,
1421 rc = record_end_log(obd, &llh);
1423 name_destroy(&lmvuuid);
1424 name_destroy(&mdcuuid);
1425 name_destroy(&mdcname);
1426 name_destroy(&nodeuuid);
1430 /* add new mdc to already existent MDS */
1431 static int mgs_write_log_mdc_to_mdt(struct obd_device *obd, struct fs_db *fsdb,
1432 struct mgs_target_info *mti, char *logname)
1434 struct llog_handle *llh = NULL;
1435 char *nodeuuid, *mdcname, *mdcuuid, *mdtuuid;
1436 int idx = mti->mti_stripe_index;
1441 if (mgs_log_is_empty(obd, mti->mti_svname)) {
1442 CERROR("log is empty! Logical error\n");
1446 CDEBUG(D_MGS, "adding mdc index %d to %s\n", idx, logname);
1448 name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
1449 snprintf(index, sizeof(index), "-mdc%04x", idx);
1450 name_create(&mdcname, logname, index);
1451 name_create(&mdcuuid, mdcname, "_UUID");
1452 name_create(&mdtuuid, logname, "_UUID");
1454 rc = record_start_log(obd, &llh, logname);
1455 rc = record_marker(obd, llh, fsdb, CM_START, mti->mti_svname, "add mdc");
1456 for (i = 0; i < mti->mti_nid_count; i++) {
1457 CDEBUG(D_MGS, "add nid %s for mdt\n",
1458 libcfs_nid2str(mti->mti_nids[i]));
1459 rc = record_add_uuid(obd, llh, mti->mti_nids[i], nodeuuid);
1461 rc = record_attach(obd, llh, mdcname, LUSTRE_MDC_NAME, mdcuuid);
1462 rc = record_setup(obd, llh, mdcname, mti->mti_uuid, nodeuuid, 0, 0);
1463 rc = mgs_write_log_failnids(obd, mti, llh, mdcname);
1464 snprintf(index, sizeof(index), "%d", idx);
1466 rc = record_mdc_add(obd, llh, logname, mdcuuid, mti->mti_uuid,
1468 rc = record_marker(obd, llh, fsdb, CM_END, mti->mti_svname, "add mdc");
1469 rc = record_end_log(obd, &llh);
1471 name_destroy(&mdcuuid);
1472 name_destroy(&mdcname);
1473 name_destroy(&nodeuuid);
1474 name_destroy(&mdtuuid);
1478 static int mgs_write_log_mdt0(struct obd_device *obd, struct fs_db *fsdb,
1479 struct mgs_target_info *mti)
1481 char *log = mti->mti_svname;
1482 struct llog_handle *llh = NULL;
1483 char *uuid, *lovname;
1485 char *ptr = mti->mti_params;
1486 int rc = 0, failout = 0;
1489 OBD_ALLOC(uuid, sizeof(struct obd_uuid));
1493 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
1494 failout = (strncmp(ptr, "failout", 7) == 0);
1496 name_create(&lovname, log, "-mdtlov");
1497 if (mgs_log_is_empty(obd, log))
1498 rc = mgs_write_log_lov(obd, fsdb, mti, log, lovname);
1500 sprintf(uuid, "%s_UUID", log);
1501 sprintf(mdt_index, "%d", mti->mti_stripe_index);
1503 /* add MDT itself */
1504 rc = record_start_log(obd, &llh, log);
1508 /* FIXME this whole fn should be a single journal transaction */
1509 rc = record_marker(obd, llh, fsdb, CM_START, log, "add mdt");
1510 rc = record_attach(obd, llh, log, LUSTRE_MDT_NAME, uuid);
1511 rc = record_mount_opt(obd, llh, log, lovname, NULL);
1512 rc = record_setup(obd, llh, log, uuid, mdt_index, lovname,
1513 failout ? "n" : "f");
1514 rc = record_marker(obd, llh, fsdb, CM_END, log, "add mdt");
1515 rc = record_end_log(obd, &llh);
1517 name_destroy(&lovname);
1518 OBD_FREE(uuid, sizeof(struct obd_uuid));
1522 static inline void name_create_sv(char **buf, char *fsname, char *type, int i)
1526 sprintf(sv_index, "-%s%04x", type, i);
1527 name_create(buf, fsname, sv_index);
1530 static inline void name_create_mdt(char **buf, char *fsname, int i)
1532 name_create_sv(buf, fsname, "MDT", i);
1535 static void name_create_mdt_and_lov(char **logname, char **lovname,
1536 struct fs_db *fsdb, int i)
1538 name_create_mdt(logname, fsdb->fsdb_name, i);
1540 if (i == 0 && cfs_test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
1541 name_create(lovname, fsdb->fsdb_name, "-mdtlov");
1543 name_create(lovname, *logname, "-mdtlov");
1546 static inline void name_create_mdt_osc(char **oscname, char *ostname,
1547 struct fs_db *fsdb, int i)
1551 if (i == 0 && cfs_test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
1552 sprintf(suffix, "-osc");
1554 sprintf(suffix, "-osc-MDT%04x", i);
1555 name_create(oscname, ostname, suffix);
1558 /* envelope method for all layers log */
1559 static int mgs_write_log_mdt(struct obd_device *obd, struct fs_db *fsdb,
1560 struct mgs_target_info *mti)
1562 struct llog_handle *llh = NULL;
1564 struct temp_comp comp = { 0 };
1568 CDEBUG(D_MGS, "writing new mdt %s\n", mti->mti_svname);
1572 if (mti->mti_flags & LDD_F_UPGRADE14) {
1573 /* We're starting with an old uuid. Assume old name for lov
1574 as well since the lov entry already exists in the log. */
1575 CDEBUG(D_MGS, "old mds uuid %s\n", mti->mti_uuid);
1576 if (strncmp(mti->mti_uuid, fsdb->fsdb_mdtlov + 4,
1577 strlen(fsdb->fsdb_mdtlov) - 4) != 0) {
1578 CERROR("old mds uuid %s doesn't match log %s (%s)\n",
1579 mti->mti_uuid, fsdb->fsdb_mdtlov,
1580 fsdb->fsdb_mdtlov + 4);
1584 /* end COMPAT_146 */
1586 if (mti->mti_uuid[0] == '\0') {
1587 /* Make up our own uuid */
1588 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
1589 "%s_UUID", mti->mti_svname);
1593 rc = mgs_write_log_mdt0(obd, fsdb, mti);
1595 /* Append the mdt info to the client log */
1596 name_create(&cliname, mti->mti_fsname, "-client");
1598 if (mgs_log_is_empty(obd, cliname)) {
1599 /* Start client log */
1600 rc = mgs_write_log_lov(obd, fsdb, mti, cliname,
1602 rc = mgs_write_log_lmv(obd, fsdb, mti, cliname,
1607 #09 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
1608 #10 L attach 0:MDC_uml1_mdsA_MNT_client 1:mdc 2:1d834_MNT_client_03f
1609 #11 L setup 0:MDC_uml1_mdsA_MNT_client 1:mdsA_UUID 2:uml1_UUID
1610 #12 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
1611 #13 L add_conn 0:MDC_uml1_mdsA_MNT_client 1:uml2_UUID
1612 #14 L mount_option 0: 1:client 2:lov1 3:MDC_uml1_mdsA_MNT_client
1617 if (mti->mti_flags & LDD_F_UPGRADE14) {
1618 rc = record_start_log(obd, &llh, cliname);
1622 rc = record_marker(obd, llh, fsdb, CM_START,
1623 mti->mti_svname,"add mdc");
1625 /* Old client log already has MDC entry, but needs mount opt
1626 for new client name (lustre-client) */
1627 /* FIXME Old MDT log already has an old mount opt
1628 which we should remove (currently handled by
1629 class_del_profiles()) */
1630 rc = record_mount_opt(obd, llh, cliname, fsdb->fsdb_clilov,
1632 /* end COMPAT_146 */
1634 rc = record_marker(obd, llh, fsdb, CM_END,
1635 mti->mti_svname, "add mdc");
1639 /* copy client info about lov/lmv */
1640 comp.comp_mti = mti;
1641 comp.comp_fsdb = fsdb;
1643 rc = mgs_steal_llog_for_mdt_from_client(obd, cliname,
1646 rc = mgs_write_log_mdc_to_lmv(obd, fsdb, mti, cliname,
1649 rc = record_start_log(obd, &llh, cliname);
1653 rc = record_marker(obd, llh, fsdb, CM_START, cliname,
1655 rc = record_mount_opt(obd, llh, cliname, fsdb->fsdb_clilov,
1657 rc = record_marker(obd, llh, fsdb, CM_END, cliname,
1661 rc = record_end_log(obd, &llh);
1663 name_destroy(&cliname);
1665 // for_all_existing_mdt except current one
1666 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
1668 if (i != mti->mti_stripe_index &&
1669 cfs_test_bit(i, fsdb->fsdb_mdt_index_map)) {
1670 name_create_mdt(&mdtname, mti->mti_fsname, i);
1671 rc = mgs_write_log_mdc_to_mdt(obd, fsdb, mti, mdtname);
1672 name_destroy(&mdtname);
1679 /* Add the ost info to the client/mdt lov */
1680 static int mgs_write_log_osc_to_lov(struct obd_device *obd, struct fs_db *fsdb,
1681 struct mgs_target_info *mti,
1682 char *logname, char *suffix, char *lovname,
1683 enum lustre_sec_part sec_part, int flags)
1685 struct llog_handle *llh = NULL;
1686 char *nodeuuid, *oscname, *oscuuid, *lovuuid, *svname;
1691 CDEBUG(D_INFO, "adding osc for %s to log %s\n",
1692 mti->mti_svname, logname);
1694 if (mgs_log_is_empty(obd, logname)) {
1695 /* The first item in the log must be the lov, so we have
1696 somewhere to add our osc. */
1697 rc = mgs_write_log_lov(obd, fsdb, mti, logname, lovname);
1700 name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
1701 name_create(&svname, mti->mti_svname, "-osc");
1702 name_create(&oscname, svname, suffix);
1703 name_create(&oscuuid, oscname, "_UUID");
1704 name_create(&lovuuid, lovname, "_UUID");
1707 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
1709 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
1710 #04 L attach 0:OSC_uml1_ost1_MNT_client 1:osc 2:89070_lov1_a41dff51a
1711 #05 L setup 0:OSC_uml1_ost1_MNT_client 1:ost1_UUID 2:uml1_UUID
1713 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
1714 #07 L add_conn 0:OSC_uml1_ost1_MNT_client 1:uml2_UUID
1715 #08 L lov_modify_tgts add 0:lov1 1:ost1_UUID 2(index):0 3(gen):1
1718 rc = record_start_log(obd, &llh, logname);
1721 /* FIXME these should be a single journal transaction */
1722 rc = record_marker(obd, llh, fsdb, CM_START | flags, mti->mti_svname,
1724 for (i = 0; i < mti->mti_nid_count; i++) {
1725 CDEBUG(D_MGS, "add nid %s\n", libcfs_nid2str(mti->mti_nids[i]));
1726 rc = record_add_uuid(obd, llh, mti->mti_nids[i], nodeuuid);
1728 rc = record_attach(obd, llh, oscname, LUSTRE_OSC_NAME, lovuuid);
1729 rc = record_setup(obd, llh, oscname, mti->mti_uuid, nodeuuid, 0, 0);
1730 rc = mgs_write_log_failnids(obd, mti, llh, oscname);
1731 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
1732 rc = record_lov_add(obd, llh, lovname, mti->mti_uuid, index, "1");
1733 rc = record_marker(obd, llh, fsdb, CM_END | flags, mti->mti_svname,
1735 rc = record_end_log(obd, &llh);
1737 name_destroy(&lovuuid);
1738 name_destroy(&oscuuid);
1739 name_destroy(&oscname);
1740 name_destroy(&svname);
1741 name_destroy(&nodeuuid);
1745 static int mgs_write_log_ost(struct obd_device *obd, struct fs_db *fsdb,
1746 struct mgs_target_info *mti)
1748 struct llog_handle *llh = NULL;
1749 char *logname, *lovname;
1750 char *ptr = mti->mti_params;
1751 int rc, flags = 0, failout = 0, i;
1754 CDEBUG(D_MGS, "writing new ost %s\n", mti->mti_svname);
1756 /* The ost startup log */
1758 /* If the ost log already exists, that means that someone reformatted
1759 the ost and it called target_add again. */
1760 if (!mgs_log_is_empty(obd, mti->mti_svname)) {
1761 LCONSOLE_ERROR_MSG(0x141, "The config log for %s already "
1762 "exists, yet the server claims it never "
1763 "registered. It may have been reformatted, "
1764 "or the index changed. writeconf the MDT to "
1765 "regenerate all logs.\n", mti->mti_svname);
1770 attach obdfilter ost1 ost1_UUID
1771 setup /dev/loop2 ldiskfs f|n errors=remount-ro,user_xattr
1773 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
1774 failout = (strncmp(ptr, "failout", 7) == 0);
1775 rc = record_start_log(obd, &llh, mti->mti_svname);
1778 /* FIXME these should be a single journal transaction */
1779 rc = record_marker(obd, llh, fsdb, CM_START, mti->mti_svname,"add ost");
1780 if (*mti->mti_uuid == '\0')
1781 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
1782 "%s_UUID", mti->mti_svname);
1783 rc = record_attach(obd, llh, mti->mti_svname,
1784 "obdfilter"/*LUSTRE_OST_NAME*/, mti->mti_uuid);
1785 rc = record_setup(obd, llh, mti->mti_svname,
1786 "dev"/*ignored*/, "type"/*ignored*/,
1787 failout ? "n" : "f", 0/*options*/);
1788 rc = record_marker(obd, llh, fsdb, CM_END, mti->mti_svname, "add ost");
1789 rc = record_end_log(obd, &llh);
1791 /* We also have to update the other logs where this osc is part of
1794 if (cfs_test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
1795 /* If we're upgrading, the old mdt log already has our
1796 entry. Let's do a fake one for fun. */
1797 /* Note that we can't add any new failnids, since we don't
1798 know the old osc names. */
1799 flags = CM_SKIP | CM_UPGRADE146;
1801 } else if ((mti->mti_flags & LDD_F_UPDATE) != LDD_F_UPDATE) {
1802 /* If the update flag isn't set, don't update client/mdt
1805 LCONSOLE_WARN("Client log for %s was not updated; writeconf "
1806 "the MDT first to regenerate it.\n",
1810 /* Add ost to all MDT lov defs */
1811 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
1812 if (cfs_test_bit(i, fsdb->fsdb_mdt_index_map)) {
1815 name_create_mdt_and_lov(&logname, &lovname, fsdb, i);
1816 sprintf(mdt_index, "-MDT%04x", i);
1817 mgs_write_log_osc_to_lov(obd, fsdb, mti, logname,
1819 LUSTRE_SP_MDT, flags);
1820 name_destroy(&logname);
1821 name_destroy(&lovname);
1825 /* Append ost info to the client log */
1826 name_create(&logname, mti->mti_fsname, "-client");
1827 mgs_write_log_osc_to_lov(obd, fsdb, mti, logname, "",
1828 fsdb->fsdb_clilov, LUSTRE_SP_CLI, 0);
1829 name_destroy(&logname);
1833 static __inline__ int mgs_param_empty(char *ptr)
1837 if ((tmp = strchr(ptr, '=')) && (*(++tmp) == '\0'))
1842 static int mgs_write_log_failnid_internal(struct obd_device *obd,
1844 struct mgs_target_info *mti,
1845 char *logname, char *cliname)
1848 struct llog_handle *llh = NULL;
1850 if (mgs_param_empty(mti->mti_params)) {
1851 /* Remove _all_ failnids */
1852 rc = mgs_modify(obd, fsdb, mti, logname,
1853 mti->mti_svname, "add failnid", CM_SKIP);
1857 /* Otherwise failover nids are additive */
1858 rc = record_start_log(obd, &llh, logname);
1860 /* FIXME this should be a single journal transaction */
1861 rc = record_marker(obd, llh, fsdb, CM_START,
1862 mti->mti_svname, "add failnid");
1863 rc = mgs_write_log_failnids(obd, mti, llh, cliname);
1864 rc = record_marker(obd, llh, fsdb, CM_END,
1865 mti->mti_svname, "add failnid");
1866 rc = record_end_log(obd, &llh);
1873 /* Add additional failnids to an existing log.
1874 The mdc/osc must have been added to logs first */
1875 /* tcp nids must be in dotted-quad ascii -
1876 we can't resolve hostnames from the kernel. */
1877 static int mgs_write_log_add_failnid(struct obd_device *obd, struct fs_db *fsdb,
1878 struct mgs_target_info *mti)
1880 char *logname, *cliname;
1884 /* FIXME we currently can't erase the failnids
1885 * given when a target first registers, since they aren't part of
1886 * an "add uuid" stanza */
1888 /* Verify that we know about this target */
1889 if (mgs_log_is_empty(obd, mti->mti_svname)) {
1890 LCONSOLE_ERROR_MSG(0x142, "The target %s has not registered "
1891 "yet. It must be started before failnids "
1892 "can be added.\n", mti->mti_svname);
1896 /* Create mdc/osc client name (e.g. lustre-OST0001-osc) */
1897 if (mti->mti_flags & SVTYPE_MDT) {
1898 name_create(&cliname, mti->mti_svname, "-mdc");
1899 } else if (mti->mti_flags & SVTYPE_OST) {
1900 name_create(&cliname, mti->mti_svname, "-osc");
1905 /* Add failover nids to the client log */
1906 name_create(&logname, mti->mti_fsname, "-client");
1907 rc = mgs_write_log_failnid_internal(obd, fsdb, mti, logname, cliname);
1908 name_destroy(&logname);
1909 name_destroy(&cliname);
1911 if (mti->mti_flags & SVTYPE_OST) {
1912 /* Add OST failover nids to the MDT logs as well */
1915 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
1916 if (!cfs_test_bit(i, fsdb->fsdb_mdt_index_map))
1918 name_create_mdt(&logname, mti->mti_fsname, i);
1919 name_create_mdt_osc(&cliname, mti->mti_svname, fsdb, i);
1920 rc = mgs_write_log_failnid_internal(obd, fsdb, mti,
1922 name_destroy(&cliname);
1923 name_destroy(&logname);
1930 /** write_log_param helper to add or modify a parameter change lcfg record
1932 * @logname log to add lcfg to (e.g. client, mdt, ost)
1933 * @bufs empty bufs for temp usage
1934 * @tgtname target obd device this param is meant to affect
1935 * @ptr ptr to param=val
1937 static int mgs_wlp_lcfg(struct obd_device *obd, struct fs_db *fsdb,
1938 struct mgs_target_info *mti,
1939 char *logname, struct lustre_cfg_bufs *bufs,
1940 char *tgtname, char *ptr)
1942 char comment[MTI_NAME_MAXLEN];
1944 struct lustre_cfg *lcfg;
1947 /* Erase any old settings of this same parameter */
1948 memcpy(comment, ptr, MTI_NAME_MAXLEN);
1949 comment[MTI_NAME_MAXLEN - 1] = 0;
1950 /* But don't try to match the value. */
1951 if ((tmp = strchr(comment, '=')))
1953 /* FIXME we should skip settings that are the same as old values */
1954 rc = mgs_modify(obd, fsdb, mti, logname, tgtname, comment, CM_SKIP);
1955 del = mgs_param_empty(ptr);
1957 LCONSOLE_INFO("%sing parameter %s.%s in log %s\n", del ? "Disabl" : rc ?
1958 "Sett" : "Modify", tgtname, comment, logname);
1962 lustre_cfg_bufs_reset(bufs, tgtname);
1963 lustre_cfg_bufs_set_string(bufs, 1, ptr);
1964 lcfg = lustre_cfg_new(LCFG_PARAM, bufs);
1967 rc = mgs_write_log_direct(obd, fsdb, logname, lcfg, tgtname, comment);
1968 lustre_cfg_free(lcfg);
1972 /* write global variable settings into log */
1973 static int mgs_write_log_sys(struct obd_device *obd, struct fs_db *fsdb,
1974 struct mgs_target_info *mti, char *sys, char *ptr)
1976 struct lustre_cfg_bufs bufs;
1977 struct lustre_cfg *lcfg;
1983 if (class_match_param(ptr, PARAM_TIMEOUT, &tmp) == 0)
1984 cmd = LCFG_SET_TIMEOUT;
1985 else if (class_match_param(ptr, PARAM_LDLM_TIMEOUT, &tmp) == 0)
1986 cmd = LCFG_SET_LDLM_TIMEOUT;
1987 /* Check for known params here so we can return error to lctl */
1988 else if ((class_match_param(ptr, PARAM_AT_MIN, &tmp) == 0)
1989 || (class_match_param(ptr, PARAM_AT_MAX, &tmp) == 0)
1990 || (class_match_param(ptr, PARAM_AT_EXTRA, &tmp) == 0)
1991 || (class_match_param(ptr, PARAM_AT_EARLY_MARGIN, &tmp) == 0)
1992 || (class_match_param(ptr, PARAM_AT_HISTORY, &tmp) == 0))
1997 /* separate the value */
1998 val = simple_strtoul(tmp, NULL, 0);
2000 CDEBUG(D_MGS, "global '%s' removed\n", sys);
2002 CDEBUG(D_MGS, "global '%s' val=%d\n", sys, val);
2004 lustre_cfg_bufs_reset(&bufs, NULL);
2005 lustre_cfg_bufs_set_string(&bufs, 1, sys);
2006 lcfg = lustre_cfg_new(cmd, &bufs);
2007 lcfg->lcfg_num = val;
2008 /* truncate the comment to the parameter name */
2012 /* modify all servers and clients */
2013 rc = mgs_write_log_direct_all(obd, fsdb, mti,
2014 *tmp == '\0' ? NULL : lcfg,
2015 mti->mti_fsname, sys);
2017 lustre_cfg_free(lcfg);
2021 static int mgs_srpc_set_param_disk(struct obd_device *obd,
2023 struct mgs_target_info *mti,
2026 struct llog_handle *llh = NULL;
2028 char *comment, *ptr;
2029 struct lustre_cfg_bufs bufs;
2030 struct lustre_cfg *lcfg;
2035 ptr = strchr(param, '=');
2039 OBD_ALLOC(comment, len + 1);
2040 if (comment == NULL)
2042 strncpy(comment, param, len);
2043 comment[len] = '\0';
2046 lustre_cfg_bufs_reset(&bufs, mti->mti_svname);
2047 lustre_cfg_bufs_set_string(&bufs, 1, param);
2048 lcfg = lustre_cfg_new(LCFG_SPTLRPC_CONF, &bufs);
2050 GOTO(out_comment, rc = -ENOMEM);
2052 /* construct log name */
2053 rc = name_create(&logname, mti->mti_fsname, "-sptlrpc");
2057 if (mgs_log_is_empty(obd, logname)) {
2058 rc = record_start_log(obd, &llh, logname);
2059 record_end_log(obd, &llh);
2064 /* obsolete old one */
2065 mgs_modify(obd, fsdb, mti, logname, mti->mti_svname, comment, CM_SKIP);
2067 if (!mgs_param_empty(param)) {
2068 /* write the new one */
2069 rc = mgs_write_log_direct(obd, fsdb, logname, lcfg,
2070 mti->mti_svname, comment);
2072 CERROR("err %d writing log %s\n", rc, logname);
2075 name_destroy(&logname);
2077 lustre_cfg_free(lcfg);
2079 OBD_FREE(comment, len + 1);
2083 static int mgs_srpc_set_param_udesc_mem(struct fs_db *fsdb,
2088 /* disable the adjustable udesc parameter for now, i.e. use default
2089 * setting that client always ship udesc to MDT if possible. to enable
2090 * it simply remove the following line */
2093 ptr = strchr(param, '=');
2098 if (strcmp(param, PARAM_SRPC_UDESC))
2101 if (strcmp(ptr, "yes") == 0) {
2102 cfs_set_bit(FSDB_UDESC, &fsdb->fsdb_flags);
2103 CWARN("Enable user descriptor shipping from client to MDT\n");
2104 } else if (strcmp(ptr, "no") == 0) {
2105 cfs_clear_bit(FSDB_UDESC, &fsdb->fsdb_flags);
2106 CWARN("Disable user descriptor shipping from client to MDT\n");
2114 CERROR("Invalid param: %s\n", param);
2118 static int mgs_srpc_set_param_mem(struct fs_db *fsdb,
2122 struct sptlrpc_rule rule;
2123 struct sptlrpc_rule_set *rset;
2127 if (strncmp(param, PARAM_SRPC, sizeof(PARAM_SRPC) - 1) != 0) {
2128 CERROR("Invalid sptlrpc parameter: %s\n", param);
2132 if (strncmp(param, PARAM_SRPC_UDESC,
2133 sizeof(PARAM_SRPC_UDESC) - 1) == 0) {
2134 RETURN(mgs_srpc_set_param_udesc_mem(fsdb, param));
2137 if (strncmp(param, PARAM_SRPC_FLVR, sizeof(PARAM_SRPC_FLVR) - 1) != 0) {
2138 CERROR("Invalid sptlrpc flavor parameter: %s\n", param);
2142 param += sizeof(PARAM_SRPC_FLVR) - 1;
2144 rc = sptlrpc_parse_rule(param, &rule);
2148 /* mgs rules implies must be mgc->mgs */
2149 if (cfs_test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
2150 if ((rule.sr_from != LUSTRE_SP_MGC &&
2151 rule.sr_from != LUSTRE_SP_ANY) ||
2152 (rule.sr_to != LUSTRE_SP_MGS &&
2153 rule.sr_to != LUSTRE_SP_ANY))
2157 /* preapre room for this coming rule. svcname format should be:
2158 * - fsname: general rule
2159 * - fsname-tgtname: target-specific rule
2161 if (strchr(svname, '-')) {
2162 struct mgs_tgt_srpc_conf *tgtconf;
2165 for (tgtconf = fsdb->fsdb_srpc_tgt; tgtconf != NULL;
2166 tgtconf = tgtconf->mtsc_next) {
2167 if (!strcmp(tgtconf->mtsc_tgt, svname)) {
2176 OBD_ALLOC_PTR(tgtconf);
2177 if (tgtconf == NULL)
2180 name_len = strlen(svname);
2182 OBD_ALLOC(tgtconf->mtsc_tgt, name_len + 1);
2183 if (tgtconf->mtsc_tgt == NULL) {
2184 OBD_FREE_PTR(tgtconf);
2187 memcpy(tgtconf->mtsc_tgt, svname, name_len);
2189 tgtconf->mtsc_next = fsdb->fsdb_srpc_tgt;
2190 fsdb->fsdb_srpc_tgt = tgtconf;
2193 rset = &tgtconf->mtsc_rset;
2195 rset = &fsdb->fsdb_srpc_gen;
2198 rc = sptlrpc_rule_set_merge(rset, &rule);
2203 static int mgs_srpc_set_param(struct obd_device *obd,
2205 struct mgs_target_info *mti,
2209 int rc, copy_size, del;
2215 /* keep a copy of original param, which could be destroied
2217 copy_size = strlen(param) + 1;
2218 OBD_ALLOC(copy, copy_size);
2221 memcpy(copy, param, copy_size);
2223 del = mgs_param_empty(param);
2225 rc = mgs_srpc_set_param_mem(fsdb, mti->mti_svname, param);
2230 /* previous steps guaranteed the syntax is correct */
2231 rc = mgs_srpc_set_param_disk(obd, fsdb, mti, copy);
2235 if (cfs_test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
2237 * for mgs rules, make them effective immediately.
2239 LASSERT(fsdb->fsdb_srpc_tgt == NULL);
2240 sptlrpc_target_update_exp_flavor(obd, &fsdb->fsdb_srpc_gen);
2244 OBD_FREE(copy, copy_size);
2248 struct mgs_srpc_read_data {
2249 struct fs_db *msrd_fsdb;
2253 static int mgs_srpc_read_handler(struct llog_handle *llh,
2254 struct llog_rec_hdr *rec,
2257 struct mgs_srpc_read_data *msrd = (struct mgs_srpc_read_data *) data;
2258 struct cfg_marker *marker;
2259 struct lustre_cfg *lcfg = (struct lustre_cfg *)(rec + 1);
2260 char *svname, *param;
2264 if (rec->lrh_type != OBD_CFG_REC) {
2265 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
2269 cfg_len = rec->lrh_len - sizeof(struct llog_rec_hdr) -
2270 sizeof(struct llog_rec_tail);
2272 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
2274 CERROR("Insane cfg\n");
2278 if (lcfg->lcfg_command == LCFG_MARKER) {
2279 marker = lustre_cfg_buf(lcfg, 1);
2281 if (marker->cm_flags & CM_START &&
2282 marker->cm_flags & CM_SKIP)
2283 msrd->msrd_skip = 1;
2284 if (marker->cm_flags & CM_END)
2285 msrd->msrd_skip = 0;
2290 if (msrd->msrd_skip)
2293 if (lcfg->lcfg_command != LCFG_SPTLRPC_CONF) {
2294 CERROR("invalid command (%x)\n", lcfg->lcfg_command);
2298 svname = lustre_cfg_string(lcfg, 0);
2299 if (svname == NULL) {
2300 CERROR("svname is empty\n");
2304 param = lustre_cfg_string(lcfg, 1);
2305 if (param == NULL) {
2306 CERROR("param is empty\n");
2310 rc = mgs_srpc_set_param_mem(msrd->msrd_fsdb, svname, param);
2312 CERROR("read sptlrpc record error (%d): %s\n", rc, param);
2317 int mgs_get_fsdb_srpc_from_llog(struct obd_device *obd,
2320 struct llog_handle *llh = NULL;
2321 struct lvfs_run_ctxt saved;
2322 struct llog_ctxt *ctxt;
2324 struct mgs_srpc_read_data msrd;
2328 /* construct log name */
2329 rc = name_create(&logname, fsdb->fsdb_name, "-sptlrpc");
2333 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
2334 LASSERT(ctxt != NULL);
2336 if (mgs_log_is_empty(obd, logname))
2339 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
2341 rc = llog_create(ctxt, &llh, NULL, logname);
2345 rc = llog_init_handle(llh, LLOG_F_IS_PLAIN, NULL);
2347 GOTO(out_close, rc);
2349 if (llog_get_size(llh) <= 1)
2350 GOTO(out_close, rc = 0);
2352 msrd.msrd_fsdb = fsdb;
2355 rc = llog_process(llh, mgs_srpc_read_handler, (void *) &msrd, NULL);
2360 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
2362 llog_ctxt_put(ctxt);
2363 name_destroy(&logname);
2366 CERROR("failed to read sptlrpc config database: %d\n", rc);
2370 /** write_log_params helper for server logs (MDT or OST)
2371 * Figures out which server logs to modify, adds lcfg to each one.
2372 * Understands "match all" wildcard (lustre-OST*)
2373 * @param svtype MDT or OST
2374 * @param bufs empty lcfg bufs to use
2375 * @param ptr pointer to param=val string
2377 static int mgs_wlp_server(struct obd_device *obd, struct fs_db *fsdb,
2378 struct mgs_target_info *mti, int svtype,
2379 struct lustre_cfg_bufs *bufs,
2382 int rc = 0, type, i;
2385 if (strncmp(mti->mti_svname, mti->mti_fsname, MTI_NAME_MAXLEN) == 0)
2386 /* device is unspecified completely? */
2387 type = svtype | SVTYPE_ALL;
2389 rc = libcfs_str2server(mti->mti_svname, &type, &idx, NULL);
2393 if (type & SVTYPE_ALL) {
2396 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2397 if (!cfs_test_bit(i, type & SVTYPE_MDT ?
2398 fsdb->fsdb_mdt_index_map :
2399 fsdb->fsdb_ost_index_map))
2401 name_create_sv(&logname, mti->mti_fsname,
2402 type & SVTYPE_MDT ? "MDT" : "OST", i);
2403 rc = mgs_wlp_lcfg(obd, fsdb, mti,
2406 name_destroy(&logname);
2409 if (mgs_log_is_empty(obd, mti->mti_svname))
2411 rc = mgs_wlp_lcfg(obd, fsdb, mti,
2412 mti->mti_svname, bufs,
2413 mti->mti_svname, ptr);
2418 /* Permanent settings of all parameters by writing into the appropriate
2419 * configuration logs.
2420 * A parameter with null value ("<param>='\0'") means to erase it out of
2422 * @param ptr pointer to param=value string
2424 static int mgs_write_log_param(struct obd_device *obd, struct fs_db *fsdb,
2425 struct mgs_target_info *mti, char *ptr)
2427 struct lustre_cfg_bufs bufs;
2433 /* For various parameter settings, we have to figure out which logs
2434 care about them (e.g. both mdt and client for lov settings) */
2435 CDEBUG(D_MGS, "next param '%s'\n", ptr);
2437 /* The params are stored in MOUNT_DATA_FILE and modified via
2438 tunefs.lustre, or set using lctl conf_param */
2440 /* Processed in lustre_start_mgc */
2441 if (class_match_param(ptr, PARAM_MGSNODE, NULL) == 0)
2444 /* Processed in mgs_write_log_ost */
2445 if (class_match_param(ptr, PARAM_FAILMODE, NULL) == 0) {
2446 if (mti->mti_flags & LDD_F_PARAM) {
2447 LCONSOLE_ERROR_MSG(0x169, "%s can only be "
2448 "changed with tunefs.lustre"
2449 "and --writeconf\n", ptr);
2455 if (class_match_param(ptr, PARAM_SRPC, NULL) == 0) {
2456 rc = mgs_srpc_set_param(obd, fsdb, mti, ptr);
2460 if (class_find_param(ptr, PARAM_FAILNODE, NULL) == 0) {
2461 /* Add a failover nidlist */
2463 /* We already processed failovers params for new
2464 targets in mgs_write_log_target */
2465 if (mti->mti_flags & LDD_F_PARAM) {
2466 CDEBUG(D_MGS, "Adding failnode\n");
2467 rc = mgs_write_log_add_failnid(obd, fsdb, mti);
2472 if (class_match_param(ptr, PARAM_SYS, &tmp) == 0) {
2473 rc = mgs_write_log_sys(obd, fsdb, mti, ptr, tmp);
2477 if (class_match_param(ptr, PARAM_OSC""PARAM_ACTIVE, &tmp) == 0) {
2478 /* active=0 means off, anything else means on */
2479 int flag = (*tmp == '0') ? CM_EXCLUDE : 0;
2482 if (!(mti->mti_flags & SVTYPE_OST)) {
2483 LCONSOLE_ERROR_MSG(0x144, "%s: Only OSCs can "
2484 "be (de)activated.\n",
2486 GOTO(end, rc = -EINVAL);
2488 LCONSOLE_WARN("Permanently %sactivating %s\n",
2489 flag ? "de": "re", mti->mti_svname);
2491 name_create(&logname, mti->mti_fsname, "-client");
2492 rc = mgs_modify(obd, fsdb, mti, logname,
2493 mti->mti_svname, "add osc", flag);
2494 name_destroy(&logname);
2498 /* Add to all MDT logs for CMD */
2499 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2500 if (!cfs_test_bit(i, fsdb->fsdb_mdt_index_map))
2502 name_create_mdt(&logname, mti->mti_fsname, i);
2503 rc = mgs_modify(obd, fsdb, mti, logname,
2504 mti->mti_svname, "add osc", flag);
2505 name_destroy(&logname);
2511 LCONSOLE_ERROR_MSG(0x145, "Couldn't find %s in "
2512 "log (%d). No permanent "
2513 "changes were made to the "
2515 mti->mti_svname, rc);
2516 if (cfs_test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags))
2517 LCONSOLE_ERROR_MSG(0x146, "This may be"
2522 "update the logs.\n");
2525 /* Fall through to osc proc for deactivating live OSC
2526 on running MDT / clients. */
2528 /* Below here, let obd's XXX_process_config methods handle it */
2530 /* All lov. in proc */
2531 if (class_match_param(ptr, PARAM_LOV, NULL) == 0) {
2534 CDEBUG(D_MGS, "lov param %s\n", ptr);
2535 if (!(mti->mti_flags & SVTYPE_MDT)) {
2536 LCONSOLE_ERROR_MSG(0x147, "LOV params must be "
2537 "set on the MDT, not %s. "
2544 if (mgs_log_is_empty(obd, mti->mti_svname))
2545 GOTO(end, rc = -ENODEV);
2547 name_create_mdt_and_lov(&logname, &mdtlovname, fsdb,
2548 mti->mti_stripe_index);
2549 rc = mgs_wlp_lcfg(obd, fsdb, mti, mti->mti_svname,
2550 &bufs, mdtlovname, ptr);
2551 name_destroy(&logname);
2552 name_destroy(&mdtlovname);
2557 name_create(&logname, mti->mti_fsname, "-client");
2558 rc = mgs_wlp_lcfg(obd, fsdb, mti, logname, &bufs,
2559 fsdb->fsdb_clilov, ptr);
2560 name_destroy(&logname);
2564 /* All osc., mdc., llite. params in proc */
2565 if ((class_match_param(ptr, PARAM_OSC, NULL) == 0) ||
2566 (class_match_param(ptr, PARAM_MDC, NULL) == 0) ||
2567 (class_match_param(ptr, PARAM_LLITE, NULL) == 0)) {
2569 if (memcmp(ptr, PARAM_LLITE, strlen(PARAM_LLITE)) == 0) {
2570 name_create(&cname, mti->mti_fsname, "-client");
2571 /* Add the client type to match the obdname in
2572 class_config_llog_handler */
2573 } else if (mti->mti_flags & SVTYPE_MDT) {
2576 name_create(&cname, fsdb->fsdb_mdc, "");
2578 name_create(&cname, mti->mti_svname,
2580 } else if (mti->mti_flags & SVTYPE_OST) {
2582 if (cfs_test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
2583 LCONSOLE_ERROR_MSG(0x148, "Upgraded "
2584 "client logs for %s"
2586 "modified. Consider"
2588 "configuration with"
2591 /* We don't know the names of all the
2593 GOTO(end, rc = -EINVAL);
2595 name_create(&cname, mti->mti_svname, "-osc");
2597 GOTO(end, rc = -EINVAL);
2600 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
2603 name_create(&logname, mti->mti_fsname, "-client");
2604 rc = mgs_wlp_lcfg(obd, fsdb, mti, logname, &bufs,
2607 /* osc params affect the MDT as well */
2608 if (!rc && (mti->mti_flags & SVTYPE_OST)) {
2611 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
2612 if (!cfs_test_bit(i, fsdb->fsdb_mdt_index_map))
2614 name_destroy(&cname);
2615 name_create_mdt_osc(&cname, mti->mti_svname,
2617 name_destroy(&logname);
2618 name_create_mdt(&logname, mti->mti_fsname, i);
2619 if (!mgs_log_is_empty(obd, logname))
2620 rc = mgs_wlp_lcfg(obd, fsdb,mti,logname,
2626 name_destroy(&logname);
2627 name_destroy(&cname);
2631 /* All mdt., mdd. params in proc */
2632 if ((class_match_param(ptr, PARAM_MDT, NULL) == 0) ||
2633 (class_match_param(ptr, PARAM_MDD, NULL) == 0)) {
2634 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
2635 rc = mgs_wlp_server(obd, fsdb, mti, SVTYPE_MDT,
2640 /* All ost. params in proc */
2641 if (class_match_param(ptr, PARAM_OST, NULL) == 0) {
2642 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
2643 rc = mgs_wlp_server(obd, fsdb, mti, SVTYPE_OST,
2648 LCONSOLE_WARN("Ignoring unrecognized param '%s'\n", ptr);
2652 CERROR("err %d on param '%s'\n", rc, ptr);
2657 /* Not implementing automatic failover nid addition at this time. */
2658 int mgs_check_failnid(struct obd_device *obd, struct mgs_target_info *mti)
2665 rc = mgs_find_or_make_fsdb(obd, fsname, &fsdb);
2669 if (mgs_log_is_empty(obd, mti->mti_svname))
2670 /* should never happen */
2673 CDEBUG(D_MGS, "Checking for new failnids for %s\n", mti->mti_svname);
2675 /* FIXME We can just check mti->params to see if we're already in
2676 the failover list. Modify mti->params for rewriting back at
2677 server_register_target(). */
2679 cfs_down(&fsdb->fsdb_sem);
2680 rc = mgs_write_log_add_failnid(obd, fsdb, mti);
2681 cfs_up(&fsdb->fsdb_sem);
2688 int mgs_write_log_target(struct obd_device *obd,
2689 struct mgs_target_info *mti,
2696 /* set/check the new target index */
2697 rc = mgs_set_index(obd, mti);
2699 CERROR("Can't get index (%d)\n", rc);
2704 if (mti->mti_flags & LDD_F_UPGRADE14) {
2705 if (rc == EALREADY) {
2706 LCONSOLE_INFO("Found index %d for %s 1.4 log, "
2707 "upgrading\n", mti->mti_stripe_index,
2710 LCONSOLE_ERROR_MSG(0x149, "Failed to find %s in the old"
2711 " client log. Apparently it is not "
2712 "part of this filesystem, or the old"
2713 " log is wrong.\nUse 'writeconf' on "
2714 "the MDT to force log regeneration."
2715 "\n", mti->mti_svname);
2716 /* Not in client log? Upgrade anyhow...*/
2717 /* Argument against upgrading: reformat MDT,
2718 upgrade OST, then OST will start but will be SKIPped
2719 in client logs. Maybe error now is better. */
2720 /* RETURN(-EINVAL); */
2722 /* end COMPAT_146 */
2724 if (rc == EALREADY) {
2725 LCONSOLE_WARN("Found index %d for %s, updating log\n",
2726 mti->mti_stripe_index, mti->mti_svname);
2727 /* We would like to mark old log sections as invalid
2728 and add new log sections in the client and mdt logs.
2729 But if we add new sections, then live clients will
2730 get repeat setup instructions for already running
2731 osc's. So don't update the client/mdt logs. */
2732 mti->mti_flags &= ~LDD_F_UPDATE;
2736 cfs_down(&fsdb->fsdb_sem);
2738 if (mti->mti_flags &
2739 (LDD_F_VIRGIN | LDD_F_UPGRADE14 | LDD_F_WRITECONF)) {
2740 /* Generate a log from scratch */
2741 if (mti->mti_flags & SVTYPE_MDT) {
2742 rc = mgs_write_log_mdt(obd, fsdb, mti);
2743 } else if (mti->mti_flags & SVTYPE_OST) {
2744 rc = mgs_write_log_ost(obd, fsdb, mti);
2746 CERROR("Unknown target type %#x, can't create log for "
2747 "%s\n", mti->mti_flags, mti->mti_svname);
2750 CERROR("Can't write logs for %s (%d)\n",
2751 mti->mti_svname, rc);
2755 /* Just update the params from tunefs in mgs_write_log_params */
2756 CDEBUG(D_MGS, "Update params for %s\n", mti->mti_svname);
2757 mti->mti_flags |= LDD_F_PARAM;
2760 /* allocate temporary buffer, where class_get_next_param will
2761 make copy of a current parameter */
2762 OBD_ALLOC(buf, strlen(mti->mti_params) + 1);
2764 GOTO(out_up, rc = -ENOMEM);
2765 params = mti->mti_params;
2766 while (params != NULL) {
2767 rc = class_get_next_param(¶ms, buf);
2770 /* there is no next parameter, that is
2775 CDEBUG(D_MGS, "remaining string: '%s', param: '%s'\n",
2777 rc = mgs_write_log_param(obd, fsdb, mti, buf);
2782 OBD_FREE(buf, strlen(mti->mti_params) + 1);
2785 cfs_up(&fsdb->fsdb_sem);
2790 /* verify that we can handle the old config logs */
2791 int mgs_upgrade_sv_14(struct obd_device *obd, struct mgs_target_info *mti,
2797 /* Create ost log normally, as servers register. Servers
2798 register with their old uuids (from last_rcvd), so old
2799 (MDT and client) logs should work.
2800 - new MDT won't know about old OSTs, only the ones that have
2801 registered, so we need the old MDT log to get the LOV right
2802 in order for old clients to work.
2803 - Old clients connect to the MDT, not the MGS, for their logs, and
2804 will therefore receive the old client log from the MDT /LOGS dir.
2805 - Old clients can continue to use and connect to old or new OSTs
2806 - New clients will contact the MGS for their log
2809 LCONSOLE_INFO("upgrading server %s from pre-1.6\n", mti->mti_svname);
2810 server_mti_print("upgrade", mti);
2812 if (cfs_test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
2813 LCONSOLE_ERROR_MSG(0x14a, "The old client log %s-client is "
2814 "missing. Was tunefs.lustre successful?\n",
2819 if (fsdb->fsdb_gen == 0) {
2820 /* There were no markers in the client log, meaning we have
2821 not updated the logs for this fs */
2822 CDEBUG(D_MGS, "found old, unupdated client log\n");
2825 if (mti->mti_flags & SVTYPE_MDT) {
2826 if (mgs_log_is_empty(obd, mti->mti_svname)) {
2827 LCONSOLE_ERROR_MSG(0x14b, "The old MDT log %s is "
2828 "missing. Was tunefs.lustre "
2833 /* We're starting with an old uuid. Assume old name for lov
2834 as well since the lov entry already exists in the log. */
2835 CDEBUG(D_MGS, "old mds uuid %s\n", mti->mti_uuid);
2836 if (strncmp(mti->mti_uuid, fsdb->fsdb_mdtlov + 4,
2837 strlen(fsdb->fsdb_mdtlov) - 4) != 0) {
2838 CERROR("old mds uuid %s doesn't match log %s (%s)\n",
2839 mti->mti_uuid, fsdb->fsdb_mdtlov,
2840 fsdb->fsdb_mdtlov + 4);
2845 if (!cfs_test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
2846 LCONSOLE_ERROR_MSG(0x14c, "%s-client is supposedly an old "
2847 "log, but no old LOV or MDT was found. "
2848 "Consider updating the configuration with"
2849 " --writeconf.\n", mti->mti_fsname);
2854 /* end COMPAT_146 */
2856 int mgs_erase_log(struct obd_device *obd, char *name)
2858 struct lvfs_run_ctxt saved;
2859 struct llog_ctxt *ctxt;
2860 struct llog_handle *llh;
2863 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
2864 LASSERT(ctxt != NULL);
2866 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
2867 rc = llog_create(ctxt, &llh, NULL, name);
2869 llog_init_handle(llh, LLOG_F_IS_PLAIN, NULL);
2870 rc = llog_destroy(llh);
2871 llog_free_handle(llh);
2873 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
2874 llog_ctxt_put(ctxt);
2877 CERROR("failed to clear log %s: %d\n", name, rc);
2882 /* erase all logs for the given fs */
2883 int mgs_erase_logs(struct obd_device *obd, char *fsname)
2885 struct mgs_obd *mgs = &obd->u.mgs;
2886 static struct fs_db *fsdb;
2887 cfs_list_t dentry_list;
2888 struct l_linux_dirent *dirent, *n;
2889 int rc, len = strlen(fsname);
2893 /* Find all the logs in the CONFIGS directory */
2894 rc = class_dentry_readdir(obd, mgs->mgs_configs_dir,
2895 mgs->mgs_vfsmnt, &dentry_list);
2897 CERROR("Can't read %s dir\n", MOUNT_CONFIGS_DIR);
2901 cfs_down(&mgs->mgs_sem);
2903 /* Delete the fs db */
2904 fsdb = mgs_find_fsdb(obd, fsname);
2906 mgs_free_fsdb(obd, fsdb);
2908 cfs_list_for_each_entry_safe(dirent, n, &dentry_list, lld_list) {
2909 cfs_list_del(&dirent->lld_list);
2910 suffix = strrchr(dirent->lld_name, '-');
2911 if (suffix != NULL) {
2912 if ((len == suffix - dirent->lld_name) &&
2913 (strncmp(fsname, dirent->lld_name, len) == 0)) {
2914 CDEBUG(D_MGS, "Removing log %s\n",
2916 mgs_erase_log(obd, dirent->lld_name);
2919 OBD_FREE(dirent, sizeof(*dirent));
2922 cfs_up(&mgs->mgs_sem);
2927 /* from llog_swab */
2928 static void print_lustre_cfg(struct lustre_cfg *lcfg)
2933 CDEBUG(D_MGS, "lustre_cfg: %p\n", lcfg);
2934 CDEBUG(D_MGS, "\tlcfg->lcfg_version: %#x\n", lcfg->lcfg_version);
2936 CDEBUG(D_MGS, "\tlcfg->lcfg_command: %#x\n", lcfg->lcfg_command);
2937 CDEBUG(D_MGS, "\tlcfg->lcfg_num: %#x\n", lcfg->lcfg_num);
2938 CDEBUG(D_MGS, "\tlcfg->lcfg_flags: %#x\n", lcfg->lcfg_flags);
2939 CDEBUG(D_MGS, "\tlcfg->lcfg_nid: %s\n", libcfs_nid2str(lcfg->lcfg_nid));
2941 CDEBUG(D_MGS, "\tlcfg->lcfg_bufcount: %d\n", lcfg->lcfg_bufcount);
2942 if (lcfg->lcfg_bufcount < LUSTRE_CFG_MAX_BUFCOUNT)
2943 for (i = 0; i < lcfg->lcfg_bufcount; i++) {
2944 CDEBUG(D_MGS, "\tlcfg->lcfg_buflens[%d]: %d %s\n",
2945 i, lcfg->lcfg_buflens[i],
2946 lustre_cfg_string(lcfg, i));
2951 /* Set a permanent (config log) param for a target or fs
2952 * \param lcfg buf0 may contain the device (testfs-MDT0000) name
2953 * buf1 contains the single parameter
2955 int mgs_setparam(struct obd_device *obd, struct lustre_cfg *lcfg, char *fsname)
2958 struct mgs_target_info *mti;
2959 char *devname, *param;
2962 int rc = 0, type = 0;
2965 print_lustre_cfg(lcfg);
2967 param = lustre_cfg_string(lcfg, 1);
2968 /* format is lustre-OST0000.osc.max_dirty_mb=32 */
2969 ptr = strchr(param, '.');
2971 LCONSOLE_ERROR_MSG(0x14d, "No target specified: %s\n", param);
2977 CDEBUG(D_MGS, "device='%s' param='%s'\n", devname, param);
2979 /* Extract fsname */
2980 memset(fsname, 0, MTI_NAME_MAXLEN);
2981 /* Check to see if we're a particular device */
2982 if (libcfs_str2server(devname, &type, &index, &ptr) == 0) {
2983 /* param related to llite isn't allowed to set by OST or MDT */
2984 if (strncmp(param, PARAM_LLITE, sizeof(PARAM_LLITE)) == 0)
2986 while (*(--ptr) != '-') ; /* I know it has a - */
2987 strncpy(fsname, devname, ptr - devname);
2989 /* assume devname is the fsname */
2990 strncpy(fsname, devname, MTI_NAME_MAXLEN);
2992 fsname[MTI_NAME_MAXLEN - 1] = '\0';
2993 CDEBUG(D_MGS, "setparam fs='%s' device='%s'\n", fsname, devname);
2995 rc = mgs_find_or_make_fsdb(obd, fsname, &fsdb);
2998 if (!cfs_test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags) &&
2999 cfs_test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
3000 LCONSOLE_ERROR("setparam: Unknown filesystem '%s'.\n", fsname);
3001 mgs_free_fsdb(obd, fsdb);
3005 /* Create a fake mti to hold everything */
3008 GOTO(out, rc = -ENOMEM);
3009 strncpy(mti->mti_fsname, fsname, MTI_NAME_MAXLEN);
3010 strncpy(mti->mti_svname, devname, MTI_NAME_MAXLEN);
3011 strncpy(mti->mti_params, param, sizeof(mti->mti_params));
3012 mti->mti_stripe_index = index;
3013 mti->mti_flags = type | LDD_F_PARAM;
3015 cfs_down(&fsdb->fsdb_sem);
3016 rc = mgs_write_log_param(obd, fsdb, mti, mti->mti_params);
3017 cfs_up(&fsdb->fsdb_sem);
3020 * Revoke lock so everyone updates. Should be alright if
3021 * someone was already reading while we were updating the logs,
3022 * so we don't really need to hold the lock while we're
3025 mgs_revoke_lock(obd, fsdb);
3031 static int mgs_write_log_pool(struct obd_device *obd, char *logname,
3032 struct fs_db *fsdb, char *lovname,
3033 enum lcfg_command_type cmd,
3034 char *poolname, char *fsname,
3035 char *ostname, char *comment)
3037 struct llog_handle *llh = NULL;
3040 rc = record_start_log(obd, &llh, logname);
3043 rc = record_marker(obd, llh, fsdb, CM_START, lovname, comment);
3044 record_base(obd, llh, lovname, 0, cmd, poolname, fsname, ostname, 0);
3045 rc = record_marker(obd, llh, fsdb, CM_END, lovname, comment);
3046 rc = record_end_log(obd, &llh);
3051 int mgs_pool_cmd(struct obd_device *obd, enum lcfg_command_type cmd,
3052 char *fsname, char *poolname, char *ostname)
3057 char *label = NULL, *canceled_label = NULL;
3059 struct mgs_target_info *mti = NULL;
3063 rc = mgs_find_or_make_fsdb(obd, fsname, &fsdb);
3065 CERROR("Can't get db for %s\n", fsname);
3068 if (cfs_test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
3069 CERROR("%s is not defined\n", fsname);
3070 mgs_free_fsdb(obd, fsdb);
3074 label_sz = 10 + strlen(fsname) + strlen(poolname);
3076 /* check if ostname match fsname */
3077 if (ostname != NULL) {
3080 ptr = strrchr(ostname, '-');
3081 if ((ptr == NULL) ||
3082 (strncmp(fsname, ostname, ptr-ostname) != 0))
3084 label_sz += strlen(ostname);
3087 OBD_ALLOC(label, label_sz);
3089 GOTO(out, rc = -ENOMEM);
3092 case LCFG_POOL_NEW: {
3094 "new %s.%s", fsname, poolname);
3097 case LCFG_POOL_ADD: {
3099 "add %s.%s.%s", fsname, poolname, ostname);
3102 case LCFG_POOL_REM: {
3103 OBD_ALLOC(canceled_label, label_sz);
3104 if (canceled_label == NULL)
3105 GOTO(out, rc = -ENOMEM);
3107 "rem %s.%s.%s", fsname, poolname, ostname);
3108 sprintf(canceled_label,
3109 "add %s.%s.%s", fsname, poolname, ostname);
3112 case LCFG_POOL_DEL: {
3113 OBD_ALLOC(canceled_label, label_sz);
3114 if (canceled_label == NULL)
3115 GOTO(out, rc = -ENOMEM);
3117 "del %s.%s", fsname, poolname);
3118 sprintf(canceled_label,
3119 "new %s.%s", fsname, poolname);
3127 cfs_down(&fsdb->fsdb_sem);
3129 if (canceled_label != NULL) {
3132 GOTO(out, rc = -ENOMEM);
3135 /* write pool def to all MDT logs */
3136 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3137 if (cfs_test_bit(i, fsdb->fsdb_mdt_index_map)) {
3138 name_create_mdt_and_lov(&logname, &lovname, fsdb, i);
3140 if (canceled_label != NULL) {
3141 strcpy(mti->mti_svname, "lov pool");
3142 mgs_modify(obd, fsdb, mti, logname, lovname,
3143 canceled_label, CM_SKIP);
3146 mgs_write_log_pool(obd, logname, fsdb, lovname,
3147 cmd, fsname, poolname, ostname,
3149 name_destroy(&logname);
3150 name_destroy(&lovname);
3154 name_create(&logname, fsname, "-client");
3155 if (canceled_label != NULL)
3156 mgs_modify(obd, fsdb, mti, logname, fsdb->fsdb_clilov,
3157 canceled_label, CM_SKIP);
3159 mgs_write_log_pool(obd, logname, fsdb, fsdb->fsdb_clilov,
3160 cmd, fsname, poolname, ostname, label);
3161 name_destroy(&logname);
3163 cfs_up(&fsdb->fsdb_sem);
3164 /* request for update */
3165 mgs_revoke_lock(obd, fsdb);
3170 OBD_FREE(label, label_sz);
3172 if (canceled_label != NULL)
3173 OBD_FREE(canceled_label, label_sz);
3182 /******************** unused *********************/
3183 static int mgs_backup_llog(struct obd_device *obd, char* fsname)
3185 struct file *filp, *bak_filp;
3186 struct lvfs_run_ctxt saved;
3187 char *logname, *buf;
3188 loff_t soff = 0 , doff = 0;
3189 int count = 4096, len;
3192 OBD_ALLOC(logname, PATH_MAX);
3193 if (logname == NULL)
3196 OBD_ALLOC(buf, count);
3198 GOTO(out , rc = -ENOMEM);
3200 len = snprintf(logname, PATH_MAX, "%s/%s.bak",
3201 MOUNT_CONFIGS_DIR, fsname);
3203 if (len >= PATH_MAX - 1) {
3204 GOTO(out, -ENAMETOOLONG);
3207 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
3209 bak_filp = l_filp_open(logname, O_RDWR|O_CREAT|O_TRUNC, 0660);
3210 if (IS_ERR(bak_filp)) {
3211 rc = PTR_ERR(bak_filp);
3212 CERROR("backup logfile open %s: %d\n", logname, rc);
3215 sprintf(logname, "%s/%s", MOUNT_CONFIGS_DIR, fsname);
3216 filp = l_filp_open(logname, O_RDONLY, 0);
3219 CERROR("logfile open %s: %d\n", logname, rc);
3223 while ((rc = lustre_fread(filp, buf, count, &soff)) > 0) {
3224 rc = lustre_fwrite(bak_filp, buf, count, &doff);
3228 filp_close(filp, 0);
3230 filp_close(bak_filp, 0);
3232 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
3235 OBD_FREE(buf, count);
3236 OBD_FREE(logname, PATH_MAX);