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(struct obd_device *obd, struct dentry *dir,
70 struct vfsmount *inmnt,
71 cfs_list_t *dentry_list){
72 /* see mds_cleanup_pending */
73 struct lvfs_run_ctxt saved;
75 struct dentry *dentry;
80 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
83 GOTO(out_pop, rc = PTR_ERR(dentry));
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, &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(struct obd_device *obd, struct fs_db *fsdb)
267 struct llog_handle *loghandle;
268 struct lvfs_run_ctxt saved;
269 struct llog_ctxt *ctxt;
270 struct mgs_fsdb_handler_data d = { fsdb, 0 };
274 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
275 LASSERT(ctxt != NULL);
276 name_create(&logname, fsdb->fsdb_name, "-client");
277 cfs_mutex_lock(&fsdb->fsdb_mutex);
278 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
279 rc = llog_create(NULL, ctxt, &loghandle, NULL, logname);
283 rc = llog_init_handle(NULL, loghandle, LLOG_F_IS_PLAIN, NULL);
287 if (llog_get_size(loghandle) <= 1)
288 cfs_set_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags);
290 rc = llog_process(NULL, loghandle, mgs_fsdb_handler, (void *) &d,
292 CDEBUG(D_INFO, "get_db = %d\n", rc);
294 rc2 = llog_close(NULL, loghandle);
298 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
299 cfs_mutex_unlock(&fsdb->fsdb_mutex);
300 name_destroy(&logname);
306 static void mgs_free_fsdb_srpc(struct fs_db *fsdb)
308 struct mgs_tgt_srpc_conf *tgtconf;
310 /* free target-specific rules */
311 while (fsdb->fsdb_srpc_tgt) {
312 tgtconf = fsdb->fsdb_srpc_tgt;
313 fsdb->fsdb_srpc_tgt = tgtconf->mtsc_next;
315 LASSERT(tgtconf->mtsc_tgt);
317 sptlrpc_rule_set_free(&tgtconf->mtsc_rset);
318 OBD_FREE(tgtconf->mtsc_tgt, strlen(tgtconf->mtsc_tgt) + 1);
319 OBD_FREE_PTR(tgtconf);
322 /* free general rules */
323 sptlrpc_rule_set_free(&fsdb->fsdb_srpc_gen);
326 struct fs_db *mgs_find_fsdb(struct obd_device *obd, char *fsname)
328 struct mgs_obd *mgs = &obd->u.mgs;
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(struct obd_device *obd, char *fsname)
343 struct mgs_obd *mgs = &obd->u.mgs;
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(obd, fsdb);
387 lproc_mgs_add_live(obd, 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 obd_device *obd, struct fs_db *fsdb)
408 /* wait for anyone with the sem */
409 cfs_mutex_lock(&fsdb->fsdb_mutex);
410 lproc_mgs_del_live(obd, fsdb);
411 cfs_list_del(&fsdb->fsdb_list);
413 /* deinitialize fsr */
414 mgs_ir_fini_fs(obd, 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 obd_device *obd)
432 struct mgs_obd *mgs = &obd->u.mgs;
433 CFS_INIT_LIST_HEAD(&mgs->mgs_fs_db_list);
437 int mgs_cleanup_fsdb_list(struct obd_device *obd)
439 struct mgs_obd *mgs = &obd->u.mgs;
441 cfs_list_t *tmp, *tmp2;
442 cfs_mutex_lock(&mgs->mgs_mutex);
443 cfs_list_for_each_safe(tmp, tmp2, &mgs->mgs_fs_db_list) {
444 fsdb = cfs_list_entry(tmp, struct fs_db, fsdb_list);
445 mgs_free_fsdb(obd, fsdb);
447 cfs_mutex_unlock(&mgs->mgs_mutex);
451 int mgs_find_or_make_fsdb(struct obd_device *obd, char *name,
454 struct mgs_obd *mgs = &obd->u.mgs;
458 cfs_mutex_lock(&mgs->mgs_mutex);
459 fsdb = mgs_find_fsdb(obd, name);
461 cfs_mutex_unlock(&mgs->mgs_mutex);
466 CDEBUG(D_MGS, "Creating new db\n");
467 fsdb = mgs_new_fsdb(obd, name);
468 cfs_mutex_unlock(&mgs->mgs_mutex);
472 if (!cfs_test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
473 /* populate the db from the client llog */
474 rc = mgs_get_fsdb_from_llog(obd, fsdb);
476 CERROR("Can't get db from client log %d\n", rc);
477 mgs_free_fsdb(obd, fsdb);
482 /* populate srpc rules from params llog */
483 rc = mgs_get_fsdb_srpc_from_llog(obd, fsdb);
485 CERROR("Can't get db from params log %d\n", rc);
486 mgs_free_fsdb(obd, fsdb);
497 -1= empty client log */
498 int mgs_check_index(struct obd_device *obd, struct mgs_target_info *mti)
505 LASSERT(!(mti->mti_flags & LDD_F_NEED_INDEX));
507 rc = mgs_find_or_make_fsdb(obd, 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(struct obd_device *obd, struct mgs_target_info *mti)
550 rc = mgs_find_or_make_fsdb(obd, mti->mti_fsname, &fsdb);
552 CERROR("Can't get db for %s\n", mti->mti_fsname);
556 if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
557 imap = fsdb->fsdb_ost_index_map;
558 } else if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
559 imap = fsdb->fsdb_mdt_index_map;
560 if (fsdb->fsdb_mdt_count >= MAX_MDT_COUNT) {
561 LCONSOLE_ERROR_MSG(0x13f, "The max mdt count"
562 "is %d\n", (int)MAX_MDT_COUNT);
569 if (mti->mti_flags & LDD_F_NEED_INDEX) {
570 rc = next_index(imap, INDEX_MAP_SIZE);
573 mti->mti_stripe_index = rc;
574 if (mti->mti_flags & LDD_F_SV_TYPE_MDT)
575 fsdb->fsdb_mdt_count ++;
578 if (mti->mti_stripe_index >= INDEX_MAP_SIZE * 8) {
579 LCONSOLE_ERROR_MSG(0x13f, "Server %s requested index %d, "
580 "but the max index is %d.\n",
581 mti->mti_svname, mti->mti_stripe_index,
586 if (cfs_test_bit(mti->mti_stripe_index, imap)) {
587 if ((mti->mti_flags & LDD_F_VIRGIN) &&
588 !(mti->mti_flags & LDD_F_WRITECONF)) {
589 LCONSOLE_ERROR_MSG(0x140, "Server %s requested index "
590 "%d, but that index is already in "
591 "use. Use --writeconf to force\n",
593 mti->mti_stripe_index);
596 CDEBUG(D_MGS, "Server %s updating index %d\n",
597 mti->mti_svname, mti->mti_stripe_index);
602 cfs_set_bit(mti->mti_stripe_index, imap);
603 cfs_clear_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags);
604 server_make_name(mti->mti_flags & ~(LDD_F_VIRGIN | LDD_F_WRITECONF),
605 mti->mti_stripe_index, mti->mti_fsname, mti->mti_svname);
607 CDEBUG(D_MGS, "Set index for %s to %d\n", mti->mti_svname,
608 mti->mti_stripe_index);
613 struct mgs_modify_lookup {
614 struct cfg_marker mml_marker;
618 static int mgs_modify_handler(const struct lu_env *env,
619 struct llog_handle *llh,
620 struct llog_rec_hdr *rec, void *data)
622 struct mgs_modify_lookup *mml = data;
623 struct cfg_marker *marker;
624 struct lustre_cfg *lcfg = (struct lustre_cfg *)(rec + 1);
625 int cfg_len = rec->lrh_len - sizeof(struct llog_rec_hdr) -
626 sizeof(struct llog_rec_tail);
630 if (rec->lrh_type != OBD_CFG_REC) {
631 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
635 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
637 CERROR("Insane cfg\n");
641 /* We only care about markers */
642 if (lcfg->lcfg_command != LCFG_MARKER)
645 marker = lustre_cfg_buf(lcfg, 1);
646 if ((strcmp(mml->mml_marker.cm_comment, marker->cm_comment) == 0) &&
647 (strcmp(mml->mml_marker.cm_tgtname, marker->cm_tgtname) == 0) &&
648 !(marker->cm_flags & CM_SKIP)) {
649 /* Found a non-skipped marker match */
650 CDEBUG(D_MGS, "Changing rec %u marker %d %x->%x: %s %s\n",
651 rec->lrh_index, marker->cm_step,
652 marker->cm_flags, mml->mml_marker.cm_flags,
653 marker->cm_tgtname, marker->cm_comment);
654 /* Overwrite the old marker llog entry */
655 marker->cm_flags &= ~CM_EXCLUDE; /* in case we're unexcluding */
656 marker->cm_flags |= mml->mml_marker.cm_flags;
657 marker->cm_canceltime = mml->mml_marker.cm_canceltime;
658 /* Header and tail are added back to lrh_len in
659 llog_lvfs_write_rec */
660 rec->lrh_len = cfg_len;
661 rc = llog_write_rec(NULL, llh, rec, NULL, 0, (void *)lcfg,
670 /* Modify an existing config log record (for CM_SKIP or CM_EXCLUDE) */
671 static int mgs_modify(struct obd_device *obd, struct fs_db *fsdb,
672 struct mgs_target_info *mti, char *logname,
673 char *devname, char *comment, int flags)
675 struct llog_handle *loghandle;
676 struct lvfs_run_ctxt saved;
677 struct llog_ctxt *ctxt;
678 struct mgs_modify_lookup *mml;
682 CDEBUG(D_MGS, "modify %s/%s/%s fl=%x\n", logname, devname, comment,
685 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
687 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
688 LASSERT(ctxt != NULL);
689 rc = llog_create(NULL, ctxt, &loghandle, NULL, logname);
693 rc = llog_init_handle(NULL, loghandle, LLOG_F_IS_PLAIN, NULL);
697 if (llog_get_size(loghandle) <= 1)
698 GOTO(out_close, rc = 0);
702 GOTO(out_close, rc = -ENOMEM);
703 strcpy(mml->mml_marker.cm_comment, comment);
704 strcpy(mml->mml_marker.cm_tgtname, devname);
705 /* Modify mostly means cancel */
706 mml->mml_marker.cm_flags = flags;
707 mml->mml_marker.cm_canceltime = flags ? cfs_time_current_sec() : 0;
708 mml->mml_modified = 0;
709 rc = llog_process(NULL, loghandle, mgs_modify_handler, (void *)mml,
711 if (!rc && !mml->mml_modified)
716 rc2 = llog_close(NULL, loghandle);
720 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
721 if (rc && rc != -ENODEV)
722 CERROR("modify %s/%s failed %d\n",
723 mti->mti_svname, comment, rc);
728 /******************** config log recording functions *********************/
730 static int record_lcfg(struct obd_device *obd, struct llog_handle *llh,
731 struct lustre_cfg *lcfg)
733 struct lvfs_run_ctxt saved;
734 struct llog_rec_hdr rec;
740 LASSERT(llh->lgh_ctxt);
742 buflen = lustre_cfg_len(lcfg->lcfg_bufcount,
744 rec.lrh_len = llog_data_len(buflen);
745 rec.lrh_type = OBD_CFG_REC;
747 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
748 /* idx = -1 means append */
749 rc = llog_write_rec(NULL, llh, &rec, NULL, 0, (void *)lcfg, -1);
750 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
752 CERROR("failed %d\n", rc);
756 static int record_base(struct obd_device *obd, struct llog_handle *llh,
757 char *cfgname, lnet_nid_t nid, int cmd,
758 char *s1, char *s2, char *s3, char *s4)
760 struct lustre_cfg_bufs bufs;
761 struct lustre_cfg *lcfg;
764 CDEBUG(D_MGS, "lcfg %s %#x %s %s %s %s\n", cfgname,
765 cmd, s1, s2, s3, s4);
767 lustre_cfg_bufs_reset(&bufs, cfgname);
769 lustre_cfg_bufs_set_string(&bufs, 1, s1);
771 lustre_cfg_bufs_set_string(&bufs, 2, s2);
773 lustre_cfg_bufs_set_string(&bufs, 3, s3);
775 lustre_cfg_bufs_set_string(&bufs, 4, s4);
777 lcfg = lustre_cfg_new(cmd, &bufs);
780 lcfg->lcfg_nid = nid;
782 rc = record_lcfg(obd, llh, lcfg);
784 lustre_cfg_free(lcfg);
787 CERROR("error %d: lcfg %s %#x %s %s %s %s\n", rc, cfgname,
788 cmd, s1, s2, s3, s4);
794 static inline int record_add_uuid(struct obd_device *obd,
795 struct llog_handle *llh,
796 uint64_t nid, char *uuid)
798 return record_base(obd,llh,NULL,nid,LCFG_ADD_UUID,uuid,0,0,0);
802 static inline int record_add_conn(struct obd_device *obd,
803 struct llog_handle *llh,
807 return record_base(obd,llh,devname,0,LCFG_ADD_CONN,uuid,0,0,0);
810 static inline int record_attach(struct obd_device *obd, struct llog_handle *llh,
811 char *devname, char *type, char *uuid)
813 return record_base(obd,llh,devname,0,LCFG_ATTACH,type,uuid,0,0);
816 static inline int record_setup(struct obd_device *obd, struct llog_handle *llh,
818 char *s1, char *s2, char *s3, char *s4)
820 return record_base(obd,llh,devname,0,LCFG_SETUP,s1,s2,s3,s4);
823 static int record_lov_setup(struct obd_device *obd, struct llog_handle *llh,
824 char *devname, struct lov_desc *desc)
826 struct lustre_cfg_bufs bufs;
827 struct lustre_cfg *lcfg;
830 lustre_cfg_bufs_reset(&bufs, devname);
831 lustre_cfg_bufs_set(&bufs, 1, desc, sizeof(*desc));
832 lcfg = lustre_cfg_new(LCFG_SETUP, &bufs);
835 rc = record_lcfg(obd, llh, lcfg);
837 lustre_cfg_free(lcfg);
841 static int record_lmv_setup(struct obd_device *obd, struct llog_handle *llh,
842 char *devname, struct lmv_desc *desc)
844 struct lustre_cfg_bufs bufs;
845 struct lustre_cfg *lcfg;
848 lustre_cfg_bufs_reset(&bufs, devname);
849 lustre_cfg_bufs_set(&bufs, 1, desc, sizeof(*desc));
850 lcfg = lustre_cfg_new(LCFG_SETUP, &bufs);
852 rc = record_lcfg(obd, llh, lcfg);
854 lustre_cfg_free(lcfg);
858 static inline int record_mdc_add(struct obd_device *obd,
859 struct llog_handle *llh,
860 char *logname, char *mdcuuid,
861 char *mdtuuid, char *index,
864 return record_base(obd,llh,logname,0,LCFG_ADD_MDC,
865 mdtuuid,index,gen,mdcuuid);
868 static inline int record_lov_add(struct obd_device *obd,
869 struct llog_handle *llh,
870 char *lov_name, char *ost_uuid,
871 char *index, char *gen)
873 return record_base(obd,llh,lov_name,0,LCFG_LOV_ADD_OBD,
874 ost_uuid,index,gen,0);
877 static inline int record_mount_opt(struct obd_device *obd,
878 struct llog_handle *llh,
879 char *profile, char *lov_name,
882 return record_base(obd,llh,NULL,0,LCFG_MOUNTOPT,
883 profile,lov_name,mdc_name,0);
886 static int record_marker(struct obd_device *obd, struct llog_handle *llh,
887 struct fs_db *fsdb, __u32 flags,
888 char *tgtname, char *comment)
890 struct cfg_marker marker;
891 struct lustre_cfg_bufs bufs;
892 struct lustre_cfg *lcfg;
895 if (flags & CM_START)
897 marker.cm_step = fsdb->fsdb_gen;
898 marker.cm_flags = flags;
899 marker.cm_vers = LUSTRE_VERSION_CODE;
900 strncpy(marker.cm_tgtname, tgtname, sizeof(marker.cm_tgtname));
901 strncpy(marker.cm_comment, comment, sizeof(marker.cm_comment));
902 marker.cm_createtime = cfs_time_current_sec();
903 marker.cm_canceltime = 0;
904 lustre_cfg_bufs_reset(&bufs, NULL);
905 lustre_cfg_bufs_set(&bufs, 1, &marker, sizeof(marker));
906 lcfg = lustre_cfg_new(LCFG_MARKER, &bufs);
909 rc = record_lcfg(obd, llh, lcfg);
911 lustre_cfg_free(lcfg);
915 static int record_start_log(struct obd_device *obd,
916 struct llog_handle **llh, char *name)
918 static struct obd_uuid cfg_uuid = { .uuid = "config_uuid" };
919 struct lvfs_run_ctxt saved;
920 struct llog_ctxt *ctxt;
924 GOTO(out, rc = -EBUSY);
926 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
928 GOTO(out, rc = -ENODEV);
930 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
931 rc = llog_create(NULL, ctxt, llh, NULL, name);
933 llog_init_handle(NULL, *llh, LLOG_F_IS_PLAIN, &cfg_uuid);
937 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
942 CERROR("Can't start log %s: %d\n", name, rc);
947 static int record_end_log(struct obd_device *obd, struct llog_handle **llh)
949 struct lvfs_run_ctxt saved;
952 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
954 rc = llog_close(NULL, *llh);
957 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
961 static int mgs_log_is_empty(struct obd_device *obd, char *name)
963 struct lvfs_run_ctxt saved;
964 struct llog_handle *llh;
965 struct llog_ctxt *ctxt;
968 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
969 LASSERT(ctxt != NULL);
970 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
971 rc = llog_create(NULL, ctxt, &llh, NULL, name);
973 llog_init_handle(NULL, llh, LLOG_F_IS_PLAIN, NULL);
974 rc = llog_get_size(llh);
975 llog_close(NULL, llh);
977 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
979 /* header is record 1 */
983 /******************** config "macros" *********************/
985 /* write an lcfg directly into a log (with markers) */
986 static int mgs_write_log_direct(struct obd_device *obd, struct fs_db *fsdb,
987 char *logname, struct lustre_cfg *lcfg,
988 char *devname, char *comment)
990 struct llog_handle *llh = NULL;
997 rc = record_start_log(obd, &llh, logname);
1001 /* FIXME These should be a single journal transaction */
1002 rc = record_marker(obd, llh, fsdb, CM_START, devname, comment);
1004 rc = record_lcfg(obd, llh, lcfg);
1006 rc = record_marker(obd, llh, fsdb, CM_END, devname, comment);
1007 rc = record_end_log(obd, &llh);
1012 /* write the lcfg in all logs for the given fs */
1013 int mgs_write_log_direct_all(struct obd_device *obd, struct fs_db *fsdb,
1014 struct mgs_target_info *mti,
1015 struct lustre_cfg *lcfg,
1016 char *devname, char *comment,
1019 struct mgs_obd *mgs = &obd->u.mgs;
1020 cfs_list_t dentry_list;
1021 struct l_linux_dirent *dirent, *n;
1022 char *fsname = mti->mti_fsname;
1024 int rc = 0, len = strlen(fsname);
1027 /* We need to set params for any future logs
1028 as well. FIXME Append this file to every new log.
1029 Actually, we should store as params (text), not llogs. Or
1031 name_create(&logname, fsname, "-params");
1032 if (mgs_log_is_empty(obd, logname)) {
1033 struct llog_handle *llh = NULL;
1034 rc = record_start_log(obd, &llh, logname);
1035 record_end_log(obd, &llh);
1037 name_destroy(&logname);
1041 /* Find all the logs in the CONFIGS directory */
1042 rc = class_dentry_readdir(obd, mgs->mgs_configs_dir,
1043 mgs->mgs_vfsmnt, &dentry_list);
1045 CERROR("Can't read %s dir\n", MOUNT_CONFIGS_DIR);
1049 /* Could use fsdb index maps instead of directory listing */
1050 cfs_list_for_each_entry_safe(dirent, n, &dentry_list, lld_list) {
1051 cfs_list_del(&dirent->lld_list);
1052 /* don't write to sptlrpc rule log */
1053 if (strstr(dirent->lld_name, "-sptlrpc") != NULL)
1056 /* caller wants write server logs only */
1057 if (server_only && strstr(dirent->lld_name, "-client") != NULL)
1060 if (strncmp(fsname, dirent->lld_name, len) == 0) {
1061 CDEBUG(D_MGS, "Changing log %s\n", dirent->lld_name);
1062 /* Erase any old settings of this same parameter */
1063 mgs_modify(obd, fsdb, mti, dirent->lld_name, devname,
1065 /* Write the new one */
1067 rc = mgs_write_log_direct(obd, fsdb,
1072 CERROR("err %d writing log %s\n", rc,
1077 OBD_FREE(dirent, sizeof(*dirent));
1085 struct mgs_target_info *comp_tmti;
1086 struct mgs_target_info *comp_mti;
1087 struct fs_db *comp_fsdb;
1088 struct obd_device *comp_obd;
1091 static int mgs_write_log_mdc_to_mdt(struct obd_device *, struct fs_db *,
1092 struct mgs_target_info *, char *);
1093 static int mgs_write_log_osc_to_lov(struct obd_device *obd, struct fs_db *fsdb,
1094 struct mgs_target_info *mti,
1095 char *logname, char *suffix, char *lovname,
1096 enum lustre_sec_part sec_part, int flags);
1097 static void name_create_mdt_and_lov(char **logname, char **lovname,
1098 struct fs_db *fsdb, int i);
1100 static int mgs_steal_llog_handler(const struct lu_env *env,
1101 struct llog_handle *llh,
1102 struct llog_rec_hdr *rec, void *data)
1104 struct obd_device * obd;
1105 struct mgs_target_info *mti, *tmti;
1107 int cfg_len = rec->lrh_len;
1108 char *cfg_buf = (char*) (rec + 1);
1109 struct lustre_cfg *lcfg;
1111 struct llog_handle *mdt_llh = NULL;
1112 static int got_an_osc_or_mdc = 0;
1113 /* 0: not found any osc/mdc;
1117 static int last_step = -1;
1121 mti = ((struct temp_comp*)data)->comp_mti;
1122 tmti = ((struct temp_comp*)data)->comp_tmti;
1123 fsdb = ((struct temp_comp*)data)->comp_fsdb;
1124 obd = ((struct temp_comp*)data)->comp_obd;
1126 if (rec->lrh_type != OBD_CFG_REC) {
1127 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
1131 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
1133 CERROR("Insane cfg\n");
1137 lcfg = (struct lustre_cfg *)cfg_buf;
1139 if (lcfg->lcfg_command == LCFG_MARKER) {
1140 struct cfg_marker *marker;
1141 marker = lustre_cfg_buf(lcfg, 1);
1142 if (!strncmp(marker->cm_comment,"add osc",7) &&
1143 (marker->cm_flags & CM_START)){
1144 got_an_osc_or_mdc = 1;
1145 strncpy(tmti->mti_svname, marker->cm_tgtname,
1146 sizeof(tmti->mti_svname));
1147 rc = record_start_log(obd, &mdt_llh, mti->mti_svname);
1148 rc = record_marker(obd, mdt_llh, fsdb, CM_START,
1149 mti->mti_svname,"add osc(copied)");
1150 rc = record_end_log(obd, &mdt_llh);
1151 last_step = marker->cm_step;
1154 if (!strncmp(marker->cm_comment,"add osc",7) &&
1155 (marker->cm_flags & CM_END)){
1156 LASSERT(last_step == marker->cm_step);
1158 got_an_osc_or_mdc = 0;
1159 rc = record_start_log(obd, &mdt_llh, mti->mti_svname);
1160 rc = record_marker(obd, mdt_llh, fsdb, CM_END,
1161 mti->mti_svname,"add osc(copied)");
1162 rc = record_end_log(obd, &mdt_llh);
1165 if (!strncmp(marker->cm_comment,"add mdc",7) &&
1166 (marker->cm_flags & CM_START)){
1167 got_an_osc_or_mdc = 2;
1168 last_step = marker->cm_step;
1169 memcpy(tmti->mti_svname, marker->cm_tgtname,
1170 strlen(marker->cm_tgtname));
1174 if (!strncmp(marker->cm_comment,"add mdc",7) &&
1175 (marker->cm_flags & CM_END)){
1176 LASSERT(last_step == marker->cm_step);
1178 got_an_osc_or_mdc = 0;
1183 if (got_an_osc_or_mdc == 0 || last_step < 0)
1186 if (lcfg->lcfg_command == LCFG_ADD_UUID) {
1188 nodenid = lcfg->lcfg_nid;
1190 tmti->mti_nids[tmti->mti_nid_count] = nodenid;
1191 tmti->mti_nid_count++;
1196 if (lcfg->lcfg_command == LCFG_SETUP) {
1199 target = lustre_cfg_string(lcfg, 1);
1200 memcpy(tmti->mti_uuid, target, strlen(target));
1204 /* ignore client side sptlrpc_conf_log */
1205 if (lcfg->lcfg_command == LCFG_SPTLRPC_CONF)
1208 if (lcfg->lcfg_command == LCFG_ADD_MDC) {
1211 if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1)
1214 memcpy(tmti->mti_fsname, mti->mti_fsname,
1215 strlen(mti->mti_fsname));
1216 tmti->mti_stripe_index = index;
1218 mgs_write_log_mdc_to_mdt(obd, fsdb, tmti, mti->mti_svname);
1219 memset(tmti, 0, sizeof(*tmti));
1223 if (lcfg->lcfg_command == LCFG_LOV_ADD_OBD) {
1226 char *logname, *lovname;
1228 name_create_mdt_and_lov(&logname, &lovname, fsdb,
1229 mti->mti_stripe_index);
1230 sprintf(mdt_index, "-MDT%04x", mti->mti_stripe_index);
1232 if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1) {
1233 name_destroy(&logname);
1234 name_destroy(&lovname);
1238 tmti->mti_stripe_index = index;
1239 mgs_write_log_osc_to_lov(obd, fsdb, tmti, logname,
1242 name_destroy(&logname);
1243 name_destroy(&lovname);
1249 /* fsdb->fsdb_mutex is already held in mgs_write_log_target*/
1250 /* stealed from mgs_get_fsdb_from_llog*/
1251 static int mgs_steal_llog_for_mdt_from_client(struct obd_device *obd,
1253 struct temp_comp* comp)
1255 struct llog_handle *loghandle;
1256 struct lvfs_run_ctxt saved;
1257 struct mgs_target_info *tmti;
1258 struct llog_ctxt *ctxt;
1262 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
1263 LASSERT(ctxt != NULL);
1265 OBD_ALLOC_PTR(tmti);
1269 comp->comp_tmti = tmti;
1270 comp->comp_obd = obd;
1272 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
1274 rc = llog_create(NULL, ctxt, &loghandle, NULL, client_name);
1278 rc = llog_init_handle(NULL, loghandle, LLOG_F_IS_PLAIN, NULL);
1280 GOTO(out_close, rc);
1282 rc = llog_process(NULL, loghandle, mgs_steal_llog_handler,
1283 (void *)comp, NULL);
1284 CDEBUG(D_MGS, "steal llog re = %d\n", rc);
1286 rc2 = llog_close(NULL, loghandle);
1290 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
1292 llog_ctxt_put(ctxt);
1296 /* lmv is the second thing for client logs */
1297 /* copied from mgs_write_log_lov. Please refer to that. */
1298 static int mgs_write_log_lmv(struct obd_device *obd, struct fs_db *fsdb,
1299 struct mgs_target_info *mti,
1300 char *logname, char *lmvname)
1302 struct llog_handle *llh = NULL;
1303 struct lmv_desc *lmvdesc;
1308 CDEBUG(D_MGS, "Writing lmv(%s) log for %s\n", lmvname,logname);
1310 OBD_ALLOC_PTR(lmvdesc);
1311 if (lmvdesc == NULL)
1313 lmvdesc->ld_active_tgt_count = 0;
1314 lmvdesc->ld_tgt_count = 0;
1315 sprintf((char*)lmvdesc->ld_uuid.uuid, "%s_UUID", lmvname);
1316 uuid = (char *)lmvdesc->ld_uuid.uuid;
1318 rc = record_start_log(obd, &llh, logname);
1319 rc = record_marker(obd, llh, fsdb, CM_START, lmvname, "lmv setup");
1320 rc = record_attach(obd, llh, lmvname, "lmv", uuid);
1321 rc = record_lmv_setup(obd, llh, lmvname, lmvdesc);
1322 rc = record_marker(obd, llh, fsdb, CM_END, lmvname, "lmv setup");
1323 rc = record_end_log(obd, &llh);
1325 OBD_FREE_PTR(lmvdesc);
1329 /* lov is the first thing in the mdt and client logs */
1330 static int mgs_write_log_lov(struct obd_device *obd, struct fs_db *fsdb,
1331 struct mgs_target_info *mti,
1332 char *logname, char *lovname)
1334 struct llog_handle *llh = NULL;
1335 struct lov_desc *lovdesc;
1340 CDEBUG(D_MGS, "Writing lov(%s) log for %s\n", lovname, logname);
1343 #01 L attach 0:lov_mdsA 1:lov 2:71ccb_lov_mdsA_19f961a9e1
1344 #02 L lov_setup 0:lov_mdsA 1:(struct lov_desc)
1345 uuid=lov1_UUID, stripe count=1, size=1048576, offset=0, pattern=0
1348 /* FIXME just make lov_setup accept empty desc (put uuid in buf 2) */
1349 OBD_ALLOC_PTR(lovdesc);
1350 if (lovdesc == NULL)
1352 lovdesc->ld_magic = LOV_DESC_MAGIC;
1353 lovdesc->ld_tgt_count = 0;
1354 /* Defaults. Can be changed later by lcfg config_param */
1355 lovdesc->ld_default_stripe_count = 1;
1356 lovdesc->ld_pattern = LOV_PATTERN_RAID0;
1357 lovdesc->ld_default_stripe_size = 1024 * 1024;
1358 lovdesc->ld_default_stripe_offset = -1;
1359 lovdesc->ld_qos_maxage = QOS_DEFAULT_MAXAGE;
1360 sprintf((char*)lovdesc->ld_uuid.uuid, "%s_UUID", lovname);
1361 /* can these be the same? */
1362 uuid = (char *)lovdesc->ld_uuid.uuid;
1364 /* This should always be the first entry in a log.
1365 rc = mgs_clear_log(obd, logname); */
1366 rc = record_start_log(obd, &llh, logname);
1369 /* FIXME these should be a single journal transaction */
1370 rc = record_marker(obd, llh, fsdb, CM_START, lovname, "lov setup");
1371 rc = record_attach(obd, llh, lovname, "lov", uuid);
1372 rc = record_lov_setup(obd, llh, lovname, lovdesc);
1373 rc = record_marker(obd, llh, fsdb, CM_END, lovname, "lov setup");
1374 rc = record_end_log(obd, &llh);
1378 OBD_FREE_PTR(lovdesc);
1382 /* add failnids to open log */
1383 static int mgs_write_log_failnids(struct obd_device *obd,
1384 struct mgs_target_info *mti,
1385 struct llog_handle *llh,
1388 char *failnodeuuid = NULL;
1389 char *ptr = mti->mti_params;
1394 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) nal=90 0: 1:uml1_UUID
1395 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
1396 #05 L setup 0:OSC_uml1_ost1_mdsA 1:ost1_UUID 2:uml1_UUID
1397 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) nal=90 0: 1:uml2_UUID
1398 #0x L add_uuid nid=2@elan(0x1000000000002) nal=90 0: 1:uml2_UUID
1399 #07 L add_conn 0:OSC_uml1_ost1_mdsA 1:uml2_UUID
1402 /* Pull failnid info out of params string */
1403 while (class_find_param(ptr, PARAM_FAILNODE, &ptr) == 0) {
1404 while (class_parse_nid(ptr, &nid, &ptr) == 0) {
1405 if (failnodeuuid == NULL) {
1406 /* We don't know the failover node name,
1407 so just use the first nid as the uuid */
1408 rc = name_create(&failnodeuuid,
1409 libcfs_nid2str(nid), "");
1413 CDEBUG(D_MGS, "add nid %s for failover uuid %s, "
1414 "client %s\n", libcfs_nid2str(nid),
1415 failnodeuuid, cliname);
1416 rc = record_add_uuid(obd, llh, nid, failnodeuuid);
1419 rc = record_add_conn(obd, llh, cliname, failnodeuuid);
1420 name_destroy(&failnodeuuid);
1421 failnodeuuid = NULL;
1428 static int mgs_write_log_mdc_to_lmv(struct obd_device *obd, struct fs_db *fsdb,
1429 struct mgs_target_info *mti,
1430 char *logname, char *lmvname)
1432 struct llog_handle *llh = NULL;
1433 char *mdcname, *nodeuuid, *mdcuuid, *lmvuuid;
1438 if (mgs_log_is_empty(obd, logname)) {
1439 CERROR("log is empty! Logical error\n");
1443 CDEBUG(D_MGS, "adding mdc for %s to log %s:lmv(%s)\n",
1444 mti->mti_svname, logname, lmvname);
1446 name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
1447 name_create(&mdcname, mti->mti_svname, "-mdc");
1448 name_create(&mdcuuid, mdcname, "_UUID");
1449 name_create(&lmvuuid, lmvname, "_UUID");
1451 rc = record_start_log(obd, &llh, logname);
1452 rc = record_marker(obd, llh, fsdb, CM_START, mti->mti_svname,
1455 for (i = 0; i < mti->mti_nid_count; i++) {
1456 CDEBUG(D_MGS, "add nid %s for mdt\n",
1457 libcfs_nid2str(mti->mti_nids[i]));
1459 rc = record_add_uuid(obd, llh, mti->mti_nids[i], nodeuuid);
1462 rc = record_attach(obd, llh, mdcname, LUSTRE_MDC_NAME, lmvuuid);
1463 rc = record_setup(obd, llh, mdcname, mti->mti_uuid, nodeuuid, 0, 0);
1464 rc = mgs_write_log_failnids(obd, mti, llh, mdcname);
1465 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
1466 rc = record_mdc_add(obd, llh, lmvname, mdcuuid, mti->mti_uuid,
1468 rc = record_marker(obd, llh, fsdb, CM_END, mti->mti_svname,
1470 rc = record_end_log(obd, &llh);
1472 name_destroy(&lmvuuid);
1473 name_destroy(&mdcuuid);
1474 name_destroy(&mdcname);
1475 name_destroy(&nodeuuid);
1479 /* add new mdc to already existent MDS */
1480 static int mgs_write_log_mdc_to_mdt(struct obd_device *obd, struct fs_db *fsdb,
1481 struct mgs_target_info *mti, char *logname)
1483 struct llog_handle *llh = NULL;
1484 char *nodeuuid, *mdcname, *mdcuuid, *mdtuuid;
1485 int idx = mti->mti_stripe_index;
1490 if (mgs_log_is_empty(obd, logname)) {
1491 CERROR("log is empty! Logical error\n");
1495 CDEBUG(D_MGS, "adding mdc index %d to %s\n", idx, logname);
1497 name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
1498 snprintf(index, sizeof(index), "-mdc%04x", idx);
1499 name_create(&mdcname, logname, index);
1500 name_create(&mdcuuid, mdcname, "_UUID");
1501 name_create(&mdtuuid, logname, "_UUID");
1503 rc = record_start_log(obd, &llh, logname);
1504 rc = record_marker(obd, llh, fsdb, CM_START, mti->mti_svname, "add mdc");
1505 for (i = 0; i < mti->mti_nid_count; i++) {
1506 CDEBUG(D_MGS, "add nid %s for mdt\n",
1507 libcfs_nid2str(mti->mti_nids[i]));
1508 rc = record_add_uuid(obd, llh, mti->mti_nids[i], nodeuuid);
1510 rc = record_attach(obd, llh, mdcname, LUSTRE_MDC_NAME, mdcuuid);
1511 rc = record_setup(obd, llh, mdcname, mti->mti_uuid, nodeuuid, 0, 0);
1512 rc = mgs_write_log_failnids(obd, mti, llh, mdcname);
1513 snprintf(index, sizeof(index), "%d", idx);
1515 rc = record_mdc_add(obd, llh, logname, mdcuuid, mti->mti_uuid,
1517 rc = record_marker(obd, llh, fsdb, CM_END, mti->mti_svname, "add mdc");
1518 rc = record_end_log(obd, &llh);
1520 name_destroy(&mdcuuid);
1521 name_destroy(&mdcname);
1522 name_destroy(&nodeuuid);
1523 name_destroy(&mdtuuid);
1527 static int mgs_write_log_mdt0(struct obd_device *obd, struct fs_db *fsdb,
1528 struct mgs_target_info *mti)
1530 char *log = mti->mti_svname;
1531 struct llog_handle *llh = NULL;
1532 char *uuid, *lovname;
1534 char *ptr = mti->mti_params;
1535 int rc = 0, failout = 0;
1538 OBD_ALLOC(uuid, sizeof(struct obd_uuid));
1542 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
1543 failout = (strncmp(ptr, "failout", 7) == 0);
1545 name_create(&lovname, log, "-mdtlov");
1546 if (mgs_log_is_empty(obd, log))
1547 rc = mgs_write_log_lov(obd, fsdb, mti, log, lovname);
1549 sprintf(uuid, "%s_UUID", log);
1550 sprintf(mdt_index, "%d", mti->mti_stripe_index);
1552 /* add MDT itself */
1553 rc = record_start_log(obd, &llh, log);
1557 /* FIXME this whole fn should be a single journal transaction */
1558 rc = record_marker(obd, llh, fsdb, CM_START, log, "add mdt");
1559 rc = record_attach(obd, llh, log, LUSTRE_MDT_NAME, uuid);
1560 rc = record_mount_opt(obd, llh, log, lovname, NULL);
1561 rc = record_setup(obd, llh, log, uuid, mdt_index, lovname,
1562 failout ? "n" : "f");
1563 rc = record_marker(obd, llh, fsdb, CM_END, log, "add mdt");
1564 rc = record_end_log(obd, &llh);
1566 name_destroy(&lovname);
1567 OBD_FREE(uuid, sizeof(struct obd_uuid));
1571 static inline void name_create_mdt(char **logname, char *fsname, int i)
1575 sprintf(mdt_index, "-MDT%04x", i);
1576 name_create(logname, fsname, mdt_index);
1579 static void name_create_mdt_and_lov(char **logname, char **lovname,
1580 struct fs_db *fsdb, int i)
1582 name_create_mdt(logname, fsdb->fsdb_name, i);
1584 if (i == 0 && cfs_test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
1585 name_create(lovname, fsdb->fsdb_name, "-mdtlov");
1587 name_create(lovname, *logname, "-mdtlov");
1590 static inline void name_create_mdt_osc(char **oscname, char *ostname,
1591 struct fs_db *fsdb, int i)
1595 if (i == 0 && cfs_test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
1596 sprintf(suffix, "-osc");
1598 sprintf(suffix, "-osc-MDT%04x", i);
1599 name_create(oscname, ostname, suffix);
1602 /* envelope method for all layers log */
1603 static int mgs_write_log_mdt(struct obd_device *obd, struct fs_db *fsdb,
1604 struct mgs_target_info *mti)
1606 struct llog_handle *llh = NULL;
1608 struct temp_comp comp = { 0 };
1612 CDEBUG(D_MGS, "writing new mdt %s\n", mti->mti_svname);
1616 if (mti->mti_flags & LDD_F_UPGRADE14) {
1617 /* We're starting with an old uuid. Assume old name for lov
1618 as well since the lov entry already exists in the log. */
1619 CDEBUG(D_MGS, "old mds uuid %s\n", mti->mti_uuid);
1620 if (strncmp(mti->mti_uuid, fsdb->fsdb_mdtlov + 4,
1621 strlen(fsdb->fsdb_mdtlov) - 4) != 0) {
1622 CERROR("old mds uuid %s doesn't match log %s (%s)\n",
1623 mti->mti_uuid, fsdb->fsdb_mdtlov,
1624 fsdb->fsdb_mdtlov + 4);
1628 /* end COMPAT_146 */
1630 if (mti->mti_uuid[0] == '\0') {
1631 /* Make up our own uuid */
1632 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
1633 "%s_UUID", mti->mti_svname);
1637 rc = mgs_write_log_mdt0(obd, fsdb, mti);
1639 /* Append the mdt info to the client log */
1640 name_create(&cliname, mti->mti_fsname, "-client");
1642 if (mgs_log_is_empty(obd, cliname)) {
1643 /* Start client log */
1644 rc = mgs_write_log_lov(obd, fsdb, mti, cliname,
1646 rc = mgs_write_log_lmv(obd, fsdb, mti, cliname,
1651 #09 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
1652 #10 L attach 0:MDC_uml1_mdsA_MNT_client 1:mdc 2:1d834_MNT_client_03f
1653 #11 L setup 0:MDC_uml1_mdsA_MNT_client 1:mdsA_UUID 2:uml1_UUID
1654 #12 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
1655 #13 L add_conn 0:MDC_uml1_mdsA_MNT_client 1:uml2_UUID
1656 #14 L mount_option 0: 1:client 2:lov1 3:MDC_uml1_mdsA_MNT_client
1661 if (mti->mti_flags & LDD_F_UPGRADE14) {
1662 rc = record_start_log(obd, &llh, cliname);
1666 rc = record_marker(obd, llh, fsdb, CM_START,
1667 mti->mti_svname,"add mdc");
1669 /* Old client log already has MDC entry, but needs mount opt
1670 for new client name (lustre-client) */
1671 /* FIXME Old MDT log already has an old mount opt
1672 which we should remove (currently handled by
1673 class_del_profiles()) */
1674 rc = record_mount_opt(obd, llh, cliname, fsdb->fsdb_clilov,
1676 /* end COMPAT_146 */
1678 rc = record_marker(obd, llh, fsdb, CM_END,
1679 mti->mti_svname, "add mdc");
1683 /* copy client info about lov/lmv */
1684 comp.comp_mti = mti;
1685 comp.comp_fsdb = fsdb;
1687 rc = mgs_steal_llog_for_mdt_from_client(obd, cliname,
1690 rc = mgs_write_log_mdc_to_lmv(obd, fsdb, mti, cliname,
1693 rc = record_start_log(obd, &llh, cliname);
1697 rc = record_marker(obd, llh, fsdb, CM_START, cliname,
1699 rc = record_mount_opt(obd, llh, cliname, fsdb->fsdb_clilov,
1701 rc = record_marker(obd, llh, fsdb, CM_END, cliname,
1705 rc = record_end_log(obd, &llh);
1707 name_destroy(&cliname);
1709 // for_all_existing_mdt except current one
1710 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
1712 if (i != mti->mti_stripe_index &&
1713 cfs_test_bit(i, fsdb->fsdb_mdt_index_map)) {
1714 name_create_mdt(&mdtname, mti->mti_fsname, i);
1715 rc = mgs_write_log_mdc_to_mdt(obd, fsdb, mti, mdtname);
1716 name_destroy(&mdtname);
1723 /* Add the ost info to the client/mdt lov */
1724 static int mgs_write_log_osc_to_lov(struct obd_device *obd, struct fs_db *fsdb,
1725 struct mgs_target_info *mti,
1726 char *logname, char *suffix, char *lovname,
1727 enum lustre_sec_part sec_part, int flags)
1729 struct llog_handle *llh = NULL;
1730 char *nodeuuid, *oscname, *oscuuid, *lovuuid, *svname;
1735 CDEBUG(D_INFO, "adding osc for %s to log %s\n",
1736 mti->mti_svname, logname);
1738 if (mgs_log_is_empty(obd, logname)) {
1739 CERROR("log is empty! Logical error\n");
1743 name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
1744 name_create(&svname, mti->mti_svname, "-osc");
1745 name_create(&oscname, svname, suffix);
1746 name_create(&oscuuid, oscname, "_UUID");
1747 name_create(&lovuuid, lovname, "_UUID");
1750 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
1752 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
1753 #04 L attach 0:OSC_uml1_ost1_MNT_client 1:osc 2:89070_lov1_a41dff51a
1754 #05 L setup 0:OSC_uml1_ost1_MNT_client 1:ost1_UUID 2:uml1_UUID
1756 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
1757 #07 L add_conn 0:OSC_uml1_ost1_MNT_client 1:uml2_UUID
1758 #08 L lov_modify_tgts add 0:lov1 1:ost1_UUID 2(index):0 3(gen):1
1761 rc = record_start_log(obd, &llh, logname);
1764 /* FIXME these should be a single journal transaction */
1765 rc = record_marker(obd, llh, fsdb, CM_START | flags, mti->mti_svname,
1767 for (i = 0; i < mti->mti_nid_count; i++) {
1768 CDEBUG(D_MGS, "add nid %s\n", libcfs_nid2str(mti->mti_nids[i]));
1769 rc = record_add_uuid(obd, llh, mti->mti_nids[i], nodeuuid);
1771 rc = record_attach(obd, llh, oscname, LUSTRE_OSC_NAME, lovuuid);
1772 rc = record_setup(obd, llh, oscname, mti->mti_uuid, nodeuuid, 0, 0);
1773 rc = mgs_write_log_failnids(obd, mti, llh, oscname);
1774 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
1775 rc = record_lov_add(obd, llh, lovname, mti->mti_uuid, index, "1");
1776 rc = record_marker(obd, llh, fsdb, CM_END | flags, mti->mti_svname,
1778 rc = record_end_log(obd, &llh);
1780 name_destroy(&lovuuid);
1781 name_destroy(&oscuuid);
1782 name_destroy(&oscname);
1783 name_destroy(&svname);
1784 name_destroy(&nodeuuid);
1788 static int mgs_write_log_ost(struct obd_device *obd, struct fs_db *fsdb,
1789 struct mgs_target_info *mti)
1791 struct llog_handle *llh = NULL;
1792 char *logname, *lovname;
1793 char *ptr = mti->mti_params;
1794 int rc, flags = 0, failout = 0, i;
1797 CDEBUG(D_MGS, "writing new ost %s\n", mti->mti_svname);
1799 /* The ost startup log */
1801 /* If the ost log already exists, that means that someone reformatted
1802 the ost and it called target_add again. */
1803 if (!mgs_log_is_empty(obd, mti->mti_svname)) {
1804 LCONSOLE_ERROR_MSG(0x141, "The config log for %s already "
1805 "exists, yet the server claims it never "
1806 "registered. It may have been reformatted, "
1807 "or the index changed. writeconf the MDT to "
1808 "regenerate all logs.\n", mti->mti_svname);
1813 attach obdfilter ost1 ost1_UUID
1814 setup /dev/loop2 ldiskfs f|n errors=remount-ro,user_xattr
1816 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
1817 failout = (strncmp(ptr, "failout", 7) == 0);
1818 rc = record_start_log(obd, &llh, mti->mti_svname);
1821 /* FIXME these should be a single journal transaction */
1822 rc = record_marker(obd, llh, fsdb, CM_START, mti->mti_svname,"add ost");
1823 if (*mti->mti_uuid == '\0')
1824 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
1825 "%s_UUID", mti->mti_svname);
1826 rc = record_attach(obd, llh, mti->mti_svname,
1827 "obdfilter"/*LUSTRE_OST_NAME*/, mti->mti_uuid);
1828 rc = record_setup(obd, llh, mti->mti_svname,
1829 "dev"/*ignored*/, "type"/*ignored*/,
1830 failout ? "n" : "f", 0/*options*/);
1831 rc = record_marker(obd, llh, fsdb, CM_END, mti->mti_svname, "add ost");
1832 rc = record_end_log(obd, &llh);
1834 /* We also have to update the other logs where this osc is part of
1837 if (cfs_test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
1838 /* If we're upgrading, the old mdt log already has our
1839 entry. Let's do a fake one for fun. */
1840 /* Note that we can't add any new failnids, since we don't
1841 know the old osc names. */
1842 flags = CM_SKIP | CM_UPGRADE146;
1844 } else if ((mti->mti_flags & LDD_F_UPDATE) != LDD_F_UPDATE) {
1845 /* If the update flag isn't set, don't update client/mdt
1848 LCONSOLE_WARN("Client log for %s was not updated; writeconf "
1849 "the MDT first to regenerate it.\n",
1853 /* Add ost to all MDT lov defs */
1854 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
1855 if (cfs_test_bit(i, fsdb->fsdb_mdt_index_map)) {
1858 name_create_mdt_and_lov(&logname, &lovname, fsdb, i);
1859 sprintf(mdt_index, "-MDT%04x", i);
1860 mgs_write_log_osc_to_lov(obd, fsdb, mti, logname,
1862 LUSTRE_SP_MDT, flags);
1863 name_destroy(&logname);
1864 name_destroy(&lovname);
1868 /* Append ost info to the client log */
1869 name_create(&logname, mti->mti_fsname, "-client");
1870 if (mgs_log_is_empty(obd, logname)) {
1871 /* Start client log */
1872 rc = mgs_write_log_lov(obd, fsdb, mti, logname,
1874 rc = mgs_write_log_lmv(obd, fsdb, mti, logname,
1877 mgs_write_log_osc_to_lov(obd, fsdb, mti, logname, "",
1878 fsdb->fsdb_clilov, LUSTRE_SP_CLI, flags);
1879 name_destroy(&logname);
1883 static __inline__ int mgs_param_empty(char *ptr)
1887 if ((tmp = strchr(ptr, '=')) && (*(++tmp) == '\0'))
1892 static int mgs_write_log_failnid_internal(struct obd_device *obd,
1894 struct mgs_target_info *mti,
1895 char *logname, char *cliname)
1898 struct llog_handle *llh = NULL;
1900 if (mgs_param_empty(mti->mti_params)) {
1901 /* Remove _all_ failnids */
1902 rc = mgs_modify(obd, fsdb, mti, logname,
1903 mti->mti_svname, "add failnid", CM_SKIP);
1907 /* Otherwise failover nids are additive */
1908 rc = record_start_log(obd, &llh, logname);
1910 /* FIXME this should be a single journal transaction */
1911 rc = record_marker(obd, llh, fsdb, CM_START,
1912 mti->mti_svname, "add failnid");
1913 rc = mgs_write_log_failnids(obd, mti, llh, cliname);
1914 rc = record_marker(obd, llh, fsdb, CM_END,
1915 mti->mti_svname, "add failnid");
1916 rc = record_end_log(obd, &llh);
1923 /* Add additional failnids to an existing log.
1924 The mdc/osc must have been added to logs first */
1925 /* tcp nids must be in dotted-quad ascii -
1926 we can't resolve hostnames from the kernel. */
1927 static int mgs_write_log_add_failnid(struct obd_device *obd, struct fs_db *fsdb,
1928 struct mgs_target_info *mti)
1930 char *logname, *cliname;
1934 /* FIXME we currently can't erase the failnids
1935 * given when a target first registers, since they aren't part of
1936 * an "add uuid" stanza */
1938 /* Verify that we know about this target */
1939 if (mgs_log_is_empty(obd, mti->mti_svname)) {
1940 LCONSOLE_ERROR_MSG(0x142, "The target %s has not registered "
1941 "yet. It must be started before failnids "
1942 "can be added.\n", mti->mti_svname);
1946 /* Create mdc/osc client name (e.g. lustre-OST0001-osc) */
1947 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
1948 name_create(&cliname, mti->mti_svname, "-mdc");
1949 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
1950 name_create(&cliname, mti->mti_svname, "-osc");
1955 /* Add failover nids to the client log */
1956 name_create(&logname, mti->mti_fsname, "-client");
1957 rc = mgs_write_log_failnid_internal(obd, fsdb, mti, logname, cliname);
1958 name_destroy(&logname);
1959 name_destroy(&cliname);
1961 if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
1962 /* Add OST failover nids to the MDT logs as well */
1965 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
1966 if (!cfs_test_bit(i, fsdb->fsdb_mdt_index_map))
1968 name_create_mdt(&logname, mti->mti_fsname, i);
1969 name_create_mdt_osc(&cliname, mti->mti_svname, fsdb, i);
1970 rc = mgs_write_log_failnid_internal(obd, fsdb, mti,
1972 name_destroy(&cliname);
1973 name_destroy(&logname);
1980 static int mgs_wlp_lcfg(struct obd_device *obd, struct fs_db *fsdb,
1981 struct mgs_target_info *mti,
1982 char *logname, struct lustre_cfg_bufs *bufs,
1983 char *tgtname, char *ptr)
1985 char comment[MTI_NAME_MAXLEN];
1987 struct lustre_cfg *lcfg;
1990 /* Erase any old settings of this same parameter */
1991 memcpy(comment, ptr, MTI_NAME_MAXLEN);
1992 comment[MTI_NAME_MAXLEN - 1] = 0;
1993 /* But don't try to match the value. */
1994 if ((tmp = strchr(comment, '=')))
1996 /* FIXME we should skip settings that are the same as old values */
1997 rc = mgs_modify(obd, fsdb, mti, logname, tgtname, comment, CM_SKIP);
1998 del = mgs_param_empty(ptr);
2000 LCONSOLE_INFO("%sing parameter %s.%s in log %s\n", del ? "Disabl" : rc ?
2001 "Sett" : "Modify", tgtname, comment, logname);
2005 lustre_cfg_bufs_reset(bufs, tgtname);
2006 lustre_cfg_bufs_set_string(bufs, 1, ptr);
2007 lcfg = lustre_cfg_new(LCFG_PARAM, bufs);
2010 rc = mgs_write_log_direct(obd, fsdb, logname, lcfg, tgtname, comment);
2011 lustre_cfg_free(lcfg);
2015 /* write global variable settings into log */
2016 static int mgs_write_log_sys(struct obd_device *obd, struct fs_db *fsdb,
2017 struct mgs_target_info *mti, char *sys, char *ptr)
2019 struct lustre_cfg_bufs bufs;
2020 struct lustre_cfg *lcfg;
2022 int rc, cmd, convert = 1;
2024 if (class_match_param(ptr, PARAM_TIMEOUT, &tmp) == 0) {
2025 cmd = LCFG_SET_TIMEOUT;
2026 } else if (class_match_param(ptr, PARAM_LDLM_TIMEOUT, &tmp) == 0) {
2027 cmd = LCFG_SET_LDLM_TIMEOUT;
2028 /* Check for known params here so we can return error to lctl */
2029 } else if ((class_match_param(ptr, PARAM_AT_MIN, &tmp) == 0) ||
2030 (class_match_param(ptr, PARAM_AT_MAX, &tmp) == 0) ||
2031 (class_match_param(ptr, PARAM_AT_EXTRA, &tmp) == 0) ||
2032 (class_match_param(ptr, PARAM_AT_EARLY_MARGIN, &tmp) == 0) ||
2033 (class_match_param(ptr, PARAM_AT_HISTORY, &tmp) == 0)) {
2035 } else if (class_match_param(ptr, PARAM_JOBID_VAR, &tmp) == 0) {
2036 convert = 0; /* Don't convert string value to integer */
2042 if (mgs_param_empty(ptr))
2043 CDEBUG(D_MGS, "global '%s' removed\n", sys);
2045 CDEBUG(D_MGS, "global '%s' val=%s\n", sys, tmp);
2047 lustre_cfg_bufs_reset(&bufs, NULL);
2048 lustre_cfg_bufs_set_string(&bufs, 1, sys);
2049 if (!convert && *tmp != '\0')
2050 lustre_cfg_bufs_set_string(&bufs, 2, tmp);
2051 lcfg = lustre_cfg_new(cmd, &bufs);
2052 lcfg->lcfg_num = convert ? simple_strtoul(tmp, NULL, 0) : 0;
2053 /* truncate the comment to the parameter name */
2057 /* modify all servers and clients */
2058 rc = mgs_write_log_direct_all(obd, fsdb, mti,
2059 *tmp == '\0' ? NULL : lcfg,
2060 mti->mti_fsname, sys, 0);
2061 if (rc == 0 && *tmp != '\0') {
2063 case LCFG_SET_TIMEOUT:
2064 if (!obd_timeout_set || lcfg->lcfg_num > obd_timeout)
2065 class_process_config(lcfg);
2067 case LCFG_SET_LDLM_TIMEOUT:
2068 if (!ldlm_timeout_set || lcfg->lcfg_num > ldlm_timeout)
2069 class_process_config(lcfg);
2076 lustre_cfg_free(lcfg);
2080 /* write quota settings into log */
2081 static int mgs_write_log_quota(struct obd_device *obd, struct fs_db *fsdb,
2082 struct mgs_target_info *mti, char *quota,
2085 struct lustre_cfg_bufs bufs;
2086 struct lustre_cfg *lcfg;
2089 int cmd = LCFG_PARAM;
2092 /* support only 'meta' and 'data' pools so far */
2093 if (class_match_param(ptr, QUOTA_METAPOOL_NAME, &tmp) != 0 &&
2094 class_match_param(ptr, QUOTA_DATAPOOL_NAME, &tmp) != 0) {
2095 CERROR("parameter quota.%s isn't supported (only quota.mdt "
2096 "& quota.ost are)\n", ptr);
2101 CDEBUG(D_MGS, "global '%s' removed\n", quota);
2103 CDEBUG(D_MGS, "global '%s'\n", quota);
2105 if (strchr(tmp, 'u') == NULL && strchr(tmp, 'g') == NULL &&
2106 strcmp(tmp, "none") != 0) {
2107 CERROR("enable option(%s) isn't supported\n", tmp);
2112 lustre_cfg_bufs_reset(&bufs, NULL);
2113 lustre_cfg_bufs_set_string(&bufs, 1, quota);
2114 lcfg = lustre_cfg_new(cmd, &bufs);
2115 /* truncate the comment to the parameter name */
2120 /* XXX we duplicated quota enable information in all server
2121 * config logs, it should be moved to a separate config
2122 * log once we cleanup the config log for global param. */
2123 /* modify all servers */
2124 rc = mgs_write_log_direct_all(obd, fsdb, mti,
2125 *tmp == '\0' ? NULL : lcfg,
2126 mti->mti_fsname, quota, 1);
2128 lustre_cfg_free(lcfg);
2132 static int mgs_srpc_set_param_disk(struct obd_device *obd,
2134 struct mgs_target_info *mti,
2137 struct llog_handle *llh = NULL;
2139 char *comment, *ptr;
2140 struct lustre_cfg_bufs bufs;
2141 struct lustre_cfg *lcfg;
2146 ptr = strchr(param, '=');
2150 OBD_ALLOC(comment, len + 1);
2151 if (comment == NULL)
2153 strncpy(comment, param, len);
2154 comment[len] = '\0';
2157 lustre_cfg_bufs_reset(&bufs, mti->mti_svname);
2158 lustre_cfg_bufs_set_string(&bufs, 1, param);
2159 lcfg = lustre_cfg_new(LCFG_SPTLRPC_CONF, &bufs);
2161 GOTO(out_comment, rc = -ENOMEM);
2163 /* construct log name */
2164 rc = name_create(&logname, mti->mti_fsname, "-sptlrpc");
2168 if (mgs_log_is_empty(obd, logname)) {
2169 rc = record_start_log(obd, &llh, logname);
2170 record_end_log(obd, &llh);
2175 /* obsolete old one */
2176 mgs_modify(obd, fsdb, mti, logname, mti->mti_svname, comment, CM_SKIP);
2178 /* write the new one */
2179 rc = mgs_write_log_direct(obd, fsdb, logname, lcfg,
2180 mti->mti_svname, comment);
2182 CERROR("err %d writing log %s\n", rc, logname);
2185 name_destroy(&logname);
2187 lustre_cfg_free(lcfg);
2189 OBD_FREE(comment, len + 1);
2193 static int mgs_srpc_set_param_udesc_mem(struct fs_db *fsdb,
2198 /* disable the adjustable udesc parameter for now, i.e. use default
2199 * setting that client always ship udesc to MDT if possible. to enable
2200 * it simply remove the following line */
2203 ptr = strchr(param, '=');
2208 if (strcmp(param, PARAM_SRPC_UDESC))
2211 if (strcmp(ptr, "yes") == 0) {
2212 cfs_set_bit(FSDB_UDESC, &fsdb->fsdb_flags);
2213 CWARN("Enable user descriptor shipping from client to MDT\n");
2214 } else if (strcmp(ptr, "no") == 0) {
2215 cfs_clear_bit(FSDB_UDESC, &fsdb->fsdb_flags);
2216 CWARN("Disable user descriptor shipping from client to MDT\n");
2224 CERROR("Invalid param: %s\n", param);
2228 static int mgs_srpc_set_param_mem(struct fs_db *fsdb,
2232 struct sptlrpc_rule rule;
2233 struct sptlrpc_rule_set *rset;
2237 if (strncmp(param, PARAM_SRPC, sizeof(PARAM_SRPC) - 1) != 0) {
2238 CERROR("Invalid sptlrpc parameter: %s\n", param);
2242 if (strncmp(param, PARAM_SRPC_UDESC,
2243 sizeof(PARAM_SRPC_UDESC) - 1) == 0) {
2244 RETURN(mgs_srpc_set_param_udesc_mem(fsdb, param));
2247 if (strncmp(param, PARAM_SRPC_FLVR, sizeof(PARAM_SRPC_FLVR) - 1) != 0) {
2248 CERROR("Invalid sptlrpc flavor parameter: %s\n", param);
2252 param += sizeof(PARAM_SRPC_FLVR) - 1;
2254 rc = sptlrpc_parse_rule(param, &rule);
2258 /* mgs rules implies must be mgc->mgs */
2259 if (cfs_test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
2260 if ((rule.sr_from != LUSTRE_SP_MGC &&
2261 rule.sr_from != LUSTRE_SP_ANY) ||
2262 (rule.sr_to != LUSTRE_SP_MGS &&
2263 rule.sr_to != LUSTRE_SP_ANY))
2267 /* preapre room for this coming rule. svcname format should be:
2268 * - fsname: general rule
2269 * - fsname-tgtname: target-specific rule
2271 if (strchr(svname, '-')) {
2272 struct mgs_tgt_srpc_conf *tgtconf;
2275 for (tgtconf = fsdb->fsdb_srpc_tgt; tgtconf != NULL;
2276 tgtconf = tgtconf->mtsc_next) {
2277 if (!strcmp(tgtconf->mtsc_tgt, svname)) {
2286 OBD_ALLOC_PTR(tgtconf);
2287 if (tgtconf == NULL)
2290 name_len = strlen(svname);
2292 OBD_ALLOC(tgtconf->mtsc_tgt, name_len + 1);
2293 if (tgtconf->mtsc_tgt == NULL) {
2294 OBD_FREE_PTR(tgtconf);
2297 memcpy(tgtconf->mtsc_tgt, svname, name_len);
2299 tgtconf->mtsc_next = fsdb->fsdb_srpc_tgt;
2300 fsdb->fsdb_srpc_tgt = tgtconf;
2303 rset = &tgtconf->mtsc_rset;
2305 rset = &fsdb->fsdb_srpc_gen;
2308 rc = sptlrpc_rule_set_merge(rset, &rule);
2313 static int mgs_srpc_set_param(struct obd_device *obd,
2315 struct mgs_target_info *mti,
2325 /* keep a copy of original param, which could be destroied
2327 copy_size = strlen(param) + 1;
2328 OBD_ALLOC(copy, copy_size);
2331 memcpy(copy, param, copy_size);
2333 rc = mgs_srpc_set_param_mem(fsdb, mti->mti_svname, param);
2337 /* previous steps guaranteed the syntax is correct */
2338 rc = mgs_srpc_set_param_disk(obd, fsdb, mti, copy);
2342 if (cfs_test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
2344 * for mgs rules, make them effective immediately.
2346 LASSERT(fsdb->fsdb_srpc_tgt == NULL);
2347 sptlrpc_target_update_exp_flavor(obd, &fsdb->fsdb_srpc_gen);
2351 OBD_FREE(copy, copy_size);
2355 struct mgs_srpc_read_data {
2356 struct fs_db *msrd_fsdb;
2360 static int mgs_srpc_read_handler(const struct lu_env *env,
2361 struct llog_handle *llh,
2362 struct llog_rec_hdr *rec, void *data)
2364 struct mgs_srpc_read_data *msrd = data;
2365 struct cfg_marker *marker;
2366 struct lustre_cfg *lcfg = (struct lustre_cfg *)(rec + 1);
2367 char *svname, *param;
2371 if (rec->lrh_type != OBD_CFG_REC) {
2372 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
2376 cfg_len = rec->lrh_len - sizeof(struct llog_rec_hdr) -
2377 sizeof(struct llog_rec_tail);
2379 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
2381 CERROR("Insane cfg\n");
2385 if (lcfg->lcfg_command == LCFG_MARKER) {
2386 marker = lustre_cfg_buf(lcfg, 1);
2388 if (marker->cm_flags & CM_START &&
2389 marker->cm_flags & CM_SKIP)
2390 msrd->msrd_skip = 1;
2391 if (marker->cm_flags & CM_END)
2392 msrd->msrd_skip = 0;
2397 if (msrd->msrd_skip)
2400 if (lcfg->lcfg_command != LCFG_SPTLRPC_CONF) {
2401 CERROR("invalid command (%x)\n", lcfg->lcfg_command);
2405 svname = lustre_cfg_string(lcfg, 0);
2406 if (svname == NULL) {
2407 CERROR("svname is empty\n");
2411 param = lustre_cfg_string(lcfg, 1);
2412 if (param == NULL) {
2413 CERROR("param is empty\n");
2417 rc = mgs_srpc_set_param_mem(msrd->msrd_fsdb, svname, param);
2419 CERROR("read sptlrpc record error (%d): %s\n", rc, param);
2424 int mgs_get_fsdb_srpc_from_llog(struct obd_device *obd,
2427 struct llog_handle *llh = NULL;
2428 struct lvfs_run_ctxt saved;
2429 struct llog_ctxt *ctxt;
2431 struct mgs_srpc_read_data msrd;
2435 /* construct log name */
2436 rc = name_create(&logname, fsdb->fsdb_name, "-sptlrpc");
2440 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
2441 LASSERT(ctxt != NULL);
2443 if (mgs_log_is_empty(obd, logname))
2446 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
2448 rc = llog_create(NULL, ctxt, &llh, NULL, logname);
2452 rc = llog_init_handle(NULL, llh, LLOG_F_IS_PLAIN, NULL);
2454 GOTO(out_close, rc);
2456 if (llog_get_size(llh) <= 1)
2457 GOTO(out_close, rc = 0);
2459 msrd.msrd_fsdb = fsdb;
2462 rc = llog_process(NULL, llh, mgs_srpc_read_handler, (void *) &msrd,
2466 llog_close(NULL, llh);
2468 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
2470 llog_ctxt_put(ctxt);
2471 name_destroy(&logname);
2474 CERROR("failed to read sptlrpc config database: %d\n", rc);
2478 /* Permanent settings of all parameters by writing into the appropriate
2479 * configuration logs.
2480 * A parameter with null value ("<param>='\0'") means to erase it out of
2483 static int mgs_write_log_param(struct obd_device *obd, struct fs_db *fsdb,
2484 struct mgs_target_info *mti, char *ptr)
2486 struct lustre_cfg_bufs bufs;
2489 int rc = 0, rc2 = 0;
2492 /* For various parameter settings, we have to figure out which logs
2493 care about them (e.g. both mdt and client for lov settings) */
2494 CDEBUG(D_MGS, "next param '%s'\n", ptr);
2496 /* The params are stored in MOUNT_DATA_FILE and modified via
2497 tunefs.lustre, or set using lctl conf_param */
2499 /* Processed in lustre_start_mgc */
2500 if (class_match_param(ptr, PARAM_MGSNODE, NULL) == 0)
2503 /* Processed in ost/mdt */
2504 if (class_match_param(ptr, PARAM_NETWORK, NULL) == 0)
2507 /* Processed in mgs_write_log_ost */
2508 if (class_match_param(ptr, PARAM_FAILMODE, NULL) == 0) {
2509 if (mti->mti_flags & LDD_F_PARAM) {
2510 LCONSOLE_ERROR_MSG(0x169, "%s can only be "
2511 "changed with tunefs.lustre"
2512 "and --writeconf\n", ptr);
2518 if (class_match_param(ptr, PARAM_SRPC, NULL) == 0) {
2519 rc = mgs_srpc_set_param(obd, fsdb, mti, ptr);
2523 if (class_match_param(ptr, PARAM_FAILNODE, NULL) == 0) {
2524 /* Add a failover nidlist */
2526 /* We already processed failovers params for new
2527 targets in mgs_write_log_target */
2528 if (mti->mti_flags & LDD_F_PARAM) {
2529 CDEBUG(D_MGS, "Adding failnode\n");
2530 rc = mgs_write_log_add_failnid(obd, fsdb, mti);
2535 if (class_match_param(ptr, PARAM_SYS, &tmp) == 0) {
2536 rc = mgs_write_log_sys(obd, fsdb, mti, ptr, tmp);
2540 if (class_match_param(ptr, PARAM_QUOTA, &tmp) == 0) {
2541 rc = mgs_write_log_quota(obd, fsdb, mti, ptr, tmp);
2545 if (class_match_param(ptr, PARAM_OSC""PARAM_ACTIVE, &tmp) == 0) {
2546 /* active=0 means off, anything else means on */
2547 int flag = (*tmp == '0') ? CM_EXCLUDE : 0;
2550 if (!(mti->mti_flags & LDD_F_SV_TYPE_OST)) {
2551 LCONSOLE_ERROR_MSG(0x144, "%s: Only OSCs can "
2552 "be (de)activated.\n",
2554 GOTO(end, rc = -EINVAL);
2556 LCONSOLE_WARN("Permanently %sactivating %s\n",
2557 flag ? "de": "re", mti->mti_svname);
2559 name_create(&logname, mti->mti_fsname, "-client");
2560 rc = mgs_modify(obd, fsdb, mti, logname,
2561 mti->mti_svname, "add osc", flag);
2562 name_destroy(&logname);
2566 /* Add to all MDT logs for CMD */
2567 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2568 if (!cfs_test_bit(i, fsdb->fsdb_mdt_index_map))
2570 name_create_mdt(&logname, mti->mti_fsname, i);
2571 rc = mgs_modify(obd, fsdb, mti, logname,
2572 mti->mti_svname, "add osc", flag);
2573 name_destroy(&logname);
2579 LCONSOLE_ERROR_MSG(0x145, "Couldn't find %s in"
2580 "log (%d). No permanent "
2581 "changes were made to the "
2583 mti->mti_svname, rc);
2584 if (cfs_test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags))
2585 LCONSOLE_ERROR_MSG(0x146, "This may be"
2590 "update the logs.\n");
2593 /* Fall through to osc proc for deactivating live OSC
2594 on running MDT / clients. */
2596 /* Below here, let obd's XXX_process_config methods handle it */
2598 /* All lov. in proc */
2599 if (class_match_param(ptr, PARAM_LOV, NULL) == 0) {
2602 CDEBUG(D_MGS, "lov param %s\n", ptr);
2603 if (!(mti->mti_flags & LDD_F_SV_TYPE_MDT)) {
2604 LCONSOLE_ERROR_MSG(0x147, "LOV params must be "
2605 "set on the MDT, not %s. "
2612 if (mgs_log_is_empty(obd, mti->mti_svname))
2613 GOTO(end, rc = -ENODEV);
2615 name_create_mdt_and_lov(&logname, &mdtlovname, fsdb,
2616 mti->mti_stripe_index);
2617 rc = mgs_wlp_lcfg(obd, fsdb, mti, mti->mti_svname,
2618 &bufs, mdtlovname, ptr);
2619 name_destroy(&logname);
2620 name_destroy(&mdtlovname);
2625 name_create(&logname, mti->mti_fsname, "-client");
2626 rc = mgs_wlp_lcfg(obd, fsdb, mti, logname, &bufs,
2627 fsdb->fsdb_clilov, ptr);
2628 name_destroy(&logname);
2632 /* All osc., mdc., llite. params in proc */
2633 if ((class_match_param(ptr, PARAM_OSC, NULL) == 0) ||
2634 (class_match_param(ptr, PARAM_MDC, NULL) == 0) ||
2635 (class_match_param(ptr, PARAM_LLITE, NULL) == 0)) {
2637 if (memcmp(ptr, PARAM_LLITE, strlen(PARAM_LLITE)) == 0) {
2638 name_create(&cname, mti->mti_fsname, "-client");
2639 /* Add the client type to match the obdname in
2640 class_config_llog_handler */
2641 } else if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
2644 name_create(&cname, fsdb->fsdb_mdc, "");
2646 name_create(&cname, mti->mti_svname,
2648 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2650 if (cfs_test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
2651 LCONSOLE_ERROR_MSG(0x148, "Upgraded "
2652 "client logs for %s"
2654 "modified. Consider"
2656 "configuration with"
2659 /* We don't know the names of all the
2661 GOTO(end, rc = -EINVAL);
2663 name_create(&cname, mti->mti_svname, "-osc");
2665 GOTO(end, rc = -EINVAL);
2668 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
2671 name_create(&logname, mti->mti_fsname, "-client");
2672 rc = mgs_wlp_lcfg(obd, fsdb, mti, logname, &bufs,
2675 /* osc params affect the MDT as well */
2676 if (!rc && (mti->mti_flags & LDD_F_SV_TYPE_OST)) {
2679 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
2680 if (!cfs_test_bit(i, fsdb->fsdb_mdt_index_map))
2682 name_destroy(&cname);
2683 name_create_mdt_osc(&cname, mti->mti_svname,
2685 name_destroy(&logname);
2686 name_create_mdt(&logname, mti->mti_fsname, i);
2687 if (!mgs_log_is_empty(obd, logname))
2688 rc = mgs_wlp_lcfg(obd, fsdb,mti,logname,
2694 name_destroy(&logname);
2695 name_destroy(&cname);
2699 /* All mdt. params in proc */
2700 if (class_match_param(ptr, PARAM_MDT, NULL) == 0) {
2704 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
2705 if (strncmp(mti->mti_svname, mti->mti_fsname,
2706 MTI_NAME_MAXLEN) == 0)
2707 /* device is unspecified completely? */
2708 rc = LDD_F_SV_TYPE_MDT | LDD_F_SV_ALL;
2710 rc = server_name2index(mti->mti_svname, &idx, NULL);
2713 if ((rc & LDD_F_SV_TYPE_MDT) == 0)
2715 if (rc & LDD_F_SV_ALL) {
2716 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2717 if (!cfs_test_bit(i,
2718 fsdb->fsdb_mdt_index_map))
2720 name_create_mdt(&logname, mti->mti_fsname, i);
2721 rc = mgs_wlp_lcfg(obd, fsdb, mti,
2724 name_destroy(&logname);
2729 rc = mgs_wlp_lcfg(obd, fsdb, mti,
2730 mti->mti_svname, &bufs,
2731 mti->mti_svname, ptr);
2738 /* All mdd., ost. params in proc */
2739 if ((class_match_param(ptr, PARAM_MDD, NULL) == 0) ||
2740 (class_match_param(ptr, PARAM_OST, NULL) == 0)) {
2741 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
2742 if (mgs_log_is_empty(obd, mti->mti_svname))
2743 GOTO(end, rc = -ENODEV);
2745 rc = mgs_wlp_lcfg(obd, fsdb, mti, mti->mti_svname,
2746 &bufs, mti->mti_svname, ptr);
2750 LCONSOLE_WARN("Ignoring unrecognized param '%s'\n", ptr);
2755 CERROR("err %d on param '%s'\n", rc, ptr);
2760 /* Not implementing automatic failover nid addition at this time. */
2761 int mgs_check_failnid(struct obd_device *obd, struct mgs_target_info *mti)
2768 rc = mgs_find_or_make_fsdb(obd, fsname, &fsdb);
2772 if (mgs_log_is_empty(obd, mti->mti_svname))
2773 /* should never happen */
2776 CDEBUG(D_MGS, "Checking for new failnids for %s\n", mti->mti_svname);
2778 /* FIXME We can just check mti->params to see if we're already in
2779 the failover list. Modify mti->params for rewriting back at
2780 server_register_target(). */
2782 cfs_mutex_lock(&fsdb->fsdb_mutex);
2783 rc = mgs_write_log_add_failnid(obd, fsdb, mti);
2784 cfs_mutex_unlock(&fsdb->fsdb_mutex);
2791 int mgs_write_log_target(struct obd_device *obd,
2792 struct mgs_target_info *mti,
2799 /* set/check the new target index */
2800 rc = mgs_set_index(obd, mti);
2802 CERROR("Can't get index (%d)\n", rc);
2807 if (mti->mti_flags & LDD_F_UPGRADE14) {
2808 if (rc == EALREADY) {
2809 LCONSOLE_INFO("Found index %d for %s 1.4 log, "
2810 "upgrading\n", mti->mti_stripe_index,
2813 LCONSOLE_ERROR_MSG(0x149, "Failed to find %s in the old"
2814 " client log. Apparently it is not "
2815 "part of this filesystem, or the old"
2816 " log is wrong.\nUse 'writeconf' on "
2817 "the MDT to force log regeneration."
2818 "\n", mti->mti_svname);
2819 /* Not in client log? Upgrade anyhow...*/
2820 /* Argument against upgrading: reformat MDT,
2821 upgrade OST, then OST will start but will be SKIPped
2822 in client logs. Maybe error now is better. */
2823 /* RETURN(-EINVAL); */
2825 /* end COMPAT_146 */
2827 if (rc == EALREADY) {
2828 LCONSOLE_WARN("Found index %d for %s, updating log\n",
2829 mti->mti_stripe_index, mti->mti_svname);
2830 /* We would like to mark old log sections as invalid
2831 and add new log sections in the client and mdt logs.
2832 But if we add new sections, then live clients will
2833 get repeat setup instructions for already running
2834 osc's. So don't update the client/mdt logs. */
2835 mti->mti_flags &= ~LDD_F_UPDATE;
2839 cfs_mutex_lock(&fsdb->fsdb_mutex);
2841 if (mti->mti_flags &
2842 (LDD_F_VIRGIN | LDD_F_UPGRADE14 | LDD_F_WRITECONF)) {
2843 /* Generate a log from scratch */
2844 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
2845 rc = mgs_write_log_mdt(obd, fsdb, mti);
2846 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2847 rc = mgs_write_log_ost(obd, fsdb, mti);
2849 CERROR("Unknown target type %#x, can't create log for "
2850 "%s\n", mti->mti_flags, mti->mti_svname);
2853 CERROR("Can't write logs for %s (%d)\n",
2854 mti->mti_svname, rc);
2858 /* Just update the params from tunefs in mgs_write_log_params */
2859 CDEBUG(D_MGS, "Update params for %s\n", mti->mti_svname);
2860 mti->mti_flags |= LDD_F_PARAM;
2863 /* allocate temporary buffer, where class_get_next_param will
2864 make copy of a current parameter */
2865 OBD_ALLOC(buf, strlen(mti->mti_params) + 1);
2867 GOTO(out_up, rc = -ENOMEM);
2868 params = mti->mti_params;
2869 while (params != NULL) {
2870 rc = class_get_next_param(¶ms, buf);
2873 /* there is no next parameter, that is
2878 CDEBUG(D_MGS, "remaining string: '%s', param: '%s'\n",
2880 rc = mgs_write_log_param(obd, fsdb, mti, buf);
2885 OBD_FREE(buf, strlen(mti->mti_params) + 1);
2888 cfs_mutex_unlock(&fsdb->fsdb_mutex);
2893 /* verify that we can handle the old config logs */
2894 int mgs_upgrade_sv_14(struct obd_device *obd, struct mgs_target_info *mti,
2900 /* Create ost log normally, as servers register. Servers
2901 register with their old uuids (from last_rcvd), so old
2902 (MDT and client) logs should work.
2903 - new MDT won't know about old OSTs, only the ones that have
2904 registered, so we need the old MDT log to get the LOV right
2905 in order for old clients to work.
2906 - Old clients connect to the MDT, not the MGS, for their logs, and
2907 will therefore receive the old client log from the MDT /LOGS dir.
2908 - Old clients can continue to use and connect to old or new OSTs
2909 - New clients will contact the MGS for their log
2912 LCONSOLE_INFO("upgrading server %s from pre-1.6\n", mti->mti_svname);
2913 server_mti_print("upgrade", mti);
2915 if (cfs_test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
2916 LCONSOLE_ERROR_MSG(0x14a, "The old client log %s-client is "
2917 "missing. Was tunefs.lustre successful?\n",
2922 if (fsdb->fsdb_gen == 0) {
2923 /* There were no markers in the client log, meaning we have
2924 not updated the logs for this fs */
2925 CDEBUG(D_MGS, "found old, unupdated client log\n");
2928 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
2929 if (mgs_log_is_empty(obd, mti->mti_svname)) {
2930 LCONSOLE_ERROR_MSG(0x14b, "The old MDT log %s is "
2931 "missing. Was tunefs.lustre "
2936 /* We're starting with an old uuid. Assume old name for lov
2937 as well since the lov entry already exists in the log. */
2938 CDEBUG(D_MGS, "old mds uuid %s\n", mti->mti_uuid);
2939 if (strncmp(mti->mti_uuid, fsdb->fsdb_mdtlov + 4,
2940 strlen(fsdb->fsdb_mdtlov) - 4) != 0) {
2941 CERROR("old mds uuid %s doesn't match log %s (%s)\n",
2942 mti->mti_uuid, fsdb->fsdb_mdtlov,
2943 fsdb->fsdb_mdtlov + 4);
2948 if (!cfs_test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
2949 LCONSOLE_ERROR_MSG(0x14c, "%s-client is supposedly an old "
2950 "log, but no old LOV or MDT was found. "
2951 "Consider updating the configuration with"
2952 " --writeconf.\n", mti->mti_fsname);
2957 /* end COMPAT_146 */
2959 int mgs_erase_log(struct obd_device *obd, char *name)
2961 struct lvfs_run_ctxt saved;
2962 struct llog_ctxt *ctxt;
2963 struct llog_handle *llh;
2966 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
2967 LASSERT(ctxt != NULL);
2969 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
2970 rc = llog_create(NULL, ctxt, &llh, NULL, name);
2972 llog_init_handle(NULL, llh, LLOG_F_IS_PLAIN, NULL);
2973 rc = llog_destroy(NULL, llh);
2974 llog_free_handle(llh);
2976 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
2977 llog_ctxt_put(ctxt);
2980 CERROR("failed to clear log %s: %d\n", name, rc);
2985 /* erase all logs for the given fs */
2986 int mgs_erase_logs(struct obd_device *obd, char *fsname)
2988 struct mgs_obd *mgs = &obd->u.mgs;
2990 cfs_list_t dentry_list;
2991 struct l_linux_dirent *dirent, *n;
2992 int rc, len = strlen(fsname);
2996 /* Find all the logs in the CONFIGS directory */
2997 rc = class_dentry_readdir(obd, mgs->mgs_configs_dir,
2998 mgs->mgs_vfsmnt, &dentry_list);
3000 CERROR("Can't read %s dir\n", MOUNT_CONFIGS_DIR);
3004 cfs_mutex_lock(&mgs->mgs_mutex);
3006 /* Delete the fs db */
3007 fsdb = mgs_find_fsdb(obd, fsname);
3009 mgs_free_fsdb(obd, fsdb);
3011 cfs_list_for_each_entry_safe(dirent, n, &dentry_list, lld_list) {
3012 cfs_list_del(&dirent->lld_list);
3013 suffix = strrchr(dirent->lld_name, '-');
3014 if (suffix != NULL) {
3015 if ((len == suffix - dirent->lld_name) &&
3016 (strncmp(fsname, dirent->lld_name, len) == 0)) {
3017 CDEBUG(D_MGS, "Removing log %s\n",
3019 mgs_erase_log(obd, dirent->lld_name);
3022 OBD_FREE(dirent, sizeof(*dirent));
3025 cfs_mutex_unlock(&mgs->mgs_mutex);
3030 /* from llog_swab */
3031 static void print_lustre_cfg(struct lustre_cfg *lcfg)
3036 CDEBUG(D_MGS, "lustre_cfg: %p\n", lcfg);
3037 CDEBUG(D_MGS, "\tlcfg->lcfg_version: %#x\n", lcfg->lcfg_version);
3039 CDEBUG(D_MGS, "\tlcfg->lcfg_command: %#x\n", lcfg->lcfg_command);
3040 CDEBUG(D_MGS, "\tlcfg->lcfg_num: %#x\n", lcfg->lcfg_num);
3041 CDEBUG(D_MGS, "\tlcfg->lcfg_flags: %#x\n", lcfg->lcfg_flags);
3042 CDEBUG(D_MGS, "\tlcfg->lcfg_nid: %s\n", libcfs_nid2str(lcfg->lcfg_nid));
3044 CDEBUG(D_MGS, "\tlcfg->lcfg_bufcount: %d\n", lcfg->lcfg_bufcount);
3045 if (lcfg->lcfg_bufcount < LUSTRE_CFG_MAX_BUFCOUNT)
3046 for (i = 0; i < lcfg->lcfg_bufcount; i++) {
3047 CDEBUG(D_MGS, "\tlcfg->lcfg_buflens[%d]: %d %s\n",
3048 i, lcfg->lcfg_buflens[i],
3049 lustre_cfg_string(lcfg, i));
3054 /* Set a permanent (config log) param for a target or fs
3055 * \param lcfg buf0 may contain the device (testfs-MDT0000) name
3056 * buf1 contains the single parameter
3058 int mgs_setparam(struct obd_device *obd, struct lustre_cfg *lcfg, char *fsname)
3061 struct mgs_target_info *mti;
3062 char *devname, *param;
3068 print_lustre_cfg(lcfg);
3070 /* lustre, lustre-mdtlov, lustre-client, lustre-MDT0000 */
3071 devname = lustre_cfg_string(lcfg, 0);
3072 param = lustre_cfg_string(lcfg, 1);
3074 /* Assume device name embedded in param:
3075 lustre-OST0000.osc.max_dirty_mb=32 */
3076 ptr = strchr(param, '.');
3084 LCONSOLE_ERROR_MSG(0x14d, "No target specified: %s\n", param);
3088 /* Extract fsname */
3089 ptr = strrchr(devname, '-');
3090 memset(fsname, 0, MTI_NAME_MAXLEN);
3091 if (ptr && (server_name2index(ptr, &index, NULL) >= 0)) {
3092 /* param related to llite isn't allowed to set by OST or MDT */
3093 if (strncmp(param, PARAM_LLITE, sizeof(PARAM_LLITE)) == 0)
3096 strncpy(fsname, devname, ptr - devname);
3098 /* assume devname is the fsname */
3099 strncpy(fsname, devname, MTI_NAME_MAXLEN);
3101 fsname[MTI_NAME_MAXLEN - 1] = 0;
3102 CDEBUG(D_MGS, "setparam fs='%s' device='%s'\n", fsname, devname);
3104 rc = mgs_find_or_make_fsdb(obd, fsname, &fsdb);
3107 if (!cfs_test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags) &&
3108 cfs_test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
3109 CERROR("No filesystem targets for %s. cfg_device from lctl "
3110 "is '%s'\n", fsname, devname);
3111 mgs_free_fsdb(obd, fsdb);
3115 /* Create a fake mti to hold everything */
3118 GOTO(out, rc = -ENOMEM);
3119 strncpy(mti->mti_fsname, fsname, MTI_NAME_MAXLEN);
3120 strncpy(mti->mti_svname, devname, MTI_NAME_MAXLEN);
3121 strncpy(mti->mti_params, param, sizeof(mti->mti_params));
3122 rc = server_name2index(mti->mti_svname, &mti->mti_stripe_index, &tmp);
3124 /* Not a valid server; may be only fsname */
3127 /* Strip -osc or -mdc suffix from svname */
3128 if (server_make_name(rc, mti->mti_stripe_index, mti->mti_fsname,
3130 GOTO(out, rc = -EINVAL);
3132 mti->mti_flags = rc | LDD_F_PARAM;
3134 cfs_mutex_lock(&fsdb->fsdb_mutex);
3135 rc = mgs_write_log_param(obd, fsdb, mti, mti->mti_params);
3136 cfs_mutex_unlock(&fsdb->fsdb_mutex);
3139 * Revoke lock so everyone updates. Should be alright if
3140 * someone was already reading while we were updating the logs,
3141 * so we don't really need to hold the lock while we're
3144 mgs_revoke_lock(obd, fsdb, CONFIG_T_CONFIG);
3150 static int mgs_write_log_pool(struct obd_device *obd, char *logname,
3151 struct fs_db *fsdb, char *lovname,
3152 enum lcfg_command_type cmd,
3153 char *poolname, char *fsname,
3154 char *ostname, char *comment)
3156 struct llog_handle *llh = NULL;
3159 rc = record_start_log(obd, &llh, logname);
3162 rc = record_marker(obd, llh, fsdb, CM_START, lovname, comment);
3163 record_base(obd, llh, lovname, 0, cmd, poolname, fsname, ostname, 0);
3164 rc = record_marker(obd, llh, fsdb, CM_END, lovname, comment);
3165 rc = record_end_log(obd, &llh);
3170 int mgs_pool_cmd(struct obd_device *obd, enum lcfg_command_type cmd,
3171 char *fsname, char *poolname, char *ostname)
3176 char *label = NULL, *canceled_label = NULL;
3178 struct mgs_target_info *mti = NULL;
3182 rc = mgs_find_or_make_fsdb(obd, fsname, &fsdb);
3184 CERROR("Can't get db for %s\n", fsname);
3187 if (cfs_test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
3188 CERROR("%s is not defined\n", fsname);
3189 mgs_free_fsdb(obd, fsdb);
3193 label_sz = 10 + strlen(fsname) + strlen(poolname);
3195 /* check if ostname match fsname */
3196 if (ostname != NULL) {
3199 ptr = strrchr(ostname, '-');
3200 if ((ptr == NULL) ||
3201 (strncmp(fsname, ostname, ptr-ostname) != 0))
3203 label_sz += strlen(ostname);
3206 OBD_ALLOC(label, label_sz);
3208 GOTO(out, rc = -ENOMEM);
3211 case LCFG_POOL_NEW: {
3213 "new %s.%s", fsname, poolname);
3216 case LCFG_POOL_ADD: {
3218 "add %s.%s.%s", fsname, poolname, ostname);
3221 case LCFG_POOL_REM: {
3222 OBD_ALLOC(canceled_label, label_sz);
3223 if (canceled_label == NULL)
3224 GOTO(out, rc = -ENOMEM);
3226 "rem %s.%s.%s", fsname, poolname, ostname);
3227 sprintf(canceled_label,
3228 "add %s.%s.%s", fsname, poolname, ostname);
3231 case LCFG_POOL_DEL: {
3232 OBD_ALLOC(canceled_label, label_sz);
3233 if (canceled_label == NULL)
3234 GOTO(out, rc = -ENOMEM);
3236 "del %s.%s", fsname, poolname);
3237 sprintf(canceled_label,
3238 "new %s.%s", fsname, poolname);
3246 cfs_mutex_lock(&fsdb->fsdb_mutex);
3248 if (canceled_label != NULL) {
3251 GOTO(out, rc = -ENOMEM);
3254 /* write pool def to all MDT logs */
3255 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3256 if (cfs_test_bit(i, fsdb->fsdb_mdt_index_map)) {
3257 name_create_mdt_and_lov(&logname, &lovname, fsdb, i);
3259 if (canceled_label != NULL) {
3260 strcpy(mti->mti_svname, "lov pool");
3261 mgs_modify(obd, fsdb, mti, logname, lovname,
3262 canceled_label, CM_SKIP);
3265 mgs_write_log_pool(obd, logname, fsdb, lovname,
3266 cmd, fsname, poolname, ostname,
3268 name_destroy(&logname);
3269 name_destroy(&lovname);
3273 name_create(&logname, fsname, "-client");
3274 if (canceled_label != NULL)
3275 mgs_modify(obd, fsdb, mti, logname, fsdb->fsdb_clilov,
3276 canceled_label, CM_SKIP);
3278 mgs_write_log_pool(obd, logname, fsdb, fsdb->fsdb_clilov,
3279 cmd, fsname, poolname, ostname, label);
3280 name_destroy(&logname);
3282 cfs_mutex_unlock(&fsdb->fsdb_mutex);
3283 /* request for update */
3284 mgs_revoke_lock(obd, fsdb, CONFIG_T_CONFIG);
3289 OBD_FREE(label, label_sz);
3291 if (canceled_label != NULL)
3292 OBD_FREE(canceled_label, label_sz);
3301 /******************** unused *********************/
3302 static int mgs_backup_llog(struct obd_device *obd, char* fsname)
3304 struct file *filp, *bak_filp;
3305 struct lvfs_run_ctxt saved;
3306 char *logname, *buf;
3307 loff_t soff = 0 , doff = 0;
3308 int count = 4096, len;
3311 OBD_ALLOC(logname, PATH_MAX);
3312 if (logname == NULL)
3315 OBD_ALLOC(buf, count);
3317 GOTO(out , rc = -ENOMEM);
3319 len = snprintf(logname, PATH_MAX, "%s/%s.bak",
3320 MOUNT_CONFIGS_DIR, fsname);
3322 if (len >= PATH_MAX - 1) {
3323 GOTO(out, -ENAMETOOLONG);
3326 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
3328 bak_filp = l_filp_open(logname, O_RDWR|O_CREAT|O_TRUNC, 0660);
3329 if (IS_ERR(bak_filp)) {
3330 rc = PTR_ERR(bak_filp);
3331 CERROR("backup logfile open %s: %d\n", logname, rc);
3334 sprintf(logname, "%s/%s", MOUNT_CONFIGS_DIR, fsname);
3335 filp = l_filp_open(logname, O_RDONLY, 0);
3338 CERROR("logfile open %s: %d\n", logname, rc);
3342 while ((rc = lustre_fread(filp, buf, count, &soff)) > 0) {
3343 rc = lustre_fwrite(bak_filp, buf, count, &doff);
3347 filp_close(filp, 0);
3349 filp_close(bak_filp, 0);
3351 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
3354 OBD_FREE(buf, count);
3355 OBD_FREE(logname, PATH_MAX);