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>
64 #include "mgs_internal.h"
66 /********************** Class functions ********************/
68 /* Caller must list_del and OBD_FREE each dentry from the list */
69 int class_dentry_readdir(const struct lu_env *env,
70 struct mgs_device *mgs, cfs_list_t *dentry_list)
72 /* see mds_cleanup_pending */
73 struct lvfs_run_ctxt saved;
75 struct dentry *dentry;
80 push_ctxt(&saved, &mgs->mgs_obd->obd_lvfs_ctxt, NULL);
81 dentry = dget(mgs->mgs_configs_dir);
83 GOTO(out_pop, rc = PTR_ERR(dentry));
84 mnt = mntget(mgs->mgs_vfsmnt);
87 GOTO(out_pop, rc = PTR_ERR(mnt));
90 file = ll_dentry_open(dentry, mnt, O_RDONLY, current_cred());
92 /* dentry_open_it() drops the dentry, mnt refs */
93 GOTO(out_pop, rc = PTR_ERR(file));
95 CFS_INIT_LIST_HEAD(dentry_list);
96 rc = l_readdir(file, dentry_list);
98 /* filp_close->fput() drops the dentry, mnt refs */
101 pop_ctxt(&saved, &mgs->mgs_obd->obd_lvfs_ctxt, NULL);
105 /******************** DB functions *********************/
107 static inline int name_create(char **newname, char *prefix, char *suffix)
110 OBD_ALLOC(*newname, strlen(prefix) + strlen(suffix) + 1);
113 sprintf(*newname, "%s%s", prefix, suffix);
117 static inline void name_destroy(char **name)
120 OBD_FREE(*name, strlen(*name) + 1);
124 struct mgs_fsdb_handler_data
130 /* from the (client) config log, figure out:
131 1. which ost's/mdt's are configured (by index)
132 2. what the last config step is
133 3. COMPAT_146 lov name
134 4. COMPAT_146 mdt lov name
135 5. COMPAT_146 mdc name
136 6. COMPAT_18 osc name
138 /* It might be better to have a separate db file, instead of parsing the info
139 out of the client log. This is slow and potentially error-prone. */
140 static int mgs_fsdb_handler(const struct lu_env *env, struct llog_handle *llh,
141 struct llog_rec_hdr *rec, void *data)
143 struct mgs_fsdb_handler_data *d = data;
144 struct fs_db *fsdb = d->fsdb;
145 int cfg_len = rec->lrh_len;
146 char *cfg_buf = (char*) (rec + 1);
147 struct lustre_cfg *lcfg;
152 if (rec->lrh_type != OBD_CFG_REC) {
153 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
157 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
159 CERROR("Insane cfg\n");
163 lcfg = (struct lustre_cfg *)cfg_buf;
165 CDEBUG(D_INFO, "cmd %x %s %s\n", lcfg->lcfg_command,
166 lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));
168 /* Figure out ost indicies */
169 /* lov_modify_tgts add 0:lov1 1:ost1_UUID 2(index):0 3(gen):1 */
170 if (lcfg->lcfg_command == LCFG_LOV_ADD_OBD ||
171 lcfg->lcfg_command == LCFG_LOV_DEL_OBD) {
172 index = simple_strtoul(lustre_cfg_string(lcfg, 2),
174 CDEBUG(D_MGS, "OST index for %s is %u (%s)\n",
175 lustre_cfg_string(lcfg, 1), index,
176 lustre_cfg_string(lcfg, 2));
177 cfs_set_bit(index, fsdb->fsdb_ost_index_map);
180 /* Figure out mdt indicies */
181 /* attach 0:MDC_uml1_mdsA_MNT_client 1:mdc 2:1d834_MNT_client_03f */
182 if ((lcfg->lcfg_command == LCFG_ATTACH) &&
183 (strcmp(lustre_cfg_string(lcfg, 1), LUSTRE_MDC_NAME) == 0)) {
184 rc = server_name2index(lustre_cfg_string(lcfg, 0),
186 if (rc != LDD_F_SV_TYPE_MDT) {
187 CWARN("Unparsable MDC name %s, assuming index 0\n",
188 lustre_cfg_string(lcfg, 0));
192 CDEBUG(D_MGS, "MDT index is %u\n", index);
193 cfs_set_bit(index, fsdb->fsdb_mdt_index_map);
194 fsdb->fsdb_mdt_count ++;
198 /* figure out the old LOV name. fsdb_gen = 0 means old log */
199 /* #01 L attach 0:lov_mdsA 1:lov 2:cdbe9_lov_mdsA_dc8cf7f3bb */
200 if ((fsdb->fsdb_gen == 0) && (lcfg->lcfg_command == LCFG_ATTACH) &&
201 (strcmp(lustre_cfg_string(lcfg, 1), LUSTRE_LOV_NAME) == 0)) {
202 cfs_set_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags);
203 name_destroy(&fsdb->fsdb_clilov);
204 rc = name_create(&fsdb->fsdb_clilov,
205 lustre_cfg_string(lcfg, 0), "");
208 CDEBUG(D_MGS, "client lov name is %s\n", fsdb->fsdb_clilov);
211 /* figure out the old MDT lov name from the MDT uuid */
212 if ((fsdb->fsdb_gen == 0) && (lcfg->lcfg_command == LCFG_SETUP) &&
213 (strncmp(lustre_cfg_string(lcfg, 0), "MDC_", 4) == 0)) {
215 cfs_set_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags);
216 ptr = strstr(lustre_cfg_string(lcfg, 1), "_UUID");
218 CERROR("Can't parse MDT uuid %s\n",
219 lustre_cfg_string(lcfg, 1));
223 name_destroy(&fsdb->fsdb_mdtlov);
224 rc = name_create(&fsdb->fsdb_mdtlov,
225 "lov_", lustre_cfg_string(lcfg, 1));
228 name_destroy(&fsdb->fsdb_mdc);
229 rc = name_create(&fsdb->fsdb_mdc,
230 lustre_cfg_string(lcfg, 0), "");
233 CDEBUG(D_MGS, "MDT lov name is %s\n", fsdb->fsdb_mdtlov);
238 * compat to 1.8, check osc name used by MDT0 to OSTs, bz18548.
240 if (!cfs_test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags) &&
241 lcfg->lcfg_command == LCFG_ATTACH &&
242 strcmp(lustre_cfg_string(lcfg, 1), LUSTRE_OSC_NAME) == 0) {
243 if (OBD_OCD_VERSION_MAJOR(d->ver) == 1 &&
244 OBD_OCD_VERSION_MINOR(d->ver) <= 8) {
245 CWARN("MDT using 1.8 OSC name scheme\n");
246 cfs_set_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags);
250 if (lcfg->lcfg_command == LCFG_MARKER) {
251 struct cfg_marker *marker;
252 marker = lustre_cfg_buf(lcfg, 1);
254 d->ver = marker->cm_vers;
256 /* Keep track of the latest marker step */
257 fsdb->fsdb_gen = max(fsdb->fsdb_gen, marker->cm_step);
263 /* fsdb->fsdb_mutex is already held in mgs_find_or_make_fsdb*/
264 static int mgs_get_fsdb_from_llog(const struct lu_env *env,
265 struct mgs_device *mgs,
269 struct llog_handle *loghandle;
270 struct lvfs_run_ctxt saved;
271 struct llog_ctxt *ctxt;
272 struct mgs_fsdb_handler_data d = { fsdb, 0 };
276 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
277 LASSERT(ctxt != NULL);
278 name_create(&logname, fsdb->fsdb_name, "-client");
279 cfs_mutex_lock(&fsdb->fsdb_mutex);
280 push_ctxt(&saved, &mgs->mgs_obd->obd_lvfs_ctxt, NULL);
281 rc = llog_open_create(NULL, ctxt, &loghandle, NULL, logname);
285 rc = llog_init_handle(NULL, loghandle, LLOG_F_IS_PLAIN, NULL);
289 if (llog_get_size(loghandle) <= 1)
290 cfs_set_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags);
292 rc = llog_process_or_fork(env, loghandle, mgs_fsdb_handler, (void *)&d,
294 CDEBUG(D_INFO, "get_db = %d\n", rc);
296 rc2 = llog_close(NULL, loghandle);
300 pop_ctxt(&saved, &mgs->mgs_obd->obd_lvfs_ctxt, NULL);
301 cfs_mutex_unlock(&fsdb->fsdb_mutex);
302 name_destroy(&logname);
308 static void mgs_free_fsdb_srpc(struct fs_db *fsdb)
310 struct mgs_tgt_srpc_conf *tgtconf;
312 /* free target-specific rules */
313 while (fsdb->fsdb_srpc_tgt) {
314 tgtconf = fsdb->fsdb_srpc_tgt;
315 fsdb->fsdb_srpc_tgt = tgtconf->mtsc_next;
317 LASSERT(tgtconf->mtsc_tgt);
319 sptlrpc_rule_set_free(&tgtconf->mtsc_rset);
320 OBD_FREE(tgtconf->mtsc_tgt, strlen(tgtconf->mtsc_tgt) + 1);
321 OBD_FREE_PTR(tgtconf);
324 /* free general rules */
325 sptlrpc_rule_set_free(&fsdb->fsdb_srpc_gen);
328 struct fs_db *mgs_find_fsdb(struct mgs_device *mgs, char *fsname)
333 cfs_list_for_each(tmp, &mgs->mgs_fs_db_list) {
334 fsdb = cfs_list_entry(tmp, struct fs_db, fsdb_list);
335 if (strcmp(fsdb->fsdb_name, fsname) == 0)
341 /* caller must hold the mgs->mgs_fs_db_lock */
342 static struct fs_db *mgs_new_fsdb(const struct lu_env *env,
343 struct mgs_device *mgs, char *fsname)
349 if (strlen(fsname) >= sizeof(fsdb->fsdb_name)) {
350 CERROR("fsname %s is too long\n", fsname);
358 strcpy(fsdb->fsdb_name, fsname);
359 cfs_mutex_init(&fsdb->fsdb_mutex);
360 cfs_set_bit(FSDB_UDESC, &fsdb->fsdb_flags);
362 if (strcmp(fsname, MGSSELF_NAME) == 0) {
363 cfs_set_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags);
365 OBD_ALLOC(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
366 OBD_ALLOC(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
367 if (!fsdb->fsdb_ost_index_map || !fsdb->fsdb_mdt_index_map) {
368 CERROR("No memory for index maps\n");
372 rc = name_create(&fsdb->fsdb_mdtlov, fsname, "-mdtlov");
375 rc = name_create(&fsdb->fsdb_mdtlmv, fsname, "-mdtlmv");
378 rc = name_create(&fsdb->fsdb_clilov, fsname, "-clilov");
381 rc = name_create(&fsdb->fsdb_clilmv, fsname, "-clilmv");
385 /* initialise data for NID table */
386 mgs_ir_init_fs(env, mgs, fsdb);
388 lproc_mgs_add_live(mgs, fsdb);
391 cfs_list_add(&fsdb->fsdb_list, &mgs->mgs_fs_db_list);
395 if (fsdb->fsdb_ost_index_map)
396 OBD_FREE(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
397 if (fsdb->fsdb_mdt_index_map)
398 OBD_FREE(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
399 name_destroy(&fsdb->fsdb_clilov);
400 name_destroy(&fsdb->fsdb_clilmv);
401 name_destroy(&fsdb->fsdb_mdtlov);
402 name_destroy(&fsdb->fsdb_mdtlmv);
407 static void mgs_free_fsdb(struct mgs_device *mgs, struct fs_db *fsdb)
409 /* wait for anyone with the sem */
410 cfs_mutex_lock(&fsdb->fsdb_mutex);
411 lproc_mgs_del_live(mgs, fsdb);
412 cfs_list_del(&fsdb->fsdb_list);
414 /* deinitialize fsr */
415 mgs_ir_fini_fs(mgs, fsdb);
417 if (fsdb->fsdb_ost_index_map)
418 OBD_FREE(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
419 if (fsdb->fsdb_mdt_index_map)
420 OBD_FREE(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
421 name_destroy(&fsdb->fsdb_clilov);
422 name_destroy(&fsdb->fsdb_clilmv);
423 name_destroy(&fsdb->fsdb_mdtlov);
424 name_destroy(&fsdb->fsdb_mdtlmv);
425 name_destroy(&fsdb->fsdb_mdc);
426 mgs_free_fsdb_srpc(fsdb);
427 cfs_mutex_unlock(&fsdb->fsdb_mutex);
431 int mgs_init_fsdb_list(struct mgs_device *mgs)
433 CFS_INIT_LIST_HEAD(&mgs->mgs_fs_db_list);
437 int mgs_cleanup_fsdb_list(struct mgs_device *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(mgs, fsdb);
446 cfs_mutex_unlock(&mgs->mgs_mutex);
450 int mgs_find_or_make_fsdb(const struct lu_env *env,
451 struct mgs_device *mgs, char *name,
457 cfs_mutex_lock(&mgs->mgs_mutex);
458 fsdb = mgs_find_fsdb(mgs, name);
460 cfs_mutex_unlock(&mgs->mgs_mutex);
465 CDEBUG(D_MGS, "Creating new db\n");
466 fsdb = mgs_new_fsdb(env, mgs, 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(env, mgs, fsdb);
475 CERROR("Can't get db from client log %d\n", rc);
476 mgs_free_fsdb(mgs, fsdb);
481 /* populate srpc rules from params llog */
482 rc = mgs_get_fsdb_srpc_from_llog(env, mgs, fsdb);
484 CERROR("Can't get db from params log %d\n", rc);
485 mgs_free_fsdb(mgs, fsdb);
496 -1= empty client log */
497 int mgs_check_index(const struct lu_env *env,
498 struct mgs_device *mgs,
499 struct mgs_target_info *mti)
506 LASSERT(!(mti->mti_flags & LDD_F_NEED_INDEX));
508 rc = mgs_find_or_make_fsdb(env, mgs, mti->mti_fsname, &fsdb);
510 CERROR("Can't get db for %s\n", mti->mti_fsname);
514 if (cfs_test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags))
517 if (mti->mti_flags & LDD_F_SV_TYPE_OST)
518 imap = fsdb->fsdb_ost_index_map;
519 else if (mti->mti_flags & LDD_F_SV_TYPE_MDT)
520 imap = fsdb->fsdb_mdt_index_map;
524 if (cfs_test_bit(mti->mti_stripe_index, imap))
529 static __inline__ int next_index(void *index_map, int map_len)
532 for (i = 0; i < map_len * 8; i++)
533 if (!cfs_test_bit(i, index_map)) {
536 CERROR("max index %d exceeded.\n", i);
541 0 newly marked as in use
543 +EALREADY for update of an old index */
544 static int mgs_set_index(const struct lu_env *env,
545 struct mgs_device *mgs,
546 struct mgs_target_info *mti)
553 rc = mgs_find_or_make_fsdb(env, mgs, mti->mti_fsname, &fsdb);
555 CERROR("Can't get db for %s\n", mti->mti_fsname);
559 if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
560 imap = fsdb->fsdb_ost_index_map;
561 } else if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
562 imap = fsdb->fsdb_mdt_index_map;
563 if (fsdb->fsdb_mdt_count >= MAX_MDT_COUNT) {
564 LCONSOLE_ERROR_MSG(0x13f, "The max mdt count"
565 "is %d\n", (int)MAX_MDT_COUNT);
572 if (mti->mti_flags & LDD_F_NEED_INDEX) {
573 rc = next_index(imap, INDEX_MAP_SIZE);
576 mti->mti_stripe_index = rc;
577 if (mti->mti_flags & LDD_F_SV_TYPE_MDT)
578 fsdb->fsdb_mdt_count ++;
581 if (mti->mti_stripe_index >= INDEX_MAP_SIZE * 8) {
582 LCONSOLE_ERROR_MSG(0x13f, "Server %s requested index %d, "
583 "but the max index is %d.\n",
584 mti->mti_svname, mti->mti_stripe_index,
589 if (cfs_test_bit(mti->mti_stripe_index, imap)) {
590 if ((mti->mti_flags & LDD_F_VIRGIN) &&
591 !(mti->mti_flags & LDD_F_WRITECONF)) {
592 LCONSOLE_ERROR_MSG(0x140, "Server %s requested index "
593 "%d, but that index is already in "
594 "use. Use --writeconf to force\n",
596 mti->mti_stripe_index);
599 CDEBUG(D_MGS, "Server %s updating index %d\n",
600 mti->mti_svname, mti->mti_stripe_index);
605 cfs_set_bit(mti->mti_stripe_index, imap);
606 cfs_clear_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags);
607 server_make_name(mti->mti_flags & ~(LDD_F_VIRGIN | LDD_F_WRITECONF),
608 mti->mti_stripe_index, mti->mti_fsname, mti->mti_svname);
610 CDEBUG(D_MGS, "Set index for %s to %d\n", mti->mti_svname,
611 mti->mti_stripe_index);
616 struct mgs_modify_lookup {
617 struct cfg_marker mml_marker;
621 static int mgs_modify_handler(const struct lu_env *env,
622 struct llog_handle *llh,
623 struct llog_rec_hdr *rec, void *data)
625 struct mgs_modify_lookup *mml = data;
626 struct cfg_marker *marker;
627 struct lustre_cfg *lcfg = (struct lustre_cfg *)(rec + 1);
628 int cfg_len = rec->lrh_len - sizeof(struct llog_rec_hdr) -
629 sizeof(struct llog_rec_tail);
633 if (rec->lrh_type != OBD_CFG_REC) {
634 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
638 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
640 CERROR("Insane cfg\n");
644 /* We only care about markers */
645 if (lcfg->lcfg_command != LCFG_MARKER)
648 marker = lustre_cfg_buf(lcfg, 1);
649 if ((strcmp(mml->mml_marker.cm_comment, marker->cm_comment) == 0) &&
650 (strcmp(mml->mml_marker.cm_tgtname, marker->cm_tgtname) == 0) &&
651 !(marker->cm_flags & CM_SKIP)) {
652 /* Found a non-skipped marker match */
653 CDEBUG(D_MGS, "Changing rec %u marker %d %x->%x: %s %s\n",
654 rec->lrh_index, marker->cm_step,
655 marker->cm_flags, mml->mml_marker.cm_flags,
656 marker->cm_tgtname, marker->cm_comment);
657 /* Overwrite the old marker llog entry */
658 marker->cm_flags &= ~CM_EXCLUDE; /* in case we're unexcluding */
659 marker->cm_flags |= mml->mml_marker.cm_flags;
660 marker->cm_canceltime = mml->mml_marker.cm_canceltime;
661 /* Header and tail are added back to lrh_len in
662 llog_lvfs_write_rec */
663 rec->lrh_len = cfg_len;
664 rc = llog_write_rec(NULL, llh, rec, NULL, 0, (void *)lcfg,
673 /* Modify an existing config log record (for CM_SKIP or CM_EXCLUDE) */
674 static int mgs_modify(const struct lu_env *env, struct mgs_device *mgs,
675 struct fs_db *fsdb, struct mgs_target_info *mti,
676 char *logname, char *devname, char *comment, int flags)
678 struct llog_handle *loghandle;
679 struct lvfs_run_ctxt saved;
680 struct llog_ctxt *ctxt;
681 struct mgs_modify_lookup *mml;
685 CDEBUG(D_MGS, "modify %s/%s/%s fl=%x\n", logname, devname, comment,
688 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
689 LASSERT(ctxt != NULL);
690 push_ctxt(&saved, &mgs->mgs_obd->obd_lvfs_ctxt, NULL);
691 rc = llog_open(NULL, ctxt, &loghandle, NULL, logname,
699 rc = llog_init_handle(NULL, loghandle, LLOG_F_IS_PLAIN, NULL);
703 if (llog_get_size(loghandle) <= 1)
704 GOTO(out_close, rc = 0);
708 GOTO(out_close, rc = -ENOMEM);
709 strcpy(mml->mml_marker.cm_comment, comment);
710 strcpy(mml->mml_marker.cm_tgtname, devname);
711 /* Modify mostly means cancel */
712 mml->mml_marker.cm_flags = flags;
713 mml->mml_marker.cm_canceltime = flags ? cfs_time_current_sec() : 0;
714 mml->mml_modified = 0;
715 rc = llog_process_or_fork(env, loghandle, mgs_modify_handler,
716 (void *)mml, NULL, false);
717 if (!rc && !mml->mml_modified)
722 rc2 = llog_close(NULL, loghandle);
726 pop_ctxt(&saved, &mgs->mgs_obd->obd_lvfs_ctxt, NULL);
727 if (rc && rc != -ENODEV)
728 CERROR("modify %s/%s failed %d\n",
729 mti->mti_svname, comment, rc);
734 /******************** config log recording functions *********************/
736 static int record_lcfg(const struct lu_env *env, struct llog_handle *llh,
737 struct lustre_cfg *lcfg)
739 struct lvfs_run_ctxt saved;
740 struct llog_rec_hdr rec;
742 struct obd_device *obd = llh->lgh_ctxt->loc_obd;
747 LASSERT(llh->lgh_ctxt);
749 buflen = lustre_cfg_len(lcfg->lcfg_bufcount,
751 rec.lrh_len = llog_data_len(buflen);
752 rec.lrh_type = OBD_CFG_REC;
754 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
755 /* idx = -1 means append */
756 rc = llog_write_rec(NULL, llh, &rec, NULL, 0, (void *)lcfg, -1);
757 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
759 CERROR("failed %d\n", rc);
763 static int record_base(const struct lu_env *env, struct llog_handle *llh,
764 char *cfgname, lnet_nid_t nid, int cmd,
765 char *s1, char *s2, char *s3, char *s4)
767 struct mgs_thread_info *mgi = mgs_env_info(env);
768 struct lustre_cfg *lcfg;
771 CDEBUG(D_MGS, "lcfg %s %#x %s %s %s %s\n", cfgname,
772 cmd, s1, s2, s3, s4);
774 lustre_cfg_bufs_reset(&mgi->mgi_bufs, cfgname);
776 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, s1);
778 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 2, s2);
780 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 3, s3);
782 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 4, s4);
784 lcfg = lustre_cfg_new(cmd, &mgi->mgi_bufs);
787 lcfg->lcfg_nid = nid;
789 rc = record_lcfg(env, llh, lcfg);
791 lustre_cfg_free(lcfg);
794 CERROR("error %d: lcfg %s %#x %s %s %s %s\n", rc, cfgname,
795 cmd, s1, s2, s3, s4);
801 static inline int record_add_uuid(const struct lu_env *env,
802 struct llog_handle *llh,
803 uint64_t nid, char *uuid)
805 return record_base(env, llh, NULL, nid, LCFG_ADD_UUID, uuid, 0, 0, 0);
809 static inline int record_add_conn(const struct lu_env *env,
810 struct llog_handle *llh,
811 char *devname, char *uuid)
813 return record_base(env, llh, devname, 0, LCFG_ADD_CONN, uuid, 0, 0, 0);
816 static inline int record_attach(const struct lu_env *env,
817 struct llog_handle *llh, char *devname,
818 char *type, char *uuid)
820 return record_base(env, llh,devname, 0, LCFG_ATTACH, type, uuid, 0, 0);
823 static inline int record_setup(const struct lu_env *env,
824 struct llog_handle *llh, char *devname,
825 char *s1, char *s2, char *s3, char *s4)
827 return record_base(env, llh, devname, 0, LCFG_SETUP, s1, s2, s3, s4);
830 static int record_lov_setup(const struct lu_env *env, struct llog_handle *llh,
831 char *devname, struct lov_desc *desc)
833 struct mgs_thread_info *mgi = mgs_env_info(env);
834 struct lustre_cfg *lcfg;
837 lustre_cfg_bufs_reset(&mgi->mgi_bufs, devname);
838 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, desc, sizeof(*desc));
839 lcfg = lustre_cfg_new(LCFG_SETUP, &mgi->mgi_bufs);
842 rc = record_lcfg(env, llh, lcfg);
844 lustre_cfg_free(lcfg);
848 static int record_lmv_setup(const struct lu_env *env, struct llog_handle *llh,
849 char *devname, struct lmv_desc *desc)
851 struct mgs_thread_info *mgi = mgs_env_info(env);
852 struct lustre_cfg *lcfg;
855 lustre_cfg_bufs_reset(&mgi->mgi_bufs, devname);
856 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, desc, sizeof(*desc));
857 lcfg = lustre_cfg_new(LCFG_SETUP, &mgi->mgi_bufs);
859 rc = record_lcfg(env, llh, lcfg);
861 lustre_cfg_free(lcfg);
865 static inline int record_mdc_add(const struct lu_env *env,
866 struct llog_handle *llh,
867 char *logname, char *mdcuuid,
868 char *mdtuuid, char *index,
871 return record_base(env,llh,logname,0,LCFG_ADD_MDC,
872 mdtuuid,index,gen,mdcuuid);
875 static inline int record_lov_add(const struct lu_env *env,
876 struct llog_handle *llh,
877 char *lov_name, char *ost_uuid,
878 char *index, char *gen)
880 return record_base(env,llh,lov_name,0,LCFG_LOV_ADD_OBD,
881 ost_uuid,index,gen,0);
884 static inline int record_mount_opt(const struct lu_env *env,
885 struct llog_handle *llh,
886 char *profile, char *lov_name,
889 return record_base(env,llh,NULL,0,LCFG_MOUNTOPT,
890 profile,lov_name,mdc_name,0);
893 static int record_marker(const struct lu_env *env,
894 struct llog_handle *llh,
895 struct fs_db *fsdb, __u32 flags,
896 char *tgtname, char *comment)
898 struct mgs_thread_info *mgi = mgs_env_info(env);
899 struct lustre_cfg *lcfg;
902 if (flags & CM_START)
904 mgi->mgi_marker.cm_step = fsdb->fsdb_gen;
905 mgi->mgi_marker.cm_flags = flags;
906 mgi->mgi_marker.cm_vers = LUSTRE_VERSION_CODE;
907 strncpy(mgi->mgi_marker.cm_tgtname, tgtname,
908 sizeof(mgi->mgi_marker.cm_tgtname));
909 strncpy(mgi->mgi_marker.cm_comment, comment,
910 sizeof(mgi->mgi_marker.cm_comment));
911 mgi->mgi_marker.cm_createtime = cfs_time_current_sec();
912 mgi->mgi_marker.cm_canceltime = 0;
913 lustre_cfg_bufs_reset(&mgi->mgi_bufs, NULL);
914 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, &mgi->mgi_marker,
915 sizeof(mgi->mgi_marker));
916 lcfg = lustre_cfg_new(LCFG_MARKER, &mgi->mgi_bufs);
919 rc = record_lcfg(env, llh, lcfg);
921 lustre_cfg_free(lcfg);
925 static int record_start_log(const struct lu_env *env,
926 struct mgs_device *mgs,
927 struct llog_handle **llh, char *name)
929 static struct obd_uuid cfg_uuid = { .uuid = "config_uuid" };
930 struct lvfs_run_ctxt saved;
931 struct llog_ctxt *ctxt;
935 GOTO(out, rc = -EBUSY);
937 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
939 GOTO(out, rc = -ENODEV);
940 LASSERT(ctxt->loc_obd == mgs->mgs_obd);
942 push_ctxt(&saved, &mgs->mgs_obd->obd_lvfs_ctxt, NULL);
943 rc = llog_open_create(NULL, ctxt, llh, NULL, name);
946 rc = llog_init_handle(NULL, *llh, LLOG_F_IS_PLAIN, &cfg_uuid);
948 llog_close(NULL, *llh);
952 pop_ctxt(&saved, &mgs->mgs_obd->obd_lvfs_ctxt, NULL);
956 CERROR("Can't start log %s: %d\n", name, rc);
960 static int record_end_log(const struct lu_env *env, struct llog_handle **llh)
962 struct lvfs_run_ctxt saved;
963 struct obd_device *obd = (*llh)->lgh_ctxt->loc_obd;
966 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
968 rc = llog_close(NULL, *llh);
971 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
975 static int mgs_log_is_empty(const struct lu_env *env,
976 struct mgs_device *mgs, char *name)
978 struct lvfs_run_ctxt saved;
979 struct llog_handle *llh;
980 struct llog_ctxt *ctxt;
983 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
984 LASSERT(ctxt != NULL);
985 push_ctxt(&saved, &mgs->mgs_obd->obd_lvfs_ctxt, NULL);
986 rc = llog_open(NULL, ctxt, &llh, NULL, name, LLOG_OPEN_EXISTS);
993 llog_init_handle(NULL, llh, LLOG_F_IS_PLAIN, NULL);
996 rc = llog_get_size(llh);
999 llog_close(NULL, llh);
1001 pop_ctxt(&saved, &mgs->mgs_obd->obd_lvfs_ctxt, NULL);
1002 llog_ctxt_put(ctxt);
1003 /* header is record 1 */
1007 /******************** config "macros" *********************/
1009 /* write an lcfg directly into a log (with markers) */
1010 static int mgs_write_log_direct(const struct lu_env *env,
1011 struct mgs_device *mgs, struct fs_db *fsdb,
1012 char *logname, struct lustre_cfg *lcfg,
1013 char *devname, char *comment)
1015 struct llog_handle *llh = NULL;
1022 rc = record_start_log(env, mgs, &llh, logname);
1026 /* FIXME These should be a single journal transaction */
1027 rc = record_marker(env, llh, fsdb, CM_START, devname, comment);
1029 rc = record_lcfg(env, llh, lcfg);
1031 rc = record_marker(env, llh, fsdb, CM_END, devname, comment);
1032 rc = record_end_log(env, &llh);
1037 /* write the lcfg in all logs for the given fs */
1038 int mgs_write_log_direct_all(const struct lu_env *env,
1039 struct mgs_device *mgs,
1041 struct mgs_target_info *mti,
1042 struct lustre_cfg *lcfg,
1043 char *devname, char *comment,
1046 cfs_list_t dentry_list;
1047 struct l_linux_dirent *dirent, *n;
1048 char *fsname = mti->mti_fsname;
1050 int rc = 0, len = strlen(fsname);
1053 /* We need to set params for any future logs
1054 as well. FIXME Append this file to every new log.
1055 Actually, we should store as params (text), not llogs. Or
1057 name_create(&logname, fsname, "-params");
1058 if (mgs_log_is_empty(env, mgs, logname)) {
1059 struct llog_handle *llh = NULL;
1060 rc = record_start_log(env, mgs, &llh, logname);
1061 record_end_log(env, &llh);
1063 name_destroy(&logname);
1067 /* Find all the logs in the CONFIGS directory */
1068 rc = class_dentry_readdir(env, mgs, &dentry_list);
1070 CERROR("Can't read %s dir\n", MOUNT_CONFIGS_DIR);
1074 /* Could use fsdb index maps instead of directory listing */
1075 cfs_list_for_each_entry_safe(dirent, n, &dentry_list, lld_list) {
1076 cfs_list_del(&dirent->lld_list);
1077 /* don't write to sptlrpc rule log */
1078 if (strstr(dirent->lld_name, "-sptlrpc") != NULL)
1081 /* caller wants write server logs only */
1082 if (server_only && strstr(dirent->lld_name, "-client") != NULL)
1085 if (strncmp(fsname, dirent->lld_name, len) == 0) {
1086 CDEBUG(D_MGS, "Changing log %s\n", dirent->lld_name);
1087 /* Erase any old settings of this same parameter */
1088 mgs_modify(env, mgs, fsdb, mti, dirent->lld_name,
1089 devname, comment, CM_SKIP);
1090 /* Write the new one */
1092 rc = mgs_write_log_direct(env, mgs, fsdb,
1097 CERROR("err %d writing log %s\n", rc,
1102 OBD_FREE(dirent, sizeof(*dirent));
1108 static int mgs_write_log_mdc_to_mdt(const struct lu_env *env,
1109 struct mgs_device *mgs,
1111 struct mgs_target_info *mti,
1113 static int mgs_write_log_osc_to_lov(const struct lu_env *env,
1114 struct mgs_device *mgs,
1116 struct mgs_target_info *mti,
1117 char *logname, char *suffix, char *lovname,
1118 enum lustre_sec_part sec_part, int flags);
1119 static void name_create_mdt_and_lov(char **logname, char **lovname,
1120 struct fs_db *fsdb, int i);
1122 static int mgs_steal_llog_handler(const struct lu_env *env,
1123 struct llog_handle *llh,
1124 struct llog_rec_hdr *rec, void *data)
1126 struct mgs_device *mgs;
1127 struct mgs_target_info *mti, *tmti;
1129 int cfg_len = rec->lrh_len;
1130 char *cfg_buf = (char*) (rec + 1);
1131 struct lustre_cfg *lcfg;
1133 struct llog_handle *mdt_llh = NULL;
1134 static int got_an_osc_or_mdc = 0;
1135 /* 0: not found any osc/mdc;
1139 static int last_step = -1;
1143 mti = ((struct temp_comp*)data)->comp_mti;
1144 tmti = ((struct temp_comp*)data)->comp_tmti;
1145 fsdb = ((struct temp_comp*)data)->comp_fsdb;
1146 mgs = ((struct temp_comp*)data)->comp_mgs;
1148 if (rec->lrh_type != OBD_CFG_REC) {
1149 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
1153 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
1155 CERROR("Insane cfg\n");
1159 lcfg = (struct lustre_cfg *)cfg_buf;
1161 if (lcfg->lcfg_command == LCFG_MARKER) {
1162 struct cfg_marker *marker;
1163 marker = lustre_cfg_buf(lcfg, 1);
1164 if (!strncmp(marker->cm_comment,"add osc",7) &&
1165 (marker->cm_flags & CM_START)){
1166 got_an_osc_or_mdc = 1;
1167 strncpy(tmti->mti_svname, marker->cm_tgtname,
1168 sizeof(tmti->mti_svname));
1169 rc = record_start_log(env, mgs, &mdt_llh,
1171 rc = record_marker(env, mdt_llh, fsdb, CM_START,
1172 mti->mti_svname,"add osc(copied)");
1173 rc = record_end_log(env, &mdt_llh);
1174 last_step = marker->cm_step;
1177 if (!strncmp(marker->cm_comment,"add osc",7) &&
1178 (marker->cm_flags & CM_END)){
1179 LASSERT(last_step == marker->cm_step);
1181 got_an_osc_or_mdc = 0;
1182 rc = record_start_log(env, mgs, &mdt_llh,
1184 rc = record_marker(env, mdt_llh, fsdb, CM_END,
1185 mti->mti_svname,"add osc(copied)");
1186 rc = record_end_log(env, &mdt_llh);
1189 if (!strncmp(marker->cm_comment,"add mdc",7) &&
1190 (marker->cm_flags & CM_START)){
1191 got_an_osc_or_mdc = 2;
1192 last_step = marker->cm_step;
1193 memcpy(tmti->mti_svname, marker->cm_tgtname,
1194 strlen(marker->cm_tgtname));
1198 if (!strncmp(marker->cm_comment,"add mdc",7) &&
1199 (marker->cm_flags & CM_END)){
1200 LASSERT(last_step == marker->cm_step);
1202 got_an_osc_or_mdc = 0;
1207 if (got_an_osc_or_mdc == 0 || last_step < 0)
1210 if (lcfg->lcfg_command == LCFG_ADD_UUID) {
1212 nodenid = lcfg->lcfg_nid;
1214 tmti->mti_nids[tmti->mti_nid_count] = nodenid;
1215 tmti->mti_nid_count++;
1220 if (lcfg->lcfg_command == LCFG_SETUP) {
1223 target = lustre_cfg_string(lcfg, 1);
1224 memcpy(tmti->mti_uuid, target, strlen(target));
1228 /* ignore client side sptlrpc_conf_log */
1229 if (lcfg->lcfg_command == LCFG_SPTLRPC_CONF)
1232 if (lcfg->lcfg_command == LCFG_ADD_MDC) {
1235 if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1)
1238 memcpy(tmti->mti_fsname, mti->mti_fsname,
1239 strlen(mti->mti_fsname));
1240 tmti->mti_stripe_index = index;
1242 mgs_write_log_mdc_to_mdt(env, mgs, fsdb,
1243 tmti, mti->mti_svname);
1244 memset(tmti, 0, sizeof(*tmti));
1248 if (lcfg->lcfg_command == LCFG_LOV_ADD_OBD) {
1251 char *logname, *lovname;
1253 name_create_mdt_and_lov(&logname, &lovname, fsdb,
1254 mti->mti_stripe_index);
1255 sprintf(mdt_index, "-MDT%04x", mti->mti_stripe_index);
1257 if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1) {
1258 name_destroy(&logname);
1259 name_destroy(&lovname);
1263 tmti->mti_stripe_index = index;
1264 mgs_write_log_osc_to_lov(env, mgs, fsdb, tmti, logname,
1267 name_destroy(&logname);
1268 name_destroy(&lovname);
1274 /* fsdb->fsdb_mutex is already held in mgs_write_log_target*/
1275 /* stealed from mgs_get_fsdb_from_llog*/
1276 static int mgs_steal_llog_for_mdt_from_client(const struct lu_env *env,
1277 struct mgs_device *mgs,
1279 struct temp_comp* comp)
1281 struct llog_handle *loghandle;
1282 struct lvfs_run_ctxt saved;
1283 struct mgs_target_info *tmti;
1284 struct llog_ctxt *ctxt;
1289 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
1290 LASSERT(ctxt != NULL);
1292 OBD_ALLOC_PTR(tmti);
1294 GOTO(out_ctxt, rc = -ENOMEM);
1296 comp->comp_tmti = tmti;
1297 comp->comp_mgs = mgs;
1299 push_ctxt(&saved, &mgs->mgs_obd->obd_lvfs_ctxt, NULL);
1301 rc = llog_open(NULL, ctxt, &loghandle, NULL, client_name,
1309 rc = llog_init_handle(NULL, loghandle, LLOG_F_IS_PLAIN, NULL);
1311 GOTO(out_close, rc);
1313 rc = llog_process_or_fork(env, loghandle, mgs_steal_llog_handler,
1314 (void *)comp, NULL, false);
1315 CDEBUG(D_MGS, "steal llog re = %d\n", rc);
1317 llog_close(NULL, loghandle);
1319 pop_ctxt(&saved, &mgs->mgs_obd->obd_lvfs_ctxt, NULL);
1322 llog_ctxt_put(ctxt);
1326 /* lmv is the second thing for client logs */
1327 /* copied from mgs_write_log_lov. Please refer to that. */
1328 static int mgs_write_log_lmv(const struct lu_env *env,
1329 struct mgs_device *mgs,
1331 struct mgs_target_info *mti,
1332 char *logname, char *lmvname)
1334 struct llog_handle *llh = NULL;
1335 struct lmv_desc *lmvdesc;
1340 CDEBUG(D_MGS, "Writing lmv(%s) log for %s\n", lmvname,logname);
1342 OBD_ALLOC_PTR(lmvdesc);
1343 if (lmvdesc == NULL)
1345 lmvdesc->ld_active_tgt_count = 0;
1346 lmvdesc->ld_tgt_count = 0;
1347 sprintf((char*)lmvdesc->ld_uuid.uuid, "%s_UUID", lmvname);
1348 uuid = (char *)lmvdesc->ld_uuid.uuid;
1350 rc = record_start_log(env, mgs, &llh, logname);
1351 rc = record_marker(env, llh, fsdb, CM_START, lmvname, "lmv setup");
1352 rc = record_attach(env, llh, lmvname, "lmv", uuid);
1353 rc = record_lmv_setup(env, llh, lmvname, lmvdesc);
1354 rc = record_marker(env, llh, fsdb, CM_END, lmvname, "lmv setup");
1355 rc = record_end_log(env, &llh);
1357 OBD_FREE_PTR(lmvdesc);
1361 /* lov is the first thing in the mdt and client logs */
1362 static int mgs_write_log_lov(const struct lu_env *env, struct mgs_device *mgs,
1363 struct fs_db *fsdb, struct mgs_target_info *mti,
1364 char *logname, char *lovname)
1366 struct llog_handle *llh = NULL;
1367 struct lov_desc *lovdesc;
1372 CDEBUG(D_MGS, "Writing lov(%s) log for %s\n", lovname, logname);
1375 #01 L attach 0:lov_mdsA 1:lov 2:71ccb_lov_mdsA_19f961a9e1
1376 #02 L lov_setup 0:lov_mdsA 1:(struct lov_desc)
1377 uuid=lov1_UUID, stripe count=1, size=1048576, offset=0, pattern=0
1380 /* FIXME just make lov_setup accept empty desc (put uuid in buf 2) */
1381 OBD_ALLOC_PTR(lovdesc);
1382 if (lovdesc == NULL)
1384 lovdesc->ld_magic = LOV_DESC_MAGIC;
1385 lovdesc->ld_tgt_count = 0;
1386 /* Defaults. Can be changed later by lcfg config_param */
1387 lovdesc->ld_default_stripe_count = 1;
1388 lovdesc->ld_pattern = LOV_PATTERN_RAID0;
1389 lovdesc->ld_default_stripe_size = 1024 * 1024;
1390 lovdesc->ld_default_stripe_offset = -1;
1391 lovdesc->ld_qos_maxage = QOS_DEFAULT_MAXAGE;
1392 sprintf((char*)lovdesc->ld_uuid.uuid, "%s_UUID", lovname);
1393 /* can these be the same? */
1394 uuid = (char *)lovdesc->ld_uuid.uuid;
1396 /* This should always be the first entry in a log.
1397 rc = mgs_clear_log(obd, logname); */
1398 rc = record_start_log(env, mgs, &llh, logname);
1401 /* FIXME these should be a single journal transaction */
1402 rc = record_marker(env, llh, fsdb, CM_START, lovname, "lov setup");
1403 rc = record_attach(env, llh, lovname, "lov", uuid);
1404 rc = record_lov_setup(env, llh, lovname, lovdesc);
1405 rc = record_marker(env, llh, fsdb, CM_END, lovname, "lov setup");
1406 rc = record_end_log(env, &llh);
1410 OBD_FREE_PTR(lovdesc);
1414 /* add failnids to open log */
1415 static int mgs_write_log_failnids(const struct lu_env *env,
1416 struct mgs_target_info *mti,
1417 struct llog_handle *llh,
1420 char *failnodeuuid = NULL;
1421 char *ptr = mti->mti_params;
1426 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) nal=90 0: 1:uml1_UUID
1427 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
1428 #05 L setup 0:OSC_uml1_ost1_mdsA 1:ost1_UUID 2:uml1_UUID
1429 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) nal=90 0: 1:uml2_UUID
1430 #0x L add_uuid nid=2@elan(0x1000000000002) nal=90 0: 1:uml2_UUID
1431 #07 L add_conn 0:OSC_uml1_ost1_mdsA 1:uml2_UUID
1434 /* Pull failnid info out of params string */
1435 while (class_find_param(ptr, PARAM_FAILNODE, &ptr) == 0) {
1436 while (class_parse_nid(ptr, &nid, &ptr) == 0) {
1437 if (failnodeuuid == NULL) {
1438 /* We don't know the failover node name,
1439 so just use the first nid as the uuid */
1440 rc = name_create(&failnodeuuid,
1441 libcfs_nid2str(nid), "");
1445 CDEBUG(D_MGS, "add nid %s for failover uuid %s, "
1446 "client %s\n", libcfs_nid2str(nid),
1447 failnodeuuid, cliname);
1448 rc = record_add_uuid(env, llh, nid, failnodeuuid);
1451 rc = record_add_conn(env, llh, cliname, failnodeuuid);
1452 name_destroy(&failnodeuuid);
1453 failnodeuuid = NULL;
1460 static int mgs_write_log_mdc_to_lmv(const struct lu_env *env,
1461 struct mgs_device *mgs,
1463 struct mgs_target_info *mti,
1464 char *logname, char *lmvname)
1466 struct llog_handle *llh = NULL;
1467 char *mdcname, *nodeuuid, *mdcuuid, *lmvuuid;
1472 if (mgs_log_is_empty(env, mgs, logname)) {
1473 CERROR("log is empty! Logical error\n");
1477 CDEBUG(D_MGS, "adding mdc for %s to log %s:lmv(%s)\n",
1478 mti->mti_svname, logname, lmvname);
1480 name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
1481 name_create(&mdcname, mti->mti_svname, "-mdc");
1482 name_create(&mdcuuid, mdcname, "_UUID");
1483 name_create(&lmvuuid, lmvname, "_UUID");
1485 rc = record_start_log(env, mgs, &llh, logname);
1486 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
1489 for (i = 0; i < mti->mti_nid_count; i++) {
1490 CDEBUG(D_MGS, "add nid %s for mdt\n",
1491 libcfs_nid2str(mti->mti_nids[i]));
1493 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
1496 rc = record_attach(env, llh, mdcname, LUSTRE_MDC_NAME, lmvuuid);
1497 rc = record_setup(env, llh, mdcname, mti->mti_uuid, nodeuuid, 0, 0);
1498 rc = mgs_write_log_failnids(env, mti, llh, mdcname);
1499 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
1500 rc = record_mdc_add(env, llh, lmvname, mdcuuid, mti->mti_uuid,
1502 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname,
1504 rc = record_end_log(env, &llh);
1506 name_destroy(&lmvuuid);
1507 name_destroy(&mdcuuid);
1508 name_destroy(&mdcname);
1509 name_destroy(&nodeuuid);
1513 /* add new mdc to already existent MDS */
1514 static int mgs_write_log_mdc_to_mdt(const struct lu_env *env,
1515 struct mgs_device *mgs,
1517 struct mgs_target_info *mti,
1520 struct llog_handle *llh = NULL;
1521 char *nodeuuid, *mdcname, *mdcuuid, *mdtuuid;
1522 int idx = mti->mti_stripe_index;
1527 if (mgs_log_is_empty(env, mgs, logname)) {
1528 CERROR("log is empty! Logical error\n");
1532 CDEBUG(D_MGS, "adding mdc index %d to %s\n", idx, logname);
1534 name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
1535 snprintf(index, sizeof(index), "-mdc%04x", idx);
1536 name_create(&mdcname, logname, index);
1537 name_create(&mdcuuid, mdcname, "_UUID");
1538 name_create(&mdtuuid, logname, "_UUID");
1540 rc = record_start_log(env, mgs, &llh, logname);
1541 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname, "add mdc");
1542 for (i = 0; i < mti->mti_nid_count; i++) {
1543 CDEBUG(D_MGS, "add nid %s for mdt\n",
1544 libcfs_nid2str(mti->mti_nids[i]));
1545 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
1547 rc = record_attach(env, llh, mdcname, LUSTRE_MDC_NAME, mdcuuid);
1548 rc = record_setup(env, llh, mdcname, mti->mti_uuid, nodeuuid, 0, 0);
1549 rc = mgs_write_log_failnids(env, mti, llh, mdcname);
1550 snprintf(index, sizeof(index), "%d", idx);
1552 rc = record_mdc_add(env, llh, logname, mdcuuid, mti->mti_uuid,
1554 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname, "add mdc");
1555 rc = record_end_log(env, &llh);
1557 name_destroy(&mdcuuid);
1558 name_destroy(&mdcname);
1559 name_destroy(&nodeuuid);
1560 name_destroy(&mdtuuid);
1564 static int mgs_write_log_mdt0(const struct lu_env *env,
1565 struct mgs_device *mgs,
1567 struct mgs_target_info *mti)
1569 char *log = mti->mti_svname;
1570 struct llog_handle *llh = NULL;
1571 char *uuid, *lovname;
1573 char *ptr = mti->mti_params;
1574 int rc = 0, failout = 0;
1577 OBD_ALLOC(uuid, sizeof(struct obd_uuid));
1581 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
1582 failout = (strncmp(ptr, "failout", 7) == 0);
1584 name_create(&lovname, log, "-mdtlov");
1585 if (mgs_log_is_empty(env, mgs, log))
1586 rc = mgs_write_log_lov(env, mgs, fsdb, mti, log, lovname);
1588 sprintf(uuid, "%s_UUID", log);
1589 sprintf(mdt_index, "%d", mti->mti_stripe_index);
1591 /* add MDT itself */
1592 rc = record_start_log(env, mgs, &llh, log);
1596 /* FIXME this whole fn should be a single journal transaction */
1597 rc = record_marker(env, llh, fsdb, CM_START, log, "add mdt");
1598 rc = record_attach(env, llh, log, LUSTRE_MDT_NAME, uuid);
1599 rc = record_mount_opt(env, llh, log, lovname, NULL);
1600 rc = record_setup(env, llh, log, uuid, mdt_index, lovname,
1601 failout ? "n" : "f");
1602 rc = record_marker(env, llh, fsdb, CM_END, log, "add mdt");
1603 rc = record_end_log(env, &llh);
1605 name_destroy(&lovname);
1606 OBD_FREE(uuid, sizeof(struct obd_uuid));
1610 static inline void name_create_mdt(char **logname, char *fsname, int i)
1614 sprintf(mdt_index, "-MDT%04x", i);
1615 name_create(logname, fsname, mdt_index);
1618 static void name_create_mdt_and_lov(char **logname, char **lovname,
1619 struct fs_db *fsdb, int i)
1621 name_create_mdt(logname, fsdb->fsdb_name, i);
1623 if (i == 0 && cfs_test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
1624 name_create(lovname, fsdb->fsdb_name, "-mdtlov");
1626 name_create(lovname, *logname, "-mdtlov");
1629 static inline void name_create_mdt_osc(char **oscname, char *ostname,
1630 struct fs_db *fsdb, int i)
1634 if (i == 0 && cfs_test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
1635 sprintf(suffix, "-osc");
1637 sprintf(suffix, "-osc-MDT%04x", i);
1638 name_create(oscname, ostname, suffix);
1641 /* envelope method for all layers log */
1642 static int mgs_write_log_mdt(const struct lu_env *env,
1643 struct mgs_device *mgs,
1645 struct mgs_target_info *mti)
1647 struct mgs_thread_info *mgi = mgs_env_info(env);
1648 struct llog_handle *llh = NULL;
1653 CDEBUG(D_MGS, "writing new mdt %s\n", mti->mti_svname);
1657 if (mti->mti_flags & LDD_F_UPGRADE14) {
1658 /* We're starting with an old uuid. Assume old name for lov
1659 as well since the lov entry already exists in the log. */
1660 CDEBUG(D_MGS, "old mds uuid %s\n", mti->mti_uuid);
1661 if (strncmp(mti->mti_uuid, fsdb->fsdb_mdtlov + 4,
1662 strlen(fsdb->fsdb_mdtlov) - 4) != 0) {
1663 CERROR("old mds uuid %s doesn't match log %s (%s)\n",
1664 mti->mti_uuid, fsdb->fsdb_mdtlov,
1665 fsdb->fsdb_mdtlov + 4);
1669 /* end COMPAT_146 */
1671 if (mti->mti_uuid[0] == '\0') {
1672 /* Make up our own uuid */
1673 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
1674 "%s_UUID", mti->mti_svname);
1678 rc = mgs_write_log_mdt0(env, mgs, fsdb, mti);
1680 /* Append the mdt info to the client log */
1681 name_create(&cliname, mti->mti_fsname, "-client");
1683 if (mgs_log_is_empty(env, mgs, cliname)) {
1684 /* Start client log */
1685 rc = mgs_write_log_lov(env, mgs, fsdb, mti, cliname,
1687 rc = mgs_write_log_lmv(env, mgs, fsdb, mti, cliname,
1692 #09 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
1693 #10 L attach 0:MDC_uml1_mdsA_MNT_client 1:mdc 2:1d834_MNT_client_03f
1694 #11 L setup 0:MDC_uml1_mdsA_MNT_client 1:mdsA_UUID 2:uml1_UUID
1695 #12 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
1696 #13 L add_conn 0:MDC_uml1_mdsA_MNT_client 1:uml2_UUID
1697 #14 L mount_option 0: 1:client 2:lov1 3:MDC_uml1_mdsA_MNT_client
1702 if (mti->mti_flags & LDD_F_UPGRADE14) {
1703 rc = record_start_log(obd, &llh, cliname);
1707 rc = record_marker(obd, llh, fsdb, CM_START,
1708 mti->mti_svname,"add mdc");
1710 /* Old client log already has MDC entry, but needs mount opt
1711 for new client name (lustre-client) */
1712 /* FIXME Old MDT log already has an old mount opt
1713 which we should remove (currently handled by
1714 class_del_profiles()) */
1715 rc = record_mount_opt(obd, llh, cliname, fsdb->fsdb_clilov,
1717 /* end COMPAT_146 */
1719 rc = record_marker(obd, llh, fsdb, CM_END,
1720 mti->mti_svname, "add mdc");
1724 /* copy client info about lov/lmv */
1725 mgi->mgi_comp.comp_mti = mti;
1726 mgi->mgi_comp.comp_fsdb = fsdb;
1728 rc = mgs_steal_llog_for_mdt_from_client(env, mgs, cliname,
1731 rc = mgs_write_log_mdc_to_lmv(env, mgs, fsdb, mti, cliname,
1734 rc = record_start_log(env, mgs, &llh, cliname);
1738 rc = record_marker(env, llh, fsdb, CM_START, cliname,
1740 rc = record_mount_opt(env, llh, cliname, fsdb->fsdb_clilov,
1742 rc = record_marker(env, llh, fsdb, CM_END, cliname,
1746 rc = record_end_log(env, &llh);
1748 name_destroy(&cliname);
1750 // for_all_existing_mdt except current one
1751 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
1753 if (i != mti->mti_stripe_index &&
1754 cfs_test_bit(i, fsdb->fsdb_mdt_index_map)) {
1755 name_create_mdt(&mdtname, mti->mti_fsname, i);
1756 rc = mgs_write_log_mdc_to_mdt(env, mgs, fsdb,
1758 name_destroy(&mdtname);
1765 /* Add the ost info to the client/mdt lov */
1766 static int mgs_write_log_osc_to_lov(const struct lu_env *env,
1767 struct mgs_device *mgs, struct fs_db *fsdb,
1768 struct mgs_target_info *mti,
1769 char *logname, char *suffix, char *lovname,
1770 enum lustre_sec_part sec_part, int flags)
1772 struct llog_handle *llh = NULL;
1773 char *nodeuuid, *oscname, *oscuuid, *lovuuid, *svname;
1778 CDEBUG(D_INFO, "adding osc for %s to log %s\n",
1779 mti->mti_svname, logname);
1781 if (mgs_log_is_empty(env, mgs, logname)) {
1782 CERROR("log is empty! Logical error\n");
1786 name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
1787 name_create(&svname, mti->mti_svname, "-osc");
1788 name_create(&oscname, svname, suffix);
1789 name_create(&oscuuid, oscname, "_UUID");
1790 name_create(&lovuuid, lovname, "_UUID");
1793 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
1795 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
1796 #04 L attach 0:OSC_uml1_ost1_MNT_client 1:osc 2:89070_lov1_a41dff51a
1797 #05 L setup 0:OSC_uml1_ost1_MNT_client 1:ost1_UUID 2:uml1_UUID
1799 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
1800 #07 L add_conn 0:OSC_uml1_ost1_MNT_client 1:uml2_UUID
1801 #08 L lov_modify_tgts add 0:lov1 1:ost1_UUID 2(index):0 3(gen):1
1804 rc = record_start_log(env, mgs, &llh, logname);
1807 /* FIXME these should be a single journal transaction */
1808 rc = record_marker(env, llh, fsdb, CM_START | flags, mti->mti_svname,
1810 for (i = 0; i < mti->mti_nid_count; i++) {
1811 CDEBUG(D_MGS, "add nid %s\n", libcfs_nid2str(mti->mti_nids[i]));
1812 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
1814 rc = record_attach(env, llh, oscname, LUSTRE_OSC_NAME, lovuuid);
1815 rc = record_setup(env, llh, oscname, mti->mti_uuid, nodeuuid, 0, 0);
1816 rc = mgs_write_log_failnids(env, mti, llh, oscname);
1817 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
1818 rc = record_lov_add(env, llh, lovname, mti->mti_uuid, index, "1");
1819 rc = record_marker(env, llh, fsdb, CM_END | flags, mti->mti_svname,
1821 rc = record_end_log(env, &llh);
1823 name_destroy(&lovuuid);
1824 name_destroy(&oscuuid);
1825 name_destroy(&oscname);
1826 name_destroy(&svname);
1827 name_destroy(&nodeuuid);
1831 static int mgs_write_log_ost(const struct lu_env *env,
1832 struct mgs_device *mgs, struct fs_db *fsdb,
1833 struct mgs_target_info *mti)
1835 struct llog_handle *llh = NULL;
1836 char *logname, *lovname;
1837 char *ptr = mti->mti_params;
1838 int rc, flags = 0, failout = 0, i;
1841 CDEBUG(D_MGS, "writing new ost %s\n", mti->mti_svname);
1843 /* The ost startup log */
1845 /* If the ost log already exists, that means that someone reformatted
1846 the ost and it called target_add again. */
1847 if (!mgs_log_is_empty(env, mgs, mti->mti_svname)) {
1848 LCONSOLE_ERROR_MSG(0x141, "The config log for %s already "
1849 "exists, yet the server claims it never "
1850 "registered. It may have been reformatted, "
1851 "or the index changed. writeconf the MDT to "
1852 "regenerate all logs.\n", mti->mti_svname);
1857 attach obdfilter ost1 ost1_UUID
1858 setup /dev/loop2 ldiskfs f|n errors=remount-ro,user_xattr
1860 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
1861 failout = (strncmp(ptr, "failout", 7) == 0);
1862 rc = record_start_log(env, mgs, &llh, mti->mti_svname);
1865 /* FIXME these should be a single journal transaction */
1866 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,"add ost");
1867 if (*mti->mti_uuid == '\0')
1868 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
1869 "%s_UUID", mti->mti_svname);
1870 rc = record_attach(env, llh, mti->mti_svname,
1871 "obdfilter"/*LUSTRE_OST_NAME*/, mti->mti_uuid);
1872 rc = record_setup(env, llh, mti->mti_svname,
1873 "dev"/*ignored*/, "type"/*ignored*/,
1874 failout ? "n" : "f", 0/*options*/);
1875 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname, "add ost");
1876 rc = record_end_log(env, &llh);
1878 /* We also have to update the other logs where this osc is part of
1881 if (cfs_test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
1882 /* If we're upgrading, the old mdt log already has our
1883 entry. Let's do a fake one for fun. */
1884 /* Note that we can't add any new failnids, since we don't
1885 know the old osc names. */
1886 flags = CM_SKIP | CM_UPGRADE146;
1888 } else if ((mti->mti_flags & LDD_F_UPDATE) != LDD_F_UPDATE) {
1889 /* If the update flag isn't set, don't update client/mdt
1892 LCONSOLE_WARN("Client log for %s was not updated; writeconf "
1893 "the MDT first to regenerate it.\n",
1897 /* Add ost to all MDT lov defs */
1898 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
1899 if (cfs_test_bit(i, fsdb->fsdb_mdt_index_map)) {
1902 name_create_mdt_and_lov(&logname, &lovname, fsdb, i);
1903 sprintf(mdt_index, "-MDT%04x", i);
1904 mgs_write_log_osc_to_lov(env, mgs, fsdb, mti, logname,
1906 LUSTRE_SP_MDT, flags);
1907 name_destroy(&logname);
1908 name_destroy(&lovname);
1912 /* Append ost info to the client log */
1913 name_create(&logname, mti->mti_fsname, "-client");
1914 if (mgs_log_is_empty(env, mgs, logname)) {
1915 /* Start client log */
1916 rc = mgs_write_log_lov(env, mgs, fsdb, mti, logname,
1918 rc = mgs_write_log_lmv(env, mgs, fsdb, mti, logname,
1921 mgs_write_log_osc_to_lov(env, mgs, fsdb, mti, logname, "",
1922 fsdb->fsdb_clilov, LUSTRE_SP_CLI, flags);
1923 name_destroy(&logname);
1927 static __inline__ int mgs_param_empty(char *ptr)
1931 if ((tmp = strchr(ptr, '=')) && (*(++tmp) == '\0'))
1936 static int mgs_write_log_failnid_internal(const struct lu_env *env,
1937 struct mgs_device *mgs,
1939 struct mgs_target_info *mti,
1940 char *logname, char *cliname)
1943 struct llog_handle *llh = NULL;
1945 if (mgs_param_empty(mti->mti_params)) {
1946 /* Remove _all_ failnids */
1947 rc = mgs_modify(env, mgs, fsdb, mti, logname,
1948 mti->mti_svname, "add failnid", CM_SKIP);
1952 /* Otherwise failover nids are additive */
1953 rc = record_start_log(env, mgs, &llh, logname);
1955 /* FIXME this should be a single journal transaction */
1956 rc = record_marker(env, llh, fsdb, CM_START,
1957 mti->mti_svname, "add failnid");
1958 rc = mgs_write_log_failnids(env, mti, llh, cliname);
1959 rc = record_marker(env, llh, fsdb, CM_END,
1960 mti->mti_svname, "add failnid");
1961 rc = record_end_log(env, &llh);
1968 /* Add additional failnids to an existing log.
1969 The mdc/osc must have been added to logs first */
1970 /* tcp nids must be in dotted-quad ascii -
1971 we can't resolve hostnames from the kernel. */
1972 static int mgs_write_log_add_failnid(const struct lu_env *env,
1973 struct mgs_device *mgs,
1975 struct mgs_target_info *mti)
1977 char *logname, *cliname;
1981 /* FIXME we currently can't erase the failnids
1982 * given when a target first registers, since they aren't part of
1983 * an "add uuid" stanza */
1985 /* Verify that we know about this target */
1986 if (mgs_log_is_empty(env, mgs, mti->mti_svname)) {
1987 LCONSOLE_ERROR_MSG(0x142, "The target %s has not registered "
1988 "yet. It must be started before failnids "
1989 "can be added.\n", mti->mti_svname);
1993 /* Create mdc/osc client name (e.g. lustre-OST0001-osc) */
1994 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
1995 name_create(&cliname, mti->mti_svname, "-mdc");
1996 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
1997 name_create(&cliname, mti->mti_svname, "-osc");
2002 /* Add failover nids to the client log */
2003 name_create(&logname, mti->mti_fsname, "-client");
2004 rc = mgs_write_log_failnid_internal(env, mgs, fsdb,mti,logname,cliname);
2005 name_destroy(&logname);
2006 name_destroy(&cliname);
2008 if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2009 /* Add OST failover nids to the MDT logs as well */
2012 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2013 if (!cfs_test_bit(i, fsdb->fsdb_mdt_index_map))
2015 name_create_mdt(&logname, mti->mti_fsname, i);
2016 name_create_mdt_osc(&cliname, mti->mti_svname, fsdb, i);
2017 rc = mgs_write_log_failnid_internal(env, mgs, fsdb, mti,
2019 name_destroy(&cliname);
2020 name_destroy(&logname);
2027 static int mgs_wlp_lcfg(const struct lu_env *env,
2028 struct mgs_device *mgs, struct fs_db *fsdb,
2029 struct mgs_target_info *mti,
2030 char *logname, struct lustre_cfg_bufs *bufs,
2031 char *tgtname, char *ptr)
2033 char comment[MTI_NAME_MAXLEN];
2035 struct lustre_cfg *lcfg;
2038 /* Erase any old settings of this same parameter */
2039 memcpy(comment, ptr, MTI_NAME_MAXLEN);
2040 comment[MTI_NAME_MAXLEN - 1] = 0;
2041 /* But don't try to match the value. */
2042 if ((tmp = strchr(comment, '=')))
2044 /* FIXME we should skip settings that are the same as old values */
2045 rc = mgs_modify(env, mgs, fsdb, mti, logname, tgtname, comment,CM_SKIP);
2046 del = mgs_param_empty(ptr);
2048 LCONSOLE_INFO("%sing parameter %s.%s in log %s\n", del ? "Disabl" : rc ?
2049 "Sett" : "Modify", tgtname, comment, logname);
2053 lustre_cfg_bufs_reset(bufs, tgtname);
2054 lustre_cfg_bufs_set_string(bufs, 1, ptr);
2055 lcfg = lustre_cfg_new(LCFG_PARAM, bufs);
2058 rc = mgs_write_log_direct(env, mgs, fsdb, logname,lcfg,tgtname,comment);
2059 lustre_cfg_free(lcfg);
2063 /* write global variable settings into log */
2064 static int mgs_write_log_sys(const struct lu_env *env,
2065 struct mgs_device *mgs, struct fs_db *fsdb,
2066 struct mgs_target_info *mti, char *sys, char *ptr)
2068 struct mgs_thread_info *mgi = mgs_env_info(env);
2069 struct lustre_cfg *lcfg;
2071 int rc, cmd, convert = 1;
2073 if (class_match_param(ptr, PARAM_TIMEOUT, &tmp) == 0) {
2074 cmd = LCFG_SET_TIMEOUT;
2075 } else if (class_match_param(ptr, PARAM_LDLM_TIMEOUT, &tmp) == 0) {
2076 cmd = LCFG_SET_LDLM_TIMEOUT;
2077 /* Check for known params here so we can return error to lctl */
2078 } else if ((class_match_param(ptr, PARAM_AT_MIN, &tmp) == 0) ||
2079 (class_match_param(ptr, PARAM_AT_MAX, &tmp) == 0) ||
2080 (class_match_param(ptr, PARAM_AT_EXTRA, &tmp) == 0) ||
2081 (class_match_param(ptr, PARAM_AT_EARLY_MARGIN, &tmp) == 0) ||
2082 (class_match_param(ptr, PARAM_AT_HISTORY, &tmp) == 0)) {
2084 } else if (class_match_param(ptr, PARAM_JOBID_VAR, &tmp) == 0) {
2085 convert = 0; /* Don't convert string value to integer */
2091 if (mgs_param_empty(ptr))
2092 CDEBUG(D_MGS, "global '%s' removed\n", sys);
2094 CDEBUG(D_MGS, "global '%s' val=%s\n", sys, tmp);
2096 lustre_cfg_bufs_reset(&mgi->mgi_bufs, NULL);
2097 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, sys);
2098 if (!convert && *tmp != '\0')
2099 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 2, tmp);
2100 lcfg = lustre_cfg_new(cmd, &mgi->mgi_bufs);
2101 lcfg->lcfg_num = convert ? simple_strtoul(tmp, NULL, 0) : 0;
2102 /* truncate the comment to the parameter name */
2106 /* modify all servers and clients */
2107 rc = mgs_write_log_direct_all(env, mgs, fsdb, mti,
2108 *tmp == '\0' ? NULL : lcfg,
2109 mti->mti_fsname, sys, 0);
2110 if (rc == 0 && *tmp != '\0') {
2112 case LCFG_SET_TIMEOUT:
2113 if (!obd_timeout_set || lcfg->lcfg_num > obd_timeout)
2114 class_process_config(lcfg);
2116 case LCFG_SET_LDLM_TIMEOUT:
2117 if (!ldlm_timeout_set || lcfg->lcfg_num > ldlm_timeout)
2118 class_process_config(lcfg);
2125 lustre_cfg_free(lcfg);
2129 /* write quota settings into log */
2130 static int mgs_write_log_quota(const struct lu_env *env, struct mgs_device *mgs,
2131 struct fs_db *fsdb, struct mgs_target_info *mti,
2132 char *quota, char *ptr)
2134 struct lustre_cfg_bufs bufs;
2135 struct lustre_cfg *lcfg;
2138 int cmd = LCFG_PARAM;
2141 /* support only 'meta' and 'data' pools so far */
2142 if (class_match_param(ptr, QUOTA_METAPOOL_NAME, &tmp) != 0 &&
2143 class_match_param(ptr, QUOTA_DATAPOOL_NAME, &tmp) != 0) {
2144 CERROR("parameter quota.%s isn't supported (only quota.mdt "
2145 "& quota.ost are)\n", ptr);
2150 CDEBUG(D_MGS, "global '%s' removed\n", quota);
2152 CDEBUG(D_MGS, "global '%s'\n", quota);
2154 if (strchr(tmp, 'u') == NULL && strchr(tmp, 'g') == NULL &&
2155 strcmp(tmp, "none") != 0) {
2156 CERROR("enable option(%s) isn't supported\n", tmp);
2161 lustre_cfg_bufs_reset(&bufs, NULL);
2162 lustre_cfg_bufs_set_string(&bufs, 1, quota);
2163 lcfg = lustre_cfg_new(cmd, &bufs);
2164 /* truncate the comment to the parameter name */
2169 /* XXX we duplicated quota enable information in all server
2170 * config logs, it should be moved to a separate config
2171 * log once we cleanup the config log for global param. */
2172 /* modify all servers */
2173 rc = mgs_write_log_direct_all(env, mgs, fsdb, mti,
2174 *tmp == '\0' ? NULL : lcfg,
2175 mti->mti_fsname, quota, 1);
2177 lustre_cfg_free(lcfg);
2181 static int mgs_srpc_set_param_disk(const struct lu_env *env,
2182 struct mgs_device *mgs,
2184 struct mgs_target_info *mti,
2187 struct mgs_thread_info *mgi = mgs_env_info(env);
2188 struct llog_handle *llh = NULL;
2190 char *comment, *ptr;
2191 struct lustre_cfg *lcfg;
2196 ptr = strchr(param, '=');
2200 OBD_ALLOC(comment, len + 1);
2201 if (comment == NULL)
2203 strncpy(comment, param, len);
2204 comment[len] = '\0';
2207 lustre_cfg_bufs_reset(&mgi->mgi_bufs, mti->mti_svname);
2208 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, param);
2209 lcfg = lustre_cfg_new(LCFG_SPTLRPC_CONF, &mgi->mgi_bufs);
2211 GOTO(out_comment, rc = -ENOMEM);
2213 /* construct log name */
2214 rc = name_create(&logname, mti->mti_fsname, "-sptlrpc");
2218 if (mgs_log_is_empty(env, mgs, logname)) {
2219 rc = record_start_log(env, mgs, &llh, logname);
2220 record_end_log(env, &llh);
2225 /* obsolete old one */
2226 mgs_modify(env, mgs, fsdb, mti, logname, mti->mti_svname,
2229 /* write the new one */
2230 rc = mgs_write_log_direct(env, mgs, fsdb, logname, lcfg,
2231 mti->mti_svname, comment);
2233 CERROR("err %d writing log %s\n", rc, logname);
2236 name_destroy(&logname);
2238 lustre_cfg_free(lcfg);
2240 OBD_FREE(comment, len + 1);
2244 static int mgs_srpc_set_param_udesc_mem(struct fs_db *fsdb,
2249 /* disable the adjustable udesc parameter for now, i.e. use default
2250 * setting that client always ship udesc to MDT if possible. to enable
2251 * it simply remove the following line */
2254 ptr = strchr(param, '=');
2259 if (strcmp(param, PARAM_SRPC_UDESC))
2262 if (strcmp(ptr, "yes") == 0) {
2263 cfs_set_bit(FSDB_UDESC, &fsdb->fsdb_flags);
2264 CWARN("Enable user descriptor shipping from client to MDT\n");
2265 } else if (strcmp(ptr, "no") == 0) {
2266 cfs_clear_bit(FSDB_UDESC, &fsdb->fsdb_flags);
2267 CWARN("Disable user descriptor shipping from client to MDT\n");
2275 CERROR("Invalid param: %s\n", param);
2279 static int mgs_srpc_set_param_mem(struct fs_db *fsdb,
2283 struct sptlrpc_rule rule;
2284 struct sptlrpc_rule_set *rset;
2288 if (strncmp(param, PARAM_SRPC, sizeof(PARAM_SRPC) - 1) != 0) {
2289 CERROR("Invalid sptlrpc parameter: %s\n", param);
2293 if (strncmp(param, PARAM_SRPC_UDESC,
2294 sizeof(PARAM_SRPC_UDESC) - 1) == 0) {
2295 RETURN(mgs_srpc_set_param_udesc_mem(fsdb, param));
2298 if (strncmp(param, PARAM_SRPC_FLVR, sizeof(PARAM_SRPC_FLVR) - 1) != 0) {
2299 CERROR("Invalid sptlrpc flavor parameter: %s\n", param);
2303 param += sizeof(PARAM_SRPC_FLVR) - 1;
2305 rc = sptlrpc_parse_rule(param, &rule);
2309 /* mgs rules implies must be mgc->mgs */
2310 if (cfs_test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
2311 if ((rule.sr_from != LUSTRE_SP_MGC &&
2312 rule.sr_from != LUSTRE_SP_ANY) ||
2313 (rule.sr_to != LUSTRE_SP_MGS &&
2314 rule.sr_to != LUSTRE_SP_ANY))
2318 /* preapre room for this coming rule. svcname format should be:
2319 * - fsname: general rule
2320 * - fsname-tgtname: target-specific rule
2322 if (strchr(svname, '-')) {
2323 struct mgs_tgt_srpc_conf *tgtconf;
2326 for (tgtconf = fsdb->fsdb_srpc_tgt; tgtconf != NULL;
2327 tgtconf = tgtconf->mtsc_next) {
2328 if (!strcmp(tgtconf->mtsc_tgt, svname)) {
2337 OBD_ALLOC_PTR(tgtconf);
2338 if (tgtconf == NULL)
2341 name_len = strlen(svname);
2343 OBD_ALLOC(tgtconf->mtsc_tgt, name_len + 1);
2344 if (tgtconf->mtsc_tgt == NULL) {
2345 OBD_FREE_PTR(tgtconf);
2348 memcpy(tgtconf->mtsc_tgt, svname, name_len);
2350 tgtconf->mtsc_next = fsdb->fsdb_srpc_tgt;
2351 fsdb->fsdb_srpc_tgt = tgtconf;
2354 rset = &tgtconf->mtsc_rset;
2356 rset = &fsdb->fsdb_srpc_gen;
2359 rc = sptlrpc_rule_set_merge(rset, &rule);
2364 static int mgs_srpc_set_param(const struct lu_env *env,
2365 struct mgs_device *mgs,
2367 struct mgs_target_info *mti,
2377 /* keep a copy of original param, which could be destroied
2379 copy_size = strlen(param) + 1;
2380 OBD_ALLOC(copy, copy_size);
2383 memcpy(copy, param, copy_size);
2385 rc = mgs_srpc_set_param_mem(fsdb, mti->mti_svname, param);
2389 /* previous steps guaranteed the syntax is correct */
2390 rc = mgs_srpc_set_param_disk(env, mgs, fsdb, mti, copy);
2394 if (cfs_test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
2396 * for mgs rules, make them effective immediately.
2398 LASSERT(fsdb->fsdb_srpc_tgt == NULL);
2399 sptlrpc_target_update_exp_flavor(mgs->mgs_obd,
2400 &fsdb->fsdb_srpc_gen);
2404 OBD_FREE(copy, copy_size);
2408 struct mgs_srpc_read_data {
2409 struct fs_db *msrd_fsdb;
2413 static int mgs_srpc_read_handler(const struct lu_env *env,
2414 struct llog_handle *llh,
2415 struct llog_rec_hdr *rec, void *data)
2417 struct mgs_srpc_read_data *msrd = data;
2418 struct cfg_marker *marker;
2419 struct lustre_cfg *lcfg = (struct lustre_cfg *)(rec + 1);
2420 char *svname, *param;
2424 if (rec->lrh_type != OBD_CFG_REC) {
2425 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
2429 cfg_len = rec->lrh_len - sizeof(struct llog_rec_hdr) -
2430 sizeof(struct llog_rec_tail);
2432 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
2434 CERROR("Insane cfg\n");
2438 if (lcfg->lcfg_command == LCFG_MARKER) {
2439 marker = lustre_cfg_buf(lcfg, 1);
2441 if (marker->cm_flags & CM_START &&
2442 marker->cm_flags & CM_SKIP)
2443 msrd->msrd_skip = 1;
2444 if (marker->cm_flags & CM_END)
2445 msrd->msrd_skip = 0;
2450 if (msrd->msrd_skip)
2453 if (lcfg->lcfg_command != LCFG_SPTLRPC_CONF) {
2454 CERROR("invalid command (%x)\n", lcfg->lcfg_command);
2458 svname = lustre_cfg_string(lcfg, 0);
2459 if (svname == NULL) {
2460 CERROR("svname is empty\n");
2464 param = lustre_cfg_string(lcfg, 1);
2465 if (param == NULL) {
2466 CERROR("param is empty\n");
2470 rc = mgs_srpc_set_param_mem(msrd->msrd_fsdb, svname, param);
2472 CERROR("read sptlrpc record error (%d): %s\n", rc, param);
2477 int mgs_get_fsdb_srpc_from_llog(const struct lu_env *env,
2478 struct mgs_device *mgs,
2481 struct llog_handle *llh = NULL;
2482 struct lvfs_run_ctxt saved;
2483 struct llog_ctxt *ctxt;
2485 struct mgs_srpc_read_data msrd;
2489 /* construct log name */
2490 rc = name_create(&logname, fsdb->fsdb_name, "-sptlrpc");
2494 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
2495 LASSERT(ctxt != NULL);
2497 if (mgs_log_is_empty(env, mgs, logname))
2500 push_ctxt(&saved, &mgs->mgs_obd->obd_lvfs_ctxt, NULL);
2502 rc = llog_open(NULL, ctxt, &llh, NULL, logname,
2510 rc = llog_init_handle(NULL, llh, LLOG_F_IS_PLAIN, NULL);
2512 GOTO(out_close, rc);
2514 if (llog_get_size(llh) <= 1)
2515 GOTO(out_close, rc = 0);
2517 msrd.msrd_fsdb = fsdb;
2520 rc = llog_process_or_fork(env, llh, mgs_srpc_read_handler,
2521 (void *)&msrd, NULL, false);
2524 llog_close(NULL, llh);
2526 pop_ctxt(&saved, &mgs->mgs_obd->obd_lvfs_ctxt, NULL);
2528 llog_ctxt_put(ctxt);
2529 name_destroy(&logname);
2532 CERROR("failed to read sptlrpc config database: %d\n", rc);
2536 /* Permanent settings of all parameters by writing into the appropriate
2537 * configuration logs.
2538 * A parameter with null value ("<param>='\0'") means to erase it out of
2541 static int mgs_write_log_param(const struct lu_env *env,
2542 struct mgs_device *mgs, struct fs_db *fsdb,
2543 struct mgs_target_info *mti, char *ptr)
2545 struct mgs_thread_info *mgi = mgs_env_info(env);
2548 int rc = 0, rc2 = 0;
2551 /* For various parameter settings, we have to figure out which logs
2552 care about them (e.g. both mdt and client for lov settings) */
2553 CDEBUG(D_MGS, "next param '%s'\n", ptr);
2555 /* The params are stored in MOUNT_DATA_FILE and modified via
2556 tunefs.lustre, or set using lctl conf_param */
2558 /* Processed in lustre_start_mgc */
2559 if (class_match_param(ptr, PARAM_MGSNODE, NULL) == 0)
2562 /* Processed in ost/mdt */
2563 if (class_match_param(ptr, PARAM_NETWORK, NULL) == 0)
2566 /* Processed in mgs_write_log_ost */
2567 if (class_match_param(ptr, PARAM_FAILMODE, NULL) == 0) {
2568 if (mti->mti_flags & LDD_F_PARAM) {
2569 LCONSOLE_ERROR_MSG(0x169, "%s can only be "
2570 "changed with tunefs.lustre"
2571 "and --writeconf\n", ptr);
2577 if (class_match_param(ptr, PARAM_SRPC, NULL) == 0) {
2578 rc = mgs_srpc_set_param(env, mgs, fsdb, mti, ptr);
2582 if (class_match_param(ptr, PARAM_FAILNODE, NULL) == 0) {
2583 /* Add a failover nidlist */
2585 /* We already processed failovers params for new
2586 targets in mgs_write_log_target */
2587 if (mti->mti_flags & LDD_F_PARAM) {
2588 CDEBUG(D_MGS, "Adding failnode\n");
2589 rc = mgs_write_log_add_failnid(env, mgs, fsdb, mti);
2594 if (class_match_param(ptr, PARAM_SYS, &tmp) == 0) {
2595 rc = mgs_write_log_sys(env, mgs, fsdb, mti, ptr, tmp);
2599 if (class_match_param(ptr, PARAM_QUOTA, &tmp) == 0) {
2600 rc = mgs_write_log_quota(env, mgs, fsdb, mti, ptr, tmp);
2604 if (class_match_param(ptr, PARAM_OSC""PARAM_ACTIVE, &tmp) == 0) {
2605 /* active=0 means off, anything else means on */
2606 int flag = (*tmp == '0') ? CM_EXCLUDE : 0;
2609 if (!(mti->mti_flags & LDD_F_SV_TYPE_OST)) {
2610 LCONSOLE_ERROR_MSG(0x144, "%s: Only OSCs can "
2611 "be (de)activated.\n",
2613 GOTO(end, rc = -EINVAL);
2615 LCONSOLE_WARN("Permanently %sactivating %s\n",
2616 flag ? "de": "re", mti->mti_svname);
2618 name_create(&logname, mti->mti_fsname, "-client");
2619 rc = mgs_modify(env, mgs, fsdb, mti, logname,
2620 mti->mti_svname, "add osc", flag);
2621 name_destroy(&logname);
2625 /* Add to all MDT logs for CMD */
2626 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2627 if (!cfs_test_bit(i, fsdb->fsdb_mdt_index_map))
2629 name_create_mdt(&logname, mti->mti_fsname, i);
2630 rc = mgs_modify(env, mgs, fsdb, mti, logname,
2631 mti->mti_svname, "add osc", flag);
2632 name_destroy(&logname);
2638 LCONSOLE_ERROR_MSG(0x145, "Couldn't find %s in"
2639 "log (%d). No permanent "
2640 "changes were made to the "
2642 mti->mti_svname, rc);
2643 if (cfs_test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags))
2644 LCONSOLE_ERROR_MSG(0x146, "This may be"
2649 "update the logs.\n");
2652 /* Fall through to osc proc for deactivating live OSC
2653 on running MDT / clients. */
2655 /* Below here, let obd's XXX_process_config methods handle it */
2657 /* All lov. in proc */
2658 if (class_match_param(ptr, PARAM_LOV, NULL) == 0) {
2661 CDEBUG(D_MGS, "lov param %s\n", ptr);
2662 if (!(mti->mti_flags & LDD_F_SV_TYPE_MDT)) {
2663 LCONSOLE_ERROR_MSG(0x147, "LOV params must be "
2664 "set on the MDT, not %s. "
2671 if (mgs_log_is_empty(env, mgs, mti->mti_svname))
2672 GOTO(end, rc = -ENODEV);
2674 name_create_mdt_and_lov(&logname, &mdtlovname, fsdb,
2675 mti->mti_stripe_index);
2676 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, mti->mti_svname,
2677 &mgi->mgi_bufs, mdtlovname, ptr);
2678 name_destroy(&logname);
2679 name_destroy(&mdtlovname);
2684 name_create(&logname, mti->mti_fsname, "-client");
2685 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname, &mgi->mgi_bufs,
2686 fsdb->fsdb_clilov, ptr);
2687 name_destroy(&logname);
2691 /* All osc., mdc., llite. params in proc */
2692 if ((class_match_param(ptr, PARAM_OSC, NULL) == 0) ||
2693 (class_match_param(ptr, PARAM_MDC, NULL) == 0) ||
2694 (class_match_param(ptr, PARAM_LLITE, NULL) == 0)) {
2696 if (memcmp(ptr, PARAM_LLITE, strlen(PARAM_LLITE)) == 0) {
2697 name_create(&cname, mti->mti_fsname, "-client");
2698 /* Add the client type to match the obdname in
2699 class_config_llog_handler */
2700 } else if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
2703 name_create(&cname, fsdb->fsdb_mdc, "");
2705 name_create(&cname, mti->mti_svname,
2707 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2709 if (cfs_test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
2710 LCONSOLE_ERROR_MSG(0x148, "Upgraded "
2711 "client logs for %s"
2713 "modified. Consider"
2715 "configuration with"
2718 /* We don't know the names of all the
2720 GOTO(end, rc = -EINVAL);
2722 name_create(&cname, mti->mti_svname, "-osc");
2724 GOTO(end, rc = -EINVAL);
2727 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
2730 name_create(&logname, mti->mti_fsname, "-client");
2731 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname, &mgi->mgi_bufs,
2734 /* osc params affect the MDT as well */
2735 if (!rc && (mti->mti_flags & LDD_F_SV_TYPE_OST)) {
2738 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
2739 if (!cfs_test_bit(i, fsdb->fsdb_mdt_index_map))
2741 name_destroy(&cname);
2742 name_create_mdt_osc(&cname, mti->mti_svname,
2744 name_destroy(&logname);
2745 name_create_mdt(&logname, mti->mti_fsname, i);
2746 if (!mgs_log_is_empty(env, mgs, logname))
2747 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti,
2748 logname, &mgi->mgi_bufs,
2754 name_destroy(&logname);
2755 name_destroy(&cname);
2759 /* All mdt. params in proc */
2760 if (class_match_param(ptr, PARAM_MDT, NULL) == 0) {
2764 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
2765 if (strncmp(mti->mti_svname, mti->mti_fsname,
2766 MTI_NAME_MAXLEN) == 0)
2767 /* device is unspecified completely? */
2768 rc = LDD_F_SV_TYPE_MDT | LDD_F_SV_ALL;
2770 rc = server_name2index(mti->mti_svname, &idx, NULL);
2773 if ((rc & LDD_F_SV_TYPE_MDT) == 0)
2775 if (rc & LDD_F_SV_ALL) {
2776 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2777 if (!cfs_test_bit(i,
2778 fsdb->fsdb_mdt_index_map))
2780 name_create_mdt(&logname, mti->mti_fsname, i);
2781 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti,
2782 logname, &mgi->mgi_bufs,
2784 name_destroy(&logname);
2789 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti,
2790 mti->mti_svname, &mgi->mgi_bufs,
2791 mti->mti_svname, ptr);
2798 /* All mdd., ost. params in proc */
2799 if ((class_match_param(ptr, PARAM_MDD, NULL) == 0) ||
2800 (class_match_param(ptr, PARAM_OST, NULL) == 0)) {
2801 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
2802 if (mgs_log_is_empty(env, mgs, mti->mti_svname))
2803 GOTO(end, rc = -ENODEV);
2805 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, mti->mti_svname,
2806 &mgi->mgi_bufs, mti->mti_svname, ptr);
2810 LCONSOLE_WARN("Ignoring unrecognized param '%s'\n", ptr);
2815 CERROR("err %d on param '%s'\n", rc, ptr);
2820 /* Not implementing automatic failover nid addition at this time. */
2821 int mgs_check_failnid(const struct lu_env *env, struct mgs_device *mgs,
2822 struct mgs_target_info *mti)
2829 rc = mgs_find_or_make_fsdb(obd, fsname, &fsdb);
2833 if (mgs_log_is_empty(obd, mti->mti_svname))
2834 /* should never happen */
2837 CDEBUG(D_MGS, "Checking for new failnids for %s\n", mti->mti_svname);
2839 /* FIXME We can just check mti->params to see if we're already in
2840 the failover list. Modify mti->params for rewriting back at
2841 server_register_target(). */
2843 cfs_mutex_lock(&fsdb->fsdb_mutex);
2844 rc = mgs_write_log_add_failnid(obd, fsdb, mti);
2845 cfs_mutex_unlock(&fsdb->fsdb_mutex);
2852 int mgs_write_log_target(const struct lu_env *env,
2853 struct mgs_device *mgs,
2854 struct mgs_target_info *mti,
2861 /* set/check the new target index */
2862 rc = mgs_set_index(env, mgs, mti);
2864 CERROR("Can't get index (%d)\n", rc);
2869 if (mti->mti_flags & LDD_F_UPGRADE14) {
2870 if (rc == EALREADY) {
2871 LCONSOLE_INFO("Found index %d for %s 1.4 log, "
2872 "upgrading\n", mti->mti_stripe_index,
2875 LCONSOLE_ERROR_MSG(0x149, "Failed to find %s in the old"
2876 " client log. Apparently it is not "
2877 "part of this filesystem, or the old"
2878 " log is wrong.\nUse 'writeconf' on "
2879 "the MDT to force log regeneration."
2880 "\n", mti->mti_svname);
2881 /* Not in client log? Upgrade anyhow...*/
2882 /* Argument against upgrading: reformat MDT,
2883 upgrade OST, then OST will start but will be SKIPped
2884 in client logs. Maybe error now is better. */
2885 /* RETURN(-EINVAL); */
2887 /* end COMPAT_146 */
2889 if (rc == EALREADY) {
2890 LCONSOLE_WARN("Found index %d for %s, updating log\n",
2891 mti->mti_stripe_index, mti->mti_svname);
2892 /* We would like to mark old log sections as invalid
2893 and add new log sections in the client and mdt logs.
2894 But if we add new sections, then live clients will
2895 get repeat setup instructions for already running
2896 osc's. So don't update the client/mdt logs. */
2897 mti->mti_flags &= ~LDD_F_UPDATE;
2901 cfs_mutex_lock(&fsdb->fsdb_mutex);
2903 if (mti->mti_flags &
2904 (LDD_F_VIRGIN | LDD_F_UPGRADE14 | LDD_F_WRITECONF)) {
2905 /* Generate a log from scratch */
2906 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
2907 rc = mgs_write_log_mdt(env, mgs, fsdb, mti);
2908 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2909 rc = mgs_write_log_ost(env, mgs, fsdb, mti);
2911 CERROR("Unknown target type %#x, can't create log for "
2912 "%s\n", mti->mti_flags, mti->mti_svname);
2915 CERROR("Can't write logs for %s (%d)\n",
2916 mti->mti_svname, rc);
2920 /* Just update the params from tunefs in mgs_write_log_params */
2921 CDEBUG(D_MGS, "Update params for %s\n", mti->mti_svname);
2922 mti->mti_flags |= LDD_F_PARAM;
2925 /* allocate temporary buffer, where class_get_next_param will
2926 make copy of a current parameter */
2927 OBD_ALLOC(buf, strlen(mti->mti_params) + 1);
2929 GOTO(out_up, rc = -ENOMEM);
2930 params = mti->mti_params;
2931 while (params != NULL) {
2932 rc = class_get_next_param(¶ms, buf);
2935 /* there is no next parameter, that is
2940 CDEBUG(D_MGS, "remaining string: '%s', param: '%s'\n",
2942 rc = mgs_write_log_param(env, mgs, fsdb, mti, buf);
2947 OBD_FREE(buf, strlen(mti->mti_params) + 1);
2950 cfs_mutex_unlock(&fsdb->fsdb_mutex);
2955 /* verify that we can handle the old config logs */
2956 int mgs_upgrade_sv_14(const struct lu_env *env, struct mgs_device *mgs,
2957 struct mgs_target_info *mti, struct fs_db *fsdb)
2962 /* Create ost log normally, as servers register. Servers
2963 register with their old uuids (from last_rcvd), so old
2964 (MDT and client) logs should work.
2965 - new MDT won't know about old OSTs, only the ones that have
2966 registered, so we need the old MDT log to get the LOV right
2967 in order for old clients to work.
2968 - Old clients connect to the MDT, not the MGS, for their logs, and
2969 will therefore receive the old client log from the MDT /LOGS dir.
2970 - Old clients can continue to use and connect to old or new OSTs
2971 - New clients will contact the MGS for their log
2974 LCONSOLE_INFO("upgrading server %s from pre-1.6\n", mti->mti_svname);
2975 server_mti_print("upgrade", mti);
2977 if (cfs_test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
2978 LCONSOLE_ERROR_MSG(0x14a, "The old client log %s-client is "
2979 "missing. Was tunefs.lustre successful?\n",
2984 if (fsdb->fsdb_gen == 0) {
2985 /* There were no markers in the client log, meaning we have
2986 not updated the logs for this fs */
2987 CDEBUG(D_MGS, "found old, unupdated client log\n");
2990 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
2991 if (mgs_log_is_empty(env, mgs, mti->mti_svname)) {
2992 LCONSOLE_ERROR_MSG(0x14b, "The old MDT log %s is "
2993 "missing. Was tunefs.lustre "
2998 /* We're starting with an old uuid. Assume old name for lov
2999 as well since the lov entry already exists in the log. */
3000 CDEBUG(D_MGS, "old mds uuid %s\n", mti->mti_uuid);
3001 if (strncmp(mti->mti_uuid, fsdb->fsdb_mdtlov + 4,
3002 strlen(fsdb->fsdb_mdtlov) - 4) != 0) {
3003 CERROR("old mds uuid %s doesn't match log %s (%s)\n",
3004 mti->mti_uuid, fsdb->fsdb_mdtlov,
3005 fsdb->fsdb_mdtlov + 4);
3010 if (!cfs_test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
3011 LCONSOLE_ERROR_MSG(0x14c, "%s-client is supposedly an old "
3012 "log, but no old LOV or MDT was found. "
3013 "Consider updating the configuration with"
3014 " --writeconf.\n", mti->mti_fsname);
3019 /* end COMPAT_146 */
3021 int mgs_erase_log(const struct lu_env *env, struct mgs_device *mgs, char *name)
3023 struct lvfs_run_ctxt saved;
3024 struct llog_ctxt *ctxt;
3026 struct obd_device *obd = mgs->mgs_obd;
3028 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
3030 CERROR("%s: MGS config context doesn't exist\n",
3034 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
3035 rc = llog_erase(NULL, ctxt, NULL, name);
3036 /* llog may not exist */
3039 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
3040 llog_ctxt_put(ctxt);
3044 CERROR("%s: failed to clear log %s: %d\n", obd->obd_name,
3050 /* erase all logs for the given fs */
3051 int mgs_erase_logs(const struct lu_env *env, struct mgs_device *mgs, char *fsname)
3054 cfs_list_t dentry_list;
3055 struct l_linux_dirent *dirent, *n;
3056 int rc, len = strlen(fsname);
3060 /* Find all the logs in the CONFIGS directory */
3061 rc = class_dentry_readdir(env, mgs, &dentry_list);
3063 CERROR("Can't read %s dir\n", MOUNT_CONFIGS_DIR);
3067 cfs_mutex_lock(&mgs->mgs_mutex);
3069 /* Delete the fs db */
3070 fsdb = mgs_find_fsdb(mgs, fsname);
3072 mgs_free_fsdb(mgs, fsdb);
3074 cfs_list_for_each_entry_safe(dirent, n, &dentry_list, lld_list) {
3075 cfs_list_del(&dirent->lld_list);
3076 suffix = strrchr(dirent->lld_name, '-');
3077 if (suffix != NULL) {
3078 if ((len == suffix - dirent->lld_name) &&
3079 (strncmp(fsname, dirent->lld_name, len) == 0)) {
3080 CDEBUG(D_MGS, "Removing log %s\n",
3082 mgs_erase_log(env, mgs, dirent->lld_name);
3085 OBD_FREE(dirent, sizeof(*dirent));
3088 cfs_mutex_unlock(&mgs->mgs_mutex);
3093 /* from llog_swab */
3094 static void print_lustre_cfg(struct lustre_cfg *lcfg)
3099 CDEBUG(D_MGS, "lustre_cfg: %p\n", lcfg);
3100 CDEBUG(D_MGS, "\tlcfg->lcfg_version: %#x\n", lcfg->lcfg_version);
3102 CDEBUG(D_MGS, "\tlcfg->lcfg_command: %#x\n", lcfg->lcfg_command);
3103 CDEBUG(D_MGS, "\tlcfg->lcfg_num: %#x\n", lcfg->lcfg_num);
3104 CDEBUG(D_MGS, "\tlcfg->lcfg_flags: %#x\n", lcfg->lcfg_flags);
3105 CDEBUG(D_MGS, "\tlcfg->lcfg_nid: %s\n", libcfs_nid2str(lcfg->lcfg_nid));
3107 CDEBUG(D_MGS, "\tlcfg->lcfg_bufcount: %d\n", lcfg->lcfg_bufcount);
3108 if (lcfg->lcfg_bufcount < LUSTRE_CFG_MAX_BUFCOUNT)
3109 for (i = 0; i < lcfg->lcfg_bufcount; i++) {
3110 CDEBUG(D_MGS, "\tlcfg->lcfg_buflens[%d]: %d %s\n",
3111 i, lcfg->lcfg_buflens[i],
3112 lustre_cfg_string(lcfg, i));
3117 /* Set a permanent (config log) param for a target or fs
3118 * \param lcfg buf0 may contain the device (testfs-MDT0000) name
3119 * buf1 contains the single parameter
3121 int mgs_setparam(const struct lu_env *env, struct mgs_device *mgs,
3122 struct lustre_cfg *lcfg, char *fsname)
3125 struct mgs_target_info *mti;
3126 char *devname, *param;
3132 print_lustre_cfg(lcfg);
3134 /* lustre, lustre-mdtlov, lustre-client, lustre-MDT0000 */
3135 devname = lustre_cfg_string(lcfg, 0);
3136 param = lustre_cfg_string(lcfg, 1);
3138 /* Assume device name embedded in param:
3139 lustre-OST0000.osc.max_dirty_mb=32 */
3140 ptr = strchr(param, '.');
3148 LCONSOLE_ERROR_MSG(0x14d, "No target specified: %s\n", param);
3152 /* Extract fsname */
3153 ptr = strrchr(devname, '-');
3154 memset(fsname, 0, MTI_NAME_MAXLEN);
3155 if (ptr && (server_name2index(ptr, &index, NULL) >= 0)) {
3156 /* param related to llite isn't allowed to set by OST or MDT */
3157 if (strncmp(param, PARAM_LLITE, sizeof(PARAM_LLITE)) == 0)
3160 strncpy(fsname, devname, ptr - devname);
3162 /* assume devname is the fsname */
3163 strncpy(fsname, devname, MTI_NAME_MAXLEN);
3165 fsname[MTI_NAME_MAXLEN - 1] = 0;
3166 CDEBUG(D_MGS, "setparam fs='%s' device='%s'\n", fsname, devname);
3168 rc = mgs_find_or_make_fsdb(env, mgs, fsname, &fsdb);
3171 if (!cfs_test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags) &&
3172 cfs_test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
3173 CERROR("No filesystem targets for %s. cfg_device from lctl "
3174 "is '%s'\n", fsname, devname);
3175 mgs_free_fsdb(mgs, fsdb);
3179 /* Create a fake mti to hold everything */
3182 GOTO(out, rc = -ENOMEM);
3183 strncpy(mti->mti_fsname, fsname, MTI_NAME_MAXLEN);
3184 strncpy(mti->mti_svname, devname, MTI_NAME_MAXLEN);
3185 strncpy(mti->mti_params, param, sizeof(mti->mti_params));
3186 rc = server_name2index(mti->mti_svname, &mti->mti_stripe_index, &tmp);
3188 /* Not a valid server; may be only fsname */
3191 /* Strip -osc or -mdc suffix from svname */
3192 if (server_make_name(rc, mti->mti_stripe_index, mti->mti_fsname,
3194 GOTO(out, rc = -EINVAL);
3196 mti->mti_flags = rc | LDD_F_PARAM;
3198 cfs_mutex_lock(&fsdb->fsdb_mutex);
3199 rc = mgs_write_log_param(env, mgs, fsdb, mti, mti->mti_params);
3200 cfs_mutex_unlock(&fsdb->fsdb_mutex);
3203 * Revoke lock so everyone updates. Should be alright if
3204 * someone was already reading while we were updating the logs,
3205 * so we don't really need to hold the lock while we're
3208 mgs_revoke_lock(mgs, fsdb, CONFIG_T_CONFIG);
3214 static int mgs_write_log_pool(const struct lu_env *env,
3215 struct mgs_device *mgs, char *logname,
3216 struct fs_db *fsdb, char *lovname,
3217 enum lcfg_command_type cmd,
3218 char *poolname, char *fsname,
3219 char *ostname, char *comment)
3221 struct llog_handle *llh = NULL;
3224 rc = record_start_log(env, mgs, &llh, logname);
3227 rc = record_marker(env, llh, fsdb, CM_START, lovname, comment);
3228 record_base(env, llh, lovname, 0, cmd, poolname, fsname, ostname, 0);
3229 rc = record_marker(env, llh, fsdb, CM_END, lovname, comment);
3230 rc = record_end_log(env, &llh);
3235 int mgs_pool_cmd(const struct lu_env *env, struct mgs_device *mgs,
3236 enum lcfg_command_type cmd, char *fsname,
3237 char *poolname, char *ostname)
3242 char *label = NULL, *canceled_label = NULL;
3244 struct mgs_target_info *mti = NULL;
3248 rc = mgs_find_or_make_fsdb(env, mgs, fsname, &fsdb);
3250 CERROR("Can't get db for %s\n", fsname);
3253 if (cfs_test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
3254 CERROR("%s is not defined\n", fsname);
3255 mgs_free_fsdb(mgs, fsdb);
3259 label_sz = 10 + strlen(fsname) + strlen(poolname);
3261 /* check if ostname match fsname */
3262 if (ostname != NULL) {
3265 ptr = strrchr(ostname, '-');
3266 if ((ptr == NULL) ||
3267 (strncmp(fsname, ostname, ptr-ostname) != 0))
3269 label_sz += strlen(ostname);
3272 OBD_ALLOC(label, label_sz);
3274 GOTO(out, rc = -ENOMEM);
3279 "new %s.%s", fsname, poolname);
3283 "add %s.%s.%s", fsname, poolname, ostname);
3286 OBD_ALLOC(canceled_label, label_sz);
3287 if (canceled_label == NULL)
3288 GOTO(out, rc = -ENOMEM);
3290 "rem %s.%s.%s", fsname, poolname, ostname);
3291 sprintf(canceled_label,
3292 "add %s.%s.%s", fsname, poolname, ostname);
3295 OBD_ALLOC(canceled_label, label_sz);
3296 if (canceled_label == NULL)
3297 GOTO(out, rc = -ENOMEM);
3299 "del %s.%s", fsname, poolname);
3300 sprintf(canceled_label,
3301 "new %s.%s", fsname, poolname);
3307 cfs_mutex_lock(&fsdb->fsdb_mutex);
3309 if (canceled_label != NULL) {
3312 GOTO(out, rc = -ENOMEM);
3315 /* write pool def to all MDT logs */
3316 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3317 if (cfs_test_bit(i, fsdb->fsdb_mdt_index_map)) {
3318 name_create_mdt_and_lov(&logname, &lovname, fsdb, i);
3320 if (canceled_label != NULL) {
3321 strcpy(mti->mti_svname, "lov pool");
3322 mgs_modify(env, mgs, fsdb, mti, logname,
3323 lovname, canceled_label,
3327 mgs_write_log_pool(env, mgs, logname, fsdb, lovname,
3328 cmd, fsname, poolname, ostname,
3330 name_destroy(&logname);
3331 name_destroy(&lovname);
3335 name_create(&logname, fsname, "-client");
3336 if (canceled_label != NULL)
3337 mgs_modify(env, mgs, fsdb, mti, logname, fsdb->fsdb_clilov,
3338 canceled_label, CM_SKIP);
3340 mgs_write_log_pool(env, mgs, logname, fsdb, fsdb->fsdb_clilov,
3341 cmd, fsname, poolname, ostname, label);
3342 name_destroy(&logname);
3344 cfs_mutex_unlock(&fsdb->fsdb_mutex);
3345 /* request for update */
3346 mgs_revoke_lock(mgs, fsdb, CONFIG_T_CONFIG);
3351 OBD_FREE(label, label_sz);
3353 if (canceled_label != NULL)
3354 OBD_FREE(canceled_label, label_sz);
3363 /******************** unused *********************/
3364 static int mgs_backup_llog(struct obd_device *obd, char* fsname)
3366 struct file *filp, *bak_filp;
3367 struct lvfs_run_ctxt saved;
3368 char *logname, *buf;
3369 loff_t soff = 0 , doff = 0;
3370 int count = 4096, len;
3373 OBD_ALLOC(logname, PATH_MAX);
3374 if (logname == NULL)
3377 OBD_ALLOC(buf, count);
3379 GOTO(out , rc = -ENOMEM);
3381 len = snprintf(logname, PATH_MAX, "%s/%s.bak",
3382 MOUNT_CONFIGS_DIR, fsname);
3384 if (len >= PATH_MAX - 1) {
3385 GOTO(out, -ENAMETOOLONG);
3388 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
3390 bak_filp = l_filp_open(logname, O_RDWR|O_CREAT|O_TRUNC, 0660);
3391 if (IS_ERR(bak_filp)) {
3392 rc = PTR_ERR(bak_filp);
3393 CERROR("backup logfile open %s: %d\n", logname, rc);
3396 sprintf(logname, "%s/%s", MOUNT_CONFIGS_DIR, fsname);
3397 filp = l_filp_open(logname, O_RDONLY, 0);
3400 CERROR("logfile open %s: %d\n", logname, rc);
3404 while ((rc = lustre_fread(filp, buf, count, &soff)) > 0) {
3405 rc = lustre_fwrite(bak_filp, buf, count, &doff);
3409 filp_close(filp, 0);
3411 filp_close(bak_filp, 0);
3413 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
3416 OBD_FREE(buf, count);
3417 OBD_FREE(logname, PATH_MAX);