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(NULL, loghandle, mgs_fsdb_handler, (void *) &d,
291 CDEBUG(D_INFO, "get_db = %d\n", rc);
293 rc2 = llog_close(loghandle);
297 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
298 cfs_mutex_unlock(&fsdb->fsdb_mutex);
299 name_destroy(&logname);
305 static void mgs_free_fsdb_srpc(struct fs_db *fsdb)
307 struct mgs_tgt_srpc_conf *tgtconf;
309 /* free target-specific rules */
310 while (fsdb->fsdb_srpc_tgt) {
311 tgtconf = fsdb->fsdb_srpc_tgt;
312 fsdb->fsdb_srpc_tgt = tgtconf->mtsc_next;
314 LASSERT(tgtconf->mtsc_tgt);
316 sptlrpc_rule_set_free(&tgtconf->mtsc_rset);
317 OBD_FREE(tgtconf->mtsc_tgt, strlen(tgtconf->mtsc_tgt) + 1);
318 OBD_FREE_PTR(tgtconf);
321 /* free general rules */
322 sptlrpc_rule_set_free(&fsdb->fsdb_srpc_gen);
325 struct fs_db *mgs_find_fsdb(struct obd_device *obd, char *fsname)
327 struct mgs_obd *mgs = &obd->u.mgs;
331 cfs_list_for_each(tmp, &mgs->mgs_fs_db_list) {
332 fsdb = cfs_list_entry(tmp, struct fs_db, fsdb_list);
333 if (strcmp(fsdb->fsdb_name, fsname) == 0)
339 /* caller must hold the mgs->mgs_fs_db_lock */
340 static struct fs_db *mgs_new_fsdb(struct obd_device *obd, char *fsname)
342 struct mgs_obd *mgs = &obd->u.mgs;
347 if (strlen(fsname) >= sizeof(fsdb->fsdb_name)) {
348 CERROR("fsname %s is too long\n", fsname);
356 strcpy(fsdb->fsdb_name, fsname);
357 cfs_mutex_init(&fsdb->fsdb_mutex);
358 cfs_set_bit(FSDB_UDESC, &fsdb->fsdb_flags);
360 if (strcmp(fsname, MGSSELF_NAME) == 0) {
361 cfs_set_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags);
363 OBD_ALLOC(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
364 OBD_ALLOC(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
365 if (!fsdb->fsdb_ost_index_map || !fsdb->fsdb_mdt_index_map) {
366 CERROR("No memory for index maps\n");
370 rc = name_create(&fsdb->fsdb_mdtlov, fsname, "-mdtlov");
373 rc = name_create(&fsdb->fsdb_mdtlmv, fsname, "-mdtlmv");
376 rc = name_create(&fsdb->fsdb_clilov, fsname, "-clilov");
379 rc = name_create(&fsdb->fsdb_clilmv, fsname, "-clilmv");
383 /* initialise data for NID table */
384 mgs_ir_init_fs(obd, fsdb);
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_mutex_lock(&fsdb->fsdb_mutex);
409 lproc_mgs_del_live(obd, fsdb);
410 cfs_list_del(&fsdb->fsdb_list);
412 /* deinitialize fsr */
413 mgs_ir_fini_fs(obd, fsdb);
415 if (fsdb->fsdb_ost_index_map)
416 OBD_FREE(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
417 if (fsdb->fsdb_mdt_index_map)
418 OBD_FREE(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
419 name_destroy(&fsdb->fsdb_clilov);
420 name_destroy(&fsdb->fsdb_clilmv);
421 name_destroy(&fsdb->fsdb_mdtlov);
422 name_destroy(&fsdb->fsdb_mdtlmv);
423 name_destroy(&fsdb->fsdb_mdc);
424 mgs_free_fsdb_srpc(fsdb);
425 cfs_mutex_unlock(&fsdb->fsdb_mutex);
429 int mgs_init_fsdb_list(struct obd_device *obd)
431 struct mgs_obd *mgs = &obd->u.mgs;
432 CFS_INIT_LIST_HEAD(&mgs->mgs_fs_db_list);
436 int mgs_cleanup_fsdb_list(struct obd_device *obd)
438 struct mgs_obd *mgs = &obd->u.mgs;
440 cfs_list_t *tmp, *tmp2;
441 cfs_mutex_lock(&mgs->mgs_mutex);
442 cfs_list_for_each_safe(tmp, tmp2, &mgs->mgs_fs_db_list) {
443 fsdb = cfs_list_entry(tmp, struct fs_db, fsdb_list);
444 mgs_free_fsdb(obd, fsdb);
446 cfs_mutex_unlock(&mgs->mgs_mutex);
450 int mgs_find_or_make_fsdb(struct obd_device *obd, char *name,
453 struct mgs_obd *mgs = &obd->u.mgs;
457 cfs_mutex_lock(&mgs->mgs_mutex);
458 fsdb = mgs_find_fsdb(obd, name);
460 cfs_mutex_unlock(&mgs->mgs_mutex);
465 CDEBUG(D_MGS, "Creating new db\n");
466 fsdb = mgs_new_fsdb(obd, name);
467 cfs_mutex_unlock(&mgs->mgs_mutex);
471 if (!cfs_test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
472 /* populate the db from the client llog */
473 rc = mgs_get_fsdb_from_llog(obd, fsdb);
475 CERROR("Can't get db from client log %d\n", rc);
476 mgs_free_fsdb(obd, fsdb);
481 /* populate srpc rules from params llog */
482 rc = mgs_get_fsdb_srpc_from_llog(obd, fsdb);
484 CERROR("Can't get db from params log %d\n", rc);
485 mgs_free_fsdb(obd, fsdb);
496 -1= empty client log */
497 int mgs_check_index(struct obd_device *obd, struct mgs_target_info *mti)
504 LASSERT(!(mti->mti_flags & LDD_F_NEED_INDEX));
506 rc = mgs_find_or_make_fsdb(obd, mti->mti_fsname, &fsdb);
508 CERROR("Can't get db for %s\n", mti->mti_fsname);
512 if (cfs_test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags))
515 if (mti->mti_flags & LDD_F_SV_TYPE_OST)
516 imap = fsdb->fsdb_ost_index_map;
517 else if (mti->mti_flags & LDD_F_SV_TYPE_MDT)
518 imap = fsdb->fsdb_mdt_index_map;
522 if (cfs_test_bit(mti->mti_stripe_index, imap))
527 static __inline__ int next_index(void *index_map, int map_len)
530 for (i = 0; i < map_len * 8; i++)
531 if (!cfs_test_bit(i, index_map)) {
534 CERROR("max index %d exceeded.\n", i);
539 0 newly marked as in use
541 +EALREADY for update of an old index */
542 static int mgs_set_index(struct obd_device *obd, struct mgs_target_info *mti)
549 rc = mgs_find_or_make_fsdb(obd, mti->mti_fsname, &fsdb);
551 CERROR("Can't get db for %s\n", mti->mti_fsname);
555 if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
556 imap = fsdb->fsdb_ost_index_map;
557 } else if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
558 imap = fsdb->fsdb_mdt_index_map;
559 if (fsdb->fsdb_mdt_count >= MAX_MDT_COUNT) {
560 LCONSOLE_ERROR_MSG(0x13f, "The max mdt count"
561 "is %d\n", (int)MAX_MDT_COUNT);
568 if (mti->mti_flags & LDD_F_NEED_INDEX) {
569 rc = next_index(imap, INDEX_MAP_SIZE);
572 mti->mti_stripe_index = rc;
573 if (mti->mti_flags & LDD_F_SV_TYPE_MDT)
574 fsdb->fsdb_mdt_count ++;
577 if (mti->mti_stripe_index >= INDEX_MAP_SIZE * 8) {
578 LCONSOLE_ERROR_MSG(0x13f, "Server %s requested index %d, "
579 "but the max index is %d.\n",
580 mti->mti_svname, mti->mti_stripe_index,
585 if (cfs_test_bit(mti->mti_stripe_index, imap)) {
586 if ((mti->mti_flags & LDD_F_VIRGIN) &&
587 !(mti->mti_flags & LDD_F_WRITECONF)) {
588 LCONSOLE_ERROR_MSG(0x140, "Server %s requested index "
589 "%d, but that index is already in "
590 "use. Use --writeconf to force\n",
592 mti->mti_stripe_index);
595 CDEBUG(D_MGS, "Server %s updating index %d\n",
596 mti->mti_svname, mti->mti_stripe_index);
601 cfs_set_bit(mti->mti_stripe_index, imap);
602 cfs_clear_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags);
603 server_make_name(mti->mti_flags & ~LDD_F_VIRGIN, mti->mti_stripe_index,
604 mti->mti_fsname, mti->mti_svname);
606 CDEBUG(D_MGS, "Set index for %s to %d\n", mti->mti_svname,
607 mti->mti_stripe_index);
612 struct mgs_modify_lookup {
613 struct cfg_marker mml_marker;
617 static int mgs_modify_handler(struct llog_handle *llh, struct llog_rec_hdr *rec,
620 struct mgs_modify_lookup *mml = (struct mgs_modify_lookup *)data;
621 struct cfg_marker *marker;
622 struct lustre_cfg *lcfg = (struct lustre_cfg *)(rec + 1);
623 int cfg_len = rec->lrh_len - sizeof(struct llog_rec_hdr) -
624 sizeof(struct llog_rec_tail);
628 if (rec->lrh_type != OBD_CFG_REC) {
629 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
633 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
635 CERROR("Insane cfg\n");
639 /* We only care about markers */
640 if (lcfg->lcfg_command != LCFG_MARKER)
643 marker = lustre_cfg_buf(lcfg, 1);
644 if ((strcmp(mml->mml_marker.cm_comment, marker->cm_comment) == 0) &&
645 (strcmp(mml->mml_marker.cm_tgtname, marker->cm_tgtname) == 0) &&
646 !(marker->cm_flags & CM_SKIP)) {
647 /* Found a non-skipped marker match */
648 CDEBUG(D_MGS, "Changing rec %u marker %d %x->%x: %s %s\n",
649 rec->lrh_index, marker->cm_step,
650 marker->cm_flags, mml->mml_marker.cm_flags,
651 marker->cm_tgtname, marker->cm_comment);
652 /* Overwrite the old marker llog entry */
653 marker->cm_flags &= ~CM_EXCLUDE; /* in case we're unexcluding */
654 marker->cm_flags |= mml->mml_marker.cm_flags;
655 marker->cm_canceltime = mml->mml_marker.cm_canceltime;
656 /* Header and tail are added back to lrh_len in
657 llog_lvfs_write_rec */
658 rec->lrh_len = cfg_len;
659 rc = llog_write_rec(llh, rec, NULL, 0, (void *)lcfg,
668 /* Modify an existing config log record (for CM_SKIP or CM_EXCLUDE) */
669 static int mgs_modify(struct obd_device *obd, struct fs_db *fsdb,
670 struct mgs_target_info *mti, char *logname,
671 char *devname, char *comment, int flags)
673 struct llog_handle *loghandle;
674 struct lvfs_run_ctxt saved;
675 struct llog_ctxt *ctxt;
676 struct mgs_modify_lookup *mml;
680 CDEBUG(D_MGS, "modify %s/%s/%s fl=%x\n", logname, devname, comment,
683 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
685 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
686 LASSERT(ctxt != NULL);
687 rc = llog_create(ctxt, &loghandle, NULL, logname);
691 rc = llog_init_handle(loghandle, LLOG_F_IS_PLAIN, NULL);
695 if (llog_get_size(loghandle) <= 1)
696 GOTO(out_close, rc = 0);
700 GOTO(out_close, rc = -ENOMEM);
701 strcpy(mml->mml_marker.cm_comment, comment);
702 strcpy(mml->mml_marker.cm_tgtname, devname);
703 /* Modify mostly means cancel */
704 mml->mml_marker.cm_flags = flags;
705 mml->mml_marker.cm_canceltime = flags ? cfs_time_current_sec() : 0;
706 mml->mml_modified = 0;
707 rc = llog_process(NULL, loghandle, mgs_modify_handler, (void *)mml,
709 if (!rc && !mml->mml_modified)
714 rc2 = llog_close(loghandle);
718 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
719 if (rc && rc != -ENODEV)
720 CERROR("modify %s/%s failed %d\n",
721 mti->mti_svname, comment, rc);
726 /******************** config log recording functions *********************/
728 static int record_lcfg(struct obd_device *obd, struct llog_handle *llh,
729 struct lustre_cfg *lcfg)
731 struct lvfs_run_ctxt saved;
732 struct llog_rec_hdr rec;
738 LASSERT(llh->lgh_ctxt);
740 buflen = lustre_cfg_len(lcfg->lcfg_bufcount,
742 rec.lrh_len = llog_data_len(buflen);
743 rec.lrh_type = OBD_CFG_REC;
745 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
746 /* idx = -1 means append */
747 rc = llog_write_rec(llh, &rec, NULL, 0, (void *)lcfg, -1);
748 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
750 CERROR("failed %d\n", rc);
754 static int record_base(struct obd_device *obd, struct llog_handle *llh,
755 char *cfgname, lnet_nid_t nid, int cmd,
756 char *s1, char *s2, char *s3, char *s4)
758 struct lustre_cfg_bufs bufs;
759 struct lustre_cfg *lcfg;
762 CDEBUG(D_MGS, "lcfg %s %#x %s %s %s %s\n", cfgname,
763 cmd, s1, s2, s3, s4);
765 lustre_cfg_bufs_reset(&bufs, cfgname);
767 lustre_cfg_bufs_set_string(&bufs, 1, s1);
769 lustre_cfg_bufs_set_string(&bufs, 2, s2);
771 lustre_cfg_bufs_set_string(&bufs, 3, s3);
773 lustre_cfg_bufs_set_string(&bufs, 4, s4);
775 lcfg = lustre_cfg_new(cmd, &bufs);
778 lcfg->lcfg_nid = nid;
780 rc = record_lcfg(obd, llh, lcfg);
782 lustre_cfg_free(lcfg);
785 CERROR("error %d: lcfg %s %#x %s %s %s %s\n", rc, cfgname,
786 cmd, s1, s2, s3, s4);
792 static inline int record_add_uuid(struct obd_device *obd,
793 struct llog_handle *llh,
794 uint64_t nid, char *uuid)
796 return record_base(obd,llh,NULL,nid,LCFG_ADD_UUID,uuid,0,0,0);
800 static inline int record_add_conn(struct obd_device *obd,
801 struct llog_handle *llh,
805 return record_base(obd,llh,devname,0,LCFG_ADD_CONN,uuid,0,0,0);
808 static inline int record_attach(struct obd_device *obd, struct llog_handle *llh,
809 char *devname, char *type, char *uuid)
811 return record_base(obd,llh,devname,0,LCFG_ATTACH,type,uuid,0,0);
814 static inline int record_setup(struct obd_device *obd, struct llog_handle *llh,
816 char *s1, char *s2, char *s3, char *s4)
818 return record_base(obd,llh,devname,0,LCFG_SETUP,s1,s2,s3,s4);
821 static int record_lov_setup(struct obd_device *obd, struct llog_handle *llh,
822 char *devname, struct lov_desc *desc)
824 struct lustre_cfg_bufs bufs;
825 struct lustre_cfg *lcfg;
828 lustre_cfg_bufs_reset(&bufs, devname);
829 lustre_cfg_bufs_set(&bufs, 1, desc, sizeof(*desc));
830 lcfg = lustre_cfg_new(LCFG_SETUP, &bufs);
833 rc = record_lcfg(obd, llh, lcfg);
835 lustre_cfg_free(lcfg);
839 static int record_lmv_setup(struct obd_device *obd, struct llog_handle *llh,
840 char *devname, struct lmv_desc *desc)
842 struct lustre_cfg_bufs bufs;
843 struct lustre_cfg *lcfg;
846 lustre_cfg_bufs_reset(&bufs, devname);
847 lustre_cfg_bufs_set(&bufs, 1, desc, sizeof(*desc));
848 lcfg = lustre_cfg_new(LCFG_SETUP, &bufs);
850 rc = record_lcfg(obd, llh, lcfg);
852 lustre_cfg_free(lcfg);
856 static inline int record_mdc_add(struct obd_device *obd,
857 struct llog_handle *llh,
858 char *logname, char *mdcuuid,
859 char *mdtuuid, char *index,
862 return record_base(obd,llh,logname,0,LCFG_ADD_MDC,
863 mdtuuid,index,gen,mdcuuid);
866 static inline int record_lov_add(struct obd_device *obd,
867 struct llog_handle *llh,
868 char *lov_name, char *ost_uuid,
869 char *index, char *gen)
871 return record_base(obd,llh,lov_name,0,LCFG_LOV_ADD_OBD,
872 ost_uuid,index,gen,0);
875 static inline int record_mount_opt(struct obd_device *obd,
876 struct llog_handle *llh,
877 char *profile, char *lov_name,
880 return record_base(obd,llh,NULL,0,LCFG_MOUNTOPT,
881 profile,lov_name,mdc_name,0);
884 static int record_marker(struct obd_device *obd, struct llog_handle *llh,
885 struct fs_db *fsdb, __u32 flags,
886 char *tgtname, char *comment)
888 struct cfg_marker marker;
889 struct lustre_cfg_bufs bufs;
890 struct lustre_cfg *lcfg;
893 if (flags & CM_START)
895 marker.cm_step = fsdb->fsdb_gen;
896 marker.cm_flags = flags;
897 marker.cm_vers = LUSTRE_VERSION_CODE;
898 strncpy(marker.cm_tgtname, tgtname, sizeof(marker.cm_tgtname));
899 strncpy(marker.cm_comment, comment, sizeof(marker.cm_comment));
900 marker.cm_createtime = cfs_time_current_sec();
901 marker.cm_canceltime = 0;
902 lustre_cfg_bufs_reset(&bufs, NULL);
903 lustre_cfg_bufs_set(&bufs, 1, &marker, sizeof(marker));
904 lcfg = lustre_cfg_new(LCFG_MARKER, &bufs);
907 rc = record_lcfg(obd, llh, lcfg);
909 lustre_cfg_free(lcfg);
913 static int record_start_log(struct obd_device *obd,
914 struct llog_handle **llh, char *name)
916 static struct obd_uuid cfg_uuid = { .uuid = "config_uuid" };
917 struct lvfs_run_ctxt saved;
918 struct llog_ctxt *ctxt;
922 GOTO(out, rc = -EBUSY);
924 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
926 GOTO(out, rc = -ENODEV);
928 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
929 rc = llog_create(ctxt, llh, NULL, name);
931 llog_init_handle(*llh, LLOG_F_IS_PLAIN, &cfg_uuid);
935 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
940 CERROR("Can't start log %s: %d\n", name, rc);
945 static int record_end_log(struct obd_device *obd, struct llog_handle **llh)
947 struct lvfs_run_ctxt saved;
950 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
952 rc = llog_close(*llh);
955 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
959 static int mgs_log_is_empty(struct obd_device *obd, char *name)
961 struct lvfs_run_ctxt saved;
962 struct llog_handle *llh;
963 struct llog_ctxt *ctxt;
966 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
967 LASSERT(ctxt != NULL);
968 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
969 rc = llog_create(ctxt, &llh, NULL, name);
971 llog_init_handle(llh, LLOG_F_IS_PLAIN, NULL);
972 rc = llog_get_size(llh);
975 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
977 /* header is record 1 */
981 /******************** config "macros" *********************/
983 /* write an lcfg directly into a log (with markers) */
984 static int mgs_write_log_direct(struct obd_device *obd, struct fs_db *fsdb,
985 char *logname, struct lustre_cfg *lcfg,
986 char *devname, char *comment)
988 struct llog_handle *llh = NULL;
995 rc = record_start_log(obd, &llh, logname);
999 /* FIXME These should be a single journal transaction */
1000 rc = record_marker(obd, llh, fsdb, CM_START, devname, comment);
1002 rc = record_lcfg(obd, llh, lcfg);
1004 rc = record_marker(obd, llh, fsdb, CM_END, devname, comment);
1005 rc = record_end_log(obd, &llh);
1010 /* write the lcfg in all logs for the given fs */
1011 int mgs_write_log_direct_all(struct obd_device *obd, struct fs_db *fsdb,
1012 struct mgs_target_info *mti,
1013 struct lustre_cfg *lcfg,
1014 char *devname, char *comment)
1016 struct mgs_obd *mgs = &obd->u.mgs;
1017 cfs_list_t dentry_list;
1018 struct l_linux_dirent *dirent, *n;
1019 char *fsname = mti->mti_fsname;
1021 int rc = 0, len = strlen(fsname);
1024 /* We need to set params for any future logs
1025 as well. FIXME Append this file to every new log.
1026 Actually, we should store as params (text), not llogs. Or
1028 name_create(&logname, fsname, "-params");
1029 if (mgs_log_is_empty(obd, logname)) {
1030 struct llog_handle *llh = NULL;
1031 rc = record_start_log(obd, &llh, logname);
1032 record_end_log(obd, &llh);
1034 name_destroy(&logname);
1038 /* Find all the logs in the CONFIGS directory */
1039 rc = class_dentry_readdir(obd, mgs->mgs_configs_dir,
1040 mgs->mgs_vfsmnt, &dentry_list);
1042 CERROR("Can't read %s dir\n", MOUNT_CONFIGS_DIR);
1046 /* Could use fsdb index maps instead of directory listing */
1047 cfs_list_for_each_entry_safe(dirent, n, &dentry_list, lld_list) {
1048 cfs_list_del(&dirent->lld_list);
1049 /* don't write to sptlrpc rule log */
1050 if (strncmp(fsname, dirent->lld_name, len) == 0 &&
1051 strstr(dirent->lld_name, "-sptlrpc") == NULL) {
1052 CDEBUG(D_MGS, "Changing log %s\n", dirent->lld_name);
1053 /* Erase any old settings of this same parameter */
1054 mgs_modify(obd, fsdb, mti, dirent->lld_name, devname,
1056 /* Write the new one */
1058 rc = mgs_write_log_direct(obd, fsdb,
1063 CERROR("err %d writing log %s\n", rc,
1067 OBD_FREE(dirent, sizeof(*dirent));
1075 struct mgs_target_info *comp_tmti;
1076 struct mgs_target_info *comp_mti;
1077 struct fs_db *comp_fsdb;
1078 struct obd_device *comp_obd;
1081 static int mgs_write_log_mdc_to_mdt(struct obd_device *, struct fs_db *,
1082 struct mgs_target_info *, char *);
1083 static int mgs_write_log_osc_to_lov(struct obd_device *obd, struct fs_db *fsdb,
1084 struct mgs_target_info *mti,
1085 char *logname, char *suffix, char *lovname,
1086 enum lustre_sec_part sec_part, int flags);
1087 static void name_create_mdt_and_lov(char **logname, char **lovname,
1088 struct fs_db *fsdb, int i);
1090 static int mgs_steal_llog_handler(struct llog_handle *llh,
1091 struct llog_rec_hdr *rec,
1094 struct obd_device * obd;
1095 struct mgs_target_info *mti, *tmti;
1097 int cfg_len = rec->lrh_len;
1098 char *cfg_buf = (char*) (rec + 1);
1099 struct lustre_cfg *lcfg;
1101 struct llog_handle *mdt_llh = NULL;
1102 static int got_an_osc_or_mdc = 0;
1103 /* 0: not found any osc/mdc;
1107 static int last_step = -1;
1111 mti = ((struct temp_comp*)data)->comp_mti;
1112 tmti = ((struct temp_comp*)data)->comp_tmti;
1113 fsdb = ((struct temp_comp*)data)->comp_fsdb;
1114 obd = ((struct temp_comp*)data)->comp_obd;
1116 if (rec->lrh_type != OBD_CFG_REC) {
1117 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
1121 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
1123 CERROR("Insane cfg\n");
1127 lcfg = (struct lustre_cfg *)cfg_buf;
1129 if (lcfg->lcfg_command == LCFG_MARKER) {
1130 struct cfg_marker *marker;
1131 marker = lustre_cfg_buf(lcfg, 1);
1132 if (!strncmp(marker->cm_comment,"add osc",7) &&
1133 (marker->cm_flags & CM_START)){
1134 got_an_osc_or_mdc = 1;
1135 strncpy(tmti->mti_svname, marker->cm_tgtname,
1136 sizeof(tmti->mti_svname));
1137 rc = record_start_log(obd, &mdt_llh, mti->mti_svname);
1138 rc = record_marker(obd, mdt_llh, fsdb, CM_START,
1139 mti->mti_svname,"add osc(copied)");
1140 rc = record_end_log(obd, &mdt_llh);
1141 last_step = marker->cm_step;
1144 if (!strncmp(marker->cm_comment,"add osc",7) &&
1145 (marker->cm_flags & CM_END)){
1146 LASSERT(last_step == marker->cm_step);
1148 got_an_osc_or_mdc = 0;
1149 rc = record_start_log(obd, &mdt_llh, mti->mti_svname);
1150 rc = record_marker(obd, mdt_llh, fsdb, CM_END,
1151 mti->mti_svname,"add osc(copied)");
1152 rc = record_end_log(obd, &mdt_llh);
1155 if (!strncmp(marker->cm_comment,"add mdc",7) &&
1156 (marker->cm_flags & CM_START)){
1157 got_an_osc_or_mdc = 2;
1158 last_step = marker->cm_step;
1159 memcpy(tmti->mti_svname, marker->cm_tgtname,
1160 strlen(marker->cm_tgtname));
1164 if (!strncmp(marker->cm_comment,"add mdc",7) &&
1165 (marker->cm_flags & CM_END)){
1166 LASSERT(last_step == marker->cm_step);
1168 got_an_osc_or_mdc = 0;
1173 if (got_an_osc_or_mdc == 0 || last_step < 0)
1176 if (lcfg->lcfg_command == LCFG_ADD_UUID) {
1178 nodenid = lcfg->lcfg_nid;
1180 tmti->mti_nids[tmti->mti_nid_count] = nodenid;
1181 tmti->mti_nid_count++;
1186 if (lcfg->lcfg_command == LCFG_SETUP) {
1189 target = lustre_cfg_string(lcfg, 1);
1190 memcpy(tmti->mti_uuid, target, strlen(target));
1194 /* ignore client side sptlrpc_conf_log */
1195 if (lcfg->lcfg_command == LCFG_SPTLRPC_CONF)
1198 if (lcfg->lcfg_command == LCFG_ADD_MDC) {
1201 if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1)
1204 memcpy(tmti->mti_fsname, mti->mti_fsname,
1205 strlen(mti->mti_fsname));
1206 tmti->mti_stripe_index = index;
1208 mgs_write_log_mdc_to_mdt(obd, fsdb, tmti, mti->mti_svname);
1209 memset(tmti, 0, sizeof(*tmti));
1213 if (lcfg->lcfg_command == LCFG_LOV_ADD_OBD) {
1216 char *logname, *lovname;
1218 name_create_mdt_and_lov(&logname, &lovname, fsdb,
1219 mti->mti_stripe_index);
1220 sprintf(mdt_index, "-MDT%04x", mti->mti_stripe_index);
1222 if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1) {
1223 name_destroy(&logname);
1224 name_destroy(&lovname);
1228 tmti->mti_stripe_index = index;
1229 mgs_write_log_osc_to_lov(obd, fsdb, tmti, logname,
1232 name_destroy(&logname);
1233 name_destroy(&lovname);
1239 /* fsdb->fsdb_mutex is already held in mgs_write_log_target*/
1240 /* stealed from mgs_get_fsdb_from_llog*/
1241 static int mgs_steal_llog_for_mdt_from_client(struct obd_device *obd,
1243 struct temp_comp* comp)
1245 struct llog_handle *loghandle;
1246 struct lvfs_run_ctxt saved;
1247 struct mgs_target_info *tmti;
1248 struct llog_ctxt *ctxt;
1252 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
1253 LASSERT(ctxt != NULL);
1255 OBD_ALLOC_PTR(tmti);
1259 comp->comp_tmti = tmti;
1260 comp->comp_obd = obd;
1262 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
1264 rc = llog_create(ctxt, &loghandle, NULL, client_name);
1268 rc = llog_init_handle(loghandle, LLOG_F_IS_PLAIN, NULL);
1270 GOTO(out_close, rc);
1272 rc = llog_process(NULL, loghandle, mgs_steal_llog_handler,
1273 (void *)comp, NULL);
1274 CDEBUG(D_MGS, "steal llog re = %d\n", rc);
1276 rc2 = llog_close(loghandle);
1280 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
1282 llog_ctxt_put(ctxt);
1286 /* lmv is the second thing for client logs */
1287 /* copied from mgs_write_log_lov. Please refer to that. */
1288 static int mgs_write_log_lmv(struct obd_device *obd, struct fs_db *fsdb,
1289 struct mgs_target_info *mti,
1290 char *logname, char *lmvname)
1292 struct llog_handle *llh = NULL;
1293 struct lmv_desc *lmvdesc;
1298 CDEBUG(D_MGS, "Writing lmv(%s) log for %s\n", lmvname,logname);
1300 OBD_ALLOC_PTR(lmvdesc);
1301 if (lmvdesc == NULL)
1303 lmvdesc->ld_active_tgt_count = 0;
1304 lmvdesc->ld_tgt_count = 0;
1305 sprintf((char*)lmvdesc->ld_uuid.uuid, "%s_UUID", lmvname);
1306 uuid = (char *)lmvdesc->ld_uuid.uuid;
1308 rc = record_start_log(obd, &llh, logname);
1309 rc = record_marker(obd, llh, fsdb, CM_START, lmvname, "lmv setup");
1310 rc = record_attach(obd, llh, lmvname, "lmv", uuid);
1311 rc = record_lmv_setup(obd, llh, lmvname, lmvdesc);
1312 rc = record_marker(obd, llh, fsdb, CM_END, lmvname, "lmv setup");
1313 rc = record_end_log(obd, &llh);
1315 OBD_FREE_PTR(lmvdesc);
1319 /* lov is the first thing in the mdt and client logs */
1320 static int mgs_write_log_lov(struct obd_device *obd, struct fs_db *fsdb,
1321 struct mgs_target_info *mti,
1322 char *logname, char *lovname)
1324 struct llog_handle *llh = NULL;
1325 struct lov_desc *lovdesc;
1330 CDEBUG(D_MGS, "Writing lov(%s) log for %s\n", lovname, logname);
1333 #01 L attach 0:lov_mdsA 1:lov 2:71ccb_lov_mdsA_19f961a9e1
1334 #02 L lov_setup 0:lov_mdsA 1:(struct lov_desc)
1335 uuid=lov1_UUID, stripe count=1, size=1048576, offset=0, pattern=0
1338 /* FIXME just make lov_setup accept empty desc (put uuid in buf 2) */
1339 OBD_ALLOC_PTR(lovdesc);
1340 if (lovdesc == NULL)
1342 lovdesc->ld_magic = LOV_DESC_MAGIC;
1343 lovdesc->ld_tgt_count = 0;
1344 /* Defaults. Can be changed later by lcfg config_param */
1345 lovdesc->ld_default_stripe_count = 1;
1346 lovdesc->ld_pattern = LOV_PATTERN_RAID0;
1347 lovdesc->ld_default_stripe_size = 1024 * 1024;
1348 lovdesc->ld_default_stripe_offset = -1;
1349 lovdesc->ld_qos_maxage = QOS_DEFAULT_MAXAGE;
1350 sprintf((char*)lovdesc->ld_uuid.uuid, "%s_UUID", lovname);
1351 /* can these be the same? */
1352 uuid = (char *)lovdesc->ld_uuid.uuid;
1354 /* This should always be the first entry in a log.
1355 rc = mgs_clear_log(obd, logname); */
1356 rc = record_start_log(obd, &llh, logname);
1359 /* FIXME these should be a single journal transaction */
1360 rc = record_marker(obd, llh, fsdb, CM_START, lovname, "lov setup");
1361 rc = record_attach(obd, llh, lovname, "lov", uuid);
1362 rc = record_lov_setup(obd, llh, lovname, lovdesc);
1363 rc = record_marker(obd, llh, fsdb, CM_END, lovname, "lov setup");
1364 rc = record_end_log(obd, &llh);
1368 OBD_FREE_PTR(lovdesc);
1372 /* add failnids to open log */
1373 static int mgs_write_log_failnids(struct obd_device *obd,
1374 struct mgs_target_info *mti,
1375 struct llog_handle *llh,
1378 char *failnodeuuid = NULL;
1379 char *ptr = mti->mti_params;
1384 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) nal=90 0: 1:uml1_UUID
1385 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
1386 #05 L setup 0:OSC_uml1_ost1_mdsA 1:ost1_UUID 2:uml1_UUID
1387 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) nal=90 0: 1:uml2_UUID
1388 #0x L add_uuid nid=2@elan(0x1000000000002) nal=90 0: 1:uml2_UUID
1389 #07 L add_conn 0:OSC_uml1_ost1_mdsA 1:uml2_UUID
1392 /* Pull failnid info out of params string */
1393 while (class_find_param(ptr, PARAM_FAILNODE, &ptr) == 0) {
1394 while (class_parse_nid(ptr, &nid, &ptr) == 0) {
1395 if (failnodeuuid == NULL) {
1396 /* We don't know the failover node name,
1397 so just use the first nid as the uuid */
1398 rc = name_create(&failnodeuuid,
1399 libcfs_nid2str(nid), "");
1403 CDEBUG(D_MGS, "add nid %s for failover uuid %s, "
1404 "client %s\n", libcfs_nid2str(nid),
1405 failnodeuuid, cliname);
1406 rc = record_add_uuid(obd, llh, nid, failnodeuuid);
1409 rc = record_add_conn(obd, llh, cliname, failnodeuuid);
1410 name_destroy(&failnodeuuid);
1411 failnodeuuid = NULL;
1418 static int mgs_write_log_mdc_to_lmv(struct obd_device *obd, struct fs_db *fsdb,
1419 struct mgs_target_info *mti,
1420 char *logname, char *lmvname)
1422 struct llog_handle *llh = NULL;
1423 char *mdcname, *nodeuuid, *mdcuuid, *lmvuuid;
1428 if (mgs_log_is_empty(obd, logname)) {
1429 CERROR("log is empty! Logical error\n");
1433 CDEBUG(D_MGS, "adding mdc for %s to log %s:lmv(%s)\n",
1434 mti->mti_svname, logname, lmvname);
1436 name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
1437 name_create(&mdcname, mti->mti_svname, "-mdc");
1438 name_create(&mdcuuid, mdcname, "_UUID");
1439 name_create(&lmvuuid, lmvname, "_UUID");
1441 rc = record_start_log(obd, &llh, logname);
1442 rc = record_marker(obd, llh, fsdb, CM_START, mti->mti_svname,
1445 for (i = 0; i < mti->mti_nid_count; i++) {
1446 CDEBUG(D_MGS, "add nid %s for mdt\n",
1447 libcfs_nid2str(mti->mti_nids[i]));
1449 rc = record_add_uuid(obd, llh, mti->mti_nids[i], nodeuuid);
1452 rc = record_attach(obd, llh, mdcname, LUSTRE_MDC_NAME, lmvuuid);
1453 rc = record_setup(obd, llh, mdcname, mti->mti_uuid, nodeuuid, 0, 0);
1454 rc = mgs_write_log_failnids(obd, mti, llh, mdcname);
1455 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
1456 rc = record_mdc_add(obd, llh, lmvname, mdcuuid, mti->mti_uuid,
1458 rc = record_marker(obd, llh, fsdb, CM_END, mti->mti_svname,
1460 rc = record_end_log(obd, &llh);
1462 name_destroy(&lmvuuid);
1463 name_destroy(&mdcuuid);
1464 name_destroy(&mdcname);
1465 name_destroy(&nodeuuid);
1469 /* add new mdc to already existent MDS */
1470 static int mgs_write_log_mdc_to_mdt(struct obd_device *obd, struct fs_db *fsdb,
1471 struct mgs_target_info *mti, char *logname)
1473 struct llog_handle *llh = NULL;
1474 char *nodeuuid, *mdcname, *mdcuuid, *mdtuuid;
1475 int idx = mti->mti_stripe_index;
1480 if (mgs_log_is_empty(obd, logname)) {
1481 CERROR("log is empty! Logical error\n");
1485 CDEBUG(D_MGS, "adding mdc index %d to %s\n", idx, logname);
1487 name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
1488 snprintf(index, sizeof(index), "-mdc%04x", idx);
1489 name_create(&mdcname, logname, index);
1490 name_create(&mdcuuid, mdcname, "_UUID");
1491 name_create(&mdtuuid, logname, "_UUID");
1493 rc = record_start_log(obd, &llh, logname);
1494 rc = record_marker(obd, llh, fsdb, CM_START, mti->mti_svname, "add mdc");
1495 for (i = 0; i < mti->mti_nid_count; i++) {
1496 CDEBUG(D_MGS, "add nid %s for mdt\n",
1497 libcfs_nid2str(mti->mti_nids[i]));
1498 rc = record_add_uuid(obd, llh, mti->mti_nids[i], nodeuuid);
1500 rc = record_attach(obd, llh, mdcname, LUSTRE_MDC_NAME, mdcuuid);
1501 rc = record_setup(obd, llh, mdcname, mti->mti_uuid, nodeuuid, 0, 0);
1502 rc = mgs_write_log_failnids(obd, mti, llh, mdcname);
1503 snprintf(index, sizeof(index), "%d", idx);
1505 rc = record_mdc_add(obd, llh, logname, mdcuuid, mti->mti_uuid,
1507 rc = record_marker(obd, llh, fsdb, CM_END, mti->mti_svname, "add mdc");
1508 rc = record_end_log(obd, &llh);
1510 name_destroy(&mdcuuid);
1511 name_destroy(&mdcname);
1512 name_destroy(&nodeuuid);
1513 name_destroy(&mdtuuid);
1517 static int mgs_write_log_mdt0(struct obd_device *obd, struct fs_db *fsdb,
1518 struct mgs_target_info *mti)
1520 char *log = mti->mti_svname;
1521 struct llog_handle *llh = NULL;
1522 char *uuid, *lovname;
1524 char *ptr = mti->mti_params;
1525 int rc = 0, failout = 0;
1528 OBD_ALLOC(uuid, sizeof(struct obd_uuid));
1532 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
1533 failout = (strncmp(ptr, "failout", 7) == 0);
1535 name_create(&lovname, log, "-mdtlov");
1536 if (mgs_log_is_empty(obd, log))
1537 rc = mgs_write_log_lov(obd, fsdb, mti, log, lovname);
1539 sprintf(uuid, "%s_UUID", log);
1540 sprintf(mdt_index, "%d", mti->mti_stripe_index);
1542 /* add MDT itself */
1543 rc = record_start_log(obd, &llh, log);
1547 /* FIXME this whole fn should be a single journal transaction */
1548 rc = record_marker(obd, llh, fsdb, CM_START, log, "add mdt");
1549 rc = record_attach(obd, llh, log, LUSTRE_MDT_NAME, uuid);
1550 rc = record_mount_opt(obd, llh, log, lovname, NULL);
1551 rc = record_setup(obd, llh, log, uuid, mdt_index, lovname,
1552 failout ? "n" : "f");
1553 rc = record_marker(obd, llh, fsdb, CM_END, log, "add mdt");
1554 rc = record_end_log(obd, &llh);
1556 name_destroy(&lovname);
1557 OBD_FREE(uuid, sizeof(struct obd_uuid));
1561 static inline void name_create_mdt(char **logname, char *fsname, int i)
1565 sprintf(mdt_index, "-MDT%04x", i);
1566 name_create(logname, fsname, mdt_index);
1569 static void name_create_mdt_and_lov(char **logname, char **lovname,
1570 struct fs_db *fsdb, int i)
1572 name_create_mdt(logname, fsdb->fsdb_name, i);
1574 if (i == 0 && cfs_test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
1575 name_create(lovname, fsdb->fsdb_name, "-mdtlov");
1577 name_create(lovname, *logname, "-mdtlov");
1580 static inline void name_create_mdt_osc(char **oscname, char *ostname,
1581 struct fs_db *fsdb, int i)
1585 if (i == 0 && cfs_test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
1586 sprintf(suffix, "-osc");
1588 sprintf(suffix, "-osc-MDT%04x", i);
1589 name_create(oscname, ostname, suffix);
1592 /* envelope method for all layers log */
1593 static int mgs_write_log_mdt(struct obd_device *obd, struct fs_db *fsdb,
1594 struct mgs_target_info *mti)
1596 struct llog_handle *llh = NULL;
1598 struct temp_comp comp = { 0 };
1602 CDEBUG(D_MGS, "writing new mdt %s\n", mti->mti_svname);
1606 if (mti->mti_flags & LDD_F_UPGRADE14) {
1607 /* We're starting with an old uuid. Assume old name for lov
1608 as well since the lov entry already exists in the log. */
1609 CDEBUG(D_MGS, "old mds uuid %s\n", mti->mti_uuid);
1610 if (strncmp(mti->mti_uuid, fsdb->fsdb_mdtlov + 4,
1611 strlen(fsdb->fsdb_mdtlov) - 4) != 0) {
1612 CERROR("old mds uuid %s doesn't match log %s (%s)\n",
1613 mti->mti_uuid, fsdb->fsdb_mdtlov,
1614 fsdb->fsdb_mdtlov + 4);
1618 /* end COMPAT_146 */
1620 if (mti->mti_uuid[0] == '\0') {
1621 /* Make up our own uuid */
1622 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
1623 "%s_UUID", mti->mti_svname);
1627 rc = mgs_write_log_mdt0(obd, fsdb, mti);
1629 /* Append the mdt info to the client log */
1630 name_create(&cliname, mti->mti_fsname, "-client");
1632 if (mgs_log_is_empty(obd, cliname)) {
1633 /* Start client log */
1634 rc = mgs_write_log_lov(obd, fsdb, mti, cliname,
1636 rc = mgs_write_log_lmv(obd, fsdb, mti, cliname,
1641 #09 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
1642 #10 L attach 0:MDC_uml1_mdsA_MNT_client 1:mdc 2:1d834_MNT_client_03f
1643 #11 L setup 0:MDC_uml1_mdsA_MNT_client 1:mdsA_UUID 2:uml1_UUID
1644 #12 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
1645 #13 L add_conn 0:MDC_uml1_mdsA_MNT_client 1:uml2_UUID
1646 #14 L mount_option 0: 1:client 2:lov1 3:MDC_uml1_mdsA_MNT_client
1651 if (mti->mti_flags & LDD_F_UPGRADE14) {
1652 rc = record_start_log(obd, &llh, cliname);
1656 rc = record_marker(obd, llh, fsdb, CM_START,
1657 mti->mti_svname,"add mdc");
1659 /* Old client log already has MDC entry, but needs mount opt
1660 for new client name (lustre-client) */
1661 /* FIXME Old MDT log already has an old mount opt
1662 which we should remove (currently handled by
1663 class_del_profiles()) */
1664 rc = record_mount_opt(obd, llh, cliname, fsdb->fsdb_clilov,
1666 /* end COMPAT_146 */
1668 rc = record_marker(obd, llh, fsdb, CM_END,
1669 mti->mti_svname, "add mdc");
1673 /* copy client info about lov/lmv */
1674 comp.comp_mti = mti;
1675 comp.comp_fsdb = fsdb;
1677 rc = mgs_steal_llog_for_mdt_from_client(obd, cliname,
1680 rc = mgs_write_log_mdc_to_lmv(obd, fsdb, mti, cliname,
1683 rc = record_start_log(obd, &llh, cliname);
1687 rc = record_marker(obd, llh, fsdb, CM_START, cliname,
1689 rc = record_mount_opt(obd, llh, cliname, fsdb->fsdb_clilov,
1691 rc = record_marker(obd, llh, fsdb, CM_END, cliname,
1695 rc = record_end_log(obd, &llh);
1697 name_destroy(&cliname);
1699 // for_all_existing_mdt except current one
1700 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
1702 if (i != mti->mti_stripe_index &&
1703 cfs_test_bit(i, fsdb->fsdb_mdt_index_map)) {
1704 name_create_mdt(&mdtname, mti->mti_fsname, i);
1705 rc = mgs_write_log_mdc_to_mdt(obd, fsdb, mti, mdtname);
1706 name_destroy(&mdtname);
1713 /* Add the ost info to the client/mdt lov */
1714 static int mgs_write_log_osc_to_lov(struct obd_device *obd, struct fs_db *fsdb,
1715 struct mgs_target_info *mti,
1716 char *logname, char *suffix, char *lovname,
1717 enum lustre_sec_part sec_part, int flags)
1719 struct llog_handle *llh = NULL;
1720 char *nodeuuid, *oscname, *oscuuid, *lovuuid, *svname;
1725 CDEBUG(D_INFO, "adding osc for %s to log %s\n",
1726 mti->mti_svname, logname);
1728 if (mgs_log_is_empty(obd, logname)) {
1729 CERROR("log is empty! Logical error\n");
1733 name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
1734 name_create(&svname, mti->mti_svname, "-osc");
1735 name_create(&oscname, svname, suffix);
1736 name_create(&oscuuid, oscname, "_UUID");
1737 name_create(&lovuuid, lovname, "_UUID");
1740 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
1742 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
1743 #04 L attach 0:OSC_uml1_ost1_MNT_client 1:osc 2:89070_lov1_a41dff51a
1744 #05 L setup 0:OSC_uml1_ost1_MNT_client 1:ost1_UUID 2:uml1_UUID
1746 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
1747 #07 L add_conn 0:OSC_uml1_ost1_MNT_client 1:uml2_UUID
1748 #08 L lov_modify_tgts add 0:lov1 1:ost1_UUID 2(index):0 3(gen):1
1751 rc = record_start_log(obd, &llh, logname);
1754 /* FIXME these should be a single journal transaction */
1755 rc = record_marker(obd, llh, fsdb, CM_START | flags, mti->mti_svname,
1757 for (i = 0; i < mti->mti_nid_count; i++) {
1758 CDEBUG(D_MGS, "add nid %s\n", libcfs_nid2str(mti->mti_nids[i]));
1759 rc = record_add_uuid(obd, llh, mti->mti_nids[i], nodeuuid);
1761 rc = record_attach(obd, llh, oscname, LUSTRE_OSC_NAME, lovuuid);
1762 rc = record_setup(obd, llh, oscname, mti->mti_uuid, nodeuuid, 0, 0);
1763 rc = mgs_write_log_failnids(obd, mti, llh, oscname);
1764 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
1765 rc = record_lov_add(obd, llh, lovname, mti->mti_uuid, index, "1");
1766 rc = record_marker(obd, llh, fsdb, CM_END | flags, mti->mti_svname,
1768 rc = record_end_log(obd, &llh);
1770 name_destroy(&lovuuid);
1771 name_destroy(&oscuuid);
1772 name_destroy(&oscname);
1773 name_destroy(&svname);
1774 name_destroy(&nodeuuid);
1778 static int mgs_write_log_ost(struct obd_device *obd, struct fs_db *fsdb,
1779 struct mgs_target_info *mti)
1781 struct llog_handle *llh = NULL;
1782 char *logname, *lovname;
1783 char *ptr = mti->mti_params;
1784 int rc, flags = 0, failout = 0, i;
1787 CDEBUG(D_MGS, "writing new ost %s\n", mti->mti_svname);
1789 /* The ost startup log */
1791 /* If the ost log already exists, that means that someone reformatted
1792 the ost and it called target_add again. */
1793 if (!mgs_log_is_empty(obd, mti->mti_svname)) {
1794 LCONSOLE_ERROR_MSG(0x141, "The config log for %s already "
1795 "exists, yet the server claims it never "
1796 "registered. It may have been reformatted, "
1797 "or the index changed. writeconf the MDT to "
1798 "regenerate all logs.\n", mti->mti_svname);
1803 attach obdfilter ost1 ost1_UUID
1804 setup /dev/loop2 ldiskfs f|n errors=remount-ro,user_xattr
1806 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
1807 failout = (strncmp(ptr, "failout", 7) == 0);
1808 rc = record_start_log(obd, &llh, mti->mti_svname);
1811 /* FIXME these should be a single journal transaction */
1812 rc = record_marker(obd, llh, fsdb, CM_START, mti->mti_svname,"add ost");
1813 if (*mti->mti_uuid == '\0')
1814 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
1815 "%s_UUID", mti->mti_svname);
1816 rc = record_attach(obd, llh, mti->mti_svname,
1817 "obdfilter"/*LUSTRE_OST_NAME*/, mti->mti_uuid);
1818 rc = record_setup(obd, llh, mti->mti_svname,
1819 "dev"/*ignored*/, "type"/*ignored*/,
1820 failout ? "n" : "f", 0/*options*/);
1821 rc = record_marker(obd, llh, fsdb, CM_END, mti->mti_svname, "add ost");
1822 rc = record_end_log(obd, &llh);
1824 /* We also have to update the other logs where this osc is part of
1827 if (cfs_test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
1828 /* If we're upgrading, the old mdt log already has our
1829 entry. Let's do a fake one for fun. */
1830 /* Note that we can't add any new failnids, since we don't
1831 know the old osc names. */
1832 flags = CM_SKIP | CM_UPGRADE146;
1834 } else if ((mti->mti_flags & LDD_F_UPDATE) != LDD_F_UPDATE) {
1835 /* If the update flag isn't set, don't update client/mdt
1838 LCONSOLE_WARN("Client log for %s was not updated; writeconf "
1839 "the MDT first to regenerate it.\n",
1843 /* Add ost to all MDT lov defs */
1844 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
1845 if (cfs_test_bit(i, fsdb->fsdb_mdt_index_map)) {
1848 name_create_mdt_and_lov(&logname, &lovname, fsdb, i);
1849 sprintf(mdt_index, "-MDT%04x", i);
1850 mgs_write_log_osc_to_lov(obd, fsdb, mti, logname,
1852 LUSTRE_SP_MDT, flags);
1853 name_destroy(&logname);
1854 name_destroy(&lovname);
1858 /* Append ost info to the client log */
1859 name_create(&logname, mti->mti_fsname, "-client");
1860 if (mgs_log_is_empty(obd, logname)) {
1861 /* Start client log */
1862 rc = mgs_write_log_lov(obd, fsdb, mti, logname,
1864 rc = mgs_write_log_lmv(obd, fsdb, mti, logname,
1867 mgs_write_log_osc_to_lov(obd, fsdb, mti, logname, "",
1868 fsdb->fsdb_clilov, LUSTRE_SP_CLI, flags);
1869 name_destroy(&logname);
1873 static __inline__ int mgs_param_empty(char *ptr)
1877 if ((tmp = strchr(ptr, '=')) && (*(++tmp) == '\0'))
1882 static int mgs_write_log_failnid_internal(struct obd_device *obd,
1884 struct mgs_target_info *mti,
1885 char *logname, char *cliname)
1888 struct llog_handle *llh = NULL;
1890 if (mgs_param_empty(mti->mti_params)) {
1891 /* Remove _all_ failnids */
1892 rc = mgs_modify(obd, fsdb, mti, logname,
1893 mti->mti_svname, "add failnid", CM_SKIP);
1897 /* Otherwise failover nids are additive */
1898 rc = record_start_log(obd, &llh, logname);
1900 /* FIXME this should be a single journal transaction */
1901 rc = record_marker(obd, llh, fsdb, CM_START,
1902 mti->mti_svname, "add failnid");
1903 rc = mgs_write_log_failnids(obd, mti, llh, cliname);
1904 rc = record_marker(obd, llh, fsdb, CM_END,
1905 mti->mti_svname, "add failnid");
1906 rc = record_end_log(obd, &llh);
1913 /* Add additional failnids to an existing log.
1914 The mdc/osc must have been added to logs first */
1915 /* tcp nids must be in dotted-quad ascii -
1916 we can't resolve hostnames from the kernel. */
1917 static int mgs_write_log_add_failnid(struct obd_device *obd, struct fs_db *fsdb,
1918 struct mgs_target_info *mti)
1920 char *logname, *cliname;
1924 /* FIXME we currently can't erase the failnids
1925 * given when a target first registers, since they aren't part of
1926 * an "add uuid" stanza */
1928 /* Verify that we know about this target */
1929 if (mgs_log_is_empty(obd, mti->mti_svname)) {
1930 LCONSOLE_ERROR_MSG(0x142, "The target %s has not registered "
1931 "yet. It must be started before failnids "
1932 "can be added.\n", mti->mti_svname);
1936 /* Create mdc/osc client name (e.g. lustre-OST0001-osc) */
1937 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
1938 name_create(&cliname, mti->mti_svname, "-mdc");
1939 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
1940 name_create(&cliname, mti->mti_svname, "-osc");
1945 /* Add failover nids to the client log */
1946 name_create(&logname, mti->mti_fsname, "-client");
1947 rc = mgs_write_log_failnid_internal(obd, fsdb, mti, logname, cliname);
1948 name_destroy(&logname);
1949 name_destroy(&cliname);
1951 if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
1952 /* Add OST failover nids to the MDT logs as well */
1955 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
1956 if (!cfs_test_bit(i, fsdb->fsdb_mdt_index_map))
1958 name_create_mdt(&logname, mti->mti_fsname, i);
1959 name_create_mdt_osc(&cliname, mti->mti_svname, fsdb, i);
1960 rc = mgs_write_log_failnid_internal(obd, fsdb, mti,
1962 name_destroy(&cliname);
1963 name_destroy(&logname);
1970 static int mgs_wlp_lcfg(struct obd_device *obd, struct fs_db *fsdb,
1971 struct mgs_target_info *mti,
1972 char *logname, struct lustre_cfg_bufs *bufs,
1973 char *tgtname, char *ptr)
1975 char comment[MTI_NAME_MAXLEN];
1977 struct lustre_cfg *lcfg;
1980 /* Erase any old settings of this same parameter */
1981 memcpy(comment, ptr, MTI_NAME_MAXLEN);
1982 comment[MTI_NAME_MAXLEN - 1] = 0;
1983 /* But don't try to match the value. */
1984 if ((tmp = strchr(comment, '=')))
1986 /* FIXME we should skip settings that are the same as old values */
1987 rc = mgs_modify(obd, fsdb, mti, logname, tgtname, comment, CM_SKIP);
1988 del = mgs_param_empty(ptr);
1990 LCONSOLE_INFO("%sing parameter %s.%s in log %s\n", del ? "Disabl" : rc ?
1991 "Sett" : "Modify", tgtname, comment, logname);
1995 lustre_cfg_bufs_reset(bufs, tgtname);
1996 lustre_cfg_bufs_set_string(bufs, 1, ptr);
1997 lcfg = lustre_cfg_new(LCFG_PARAM, bufs);
2000 rc = mgs_write_log_direct(obd, fsdb, logname, lcfg, tgtname, comment);
2001 lustre_cfg_free(lcfg);
2005 /* write global variable settings into log */
2006 static int mgs_write_log_sys(struct obd_device *obd, struct fs_db *fsdb,
2007 struct mgs_target_info *mti, char *sys, char *ptr)
2009 struct lustre_cfg_bufs bufs;
2010 struct lustre_cfg *lcfg;
2012 int rc, cmd, convert = 1;
2014 if (class_match_param(ptr, PARAM_TIMEOUT, &tmp) == 0) {
2015 cmd = LCFG_SET_TIMEOUT;
2016 } else if (class_match_param(ptr, PARAM_LDLM_TIMEOUT, &tmp) == 0) {
2017 cmd = LCFG_SET_LDLM_TIMEOUT;
2018 /* Check for known params here so we can return error to lctl */
2019 } else if ((class_match_param(ptr, PARAM_AT_MIN, &tmp) == 0) ||
2020 (class_match_param(ptr, PARAM_AT_MAX, &tmp) == 0) ||
2021 (class_match_param(ptr, PARAM_AT_EXTRA, &tmp) == 0) ||
2022 (class_match_param(ptr, PARAM_AT_EARLY_MARGIN, &tmp) == 0) ||
2023 (class_match_param(ptr, PARAM_AT_HISTORY, &tmp) == 0)) {
2025 } else if (class_match_param(ptr, PARAM_JOBID_VAR, &tmp) == 0) {
2026 convert = 0; /* Don't convert string value to integer */
2032 if (mgs_param_empty(ptr))
2033 CDEBUG(D_MGS, "global '%s' removed\n", sys);
2035 CDEBUG(D_MGS, "global '%s' val=%s\n", sys, tmp);
2037 lustre_cfg_bufs_reset(&bufs, NULL);
2038 lustre_cfg_bufs_set_string(&bufs, 1, sys);
2039 if (!convert && *tmp != '\0')
2040 lustre_cfg_bufs_set_string(&bufs, 2, tmp);
2041 lcfg = lustre_cfg_new(cmd, &bufs);
2042 lcfg->lcfg_num = convert ? simple_strtoul(tmp, NULL, 0) : 0;
2043 /* truncate the comment to the parameter name */
2047 /* modify all servers and clients */
2048 rc = mgs_write_log_direct_all(obd, fsdb, mti,
2049 *tmp == '\0' ? NULL : lcfg,
2050 mti->mti_fsname, sys);
2051 if (rc == 0 && *tmp != '\0') {
2053 case LCFG_SET_TIMEOUT:
2054 if (!obd_timeout_set || lcfg->lcfg_num > obd_timeout)
2055 class_process_config(lcfg);
2057 case LCFG_SET_LDLM_TIMEOUT:
2058 if (!ldlm_timeout_set || lcfg->lcfg_num > ldlm_timeout)
2059 class_process_config(lcfg);
2066 lustre_cfg_free(lcfg);
2070 static int mgs_srpc_set_param_disk(struct obd_device *obd,
2072 struct mgs_target_info *mti,
2075 struct llog_handle *llh = NULL;
2077 char *comment, *ptr;
2078 struct lustre_cfg_bufs bufs;
2079 struct lustre_cfg *lcfg;
2084 ptr = strchr(param, '=');
2088 OBD_ALLOC(comment, len + 1);
2089 if (comment == NULL)
2091 strncpy(comment, param, len);
2092 comment[len] = '\0';
2095 lustre_cfg_bufs_reset(&bufs, mti->mti_svname);
2096 lustre_cfg_bufs_set_string(&bufs, 1, param);
2097 lcfg = lustre_cfg_new(LCFG_SPTLRPC_CONF, &bufs);
2099 GOTO(out_comment, rc = -ENOMEM);
2101 /* construct log name */
2102 rc = name_create(&logname, mti->mti_fsname, "-sptlrpc");
2106 if (mgs_log_is_empty(obd, logname)) {
2107 rc = record_start_log(obd, &llh, logname);
2108 record_end_log(obd, &llh);
2113 /* obsolete old one */
2114 mgs_modify(obd, fsdb, mti, logname, mti->mti_svname, comment, CM_SKIP);
2116 /* write the new one */
2117 rc = mgs_write_log_direct(obd, fsdb, logname, lcfg,
2118 mti->mti_svname, comment);
2120 CERROR("err %d writing log %s\n", rc, logname);
2123 name_destroy(&logname);
2125 lustre_cfg_free(lcfg);
2127 OBD_FREE(comment, len + 1);
2131 static int mgs_srpc_set_param_udesc_mem(struct fs_db *fsdb,
2136 /* disable the adjustable udesc parameter for now, i.e. use default
2137 * setting that client always ship udesc to MDT if possible. to enable
2138 * it simply remove the following line */
2141 ptr = strchr(param, '=');
2146 if (strcmp(param, PARAM_SRPC_UDESC))
2149 if (strcmp(ptr, "yes") == 0) {
2150 cfs_set_bit(FSDB_UDESC, &fsdb->fsdb_flags);
2151 CWARN("Enable user descriptor shipping from client to MDT\n");
2152 } else if (strcmp(ptr, "no") == 0) {
2153 cfs_clear_bit(FSDB_UDESC, &fsdb->fsdb_flags);
2154 CWARN("Disable user descriptor shipping from client to MDT\n");
2162 CERROR("Invalid param: %s\n", param);
2166 static int mgs_srpc_set_param_mem(struct fs_db *fsdb,
2170 struct sptlrpc_rule rule;
2171 struct sptlrpc_rule_set *rset;
2175 if (strncmp(param, PARAM_SRPC, sizeof(PARAM_SRPC) - 1) != 0) {
2176 CERROR("Invalid sptlrpc parameter: %s\n", param);
2180 if (strncmp(param, PARAM_SRPC_UDESC,
2181 sizeof(PARAM_SRPC_UDESC) - 1) == 0) {
2182 RETURN(mgs_srpc_set_param_udesc_mem(fsdb, param));
2185 if (strncmp(param, PARAM_SRPC_FLVR, sizeof(PARAM_SRPC_FLVR) - 1) != 0) {
2186 CERROR("Invalid sptlrpc flavor parameter: %s\n", param);
2190 param += sizeof(PARAM_SRPC_FLVR) - 1;
2192 rc = sptlrpc_parse_rule(param, &rule);
2196 /* mgs rules implies must be mgc->mgs */
2197 if (cfs_test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
2198 if ((rule.sr_from != LUSTRE_SP_MGC &&
2199 rule.sr_from != LUSTRE_SP_ANY) ||
2200 (rule.sr_to != LUSTRE_SP_MGS &&
2201 rule.sr_to != LUSTRE_SP_ANY))
2205 /* preapre room for this coming rule. svcname format should be:
2206 * - fsname: general rule
2207 * - fsname-tgtname: target-specific rule
2209 if (strchr(svname, '-')) {
2210 struct mgs_tgt_srpc_conf *tgtconf;
2213 for (tgtconf = fsdb->fsdb_srpc_tgt; tgtconf != NULL;
2214 tgtconf = tgtconf->mtsc_next) {
2215 if (!strcmp(tgtconf->mtsc_tgt, svname)) {
2224 OBD_ALLOC_PTR(tgtconf);
2225 if (tgtconf == NULL)
2228 name_len = strlen(svname);
2230 OBD_ALLOC(tgtconf->mtsc_tgt, name_len + 1);
2231 if (tgtconf->mtsc_tgt == NULL) {
2232 OBD_FREE_PTR(tgtconf);
2235 memcpy(tgtconf->mtsc_tgt, svname, name_len);
2237 tgtconf->mtsc_next = fsdb->fsdb_srpc_tgt;
2238 fsdb->fsdb_srpc_tgt = tgtconf;
2241 rset = &tgtconf->mtsc_rset;
2243 rset = &fsdb->fsdb_srpc_gen;
2246 rc = sptlrpc_rule_set_merge(rset, &rule);
2251 static int mgs_srpc_set_param(struct obd_device *obd,
2253 struct mgs_target_info *mti,
2263 /* keep a copy of original param, which could be destroied
2265 copy_size = strlen(param) + 1;
2266 OBD_ALLOC(copy, copy_size);
2269 memcpy(copy, param, copy_size);
2271 rc = mgs_srpc_set_param_mem(fsdb, mti->mti_svname, param);
2275 /* previous steps guaranteed the syntax is correct */
2276 rc = mgs_srpc_set_param_disk(obd, fsdb, mti, copy);
2280 if (cfs_test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
2282 * for mgs rules, make them effective immediately.
2284 LASSERT(fsdb->fsdb_srpc_tgt == NULL);
2285 sptlrpc_target_update_exp_flavor(obd, &fsdb->fsdb_srpc_gen);
2289 OBD_FREE(copy, copy_size);
2293 struct mgs_srpc_read_data {
2294 struct fs_db *msrd_fsdb;
2298 static int mgs_srpc_read_handler(struct llog_handle *llh,
2299 struct llog_rec_hdr *rec,
2302 struct mgs_srpc_read_data *msrd = (struct mgs_srpc_read_data *) data;
2303 struct cfg_marker *marker;
2304 struct lustre_cfg *lcfg = (struct lustre_cfg *)(rec + 1);
2305 char *svname, *param;
2309 if (rec->lrh_type != OBD_CFG_REC) {
2310 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
2314 cfg_len = rec->lrh_len - sizeof(struct llog_rec_hdr) -
2315 sizeof(struct llog_rec_tail);
2317 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
2319 CERROR("Insane cfg\n");
2323 if (lcfg->lcfg_command == LCFG_MARKER) {
2324 marker = lustre_cfg_buf(lcfg, 1);
2326 if (marker->cm_flags & CM_START &&
2327 marker->cm_flags & CM_SKIP)
2328 msrd->msrd_skip = 1;
2329 if (marker->cm_flags & CM_END)
2330 msrd->msrd_skip = 0;
2335 if (msrd->msrd_skip)
2338 if (lcfg->lcfg_command != LCFG_SPTLRPC_CONF) {
2339 CERROR("invalid command (%x)\n", lcfg->lcfg_command);
2343 svname = lustre_cfg_string(lcfg, 0);
2344 if (svname == NULL) {
2345 CERROR("svname is empty\n");
2349 param = lustre_cfg_string(lcfg, 1);
2350 if (param == NULL) {
2351 CERROR("param is empty\n");
2355 rc = mgs_srpc_set_param_mem(msrd->msrd_fsdb, svname, param);
2357 CERROR("read sptlrpc record error (%d): %s\n", rc, param);
2362 int mgs_get_fsdb_srpc_from_llog(struct obd_device *obd,
2365 struct llog_handle *llh = NULL;
2366 struct lvfs_run_ctxt saved;
2367 struct llog_ctxt *ctxt;
2369 struct mgs_srpc_read_data msrd;
2373 /* construct log name */
2374 rc = name_create(&logname, fsdb->fsdb_name, "-sptlrpc");
2378 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
2379 LASSERT(ctxt != NULL);
2381 if (mgs_log_is_empty(obd, logname))
2384 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
2386 rc = llog_create(ctxt, &llh, NULL, logname);
2390 rc = llog_init_handle(llh, LLOG_F_IS_PLAIN, NULL);
2392 GOTO(out_close, rc);
2394 if (llog_get_size(llh) <= 1)
2395 GOTO(out_close, rc = 0);
2397 msrd.msrd_fsdb = fsdb;
2400 rc = llog_process(NULL, llh, mgs_srpc_read_handler, (void *) &msrd,
2406 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
2408 llog_ctxt_put(ctxt);
2409 name_destroy(&logname);
2412 CERROR("failed to read sptlrpc config database: %d\n", rc);
2416 /* Permanent settings of all parameters by writing into the appropriate
2417 * configuration logs.
2418 * A parameter with null value ("<param>='\0'") means to erase it out of
2421 static int mgs_write_log_param(struct obd_device *obd, struct fs_db *fsdb,
2422 struct mgs_target_info *mti, char *ptr)
2424 struct lustre_cfg_bufs bufs;
2427 int rc = 0, rc2 = 0;
2430 /* For various parameter settings, we have to figure out which logs
2431 care about them (e.g. both mdt and client for lov settings) */
2432 CDEBUG(D_MGS, "next param '%s'\n", ptr);
2434 /* The params are stored in MOUNT_DATA_FILE and modified via
2435 tunefs.lustre, or set using lctl conf_param */
2437 /* Processed in lustre_start_mgc */
2438 if (class_match_param(ptr, PARAM_MGSNODE, NULL) == 0)
2441 /* Processed in ost/mdt */
2442 if (class_match_param(ptr, PARAM_NETWORK, NULL) == 0)
2445 /* Processed in mgs_write_log_ost */
2446 if (class_match_param(ptr, PARAM_FAILMODE, NULL) == 0) {
2447 if (mti->mti_flags & LDD_F_PARAM) {
2448 LCONSOLE_ERROR_MSG(0x169, "%s can only be "
2449 "changed with tunefs.lustre"
2450 "and --writeconf\n", ptr);
2456 if (class_match_param(ptr, PARAM_SRPC, NULL) == 0) {
2457 rc = mgs_srpc_set_param(obd, fsdb, mti, ptr);
2461 if (class_match_param(ptr, PARAM_FAILNODE, NULL) == 0) {
2462 /* Add a failover nidlist */
2464 /* We already processed failovers params for new
2465 targets in mgs_write_log_target */
2466 if (mti->mti_flags & LDD_F_PARAM) {
2467 CDEBUG(D_MGS, "Adding failnode\n");
2468 rc = mgs_write_log_add_failnid(obd, fsdb, mti);
2473 if (class_match_param(ptr, PARAM_SYS, &tmp) == 0) {
2474 rc = mgs_write_log_sys(obd, fsdb, mti, ptr, tmp);
2478 if (class_match_param(ptr, PARAM_OSC""PARAM_ACTIVE, &tmp) == 0) {
2479 /* active=0 means off, anything else means on */
2480 int flag = (*tmp == '0') ? CM_EXCLUDE : 0;
2483 if (!(mti->mti_flags & LDD_F_SV_TYPE_OST)) {
2484 LCONSOLE_ERROR_MSG(0x144, "%s: Only OSCs can "
2485 "be (de)activated.\n",
2487 GOTO(end, rc = -EINVAL);
2489 LCONSOLE_WARN("Permanently %sactivating %s\n",
2490 flag ? "de": "re", mti->mti_svname);
2492 name_create(&logname, mti->mti_fsname, "-client");
2493 rc = mgs_modify(obd, fsdb, mti, logname,
2494 mti->mti_svname, "add osc", flag);
2495 name_destroy(&logname);
2499 /* Add to all MDT logs for CMD */
2500 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2501 if (!cfs_test_bit(i, fsdb->fsdb_mdt_index_map))
2503 name_create_mdt(&logname, mti->mti_fsname, i);
2504 rc = mgs_modify(obd, fsdb, mti, logname,
2505 mti->mti_svname, "add osc", flag);
2506 name_destroy(&logname);
2512 LCONSOLE_ERROR_MSG(0x145, "Couldn't find %s in"
2513 "log (%d). No permanent "
2514 "changes were made to the "
2516 mti->mti_svname, rc);
2517 if (cfs_test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags))
2518 LCONSOLE_ERROR_MSG(0x146, "This may be"
2523 "update the logs.\n");
2526 /* Fall through to osc proc for deactivating live OSC
2527 on running MDT / clients. */
2529 /* Below here, let obd's XXX_process_config methods handle it */
2531 /* All lov. in proc */
2532 if (class_match_param(ptr, PARAM_LOV, NULL) == 0) {
2535 CDEBUG(D_MGS, "lov param %s\n", ptr);
2536 if (!(mti->mti_flags & LDD_F_SV_TYPE_MDT)) {
2537 LCONSOLE_ERROR_MSG(0x147, "LOV params must be "
2538 "set on the MDT, not %s. "
2545 if (mgs_log_is_empty(obd, mti->mti_svname))
2546 GOTO(end, rc = -ENODEV);
2548 name_create_mdt_and_lov(&logname, &mdtlovname, fsdb,
2549 mti->mti_stripe_index);
2550 rc = mgs_wlp_lcfg(obd, fsdb, mti, mti->mti_svname,
2551 &bufs, mdtlovname, ptr);
2552 name_destroy(&logname);
2553 name_destroy(&mdtlovname);
2558 name_create(&logname, mti->mti_fsname, "-client");
2559 rc = mgs_wlp_lcfg(obd, fsdb, mti, logname, &bufs,
2560 fsdb->fsdb_clilov, ptr);
2561 name_destroy(&logname);
2565 /* All osc., mdc., llite. params in proc */
2566 if ((class_match_param(ptr, PARAM_OSC, NULL) == 0) ||
2567 (class_match_param(ptr, PARAM_MDC, NULL) == 0) ||
2568 (class_match_param(ptr, PARAM_LLITE, NULL) == 0)) {
2570 if (memcmp(ptr, PARAM_LLITE, strlen(PARAM_LLITE)) == 0) {
2571 name_create(&cname, mti->mti_fsname, "-client");
2572 /* Add the client type to match the obdname in
2573 class_config_llog_handler */
2574 } else if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
2577 name_create(&cname, fsdb->fsdb_mdc, "");
2579 name_create(&cname, mti->mti_svname,
2581 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2583 if (cfs_test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
2584 LCONSOLE_ERROR_MSG(0x148, "Upgraded "
2585 "client logs for %s"
2587 "modified. Consider"
2589 "configuration with"
2592 /* We don't know the names of all the
2594 GOTO(end, rc = -EINVAL);
2596 name_create(&cname, mti->mti_svname, "-osc");
2598 GOTO(end, rc = -EINVAL);
2601 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
2604 name_create(&logname, mti->mti_fsname, "-client");
2605 rc = mgs_wlp_lcfg(obd, fsdb, mti, logname, &bufs,
2608 /* osc params affect the MDT as well */
2609 if (!rc && (mti->mti_flags & LDD_F_SV_TYPE_OST)) {
2612 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
2613 if (!cfs_test_bit(i, fsdb->fsdb_mdt_index_map))
2615 name_destroy(&cname);
2616 name_create_mdt_osc(&cname, mti->mti_svname,
2618 name_destroy(&logname);
2619 name_create_mdt(&logname, mti->mti_fsname, i);
2620 if (!mgs_log_is_empty(obd, logname))
2621 rc = mgs_wlp_lcfg(obd, fsdb,mti,logname,
2627 name_destroy(&logname);
2628 name_destroy(&cname);
2632 /* All mdt. params in proc */
2633 if (class_match_param(ptr, PARAM_MDT, NULL) == 0) {
2637 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
2638 if (strncmp(mti->mti_svname, mti->mti_fsname,
2639 MTI_NAME_MAXLEN) == 0)
2640 /* device is unspecified completely? */
2641 rc = LDD_F_SV_TYPE_MDT | LDD_F_SV_ALL;
2643 rc = server_name2index(mti->mti_svname, &idx, NULL);
2646 if ((rc & LDD_F_SV_TYPE_MDT) == 0)
2648 if (rc & LDD_F_SV_ALL) {
2649 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2650 if (!cfs_test_bit(i,
2651 fsdb->fsdb_mdt_index_map))
2653 name_create_mdt(&logname, mti->mti_fsname, i);
2654 rc = mgs_wlp_lcfg(obd, fsdb, mti,
2657 name_destroy(&logname);
2662 rc = mgs_wlp_lcfg(obd, fsdb, mti,
2663 mti->mti_svname, &bufs,
2664 mti->mti_svname, ptr);
2671 /* All mdd., ost. params in proc */
2672 if ((class_match_param(ptr, PARAM_MDD, NULL) == 0) ||
2673 (class_match_param(ptr, PARAM_OST, NULL) == 0)) {
2674 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
2675 if (mgs_log_is_empty(obd, mti->mti_svname))
2676 GOTO(end, rc = -ENODEV);
2678 rc = mgs_wlp_lcfg(obd, fsdb, mti, mti->mti_svname,
2679 &bufs, mti->mti_svname, ptr);
2683 LCONSOLE_WARN("Ignoring unrecognized param '%s'\n", ptr);
2688 CERROR("err %d on param '%s'\n", rc, ptr);
2693 /* Not implementing automatic failover nid addition at this time. */
2694 int mgs_check_failnid(struct obd_device *obd, struct mgs_target_info *mti)
2701 rc = mgs_find_or_make_fsdb(obd, fsname, &fsdb);
2705 if (mgs_log_is_empty(obd, mti->mti_svname))
2706 /* should never happen */
2709 CDEBUG(D_MGS, "Checking for new failnids for %s\n", mti->mti_svname);
2711 /* FIXME We can just check mti->params to see if we're already in
2712 the failover list. Modify mti->params for rewriting back at
2713 server_register_target(). */
2715 cfs_mutex_lock(&fsdb->fsdb_mutex);
2716 rc = mgs_write_log_add_failnid(obd, fsdb, mti);
2717 cfs_mutex_unlock(&fsdb->fsdb_mutex);
2724 int mgs_write_log_target(struct obd_device *obd,
2725 struct mgs_target_info *mti,
2732 /* set/check the new target index */
2733 rc = mgs_set_index(obd, mti);
2735 CERROR("Can't get index (%d)\n", rc);
2740 if (mti->mti_flags & LDD_F_UPGRADE14) {
2741 if (rc == EALREADY) {
2742 LCONSOLE_INFO("Found index %d for %s 1.4 log, "
2743 "upgrading\n", mti->mti_stripe_index,
2746 LCONSOLE_ERROR_MSG(0x149, "Failed to find %s in the old"
2747 " client log. Apparently it is not "
2748 "part of this filesystem, or the old"
2749 " log is wrong.\nUse 'writeconf' on "
2750 "the MDT to force log regeneration."
2751 "\n", mti->mti_svname);
2752 /* Not in client log? Upgrade anyhow...*/
2753 /* Argument against upgrading: reformat MDT,
2754 upgrade OST, then OST will start but will be SKIPped
2755 in client logs. Maybe error now is better. */
2756 /* RETURN(-EINVAL); */
2758 /* end COMPAT_146 */
2760 if (rc == EALREADY) {
2761 LCONSOLE_WARN("Found index %d for %s, updating log\n",
2762 mti->mti_stripe_index, mti->mti_svname);
2763 /* We would like to mark old log sections as invalid
2764 and add new log sections in the client and mdt logs.
2765 But if we add new sections, then live clients will
2766 get repeat setup instructions for already running
2767 osc's. So don't update the client/mdt logs. */
2768 mti->mti_flags &= ~LDD_F_UPDATE;
2772 cfs_mutex_lock(&fsdb->fsdb_mutex);
2774 if (mti->mti_flags &
2775 (LDD_F_VIRGIN | LDD_F_UPGRADE14 | LDD_F_WRITECONF)) {
2776 /* Generate a log from scratch */
2777 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
2778 rc = mgs_write_log_mdt(obd, fsdb, mti);
2779 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2780 rc = mgs_write_log_ost(obd, fsdb, mti);
2782 CERROR("Unknown target type %#x, can't create log for "
2783 "%s\n", mti->mti_flags, mti->mti_svname);
2786 CERROR("Can't write logs for %s (%d)\n",
2787 mti->mti_svname, rc);
2791 /* Just update the params from tunefs in mgs_write_log_params */
2792 CDEBUG(D_MGS, "Update params for %s\n", mti->mti_svname);
2793 mti->mti_flags |= LDD_F_PARAM;
2796 /* allocate temporary buffer, where class_get_next_param will
2797 make copy of a current parameter */
2798 OBD_ALLOC(buf, strlen(mti->mti_params) + 1);
2800 GOTO(out_up, rc = -ENOMEM);
2801 params = mti->mti_params;
2802 while (params != NULL) {
2803 rc = class_get_next_param(¶ms, buf);
2806 /* there is no next parameter, that is
2811 CDEBUG(D_MGS, "remaining string: '%s', param: '%s'\n",
2813 rc = mgs_write_log_param(obd, fsdb, mti, buf);
2818 OBD_FREE(buf, strlen(mti->mti_params) + 1);
2821 cfs_mutex_unlock(&fsdb->fsdb_mutex);
2826 /* verify that we can handle the old config logs */
2827 int mgs_upgrade_sv_14(struct obd_device *obd, struct mgs_target_info *mti,
2833 /* Create ost log normally, as servers register. Servers
2834 register with their old uuids (from last_rcvd), so old
2835 (MDT and client) logs should work.
2836 - new MDT won't know about old OSTs, only the ones that have
2837 registered, so we need the old MDT log to get the LOV right
2838 in order for old clients to work.
2839 - Old clients connect to the MDT, not the MGS, for their logs, and
2840 will therefore receive the old client log from the MDT /LOGS dir.
2841 - Old clients can continue to use and connect to old or new OSTs
2842 - New clients will contact the MGS for their log
2845 LCONSOLE_INFO("upgrading server %s from pre-1.6\n", mti->mti_svname);
2846 server_mti_print("upgrade", mti);
2848 if (cfs_test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
2849 LCONSOLE_ERROR_MSG(0x14a, "The old client log %s-client is "
2850 "missing. Was tunefs.lustre successful?\n",
2855 if (fsdb->fsdb_gen == 0) {
2856 /* There were no markers in the client log, meaning we have
2857 not updated the logs for this fs */
2858 CDEBUG(D_MGS, "found old, unupdated client log\n");
2861 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
2862 if (mgs_log_is_empty(obd, mti->mti_svname)) {
2863 LCONSOLE_ERROR_MSG(0x14b, "The old MDT log %s is "
2864 "missing. Was tunefs.lustre "
2869 /* We're starting with an old uuid. Assume old name for lov
2870 as well since the lov entry already exists in the log. */
2871 CDEBUG(D_MGS, "old mds uuid %s\n", mti->mti_uuid);
2872 if (strncmp(mti->mti_uuid, fsdb->fsdb_mdtlov + 4,
2873 strlen(fsdb->fsdb_mdtlov) - 4) != 0) {
2874 CERROR("old mds uuid %s doesn't match log %s (%s)\n",
2875 mti->mti_uuid, fsdb->fsdb_mdtlov,
2876 fsdb->fsdb_mdtlov + 4);
2881 if (!cfs_test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
2882 LCONSOLE_ERROR_MSG(0x14c, "%s-client is supposedly an old "
2883 "log, but no old LOV or MDT was found. "
2884 "Consider updating the configuration with"
2885 " --writeconf.\n", mti->mti_fsname);
2890 /* end COMPAT_146 */
2892 int mgs_erase_log(struct obd_device *obd, char *name)
2894 struct lvfs_run_ctxt saved;
2895 struct llog_ctxt *ctxt;
2896 struct llog_handle *llh;
2899 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
2900 LASSERT(ctxt != NULL);
2902 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
2903 rc = llog_create(ctxt, &llh, NULL, name);
2905 llog_init_handle(llh, LLOG_F_IS_PLAIN, NULL);
2906 rc = llog_destroy(llh);
2907 llog_free_handle(llh);
2909 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
2910 llog_ctxt_put(ctxt);
2913 CERROR("failed to clear log %s: %d\n", name, rc);
2918 /* erase all logs for the given fs */
2919 int mgs_erase_logs(struct obd_device *obd, char *fsname)
2921 struct mgs_obd *mgs = &obd->u.mgs;
2923 cfs_list_t dentry_list;
2924 struct l_linux_dirent *dirent, *n;
2925 int rc, len = strlen(fsname);
2929 /* Find all the logs in the CONFIGS directory */
2930 rc = class_dentry_readdir(obd, mgs->mgs_configs_dir,
2931 mgs->mgs_vfsmnt, &dentry_list);
2933 CERROR("Can't read %s dir\n", MOUNT_CONFIGS_DIR);
2937 cfs_mutex_lock(&mgs->mgs_mutex);
2939 /* Delete the fs db */
2940 fsdb = mgs_find_fsdb(obd, fsname);
2942 mgs_free_fsdb(obd, fsdb);
2944 cfs_list_for_each_entry_safe(dirent, n, &dentry_list, lld_list) {
2945 cfs_list_del(&dirent->lld_list);
2946 suffix = strrchr(dirent->lld_name, '-');
2947 if (suffix != NULL) {
2948 if ((len == suffix - dirent->lld_name) &&
2949 (strncmp(fsname, dirent->lld_name, len) == 0)) {
2950 CDEBUG(D_MGS, "Removing log %s\n",
2952 mgs_erase_log(obd, dirent->lld_name);
2955 OBD_FREE(dirent, sizeof(*dirent));
2958 cfs_mutex_unlock(&mgs->mgs_mutex);
2963 /* from llog_swab */
2964 static void print_lustre_cfg(struct lustre_cfg *lcfg)
2969 CDEBUG(D_MGS, "lustre_cfg: %p\n", lcfg);
2970 CDEBUG(D_MGS, "\tlcfg->lcfg_version: %#x\n", lcfg->lcfg_version);
2972 CDEBUG(D_MGS, "\tlcfg->lcfg_command: %#x\n", lcfg->lcfg_command);
2973 CDEBUG(D_MGS, "\tlcfg->lcfg_num: %#x\n", lcfg->lcfg_num);
2974 CDEBUG(D_MGS, "\tlcfg->lcfg_flags: %#x\n", lcfg->lcfg_flags);
2975 CDEBUG(D_MGS, "\tlcfg->lcfg_nid: %s\n", libcfs_nid2str(lcfg->lcfg_nid));
2977 CDEBUG(D_MGS, "\tlcfg->lcfg_bufcount: %d\n", lcfg->lcfg_bufcount);
2978 if (lcfg->lcfg_bufcount < LUSTRE_CFG_MAX_BUFCOUNT)
2979 for (i = 0; i < lcfg->lcfg_bufcount; i++) {
2980 CDEBUG(D_MGS, "\tlcfg->lcfg_buflens[%d]: %d %s\n",
2981 i, lcfg->lcfg_buflens[i],
2982 lustre_cfg_string(lcfg, i));
2987 /* Set a permanent (config log) param for a target or fs
2988 * \param lcfg buf0 may contain the device (testfs-MDT0000) name
2989 * buf1 contains the single parameter
2991 int mgs_setparam(struct obd_device *obd, struct lustre_cfg *lcfg, char *fsname)
2994 struct mgs_target_info *mti;
2995 char *devname, *param;
3001 print_lustre_cfg(lcfg);
3003 /* lustre, lustre-mdtlov, lustre-client, lustre-MDT0000 */
3004 devname = lustre_cfg_string(lcfg, 0);
3005 param = lustre_cfg_string(lcfg, 1);
3007 /* Assume device name embedded in param:
3008 lustre-OST0000.osc.max_dirty_mb=32 */
3009 ptr = strchr(param, '.');
3017 LCONSOLE_ERROR_MSG(0x14d, "No target specified: %s\n", param);
3021 /* Extract fsname */
3022 ptr = strrchr(devname, '-');
3023 memset(fsname, 0, MTI_NAME_MAXLEN);
3024 if (ptr && (server_name2index(ptr, &index, NULL) >= 0)) {
3025 /* param related to llite isn't allowed to set by OST or MDT */
3026 if (strncmp(param, PARAM_LLITE, sizeof(PARAM_LLITE)) == 0)
3029 strncpy(fsname, devname, ptr - devname);
3031 /* assume devname is the fsname */
3032 strncpy(fsname, devname, MTI_NAME_MAXLEN);
3034 fsname[MTI_NAME_MAXLEN - 1] = 0;
3035 CDEBUG(D_MGS, "setparam fs='%s' device='%s'\n", fsname, devname);
3037 rc = mgs_find_or_make_fsdb(obd, fsname, &fsdb);
3040 if (!cfs_test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags) &&
3041 cfs_test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
3042 CERROR("No filesystem targets for %s. cfg_device from lctl "
3043 "is '%s'\n", fsname, devname);
3044 mgs_free_fsdb(obd, fsdb);
3048 /* Create a fake mti to hold everything */
3051 GOTO(out, rc = -ENOMEM);
3052 strncpy(mti->mti_fsname, fsname, MTI_NAME_MAXLEN);
3053 strncpy(mti->mti_svname, devname, MTI_NAME_MAXLEN);
3054 strncpy(mti->mti_params, param, sizeof(mti->mti_params));
3055 rc = server_name2index(mti->mti_svname, &mti->mti_stripe_index, &tmp);
3057 /* Not a valid server; may be only fsname */
3060 /* Strip -osc or -mdc suffix from svname */
3061 if (server_make_name(rc, mti->mti_stripe_index, mti->mti_fsname,
3063 GOTO(out, rc = -EINVAL);
3065 mti->mti_flags = rc | LDD_F_PARAM;
3067 cfs_mutex_lock(&fsdb->fsdb_mutex);
3068 rc = mgs_write_log_param(obd, fsdb, mti, mti->mti_params);
3069 cfs_mutex_unlock(&fsdb->fsdb_mutex);
3072 * Revoke lock so everyone updates. Should be alright if
3073 * someone was already reading while we were updating the logs,
3074 * so we don't really need to hold the lock while we're
3077 mgs_revoke_lock(obd, fsdb, CONFIG_T_CONFIG);
3083 static int mgs_write_log_pool(struct obd_device *obd, char *logname,
3084 struct fs_db *fsdb, char *lovname,
3085 enum lcfg_command_type cmd,
3086 char *poolname, char *fsname,
3087 char *ostname, char *comment)
3089 struct llog_handle *llh = NULL;
3092 rc = record_start_log(obd, &llh, logname);
3095 rc = record_marker(obd, llh, fsdb, CM_START, lovname, comment);
3096 record_base(obd, llh, lovname, 0, cmd, poolname, fsname, ostname, 0);
3097 rc = record_marker(obd, llh, fsdb, CM_END, lovname, comment);
3098 rc = record_end_log(obd, &llh);
3103 int mgs_pool_cmd(struct obd_device *obd, enum lcfg_command_type cmd,
3104 char *fsname, char *poolname, char *ostname)
3109 char *label = NULL, *canceled_label = NULL;
3111 struct mgs_target_info *mti = NULL;
3115 rc = mgs_find_or_make_fsdb(obd, fsname, &fsdb);
3117 CERROR("Can't get db for %s\n", fsname);
3120 if (cfs_test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
3121 CERROR("%s is not defined\n", fsname);
3122 mgs_free_fsdb(obd, fsdb);
3126 label_sz = 10 + strlen(fsname) + strlen(poolname);
3128 /* check if ostname match fsname */
3129 if (ostname != NULL) {
3132 ptr = strrchr(ostname, '-');
3133 if ((ptr == NULL) ||
3134 (strncmp(fsname, ostname, ptr-ostname) != 0))
3136 label_sz += strlen(ostname);
3139 OBD_ALLOC(label, label_sz);
3141 GOTO(out, rc = -ENOMEM);
3144 case LCFG_POOL_NEW: {
3146 "new %s.%s", fsname, poolname);
3149 case LCFG_POOL_ADD: {
3151 "add %s.%s.%s", fsname, poolname, ostname);
3154 case LCFG_POOL_REM: {
3155 OBD_ALLOC(canceled_label, label_sz);
3156 if (canceled_label == NULL)
3157 GOTO(out, rc = -ENOMEM);
3159 "rem %s.%s.%s", fsname, poolname, ostname);
3160 sprintf(canceled_label,
3161 "add %s.%s.%s", fsname, poolname, ostname);
3164 case LCFG_POOL_DEL: {
3165 OBD_ALLOC(canceled_label, label_sz);
3166 if (canceled_label == NULL)
3167 GOTO(out, rc = -ENOMEM);
3169 "del %s.%s", fsname, poolname);
3170 sprintf(canceled_label,
3171 "new %s.%s", fsname, poolname);
3179 cfs_mutex_lock(&fsdb->fsdb_mutex);
3181 if (canceled_label != NULL) {
3184 GOTO(out, rc = -ENOMEM);
3187 /* write pool def to all MDT logs */
3188 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3189 if (cfs_test_bit(i, fsdb->fsdb_mdt_index_map)) {
3190 name_create_mdt_and_lov(&logname, &lovname, fsdb, i);
3192 if (canceled_label != NULL) {
3193 strcpy(mti->mti_svname, "lov pool");
3194 mgs_modify(obd, fsdb, mti, logname, lovname,
3195 canceled_label, CM_SKIP);
3198 mgs_write_log_pool(obd, logname, fsdb, lovname,
3199 cmd, fsname, poolname, ostname,
3201 name_destroy(&logname);
3202 name_destroy(&lovname);
3206 name_create(&logname, fsname, "-client");
3207 if (canceled_label != NULL)
3208 mgs_modify(obd, fsdb, mti, logname, fsdb->fsdb_clilov,
3209 canceled_label, CM_SKIP);
3211 mgs_write_log_pool(obd, logname, fsdb, fsdb->fsdb_clilov,
3212 cmd, fsname, poolname, ostname, label);
3213 name_destroy(&logname);
3215 cfs_mutex_unlock(&fsdb->fsdb_mutex);
3216 /* request for update */
3217 mgs_revoke_lock(obd, fsdb, CONFIG_T_CONFIG);
3222 OBD_FREE(label, label_sz);
3224 if (canceled_label != NULL)
3225 OBD_FREE(canceled_label, label_sz);
3234 /******************** unused *********************/
3235 static int mgs_backup_llog(struct obd_device *obd, char* fsname)
3237 struct file *filp, *bak_filp;
3238 struct lvfs_run_ctxt saved;
3239 char *logname, *buf;
3240 loff_t soff = 0 , doff = 0;
3241 int count = 4096, len;
3244 OBD_ALLOC(logname, PATH_MAX);
3245 if (logname == NULL)
3248 OBD_ALLOC(buf, count);
3250 GOTO(out , rc = -ENOMEM);
3252 len = snprintf(logname, PATH_MAX, "%s/%s.bak",
3253 MOUNT_CONFIGS_DIR, fsname);
3255 if (len >= PATH_MAX - 1) {
3256 GOTO(out, -ENAMETOOLONG);
3259 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
3261 bak_filp = l_filp_open(logname, O_RDWR|O_CREAT|O_TRUNC, 0660);
3262 if (IS_ERR(bak_filp)) {
3263 rc = PTR_ERR(bak_filp);
3264 CERROR("backup logfile open %s: %d\n", logname, rc);
3267 sprintf(logname, "%s/%s", MOUNT_CONFIGS_DIR, fsname);
3268 filp = l_filp_open(logname, O_RDONLY, 0);
3271 CERROR("logfile open %s: %d\n", logname, rc);
3275 while ((rc = lustre_fread(filp, buf, count, &soff)) > 0) {
3276 rc = lustre_fwrite(bak_filp, buf, count, &doff);
3280 filp_close(filp, 0);
3282 filp_close(bak_filp, 0);
3284 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
3287 OBD_FREE(buf, count);
3288 OBD_FREE(logname, PATH_MAX);