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(const struct lu_env *env, struct llog_handle *llh,
140 struct llog_rec_hdr *rec, void *data)
142 struct mgs_fsdb_handler_data *d = 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(NULL, ctxt, &loghandle, NULL, logname);
282 rc = llog_init_handle(NULL, 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(NULL, 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 | LDD_F_WRITECONF),
604 mti->mti_stripe_index, 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(const struct lu_env *env,
618 struct llog_handle *llh,
619 struct llog_rec_hdr *rec, void *data)
621 struct mgs_modify_lookup *mml = data;
622 struct cfg_marker *marker;
623 struct lustre_cfg *lcfg = (struct lustre_cfg *)(rec + 1);
624 int cfg_len = rec->lrh_len - sizeof(struct llog_rec_hdr) -
625 sizeof(struct llog_rec_tail);
629 if (rec->lrh_type != OBD_CFG_REC) {
630 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
634 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
636 CERROR("Insane cfg\n");
640 /* We only care about markers */
641 if (lcfg->lcfg_command != LCFG_MARKER)
644 marker = lustre_cfg_buf(lcfg, 1);
645 if ((strcmp(mml->mml_marker.cm_comment, marker->cm_comment) == 0) &&
646 (strcmp(mml->mml_marker.cm_tgtname, marker->cm_tgtname) == 0) &&
647 !(marker->cm_flags & CM_SKIP)) {
648 /* Found a non-skipped marker match */
649 CDEBUG(D_MGS, "Changing rec %u marker %d %x->%x: %s %s\n",
650 rec->lrh_index, marker->cm_step,
651 marker->cm_flags, mml->mml_marker.cm_flags,
652 marker->cm_tgtname, marker->cm_comment);
653 /* Overwrite the old marker llog entry */
654 marker->cm_flags &= ~CM_EXCLUDE; /* in case we're unexcluding */
655 marker->cm_flags |= mml->mml_marker.cm_flags;
656 marker->cm_canceltime = mml->mml_marker.cm_canceltime;
657 /* Header and tail are added back to lrh_len in
658 llog_lvfs_write_rec */
659 rec->lrh_len = cfg_len;
660 rc = llog_write_rec(NULL, llh, rec, NULL, 0, (void *)lcfg,
669 /* Modify an existing config log record (for CM_SKIP or CM_EXCLUDE) */
670 static int mgs_modify(struct obd_device *obd, struct fs_db *fsdb,
671 struct mgs_target_info *mti, char *logname,
672 char *devname, char *comment, int flags)
674 struct llog_handle *loghandle;
675 struct lvfs_run_ctxt saved;
676 struct llog_ctxt *ctxt;
677 struct mgs_modify_lookup *mml;
681 CDEBUG(D_MGS, "modify %s/%s/%s fl=%x\n", logname, devname, comment,
684 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
686 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
687 LASSERT(ctxt != NULL);
688 rc = llog_create(NULL, ctxt, &loghandle, NULL, logname);
692 rc = llog_init_handle(NULL, loghandle, LLOG_F_IS_PLAIN, NULL);
696 if (llog_get_size(loghandle) <= 1)
697 GOTO(out_close, rc = 0);
701 GOTO(out_close, rc = -ENOMEM);
702 strcpy(mml->mml_marker.cm_comment, comment);
703 strcpy(mml->mml_marker.cm_tgtname, devname);
704 /* Modify mostly means cancel */
705 mml->mml_marker.cm_flags = flags;
706 mml->mml_marker.cm_canceltime = flags ? cfs_time_current_sec() : 0;
707 mml->mml_modified = 0;
708 rc = llog_process(NULL, loghandle, mgs_modify_handler, (void *)mml,
710 if (!rc && !mml->mml_modified)
715 rc2 = llog_close(NULL, loghandle);
719 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
720 if (rc && rc != -ENODEV)
721 CERROR("modify %s/%s failed %d\n",
722 mti->mti_svname, comment, rc);
727 /******************** config log recording functions *********************/
729 static int record_lcfg(struct obd_device *obd, struct llog_handle *llh,
730 struct lustre_cfg *lcfg)
732 struct lvfs_run_ctxt saved;
733 struct llog_rec_hdr rec;
739 LASSERT(llh->lgh_ctxt);
741 buflen = lustre_cfg_len(lcfg->lcfg_bufcount,
743 rec.lrh_len = llog_data_len(buflen);
744 rec.lrh_type = OBD_CFG_REC;
746 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
747 /* idx = -1 means append */
748 rc = llog_write_rec(NULL, llh, &rec, NULL, 0, (void *)lcfg, -1);
749 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
751 CERROR("failed %d\n", rc);
755 static int record_base(struct obd_device *obd, struct llog_handle *llh,
756 char *cfgname, lnet_nid_t nid, int cmd,
757 char *s1, char *s2, char *s3, char *s4)
759 struct lustre_cfg_bufs bufs;
760 struct lustre_cfg *lcfg;
763 CDEBUG(D_MGS, "lcfg %s %#x %s %s %s %s\n", cfgname,
764 cmd, s1, s2, s3, s4);
766 lustre_cfg_bufs_reset(&bufs, cfgname);
768 lustre_cfg_bufs_set_string(&bufs, 1, s1);
770 lustre_cfg_bufs_set_string(&bufs, 2, s2);
772 lustre_cfg_bufs_set_string(&bufs, 3, s3);
774 lustre_cfg_bufs_set_string(&bufs, 4, s4);
776 lcfg = lustre_cfg_new(cmd, &bufs);
779 lcfg->lcfg_nid = nid;
781 rc = record_lcfg(obd, llh, lcfg);
783 lustre_cfg_free(lcfg);
786 CERROR("error %d: lcfg %s %#x %s %s %s %s\n", rc, cfgname,
787 cmd, s1, s2, s3, s4);
793 static inline int record_add_uuid(struct obd_device *obd,
794 struct llog_handle *llh,
795 uint64_t nid, char *uuid)
797 return record_base(obd,llh,NULL,nid,LCFG_ADD_UUID,uuid,0,0,0);
801 static inline int record_add_conn(struct obd_device *obd,
802 struct llog_handle *llh,
806 return record_base(obd,llh,devname,0,LCFG_ADD_CONN,uuid,0,0,0);
809 static inline int record_attach(struct obd_device *obd, struct llog_handle *llh,
810 char *devname, char *type, char *uuid)
812 return record_base(obd,llh,devname,0,LCFG_ATTACH,type,uuid,0,0);
815 static inline int record_setup(struct obd_device *obd, struct llog_handle *llh,
817 char *s1, char *s2, char *s3, char *s4)
819 return record_base(obd,llh,devname,0,LCFG_SETUP,s1,s2,s3,s4);
822 static int record_lov_setup(struct obd_device *obd, struct llog_handle *llh,
823 char *devname, struct lov_desc *desc)
825 struct lustre_cfg_bufs bufs;
826 struct lustre_cfg *lcfg;
829 lustre_cfg_bufs_reset(&bufs, devname);
830 lustre_cfg_bufs_set(&bufs, 1, desc, sizeof(*desc));
831 lcfg = lustre_cfg_new(LCFG_SETUP, &bufs);
834 rc = record_lcfg(obd, llh, lcfg);
836 lustre_cfg_free(lcfg);
840 static int record_lmv_setup(struct obd_device *obd, struct llog_handle *llh,
841 char *devname, struct lmv_desc *desc)
843 struct lustre_cfg_bufs bufs;
844 struct lustre_cfg *lcfg;
847 lustre_cfg_bufs_reset(&bufs, devname);
848 lustre_cfg_bufs_set(&bufs, 1, desc, sizeof(*desc));
849 lcfg = lustre_cfg_new(LCFG_SETUP, &bufs);
851 rc = record_lcfg(obd, llh, lcfg);
853 lustre_cfg_free(lcfg);
857 static inline int record_mdc_add(struct obd_device *obd,
858 struct llog_handle *llh,
859 char *logname, char *mdcuuid,
860 char *mdtuuid, char *index,
863 return record_base(obd,llh,logname,0,LCFG_ADD_MDC,
864 mdtuuid,index,gen,mdcuuid);
867 static inline int record_lov_add(struct obd_device *obd,
868 struct llog_handle *llh,
869 char *lov_name, char *ost_uuid,
870 char *index, char *gen)
872 return record_base(obd,llh,lov_name,0,LCFG_LOV_ADD_OBD,
873 ost_uuid,index,gen,0);
876 static inline int record_mount_opt(struct obd_device *obd,
877 struct llog_handle *llh,
878 char *profile, char *lov_name,
881 return record_base(obd,llh,NULL,0,LCFG_MOUNTOPT,
882 profile,lov_name,mdc_name,0);
885 static int record_marker(struct obd_device *obd, struct llog_handle *llh,
886 struct fs_db *fsdb, __u32 flags,
887 char *tgtname, char *comment)
889 struct cfg_marker marker;
890 struct lustre_cfg_bufs bufs;
891 struct lustre_cfg *lcfg;
894 if (flags & CM_START)
896 marker.cm_step = fsdb->fsdb_gen;
897 marker.cm_flags = flags;
898 marker.cm_vers = LUSTRE_VERSION_CODE;
899 strncpy(marker.cm_tgtname, tgtname, sizeof(marker.cm_tgtname));
900 strncpy(marker.cm_comment, comment, sizeof(marker.cm_comment));
901 marker.cm_createtime = cfs_time_current_sec();
902 marker.cm_canceltime = 0;
903 lustre_cfg_bufs_reset(&bufs, NULL);
904 lustre_cfg_bufs_set(&bufs, 1, &marker, sizeof(marker));
905 lcfg = lustre_cfg_new(LCFG_MARKER, &bufs);
908 rc = record_lcfg(obd, llh, lcfg);
910 lustre_cfg_free(lcfg);
914 static int record_start_log(struct obd_device *obd,
915 struct llog_handle **llh, char *name)
917 static struct obd_uuid cfg_uuid = { .uuid = "config_uuid" };
918 struct lvfs_run_ctxt saved;
919 struct llog_ctxt *ctxt;
923 GOTO(out, rc = -EBUSY);
925 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
927 GOTO(out, rc = -ENODEV);
929 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
930 rc = llog_create(NULL, ctxt, llh, NULL, name);
932 llog_init_handle(NULL, *llh, LLOG_F_IS_PLAIN, &cfg_uuid);
936 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
941 CERROR("Can't start log %s: %d\n", name, rc);
946 static int record_end_log(struct obd_device *obd, struct llog_handle **llh)
948 struct lvfs_run_ctxt saved;
951 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
953 rc = llog_close(NULL, *llh);
956 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
960 static int mgs_log_is_empty(struct obd_device *obd, char *name)
962 struct lvfs_run_ctxt saved;
963 struct llog_handle *llh;
964 struct llog_ctxt *ctxt;
967 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
968 LASSERT(ctxt != NULL);
969 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
970 rc = llog_create(NULL, ctxt, &llh, NULL, name);
972 llog_init_handle(NULL, llh, LLOG_F_IS_PLAIN, NULL);
973 rc = llog_get_size(llh);
974 llog_close(NULL, llh);
976 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
978 /* header is record 1 */
982 /******************** config "macros" *********************/
984 /* write an lcfg directly into a log (with markers) */
985 static int mgs_write_log_direct(struct obd_device *obd, struct fs_db *fsdb,
986 char *logname, struct lustre_cfg *lcfg,
987 char *devname, char *comment)
989 struct llog_handle *llh = NULL;
996 rc = record_start_log(obd, &llh, logname);
1000 /* FIXME These should be a single journal transaction */
1001 rc = record_marker(obd, llh, fsdb, CM_START, devname, comment);
1003 rc = record_lcfg(obd, llh, lcfg);
1005 rc = record_marker(obd, llh, fsdb, CM_END, devname, comment);
1006 rc = record_end_log(obd, &llh);
1011 /* write the lcfg in all logs for the given fs */
1012 int mgs_write_log_direct_all(struct obd_device *obd, struct fs_db *fsdb,
1013 struct mgs_target_info *mti,
1014 struct lustre_cfg *lcfg,
1015 char *devname, char *comment)
1017 struct mgs_obd *mgs = &obd->u.mgs;
1018 cfs_list_t dentry_list;
1019 struct l_linux_dirent *dirent, *n;
1020 char *fsname = mti->mti_fsname;
1022 int rc = 0, len = strlen(fsname);
1025 /* We need to set params for any future logs
1026 as well. FIXME Append this file to every new log.
1027 Actually, we should store as params (text), not llogs. Or
1029 name_create(&logname, fsname, "-params");
1030 if (mgs_log_is_empty(obd, logname)) {
1031 struct llog_handle *llh = NULL;
1032 rc = record_start_log(obd, &llh, logname);
1033 record_end_log(obd, &llh);
1035 name_destroy(&logname);
1039 /* Find all the logs in the CONFIGS directory */
1040 rc = class_dentry_readdir(obd, mgs->mgs_configs_dir,
1041 mgs->mgs_vfsmnt, &dentry_list);
1043 CERROR("Can't read %s dir\n", MOUNT_CONFIGS_DIR);
1047 /* Could use fsdb index maps instead of directory listing */
1048 cfs_list_for_each_entry_safe(dirent, n, &dentry_list, lld_list) {
1049 cfs_list_del(&dirent->lld_list);
1050 /* don't write to sptlrpc rule log */
1051 if (strncmp(fsname, dirent->lld_name, len) == 0 &&
1052 strstr(dirent->lld_name, "-sptlrpc") == NULL) {
1053 CDEBUG(D_MGS, "Changing log %s\n", dirent->lld_name);
1054 /* Erase any old settings of this same parameter */
1055 mgs_modify(obd, fsdb, mti, dirent->lld_name, devname,
1057 /* Write the new one */
1059 rc = mgs_write_log_direct(obd, fsdb,
1064 CERROR("err %d writing log %s\n", rc,
1068 OBD_FREE(dirent, sizeof(*dirent));
1076 struct mgs_target_info *comp_tmti;
1077 struct mgs_target_info *comp_mti;
1078 struct fs_db *comp_fsdb;
1079 struct obd_device *comp_obd;
1082 static int mgs_write_log_mdc_to_mdt(struct obd_device *, struct fs_db *,
1083 struct mgs_target_info *, char *);
1084 static int mgs_write_log_osc_to_lov(struct obd_device *obd, struct fs_db *fsdb,
1085 struct mgs_target_info *mti,
1086 char *logname, char *suffix, char *lovname,
1087 enum lustre_sec_part sec_part, int flags);
1088 static void name_create_mdt_and_lov(char **logname, char **lovname,
1089 struct fs_db *fsdb, int i);
1091 static int mgs_steal_llog_handler(const struct lu_env *env,
1092 struct llog_handle *llh,
1093 struct llog_rec_hdr *rec, void *data)
1095 struct obd_device * obd;
1096 struct mgs_target_info *mti, *tmti;
1098 int cfg_len = rec->lrh_len;
1099 char *cfg_buf = (char*) (rec + 1);
1100 struct lustre_cfg *lcfg;
1102 struct llog_handle *mdt_llh = NULL;
1103 static int got_an_osc_or_mdc = 0;
1104 /* 0: not found any osc/mdc;
1108 static int last_step = -1;
1112 mti = ((struct temp_comp*)data)->comp_mti;
1113 tmti = ((struct temp_comp*)data)->comp_tmti;
1114 fsdb = ((struct temp_comp*)data)->comp_fsdb;
1115 obd = ((struct temp_comp*)data)->comp_obd;
1117 if (rec->lrh_type != OBD_CFG_REC) {
1118 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
1122 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
1124 CERROR("Insane cfg\n");
1128 lcfg = (struct lustre_cfg *)cfg_buf;
1130 if (lcfg->lcfg_command == LCFG_MARKER) {
1131 struct cfg_marker *marker;
1132 marker = lustre_cfg_buf(lcfg, 1);
1133 if (!strncmp(marker->cm_comment,"add osc",7) &&
1134 (marker->cm_flags & CM_START)){
1135 got_an_osc_or_mdc = 1;
1136 strncpy(tmti->mti_svname, marker->cm_tgtname,
1137 sizeof(tmti->mti_svname));
1138 rc = record_start_log(obd, &mdt_llh, mti->mti_svname);
1139 rc = record_marker(obd, mdt_llh, fsdb, CM_START,
1140 mti->mti_svname,"add osc(copied)");
1141 rc = record_end_log(obd, &mdt_llh);
1142 last_step = marker->cm_step;
1145 if (!strncmp(marker->cm_comment,"add osc",7) &&
1146 (marker->cm_flags & CM_END)){
1147 LASSERT(last_step == marker->cm_step);
1149 got_an_osc_or_mdc = 0;
1150 rc = record_start_log(obd, &mdt_llh, mti->mti_svname);
1151 rc = record_marker(obd, mdt_llh, fsdb, CM_END,
1152 mti->mti_svname,"add osc(copied)");
1153 rc = record_end_log(obd, &mdt_llh);
1156 if (!strncmp(marker->cm_comment,"add mdc",7) &&
1157 (marker->cm_flags & CM_START)){
1158 got_an_osc_or_mdc = 2;
1159 last_step = marker->cm_step;
1160 memcpy(tmti->mti_svname, marker->cm_tgtname,
1161 strlen(marker->cm_tgtname));
1165 if (!strncmp(marker->cm_comment,"add mdc",7) &&
1166 (marker->cm_flags & CM_END)){
1167 LASSERT(last_step == marker->cm_step);
1169 got_an_osc_or_mdc = 0;
1174 if (got_an_osc_or_mdc == 0 || last_step < 0)
1177 if (lcfg->lcfg_command == LCFG_ADD_UUID) {
1179 nodenid = lcfg->lcfg_nid;
1181 tmti->mti_nids[tmti->mti_nid_count] = nodenid;
1182 tmti->mti_nid_count++;
1187 if (lcfg->lcfg_command == LCFG_SETUP) {
1190 target = lustre_cfg_string(lcfg, 1);
1191 memcpy(tmti->mti_uuid, target, strlen(target));
1195 /* ignore client side sptlrpc_conf_log */
1196 if (lcfg->lcfg_command == LCFG_SPTLRPC_CONF)
1199 if (lcfg->lcfg_command == LCFG_ADD_MDC) {
1202 if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1)
1205 memcpy(tmti->mti_fsname, mti->mti_fsname,
1206 strlen(mti->mti_fsname));
1207 tmti->mti_stripe_index = index;
1209 mgs_write_log_mdc_to_mdt(obd, fsdb, tmti, mti->mti_svname);
1210 memset(tmti, 0, sizeof(*tmti));
1214 if (lcfg->lcfg_command == LCFG_LOV_ADD_OBD) {
1217 char *logname, *lovname;
1219 name_create_mdt_and_lov(&logname, &lovname, fsdb,
1220 mti->mti_stripe_index);
1221 sprintf(mdt_index, "-MDT%04x", mti->mti_stripe_index);
1223 if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1) {
1224 name_destroy(&logname);
1225 name_destroy(&lovname);
1229 tmti->mti_stripe_index = index;
1230 mgs_write_log_osc_to_lov(obd, fsdb, tmti, logname,
1233 name_destroy(&logname);
1234 name_destroy(&lovname);
1240 /* fsdb->fsdb_mutex is already held in mgs_write_log_target*/
1241 /* stealed from mgs_get_fsdb_from_llog*/
1242 static int mgs_steal_llog_for_mdt_from_client(struct obd_device *obd,
1244 struct temp_comp* comp)
1246 struct llog_handle *loghandle;
1247 struct lvfs_run_ctxt saved;
1248 struct mgs_target_info *tmti;
1249 struct llog_ctxt *ctxt;
1253 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
1254 LASSERT(ctxt != NULL);
1256 OBD_ALLOC_PTR(tmti);
1260 comp->comp_tmti = tmti;
1261 comp->comp_obd = obd;
1263 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
1265 rc = llog_create(NULL, ctxt, &loghandle, NULL, client_name);
1269 rc = llog_init_handle(NULL, loghandle, LLOG_F_IS_PLAIN, NULL);
1271 GOTO(out_close, rc);
1273 rc = llog_process(NULL, loghandle, mgs_steal_llog_handler,
1274 (void *)comp, NULL);
1275 CDEBUG(D_MGS, "steal llog re = %d\n", rc);
1277 rc2 = llog_close(NULL, loghandle);
1281 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
1283 llog_ctxt_put(ctxt);
1287 /* lmv is the second thing for client logs */
1288 /* copied from mgs_write_log_lov. Please refer to that. */
1289 static int mgs_write_log_lmv(struct obd_device *obd, struct fs_db *fsdb,
1290 struct mgs_target_info *mti,
1291 char *logname, char *lmvname)
1293 struct llog_handle *llh = NULL;
1294 struct lmv_desc *lmvdesc;
1299 CDEBUG(D_MGS, "Writing lmv(%s) log for %s\n", lmvname,logname);
1301 OBD_ALLOC_PTR(lmvdesc);
1302 if (lmvdesc == NULL)
1304 lmvdesc->ld_active_tgt_count = 0;
1305 lmvdesc->ld_tgt_count = 0;
1306 sprintf((char*)lmvdesc->ld_uuid.uuid, "%s_UUID", lmvname);
1307 uuid = (char *)lmvdesc->ld_uuid.uuid;
1309 rc = record_start_log(obd, &llh, logname);
1310 rc = record_marker(obd, llh, fsdb, CM_START, lmvname, "lmv setup");
1311 rc = record_attach(obd, llh, lmvname, "lmv", uuid);
1312 rc = record_lmv_setup(obd, llh, lmvname, lmvdesc);
1313 rc = record_marker(obd, llh, fsdb, CM_END, lmvname, "lmv setup");
1314 rc = record_end_log(obd, &llh);
1316 OBD_FREE_PTR(lmvdesc);
1320 /* lov is the first thing in the mdt and client logs */
1321 static int mgs_write_log_lov(struct obd_device *obd, struct fs_db *fsdb,
1322 struct mgs_target_info *mti,
1323 char *logname, char *lovname)
1325 struct llog_handle *llh = NULL;
1326 struct lov_desc *lovdesc;
1331 CDEBUG(D_MGS, "Writing lov(%s) log for %s\n", lovname, logname);
1334 #01 L attach 0:lov_mdsA 1:lov 2:71ccb_lov_mdsA_19f961a9e1
1335 #02 L lov_setup 0:lov_mdsA 1:(struct lov_desc)
1336 uuid=lov1_UUID, stripe count=1, size=1048576, offset=0, pattern=0
1339 /* FIXME just make lov_setup accept empty desc (put uuid in buf 2) */
1340 OBD_ALLOC_PTR(lovdesc);
1341 if (lovdesc == NULL)
1343 lovdesc->ld_magic = LOV_DESC_MAGIC;
1344 lovdesc->ld_tgt_count = 0;
1345 /* Defaults. Can be changed later by lcfg config_param */
1346 lovdesc->ld_default_stripe_count = 1;
1347 lovdesc->ld_pattern = LOV_PATTERN_RAID0;
1348 lovdesc->ld_default_stripe_size = 1024 * 1024;
1349 lovdesc->ld_default_stripe_offset = -1;
1350 lovdesc->ld_qos_maxage = QOS_DEFAULT_MAXAGE;
1351 sprintf((char*)lovdesc->ld_uuid.uuid, "%s_UUID", lovname);
1352 /* can these be the same? */
1353 uuid = (char *)lovdesc->ld_uuid.uuid;
1355 /* This should always be the first entry in a log.
1356 rc = mgs_clear_log(obd, logname); */
1357 rc = record_start_log(obd, &llh, logname);
1360 /* FIXME these should be a single journal transaction */
1361 rc = record_marker(obd, llh, fsdb, CM_START, lovname, "lov setup");
1362 rc = record_attach(obd, llh, lovname, "lov", uuid);
1363 rc = record_lov_setup(obd, llh, lovname, lovdesc);
1364 rc = record_marker(obd, llh, fsdb, CM_END, lovname, "lov setup");
1365 rc = record_end_log(obd, &llh);
1369 OBD_FREE_PTR(lovdesc);
1373 /* add failnids to open log */
1374 static int mgs_write_log_failnids(struct obd_device *obd,
1375 struct mgs_target_info *mti,
1376 struct llog_handle *llh,
1379 char *failnodeuuid = NULL;
1380 char *ptr = mti->mti_params;
1385 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) nal=90 0: 1:uml1_UUID
1386 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
1387 #05 L setup 0:OSC_uml1_ost1_mdsA 1:ost1_UUID 2:uml1_UUID
1388 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) nal=90 0: 1:uml2_UUID
1389 #0x L add_uuid nid=2@elan(0x1000000000002) nal=90 0: 1:uml2_UUID
1390 #07 L add_conn 0:OSC_uml1_ost1_mdsA 1:uml2_UUID
1393 /* Pull failnid info out of params string */
1394 while (class_find_param(ptr, PARAM_FAILNODE, &ptr) == 0) {
1395 while (class_parse_nid(ptr, &nid, &ptr) == 0) {
1396 if (failnodeuuid == NULL) {
1397 /* We don't know the failover node name,
1398 so just use the first nid as the uuid */
1399 rc = name_create(&failnodeuuid,
1400 libcfs_nid2str(nid), "");
1404 CDEBUG(D_MGS, "add nid %s for failover uuid %s, "
1405 "client %s\n", libcfs_nid2str(nid),
1406 failnodeuuid, cliname);
1407 rc = record_add_uuid(obd, llh, nid, failnodeuuid);
1410 rc = record_add_conn(obd, llh, cliname, failnodeuuid);
1411 name_destroy(&failnodeuuid);
1412 failnodeuuid = NULL;
1419 static int mgs_write_log_mdc_to_lmv(struct obd_device *obd, struct fs_db *fsdb,
1420 struct mgs_target_info *mti,
1421 char *logname, char *lmvname)
1423 struct llog_handle *llh = NULL;
1424 char *mdcname, *nodeuuid, *mdcuuid, *lmvuuid;
1429 if (mgs_log_is_empty(obd, logname)) {
1430 CERROR("log is empty! Logical error\n");
1434 CDEBUG(D_MGS, "adding mdc for %s to log %s:lmv(%s)\n",
1435 mti->mti_svname, logname, lmvname);
1437 name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
1438 name_create(&mdcname, mti->mti_svname, "-mdc");
1439 name_create(&mdcuuid, mdcname, "_UUID");
1440 name_create(&lmvuuid, lmvname, "_UUID");
1442 rc = record_start_log(obd, &llh, logname);
1443 rc = record_marker(obd, llh, fsdb, CM_START, mti->mti_svname,
1446 for (i = 0; i < mti->mti_nid_count; i++) {
1447 CDEBUG(D_MGS, "add nid %s for mdt\n",
1448 libcfs_nid2str(mti->mti_nids[i]));
1450 rc = record_add_uuid(obd, llh, mti->mti_nids[i], nodeuuid);
1453 rc = record_attach(obd, llh, mdcname, LUSTRE_MDC_NAME, lmvuuid);
1454 rc = record_setup(obd, llh, mdcname, mti->mti_uuid, nodeuuid, 0, 0);
1455 rc = mgs_write_log_failnids(obd, mti, llh, mdcname);
1456 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
1457 rc = record_mdc_add(obd, llh, lmvname, mdcuuid, mti->mti_uuid,
1459 rc = record_marker(obd, llh, fsdb, CM_END, mti->mti_svname,
1461 rc = record_end_log(obd, &llh);
1463 name_destroy(&lmvuuid);
1464 name_destroy(&mdcuuid);
1465 name_destroy(&mdcname);
1466 name_destroy(&nodeuuid);
1470 /* add new mdc to already existent MDS */
1471 static int mgs_write_log_mdc_to_mdt(struct obd_device *obd, struct fs_db *fsdb,
1472 struct mgs_target_info *mti, char *logname)
1474 struct llog_handle *llh = NULL;
1475 char *nodeuuid, *mdcname, *mdcuuid, *mdtuuid;
1476 int idx = mti->mti_stripe_index;
1481 if (mgs_log_is_empty(obd, logname)) {
1482 CERROR("log is empty! Logical error\n");
1486 CDEBUG(D_MGS, "adding mdc index %d to %s\n", idx, logname);
1488 name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
1489 snprintf(index, sizeof(index), "-mdc%04x", idx);
1490 name_create(&mdcname, logname, index);
1491 name_create(&mdcuuid, mdcname, "_UUID");
1492 name_create(&mdtuuid, logname, "_UUID");
1494 rc = record_start_log(obd, &llh, logname);
1495 rc = record_marker(obd, llh, fsdb, CM_START, mti->mti_svname, "add mdc");
1496 for (i = 0; i < mti->mti_nid_count; i++) {
1497 CDEBUG(D_MGS, "add nid %s for mdt\n",
1498 libcfs_nid2str(mti->mti_nids[i]));
1499 rc = record_add_uuid(obd, llh, mti->mti_nids[i], nodeuuid);
1501 rc = record_attach(obd, llh, mdcname, LUSTRE_MDC_NAME, mdcuuid);
1502 rc = record_setup(obd, llh, mdcname, mti->mti_uuid, nodeuuid, 0, 0);
1503 rc = mgs_write_log_failnids(obd, mti, llh, mdcname);
1504 snprintf(index, sizeof(index), "%d", idx);
1506 rc = record_mdc_add(obd, llh, logname, mdcuuid, mti->mti_uuid,
1508 rc = record_marker(obd, llh, fsdb, CM_END, mti->mti_svname, "add mdc");
1509 rc = record_end_log(obd, &llh);
1511 name_destroy(&mdcuuid);
1512 name_destroy(&mdcname);
1513 name_destroy(&nodeuuid);
1514 name_destroy(&mdtuuid);
1518 static int mgs_write_log_mdt0(struct obd_device *obd, struct fs_db *fsdb,
1519 struct mgs_target_info *mti)
1521 char *log = mti->mti_svname;
1522 struct llog_handle *llh = NULL;
1523 char *uuid, *lovname;
1525 char *ptr = mti->mti_params;
1526 int rc = 0, failout = 0;
1529 OBD_ALLOC(uuid, sizeof(struct obd_uuid));
1533 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
1534 failout = (strncmp(ptr, "failout", 7) == 0);
1536 name_create(&lovname, log, "-mdtlov");
1537 if (mgs_log_is_empty(obd, log))
1538 rc = mgs_write_log_lov(obd, fsdb, mti, log, lovname);
1540 sprintf(uuid, "%s_UUID", log);
1541 sprintf(mdt_index, "%d", mti->mti_stripe_index);
1543 /* add MDT itself */
1544 rc = record_start_log(obd, &llh, log);
1548 /* FIXME this whole fn should be a single journal transaction */
1549 rc = record_marker(obd, llh, fsdb, CM_START, log, "add mdt");
1550 rc = record_attach(obd, llh, log, LUSTRE_MDT_NAME, uuid);
1551 rc = record_mount_opt(obd, llh, log, lovname, NULL);
1552 rc = record_setup(obd, llh, log, uuid, mdt_index, lovname,
1553 failout ? "n" : "f");
1554 rc = record_marker(obd, llh, fsdb, CM_END, log, "add mdt");
1555 rc = record_end_log(obd, &llh);
1557 name_destroy(&lovname);
1558 OBD_FREE(uuid, sizeof(struct obd_uuid));
1562 static inline void name_create_mdt(char **logname, char *fsname, int i)
1566 sprintf(mdt_index, "-MDT%04x", i);
1567 name_create(logname, fsname, mdt_index);
1570 static void name_create_mdt_and_lov(char **logname, char **lovname,
1571 struct fs_db *fsdb, int i)
1573 name_create_mdt(logname, fsdb->fsdb_name, i);
1575 if (i == 0 && cfs_test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
1576 name_create(lovname, fsdb->fsdb_name, "-mdtlov");
1578 name_create(lovname, *logname, "-mdtlov");
1581 static inline void name_create_mdt_osc(char **oscname, char *ostname,
1582 struct fs_db *fsdb, int i)
1586 if (i == 0 && cfs_test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
1587 sprintf(suffix, "-osc");
1589 sprintf(suffix, "-osc-MDT%04x", i);
1590 name_create(oscname, ostname, suffix);
1593 /* envelope method for all layers log */
1594 static int mgs_write_log_mdt(struct obd_device *obd, struct fs_db *fsdb,
1595 struct mgs_target_info *mti)
1597 struct llog_handle *llh = NULL;
1599 struct temp_comp comp = { 0 };
1603 CDEBUG(D_MGS, "writing new mdt %s\n", mti->mti_svname);
1607 if (mti->mti_flags & LDD_F_UPGRADE14) {
1608 /* We're starting with an old uuid. Assume old name for lov
1609 as well since the lov entry already exists in the log. */
1610 CDEBUG(D_MGS, "old mds uuid %s\n", mti->mti_uuid);
1611 if (strncmp(mti->mti_uuid, fsdb->fsdb_mdtlov + 4,
1612 strlen(fsdb->fsdb_mdtlov) - 4) != 0) {
1613 CERROR("old mds uuid %s doesn't match log %s (%s)\n",
1614 mti->mti_uuid, fsdb->fsdb_mdtlov,
1615 fsdb->fsdb_mdtlov + 4);
1619 /* end COMPAT_146 */
1621 if (mti->mti_uuid[0] == '\0') {
1622 /* Make up our own uuid */
1623 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
1624 "%s_UUID", mti->mti_svname);
1628 rc = mgs_write_log_mdt0(obd, fsdb, mti);
1630 /* Append the mdt info to the client log */
1631 name_create(&cliname, mti->mti_fsname, "-client");
1633 if (mgs_log_is_empty(obd, cliname)) {
1634 /* Start client log */
1635 rc = mgs_write_log_lov(obd, fsdb, mti, cliname,
1637 rc = mgs_write_log_lmv(obd, fsdb, mti, cliname,
1642 #09 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
1643 #10 L attach 0:MDC_uml1_mdsA_MNT_client 1:mdc 2:1d834_MNT_client_03f
1644 #11 L setup 0:MDC_uml1_mdsA_MNT_client 1:mdsA_UUID 2:uml1_UUID
1645 #12 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
1646 #13 L add_conn 0:MDC_uml1_mdsA_MNT_client 1:uml2_UUID
1647 #14 L mount_option 0: 1:client 2:lov1 3:MDC_uml1_mdsA_MNT_client
1652 if (mti->mti_flags & LDD_F_UPGRADE14) {
1653 rc = record_start_log(obd, &llh, cliname);
1657 rc = record_marker(obd, llh, fsdb, CM_START,
1658 mti->mti_svname,"add mdc");
1660 /* Old client log already has MDC entry, but needs mount opt
1661 for new client name (lustre-client) */
1662 /* FIXME Old MDT log already has an old mount opt
1663 which we should remove (currently handled by
1664 class_del_profiles()) */
1665 rc = record_mount_opt(obd, llh, cliname, fsdb->fsdb_clilov,
1667 /* end COMPAT_146 */
1669 rc = record_marker(obd, llh, fsdb, CM_END,
1670 mti->mti_svname, "add mdc");
1674 /* copy client info about lov/lmv */
1675 comp.comp_mti = mti;
1676 comp.comp_fsdb = fsdb;
1678 rc = mgs_steal_llog_for_mdt_from_client(obd, cliname,
1681 rc = mgs_write_log_mdc_to_lmv(obd, fsdb, mti, cliname,
1684 rc = record_start_log(obd, &llh, cliname);
1688 rc = record_marker(obd, llh, fsdb, CM_START, cliname,
1690 rc = record_mount_opt(obd, llh, cliname, fsdb->fsdb_clilov,
1692 rc = record_marker(obd, llh, fsdb, CM_END, cliname,
1696 rc = record_end_log(obd, &llh);
1698 name_destroy(&cliname);
1700 // for_all_existing_mdt except current one
1701 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
1703 if (i != mti->mti_stripe_index &&
1704 cfs_test_bit(i, fsdb->fsdb_mdt_index_map)) {
1705 name_create_mdt(&mdtname, mti->mti_fsname, i);
1706 rc = mgs_write_log_mdc_to_mdt(obd, fsdb, mti, mdtname);
1707 name_destroy(&mdtname);
1714 /* Add the ost info to the client/mdt lov */
1715 static int mgs_write_log_osc_to_lov(struct obd_device *obd, struct fs_db *fsdb,
1716 struct mgs_target_info *mti,
1717 char *logname, char *suffix, char *lovname,
1718 enum lustre_sec_part sec_part, int flags)
1720 struct llog_handle *llh = NULL;
1721 char *nodeuuid, *oscname, *oscuuid, *lovuuid, *svname;
1726 CDEBUG(D_INFO, "adding osc for %s to log %s\n",
1727 mti->mti_svname, logname);
1729 if (mgs_log_is_empty(obd, logname)) {
1730 CERROR("log is empty! Logical error\n");
1734 name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
1735 name_create(&svname, mti->mti_svname, "-osc");
1736 name_create(&oscname, svname, suffix);
1737 name_create(&oscuuid, oscname, "_UUID");
1738 name_create(&lovuuid, lovname, "_UUID");
1741 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
1743 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
1744 #04 L attach 0:OSC_uml1_ost1_MNT_client 1:osc 2:89070_lov1_a41dff51a
1745 #05 L setup 0:OSC_uml1_ost1_MNT_client 1:ost1_UUID 2:uml1_UUID
1747 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
1748 #07 L add_conn 0:OSC_uml1_ost1_MNT_client 1:uml2_UUID
1749 #08 L lov_modify_tgts add 0:lov1 1:ost1_UUID 2(index):0 3(gen):1
1752 rc = record_start_log(obd, &llh, logname);
1755 /* FIXME these should be a single journal transaction */
1756 rc = record_marker(obd, llh, fsdb, CM_START | flags, mti->mti_svname,
1758 for (i = 0; i < mti->mti_nid_count; i++) {
1759 CDEBUG(D_MGS, "add nid %s\n", libcfs_nid2str(mti->mti_nids[i]));
1760 rc = record_add_uuid(obd, llh, mti->mti_nids[i], nodeuuid);
1762 rc = record_attach(obd, llh, oscname, LUSTRE_OSC_NAME, lovuuid);
1763 rc = record_setup(obd, llh, oscname, mti->mti_uuid, nodeuuid, 0, 0);
1764 rc = mgs_write_log_failnids(obd, mti, llh, oscname);
1765 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
1766 rc = record_lov_add(obd, llh, lovname, mti->mti_uuid, index, "1");
1767 rc = record_marker(obd, llh, fsdb, CM_END | flags, mti->mti_svname,
1769 rc = record_end_log(obd, &llh);
1771 name_destroy(&lovuuid);
1772 name_destroy(&oscuuid);
1773 name_destroy(&oscname);
1774 name_destroy(&svname);
1775 name_destroy(&nodeuuid);
1779 static int mgs_write_log_ost(struct obd_device *obd, struct fs_db *fsdb,
1780 struct mgs_target_info *mti)
1782 struct llog_handle *llh = NULL;
1783 char *logname, *lovname;
1784 char *ptr = mti->mti_params;
1785 int rc, flags = 0, failout = 0, i;
1788 CDEBUG(D_MGS, "writing new ost %s\n", mti->mti_svname);
1790 /* The ost startup log */
1792 /* If the ost log already exists, that means that someone reformatted
1793 the ost and it called target_add again. */
1794 if (!mgs_log_is_empty(obd, mti->mti_svname)) {
1795 LCONSOLE_ERROR_MSG(0x141, "The config log for %s already "
1796 "exists, yet the server claims it never "
1797 "registered. It may have been reformatted, "
1798 "or the index changed. writeconf the MDT to "
1799 "regenerate all logs.\n", mti->mti_svname);
1804 attach obdfilter ost1 ost1_UUID
1805 setup /dev/loop2 ldiskfs f|n errors=remount-ro,user_xattr
1807 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
1808 failout = (strncmp(ptr, "failout", 7) == 0);
1809 rc = record_start_log(obd, &llh, mti->mti_svname);
1812 /* FIXME these should be a single journal transaction */
1813 rc = record_marker(obd, llh, fsdb, CM_START, mti->mti_svname,"add ost");
1814 if (*mti->mti_uuid == '\0')
1815 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
1816 "%s_UUID", mti->mti_svname);
1817 rc = record_attach(obd, llh, mti->mti_svname,
1818 "obdfilter"/*LUSTRE_OST_NAME*/, mti->mti_uuid);
1819 rc = record_setup(obd, llh, mti->mti_svname,
1820 "dev"/*ignored*/, "type"/*ignored*/,
1821 failout ? "n" : "f", 0/*options*/);
1822 rc = record_marker(obd, llh, fsdb, CM_END, mti->mti_svname, "add ost");
1823 rc = record_end_log(obd, &llh);
1825 /* We also have to update the other logs where this osc is part of
1828 if (cfs_test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
1829 /* If we're upgrading, the old mdt log already has our
1830 entry. Let's do a fake one for fun. */
1831 /* Note that we can't add any new failnids, since we don't
1832 know the old osc names. */
1833 flags = CM_SKIP | CM_UPGRADE146;
1835 } else if ((mti->mti_flags & LDD_F_UPDATE) != LDD_F_UPDATE) {
1836 /* If the update flag isn't set, don't update client/mdt
1839 LCONSOLE_WARN("Client log for %s was not updated; writeconf "
1840 "the MDT first to regenerate it.\n",
1844 /* Add ost to all MDT lov defs */
1845 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
1846 if (cfs_test_bit(i, fsdb->fsdb_mdt_index_map)) {
1849 name_create_mdt_and_lov(&logname, &lovname, fsdb, i);
1850 sprintf(mdt_index, "-MDT%04x", i);
1851 mgs_write_log_osc_to_lov(obd, fsdb, mti, logname,
1853 LUSTRE_SP_MDT, flags);
1854 name_destroy(&logname);
1855 name_destroy(&lovname);
1859 /* Append ost info to the client log */
1860 name_create(&logname, mti->mti_fsname, "-client");
1861 if (mgs_log_is_empty(obd, logname)) {
1862 /* Start client log */
1863 rc = mgs_write_log_lov(obd, fsdb, mti, logname,
1865 rc = mgs_write_log_lmv(obd, fsdb, mti, logname,
1868 mgs_write_log_osc_to_lov(obd, fsdb, mti, logname, "",
1869 fsdb->fsdb_clilov, LUSTRE_SP_CLI, flags);
1870 name_destroy(&logname);
1874 static __inline__ int mgs_param_empty(char *ptr)
1878 if ((tmp = strchr(ptr, '=')) && (*(++tmp) == '\0'))
1883 static int mgs_write_log_failnid_internal(struct obd_device *obd,
1885 struct mgs_target_info *mti,
1886 char *logname, char *cliname)
1889 struct llog_handle *llh = NULL;
1891 if (mgs_param_empty(mti->mti_params)) {
1892 /* Remove _all_ failnids */
1893 rc = mgs_modify(obd, fsdb, mti, logname,
1894 mti->mti_svname, "add failnid", CM_SKIP);
1898 /* Otherwise failover nids are additive */
1899 rc = record_start_log(obd, &llh, logname);
1901 /* FIXME this should be a single journal transaction */
1902 rc = record_marker(obd, llh, fsdb, CM_START,
1903 mti->mti_svname, "add failnid");
1904 rc = mgs_write_log_failnids(obd, mti, llh, cliname);
1905 rc = record_marker(obd, llh, fsdb, CM_END,
1906 mti->mti_svname, "add failnid");
1907 rc = record_end_log(obd, &llh);
1914 /* Add additional failnids to an existing log.
1915 The mdc/osc must have been added to logs first */
1916 /* tcp nids must be in dotted-quad ascii -
1917 we can't resolve hostnames from the kernel. */
1918 static int mgs_write_log_add_failnid(struct obd_device *obd, struct fs_db *fsdb,
1919 struct mgs_target_info *mti)
1921 char *logname, *cliname;
1925 /* FIXME we currently can't erase the failnids
1926 * given when a target first registers, since they aren't part of
1927 * an "add uuid" stanza */
1929 /* Verify that we know about this target */
1930 if (mgs_log_is_empty(obd, mti->mti_svname)) {
1931 LCONSOLE_ERROR_MSG(0x142, "The target %s has not registered "
1932 "yet. It must be started before failnids "
1933 "can be added.\n", mti->mti_svname);
1937 /* Create mdc/osc client name (e.g. lustre-OST0001-osc) */
1938 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
1939 name_create(&cliname, mti->mti_svname, "-mdc");
1940 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
1941 name_create(&cliname, mti->mti_svname, "-osc");
1946 /* Add failover nids to the client log */
1947 name_create(&logname, mti->mti_fsname, "-client");
1948 rc = mgs_write_log_failnid_internal(obd, fsdb, mti, logname, cliname);
1949 name_destroy(&logname);
1950 name_destroy(&cliname);
1952 if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
1953 /* Add OST failover nids to the MDT logs as well */
1956 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
1957 if (!cfs_test_bit(i, fsdb->fsdb_mdt_index_map))
1959 name_create_mdt(&logname, mti->mti_fsname, i);
1960 name_create_mdt_osc(&cliname, mti->mti_svname, fsdb, i);
1961 rc = mgs_write_log_failnid_internal(obd, fsdb, mti,
1963 name_destroy(&cliname);
1964 name_destroy(&logname);
1971 static int mgs_wlp_lcfg(struct obd_device *obd, struct fs_db *fsdb,
1972 struct mgs_target_info *mti,
1973 char *logname, struct lustre_cfg_bufs *bufs,
1974 char *tgtname, char *ptr)
1976 char comment[MTI_NAME_MAXLEN];
1978 struct lustre_cfg *lcfg;
1981 /* Erase any old settings of this same parameter */
1982 memcpy(comment, ptr, MTI_NAME_MAXLEN);
1983 comment[MTI_NAME_MAXLEN - 1] = 0;
1984 /* But don't try to match the value. */
1985 if ((tmp = strchr(comment, '=')))
1987 /* FIXME we should skip settings that are the same as old values */
1988 rc = mgs_modify(obd, fsdb, mti, logname, tgtname, comment, CM_SKIP);
1989 del = mgs_param_empty(ptr);
1991 LCONSOLE_INFO("%sing parameter %s.%s in log %s\n", del ? "Disabl" : rc ?
1992 "Sett" : "Modify", tgtname, comment, logname);
1996 lustre_cfg_bufs_reset(bufs, tgtname);
1997 lustre_cfg_bufs_set_string(bufs, 1, ptr);
1998 lcfg = lustre_cfg_new(LCFG_PARAM, bufs);
2001 rc = mgs_write_log_direct(obd, fsdb, logname, lcfg, tgtname, comment);
2002 lustre_cfg_free(lcfg);
2006 /* write global variable settings into log */
2007 static int mgs_write_log_sys(struct obd_device *obd, struct fs_db *fsdb,
2008 struct mgs_target_info *mti, char *sys, char *ptr)
2010 struct lustre_cfg_bufs bufs;
2011 struct lustre_cfg *lcfg;
2013 int rc, cmd, convert = 1;
2015 if (class_match_param(ptr, PARAM_TIMEOUT, &tmp) == 0) {
2016 cmd = LCFG_SET_TIMEOUT;
2017 } else if (class_match_param(ptr, PARAM_LDLM_TIMEOUT, &tmp) == 0) {
2018 cmd = LCFG_SET_LDLM_TIMEOUT;
2019 /* Check for known params here so we can return error to lctl */
2020 } else if ((class_match_param(ptr, PARAM_AT_MIN, &tmp) == 0) ||
2021 (class_match_param(ptr, PARAM_AT_MAX, &tmp) == 0) ||
2022 (class_match_param(ptr, PARAM_AT_EXTRA, &tmp) == 0) ||
2023 (class_match_param(ptr, PARAM_AT_EARLY_MARGIN, &tmp) == 0) ||
2024 (class_match_param(ptr, PARAM_AT_HISTORY, &tmp) == 0)) {
2026 } else if (class_match_param(ptr, PARAM_JOBID_VAR, &tmp) == 0) {
2027 convert = 0; /* Don't convert string value to integer */
2033 if (mgs_param_empty(ptr))
2034 CDEBUG(D_MGS, "global '%s' removed\n", sys);
2036 CDEBUG(D_MGS, "global '%s' val=%s\n", sys, tmp);
2038 lustre_cfg_bufs_reset(&bufs, NULL);
2039 lustre_cfg_bufs_set_string(&bufs, 1, sys);
2040 if (!convert && *tmp != '\0')
2041 lustre_cfg_bufs_set_string(&bufs, 2, tmp);
2042 lcfg = lustre_cfg_new(cmd, &bufs);
2043 lcfg->lcfg_num = convert ? simple_strtoul(tmp, NULL, 0) : 0;
2044 /* truncate the comment to the parameter name */
2048 /* modify all servers and clients */
2049 rc = mgs_write_log_direct_all(obd, fsdb, mti,
2050 *tmp == '\0' ? NULL : lcfg,
2051 mti->mti_fsname, sys);
2052 if (rc == 0 && *tmp != '\0') {
2054 case LCFG_SET_TIMEOUT:
2055 if (!obd_timeout_set || lcfg->lcfg_num > obd_timeout)
2056 class_process_config(lcfg);
2058 case LCFG_SET_LDLM_TIMEOUT:
2059 if (!ldlm_timeout_set || lcfg->lcfg_num > ldlm_timeout)
2060 class_process_config(lcfg);
2067 lustre_cfg_free(lcfg);
2071 static int mgs_srpc_set_param_disk(struct obd_device *obd,
2073 struct mgs_target_info *mti,
2076 struct llog_handle *llh = NULL;
2078 char *comment, *ptr;
2079 struct lustre_cfg_bufs bufs;
2080 struct lustre_cfg *lcfg;
2085 ptr = strchr(param, '=');
2089 OBD_ALLOC(comment, len + 1);
2090 if (comment == NULL)
2092 strncpy(comment, param, len);
2093 comment[len] = '\0';
2096 lustre_cfg_bufs_reset(&bufs, mti->mti_svname);
2097 lustre_cfg_bufs_set_string(&bufs, 1, param);
2098 lcfg = lustre_cfg_new(LCFG_SPTLRPC_CONF, &bufs);
2100 GOTO(out_comment, rc = -ENOMEM);
2102 /* construct log name */
2103 rc = name_create(&logname, mti->mti_fsname, "-sptlrpc");
2107 if (mgs_log_is_empty(obd, logname)) {
2108 rc = record_start_log(obd, &llh, logname);
2109 record_end_log(obd, &llh);
2114 /* obsolete old one */
2115 mgs_modify(obd, fsdb, mti, logname, mti->mti_svname, comment, CM_SKIP);
2117 /* write the new one */
2118 rc = mgs_write_log_direct(obd, fsdb, logname, lcfg,
2119 mti->mti_svname, comment);
2121 CERROR("err %d writing log %s\n", rc, logname);
2124 name_destroy(&logname);
2126 lustre_cfg_free(lcfg);
2128 OBD_FREE(comment, len + 1);
2132 static int mgs_srpc_set_param_udesc_mem(struct fs_db *fsdb,
2137 /* disable the adjustable udesc parameter for now, i.e. use default
2138 * setting that client always ship udesc to MDT if possible. to enable
2139 * it simply remove the following line */
2142 ptr = strchr(param, '=');
2147 if (strcmp(param, PARAM_SRPC_UDESC))
2150 if (strcmp(ptr, "yes") == 0) {
2151 cfs_set_bit(FSDB_UDESC, &fsdb->fsdb_flags);
2152 CWARN("Enable user descriptor shipping from client to MDT\n");
2153 } else if (strcmp(ptr, "no") == 0) {
2154 cfs_clear_bit(FSDB_UDESC, &fsdb->fsdb_flags);
2155 CWARN("Disable user descriptor shipping from client to MDT\n");
2163 CERROR("Invalid param: %s\n", param);
2167 static int mgs_srpc_set_param_mem(struct fs_db *fsdb,
2171 struct sptlrpc_rule rule;
2172 struct sptlrpc_rule_set *rset;
2176 if (strncmp(param, PARAM_SRPC, sizeof(PARAM_SRPC) - 1) != 0) {
2177 CERROR("Invalid sptlrpc parameter: %s\n", param);
2181 if (strncmp(param, PARAM_SRPC_UDESC,
2182 sizeof(PARAM_SRPC_UDESC) - 1) == 0) {
2183 RETURN(mgs_srpc_set_param_udesc_mem(fsdb, param));
2186 if (strncmp(param, PARAM_SRPC_FLVR, sizeof(PARAM_SRPC_FLVR) - 1) != 0) {
2187 CERROR("Invalid sptlrpc flavor parameter: %s\n", param);
2191 param += sizeof(PARAM_SRPC_FLVR) - 1;
2193 rc = sptlrpc_parse_rule(param, &rule);
2197 /* mgs rules implies must be mgc->mgs */
2198 if (cfs_test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
2199 if ((rule.sr_from != LUSTRE_SP_MGC &&
2200 rule.sr_from != LUSTRE_SP_ANY) ||
2201 (rule.sr_to != LUSTRE_SP_MGS &&
2202 rule.sr_to != LUSTRE_SP_ANY))
2206 /* preapre room for this coming rule. svcname format should be:
2207 * - fsname: general rule
2208 * - fsname-tgtname: target-specific rule
2210 if (strchr(svname, '-')) {
2211 struct mgs_tgt_srpc_conf *tgtconf;
2214 for (tgtconf = fsdb->fsdb_srpc_tgt; tgtconf != NULL;
2215 tgtconf = tgtconf->mtsc_next) {
2216 if (!strcmp(tgtconf->mtsc_tgt, svname)) {
2225 OBD_ALLOC_PTR(tgtconf);
2226 if (tgtconf == NULL)
2229 name_len = strlen(svname);
2231 OBD_ALLOC(tgtconf->mtsc_tgt, name_len + 1);
2232 if (tgtconf->mtsc_tgt == NULL) {
2233 OBD_FREE_PTR(tgtconf);
2236 memcpy(tgtconf->mtsc_tgt, svname, name_len);
2238 tgtconf->mtsc_next = fsdb->fsdb_srpc_tgt;
2239 fsdb->fsdb_srpc_tgt = tgtconf;
2242 rset = &tgtconf->mtsc_rset;
2244 rset = &fsdb->fsdb_srpc_gen;
2247 rc = sptlrpc_rule_set_merge(rset, &rule);
2252 static int mgs_srpc_set_param(struct obd_device *obd,
2254 struct mgs_target_info *mti,
2264 /* keep a copy of original param, which could be destroied
2266 copy_size = strlen(param) + 1;
2267 OBD_ALLOC(copy, copy_size);
2270 memcpy(copy, param, copy_size);
2272 rc = mgs_srpc_set_param_mem(fsdb, mti->mti_svname, param);
2276 /* previous steps guaranteed the syntax is correct */
2277 rc = mgs_srpc_set_param_disk(obd, fsdb, mti, copy);
2281 if (cfs_test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
2283 * for mgs rules, make them effective immediately.
2285 LASSERT(fsdb->fsdb_srpc_tgt == NULL);
2286 sptlrpc_target_update_exp_flavor(obd, &fsdb->fsdb_srpc_gen);
2290 OBD_FREE(copy, copy_size);
2294 struct mgs_srpc_read_data {
2295 struct fs_db *msrd_fsdb;
2299 static int mgs_srpc_read_handler(const struct lu_env *env,
2300 struct llog_handle *llh,
2301 struct llog_rec_hdr *rec, void *data)
2303 struct mgs_srpc_read_data *msrd = data;
2304 struct cfg_marker *marker;
2305 struct lustre_cfg *lcfg = (struct lustre_cfg *)(rec + 1);
2306 char *svname, *param;
2310 if (rec->lrh_type != OBD_CFG_REC) {
2311 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
2315 cfg_len = rec->lrh_len - sizeof(struct llog_rec_hdr) -
2316 sizeof(struct llog_rec_tail);
2318 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
2320 CERROR("Insane cfg\n");
2324 if (lcfg->lcfg_command == LCFG_MARKER) {
2325 marker = lustre_cfg_buf(lcfg, 1);
2327 if (marker->cm_flags & CM_START &&
2328 marker->cm_flags & CM_SKIP)
2329 msrd->msrd_skip = 1;
2330 if (marker->cm_flags & CM_END)
2331 msrd->msrd_skip = 0;
2336 if (msrd->msrd_skip)
2339 if (lcfg->lcfg_command != LCFG_SPTLRPC_CONF) {
2340 CERROR("invalid command (%x)\n", lcfg->lcfg_command);
2344 svname = lustre_cfg_string(lcfg, 0);
2345 if (svname == NULL) {
2346 CERROR("svname is empty\n");
2350 param = lustre_cfg_string(lcfg, 1);
2351 if (param == NULL) {
2352 CERROR("param is empty\n");
2356 rc = mgs_srpc_set_param_mem(msrd->msrd_fsdb, svname, param);
2358 CERROR("read sptlrpc record error (%d): %s\n", rc, param);
2363 int mgs_get_fsdb_srpc_from_llog(struct obd_device *obd,
2366 struct llog_handle *llh = NULL;
2367 struct lvfs_run_ctxt saved;
2368 struct llog_ctxt *ctxt;
2370 struct mgs_srpc_read_data msrd;
2374 /* construct log name */
2375 rc = name_create(&logname, fsdb->fsdb_name, "-sptlrpc");
2379 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
2380 LASSERT(ctxt != NULL);
2382 if (mgs_log_is_empty(obd, logname))
2385 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
2387 rc = llog_create(NULL, ctxt, &llh, NULL, logname);
2391 rc = llog_init_handle(NULL, llh, LLOG_F_IS_PLAIN, NULL);
2393 GOTO(out_close, rc);
2395 if (llog_get_size(llh) <= 1)
2396 GOTO(out_close, rc = 0);
2398 msrd.msrd_fsdb = fsdb;
2401 rc = llog_process(NULL, llh, mgs_srpc_read_handler, (void *) &msrd,
2405 llog_close(NULL, llh);
2407 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
2409 llog_ctxt_put(ctxt);
2410 name_destroy(&logname);
2413 CERROR("failed to read sptlrpc config database: %d\n", rc);
2417 /* Permanent settings of all parameters by writing into the appropriate
2418 * configuration logs.
2419 * A parameter with null value ("<param>='\0'") means to erase it out of
2422 static int mgs_write_log_param(struct obd_device *obd, struct fs_db *fsdb,
2423 struct mgs_target_info *mti, char *ptr)
2425 struct lustre_cfg_bufs bufs;
2428 int rc = 0, rc2 = 0;
2431 /* For various parameter settings, we have to figure out which logs
2432 care about them (e.g. both mdt and client for lov settings) */
2433 CDEBUG(D_MGS, "next param '%s'\n", ptr);
2435 /* The params are stored in MOUNT_DATA_FILE and modified via
2436 tunefs.lustre, or set using lctl conf_param */
2438 /* Processed in lustre_start_mgc */
2439 if (class_match_param(ptr, PARAM_MGSNODE, NULL) == 0)
2442 /* Processed in ost/mdt */
2443 if (class_match_param(ptr, PARAM_NETWORK, NULL) == 0)
2446 /* Processed in mgs_write_log_ost */
2447 if (class_match_param(ptr, PARAM_FAILMODE, NULL) == 0) {
2448 if (mti->mti_flags & LDD_F_PARAM) {
2449 LCONSOLE_ERROR_MSG(0x169, "%s can only be "
2450 "changed with tunefs.lustre"
2451 "and --writeconf\n", ptr);
2457 if (class_match_param(ptr, PARAM_SRPC, NULL) == 0) {
2458 rc = mgs_srpc_set_param(obd, fsdb, mti, ptr);
2462 if (class_match_param(ptr, PARAM_FAILNODE, NULL) == 0) {
2463 /* Add a failover nidlist */
2465 /* We already processed failovers params for new
2466 targets in mgs_write_log_target */
2467 if (mti->mti_flags & LDD_F_PARAM) {
2468 CDEBUG(D_MGS, "Adding failnode\n");
2469 rc = mgs_write_log_add_failnid(obd, fsdb, mti);
2474 if (class_match_param(ptr, PARAM_SYS, &tmp) == 0) {
2475 rc = mgs_write_log_sys(obd, fsdb, mti, ptr, tmp);
2479 if (class_match_param(ptr, PARAM_OSC""PARAM_ACTIVE, &tmp) == 0) {
2480 /* active=0 means off, anything else means on */
2481 int flag = (*tmp == '0') ? CM_EXCLUDE : 0;
2484 if (!(mti->mti_flags & LDD_F_SV_TYPE_OST)) {
2485 LCONSOLE_ERROR_MSG(0x144, "%s: Only OSCs can "
2486 "be (de)activated.\n",
2488 GOTO(end, rc = -EINVAL);
2490 LCONSOLE_WARN("Permanently %sactivating %s\n",
2491 flag ? "de": "re", mti->mti_svname);
2493 name_create(&logname, mti->mti_fsname, "-client");
2494 rc = mgs_modify(obd, fsdb, mti, logname,
2495 mti->mti_svname, "add osc", flag);
2496 name_destroy(&logname);
2500 /* Add to all MDT logs for CMD */
2501 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2502 if (!cfs_test_bit(i, fsdb->fsdb_mdt_index_map))
2504 name_create_mdt(&logname, mti->mti_fsname, i);
2505 rc = mgs_modify(obd, fsdb, mti, logname,
2506 mti->mti_svname, "add osc", flag);
2507 name_destroy(&logname);
2513 LCONSOLE_ERROR_MSG(0x145, "Couldn't find %s in"
2514 "log (%d). No permanent "
2515 "changes were made to the "
2517 mti->mti_svname, rc);
2518 if (cfs_test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags))
2519 LCONSOLE_ERROR_MSG(0x146, "This may be"
2524 "update the logs.\n");
2527 /* Fall through to osc proc for deactivating live OSC
2528 on running MDT / clients. */
2530 /* Below here, let obd's XXX_process_config methods handle it */
2532 /* All lov. in proc */
2533 if (class_match_param(ptr, PARAM_LOV, NULL) == 0) {
2536 CDEBUG(D_MGS, "lov param %s\n", ptr);
2537 if (!(mti->mti_flags & LDD_F_SV_TYPE_MDT)) {
2538 LCONSOLE_ERROR_MSG(0x147, "LOV params must be "
2539 "set on the MDT, not %s. "
2546 if (mgs_log_is_empty(obd, mti->mti_svname))
2547 GOTO(end, rc = -ENODEV);
2549 name_create_mdt_and_lov(&logname, &mdtlovname, fsdb,
2550 mti->mti_stripe_index);
2551 rc = mgs_wlp_lcfg(obd, fsdb, mti, mti->mti_svname,
2552 &bufs, mdtlovname, ptr);
2553 name_destroy(&logname);
2554 name_destroy(&mdtlovname);
2559 name_create(&logname, mti->mti_fsname, "-client");
2560 rc = mgs_wlp_lcfg(obd, fsdb, mti, logname, &bufs,
2561 fsdb->fsdb_clilov, ptr);
2562 name_destroy(&logname);
2566 /* All osc., mdc., llite. params in proc */
2567 if ((class_match_param(ptr, PARAM_OSC, NULL) == 0) ||
2568 (class_match_param(ptr, PARAM_MDC, NULL) == 0) ||
2569 (class_match_param(ptr, PARAM_LLITE, NULL) == 0)) {
2571 if (memcmp(ptr, PARAM_LLITE, strlen(PARAM_LLITE)) == 0) {
2572 name_create(&cname, mti->mti_fsname, "-client");
2573 /* Add the client type to match the obdname in
2574 class_config_llog_handler */
2575 } else if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
2578 name_create(&cname, fsdb->fsdb_mdc, "");
2580 name_create(&cname, mti->mti_svname,
2582 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2584 if (cfs_test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
2585 LCONSOLE_ERROR_MSG(0x148, "Upgraded "
2586 "client logs for %s"
2588 "modified. Consider"
2590 "configuration with"
2593 /* We don't know the names of all the
2595 GOTO(end, rc = -EINVAL);
2597 name_create(&cname, mti->mti_svname, "-osc");
2599 GOTO(end, rc = -EINVAL);
2602 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
2605 name_create(&logname, mti->mti_fsname, "-client");
2606 rc = mgs_wlp_lcfg(obd, fsdb, mti, logname, &bufs,
2609 /* osc params affect the MDT as well */
2610 if (!rc && (mti->mti_flags & LDD_F_SV_TYPE_OST)) {
2613 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
2614 if (!cfs_test_bit(i, fsdb->fsdb_mdt_index_map))
2616 name_destroy(&cname);
2617 name_create_mdt_osc(&cname, mti->mti_svname,
2619 name_destroy(&logname);
2620 name_create_mdt(&logname, mti->mti_fsname, i);
2621 if (!mgs_log_is_empty(obd, logname))
2622 rc = mgs_wlp_lcfg(obd, fsdb,mti,logname,
2628 name_destroy(&logname);
2629 name_destroy(&cname);
2633 /* All mdt. params in proc */
2634 if (class_match_param(ptr, PARAM_MDT, NULL) == 0) {
2638 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
2639 if (strncmp(mti->mti_svname, mti->mti_fsname,
2640 MTI_NAME_MAXLEN) == 0)
2641 /* device is unspecified completely? */
2642 rc = LDD_F_SV_TYPE_MDT | LDD_F_SV_ALL;
2644 rc = server_name2index(mti->mti_svname, &idx, NULL);
2647 if ((rc & LDD_F_SV_TYPE_MDT) == 0)
2649 if (rc & LDD_F_SV_ALL) {
2650 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2651 if (!cfs_test_bit(i,
2652 fsdb->fsdb_mdt_index_map))
2654 name_create_mdt(&logname, mti->mti_fsname, i);
2655 rc = mgs_wlp_lcfg(obd, fsdb, mti,
2658 name_destroy(&logname);
2663 rc = mgs_wlp_lcfg(obd, fsdb, mti,
2664 mti->mti_svname, &bufs,
2665 mti->mti_svname, ptr);
2672 /* All mdd., ost. params in proc */
2673 if ((class_match_param(ptr, PARAM_MDD, NULL) == 0) ||
2674 (class_match_param(ptr, PARAM_OST, NULL) == 0)) {
2675 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
2676 if (mgs_log_is_empty(obd, mti->mti_svname))
2677 GOTO(end, rc = -ENODEV);
2679 rc = mgs_wlp_lcfg(obd, fsdb, mti, mti->mti_svname,
2680 &bufs, mti->mti_svname, ptr);
2684 LCONSOLE_WARN("Ignoring unrecognized param '%s'\n", ptr);
2689 CERROR("err %d on param '%s'\n", rc, ptr);
2694 /* Not implementing automatic failover nid addition at this time. */
2695 int mgs_check_failnid(struct obd_device *obd, struct mgs_target_info *mti)
2702 rc = mgs_find_or_make_fsdb(obd, fsname, &fsdb);
2706 if (mgs_log_is_empty(obd, mti->mti_svname))
2707 /* should never happen */
2710 CDEBUG(D_MGS, "Checking for new failnids for %s\n", mti->mti_svname);
2712 /* FIXME We can just check mti->params to see if we're already in
2713 the failover list. Modify mti->params for rewriting back at
2714 server_register_target(). */
2716 cfs_mutex_lock(&fsdb->fsdb_mutex);
2717 rc = mgs_write_log_add_failnid(obd, fsdb, mti);
2718 cfs_mutex_unlock(&fsdb->fsdb_mutex);
2725 int mgs_write_log_target(struct obd_device *obd,
2726 struct mgs_target_info *mti,
2733 /* set/check the new target index */
2734 rc = mgs_set_index(obd, mti);
2736 CERROR("Can't get index (%d)\n", rc);
2741 if (mti->mti_flags & LDD_F_UPGRADE14) {
2742 if (rc == EALREADY) {
2743 LCONSOLE_INFO("Found index %d for %s 1.4 log, "
2744 "upgrading\n", mti->mti_stripe_index,
2747 LCONSOLE_ERROR_MSG(0x149, "Failed to find %s in the old"
2748 " client log. Apparently it is not "
2749 "part of this filesystem, or the old"
2750 " log is wrong.\nUse 'writeconf' on "
2751 "the MDT to force log regeneration."
2752 "\n", mti->mti_svname);
2753 /* Not in client log? Upgrade anyhow...*/
2754 /* Argument against upgrading: reformat MDT,
2755 upgrade OST, then OST will start but will be SKIPped
2756 in client logs. Maybe error now is better. */
2757 /* RETURN(-EINVAL); */
2759 /* end COMPAT_146 */
2761 if (rc == EALREADY) {
2762 LCONSOLE_WARN("Found index %d for %s, updating log\n",
2763 mti->mti_stripe_index, mti->mti_svname);
2764 /* We would like to mark old log sections as invalid
2765 and add new log sections in the client and mdt logs.
2766 But if we add new sections, then live clients will
2767 get repeat setup instructions for already running
2768 osc's. So don't update the client/mdt logs. */
2769 mti->mti_flags &= ~LDD_F_UPDATE;
2773 cfs_mutex_lock(&fsdb->fsdb_mutex);
2775 if (mti->mti_flags &
2776 (LDD_F_VIRGIN | LDD_F_UPGRADE14 | LDD_F_WRITECONF)) {
2777 /* Generate a log from scratch */
2778 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
2779 rc = mgs_write_log_mdt(obd, fsdb, mti);
2780 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2781 rc = mgs_write_log_ost(obd, fsdb, mti);
2783 CERROR("Unknown target type %#x, can't create log for "
2784 "%s\n", mti->mti_flags, mti->mti_svname);
2787 CERROR("Can't write logs for %s (%d)\n",
2788 mti->mti_svname, rc);
2792 /* Just update the params from tunefs in mgs_write_log_params */
2793 CDEBUG(D_MGS, "Update params for %s\n", mti->mti_svname);
2794 mti->mti_flags |= LDD_F_PARAM;
2797 /* allocate temporary buffer, where class_get_next_param will
2798 make copy of a current parameter */
2799 OBD_ALLOC(buf, strlen(mti->mti_params) + 1);
2801 GOTO(out_up, rc = -ENOMEM);
2802 params = mti->mti_params;
2803 while (params != NULL) {
2804 rc = class_get_next_param(¶ms, buf);
2807 /* there is no next parameter, that is
2812 CDEBUG(D_MGS, "remaining string: '%s', param: '%s'\n",
2814 rc = mgs_write_log_param(obd, fsdb, mti, buf);
2819 OBD_FREE(buf, strlen(mti->mti_params) + 1);
2822 cfs_mutex_unlock(&fsdb->fsdb_mutex);
2827 /* verify that we can handle the old config logs */
2828 int mgs_upgrade_sv_14(struct obd_device *obd, struct mgs_target_info *mti,
2834 /* Create ost log normally, as servers register. Servers
2835 register with their old uuids (from last_rcvd), so old
2836 (MDT and client) logs should work.
2837 - new MDT won't know about old OSTs, only the ones that have
2838 registered, so we need the old MDT log to get the LOV right
2839 in order for old clients to work.
2840 - Old clients connect to the MDT, not the MGS, for their logs, and
2841 will therefore receive the old client log from the MDT /LOGS dir.
2842 - Old clients can continue to use and connect to old or new OSTs
2843 - New clients will contact the MGS for their log
2846 LCONSOLE_INFO("upgrading server %s from pre-1.6\n", mti->mti_svname);
2847 server_mti_print("upgrade", mti);
2849 if (cfs_test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
2850 LCONSOLE_ERROR_MSG(0x14a, "The old client log %s-client is "
2851 "missing. Was tunefs.lustre successful?\n",
2856 if (fsdb->fsdb_gen == 0) {
2857 /* There were no markers in the client log, meaning we have
2858 not updated the logs for this fs */
2859 CDEBUG(D_MGS, "found old, unupdated client log\n");
2862 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
2863 if (mgs_log_is_empty(obd, mti->mti_svname)) {
2864 LCONSOLE_ERROR_MSG(0x14b, "The old MDT log %s is "
2865 "missing. Was tunefs.lustre "
2870 /* We're starting with an old uuid. Assume old name for lov
2871 as well since the lov entry already exists in the log. */
2872 CDEBUG(D_MGS, "old mds uuid %s\n", mti->mti_uuid);
2873 if (strncmp(mti->mti_uuid, fsdb->fsdb_mdtlov + 4,
2874 strlen(fsdb->fsdb_mdtlov) - 4) != 0) {
2875 CERROR("old mds uuid %s doesn't match log %s (%s)\n",
2876 mti->mti_uuid, fsdb->fsdb_mdtlov,
2877 fsdb->fsdb_mdtlov + 4);
2882 if (!cfs_test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
2883 LCONSOLE_ERROR_MSG(0x14c, "%s-client is supposedly an old "
2884 "log, but no old LOV or MDT was found. "
2885 "Consider updating the configuration with"
2886 " --writeconf.\n", mti->mti_fsname);
2891 /* end COMPAT_146 */
2893 int mgs_erase_log(struct obd_device *obd, char *name)
2895 struct lvfs_run_ctxt saved;
2896 struct llog_ctxt *ctxt;
2897 struct llog_handle *llh;
2900 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
2901 LASSERT(ctxt != NULL);
2903 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
2904 rc = llog_create(NULL, ctxt, &llh, NULL, name);
2906 llog_init_handle(NULL, llh, LLOG_F_IS_PLAIN, NULL);
2907 rc = llog_destroy(NULL, llh);
2908 llog_free_handle(llh);
2910 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
2911 llog_ctxt_put(ctxt);
2914 CERROR("failed to clear log %s: %d\n", name, rc);
2919 /* erase all logs for the given fs */
2920 int mgs_erase_logs(struct obd_device *obd, char *fsname)
2922 struct mgs_obd *mgs = &obd->u.mgs;
2924 cfs_list_t dentry_list;
2925 struct l_linux_dirent *dirent, *n;
2926 int rc, len = strlen(fsname);
2930 /* Find all the logs in the CONFIGS directory */
2931 rc = class_dentry_readdir(obd, mgs->mgs_configs_dir,
2932 mgs->mgs_vfsmnt, &dentry_list);
2934 CERROR("Can't read %s dir\n", MOUNT_CONFIGS_DIR);
2938 cfs_mutex_lock(&mgs->mgs_mutex);
2940 /* Delete the fs db */
2941 fsdb = mgs_find_fsdb(obd, fsname);
2943 mgs_free_fsdb(obd, fsdb);
2945 cfs_list_for_each_entry_safe(dirent, n, &dentry_list, lld_list) {
2946 cfs_list_del(&dirent->lld_list);
2947 suffix = strrchr(dirent->lld_name, '-');
2948 if (suffix != NULL) {
2949 if ((len == suffix - dirent->lld_name) &&
2950 (strncmp(fsname, dirent->lld_name, len) == 0)) {
2951 CDEBUG(D_MGS, "Removing log %s\n",
2953 mgs_erase_log(obd, dirent->lld_name);
2956 OBD_FREE(dirent, sizeof(*dirent));
2959 cfs_mutex_unlock(&mgs->mgs_mutex);
2964 /* from llog_swab */
2965 static void print_lustre_cfg(struct lustre_cfg *lcfg)
2970 CDEBUG(D_MGS, "lustre_cfg: %p\n", lcfg);
2971 CDEBUG(D_MGS, "\tlcfg->lcfg_version: %#x\n", lcfg->lcfg_version);
2973 CDEBUG(D_MGS, "\tlcfg->lcfg_command: %#x\n", lcfg->lcfg_command);
2974 CDEBUG(D_MGS, "\tlcfg->lcfg_num: %#x\n", lcfg->lcfg_num);
2975 CDEBUG(D_MGS, "\tlcfg->lcfg_flags: %#x\n", lcfg->lcfg_flags);
2976 CDEBUG(D_MGS, "\tlcfg->lcfg_nid: %s\n", libcfs_nid2str(lcfg->lcfg_nid));
2978 CDEBUG(D_MGS, "\tlcfg->lcfg_bufcount: %d\n", lcfg->lcfg_bufcount);
2979 if (lcfg->lcfg_bufcount < LUSTRE_CFG_MAX_BUFCOUNT)
2980 for (i = 0; i < lcfg->lcfg_bufcount; i++) {
2981 CDEBUG(D_MGS, "\tlcfg->lcfg_buflens[%d]: %d %s\n",
2982 i, lcfg->lcfg_buflens[i],
2983 lustre_cfg_string(lcfg, i));
2988 /* Set a permanent (config log) param for a target or fs
2989 * \param lcfg buf0 may contain the device (testfs-MDT0000) name
2990 * buf1 contains the single parameter
2992 int mgs_setparam(struct obd_device *obd, struct lustre_cfg *lcfg, char *fsname)
2995 struct mgs_target_info *mti;
2996 char *devname, *param;
3002 print_lustre_cfg(lcfg);
3004 /* lustre, lustre-mdtlov, lustre-client, lustre-MDT0000 */
3005 devname = lustre_cfg_string(lcfg, 0);
3006 param = lustre_cfg_string(lcfg, 1);
3008 /* Assume device name embedded in param:
3009 lustre-OST0000.osc.max_dirty_mb=32 */
3010 ptr = strchr(param, '.');
3018 LCONSOLE_ERROR_MSG(0x14d, "No target specified: %s\n", param);
3022 /* Extract fsname */
3023 ptr = strrchr(devname, '-');
3024 memset(fsname, 0, MTI_NAME_MAXLEN);
3025 if (ptr && (server_name2index(ptr, &index, NULL) >= 0)) {
3026 /* param related to llite isn't allowed to set by OST or MDT */
3027 if (strncmp(param, PARAM_LLITE, sizeof(PARAM_LLITE)) == 0)
3030 strncpy(fsname, devname, ptr - devname);
3032 /* assume devname is the fsname */
3033 strncpy(fsname, devname, MTI_NAME_MAXLEN);
3035 fsname[MTI_NAME_MAXLEN - 1] = 0;
3036 CDEBUG(D_MGS, "setparam fs='%s' device='%s'\n", fsname, devname);
3038 rc = mgs_find_or_make_fsdb(obd, fsname, &fsdb);
3041 if (!cfs_test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags) &&
3042 cfs_test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
3043 CERROR("No filesystem targets for %s. cfg_device from lctl "
3044 "is '%s'\n", fsname, devname);
3045 mgs_free_fsdb(obd, fsdb);
3049 /* Create a fake mti to hold everything */
3052 GOTO(out, rc = -ENOMEM);
3053 strncpy(mti->mti_fsname, fsname, MTI_NAME_MAXLEN);
3054 strncpy(mti->mti_svname, devname, MTI_NAME_MAXLEN);
3055 strncpy(mti->mti_params, param, sizeof(mti->mti_params));
3056 rc = server_name2index(mti->mti_svname, &mti->mti_stripe_index, &tmp);
3058 /* Not a valid server; may be only fsname */
3061 /* Strip -osc or -mdc suffix from svname */
3062 if (server_make_name(rc, mti->mti_stripe_index, mti->mti_fsname,
3064 GOTO(out, rc = -EINVAL);
3066 mti->mti_flags = rc | LDD_F_PARAM;
3068 cfs_mutex_lock(&fsdb->fsdb_mutex);
3069 rc = mgs_write_log_param(obd, fsdb, mti, mti->mti_params);
3070 cfs_mutex_unlock(&fsdb->fsdb_mutex);
3073 * Revoke lock so everyone updates. Should be alright if
3074 * someone was already reading while we were updating the logs,
3075 * so we don't really need to hold the lock while we're
3078 mgs_revoke_lock(obd, fsdb, CONFIG_T_CONFIG);
3084 static int mgs_write_log_pool(struct obd_device *obd, char *logname,
3085 struct fs_db *fsdb, char *lovname,
3086 enum lcfg_command_type cmd,
3087 char *poolname, char *fsname,
3088 char *ostname, char *comment)
3090 struct llog_handle *llh = NULL;
3093 rc = record_start_log(obd, &llh, logname);
3096 rc = record_marker(obd, llh, fsdb, CM_START, lovname, comment);
3097 record_base(obd, llh, lovname, 0, cmd, poolname, fsname, ostname, 0);
3098 rc = record_marker(obd, llh, fsdb, CM_END, lovname, comment);
3099 rc = record_end_log(obd, &llh);
3104 int mgs_pool_cmd(struct obd_device *obd, enum lcfg_command_type cmd,
3105 char *fsname, char *poolname, char *ostname)
3110 char *label = NULL, *canceled_label = NULL;
3112 struct mgs_target_info *mti = NULL;
3116 rc = mgs_find_or_make_fsdb(obd, fsname, &fsdb);
3118 CERROR("Can't get db for %s\n", fsname);
3121 if (cfs_test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
3122 CERROR("%s is not defined\n", fsname);
3123 mgs_free_fsdb(obd, fsdb);
3127 label_sz = 10 + strlen(fsname) + strlen(poolname);
3129 /* check if ostname match fsname */
3130 if (ostname != NULL) {
3133 ptr = strrchr(ostname, '-');
3134 if ((ptr == NULL) ||
3135 (strncmp(fsname, ostname, ptr-ostname) != 0))
3137 label_sz += strlen(ostname);
3140 OBD_ALLOC(label, label_sz);
3142 GOTO(out, rc = -ENOMEM);
3145 case LCFG_POOL_NEW: {
3147 "new %s.%s", fsname, poolname);
3150 case LCFG_POOL_ADD: {
3152 "add %s.%s.%s", fsname, poolname, ostname);
3155 case LCFG_POOL_REM: {
3156 OBD_ALLOC(canceled_label, label_sz);
3157 if (canceled_label == NULL)
3158 GOTO(out, rc = -ENOMEM);
3160 "rem %s.%s.%s", fsname, poolname, ostname);
3161 sprintf(canceled_label,
3162 "add %s.%s.%s", fsname, poolname, ostname);
3165 case LCFG_POOL_DEL: {
3166 OBD_ALLOC(canceled_label, label_sz);
3167 if (canceled_label == NULL)
3168 GOTO(out, rc = -ENOMEM);
3170 "del %s.%s", fsname, poolname);
3171 sprintf(canceled_label,
3172 "new %s.%s", fsname, poolname);
3180 cfs_mutex_lock(&fsdb->fsdb_mutex);
3182 if (canceled_label != NULL) {
3185 GOTO(out, rc = -ENOMEM);
3188 /* write pool def to all MDT logs */
3189 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3190 if (cfs_test_bit(i, fsdb->fsdb_mdt_index_map)) {
3191 name_create_mdt_and_lov(&logname, &lovname, fsdb, i);
3193 if (canceled_label != NULL) {
3194 strcpy(mti->mti_svname, "lov pool");
3195 mgs_modify(obd, fsdb, mti, logname, lovname,
3196 canceled_label, CM_SKIP);
3199 mgs_write_log_pool(obd, logname, fsdb, lovname,
3200 cmd, fsname, poolname, ostname,
3202 name_destroy(&logname);
3203 name_destroy(&lovname);
3207 name_create(&logname, fsname, "-client");
3208 if (canceled_label != NULL)
3209 mgs_modify(obd, fsdb, mti, logname, fsdb->fsdb_clilov,
3210 canceled_label, CM_SKIP);
3212 mgs_write_log_pool(obd, logname, fsdb, fsdb->fsdb_clilov,
3213 cmd, fsname, poolname, ostname, label);
3214 name_destroy(&logname);
3216 cfs_mutex_unlock(&fsdb->fsdb_mutex);
3217 /* request for update */
3218 mgs_revoke_lock(obd, fsdb, CONFIG_T_CONFIG);
3223 OBD_FREE(label, label_sz);
3225 if (canceled_label != NULL)
3226 OBD_FREE(canceled_label, label_sz);
3235 /******************** unused *********************/
3236 static int mgs_backup_llog(struct obd_device *obd, char* fsname)
3238 struct file *filp, *bak_filp;
3239 struct lvfs_run_ctxt saved;
3240 char *logname, *buf;
3241 loff_t soff = 0 , doff = 0;
3242 int count = 4096, len;
3245 OBD_ALLOC(logname, PATH_MAX);
3246 if (logname == NULL)
3249 OBD_ALLOC(buf, count);
3251 GOTO(out , rc = -ENOMEM);
3253 len = snprintf(logname, PATH_MAX, "%s/%s.bak",
3254 MOUNT_CONFIGS_DIR, fsname);
3256 if (len >= PATH_MAX - 1) {
3257 GOTO(out, -ENAMETOOLONG);
3260 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
3262 bak_filp = l_filp_open(logname, O_RDWR|O_CREAT|O_TRUNC, 0660);
3263 if (IS_ERR(bak_filp)) {
3264 rc = PTR_ERR(bak_filp);
3265 CERROR("backup logfile open %s: %d\n", logname, rc);
3268 sprintf(logname, "%s/%s", MOUNT_CONFIGS_DIR, fsname);
3269 filp = l_filp_open(logname, O_RDONLY, 0);
3272 CERROR("logfile open %s: %d\n", logname, rc);
3276 while ((rc = lustre_fread(filp, buf, count, &soff)) > 0) {
3277 rc = lustre_fwrite(bak_filp, buf, count, &doff);
3281 filp_close(filp, 0);
3283 filp_close(bak_filp, 0);
3285 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
3288 OBD_FREE(buf, count);
3289 OBD_FREE(logname, PATH_MAX);