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 rc = name_create(&logname, fsdb->fsdb_name, "-client");
281 cfs_mutex_lock(&fsdb->fsdb_mutex);
282 push_ctxt(&saved, &mgs->mgs_obd->obd_lvfs_ctxt, NULL);
283 rc = llog_open_create(NULL, ctxt, &loghandle, NULL, logname);
287 rc = llog_init_handle(NULL, loghandle, LLOG_F_IS_PLAIN, NULL);
291 if (llog_get_size(loghandle) <= 1)
292 cfs_set_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags);
294 rc = llog_process_or_fork(env, loghandle, mgs_fsdb_handler, (void *)&d,
296 CDEBUG(D_INFO, "get_db = %d\n", rc);
298 rc2 = llog_close(NULL, loghandle);
302 pop_ctxt(&saved, &mgs->mgs_obd->obd_lvfs_ctxt, NULL);
303 cfs_mutex_unlock(&fsdb->fsdb_mutex);
304 name_destroy(&logname);
311 static void mgs_free_fsdb_srpc(struct fs_db *fsdb)
313 struct mgs_tgt_srpc_conf *tgtconf;
315 /* free target-specific rules */
316 while (fsdb->fsdb_srpc_tgt) {
317 tgtconf = fsdb->fsdb_srpc_tgt;
318 fsdb->fsdb_srpc_tgt = tgtconf->mtsc_next;
320 LASSERT(tgtconf->mtsc_tgt);
322 sptlrpc_rule_set_free(&tgtconf->mtsc_rset);
323 OBD_FREE(tgtconf->mtsc_tgt, strlen(tgtconf->mtsc_tgt) + 1);
324 OBD_FREE_PTR(tgtconf);
327 /* free general rules */
328 sptlrpc_rule_set_free(&fsdb->fsdb_srpc_gen);
331 struct fs_db *mgs_find_fsdb(struct mgs_device *mgs, char *fsname)
336 cfs_list_for_each(tmp, &mgs->mgs_fs_db_list) {
337 fsdb = cfs_list_entry(tmp, struct fs_db, fsdb_list);
338 if (strcmp(fsdb->fsdb_name, fsname) == 0)
344 /* caller must hold the mgs->mgs_fs_db_lock */
345 static struct fs_db *mgs_new_fsdb(const struct lu_env *env,
346 struct mgs_device *mgs, char *fsname)
352 if (strlen(fsname) >= sizeof(fsdb->fsdb_name)) {
353 CERROR("fsname %s is too long\n", fsname);
361 strcpy(fsdb->fsdb_name, fsname);
362 cfs_mutex_init(&fsdb->fsdb_mutex);
363 cfs_set_bit(FSDB_UDESC, &fsdb->fsdb_flags);
365 if (strcmp(fsname, MGSSELF_NAME) == 0) {
366 cfs_set_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags);
368 OBD_ALLOC(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
369 OBD_ALLOC(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
370 if (!fsdb->fsdb_ost_index_map || !fsdb->fsdb_mdt_index_map) {
371 CERROR("No memory for index maps\n");
372 GOTO(err, rc = -ENOMEM);
375 rc = name_create(&fsdb->fsdb_mdtlov, fsname, "-mdtlov");
378 rc = name_create(&fsdb->fsdb_mdtlmv, fsname, "-mdtlmv");
381 rc = name_create(&fsdb->fsdb_clilov, fsname, "-clilov");
384 rc = name_create(&fsdb->fsdb_clilmv, fsname, "-clilmv");
388 /* initialise data for NID table */
389 mgs_ir_init_fs(env, mgs, fsdb);
391 lproc_mgs_add_live(mgs, fsdb);
394 cfs_list_add(&fsdb->fsdb_list, &mgs->mgs_fs_db_list);
398 if (fsdb->fsdb_ost_index_map)
399 OBD_FREE(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
400 if (fsdb->fsdb_mdt_index_map)
401 OBD_FREE(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
402 name_destroy(&fsdb->fsdb_clilov);
403 name_destroy(&fsdb->fsdb_clilmv);
404 name_destroy(&fsdb->fsdb_mdtlov);
405 name_destroy(&fsdb->fsdb_mdtlmv);
410 static void mgs_free_fsdb(struct mgs_device *mgs, struct fs_db *fsdb)
412 /* wait for anyone with the sem */
413 cfs_mutex_lock(&fsdb->fsdb_mutex);
414 lproc_mgs_del_live(mgs, fsdb);
415 cfs_list_del(&fsdb->fsdb_list);
417 /* deinitialize fsr */
418 mgs_ir_fini_fs(mgs, fsdb);
420 if (fsdb->fsdb_ost_index_map)
421 OBD_FREE(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
422 if (fsdb->fsdb_mdt_index_map)
423 OBD_FREE(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
424 name_destroy(&fsdb->fsdb_clilov);
425 name_destroy(&fsdb->fsdb_clilmv);
426 name_destroy(&fsdb->fsdb_mdtlov);
427 name_destroy(&fsdb->fsdb_mdtlmv);
428 name_destroy(&fsdb->fsdb_mdc);
429 mgs_free_fsdb_srpc(fsdb);
430 cfs_mutex_unlock(&fsdb->fsdb_mutex);
434 int mgs_init_fsdb_list(struct mgs_device *mgs)
436 CFS_INIT_LIST_HEAD(&mgs->mgs_fs_db_list);
440 int mgs_cleanup_fsdb_list(struct mgs_device *mgs)
443 cfs_list_t *tmp, *tmp2;
444 cfs_mutex_lock(&mgs->mgs_mutex);
445 cfs_list_for_each_safe(tmp, tmp2, &mgs->mgs_fs_db_list) {
446 fsdb = cfs_list_entry(tmp, struct fs_db, fsdb_list);
447 mgs_free_fsdb(mgs, fsdb);
449 cfs_mutex_unlock(&mgs->mgs_mutex);
453 int mgs_find_or_make_fsdb(const struct lu_env *env,
454 struct mgs_device *mgs, char *name,
460 cfs_mutex_lock(&mgs->mgs_mutex);
461 fsdb = mgs_find_fsdb(mgs, name);
463 cfs_mutex_unlock(&mgs->mgs_mutex);
468 CDEBUG(D_MGS, "Creating new db\n");
469 fsdb = mgs_new_fsdb(env, mgs, name);
470 cfs_mutex_unlock(&mgs->mgs_mutex);
474 if (!cfs_test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
475 /* populate the db from the client llog */
476 rc = mgs_get_fsdb_from_llog(env, mgs, fsdb);
478 CERROR("Can't get db from client log %d\n", rc);
479 mgs_free_fsdb(mgs, fsdb);
484 /* populate srpc rules from params llog */
485 rc = mgs_get_fsdb_srpc_from_llog(env, mgs, fsdb);
487 CERROR("Can't get db from params log %d\n", rc);
488 mgs_free_fsdb(mgs, fsdb);
499 -1= empty client log */
500 int mgs_check_index(const struct lu_env *env,
501 struct mgs_device *mgs,
502 struct mgs_target_info *mti)
509 LASSERT(!(mti->mti_flags & LDD_F_NEED_INDEX));
511 rc = mgs_find_or_make_fsdb(env, mgs, mti->mti_fsname, &fsdb);
513 CERROR("Can't get db for %s\n", mti->mti_fsname);
517 if (cfs_test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags))
520 if (mti->mti_flags & LDD_F_SV_TYPE_OST)
521 imap = fsdb->fsdb_ost_index_map;
522 else if (mti->mti_flags & LDD_F_SV_TYPE_MDT)
523 imap = fsdb->fsdb_mdt_index_map;
527 if (cfs_test_bit(mti->mti_stripe_index, imap))
532 static __inline__ int next_index(void *index_map, int map_len)
535 for (i = 0; i < map_len * 8; i++)
536 if (!cfs_test_bit(i, index_map)) {
539 CERROR("max index %d exceeded.\n", i);
544 0 newly marked as in use
546 +EALREADY for update of an old index */
547 static int mgs_set_index(const struct lu_env *env,
548 struct mgs_device *mgs,
549 struct mgs_target_info *mti)
556 rc = mgs_find_or_make_fsdb(env, mgs, mti->mti_fsname, &fsdb);
558 CERROR("Can't get db for %s\n", mti->mti_fsname);
562 if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
563 imap = fsdb->fsdb_ost_index_map;
564 } else if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
565 imap = fsdb->fsdb_mdt_index_map;
566 if (fsdb->fsdb_mdt_count >= MAX_MDT_COUNT) {
567 LCONSOLE_ERROR_MSG(0x13f, "The max mdt count"
568 "is %d\n", (int)MAX_MDT_COUNT);
575 if (mti->mti_flags & LDD_F_NEED_INDEX) {
576 rc = next_index(imap, INDEX_MAP_SIZE);
579 mti->mti_stripe_index = rc;
580 if (mti->mti_flags & LDD_F_SV_TYPE_MDT)
581 fsdb->fsdb_mdt_count ++;
584 if (mti->mti_stripe_index >= INDEX_MAP_SIZE * 8) {
585 LCONSOLE_ERROR_MSG(0x13f, "Server %s requested index %d, "
586 "but the max index is %d.\n",
587 mti->mti_svname, mti->mti_stripe_index,
592 if (cfs_test_bit(mti->mti_stripe_index, imap)) {
593 if ((mti->mti_flags & LDD_F_VIRGIN) &&
594 !(mti->mti_flags & LDD_F_WRITECONF)) {
595 LCONSOLE_ERROR_MSG(0x140, "Server %s requested index "
596 "%d, but that index is already in "
597 "use. Use --writeconf to force\n",
599 mti->mti_stripe_index);
602 CDEBUG(D_MGS, "Server %s updating index %d\n",
603 mti->mti_svname, mti->mti_stripe_index);
608 cfs_set_bit(mti->mti_stripe_index, imap);
609 cfs_clear_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags);
610 server_make_name(mti->mti_flags & ~(LDD_F_VIRGIN | LDD_F_WRITECONF),
611 mti->mti_stripe_index, mti->mti_fsname, mti->mti_svname);
613 CDEBUG(D_MGS, "Set index for %s to %d\n", mti->mti_svname,
614 mti->mti_stripe_index);
619 struct mgs_modify_lookup {
620 struct cfg_marker mml_marker;
624 static int mgs_modify_handler(const struct lu_env *env,
625 struct llog_handle *llh,
626 struct llog_rec_hdr *rec, void *data)
628 struct mgs_modify_lookup *mml = data;
629 struct cfg_marker *marker;
630 struct lustre_cfg *lcfg = (struct lustre_cfg *)(rec + 1);
631 int cfg_len = rec->lrh_len - sizeof(struct llog_rec_hdr) -
632 sizeof(struct llog_rec_tail);
636 if (rec->lrh_type != OBD_CFG_REC) {
637 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
641 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
643 CERROR("Insane cfg\n");
647 /* We only care about markers */
648 if (lcfg->lcfg_command != LCFG_MARKER)
651 marker = lustre_cfg_buf(lcfg, 1);
652 if ((strcmp(mml->mml_marker.cm_comment, marker->cm_comment) == 0) &&
653 (strcmp(mml->mml_marker.cm_tgtname, marker->cm_tgtname) == 0) &&
654 !(marker->cm_flags & CM_SKIP)) {
655 /* Found a non-skipped marker match */
656 CDEBUG(D_MGS, "Changing rec %u marker %d %x->%x: %s %s\n",
657 rec->lrh_index, marker->cm_step,
658 marker->cm_flags, mml->mml_marker.cm_flags,
659 marker->cm_tgtname, marker->cm_comment);
660 /* Overwrite the old marker llog entry */
661 marker->cm_flags &= ~CM_EXCLUDE; /* in case we're unexcluding */
662 marker->cm_flags |= mml->mml_marker.cm_flags;
663 marker->cm_canceltime = mml->mml_marker.cm_canceltime;
664 /* Header and tail are added back to lrh_len in
665 llog_lvfs_write_rec */
666 rec->lrh_len = cfg_len;
667 rc = llog_write_rec(NULL, llh, rec, NULL, 0, (void *)lcfg,
676 /* Modify an existing config log record (for CM_SKIP or CM_EXCLUDE) */
677 static int mgs_modify(const struct lu_env *env, struct mgs_device *mgs,
678 struct fs_db *fsdb, struct mgs_target_info *mti,
679 char *logname, char *devname, char *comment, int flags)
681 struct llog_handle *loghandle;
682 struct lvfs_run_ctxt saved;
683 struct llog_ctxt *ctxt;
684 struct mgs_modify_lookup *mml;
688 CDEBUG(D_MGS, "modify %s/%s/%s fl=%x\n", logname, devname, comment,
691 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
692 LASSERT(ctxt != NULL);
693 push_ctxt(&saved, &mgs->mgs_obd->obd_lvfs_ctxt, NULL);
694 rc = llog_open(NULL, ctxt, &loghandle, NULL, logname,
702 rc = llog_init_handle(NULL, loghandle, LLOG_F_IS_PLAIN, NULL);
706 if (llog_get_size(loghandle) <= 1)
707 GOTO(out_close, rc = 0);
711 GOTO(out_close, rc = -ENOMEM);
712 strcpy(mml->mml_marker.cm_comment, comment);
713 strcpy(mml->mml_marker.cm_tgtname, devname);
714 /* Modify mostly means cancel */
715 mml->mml_marker.cm_flags = flags;
716 mml->mml_marker.cm_canceltime = flags ? cfs_time_current_sec() : 0;
717 mml->mml_modified = 0;
718 rc = llog_process_or_fork(env, loghandle, mgs_modify_handler,
719 (void *)mml, NULL, false);
720 if (!rc && !mml->mml_modified)
725 rc2 = llog_close(NULL, loghandle);
729 pop_ctxt(&saved, &mgs->mgs_obd->obd_lvfs_ctxt, NULL);
731 CERROR("modify %s/%s failed %d\n",
732 mti->mti_svname, comment, rc);
737 /******************** config log recording functions *********************/
739 static int record_lcfg(const struct lu_env *env, struct llog_handle *llh,
740 struct lustre_cfg *lcfg)
742 struct lvfs_run_ctxt saved;
743 struct llog_rec_hdr rec;
745 struct obd_device *obd = llh->lgh_ctxt->loc_obd;
750 LASSERT(llh->lgh_ctxt);
752 buflen = lustre_cfg_len(lcfg->lcfg_bufcount,
754 rec.lrh_len = llog_data_len(buflen);
755 rec.lrh_type = OBD_CFG_REC;
757 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
758 /* idx = -1 means append */
759 rc = llog_write_rec(NULL, llh, &rec, NULL, 0, (void *)lcfg, -1);
760 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
762 CERROR("failed %d\n", rc);
766 static int record_base(const struct lu_env *env, struct llog_handle *llh,
767 char *cfgname, lnet_nid_t nid, int cmd,
768 char *s1, char *s2, char *s3, char *s4)
770 struct mgs_thread_info *mgi = mgs_env_info(env);
771 struct lustre_cfg *lcfg;
774 CDEBUG(D_MGS, "lcfg %s %#x %s %s %s %s\n", cfgname,
775 cmd, s1, s2, s3, s4);
777 lustre_cfg_bufs_reset(&mgi->mgi_bufs, cfgname);
779 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, s1);
781 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 2, s2);
783 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 3, s3);
785 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 4, s4);
787 lcfg = lustre_cfg_new(cmd, &mgi->mgi_bufs);
790 lcfg->lcfg_nid = nid;
792 rc = record_lcfg(env, llh, lcfg);
794 lustre_cfg_free(lcfg);
797 CERROR("error %d: lcfg %s %#x %s %s %s %s\n", rc, cfgname,
798 cmd, s1, s2, s3, s4);
804 static inline int record_add_uuid(const struct lu_env *env,
805 struct llog_handle *llh,
806 uint64_t nid, char *uuid)
808 return record_base(env, llh, NULL, nid, LCFG_ADD_UUID, uuid, 0, 0, 0);
812 static inline int record_add_conn(const struct lu_env *env,
813 struct llog_handle *llh,
814 char *devname, char *uuid)
816 return record_base(env, llh, devname, 0, LCFG_ADD_CONN, uuid, 0, 0, 0);
819 static inline int record_attach(const struct lu_env *env,
820 struct llog_handle *llh, char *devname,
821 char *type, char *uuid)
823 return record_base(env, llh,devname, 0, LCFG_ATTACH, type, uuid, 0, 0);
826 static inline int record_setup(const struct lu_env *env,
827 struct llog_handle *llh, char *devname,
828 char *s1, char *s2, char *s3, char *s4)
830 return record_base(env, llh, devname, 0, LCFG_SETUP, s1, s2, s3, s4);
833 static int record_lov_setup(const struct lu_env *env, struct llog_handle *llh,
834 char *devname, struct lov_desc *desc)
836 struct mgs_thread_info *mgi = mgs_env_info(env);
837 struct lustre_cfg *lcfg;
840 lustre_cfg_bufs_reset(&mgi->mgi_bufs, devname);
841 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, desc, sizeof(*desc));
842 lcfg = lustre_cfg_new(LCFG_SETUP, &mgi->mgi_bufs);
845 rc = record_lcfg(env, llh, lcfg);
847 lustre_cfg_free(lcfg);
851 static int record_lmv_setup(const struct lu_env *env, struct llog_handle *llh,
852 char *devname, struct lmv_desc *desc)
854 struct mgs_thread_info *mgi = mgs_env_info(env);
855 struct lustre_cfg *lcfg;
858 lustre_cfg_bufs_reset(&mgi->mgi_bufs, devname);
859 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, desc, sizeof(*desc));
860 lcfg = lustre_cfg_new(LCFG_SETUP, &mgi->mgi_bufs);
862 rc = record_lcfg(env, llh, lcfg);
864 lustre_cfg_free(lcfg);
868 static inline int record_mdc_add(const struct lu_env *env,
869 struct llog_handle *llh,
870 char *logname, char *mdcuuid,
871 char *mdtuuid, char *index,
874 return record_base(env,llh,logname,0,LCFG_ADD_MDC,
875 mdtuuid,index,gen,mdcuuid);
878 static inline int record_lov_add(const struct lu_env *env,
879 struct llog_handle *llh,
880 char *lov_name, char *ost_uuid,
881 char *index, char *gen)
883 return record_base(env,llh,lov_name,0,LCFG_LOV_ADD_OBD,
884 ost_uuid,index,gen,0);
887 static inline int record_mount_opt(const struct lu_env *env,
888 struct llog_handle *llh,
889 char *profile, char *lov_name,
892 return record_base(env,llh,NULL,0,LCFG_MOUNTOPT,
893 profile,lov_name,mdc_name,0);
896 static int record_marker(const struct lu_env *env,
897 struct llog_handle *llh,
898 struct fs_db *fsdb, __u32 flags,
899 char *tgtname, char *comment)
901 struct mgs_thread_info *mgi = mgs_env_info(env);
902 struct lustre_cfg *lcfg;
905 if (flags & CM_START)
907 mgi->mgi_marker.cm_step = fsdb->fsdb_gen;
908 mgi->mgi_marker.cm_flags = flags;
909 mgi->mgi_marker.cm_vers = LUSTRE_VERSION_CODE;
910 strncpy(mgi->mgi_marker.cm_tgtname, tgtname,
911 sizeof(mgi->mgi_marker.cm_tgtname));
912 strncpy(mgi->mgi_marker.cm_comment, comment,
913 sizeof(mgi->mgi_marker.cm_comment));
914 mgi->mgi_marker.cm_createtime = cfs_time_current_sec();
915 mgi->mgi_marker.cm_canceltime = 0;
916 lustre_cfg_bufs_reset(&mgi->mgi_bufs, NULL);
917 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, &mgi->mgi_marker,
918 sizeof(mgi->mgi_marker));
919 lcfg = lustre_cfg_new(LCFG_MARKER, &mgi->mgi_bufs);
922 rc = record_lcfg(env, llh, lcfg);
924 lustre_cfg_free(lcfg);
928 static int record_start_log(const struct lu_env *env,
929 struct mgs_device *mgs,
930 struct llog_handle **llh, char *name)
932 static struct obd_uuid cfg_uuid = { .uuid = "config_uuid" };
933 struct lvfs_run_ctxt saved;
934 struct llog_ctxt *ctxt;
938 GOTO(out, rc = -EBUSY);
940 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
942 GOTO(out, rc = -ENODEV);
943 LASSERT(ctxt->loc_obd == mgs->mgs_obd);
945 push_ctxt(&saved, &mgs->mgs_obd->obd_lvfs_ctxt, NULL);
946 rc = llog_open_create(NULL, ctxt, llh, NULL, name);
949 rc = llog_init_handle(NULL, *llh, LLOG_F_IS_PLAIN, &cfg_uuid);
951 llog_close(NULL, *llh);
955 pop_ctxt(&saved, &mgs->mgs_obd->obd_lvfs_ctxt, NULL);
959 CERROR("Can't start log %s: %d\n", name, rc);
963 static int record_end_log(const struct lu_env *env, struct llog_handle **llh)
965 struct lvfs_run_ctxt saved;
966 struct obd_device *obd = (*llh)->lgh_ctxt->loc_obd;
969 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
971 rc = llog_close(NULL, *llh);
974 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
978 static int mgs_log_is_empty(const struct lu_env *env,
979 struct mgs_device *mgs, char *name)
981 struct lvfs_run_ctxt saved;
982 struct llog_handle *llh;
983 struct llog_ctxt *ctxt;
986 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
987 LASSERT(ctxt != NULL);
988 push_ctxt(&saved, &mgs->mgs_obd->obd_lvfs_ctxt, NULL);
989 rc = llog_open(NULL, ctxt, &llh, NULL, name, LLOG_OPEN_EXISTS);
996 llog_init_handle(NULL, llh, LLOG_F_IS_PLAIN, NULL);
999 rc = llog_get_size(llh);
1002 llog_close(NULL, llh);
1004 pop_ctxt(&saved, &mgs->mgs_obd->obd_lvfs_ctxt, NULL);
1005 llog_ctxt_put(ctxt);
1006 /* header is record 1 */
1010 /******************** config "macros" *********************/
1012 /* write an lcfg directly into a log (with markers) */
1013 static int mgs_write_log_direct(const struct lu_env *env,
1014 struct mgs_device *mgs, struct fs_db *fsdb,
1015 char *logname, struct lustre_cfg *lcfg,
1016 char *devname, char *comment)
1018 struct llog_handle *llh = NULL;
1025 rc = record_start_log(env, mgs, &llh, logname);
1029 /* FIXME These should be a single journal transaction */
1030 rc = record_marker(env, llh, fsdb, CM_START, devname, comment);
1033 rc = record_lcfg(env, llh, lcfg);
1036 rc = record_marker(env, llh, fsdb, CM_END, devname, comment);
1040 record_end_log(env, &llh);
1044 /* write the lcfg in all logs for the given fs */
1045 int mgs_write_log_direct_all(const struct lu_env *env,
1046 struct mgs_device *mgs,
1048 struct mgs_target_info *mti,
1049 struct lustre_cfg *lcfg,
1050 char *devname, char *comment,
1053 cfs_list_t dentry_list;
1054 struct l_linux_dirent *dirent, *n;
1055 char *fsname = mti->mti_fsname;
1057 int rc = 0, len = strlen(fsname);
1060 /* We need to set params for any future logs
1061 as well. FIXME Append this file to every new log.
1062 Actually, we should store as params (text), not llogs. Or
1064 rc = name_create(&logname, fsname, "-params");
1067 if (mgs_log_is_empty(env, mgs, logname)) {
1068 struct llog_handle *llh = NULL;
1069 rc = record_start_log(env, mgs, &llh, logname);
1070 record_end_log(env, &llh);
1072 name_destroy(&logname);
1076 /* Find all the logs in the CONFIGS directory */
1077 rc = class_dentry_readdir(env, mgs, &dentry_list);
1079 CERROR("Can't read %s dir\n", MOUNT_CONFIGS_DIR);
1083 /* Could use fsdb index maps instead of directory listing */
1084 cfs_list_for_each_entry_safe(dirent, n, &dentry_list, lld_list) {
1085 cfs_list_del(&dirent->lld_list);
1086 /* don't write to sptlrpc rule log */
1087 if (strstr(dirent->lld_name, "-sptlrpc") != NULL)
1090 /* caller wants write server logs only */
1091 if (server_only && strstr(dirent->lld_name, "-client") != NULL)
1094 if (strncmp(fsname, dirent->lld_name, len) == 0) {
1095 CDEBUG(D_MGS, "Changing log %s\n", dirent->lld_name);
1096 /* Erase any old settings of this same parameter */
1097 mgs_modify(env, mgs, fsdb, mti, dirent->lld_name,
1098 devname, comment, CM_SKIP);
1099 /* Write the new one */
1101 rc = mgs_write_log_direct(env, mgs, fsdb,
1106 CERROR("err %d writing log %s\n", rc,
1111 OBD_FREE(dirent, sizeof(*dirent));
1117 static int mgs_write_log_mdc_to_mdt(const struct lu_env *env,
1118 struct mgs_device *mgs,
1120 struct mgs_target_info *mti,
1122 static int mgs_write_log_osc_to_lov(const struct lu_env *env,
1123 struct mgs_device *mgs,
1125 struct mgs_target_info *mti,
1126 char *logname, char *suffix, char *lovname,
1127 enum lustre_sec_part sec_part, int flags);
1128 static int name_create_mdt_and_lov(char **logname, char **lovname,
1129 struct fs_db *fsdb, int i);
1131 static int mgs_steal_llog_handler(const struct lu_env *env,
1132 struct llog_handle *llh,
1133 struct llog_rec_hdr *rec, void *data)
1135 struct mgs_device *mgs;
1136 struct mgs_target_info *mti, *tmti;
1138 int cfg_len = rec->lrh_len;
1139 char *cfg_buf = (char*) (rec + 1);
1140 struct lustre_cfg *lcfg;
1142 struct llog_handle *mdt_llh = NULL;
1143 static int got_an_osc_or_mdc = 0;
1144 /* 0: not found any osc/mdc;
1148 static int last_step = -1;
1152 mti = ((struct temp_comp*)data)->comp_mti;
1153 tmti = ((struct temp_comp*)data)->comp_tmti;
1154 fsdb = ((struct temp_comp*)data)->comp_fsdb;
1155 mgs = ((struct temp_comp*)data)->comp_mgs;
1157 if (rec->lrh_type != OBD_CFG_REC) {
1158 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
1162 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
1164 CERROR("Insane cfg\n");
1168 lcfg = (struct lustre_cfg *)cfg_buf;
1170 if (lcfg->lcfg_command == LCFG_MARKER) {
1171 struct cfg_marker *marker;
1172 marker = lustre_cfg_buf(lcfg, 1);
1173 if (!strncmp(marker->cm_comment,"add osc",7) &&
1174 (marker->cm_flags & CM_START)){
1175 got_an_osc_or_mdc = 1;
1176 strncpy(tmti->mti_svname, marker->cm_tgtname,
1177 sizeof(tmti->mti_svname));
1178 rc = record_start_log(env, mgs, &mdt_llh,
1182 rc = record_marker(env, mdt_llh, fsdb, CM_START,
1183 mti->mti_svname,"add osc(copied)");
1184 record_end_log(env, &mdt_llh);
1185 last_step = marker->cm_step;
1188 if (!strncmp(marker->cm_comment,"add osc",7) &&
1189 (marker->cm_flags & CM_END)){
1190 LASSERT(last_step == marker->cm_step);
1192 got_an_osc_or_mdc = 0;
1193 rc = record_start_log(env, mgs, &mdt_llh,
1197 rc = record_marker(env, mdt_llh, fsdb, CM_END,
1198 mti->mti_svname,"add osc(copied)");
1199 record_end_log(env, &mdt_llh);
1202 if (!strncmp(marker->cm_comment,"add mdc",7) &&
1203 (marker->cm_flags & CM_START)){
1204 got_an_osc_or_mdc = 2;
1205 last_step = marker->cm_step;
1206 memcpy(tmti->mti_svname, marker->cm_tgtname,
1207 strlen(marker->cm_tgtname));
1211 if (!strncmp(marker->cm_comment,"add mdc",7) &&
1212 (marker->cm_flags & CM_END)){
1213 LASSERT(last_step == marker->cm_step);
1215 got_an_osc_or_mdc = 0;
1220 if (got_an_osc_or_mdc == 0 || last_step < 0)
1223 if (lcfg->lcfg_command == LCFG_ADD_UUID) {
1225 nodenid = lcfg->lcfg_nid;
1227 tmti->mti_nids[tmti->mti_nid_count] = nodenid;
1228 tmti->mti_nid_count++;
1233 if (lcfg->lcfg_command == LCFG_SETUP) {
1236 target = lustre_cfg_string(lcfg, 1);
1237 memcpy(tmti->mti_uuid, target, strlen(target));
1241 /* ignore client side sptlrpc_conf_log */
1242 if (lcfg->lcfg_command == LCFG_SPTLRPC_CONF)
1245 if (lcfg->lcfg_command == LCFG_ADD_MDC) {
1248 if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1)
1251 memcpy(tmti->mti_fsname, mti->mti_fsname,
1252 strlen(mti->mti_fsname));
1253 tmti->mti_stripe_index = index;
1255 rc = mgs_write_log_mdc_to_mdt(env, mgs, fsdb, tmti,
1257 memset(tmti, 0, sizeof(*tmti));
1261 if (lcfg->lcfg_command == LCFG_LOV_ADD_OBD) {
1264 char *logname, *lovname;
1266 rc = name_create_mdt_and_lov(&logname, &lovname, fsdb,
1267 mti->mti_stripe_index);
1270 sprintf(mdt_index, "-MDT%04x", mti->mti_stripe_index);
1272 if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1) {
1273 name_destroy(&logname);
1274 name_destroy(&lovname);
1278 tmti->mti_stripe_index = index;
1279 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, tmti, logname,
1282 name_destroy(&logname);
1283 name_destroy(&lovname);
1289 /* fsdb->fsdb_mutex is already held in mgs_write_log_target*/
1290 /* stealed from mgs_get_fsdb_from_llog*/
1291 static int mgs_steal_llog_for_mdt_from_client(const struct lu_env *env,
1292 struct mgs_device *mgs,
1294 struct temp_comp* comp)
1296 struct llog_handle *loghandle;
1297 struct lvfs_run_ctxt saved;
1298 struct mgs_target_info *tmti;
1299 struct llog_ctxt *ctxt;
1304 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
1305 LASSERT(ctxt != NULL);
1307 OBD_ALLOC_PTR(tmti);
1309 GOTO(out_ctxt, rc = -ENOMEM);
1311 comp->comp_tmti = tmti;
1312 comp->comp_mgs = mgs;
1314 push_ctxt(&saved, &mgs->mgs_obd->obd_lvfs_ctxt, NULL);
1316 rc = llog_open(NULL, ctxt, &loghandle, NULL, client_name,
1324 rc = llog_init_handle(NULL, loghandle, LLOG_F_IS_PLAIN, NULL);
1326 GOTO(out_close, rc);
1328 rc = llog_process_or_fork(env, loghandle, mgs_steal_llog_handler,
1329 (void *)comp, NULL, false);
1330 CDEBUG(D_MGS, "steal llog re = %d\n", rc);
1332 llog_close(NULL, loghandle);
1334 pop_ctxt(&saved, &mgs->mgs_obd->obd_lvfs_ctxt, NULL);
1337 llog_ctxt_put(ctxt);
1341 /* lmv is the second thing for client logs */
1342 /* copied from mgs_write_log_lov. Please refer to that. */
1343 static int mgs_write_log_lmv(const struct lu_env *env,
1344 struct mgs_device *mgs,
1346 struct mgs_target_info *mti,
1347 char *logname, char *lmvname)
1349 struct llog_handle *llh = NULL;
1350 struct lmv_desc *lmvdesc;
1355 CDEBUG(D_MGS, "Writing lmv(%s) log for %s\n", lmvname,logname);
1357 OBD_ALLOC_PTR(lmvdesc);
1358 if (lmvdesc == NULL)
1360 lmvdesc->ld_active_tgt_count = 0;
1361 lmvdesc->ld_tgt_count = 0;
1362 sprintf((char*)lmvdesc->ld_uuid.uuid, "%s_UUID", lmvname);
1363 uuid = (char *)lmvdesc->ld_uuid.uuid;
1365 rc = record_start_log(env, mgs, &llh, logname);
1368 rc = record_marker(env, llh, fsdb, CM_START, lmvname, "lmv setup");
1371 rc = record_attach(env, llh, lmvname, "lmv", uuid);
1374 rc = record_lmv_setup(env, llh, lmvname, lmvdesc);
1377 rc = record_marker(env, llh, fsdb, CM_END, lmvname, "lmv setup");
1381 record_end_log(env, &llh);
1383 OBD_FREE_PTR(lmvdesc);
1387 /* lov is the first thing in the mdt and client logs */
1388 static int mgs_write_log_lov(const struct lu_env *env, struct mgs_device *mgs,
1389 struct fs_db *fsdb, struct mgs_target_info *mti,
1390 char *logname, char *lovname)
1392 struct llog_handle *llh = NULL;
1393 struct lov_desc *lovdesc;
1398 CDEBUG(D_MGS, "Writing lov(%s) log for %s\n", lovname, logname);
1401 #01 L attach 0:lov_mdsA 1:lov 2:71ccb_lov_mdsA_19f961a9e1
1402 #02 L lov_setup 0:lov_mdsA 1:(struct lov_desc)
1403 uuid=lov1_UUID, stripe count=1, size=1048576, offset=0, pattern=0
1406 /* FIXME just make lov_setup accept empty desc (put uuid in buf 2) */
1407 OBD_ALLOC_PTR(lovdesc);
1408 if (lovdesc == NULL)
1410 lovdesc->ld_magic = LOV_DESC_MAGIC;
1411 lovdesc->ld_tgt_count = 0;
1412 /* Defaults. Can be changed later by lcfg config_param */
1413 lovdesc->ld_default_stripe_count = 1;
1414 lovdesc->ld_pattern = LOV_PATTERN_RAID0;
1415 lovdesc->ld_default_stripe_size = 1024 * 1024;
1416 lovdesc->ld_default_stripe_offset = -1;
1417 lovdesc->ld_qos_maxage = QOS_DEFAULT_MAXAGE;
1418 sprintf((char*)lovdesc->ld_uuid.uuid, "%s_UUID", lovname);
1419 /* can these be the same? */
1420 uuid = (char *)lovdesc->ld_uuid.uuid;
1422 /* This should always be the first entry in a log.
1423 rc = mgs_clear_log(obd, logname); */
1424 rc = record_start_log(env, mgs, &llh, logname);
1427 /* FIXME these should be a single journal transaction */
1428 rc = record_marker(env, llh, fsdb, CM_START, lovname, "lov setup");
1431 rc = record_attach(env, llh, lovname, "lov", uuid);
1434 rc = record_lov_setup(env, llh, lovname, lovdesc);
1437 rc = record_marker(env, llh, fsdb, CM_END, lovname, "lov setup");
1442 record_end_log(env, &llh);
1444 OBD_FREE_PTR(lovdesc);
1448 /* add failnids to open log */
1449 static int mgs_write_log_failnids(const struct lu_env *env,
1450 struct mgs_target_info *mti,
1451 struct llog_handle *llh,
1454 char *failnodeuuid = NULL;
1455 char *ptr = mti->mti_params;
1460 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) nal=90 0: 1:uml1_UUID
1461 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
1462 #05 L setup 0:OSC_uml1_ost1_mdsA 1:ost1_UUID 2:uml1_UUID
1463 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) nal=90 0: 1:uml2_UUID
1464 #0x L add_uuid nid=2@elan(0x1000000000002) nal=90 0: 1:uml2_UUID
1465 #07 L add_conn 0:OSC_uml1_ost1_mdsA 1:uml2_UUID
1468 /* Pull failnid info out of params string */
1469 while (class_find_param(ptr, PARAM_FAILNODE, &ptr) == 0) {
1470 while (class_parse_nid(ptr, &nid, &ptr) == 0) {
1471 if (failnodeuuid == NULL) {
1472 /* We don't know the failover node name,
1473 so just use the first nid as the uuid */
1474 rc = name_create(&failnodeuuid,
1475 libcfs_nid2str(nid), "");
1479 CDEBUG(D_MGS, "add nid %s for failover uuid %s, "
1480 "client %s\n", libcfs_nid2str(nid),
1481 failnodeuuid, cliname);
1482 rc = record_add_uuid(env, llh, nid, failnodeuuid);
1485 rc = record_add_conn(env, llh, cliname, failnodeuuid);
1488 name_destroy(&failnodeuuid);
1492 static int mgs_write_log_mdc_to_lmv(const struct lu_env *env,
1493 struct mgs_device *mgs,
1495 struct mgs_target_info *mti,
1496 char *logname, char *lmvname)
1498 struct llog_handle *llh = NULL;
1499 char *mdcname = NULL;
1500 char *nodeuuid = NULL;
1501 char *mdcuuid = NULL;
1502 char *lmvuuid = NULL;
1507 if (mgs_log_is_empty(env, mgs, logname)) {
1508 CERROR("log is empty! Logical error\n");
1512 CDEBUG(D_MGS, "adding mdc for %s to log %s:lmv(%s)\n",
1513 mti->mti_svname, logname, lmvname);
1515 rc = name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
1518 rc = name_create(&mdcname, mti->mti_svname, "-mdc");
1521 rc = name_create(&mdcuuid, mdcname, "_UUID");
1524 rc = name_create(&lmvuuid, lmvname, "_UUID");
1528 rc = record_start_log(env, mgs, &llh, logname);
1531 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
1535 for (i = 0; i < mti->mti_nid_count; i++) {
1536 CDEBUG(D_MGS, "add nid %s for mdt\n",
1537 libcfs_nid2str(mti->mti_nids[i]));
1539 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
1544 rc = record_attach(env, llh, mdcname, LUSTRE_MDC_NAME, lmvuuid);
1547 rc = record_setup(env, llh, mdcname, mti->mti_uuid, nodeuuid, 0, 0);
1550 rc = mgs_write_log_failnids(env, mti, llh, mdcname);
1553 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
1554 rc = record_mdc_add(env, llh, lmvname, mdcuuid, mti->mti_uuid,
1558 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname,
1563 record_end_log(env, &llh);
1565 name_destroy(&lmvuuid);
1566 name_destroy(&mdcuuid);
1567 name_destroy(&mdcname);
1568 name_destroy(&nodeuuid);
1572 /* add new mdc to already existent MDS */
1573 static int mgs_write_log_mdc_to_mdt(const struct lu_env *env,
1574 struct mgs_device *mgs,
1576 struct mgs_target_info *mti,
1579 struct llog_handle *llh = NULL;
1580 char *nodeuuid = NULL;
1581 char *mdcname = NULL;
1582 char *mdcuuid = NULL;
1583 char *mdtuuid = NULL;
1584 int idx = mti->mti_stripe_index;
1589 if (mgs_log_is_empty(env, mgs, logname)) {
1590 CERROR("log is empty! Logical error\n");
1594 CDEBUG(D_MGS, "adding mdc index %d to %s\n", idx, logname);
1596 rc = name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
1599 snprintf(index, sizeof(index), "-mdc%04x", idx);
1600 rc = name_create(&mdcname, logname, index);
1603 rc = name_create(&mdcuuid, mdcname, "_UUID");
1606 rc = name_create(&mdtuuid, logname, "_UUID");
1610 rc = record_start_log(env, mgs, &llh, logname);
1613 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname, "add mdc");
1616 for (i = 0; i < mti->mti_nid_count; i++) {
1617 CDEBUG(D_MGS, "add nid %s for mdt\n",
1618 libcfs_nid2str(mti->mti_nids[i]));
1619 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
1623 rc = record_attach(env, llh, mdcname, LUSTRE_MDC_NAME, mdcuuid);
1626 rc = record_setup(env, llh, mdcname, mti->mti_uuid, nodeuuid, 0, 0);
1629 rc = mgs_write_log_failnids(env, mti, llh, mdcname);
1632 snprintf(index, sizeof(index), "%d", idx);
1634 rc = record_mdc_add(env, llh, logname, mdcuuid, mti->mti_uuid,
1638 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname, "add mdc");
1642 record_end_log(env, &llh);
1644 name_destroy(&mdtuuid);
1645 name_destroy(&mdcuuid);
1646 name_destroy(&mdcname);
1647 name_destroy(&nodeuuid);
1651 static int mgs_write_log_mdt0(const struct lu_env *env,
1652 struct mgs_device *mgs,
1654 struct mgs_target_info *mti)
1656 char *log = mti->mti_svname;
1657 struct llog_handle *llh = NULL;
1658 char *uuid, *lovname;
1660 char *ptr = mti->mti_params;
1661 int rc = 0, failout = 0;
1664 OBD_ALLOC(uuid, sizeof(struct obd_uuid));
1668 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
1669 failout = (strncmp(ptr, "failout", 7) == 0);
1671 rc = name_create(&lovname, log, "-mdtlov");
1674 if (mgs_log_is_empty(env, mgs, log)) {
1675 rc = mgs_write_log_lov(env, mgs, fsdb, mti, log, lovname);
1680 sprintf(mdt_index, "%d", mti->mti_stripe_index);
1682 rc = record_start_log(env, mgs, &llh, log);
1686 /* add MDT itself */
1688 /* FIXME this whole fn should be a single journal transaction */
1689 sprintf(uuid, "%s_UUID", log);
1690 rc = record_marker(env, llh, fsdb, CM_START, log, "add mdt");
1693 rc = record_attach(env, llh, log, LUSTRE_MDT_NAME, uuid);
1696 rc = record_mount_opt(env, llh, log, lovname, NULL);
1699 rc = record_setup(env, llh, log, uuid, mdt_index, lovname,
1700 failout ? "n" : "f");
1703 rc = record_marker(env, llh, fsdb, CM_END, log, "add mdt");
1707 record_end_log(env, &llh);
1709 name_destroy(&lovname);
1711 OBD_FREE(uuid, sizeof(struct obd_uuid));
1715 static inline int name_create_mdt(char **logname, char *fsname, int i)
1719 sprintf(mdt_index, "-MDT%04x", i);
1720 return name_create(logname, fsname, mdt_index);
1723 static int name_create_mdt_and_lov(char **logname, char **lovname,
1724 struct fs_db *fsdb, int i)
1728 rc = name_create_mdt(logname, fsdb->fsdb_name, i);
1732 if (i == 0 && cfs_test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
1733 rc = name_create(lovname, fsdb->fsdb_name, "-mdtlov");
1735 rc = name_create(lovname, *logname, "-mdtlov");
1737 name_destroy(logname);
1743 static inline int name_create_mdt_osc(char **oscname, char *ostname,
1744 struct fs_db *fsdb, int i)
1748 if (i == 0 && cfs_test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
1749 sprintf(suffix, "-osc");
1751 sprintf(suffix, "-osc-MDT%04x", i);
1752 return name_create(oscname, ostname, suffix);
1755 /* envelope method for all layers log */
1756 static int mgs_write_log_mdt(const struct lu_env *env,
1757 struct mgs_device *mgs,
1759 struct mgs_target_info *mti)
1761 struct mgs_thread_info *mgi = mgs_env_info(env);
1762 struct llog_handle *llh = NULL;
1767 CDEBUG(D_MGS, "writing new mdt %s\n", mti->mti_svname);
1771 if (mti->mti_flags & LDD_F_UPGRADE14) {
1772 /* We're starting with an old uuid. Assume old name for lov
1773 as well since the lov entry already exists in the log. */
1774 CDEBUG(D_MGS, "old mds uuid %s\n", mti->mti_uuid);
1775 if (strncmp(mti->mti_uuid, fsdb->fsdb_mdtlov + 4,
1776 strlen(fsdb->fsdb_mdtlov) - 4) != 0) {
1777 CERROR("old mds uuid %s doesn't match log %s (%s)\n",
1778 mti->mti_uuid, fsdb->fsdb_mdtlov,
1779 fsdb->fsdb_mdtlov + 4);
1783 /* end COMPAT_146 */
1785 if (mti->mti_uuid[0] == '\0') {
1786 /* Make up our own uuid */
1787 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
1788 "%s_UUID", mti->mti_svname);
1792 rc = mgs_write_log_mdt0(env, mgs, fsdb, mti);
1795 /* Append the mdt info to the client log */
1796 rc = name_create(&cliname, mti->mti_fsname, "-client");
1800 if (mgs_log_is_empty(env, mgs, cliname)) {
1801 /* Start client log */
1802 rc = mgs_write_log_lov(env, mgs, fsdb, mti, cliname,
1806 rc = mgs_write_log_lmv(env, mgs, fsdb, mti, cliname,
1813 #09 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
1814 #10 L attach 0:MDC_uml1_mdsA_MNT_client 1:mdc 2:1d834_MNT_client_03f
1815 #11 L setup 0:MDC_uml1_mdsA_MNT_client 1:mdsA_UUID 2:uml1_UUID
1816 #12 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
1817 #13 L add_conn 0:MDC_uml1_mdsA_MNT_client 1:uml2_UUID
1818 #14 L mount_option 0: 1:client 2:lov1 3:MDC_uml1_mdsA_MNT_client
1823 if (mti->mti_flags & LDD_F_UPGRADE14) {
1824 rc = record_start_log(obd, &llh, cliname);
1828 rc = record_marker(obd, llh, fsdb, CM_START,
1829 mti->mti_svname,"add mdc");
1831 /* Old client log already has MDC entry, but needs mount opt
1832 for new client name (lustre-client) */
1833 /* FIXME Old MDT log already has an old mount opt
1834 which we should remove (currently handled by
1835 class_del_profiles()) */
1836 rc = record_mount_opt(obd, llh, cliname, fsdb->fsdb_clilov,
1838 /* end COMPAT_146 */
1840 rc = record_marker(obd, llh, fsdb, CM_END,
1841 mti->mti_svname, "add mdc");
1845 /* copy client info about lov/lmv */
1846 mgi->mgi_comp.comp_mti = mti;
1847 mgi->mgi_comp.comp_fsdb = fsdb;
1849 rc = mgs_steal_llog_for_mdt_from_client(env, mgs, cliname,
1853 rc = mgs_write_log_mdc_to_lmv(env, mgs, fsdb, mti, cliname,
1859 rc = record_start_log(env, mgs, &llh, cliname);
1863 rc = record_marker(env, llh, fsdb, CM_START, cliname,
1867 rc = record_mount_opt(env, llh, cliname, fsdb->fsdb_clilov,
1871 rc = record_marker(env, llh, fsdb, CM_END, cliname,
1877 /* for_all_existing_mdt except current one */
1878 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
1880 if (i != mti->mti_stripe_index &&
1881 cfs_test_bit(i, fsdb->fsdb_mdt_index_map)) {
1882 rc = name_create_mdt(&mdtname, mti->mti_fsname, i);
1885 rc = mgs_write_log_mdc_to_mdt(env, mgs, fsdb, mti, mdtname);
1886 name_destroy(&mdtname);
1892 record_end_log(env, &llh);
1894 name_destroy(&cliname);
1898 /* Add the ost info to the client/mdt lov */
1899 static int mgs_write_log_osc_to_lov(const struct lu_env *env,
1900 struct mgs_device *mgs, struct fs_db *fsdb,
1901 struct mgs_target_info *mti,
1902 char *logname, char *suffix, char *lovname,
1903 enum lustre_sec_part sec_part, int flags)
1905 struct llog_handle *llh = NULL;
1906 char *nodeuuid = NULL;
1907 char *oscname = NULL;
1908 char *oscuuid = NULL;
1909 char *lovuuid = NULL;
1910 char *svname = NULL;
1915 CDEBUG(D_INFO, "adding osc for %s to log %s\n",
1916 mti->mti_svname, logname);
1918 if (mgs_log_is_empty(env, mgs, logname)) {
1919 CERROR("log is empty! Logical error\n");
1923 rc = name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
1926 rc = name_create(&svname, mti->mti_svname, "-osc");
1929 rc = name_create(&oscname, svname, suffix);
1932 rc = name_create(&oscuuid, oscname, "_UUID");
1935 rc = name_create(&lovuuid, lovname, "_UUID");
1940 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
1942 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
1943 #04 L attach 0:OSC_uml1_ost1_MNT_client 1:osc 2:89070_lov1_a41dff51a
1944 #05 L setup 0:OSC_uml1_ost1_MNT_client 1:ost1_UUID 2:uml1_UUID
1946 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
1947 #07 L add_conn 0:OSC_uml1_ost1_MNT_client 1:uml2_UUID
1948 #08 L lov_modify_tgts add 0:lov1 1:ost1_UUID 2(index):0 3(gen):1
1951 rc = record_start_log(env, mgs, &llh, logname);
1954 /* FIXME these should be a single journal transaction */
1955 rc = record_marker(env, llh, fsdb, CM_START | flags, mti->mti_svname,
1959 for (i = 0; i < mti->mti_nid_count; i++) {
1960 CDEBUG(D_MGS, "add nid %s\n", libcfs_nid2str(mti->mti_nids[i]));
1961 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
1965 rc = record_attach(env, llh, oscname, LUSTRE_OSC_NAME, lovuuid);
1968 rc = record_setup(env, llh, oscname, mti->mti_uuid, nodeuuid, 0, 0);
1971 rc = mgs_write_log_failnids(env, mti, llh, oscname);
1974 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
1975 rc = record_lov_add(env, llh, lovname, mti->mti_uuid, index, "1");
1978 rc = record_marker(env, llh, fsdb, CM_END | flags, mti->mti_svname,
1983 record_end_log(env, &llh);
1985 name_destroy(&lovuuid);
1986 name_destroy(&oscuuid);
1987 name_destroy(&oscname);
1988 name_destroy(&svname);
1989 name_destroy(&nodeuuid);
1993 static int mgs_write_log_ost(const struct lu_env *env,
1994 struct mgs_device *mgs, struct fs_db *fsdb,
1995 struct mgs_target_info *mti)
1997 struct llog_handle *llh = NULL;
1998 char *logname, *lovname;
1999 char *ptr = mti->mti_params;
2000 int rc, flags = 0, failout = 0, i;
2003 CDEBUG(D_MGS, "writing new ost %s\n", mti->mti_svname);
2005 /* The ost startup log */
2007 /* If the ost log already exists, that means that someone reformatted
2008 the ost and it called target_add again. */
2009 if (!mgs_log_is_empty(env, mgs, mti->mti_svname)) {
2010 LCONSOLE_ERROR_MSG(0x141, "The config log for %s already "
2011 "exists, yet the server claims it never "
2012 "registered. It may have been reformatted, "
2013 "or the index changed. writeconf the MDT to "
2014 "regenerate all logs.\n", mti->mti_svname);
2019 attach obdfilter ost1 ost1_UUID
2020 setup /dev/loop2 ldiskfs f|n errors=remount-ro,user_xattr
2022 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
2023 failout = (strncmp(ptr, "failout", 7) == 0);
2024 rc = record_start_log(env, mgs, &llh, mti->mti_svname);
2027 /* FIXME these should be a single journal transaction */
2028 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,"add ost");
2031 if (*mti->mti_uuid == '\0')
2032 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
2033 "%s_UUID", mti->mti_svname);
2034 rc = record_attach(env, llh, mti->mti_svname,
2035 "obdfilter"/*LUSTRE_OST_NAME*/, mti->mti_uuid);
2038 rc = record_setup(env, llh, mti->mti_svname,
2039 "dev"/*ignored*/, "type"/*ignored*/,
2040 failout ? "n" : "f", 0/*options*/);
2043 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname, "add ost");
2047 record_end_log(env, &llh);
2050 /* We also have to update the other logs where this osc is part of
2053 if (cfs_test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
2054 /* If we're upgrading, the old mdt log already has our
2055 entry. Let's do a fake one for fun. */
2056 /* Note that we can't add any new failnids, since we don't
2057 know the old osc names. */
2058 flags = CM_SKIP | CM_UPGRADE146;
2060 } else if ((mti->mti_flags & LDD_F_UPDATE) != LDD_F_UPDATE) {
2061 /* If the update flag isn't set, don't update client/mdt
2064 LCONSOLE_WARN("Client log for %s was not updated; writeconf "
2065 "the MDT first to regenerate it.\n",
2069 /* Add ost to all MDT lov defs */
2070 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
2071 if (cfs_test_bit(i, fsdb->fsdb_mdt_index_map)) {
2074 rc = name_create_mdt_and_lov(&logname, &lovname, fsdb,
2078 sprintf(mdt_index, "-MDT%04x", i);
2079 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, mti,
2081 lovname, LUSTRE_SP_MDT,
2083 name_destroy(&logname);
2084 name_destroy(&lovname);
2090 /* Append ost info to the client log */
2091 rc = name_create(&logname, mti->mti_fsname, "-client");
2094 if (mgs_log_is_empty(env, mgs, logname)) {
2095 /* Start client log */
2096 rc = mgs_write_log_lov(env, mgs, fsdb, mti, logname,
2100 rc = mgs_write_log_lmv(env, mgs, fsdb, mti, logname,
2105 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, mti, logname, "",
2106 fsdb->fsdb_clilov, LUSTRE_SP_CLI, 0);
2108 name_destroy(&logname);
2112 static __inline__ int mgs_param_empty(char *ptr)
2116 if ((tmp = strchr(ptr, '=')) && (*(++tmp) == '\0'))
2121 static int mgs_write_log_failnid_internal(const struct lu_env *env,
2122 struct mgs_device *mgs,
2124 struct mgs_target_info *mti,
2125 char *logname, char *cliname)
2128 struct llog_handle *llh = NULL;
2130 if (mgs_param_empty(mti->mti_params)) {
2131 /* Remove _all_ failnids */
2132 rc = mgs_modify(env, mgs, fsdb, mti, logname,
2133 mti->mti_svname, "add failnid", CM_SKIP);
2134 return rc < 0 ? rc : 0;
2137 /* Otherwise failover nids are additive */
2138 rc = record_start_log(env, mgs, &llh, logname);
2141 /* FIXME this should be a single journal transaction */
2142 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
2146 rc = mgs_write_log_failnids(env, mti, llh, cliname);
2149 rc = record_marker(env, llh, fsdb, CM_END,
2150 mti->mti_svname, "add failnid");
2152 record_end_log(env, &llh);
2157 /* Add additional failnids to an existing log.
2158 The mdc/osc must have been added to logs first */
2159 /* tcp nids must be in dotted-quad ascii -
2160 we can't resolve hostnames from the kernel. */
2161 static int mgs_write_log_add_failnid(const struct lu_env *env,
2162 struct mgs_device *mgs,
2164 struct mgs_target_info *mti)
2166 char *logname, *cliname;
2170 /* FIXME we currently can't erase the failnids
2171 * given when a target first registers, since they aren't part of
2172 * an "add uuid" stanza */
2174 /* Verify that we know about this target */
2175 if (mgs_log_is_empty(env, mgs, mti->mti_svname)) {
2176 LCONSOLE_ERROR_MSG(0x142, "The target %s has not registered "
2177 "yet. It must be started before failnids "
2178 "can be added.\n", mti->mti_svname);
2182 /* Create mdc/osc client name (e.g. lustre-OST0001-osc) */
2183 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
2184 rc = name_create(&cliname, mti->mti_svname, "-mdc");
2185 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2186 rc = name_create(&cliname, mti->mti_svname, "-osc");
2192 /* Add failover nids to the client log */
2193 rc = name_create(&logname, mti->mti_fsname, "-client");
2195 name_destroy(&cliname);
2198 rc = mgs_write_log_failnid_internal(env, mgs, fsdb,mti,logname,cliname);
2199 name_destroy(&logname);
2200 name_destroy(&cliname);
2204 if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2205 /* Add OST failover nids to the MDT logs as well */
2208 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2209 if (!cfs_test_bit(i, fsdb->fsdb_mdt_index_map))
2211 rc = name_create_mdt(&logname, mti->mti_fsname, i);
2214 rc = name_create_mdt_osc(&cliname, mti->mti_svname,
2217 name_destroy(&logname);
2220 rc = mgs_write_log_failnid_internal(env, mgs, fsdb,
2223 name_destroy(&cliname);
2224 name_destroy(&logname);
2233 static int mgs_wlp_lcfg(const struct lu_env *env,
2234 struct mgs_device *mgs, struct fs_db *fsdb,
2235 struct mgs_target_info *mti,
2236 char *logname, struct lustre_cfg_bufs *bufs,
2237 char *tgtname, char *ptr)
2239 char comment[MTI_NAME_MAXLEN];
2241 struct lustre_cfg *lcfg;
2244 /* Erase any old settings of this same parameter */
2245 memcpy(comment, ptr, MTI_NAME_MAXLEN);
2246 comment[MTI_NAME_MAXLEN - 1] = 0;
2247 /* But don't try to match the value. */
2248 if ((tmp = strchr(comment, '=')))
2250 /* FIXME we should skip settings that are the same as old values */
2251 rc = mgs_modify(env, mgs, fsdb, mti, logname, tgtname, comment,CM_SKIP);
2254 del = mgs_param_empty(ptr);
2256 LCONSOLE_INFO("%sing parameter %s.%s in log %s\n", del ? "Disabl" : rc ?
2257 "Sett" : "Modify", tgtname, comment, logname);
2261 lustre_cfg_bufs_reset(bufs, tgtname);
2262 lustre_cfg_bufs_set_string(bufs, 1, ptr);
2263 lcfg = lustre_cfg_new(LCFG_PARAM, bufs);
2266 rc = mgs_write_log_direct(env, mgs, fsdb, logname,lcfg,tgtname,comment);
2267 lustre_cfg_free(lcfg);
2271 /* write global variable settings into log */
2272 static int mgs_write_log_sys(const struct lu_env *env,
2273 struct mgs_device *mgs, struct fs_db *fsdb,
2274 struct mgs_target_info *mti, char *sys, char *ptr)
2276 struct mgs_thread_info *mgi = mgs_env_info(env);
2277 struct lustre_cfg *lcfg;
2279 int rc, cmd, convert = 1;
2281 if (class_match_param(ptr, PARAM_TIMEOUT, &tmp) == 0) {
2282 cmd = LCFG_SET_TIMEOUT;
2283 } else if (class_match_param(ptr, PARAM_LDLM_TIMEOUT, &tmp) == 0) {
2284 cmd = LCFG_SET_LDLM_TIMEOUT;
2285 /* Check for known params here so we can return error to lctl */
2286 } else if ((class_match_param(ptr, PARAM_AT_MIN, &tmp) == 0) ||
2287 (class_match_param(ptr, PARAM_AT_MAX, &tmp) == 0) ||
2288 (class_match_param(ptr, PARAM_AT_EXTRA, &tmp) == 0) ||
2289 (class_match_param(ptr, PARAM_AT_EARLY_MARGIN, &tmp) == 0) ||
2290 (class_match_param(ptr, PARAM_AT_HISTORY, &tmp) == 0)) {
2292 } else if (class_match_param(ptr, PARAM_JOBID_VAR, &tmp) == 0) {
2293 convert = 0; /* Don't convert string value to integer */
2299 if (mgs_param_empty(ptr))
2300 CDEBUG(D_MGS, "global '%s' removed\n", sys);
2302 CDEBUG(D_MGS, "global '%s' val=%s\n", sys, tmp);
2304 lustre_cfg_bufs_reset(&mgi->mgi_bufs, NULL);
2305 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, sys);
2306 if (!convert && *tmp != '\0')
2307 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 2, tmp);
2308 lcfg = lustre_cfg_new(cmd, &mgi->mgi_bufs);
2309 lcfg->lcfg_num = convert ? simple_strtoul(tmp, NULL, 0) : 0;
2310 /* truncate the comment to the parameter name */
2314 /* modify all servers and clients */
2315 rc = mgs_write_log_direct_all(env, mgs, fsdb, mti,
2316 *tmp == '\0' ? NULL : lcfg,
2317 mti->mti_fsname, sys, 0);
2318 if (rc == 0 && *tmp != '\0') {
2320 case LCFG_SET_TIMEOUT:
2321 if (!obd_timeout_set || lcfg->lcfg_num > obd_timeout)
2322 class_process_config(lcfg);
2324 case LCFG_SET_LDLM_TIMEOUT:
2325 if (!ldlm_timeout_set || lcfg->lcfg_num > ldlm_timeout)
2326 class_process_config(lcfg);
2333 lustre_cfg_free(lcfg);
2337 /* write quota settings into log */
2338 static int mgs_write_log_quota(const struct lu_env *env, struct mgs_device *mgs,
2339 struct fs_db *fsdb, struct mgs_target_info *mti,
2340 char *quota, char *ptr)
2342 struct lustre_cfg_bufs bufs;
2343 struct lustre_cfg *lcfg;
2346 int cmd = LCFG_PARAM;
2349 /* support only 'meta' and 'data' pools so far */
2350 if (class_match_param(ptr, QUOTA_METAPOOL_NAME, &tmp) != 0 &&
2351 class_match_param(ptr, QUOTA_DATAPOOL_NAME, &tmp) != 0) {
2352 CERROR("parameter quota.%s isn't supported (only quota.mdt "
2353 "& quota.ost are)\n", ptr);
2358 CDEBUG(D_MGS, "global '%s' removed\n", quota);
2360 CDEBUG(D_MGS, "global '%s'\n", quota);
2362 if (strchr(tmp, 'u') == NULL && strchr(tmp, 'g') == NULL &&
2363 strcmp(tmp, "none") != 0) {
2364 CERROR("enable option(%s) isn't supported\n", tmp);
2369 lustre_cfg_bufs_reset(&bufs, NULL);
2370 lustre_cfg_bufs_set_string(&bufs, 1, quota);
2371 lcfg = lustre_cfg_new(cmd, &bufs);
2372 /* truncate the comment to the parameter name */
2377 /* XXX we duplicated quota enable information in all server
2378 * config logs, it should be moved to a separate config
2379 * log once we cleanup the config log for global param. */
2380 /* modify all servers */
2381 rc = mgs_write_log_direct_all(env, mgs, fsdb, mti,
2382 *tmp == '\0' ? NULL : lcfg,
2383 mti->mti_fsname, quota, 1);
2385 lustre_cfg_free(lcfg);
2389 static int mgs_srpc_set_param_disk(const struct lu_env *env,
2390 struct mgs_device *mgs,
2392 struct mgs_target_info *mti,
2395 struct mgs_thread_info *mgi = mgs_env_info(env);
2396 struct llog_handle *llh = NULL;
2398 char *comment, *ptr;
2399 struct lustre_cfg *lcfg;
2404 ptr = strchr(param, '=');
2408 OBD_ALLOC(comment, len + 1);
2409 if (comment == NULL)
2411 strncpy(comment, param, len);
2412 comment[len] = '\0';
2415 lustre_cfg_bufs_reset(&mgi->mgi_bufs, mti->mti_svname);
2416 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, param);
2417 lcfg = lustre_cfg_new(LCFG_SPTLRPC_CONF, &mgi->mgi_bufs);
2419 GOTO(out_comment, rc = -ENOMEM);
2421 /* construct log name */
2422 rc = name_create(&logname, mti->mti_fsname, "-sptlrpc");
2426 if (mgs_log_is_empty(env, mgs, logname)) {
2427 rc = record_start_log(env, mgs, &llh, logname);
2430 record_end_log(env, &llh);
2433 /* obsolete old one */
2434 rc = mgs_modify(env, mgs, fsdb, mti, logname, mti->mti_svname,
2438 /* write the new one */
2439 rc = mgs_write_log_direct(env, mgs, fsdb, logname, lcfg,
2440 mti->mti_svname, comment);
2442 CERROR("err %d writing log %s\n", rc, logname);
2444 name_destroy(&logname);
2446 lustre_cfg_free(lcfg);
2448 OBD_FREE(comment, len + 1);
2452 static int mgs_srpc_set_param_udesc_mem(struct fs_db *fsdb,
2457 /* disable the adjustable udesc parameter for now, i.e. use default
2458 * setting that client always ship udesc to MDT if possible. to enable
2459 * it simply remove the following line */
2462 ptr = strchr(param, '=');
2467 if (strcmp(param, PARAM_SRPC_UDESC))
2470 if (strcmp(ptr, "yes") == 0) {
2471 cfs_set_bit(FSDB_UDESC, &fsdb->fsdb_flags);
2472 CWARN("Enable user descriptor shipping from client to MDT\n");
2473 } else if (strcmp(ptr, "no") == 0) {
2474 cfs_clear_bit(FSDB_UDESC, &fsdb->fsdb_flags);
2475 CWARN("Disable user descriptor shipping from client to MDT\n");
2483 CERROR("Invalid param: %s\n", param);
2487 static int mgs_srpc_set_param_mem(struct fs_db *fsdb,
2491 struct sptlrpc_rule rule;
2492 struct sptlrpc_rule_set *rset;
2496 if (strncmp(param, PARAM_SRPC, sizeof(PARAM_SRPC) - 1) != 0) {
2497 CERROR("Invalid sptlrpc parameter: %s\n", param);
2501 if (strncmp(param, PARAM_SRPC_UDESC,
2502 sizeof(PARAM_SRPC_UDESC) - 1) == 0) {
2503 RETURN(mgs_srpc_set_param_udesc_mem(fsdb, param));
2506 if (strncmp(param, PARAM_SRPC_FLVR, sizeof(PARAM_SRPC_FLVR) - 1) != 0) {
2507 CERROR("Invalid sptlrpc flavor parameter: %s\n", param);
2511 param += sizeof(PARAM_SRPC_FLVR) - 1;
2513 rc = sptlrpc_parse_rule(param, &rule);
2517 /* mgs rules implies must be mgc->mgs */
2518 if (cfs_test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
2519 if ((rule.sr_from != LUSTRE_SP_MGC &&
2520 rule.sr_from != LUSTRE_SP_ANY) ||
2521 (rule.sr_to != LUSTRE_SP_MGS &&
2522 rule.sr_to != LUSTRE_SP_ANY))
2526 /* preapre room for this coming rule. svcname format should be:
2527 * - fsname: general rule
2528 * - fsname-tgtname: target-specific rule
2530 if (strchr(svname, '-')) {
2531 struct mgs_tgt_srpc_conf *tgtconf;
2534 for (tgtconf = fsdb->fsdb_srpc_tgt; tgtconf != NULL;
2535 tgtconf = tgtconf->mtsc_next) {
2536 if (!strcmp(tgtconf->mtsc_tgt, svname)) {
2545 OBD_ALLOC_PTR(tgtconf);
2546 if (tgtconf == NULL)
2549 name_len = strlen(svname);
2551 OBD_ALLOC(tgtconf->mtsc_tgt, name_len + 1);
2552 if (tgtconf->mtsc_tgt == NULL) {
2553 OBD_FREE_PTR(tgtconf);
2556 memcpy(tgtconf->mtsc_tgt, svname, name_len);
2558 tgtconf->mtsc_next = fsdb->fsdb_srpc_tgt;
2559 fsdb->fsdb_srpc_tgt = tgtconf;
2562 rset = &tgtconf->mtsc_rset;
2564 rset = &fsdb->fsdb_srpc_gen;
2567 rc = sptlrpc_rule_set_merge(rset, &rule);
2572 static int mgs_srpc_set_param(const struct lu_env *env,
2573 struct mgs_device *mgs,
2575 struct mgs_target_info *mti,
2585 /* keep a copy of original param, which could be destroied
2587 copy_size = strlen(param) + 1;
2588 OBD_ALLOC(copy, copy_size);
2591 memcpy(copy, param, copy_size);
2593 rc = mgs_srpc_set_param_mem(fsdb, mti->mti_svname, param);
2597 /* previous steps guaranteed the syntax is correct */
2598 rc = mgs_srpc_set_param_disk(env, mgs, fsdb, mti, copy);
2602 if (cfs_test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
2604 * for mgs rules, make them effective immediately.
2606 LASSERT(fsdb->fsdb_srpc_tgt == NULL);
2607 sptlrpc_target_update_exp_flavor(mgs->mgs_obd,
2608 &fsdb->fsdb_srpc_gen);
2612 OBD_FREE(copy, copy_size);
2616 struct mgs_srpc_read_data {
2617 struct fs_db *msrd_fsdb;
2621 static int mgs_srpc_read_handler(const struct lu_env *env,
2622 struct llog_handle *llh,
2623 struct llog_rec_hdr *rec, void *data)
2625 struct mgs_srpc_read_data *msrd = data;
2626 struct cfg_marker *marker;
2627 struct lustre_cfg *lcfg = (struct lustre_cfg *)(rec + 1);
2628 char *svname, *param;
2632 if (rec->lrh_type != OBD_CFG_REC) {
2633 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
2637 cfg_len = rec->lrh_len - sizeof(struct llog_rec_hdr) -
2638 sizeof(struct llog_rec_tail);
2640 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
2642 CERROR("Insane cfg\n");
2646 if (lcfg->lcfg_command == LCFG_MARKER) {
2647 marker = lustre_cfg_buf(lcfg, 1);
2649 if (marker->cm_flags & CM_START &&
2650 marker->cm_flags & CM_SKIP)
2651 msrd->msrd_skip = 1;
2652 if (marker->cm_flags & CM_END)
2653 msrd->msrd_skip = 0;
2658 if (msrd->msrd_skip)
2661 if (lcfg->lcfg_command != LCFG_SPTLRPC_CONF) {
2662 CERROR("invalid command (%x)\n", lcfg->lcfg_command);
2666 svname = lustre_cfg_string(lcfg, 0);
2667 if (svname == NULL) {
2668 CERROR("svname is empty\n");
2672 param = lustre_cfg_string(lcfg, 1);
2673 if (param == NULL) {
2674 CERROR("param is empty\n");
2678 rc = mgs_srpc_set_param_mem(msrd->msrd_fsdb, svname, param);
2680 CERROR("read sptlrpc record error (%d): %s\n", rc, param);
2685 int mgs_get_fsdb_srpc_from_llog(const struct lu_env *env,
2686 struct mgs_device *mgs,
2689 struct llog_handle *llh = NULL;
2690 struct lvfs_run_ctxt saved;
2691 struct llog_ctxt *ctxt;
2693 struct mgs_srpc_read_data msrd;
2697 /* construct log name */
2698 rc = name_create(&logname, fsdb->fsdb_name, "-sptlrpc");
2702 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
2703 LASSERT(ctxt != NULL);
2705 if (mgs_log_is_empty(env, mgs, logname))
2708 push_ctxt(&saved, &mgs->mgs_obd->obd_lvfs_ctxt, NULL);
2710 rc = llog_open(NULL, ctxt, &llh, NULL, logname,
2718 rc = llog_init_handle(NULL, llh, LLOG_F_IS_PLAIN, NULL);
2720 GOTO(out_close, rc);
2722 if (llog_get_size(llh) <= 1)
2723 GOTO(out_close, rc = 0);
2725 msrd.msrd_fsdb = fsdb;
2728 rc = llog_process_or_fork(env, llh, mgs_srpc_read_handler,
2729 (void *)&msrd, NULL, false);
2732 llog_close(NULL, llh);
2734 pop_ctxt(&saved, &mgs->mgs_obd->obd_lvfs_ctxt, NULL);
2736 llog_ctxt_put(ctxt);
2737 name_destroy(&logname);
2740 CERROR("failed to read sptlrpc config database: %d\n", rc);
2744 /* Permanent settings of all parameters by writing into the appropriate
2745 * configuration logs.
2746 * A parameter with null value ("<param>='\0'") means to erase it out of
2749 static int mgs_write_log_param(const struct lu_env *env,
2750 struct mgs_device *mgs, struct fs_db *fsdb,
2751 struct mgs_target_info *mti, char *ptr)
2753 struct mgs_thread_info *mgi = mgs_env_info(env);
2756 int rc = 0, rc2 = 0;
2759 /* For various parameter settings, we have to figure out which logs
2760 care about them (e.g. both mdt and client for lov settings) */
2761 CDEBUG(D_MGS, "next param '%s'\n", ptr);
2763 /* The params are stored in MOUNT_DATA_FILE and modified via
2764 tunefs.lustre, or set using lctl conf_param */
2766 /* Processed in lustre_start_mgc */
2767 if (class_match_param(ptr, PARAM_MGSNODE, NULL) == 0)
2770 /* Processed in ost/mdt */
2771 if (class_match_param(ptr, PARAM_NETWORK, NULL) == 0)
2774 /* Processed in mgs_write_log_ost */
2775 if (class_match_param(ptr, PARAM_FAILMODE, NULL) == 0) {
2776 if (mti->mti_flags & LDD_F_PARAM) {
2777 LCONSOLE_ERROR_MSG(0x169, "%s can only be "
2778 "changed with tunefs.lustre"
2779 "and --writeconf\n", ptr);
2785 if (class_match_param(ptr, PARAM_SRPC, NULL) == 0) {
2786 rc = mgs_srpc_set_param(env, mgs, fsdb, mti, ptr);
2790 if (class_match_param(ptr, PARAM_FAILNODE, NULL) == 0) {
2791 /* Add a failover nidlist */
2793 /* We already processed failovers params for new
2794 targets in mgs_write_log_target */
2795 if (mti->mti_flags & LDD_F_PARAM) {
2796 CDEBUG(D_MGS, "Adding failnode\n");
2797 rc = mgs_write_log_add_failnid(env, mgs, fsdb, mti);
2802 if (class_match_param(ptr, PARAM_SYS, &tmp) == 0) {
2803 rc = mgs_write_log_sys(env, mgs, fsdb, mti, ptr, tmp);
2807 if (class_match_param(ptr, PARAM_QUOTA, &tmp) == 0) {
2808 rc = mgs_write_log_quota(env, mgs, fsdb, mti, ptr, tmp);
2812 if (class_match_param(ptr, PARAM_OSC""PARAM_ACTIVE, &tmp) == 0) {
2813 /* active=0 means off, anything else means on */
2814 int flag = (*tmp == '0') ? CM_EXCLUDE : 0;
2817 if (!(mti->mti_flags & LDD_F_SV_TYPE_OST)) {
2818 LCONSOLE_ERROR_MSG(0x144, "%s: Only OSCs can "
2819 "be (de)activated.\n",
2821 GOTO(end, rc = -EINVAL);
2823 LCONSOLE_WARN("Permanently %sactivating %s\n",
2824 flag ? "de": "re", mti->mti_svname);
2826 rc = name_create(&logname, mti->mti_fsname, "-client");
2829 rc = mgs_modify(env, mgs, fsdb, mti, logname,
2830 mti->mti_svname, "add osc", flag);
2831 name_destroy(&logname);
2835 /* Add to all MDT logs for CMD */
2836 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2837 if (!cfs_test_bit(i, fsdb->fsdb_mdt_index_map))
2839 rc = name_create_mdt(&logname, mti->mti_fsname, i);
2842 rc = mgs_modify(env, mgs, fsdb, mti, logname,
2843 mti->mti_svname, "add osc", flag);
2844 name_destroy(&logname);
2850 LCONSOLE_ERROR_MSG(0x145, "Couldn't find %s in"
2851 "log (%d). No permanent "
2852 "changes were made to the "
2854 mti->mti_svname, rc);
2855 if (cfs_test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags))
2856 LCONSOLE_ERROR_MSG(0x146, "This may be"
2861 "update the logs.\n");
2864 /* Fall through to osc proc for deactivating live OSC
2865 on running MDT / clients. */
2867 /* Below here, let obd's XXX_process_config methods handle it */
2869 /* All lov. in proc */
2870 if (class_match_param(ptr, PARAM_LOV, NULL) == 0) {
2873 CDEBUG(D_MGS, "lov param %s\n", ptr);
2874 if (!(mti->mti_flags & LDD_F_SV_TYPE_MDT)) {
2875 LCONSOLE_ERROR_MSG(0x147, "LOV params must be "
2876 "set on the MDT, not %s. "
2883 if (mgs_log_is_empty(env, mgs, mti->mti_svname))
2884 GOTO(end, rc = -ENODEV);
2886 rc = name_create_mdt_and_lov(&logname, &mdtlovname, fsdb,
2887 mti->mti_stripe_index);
2890 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, mti->mti_svname,
2891 &mgi->mgi_bufs, mdtlovname, ptr);
2892 name_destroy(&logname);
2893 name_destroy(&mdtlovname);
2898 rc = name_create(&logname, mti->mti_fsname, "-client");
2901 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname, &mgi->mgi_bufs,
2902 fsdb->fsdb_clilov, ptr);
2903 name_destroy(&logname);
2907 /* All osc., mdc., llite. params in proc */
2908 if ((class_match_param(ptr, PARAM_OSC, NULL) == 0) ||
2909 (class_match_param(ptr, PARAM_MDC, NULL) == 0) ||
2910 (class_match_param(ptr, PARAM_LLITE, NULL) == 0)) {
2912 if (memcmp(ptr, PARAM_LLITE, strlen(PARAM_LLITE)) == 0) {
2913 name_create(&cname, mti->mti_fsname, "-client");
2914 /* Add the client type to match the obdname in
2915 class_config_llog_handler */
2916 } else if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
2919 name_create(&cname, fsdb->fsdb_mdc, "");
2921 name_create(&cname, mti->mti_svname,
2923 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2925 if (cfs_test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
2926 LCONSOLE_ERROR_MSG(0x148, "Upgraded "
2927 "client logs for %s"
2929 "modified. Consider"
2931 "configuration with"
2934 /* We don't know the names of all the
2936 GOTO(end, rc = -EINVAL);
2938 name_create(&cname, mti->mti_svname, "-osc");
2940 GOTO(end, rc = -EINVAL);
2945 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
2948 rc = name_create(&logname, mti->mti_fsname, "-client");
2950 name_destroy(&cname);
2953 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname, &mgi->mgi_bufs,
2956 /* osc params affect the MDT as well */
2957 if (!rc && (mti->mti_flags & LDD_F_SV_TYPE_OST)) {
2960 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
2961 if (!cfs_test_bit(i, fsdb->fsdb_mdt_index_map))
2963 name_destroy(&cname);
2964 rc = name_create_mdt_osc(&cname, mti->mti_svname,
2966 name_destroy(&logname);
2969 rc = name_create_mdt(&logname,
2970 mti->mti_fsname, i);
2973 if (!mgs_log_is_empty(env, mgs, logname)) {
2974 rc = mgs_wlp_lcfg(env, mgs, fsdb,
2983 name_destroy(&logname);
2984 name_destroy(&cname);
2988 /* All mdt. params in proc */
2989 if (class_match_param(ptr, PARAM_MDT, NULL) == 0) {
2993 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
2994 if (strncmp(mti->mti_svname, mti->mti_fsname,
2995 MTI_NAME_MAXLEN) == 0)
2996 /* device is unspecified completely? */
2997 rc = LDD_F_SV_TYPE_MDT | LDD_F_SV_ALL;
2999 rc = server_name2index(mti->mti_svname, &idx, NULL);
3002 if ((rc & LDD_F_SV_TYPE_MDT) == 0)
3004 if (rc & LDD_F_SV_ALL) {
3005 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3006 if (!cfs_test_bit(i,
3007 fsdb->fsdb_mdt_index_map))
3009 rc = name_create_mdt(&logname,
3010 mti->mti_fsname, i);
3013 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti,
3014 logname, &mgi->mgi_bufs,
3016 name_destroy(&logname);
3021 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti,
3022 mti->mti_svname, &mgi->mgi_bufs,
3023 mti->mti_svname, ptr);
3030 /* All mdd., ost. params in proc */
3031 if ((class_match_param(ptr, PARAM_MDD, NULL) == 0) ||
3032 (class_match_param(ptr, PARAM_OST, NULL) == 0)) {
3033 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
3034 if (mgs_log_is_empty(env, mgs, mti->mti_svname))
3035 GOTO(end, rc = -ENODEV);
3037 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, mti->mti_svname,
3038 &mgi->mgi_bufs, mti->mti_svname, ptr);
3042 LCONSOLE_WARN("Ignoring unrecognized param '%s'\n", ptr);
3047 CERROR("err %d on param '%s'\n", rc, ptr);
3052 /* Not implementing automatic failover nid addition at this time. */
3053 int mgs_check_failnid(const struct lu_env *env, struct mgs_device *mgs,
3054 struct mgs_target_info *mti)
3061 rc = mgs_find_or_make_fsdb(obd, fsname, &fsdb);
3065 if (mgs_log_is_empty(obd, mti->mti_svname))
3066 /* should never happen */
3069 CDEBUG(D_MGS, "Checking for new failnids for %s\n", mti->mti_svname);
3071 /* FIXME We can just check mti->params to see if we're already in
3072 the failover list. Modify mti->params for rewriting back at
3073 server_register_target(). */
3075 cfs_mutex_lock(&fsdb->fsdb_mutex);
3076 rc = mgs_write_log_add_failnid(obd, fsdb, mti);
3077 cfs_mutex_unlock(&fsdb->fsdb_mutex);
3084 int mgs_write_log_target(const struct lu_env *env,
3085 struct mgs_device *mgs,
3086 struct mgs_target_info *mti,
3093 /* set/check the new target index */
3094 rc = mgs_set_index(env, mgs, mti);
3096 CERROR("Can't get index (%d)\n", rc);
3101 if (mti->mti_flags & LDD_F_UPGRADE14) {
3102 if (rc == EALREADY) {
3103 LCONSOLE_INFO("Found index %d for %s 1.4 log, "
3104 "upgrading\n", mti->mti_stripe_index,
3107 LCONSOLE_ERROR_MSG(0x149, "Failed to find %s in the old"
3108 " client log. Apparently it is not "
3109 "part of this filesystem, or the old"
3110 " log is wrong.\nUse 'writeconf' on "
3111 "the MDT to force log regeneration."
3112 "\n", mti->mti_svname);
3113 /* Not in client log? Upgrade anyhow...*/
3114 /* Argument against upgrading: reformat MDT,
3115 upgrade OST, then OST will start but will be SKIPped
3116 in client logs. Maybe error now is better. */
3117 /* RETURN(-EINVAL); */
3119 /* end COMPAT_146 */
3121 if (rc == EALREADY) {
3122 LCONSOLE_WARN("Found index %d for %s, updating log\n",
3123 mti->mti_stripe_index, mti->mti_svname);
3124 /* We would like to mark old log sections as invalid
3125 and add new log sections in the client and mdt logs.
3126 But if we add new sections, then live clients will
3127 get repeat setup instructions for already running
3128 osc's. So don't update the client/mdt logs. */
3129 mti->mti_flags &= ~LDD_F_UPDATE;
3133 cfs_mutex_lock(&fsdb->fsdb_mutex);
3135 if (mti->mti_flags &
3136 (LDD_F_VIRGIN | LDD_F_UPGRADE14 | LDD_F_WRITECONF)) {
3137 /* Generate a log from scratch */
3138 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
3139 rc = mgs_write_log_mdt(env, mgs, fsdb, mti);
3140 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
3141 rc = mgs_write_log_ost(env, mgs, fsdb, mti);
3143 CERROR("Unknown target type %#x, can't create log for "
3144 "%s\n", mti->mti_flags, mti->mti_svname);
3147 CERROR("Can't write logs for %s (%d)\n",
3148 mti->mti_svname, rc);
3152 /* Just update the params from tunefs in mgs_write_log_params */
3153 CDEBUG(D_MGS, "Update params for %s\n", mti->mti_svname);
3154 mti->mti_flags |= LDD_F_PARAM;
3157 /* allocate temporary buffer, where class_get_next_param will
3158 make copy of a current parameter */
3159 OBD_ALLOC(buf, strlen(mti->mti_params) + 1);
3161 GOTO(out_up, rc = -ENOMEM);
3162 params = mti->mti_params;
3163 while (params != NULL) {
3164 rc = class_get_next_param(¶ms, buf);
3167 /* there is no next parameter, that is
3172 CDEBUG(D_MGS, "remaining string: '%s', param: '%s'\n",
3174 rc = mgs_write_log_param(env, mgs, fsdb, mti, buf);
3179 OBD_FREE(buf, strlen(mti->mti_params) + 1);
3182 cfs_mutex_unlock(&fsdb->fsdb_mutex);
3187 /* verify that we can handle the old config logs */
3188 int mgs_upgrade_sv_14(const struct lu_env *env, struct mgs_device *mgs,
3189 struct mgs_target_info *mti, struct fs_db *fsdb)
3194 /* Create ost log normally, as servers register. Servers
3195 register with their old uuids (from last_rcvd), so old
3196 (MDT and client) logs should work.
3197 - new MDT won't know about old OSTs, only the ones that have
3198 registered, so we need the old MDT log to get the LOV right
3199 in order for old clients to work.
3200 - Old clients connect to the MDT, not the MGS, for their logs, and
3201 will therefore receive the old client log from the MDT /LOGS dir.
3202 - Old clients can continue to use and connect to old or new OSTs
3203 - New clients will contact the MGS for their log
3206 LCONSOLE_INFO("upgrading server %s from pre-1.6\n", mti->mti_svname);
3207 server_mti_print("upgrade", mti);
3209 if (cfs_test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
3210 LCONSOLE_ERROR_MSG(0x14a, "The old client log %s-client is "
3211 "missing. Was tunefs.lustre successful?\n",
3216 if (fsdb->fsdb_gen == 0) {
3217 /* There were no markers in the client log, meaning we have
3218 not updated the logs for this fs */
3219 CDEBUG(D_MGS, "found old, unupdated client log\n");
3222 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
3223 if (mgs_log_is_empty(env, mgs, mti->mti_svname)) {
3224 LCONSOLE_ERROR_MSG(0x14b, "The old MDT log %s is "
3225 "missing. Was tunefs.lustre "
3230 /* We're starting with an old uuid. Assume old name for lov
3231 as well since the lov entry already exists in the log. */
3232 CDEBUG(D_MGS, "old mds uuid %s\n", mti->mti_uuid);
3233 if (strncmp(mti->mti_uuid, fsdb->fsdb_mdtlov + 4,
3234 strlen(fsdb->fsdb_mdtlov) - 4) != 0) {
3235 CERROR("old mds uuid %s doesn't match log %s (%s)\n",
3236 mti->mti_uuid, fsdb->fsdb_mdtlov,
3237 fsdb->fsdb_mdtlov + 4);
3242 if (!cfs_test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
3243 LCONSOLE_ERROR_MSG(0x14c, "%s-client is supposedly an old "
3244 "log, but no old LOV or MDT was found. "
3245 "Consider updating the configuration with"
3246 " --writeconf.\n", mti->mti_fsname);
3251 /* end COMPAT_146 */
3253 int mgs_erase_log(const struct lu_env *env, struct mgs_device *mgs, char *name)
3255 struct lvfs_run_ctxt saved;
3256 struct llog_ctxt *ctxt;
3258 struct obd_device *obd = mgs->mgs_obd;
3260 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
3262 CERROR("%s: MGS config context doesn't exist\n",
3266 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
3267 rc = llog_erase(NULL, ctxt, NULL, name);
3268 /* llog may not exist */
3271 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
3272 llog_ctxt_put(ctxt);
3276 CERROR("%s: failed to clear log %s: %d\n", obd->obd_name,
3282 /* erase all logs for the given fs */
3283 int mgs_erase_logs(const struct lu_env *env, struct mgs_device *mgs, char *fsname)
3286 cfs_list_t dentry_list;
3287 struct l_linux_dirent *dirent, *n;
3288 int rc, len = strlen(fsname);
3292 /* Find all the logs in the CONFIGS directory */
3293 rc = class_dentry_readdir(env, mgs, &dentry_list);
3295 CERROR("Can't read %s dir\n", MOUNT_CONFIGS_DIR);
3299 cfs_mutex_lock(&mgs->mgs_mutex);
3301 /* Delete the fs db */
3302 fsdb = mgs_find_fsdb(mgs, fsname);
3304 mgs_free_fsdb(mgs, fsdb);
3306 cfs_list_for_each_entry_safe(dirent, n, &dentry_list, lld_list) {
3307 cfs_list_del(&dirent->lld_list);
3308 suffix = strrchr(dirent->lld_name, '-');
3309 if (suffix != NULL) {
3310 if ((len == suffix - dirent->lld_name) &&
3311 (strncmp(fsname, dirent->lld_name, len) == 0)) {
3312 CDEBUG(D_MGS, "Removing log %s\n",
3314 mgs_erase_log(env, mgs, dirent->lld_name);
3317 OBD_FREE(dirent, sizeof(*dirent));
3320 cfs_mutex_unlock(&mgs->mgs_mutex);
3325 /* from llog_swab */
3326 static void print_lustre_cfg(struct lustre_cfg *lcfg)
3331 CDEBUG(D_MGS, "lustre_cfg: %p\n", lcfg);
3332 CDEBUG(D_MGS, "\tlcfg->lcfg_version: %#x\n", lcfg->lcfg_version);
3334 CDEBUG(D_MGS, "\tlcfg->lcfg_command: %#x\n", lcfg->lcfg_command);
3335 CDEBUG(D_MGS, "\tlcfg->lcfg_num: %#x\n", lcfg->lcfg_num);
3336 CDEBUG(D_MGS, "\tlcfg->lcfg_flags: %#x\n", lcfg->lcfg_flags);
3337 CDEBUG(D_MGS, "\tlcfg->lcfg_nid: %s\n", libcfs_nid2str(lcfg->lcfg_nid));
3339 CDEBUG(D_MGS, "\tlcfg->lcfg_bufcount: %d\n", lcfg->lcfg_bufcount);
3340 if (lcfg->lcfg_bufcount < LUSTRE_CFG_MAX_BUFCOUNT)
3341 for (i = 0; i < lcfg->lcfg_bufcount; i++) {
3342 CDEBUG(D_MGS, "\tlcfg->lcfg_buflens[%d]: %d %s\n",
3343 i, lcfg->lcfg_buflens[i],
3344 lustre_cfg_string(lcfg, i));
3349 /* Set a permanent (config log) param for a target or fs
3350 * \param lcfg buf0 may contain the device (testfs-MDT0000) name
3351 * buf1 contains the single parameter
3353 int mgs_setparam(const struct lu_env *env, struct mgs_device *mgs,
3354 struct lustre_cfg *lcfg, char *fsname)
3357 struct mgs_target_info *mti;
3358 char *devname, *param;
3364 print_lustre_cfg(lcfg);
3366 /* lustre, lustre-mdtlov, lustre-client, lustre-MDT0000 */
3367 devname = lustre_cfg_string(lcfg, 0);
3368 param = lustre_cfg_string(lcfg, 1);
3370 /* Assume device name embedded in param:
3371 lustre-OST0000.osc.max_dirty_mb=32 */
3372 ptr = strchr(param, '.');
3380 LCONSOLE_ERROR_MSG(0x14d, "No target specified: %s\n", param);
3384 /* Extract fsname */
3385 ptr = strrchr(devname, '-');
3386 memset(fsname, 0, MTI_NAME_MAXLEN);
3387 if (ptr && (server_name2index(ptr, &index, NULL) >= 0)) {
3388 /* param related to llite isn't allowed to set by OST or MDT */
3389 if (strncmp(param, PARAM_LLITE, sizeof(PARAM_LLITE)) == 0)
3392 strncpy(fsname, devname, ptr - devname);
3394 /* assume devname is the fsname */
3395 strncpy(fsname, devname, MTI_NAME_MAXLEN);
3397 fsname[MTI_NAME_MAXLEN - 1] = 0;
3398 CDEBUG(D_MGS, "setparam fs='%s' device='%s'\n", fsname, devname);
3400 rc = mgs_find_or_make_fsdb(env, mgs, fsname, &fsdb);
3403 if (!cfs_test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags) &&
3404 cfs_test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
3405 CERROR("No filesystem targets for %s. cfg_device from lctl "
3406 "is '%s'\n", fsname, devname);
3407 mgs_free_fsdb(mgs, fsdb);
3411 /* Create a fake mti to hold everything */
3414 GOTO(out, rc = -ENOMEM);
3415 strncpy(mti->mti_fsname, fsname, MTI_NAME_MAXLEN);
3416 strncpy(mti->mti_svname, devname, MTI_NAME_MAXLEN);
3417 strncpy(mti->mti_params, param, sizeof(mti->mti_params));
3418 rc = server_name2index(mti->mti_svname, &mti->mti_stripe_index, &tmp);
3420 /* Not a valid server; may be only fsname */
3423 /* Strip -osc or -mdc suffix from svname */
3424 if (server_make_name(rc, mti->mti_stripe_index, mti->mti_fsname,
3426 GOTO(out, rc = -EINVAL);
3428 mti->mti_flags = rc | LDD_F_PARAM;
3430 cfs_mutex_lock(&fsdb->fsdb_mutex);
3431 rc = mgs_write_log_param(env, mgs, fsdb, mti, mti->mti_params);
3432 cfs_mutex_unlock(&fsdb->fsdb_mutex);
3435 * Revoke lock so everyone updates. Should be alright if
3436 * someone was already reading while we were updating the logs,
3437 * so we don't really need to hold the lock while we're
3440 mgs_revoke_lock(mgs, fsdb, CONFIG_T_CONFIG);
3446 static int mgs_write_log_pool(const struct lu_env *env,
3447 struct mgs_device *mgs, char *logname,
3448 struct fs_db *fsdb, char *lovname,
3449 enum lcfg_command_type cmd,
3450 char *poolname, char *fsname,
3451 char *ostname, char *comment)
3453 struct llog_handle *llh = NULL;
3456 rc = record_start_log(env, mgs, &llh, logname);
3459 rc = record_marker(env, llh, fsdb, CM_START, lovname, comment);
3462 rc = record_base(env, llh, lovname, 0, cmd, poolname, fsname, ostname, 0);
3465 rc = record_marker(env, llh, fsdb, CM_END, lovname, comment);
3467 record_end_log(env, &llh);
3471 int mgs_pool_cmd(const struct lu_env *env, struct mgs_device *mgs,
3472 enum lcfg_command_type cmd, char *fsname,
3473 char *poolname, char *ostname)
3478 char *label = NULL, *canceled_label = NULL;
3480 struct mgs_target_info *mti = NULL;
3484 rc = mgs_find_or_make_fsdb(env, mgs, fsname, &fsdb);
3486 CERROR("Can't get db for %s\n", fsname);
3489 if (cfs_test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
3490 CERROR("%s is not defined\n", fsname);
3491 mgs_free_fsdb(mgs, fsdb);
3495 label_sz = 10 + strlen(fsname) + strlen(poolname);
3497 /* check if ostname match fsname */
3498 if (ostname != NULL) {
3501 ptr = strrchr(ostname, '-');
3502 if ((ptr == NULL) ||
3503 (strncmp(fsname, ostname, ptr-ostname) != 0))
3505 label_sz += strlen(ostname);
3508 OBD_ALLOC(label, label_sz);
3515 "new %s.%s", fsname, poolname);
3519 "add %s.%s.%s", fsname, poolname, ostname);
3522 OBD_ALLOC(canceled_label, label_sz);
3523 if (canceled_label == NULL)
3524 GOTO(out_label, rc = -ENOMEM);
3526 "rem %s.%s.%s", fsname, poolname, ostname);
3527 sprintf(canceled_label,
3528 "add %s.%s.%s", fsname, poolname, ostname);
3531 OBD_ALLOC(canceled_label, label_sz);
3532 if (canceled_label == NULL)
3533 GOTO(out_label, rc = -ENOMEM);
3535 "del %s.%s", fsname, poolname);
3536 sprintf(canceled_label,
3537 "new %s.%s", fsname, poolname);
3543 cfs_mutex_lock(&fsdb->fsdb_mutex);
3545 if (canceled_label != NULL) {
3548 GOTO(out_cancel, rc = -ENOMEM);
3551 /* write pool def to all MDT logs */
3552 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3553 if (cfs_test_bit(i, fsdb->fsdb_mdt_index_map)) {
3554 rc = name_create_mdt_and_lov(&logname, &lovname,
3557 cfs_mutex_unlock(&fsdb->fsdb_mutex);
3560 if (canceled_label != NULL) {
3561 strcpy(mti->mti_svname, "lov pool");
3562 rc = mgs_modify(env, mgs, fsdb, mti, logname,
3563 lovname, canceled_label,
3568 rc = mgs_write_log_pool(env, mgs, logname,
3572 name_destroy(&logname);
3573 name_destroy(&lovname);
3575 cfs_mutex_unlock(&fsdb->fsdb_mutex);
3581 rc = name_create(&logname, fsname, "-client");
3583 cfs_mutex_unlock(&fsdb->fsdb_mutex);
3586 if (canceled_label != NULL) {
3587 rc = mgs_modify(env, mgs, fsdb, mti, logname,
3588 fsdb->fsdb_clilov, canceled_label, CM_SKIP);
3590 cfs_mutex_unlock(&fsdb->fsdb_mutex);
3591 name_destroy(&logname);
3596 rc = mgs_write_log_pool(env, mgs, logname, fsdb, fsdb->fsdb_clilov,
3597 cmd, fsname, poolname, ostname, label);
3598 cfs_mutex_unlock(&fsdb->fsdb_mutex);
3599 name_destroy(&logname);
3600 /* request for update */
3601 mgs_revoke_lock(mgs, fsdb, CONFIG_T_CONFIG);
3608 if (canceled_label != NULL)
3609 OBD_FREE(canceled_label, label_sz);
3611 OBD_FREE(label, label_sz);
3616 /******************** unused *********************/
3617 static int mgs_backup_llog(struct obd_device *obd, char* fsname)
3619 struct file *filp, *bak_filp;
3620 struct lvfs_run_ctxt saved;
3621 char *logname, *buf;
3622 loff_t soff = 0 , doff = 0;
3623 int count = 4096, len;
3626 OBD_ALLOC(logname, PATH_MAX);
3627 if (logname == NULL)
3630 OBD_ALLOC(buf, count);
3632 GOTO(out , rc = -ENOMEM);
3634 len = snprintf(logname, PATH_MAX, "%s/%s.bak",
3635 MOUNT_CONFIGS_DIR, fsname);
3637 if (len >= PATH_MAX - 1) {
3638 GOTO(out, -ENAMETOOLONG);
3641 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
3643 bak_filp = l_filp_open(logname, O_RDWR|O_CREAT|O_TRUNC, 0660);
3644 if (IS_ERR(bak_filp)) {
3645 rc = PTR_ERR(bak_filp);
3646 CERROR("backup logfile open %s: %d\n", logname, rc);
3649 sprintf(logname, "%s/%s", MOUNT_CONFIGS_DIR, fsname);
3650 filp = l_filp_open(logname, O_RDONLY, 0);
3653 CERROR("logfile open %s: %d\n", logname, rc);
3657 while ((rc = lustre_fread(filp, buf, count, &soff)) > 0) {
3658 rc = lustre_fwrite(bak_filp, buf, count, &doff);
3662 filp_close(filp, 0);
3664 filp_close(bak_filp, 0);
3666 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
3669 OBD_FREE(buf, count);
3670 OBD_FREE(logname, PATH_MAX);