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(NULL, loghandle, mgs_fsdb_handler, (void *)&d, NULL);
293 CDEBUG(D_INFO, "get_db = %d\n", rc);
295 rc2 = llog_close(NULL, loghandle);
299 pop_ctxt(&saved, &mgs->mgs_obd->obd_lvfs_ctxt, NULL);
300 cfs_mutex_unlock(&fsdb->fsdb_mutex);
301 name_destroy(&logname);
307 static void mgs_free_fsdb_srpc(struct fs_db *fsdb)
309 struct mgs_tgt_srpc_conf *tgtconf;
311 /* free target-specific rules */
312 while (fsdb->fsdb_srpc_tgt) {
313 tgtconf = fsdb->fsdb_srpc_tgt;
314 fsdb->fsdb_srpc_tgt = tgtconf->mtsc_next;
316 LASSERT(tgtconf->mtsc_tgt);
318 sptlrpc_rule_set_free(&tgtconf->mtsc_rset);
319 OBD_FREE(tgtconf->mtsc_tgt, strlen(tgtconf->mtsc_tgt) + 1);
320 OBD_FREE_PTR(tgtconf);
323 /* free general rules */
324 sptlrpc_rule_set_free(&fsdb->fsdb_srpc_gen);
327 struct fs_db *mgs_find_fsdb(struct mgs_device *mgs, char *fsname)
332 cfs_list_for_each(tmp, &mgs->mgs_fs_db_list) {
333 fsdb = cfs_list_entry(tmp, struct fs_db, fsdb_list);
334 if (strcmp(fsdb->fsdb_name, fsname) == 0)
340 /* caller must hold the mgs->mgs_fs_db_lock */
341 static struct fs_db *mgs_new_fsdb(const struct lu_env *env,
342 struct mgs_device *mgs, char *fsname)
348 if (strlen(fsname) >= sizeof(fsdb->fsdb_name)) {
349 CERROR("fsname %s is too long\n", fsname);
357 strcpy(fsdb->fsdb_name, fsname);
358 cfs_mutex_init(&fsdb->fsdb_mutex);
359 cfs_set_bit(FSDB_UDESC, &fsdb->fsdb_flags);
361 if (strcmp(fsname, MGSSELF_NAME) == 0) {
362 cfs_set_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags);
364 OBD_ALLOC(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
365 OBD_ALLOC(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
366 if (!fsdb->fsdb_ost_index_map || !fsdb->fsdb_mdt_index_map) {
367 CERROR("No memory for index maps\n");
371 rc = name_create(&fsdb->fsdb_mdtlov, fsname, "-mdtlov");
374 rc = name_create(&fsdb->fsdb_mdtlmv, fsname, "-mdtlmv");
377 rc = name_create(&fsdb->fsdb_clilov, fsname, "-clilov");
380 rc = name_create(&fsdb->fsdb_clilmv, fsname, "-clilmv");
384 /* initialise data for NID table */
385 mgs_ir_init_fs(env, mgs, fsdb);
387 lproc_mgs_add_live(mgs, fsdb);
390 cfs_list_add(&fsdb->fsdb_list, &mgs->mgs_fs_db_list);
394 if (fsdb->fsdb_ost_index_map)
395 OBD_FREE(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
396 if (fsdb->fsdb_mdt_index_map)
397 OBD_FREE(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
398 name_destroy(&fsdb->fsdb_clilov);
399 name_destroy(&fsdb->fsdb_clilmv);
400 name_destroy(&fsdb->fsdb_mdtlov);
401 name_destroy(&fsdb->fsdb_mdtlmv);
406 static void mgs_free_fsdb(struct mgs_device *mgs, struct fs_db *fsdb)
408 /* wait for anyone with the sem */
409 cfs_mutex_lock(&fsdb->fsdb_mutex);
410 lproc_mgs_del_live(mgs, fsdb);
411 cfs_list_del(&fsdb->fsdb_list);
413 /* deinitialize fsr */
414 mgs_ir_fini_fs(mgs, fsdb);
416 if (fsdb->fsdb_ost_index_map)
417 OBD_FREE(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
418 if (fsdb->fsdb_mdt_index_map)
419 OBD_FREE(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
420 name_destroy(&fsdb->fsdb_clilov);
421 name_destroy(&fsdb->fsdb_clilmv);
422 name_destroy(&fsdb->fsdb_mdtlov);
423 name_destroy(&fsdb->fsdb_mdtlmv);
424 name_destroy(&fsdb->fsdb_mdc);
425 mgs_free_fsdb_srpc(fsdb);
426 cfs_mutex_unlock(&fsdb->fsdb_mutex);
430 int mgs_init_fsdb_list(struct mgs_device *mgs)
432 CFS_INIT_LIST_HEAD(&mgs->mgs_fs_db_list);
436 int mgs_cleanup_fsdb_list(struct mgs_device *mgs)
439 cfs_list_t *tmp, *tmp2;
440 cfs_mutex_lock(&mgs->mgs_mutex);
441 cfs_list_for_each_safe(tmp, tmp2, &mgs->mgs_fs_db_list) {
442 fsdb = cfs_list_entry(tmp, struct fs_db, fsdb_list);
443 mgs_free_fsdb(mgs, fsdb);
445 cfs_mutex_unlock(&mgs->mgs_mutex);
449 int mgs_find_or_make_fsdb(const struct lu_env *env,
450 struct mgs_device *mgs, char *name,
456 cfs_mutex_lock(&mgs->mgs_mutex);
457 fsdb = mgs_find_fsdb(mgs, name);
459 cfs_mutex_unlock(&mgs->mgs_mutex);
464 CDEBUG(D_MGS, "Creating new db\n");
465 fsdb = mgs_new_fsdb(env, mgs, name);
466 cfs_mutex_unlock(&mgs->mgs_mutex);
470 if (!cfs_test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
471 /* populate the db from the client llog */
472 rc = mgs_get_fsdb_from_llog(env, mgs, fsdb);
474 CERROR("Can't get db from client log %d\n", rc);
475 mgs_free_fsdb(mgs, fsdb);
480 /* populate srpc rules from params llog */
481 rc = mgs_get_fsdb_srpc_from_llog(env, mgs, fsdb);
483 CERROR("Can't get db from params log %d\n", rc);
484 mgs_free_fsdb(mgs, fsdb);
495 -1= empty client log */
496 int mgs_check_index(const struct lu_env *env,
497 struct mgs_device *mgs,
498 struct mgs_target_info *mti)
505 LASSERT(!(mti->mti_flags & LDD_F_NEED_INDEX));
507 rc = mgs_find_or_make_fsdb(env, mgs, mti->mti_fsname, &fsdb);
509 CERROR("Can't get db for %s\n", mti->mti_fsname);
513 if (cfs_test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags))
516 if (mti->mti_flags & LDD_F_SV_TYPE_OST)
517 imap = fsdb->fsdb_ost_index_map;
518 else if (mti->mti_flags & LDD_F_SV_TYPE_MDT)
519 imap = fsdb->fsdb_mdt_index_map;
523 if (cfs_test_bit(mti->mti_stripe_index, imap))
528 static __inline__ int next_index(void *index_map, int map_len)
531 for (i = 0; i < map_len * 8; i++)
532 if (!cfs_test_bit(i, index_map)) {
535 CERROR("max index %d exceeded.\n", i);
540 0 newly marked as in use
542 +EALREADY for update of an old index */
543 static int mgs_set_index(const struct lu_env *env,
544 struct mgs_device *mgs,
545 struct mgs_target_info *mti)
552 rc = mgs_find_or_make_fsdb(env, mgs, mti->mti_fsname, &fsdb);
554 CERROR("Can't get db for %s\n", mti->mti_fsname);
558 if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
559 imap = fsdb->fsdb_ost_index_map;
560 } else if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
561 imap = fsdb->fsdb_mdt_index_map;
562 if (fsdb->fsdb_mdt_count >= MAX_MDT_COUNT) {
563 LCONSOLE_ERROR_MSG(0x13f, "The max mdt count"
564 "is %d\n", (int)MAX_MDT_COUNT);
571 if (mti->mti_flags & LDD_F_NEED_INDEX) {
572 rc = next_index(imap, INDEX_MAP_SIZE);
575 mti->mti_stripe_index = rc;
576 if (mti->mti_flags & LDD_F_SV_TYPE_MDT)
577 fsdb->fsdb_mdt_count ++;
580 if (mti->mti_stripe_index >= INDEX_MAP_SIZE * 8) {
581 LCONSOLE_ERROR_MSG(0x13f, "Server %s requested index %d, "
582 "but the max index is %d.\n",
583 mti->mti_svname, mti->mti_stripe_index,
588 if (cfs_test_bit(mti->mti_stripe_index, imap)) {
589 if ((mti->mti_flags & LDD_F_VIRGIN) &&
590 !(mti->mti_flags & LDD_F_WRITECONF)) {
591 LCONSOLE_ERROR_MSG(0x140, "Server %s requested index "
592 "%d, but that index is already in "
593 "use. Use --writeconf to force\n",
595 mti->mti_stripe_index);
598 CDEBUG(D_MGS, "Server %s updating index %d\n",
599 mti->mti_svname, mti->mti_stripe_index);
604 cfs_set_bit(mti->mti_stripe_index, imap);
605 cfs_clear_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags);
606 server_make_name(mti->mti_flags & ~(LDD_F_VIRGIN | LDD_F_WRITECONF),
607 mti->mti_stripe_index, mti->mti_fsname, mti->mti_svname);
609 CDEBUG(D_MGS, "Set index for %s to %d\n", mti->mti_svname,
610 mti->mti_stripe_index);
615 struct mgs_modify_lookup {
616 struct cfg_marker mml_marker;
620 static int mgs_modify_handler(const struct lu_env *env,
621 struct llog_handle *llh,
622 struct llog_rec_hdr *rec, void *data)
624 struct mgs_modify_lookup *mml = data;
625 struct cfg_marker *marker;
626 struct lustre_cfg *lcfg = (struct lustre_cfg *)(rec + 1);
627 int cfg_len = rec->lrh_len - sizeof(struct llog_rec_hdr) -
628 sizeof(struct llog_rec_tail);
632 if (rec->lrh_type != OBD_CFG_REC) {
633 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
637 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
639 CERROR("Insane cfg\n");
643 /* We only care about markers */
644 if (lcfg->lcfg_command != LCFG_MARKER)
647 marker = lustre_cfg_buf(lcfg, 1);
648 if ((strcmp(mml->mml_marker.cm_comment, marker->cm_comment) == 0) &&
649 (strcmp(mml->mml_marker.cm_tgtname, marker->cm_tgtname) == 0) &&
650 !(marker->cm_flags & CM_SKIP)) {
651 /* Found a non-skipped marker match */
652 CDEBUG(D_MGS, "Changing rec %u marker %d %x->%x: %s %s\n",
653 rec->lrh_index, marker->cm_step,
654 marker->cm_flags, mml->mml_marker.cm_flags,
655 marker->cm_tgtname, marker->cm_comment);
656 /* Overwrite the old marker llog entry */
657 marker->cm_flags &= ~CM_EXCLUDE; /* in case we're unexcluding */
658 marker->cm_flags |= mml->mml_marker.cm_flags;
659 marker->cm_canceltime = mml->mml_marker.cm_canceltime;
660 /* Header and tail are added back to lrh_len in
661 llog_lvfs_write_rec */
662 rec->lrh_len = cfg_len;
663 rc = llog_write_rec(NULL, llh, rec, NULL, 0, (void *)lcfg,
672 /* Modify an existing config log record (for CM_SKIP or CM_EXCLUDE) */
673 static int mgs_modify(const struct lu_env *env, struct mgs_device *mgs,
674 struct fs_db *fsdb, struct mgs_target_info *mti,
675 char *logname, char *devname, char *comment, int flags)
677 struct llog_handle *loghandle;
678 struct lvfs_run_ctxt saved;
679 struct llog_ctxt *ctxt;
680 struct mgs_modify_lookup *mml;
684 CDEBUG(D_MGS, "modify %s/%s/%s fl=%x\n", logname, devname, comment,
687 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
688 LASSERT(ctxt != NULL);
689 push_ctxt(&saved, &mgs->mgs_obd->obd_lvfs_ctxt, NULL);
690 rc = llog_open(NULL, ctxt, &loghandle, NULL, logname,
698 rc = llog_init_handle(NULL, loghandle, LLOG_F_IS_PLAIN, NULL);
702 if (llog_get_size(loghandle) <= 1)
703 GOTO(out_close, rc = 0);
707 GOTO(out_close, rc = -ENOMEM);
708 strcpy(mml->mml_marker.cm_comment, comment);
709 strcpy(mml->mml_marker.cm_tgtname, devname);
710 /* Modify mostly means cancel */
711 mml->mml_marker.cm_flags = flags;
712 mml->mml_marker.cm_canceltime = flags ? cfs_time_current_sec() : 0;
713 mml->mml_modified = 0;
714 rc = llog_process(NULL, loghandle, mgs_modify_handler, (void *)mml,
716 if (!rc && !mml->mml_modified)
721 rc2 = llog_close(NULL, loghandle);
725 pop_ctxt(&saved, &mgs->mgs_obd->obd_lvfs_ctxt, NULL);
726 if (rc && rc != -ENODEV)
727 CERROR("modify %s/%s failed %d\n",
728 mti->mti_svname, comment, rc);
733 /******************** config log recording functions *********************/
735 static int record_lcfg(const struct lu_env *env, struct llog_handle *llh,
736 struct lustre_cfg *lcfg)
738 struct lvfs_run_ctxt saved;
739 struct llog_rec_hdr rec;
741 struct obd_device *obd = llh->lgh_ctxt->loc_obd;
746 LASSERT(llh->lgh_ctxt);
748 buflen = lustre_cfg_len(lcfg->lcfg_bufcount,
750 rec.lrh_len = llog_data_len(buflen);
751 rec.lrh_type = OBD_CFG_REC;
753 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
754 /* idx = -1 means append */
755 rc = llog_write_rec(NULL, llh, &rec, NULL, 0, (void *)lcfg, -1);
756 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
758 CERROR("failed %d\n", rc);
762 static int record_base(const struct lu_env *env, struct llog_handle *llh,
763 char *cfgname, lnet_nid_t nid, int cmd,
764 char *s1, char *s2, char *s3, char *s4)
766 struct lustre_cfg_bufs bufs;
767 struct lustre_cfg *lcfg;
770 CDEBUG(D_MGS, "lcfg %s %#x %s %s %s %s\n", cfgname,
771 cmd, s1, s2, s3, s4);
773 lustre_cfg_bufs_reset(&bufs, cfgname);
775 lustre_cfg_bufs_set_string(&bufs, 1, s1);
777 lustre_cfg_bufs_set_string(&bufs, 2, s2);
779 lustre_cfg_bufs_set_string(&bufs, 3, s3);
781 lustre_cfg_bufs_set_string(&bufs, 4, s4);
783 lcfg = lustre_cfg_new(cmd, &bufs);
786 lcfg->lcfg_nid = nid;
788 rc = record_lcfg(env, llh, lcfg);
790 lustre_cfg_free(lcfg);
793 CERROR("error %d: lcfg %s %#x %s %s %s %s\n", rc, cfgname,
794 cmd, s1, s2, s3, s4);
800 static inline int record_add_uuid(const struct lu_env *env,
801 struct llog_handle *llh,
802 uint64_t nid, char *uuid)
804 return record_base(env, llh, NULL, nid, LCFG_ADD_UUID, uuid, 0, 0, 0);
808 static inline int record_add_conn(const struct lu_env *env,
809 struct llog_handle *llh,
810 char *devname, char *uuid)
812 return record_base(env, llh, devname, 0, LCFG_ADD_CONN, uuid, 0, 0, 0);
815 static inline int record_attach(const struct lu_env *env,
816 struct llog_handle *llh, char *devname,
817 char *type, char *uuid)
819 return record_base(env, llh,devname, 0, LCFG_ATTACH, type, uuid, 0, 0);
822 static inline int record_setup(const struct lu_env *env,
823 struct llog_handle *llh, char *devname,
824 char *s1, char *s2, char *s3, char *s4)
826 return record_base(env, llh, devname, 0, LCFG_SETUP, s1, s2, s3, s4);
829 static int record_lov_setup(const struct lu_env *env, struct llog_handle *llh,
830 char *devname, struct lov_desc *desc)
832 struct lustre_cfg_bufs bufs;
833 struct lustre_cfg *lcfg;
836 lustre_cfg_bufs_reset(&bufs, devname);
837 lustre_cfg_bufs_set(&bufs, 1, desc, sizeof(*desc));
838 lcfg = lustre_cfg_new(LCFG_SETUP, &bufs);
841 rc = record_lcfg(env, llh, lcfg);
843 lustre_cfg_free(lcfg);
847 static int record_lmv_setup(const struct lu_env *env, struct llog_handle *llh,
848 char *devname, struct lmv_desc *desc)
850 struct lustre_cfg_bufs bufs;
851 struct lustre_cfg *lcfg;
854 lustre_cfg_bufs_reset(&bufs, devname);
855 lustre_cfg_bufs_set(&bufs, 1, desc, sizeof(*desc));
856 lcfg = lustre_cfg_new(LCFG_SETUP, &bufs);
858 rc = record_lcfg(env, llh, lcfg);
860 lustre_cfg_free(lcfg);
864 static inline int record_mdc_add(const struct lu_env *env,
865 struct llog_handle *llh,
866 char *logname, char *mdcuuid,
867 char *mdtuuid, char *index,
870 return record_base(env,llh,logname,0,LCFG_ADD_MDC,
871 mdtuuid,index,gen,mdcuuid);
874 static inline int record_lov_add(const struct lu_env *env,
875 struct llog_handle *llh,
876 char *lov_name, char *ost_uuid,
877 char *index, char *gen)
879 return record_base(env,llh,lov_name,0,LCFG_LOV_ADD_OBD,
880 ost_uuid,index,gen,0);
883 static inline int record_mount_opt(const struct lu_env *env,
884 struct llog_handle *llh,
885 char *profile, char *lov_name,
888 return record_base(env,llh,NULL,0,LCFG_MOUNTOPT,
889 profile,lov_name,mdc_name,0);
892 static int record_marker(const struct lu_env *env,
893 struct llog_handle *llh,
894 struct fs_db *fsdb, __u32 flags,
895 char *tgtname, char *comment)
897 struct cfg_marker marker;
898 struct lustre_cfg_bufs bufs;
899 struct lustre_cfg *lcfg;
902 if (flags & CM_START)
904 marker.cm_step = fsdb->fsdb_gen;
905 marker.cm_flags = flags;
906 marker.cm_vers = LUSTRE_VERSION_CODE;
907 strncpy(marker.cm_tgtname, tgtname, sizeof(marker.cm_tgtname));
908 strncpy(marker.cm_comment, comment, sizeof(marker.cm_comment));
909 marker.cm_createtime = cfs_time_current_sec();
910 marker.cm_canceltime = 0;
911 lustre_cfg_bufs_reset(&bufs, NULL);
912 lustre_cfg_bufs_set(&bufs, 1, &marker, sizeof(marker));
913 lcfg = lustre_cfg_new(LCFG_MARKER, &bufs);
916 rc = record_lcfg(env, llh, lcfg);
918 lustre_cfg_free(lcfg);
922 static int record_start_log(const struct lu_env *env,
923 struct mgs_device *mgs,
924 struct llog_handle **llh, char *name)
926 static struct obd_uuid cfg_uuid = { .uuid = "config_uuid" };
927 struct lvfs_run_ctxt saved;
928 struct llog_ctxt *ctxt;
932 GOTO(out, rc = -EBUSY);
934 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
936 GOTO(out, rc = -ENODEV);
937 LASSERT(ctxt->loc_obd == mgs->mgs_obd);
939 push_ctxt(&saved, &mgs->mgs_obd->obd_lvfs_ctxt, NULL);
940 rc = llog_open_create(NULL, ctxt, llh, NULL, name);
943 rc = llog_init_handle(NULL, *llh, LLOG_F_IS_PLAIN, &cfg_uuid);
945 llog_close(NULL, *llh);
949 pop_ctxt(&saved, &mgs->mgs_obd->obd_lvfs_ctxt, NULL);
953 CERROR("Can't start log %s: %d\n", name, rc);
957 static int record_end_log(const struct lu_env *env, struct llog_handle **llh)
959 struct lvfs_run_ctxt saved;
960 struct obd_device *obd = (*llh)->lgh_ctxt->loc_obd;
963 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
965 rc = llog_close(NULL, *llh);
968 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
972 static int mgs_log_is_empty(const struct lu_env *env,
973 struct mgs_device *mgs, char *name)
975 struct lvfs_run_ctxt saved;
976 struct llog_handle *llh;
977 struct llog_ctxt *ctxt;
980 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
981 LASSERT(ctxt != NULL);
982 push_ctxt(&saved, &mgs->mgs_obd->obd_lvfs_ctxt, NULL);
983 rc = llog_open(NULL, ctxt, &llh, NULL, name, LLOG_OPEN_EXISTS);
990 llog_init_handle(NULL, llh, LLOG_F_IS_PLAIN, NULL);
993 rc = llog_get_size(llh);
996 llog_close(NULL, llh);
998 pop_ctxt(&saved, &mgs->mgs_obd->obd_lvfs_ctxt, NULL);
1000 /* header is record 1 */
1004 /******************** config "macros" *********************/
1006 /* write an lcfg directly into a log (with markers) */
1007 static int mgs_write_log_direct(const struct lu_env *env,
1008 struct mgs_device *mgs, struct fs_db *fsdb,
1009 char *logname, struct lustre_cfg *lcfg,
1010 char *devname, char *comment)
1012 struct llog_handle *llh = NULL;
1019 rc = record_start_log(env, mgs, &llh, logname);
1023 /* FIXME These should be a single journal transaction */
1024 rc = record_marker(env, llh, fsdb, CM_START, devname, comment);
1026 rc = record_lcfg(env, llh, lcfg);
1028 rc = record_marker(env, llh, fsdb, CM_END, devname, comment);
1029 rc = record_end_log(env, &llh);
1034 /* write the lcfg in all logs for the given fs */
1035 int mgs_write_log_direct_all(const struct lu_env *env,
1036 struct mgs_device *mgs,
1038 struct mgs_target_info *mti,
1039 struct lustre_cfg *lcfg,
1040 char *devname, char *comment,
1043 cfs_list_t dentry_list;
1044 struct l_linux_dirent *dirent, *n;
1045 char *fsname = mti->mti_fsname;
1047 int rc = 0, len = strlen(fsname);
1050 /* We need to set params for any future logs
1051 as well. FIXME Append this file to every new log.
1052 Actually, we should store as params (text), not llogs. Or
1054 name_create(&logname, fsname, "-params");
1055 if (mgs_log_is_empty(env, mgs, logname)) {
1056 struct llog_handle *llh = NULL;
1057 rc = record_start_log(env, mgs, &llh, logname);
1058 record_end_log(env, &llh);
1060 name_destroy(&logname);
1064 /* Find all the logs in the CONFIGS directory */
1065 rc = class_dentry_readdir(env, mgs, &dentry_list);
1067 CERROR("Can't read %s dir\n", MOUNT_CONFIGS_DIR);
1071 /* Could use fsdb index maps instead of directory listing */
1072 cfs_list_for_each_entry_safe(dirent, n, &dentry_list, lld_list) {
1073 cfs_list_del(&dirent->lld_list);
1074 /* don't write to sptlrpc rule log */
1075 if (strstr(dirent->lld_name, "-sptlrpc") != NULL)
1078 /* caller wants write server logs only */
1079 if (server_only && strstr(dirent->lld_name, "-client") != NULL)
1082 if (strncmp(fsname, dirent->lld_name, len) == 0) {
1083 CDEBUG(D_MGS, "Changing log %s\n", dirent->lld_name);
1084 /* Erase any old settings of this same parameter */
1085 mgs_modify(env, mgs, fsdb, mti, dirent->lld_name,
1086 devname, comment, CM_SKIP);
1087 /* Write the new one */
1089 rc = mgs_write_log_direct(env, mgs, fsdb,
1094 CERROR("err %d writing log %s\n", rc,
1099 OBD_FREE(dirent, sizeof(*dirent));
1107 struct mgs_target_info *comp_tmti;
1108 struct mgs_target_info *comp_mti;
1109 struct fs_db *comp_fsdb;
1110 struct mgs_device *comp_mgs;
1111 const struct lu_env *comp_env;
1114 static int mgs_write_log_mdc_to_mdt(const struct lu_env *env,
1115 struct mgs_device *mgs,
1117 struct mgs_target_info *mti,
1119 static int mgs_write_log_osc_to_lov(const struct lu_env *env,
1120 struct mgs_device *mgs,
1122 struct mgs_target_info *mti,
1123 char *logname, char *suffix, char *lovname,
1124 enum lustre_sec_part sec_part, int flags);
1125 static void name_create_mdt_and_lov(char **logname, char **lovname,
1126 struct fs_db *fsdb, int i);
1128 static int mgs_steal_llog_handler(const struct lu_env *env,
1129 struct llog_handle *llh,
1130 struct llog_rec_hdr *rec, void *data)
1132 struct mgs_device *mgs;
1133 struct mgs_target_info *mti, *tmti;
1135 int cfg_len = rec->lrh_len;
1136 char *cfg_buf = (char*) (rec + 1);
1137 struct lustre_cfg *lcfg;
1139 struct llog_handle *mdt_llh = NULL;
1140 static int got_an_osc_or_mdc = 0;
1141 /* 0: not found any osc/mdc;
1145 static int last_step = -1;
1149 mti = ((struct temp_comp*)data)->comp_mti;
1150 tmti = ((struct temp_comp*)data)->comp_tmti;
1151 fsdb = ((struct temp_comp*)data)->comp_fsdb;
1152 mgs = ((struct temp_comp*)data)->comp_mgs;
1154 if (rec->lrh_type != OBD_CFG_REC) {
1155 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
1159 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
1161 CERROR("Insane cfg\n");
1165 lcfg = (struct lustre_cfg *)cfg_buf;
1167 if (lcfg->lcfg_command == LCFG_MARKER) {
1168 struct cfg_marker *marker;
1169 marker = lustre_cfg_buf(lcfg, 1);
1170 if (!strncmp(marker->cm_comment,"add osc",7) &&
1171 (marker->cm_flags & CM_START)){
1172 got_an_osc_or_mdc = 1;
1173 strncpy(tmti->mti_svname, marker->cm_tgtname,
1174 sizeof(tmti->mti_svname));
1175 rc = record_start_log(env, mgs, &mdt_llh,
1177 rc = record_marker(env, mdt_llh, fsdb, CM_START,
1178 mti->mti_svname,"add osc(copied)");
1179 rc = record_end_log(env, &mdt_llh);
1180 last_step = marker->cm_step;
1183 if (!strncmp(marker->cm_comment,"add osc",7) &&
1184 (marker->cm_flags & CM_END)){
1185 LASSERT(last_step == marker->cm_step);
1187 got_an_osc_or_mdc = 0;
1188 rc = record_start_log(env, mgs, &mdt_llh,
1190 rc = record_marker(env, mdt_llh, fsdb, CM_END,
1191 mti->mti_svname,"add osc(copied)");
1192 rc = record_end_log(env, &mdt_llh);
1195 if (!strncmp(marker->cm_comment,"add mdc",7) &&
1196 (marker->cm_flags & CM_START)){
1197 got_an_osc_or_mdc = 2;
1198 last_step = marker->cm_step;
1199 memcpy(tmti->mti_svname, marker->cm_tgtname,
1200 strlen(marker->cm_tgtname));
1204 if (!strncmp(marker->cm_comment,"add mdc",7) &&
1205 (marker->cm_flags & CM_END)){
1206 LASSERT(last_step == marker->cm_step);
1208 got_an_osc_or_mdc = 0;
1213 if (got_an_osc_or_mdc == 0 || last_step < 0)
1216 if (lcfg->lcfg_command == LCFG_ADD_UUID) {
1218 nodenid = lcfg->lcfg_nid;
1220 tmti->mti_nids[tmti->mti_nid_count] = nodenid;
1221 tmti->mti_nid_count++;
1226 if (lcfg->lcfg_command == LCFG_SETUP) {
1229 target = lustre_cfg_string(lcfg, 1);
1230 memcpy(tmti->mti_uuid, target, strlen(target));
1234 /* ignore client side sptlrpc_conf_log */
1235 if (lcfg->lcfg_command == LCFG_SPTLRPC_CONF)
1238 if (lcfg->lcfg_command == LCFG_ADD_MDC) {
1241 if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1)
1244 memcpy(tmti->mti_fsname, mti->mti_fsname,
1245 strlen(mti->mti_fsname));
1246 tmti->mti_stripe_index = index;
1248 mgs_write_log_mdc_to_mdt(env, mgs, fsdb,
1249 tmti, mti->mti_svname);
1250 memset(tmti, 0, sizeof(*tmti));
1254 if (lcfg->lcfg_command == LCFG_LOV_ADD_OBD) {
1257 char *logname, *lovname;
1259 name_create_mdt_and_lov(&logname, &lovname, fsdb,
1260 mti->mti_stripe_index);
1261 sprintf(mdt_index, "-MDT%04x", mti->mti_stripe_index);
1263 if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1) {
1264 name_destroy(&logname);
1265 name_destroy(&lovname);
1269 tmti->mti_stripe_index = index;
1270 mgs_write_log_osc_to_lov(env, mgs, fsdb, tmti, logname,
1273 name_destroy(&logname);
1274 name_destroy(&lovname);
1280 /* fsdb->fsdb_mutex is already held in mgs_write_log_target*/
1281 /* stealed from mgs_get_fsdb_from_llog*/
1282 static int mgs_steal_llog_for_mdt_from_client(const struct lu_env *env,
1283 struct mgs_device *mgs,
1285 struct temp_comp* comp)
1287 struct llog_handle *loghandle;
1288 struct lvfs_run_ctxt saved;
1289 struct mgs_target_info *tmti;
1290 struct llog_ctxt *ctxt;
1295 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
1296 LASSERT(ctxt != NULL);
1298 OBD_ALLOC_PTR(tmti);
1300 GOTO(out_ctxt, rc = -ENOMEM);
1302 comp->comp_tmti = tmti;
1303 comp->comp_mgs = mgs;
1305 push_ctxt(&saved, &mgs->mgs_obd->obd_lvfs_ctxt, NULL);
1307 rc = llog_open(NULL, ctxt, &loghandle, NULL, client_name,
1315 rc = llog_init_handle(NULL, loghandle, LLOG_F_IS_PLAIN, NULL);
1317 GOTO(out_close, rc);
1319 rc = llog_process(NULL, loghandle, mgs_steal_llog_handler,
1320 (void *)comp, NULL);
1321 CDEBUG(D_MGS, "steal llog re = %d\n", rc);
1323 llog_close(NULL, loghandle);
1325 pop_ctxt(&saved, &mgs->mgs_obd->obd_lvfs_ctxt, NULL);
1328 llog_ctxt_put(ctxt);
1332 /* lmv is the second thing for client logs */
1333 /* copied from mgs_write_log_lov. Please refer to that. */
1334 static int mgs_write_log_lmv(const struct lu_env *env,
1335 struct mgs_device *mgs,
1337 struct mgs_target_info *mti,
1338 char *logname, char *lmvname)
1340 struct llog_handle *llh = NULL;
1341 struct lmv_desc *lmvdesc;
1346 CDEBUG(D_MGS, "Writing lmv(%s) log for %s\n", lmvname,logname);
1348 OBD_ALLOC_PTR(lmvdesc);
1349 if (lmvdesc == NULL)
1351 lmvdesc->ld_active_tgt_count = 0;
1352 lmvdesc->ld_tgt_count = 0;
1353 sprintf((char*)lmvdesc->ld_uuid.uuid, "%s_UUID", lmvname);
1354 uuid = (char *)lmvdesc->ld_uuid.uuid;
1356 rc = record_start_log(env, mgs, &llh, logname);
1357 rc = record_marker(env, llh, fsdb, CM_START, lmvname, "lmv setup");
1358 rc = record_attach(env, llh, lmvname, "lmv", uuid);
1359 rc = record_lmv_setup(env, llh, lmvname, lmvdesc);
1360 rc = record_marker(env, llh, fsdb, CM_END, lmvname, "lmv setup");
1361 rc = record_end_log(env, &llh);
1363 OBD_FREE_PTR(lmvdesc);
1367 /* lov is the first thing in the mdt and client logs */
1368 static int mgs_write_log_lov(const struct lu_env *env, struct mgs_device *mgs,
1369 struct fs_db *fsdb, struct mgs_target_info *mti,
1370 char *logname, char *lovname)
1372 struct llog_handle *llh = NULL;
1373 struct lov_desc *lovdesc;
1378 CDEBUG(D_MGS, "Writing lov(%s) log for %s\n", lovname, logname);
1381 #01 L attach 0:lov_mdsA 1:lov 2:71ccb_lov_mdsA_19f961a9e1
1382 #02 L lov_setup 0:lov_mdsA 1:(struct lov_desc)
1383 uuid=lov1_UUID, stripe count=1, size=1048576, offset=0, pattern=0
1386 /* FIXME just make lov_setup accept empty desc (put uuid in buf 2) */
1387 OBD_ALLOC_PTR(lovdesc);
1388 if (lovdesc == NULL)
1390 lovdesc->ld_magic = LOV_DESC_MAGIC;
1391 lovdesc->ld_tgt_count = 0;
1392 /* Defaults. Can be changed later by lcfg config_param */
1393 lovdesc->ld_default_stripe_count = 1;
1394 lovdesc->ld_pattern = LOV_PATTERN_RAID0;
1395 lovdesc->ld_default_stripe_size = 1024 * 1024;
1396 lovdesc->ld_default_stripe_offset = -1;
1397 lovdesc->ld_qos_maxage = QOS_DEFAULT_MAXAGE;
1398 sprintf((char*)lovdesc->ld_uuid.uuid, "%s_UUID", lovname);
1399 /* can these be the same? */
1400 uuid = (char *)lovdesc->ld_uuid.uuid;
1402 /* This should always be the first entry in a log.
1403 rc = mgs_clear_log(obd, logname); */
1404 rc = record_start_log(env, mgs, &llh, logname);
1407 /* FIXME these should be a single journal transaction */
1408 rc = record_marker(env, llh, fsdb, CM_START, lovname, "lov setup");
1409 rc = record_attach(env, llh, lovname, "lov", uuid);
1410 rc = record_lov_setup(env, llh, lovname, lovdesc);
1411 rc = record_marker(env, llh, fsdb, CM_END, lovname, "lov setup");
1412 rc = record_end_log(env, &llh);
1416 OBD_FREE_PTR(lovdesc);
1420 /* add failnids to open log */
1421 static int mgs_write_log_failnids(const struct lu_env *env,
1422 struct mgs_target_info *mti,
1423 struct llog_handle *llh,
1426 char *failnodeuuid = NULL;
1427 char *ptr = mti->mti_params;
1432 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) nal=90 0: 1:uml1_UUID
1433 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
1434 #05 L setup 0:OSC_uml1_ost1_mdsA 1:ost1_UUID 2:uml1_UUID
1435 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) nal=90 0: 1:uml2_UUID
1436 #0x L add_uuid nid=2@elan(0x1000000000002) nal=90 0: 1:uml2_UUID
1437 #07 L add_conn 0:OSC_uml1_ost1_mdsA 1:uml2_UUID
1440 /* Pull failnid info out of params string */
1441 while (class_find_param(ptr, PARAM_FAILNODE, &ptr) == 0) {
1442 while (class_parse_nid(ptr, &nid, &ptr) == 0) {
1443 if (failnodeuuid == NULL) {
1444 /* We don't know the failover node name,
1445 so just use the first nid as the uuid */
1446 rc = name_create(&failnodeuuid,
1447 libcfs_nid2str(nid), "");
1451 CDEBUG(D_MGS, "add nid %s for failover uuid %s, "
1452 "client %s\n", libcfs_nid2str(nid),
1453 failnodeuuid, cliname);
1454 rc = record_add_uuid(env, llh, nid, failnodeuuid);
1457 rc = record_add_conn(env, llh, cliname, failnodeuuid);
1458 name_destroy(&failnodeuuid);
1459 failnodeuuid = NULL;
1466 static int mgs_write_log_mdc_to_lmv(const struct lu_env *env,
1467 struct mgs_device *mgs,
1469 struct mgs_target_info *mti,
1470 char *logname, char *lmvname)
1472 struct llog_handle *llh = NULL;
1473 char *mdcname, *nodeuuid, *mdcuuid, *lmvuuid;
1478 if (mgs_log_is_empty(env, mgs, logname)) {
1479 CERROR("log is empty! Logical error\n");
1483 CDEBUG(D_MGS, "adding mdc for %s to log %s:lmv(%s)\n",
1484 mti->mti_svname, logname, lmvname);
1486 name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
1487 name_create(&mdcname, mti->mti_svname, "-mdc");
1488 name_create(&mdcuuid, mdcname, "_UUID");
1489 name_create(&lmvuuid, lmvname, "_UUID");
1491 rc = record_start_log(env, mgs, &llh, logname);
1492 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
1495 for (i = 0; i < mti->mti_nid_count; i++) {
1496 CDEBUG(D_MGS, "add nid %s for mdt\n",
1497 libcfs_nid2str(mti->mti_nids[i]));
1499 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
1502 rc = record_attach(env, llh, mdcname, LUSTRE_MDC_NAME, lmvuuid);
1503 rc = record_setup(env, llh, mdcname, mti->mti_uuid, nodeuuid, 0, 0);
1504 rc = mgs_write_log_failnids(env, mti, llh, mdcname);
1505 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
1506 rc = record_mdc_add(env, llh, lmvname, mdcuuid, mti->mti_uuid,
1508 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname,
1510 rc = record_end_log(env, &llh);
1512 name_destroy(&lmvuuid);
1513 name_destroy(&mdcuuid);
1514 name_destroy(&mdcname);
1515 name_destroy(&nodeuuid);
1519 /* add new mdc to already existent MDS */
1520 static int mgs_write_log_mdc_to_mdt(const struct lu_env *env,
1521 struct mgs_device *mgs,
1523 struct mgs_target_info *mti,
1526 struct llog_handle *llh = NULL;
1527 char *nodeuuid, *mdcname, *mdcuuid, *mdtuuid;
1528 int idx = mti->mti_stripe_index;
1533 if (mgs_log_is_empty(env, mgs, logname)) {
1534 CERROR("log is empty! Logical error\n");
1538 CDEBUG(D_MGS, "adding mdc index %d to %s\n", idx, logname);
1540 name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
1541 snprintf(index, sizeof(index), "-mdc%04x", idx);
1542 name_create(&mdcname, logname, index);
1543 name_create(&mdcuuid, mdcname, "_UUID");
1544 name_create(&mdtuuid, logname, "_UUID");
1546 rc = record_start_log(env, mgs, &llh, logname);
1547 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname, "add mdc");
1548 for (i = 0; i < mti->mti_nid_count; i++) {
1549 CDEBUG(D_MGS, "add nid %s for mdt\n",
1550 libcfs_nid2str(mti->mti_nids[i]));
1551 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
1553 rc = record_attach(env, llh, mdcname, LUSTRE_MDC_NAME, mdcuuid);
1554 rc = record_setup(env, llh, mdcname, mti->mti_uuid, nodeuuid, 0, 0);
1555 rc = mgs_write_log_failnids(env, mti, llh, mdcname);
1556 snprintf(index, sizeof(index), "%d", idx);
1558 rc = record_mdc_add(env, llh, logname, mdcuuid, mti->mti_uuid,
1560 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname, "add mdc");
1561 rc = record_end_log(env, &llh);
1563 name_destroy(&mdcuuid);
1564 name_destroy(&mdcname);
1565 name_destroy(&nodeuuid);
1566 name_destroy(&mdtuuid);
1570 static int mgs_write_log_mdt0(const struct lu_env *env,
1571 struct mgs_device *mgs,
1573 struct mgs_target_info *mti)
1575 char *log = mti->mti_svname;
1576 struct llog_handle *llh = NULL;
1577 char *uuid, *lovname;
1579 char *ptr = mti->mti_params;
1580 int rc = 0, failout = 0;
1583 OBD_ALLOC(uuid, sizeof(struct obd_uuid));
1587 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
1588 failout = (strncmp(ptr, "failout", 7) == 0);
1590 name_create(&lovname, log, "-mdtlov");
1591 if (mgs_log_is_empty(env, mgs, log))
1592 rc = mgs_write_log_lov(env, mgs, fsdb, mti, log, lovname);
1594 sprintf(uuid, "%s_UUID", log);
1595 sprintf(mdt_index, "%d", mti->mti_stripe_index);
1597 /* add MDT itself */
1598 rc = record_start_log(env, mgs, &llh, log);
1602 /* FIXME this whole fn should be a single journal transaction */
1603 rc = record_marker(env, llh, fsdb, CM_START, log, "add mdt");
1604 rc = record_attach(env, llh, log, LUSTRE_MDT_NAME, uuid);
1605 rc = record_mount_opt(env, llh, log, lovname, NULL);
1606 rc = record_setup(env, llh, log, uuid, mdt_index, lovname,
1607 failout ? "n" : "f");
1608 rc = record_marker(env, llh, fsdb, CM_END, log, "add mdt");
1609 rc = record_end_log(env, &llh);
1611 name_destroy(&lovname);
1612 OBD_FREE(uuid, sizeof(struct obd_uuid));
1616 static inline void name_create_mdt(char **logname, char *fsname, int i)
1620 sprintf(mdt_index, "-MDT%04x", i);
1621 name_create(logname, fsname, mdt_index);
1624 static void name_create_mdt_and_lov(char **logname, char **lovname,
1625 struct fs_db *fsdb, int i)
1627 name_create_mdt(logname, fsdb->fsdb_name, i);
1629 if (i == 0 && cfs_test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
1630 name_create(lovname, fsdb->fsdb_name, "-mdtlov");
1632 name_create(lovname, *logname, "-mdtlov");
1635 static inline void name_create_mdt_osc(char **oscname, char *ostname,
1636 struct fs_db *fsdb, int i)
1640 if (i == 0 && cfs_test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
1641 sprintf(suffix, "-osc");
1643 sprintf(suffix, "-osc-MDT%04x", i);
1644 name_create(oscname, ostname, suffix);
1647 /* envelope method for all layers log */
1648 static int mgs_write_log_mdt(const struct lu_env *env,
1649 struct mgs_device *mgs,
1651 struct mgs_target_info *mti)
1653 struct llog_handle *llh = NULL;
1655 struct temp_comp comp = { 0 };
1659 CDEBUG(D_MGS, "writing new mdt %s\n", mti->mti_svname);
1663 if (mti->mti_flags & LDD_F_UPGRADE14) {
1664 /* We're starting with an old uuid. Assume old name for lov
1665 as well since the lov entry already exists in the log. */
1666 CDEBUG(D_MGS, "old mds uuid %s\n", mti->mti_uuid);
1667 if (strncmp(mti->mti_uuid, fsdb->fsdb_mdtlov + 4,
1668 strlen(fsdb->fsdb_mdtlov) - 4) != 0) {
1669 CERROR("old mds uuid %s doesn't match log %s (%s)\n",
1670 mti->mti_uuid, fsdb->fsdb_mdtlov,
1671 fsdb->fsdb_mdtlov + 4);
1675 /* end COMPAT_146 */
1677 if (mti->mti_uuid[0] == '\0') {
1678 /* Make up our own uuid */
1679 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
1680 "%s_UUID", mti->mti_svname);
1684 rc = mgs_write_log_mdt0(env, mgs, fsdb, mti);
1686 /* Append the mdt info to the client log */
1687 name_create(&cliname, mti->mti_fsname, "-client");
1689 if (mgs_log_is_empty(env, mgs, cliname)) {
1690 /* Start client log */
1691 rc = mgs_write_log_lov(env, mgs, fsdb, mti, cliname,
1693 rc = mgs_write_log_lmv(env, mgs, fsdb, mti, cliname,
1698 #09 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
1699 #10 L attach 0:MDC_uml1_mdsA_MNT_client 1:mdc 2:1d834_MNT_client_03f
1700 #11 L setup 0:MDC_uml1_mdsA_MNT_client 1:mdsA_UUID 2:uml1_UUID
1701 #12 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
1702 #13 L add_conn 0:MDC_uml1_mdsA_MNT_client 1:uml2_UUID
1703 #14 L mount_option 0: 1:client 2:lov1 3:MDC_uml1_mdsA_MNT_client
1708 if (mti->mti_flags & LDD_F_UPGRADE14) {
1709 rc = record_start_log(obd, &llh, cliname);
1713 rc = record_marker(obd, llh, fsdb, CM_START,
1714 mti->mti_svname,"add mdc");
1716 /* Old client log already has MDC entry, but needs mount opt
1717 for new client name (lustre-client) */
1718 /* FIXME Old MDT log already has an old mount opt
1719 which we should remove (currently handled by
1720 class_del_profiles()) */
1721 rc = record_mount_opt(obd, llh, cliname, fsdb->fsdb_clilov,
1723 /* end COMPAT_146 */
1725 rc = record_marker(obd, llh, fsdb, CM_END,
1726 mti->mti_svname, "add mdc");
1730 /* copy client info about lov/lmv */
1731 comp.comp_mti = mti;
1732 comp.comp_fsdb = fsdb;
1734 rc = mgs_steal_llog_for_mdt_from_client(env, mgs, cliname,
1737 rc = mgs_write_log_mdc_to_lmv(env, mgs, fsdb, mti, cliname,
1740 rc = record_start_log(env, mgs, &llh, cliname);
1744 rc = record_marker(env, llh, fsdb, CM_START, cliname,
1746 rc = record_mount_opt(env, llh, cliname, fsdb->fsdb_clilov,
1748 rc = record_marker(env, llh, fsdb, CM_END, cliname,
1752 rc = record_end_log(env, &llh);
1754 name_destroy(&cliname);
1756 // for_all_existing_mdt except current one
1757 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
1759 if (i != mti->mti_stripe_index &&
1760 cfs_test_bit(i, fsdb->fsdb_mdt_index_map)) {
1761 name_create_mdt(&mdtname, mti->mti_fsname, i);
1762 rc = mgs_write_log_mdc_to_mdt(env, mgs, fsdb,
1764 name_destroy(&mdtname);
1771 /* Add the ost info to the client/mdt lov */
1772 static int mgs_write_log_osc_to_lov(const struct lu_env *env,
1773 struct mgs_device *mgs, struct fs_db *fsdb,
1774 struct mgs_target_info *mti,
1775 char *logname, char *suffix, char *lovname,
1776 enum lustre_sec_part sec_part, int flags)
1778 struct llog_handle *llh = NULL;
1779 char *nodeuuid, *oscname, *oscuuid, *lovuuid, *svname;
1784 CDEBUG(D_INFO, "adding osc for %s to log %s\n",
1785 mti->mti_svname, logname);
1787 if (mgs_log_is_empty(env, mgs, logname)) {
1788 CERROR("log is empty! Logical error\n");
1792 name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
1793 name_create(&svname, mti->mti_svname, "-osc");
1794 name_create(&oscname, svname, suffix);
1795 name_create(&oscuuid, oscname, "_UUID");
1796 name_create(&lovuuid, lovname, "_UUID");
1799 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
1801 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
1802 #04 L attach 0:OSC_uml1_ost1_MNT_client 1:osc 2:89070_lov1_a41dff51a
1803 #05 L setup 0:OSC_uml1_ost1_MNT_client 1:ost1_UUID 2:uml1_UUID
1805 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
1806 #07 L add_conn 0:OSC_uml1_ost1_MNT_client 1:uml2_UUID
1807 #08 L lov_modify_tgts add 0:lov1 1:ost1_UUID 2(index):0 3(gen):1
1810 rc = record_start_log(env, mgs, &llh, logname);
1813 /* FIXME these should be a single journal transaction */
1814 rc = record_marker(env, llh, fsdb, CM_START | flags, mti->mti_svname,
1816 for (i = 0; i < mti->mti_nid_count; i++) {
1817 CDEBUG(D_MGS, "add nid %s\n", libcfs_nid2str(mti->mti_nids[i]));
1818 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
1820 rc = record_attach(env, llh, oscname, LUSTRE_OSC_NAME, lovuuid);
1821 rc = record_setup(env, llh, oscname, mti->mti_uuid, nodeuuid, 0, 0);
1822 rc = mgs_write_log_failnids(env, mti, llh, oscname);
1823 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
1824 rc = record_lov_add(env, llh, lovname, mti->mti_uuid, index, "1");
1825 rc = record_marker(env, llh, fsdb, CM_END | flags, mti->mti_svname,
1827 rc = record_end_log(env, &llh);
1829 name_destroy(&lovuuid);
1830 name_destroy(&oscuuid);
1831 name_destroy(&oscname);
1832 name_destroy(&svname);
1833 name_destroy(&nodeuuid);
1837 static int mgs_write_log_ost(const struct lu_env *env,
1838 struct mgs_device *mgs, struct fs_db *fsdb,
1839 struct mgs_target_info *mti)
1841 struct llog_handle *llh = NULL;
1842 char *logname, *lovname;
1843 char *ptr = mti->mti_params;
1844 int rc, flags = 0, failout = 0, i;
1847 CDEBUG(D_MGS, "writing new ost %s\n", mti->mti_svname);
1849 /* The ost startup log */
1851 /* If the ost log already exists, that means that someone reformatted
1852 the ost and it called target_add again. */
1853 if (!mgs_log_is_empty(env, mgs, mti->mti_svname)) {
1854 LCONSOLE_ERROR_MSG(0x141, "The config log for %s already "
1855 "exists, yet the server claims it never "
1856 "registered. It may have been reformatted, "
1857 "or the index changed. writeconf the MDT to "
1858 "regenerate all logs.\n", mti->mti_svname);
1863 attach obdfilter ost1 ost1_UUID
1864 setup /dev/loop2 ldiskfs f|n errors=remount-ro,user_xattr
1866 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
1867 failout = (strncmp(ptr, "failout", 7) == 0);
1868 rc = record_start_log(env, mgs, &llh, mti->mti_svname);
1871 /* FIXME these should be a single journal transaction */
1872 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,"add ost");
1873 if (*mti->mti_uuid == '\0')
1874 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
1875 "%s_UUID", mti->mti_svname);
1876 rc = record_attach(env, llh, mti->mti_svname,
1877 "obdfilter"/*LUSTRE_OST_NAME*/, mti->mti_uuid);
1878 rc = record_setup(env, llh, mti->mti_svname,
1879 "dev"/*ignored*/, "type"/*ignored*/,
1880 failout ? "n" : "f", 0/*options*/);
1881 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname, "add ost");
1882 rc = record_end_log(env, &llh);
1884 /* We also have to update the other logs where this osc is part of
1887 if (cfs_test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
1888 /* If we're upgrading, the old mdt log already has our
1889 entry. Let's do a fake one for fun. */
1890 /* Note that we can't add any new failnids, since we don't
1891 know the old osc names. */
1892 flags = CM_SKIP | CM_UPGRADE146;
1894 } else if ((mti->mti_flags & LDD_F_UPDATE) != LDD_F_UPDATE) {
1895 /* If the update flag isn't set, don't update client/mdt
1898 LCONSOLE_WARN("Client log for %s was not updated; writeconf "
1899 "the MDT first to regenerate it.\n",
1903 /* Add ost to all MDT lov defs */
1904 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
1905 if (cfs_test_bit(i, fsdb->fsdb_mdt_index_map)) {
1908 name_create_mdt_and_lov(&logname, &lovname, fsdb, i);
1909 sprintf(mdt_index, "-MDT%04x", i);
1910 mgs_write_log_osc_to_lov(env, mgs, fsdb, mti, logname,
1912 LUSTRE_SP_MDT, flags);
1913 name_destroy(&logname);
1914 name_destroy(&lovname);
1918 /* Append ost info to the client log */
1919 name_create(&logname, mti->mti_fsname, "-client");
1920 if (mgs_log_is_empty(env, mgs, logname)) {
1921 /* Start client log */
1922 rc = mgs_write_log_lov(env, mgs, fsdb, mti, logname,
1924 rc = mgs_write_log_lmv(env, mgs, fsdb, mti, logname,
1927 mgs_write_log_osc_to_lov(env, mgs, fsdb, mti, logname, "",
1928 fsdb->fsdb_clilov, LUSTRE_SP_CLI, flags);
1929 name_destroy(&logname);
1933 static __inline__ int mgs_param_empty(char *ptr)
1937 if ((tmp = strchr(ptr, '=')) && (*(++tmp) == '\0'))
1942 static int mgs_write_log_failnid_internal(const struct lu_env *env,
1943 struct mgs_device *mgs,
1945 struct mgs_target_info *mti,
1946 char *logname, char *cliname)
1949 struct llog_handle *llh = NULL;
1951 if (mgs_param_empty(mti->mti_params)) {
1952 /* Remove _all_ failnids */
1953 rc = mgs_modify(env, mgs, fsdb, mti, logname,
1954 mti->mti_svname, "add failnid", CM_SKIP);
1958 /* Otherwise failover nids are additive */
1959 rc = record_start_log(env, mgs, &llh, logname);
1961 /* FIXME this should be a single journal transaction */
1962 rc = record_marker(env, llh, fsdb, CM_START,
1963 mti->mti_svname, "add failnid");
1964 rc = mgs_write_log_failnids(env, mti, llh, cliname);
1965 rc = record_marker(env, llh, fsdb, CM_END,
1966 mti->mti_svname, "add failnid");
1967 rc = record_end_log(env, &llh);
1974 /* Add additional failnids to an existing log.
1975 The mdc/osc must have been added to logs first */
1976 /* tcp nids must be in dotted-quad ascii -
1977 we can't resolve hostnames from the kernel. */
1978 static int mgs_write_log_add_failnid(const struct lu_env *env,
1979 struct mgs_device *mgs,
1981 struct mgs_target_info *mti)
1983 char *logname, *cliname;
1987 /* FIXME we currently can't erase the failnids
1988 * given when a target first registers, since they aren't part of
1989 * an "add uuid" stanza */
1991 /* Verify that we know about this target */
1992 if (mgs_log_is_empty(env, mgs, mti->mti_svname)) {
1993 LCONSOLE_ERROR_MSG(0x142, "The target %s has not registered "
1994 "yet. It must be started before failnids "
1995 "can be added.\n", mti->mti_svname);
1999 /* Create mdc/osc client name (e.g. lustre-OST0001-osc) */
2000 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
2001 name_create(&cliname, mti->mti_svname, "-mdc");
2002 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2003 name_create(&cliname, mti->mti_svname, "-osc");
2008 /* Add failover nids to the client log */
2009 name_create(&logname, mti->mti_fsname, "-client");
2010 rc = mgs_write_log_failnid_internal(env, mgs, fsdb,mti,logname,cliname);
2011 name_destroy(&logname);
2012 name_destroy(&cliname);
2014 if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2015 /* Add OST failover nids to the MDT logs as well */
2018 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2019 if (!cfs_test_bit(i, fsdb->fsdb_mdt_index_map))
2021 name_create_mdt(&logname, mti->mti_fsname, i);
2022 name_create_mdt_osc(&cliname, mti->mti_svname, fsdb, i);
2023 rc = mgs_write_log_failnid_internal(env, mgs, fsdb, mti,
2025 name_destroy(&cliname);
2026 name_destroy(&logname);
2033 static int mgs_wlp_lcfg(const struct lu_env *env,
2034 struct mgs_device *mgs, struct fs_db *fsdb,
2035 struct mgs_target_info *mti,
2036 char *logname, struct lustre_cfg_bufs *bufs,
2037 char *tgtname, char *ptr)
2039 char comment[MTI_NAME_MAXLEN];
2041 struct lustre_cfg *lcfg;
2044 /* Erase any old settings of this same parameter */
2045 memcpy(comment, ptr, MTI_NAME_MAXLEN);
2046 comment[MTI_NAME_MAXLEN - 1] = 0;
2047 /* But don't try to match the value. */
2048 if ((tmp = strchr(comment, '=')))
2050 /* FIXME we should skip settings that are the same as old values */
2051 rc = mgs_modify(env, mgs, fsdb, mti, logname, tgtname, comment,CM_SKIP);
2052 del = mgs_param_empty(ptr);
2054 LCONSOLE_INFO("%sing parameter %s.%s in log %s\n", del ? "Disabl" : rc ?
2055 "Sett" : "Modify", tgtname, comment, logname);
2059 lustre_cfg_bufs_reset(bufs, tgtname);
2060 lustre_cfg_bufs_set_string(bufs, 1, ptr);
2061 lcfg = lustre_cfg_new(LCFG_PARAM, bufs);
2064 rc = mgs_write_log_direct(env, mgs, fsdb, logname,lcfg,tgtname,comment);
2065 lustre_cfg_free(lcfg);
2069 /* write global variable settings into log */
2070 static int mgs_write_log_sys(const struct lu_env *env,
2071 struct mgs_device *mgs, struct fs_db *fsdb,
2072 struct mgs_target_info *mti, char *sys, char *ptr)
2074 struct lustre_cfg_bufs bufs;
2075 struct lustre_cfg *lcfg;
2077 int rc, cmd, convert = 1;
2079 if (class_match_param(ptr, PARAM_TIMEOUT, &tmp) == 0) {
2080 cmd = LCFG_SET_TIMEOUT;
2081 } else if (class_match_param(ptr, PARAM_LDLM_TIMEOUT, &tmp) == 0) {
2082 cmd = LCFG_SET_LDLM_TIMEOUT;
2083 /* Check for known params here so we can return error to lctl */
2084 } else if ((class_match_param(ptr, PARAM_AT_MIN, &tmp) == 0) ||
2085 (class_match_param(ptr, PARAM_AT_MAX, &tmp) == 0) ||
2086 (class_match_param(ptr, PARAM_AT_EXTRA, &tmp) == 0) ||
2087 (class_match_param(ptr, PARAM_AT_EARLY_MARGIN, &tmp) == 0) ||
2088 (class_match_param(ptr, PARAM_AT_HISTORY, &tmp) == 0)) {
2090 } else if (class_match_param(ptr, PARAM_JOBID_VAR, &tmp) == 0) {
2091 convert = 0; /* Don't convert string value to integer */
2097 if (mgs_param_empty(ptr))
2098 CDEBUG(D_MGS, "global '%s' removed\n", sys);
2100 CDEBUG(D_MGS, "global '%s' val=%s\n", sys, tmp);
2102 lustre_cfg_bufs_reset(&bufs, NULL);
2103 lustre_cfg_bufs_set_string(&bufs, 1, sys);
2104 if (!convert && *tmp != '\0')
2105 lustre_cfg_bufs_set_string(&bufs, 2, tmp);
2106 lcfg = lustre_cfg_new(cmd, &bufs);
2107 lcfg->lcfg_num = convert ? simple_strtoul(tmp, NULL, 0) : 0;
2108 /* truncate the comment to the parameter name */
2112 /* modify all servers and clients */
2113 rc = mgs_write_log_direct_all(env, mgs, fsdb, mti,
2114 *tmp == '\0' ? NULL : lcfg,
2115 mti->mti_fsname, sys, 0);
2116 if (rc == 0 && *tmp != '\0') {
2118 case LCFG_SET_TIMEOUT:
2119 if (!obd_timeout_set || lcfg->lcfg_num > obd_timeout)
2120 class_process_config(lcfg);
2122 case LCFG_SET_LDLM_TIMEOUT:
2123 if (!ldlm_timeout_set || lcfg->lcfg_num > ldlm_timeout)
2124 class_process_config(lcfg);
2131 lustre_cfg_free(lcfg);
2135 /* write quota settings into log */
2136 static int mgs_write_log_quota(const struct lu_env *env, struct mgs_device *mgs,
2137 struct fs_db *fsdb, struct mgs_target_info *mti,
2138 char *quota, char *ptr)
2140 struct lustre_cfg_bufs bufs;
2141 struct lustre_cfg *lcfg;
2144 int cmd = LCFG_PARAM;
2147 /* support only 'meta' and 'data' pools so far */
2148 if (class_match_param(ptr, QUOTA_METAPOOL_NAME, &tmp) != 0 &&
2149 class_match_param(ptr, QUOTA_DATAPOOL_NAME, &tmp) != 0) {
2150 CERROR("parameter quota.%s isn't supported (only quota.mdt "
2151 "& quota.ost are)\n", ptr);
2156 CDEBUG(D_MGS, "global '%s' removed\n", quota);
2158 CDEBUG(D_MGS, "global '%s'\n", quota);
2160 if (strchr(tmp, 'u') == NULL && strchr(tmp, 'g') == NULL &&
2161 strcmp(tmp, "none") != 0) {
2162 CERROR("enable option(%s) isn't supported\n", tmp);
2167 lustre_cfg_bufs_reset(&bufs, NULL);
2168 lustre_cfg_bufs_set_string(&bufs, 1, quota);
2169 lcfg = lustre_cfg_new(cmd, &bufs);
2170 /* truncate the comment to the parameter name */
2175 /* XXX we duplicated quota enable information in all server
2176 * config logs, it should be moved to a separate config
2177 * log once we cleanup the config log for global param. */
2178 /* modify all servers */
2179 rc = mgs_write_log_direct_all(env, mgs, fsdb, mti,
2180 *tmp == '\0' ? NULL : lcfg,
2181 mti->mti_fsname, quota, 1);
2183 lustre_cfg_free(lcfg);
2187 static int mgs_srpc_set_param_disk(const struct lu_env *env,
2188 struct mgs_device *mgs,
2190 struct mgs_target_info *mti,
2193 struct llog_handle *llh = NULL;
2195 char *comment, *ptr;
2196 struct lustre_cfg_bufs bufs;
2197 struct lustre_cfg *lcfg;
2202 ptr = strchr(param, '=');
2206 OBD_ALLOC(comment, len + 1);
2207 if (comment == NULL)
2209 strncpy(comment, param, len);
2210 comment[len] = '\0';
2213 lustre_cfg_bufs_reset(&bufs, mti->mti_svname);
2214 lustre_cfg_bufs_set_string(&bufs, 1, param);
2215 lcfg = lustre_cfg_new(LCFG_SPTLRPC_CONF, &bufs);
2217 GOTO(out_comment, rc = -ENOMEM);
2219 /* construct log name */
2220 rc = name_create(&logname, mti->mti_fsname, "-sptlrpc");
2224 if (mgs_log_is_empty(env, mgs, logname)) {
2225 rc = record_start_log(env, mgs, &llh, logname);
2226 record_end_log(env, &llh);
2231 /* obsolete old one */
2232 mgs_modify(env, mgs, fsdb, mti, logname, mti->mti_svname,
2235 /* write the new one */
2236 rc = mgs_write_log_direct(env, mgs, fsdb, logname, lcfg,
2237 mti->mti_svname, comment);
2239 CERROR("err %d writing log %s\n", rc, logname);
2242 name_destroy(&logname);
2244 lustre_cfg_free(lcfg);
2246 OBD_FREE(comment, len + 1);
2250 static int mgs_srpc_set_param_udesc_mem(struct fs_db *fsdb,
2255 /* disable the adjustable udesc parameter for now, i.e. use default
2256 * setting that client always ship udesc to MDT if possible. to enable
2257 * it simply remove the following line */
2260 ptr = strchr(param, '=');
2265 if (strcmp(param, PARAM_SRPC_UDESC))
2268 if (strcmp(ptr, "yes") == 0) {
2269 cfs_set_bit(FSDB_UDESC, &fsdb->fsdb_flags);
2270 CWARN("Enable user descriptor shipping from client to MDT\n");
2271 } else if (strcmp(ptr, "no") == 0) {
2272 cfs_clear_bit(FSDB_UDESC, &fsdb->fsdb_flags);
2273 CWARN("Disable user descriptor shipping from client to MDT\n");
2281 CERROR("Invalid param: %s\n", param);
2285 static int mgs_srpc_set_param_mem(struct fs_db *fsdb,
2289 struct sptlrpc_rule rule;
2290 struct sptlrpc_rule_set *rset;
2294 if (strncmp(param, PARAM_SRPC, sizeof(PARAM_SRPC) - 1) != 0) {
2295 CERROR("Invalid sptlrpc parameter: %s\n", param);
2299 if (strncmp(param, PARAM_SRPC_UDESC,
2300 sizeof(PARAM_SRPC_UDESC) - 1) == 0) {
2301 RETURN(mgs_srpc_set_param_udesc_mem(fsdb, param));
2304 if (strncmp(param, PARAM_SRPC_FLVR, sizeof(PARAM_SRPC_FLVR) - 1) != 0) {
2305 CERROR("Invalid sptlrpc flavor parameter: %s\n", param);
2309 param += sizeof(PARAM_SRPC_FLVR) - 1;
2311 rc = sptlrpc_parse_rule(param, &rule);
2315 /* mgs rules implies must be mgc->mgs */
2316 if (cfs_test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
2317 if ((rule.sr_from != LUSTRE_SP_MGC &&
2318 rule.sr_from != LUSTRE_SP_ANY) ||
2319 (rule.sr_to != LUSTRE_SP_MGS &&
2320 rule.sr_to != LUSTRE_SP_ANY))
2324 /* preapre room for this coming rule. svcname format should be:
2325 * - fsname: general rule
2326 * - fsname-tgtname: target-specific rule
2328 if (strchr(svname, '-')) {
2329 struct mgs_tgt_srpc_conf *tgtconf;
2332 for (tgtconf = fsdb->fsdb_srpc_tgt; tgtconf != NULL;
2333 tgtconf = tgtconf->mtsc_next) {
2334 if (!strcmp(tgtconf->mtsc_tgt, svname)) {
2343 OBD_ALLOC_PTR(tgtconf);
2344 if (tgtconf == NULL)
2347 name_len = strlen(svname);
2349 OBD_ALLOC(tgtconf->mtsc_tgt, name_len + 1);
2350 if (tgtconf->mtsc_tgt == NULL) {
2351 OBD_FREE_PTR(tgtconf);
2354 memcpy(tgtconf->mtsc_tgt, svname, name_len);
2356 tgtconf->mtsc_next = fsdb->fsdb_srpc_tgt;
2357 fsdb->fsdb_srpc_tgt = tgtconf;
2360 rset = &tgtconf->mtsc_rset;
2362 rset = &fsdb->fsdb_srpc_gen;
2365 rc = sptlrpc_rule_set_merge(rset, &rule);
2370 static int mgs_srpc_set_param(const struct lu_env *env,
2371 struct mgs_device *mgs,
2373 struct mgs_target_info *mti,
2383 /* keep a copy of original param, which could be destroied
2385 copy_size = strlen(param) + 1;
2386 OBD_ALLOC(copy, copy_size);
2389 memcpy(copy, param, copy_size);
2391 rc = mgs_srpc_set_param_mem(fsdb, mti->mti_svname, param);
2395 /* previous steps guaranteed the syntax is correct */
2396 rc = mgs_srpc_set_param_disk(env, mgs, fsdb, mti, copy);
2400 if (cfs_test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
2402 * for mgs rules, make them effective immediately.
2404 LASSERT(fsdb->fsdb_srpc_tgt == NULL);
2405 sptlrpc_target_update_exp_flavor(mgs->mgs_obd,
2406 &fsdb->fsdb_srpc_gen);
2410 OBD_FREE(copy, copy_size);
2414 struct mgs_srpc_read_data {
2415 struct fs_db *msrd_fsdb;
2419 static int mgs_srpc_read_handler(const struct lu_env *env,
2420 struct llog_handle *llh,
2421 struct llog_rec_hdr *rec, void *data)
2423 struct mgs_srpc_read_data *msrd = data;
2424 struct cfg_marker *marker;
2425 struct lustre_cfg *lcfg = (struct lustre_cfg *)(rec + 1);
2426 char *svname, *param;
2430 if (rec->lrh_type != OBD_CFG_REC) {
2431 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
2435 cfg_len = rec->lrh_len - sizeof(struct llog_rec_hdr) -
2436 sizeof(struct llog_rec_tail);
2438 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
2440 CERROR("Insane cfg\n");
2444 if (lcfg->lcfg_command == LCFG_MARKER) {
2445 marker = lustre_cfg_buf(lcfg, 1);
2447 if (marker->cm_flags & CM_START &&
2448 marker->cm_flags & CM_SKIP)
2449 msrd->msrd_skip = 1;
2450 if (marker->cm_flags & CM_END)
2451 msrd->msrd_skip = 0;
2456 if (msrd->msrd_skip)
2459 if (lcfg->lcfg_command != LCFG_SPTLRPC_CONF) {
2460 CERROR("invalid command (%x)\n", lcfg->lcfg_command);
2464 svname = lustre_cfg_string(lcfg, 0);
2465 if (svname == NULL) {
2466 CERROR("svname is empty\n");
2470 param = lustre_cfg_string(lcfg, 1);
2471 if (param == NULL) {
2472 CERROR("param is empty\n");
2476 rc = mgs_srpc_set_param_mem(msrd->msrd_fsdb, svname, param);
2478 CERROR("read sptlrpc record error (%d): %s\n", rc, param);
2483 int mgs_get_fsdb_srpc_from_llog(const struct lu_env *env,
2484 struct mgs_device *mgs,
2487 struct llog_handle *llh = NULL;
2488 struct lvfs_run_ctxt saved;
2489 struct llog_ctxt *ctxt;
2491 struct mgs_srpc_read_data msrd;
2495 /* construct log name */
2496 rc = name_create(&logname, fsdb->fsdb_name, "-sptlrpc");
2500 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
2501 LASSERT(ctxt != NULL);
2503 if (mgs_log_is_empty(env, mgs, logname))
2506 push_ctxt(&saved, &mgs->mgs_obd->obd_lvfs_ctxt, NULL);
2508 rc = llog_open(NULL, ctxt, &llh, NULL, logname,
2516 rc = llog_init_handle(NULL, llh, LLOG_F_IS_PLAIN, NULL);
2518 GOTO(out_close, rc);
2520 if (llog_get_size(llh) <= 1)
2521 GOTO(out_close, rc = 0);
2523 msrd.msrd_fsdb = fsdb;
2526 rc = llog_process(NULL, llh, mgs_srpc_read_handler, (void *)&msrd,
2530 llog_close(NULL, llh);
2532 pop_ctxt(&saved, &mgs->mgs_obd->obd_lvfs_ctxt, NULL);
2534 llog_ctxt_put(ctxt);
2535 name_destroy(&logname);
2538 CERROR("failed to read sptlrpc config database: %d\n", rc);
2542 /* Permanent settings of all parameters by writing into the appropriate
2543 * configuration logs.
2544 * A parameter with null value ("<param>='\0'") means to erase it out of
2547 static int mgs_write_log_param(const struct lu_env *env,
2548 struct mgs_device *mgs, struct fs_db *fsdb,
2549 struct mgs_target_info *mti, char *ptr)
2551 struct lustre_cfg_bufs bufs;
2554 int rc = 0, rc2 = 0;
2557 /* For various parameter settings, we have to figure out which logs
2558 care about them (e.g. both mdt and client for lov settings) */
2559 CDEBUG(D_MGS, "next param '%s'\n", ptr);
2561 /* The params are stored in MOUNT_DATA_FILE and modified via
2562 tunefs.lustre, or set using lctl conf_param */
2564 /* Processed in lustre_start_mgc */
2565 if (class_match_param(ptr, PARAM_MGSNODE, NULL) == 0)
2568 /* Processed in ost/mdt */
2569 if (class_match_param(ptr, PARAM_NETWORK, NULL) == 0)
2572 /* Processed in mgs_write_log_ost */
2573 if (class_match_param(ptr, PARAM_FAILMODE, NULL) == 0) {
2574 if (mti->mti_flags & LDD_F_PARAM) {
2575 LCONSOLE_ERROR_MSG(0x169, "%s can only be "
2576 "changed with tunefs.lustre"
2577 "and --writeconf\n", ptr);
2583 if (class_match_param(ptr, PARAM_SRPC, NULL) == 0) {
2584 rc = mgs_srpc_set_param(env, mgs, fsdb, mti, ptr);
2588 if (class_match_param(ptr, PARAM_FAILNODE, NULL) == 0) {
2589 /* Add a failover nidlist */
2591 /* We already processed failovers params for new
2592 targets in mgs_write_log_target */
2593 if (mti->mti_flags & LDD_F_PARAM) {
2594 CDEBUG(D_MGS, "Adding failnode\n");
2595 rc = mgs_write_log_add_failnid(env, mgs, fsdb, mti);
2600 if (class_match_param(ptr, PARAM_SYS, &tmp) == 0) {
2601 rc = mgs_write_log_sys(env, mgs, fsdb, mti, ptr, tmp);
2605 if (class_match_param(ptr, PARAM_QUOTA, &tmp) == 0) {
2606 rc = mgs_write_log_quota(env, mgs, fsdb, mti, ptr, tmp);
2610 if (class_match_param(ptr, PARAM_OSC""PARAM_ACTIVE, &tmp) == 0) {
2611 /* active=0 means off, anything else means on */
2612 int flag = (*tmp == '0') ? CM_EXCLUDE : 0;
2615 if (!(mti->mti_flags & LDD_F_SV_TYPE_OST)) {
2616 LCONSOLE_ERROR_MSG(0x144, "%s: Only OSCs can "
2617 "be (de)activated.\n",
2619 GOTO(end, rc = -EINVAL);
2621 LCONSOLE_WARN("Permanently %sactivating %s\n",
2622 flag ? "de": "re", mti->mti_svname);
2624 name_create(&logname, mti->mti_fsname, "-client");
2625 rc = mgs_modify(env, mgs, fsdb, mti, logname,
2626 mti->mti_svname, "add osc", flag);
2627 name_destroy(&logname);
2631 /* Add to all MDT logs for CMD */
2632 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2633 if (!cfs_test_bit(i, fsdb->fsdb_mdt_index_map))
2635 name_create_mdt(&logname, mti->mti_fsname, i);
2636 rc = mgs_modify(env, mgs, fsdb, mti, logname,
2637 mti->mti_svname, "add osc", flag);
2638 name_destroy(&logname);
2644 LCONSOLE_ERROR_MSG(0x145, "Couldn't find %s in"
2645 "log (%d). No permanent "
2646 "changes were made to the "
2648 mti->mti_svname, rc);
2649 if (cfs_test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags))
2650 LCONSOLE_ERROR_MSG(0x146, "This may be"
2655 "update the logs.\n");
2658 /* Fall through to osc proc for deactivating live OSC
2659 on running MDT / clients. */
2661 /* Below here, let obd's XXX_process_config methods handle it */
2663 /* All lov. in proc */
2664 if (class_match_param(ptr, PARAM_LOV, NULL) == 0) {
2667 CDEBUG(D_MGS, "lov param %s\n", ptr);
2668 if (!(mti->mti_flags & LDD_F_SV_TYPE_MDT)) {
2669 LCONSOLE_ERROR_MSG(0x147, "LOV params must be "
2670 "set on the MDT, not %s. "
2677 if (mgs_log_is_empty(env, mgs, mti->mti_svname))
2678 GOTO(end, rc = -ENODEV);
2680 name_create_mdt_and_lov(&logname, &mdtlovname, fsdb,
2681 mti->mti_stripe_index);
2682 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, mti->mti_svname,
2683 &bufs, mdtlovname, ptr);
2684 name_destroy(&logname);
2685 name_destroy(&mdtlovname);
2690 name_create(&logname, mti->mti_fsname, "-client");
2691 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname, &bufs,
2692 fsdb->fsdb_clilov, ptr);
2693 name_destroy(&logname);
2697 /* All osc., mdc., llite. params in proc */
2698 if ((class_match_param(ptr, PARAM_OSC, NULL) == 0) ||
2699 (class_match_param(ptr, PARAM_MDC, NULL) == 0) ||
2700 (class_match_param(ptr, PARAM_LLITE, NULL) == 0)) {
2702 if (memcmp(ptr, PARAM_LLITE, strlen(PARAM_LLITE)) == 0) {
2703 name_create(&cname, mti->mti_fsname, "-client");
2704 /* Add the client type to match the obdname in
2705 class_config_llog_handler */
2706 } else if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
2709 name_create(&cname, fsdb->fsdb_mdc, "");
2711 name_create(&cname, mti->mti_svname,
2713 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2715 if (cfs_test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
2716 LCONSOLE_ERROR_MSG(0x148, "Upgraded "
2717 "client logs for %s"
2719 "modified. Consider"
2721 "configuration with"
2724 /* We don't know the names of all the
2726 GOTO(end, rc = -EINVAL);
2728 name_create(&cname, mti->mti_svname, "-osc");
2730 GOTO(end, rc = -EINVAL);
2733 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
2736 name_create(&logname, mti->mti_fsname, "-client");
2737 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname, &bufs,
2740 /* osc params affect the MDT as well */
2741 if (!rc && (mti->mti_flags & LDD_F_SV_TYPE_OST)) {
2744 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
2745 if (!cfs_test_bit(i, fsdb->fsdb_mdt_index_map))
2747 name_destroy(&cname);
2748 name_create_mdt_osc(&cname, mti->mti_svname,
2750 name_destroy(&logname);
2751 name_create_mdt(&logname, mti->mti_fsname, i);
2752 if (!mgs_log_is_empty(env, mgs, logname))
2753 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti,
2754 logname, &bufs, cname,
2760 name_destroy(&logname);
2761 name_destroy(&cname);
2765 /* All mdt. params in proc */
2766 if (class_match_param(ptr, PARAM_MDT, NULL) == 0) {
2770 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
2771 if (strncmp(mti->mti_svname, mti->mti_fsname,
2772 MTI_NAME_MAXLEN) == 0)
2773 /* device is unspecified completely? */
2774 rc = LDD_F_SV_TYPE_MDT | LDD_F_SV_ALL;
2776 rc = server_name2index(mti->mti_svname, &idx, NULL);
2779 if ((rc & LDD_F_SV_TYPE_MDT) == 0)
2781 if (rc & LDD_F_SV_ALL) {
2782 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2783 if (!cfs_test_bit(i,
2784 fsdb->fsdb_mdt_index_map))
2786 name_create_mdt(&logname, mti->mti_fsname, i);
2787 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti,
2790 name_destroy(&logname);
2795 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti,
2796 mti->mti_svname, &bufs,
2797 mti->mti_svname, ptr);
2804 /* All mdd., ost. params in proc */
2805 if ((class_match_param(ptr, PARAM_MDD, NULL) == 0) ||
2806 (class_match_param(ptr, PARAM_OST, NULL) == 0)) {
2807 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
2808 if (mgs_log_is_empty(env, mgs, mti->mti_svname))
2809 GOTO(end, rc = -ENODEV);
2811 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, mti->mti_svname,
2812 &bufs, mti->mti_svname, ptr);
2816 LCONSOLE_WARN("Ignoring unrecognized param '%s'\n", ptr);
2821 CERROR("err %d on param '%s'\n", rc, ptr);
2826 /* Not implementing automatic failover nid addition at this time. */
2827 int mgs_check_failnid(const struct lu_env *env, struct mgs_device *mgs,
2828 struct mgs_target_info *mti)
2835 rc = mgs_find_or_make_fsdb(obd, fsname, &fsdb);
2839 if (mgs_log_is_empty(obd, mti->mti_svname))
2840 /* should never happen */
2843 CDEBUG(D_MGS, "Checking for new failnids for %s\n", mti->mti_svname);
2845 /* FIXME We can just check mti->params to see if we're already in
2846 the failover list. Modify mti->params for rewriting back at
2847 server_register_target(). */
2849 cfs_mutex_lock(&fsdb->fsdb_mutex);
2850 rc = mgs_write_log_add_failnid(obd, fsdb, mti);
2851 cfs_mutex_unlock(&fsdb->fsdb_mutex);
2858 int mgs_write_log_target(const struct lu_env *env,
2859 struct mgs_device *mgs,
2860 struct mgs_target_info *mti,
2867 /* set/check the new target index */
2868 rc = mgs_set_index(env, mgs, mti);
2870 CERROR("Can't get index (%d)\n", rc);
2875 if (mti->mti_flags & LDD_F_UPGRADE14) {
2876 if (rc == EALREADY) {
2877 LCONSOLE_INFO("Found index %d for %s 1.4 log, "
2878 "upgrading\n", mti->mti_stripe_index,
2881 LCONSOLE_ERROR_MSG(0x149, "Failed to find %s in the old"
2882 " client log. Apparently it is not "
2883 "part of this filesystem, or the old"
2884 " log is wrong.\nUse 'writeconf' on "
2885 "the MDT to force log regeneration."
2886 "\n", mti->mti_svname);
2887 /* Not in client log? Upgrade anyhow...*/
2888 /* Argument against upgrading: reformat MDT,
2889 upgrade OST, then OST will start but will be SKIPped
2890 in client logs. Maybe error now is better. */
2891 /* RETURN(-EINVAL); */
2893 /* end COMPAT_146 */
2895 if (rc == EALREADY) {
2896 LCONSOLE_WARN("Found index %d for %s, updating log\n",
2897 mti->mti_stripe_index, mti->mti_svname);
2898 /* We would like to mark old log sections as invalid
2899 and add new log sections in the client and mdt logs.
2900 But if we add new sections, then live clients will
2901 get repeat setup instructions for already running
2902 osc's. So don't update the client/mdt logs. */
2903 mti->mti_flags &= ~LDD_F_UPDATE;
2907 cfs_mutex_lock(&fsdb->fsdb_mutex);
2909 if (mti->mti_flags &
2910 (LDD_F_VIRGIN | LDD_F_UPGRADE14 | LDD_F_WRITECONF)) {
2911 /* Generate a log from scratch */
2912 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
2913 rc = mgs_write_log_mdt(env, mgs, fsdb, mti);
2914 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2915 rc = mgs_write_log_ost(env, mgs, fsdb, mti);
2917 CERROR("Unknown target type %#x, can't create log for "
2918 "%s\n", mti->mti_flags, mti->mti_svname);
2921 CERROR("Can't write logs for %s (%d)\n",
2922 mti->mti_svname, rc);
2926 /* Just update the params from tunefs in mgs_write_log_params */
2927 CDEBUG(D_MGS, "Update params for %s\n", mti->mti_svname);
2928 mti->mti_flags |= LDD_F_PARAM;
2931 /* allocate temporary buffer, where class_get_next_param will
2932 make copy of a current parameter */
2933 OBD_ALLOC(buf, strlen(mti->mti_params) + 1);
2935 GOTO(out_up, rc = -ENOMEM);
2936 params = mti->mti_params;
2937 while (params != NULL) {
2938 rc = class_get_next_param(¶ms, buf);
2941 /* there is no next parameter, that is
2946 CDEBUG(D_MGS, "remaining string: '%s', param: '%s'\n",
2948 rc = mgs_write_log_param(env, mgs, fsdb, mti, buf);
2953 OBD_FREE(buf, strlen(mti->mti_params) + 1);
2956 cfs_mutex_unlock(&fsdb->fsdb_mutex);
2961 /* verify that we can handle the old config logs */
2962 int mgs_upgrade_sv_14(const struct lu_env *env, struct mgs_device *mgs,
2963 struct mgs_target_info *mti, struct fs_db *fsdb)
2968 /* Create ost log normally, as servers register. Servers
2969 register with their old uuids (from last_rcvd), so old
2970 (MDT and client) logs should work.
2971 - new MDT won't know about old OSTs, only the ones that have
2972 registered, so we need the old MDT log to get the LOV right
2973 in order for old clients to work.
2974 - Old clients connect to the MDT, not the MGS, for their logs, and
2975 will therefore receive the old client log from the MDT /LOGS dir.
2976 - Old clients can continue to use and connect to old or new OSTs
2977 - New clients will contact the MGS for their log
2980 LCONSOLE_INFO("upgrading server %s from pre-1.6\n", mti->mti_svname);
2981 server_mti_print("upgrade", mti);
2983 if (cfs_test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
2984 LCONSOLE_ERROR_MSG(0x14a, "The old client log %s-client is "
2985 "missing. Was tunefs.lustre successful?\n",
2990 if (fsdb->fsdb_gen == 0) {
2991 /* There were no markers in the client log, meaning we have
2992 not updated the logs for this fs */
2993 CDEBUG(D_MGS, "found old, unupdated client log\n");
2996 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
2997 if (mgs_log_is_empty(env, mgs, mti->mti_svname)) {
2998 LCONSOLE_ERROR_MSG(0x14b, "The old MDT log %s is "
2999 "missing. Was tunefs.lustre "
3004 /* We're starting with an old uuid. Assume old name for lov
3005 as well since the lov entry already exists in the log. */
3006 CDEBUG(D_MGS, "old mds uuid %s\n", mti->mti_uuid);
3007 if (strncmp(mti->mti_uuid, fsdb->fsdb_mdtlov + 4,
3008 strlen(fsdb->fsdb_mdtlov) - 4) != 0) {
3009 CERROR("old mds uuid %s doesn't match log %s (%s)\n",
3010 mti->mti_uuid, fsdb->fsdb_mdtlov,
3011 fsdb->fsdb_mdtlov + 4);
3016 if (!cfs_test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
3017 LCONSOLE_ERROR_MSG(0x14c, "%s-client is supposedly an old "
3018 "log, but no old LOV or MDT was found. "
3019 "Consider updating the configuration with"
3020 " --writeconf.\n", mti->mti_fsname);
3025 /* end COMPAT_146 */
3027 int mgs_erase_log(const struct lu_env *env, struct mgs_device *mgs, char *name)
3029 struct lvfs_run_ctxt saved;
3030 struct llog_ctxt *ctxt;
3032 struct obd_device *obd = mgs->mgs_obd;
3034 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
3036 CERROR("%s: MGS config context doesn't exist\n",
3040 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
3041 rc = llog_erase(NULL, ctxt, NULL, name);
3042 /* llog may not exist */
3045 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
3046 llog_ctxt_put(ctxt);
3050 CERROR("%s: failed to clear log %s: %d\n", obd->obd_name,
3056 /* erase all logs for the given fs */
3057 int mgs_erase_logs(const struct lu_env *env, struct mgs_device *mgs, char *fsname)
3060 cfs_list_t dentry_list;
3061 struct l_linux_dirent *dirent, *n;
3062 int rc, len = strlen(fsname);
3066 /* Find all the logs in the CONFIGS directory */
3067 rc = class_dentry_readdir(env, mgs, &dentry_list);
3069 CERROR("Can't read %s dir\n", MOUNT_CONFIGS_DIR);
3073 cfs_mutex_lock(&mgs->mgs_mutex);
3075 /* Delete the fs db */
3076 fsdb = mgs_find_fsdb(mgs, fsname);
3078 mgs_free_fsdb(mgs, fsdb);
3080 cfs_list_for_each_entry_safe(dirent, n, &dentry_list, lld_list) {
3081 cfs_list_del(&dirent->lld_list);
3082 suffix = strrchr(dirent->lld_name, '-');
3083 if (suffix != NULL) {
3084 if ((len == suffix - dirent->lld_name) &&
3085 (strncmp(fsname, dirent->lld_name, len) == 0)) {
3086 CDEBUG(D_MGS, "Removing log %s\n",
3088 mgs_erase_log(env, mgs, dirent->lld_name);
3091 OBD_FREE(dirent, sizeof(*dirent));
3094 cfs_mutex_unlock(&mgs->mgs_mutex);
3099 /* from llog_swab */
3100 static void print_lustre_cfg(struct lustre_cfg *lcfg)
3105 CDEBUG(D_MGS, "lustre_cfg: %p\n", lcfg);
3106 CDEBUG(D_MGS, "\tlcfg->lcfg_version: %#x\n", lcfg->lcfg_version);
3108 CDEBUG(D_MGS, "\tlcfg->lcfg_command: %#x\n", lcfg->lcfg_command);
3109 CDEBUG(D_MGS, "\tlcfg->lcfg_num: %#x\n", lcfg->lcfg_num);
3110 CDEBUG(D_MGS, "\tlcfg->lcfg_flags: %#x\n", lcfg->lcfg_flags);
3111 CDEBUG(D_MGS, "\tlcfg->lcfg_nid: %s\n", libcfs_nid2str(lcfg->lcfg_nid));
3113 CDEBUG(D_MGS, "\tlcfg->lcfg_bufcount: %d\n", lcfg->lcfg_bufcount);
3114 if (lcfg->lcfg_bufcount < LUSTRE_CFG_MAX_BUFCOUNT)
3115 for (i = 0; i < lcfg->lcfg_bufcount; i++) {
3116 CDEBUG(D_MGS, "\tlcfg->lcfg_buflens[%d]: %d %s\n",
3117 i, lcfg->lcfg_buflens[i],
3118 lustre_cfg_string(lcfg, i));
3123 /* Set a permanent (config log) param for a target or fs
3124 * \param lcfg buf0 may contain the device (testfs-MDT0000) name
3125 * buf1 contains the single parameter
3127 int mgs_setparam(const struct lu_env *env, struct mgs_device *mgs,
3128 struct lustre_cfg *lcfg, char *fsname)
3131 struct mgs_target_info *mti;
3132 char *devname, *param;
3138 print_lustre_cfg(lcfg);
3140 /* lustre, lustre-mdtlov, lustre-client, lustre-MDT0000 */
3141 devname = lustre_cfg_string(lcfg, 0);
3142 param = lustre_cfg_string(lcfg, 1);
3144 /* Assume device name embedded in param:
3145 lustre-OST0000.osc.max_dirty_mb=32 */
3146 ptr = strchr(param, '.');
3154 LCONSOLE_ERROR_MSG(0x14d, "No target specified: %s\n", param);
3158 /* Extract fsname */
3159 ptr = strrchr(devname, '-');
3160 memset(fsname, 0, MTI_NAME_MAXLEN);
3161 if (ptr && (server_name2index(ptr, &index, NULL) >= 0)) {
3162 /* param related to llite isn't allowed to set by OST or MDT */
3163 if (strncmp(param, PARAM_LLITE, sizeof(PARAM_LLITE)) == 0)
3166 strncpy(fsname, devname, ptr - devname);
3168 /* assume devname is the fsname */
3169 strncpy(fsname, devname, MTI_NAME_MAXLEN);
3171 fsname[MTI_NAME_MAXLEN - 1] = 0;
3172 CDEBUG(D_MGS, "setparam fs='%s' device='%s'\n", fsname, devname);
3174 rc = mgs_find_or_make_fsdb(env, mgs, fsname, &fsdb);
3177 if (!cfs_test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags) &&
3178 cfs_test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
3179 CERROR("No filesystem targets for %s. cfg_device from lctl "
3180 "is '%s'\n", fsname, devname);
3181 mgs_free_fsdb(mgs, fsdb);
3185 /* Create a fake mti to hold everything */
3188 GOTO(out, rc = -ENOMEM);
3189 strncpy(mti->mti_fsname, fsname, MTI_NAME_MAXLEN);
3190 strncpy(mti->mti_svname, devname, MTI_NAME_MAXLEN);
3191 strncpy(mti->mti_params, param, sizeof(mti->mti_params));
3192 rc = server_name2index(mti->mti_svname, &mti->mti_stripe_index, &tmp);
3194 /* Not a valid server; may be only fsname */
3197 /* Strip -osc or -mdc suffix from svname */
3198 if (server_make_name(rc, mti->mti_stripe_index, mti->mti_fsname,
3200 GOTO(out, rc = -EINVAL);
3202 mti->mti_flags = rc | LDD_F_PARAM;
3204 cfs_mutex_lock(&fsdb->fsdb_mutex);
3205 rc = mgs_write_log_param(env, mgs, fsdb, mti, mti->mti_params);
3206 cfs_mutex_unlock(&fsdb->fsdb_mutex);
3209 * Revoke lock so everyone updates. Should be alright if
3210 * someone was already reading while we were updating the logs,
3211 * so we don't really need to hold the lock while we're
3214 mgs_revoke_lock(mgs, fsdb, CONFIG_T_CONFIG);
3220 static int mgs_write_log_pool(const struct lu_env *env,
3221 struct mgs_device *mgs, char *logname,
3222 struct fs_db *fsdb, char *lovname,
3223 enum lcfg_command_type cmd,
3224 char *poolname, char *fsname,
3225 char *ostname, char *comment)
3227 struct llog_handle *llh = NULL;
3230 rc = record_start_log(env, mgs, &llh, logname);
3233 rc = record_marker(env, llh, fsdb, CM_START, lovname, comment);
3234 record_base(env, llh, lovname, 0, cmd, poolname, fsname, ostname, 0);
3235 rc = record_marker(env, llh, fsdb, CM_END, lovname, comment);
3236 rc = record_end_log(env, &llh);
3241 int mgs_pool_cmd(const struct lu_env *env, struct mgs_device *mgs,
3242 enum lcfg_command_type cmd, char *fsname,
3243 char *poolname, char *ostname)
3248 char *label = NULL, *canceled_label = NULL;
3250 struct mgs_target_info *mti = NULL;
3254 rc = mgs_find_or_make_fsdb(env, mgs, fsname, &fsdb);
3256 CERROR("Can't get db for %s\n", fsname);
3259 if (cfs_test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
3260 CERROR("%s is not defined\n", fsname);
3261 mgs_free_fsdb(mgs, fsdb);
3265 label_sz = 10 + strlen(fsname) + strlen(poolname);
3267 /* check if ostname match fsname */
3268 if (ostname != NULL) {
3271 ptr = strrchr(ostname, '-');
3272 if ((ptr == NULL) ||
3273 (strncmp(fsname, ostname, ptr-ostname) != 0))
3275 label_sz += strlen(ostname);
3278 OBD_ALLOC(label, label_sz);
3280 GOTO(out, rc = -ENOMEM);
3285 "new %s.%s", fsname, poolname);
3289 "add %s.%s.%s", fsname, poolname, ostname);
3292 OBD_ALLOC(canceled_label, label_sz);
3293 if (canceled_label == NULL)
3294 GOTO(out, rc = -ENOMEM);
3296 "rem %s.%s.%s", fsname, poolname, ostname);
3297 sprintf(canceled_label,
3298 "add %s.%s.%s", fsname, poolname, ostname);
3301 OBD_ALLOC(canceled_label, label_sz);
3302 if (canceled_label == NULL)
3303 GOTO(out, rc = -ENOMEM);
3305 "del %s.%s", fsname, poolname);
3306 sprintf(canceled_label,
3307 "new %s.%s", fsname, poolname);
3313 cfs_mutex_lock(&fsdb->fsdb_mutex);
3315 if (canceled_label != NULL) {
3318 GOTO(out, rc = -ENOMEM);
3321 /* write pool def to all MDT logs */
3322 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3323 if (cfs_test_bit(i, fsdb->fsdb_mdt_index_map)) {
3324 name_create_mdt_and_lov(&logname, &lovname, fsdb, i);
3326 if (canceled_label != NULL) {
3327 strcpy(mti->mti_svname, "lov pool");
3328 mgs_modify(env, mgs, fsdb, mti, logname,
3329 lovname, canceled_label,
3333 mgs_write_log_pool(env, mgs, logname, fsdb, lovname,
3334 cmd, fsname, poolname, ostname,
3336 name_destroy(&logname);
3337 name_destroy(&lovname);
3341 name_create(&logname, fsname, "-client");
3342 if (canceled_label != NULL)
3343 mgs_modify(env, mgs, fsdb, mti, logname, fsdb->fsdb_clilov,
3344 canceled_label, CM_SKIP);
3346 mgs_write_log_pool(env, mgs, logname, fsdb, fsdb->fsdb_clilov,
3347 cmd, fsname, poolname, ostname, label);
3348 name_destroy(&logname);
3350 cfs_mutex_unlock(&fsdb->fsdb_mutex);
3351 /* request for update */
3352 mgs_revoke_lock(mgs, fsdb, CONFIG_T_CONFIG);
3357 OBD_FREE(label, label_sz);
3359 if (canceled_label != NULL)
3360 OBD_FREE(canceled_label, label_sz);
3369 /******************** unused *********************/
3370 static int mgs_backup_llog(struct obd_device *obd, char* fsname)
3372 struct file *filp, *bak_filp;
3373 struct lvfs_run_ctxt saved;
3374 char *logname, *buf;
3375 loff_t soff = 0 , doff = 0;
3376 int count = 4096, len;
3379 OBD_ALLOC(logname, PATH_MAX);
3380 if (logname == NULL)
3383 OBD_ALLOC(buf, count);
3385 GOTO(out , rc = -ENOMEM);
3387 len = snprintf(logname, PATH_MAX, "%s/%s.bak",
3388 MOUNT_CONFIGS_DIR, fsname);
3390 if (len >= PATH_MAX - 1) {
3391 GOTO(out, -ENAMETOOLONG);
3394 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
3396 bak_filp = l_filp_open(logname, O_RDWR|O_CREAT|O_TRUNC, 0660);
3397 if (IS_ERR(bak_filp)) {
3398 rc = PTR_ERR(bak_filp);
3399 CERROR("backup logfile open %s: %d\n", logname, rc);
3402 sprintf(logname, "%s/%s", MOUNT_CONFIGS_DIR, fsname);
3403 filp = l_filp_open(logname, O_RDONLY, 0);
3406 CERROR("logfile open %s: %d\n", logname, rc);
3410 while ((rc = lustre_fread(filp, buf, count, &soff)) > 0) {
3411 rc = lustre_fwrite(bak_filp, buf, count, &doff);
3415 filp_close(filp, 0);
3417 filp_close(bak_filp, 0);
3419 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
3422 OBD_FREE(buf, count);
3423 OBD_FREE(logname, PATH_MAX);