1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
4 * lustre/mgs/mgs_llog.c
5 * Lustre Management Server (mgs) config llog creation
7 * Copyright (C) 2006 Cluster File Systems, Inc.
8 * Author: Nathan Rutman <nathan@clusterfs.com>
10 * This file is part of Lustre, http://www.lustre.org.
12 * Lustre is free software; you can redistribute it and/or
13 * modify it under the terms of version 2 of the GNU General Public
14 * License as published by the Free Software Foundation.
16 * Lustre is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with Lustre; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
29 #define DEBUG_SUBSYSTEM S_MGS
30 #define D_MGS D_CONFIG /*|D_WARNING*/
33 #include <linux/module.h>
34 #include <linux/pagemap.h>
40 #include <obd_class.h>
41 #include <lustre_log.h>
43 #include <libcfs/list.h>
44 #include <linux/lvfs.h>
45 #include <lustre_fsfilt.h>
46 #include <lustre_disk.h>
47 #include <lustre_param.h>
48 #include <lustre_sec.h>
49 #include "mgs_internal.h"
51 static int mgs_get_fsdb_srpc_from_llog(struct obd_device *obd,
53 static int mgs_get_srpc_conf_log(struct fs_db *fsdb, const char *tgt,
54 enum lustre_sec_part from,
55 enum lustre_sec_part to,
56 struct sptlrpc_conf_log *log);
58 /********************** Class functions ********************/
60 /* Caller must list_del and OBD_FREE each dentry from the list */
61 int class_dentry_readdir(struct obd_device *obd, struct dentry *dir,
62 struct vfsmount *inmnt,
63 struct list_head *dentry_list){
64 /* see mds_cleanup_pending */
65 struct lvfs_run_ctxt saved;
67 struct dentry *dentry;
72 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
75 GOTO(out_pop, rc = PTR_ERR(dentry));
79 GOTO(out_pop, rc = PTR_ERR(mnt));
82 file = dentry_open(dentry, mnt, O_RDONLY);
84 /* dentry_open_it() drops the dentry, mnt refs */
85 GOTO(out_pop, rc = PTR_ERR(file));
87 CFS_INIT_LIST_HEAD(dentry_list);
88 rc = l_readdir(file, dentry_list);
90 /* filp_close->fput() drops the dentry, mnt refs */
93 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
97 /******************** DB functions *********************/
99 static inline int name_create(char **newname, char *prefix, char *suffix)
102 OBD_ALLOC(*newname, strlen(prefix) + strlen(suffix) + 1);
105 sprintf(*newname, "%s%s", prefix, suffix);
109 static inline void name_destroy(char **name)
112 OBD_FREE(*name, strlen(*name) + 1);
116 /* from the (client) config log, figure out:
117 1. which ost's/mdt's are configured (by index)
118 2. what the last config step is
119 3. COMPAT_146 lov name
120 4. COMPAT_146 mdt lov name
121 5. COMPAT_146 mdc name
123 /* It might be better to have a separate db file, instead of parsing the info
124 out of the client log. This is slow and potentially error-prone. */
125 static int mgs_fsdb_handler(struct llog_handle *llh, struct llog_rec_hdr *rec,
128 struct fs_db *fsdb = (struct fs_db *)data;
129 int cfg_len = rec->lrh_len;
130 char *cfg_buf = (char*) (rec + 1);
131 struct lustre_cfg *lcfg;
136 if (rec->lrh_type != OBD_CFG_REC) {
137 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
141 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
143 CERROR("Insane cfg\n");
147 lcfg = (struct lustre_cfg *)cfg_buf;
149 CDEBUG(D_INFO, "cmd %x %s %s\n", lcfg->lcfg_command,
150 lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));
152 /* Figure out ost indicies */
153 /* lov_modify_tgts add 0:lov1 1:ost1_UUID 2(index):0 3(gen):1 */
154 if (lcfg->lcfg_command == LCFG_LOV_ADD_OBD ||
155 lcfg->lcfg_command == LCFG_LOV_DEL_OBD) {
156 index = simple_strtoul(lustre_cfg_string(lcfg, 2),
158 CDEBUG(D_MGS, "OST index for %s is %u (%s)\n",
159 lustre_cfg_string(lcfg, 1), index,
160 lustre_cfg_string(lcfg, 2));
161 set_bit(index, fsdb->fsdb_ost_index_map);
164 /* Figure out mdt indicies */
165 /* attach 0:MDC_uml1_mdsA_MNT_client 1:mdc 2:1d834_MNT_client_03f */
166 if ((lcfg->lcfg_command == LCFG_ATTACH) &&
167 (strcmp(lustre_cfg_string(lcfg, 1), LUSTRE_MDC_NAME) == 0)) {
168 rc = server_name2index(lustre_cfg_string(lcfg, 0),
170 if (rc != LDD_F_SV_TYPE_MDT) {
171 CWARN("Unparsable MDC name %s, assuming index 0\n",
172 lustre_cfg_string(lcfg, 0));
176 CDEBUG(D_MGS, "MDT index is %u\n", index);
177 set_bit(index, fsdb->fsdb_mdt_index_map);
181 /* figure out the old LOV name. fsdb_gen = 0 means old log */
182 /* #01 L attach 0:lov_mdsA 1:lov 2:cdbe9_lov_mdsA_dc8cf7f3bb */
183 if ((fsdb->fsdb_gen == 0) && (lcfg->lcfg_command == LCFG_ATTACH) &&
184 (strcmp(lustre_cfg_string(lcfg, 1), LUSTRE_LOV_NAME) == 0)) {
185 fsdb->fsdb_flags |= FSDB_OLDLOG14;
186 name_destroy(&fsdb->fsdb_clilov);
187 rc = name_create(&fsdb->fsdb_clilov,
188 lustre_cfg_string(lcfg, 0), "");
191 CDEBUG(D_MGS, "client lov name is %s\n", fsdb->fsdb_clilov);
194 /* figure out the old MDT lov name from the MDT uuid */
195 if ((fsdb->fsdb_gen == 0) && (lcfg->lcfg_command == LCFG_SETUP) &&
196 (strncmp(lustre_cfg_string(lcfg, 0), "MDC_", 4) == 0)) {
198 fsdb->fsdb_flags |= FSDB_OLDLOG14;
199 ptr = strstr(lustre_cfg_string(lcfg, 1), "_UUID");
201 CERROR("Can't parse MDT uuid %s\n",
202 lustre_cfg_string(lcfg, 1));
206 name_destroy(&fsdb->fsdb_mdtlov);
207 rc = name_create(&fsdb->fsdb_mdtlov,
208 "lov_", lustre_cfg_string(lcfg, 1));
211 name_destroy(&fsdb->fsdb_mdc);
212 rc = name_create(&fsdb->fsdb_mdc,
213 lustre_cfg_string(lcfg, 0), "");
216 CDEBUG(D_MGS, "MDT lov name is %s\n", fsdb->fsdb_mdtlov);
220 /* Keep track of the latest marker step */
221 if (lcfg->lcfg_command == LCFG_MARKER) {
222 struct cfg_marker *marker;
223 marker = lustre_cfg_buf(lcfg, 1);
224 fsdb->fsdb_gen = max(fsdb->fsdb_gen, marker->cm_step);
230 /* fsdb->fsdb_sem is already held in mgs_find_or_make_fsdb*/
231 static int mgs_get_fsdb_from_llog(struct obd_device *obd, struct fs_db *fsdb)
234 struct llog_handle *loghandle;
235 struct lvfs_run_ctxt saved;
236 struct llog_ctxt *ctxt;
240 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
241 LASSERT(ctxt != NULL);
242 name_create(&logname, fsdb->fsdb_name, "-client");
243 down(&fsdb->fsdb_sem);
244 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
245 rc = llog_create(ctxt, &loghandle, NULL, logname);
249 rc = llog_init_handle(loghandle, LLOG_F_IS_PLAIN, NULL);
253 if (llog_get_size(loghandle) <= 1)
254 fsdb->fsdb_flags |= FSDB_LOG_EMPTY;
256 rc = llog_process(loghandle, mgs_fsdb_handler, (void *)fsdb, NULL);
257 CDEBUG(D_INFO, "get_db = %d\n", rc);
259 rc2 = llog_close(loghandle);
263 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
265 name_destroy(&logname);
271 static void mgs_free_fsdb_srpc(struct fs_db *fsdb)
273 struct mgs_tgt_srpc_conf *tgtconf;
275 /* free target-specific rules */
276 while (fsdb->fsdb_srpc_tgt) {
277 tgtconf = fsdb->fsdb_srpc_tgt;
278 fsdb->fsdb_srpc_tgt = tgtconf->mtsc_next;
280 LASSERT(tgtconf->mtsc_tgt);
282 sptlrpc_rule_set_free(&tgtconf->mtsc_rset);
283 OBD_FREE(tgtconf->mtsc_tgt, strlen(tgtconf->mtsc_tgt) + 1);
284 OBD_FREE_PTR(tgtconf);
287 /* free general rules */
288 sptlrpc_rule_set_free(&fsdb->fsdb_srpc_gen);
291 static struct fs_db *mgs_find_fsdb(struct obd_device *obd, char *fsname)
293 struct mgs_obd *mgs = &obd->u.mgs;
295 struct list_head *tmp;
297 list_for_each(tmp, &mgs->mgs_fs_db_list) {
298 fsdb = list_entry(tmp, struct fs_db, fsdb_list);
299 if (strcmp(fsdb->fsdb_name, fsname) == 0)
305 /* caller must hold the mgs->mgs_fs_db_lock */
306 static struct fs_db *mgs_new_fsdb(struct obd_device *obd, char *fsname)
308 struct mgs_obd *mgs = &obd->u.mgs;
317 OBD_ALLOC(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
318 OBD_ALLOC(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
319 if (!fsdb->fsdb_ost_index_map || !fsdb->fsdb_mdt_index_map) {
320 CERROR("No memory for index maps\n");
324 strncpy(fsdb->fsdb_name, fsname, sizeof(fsdb->fsdb_name));
325 fsdb->fsdb_name[sizeof(fsdb->fsdb_name) - 1] = 0;
326 rc = name_create(&fsdb->fsdb_mdtlov, fsname, "-mdtlov");
329 rc = name_create(&fsdb->fsdb_mdtlmv, fsname, "-mdtlmv");
332 rc = name_create(&fsdb->fsdb_clilov, fsname, "-clilov");
336 rc = name_create(&fsdb->fsdb_clilmv, fsname, "-clilmv");
340 fsdb->fsdb_srpc_fl_udesc = 1;
341 sema_init(&fsdb->fsdb_sem, 1);
342 list_add(&fsdb->fsdb_list, &mgs->mgs_fs_db_list);
343 lproc_mgs_add_live(obd, fsdb);
347 if (fsdb->fsdb_ost_index_map)
348 OBD_FREE(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
349 if (fsdb->fsdb_mdt_index_map)
350 OBD_FREE(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
351 name_destroy(&fsdb->fsdb_clilov);
352 name_destroy(&fsdb->fsdb_clilmv);
353 name_destroy(&fsdb->fsdb_mdtlov);
354 name_destroy(&fsdb->fsdb_mdtlmv);
359 static void mgs_free_fsdb(struct obd_device *obd, struct fs_db *fsdb)
361 /* wait for anyone with the sem */
362 down(&fsdb->fsdb_sem);
363 lproc_mgs_del_live(obd, fsdb);
364 list_del(&fsdb->fsdb_list);
365 OBD_FREE(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
366 OBD_FREE(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
367 name_destroy(&fsdb->fsdb_clilov);
368 name_destroy(&fsdb->fsdb_clilmv);
369 name_destroy(&fsdb->fsdb_mdtlov);
370 name_destroy(&fsdb->fsdb_mdtlmv);
371 name_destroy(&fsdb->fsdb_mdc);
372 mgs_free_fsdb_srpc(fsdb);
376 int mgs_init_fsdb_list(struct obd_device *obd)
378 struct mgs_obd *mgs = &obd->u.mgs;
379 CFS_INIT_LIST_HEAD(&mgs->mgs_fs_db_list);
383 int mgs_cleanup_fsdb_list(struct obd_device *obd)
385 struct mgs_obd *mgs = &obd->u.mgs;
387 struct list_head *tmp, *tmp2;
389 list_for_each_safe(tmp, tmp2, &mgs->mgs_fs_db_list) {
390 fsdb = list_entry(tmp, struct fs_db, fsdb_list);
391 mgs_free_fsdb(obd, fsdb);
397 static int mgs_find_or_make_fsdb(struct obd_device *obd, char *name,
400 struct mgs_obd *mgs = &obd->u.mgs;
405 fsdb = mgs_find_fsdb(obd, name);
412 CDEBUG(D_MGS, "Creating new db\n");
413 fsdb = mgs_new_fsdb(obd, name);
418 /* populate the db from the client llog */
419 rc = mgs_get_fsdb_from_llog(obd, fsdb);
421 CERROR("Can't get db from client log %d\n", rc);
422 mgs_free_fsdb(obd, fsdb);
426 /* populate srpc rules from params llog */
427 rc = mgs_get_fsdb_srpc_from_llog(obd, fsdb);
429 CERROR("Can't get db from params log %d\n", rc);
430 mgs_free_fsdb(obd, fsdb);
441 -1= empty client log */
442 int mgs_check_index(struct obd_device *obd, struct mgs_target_info *mti)
449 LASSERT(!(mti->mti_flags & LDD_F_NEED_INDEX));
451 rc = mgs_find_or_make_fsdb(obd, mti->mti_fsname, &fsdb);
453 CERROR("Can't get db for %s\n", mti->mti_fsname);
457 if (fsdb->fsdb_flags & FSDB_LOG_EMPTY)
460 if (mti->mti_flags & LDD_F_SV_TYPE_OST)
461 imap = fsdb->fsdb_ost_index_map;
462 else if (mti->mti_flags & LDD_F_SV_TYPE_MDT)
463 imap = fsdb->fsdb_mdt_index_map;
467 if (test_bit(mti->mti_stripe_index, imap))
472 static __inline__ int next_index(void *index_map, int map_len)
475 for (i = 0; i < map_len * 8; i++)
476 if (!test_bit(i, index_map)) {
479 CERROR("max index %d exceeded.\n", i);
484 0 newly marked as in use
486 +EALREADY for update of an old index */
487 int mgs_set_index(struct obd_device *obd, struct mgs_target_info *mti)
494 rc = mgs_find_or_make_fsdb(obd, mti->mti_fsname, &fsdb);
496 CERROR("Can't get db for %s\n", mti->mti_fsname);
500 if (mti->mti_flags & LDD_F_SV_TYPE_OST)
501 imap = fsdb->fsdb_ost_index_map;
502 else if (mti->mti_flags & LDD_F_SV_TYPE_MDT)
503 imap = fsdb->fsdb_mdt_index_map;
507 if (mti->mti_flags & LDD_F_NEED_INDEX) {
508 rc = next_index(imap, INDEX_MAP_SIZE);
511 mti->mti_stripe_index = rc;
514 if (mti->mti_stripe_index >= INDEX_MAP_SIZE * 8) {
515 LCONSOLE_ERROR_MSG(0x13f, "Server %s requested index %d, "
516 "but the max index is %d.\n",
517 mti->mti_svname, mti->mti_stripe_index,
522 if (test_bit(mti->mti_stripe_index, imap)) {
523 if ((mti->mti_flags & LDD_F_VIRGIN) &&
524 !(mti->mti_flags & LDD_F_WRITECONF)) {
525 LCONSOLE_ERROR_MSG(0x140, "Server %s requested index "
526 "%d, but that index is already in "
527 "use. Use --writeconf to force\n",
529 mti->mti_stripe_index);
532 CDEBUG(D_MGS, "Server %s updating index %d\n",
533 mti->mti_svname, mti->mti_stripe_index);
538 set_bit(mti->mti_stripe_index, imap);
539 fsdb->fsdb_flags &= ~FSDB_LOG_EMPTY;
540 server_make_name(mti->mti_flags, mti->mti_stripe_index,
541 mti->mti_fsname, mti->mti_svname);
543 CDEBUG(D_MGS, "Set index for %s to %d\n", mti->mti_svname,
544 mti->mti_stripe_index);
549 struct mgs_modify_lookup {
550 struct cfg_marker mml_marker;
554 static int mgs_modify_handler(struct llog_handle *llh, struct llog_rec_hdr *rec,
557 struct mgs_modify_lookup *mml = (struct mgs_modify_lookup *)data;
558 struct cfg_marker *marker;
559 struct lustre_cfg *lcfg = (struct lustre_cfg *)(rec + 1);
560 int cfg_len = rec->lrh_len - sizeof(struct llog_rec_hdr) -
561 sizeof(struct llog_rec_tail);
565 if (rec->lrh_type != OBD_CFG_REC) {
566 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
570 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
572 CERROR("Insane cfg\n");
576 /* We only care about markers */
577 if (lcfg->lcfg_command != LCFG_MARKER)
580 marker = lustre_cfg_buf(lcfg, 1);
581 if ((strcmp(mml->mml_marker.cm_comment, marker->cm_comment) == 0) &&
582 (strcmp(mml->mml_marker.cm_tgtname, marker->cm_tgtname) == 0) &&
583 !(marker->cm_flags & CM_SKIP)) {
584 /* Found a non-skipped marker match */
585 CDEBUG(D_MGS, "Changing rec %u marker %d %x->%x: %s %s\n",
586 rec->lrh_index, marker->cm_step,
587 marker->cm_flags, mml->mml_marker.cm_flags,
588 marker->cm_tgtname, marker->cm_comment);
589 /* Overwrite the old marker llog entry */
590 marker->cm_flags &= ~CM_EXCLUDE; /* in case we're unexcluding */
591 marker->cm_flags |= mml->mml_marker.cm_flags;
592 marker->cm_canceltime = mml->mml_marker.cm_canceltime;
593 /* Header and tail are added back to lrh_len in
594 llog_lvfs_write_rec */
595 rec->lrh_len = cfg_len;
596 rc = llog_write_rec(llh, rec, NULL, 0, (void *)lcfg,
605 /* Modify an existing config log record (for CM_SKIP or CM_EXCLUDE) */
606 static int mgs_modify(struct obd_device *obd, struct fs_db *fsdb,
607 struct mgs_target_info *mti, char *logname,
608 char *devname, char *comment, int flags)
610 struct llog_handle *loghandle;
611 struct lvfs_run_ctxt saved;
612 struct llog_ctxt *ctxt;
613 struct mgs_modify_lookup *mml;
617 CDEBUG(D_MGS, "modify %s/%s/%s\n", logname, devname, comment);
619 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
621 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
622 LASSERT(ctxt != NULL);
623 rc = llog_create(ctxt, &loghandle, NULL, logname);
627 rc = llog_init_handle(loghandle, LLOG_F_IS_PLAIN, NULL);
631 if (llog_get_size(loghandle) <= 1)
632 GOTO(out_close, rc = 0);
636 GOTO(out_close, rc = -ENOMEM);
637 strcpy(mml->mml_marker.cm_comment, comment);
638 strcpy(mml->mml_marker.cm_tgtname, devname);
639 /* Modify mostly means cancel */
640 mml->mml_marker.cm_flags = flags;
641 mml->mml_marker.cm_canceltime = flags ? cfs_time_current_sec() : 0;
642 mml->mml_modified = 0;
643 rc = llog_process(loghandle, mgs_modify_handler, (void *)mml, NULL);
644 if (!rc && !mml->mml_modified)
649 rc2 = llog_close(loghandle);
653 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
654 if (rc && rc != -ENODEV)
655 CERROR("modify %s/%s failed %d\n",
656 mti->mti_svname, comment, rc);
661 /******************** config log recording functions *********************/
663 static int record_lcfg(struct obd_device *obd, struct llog_handle *llh,
664 struct lustre_cfg *lcfg)
666 struct lvfs_run_ctxt saved;
667 struct llog_rec_hdr rec;
673 LASSERT(llh->lgh_ctxt);
675 buflen = lustre_cfg_len(lcfg->lcfg_bufcount,
677 rec.lrh_len = llog_data_len(buflen);
678 rec.lrh_type = OBD_CFG_REC;
680 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
681 /* idx = -1 means append */
682 rc = llog_write_rec(llh, &rec, NULL, 0, (void *)lcfg, -1);
683 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
685 CERROR("failed %d\n", rc);
689 static int record_base(struct obd_device *obd, struct llog_handle *llh,
690 char *cfgname, lnet_nid_t nid, int cmd,
691 char *s1, char *s2, char *s3, char *s4)
693 struct lustre_cfg_bufs bufs;
694 struct lustre_cfg *lcfg;
697 CDEBUG(D_MGS, "lcfg %s %#x %s %s %s %s\n", cfgname,
698 cmd, s1, s2, s3, s4);
700 lustre_cfg_bufs_reset(&bufs, cfgname);
702 lustre_cfg_bufs_set_string(&bufs, 1, s1);
704 lustre_cfg_bufs_set_string(&bufs, 2, s2);
706 lustre_cfg_bufs_set_string(&bufs, 3, s3);
708 lustre_cfg_bufs_set_string(&bufs, 4, s4);
710 lcfg = lustre_cfg_new(cmd, &bufs);
713 lcfg->lcfg_nid = nid;
715 rc = record_lcfg(obd, llh, lcfg);
717 lustre_cfg_free(lcfg);
720 CERROR("error %d: lcfg %s %#x %s %s %s %s\n", rc, cfgname,
721 cmd, s1, s2, s3, s4);
727 static inline int record_add_uuid(struct obd_device *obd,
728 struct llog_handle *llh,
729 uint64_t nid, char *uuid)
731 return record_base(obd,llh,NULL,nid,LCFG_ADD_UUID,uuid,0,0,0);
735 static inline int record_add_conn(struct obd_device *obd,
736 struct llog_handle *llh,
740 return record_base(obd,llh,devname,0,LCFG_ADD_CONN,uuid,0,0,0);
743 static inline int record_attach(struct obd_device *obd, struct llog_handle *llh,
744 char *devname, char *type, char *uuid)
746 return record_base(obd,llh,devname,0,LCFG_ATTACH,type,uuid,0,0);
749 static inline int record_setup(struct obd_device *obd, struct llog_handle *llh,
751 char *s1, char *s2, char *s3, char *s4)
753 return record_base(obd,llh,devname,0,LCFG_SETUP,s1,s2,s3,s4);
756 static inline int record_sptlrpc_conf(struct obd_device *obd,
757 struct llog_handle *llh,
759 struct sptlrpc_conf_log *srpc_log)
761 struct lustre_cfg_bufs bufs;
762 struct lustre_cfg *lcfg;
765 lustre_cfg_bufs_reset(&bufs, devname);
766 lustre_cfg_bufs_set(&bufs, 1, srpc_log, sizeof(*srpc_log));
767 lcfg = lustre_cfg_new(LCFG_SPTLRPC_CONF, &bufs);
769 rc = record_lcfg(obd, llh, lcfg);
771 lustre_cfg_free(lcfg);
775 static int record_lov_setup(struct obd_device *obd, struct llog_handle *llh,
776 char *devname, struct lov_desc *desc)
778 struct lustre_cfg_bufs bufs;
779 struct lustre_cfg *lcfg;
782 lustre_cfg_bufs_reset(&bufs, devname);
783 lustre_cfg_bufs_set(&bufs, 1, desc, sizeof(*desc));
784 lcfg = lustre_cfg_new(LCFG_SETUP, &bufs);
787 rc = record_lcfg(obd, llh, lcfg);
789 lustre_cfg_free(lcfg);
793 static int record_lmv_setup(struct obd_device *obd, struct llog_handle *llh,
794 char *devname, struct lmv_desc *desc)
796 struct lustre_cfg_bufs bufs;
797 struct lustre_cfg *lcfg;
800 lustre_cfg_bufs_reset(&bufs, devname);
801 lustre_cfg_bufs_set(&bufs, 1, desc, sizeof(*desc));
802 lcfg = lustre_cfg_new(LCFG_SETUP, &bufs);
804 rc = record_lcfg(obd, llh, lcfg);
806 lustre_cfg_free(lcfg);
810 static inline int record_mdc_add(struct obd_device *obd,
811 struct llog_handle *llh,
812 char *logname, char *mdcuuid,
813 char *mdtuuid, char *index,
816 return record_base(obd,llh,logname,0,LCFG_ADD_MDC,
817 mdtuuid,index,gen,mdcuuid);
820 static inline int record_lov_add(struct obd_device *obd,
821 struct llog_handle *llh,
822 char *lov_name, char *ost_uuid,
823 char *index, char *gen)
825 return record_base(obd,llh,lov_name,0,LCFG_LOV_ADD_OBD,
826 ost_uuid,index,gen,0);
829 static inline int record_mount_opt(struct obd_device *obd,
830 struct llog_handle *llh,
831 char *profile, char *lov_name,
834 return record_base(obd,llh,NULL,0,LCFG_MOUNTOPT,
835 profile,lov_name,mdc_name,0);
838 static int record_marker(struct obd_device *obd, struct llog_handle *llh,
839 struct fs_db *fsdb, __u32 flags,
840 char *tgtname, char *comment)
842 struct cfg_marker marker;
843 struct lustre_cfg_bufs bufs;
844 struct lustre_cfg *lcfg;
847 if (flags & CM_START)
849 marker.cm_step = fsdb->fsdb_gen;
850 marker.cm_flags = flags;
851 marker.cm_vers = LUSTRE_VERSION_CODE;
852 strncpy(marker.cm_tgtname, tgtname, sizeof(marker.cm_tgtname));
853 strncpy(marker.cm_comment, comment, sizeof(marker.cm_comment));
854 marker.cm_createtime = cfs_time_current_sec();
855 marker.cm_canceltime = 0;
856 lustre_cfg_bufs_reset(&bufs, NULL);
857 lustre_cfg_bufs_set(&bufs, 1, &marker, sizeof(marker));
858 lcfg = lustre_cfg_new(LCFG_MARKER, &bufs);
861 rc = record_lcfg(obd, llh, lcfg);
863 lustre_cfg_free(lcfg);
867 static int record_start_log(struct obd_device *obd,
868 struct llog_handle **llh, char *name)
870 static struct obd_uuid cfg_uuid = { .uuid = "config_uuid" };
871 struct lvfs_run_ctxt saved;
872 struct llog_ctxt *ctxt;
876 GOTO(out, rc = -EBUSY);
878 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
880 GOTO(out, rc = -ENODEV);
882 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
883 rc = llog_create(ctxt, llh, NULL, name);
885 llog_init_handle(*llh, LLOG_F_IS_PLAIN, &cfg_uuid);
889 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
894 CERROR("Can't start log %s: %d\n", name, rc);
899 static int record_end_log(struct obd_device *obd, struct llog_handle **llh)
901 struct lvfs_run_ctxt saved;
904 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
906 rc = llog_close(*llh);
909 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
913 static int mgs_log_is_empty(struct obd_device *obd, char *name)
915 struct lvfs_run_ctxt saved;
916 struct llog_handle *llh;
917 struct llog_ctxt *ctxt;
920 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
921 LASSERT(ctxt != NULL);
922 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
923 rc = llog_create(ctxt, &llh, NULL, name);
925 llog_init_handle(llh, LLOG_F_IS_PLAIN, NULL);
926 rc = llog_get_size(llh);
929 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
931 /* header is record 1 */
935 /******************** config "macros" *********************/
937 /* write an lcfg directly into a log (with markers) */
938 static int mgs_write_log_direct(struct obd_device *obd, struct fs_db *fsdb,
939 char *logname, struct lustre_cfg *lcfg,
940 char *devname, char *comment)
942 struct llog_handle *llh = NULL;
949 rc = record_start_log(obd, &llh, logname);
953 /* FIXME These should be a single journal transaction */
954 rc = record_marker(obd, llh, fsdb, CM_START, devname, comment);
956 rc = record_lcfg(obd, llh, lcfg);
958 rc = record_marker(obd, llh, fsdb, CM_END, devname, comment);
959 rc = record_end_log(obd, &llh);
964 /* write the lcfg in all logs for the given fs */
965 int mgs_write_log_direct_all(struct obd_device *obd, struct fs_db *fsdb,
966 struct mgs_target_info *mti,
967 struct lustre_cfg *lcfg,
968 char *devname, char *comment)
970 struct mgs_obd *mgs = &obd->u.mgs;
971 struct list_head dentry_list;
972 struct l_linux_dirent *dirent, *n;
973 char *fsname = mti->mti_fsname;
975 int rc = 0, len = strlen(fsname);
978 /* We need to set params for any future logs
979 as well. FIXME Append this file to every new log.
980 Actually, we should store as params (text), not llogs. Or
982 name_create(&logname, fsname, "-params");
983 if (mgs_log_is_empty(obd, logname)) {
984 struct llog_handle *llh = NULL;
985 rc = record_start_log(obd, &llh, logname);
986 record_end_log(obd, &llh);
988 name_destroy(&logname);
992 /* Find all the logs in the CONFIGS directory */
993 rc = class_dentry_readdir(obd, mgs->mgs_configs_dir,
994 mgs->mgs_vfsmnt, &dentry_list);
996 CERROR("Can't read %s dir\n", MOUNT_CONFIGS_DIR);
1000 /* Could use fsdb index maps instead of directory listing */
1001 list_for_each_entry_safe(dirent, n, &dentry_list, lld_list) {
1002 list_del(&dirent->lld_list);
1003 /* don't write to sptlrpc rule log */
1004 if (strncmp(fsname, dirent->lld_name, len) == 0 &&
1005 strstr(dirent->lld_name, "-sptlrpc") == NULL) {
1006 CDEBUG(D_MGS, "Changing log %s\n", dirent->lld_name);
1007 /* Erase any old settings of this same parameter */
1008 mgs_modify(obd, fsdb, mti, dirent->lld_name, devname,
1010 /* Write the new one */
1011 rc = mgs_write_log_direct(obd, fsdb, dirent->lld_name,
1012 lcfg, devname, comment);
1014 CERROR("err %d writing log %s\n", rc,
1017 OBD_FREE(dirent, sizeof(*dirent));
1025 struct mgs_target_info *comp_tmti;
1026 struct mgs_target_info *comp_mti;
1027 struct fs_db *comp_fsdb;
1028 struct obd_device *comp_obd;
1031 static int mgs_write_log_mdc_to_mdt(struct obd_device *, struct fs_db *,
1032 struct mgs_target_info *, char *);
1034 static int mgs_steal_llog_handler(struct llog_handle *llh,
1035 struct llog_rec_hdr *rec,
1038 struct obd_device * obd;
1039 struct mgs_target_info *mti, *tmti;
1041 int cfg_len = rec->lrh_len;
1042 char *cfg_buf = (char*) (rec + 1);
1043 struct lustre_cfg *lcfg;
1045 struct llog_handle *mdt_llh = NULL;
1046 static int got_an_osc_or_mdc = 0;
1047 /* 0: not found any osc/mdc;
1051 static int last_step = -1;
1055 mti = ((struct temp_comp*)data)->comp_mti;
1056 tmti = ((struct temp_comp*)data)->comp_tmti;
1057 fsdb = ((struct temp_comp*)data)->comp_fsdb;
1058 obd = ((struct temp_comp*)data)->comp_obd;
1060 if (rec->lrh_type != OBD_CFG_REC) {
1061 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
1065 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
1067 CERROR("Insane cfg\n");
1071 lcfg = (struct lustre_cfg *)cfg_buf;
1073 if (lcfg->lcfg_command == LCFG_MARKER) {
1074 struct cfg_marker *marker;
1075 marker = lustre_cfg_buf(lcfg, 1);
1076 if (!strncmp(marker->cm_comment,"add osc",7) &&
1077 (marker->cm_flags & CM_START)){
1078 got_an_osc_or_mdc = 1;
1079 rc = record_start_log(obd, &mdt_llh, mti->mti_svname);
1080 rc = record_marker(obd, mdt_llh, fsdb, CM_START,
1081 mti->mti_svname,"add osc(copied)");
1082 rc = record_end_log(obd, &mdt_llh);
1083 last_step = marker->cm_step;
1086 if (!strncmp(marker->cm_comment,"add osc",7) &&
1087 (marker->cm_flags & CM_END)){
1088 LASSERT(last_step == marker->cm_step);
1090 got_an_osc_or_mdc = 0;
1091 rc = record_start_log(obd, &mdt_llh, mti->mti_svname);
1092 rc = record_marker(obd, mdt_llh, fsdb, CM_END,
1093 mti->mti_svname,"add osc(copied)");
1094 rc = record_end_log(obd, &mdt_llh);
1097 if (!strncmp(marker->cm_comment,"add mdc",7) &&
1098 (marker->cm_flags & CM_START)){
1099 got_an_osc_or_mdc = 2;
1100 last_step = marker->cm_step;
1101 memcpy(tmti->mti_svname, marker->cm_tgtname,
1102 strlen(marker->cm_tgtname));
1106 if (!strncmp(marker->cm_comment,"add mdc",7) &&
1107 (marker->cm_flags & CM_END)){
1108 LASSERT(last_step == marker->cm_step);
1110 got_an_osc_or_mdc = 0;
1115 if (got_an_osc_or_mdc == 0 || last_step < 0)
1118 if (lcfg->lcfg_command == LCFG_ADD_UUID) {
1120 nodenid = lcfg->lcfg_nid;
1122 tmti->mti_nids[tmti->mti_nid_count] = nodenid;
1123 tmti->mti_nid_count++;
1128 if (lcfg->lcfg_command == LCFG_SETUP) {
1131 target = lustre_cfg_string(lcfg, 1);
1132 memcpy(tmti->mti_uuid, target, strlen(target));
1136 /* ignore client side sptlrpc_conf_log */
1137 if (lcfg->lcfg_command == LCFG_SPTLRPC_CONF)
1140 if (lcfg->lcfg_command == LCFG_ADD_MDC) {
1143 if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1)
1146 memcpy(tmti->mti_fsname, mti->mti_fsname,
1147 strlen(mti->mti_fsname));
1148 tmti->mti_stripe_index = index;
1150 mgs_write_log_mdc_to_mdt(obd, fsdb, tmti, mti->mti_svname);
1151 memset(tmti, 0, sizeof(*tmti));
1157 /* fsdb->fsdb_sem is already held in mgs_write_log_target*/
1158 /* stealed from mgs_get_fsdb_from_llog*/
1159 static int mgs_steal_llog_for_mdt_from_client(struct obd_device *obd,
1161 struct temp_comp* comp)
1163 struct llog_handle *loghandle;
1164 struct lvfs_run_ctxt saved;
1165 struct mgs_target_info *tmti;
1166 struct llog_ctxt *ctxt;
1170 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
1171 LASSERT(ctxt != NULL);
1173 OBD_ALLOC_PTR(tmti);
1177 comp->comp_tmti = tmti;
1178 comp->comp_obd = obd;
1180 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
1182 rc = llog_create(ctxt, &loghandle, NULL, client_name);
1186 rc = llog_init_handle(loghandle, LLOG_F_IS_PLAIN, NULL);
1188 GOTO(out_close, rc);
1190 rc = llog_process(loghandle, mgs_steal_llog_handler, (void *)comp, NULL);
1191 CDEBUG(D_MGS, "steal llog re = %d\n", rc);
1193 rc2 = llog_close(loghandle);
1197 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
1199 llog_ctxt_put(ctxt);
1203 /* lmv is the second thing for client logs */
1204 /* copied from mgs_write_log_lov. Please refer to that. */
1205 static int mgs_write_log_lmv(struct obd_device *obd, struct fs_db *fsdb,
1206 struct mgs_target_info *mti,
1207 char *logname, char *lmvname)
1209 struct llog_handle *llh = NULL;
1210 struct lmv_desc *lmvdesc;
1215 CDEBUG(D_MGS, "Writing lmv(%s) log for %s\n", lmvname,logname);
1217 OBD_ALLOC(lmvdesc, sizeof(*lmvdesc));
1218 if (lmvdesc == NULL)
1220 lmvdesc->ld_active_tgt_count = 0;
1221 lmvdesc->ld_tgt_count = 0;
1222 sprintf((char*)lmvdesc->ld_uuid.uuid, "%s_UUID", lmvname);
1223 uuid = (char *)lmvdesc->ld_uuid.uuid;
1225 rc = record_start_log(obd, &llh, logname);
1226 rc = record_marker(obd, llh, fsdb, CM_START, lmvname, "lmv setup");
1227 rc = record_attach(obd, llh, lmvname, "lmv", uuid);
1228 rc = record_lmv_setup(obd, llh, lmvname, lmvdesc);
1229 rc = record_marker(obd, llh, fsdb, CM_END, lmvname, "lmv setup");
1230 rc = record_end_log(obd, &llh);
1232 OBD_FREE(lmvdesc, sizeof(*lmvdesc));
1235 /***************************************END PROTO**********************/
1237 /* lov is the first thing in the mdt and client logs */
1238 static int mgs_write_log_lov(struct obd_device *obd, struct fs_db *fsdb,
1239 struct mgs_target_info *mti,
1240 char *logname, char *lovname)
1242 struct llog_handle *llh = NULL;
1243 struct lov_desc *lovdesc;
1248 CDEBUG(D_MGS, "Writing lov(%s) log for %s\n", lovname, logname);
1251 #01 L attach 0:lov_mdsA 1:lov 2:71ccb_lov_mdsA_19f961a9e1
1252 #02 L lov_setup 0:lov_mdsA 1:(struct lov_desc)
1253 uuid=lov1_UUID, stripe count=1, size=1048576, offset=0, pattern=0
1256 /* FIXME just make lov_setup accept empty desc (put uuid in buf 2) */
1257 OBD_ALLOC(lovdesc, sizeof(*lovdesc));
1258 if (lovdesc == NULL)
1260 lovdesc->ld_magic = LOV_DESC_MAGIC;
1261 lovdesc->ld_tgt_count = 0;
1262 /* Defaults. Can be changed later by lcfg config_param */
1263 lovdesc->ld_default_stripe_count = 1;
1264 lovdesc->ld_pattern = LOV_PATTERN_RAID0;
1265 lovdesc->ld_default_stripe_size = 1024 * 1024;
1266 lovdesc->ld_default_stripe_offset = 0;
1267 lovdesc->ld_qos_maxage = QOS_DEFAULT_MAXAGE;
1268 sprintf((char*)lovdesc->ld_uuid.uuid, "%s_UUID", lovname);
1269 /* can these be the same? */
1270 uuid = (char *)lovdesc->ld_uuid.uuid;
1272 /* This should always be the first entry in a log.
1273 rc = mgs_clear_log(obd, logname); */
1274 rc = record_start_log(obd, &llh, logname);
1277 /* FIXME these should be a single journal transaction */
1278 rc = record_marker(obd, llh, fsdb, CM_START, lovname, "lov setup");
1279 rc = record_attach(obd, llh, lovname, "lov", uuid);
1280 rc = record_lov_setup(obd, llh, lovname, lovdesc);
1281 rc = record_marker(obd, llh, fsdb, CM_END, lovname, "lov setup");
1282 rc = record_end_log(obd, &llh);
1284 OBD_FREE(lovdesc, sizeof(*lovdesc));
1288 /* add failnids to open log */
1289 static int mgs_write_log_failnids(struct obd_device *obd,
1290 struct mgs_target_info *mti,
1291 struct llog_handle *llh,
1294 char *failnodeuuid = NULL;
1295 char *ptr = mti->mti_params;
1300 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) nal=90 0: 1:uml1_UUID
1301 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
1302 #05 L setup 0:OSC_uml1_ost1_mdsA 1:ost1_UUID 2:uml1_UUID
1303 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) nal=90 0: 1:uml2_UUID
1304 #0x L add_uuid nid=2@elan(0x1000000000002) nal=90 0: 1:uml2_UUID
1305 #07 L add_conn 0:OSC_uml1_ost1_mdsA 1:uml2_UUID
1308 /* Pull failnid info out of params string */
1309 while (class_find_param(ptr, PARAM_FAILNODE, &ptr) == 0) {
1310 while (class_parse_nid(ptr, &nid, &ptr) == 0) {
1311 if (failnodeuuid == NULL) {
1312 /* We don't know the failover node name,
1313 so just use the first nid as the uuid */
1314 rc = name_create(&failnodeuuid,
1315 libcfs_nid2str(nid), "");
1319 CDEBUG(D_MGS, "add nid %s for failover uuid %s, "
1320 "client %s\n", libcfs_nid2str(nid),
1321 failnodeuuid, cliname);
1322 rc = record_add_uuid(obd, llh, nid, failnodeuuid);
1325 rc = record_add_conn(obd, llh, cliname, failnodeuuid);
1326 name_destroy(&failnodeuuid);
1327 failnodeuuid = NULL;
1334 static int mgs_write_log_mdc_to_lmv(struct obd_device *obd, struct fs_db *fsdb,
1335 struct mgs_target_info *mti,
1336 char *logname, char *lmvname)
1338 struct llog_handle *llh = NULL;
1339 struct sptlrpc_conf_log *srpc_log;
1340 char *mdcname, *nodeuuid, *mdcuuid, *lmvuuid;
1345 if (mgs_log_is_empty(obd, logname)) {
1346 CERROR("log is empty! Logical error\n");
1350 CDEBUG(D_MGS, "adding mdc for %s to log %s:lmv(%s)\n",
1351 mti->mti_svname, logname, lmvname);
1353 srpc_log = sptlrpc_conf_log_alloc();
1354 if (IS_ERR(srpc_log))
1355 RETURN(PTR_ERR(srpc_log));
1356 srpc_log->scl_part = LUSTRE_SP_CLI;
1358 rc = mgs_get_srpc_conf_log(fsdb, mti->mti_svname,
1359 LUSTRE_SP_CLI, LUSTRE_SP_MDT, srpc_log);
1363 name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
1364 name_create(&mdcname, mti->mti_svname, "-mdc");
1365 name_create(&mdcuuid, mdcname, "_UUID");
1366 name_create(&lmvuuid, lmvname, "_UUID");
1368 rc = record_start_log(obd, &llh, logname);
1369 rc = record_marker(obd, llh, fsdb, CM_START, mti->mti_svname,
1372 for (i = 0; i < mti->mti_nid_count; i++) {
1373 CDEBUG(D_MGS, "add nid %s for mdt\n",
1374 libcfs_nid2str(mti->mti_nids[i]));
1376 rc = record_add_uuid(obd, llh, mti->mti_nids[i], nodeuuid);
1379 rc = record_attach(obd, llh, mdcname, LUSTRE_MDC_NAME, lmvuuid);
1380 rc = record_setup(obd, llh, mdcname, mti->mti_uuid, nodeuuid, 0, 0);
1381 rc = record_sptlrpc_conf(obd, llh, mdcname, srpc_log);
1382 rc = mgs_write_log_failnids(obd, mti, llh, mdcname);
1383 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
1384 rc = record_mdc_add(obd, llh, lmvname, mdcuuid, mti->mti_uuid,
1386 rc = record_marker(obd, llh, fsdb, CM_END, mti->mti_svname,
1388 rc = record_end_log(obd, &llh);
1390 name_destroy(&lmvuuid);
1391 name_destroy(&mdcuuid);
1392 name_destroy(&mdcname);
1393 name_destroy(&nodeuuid);
1395 sptlrpc_conf_log_free(srpc_log);
1399 /* add new mdc to already existent MDS */
1400 static int mgs_write_log_mdc_to_mdt(struct obd_device *obd, struct fs_db *fsdb,
1401 struct mgs_target_info *mti, char *logname)
1403 struct llog_handle *llh = NULL;
1404 struct sptlrpc_conf_log *srpc_log;
1405 char *nodeuuid, *mdcname, *mdcuuid, *mdtuuid;
1406 int idx = mti->mti_stripe_index;
1411 if (mgs_log_is_empty(obd, mti->mti_svname)) {
1412 CERROR("log is empty! Logical error\n");
1416 CDEBUG(D_MGS, "adding mdc index %d to %s\n", idx, logname);
1418 srpc_log = sptlrpc_conf_log_alloc();
1419 if (IS_ERR(srpc_log))
1420 RETURN(PTR_ERR(srpc_log));
1421 srpc_log->scl_part = LUSTRE_SP_MDT;
1423 rc = mgs_get_srpc_conf_log(fsdb, mti->mti_svname,
1424 LUSTRE_SP_MDT, LUSTRE_SP_MDT, srpc_log);
1428 name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
1429 snprintf(index, sizeof(index), "-mdc%04x", idx);
1430 name_create(&mdcname, logname, index);
1431 name_create(&mdcuuid, mdcname, "_UUID");
1432 name_create(&mdtuuid, logname, "_UUID");
1434 rc = record_start_log(obd, &llh, logname);
1435 rc = record_marker(obd, llh, fsdb, CM_START, mti->mti_svname, "add mdc");
1436 for (i = 0; i < mti->mti_nid_count; i++) {
1437 CDEBUG(D_MGS, "add nid %s for mdt\n",
1438 libcfs_nid2str(mti->mti_nids[i]));
1439 rc = record_add_uuid(obd, llh, mti->mti_nids[i], nodeuuid);
1441 rc = record_attach(obd, llh, mdcname, LUSTRE_MDC_NAME, mdcuuid);
1442 rc = record_setup(obd, llh, mdcname, mti->mti_uuid, nodeuuid, 0, 0);
1443 rc = record_sptlrpc_conf(obd, llh, mdcname, srpc_log);
1444 rc = mgs_write_log_failnids(obd, mti, llh, mdcname);
1445 snprintf(index, sizeof(index), "%d", idx);
1447 rc = record_mdc_add(obd, llh, logname, mdcuuid, mti->mti_uuid,
1449 rc = record_marker(obd, llh, fsdb, CM_END, mti->mti_svname, "add mdc");
1450 rc = record_end_log(obd, &llh);
1452 name_destroy(&mdcuuid);
1453 name_destroy(&mdcname);
1454 name_destroy(&nodeuuid);
1455 name_destroy(&mdtuuid);
1457 sptlrpc_conf_log_free(srpc_log);
1461 static int mgs_write_log_mdt0(struct obd_device *obd, struct fs_db *fsdb,
1462 struct mgs_target_info *mti)
1464 char *log = mti->mti_svname;
1465 struct llog_handle *llh = NULL;
1466 char *uuid, *lovname;
1468 struct sptlrpc_conf_log *srpc_log;
1469 char *ptr = mti->mti_params;
1470 int rc = 0, failout = 0;
1473 srpc_log = sptlrpc_conf_log_alloc();
1474 if (IS_ERR(srpc_log))
1475 RETURN(PTR_ERR(srpc_log));
1476 srpc_log->scl_part = LUSTRE_SP_MDT;
1478 rc = mgs_get_srpc_conf_log(fsdb, mti->mti_svname,
1479 LUSTRE_SP_ANY, LUSTRE_SP_MDT, srpc_log);
1483 OBD_ALLOC(uuid, sizeof(struct obd_uuid));
1485 GOTO(out_srpc, rc = -ENOMEM);
1487 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
1488 failout = (strncmp(ptr, "failout", 7) == 0);
1490 name_create(&lovname, log, "-mdtlov");
1491 if (mgs_log_is_empty(obd, log))
1492 rc = mgs_write_log_lov(obd, fsdb, mti, log, lovname);
1494 sprintf(uuid, "%s_UUID", log);
1495 sprintf(mdt_index,"%d",mti->mti_stripe_index);
1497 /* add MDT itself */
1498 rc = record_start_log(obd, &llh, log);
1502 /* FIXME this whole fn should be a single journal transaction */
1503 rc = record_marker(obd, llh, fsdb, CM_START, log, "add mdt");
1504 rc = record_attach(obd, llh, log, LUSTRE_MDT_NAME, uuid);
1505 rc = record_mount_opt(obd, llh, log, lovname, NULL);
1506 rc = record_setup(obd, llh, log, uuid, mdt_index, lovname,
1507 failout ? "n" : "f");
1508 rc = record_sptlrpc_conf(obd, llh, log, srpc_log);
1509 rc = record_marker(obd, llh, fsdb, CM_END, log, "add mdt");
1510 rc = record_end_log(obd, &llh);
1512 name_destroy(&lovname);
1513 OBD_FREE(uuid, sizeof(struct obd_uuid));
1515 sptlrpc_conf_log_free(srpc_log);
1519 /* envelope method for all layers log */
1520 static int mgs_write_log_mdt(struct obd_device *obd, struct fs_db *fsdb,
1521 struct mgs_target_info *mti)
1523 struct llog_handle *llh = NULL;
1525 struct temp_comp comp = { 0 };
1530 CDEBUG(D_MGS, "writing new mdt %s\n", mti->mti_svname);
1534 if (mti->mti_flags & LDD_F_UPGRADE14) {
1535 /* We're starting with an old uuid. Assume old name for lov
1536 as well since the lov entry already exists in the log. */
1537 CDEBUG(D_MGS, "old mds uuid %s\n", mti->mti_uuid);
1538 if (strncmp(mti->mti_uuid, fsdb->fsdb_mdtlov + 4,
1539 strlen(fsdb->fsdb_mdtlov) - 4) != 0) {
1540 CERROR("old mds uuid %s doesn't match log %s (%s)\n",
1541 mti->mti_uuid, fsdb->fsdb_mdtlov,
1542 fsdb->fsdb_mdtlov + 4);
1546 /* end COMPAT_146 */
1548 if (mti->mti_uuid[0] == '\0') {
1549 /* Make up our own uuid */
1550 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
1551 "%s_UUID", mti->mti_svname);
1555 rc = mgs_write_log_mdt0(obd, fsdb, mti);
1557 /* Append the mdt info to the client log */
1558 name_create(&cliname, mti->mti_fsname, "-client");
1560 if (mgs_log_is_empty(obd, cliname)) {
1561 /* Start client log */
1562 rc = mgs_write_log_lov(obd, fsdb, mti, cliname,
1564 rc = mgs_write_log_lmv(obd, fsdb, mti, cliname,
1569 #09 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
1570 #10 L attach 0:MDC_uml1_mdsA_MNT_client 1:mdc 2:1d834_MNT_client_03f
1571 #11 L setup 0:MDC_uml1_mdsA_MNT_client 1:mdsA_UUID 2:uml1_UUID
1572 #12 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
1573 #13 L add_conn 0:MDC_uml1_mdsA_MNT_client 1:uml2_UUID
1574 #14 L mount_option 0: 1:client 2:lov1 3:MDC_uml1_mdsA_MNT_client
1579 if (mti->mti_flags & LDD_F_UPGRADE14) {
1580 rc = record_start_log(obd, &llh, cliname);
1584 rc = record_marker(obd, llh, fsdb, CM_START,
1585 mti->mti_svname,"add mdc");
1587 /* Old client log already has MDC entry, but needs mount opt
1588 for new client name (lustre-client) */
1589 /* FIXME Old MDT log already has an old mount opt
1590 which we should remove (currently handled by
1591 class_del_profiles()) */
1592 rc = record_mount_opt(obd, llh, cliname, fsdb->fsdb_clilov,
1594 /* end COMPAT_146 */
1596 rc = record_marker(obd, llh, fsdb, CM_END,
1597 mti->mti_svname, "add mdc");
1601 /* copy client info about lov/lmv */
1602 comp.comp_mti = mti;
1603 comp.comp_fsdb = fsdb;
1605 rc = mgs_steal_llog_for_mdt_from_client(obd, cliname,
1608 rc = mgs_write_log_mdc_to_lmv(obd, fsdb, mti, cliname,
1611 rc = record_start_log(obd, &llh, cliname);
1615 rc = record_marker(obd, llh, fsdb, CM_START, cliname,
1617 rc = record_mount_opt(obd, llh, cliname, fsdb->fsdb_clilov,
1619 rc = record_marker(obd, llh, fsdb, CM_END, cliname,
1623 rc = record_end_log(obd, &llh);
1625 name_destroy(&cliname);
1627 // for_all_existing_mdt except current one
1628 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
1630 if (i != mti->mti_stripe_index &&
1631 test_bit(i, fsdb->fsdb_mdt_index_map)) {
1632 sprintf(mdt_index,"-MDT%04x",i);
1634 name_create(&mdtname, mti->mti_fsname, mdt_index);
1635 rc = mgs_write_log_mdc_to_mdt(obd, fsdb, mti, mdtname);
1636 name_destroy(&mdtname);
1643 /* Add the ost info to the client/mdt lov */
1644 static int mgs_write_log_osc_to_lov(struct obd_device *obd, struct fs_db *fsdb,
1645 struct mgs_target_info *mti,
1646 char *logname, char *suffix, char *lovname,
1647 enum lustre_sec_part sec_part, int flags)
1649 struct llog_handle *llh = NULL;
1650 struct sptlrpc_conf_log *srpc_log;
1651 char *nodeuuid, *oscname, *oscuuid, *lovuuid, *svname;
1656 CDEBUG(D_INFO, "adding osc for %s to log %s\n",
1657 mti->mti_svname, logname);
1659 srpc_log = sptlrpc_conf_log_alloc();
1660 if (IS_ERR(srpc_log))
1661 RETURN(PTR_ERR(srpc_log));
1662 srpc_log->scl_part = sec_part;
1664 rc = mgs_get_srpc_conf_log(fsdb, mti->mti_svname,
1665 sec_part, LUSTRE_SP_OST, srpc_log);
1669 if (mgs_log_is_empty(obd, logname)) {
1670 /* The first item in the log must be the lov, so we have
1671 somewhere to add our osc. */
1672 rc = mgs_write_log_lov(obd, fsdb, mti, logname, lovname);
1675 name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
1676 name_create(&svname, mti->mti_svname, "-osc");
1677 name_create(&oscname, svname, suffix);
1678 name_create(&oscuuid, oscname, "_UUID");
1679 name_create(&lovuuid, lovname, "_UUID");
1682 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
1684 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
1685 #04 L attach 0:OSC_uml1_ost1_MNT_client 1:osc 2:89070_lov1_a41dff51a
1686 #05 L setup 0:OSC_uml1_ost1_MNT_client 1:ost1_UUID 2:uml1_UUID
1688 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
1689 #07 L add_conn 0:OSC_uml1_ost1_MNT_client 1:uml2_UUID
1690 #08 L lov_modify_tgts add 0:lov1 1:ost1_UUID 2(index):0 3(gen):1
1693 rc = record_start_log(obd, &llh, logname);
1696 /* FIXME these should be a single journal transaction */
1697 rc = record_marker(obd, llh, fsdb, CM_START | flags, mti->mti_svname,
1699 for (i = 0; i < mti->mti_nid_count; i++) {
1700 CDEBUG(D_MGS, "add nid %s\n", libcfs_nid2str(mti->mti_nids[i]));
1701 rc = record_add_uuid(obd, llh, mti->mti_nids[i], nodeuuid);
1703 rc = record_attach(obd, llh, oscname, LUSTRE_OSC_NAME, lovuuid);
1704 rc = record_setup(obd, llh, oscname, mti->mti_uuid, nodeuuid, 0, 0);
1705 rc = record_sptlrpc_conf(obd, llh, oscname, srpc_log);
1706 rc = mgs_write_log_failnids(obd, mti, llh, oscname);
1707 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
1708 rc = record_lov_add(obd, llh, lovname, mti->mti_uuid, index, "1");
1709 rc = record_marker(obd, llh, fsdb, CM_END | flags, mti->mti_svname,
1711 rc = record_end_log(obd, &llh);
1713 name_destroy(&lovuuid);
1714 name_destroy(&oscuuid);
1715 name_destroy(&oscname);
1716 name_destroy(&svname);
1717 name_destroy(&nodeuuid);
1719 sptlrpc_conf_log_free(srpc_log);
1723 static int mgs_write_log_ost(struct obd_device *obd, struct fs_db *fsdb,
1724 struct mgs_target_info *mti)
1726 struct llog_handle *llh = NULL;
1727 struct sptlrpc_conf_log *srpc_log;
1728 char *logname, *lovname;
1730 char *ptr = mti->mti_params;
1731 int rc, flags = 0, failout = 0, i;
1734 CDEBUG(D_MGS, "writing new ost %s\n", mti->mti_svname);
1736 /* The ost startup log */
1738 /* If the ost log already exists, that means that someone reformatted
1739 the ost and it called target_add again. */
1740 if (!mgs_log_is_empty(obd, mti->mti_svname)) {
1741 LCONSOLE_ERROR_MSG(0x141, "The config log for %s already "
1742 "exists, yet the server claims it never "
1743 "registered. It may have been reformatted, "
1744 "or the index changed. writeconf the MDT to "
1745 "regenerate all logs.\n", mti->mti_svname);
1749 srpc_log = sptlrpc_conf_log_alloc();
1750 if (IS_ERR(srpc_log))
1751 RETURN(PTR_ERR(srpc_log));
1752 srpc_log->scl_part = LUSTRE_SP_OST;
1754 rc = mgs_get_srpc_conf_log(fsdb, mti->mti_svname,
1755 LUSTRE_SP_ANY, LUSTRE_SP_OST, srpc_log);
1760 attach obdfilter ost1 ost1_UUID
1761 setup /dev/loop2 ldiskfs f|n errors=remount-ro,user_xattr
1763 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
1764 failout = (strncmp(ptr, "failout", 7) == 0);
1765 rc = record_start_log(obd, &llh, mti->mti_svname);
1768 /* FIXME these should be a single journal transaction */
1769 rc = record_marker(obd, llh, fsdb, CM_START, mti->mti_svname,"add ost");
1770 if (*mti->mti_uuid == '\0')
1771 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
1772 "%s_UUID", mti->mti_svname);
1773 rc = record_attach(obd, llh, mti->mti_svname,
1774 "obdfilter"/*LUSTRE_OST_NAME*/, mti->mti_uuid);
1775 rc = record_setup(obd, llh, mti->mti_svname,
1776 "dev"/*ignored*/, "type"/*ignored*/,
1777 failout ? "n" : "f", 0/*options*/);
1778 rc = record_sptlrpc_conf(obd, llh, mti->mti_svname, srpc_log);
1779 rc = record_marker(obd, llh, fsdb, CM_END, mti->mti_svname, "add ost");
1780 rc = record_end_log(obd, &llh);
1782 /* We also have to update the other logs where this osc is part of
1785 if (fsdb->fsdb_flags & FSDB_OLDLOG14) {
1786 /* If we're upgrading, the old mdt log already has our
1787 entry. Let's do a fake one for fun. */
1788 /* Note that we can't add any new failnids, since we don't
1789 know the old osc names. */
1790 flags = CM_SKIP | CM_UPGRADE146;
1792 } else if ((mti->mti_flags & LDD_F_UPDATE) != LDD_F_UPDATE) {
1793 /* If the update flag isn't set, don't update client/mdt
1796 LCONSOLE_WARN("Client log for %s was not updated; writeconf "
1797 "the MDT first to regenerate it.\n",
1801 // for_all_existing_mdt
1802 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
1803 if (test_bit(i, fsdb->fsdb_mdt_index_map)) {
1804 sprintf(mdt_index,"-MDT%04x",i);
1805 name_create(&logname, mti->mti_fsname, mdt_index);
1806 name_create(&lovname, logname, "-mdtlov");
1807 mgs_write_log_osc_to_lov(obd, fsdb, mti, logname,
1809 LUSTRE_SP_MDT, flags);
1810 name_destroy(&logname);
1811 name_destroy(&lovname);
1815 /* Append ost info to the client log */
1816 name_create(&logname, mti->mti_fsname, "-client");
1817 mgs_write_log_osc_to_lov(obd, fsdb, mti, logname, "",
1818 fsdb->fsdb_clilov, LUSTRE_SP_CLI, 0);
1819 name_destroy(&logname);
1821 sptlrpc_conf_log_free(srpc_log);
1825 /* Add additional failnids to an existing log.
1826 The mdc/osc must have been added to logs first */
1827 /* tcp nids must be in dotted-quad ascii -
1828 we can't resolve hostnames from the kernel. */
1829 static int mgs_write_log_add_failnid(struct obd_device *obd, struct fs_db *fsdb,
1830 struct mgs_target_info *mti)
1832 char *logname, *cliname;
1833 struct llog_handle *llh = NULL;
1837 /* FIXME how do we delete a failnid? Currently --writeconf is the
1838 only way. Maybe make --erase-params pass a flag to really
1839 erase all params from logs - except it can't erase the failnids
1840 given when a target first registers, since they aren't processed
1843 /* Verify that we know about this target */
1844 if (mgs_log_is_empty(obd, mti->mti_svname)) {
1845 LCONSOLE_ERROR_MSG(0x142, "The target %s has not registered "
1846 "yet. It must be started before failnids "
1847 "can be added.\n", mti->mti_svname);
1851 /* Create mdc/osc client name (e.g. lustre-OST0001-osc) */
1852 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
1853 name_create(&cliname, mti->mti_svname, "-mdc");
1854 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
1855 name_create(&cliname, mti->mti_svname, "-osc");
1860 /* Add failover nids to client log */
1861 name_create(&logname, mti->mti_fsname, "-client");
1862 rc = record_start_log(obd, &llh, logname);
1864 /* FIXME this fn should be a single journal transaction */
1865 rc = record_marker(obd, llh, fsdb, CM_START, mti->mti_svname,
1867 rc = mgs_write_log_failnids(obd, mti, llh, cliname);
1868 rc = record_marker(obd, llh, fsdb, CM_END, mti->mti_svname,
1870 rc = record_end_log(obd, &llh);
1872 name_destroy(&logname);
1874 if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
1875 /* Add OST failover nids to the MDT log as well */
1876 name_create(&logname, mti->mti_fsname, "-MDT0000");
1877 rc = record_start_log(obd, &llh, logname);
1879 rc = record_marker(obd, llh, fsdb, CM_START,
1880 mti->mti_svname, "add failnid");
1881 rc = mgs_write_log_failnids(obd, mti, llh, cliname);
1882 rc = record_marker(obd, llh, fsdb, CM_END,
1883 mti->mti_svname, "add failnid");
1884 rc = record_end_log(obd, &llh);
1886 name_destroy(&logname);
1889 name_destroy(&cliname);
1893 static int mgs_wlp_lcfg(struct obd_device *obd, struct fs_db *fsdb,
1894 struct mgs_target_info *mti,
1895 char *logname, struct lustre_cfg_bufs *bufs,
1896 char *tgtname, char *ptr)
1898 char comment[MTI_NAME_MAXLEN];
1900 struct lustre_cfg *lcfg;
1903 /* Erase any old settings of this same parameter */
1904 memcpy(comment, ptr, MTI_NAME_MAXLEN);
1905 comment[MTI_NAME_MAXLEN - 1] = 0;
1906 /* But don't try to match the value. */
1907 if ((tmp = strchr(comment, '=')))
1909 /* FIXME we should skip settings that are the same as old values */
1910 rc = mgs_modify(obd, fsdb, mti, logname, tgtname, comment, CM_SKIP);
1911 LCONSOLE_INFO("%sing parameter %s.%s in log %s\n", rc ?
1912 "Sett" : "Modify", tgtname, comment, logname);
1914 lustre_cfg_bufs_reset(bufs, tgtname);
1915 lustre_cfg_bufs_set_string(bufs, 1, ptr);
1916 lcfg = lustre_cfg_new(LCFG_PARAM, bufs);
1919 rc = mgs_write_log_direct(obd, fsdb, logname, lcfg, tgtname, comment);
1920 lustre_cfg_free(lcfg);
1925 * populate rules which applied to a target device
1927 static int mgs_get_srpc_conf_log(struct fs_db *fsdb, const char *tgt,
1928 enum lustre_sec_part from,
1929 enum lustre_sec_part to,
1930 struct sptlrpc_conf_log *log)
1932 struct mgs_tgt_srpc_conf *tgtconf;
1933 struct sptlrpc_rule_set *tgt_rset;
1934 int found_tgt = 0, rc;
1936 for (tgtconf = fsdb->fsdb_srpc_tgt; tgtconf;
1937 tgtconf = tgtconf->mtsc_next) {
1938 if (!strcmp(tgt, tgtconf->mtsc_tgt)) {
1945 tgt_rset = &tgtconf->mtsc_rset;
1949 rc = sptlrpc_conf_log_populate(&fsdb->fsdb_srpc_gen, tgt_rset,
1950 from, to, fsdb->fsdb_srpc_fl_udesc, log);
1952 CERROR("failed to populate srpc log for %s: %d\n", tgt, rc);
1957 struct mgs_msl_data {
1958 struct obd_device *mmd_obd;
1959 struct fs_db *mmd_fsdb;
1960 struct mgs_target_info *mmd_mti;
1964 enum lustre_sec_part mmd_tgtpart;
1965 char mmd_tgtname[MTI_NAME_MAXLEN];
1968 static void mgs_msl_data_cleanup(struct mgs_msl_data *mmd)
1970 mmd->mmd_attached = 0;
1971 mmd->mmd_tgtname[0] = '\0';
1974 static int mgs_msl_tgt_uuid2name(char *tgtname, char *tgtuuid)
1978 if (tgtuuid == NULL) {
1979 CERROR("missing target UUID???\n");
1983 ptr = strstr(tgtuuid, "_UUID");
1985 CERROR("unrecognized UUID: %s\n", tgtuuid);
1990 strncpy(tgtname, tgtuuid, MTI_NAME_MAXLEN);
1991 tgtname[MTI_NAME_MAXLEN - 1] = '\0';
1996 static int mgs_modify_srpc_log_handler(struct llog_handle *llh,
1997 struct llog_rec_hdr *rec,
2000 struct mgs_msl_data *mmd = (struct mgs_msl_data *)data;
2001 struct cfg_marker *marker;
2002 struct lustre_cfg *lcfg = (struct lustre_cfg *)(rec + 1);
2006 if (rec->lrh_type != OBD_CFG_REC) {
2007 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
2011 cfg_len = rec->lrh_len - sizeof(struct llog_rec_hdr) -
2012 sizeof(struct llog_rec_tail);
2014 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
2016 CERROR("Insane cfg\n");
2020 if (lcfg->lcfg_command == LCFG_MARKER) {
2021 marker = lustre_cfg_buf(lcfg, 1);
2023 if (marker->cm_flags & CM_START &&
2024 marker->cm_flags & CM_SKIP)
2026 if (marker->cm_flags & CM_END)
2035 switch (lcfg->lcfg_command) {
2037 mmd->mmd_attached = 1;
2039 if (!strcmp(lustre_cfg_string(lcfg, 1), LUSTRE_OST_NAME)) {
2040 mmd->mmd_server = 1;
2041 mmd->mmd_tgtpart = LUSTRE_SP_OST;
2042 } else if (!strcmp(lustre_cfg_string(lcfg, 1),
2044 mmd->mmd_server = 1;
2045 mmd->mmd_tgtpart = LUSTRE_SP_MDT;
2046 } else if (!strcmp(lustre_cfg_string(lcfg, 1),
2048 mmd->mmd_server = 0;
2049 mmd->mmd_tgtpart = LUSTRE_SP_OST;
2050 } else if (!strcmp(lustre_cfg_string(lcfg, 1),
2052 mmd->mmd_server = 0;
2053 mmd->mmd_tgtpart = LUSTRE_SP_MDT;
2055 mmd->mmd_attached = 0;
2058 if (mmd->mmd_attached && mmd->mmd_server) {
2059 rc = mgs_msl_tgt_uuid2name(mmd->mmd_tgtname,
2060 lustre_cfg_string(lcfg, 2));
2062 mgs_msl_data_cleanup(mmd);
2069 if (!mmd->mmd_attached)
2072 /* already got tgtname at LCFG_ATTACH */
2073 if (mmd->mmd_server)
2076 rc = mgs_msl_tgt_uuid2name(mmd->mmd_tgtname,
2077 lustre_cfg_string(lcfg, 1));
2079 mgs_msl_data_cleanup(mmd);
2084 case LCFG_SPTLRPC_CONF: {
2085 struct sptlrpc_conf_log *log;
2086 enum lustre_sec_part from;
2088 if (!mmd->mmd_attached)
2091 log = sptlrpc_conf_log_extract(lcfg);
2093 CERROR("missing sptlrpc config log???\n");
2094 mgs_msl_data_cleanup(mmd);
2098 if (mmd->mmd_server)
2099 from = LUSTRE_SP_ANY;
2101 from = log->scl_part;
2103 /* cleanup the old log */
2104 sptlrpc_conf_log_cleanup(log);
2106 /* populate new log */
2107 rc = mgs_get_srpc_conf_log(mmd->mmd_fsdb, mmd->mmd_tgtname,
2108 from, mmd->mmd_tgtpart, log);
2110 mgs_msl_data_cleanup(mmd);
2114 /* Overwrite the log */
2115 rec->lrh_len = cfg_len;
2116 rc = llog_write_rec(llh, rec, NULL, 0, (void *)lcfg,
2119 CERROR("overwrite sptlrpc conf log failed: %d\n", rc);
2121 /* append new one */
2122 rc = record_marker(mmd->mmd_obd, llh, mmd->mmd_fsdb, CM_START,
2123 mmd->mmd_mti->mti_svname, "sptlrpc config");
2124 rc = record_sptlrpc_conf(mmd->mmd_obd, llh,
2125 lustre_cfg_string(lcfg, 0), log);
2126 rc = record_marker(mmd->mmd_obd, llh, mmd->mmd_fsdb, CM_END,
2127 mmd->mmd_mti->mti_svname, "sptlrpc config");
2129 mgs_msl_data_cleanup(mmd);
2133 /* ignore all others */
2140 static int mgs_modify_srpc_log(struct obd_device *obd,
2142 struct mgs_target_info *mti,
2145 struct llog_handle *llh;
2146 struct lvfs_run_ctxt saved;
2147 struct llog_ctxt *ctxt;
2148 struct mgs_msl_data *mmd;
2152 CDEBUG(D_MGS, "modify sptlrpc log for %s\n", logname);
2154 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
2156 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
2157 LASSERT(ctxt != NULL);
2158 rc = llog_create(ctxt, &llh, NULL, logname);
2162 rc = llog_init_handle(llh, LLOG_F_IS_PLAIN, NULL);
2164 GOTO(out_close, rc);
2166 if (llog_get_size(llh) <= 1)
2167 GOTO(out_close, rc = 0);
2171 GOTO(out_close, rc = -ENOMEM);
2174 mmd->mmd_fsdb = fsdb;
2177 rc = llog_process(llh, mgs_modify_srpc_log_handler, (void *) mmd, NULL);
2182 rc2 = llog_close(llh);
2187 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
2188 llog_ctxt_put(ctxt);
2191 CERROR("modify sptlrpc log %s failed %d\n", logname, rc);
2196 * for each of log, remove old conf at first
2198 static int mgs_modify_srpc_log_all(struct obd_device *obd,
2200 struct mgs_target_info *mti)
2207 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
2208 if (test_bit(i, fsdb->fsdb_mdt_index_map)) {
2209 sprintf(tgt_index,"-MDT%04x",i);
2211 name_create(&logname, mti->mti_fsname, tgt_index);
2212 rc2 = mgs_modify(obd, fsdb, mti, logname,
2213 mti->mti_fsname, "sptlrpc config",
2215 rc2 = mgs_modify_srpc_log(obd, fsdb, mti, logname);
2216 name_destroy(&logname);
2223 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
2224 if (test_bit(i, fsdb->fsdb_ost_index_map)) {
2225 sprintf(tgt_index,"-OST%04x",i);
2227 name_create(&logname, mti->mti_fsname, tgt_index);
2228 rc2 = mgs_modify(obd, fsdb, mti, logname,
2229 mti->mti_fsname, "sptlrpc config",
2231 rc2 = mgs_modify_srpc_log(obd, fsdb, mti, logname);
2232 name_destroy(&logname);
2239 name_create(&logname, mti->mti_fsname, "-client");
2240 rc2 = mgs_modify(obd, fsdb, mti, logname,
2241 mti->mti_fsname, "sptlrpc config", CM_SKIP);
2242 rc2 = mgs_modify_srpc_log(obd, fsdb, mti, logname);
2243 name_destroy(&logname);
2251 static int mgs_srpc_set_param_disk(struct obd_device *obd,
2253 struct mgs_target_info *mti,
2256 struct llog_handle *llh = NULL;
2258 char *comment, *ptr;
2259 struct lustre_cfg_bufs bufs;
2260 struct lustre_cfg *lcfg;
2265 ptr = strchr(param, '=');
2269 OBD_ALLOC(comment, len + 1);
2270 if (comment == NULL)
2272 strncpy(comment, param, len);
2273 comment[len] = '\0';
2276 lustre_cfg_bufs_reset(&bufs, mti->mti_svname);
2277 lustre_cfg_bufs_set_string(&bufs, 1, param);
2278 lcfg = lustre_cfg_new(0, &bufs);
2280 GOTO(out_comment, rc = -ENOMEM);
2282 /* construct log name */
2283 rc = name_create(&logname, mti->mti_fsname, "-sptlrpc");
2287 if (mgs_log_is_empty(obd, logname)) {
2288 rc = record_start_log(obd, &llh, logname);
2289 record_end_log(obd, &llh);
2294 /* obsolete old one */
2295 mgs_modify(obd, fsdb, mti, logname, mti->mti_svname, comment, CM_SKIP);
2297 /* write the new one */
2298 rc = mgs_write_log_direct(obd, fsdb, logname, lcfg,
2299 mti->mti_svname, comment);
2301 CERROR("err %d writing log %s\n", rc, logname);
2304 name_destroy(&logname);
2306 lustre_cfg_free(lcfg);
2308 OBD_FREE(comment, len + 1);
2312 static int mgs_srpc_set_param_udesc_mem(struct fs_db *fsdb,
2317 /* disable the adjustable udesc parameter for now, i.e. use default
2318 * setting that client always ship udesc to MDT if possible. to enable
2319 * it simply remove the following line */
2322 ptr = strchr(param, '=');
2327 if (strcmp(param, PARAM_SRPC_UDESC))
2330 if (strcmp(ptr, "yes") == 0) {
2331 fsdb->fsdb_srpc_fl_udesc = 1;
2332 CWARN("Enable user descriptor shipping from client to MDT\n");
2333 } else if (strcmp(ptr, "no") == 0) {
2334 fsdb->fsdb_srpc_fl_udesc = 0;
2335 CWARN("Disable user descriptor shipping from client to MDT\n");
2343 CERROR("Invalid param: %s\n", param);
2347 static int mgs_srpc_set_param_mem(struct fs_db *fsdb,
2351 struct sptlrpc_rule rule;
2352 struct sptlrpc_rule_set *rset;
2356 if (strncmp(param, PARAM_SRPC, sizeof(PARAM_SRPC) - 1) != 0) {
2357 CERROR("Invalid sptlrpc parameter: %s\n", param);
2361 if (strncmp(param, PARAM_SRPC_UDESC,
2362 sizeof(PARAM_SRPC_UDESC) - 1) == 0) {
2363 RETURN(mgs_srpc_set_param_udesc_mem(fsdb, param));
2366 if (strncmp(param, PARAM_SRPC_FLVR, sizeof(PARAM_SRPC_FLVR) - 1) != 0) {
2367 CERROR("Invalid sptlrpc flavor parameter: %s\n", param);
2371 param += sizeof(PARAM_SRPC_FLVR) - 1;
2373 rc = sptlrpc_parse_rule(param, &rule);
2377 /* preapre room for this coming rule. svcname format should be:
2378 * - fsname: general rule
2379 * - fsname-tgtname: target-specific rule
2381 if (strchr(svname, '-')) {
2382 struct mgs_tgt_srpc_conf *tgtconf;
2385 for (tgtconf = fsdb->fsdb_srpc_tgt; tgtconf != NULL;
2386 tgtconf = tgtconf->mtsc_next) {
2387 if (!strcmp(tgtconf->mtsc_tgt, svname)) {
2396 OBD_ALLOC_PTR(tgtconf);
2397 if (tgtconf == NULL)
2400 name_len = strlen(svname);
2402 OBD_ALLOC(tgtconf->mtsc_tgt, name_len + 1);
2403 if (tgtconf->mtsc_tgt == NULL) {
2404 OBD_FREE_PTR(tgtconf);
2407 memcpy(tgtconf->mtsc_tgt, svname, name_len);
2409 tgtconf->mtsc_next = fsdb->fsdb_srpc_tgt;
2410 fsdb->fsdb_srpc_tgt = tgtconf;
2413 rset = &tgtconf->mtsc_rset;
2415 rset = &fsdb->fsdb_srpc_gen;
2418 /* limit the maximum number of rules, but allow deletion in any case */
2419 if (rset->srs_nrule >= SPTLRPC_CONF_LOG_MAX / 2 &&
2420 rule.sr_flvr.sf_rpc != SPTLRPC_FLVR_INVALID) {
2421 CERROR("too many (%d) rules already for %s\n",
2422 rset->srs_nrule, svname);
2426 rc = sptlrpc_rule_set_merge(rset, &rule, 1);
2431 static int mgs_srpc_set_param(struct obd_device *obd,
2433 struct mgs_target_info *mti,
2440 /* keep a copy of original param, which could be destroied
2442 copy_size = strlen(param) + 1;
2443 OBD_ALLOC(copy, copy_size);
2446 memcpy(copy, param, copy_size);
2448 rc = mgs_srpc_set_param_mem(fsdb, mti->mti_svname, param);
2452 /* previous steps guaranteed the syntax is correct */
2453 rc = mgs_srpc_set_param_disk(obd, fsdb, mti, copy);
2457 /* now apply the new rules to all existing config logs */
2458 rc = mgs_modify_srpc_log_all(obd, fsdb, mti);
2461 OBD_FREE(copy, copy_size);
2465 struct mgs_srpc_read_data {
2466 struct fs_db *msrd_fsdb;
2470 static int mgs_srpc_read_handler(struct llog_handle *llh,
2471 struct llog_rec_hdr *rec,
2474 struct mgs_srpc_read_data *msrd = (struct mgs_srpc_read_data *) data;
2475 struct cfg_marker *marker;
2476 struct lustre_cfg *lcfg = (struct lustre_cfg *)(rec + 1);
2477 char *svname, *param;
2481 if (rec->lrh_type != OBD_CFG_REC) {
2482 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
2486 cfg_len = rec->lrh_len - sizeof(struct llog_rec_hdr) -
2487 sizeof(struct llog_rec_tail);
2489 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
2491 CERROR("Insane cfg\n");
2495 if (lcfg->lcfg_command == LCFG_MARKER) {
2496 marker = lustre_cfg_buf(lcfg, 1);
2498 if (marker->cm_flags & CM_START &&
2499 marker->cm_flags & CM_SKIP)
2500 msrd->msrd_skip = 1;
2501 if (marker->cm_flags & CM_END)
2502 msrd->msrd_skip = 0;
2507 if (msrd->msrd_skip)
2510 if (lcfg->lcfg_command != 0) {
2511 CERROR("invalid command (%x)\n", lcfg->lcfg_command);
2515 svname = lustre_cfg_string(lcfg, 0);
2516 if (svname == NULL) {
2517 CERROR("svname is empty\n");
2521 param = lustre_cfg_string(lcfg, 1);
2522 if (param == NULL) {
2523 CERROR("param is empty\n");
2527 rc = mgs_srpc_set_param_mem(msrd->msrd_fsdb, svname, param);
2529 CERROR("read sptlrpc record error (%d): %s\n", rc, param);
2534 static int mgs_get_fsdb_srpc_from_llog(struct obd_device *obd,
2537 struct llog_handle *llh = NULL;
2538 struct lvfs_run_ctxt saved;
2539 struct llog_ctxt *ctxt;
2541 struct mgs_srpc_read_data msrd;
2545 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
2546 LASSERT(ctxt != NULL);
2548 /* construct log name */
2549 rc = name_create(&logname, fsdb->fsdb_name, "-sptlrpc");
2553 if (mgs_log_is_empty(obd, logname))
2556 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
2558 rc = llog_create(ctxt, &llh, NULL, logname);
2562 rc = llog_init_handle(llh, LLOG_F_IS_PLAIN, NULL);
2564 GOTO(out_close, rc);
2566 if (llog_get_size(llh) <= 1)
2567 GOTO(out_close, rc = 0);
2569 msrd.msrd_fsdb = fsdb;
2572 rc = llog_process(llh, mgs_srpc_read_handler, (void *) &msrd, NULL);
2577 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
2579 name_destroy(&logname);
2580 llog_ctxt_put(ctxt);
2583 CERROR("failed to read sptlrpc config database: %d\n", rc);
2587 static int mgs_write_log_params(struct obd_device *obd, struct fs_db *fsdb,
2588 struct mgs_target_info *mti)
2590 struct lustre_cfg_bufs bufs;
2591 struct lustre_cfg *lcfg;
2593 char *ptr = mti->mti_params;
2598 if (!mti->mti_params)
2601 /* For various parameter settings, we have to figure out which logs
2602 care about them (e.g. both mdt and client for lov settings) */
2608 endptr = strchr(ptr, ' ');
2611 CDEBUG(D_MGS, "next param '%s'\n", ptr);
2613 /* The params are stored in MOUNT_DATA_FILE and modified
2614 via tunefs.lustre */
2616 /* Processed in lustre_start_mgc */
2617 if (class_match_param(ptr, PARAM_MGSNODE, NULL) == 0)
2618 GOTO(end_while, rc);
2620 /* Processed in mgs_write_log_ost */
2621 if (class_match_param(ptr, PARAM_FAILMODE, NULL) == 0) {
2622 if (mti->mti_flags & LDD_F_PARAM) {
2623 LCONSOLE_ERROR_MSG(0x169, "%s can only be "
2624 "changed with tunefs.lustre"
2625 "and --writeconf\n", ptr);
2628 GOTO(end_while, rc);
2631 if (class_match_param(ptr, PARAM_SRPC, NULL) == 0) {
2632 rc = mgs_srpc_set_param(obd, fsdb, mti, ptr);
2633 GOTO(end_while, rc);
2636 if (class_match_param(ptr, PARAM_FAILNODE, NULL) == 0) {
2637 /* Add a failover nidlist */
2639 /* We already processed failovers params for new
2640 targets in mgs_write_log_target */
2641 if (mti->mti_flags & LDD_F_PARAM) {
2642 CDEBUG(D_MGS, "Adding failnode\n");
2643 rc = mgs_write_log_add_failnid(obd, fsdb, mti);
2645 GOTO(end_while, rc);
2648 if (class_match_param(ptr, PARAM_SYS_TIMEOUT, &tmp) == 0) {
2649 /* Change obd timeout */
2651 timeout = simple_strtoul(tmp, NULL, 0);
2653 CDEBUG(D_MGS, "obd timeout %d\n", timeout);
2654 lustre_cfg_bufs_reset(&bufs, NULL);
2655 lcfg = lustre_cfg_new(LCFG_SET_TIMEOUT, &bufs);
2656 lcfg->lcfg_num = timeout;
2657 /* modify all servers and clients */
2658 rc = mgs_write_log_direct_all(obd, fsdb, mti, lcfg,
2661 lustre_cfg_free(lcfg);
2662 GOTO(end_while, rc);
2665 if (class_match_param(ptr, PARAM_OSC""PARAM_ACTIVE, &tmp) == 0) {
2666 /* active=0 means off, anything else means on */
2668 int flag = (*tmp == '0') ? CM_EXCLUDE : 0;
2671 if (!(mti->mti_flags & LDD_F_SV_TYPE_OST)) {
2672 LCONSOLE_ERROR_MSG(0x144, "%s: Only OSCs can "
2673 "be (de)activated.\n",
2678 LCONSOLE_WARN("Permanently %sactivating %s\n",
2679 flag ? "de": "re", mti->mti_svname);
2681 name_create(&logname, mti->mti_fsname, "-client");
2682 rc = mgs_modify(obd, fsdb, mti, logname,
2683 mti->mti_svname, "add osc", flag);
2684 name_destroy(&logname);
2688 /* FIXME add to all MDT logs for CMD */
2689 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2690 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
2692 sprintf(mdt_index,"-MDT%04x", i);
2693 name_create(&logname, mti->mti_fsname, mdt_index);
2694 rc = mgs_modify(obd, fsdb, mti, logname,
2695 mti->mti_svname, "add osc", flag);
2696 name_destroy(&logname);
2702 LCONSOLE_ERROR_MSG(0x145, "Couldn't find %s in"
2703 "log (%d). No permanent "
2704 "changes were made to the "
2706 mti->mti_svname, rc);
2707 if (fsdb->fsdb_flags & FSDB_OLDLOG14)
2708 LCONSOLE_ERROR_MSG(0x146, "This may be"
2713 "update the logs.\n");
2716 /* Fall through to osc proc for deactivating
2717 live OSC on running MDT / clients. */
2719 /* Below here, let obd's XXX_process_config methods handle it */
2721 /* All lov. in proc */
2722 if (class_match_param(ptr, PARAM_LOV, NULL) == 0) {
2726 CDEBUG(D_MGS, "lov param %s\n", ptr);
2727 if (!(mti->mti_flags & LDD_F_SV_TYPE_MDT)) {
2728 LCONSOLE_ERROR_MSG(0x147, "LOV params must be "
2729 "set on the MDT, not %s. "
2737 if (mgs_log_is_empty(obd, mti->mti_svname))
2738 GOTO(end_while, rc = -ENODEV);
2740 sprintf(mdt_index,"-MDT%04x", mti->mti_stripe_index);
2741 name_create(&logname, mti->mti_fsname, mdt_index);
2742 name_create(&mdtlovname, logname, "-mdtlov");
2743 rc = mgs_wlp_lcfg(obd, fsdb, mti, mti->mti_svname,
2744 &bufs, mdtlovname, ptr);
2745 name_destroy(&logname);
2746 name_destroy(&mdtlovname);
2748 GOTO(end_while, rc);
2751 name_create(&logname, mti->mti_fsname, "-client");
2752 rc = mgs_wlp_lcfg(obd, fsdb, mti, logname, &bufs,
2753 fsdb->fsdb_clilov, ptr);
2754 name_destroy(&logname);
2755 GOTO(end_while, rc);
2758 /* All osc., mdc., llite. params in proc */
2759 if ((class_match_param(ptr, PARAM_OSC, NULL) == 0) ||
2760 (class_match_param(ptr, PARAM_MDC, NULL) == 0) ||
2761 (class_match_param(ptr, PARAM_LLITE, NULL) == 0)) {
2763 if (memcmp(ptr, PARAM_LLITE, strlen(PARAM_LLITE)) == 0) {
2764 name_create(&cname, mti->mti_fsname, "-client");
2765 /* Add the client type to match the obdname
2766 in class_config_llog_handler */
2767 } else if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
2770 name_create(&cname, fsdb->fsdb_mdc, "");
2772 name_create(&cname, mti->mti_svname,
2774 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2776 if (fsdb->fsdb_flags & FSDB_OLDLOG14) {
2777 LCONSOLE_ERROR_MSG(0x148, "Upgraded "
2778 "client logs for %s"
2780 "modified. Consider"
2782 "configuration with"
2785 /* We don't know the names of all the
2790 name_create(&cname, mti->mti_svname, "-osc");
2796 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
2799 name_create(&logname, mti->mti_fsname, "-client");
2800 rc = mgs_wlp_lcfg(obd, fsdb, mti, logname, &bufs,
2803 /* osc params affect the MDT as well */
2804 if (!rc && (mti->mti_flags & LDD_F_SV_TYPE_OST)) {
2808 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
2809 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
2811 name_destroy(&cname);
2812 sprintf(mdt_index, "-osc-MDT%04x", i);
2813 name_create(&cname, mti->mti_svname,
2815 name_destroy(&logname);
2816 sprintf(mdt_index, "-MDT%04x", i);
2817 name_create(&logname, mti->mti_fsname,
2819 if (!mgs_log_is_empty(obd, logname))
2820 rc = mgs_wlp_lcfg(obd, fsdb,
2828 name_destroy(&logname);
2829 name_destroy(&cname);
2830 GOTO(end_while, rc);
2833 /* All mdt., ost. params in proc */
2834 if ((class_match_param(ptr, PARAM_MDT, NULL) == 0) ||
2835 (class_match_param(ptr, PARAM_OST, NULL) == 0)) {
2836 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
2837 if (mgs_log_is_empty(obd, mti->mti_svname)) {
2841 rc = mgs_wlp_lcfg(obd, fsdb, mti, mti->mti_svname,
2842 &bufs, mti->mti_svname, ptr);
2843 GOTO(end_while, rc);
2846 LCONSOLE_WARN("Ignoring unrecognized param '%s'\n", ptr);
2850 CERROR("err %d on param '%s\n", rc, ptr);
2865 /* Not implementing automatic failover nid addition at this time. */
2866 int mgs_check_failnid(struct obd_device *obd, struct mgs_target_info *mti)
2873 rc = mgs_find_or_make_fsdb(obd, fsname, &fsdb);
2877 if (mgs_log_is_empty(obd, mti->mti_svname))
2878 /* should never happen */
2881 CDEBUG(D_MGS, "Checking for new failnids for %s\n", mti->mti_svname);
2883 /* FIXME We can just check mti->params to see if we're already in
2884 the failover list. Modify mti->params for rewriting back at
2885 server_register_target(). */
2887 down(&fsdb->fsdb_sem);
2888 rc = mgs_write_log_add_failnid(obd, fsdb, mti);
2889 up(&fsdb->fsdb_sem);
2896 int mgs_write_log_target(struct obd_device *obd,
2897 struct mgs_target_info *mti)
2903 /* set/check the new target index */
2904 rc = mgs_set_index(obd, mti);
2906 CERROR("Can't get index (%d)\n", rc);
2911 if (mti->mti_flags & LDD_F_UPGRADE14) {
2912 if (rc == EALREADY) {
2913 LCONSOLE_INFO("Found index %d for %s 1.4 log, "
2914 "upgrading\n", mti->mti_stripe_index,
2917 LCONSOLE_ERROR_MSG(0x149, "Failed to find %s in the old"
2918 " client log. Apparently it is not "
2919 "part of this filesystem, or the old"
2920 " log is wrong.\nUse 'writeconf' on "
2921 "the MDT to force log regeneration."
2922 "\n", mti->mti_svname);
2923 /* Not in client log? Upgrade anyhow...*/
2924 /* Argument against upgrading: reformat MDT,
2925 upgrade OST, then OST will start but will be SKIPped
2926 in client logs. Maybe error now is better. */
2927 /* RETURN(-EINVAL); */
2929 /* end COMPAT_146 */
2931 if (rc == EALREADY) {
2932 LCONSOLE_WARN("Found index %d for %s, updating log\n",
2933 mti->mti_stripe_index, mti->mti_svname);
2934 /* We would like to mark old log sections as invalid
2935 and add new log sections in the client and mdt logs.
2936 But if we add new sections, then live clients will
2937 get repeat setup instructions for already running
2938 osc's. So don't update the client/mdt logs. */
2939 mti->mti_flags &= ~LDD_F_UPDATE;
2943 rc = mgs_find_or_make_fsdb(obd, mti->mti_fsname, &fsdb);
2945 CERROR("Can't get db for %s\n", mti->mti_fsname);
2949 down(&fsdb->fsdb_sem);
2951 if (mti->mti_flags &
2952 (LDD_F_VIRGIN | LDD_F_UPGRADE14 | LDD_F_WRITECONF)) {
2953 /* Generate a log from scratch */
2954 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
2955 rc = mgs_write_log_mdt(obd, fsdb, mti);
2956 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2957 rc = mgs_write_log_ost(obd, fsdb, mti);
2959 CERROR("Unknown target type %#x, can't create log for "
2960 "%s\n", mti->mti_flags, mti->mti_svname);
2963 CERROR("Can't write logs for %s (%d)\n",
2964 mti->mti_svname, rc);
2968 /* Just update the params from tunefs in mgs_write_log_params */
2969 CDEBUG(D_MGS, "Update params for %s\n", mti->mti_svname);
2970 mti->mti_flags |= LDD_F_PARAM;
2973 rc = mgs_write_log_params(obd, fsdb, mti);
2976 up(&fsdb->fsdb_sem);
2981 /* verify that we can handle the old config logs */
2982 int mgs_upgrade_sv_14(struct obd_device *obd, struct mgs_target_info *mti)
2988 /* Create ost log normally, as servers register. Servers
2989 register with their old uuids (from last_rcvd), so old
2990 (MDT and client) logs should work.
2991 - new MDT won't know about old OSTs, only the ones that have
2992 registered, so we need the old MDT log to get the LOV right
2993 in order for old clients to work.
2994 - Old clients connect to the MDT, not the MGS, for their logs, and
2995 will therefore receive the old client log from the MDT /LOGS dir.
2996 - Old clients can continue to use and connect to old or new OSTs
2997 - New clients will contact the MGS for their log
3000 LCONSOLE_INFO("upgrading server %s from pre-1.6\n", mti->mti_svname);
3001 server_mti_print("upgrade", mti);
3003 rc = mgs_find_or_make_fsdb(obd, mti->mti_fsname, &fsdb);
3007 if (fsdb->fsdb_flags & FSDB_LOG_EMPTY) {
3008 LCONSOLE_ERROR_MSG(0x14a, "The old client log %s-client is "
3009 "missing. Was tunefs.lustre successful?\n",
3014 if (fsdb->fsdb_gen == 0) {
3015 /* There were no markers in the client log, meaning we have
3016 not updated the logs for this fs */
3017 CDEBUG(D_MGS, "found old, unupdated client log\n");
3020 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
3021 if (mgs_log_is_empty(obd, mti->mti_svname)) {
3022 LCONSOLE_ERROR_MSG(0x14b, "The old MDT log %s is "
3023 "missing. Was tunefs.lustre "
3028 /* We're starting with an old uuid. Assume old name for lov
3029 as well since the lov entry already exists in the log. */
3030 CDEBUG(D_MGS, "old mds uuid %s\n", mti->mti_uuid);
3031 if (strncmp(mti->mti_uuid, fsdb->fsdb_mdtlov + 4,
3032 strlen(fsdb->fsdb_mdtlov) - 4) != 0) {
3033 CERROR("old mds uuid %s doesn't match log %s (%s)\n",
3034 mti->mti_uuid, fsdb->fsdb_mdtlov,
3035 fsdb->fsdb_mdtlov + 4);
3040 if (!(fsdb->fsdb_flags & FSDB_OLDLOG14)) {
3041 LCONSOLE_ERROR_MSG(0x14c, "%s-client is supposedly an old "
3042 "log, but no old LOV or MDT was found. "
3043 "Consider updating the configuration with"
3044 " --writeconf.\n", mti->mti_fsname);
3049 /* end COMPAT_146 */
3051 int mgs_erase_log(struct obd_device *obd, char *name)
3053 struct lvfs_run_ctxt saved;
3054 struct llog_ctxt *ctxt;
3055 struct llog_handle *llh;
3058 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
3059 LASSERT(ctxt != NULL);
3061 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
3062 rc = llog_create(ctxt, &llh, NULL, name);
3064 llog_init_handle(llh, LLOG_F_IS_PLAIN, NULL);
3065 rc = llog_destroy(llh);
3066 llog_free_handle(llh);
3068 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
3069 llog_ctxt_put(ctxt);
3072 CERROR("failed to clear log %s: %d\n", name, rc);
3077 /* erase all logs for the given fs */
3078 int mgs_erase_logs(struct obd_device *obd, char *fsname)
3080 struct mgs_obd *mgs = &obd->u.mgs;
3081 static struct fs_db *fsdb;
3082 struct list_head dentry_list;
3083 struct l_linux_dirent *dirent, *n;
3084 int rc, len = strlen(fsname);
3087 /* Find all the logs in the CONFIGS directory */
3088 rc = class_dentry_readdir(obd, mgs->mgs_configs_dir,
3089 mgs->mgs_vfsmnt, &dentry_list);
3091 CERROR("Can't read %s dir\n", MOUNT_CONFIGS_DIR);
3095 down(&mgs->mgs_sem);
3097 /* Delete the fs db */
3098 fsdb = mgs_find_fsdb(obd, fsname);
3100 mgs_free_fsdb(obd, fsdb);
3102 list_for_each_entry_safe(dirent, n, &dentry_list, lld_list) {
3103 list_del(&dirent->lld_list);
3104 if (strncmp(fsname, dirent->lld_name, len) == 0) {
3105 CDEBUG(D_MGS, "Removing log %s\n", dirent->lld_name);
3106 mgs_erase_log(obd, dirent->lld_name);
3108 OBD_FREE(dirent, sizeof(*dirent));
3116 /* from llog_swab */
3117 static void print_lustre_cfg(struct lustre_cfg *lcfg)
3122 CDEBUG(D_MGS, "lustre_cfg: %p\n", lcfg);
3123 CDEBUG(D_MGS, "\tlcfg->lcfg_version: %#x\n", lcfg->lcfg_version);
3125 CDEBUG(D_MGS, "\tlcfg->lcfg_command: %#x\n", lcfg->lcfg_command);
3126 CDEBUG(D_MGS, "\tlcfg->lcfg_num: %#x\n", lcfg->lcfg_num);
3127 CDEBUG(D_MGS, "\tlcfg->lcfg_flags: %#x\n", lcfg->lcfg_flags);
3128 CDEBUG(D_MGS, "\tlcfg->lcfg_nid: %s\n", libcfs_nid2str(lcfg->lcfg_nid));
3130 CDEBUG(D_MGS, "\tlcfg->lcfg_bufcount: %d\n", lcfg->lcfg_bufcount);
3131 if (lcfg->lcfg_bufcount < LUSTRE_CFG_MAX_BUFCOUNT)
3132 for (i = 0; i < lcfg->lcfg_bufcount; i++) {
3133 CDEBUG(D_MGS, "\tlcfg->lcfg_buflens[%d]: %d %s\n",
3134 i, lcfg->lcfg_buflens[i],
3135 lustre_cfg_string(lcfg, i));
3140 /* Set a permanent (config log) param for a target or fs */
3141 int mgs_setparam(struct obd_device *obd, struct lustre_cfg *lcfg, char *fsname)
3144 struct mgs_target_info *mti;
3145 char *devname, *param;
3151 print_lustre_cfg(lcfg);
3153 /* lustre, lustre-mdtlov, lustre-client, lustre-MDT0000 */
3154 devname = lustre_cfg_string(lcfg, 0);
3155 param = lustre_cfg_string(lcfg, 1);
3157 /* Assume device name embedded in param:
3158 lustre-OST0000.osc.max_dirty_mb=32 */
3159 ptr = strchr(param, '.');
3167 LCONSOLE_ERROR_MSG(0x14d, "No target specified: %s\n", param);
3171 /* Extract fsname */
3172 ptr = strrchr(devname, '-');
3173 memset(fsname, 0, MTI_NAME_MAXLEN);
3174 if (ptr && (server_name2index(ptr, &index, NULL) >= 0)) {
3175 strncpy(fsname, devname, ptr - devname);
3177 /* assume devname is the fsname */
3178 strncpy(fsname, devname, MTI_NAME_MAXLEN);
3180 fsname[MTI_NAME_MAXLEN - 1] = 0;
3181 CDEBUG(D_MGS, "setparam on fs %s device %s\n", fsname, devname);
3183 rc = mgs_find_or_make_fsdb(obd, fsname, &fsdb);
3186 if (fsdb->fsdb_flags & FSDB_LOG_EMPTY) {
3187 CERROR("No filesystem targets for %s. cfg_device from lctl "
3188 "is '%s'\n", fsname, devname);
3189 mgs_free_fsdb(obd, fsdb);
3193 /* Create a fake mti to hold everything */
3196 GOTO(out, rc = -ENOMEM);
3197 strncpy(mti->mti_fsname, fsname, MTI_NAME_MAXLEN);
3198 strncpy(mti->mti_svname, devname, MTI_NAME_MAXLEN);
3199 strncpy(mti->mti_params, param, sizeof(mti->mti_params));
3200 rc = server_name2index(mti->mti_svname, &mti->mti_stripe_index, &tmp);
3202 /* Not a valid server; may be only fsname */
3205 /* Strip -osc or -mdc suffix from svname */
3206 if (server_make_name(rc, mti->mti_stripe_index, mti->mti_fsname,
3208 GOTO(out, rc = -EINVAL);
3210 mti->mti_flags = rc | LDD_F_PARAM;
3212 down(&fsdb->fsdb_sem);
3213 rc = mgs_write_log_params(obd, fsdb, mti);
3214 up(&fsdb->fsdb_sem);
3222 /******************** unused *********************/
3223 static int mgs_backup_llog(struct obd_device *obd, char* fsname)
3225 struct file *filp, *bak_filp;
3226 struct lvfs_run_ctxt saved;
3227 char *logname, *buf;
3228 loff_t soff = 0 , doff = 0;
3229 int count = 4096, len;
3232 OBD_ALLOC(logname, PATH_MAX);
3233 if (logname == NULL)
3236 OBD_ALLOC(buf, count);
3238 GOTO(out , rc = -ENOMEM);
3240 len = snprintf(logname, PATH_MAX, "%s/%s.bak",
3241 MOUNT_CONFIGS_DIR, fsname);
3243 if (len >= PATH_MAX - 1) {
3244 GOTO(out, -ENAMETOOLONG);
3247 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
3249 bak_filp = l_filp_open(logname, O_RDWR|O_CREAT|O_TRUNC, 0660);
3250 if (IS_ERR(bak_filp)) {
3251 rc = PTR_ERR(bak_filp);
3252 CERROR("backup logfile open %s: %d\n", logname, rc);
3255 sprintf(logname, "%s/%s", MOUNT_CONFIGS_DIR, fsname);
3256 filp = l_filp_open(logname, O_RDONLY, 0);
3259 CERROR("logfile open %s: %d\n", logname, rc);
3263 while ((rc = lustre_fread(filp, buf, count, &soff)) > 0) {
3264 rc = lustre_fwrite(bak_filp, buf, count, &doff);
3268 filp_close(filp, 0);
3270 filp_close(bak_filp, 0);
3272 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
3275 OBD_FREE(buf, count);
3276 OBD_FREE(logname, PATH_MAX);