4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 only,
8 * as published by the Free Software Foundation.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License version 2 for more details (a copy is included
14 * in the LICENSE file that accompanied this code).
16 * You should have received a copy of the GNU General Public License
17 * version 2 along with this program; If not, see
18 * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
20 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
21 * CA 95054 USA or visit www.sun.com if you need additional information or
27 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
28 * Use is subject to license terms.
30 * Copyright (c) 2011, Whamcloud, Inc.
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>
43 #define DEBUG_SUBSYSTEM S_MGS
44 #define D_MGS D_CONFIG
47 #include <linux/module.h>
48 #include <linux/pagemap.h>
54 #include <obd_class.h>
55 #include <lustre_log.h>
57 #include <libcfs/list.h>
58 #include <linux/lvfs.h>
59 #include <lustre_fsfilt.h>
60 #include <lustre_disk.h>
61 #include <lustre_param.h>
62 #include <lustre_sec.h>
63 #include "mgs_internal.h"
65 /********************** Class functions ********************/
67 /* Caller must list_del and OBD_FREE each dentry from the list */
68 int class_dentry_readdir(struct obd_device *obd, struct dentry *dir,
69 struct vfsmount *inmnt,
70 cfs_list_t *dentry_list){
71 /* see mds_cleanup_pending */
72 struct lvfs_run_ctxt saved;
74 struct dentry *dentry;
79 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
82 GOTO(out_pop, rc = PTR_ERR(dentry));
86 GOTO(out_pop, rc = PTR_ERR(mnt));
89 file = ll_dentry_open(dentry, mnt, O_RDONLY, current_cred());
91 /* dentry_open_it() drops the dentry, mnt refs */
92 GOTO(out_pop, rc = PTR_ERR(file));
94 CFS_INIT_LIST_HEAD(dentry_list);
95 rc = l_readdir(file, dentry_list);
97 /* filp_close->fput() drops the dentry, mnt refs */
100 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
104 /******************** DB functions *********************/
106 static inline int name_create(char **newname, char *prefix, char *suffix)
109 OBD_ALLOC(*newname, strlen(prefix) + strlen(suffix) + 1);
112 sprintf(*newname, "%s%s", prefix, suffix);
116 static inline void name_destroy(char **name)
119 OBD_FREE(*name, strlen(*name) + 1);
123 struct mgs_fsdb_handler_data
129 /* from the (client) config log, figure out:
130 1. which ost's/mdt's are configured (by index)
131 2. what the last config step is
132 3. COMPAT_146 lov name
133 4. COMPAT_146 mdt lov name
134 5. COMPAT_146 mdc name
135 6. COMPAT_18 osc name
137 /* It might be better to have a separate db file, instead of parsing the info
138 out of the client log. This is slow and potentially error-prone. */
139 static int mgs_fsdb_handler(struct llog_handle *llh, struct llog_rec_hdr *rec,
142 struct mgs_fsdb_handler_data *d = (struct mgs_fsdb_handler_data *) data;
143 struct fs_db *fsdb = d->fsdb;
144 int cfg_len = rec->lrh_len;
145 char *cfg_buf = (char*) (rec + 1);
146 struct lustre_cfg *lcfg;
151 if (rec->lrh_type != OBD_CFG_REC) {
152 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
156 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
158 CERROR("Insane cfg\n");
162 lcfg = (struct lustre_cfg *)cfg_buf;
164 CDEBUG(D_INFO, "cmd %x %s %s\n", lcfg->lcfg_command,
165 lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));
167 /* Figure out ost indicies */
168 /* lov_modify_tgts add 0:lov1 1:ost1_UUID 2(index):0 3(gen):1 */
169 if (lcfg->lcfg_command == LCFG_LOV_ADD_OBD ||
170 lcfg->lcfg_command == LCFG_LOV_DEL_OBD) {
171 index = simple_strtoul(lustre_cfg_string(lcfg, 2),
173 CDEBUG(D_MGS, "OST index for %s is %u (%s)\n",
174 lustre_cfg_string(lcfg, 1), index,
175 lustre_cfg_string(lcfg, 2));
176 cfs_set_bit(index, fsdb->fsdb_ost_index_map);
179 /* Figure out mdt indicies */
180 /* attach 0:MDC_uml1_mdsA_MNT_client 1:mdc 2:1d834_MNT_client_03f */
181 if ((lcfg->lcfg_command == LCFG_ATTACH) &&
182 (strcmp(lustre_cfg_string(lcfg, 1), LUSTRE_MDC_NAME) == 0)) {
183 rc = server_name2index(lustre_cfg_string(lcfg, 0),
185 if (rc != LDD_F_SV_TYPE_MDT) {
186 CWARN("Unparsable MDC name %s, assuming index 0\n",
187 lustre_cfg_string(lcfg, 0));
191 CDEBUG(D_MGS, "MDT index is %u\n", index);
192 cfs_set_bit(index, fsdb->fsdb_mdt_index_map);
193 fsdb->fsdb_mdt_count ++;
197 /* figure out the old LOV name. fsdb_gen = 0 means old log */
198 /* #01 L attach 0:lov_mdsA 1:lov 2:cdbe9_lov_mdsA_dc8cf7f3bb */
199 if ((fsdb->fsdb_gen == 0) && (lcfg->lcfg_command == LCFG_ATTACH) &&
200 (strcmp(lustre_cfg_string(lcfg, 1), LUSTRE_LOV_NAME) == 0)) {
201 cfs_set_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags);
202 name_destroy(&fsdb->fsdb_clilov);
203 rc = name_create(&fsdb->fsdb_clilov,
204 lustre_cfg_string(lcfg, 0), "");
207 CDEBUG(D_MGS, "client lov name is %s\n", fsdb->fsdb_clilov);
210 /* figure out the old MDT lov name from the MDT uuid */
211 if ((fsdb->fsdb_gen == 0) && (lcfg->lcfg_command == LCFG_SETUP) &&
212 (strncmp(lustre_cfg_string(lcfg, 0), "MDC_", 4) == 0)) {
214 cfs_set_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags);
215 ptr = strstr(lustre_cfg_string(lcfg, 1), "_UUID");
217 CERROR("Can't parse MDT uuid %s\n",
218 lustre_cfg_string(lcfg, 1));
222 name_destroy(&fsdb->fsdb_mdtlov);
223 rc = name_create(&fsdb->fsdb_mdtlov,
224 "lov_", lustre_cfg_string(lcfg, 1));
227 name_destroy(&fsdb->fsdb_mdc);
228 rc = name_create(&fsdb->fsdb_mdc,
229 lustre_cfg_string(lcfg, 0), "");
232 CDEBUG(D_MGS, "MDT lov name is %s\n", fsdb->fsdb_mdtlov);
237 * compat to 1.8, check osc name used by MDT0 to OSTs, bz18548.
239 if (!cfs_test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags) &&
240 lcfg->lcfg_command == LCFG_ATTACH &&
241 strcmp(lustre_cfg_string(lcfg, 1), LUSTRE_OSC_NAME) == 0) {
242 if (OBD_OCD_VERSION_MAJOR(d->ver) == 1 &&
243 OBD_OCD_VERSION_MINOR(d->ver) <= 8) {
244 CWARN("MDT using 1.8 OSC name scheme\n");
245 cfs_set_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags);
249 if (lcfg->lcfg_command == LCFG_MARKER) {
250 struct cfg_marker *marker;
251 marker = lustre_cfg_buf(lcfg, 1);
253 d->ver = marker->cm_vers;
255 /* Keep track of the latest marker step */
256 fsdb->fsdb_gen = max(fsdb->fsdb_gen, marker->cm_step);
262 /* fsdb->fsdb_mutex is already held in mgs_find_or_make_fsdb*/
263 static int mgs_get_fsdb_from_llog(struct obd_device *obd, struct fs_db *fsdb)
266 struct llog_handle *loghandle;
267 struct lvfs_run_ctxt saved;
268 struct llog_ctxt *ctxt;
269 struct mgs_fsdb_handler_data d = { fsdb, 0 };
273 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
274 LASSERT(ctxt != NULL);
275 name_create(&logname, fsdb->fsdb_name, "-client");
276 cfs_mutex_lock(&fsdb->fsdb_mutex);
277 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
278 rc = llog_create(ctxt, &loghandle, NULL, logname);
282 rc = llog_init_handle(loghandle, LLOG_F_IS_PLAIN, NULL);
286 if (llog_get_size(loghandle) <= 1)
287 cfs_set_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags);
289 rc = llog_process(loghandle, mgs_fsdb_handler, (void *) &d, NULL);
290 CDEBUG(D_INFO, "get_db = %d\n", rc);
292 rc2 = llog_close(loghandle);
296 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
297 cfs_mutex_unlock(&fsdb->fsdb_mutex);
298 name_destroy(&logname);
304 static void mgs_free_fsdb_srpc(struct fs_db *fsdb)
306 struct mgs_tgt_srpc_conf *tgtconf;
308 /* free target-specific rules */
309 while (fsdb->fsdb_srpc_tgt) {
310 tgtconf = fsdb->fsdb_srpc_tgt;
311 fsdb->fsdb_srpc_tgt = tgtconf->mtsc_next;
313 LASSERT(tgtconf->mtsc_tgt);
315 sptlrpc_rule_set_free(&tgtconf->mtsc_rset);
316 OBD_FREE(tgtconf->mtsc_tgt, strlen(tgtconf->mtsc_tgt) + 1);
317 OBD_FREE_PTR(tgtconf);
320 /* free general rules */
321 sptlrpc_rule_set_free(&fsdb->fsdb_srpc_gen);
324 struct fs_db *mgs_find_fsdb(struct obd_device *obd, char *fsname)
326 struct mgs_obd *mgs = &obd->u.mgs;
330 cfs_list_for_each(tmp, &mgs->mgs_fs_db_list) {
331 fsdb = cfs_list_entry(tmp, struct fs_db, fsdb_list);
332 if (strcmp(fsdb->fsdb_name, fsname) == 0)
338 /* caller must hold the mgs->mgs_fs_db_lock */
339 static struct fs_db *mgs_new_fsdb(struct obd_device *obd, char *fsname)
341 struct mgs_obd *mgs = &obd->u.mgs;
346 if (strlen(fsname) >= sizeof(fsdb->fsdb_name)) {
347 CERROR("fsname %s is too long\n", fsname);
355 strcpy(fsdb->fsdb_name, fsname);
356 cfs_mutex_init(&fsdb->fsdb_mutex);
357 cfs_set_bit(FSDB_UDESC, &fsdb->fsdb_flags);
359 if (strcmp(fsname, MGSSELF_NAME) == 0) {
360 cfs_set_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags);
362 OBD_ALLOC(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
363 OBD_ALLOC(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
364 if (!fsdb->fsdb_ost_index_map || !fsdb->fsdb_mdt_index_map) {
365 CERROR("No memory for index maps\n");
369 rc = name_create(&fsdb->fsdb_mdtlov, fsname, "-mdtlov");
372 rc = name_create(&fsdb->fsdb_mdtlmv, fsname, "-mdtlmv");
375 rc = name_create(&fsdb->fsdb_clilov, fsname, "-clilov");
378 rc = name_create(&fsdb->fsdb_clilmv, fsname, "-clilmv");
382 /* initialise data for NID table */
383 mgs_ir_init_fs(obd, fsdb);
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_mutex_lock(&fsdb->fsdb_mutex);
408 lproc_mgs_del_live(obd, fsdb);
409 cfs_list_del(&fsdb->fsdb_list);
411 /* deinitialize fsr */
412 mgs_ir_fini_fs(obd, fsdb);
414 if (fsdb->fsdb_ost_index_map)
415 OBD_FREE(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
416 if (fsdb->fsdb_mdt_index_map)
417 OBD_FREE(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
418 name_destroy(&fsdb->fsdb_clilov);
419 name_destroy(&fsdb->fsdb_clilmv);
420 name_destroy(&fsdb->fsdb_mdtlov);
421 name_destroy(&fsdb->fsdb_mdtlmv);
422 name_destroy(&fsdb->fsdb_mdc);
423 mgs_free_fsdb_srpc(fsdb);
424 cfs_mutex_unlock(&fsdb->fsdb_mutex);
428 int mgs_init_fsdb_list(struct obd_device *obd)
430 struct mgs_obd *mgs = &obd->u.mgs;
431 CFS_INIT_LIST_HEAD(&mgs->mgs_fs_db_list);
435 int mgs_cleanup_fsdb_list(struct obd_device *obd)
437 struct mgs_obd *mgs = &obd->u.mgs;
439 cfs_list_t *tmp, *tmp2;
440 cfs_mutex_lock(&mgs->mgs_mutex);
441 cfs_list_for_each_safe(tmp, tmp2, &mgs->mgs_fs_db_list) {
442 fsdb = cfs_list_entry(tmp, struct fs_db, fsdb_list);
443 mgs_free_fsdb(obd, fsdb);
445 cfs_mutex_unlock(&mgs->mgs_mutex);
449 int mgs_find_or_make_fsdb(struct obd_device *obd, char *name,
452 struct mgs_obd *mgs = &obd->u.mgs;
456 cfs_mutex_lock(&mgs->mgs_mutex);
457 fsdb = mgs_find_fsdb(obd, name);
459 cfs_mutex_unlock(&mgs->mgs_mutex);
464 CDEBUG(D_MGS, "Creating new db\n");
465 fsdb = mgs_new_fsdb(obd, name);
466 cfs_mutex_unlock(&mgs->mgs_mutex);
470 if (!cfs_test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
471 /* populate the db from the client llog */
472 rc = mgs_get_fsdb_from_llog(obd, fsdb);
474 CERROR("Can't get db from client log %d\n", rc);
475 mgs_free_fsdb(obd, fsdb);
480 /* populate srpc rules from params llog */
481 rc = mgs_get_fsdb_srpc_from_llog(obd, fsdb);
483 CERROR("Can't get db from params log %d\n", rc);
484 mgs_free_fsdb(obd, fsdb);
495 -1= empty client log */
496 int mgs_check_index(struct obd_device *obd, struct mgs_target_info *mti)
503 LASSERT(!(mti->mti_flags & LDD_F_NEED_INDEX));
505 rc = mgs_find_or_make_fsdb(obd, mti->mti_fsname, &fsdb);
507 CERROR("Can't get db for %s\n", mti->mti_fsname);
511 if (cfs_test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags))
514 if (mti->mti_flags & LDD_F_SV_TYPE_OST)
515 imap = fsdb->fsdb_ost_index_map;
516 else if (mti->mti_flags & LDD_F_SV_TYPE_MDT)
517 imap = fsdb->fsdb_mdt_index_map;
521 if (cfs_test_bit(mti->mti_stripe_index, imap))
526 static __inline__ int next_index(void *index_map, int map_len)
529 for (i = 0; i < map_len * 8; i++)
530 if (!cfs_test_bit(i, index_map)) {
533 CERROR("max index %d exceeded.\n", i);
538 0 newly marked as in use
540 +EALREADY for update of an old index */
541 static int mgs_set_index(struct obd_device *obd, struct mgs_target_info *mti)
548 rc = mgs_find_or_make_fsdb(obd, mti->mti_fsname, &fsdb);
550 CERROR("Can't get db for %s\n", mti->mti_fsname);
554 if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
555 imap = fsdb->fsdb_ost_index_map;
556 } else if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
557 imap = fsdb->fsdb_mdt_index_map;
558 if (fsdb->fsdb_mdt_count >= MAX_MDT_COUNT) {
559 LCONSOLE_ERROR_MSG(0x13f, "The max mdt count"
560 "is %d\n", (int)MAX_MDT_COUNT);
567 if (mti->mti_flags & LDD_F_NEED_INDEX) {
568 rc = next_index(imap, INDEX_MAP_SIZE);
571 mti->mti_stripe_index = rc;
572 if (mti->mti_flags & LDD_F_SV_TYPE_MDT)
573 fsdb->fsdb_mdt_count ++;
576 if (mti->mti_stripe_index >= INDEX_MAP_SIZE * 8) {
577 LCONSOLE_ERROR_MSG(0x13f, "Server %s requested index %d, "
578 "but the max index is %d.\n",
579 mti->mti_svname, mti->mti_stripe_index,
584 if (cfs_test_bit(mti->mti_stripe_index, imap)) {
585 if ((mti->mti_flags & LDD_F_VIRGIN) &&
586 !(mti->mti_flags & LDD_F_WRITECONF)) {
587 LCONSOLE_ERROR_MSG(0x140, "Server %s requested index "
588 "%d, but that index is already in "
589 "use. Use --writeconf to force\n",
591 mti->mti_stripe_index);
594 CDEBUG(D_MGS, "Server %s updating index %d\n",
595 mti->mti_svname, mti->mti_stripe_index);
600 cfs_set_bit(mti->mti_stripe_index, imap);
601 cfs_clear_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags);
602 server_make_name(mti->mti_flags & ~LDD_F_VIRGIN, mti->mti_stripe_index,
603 mti->mti_fsname, mti->mti_svname);
605 CDEBUG(D_MGS, "Set index for %s to %d\n", mti->mti_svname,
606 mti->mti_stripe_index);
611 struct mgs_modify_lookup {
612 struct cfg_marker mml_marker;
616 static int mgs_modify_handler(struct llog_handle *llh, struct llog_rec_hdr *rec,
619 struct mgs_modify_lookup *mml = (struct mgs_modify_lookup *)data;
620 struct cfg_marker *marker;
621 struct lustre_cfg *lcfg = (struct lustre_cfg *)(rec + 1);
622 int cfg_len = rec->lrh_len - sizeof(struct llog_rec_hdr) -
623 sizeof(struct llog_rec_tail);
627 if (rec->lrh_type != OBD_CFG_REC) {
628 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
632 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
634 CERROR("Insane cfg\n");
638 /* We only care about markers */
639 if (lcfg->lcfg_command != LCFG_MARKER)
642 marker = lustre_cfg_buf(lcfg, 1);
643 if ((strcmp(mml->mml_marker.cm_comment, marker->cm_comment) == 0) &&
644 (strcmp(mml->mml_marker.cm_tgtname, marker->cm_tgtname) == 0) &&
645 !(marker->cm_flags & CM_SKIP)) {
646 /* Found a non-skipped marker match */
647 CDEBUG(D_MGS, "Changing rec %u marker %d %x->%x: %s %s\n",
648 rec->lrh_index, marker->cm_step,
649 marker->cm_flags, mml->mml_marker.cm_flags,
650 marker->cm_tgtname, marker->cm_comment);
651 /* Overwrite the old marker llog entry */
652 marker->cm_flags &= ~CM_EXCLUDE; /* in case we're unexcluding */
653 marker->cm_flags |= mml->mml_marker.cm_flags;
654 marker->cm_canceltime = mml->mml_marker.cm_canceltime;
655 /* Header and tail are added back to lrh_len in
656 llog_lvfs_write_rec */
657 rec->lrh_len = cfg_len;
658 rc = llog_write_rec(llh, rec, NULL, 0, (void *)lcfg,
667 /* Modify an existing config log record (for CM_SKIP or CM_EXCLUDE) */
668 static int mgs_modify(struct obd_device *obd, struct fs_db *fsdb,
669 struct mgs_target_info *mti, char *logname,
670 char *devname, char *comment, int flags)
672 struct llog_handle *loghandle;
673 struct lvfs_run_ctxt saved;
674 struct llog_ctxt *ctxt;
675 struct mgs_modify_lookup *mml;
679 CDEBUG(D_MGS, "modify %s/%s/%s fl=%x\n", logname, devname, comment,
682 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
684 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
685 LASSERT(ctxt != NULL);
686 rc = llog_create(ctxt, &loghandle, NULL, logname);
690 rc = llog_init_handle(loghandle, LLOG_F_IS_PLAIN, NULL);
694 if (llog_get_size(loghandle) <= 1)
695 GOTO(out_close, rc = 0);
699 GOTO(out_close, rc = -ENOMEM);
700 strcpy(mml->mml_marker.cm_comment, comment);
701 strcpy(mml->mml_marker.cm_tgtname, devname);
702 /* Modify mostly means cancel */
703 mml->mml_marker.cm_flags = flags;
704 mml->mml_marker.cm_canceltime = flags ? cfs_time_current_sec() : 0;
705 mml->mml_modified = 0;
706 rc = llog_process(loghandle, mgs_modify_handler, (void *)mml, NULL);
707 if (!rc && !mml->mml_modified)
712 rc2 = llog_close(loghandle);
716 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
717 if (rc && rc != -ENODEV)
718 CERROR("modify %s/%s failed %d\n",
719 mti->mti_svname, comment, rc);
724 /******************** config log recording functions *********************/
726 static int record_lcfg(struct obd_device *obd, struct llog_handle *llh,
727 struct lustre_cfg *lcfg)
729 struct lvfs_run_ctxt saved;
730 struct llog_rec_hdr rec;
736 LASSERT(llh->lgh_ctxt);
738 buflen = lustre_cfg_len(lcfg->lcfg_bufcount,
740 rec.lrh_len = llog_data_len(buflen);
741 rec.lrh_type = OBD_CFG_REC;
743 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
744 /* idx = -1 means append */
745 rc = llog_write_rec(llh, &rec, NULL, 0, (void *)lcfg, -1);
746 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
748 CERROR("failed %d\n", rc);
752 static int record_base(struct obd_device *obd, struct llog_handle *llh,
753 char *cfgname, lnet_nid_t nid, int cmd,
754 char *s1, char *s2, char *s3, char *s4)
756 struct lustre_cfg_bufs bufs;
757 struct lustre_cfg *lcfg;
760 CDEBUG(D_MGS, "lcfg %s %#x %s %s %s %s\n", cfgname,
761 cmd, s1, s2, s3, s4);
763 lustre_cfg_bufs_reset(&bufs, cfgname);
765 lustre_cfg_bufs_set_string(&bufs, 1, s1);
767 lustre_cfg_bufs_set_string(&bufs, 2, s2);
769 lustre_cfg_bufs_set_string(&bufs, 3, s3);
771 lustre_cfg_bufs_set_string(&bufs, 4, s4);
773 lcfg = lustre_cfg_new(cmd, &bufs);
776 lcfg->lcfg_nid = nid;
778 rc = record_lcfg(obd, llh, lcfg);
780 lustre_cfg_free(lcfg);
783 CERROR("error %d: lcfg %s %#x %s %s %s %s\n", rc, cfgname,
784 cmd, s1, s2, s3, s4);
790 static inline int record_add_uuid(struct obd_device *obd,
791 struct llog_handle *llh,
792 uint64_t nid, char *uuid)
794 return record_base(obd,llh,NULL,nid,LCFG_ADD_UUID,uuid,0,0,0);
798 static inline int record_add_conn(struct obd_device *obd,
799 struct llog_handle *llh,
803 return record_base(obd,llh,devname,0,LCFG_ADD_CONN,uuid,0,0,0);
806 static inline int record_attach(struct obd_device *obd, struct llog_handle *llh,
807 char *devname, char *type, char *uuid)
809 return record_base(obd,llh,devname,0,LCFG_ATTACH,type,uuid,0,0);
812 static inline int record_setup(struct obd_device *obd, struct llog_handle *llh,
814 char *s1, char *s2, char *s3, char *s4)
816 return record_base(obd,llh,devname,0,LCFG_SETUP,s1,s2,s3,s4);
819 static int record_lov_setup(struct obd_device *obd, struct llog_handle *llh,
820 char *devname, struct lov_desc *desc)
822 struct lustre_cfg_bufs bufs;
823 struct lustre_cfg *lcfg;
826 lustre_cfg_bufs_reset(&bufs, devname);
827 lustre_cfg_bufs_set(&bufs, 1, desc, sizeof(*desc));
828 lcfg = lustre_cfg_new(LCFG_SETUP, &bufs);
831 rc = record_lcfg(obd, llh, lcfg);
833 lustre_cfg_free(lcfg);
837 static int record_lmv_setup(struct obd_device *obd, struct llog_handle *llh,
838 char *devname, struct lmv_desc *desc)
840 struct lustre_cfg_bufs bufs;
841 struct lustre_cfg *lcfg;
844 lustre_cfg_bufs_reset(&bufs, devname);
845 lustre_cfg_bufs_set(&bufs, 1, desc, sizeof(*desc));
846 lcfg = lustre_cfg_new(LCFG_SETUP, &bufs);
848 rc = record_lcfg(obd, llh, lcfg);
850 lustre_cfg_free(lcfg);
854 static inline int record_mdc_add(struct obd_device *obd,
855 struct llog_handle *llh,
856 char *logname, char *mdcuuid,
857 char *mdtuuid, char *index,
860 return record_base(obd,llh,logname,0,LCFG_ADD_MDC,
861 mdtuuid,index,gen,mdcuuid);
864 static inline int record_lov_add(struct obd_device *obd,
865 struct llog_handle *llh,
866 char *lov_name, char *ost_uuid,
867 char *index, char *gen)
869 return record_base(obd,llh,lov_name,0,LCFG_LOV_ADD_OBD,
870 ost_uuid,index,gen,0);
873 static inline int record_mount_opt(struct obd_device *obd,
874 struct llog_handle *llh,
875 char *profile, char *lov_name,
878 return record_base(obd,llh,NULL,0,LCFG_MOUNTOPT,
879 profile,lov_name,mdc_name,0);
882 static int record_marker(struct obd_device *obd, struct llog_handle *llh,
883 struct fs_db *fsdb, __u32 flags,
884 char *tgtname, char *comment)
886 struct cfg_marker marker;
887 struct lustre_cfg_bufs bufs;
888 struct lustre_cfg *lcfg;
891 if (flags & CM_START)
893 marker.cm_step = fsdb->fsdb_gen;
894 marker.cm_flags = flags;
895 marker.cm_vers = LUSTRE_VERSION_CODE;
896 strncpy(marker.cm_tgtname, tgtname, sizeof(marker.cm_tgtname));
897 strncpy(marker.cm_comment, comment, sizeof(marker.cm_comment));
898 marker.cm_createtime = cfs_time_current_sec();
899 marker.cm_canceltime = 0;
900 lustre_cfg_bufs_reset(&bufs, NULL);
901 lustre_cfg_bufs_set(&bufs, 1, &marker, sizeof(marker));
902 lcfg = lustre_cfg_new(LCFG_MARKER, &bufs);
905 rc = record_lcfg(obd, llh, lcfg);
907 lustre_cfg_free(lcfg);
911 static int record_start_log(struct obd_device *obd,
912 struct llog_handle **llh, char *name)
914 static struct obd_uuid cfg_uuid = { .uuid = "config_uuid" };
915 struct lvfs_run_ctxt saved;
916 struct llog_ctxt *ctxt;
920 GOTO(out, rc = -EBUSY);
922 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
924 GOTO(out, rc = -ENODEV);
926 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
927 rc = llog_create(ctxt, llh, NULL, name);
929 llog_init_handle(*llh, LLOG_F_IS_PLAIN, &cfg_uuid);
933 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
938 CERROR("Can't start log %s: %d\n", name, rc);
943 static int record_end_log(struct obd_device *obd, struct llog_handle **llh)
945 struct lvfs_run_ctxt saved;
948 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
950 rc = llog_close(*llh);
953 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
957 static int mgs_log_is_empty(struct obd_device *obd, char *name)
959 struct lvfs_run_ctxt saved;
960 struct llog_handle *llh;
961 struct llog_ctxt *ctxt;
964 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
965 LASSERT(ctxt != NULL);
966 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
967 rc = llog_create(ctxt, &llh, NULL, name);
969 llog_init_handle(llh, LLOG_F_IS_PLAIN, NULL);
970 rc = llog_get_size(llh);
973 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
975 /* header is record 1 */
979 /******************** config "macros" *********************/
981 /* write an lcfg directly into a log (with markers) */
982 static int mgs_write_log_direct(struct obd_device *obd, struct fs_db *fsdb,
983 char *logname, struct lustre_cfg *lcfg,
984 char *devname, char *comment)
986 struct llog_handle *llh = NULL;
993 rc = record_start_log(obd, &llh, logname);
997 /* FIXME These should be a single journal transaction */
998 rc = record_marker(obd, llh, fsdb, CM_START, devname, comment);
1000 rc = record_lcfg(obd, llh, lcfg);
1002 rc = record_marker(obd, llh, fsdb, CM_END, devname, comment);
1003 rc = record_end_log(obd, &llh);
1008 /* write the lcfg in all logs for the given fs */
1009 int mgs_write_log_direct_all(struct obd_device *obd, struct fs_db *fsdb,
1010 struct mgs_target_info *mti,
1011 struct lustre_cfg *lcfg,
1012 char *devname, char *comment)
1014 struct mgs_obd *mgs = &obd->u.mgs;
1015 cfs_list_t dentry_list;
1016 struct l_linux_dirent *dirent, *n;
1017 char *fsname = mti->mti_fsname;
1019 int rc = 0, len = strlen(fsname);
1022 /* We need to set params for any future logs
1023 as well. FIXME Append this file to every new log.
1024 Actually, we should store as params (text), not llogs. Or
1026 name_create(&logname, fsname, "-params");
1027 if (mgs_log_is_empty(obd, logname)) {
1028 struct llog_handle *llh = NULL;
1029 rc = record_start_log(obd, &llh, logname);
1030 record_end_log(obd, &llh);
1032 name_destroy(&logname);
1036 /* Find all the logs in the CONFIGS directory */
1037 rc = class_dentry_readdir(obd, mgs->mgs_configs_dir,
1038 mgs->mgs_vfsmnt, &dentry_list);
1040 CERROR("Can't read %s dir\n", MOUNT_CONFIGS_DIR);
1044 /* Could use fsdb index maps instead of directory listing */
1045 cfs_list_for_each_entry_safe(dirent, n, &dentry_list, lld_list) {
1046 cfs_list_del(&dirent->lld_list);
1047 /* don't write to sptlrpc rule log */
1048 if (strncmp(fsname, dirent->lld_name, len) == 0 &&
1049 strstr(dirent->lld_name, "-sptlrpc") == NULL) {
1050 CDEBUG(D_MGS, "Changing log %s\n", dirent->lld_name);
1051 /* Erase any old settings of this same parameter */
1052 mgs_modify(obd, fsdb, mti, dirent->lld_name, devname,
1054 /* Write the new one */
1056 rc = mgs_write_log_direct(obd, fsdb,
1061 CERROR("err %d writing log %s\n", rc,
1065 OBD_FREE(dirent, sizeof(*dirent));
1073 struct mgs_target_info *comp_tmti;
1074 struct mgs_target_info *comp_mti;
1075 struct fs_db *comp_fsdb;
1076 struct obd_device *comp_obd;
1079 static int mgs_write_log_mdc_to_mdt(struct obd_device *, struct fs_db *,
1080 struct mgs_target_info *, char *);
1081 static int mgs_write_log_osc_to_lov(struct obd_device *obd, struct fs_db *fsdb,
1082 struct mgs_target_info *mti,
1083 char *logname, char *suffix, char *lovname,
1084 enum lustre_sec_part sec_part, int flags);
1085 static void name_create_mdt_and_lov(char **logname, char **lovname,
1086 struct fs_db *fsdb, int i);
1088 static int mgs_steal_llog_handler(struct llog_handle *llh,
1089 struct llog_rec_hdr *rec,
1092 struct obd_device * obd;
1093 struct mgs_target_info *mti, *tmti;
1095 int cfg_len = rec->lrh_len;
1096 char *cfg_buf = (char*) (rec + 1);
1097 struct lustre_cfg *lcfg;
1099 struct llog_handle *mdt_llh = NULL;
1100 static int got_an_osc_or_mdc = 0;
1101 /* 0: not found any osc/mdc;
1105 static int last_step = -1;
1109 mti = ((struct temp_comp*)data)->comp_mti;
1110 tmti = ((struct temp_comp*)data)->comp_tmti;
1111 fsdb = ((struct temp_comp*)data)->comp_fsdb;
1112 obd = ((struct temp_comp*)data)->comp_obd;
1114 if (rec->lrh_type != OBD_CFG_REC) {
1115 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
1119 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
1121 CERROR("Insane cfg\n");
1125 lcfg = (struct lustre_cfg *)cfg_buf;
1127 if (lcfg->lcfg_command == LCFG_MARKER) {
1128 struct cfg_marker *marker;
1129 marker = lustre_cfg_buf(lcfg, 1);
1130 if (!strncmp(marker->cm_comment,"add osc",7) &&
1131 (marker->cm_flags & CM_START)){
1132 got_an_osc_or_mdc = 1;
1133 strncpy(tmti->mti_svname, marker->cm_tgtname,
1134 sizeof(tmti->mti_svname));
1135 rc = record_start_log(obd, &mdt_llh, mti->mti_svname);
1136 rc = record_marker(obd, mdt_llh, fsdb, CM_START,
1137 mti->mti_svname,"add osc(copied)");
1138 rc = record_end_log(obd, &mdt_llh);
1139 last_step = marker->cm_step;
1142 if (!strncmp(marker->cm_comment,"add osc",7) &&
1143 (marker->cm_flags & CM_END)){
1144 LASSERT(last_step == marker->cm_step);
1146 got_an_osc_or_mdc = 0;
1147 rc = record_start_log(obd, &mdt_llh, mti->mti_svname);
1148 rc = record_marker(obd, mdt_llh, fsdb, CM_END,
1149 mti->mti_svname,"add osc(copied)");
1150 rc = record_end_log(obd, &mdt_llh);
1153 if (!strncmp(marker->cm_comment,"add mdc",7) &&
1154 (marker->cm_flags & CM_START)){
1155 got_an_osc_or_mdc = 2;
1156 last_step = marker->cm_step;
1157 memcpy(tmti->mti_svname, marker->cm_tgtname,
1158 strlen(marker->cm_tgtname));
1162 if (!strncmp(marker->cm_comment,"add mdc",7) &&
1163 (marker->cm_flags & CM_END)){
1164 LASSERT(last_step == marker->cm_step);
1166 got_an_osc_or_mdc = 0;
1171 if (got_an_osc_or_mdc == 0 || last_step < 0)
1174 if (lcfg->lcfg_command == LCFG_ADD_UUID) {
1176 nodenid = lcfg->lcfg_nid;
1178 tmti->mti_nids[tmti->mti_nid_count] = nodenid;
1179 tmti->mti_nid_count++;
1184 if (lcfg->lcfg_command == LCFG_SETUP) {
1187 target = lustre_cfg_string(lcfg, 1);
1188 memcpy(tmti->mti_uuid, target, strlen(target));
1192 /* ignore client side sptlrpc_conf_log */
1193 if (lcfg->lcfg_command == LCFG_SPTLRPC_CONF)
1196 if (lcfg->lcfg_command == LCFG_ADD_MDC) {
1199 if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1)
1202 memcpy(tmti->mti_fsname, mti->mti_fsname,
1203 strlen(mti->mti_fsname));
1204 tmti->mti_stripe_index = index;
1206 mgs_write_log_mdc_to_mdt(obd, fsdb, tmti, mti->mti_svname);
1207 memset(tmti, 0, sizeof(*tmti));
1211 if (lcfg->lcfg_command == LCFG_LOV_ADD_OBD) {
1214 char *logname, *lovname;
1216 name_create_mdt_and_lov(&logname, &lovname, fsdb,
1217 mti->mti_stripe_index);
1218 sprintf(mdt_index, "-MDT%04x", mti->mti_stripe_index);
1220 if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1) {
1221 name_destroy(&logname);
1222 name_destroy(&lovname);
1226 tmti->mti_stripe_index = index;
1227 mgs_write_log_osc_to_lov(obd, fsdb, tmti, logname,
1230 name_destroy(&logname);
1231 name_destroy(&lovname);
1237 /* fsdb->fsdb_mutex is already held in mgs_write_log_target*/
1238 /* stealed from mgs_get_fsdb_from_llog*/
1239 static int mgs_steal_llog_for_mdt_from_client(struct obd_device *obd,
1241 struct temp_comp* comp)
1243 struct llog_handle *loghandle;
1244 struct lvfs_run_ctxt saved;
1245 struct mgs_target_info *tmti;
1246 struct llog_ctxt *ctxt;
1250 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
1251 LASSERT(ctxt != NULL);
1253 OBD_ALLOC_PTR(tmti);
1257 comp->comp_tmti = tmti;
1258 comp->comp_obd = obd;
1260 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
1262 rc = llog_create(ctxt, &loghandle, NULL, client_name);
1266 rc = llog_init_handle(loghandle, LLOG_F_IS_PLAIN, NULL);
1268 GOTO(out_close, rc);
1270 rc = llog_process(loghandle, mgs_steal_llog_handler, (void *)comp, NULL);
1271 CDEBUG(D_MGS, "steal llog re = %d\n", rc);
1273 rc2 = llog_close(loghandle);
1277 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
1279 llog_ctxt_put(ctxt);
1283 /* lmv is the second thing for client logs */
1284 /* copied from mgs_write_log_lov. Please refer to that. */
1285 static int mgs_write_log_lmv(struct obd_device *obd, struct fs_db *fsdb,
1286 struct mgs_target_info *mti,
1287 char *logname, char *lmvname)
1289 struct llog_handle *llh = NULL;
1290 struct lmv_desc *lmvdesc;
1295 CDEBUG(D_MGS, "Writing lmv(%s) log for %s\n", lmvname,logname);
1297 OBD_ALLOC_PTR(lmvdesc);
1298 if (lmvdesc == NULL)
1300 lmvdesc->ld_active_tgt_count = 0;
1301 lmvdesc->ld_tgt_count = 0;
1302 sprintf((char*)lmvdesc->ld_uuid.uuid, "%s_UUID", lmvname);
1303 uuid = (char *)lmvdesc->ld_uuid.uuid;
1305 rc = record_start_log(obd, &llh, logname);
1306 rc = record_marker(obd, llh, fsdb, CM_START, lmvname, "lmv setup");
1307 rc = record_attach(obd, llh, lmvname, "lmv", uuid);
1308 rc = record_lmv_setup(obd, llh, lmvname, lmvdesc);
1309 rc = record_marker(obd, llh, fsdb, CM_END, lmvname, "lmv setup");
1310 rc = record_end_log(obd, &llh);
1312 OBD_FREE_PTR(lmvdesc);
1316 /* lov is the first thing in the mdt and client logs */
1317 static int mgs_write_log_lov(struct obd_device *obd, struct fs_db *fsdb,
1318 struct mgs_target_info *mti,
1319 char *logname, char *lovname)
1321 struct llog_handle *llh = NULL;
1322 struct lov_desc *lovdesc;
1327 CDEBUG(D_MGS, "Writing lov(%s) log for %s\n", lovname, logname);
1330 #01 L attach 0:lov_mdsA 1:lov 2:71ccb_lov_mdsA_19f961a9e1
1331 #02 L lov_setup 0:lov_mdsA 1:(struct lov_desc)
1332 uuid=lov1_UUID, stripe count=1, size=1048576, offset=0, pattern=0
1335 /* FIXME just make lov_setup accept empty desc (put uuid in buf 2) */
1336 OBD_ALLOC_PTR(lovdesc);
1337 if (lovdesc == NULL)
1339 lovdesc->ld_magic = LOV_DESC_MAGIC;
1340 lovdesc->ld_tgt_count = 0;
1341 /* Defaults. Can be changed later by lcfg config_param */
1342 lovdesc->ld_default_stripe_count = 1;
1343 lovdesc->ld_pattern = LOV_PATTERN_RAID0;
1344 lovdesc->ld_default_stripe_size = 1024 * 1024;
1345 lovdesc->ld_default_stripe_offset = -1;
1346 lovdesc->ld_qos_maxage = QOS_DEFAULT_MAXAGE;
1347 sprintf((char*)lovdesc->ld_uuid.uuid, "%s_UUID", lovname);
1348 /* can these be the same? */
1349 uuid = (char *)lovdesc->ld_uuid.uuid;
1351 /* This should always be the first entry in a log.
1352 rc = mgs_clear_log(obd, logname); */
1353 rc = record_start_log(obd, &llh, logname);
1356 /* FIXME these should be a single journal transaction */
1357 rc = record_marker(obd, llh, fsdb, CM_START, lovname, "lov setup");
1358 rc = record_attach(obd, llh, lovname, "lov", uuid);
1359 rc = record_lov_setup(obd, llh, lovname, lovdesc);
1360 rc = record_marker(obd, llh, fsdb, CM_END, lovname, "lov setup");
1361 rc = record_end_log(obd, &llh);
1365 OBD_FREE_PTR(lovdesc);
1369 /* add failnids to open log */
1370 static int mgs_write_log_failnids(struct obd_device *obd,
1371 struct mgs_target_info *mti,
1372 struct llog_handle *llh,
1375 char *failnodeuuid = NULL;
1376 char *ptr = mti->mti_params;
1381 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) nal=90 0: 1:uml1_UUID
1382 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
1383 #05 L setup 0:OSC_uml1_ost1_mdsA 1:ost1_UUID 2:uml1_UUID
1384 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) nal=90 0: 1:uml2_UUID
1385 #0x L add_uuid nid=2@elan(0x1000000000002) nal=90 0: 1:uml2_UUID
1386 #07 L add_conn 0:OSC_uml1_ost1_mdsA 1:uml2_UUID
1389 /* Pull failnid info out of params string */
1390 while (class_find_param(ptr, PARAM_FAILNODE, &ptr) == 0) {
1391 while (class_parse_nid(ptr, &nid, &ptr) == 0) {
1392 if (failnodeuuid == NULL) {
1393 /* We don't know the failover node name,
1394 so just use the first nid as the uuid */
1395 rc = name_create(&failnodeuuid,
1396 libcfs_nid2str(nid), "");
1400 CDEBUG(D_MGS, "add nid %s for failover uuid %s, "
1401 "client %s\n", libcfs_nid2str(nid),
1402 failnodeuuid, cliname);
1403 rc = record_add_uuid(obd, llh, nid, failnodeuuid);
1406 rc = record_add_conn(obd, llh, cliname, failnodeuuid);
1407 name_destroy(&failnodeuuid);
1408 failnodeuuid = NULL;
1415 static int mgs_write_log_mdc_to_lmv(struct obd_device *obd, struct fs_db *fsdb,
1416 struct mgs_target_info *mti,
1417 char *logname, char *lmvname)
1419 struct llog_handle *llh = NULL;
1420 char *mdcname, *nodeuuid, *mdcuuid, *lmvuuid;
1425 if (mgs_log_is_empty(obd, logname)) {
1426 CERROR("log is empty! Logical error\n");
1430 CDEBUG(D_MGS, "adding mdc for %s to log %s:lmv(%s)\n",
1431 mti->mti_svname, logname, lmvname);
1433 name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
1434 name_create(&mdcname, mti->mti_svname, "-mdc");
1435 name_create(&mdcuuid, mdcname, "_UUID");
1436 name_create(&lmvuuid, lmvname, "_UUID");
1438 rc = record_start_log(obd, &llh, logname);
1439 rc = record_marker(obd, llh, fsdb, CM_START, mti->mti_svname,
1442 for (i = 0; i < mti->mti_nid_count; i++) {
1443 CDEBUG(D_MGS, "add nid %s for mdt\n",
1444 libcfs_nid2str(mti->mti_nids[i]));
1446 rc = record_add_uuid(obd, llh, mti->mti_nids[i], nodeuuid);
1449 rc = record_attach(obd, llh, mdcname, LUSTRE_MDC_NAME, lmvuuid);
1450 rc = record_setup(obd, llh, mdcname, mti->mti_uuid, nodeuuid, 0, 0);
1451 rc = mgs_write_log_failnids(obd, mti, llh, mdcname);
1452 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
1453 rc = record_mdc_add(obd, llh, lmvname, mdcuuid, mti->mti_uuid,
1455 rc = record_marker(obd, llh, fsdb, CM_END, mti->mti_svname,
1457 rc = record_end_log(obd, &llh);
1459 name_destroy(&lmvuuid);
1460 name_destroy(&mdcuuid);
1461 name_destroy(&mdcname);
1462 name_destroy(&nodeuuid);
1466 /* add new mdc to already existent MDS */
1467 static int mgs_write_log_mdc_to_mdt(struct obd_device *obd, struct fs_db *fsdb,
1468 struct mgs_target_info *mti, char *logname)
1470 struct llog_handle *llh = NULL;
1471 char *nodeuuid, *mdcname, *mdcuuid, *mdtuuid;
1472 int idx = mti->mti_stripe_index;
1477 if (mgs_log_is_empty(obd, logname)) {
1478 CERROR("log is empty! Logical error\n");
1482 CDEBUG(D_MGS, "adding mdc index %d to %s\n", idx, logname);
1484 name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
1485 snprintf(index, sizeof(index), "-mdc%04x", idx);
1486 name_create(&mdcname, logname, index);
1487 name_create(&mdcuuid, mdcname, "_UUID");
1488 name_create(&mdtuuid, logname, "_UUID");
1490 rc = record_start_log(obd, &llh, logname);
1491 rc = record_marker(obd, llh, fsdb, CM_START, mti->mti_svname, "add mdc");
1492 for (i = 0; i < mti->mti_nid_count; i++) {
1493 CDEBUG(D_MGS, "add nid %s for mdt\n",
1494 libcfs_nid2str(mti->mti_nids[i]));
1495 rc = record_add_uuid(obd, llh, mti->mti_nids[i], nodeuuid);
1497 rc = record_attach(obd, llh, mdcname, LUSTRE_MDC_NAME, mdcuuid);
1498 rc = record_setup(obd, llh, mdcname, mti->mti_uuid, nodeuuid, 0, 0);
1499 rc = mgs_write_log_failnids(obd, mti, llh, mdcname);
1500 snprintf(index, sizeof(index), "%d", idx);
1502 rc = record_mdc_add(obd, llh, logname, mdcuuid, mti->mti_uuid,
1504 rc = record_marker(obd, llh, fsdb, CM_END, mti->mti_svname, "add mdc");
1505 rc = record_end_log(obd, &llh);
1507 name_destroy(&mdcuuid);
1508 name_destroy(&mdcname);
1509 name_destroy(&nodeuuid);
1510 name_destroy(&mdtuuid);
1514 static int mgs_write_log_mdt0(struct obd_device *obd, struct fs_db *fsdb,
1515 struct mgs_target_info *mti)
1517 char *log = mti->mti_svname;
1518 struct llog_handle *llh = NULL;
1519 char *uuid, *lovname;
1521 char *ptr = mti->mti_params;
1522 int rc = 0, failout = 0;
1525 OBD_ALLOC(uuid, sizeof(struct obd_uuid));
1529 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
1530 failout = (strncmp(ptr, "failout", 7) == 0);
1532 name_create(&lovname, log, "-mdtlov");
1533 if (mgs_log_is_empty(obd, log))
1534 rc = mgs_write_log_lov(obd, fsdb, mti, log, lovname);
1536 sprintf(uuid, "%s_UUID", log);
1537 sprintf(mdt_index, "%d", mti->mti_stripe_index);
1539 /* add MDT itself */
1540 rc = record_start_log(obd, &llh, log);
1544 /* FIXME this whole fn should be a single journal transaction */
1545 rc = record_marker(obd, llh, fsdb, CM_START, log, "add mdt");
1546 rc = record_attach(obd, llh, log, LUSTRE_MDT_NAME, uuid);
1547 rc = record_mount_opt(obd, llh, log, lovname, NULL);
1548 rc = record_setup(obd, llh, log, uuid, mdt_index, lovname,
1549 failout ? "n" : "f");
1550 rc = record_marker(obd, llh, fsdb, CM_END, log, "add mdt");
1551 rc = record_end_log(obd, &llh);
1553 name_destroy(&lovname);
1554 OBD_FREE(uuid, sizeof(struct obd_uuid));
1558 static inline void name_create_mdt(char **logname, char *fsname, int i)
1562 sprintf(mdt_index, "-MDT%04x", i);
1563 name_create(logname, fsname, mdt_index);
1566 static void name_create_mdt_and_lov(char **logname, char **lovname,
1567 struct fs_db *fsdb, int i)
1569 name_create_mdt(logname, fsdb->fsdb_name, i);
1571 if (i == 0 && cfs_test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
1572 name_create(lovname, fsdb->fsdb_name, "-mdtlov");
1574 name_create(lovname, *logname, "-mdtlov");
1577 static inline void name_create_mdt_osc(char **oscname, char *ostname,
1578 struct fs_db *fsdb, int i)
1582 if (i == 0 && cfs_test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
1583 sprintf(suffix, "-osc");
1585 sprintf(suffix, "-osc-MDT%04x", i);
1586 name_create(oscname, ostname, suffix);
1589 /* envelope method for all layers log */
1590 static int mgs_write_log_mdt(struct obd_device *obd, struct fs_db *fsdb,
1591 struct mgs_target_info *mti)
1593 struct llog_handle *llh = NULL;
1595 struct temp_comp comp = { 0 };
1599 CDEBUG(D_MGS, "writing new mdt %s\n", mti->mti_svname);
1603 if (mti->mti_flags & LDD_F_UPGRADE14) {
1604 /* We're starting with an old uuid. Assume old name for lov
1605 as well since the lov entry already exists in the log. */
1606 CDEBUG(D_MGS, "old mds uuid %s\n", mti->mti_uuid);
1607 if (strncmp(mti->mti_uuid, fsdb->fsdb_mdtlov + 4,
1608 strlen(fsdb->fsdb_mdtlov) - 4) != 0) {
1609 CERROR("old mds uuid %s doesn't match log %s (%s)\n",
1610 mti->mti_uuid, fsdb->fsdb_mdtlov,
1611 fsdb->fsdb_mdtlov + 4);
1615 /* end COMPAT_146 */
1617 if (mti->mti_uuid[0] == '\0') {
1618 /* Make up our own uuid */
1619 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
1620 "%s_UUID", mti->mti_svname);
1624 rc = mgs_write_log_mdt0(obd, fsdb, mti);
1626 /* Append the mdt info to the client log */
1627 name_create(&cliname, mti->mti_fsname, "-client");
1629 if (mgs_log_is_empty(obd, cliname)) {
1630 /* Start client log */
1631 rc = mgs_write_log_lov(obd, fsdb, mti, cliname,
1633 rc = mgs_write_log_lmv(obd, fsdb, mti, cliname,
1638 #09 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
1639 #10 L attach 0:MDC_uml1_mdsA_MNT_client 1:mdc 2:1d834_MNT_client_03f
1640 #11 L setup 0:MDC_uml1_mdsA_MNT_client 1:mdsA_UUID 2:uml1_UUID
1641 #12 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
1642 #13 L add_conn 0:MDC_uml1_mdsA_MNT_client 1:uml2_UUID
1643 #14 L mount_option 0: 1:client 2:lov1 3:MDC_uml1_mdsA_MNT_client
1648 if (mti->mti_flags & LDD_F_UPGRADE14) {
1649 rc = record_start_log(obd, &llh, cliname);
1653 rc = record_marker(obd, llh, fsdb, CM_START,
1654 mti->mti_svname,"add mdc");
1656 /* Old client log already has MDC entry, but needs mount opt
1657 for new client name (lustre-client) */
1658 /* FIXME Old MDT log already has an old mount opt
1659 which we should remove (currently handled by
1660 class_del_profiles()) */
1661 rc = record_mount_opt(obd, llh, cliname, fsdb->fsdb_clilov,
1663 /* end COMPAT_146 */
1665 rc = record_marker(obd, llh, fsdb, CM_END,
1666 mti->mti_svname, "add mdc");
1670 /* copy client info about lov/lmv */
1671 comp.comp_mti = mti;
1672 comp.comp_fsdb = fsdb;
1674 rc = mgs_steal_llog_for_mdt_from_client(obd, cliname,
1677 rc = mgs_write_log_mdc_to_lmv(obd, fsdb, mti, cliname,
1680 rc = record_start_log(obd, &llh, cliname);
1684 rc = record_marker(obd, llh, fsdb, CM_START, cliname,
1686 rc = record_mount_opt(obd, llh, cliname, fsdb->fsdb_clilov,
1688 rc = record_marker(obd, llh, fsdb, CM_END, cliname,
1692 rc = record_end_log(obd, &llh);
1694 name_destroy(&cliname);
1696 // for_all_existing_mdt except current one
1697 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
1699 if (i != mti->mti_stripe_index &&
1700 cfs_test_bit(i, fsdb->fsdb_mdt_index_map)) {
1701 name_create_mdt(&mdtname, mti->mti_fsname, i);
1702 rc = mgs_write_log_mdc_to_mdt(obd, fsdb, mti, mdtname);
1703 name_destroy(&mdtname);
1710 /* Add the ost info to the client/mdt lov */
1711 static int mgs_write_log_osc_to_lov(struct obd_device *obd, struct fs_db *fsdb,
1712 struct mgs_target_info *mti,
1713 char *logname, char *suffix, char *lovname,
1714 enum lustre_sec_part sec_part, int flags)
1716 struct llog_handle *llh = NULL;
1717 char *nodeuuid, *oscname, *oscuuid, *lovuuid, *svname;
1722 CDEBUG(D_INFO, "adding osc for %s to log %s\n",
1723 mti->mti_svname, logname);
1725 if (mgs_log_is_empty(obd, logname)) {
1726 CERROR("log is empty! Logical error\n");
1730 name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
1731 name_create(&svname, mti->mti_svname, "-osc");
1732 name_create(&oscname, svname, suffix);
1733 name_create(&oscuuid, oscname, "_UUID");
1734 name_create(&lovuuid, lovname, "_UUID");
1737 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
1739 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
1740 #04 L attach 0:OSC_uml1_ost1_MNT_client 1:osc 2:89070_lov1_a41dff51a
1741 #05 L setup 0:OSC_uml1_ost1_MNT_client 1:ost1_UUID 2:uml1_UUID
1743 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
1744 #07 L add_conn 0:OSC_uml1_ost1_MNT_client 1:uml2_UUID
1745 #08 L lov_modify_tgts add 0:lov1 1:ost1_UUID 2(index):0 3(gen):1
1748 rc = record_start_log(obd, &llh, logname);
1751 /* FIXME these should be a single journal transaction */
1752 rc = record_marker(obd, llh, fsdb, CM_START | flags, mti->mti_svname,
1754 for (i = 0; i < mti->mti_nid_count; i++) {
1755 CDEBUG(D_MGS, "add nid %s\n", libcfs_nid2str(mti->mti_nids[i]));
1756 rc = record_add_uuid(obd, llh, mti->mti_nids[i], nodeuuid);
1758 rc = record_attach(obd, llh, oscname, LUSTRE_OSC_NAME, lovuuid);
1759 rc = record_setup(obd, llh, oscname, mti->mti_uuid, nodeuuid, 0, 0);
1760 rc = mgs_write_log_failnids(obd, mti, llh, oscname);
1761 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
1762 rc = record_lov_add(obd, llh, lovname, mti->mti_uuid, index, "1");
1763 rc = record_marker(obd, llh, fsdb, CM_END | flags, mti->mti_svname,
1765 rc = record_end_log(obd, &llh);
1767 name_destroy(&lovuuid);
1768 name_destroy(&oscuuid);
1769 name_destroy(&oscname);
1770 name_destroy(&svname);
1771 name_destroy(&nodeuuid);
1775 static int mgs_write_log_ost(struct obd_device *obd, struct fs_db *fsdb,
1776 struct mgs_target_info *mti)
1778 struct llog_handle *llh = NULL;
1779 char *logname, *lovname;
1780 char *ptr = mti->mti_params;
1781 int rc, flags = 0, failout = 0, i;
1784 CDEBUG(D_MGS, "writing new ost %s\n", mti->mti_svname);
1786 /* The ost startup log */
1788 /* If the ost log already exists, that means that someone reformatted
1789 the ost and it called target_add again. */
1790 if (!mgs_log_is_empty(obd, mti->mti_svname)) {
1791 LCONSOLE_ERROR_MSG(0x141, "The config log for %s already "
1792 "exists, yet the server claims it never "
1793 "registered. It may have been reformatted, "
1794 "or the index changed. writeconf the MDT to "
1795 "regenerate all logs.\n", mti->mti_svname);
1800 attach obdfilter ost1 ost1_UUID
1801 setup /dev/loop2 ldiskfs f|n errors=remount-ro,user_xattr
1803 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
1804 failout = (strncmp(ptr, "failout", 7) == 0);
1805 rc = record_start_log(obd, &llh, mti->mti_svname);
1808 /* FIXME these should be a single journal transaction */
1809 rc = record_marker(obd, llh, fsdb, CM_START, mti->mti_svname,"add ost");
1810 if (*mti->mti_uuid == '\0')
1811 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
1812 "%s_UUID", mti->mti_svname);
1813 rc = record_attach(obd, llh, mti->mti_svname,
1814 "obdfilter"/*LUSTRE_OST_NAME*/, mti->mti_uuid);
1815 rc = record_setup(obd, llh, mti->mti_svname,
1816 "dev"/*ignored*/, "type"/*ignored*/,
1817 failout ? "n" : "f", 0/*options*/);
1818 rc = record_marker(obd, llh, fsdb, CM_END, mti->mti_svname, "add ost");
1819 rc = record_end_log(obd, &llh);
1821 /* We also have to update the other logs where this osc is part of
1824 if (cfs_test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
1825 /* If we're upgrading, the old mdt log already has our
1826 entry. Let's do a fake one for fun. */
1827 /* Note that we can't add any new failnids, since we don't
1828 know the old osc names. */
1829 flags = CM_SKIP | CM_UPGRADE146;
1831 } else if ((mti->mti_flags & LDD_F_UPDATE) != LDD_F_UPDATE) {
1832 /* If the update flag isn't set, don't update client/mdt
1835 LCONSOLE_WARN("Client log for %s was not updated; writeconf "
1836 "the MDT first to regenerate it.\n",
1840 /* Add ost to all MDT lov defs */
1841 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
1842 if (cfs_test_bit(i, fsdb->fsdb_mdt_index_map)) {
1845 name_create_mdt_and_lov(&logname, &lovname, fsdb, i);
1846 sprintf(mdt_index, "-MDT%04x", i);
1847 mgs_write_log_osc_to_lov(obd, fsdb, mti, logname,
1849 LUSTRE_SP_MDT, flags);
1850 name_destroy(&logname);
1851 name_destroy(&lovname);
1855 /* Append ost info to the client log */
1856 name_create(&logname, mti->mti_fsname, "-client");
1857 if (mgs_log_is_empty(obd, logname)) {
1858 /* Start client log */
1859 rc = mgs_write_log_lov(obd, fsdb, mti, logname,
1861 rc = mgs_write_log_lmv(obd, fsdb, mti, logname,
1864 mgs_write_log_osc_to_lov(obd, fsdb, mti, logname, "",
1865 fsdb->fsdb_clilov, LUSTRE_SP_CLI, flags);
1866 name_destroy(&logname);
1870 static __inline__ int mgs_param_empty(char *ptr)
1874 if ((tmp = strchr(ptr, '=')) && (*(++tmp) == '\0'))
1879 static int mgs_write_log_failnid_internal(struct obd_device *obd,
1881 struct mgs_target_info *mti,
1882 char *logname, char *cliname)
1885 struct llog_handle *llh = NULL;
1887 if (mgs_param_empty(mti->mti_params)) {
1888 /* Remove _all_ failnids */
1889 rc = mgs_modify(obd, fsdb, mti, logname,
1890 mti->mti_svname, "add failnid", CM_SKIP);
1894 /* Otherwise failover nids are additive */
1895 rc = record_start_log(obd, &llh, logname);
1897 /* FIXME this should be a single journal transaction */
1898 rc = record_marker(obd, llh, fsdb, CM_START,
1899 mti->mti_svname, "add failnid");
1900 rc = mgs_write_log_failnids(obd, mti, llh, cliname);
1901 rc = record_marker(obd, llh, fsdb, CM_END,
1902 mti->mti_svname, "add failnid");
1903 rc = record_end_log(obd, &llh);
1910 /* Add additional failnids to an existing log.
1911 The mdc/osc must have been added to logs first */
1912 /* tcp nids must be in dotted-quad ascii -
1913 we can't resolve hostnames from the kernel. */
1914 static int mgs_write_log_add_failnid(struct obd_device *obd, struct fs_db *fsdb,
1915 struct mgs_target_info *mti)
1917 char *logname, *cliname;
1921 /* FIXME we currently can't erase the failnids
1922 * given when a target first registers, since they aren't part of
1923 * an "add uuid" stanza */
1925 /* Verify that we know about this target */
1926 if (mgs_log_is_empty(obd, mti->mti_svname)) {
1927 LCONSOLE_ERROR_MSG(0x142, "The target %s has not registered "
1928 "yet. It must be started before failnids "
1929 "can be added.\n", mti->mti_svname);
1933 /* Create mdc/osc client name (e.g. lustre-OST0001-osc) */
1934 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
1935 name_create(&cliname, mti->mti_svname, "-mdc");
1936 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
1937 name_create(&cliname, mti->mti_svname, "-osc");
1942 /* Add failover nids to the client log */
1943 name_create(&logname, mti->mti_fsname, "-client");
1944 rc = mgs_write_log_failnid_internal(obd, fsdb, mti, logname, cliname);
1945 name_destroy(&logname);
1946 name_destroy(&cliname);
1948 if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
1949 /* Add OST failover nids to the MDT logs as well */
1952 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
1953 if (!cfs_test_bit(i, fsdb->fsdb_mdt_index_map))
1955 name_create_mdt(&logname, mti->mti_fsname, i);
1956 name_create_mdt_osc(&cliname, mti->mti_svname, fsdb, i);
1957 rc = mgs_write_log_failnid_internal(obd, fsdb, mti,
1959 name_destroy(&cliname);
1960 name_destroy(&logname);
1967 static int mgs_wlp_lcfg(struct obd_device *obd, struct fs_db *fsdb,
1968 struct mgs_target_info *mti,
1969 char *logname, struct lustre_cfg_bufs *bufs,
1970 char *tgtname, char *ptr)
1972 char comment[MTI_NAME_MAXLEN];
1974 struct lustre_cfg *lcfg;
1977 /* Erase any old settings of this same parameter */
1978 memcpy(comment, ptr, MTI_NAME_MAXLEN);
1979 comment[MTI_NAME_MAXLEN - 1] = 0;
1980 /* But don't try to match the value. */
1981 if ((tmp = strchr(comment, '=')))
1983 /* FIXME we should skip settings that are the same as old values */
1984 rc = mgs_modify(obd, fsdb, mti, logname, tgtname, comment, CM_SKIP);
1985 del = mgs_param_empty(ptr);
1987 LCONSOLE_INFO("%sing parameter %s.%s in log %s\n", del ? "Disabl" : rc ?
1988 "Sett" : "Modify", tgtname, comment, logname);
1992 lustre_cfg_bufs_reset(bufs, tgtname);
1993 lustre_cfg_bufs_set_string(bufs, 1, ptr);
1994 lcfg = lustre_cfg_new(LCFG_PARAM, bufs);
1997 rc = mgs_write_log_direct(obd, fsdb, logname, lcfg, tgtname, comment);
1998 lustre_cfg_free(lcfg);
2002 /* write global variable settings into log */
2003 static int mgs_write_log_sys(struct obd_device *obd, struct fs_db *fsdb,
2004 struct mgs_target_info *mti, char *sys, char *ptr)
2006 struct lustre_cfg_bufs bufs;
2007 struct lustre_cfg *lcfg;
2009 int rc, cmd, convert = 1;
2011 if (class_match_param(ptr, PARAM_TIMEOUT, &tmp) == 0) {
2012 cmd = LCFG_SET_TIMEOUT;
2013 } else if (class_match_param(ptr, PARAM_LDLM_TIMEOUT, &tmp) == 0) {
2014 cmd = LCFG_SET_LDLM_TIMEOUT;
2015 /* Check for known params here so we can return error to lctl */
2016 } else if ((class_match_param(ptr, PARAM_AT_MIN, &tmp) == 0) ||
2017 (class_match_param(ptr, PARAM_AT_MAX, &tmp) == 0) ||
2018 (class_match_param(ptr, PARAM_AT_EXTRA, &tmp) == 0) ||
2019 (class_match_param(ptr, PARAM_AT_EARLY_MARGIN, &tmp) == 0) ||
2020 (class_match_param(ptr, PARAM_AT_HISTORY, &tmp) == 0)) {
2022 } else if (class_match_param(ptr, PARAM_JOBID_VAR, &tmp) == 0) {
2023 convert = 0; /* Don't convert string value to integer */
2029 if (mgs_param_empty(ptr))
2030 CDEBUG(D_MGS, "global '%s' removed\n", sys);
2032 CDEBUG(D_MGS, "global '%s' val=%s\n", sys, tmp);
2034 lustre_cfg_bufs_reset(&bufs, NULL);
2035 lustre_cfg_bufs_set_string(&bufs, 1, sys);
2036 if (!convert && *tmp != '\0')
2037 lustre_cfg_bufs_set_string(&bufs, 2, tmp);
2038 lcfg = lustre_cfg_new(cmd, &bufs);
2039 lcfg->lcfg_num = convert ? simple_strtoul(tmp, NULL, 0) : 0;
2040 /* truncate the comment to the parameter name */
2044 /* modify all servers and clients */
2045 rc = mgs_write_log_direct_all(obd, fsdb, mti,
2046 *tmp == '\0' ? NULL : lcfg,
2047 mti->mti_fsname, sys);
2048 if (rc == 0 && *tmp != '\0') {
2050 case LCFG_SET_TIMEOUT:
2051 if (!obd_timeout_set || lcfg->lcfg_num > obd_timeout)
2052 class_process_config(lcfg);
2054 case LCFG_SET_LDLM_TIMEOUT:
2055 if (!ldlm_timeout_set || lcfg->lcfg_num > ldlm_timeout)
2056 class_process_config(lcfg);
2063 lustre_cfg_free(lcfg);
2067 static int mgs_srpc_set_param_disk(struct obd_device *obd,
2069 struct mgs_target_info *mti,
2072 struct llog_handle *llh = NULL;
2074 char *comment, *ptr;
2075 struct lustre_cfg_bufs bufs;
2076 struct lustre_cfg *lcfg;
2081 ptr = strchr(param, '=');
2085 OBD_ALLOC(comment, len + 1);
2086 if (comment == NULL)
2088 strncpy(comment, param, len);
2089 comment[len] = '\0';
2092 lustre_cfg_bufs_reset(&bufs, mti->mti_svname);
2093 lustre_cfg_bufs_set_string(&bufs, 1, param);
2094 lcfg = lustre_cfg_new(LCFG_SPTLRPC_CONF, &bufs);
2096 GOTO(out_comment, rc = -ENOMEM);
2098 /* construct log name */
2099 rc = name_create(&logname, mti->mti_fsname, "-sptlrpc");
2103 if (mgs_log_is_empty(obd, logname)) {
2104 rc = record_start_log(obd, &llh, logname);
2105 record_end_log(obd, &llh);
2110 /* obsolete old one */
2111 mgs_modify(obd, fsdb, mti, logname, mti->mti_svname, comment, CM_SKIP);
2113 /* write the new one */
2114 rc = mgs_write_log_direct(obd, fsdb, logname, lcfg,
2115 mti->mti_svname, comment);
2117 CERROR("err %d writing log %s\n", rc, logname);
2120 name_destroy(&logname);
2122 lustre_cfg_free(lcfg);
2124 OBD_FREE(comment, len + 1);
2128 static int mgs_srpc_set_param_udesc_mem(struct fs_db *fsdb,
2133 /* disable the adjustable udesc parameter for now, i.e. use default
2134 * setting that client always ship udesc to MDT if possible. to enable
2135 * it simply remove the following line */
2138 ptr = strchr(param, '=');
2143 if (strcmp(param, PARAM_SRPC_UDESC))
2146 if (strcmp(ptr, "yes") == 0) {
2147 cfs_set_bit(FSDB_UDESC, &fsdb->fsdb_flags);
2148 CWARN("Enable user descriptor shipping from client to MDT\n");
2149 } else if (strcmp(ptr, "no") == 0) {
2150 cfs_clear_bit(FSDB_UDESC, &fsdb->fsdb_flags);
2151 CWARN("Disable user descriptor shipping from client to MDT\n");
2159 CERROR("Invalid param: %s\n", param);
2163 static int mgs_srpc_set_param_mem(struct fs_db *fsdb,
2167 struct sptlrpc_rule rule;
2168 struct sptlrpc_rule_set *rset;
2172 if (strncmp(param, PARAM_SRPC, sizeof(PARAM_SRPC) - 1) != 0) {
2173 CERROR("Invalid sptlrpc parameter: %s\n", param);
2177 if (strncmp(param, PARAM_SRPC_UDESC,
2178 sizeof(PARAM_SRPC_UDESC) - 1) == 0) {
2179 RETURN(mgs_srpc_set_param_udesc_mem(fsdb, param));
2182 if (strncmp(param, PARAM_SRPC_FLVR, sizeof(PARAM_SRPC_FLVR) - 1) != 0) {
2183 CERROR("Invalid sptlrpc flavor parameter: %s\n", param);
2187 param += sizeof(PARAM_SRPC_FLVR) - 1;
2189 rc = sptlrpc_parse_rule(param, &rule);
2193 /* mgs rules implies must be mgc->mgs */
2194 if (cfs_test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
2195 if ((rule.sr_from != LUSTRE_SP_MGC &&
2196 rule.sr_from != LUSTRE_SP_ANY) ||
2197 (rule.sr_to != LUSTRE_SP_MGS &&
2198 rule.sr_to != LUSTRE_SP_ANY))
2202 /* preapre room for this coming rule. svcname format should be:
2203 * - fsname: general rule
2204 * - fsname-tgtname: target-specific rule
2206 if (strchr(svname, '-')) {
2207 struct mgs_tgt_srpc_conf *tgtconf;
2210 for (tgtconf = fsdb->fsdb_srpc_tgt; tgtconf != NULL;
2211 tgtconf = tgtconf->mtsc_next) {
2212 if (!strcmp(tgtconf->mtsc_tgt, svname)) {
2221 OBD_ALLOC_PTR(tgtconf);
2222 if (tgtconf == NULL)
2225 name_len = strlen(svname);
2227 OBD_ALLOC(tgtconf->mtsc_tgt, name_len + 1);
2228 if (tgtconf->mtsc_tgt == NULL) {
2229 OBD_FREE_PTR(tgtconf);
2232 memcpy(tgtconf->mtsc_tgt, svname, name_len);
2234 tgtconf->mtsc_next = fsdb->fsdb_srpc_tgt;
2235 fsdb->fsdb_srpc_tgt = tgtconf;
2238 rset = &tgtconf->mtsc_rset;
2240 rset = &fsdb->fsdb_srpc_gen;
2243 rc = sptlrpc_rule_set_merge(rset, &rule);
2248 static int mgs_srpc_set_param(struct obd_device *obd,
2250 struct mgs_target_info *mti,
2260 /* keep a copy of original param, which could be destroied
2262 copy_size = strlen(param) + 1;
2263 OBD_ALLOC(copy, copy_size);
2266 memcpy(copy, param, copy_size);
2268 rc = mgs_srpc_set_param_mem(fsdb, mti->mti_svname, param);
2272 /* previous steps guaranteed the syntax is correct */
2273 rc = mgs_srpc_set_param_disk(obd, fsdb, mti, copy);
2277 if (cfs_test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
2279 * for mgs rules, make them effective immediately.
2281 LASSERT(fsdb->fsdb_srpc_tgt == NULL);
2282 sptlrpc_target_update_exp_flavor(obd, &fsdb->fsdb_srpc_gen);
2286 OBD_FREE(copy, copy_size);
2290 struct mgs_srpc_read_data {
2291 struct fs_db *msrd_fsdb;
2295 static int mgs_srpc_read_handler(struct llog_handle *llh,
2296 struct llog_rec_hdr *rec,
2299 struct mgs_srpc_read_data *msrd = (struct mgs_srpc_read_data *) data;
2300 struct cfg_marker *marker;
2301 struct lustre_cfg *lcfg = (struct lustre_cfg *)(rec + 1);
2302 char *svname, *param;
2306 if (rec->lrh_type != OBD_CFG_REC) {
2307 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
2311 cfg_len = rec->lrh_len - sizeof(struct llog_rec_hdr) -
2312 sizeof(struct llog_rec_tail);
2314 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
2316 CERROR("Insane cfg\n");
2320 if (lcfg->lcfg_command == LCFG_MARKER) {
2321 marker = lustre_cfg_buf(lcfg, 1);
2323 if (marker->cm_flags & CM_START &&
2324 marker->cm_flags & CM_SKIP)
2325 msrd->msrd_skip = 1;
2326 if (marker->cm_flags & CM_END)
2327 msrd->msrd_skip = 0;
2332 if (msrd->msrd_skip)
2335 if (lcfg->lcfg_command != LCFG_SPTLRPC_CONF) {
2336 CERROR("invalid command (%x)\n", lcfg->lcfg_command);
2340 svname = lustre_cfg_string(lcfg, 0);
2341 if (svname == NULL) {
2342 CERROR("svname is empty\n");
2346 param = lustre_cfg_string(lcfg, 1);
2347 if (param == NULL) {
2348 CERROR("param is empty\n");
2352 rc = mgs_srpc_set_param_mem(msrd->msrd_fsdb, svname, param);
2354 CERROR("read sptlrpc record error (%d): %s\n", rc, param);
2359 int mgs_get_fsdb_srpc_from_llog(struct obd_device *obd,
2362 struct llog_handle *llh = NULL;
2363 struct lvfs_run_ctxt saved;
2364 struct llog_ctxt *ctxt;
2366 struct mgs_srpc_read_data msrd;
2370 /* construct log name */
2371 rc = name_create(&logname, fsdb->fsdb_name, "-sptlrpc");
2375 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
2376 LASSERT(ctxt != NULL);
2378 if (mgs_log_is_empty(obd, logname))
2381 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
2383 rc = llog_create(ctxt, &llh, NULL, logname);
2387 rc = llog_init_handle(llh, LLOG_F_IS_PLAIN, NULL);
2389 GOTO(out_close, rc);
2391 if (llog_get_size(llh) <= 1)
2392 GOTO(out_close, rc = 0);
2394 msrd.msrd_fsdb = fsdb;
2397 rc = llog_process(llh, mgs_srpc_read_handler, (void *) &msrd, NULL);
2402 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
2404 llog_ctxt_put(ctxt);
2405 name_destroy(&logname);
2408 CERROR("failed to read sptlrpc config database: %d\n", rc);
2412 /* Permanent settings of all parameters by writing into the appropriate
2413 * configuration logs.
2414 * A parameter with null value ("<param>='\0'") means to erase it out of
2417 static int mgs_write_log_param(struct obd_device *obd, struct fs_db *fsdb,
2418 struct mgs_target_info *mti, char *ptr)
2420 struct lustre_cfg_bufs bufs;
2423 int rc = 0, rc2 = 0;
2426 /* For various parameter settings, we have to figure out which logs
2427 care about them (e.g. both mdt and client for lov settings) */
2428 CDEBUG(D_MGS, "next param '%s'\n", ptr);
2430 /* The params are stored in MOUNT_DATA_FILE and modified via
2431 tunefs.lustre, or set using lctl conf_param */
2433 /* Processed in lustre_start_mgc */
2434 if (class_match_param(ptr, PARAM_MGSNODE, NULL) == 0)
2437 /* Processed in ost/mdt */
2438 if (class_match_param(ptr, PARAM_NETWORK, NULL) == 0)
2441 /* Processed in mgs_write_log_ost */
2442 if (class_match_param(ptr, PARAM_FAILMODE, NULL) == 0) {
2443 if (mti->mti_flags & LDD_F_PARAM) {
2444 LCONSOLE_ERROR_MSG(0x169, "%s can only be "
2445 "changed with tunefs.lustre"
2446 "and --writeconf\n", ptr);
2452 if (class_match_param(ptr, PARAM_SRPC, NULL) == 0) {
2453 rc = mgs_srpc_set_param(obd, fsdb, mti, ptr);
2457 if (class_match_param(ptr, PARAM_FAILNODE, NULL) == 0) {
2458 /* Add a failover nidlist */
2460 /* We already processed failovers params for new
2461 targets in mgs_write_log_target */
2462 if (mti->mti_flags & LDD_F_PARAM) {
2463 CDEBUG(D_MGS, "Adding failnode\n");
2464 rc = mgs_write_log_add_failnid(obd, fsdb, mti);
2469 if (class_match_param(ptr, PARAM_SYS, &tmp) == 0) {
2470 rc = mgs_write_log_sys(obd, fsdb, mti, ptr, tmp);
2474 if (class_match_param(ptr, PARAM_OSC""PARAM_ACTIVE, &tmp) == 0) {
2475 /* active=0 means off, anything else means on */
2476 int flag = (*tmp == '0') ? CM_EXCLUDE : 0;
2479 if (!(mti->mti_flags & LDD_F_SV_TYPE_OST)) {
2480 LCONSOLE_ERROR_MSG(0x144, "%s: Only OSCs can "
2481 "be (de)activated.\n",
2483 GOTO(end, rc = -EINVAL);
2485 LCONSOLE_WARN("Permanently %sactivating %s\n",
2486 flag ? "de": "re", mti->mti_svname);
2488 name_create(&logname, mti->mti_fsname, "-client");
2489 rc = mgs_modify(obd, fsdb, mti, logname,
2490 mti->mti_svname, "add osc", flag);
2491 name_destroy(&logname);
2495 /* Add to all MDT logs for CMD */
2496 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2497 if (!cfs_test_bit(i, fsdb->fsdb_mdt_index_map))
2499 name_create_mdt(&logname, mti->mti_fsname, i);
2500 rc = mgs_modify(obd, fsdb, mti, logname,
2501 mti->mti_svname, "add osc", flag);
2502 name_destroy(&logname);
2508 LCONSOLE_ERROR_MSG(0x145, "Couldn't find %s in"
2509 "log (%d). No permanent "
2510 "changes were made to the "
2512 mti->mti_svname, rc);
2513 if (cfs_test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags))
2514 LCONSOLE_ERROR_MSG(0x146, "This may be"
2519 "update the logs.\n");
2522 /* Fall through to osc proc for deactivating live OSC
2523 on running MDT / clients. */
2525 /* Below here, let obd's XXX_process_config methods handle it */
2527 /* All lov. in proc */
2528 if (class_match_param(ptr, PARAM_LOV, NULL) == 0) {
2531 CDEBUG(D_MGS, "lov param %s\n", ptr);
2532 if (!(mti->mti_flags & LDD_F_SV_TYPE_MDT)) {
2533 LCONSOLE_ERROR_MSG(0x147, "LOV params must be "
2534 "set on the MDT, not %s. "
2541 if (mgs_log_is_empty(obd, mti->mti_svname))
2542 GOTO(end, rc = -ENODEV);
2544 name_create_mdt_and_lov(&logname, &mdtlovname, fsdb,
2545 mti->mti_stripe_index);
2546 rc = mgs_wlp_lcfg(obd, fsdb, mti, mti->mti_svname,
2547 &bufs, mdtlovname, ptr);
2548 name_destroy(&logname);
2549 name_destroy(&mdtlovname);
2554 name_create(&logname, mti->mti_fsname, "-client");
2555 rc = mgs_wlp_lcfg(obd, fsdb, mti, logname, &bufs,
2556 fsdb->fsdb_clilov, ptr);
2557 name_destroy(&logname);
2561 /* All osc., mdc., llite. params in proc */
2562 if ((class_match_param(ptr, PARAM_OSC, NULL) == 0) ||
2563 (class_match_param(ptr, PARAM_MDC, NULL) == 0) ||
2564 (class_match_param(ptr, PARAM_LLITE, NULL) == 0)) {
2566 if (memcmp(ptr, PARAM_LLITE, strlen(PARAM_LLITE)) == 0) {
2567 name_create(&cname, mti->mti_fsname, "-client");
2568 /* Add the client type to match the obdname in
2569 class_config_llog_handler */
2570 } else if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
2573 name_create(&cname, fsdb->fsdb_mdc, "");
2575 name_create(&cname, mti->mti_svname,
2577 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2579 if (cfs_test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
2580 LCONSOLE_ERROR_MSG(0x148, "Upgraded "
2581 "client logs for %s"
2583 "modified. Consider"
2585 "configuration with"
2588 /* We don't know the names of all the
2590 GOTO(end, rc = -EINVAL);
2592 name_create(&cname, mti->mti_svname, "-osc");
2594 GOTO(end, rc = -EINVAL);
2597 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
2600 name_create(&logname, mti->mti_fsname, "-client");
2601 rc = mgs_wlp_lcfg(obd, fsdb, mti, logname, &bufs,
2604 /* osc params affect the MDT as well */
2605 if (!rc && (mti->mti_flags & LDD_F_SV_TYPE_OST)) {
2608 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
2609 if (!cfs_test_bit(i, fsdb->fsdb_mdt_index_map))
2611 name_destroy(&cname);
2612 name_create_mdt_osc(&cname, mti->mti_svname,
2614 name_destroy(&logname);
2615 name_create_mdt(&logname, mti->mti_fsname, i);
2616 if (!mgs_log_is_empty(obd, logname))
2617 rc = mgs_wlp_lcfg(obd, fsdb,mti,logname,
2623 name_destroy(&logname);
2624 name_destroy(&cname);
2628 /* All mdt. params in proc */
2629 if (class_match_param(ptr, PARAM_MDT, NULL) == 0) {
2633 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
2634 if (strncmp(mti->mti_svname, mti->mti_fsname,
2635 MTI_NAME_MAXLEN) == 0)
2636 /* device is unspecified completely? */
2637 rc = LDD_F_SV_TYPE_MDT | LDD_F_SV_ALL;
2639 rc = server_name2index(mti->mti_svname, &idx, NULL);
2642 if ((rc & LDD_F_SV_TYPE_MDT) == 0)
2644 if (rc & LDD_F_SV_ALL) {
2645 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2646 if (!cfs_test_bit(i,
2647 fsdb->fsdb_mdt_index_map))
2649 name_create_mdt(&logname, mti->mti_fsname, i);
2650 rc = mgs_wlp_lcfg(obd, fsdb, mti,
2653 name_destroy(&logname);
2658 rc = mgs_wlp_lcfg(obd, fsdb, mti,
2659 mti->mti_svname, &bufs,
2660 mti->mti_svname, ptr);
2667 /* All mdd., ost. params in proc */
2668 if ((class_match_param(ptr, PARAM_MDD, NULL) == 0) ||
2669 (class_match_param(ptr, PARAM_OST, NULL) == 0)) {
2670 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
2671 if (mgs_log_is_empty(obd, mti->mti_svname))
2672 GOTO(end, rc = -ENODEV);
2674 rc = mgs_wlp_lcfg(obd, fsdb, mti, mti->mti_svname,
2675 &bufs, mti->mti_svname, ptr);
2679 LCONSOLE_WARN("Ignoring unrecognized param '%s'\n", ptr);
2684 CERROR("err %d on param '%s'\n", rc, ptr);
2689 /* Not implementing automatic failover nid addition at this time. */
2690 int mgs_check_failnid(struct obd_device *obd, struct mgs_target_info *mti)
2697 rc = mgs_find_or_make_fsdb(obd, fsname, &fsdb);
2701 if (mgs_log_is_empty(obd, mti->mti_svname))
2702 /* should never happen */
2705 CDEBUG(D_MGS, "Checking for new failnids for %s\n", mti->mti_svname);
2707 /* FIXME We can just check mti->params to see if we're already in
2708 the failover list. Modify mti->params for rewriting back at
2709 server_register_target(). */
2711 cfs_mutex_lock(&fsdb->fsdb_mutex);
2712 rc = mgs_write_log_add_failnid(obd, fsdb, mti);
2713 cfs_mutex_unlock(&fsdb->fsdb_mutex);
2720 int mgs_write_log_target(struct obd_device *obd,
2721 struct mgs_target_info *mti,
2728 /* set/check the new target index */
2729 rc = mgs_set_index(obd, mti);
2731 CERROR("Can't get index (%d)\n", rc);
2736 if (mti->mti_flags & LDD_F_UPGRADE14) {
2737 if (rc == EALREADY) {
2738 LCONSOLE_INFO("Found index %d for %s 1.4 log, "
2739 "upgrading\n", mti->mti_stripe_index,
2742 LCONSOLE_ERROR_MSG(0x149, "Failed to find %s in the old"
2743 " client log. Apparently it is not "
2744 "part of this filesystem, or the old"
2745 " log is wrong.\nUse 'writeconf' on "
2746 "the MDT to force log regeneration."
2747 "\n", mti->mti_svname);
2748 /* Not in client log? Upgrade anyhow...*/
2749 /* Argument against upgrading: reformat MDT,
2750 upgrade OST, then OST will start but will be SKIPped
2751 in client logs. Maybe error now is better. */
2752 /* RETURN(-EINVAL); */
2754 /* end COMPAT_146 */
2756 if (rc == EALREADY) {
2757 LCONSOLE_WARN("Found index %d for %s, updating log\n",
2758 mti->mti_stripe_index, mti->mti_svname);
2759 /* We would like to mark old log sections as invalid
2760 and add new log sections in the client and mdt logs.
2761 But if we add new sections, then live clients will
2762 get repeat setup instructions for already running
2763 osc's. So don't update the client/mdt logs. */
2764 mti->mti_flags &= ~LDD_F_UPDATE;
2768 cfs_mutex_lock(&fsdb->fsdb_mutex);
2770 if (mti->mti_flags &
2771 (LDD_F_VIRGIN | LDD_F_UPGRADE14 | LDD_F_WRITECONF)) {
2772 /* Generate a log from scratch */
2773 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
2774 rc = mgs_write_log_mdt(obd, fsdb, mti);
2775 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2776 rc = mgs_write_log_ost(obd, fsdb, mti);
2778 CERROR("Unknown target type %#x, can't create log for "
2779 "%s\n", mti->mti_flags, mti->mti_svname);
2782 CERROR("Can't write logs for %s (%d)\n",
2783 mti->mti_svname, rc);
2787 /* Just update the params from tunefs in mgs_write_log_params */
2788 CDEBUG(D_MGS, "Update params for %s\n", mti->mti_svname);
2789 mti->mti_flags |= LDD_F_PARAM;
2792 /* allocate temporary buffer, where class_get_next_param will
2793 make copy of a current parameter */
2794 OBD_ALLOC(buf, strlen(mti->mti_params) + 1);
2796 GOTO(out_up, rc = -ENOMEM);
2797 params = mti->mti_params;
2798 while (params != NULL) {
2799 rc = class_get_next_param(¶ms, buf);
2802 /* there is no next parameter, that is
2807 CDEBUG(D_MGS, "remaining string: '%s', param: '%s'\n",
2809 rc = mgs_write_log_param(obd, fsdb, mti, buf);
2814 OBD_FREE(buf, strlen(mti->mti_params) + 1);
2817 cfs_mutex_unlock(&fsdb->fsdb_mutex);
2822 /* verify that we can handle the old config logs */
2823 int mgs_upgrade_sv_14(struct obd_device *obd, struct mgs_target_info *mti,
2829 /* Create ost log normally, as servers register. Servers
2830 register with their old uuids (from last_rcvd), so old
2831 (MDT and client) logs should work.
2832 - new MDT won't know about old OSTs, only the ones that have
2833 registered, so we need the old MDT log to get the LOV right
2834 in order for old clients to work.
2835 - Old clients connect to the MDT, not the MGS, for their logs, and
2836 will therefore receive the old client log from the MDT /LOGS dir.
2837 - Old clients can continue to use and connect to old or new OSTs
2838 - New clients will contact the MGS for their log
2841 LCONSOLE_INFO("upgrading server %s from pre-1.6\n", mti->mti_svname);
2842 server_mti_print("upgrade", mti);
2844 if (cfs_test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
2845 LCONSOLE_ERROR_MSG(0x14a, "The old client log %s-client is "
2846 "missing. Was tunefs.lustre successful?\n",
2851 if (fsdb->fsdb_gen == 0) {
2852 /* There were no markers in the client log, meaning we have
2853 not updated the logs for this fs */
2854 CDEBUG(D_MGS, "found old, unupdated client log\n");
2857 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
2858 if (mgs_log_is_empty(obd, mti->mti_svname)) {
2859 LCONSOLE_ERROR_MSG(0x14b, "The old MDT log %s is "
2860 "missing. Was tunefs.lustre "
2865 /* We're starting with an old uuid. Assume old name for lov
2866 as well since the lov entry already exists in the log. */
2867 CDEBUG(D_MGS, "old mds uuid %s\n", mti->mti_uuid);
2868 if (strncmp(mti->mti_uuid, fsdb->fsdb_mdtlov + 4,
2869 strlen(fsdb->fsdb_mdtlov) - 4) != 0) {
2870 CERROR("old mds uuid %s doesn't match log %s (%s)\n",
2871 mti->mti_uuid, fsdb->fsdb_mdtlov,
2872 fsdb->fsdb_mdtlov + 4);
2877 if (!cfs_test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
2878 LCONSOLE_ERROR_MSG(0x14c, "%s-client is supposedly an old "
2879 "log, but no old LOV or MDT was found. "
2880 "Consider updating the configuration with"
2881 " --writeconf.\n", mti->mti_fsname);
2886 /* end COMPAT_146 */
2888 int mgs_erase_log(struct obd_device *obd, char *name)
2890 struct lvfs_run_ctxt saved;
2891 struct llog_ctxt *ctxt;
2892 struct llog_handle *llh;
2895 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
2896 LASSERT(ctxt != NULL);
2898 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
2899 rc = llog_create(ctxt, &llh, NULL, name);
2901 llog_init_handle(llh, LLOG_F_IS_PLAIN, NULL);
2902 rc = llog_destroy(llh);
2903 llog_free_handle(llh);
2905 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
2906 llog_ctxt_put(ctxt);
2909 CERROR("failed to clear log %s: %d\n", name, rc);
2914 /* erase all logs for the given fs */
2915 int mgs_erase_logs(struct obd_device *obd, char *fsname)
2917 struct mgs_obd *mgs = &obd->u.mgs;
2919 cfs_list_t dentry_list;
2920 struct l_linux_dirent *dirent, *n;
2921 int rc, len = strlen(fsname);
2925 /* Find all the logs in the CONFIGS directory */
2926 rc = class_dentry_readdir(obd, mgs->mgs_configs_dir,
2927 mgs->mgs_vfsmnt, &dentry_list);
2929 CERROR("Can't read %s dir\n", MOUNT_CONFIGS_DIR);
2933 cfs_mutex_lock(&mgs->mgs_mutex);
2935 /* Delete the fs db */
2936 fsdb = mgs_find_fsdb(obd, fsname);
2938 mgs_free_fsdb(obd, fsdb);
2940 cfs_list_for_each_entry_safe(dirent, n, &dentry_list, lld_list) {
2941 cfs_list_del(&dirent->lld_list);
2942 suffix = strrchr(dirent->lld_name, '-');
2943 if (suffix != NULL) {
2944 if ((len == suffix - dirent->lld_name) &&
2945 (strncmp(fsname, dirent->lld_name, len) == 0)) {
2946 CDEBUG(D_MGS, "Removing log %s\n",
2948 mgs_erase_log(obd, dirent->lld_name);
2951 OBD_FREE(dirent, sizeof(*dirent));
2954 cfs_mutex_unlock(&mgs->mgs_mutex);
2959 /* from llog_swab */
2960 static void print_lustre_cfg(struct lustre_cfg *lcfg)
2965 CDEBUG(D_MGS, "lustre_cfg: %p\n", lcfg);
2966 CDEBUG(D_MGS, "\tlcfg->lcfg_version: %#x\n", lcfg->lcfg_version);
2968 CDEBUG(D_MGS, "\tlcfg->lcfg_command: %#x\n", lcfg->lcfg_command);
2969 CDEBUG(D_MGS, "\tlcfg->lcfg_num: %#x\n", lcfg->lcfg_num);
2970 CDEBUG(D_MGS, "\tlcfg->lcfg_flags: %#x\n", lcfg->lcfg_flags);
2971 CDEBUG(D_MGS, "\tlcfg->lcfg_nid: %s\n", libcfs_nid2str(lcfg->lcfg_nid));
2973 CDEBUG(D_MGS, "\tlcfg->lcfg_bufcount: %d\n", lcfg->lcfg_bufcount);
2974 if (lcfg->lcfg_bufcount < LUSTRE_CFG_MAX_BUFCOUNT)
2975 for (i = 0; i < lcfg->lcfg_bufcount; i++) {
2976 CDEBUG(D_MGS, "\tlcfg->lcfg_buflens[%d]: %d %s\n",
2977 i, lcfg->lcfg_buflens[i],
2978 lustre_cfg_string(lcfg, i));
2983 /* Set a permanent (config log) param for a target or fs
2984 * \param lcfg buf0 may contain the device (testfs-MDT0000) name
2985 * buf1 contains the single parameter
2987 int mgs_setparam(struct obd_device *obd, struct lustre_cfg *lcfg, char *fsname)
2990 struct mgs_target_info *mti;
2991 char *devname, *param;
2997 print_lustre_cfg(lcfg);
2999 /* lustre, lustre-mdtlov, lustre-client, lustre-MDT0000 */
3000 devname = lustre_cfg_string(lcfg, 0);
3001 param = lustre_cfg_string(lcfg, 1);
3003 /* Assume device name embedded in param:
3004 lustre-OST0000.osc.max_dirty_mb=32 */
3005 ptr = strchr(param, '.');
3013 LCONSOLE_ERROR_MSG(0x14d, "No target specified: %s\n", param);
3017 /* Extract fsname */
3018 ptr = strrchr(devname, '-');
3019 memset(fsname, 0, MTI_NAME_MAXLEN);
3020 if (ptr && (server_name2index(ptr, &index, NULL) >= 0)) {
3021 /* param related to llite isn't allowed to set by OST or MDT */
3022 if (strncmp(param, PARAM_LLITE, sizeof(PARAM_LLITE)) == 0)
3025 strncpy(fsname, devname, ptr - devname);
3027 /* assume devname is the fsname */
3028 strncpy(fsname, devname, MTI_NAME_MAXLEN);
3030 fsname[MTI_NAME_MAXLEN - 1] = 0;
3031 CDEBUG(D_MGS, "setparam fs='%s' device='%s'\n", fsname, devname);
3033 rc = mgs_find_or_make_fsdb(obd, fsname, &fsdb);
3036 if (!cfs_test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags) &&
3037 cfs_test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
3038 CERROR("No filesystem targets for %s. cfg_device from lctl "
3039 "is '%s'\n", fsname, devname);
3040 mgs_free_fsdb(obd, fsdb);
3044 /* Create a fake mti to hold everything */
3047 GOTO(out, rc = -ENOMEM);
3048 strncpy(mti->mti_fsname, fsname, MTI_NAME_MAXLEN);
3049 strncpy(mti->mti_svname, devname, MTI_NAME_MAXLEN);
3050 strncpy(mti->mti_params, param, sizeof(mti->mti_params));
3051 rc = server_name2index(mti->mti_svname, &mti->mti_stripe_index, &tmp);
3053 /* Not a valid server; may be only fsname */
3056 /* Strip -osc or -mdc suffix from svname */
3057 if (server_make_name(rc, mti->mti_stripe_index, mti->mti_fsname,
3059 GOTO(out, rc = -EINVAL);
3061 mti->mti_flags = rc | LDD_F_PARAM;
3063 cfs_mutex_lock(&fsdb->fsdb_mutex);
3064 rc = mgs_write_log_param(obd, fsdb, mti, mti->mti_params);
3065 cfs_mutex_unlock(&fsdb->fsdb_mutex);
3068 * Revoke lock so everyone updates. Should be alright if
3069 * someone was already reading while we were updating the logs,
3070 * so we don't really need to hold the lock while we're
3073 mgs_revoke_lock(obd, fsdb, CONFIG_T_CONFIG);
3079 static int mgs_write_log_pool(struct obd_device *obd, char *logname,
3080 struct fs_db *fsdb, char *lovname,
3081 enum lcfg_command_type cmd,
3082 char *poolname, char *fsname,
3083 char *ostname, char *comment)
3085 struct llog_handle *llh = NULL;
3088 rc = record_start_log(obd, &llh, logname);
3091 rc = record_marker(obd, llh, fsdb, CM_START, lovname, comment);
3092 record_base(obd, llh, lovname, 0, cmd, poolname, fsname, ostname, 0);
3093 rc = record_marker(obd, llh, fsdb, CM_END, lovname, comment);
3094 rc = record_end_log(obd, &llh);
3099 int mgs_pool_cmd(struct obd_device *obd, enum lcfg_command_type cmd,
3100 char *fsname, char *poolname, char *ostname)
3105 char *label = NULL, *canceled_label = NULL;
3107 struct mgs_target_info *mti = NULL;
3111 rc = mgs_find_or_make_fsdb(obd, fsname, &fsdb);
3113 CERROR("Can't get db for %s\n", fsname);
3116 if (cfs_test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
3117 CERROR("%s is not defined\n", fsname);
3118 mgs_free_fsdb(obd, fsdb);
3122 label_sz = 10 + strlen(fsname) + strlen(poolname);
3124 /* check if ostname match fsname */
3125 if (ostname != NULL) {
3128 ptr = strrchr(ostname, '-');
3129 if ((ptr == NULL) ||
3130 (strncmp(fsname, ostname, ptr-ostname) != 0))
3132 label_sz += strlen(ostname);
3135 OBD_ALLOC(label, label_sz);
3137 GOTO(out, rc = -ENOMEM);
3140 case LCFG_POOL_NEW: {
3142 "new %s.%s", fsname, poolname);
3145 case LCFG_POOL_ADD: {
3147 "add %s.%s.%s", fsname, poolname, ostname);
3150 case LCFG_POOL_REM: {
3151 OBD_ALLOC(canceled_label, label_sz);
3152 if (canceled_label == NULL)
3153 GOTO(out, rc = -ENOMEM);
3155 "rem %s.%s.%s", fsname, poolname, ostname);
3156 sprintf(canceled_label,
3157 "add %s.%s.%s", fsname, poolname, ostname);
3160 case LCFG_POOL_DEL: {
3161 OBD_ALLOC(canceled_label, label_sz);
3162 if (canceled_label == NULL)
3163 GOTO(out, rc = -ENOMEM);
3165 "del %s.%s", fsname, poolname);
3166 sprintf(canceled_label,
3167 "new %s.%s", fsname, poolname);
3175 cfs_mutex_lock(&fsdb->fsdb_mutex);
3177 if (canceled_label != NULL) {
3180 GOTO(out, rc = -ENOMEM);
3183 /* write pool def to all MDT logs */
3184 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3185 if (cfs_test_bit(i, fsdb->fsdb_mdt_index_map)) {
3186 name_create_mdt_and_lov(&logname, &lovname, fsdb, i);
3188 if (canceled_label != NULL) {
3189 strcpy(mti->mti_svname, "lov pool");
3190 mgs_modify(obd, fsdb, mti, logname, lovname,
3191 canceled_label, CM_SKIP);
3194 mgs_write_log_pool(obd, logname, fsdb, lovname,
3195 cmd, fsname, poolname, ostname,
3197 name_destroy(&logname);
3198 name_destroy(&lovname);
3202 name_create(&logname, fsname, "-client");
3203 if (canceled_label != NULL)
3204 mgs_modify(obd, fsdb, mti, logname, fsdb->fsdb_clilov,
3205 canceled_label, CM_SKIP);
3207 mgs_write_log_pool(obd, logname, fsdb, fsdb->fsdb_clilov,
3208 cmd, fsname, poolname, ostname, label);
3209 name_destroy(&logname);
3211 cfs_mutex_unlock(&fsdb->fsdb_mutex);
3212 /* request for update */
3213 mgs_revoke_lock(obd, fsdb, CONFIG_T_CONFIG);
3218 OBD_FREE(label, label_sz);
3220 if (canceled_label != NULL)
3221 OBD_FREE(canceled_label, label_sz);
3230 /******************** unused *********************/
3231 static int mgs_backup_llog(struct obd_device *obd, char* fsname)
3233 struct file *filp, *bak_filp;
3234 struct lvfs_run_ctxt saved;
3235 char *logname, *buf;
3236 loff_t soff = 0 , doff = 0;
3237 int count = 4096, len;
3240 OBD_ALLOC(logname, PATH_MAX);
3241 if (logname == NULL)
3244 OBD_ALLOC(buf, count);
3246 GOTO(out , rc = -ENOMEM);
3248 len = snprintf(logname, PATH_MAX, "%s/%s.bak",
3249 MOUNT_CONFIGS_DIR, fsname);
3251 if (len >= PATH_MAX - 1) {
3252 GOTO(out, -ENAMETOOLONG);
3255 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
3257 bak_filp = l_filp_open(logname, O_RDWR|O_CREAT|O_TRUNC, 0660);
3258 if (IS_ERR(bak_filp)) {
3259 rc = PTR_ERR(bak_filp);
3260 CERROR("backup logfile open %s: %d\n", logname, rc);
3263 sprintf(logname, "%s/%s", MOUNT_CONFIGS_DIR, fsname);
3264 filp = l_filp_open(logname, O_RDONLY, 0);
3267 CERROR("logfile open %s: %d\n", logname, rc);
3271 while ((rc = lustre_fread(filp, buf, count, &soff)) > 0) {
3272 rc = lustre_fwrite(bak_filp, buf, count, &doff);
3276 filp_close(filp, 0);
3278 filp_close(bak_filp, 0);
3280 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
3283 OBD_FREE(buf, count);
3284 OBD_FREE(logname, PATH_MAX);