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 LCONSOLE_ERROR_MSG(0x140, "Server %s requested index "
525 "%d, but that index is already in "
526 "use\n", mti->mti_svname,
527 mti->mti_stripe_index);
530 CDEBUG(D_MGS, "Server %s updating index %d\n",
531 mti->mti_svname, mti->mti_stripe_index);
536 set_bit(mti->mti_stripe_index, imap);
537 fsdb->fsdb_flags &= ~FSDB_LOG_EMPTY;
538 server_make_name(mti->mti_flags, mti->mti_stripe_index,
539 mti->mti_fsname, mti->mti_svname);
541 CDEBUG(D_MGS, "Set index for %s to %d\n", mti->mti_svname,
542 mti->mti_stripe_index);
547 struct mgs_modify_lookup {
548 struct cfg_marker mml_marker;
552 static int mgs_modify_handler(struct llog_handle *llh, struct llog_rec_hdr *rec,
555 struct mgs_modify_lookup *mml = (struct mgs_modify_lookup *)data;
556 struct cfg_marker *marker;
557 struct lustre_cfg *lcfg = (struct lustre_cfg *)(rec + 1);
558 int cfg_len = rec->lrh_len - sizeof(struct llog_rec_hdr) -
559 sizeof(struct llog_rec_tail);
563 if (rec->lrh_type != OBD_CFG_REC) {
564 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
568 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
570 CERROR("Insane cfg\n");
574 /* We only care about markers */
575 if (lcfg->lcfg_command != LCFG_MARKER)
578 marker = lustre_cfg_buf(lcfg, 1);
579 if ((strcmp(mml->mml_marker.cm_comment, marker->cm_comment) == 0) &&
580 (strcmp(mml->mml_marker.cm_tgtname, marker->cm_tgtname) == 0) &&
581 !(marker->cm_flags & CM_SKIP)) {
582 /* Found a non-skipped marker match */
583 CDEBUG(D_MGS, "Changing rec %u marker %d %x->%x: %s %s\n",
584 rec->lrh_index, marker->cm_step,
585 marker->cm_flags, mml->mml_marker.cm_flags,
586 marker->cm_tgtname, marker->cm_comment);
587 /* Overwrite the old marker llog entry */
588 marker->cm_flags &= ~CM_EXCLUDE; /* in case we're unexcluding */
589 marker->cm_flags |= mml->mml_marker.cm_flags;
590 marker->cm_canceltime = mml->mml_marker.cm_canceltime;
591 /* Header and tail are added back to lrh_len in
592 llog_lvfs_write_rec */
593 rec->lrh_len = cfg_len;
594 rc = llog_write_rec(llh, rec, NULL, 0, (void *)lcfg,
603 /* Modify an existing config log record (for CM_SKIP or CM_EXCLUDE) */
604 static int mgs_modify(struct obd_device *obd, struct fs_db *fsdb,
605 struct mgs_target_info *mti, char *logname,
606 char *devname, char *comment, int flags)
608 struct llog_handle *loghandle;
609 struct lvfs_run_ctxt saved;
610 struct llog_ctxt *ctxt;
611 struct mgs_modify_lookup *mml;
615 CDEBUG(D_MGS, "modify %s/%s/%s\n", logname, devname, comment);
617 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
619 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
620 LASSERT(ctxt != NULL);
621 rc = llog_create(ctxt, &loghandle, NULL, logname);
625 rc = llog_init_handle(loghandle, LLOG_F_IS_PLAIN, NULL);
629 if (llog_get_size(loghandle) <= 1)
630 GOTO(out_close, rc = 0);
634 GOTO(out_close, rc = -ENOMEM);
635 strcpy(mml->mml_marker.cm_comment, comment);
636 strcpy(mml->mml_marker.cm_tgtname, devname);
637 /* Modify mostly means cancel */
638 mml->mml_marker.cm_flags = flags;
639 mml->mml_marker.cm_canceltime = flags ? cfs_time_current_sec() : 0;
640 mml->mml_modified = 0;
641 rc = llog_process(loghandle, mgs_modify_handler, (void *)mml, NULL);
642 if (!rc && !mml->mml_modified)
647 rc2 = llog_close(loghandle);
651 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
652 if (rc && rc != -ENODEV)
653 CERROR("modify %s/%s failed %d\n",
654 mti->mti_svname, comment, rc);
659 /******************** config log recording functions *********************/
661 static int record_lcfg(struct obd_device *obd, struct llog_handle *llh,
662 struct lustre_cfg *lcfg)
664 struct lvfs_run_ctxt saved;
665 struct llog_rec_hdr rec;
671 LASSERT(llh->lgh_ctxt);
673 buflen = lustre_cfg_len(lcfg->lcfg_bufcount,
675 rec.lrh_len = llog_data_len(buflen);
676 rec.lrh_type = OBD_CFG_REC;
678 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
679 /* idx = -1 means append */
680 rc = llog_write_rec(llh, &rec, NULL, 0, (void *)lcfg, -1);
681 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
683 CERROR("failed %d\n", rc);
687 static int record_base(struct obd_device *obd, struct llog_handle *llh,
688 char *cfgname, lnet_nid_t nid, int cmd,
689 char *s1, char *s2, char *s3, char *s4)
691 struct lustre_cfg_bufs bufs;
692 struct lustre_cfg *lcfg;
695 CDEBUG(D_MGS, "lcfg %s %#x %s %s %s %s\n", cfgname,
696 cmd, s1, s2, s3, s4);
698 lustre_cfg_bufs_reset(&bufs, cfgname);
700 lustre_cfg_bufs_set_string(&bufs, 1, s1);
702 lustre_cfg_bufs_set_string(&bufs, 2, s2);
704 lustre_cfg_bufs_set_string(&bufs, 3, s3);
706 lustre_cfg_bufs_set_string(&bufs, 4, s4);
708 lcfg = lustre_cfg_new(cmd, &bufs);
711 lcfg->lcfg_nid = nid;
713 rc = record_lcfg(obd, llh, lcfg);
715 lustre_cfg_free(lcfg);
718 CERROR("error %d: lcfg %s %#x %s %s %s %s\n", rc, cfgname,
719 cmd, s1, s2, s3, s4);
725 static inline int record_add_uuid(struct obd_device *obd,
726 struct llog_handle *llh,
727 uint64_t nid, char *uuid)
729 return record_base(obd,llh,NULL,nid,LCFG_ADD_UUID,uuid,0,0,0);
733 static inline int record_add_conn(struct obd_device *obd,
734 struct llog_handle *llh,
738 return record_base(obd,llh,devname,0,LCFG_ADD_CONN,uuid,0,0,0);
741 static inline int record_attach(struct obd_device *obd, struct llog_handle *llh,
742 char *devname, char *type, char *uuid)
744 return record_base(obd,llh,devname,0,LCFG_ATTACH,type,uuid,0,0);
747 static inline int record_setup(struct obd_device *obd, struct llog_handle *llh,
749 char *s1, char *s2, char *s3, char *s4)
751 return record_base(obd,llh,devname,0,LCFG_SETUP,s1,s2,s3,s4);
754 static inline int record_sptlrpc_conf(struct obd_device *obd,
755 struct llog_handle *llh,
757 struct sptlrpc_conf_log *srpc_log)
759 struct lustre_cfg_bufs bufs;
760 struct lustre_cfg *lcfg;
763 lustre_cfg_bufs_reset(&bufs, devname);
764 lustre_cfg_bufs_set(&bufs, 1, srpc_log, sizeof(*srpc_log));
765 lcfg = lustre_cfg_new(LCFG_SPTLRPC_CONF, &bufs);
767 rc = record_lcfg(obd, llh, lcfg);
769 lustre_cfg_free(lcfg);
773 static int record_lov_setup(struct obd_device *obd, struct llog_handle *llh,
774 char *devname, struct lov_desc *desc)
776 struct lustre_cfg_bufs bufs;
777 struct lustre_cfg *lcfg;
780 lustre_cfg_bufs_reset(&bufs, devname);
781 lustre_cfg_bufs_set(&bufs, 1, desc, sizeof(*desc));
782 lcfg = lustre_cfg_new(LCFG_SETUP, &bufs);
785 rc = record_lcfg(obd, llh, lcfg);
787 lustre_cfg_free(lcfg);
791 static int record_lmv_setup(struct obd_device *obd, struct llog_handle *llh,
792 char *devname, struct lmv_desc *desc)
794 struct lustre_cfg_bufs bufs;
795 struct lustre_cfg *lcfg;
798 lustre_cfg_bufs_reset(&bufs, devname);
799 lustre_cfg_bufs_set(&bufs, 1, desc, sizeof(*desc));
800 lcfg = lustre_cfg_new(LCFG_SETUP, &bufs);
802 rc = record_lcfg(obd, llh, lcfg);
804 lustre_cfg_free(lcfg);
808 static inline int record_mdc_add(struct obd_device *obd,
809 struct llog_handle *llh,
810 char *logname, char *mdcuuid,
811 char *mdtuuid, char *index,
814 return record_base(obd,llh,logname,0,LCFG_ADD_MDC,
815 mdtuuid,index,gen,mdcuuid);
818 static inline int record_lov_add(struct obd_device *obd,
819 struct llog_handle *llh,
820 char *lov_name, char *ost_uuid,
821 char *index, char *gen)
823 return record_base(obd,llh,lov_name,0,LCFG_LOV_ADD_OBD,
824 ost_uuid,index,gen,0);
827 static inline int record_mount_opt(struct obd_device *obd,
828 struct llog_handle *llh,
829 char *profile, char *lov_name,
832 return record_base(obd,llh,NULL,0,LCFG_MOUNTOPT,
833 profile,lov_name,mdc_name,0);
836 static int record_marker(struct obd_device *obd, struct llog_handle *llh,
837 struct fs_db *fsdb, __u32 flags,
838 char *tgtname, char *comment)
840 struct cfg_marker marker;
841 struct lustre_cfg_bufs bufs;
842 struct lustre_cfg *lcfg;
845 if (flags & CM_START)
847 marker.cm_step = fsdb->fsdb_gen;
848 marker.cm_flags = flags;
849 marker.cm_vers = LUSTRE_VERSION_CODE;
850 strncpy(marker.cm_tgtname, tgtname, sizeof(marker.cm_tgtname));
851 strncpy(marker.cm_comment, comment, sizeof(marker.cm_comment));
852 marker.cm_createtime = cfs_time_current_sec();
853 marker.cm_canceltime = 0;
854 lustre_cfg_bufs_reset(&bufs, NULL);
855 lustre_cfg_bufs_set(&bufs, 1, &marker, sizeof(marker));
856 lcfg = lustre_cfg_new(LCFG_MARKER, &bufs);
859 rc = record_lcfg(obd, llh, lcfg);
861 lustre_cfg_free(lcfg);
865 static int record_start_log(struct obd_device *obd,
866 struct llog_handle **llh, char *name)
868 static struct obd_uuid cfg_uuid = { .uuid = "config_uuid" };
869 struct lvfs_run_ctxt saved;
870 struct llog_ctxt *ctxt;
874 GOTO(out, rc = -EBUSY);
876 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
878 GOTO(out, rc = -ENODEV);
880 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
881 rc = llog_create(ctxt, llh, NULL, name);
883 llog_init_handle(*llh, LLOG_F_IS_PLAIN, &cfg_uuid);
887 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
892 CERROR("Can't start log %s: %d\n", name, rc);
897 static int record_end_log(struct obd_device *obd, struct llog_handle **llh)
899 struct lvfs_run_ctxt saved;
902 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
904 rc = llog_close(*llh);
907 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
911 static int mgs_log_is_empty(struct obd_device *obd, char *name)
913 struct lvfs_run_ctxt saved;
914 struct llog_handle *llh;
915 struct llog_ctxt *ctxt;
918 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
919 LASSERT(ctxt != NULL);
920 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
921 rc = llog_create(ctxt, &llh, NULL, name);
923 llog_init_handle(llh, LLOG_F_IS_PLAIN, NULL);
924 rc = llog_get_size(llh);
927 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
929 /* header is record 1 */
933 /******************** config "macros" *********************/
935 /* write an lcfg directly into a log (with markers) */
936 static int mgs_write_log_direct(struct obd_device *obd, struct fs_db *fsdb,
937 char *logname, struct lustre_cfg *lcfg,
938 char *devname, char *comment)
940 struct llog_handle *llh = NULL;
947 rc = record_start_log(obd, &llh, logname);
951 /* FIXME These should be a single journal transaction */
952 rc = record_marker(obd, llh, fsdb, CM_START, devname, comment);
954 rc = record_lcfg(obd, llh, lcfg);
956 rc = record_marker(obd, llh, fsdb, CM_END, devname, comment);
957 rc = record_end_log(obd, &llh);
962 /* write the lcfg in all logs for the given fs */
963 int mgs_write_log_direct_all(struct obd_device *obd, struct fs_db *fsdb,
964 struct mgs_target_info *mti,
965 struct lustre_cfg *lcfg,
966 char *devname, char *comment)
968 struct mgs_obd *mgs = &obd->u.mgs;
969 struct list_head dentry_list;
970 struct l_linux_dirent *dirent, *n;
971 char *fsname = mti->mti_fsname;
973 int rc = 0, len = strlen(fsname);
976 /* We need to set params for any future logs
977 as well. FIXME Append this file to every new log.
978 Actually, we should store as params (text), not llogs. Or
980 name_create(&logname, fsname, "-params");
981 if (mgs_log_is_empty(obd, logname)) {
982 struct llog_handle *llh = NULL;
983 rc = record_start_log(obd, &llh, logname);
984 record_end_log(obd, &llh);
986 name_destroy(&logname);
990 /* Find all the logs in the CONFIGS directory */
991 rc = class_dentry_readdir(obd, mgs->mgs_configs_dir,
992 mgs->mgs_vfsmnt, &dentry_list);
994 CERROR("Can't read %s dir\n", MOUNT_CONFIGS_DIR);
998 /* Could use fsdb index maps instead of directory listing */
999 list_for_each_entry_safe(dirent, n, &dentry_list, lld_list) {
1000 list_del(&dirent->lld_list);
1001 /* don't write to sptlrpc rule log */
1002 if (strncmp(fsname, dirent->lld_name, len) == 0 &&
1003 strstr(dirent->lld_name, "-sptlrpc") == NULL) {
1004 CDEBUG(D_MGS, "Changing log %s\n", dirent->lld_name);
1005 /* Erase any old settings of this same parameter */
1006 mgs_modify(obd, fsdb, mti, dirent->lld_name, devname,
1008 /* Write the new one */
1009 rc = mgs_write_log_direct(obd, fsdb, dirent->lld_name,
1010 lcfg, devname, comment);
1012 CERROR("err %d writing log %s\n", rc,
1015 OBD_FREE(dirent, sizeof(*dirent));
1023 struct mgs_target_info *comp_tmti;
1024 struct mgs_target_info *comp_mti;
1025 struct fs_db *comp_fsdb;
1026 struct obd_device *comp_obd;
1029 static int mgs_write_log_mdc_to_mdt(struct obd_device *, struct fs_db *,
1030 struct mgs_target_info *, char *);
1032 static int mgs_steal_llog_handler(struct llog_handle *llh,
1033 struct llog_rec_hdr *rec,
1036 struct obd_device * obd;
1037 struct mgs_target_info *mti, *tmti;
1039 int cfg_len = rec->lrh_len;
1040 char *cfg_buf = (char*) (rec + 1);
1041 struct lustre_cfg *lcfg;
1043 struct llog_handle *mdt_llh = NULL;
1044 static int got_an_osc_or_mdc = 0;
1045 /* 0: not found any osc/mdc;
1049 static int last_step = -1;
1053 mti = ((struct temp_comp*)data)->comp_mti;
1054 tmti = ((struct temp_comp*)data)->comp_tmti;
1055 fsdb = ((struct temp_comp*)data)->comp_fsdb;
1056 obd = ((struct temp_comp*)data)->comp_obd;
1058 if (rec->lrh_type != OBD_CFG_REC) {
1059 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
1063 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
1065 CERROR("Insane cfg\n");
1069 lcfg = (struct lustre_cfg *)cfg_buf;
1071 if (lcfg->lcfg_command == LCFG_MARKER) {
1072 struct cfg_marker *marker;
1073 marker = lustre_cfg_buf(lcfg, 1);
1074 if (!strncmp(marker->cm_comment,"add osc",7) &&
1075 (marker->cm_flags & CM_START)){
1076 got_an_osc_or_mdc = 1;
1077 rc = record_start_log(obd, &mdt_llh, mti->mti_svname);
1078 rc = record_marker(obd, mdt_llh, fsdb, CM_START,
1079 mti->mti_svname,"add osc(copied)");
1080 rc = record_end_log(obd, &mdt_llh);
1081 last_step = marker->cm_step;
1084 if (!strncmp(marker->cm_comment,"add osc",7) &&
1085 (marker->cm_flags & CM_END)){
1086 LASSERT(last_step == marker->cm_step);
1088 got_an_osc_or_mdc = 0;
1089 rc = record_start_log(obd, &mdt_llh, mti->mti_svname);
1090 rc = record_marker(obd, mdt_llh, fsdb, CM_END,
1091 mti->mti_svname,"add osc(copied)");
1092 rc = record_end_log(obd, &mdt_llh);
1095 if (!strncmp(marker->cm_comment,"add mdc",7) &&
1096 (marker->cm_flags & CM_START)){
1097 got_an_osc_or_mdc = 2;
1098 last_step = marker->cm_step;
1099 memcpy(tmti->mti_svname, marker->cm_tgtname,
1100 strlen(marker->cm_tgtname));
1104 if (!strncmp(marker->cm_comment,"add mdc",7) &&
1105 (marker->cm_flags & CM_END)){
1106 LASSERT(last_step == marker->cm_step);
1108 got_an_osc_or_mdc = 0;
1113 if (got_an_osc_or_mdc == 0 || last_step < 0)
1116 if (lcfg->lcfg_command == LCFG_ADD_UUID) {
1118 nodenid = lcfg->lcfg_nid;
1120 tmti->mti_nids[tmti->mti_nid_count] = nodenid;
1121 tmti->mti_nid_count++;
1126 if (lcfg->lcfg_command == LCFG_SETUP) {
1129 target = lustre_cfg_string(lcfg, 1);
1130 memcpy(tmti->mti_uuid, target, strlen(target));
1134 /* ignore client side sptlrpc_conf_log */
1135 if (lcfg->lcfg_command == LCFG_SPTLRPC_CONF)
1138 if (lcfg->lcfg_command == LCFG_ADD_MDC) {
1141 if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1)
1144 memcpy(tmti->mti_fsname, mti->mti_fsname,
1145 strlen(mti->mti_fsname));
1146 tmti->mti_stripe_index = index;
1148 mgs_write_log_mdc_to_mdt(obd, fsdb, tmti, mti->mti_svname);
1149 memset(tmti, 0, sizeof(*tmti));
1155 /* fsdb->fsdb_sem is already held in mgs_write_log_target*/
1156 /* stealed from mgs_get_fsdb_from_llog*/
1157 static int mgs_steal_llog_for_mdt_from_client(struct obd_device *obd,
1159 struct temp_comp* comp)
1161 struct llog_handle *loghandle;
1162 struct lvfs_run_ctxt saved;
1163 struct mgs_target_info *tmti;
1164 struct llog_ctxt *ctxt;
1168 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
1169 LASSERT(ctxt != NULL);
1171 OBD_ALLOC_PTR(tmti);
1175 comp->comp_tmti = tmti;
1176 comp->comp_obd = obd;
1178 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
1180 rc = llog_create(ctxt, &loghandle, NULL, client_name);
1184 rc = llog_init_handle(loghandle, LLOG_F_IS_PLAIN, NULL);
1186 GOTO(out_close, rc);
1188 rc = llog_process(loghandle, mgs_steal_llog_handler, (void *)comp, NULL);
1189 CDEBUG(D_MGS, "steal llog re = %d\n", rc);
1191 rc2 = llog_close(loghandle);
1195 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
1197 llog_ctxt_put(ctxt);
1201 /* lmv is the second thing for client logs */
1202 /* copied from mgs_write_log_lov. Please refer to that. */
1203 static int mgs_write_log_lmv(struct obd_device *obd, struct fs_db *fsdb,
1204 struct mgs_target_info *mti,
1205 char *logname, char *lmvname)
1207 struct llog_handle *llh = NULL;
1208 struct lmv_desc *lmvdesc;
1213 CDEBUG(D_MGS, "Writing lmv(%s) log for %s\n", lmvname,logname);
1215 OBD_ALLOC(lmvdesc, sizeof(*lmvdesc));
1216 if (lmvdesc == NULL)
1218 lmvdesc->ld_active_tgt_count = 0;
1219 lmvdesc->ld_tgt_count = 0;
1220 sprintf((char*)lmvdesc->ld_uuid.uuid, "%s_UUID", lmvname);
1221 uuid = (char *)lmvdesc->ld_uuid.uuid;
1223 rc = record_start_log(obd, &llh, logname);
1224 rc = record_marker(obd, llh, fsdb, CM_START, lmvname, "lmv setup");
1225 rc = record_attach(obd, llh, lmvname, "lmv", uuid);
1226 rc = record_lmv_setup(obd, llh, lmvname, lmvdesc);
1227 rc = record_marker(obd, llh, fsdb, CM_END, lmvname, "lmv setup");
1228 rc = record_end_log(obd, &llh);
1230 OBD_FREE(lmvdesc, sizeof(*lmvdesc));
1233 /***************************************END PROTO**********************/
1235 /* lov is the first thing in the mdt and client logs */
1236 static int mgs_write_log_lov(struct obd_device *obd, struct fs_db *fsdb,
1237 struct mgs_target_info *mti,
1238 char *logname, char *lovname)
1240 struct llog_handle *llh = NULL;
1241 struct lov_desc *lovdesc;
1246 CDEBUG(D_MGS, "Writing lov(%s) log for %s\n", lovname, logname);
1249 #01 L attach 0:lov_mdsA 1:lov 2:71ccb_lov_mdsA_19f961a9e1
1250 #02 L lov_setup 0:lov_mdsA 1:(struct lov_desc)
1251 uuid=lov1_UUID, stripe count=1, size=1048576, offset=0, pattern=0
1254 /* FIXME just make lov_setup accept empty desc (put uuid in buf 2) */
1255 OBD_ALLOC(lovdesc, sizeof(*lovdesc));
1256 if (lovdesc == NULL)
1258 lovdesc->ld_magic = LOV_DESC_MAGIC;
1259 lovdesc->ld_tgt_count = 0;
1260 /* Defaults. Can be changed later by lcfg config_param */
1261 lovdesc->ld_default_stripe_count = 1;
1262 lovdesc->ld_pattern = LOV_PATTERN_RAID0;
1263 lovdesc->ld_default_stripe_size = 1024 * 1024;
1264 lovdesc->ld_default_stripe_offset = 0;
1265 lovdesc->ld_qos_maxage = QOS_DEFAULT_MAXAGE;
1266 sprintf((char*)lovdesc->ld_uuid.uuid, "%s_UUID", lovname);
1267 /* can these be the same? */
1268 uuid = (char *)lovdesc->ld_uuid.uuid;
1270 /* This should always be the first entry in a log.
1271 rc = mgs_clear_log(obd, logname); */
1272 rc = record_start_log(obd, &llh, logname);
1275 /* FIXME these should be a single journal transaction */
1276 rc = record_marker(obd, llh, fsdb, CM_START, lovname, "lov setup");
1277 rc = record_attach(obd, llh, lovname, "lov", uuid);
1278 rc = record_lov_setup(obd, llh, lovname, lovdesc);
1279 rc = record_marker(obd, llh, fsdb, CM_END, lovname, "lov setup");
1280 rc = record_end_log(obd, &llh);
1282 OBD_FREE(lovdesc, sizeof(*lovdesc));
1286 /* add failnids to open log */
1287 static int mgs_write_log_failnids(struct obd_device *obd,
1288 struct mgs_target_info *mti,
1289 struct llog_handle *llh,
1292 char *failnodeuuid = NULL;
1293 char *ptr = mti->mti_params;
1298 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) nal=90 0: 1:uml1_UUID
1299 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
1300 #05 L setup 0:OSC_uml1_ost1_mdsA 1:ost1_UUID 2:uml1_UUID
1301 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) nal=90 0: 1:uml2_UUID
1302 #0x L add_uuid nid=2@elan(0x1000000000002) nal=90 0: 1:uml2_UUID
1303 #07 L add_conn 0:OSC_uml1_ost1_mdsA 1:uml2_UUID
1306 /* Pull failnid info out of params string */
1307 while (class_find_param(ptr, PARAM_FAILNODE, &ptr) == 0) {
1308 while (class_parse_nid(ptr, &nid, &ptr) == 0) {
1309 if (failnodeuuid == NULL) {
1310 /* We don't know the failover node name,
1311 so just use the first nid as the uuid */
1312 rc = name_create(&failnodeuuid,
1313 libcfs_nid2str(nid), "");
1317 CDEBUG(D_MGS, "add nid %s for failover uuid %s, "
1318 "client %s\n", libcfs_nid2str(nid),
1319 failnodeuuid, cliname);
1320 rc = record_add_uuid(obd, llh, nid, failnodeuuid);
1323 rc = record_add_conn(obd, llh, cliname, failnodeuuid);
1324 name_destroy(&failnodeuuid);
1325 failnodeuuid = NULL;
1332 static int mgs_write_log_mdc_to_lmv(struct obd_device *obd, struct fs_db *fsdb,
1333 struct mgs_target_info *mti,
1334 char *logname, char *lmvname)
1336 struct llog_handle *llh = NULL;
1337 struct sptlrpc_conf_log *srpc_log;
1338 char *mdcname, *nodeuuid, *mdcuuid, *lmvuuid;
1343 if (mgs_log_is_empty(obd, logname)) {
1344 CERROR("log is empty! Logical error\n");
1348 CDEBUG(D_MGS, "adding mdc for %s to log %s:lmv(%s)\n",
1349 mti->mti_svname, logname, lmvname);
1351 srpc_log = sptlrpc_conf_log_alloc();
1352 if (IS_ERR(srpc_log))
1353 RETURN(PTR_ERR(srpc_log));
1354 srpc_log->scl_part = LUSTRE_SP_CLI;
1356 rc = mgs_get_srpc_conf_log(fsdb, mti->mti_svname,
1357 LUSTRE_SP_CLI, LUSTRE_SP_MDT, srpc_log);
1361 name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
1362 name_create(&mdcname, mti->mti_svname, "-mdc");
1363 name_create(&mdcuuid, mdcname, "_UUID");
1364 name_create(&lmvuuid, lmvname, "_UUID");
1366 rc = record_start_log(obd, &llh, logname);
1367 rc = record_marker(obd, llh, fsdb, CM_START, mti->mti_svname,
1370 for (i = 0; i < mti->mti_nid_count; i++) {
1371 CDEBUG(D_MGS, "add nid %s for mdt\n",
1372 libcfs_nid2str(mti->mti_nids[i]));
1374 rc = record_add_uuid(obd, llh, mti->mti_nids[i], nodeuuid);
1377 rc = record_attach(obd, llh, mdcname, LUSTRE_MDC_NAME, lmvuuid);
1378 rc = record_setup(obd, llh, mdcname, mti->mti_uuid, nodeuuid, 0, 0);
1379 rc = record_sptlrpc_conf(obd, llh, mdcname, srpc_log);
1380 rc = mgs_write_log_failnids(obd, mti, llh, mdcname);
1381 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
1382 rc = record_mdc_add(obd, llh, lmvname, mdcuuid, mti->mti_uuid,
1384 rc = record_marker(obd, llh, fsdb, CM_END, mti->mti_svname,
1386 rc = record_end_log(obd, &llh);
1388 name_destroy(&lmvuuid);
1389 name_destroy(&mdcuuid);
1390 name_destroy(&mdcname);
1391 name_destroy(&nodeuuid);
1393 sptlrpc_conf_log_free(srpc_log);
1397 /* add new mdc to already existent MDS */
1398 static int mgs_write_log_mdc_to_mdt(struct obd_device *obd, struct fs_db *fsdb,
1399 struct mgs_target_info *mti, char *logname)
1401 struct llog_handle *llh = NULL;
1402 struct sptlrpc_conf_log *srpc_log;
1403 char *nodeuuid, *mdcname, *mdcuuid, *mdtuuid;
1404 int idx = mti->mti_stripe_index;
1409 if (mgs_log_is_empty(obd, mti->mti_svname)) {
1410 CERROR("log is empty! Logical error\n");
1414 CDEBUG(D_MGS, "adding mdc index %d to %s\n", idx, logname);
1416 srpc_log = sptlrpc_conf_log_alloc();
1417 if (IS_ERR(srpc_log))
1418 RETURN(PTR_ERR(srpc_log));
1419 srpc_log->scl_part = LUSTRE_SP_MDT;
1421 rc = mgs_get_srpc_conf_log(fsdb, mti->mti_svname,
1422 LUSTRE_SP_MDT, LUSTRE_SP_MDT, srpc_log);
1426 name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
1427 snprintf(index, sizeof(index), "-mdc%04x", idx);
1428 name_create(&mdcname, logname, index);
1429 name_create(&mdcuuid, mdcname, "_UUID");
1430 name_create(&mdtuuid, logname, "_UUID");
1432 rc = record_start_log(obd, &llh, logname);
1433 rc = record_marker(obd, llh, fsdb, CM_START, mti->mti_svname, "add mdc");
1434 for (i = 0; i < mti->mti_nid_count; i++) {
1435 CDEBUG(D_MGS, "add nid %s for mdt\n",
1436 libcfs_nid2str(mti->mti_nids[i]));
1437 rc = record_add_uuid(obd, llh, mti->mti_nids[i], nodeuuid);
1439 rc = record_attach(obd, llh, mdcname, LUSTRE_MDC_NAME, mdcuuid);
1440 rc = record_setup(obd, llh, mdcname, mti->mti_uuid, nodeuuid, 0, 0);
1441 rc = record_sptlrpc_conf(obd, llh, mdcname, srpc_log);
1442 rc = mgs_write_log_failnids(obd, mti, llh, mdcname);
1443 snprintf(index, sizeof(index), "%d", idx);
1445 rc = record_mdc_add(obd, llh, logname, mdcuuid, mti->mti_uuid,
1447 rc = record_marker(obd, llh, fsdb, CM_END, mti->mti_svname, "add mdc");
1448 rc = record_end_log(obd, &llh);
1450 name_destroy(&mdcuuid);
1451 name_destroy(&mdcname);
1452 name_destroy(&nodeuuid);
1453 name_destroy(&mdtuuid);
1455 sptlrpc_conf_log_free(srpc_log);
1459 static int mgs_write_log_mdt0(struct obd_device *obd, struct fs_db *fsdb,
1460 struct mgs_target_info *mti)
1462 char *log = mti->mti_svname;
1463 struct llog_handle *llh = NULL;
1464 char *uuid, *lovname;
1466 struct sptlrpc_conf_log *srpc_log;
1467 char *ptr = mti->mti_params;
1468 int rc = 0, failout = 0;
1471 srpc_log = sptlrpc_conf_log_alloc();
1472 if (IS_ERR(srpc_log))
1473 RETURN(PTR_ERR(srpc_log));
1474 srpc_log->scl_part = LUSTRE_SP_MDT;
1476 rc = mgs_get_srpc_conf_log(fsdb, mti->mti_svname,
1477 LUSTRE_SP_ANY, LUSTRE_SP_MDT, srpc_log);
1481 OBD_ALLOC(uuid, sizeof(struct obd_uuid));
1483 GOTO(out_srpc, rc = -ENOMEM);
1485 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
1486 failout = (strncmp(ptr, "failout", 7) == 0);
1488 name_create(&lovname, log, "-mdtlov");
1489 if (mgs_log_is_empty(obd, log))
1490 rc = mgs_write_log_lov(obd, fsdb, mti, log, lovname);
1492 sprintf(uuid, "%s_UUID", log);
1493 sprintf(mdt_index,"%d",mti->mti_stripe_index);
1495 /* add MDT itself */
1496 rc = record_start_log(obd, &llh, log);
1500 /* FIXME this whole fn should be a single journal transaction */
1501 rc = record_marker(obd, llh, fsdb, CM_START, log, "add mdt");
1502 rc = record_attach(obd, llh, log, LUSTRE_MDT_NAME, uuid);
1503 rc = record_mount_opt(obd, llh, log, lovname, NULL);
1504 rc = record_setup(obd, llh, log, uuid, mdt_index, lovname,
1505 failout ? "n" : "f");
1506 rc = record_sptlrpc_conf(obd, llh, log, srpc_log);
1507 rc = record_marker(obd, llh, fsdb, CM_END, log, "add mdt");
1508 rc = record_end_log(obd, &llh);
1510 name_destroy(&lovname);
1511 OBD_FREE(uuid, sizeof(struct obd_uuid));
1513 sptlrpc_conf_log_free(srpc_log);
1517 /* envelope method for all layers log */
1518 static int mgs_write_log_mdt(struct obd_device *obd, struct fs_db *fsdb,
1519 struct mgs_target_info *mti)
1521 struct llog_handle *llh = NULL;
1523 struct temp_comp comp = { 0 };
1528 CDEBUG(D_MGS, "writing new mdt %s\n", mti->mti_svname);
1532 if (mti->mti_flags & LDD_F_UPGRADE14) {
1533 /* We're starting with an old uuid. Assume old name for lov
1534 as well since the lov entry already exists in the log. */
1535 CDEBUG(D_MGS, "old mds uuid %s\n", mti->mti_uuid);
1536 if (strncmp(mti->mti_uuid, fsdb->fsdb_mdtlov + 4,
1537 strlen(fsdb->fsdb_mdtlov) - 4) != 0) {
1538 CERROR("old mds uuid %s doesn't match log %s (%s)\n",
1539 mti->mti_uuid, fsdb->fsdb_mdtlov,
1540 fsdb->fsdb_mdtlov + 4);
1544 /* end COMPAT_146 */
1546 if (mti->mti_uuid[0] == '\0') {
1547 /* Make up our own uuid */
1548 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
1549 "%s_UUID", mti->mti_svname);
1553 rc = mgs_write_log_mdt0(obd, fsdb, mti);
1555 /* Append the mdt info to the client log */
1556 name_create(&cliname, mti->mti_fsname, "-client");
1558 if (mgs_log_is_empty(obd, cliname)) {
1559 /* Start client log */
1560 rc = mgs_write_log_lov(obd, fsdb, mti, cliname,
1562 rc = mgs_write_log_lmv(obd, fsdb, mti, cliname,
1567 #09 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
1568 #10 L attach 0:MDC_uml1_mdsA_MNT_client 1:mdc 2:1d834_MNT_client_03f
1569 #11 L setup 0:MDC_uml1_mdsA_MNT_client 1:mdsA_UUID 2:uml1_UUID
1570 #12 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
1571 #13 L add_conn 0:MDC_uml1_mdsA_MNT_client 1:uml2_UUID
1572 #14 L mount_option 0: 1:client 2:lov1 3:MDC_uml1_mdsA_MNT_client
1577 if (mti->mti_flags & LDD_F_UPGRADE14) {
1578 rc = record_start_log(obd, &llh, cliname);
1582 rc = record_marker(obd, llh, fsdb, CM_START,
1583 mti->mti_svname,"add mdc");
1585 /* Old client log already has MDC entry, but needs mount opt
1586 for new client name (lustre-client) */
1587 /* FIXME Old MDT log already has an old mount opt
1588 which we should remove (currently handled by
1589 class_del_profiles()) */
1590 rc = record_mount_opt(obd, llh, cliname, fsdb->fsdb_clilov,
1592 /* end COMPAT_146 */
1594 rc = record_marker(obd, llh, fsdb, CM_END,
1595 mti->mti_svname, "add mdc");
1599 /* copy client info about lov/lmv */
1600 comp.comp_mti = mti;
1601 comp.comp_fsdb = fsdb;
1603 rc = mgs_steal_llog_for_mdt_from_client(obd, cliname,
1606 rc = mgs_write_log_mdc_to_lmv(obd, fsdb, mti, cliname,
1609 rc = record_start_log(obd, &llh, cliname);
1613 rc = record_marker(obd, llh, fsdb, CM_START, cliname,
1615 rc = record_mount_opt(obd, llh, cliname, fsdb->fsdb_clilov,
1617 rc = record_marker(obd, llh, fsdb, CM_END, cliname,
1621 rc = record_end_log(obd, &llh);
1623 name_destroy(&cliname);
1625 // for_all_existing_mdt except current one
1626 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
1628 if (i != mti->mti_stripe_index &&
1629 test_bit(i, fsdb->fsdb_mdt_index_map)) {
1630 sprintf(mdt_index,"-MDT%04x",i);
1632 name_create(&mdtname, mti->mti_fsname, mdt_index);
1633 rc = mgs_write_log_mdc_to_mdt(obd, fsdb, mti, mdtname);
1634 name_destroy(&mdtname);
1641 /* Add the ost info to the client/mdt lov */
1642 static int mgs_write_log_osc_to_lov(struct obd_device *obd, struct fs_db *fsdb,
1643 struct mgs_target_info *mti,
1644 char *logname, char *suffix, char *lovname,
1645 enum lustre_sec_part sec_part, int flags)
1647 struct llog_handle *llh = NULL;
1648 struct sptlrpc_conf_log *srpc_log;
1649 char *nodeuuid, *oscname, *oscuuid, *lovuuid, *svname;
1654 CDEBUG(D_INFO, "adding osc for %s to log %s\n",
1655 mti->mti_svname, logname);
1657 srpc_log = sptlrpc_conf_log_alloc();
1658 if (IS_ERR(srpc_log))
1659 RETURN(PTR_ERR(srpc_log));
1660 srpc_log->scl_part = sec_part;
1662 rc = mgs_get_srpc_conf_log(fsdb, mti->mti_svname,
1663 sec_part, LUSTRE_SP_OST, srpc_log);
1667 if (mgs_log_is_empty(obd, logname)) {
1668 /* The first item in the log must be the lov, so we have
1669 somewhere to add our osc. */
1670 rc = mgs_write_log_lov(obd, fsdb, mti, logname, lovname);
1673 name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
1674 name_create(&svname, mti->mti_svname, "-osc");
1675 name_create(&oscname, svname, suffix);
1676 name_create(&oscuuid, oscname, "_UUID");
1677 name_create(&lovuuid, lovname, "_UUID");
1680 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
1682 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
1683 #04 L attach 0:OSC_uml1_ost1_MNT_client 1:osc 2:89070_lov1_a41dff51a
1684 #05 L setup 0:OSC_uml1_ost1_MNT_client 1:ost1_UUID 2:uml1_UUID
1686 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
1687 #07 L add_conn 0:OSC_uml1_ost1_MNT_client 1:uml2_UUID
1688 #08 L lov_modify_tgts add 0:lov1 1:ost1_UUID 2(index):0 3(gen):1
1691 rc = record_start_log(obd, &llh, logname);
1694 /* FIXME these should be a single journal transaction */
1695 rc = record_marker(obd, llh, fsdb, CM_START | flags, mti->mti_svname,
1697 for (i = 0; i < mti->mti_nid_count; i++) {
1698 CDEBUG(D_MGS, "add nid %s\n", libcfs_nid2str(mti->mti_nids[i]));
1699 rc = record_add_uuid(obd, llh, mti->mti_nids[i], nodeuuid);
1701 rc = record_attach(obd, llh, oscname, LUSTRE_OSC_NAME, lovuuid);
1702 rc = record_setup(obd, llh, oscname, mti->mti_uuid, nodeuuid, 0, 0);
1703 rc = record_sptlrpc_conf(obd, llh, oscname, srpc_log);
1704 rc = mgs_write_log_failnids(obd, mti, llh, oscname);
1705 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
1706 rc = record_lov_add(obd, llh, lovname, mti->mti_uuid, index, "1");
1707 rc = record_marker(obd, llh, fsdb, CM_END | flags, mti->mti_svname,
1709 rc = record_end_log(obd, &llh);
1711 name_destroy(&lovuuid);
1712 name_destroy(&oscuuid);
1713 name_destroy(&oscname);
1714 name_destroy(&svname);
1715 name_destroy(&nodeuuid);
1717 sptlrpc_conf_log_free(srpc_log);
1721 static int mgs_write_log_ost(struct obd_device *obd, struct fs_db *fsdb,
1722 struct mgs_target_info *mti)
1724 struct llog_handle *llh = NULL;
1725 struct sptlrpc_conf_log *srpc_log;
1726 char *logname, *lovname;
1728 char *ptr = mti->mti_params;
1729 int rc, flags = 0, failout = 0, i;
1732 CDEBUG(D_MGS, "writing new ost %s\n", mti->mti_svname);
1734 /* The ost startup log */
1736 /* If the ost log already exists, that means that someone reformatted
1737 the ost and it called target_add again. */
1738 if (!mgs_log_is_empty(obd, mti->mti_svname)) {
1739 LCONSOLE_ERROR_MSG(0x141, "The config log for %s already "
1740 "exists, yet the server claims it never "
1741 "registered. It may have been reformatted, "
1742 "or the index changed. writeconf the MDT to "
1743 "regenerate all logs.\n", mti->mti_svname);
1747 srpc_log = sptlrpc_conf_log_alloc();
1748 if (IS_ERR(srpc_log))
1749 RETURN(PTR_ERR(srpc_log));
1750 srpc_log->scl_part = LUSTRE_SP_OST;
1752 rc = mgs_get_srpc_conf_log(fsdb, mti->mti_svname,
1753 LUSTRE_SP_ANY, LUSTRE_SP_OST, srpc_log);
1758 attach obdfilter ost1 ost1_UUID
1759 setup /dev/loop2 ldiskfs f|n errors=remount-ro,user_xattr
1761 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
1762 failout = (strncmp(ptr, "failout", 7) == 0);
1763 rc = record_start_log(obd, &llh, mti->mti_svname);
1766 /* FIXME these should be a single journal transaction */
1767 rc = record_marker(obd, llh, fsdb, CM_START, mti->mti_svname,"add ost");
1768 if (*mti->mti_uuid == '\0')
1769 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
1770 "%s_UUID", mti->mti_svname);
1771 rc = record_attach(obd, llh, mti->mti_svname,
1772 "obdfilter"/*LUSTRE_OST_NAME*/, mti->mti_uuid);
1773 rc = record_setup(obd, llh, mti->mti_svname,
1774 "dev"/*ignored*/, "type"/*ignored*/,
1775 failout ? "n" : "f", 0/*options*/);
1776 rc = record_sptlrpc_conf(obd, llh, mti->mti_svname, srpc_log);
1777 rc = record_marker(obd, llh, fsdb, CM_END, mti->mti_svname, "add ost");
1778 rc = record_end_log(obd, &llh);
1780 /* We also have to update the other logs where this osc is part of
1783 if (fsdb->fsdb_flags & FSDB_OLDLOG14) {
1784 /* If we're upgrading, the old mdt log already has our
1785 entry. Let's do a fake one for fun. */
1786 /* Note that we can't add any new failnids, since we don't
1787 know the old osc names. */
1788 flags = CM_SKIP | CM_UPGRADE146;
1790 } else if ((mti->mti_flags & LDD_F_UPDATE) != LDD_F_UPDATE) {
1791 /* If the update flag isn't set, don't update client/mdt
1794 LCONSOLE_WARN("Client log for %s was not updated; writeconf "
1795 "the MDT first to regenerate it.\n",
1799 // for_all_existing_mdt
1800 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
1801 if (test_bit(i, fsdb->fsdb_mdt_index_map)) {
1802 sprintf(mdt_index,"-MDT%04x",i);
1803 name_create(&logname, mti->mti_fsname, mdt_index);
1804 name_create(&lovname, logname, "-mdtlov");
1805 mgs_write_log_osc_to_lov(obd, fsdb, mti, logname,
1807 LUSTRE_SP_MDT, flags);
1808 name_destroy(&logname);
1809 name_destroy(&lovname);
1813 /* Append ost info to the client log */
1814 name_create(&logname, mti->mti_fsname, "-client");
1815 mgs_write_log_osc_to_lov(obd, fsdb, mti, logname, "",
1816 fsdb->fsdb_clilov, LUSTRE_SP_CLI, 0);
1817 name_destroy(&logname);
1819 sptlrpc_conf_log_free(srpc_log);
1823 /* Add additional failnids to an existing log.
1824 The mdc/osc must have been added to logs first */
1825 /* tcp nids must be in dotted-quad ascii -
1826 we can't resolve hostnames from the kernel. */
1827 static int mgs_write_log_add_failnid(struct obd_device *obd, struct fs_db *fsdb,
1828 struct mgs_target_info *mti)
1830 char *logname, *cliname;
1831 struct llog_handle *llh = NULL;
1835 /* FIXME how do we delete a failnid? Currently --writeconf is the
1836 only way. Maybe make --erase-params pass a flag to really
1837 erase all params from logs - except it can't erase the failnids
1838 given when a target first registers, since they aren't processed
1841 /* Verify that we know about this target */
1842 if (mgs_log_is_empty(obd, mti->mti_svname)) {
1843 LCONSOLE_ERROR_MSG(0x142, "The target %s has not registered "
1844 "yet. It must be started before failnids "
1845 "can be added.\n", mti->mti_svname);
1849 /* Create mdc/osc client name (e.g. lustre-OST0001-osc) */
1850 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
1851 name_create(&cliname, mti->mti_svname, "-mdc");
1852 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
1853 name_create(&cliname, mti->mti_svname, "-osc");
1858 /* Add failover nids to client log */
1859 name_create(&logname, mti->mti_fsname, "-client");
1860 rc = record_start_log(obd, &llh, logname);
1862 /* FIXME this fn should be a single journal transaction */
1863 rc = record_marker(obd, llh, fsdb, CM_START, mti->mti_svname,
1865 rc = mgs_write_log_failnids(obd, mti, llh, cliname);
1866 rc = record_marker(obd, llh, fsdb, CM_END, mti->mti_svname,
1868 rc = record_end_log(obd, &llh);
1870 name_destroy(&logname);
1872 if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
1873 /* Add OST failover nids to the MDT log as well */
1874 name_create(&logname, mti->mti_fsname, "-MDT0000");
1875 rc = record_start_log(obd, &llh, logname);
1877 rc = record_marker(obd, llh, fsdb, CM_START,
1878 mti->mti_svname, "add failnid");
1879 rc = mgs_write_log_failnids(obd, mti, llh, cliname);
1880 rc = record_marker(obd, llh, fsdb, CM_END,
1881 mti->mti_svname, "add failnid");
1882 rc = record_end_log(obd, &llh);
1884 name_destroy(&logname);
1887 name_destroy(&cliname);
1891 static int mgs_wlp_lcfg(struct obd_device *obd, struct fs_db *fsdb,
1892 struct mgs_target_info *mti,
1893 char *logname, struct lustre_cfg_bufs *bufs,
1894 char *tgtname, char *ptr)
1896 char comment[MTI_NAME_MAXLEN];
1898 struct lustre_cfg *lcfg;
1901 /* Erase any old settings of this same parameter */
1902 memcpy(comment, ptr, MTI_NAME_MAXLEN);
1903 comment[MTI_NAME_MAXLEN - 1] = 0;
1904 /* But don't try to match the value. */
1905 if ((tmp = strchr(comment, '=')))
1907 /* FIXME we should skip settings that are the same as old values */
1908 rc = mgs_modify(obd, fsdb, mti, logname, tgtname, comment, CM_SKIP);
1909 LCONSOLE_INFO("%sing parameter %s.%s in log %s\n", rc ?
1910 "Sett" : "Modify", tgtname, comment, logname);
1912 lustre_cfg_bufs_reset(bufs, tgtname);
1913 lustre_cfg_bufs_set_string(bufs, 1, ptr);
1914 lcfg = lustre_cfg_new(LCFG_PARAM, bufs);
1917 rc = mgs_write_log_direct(obd, fsdb, logname, lcfg, tgtname, comment);
1918 lustre_cfg_free(lcfg);
1923 * populate rules which applied to a target device
1925 static int mgs_get_srpc_conf_log(struct fs_db *fsdb, const char *tgt,
1926 enum lustre_sec_part from,
1927 enum lustre_sec_part to,
1928 struct sptlrpc_conf_log *log)
1930 struct mgs_tgt_srpc_conf *tgtconf;
1931 struct sptlrpc_rule_set *tgt_rset;
1932 int found_tgt = 0, rc;
1934 for (tgtconf = fsdb->fsdb_srpc_tgt; tgtconf;
1935 tgtconf = tgtconf->mtsc_next) {
1936 if (!strcmp(tgt, tgtconf->mtsc_tgt)) {
1943 tgt_rset = &tgtconf->mtsc_rset;
1947 rc = sptlrpc_conf_log_populate(&fsdb->fsdb_srpc_gen, tgt_rset,
1948 from, to, fsdb->fsdb_srpc_fl_udesc, log);
1950 CERROR("failed to populate srpc log for %s: %d\n", tgt, rc);
1955 struct mgs_msl_data {
1956 struct obd_device *mmd_obd;
1957 struct fs_db *mmd_fsdb;
1958 struct mgs_target_info *mmd_mti;
1962 enum lustre_sec_part mmd_tgtpart;
1963 char mmd_tgtname[MTI_NAME_MAXLEN];
1966 static void mgs_msl_data_cleanup(struct mgs_msl_data *mmd)
1968 mmd->mmd_attached = 0;
1969 mmd->mmd_tgtname[0] = '\0';
1972 static int mgs_msl_tgt_uuid2name(char *tgtname, char *tgtuuid)
1976 if (tgtuuid == NULL) {
1977 CERROR("missing target UUID???\n");
1981 ptr = strstr(tgtuuid, "_UUID");
1983 CERROR("unrecognized UUID: %s\n", tgtuuid);
1988 strncpy(tgtname, tgtuuid, MTI_NAME_MAXLEN);
1989 tgtname[MTI_NAME_MAXLEN - 1] = '\0';
1994 static int mgs_modify_srpc_log_handler(struct llog_handle *llh,
1995 struct llog_rec_hdr *rec,
1998 struct mgs_msl_data *mmd = (struct mgs_msl_data *)data;
1999 struct cfg_marker *marker;
2000 struct lustre_cfg *lcfg = (struct lustre_cfg *)(rec + 1);
2004 if (rec->lrh_type != OBD_CFG_REC) {
2005 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
2009 cfg_len = rec->lrh_len - sizeof(struct llog_rec_hdr) -
2010 sizeof(struct llog_rec_tail);
2012 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
2014 CERROR("Insane cfg\n");
2018 if (lcfg->lcfg_command == LCFG_MARKER) {
2019 marker = lustre_cfg_buf(lcfg, 1);
2021 if (marker->cm_flags & CM_START &&
2022 marker->cm_flags & CM_SKIP)
2024 if (marker->cm_flags & CM_END)
2033 switch (lcfg->lcfg_command) {
2035 mmd->mmd_attached = 1;
2037 if (!strcmp(lustre_cfg_string(lcfg, 1), LUSTRE_OST_NAME)) {
2038 mmd->mmd_server = 1;
2039 mmd->mmd_tgtpart = LUSTRE_SP_OST;
2040 } else if (!strcmp(lustre_cfg_string(lcfg, 1),
2042 mmd->mmd_server = 1;
2043 mmd->mmd_tgtpart = LUSTRE_SP_MDT;
2044 } else if (!strcmp(lustre_cfg_string(lcfg, 1),
2046 mmd->mmd_server = 0;
2047 mmd->mmd_tgtpart = LUSTRE_SP_OST;
2048 } else if (!strcmp(lustre_cfg_string(lcfg, 1),
2050 mmd->mmd_server = 0;
2051 mmd->mmd_tgtpart = LUSTRE_SP_MDT;
2053 mmd->mmd_attached = 0;
2056 if (mmd->mmd_attached && mmd->mmd_server) {
2057 rc = mgs_msl_tgt_uuid2name(mmd->mmd_tgtname,
2058 lustre_cfg_string(lcfg, 2));
2060 mgs_msl_data_cleanup(mmd);
2067 if (!mmd->mmd_attached)
2070 /* already got tgtname at LCFG_ATTACH */
2071 if (mmd->mmd_server)
2074 rc = mgs_msl_tgt_uuid2name(mmd->mmd_tgtname,
2075 lustre_cfg_string(lcfg, 1));
2077 mgs_msl_data_cleanup(mmd);
2082 case LCFG_SPTLRPC_CONF: {
2083 struct sptlrpc_conf_log *log;
2084 enum lustre_sec_part from;
2086 if (!mmd->mmd_attached)
2089 log = sptlrpc_conf_log_extract(lcfg);
2091 CERROR("missing sptlrpc config log???\n");
2092 mgs_msl_data_cleanup(mmd);
2096 if (mmd->mmd_server)
2097 from = LUSTRE_SP_ANY;
2099 from = log->scl_part;
2101 /* cleanup the old log */
2102 sptlrpc_conf_log_cleanup(log);
2104 /* populate new log */
2105 rc = mgs_get_srpc_conf_log(mmd->mmd_fsdb, mmd->mmd_tgtname,
2106 from, mmd->mmd_tgtpart, log);
2108 mgs_msl_data_cleanup(mmd);
2112 /* Overwrite the log */
2113 rec->lrh_len = cfg_len;
2114 rc = llog_write_rec(llh, rec, NULL, 0, (void *)lcfg,
2117 CERROR("overwrite sptlrpc conf log failed: %d\n", rc);
2119 /* append new one */
2120 rc = record_marker(mmd->mmd_obd, llh, mmd->mmd_fsdb, CM_START,
2121 mmd->mmd_mti->mti_svname, "sptlrpc config");
2122 rc = record_sptlrpc_conf(mmd->mmd_obd, llh,
2123 lustre_cfg_string(lcfg, 0), log);
2124 rc = record_marker(mmd->mmd_obd, llh, mmd->mmd_fsdb, CM_END,
2125 mmd->mmd_mti->mti_svname, "sptlrpc config");
2127 mgs_msl_data_cleanup(mmd);
2131 /* ignore all others */
2138 static int mgs_modify_srpc_log(struct obd_device *obd,
2140 struct mgs_target_info *mti,
2143 struct llog_handle *llh;
2144 struct lvfs_run_ctxt saved;
2145 struct llog_ctxt *ctxt;
2146 struct mgs_msl_data *mmd;
2150 CDEBUG(D_MGS, "modify sptlrpc log for %s\n", logname);
2152 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
2154 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
2155 LASSERT(ctxt != NULL);
2156 rc = llog_create(ctxt, &llh, NULL, logname);
2160 rc = llog_init_handle(llh, LLOG_F_IS_PLAIN, NULL);
2162 GOTO(out_close, rc);
2164 if (llog_get_size(llh) <= 1)
2165 GOTO(out_close, rc = 0);
2169 GOTO(out_close, rc = -ENOMEM);
2172 mmd->mmd_fsdb = fsdb;
2175 rc = llog_process(llh, mgs_modify_srpc_log_handler, (void *) mmd, NULL);
2180 rc2 = llog_close(llh);
2185 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
2186 llog_ctxt_put(ctxt);
2189 CERROR("modify sptlrpc log %s failed %d\n", logname, rc);
2194 * for each of log, remove old conf at first
2196 static int mgs_modify_srpc_log_all(struct obd_device *obd,
2198 struct mgs_target_info *mti)
2205 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
2206 if (test_bit(i, fsdb->fsdb_mdt_index_map)) {
2207 sprintf(tgt_index,"-MDT%04x",i);
2209 name_create(&logname, mti->mti_fsname, tgt_index);
2210 rc2 = mgs_modify(obd, fsdb, mti, logname,
2211 mti->mti_fsname, "sptlrpc config",
2213 rc2 = mgs_modify_srpc_log(obd, fsdb, mti, logname);
2214 name_destroy(&logname);
2221 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
2222 if (test_bit(i, fsdb->fsdb_ost_index_map)) {
2223 sprintf(tgt_index,"-OST%04x",i);
2225 name_create(&logname, mti->mti_fsname, tgt_index);
2226 rc2 = mgs_modify(obd, fsdb, mti, logname,
2227 mti->mti_fsname, "sptlrpc config",
2229 rc2 = mgs_modify_srpc_log(obd, fsdb, mti, logname);
2230 name_destroy(&logname);
2237 name_create(&logname, mti->mti_fsname, "-client");
2238 rc2 = mgs_modify(obd, fsdb, mti, logname,
2239 mti->mti_fsname, "sptlrpc config", CM_SKIP);
2240 rc2 = mgs_modify_srpc_log(obd, fsdb, mti, logname);
2241 name_destroy(&logname);
2249 static int mgs_srpc_set_param_disk(struct obd_device *obd,
2251 struct mgs_target_info *mti,
2254 struct llog_handle *llh = NULL;
2256 char *comment, *ptr;
2257 struct lustre_cfg_bufs bufs;
2258 struct lustre_cfg *lcfg;
2263 ptr = strchr(param, '=');
2267 OBD_ALLOC(comment, len + 1);
2268 if (comment == NULL)
2270 strncpy(comment, param, len);
2271 comment[len] = '\0';
2274 lustre_cfg_bufs_reset(&bufs, mti->mti_svname);
2275 lustre_cfg_bufs_set_string(&bufs, 1, param);
2276 lcfg = lustre_cfg_new(0, &bufs);
2278 GOTO(out_comment, rc = -ENOMEM);
2280 /* construct log name */
2281 rc = name_create(&logname, mti->mti_fsname, "-sptlrpc");
2285 if (mgs_log_is_empty(obd, logname)) {
2286 rc = record_start_log(obd, &llh, logname);
2287 record_end_log(obd, &llh);
2292 /* obsolete old one */
2293 mgs_modify(obd, fsdb, mti, logname, mti->mti_svname, comment, CM_SKIP);
2295 /* write the new one */
2296 rc = mgs_write_log_direct(obd, fsdb, logname, lcfg,
2297 mti->mti_svname, comment);
2299 CERROR("err %d writing log %s\n", rc, logname);
2302 name_destroy(&logname);
2304 lustre_cfg_free(lcfg);
2306 OBD_FREE(comment, len + 1);
2310 static int mgs_srpc_set_param_udesc_mem(struct fs_db *fsdb,
2315 /* disable the adjustable udesc parameter for now, i.e. use default
2316 * setting that client always ship udesc to MDT if possible. to enable
2317 * it simply remove the following line */
2320 ptr = strchr(param, '=');
2325 if (strcmp(param, PARAM_SRPC_UDESC))
2328 if (strcmp(ptr, "yes") == 0) {
2329 fsdb->fsdb_srpc_fl_udesc = 1;
2330 CWARN("Enable user descriptor shipping from client to MDT\n");
2331 } else if (strcmp(ptr, "no") == 0) {
2332 fsdb->fsdb_srpc_fl_udesc = 0;
2333 CWARN("Disable user descriptor shipping from client to MDT\n");
2341 CERROR("Invalid param: %s\n", param);
2345 static int mgs_srpc_set_param_mem(struct fs_db *fsdb,
2349 struct sptlrpc_rule rule;
2350 struct sptlrpc_rule_set *rset;
2354 if (strncmp(param, PARAM_SRPC, sizeof(PARAM_SRPC) - 1) != 0) {
2355 CERROR("Invalid sptlrpc parameter: %s\n", param);
2359 if (strncmp(param, PARAM_SRPC_UDESC,
2360 sizeof(PARAM_SRPC_UDESC) - 1) == 0) {
2361 RETURN(mgs_srpc_set_param_udesc_mem(fsdb, param));
2364 if (strncmp(param, PARAM_SRPC_FLVR, sizeof(PARAM_SRPC_FLVR) - 1) != 0) {
2365 CERROR("Invalid sptlrpc flavor parameter: %s\n", param);
2369 param += sizeof(PARAM_SRPC_FLVR) - 1;
2371 rc = sptlrpc_parse_rule(param, &rule);
2375 /* preapre room for this coming rule. svcname format should be:
2376 * - fsname: general rule
2377 * - fsname-tgtname: target-specific rule
2379 if (strchr(svname, '-')) {
2380 struct mgs_tgt_srpc_conf *tgtconf;
2383 for (tgtconf = fsdb->fsdb_srpc_tgt; tgtconf != NULL;
2384 tgtconf = tgtconf->mtsc_next) {
2385 if (!strcmp(tgtconf->mtsc_tgt, svname)) {
2394 OBD_ALLOC_PTR(tgtconf);
2395 if (tgtconf == NULL)
2398 name_len = strlen(svname);
2400 OBD_ALLOC(tgtconf->mtsc_tgt, name_len + 1);
2401 if (tgtconf->mtsc_tgt == NULL) {
2402 OBD_FREE_PTR(tgtconf);
2405 memcpy(tgtconf->mtsc_tgt, svname, name_len);
2407 tgtconf->mtsc_next = fsdb->fsdb_srpc_tgt;
2408 fsdb->fsdb_srpc_tgt = tgtconf;
2411 rset = &tgtconf->mtsc_rset;
2413 rset = &fsdb->fsdb_srpc_gen;
2416 /* limit the maximum number of rules, but allow deletion in any case */
2417 if (rset->srs_nrule >= SPTLRPC_CONF_LOG_MAX / 2 &&
2418 rule.sr_flvr.sf_rpc != SPTLRPC_FLVR_INVALID) {
2419 CERROR("too many (%d) rules already for %s\n",
2420 rset->srs_nrule, svname);
2424 rc = sptlrpc_rule_set_merge(rset, &rule, 1);
2429 static int mgs_srpc_set_param(struct obd_device *obd,
2431 struct mgs_target_info *mti,
2438 /* keep a copy of original param, which could be destroied
2440 copy_size = strlen(param) + 1;
2441 OBD_ALLOC(copy, copy_size);
2444 memcpy(copy, param, copy_size);
2446 rc = mgs_srpc_set_param_mem(fsdb, mti->mti_svname, param);
2450 /* previous steps guaranteed the syntax is correct */
2451 rc = mgs_srpc_set_param_disk(obd, fsdb, mti, copy);
2455 /* now apply the new rules to all existing config logs */
2456 rc = mgs_modify_srpc_log_all(obd, fsdb, mti);
2459 OBD_FREE(copy, copy_size);
2463 struct mgs_srpc_read_data {
2464 struct fs_db *msrd_fsdb;
2468 static int mgs_srpc_read_handler(struct llog_handle *llh,
2469 struct llog_rec_hdr *rec,
2472 struct mgs_srpc_read_data *msrd = (struct mgs_srpc_read_data *) data;
2473 struct cfg_marker *marker;
2474 struct lustre_cfg *lcfg = (struct lustre_cfg *)(rec + 1);
2475 char *svname, *param;
2479 if (rec->lrh_type != OBD_CFG_REC) {
2480 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
2484 cfg_len = rec->lrh_len - sizeof(struct llog_rec_hdr) -
2485 sizeof(struct llog_rec_tail);
2487 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
2489 CERROR("Insane cfg\n");
2493 if (lcfg->lcfg_command == LCFG_MARKER) {
2494 marker = lustre_cfg_buf(lcfg, 1);
2496 if (marker->cm_flags & CM_START &&
2497 marker->cm_flags & CM_SKIP)
2498 msrd->msrd_skip = 1;
2499 if (marker->cm_flags & CM_END)
2500 msrd->msrd_skip = 0;
2505 if (msrd->msrd_skip)
2508 if (lcfg->lcfg_command != 0) {
2509 CERROR("invalid command (%x)\n", lcfg->lcfg_command);
2513 svname = lustre_cfg_string(lcfg, 0);
2514 if (svname == NULL) {
2515 CERROR("svname is empty\n");
2519 param = lustre_cfg_string(lcfg, 1);
2520 if (param == NULL) {
2521 CERROR("param is empty\n");
2525 rc = mgs_srpc_set_param_mem(msrd->msrd_fsdb, svname, param);
2527 CERROR("read sptlrpc record error (%d): %s\n", rc, param);
2532 static int mgs_get_fsdb_srpc_from_llog(struct obd_device *obd,
2535 struct llog_handle *llh = NULL;
2536 struct lvfs_run_ctxt saved;
2537 struct llog_ctxt *ctxt;
2539 struct mgs_srpc_read_data msrd;
2543 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
2544 LASSERT(ctxt != NULL);
2546 /* construct log name */
2547 rc = name_create(&logname, fsdb->fsdb_name, "-sptlrpc");
2551 if (mgs_log_is_empty(obd, logname))
2554 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
2556 rc = llog_create(ctxt, &llh, NULL, logname);
2560 rc = llog_init_handle(llh, LLOG_F_IS_PLAIN, NULL);
2562 GOTO(out_close, rc);
2564 if (llog_get_size(llh) <= 1)
2565 GOTO(out_close, rc = 0);
2567 msrd.msrd_fsdb = fsdb;
2570 rc = llog_process(llh, mgs_srpc_read_handler, (void *) &msrd, NULL);
2575 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
2577 name_destroy(&logname);
2578 llog_ctxt_put(ctxt);
2581 CERROR("failed to read sptlrpc config database: %d\n", rc);
2585 static int mgs_write_log_params(struct obd_device *obd, struct fs_db *fsdb,
2586 struct mgs_target_info *mti)
2588 struct lustre_cfg_bufs bufs;
2589 struct lustre_cfg *lcfg;
2591 char *ptr = mti->mti_params;
2596 if (!mti->mti_params)
2599 /* For various parameter settings, we have to figure out which logs
2600 care about them (e.g. both mdt and client for lov settings) */
2606 endptr = strchr(ptr, ' ');
2609 CDEBUG(D_MGS, "next param '%s'\n", ptr);
2611 /* The params are stored in MOUNT_DATA_FILE and modified
2612 via tunefs.lustre */
2614 /* Processed in lustre_start_mgc */
2615 if (class_match_param(ptr, PARAM_MGSNODE, NULL) == 0)
2616 GOTO(end_while, rc);
2618 /* Processed in mgs_write_log_ost */
2619 if (class_match_param(ptr, PARAM_FAILMODE, NULL) == 0) {
2620 if (mti->mti_flags & LDD_F_PARAM) {
2621 LCONSOLE_ERROR_MSG(0x169, "%s can only be "
2622 "changed with tunefs.lustre"
2623 "and --writeconf\n", ptr);
2626 GOTO(end_while, rc);
2629 if (class_match_param(ptr, PARAM_SRPC, NULL) == 0) {
2630 rc = mgs_srpc_set_param(obd, fsdb, mti, ptr);
2631 GOTO(end_while, rc);
2634 if (class_match_param(ptr, PARAM_FAILNODE, NULL) == 0) {
2635 /* Add a failover nidlist */
2637 /* We already processed failovers params for new
2638 targets in mgs_write_log_target */
2639 if (mti->mti_flags & LDD_F_PARAM) {
2640 CDEBUG(D_MGS, "Adding failnode\n");
2641 rc = mgs_write_log_add_failnid(obd, fsdb, mti);
2643 GOTO(end_while, rc);
2646 if (class_match_param(ptr, PARAM_SYS_TIMEOUT, &tmp) == 0) {
2647 /* Change obd timeout */
2649 timeout = simple_strtoul(tmp, NULL, 0);
2651 CDEBUG(D_MGS, "obd timeout %d\n", timeout);
2652 lustre_cfg_bufs_reset(&bufs, NULL);
2653 lcfg = lustre_cfg_new(LCFG_SET_TIMEOUT, &bufs);
2654 lcfg->lcfg_num = timeout;
2655 /* modify all servers and clients */
2656 rc = mgs_write_log_direct_all(obd, fsdb, mti, lcfg,
2659 lustre_cfg_free(lcfg);
2660 GOTO(end_while, rc);
2663 if (class_match_param(ptr, PARAM_OSC""PARAM_ACTIVE, &tmp) == 0) {
2664 /* active=0 means off, anything else means on */
2666 int flag = (*tmp == '0') ? CM_EXCLUDE : 0;
2669 if (!(mti->mti_flags & LDD_F_SV_TYPE_OST)) {
2670 LCONSOLE_ERROR_MSG(0x144, "%s: Only OSCs can "
2671 "be (de)activated.\n",
2676 LCONSOLE_WARN("Permanently %sactivating %s\n",
2677 flag ? "de": "re", mti->mti_svname);
2679 name_create(&logname, mti->mti_fsname, "-client");
2680 rc = mgs_modify(obd, fsdb, mti, logname,
2681 mti->mti_svname, "add osc", flag);
2682 name_destroy(&logname);
2686 /* FIXME add to all MDT logs for CMD */
2687 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2688 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
2690 sprintf(mdt_index,"-MDT%04x", i);
2691 name_create(&logname, mti->mti_fsname, mdt_index);
2692 rc = mgs_modify(obd, fsdb, mti, logname,
2693 mti->mti_svname, "add osc", flag);
2694 name_destroy(&logname);
2700 LCONSOLE_ERROR_MSG(0x145, "Couldn't find %s in"
2701 "log (%d). No permanent "
2702 "changes were made to the "
2704 mti->mti_svname, rc);
2705 if (fsdb->fsdb_flags & FSDB_OLDLOG14)
2706 LCONSOLE_ERROR_MSG(0x146, "This may be"
2711 "update the logs.\n");
2714 /* Fall through to osc proc for deactivating
2715 live OSC on running MDT / clients. */
2717 /* Below here, let obd's XXX_process_config methods handle it */
2719 /* All lov. in proc */
2720 if (class_match_param(ptr, PARAM_LOV, NULL) == 0) {
2724 CDEBUG(D_MGS, "lov param %s\n", ptr);
2725 if (!(mti->mti_flags & LDD_F_SV_TYPE_MDT)) {
2726 LCONSOLE_ERROR_MSG(0x147, "LOV params must be "
2727 "set on the MDT, not %s. "
2735 if (mgs_log_is_empty(obd, mti->mti_svname))
2736 GOTO(end_while, rc = -ENODEV);
2738 sprintf(mdt_index,"-MDT%04x", mti->mti_stripe_index);
2739 name_create(&logname, mti->mti_fsname, mdt_index);
2740 name_create(&mdtlovname, logname, "-mdtlov");
2741 rc = mgs_wlp_lcfg(obd, fsdb, mti, mti->mti_svname,
2742 &bufs, mdtlovname, ptr);
2743 name_destroy(&logname);
2744 name_destroy(&mdtlovname);
2746 GOTO(end_while, rc);
2749 name_create(&logname, mti->mti_fsname, "-client");
2750 rc = mgs_wlp_lcfg(obd, fsdb, mti, logname, &bufs,
2751 fsdb->fsdb_clilov, ptr);
2752 name_destroy(&logname);
2753 GOTO(end_while, rc);
2756 /* All osc., mdc., llite. params in proc */
2757 if ((class_match_param(ptr, PARAM_OSC, NULL) == 0) ||
2758 (class_match_param(ptr, PARAM_MDC, NULL) == 0) ||
2759 (class_match_param(ptr, PARAM_LLITE, NULL) == 0)) {
2761 if (memcmp(ptr, PARAM_LLITE, strlen(PARAM_LLITE)) == 0) {
2762 name_create(&cname, mti->mti_fsname, "-client");
2763 /* Add the client type to match the obdname
2764 in class_config_llog_handler */
2765 } else if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
2768 name_create(&cname, fsdb->fsdb_mdc, "");
2770 name_create(&cname, mti->mti_svname,
2772 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2774 if (fsdb->fsdb_flags & FSDB_OLDLOG14) {
2775 LCONSOLE_ERROR_MSG(0x148, "Upgraded "
2776 "client logs for %s"
2778 "modified. Consider"
2780 "configuration with"
2783 /* We don't know the names of all the
2788 name_create(&cname, mti->mti_svname, "-osc");
2794 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
2797 name_create(&logname, mti->mti_fsname, "-client");
2798 rc = mgs_wlp_lcfg(obd, fsdb, mti, logname, &bufs,
2801 /* osc params affect the MDT as well */
2802 if (!rc && (mti->mti_flags & LDD_F_SV_TYPE_OST)) {
2806 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
2807 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
2809 name_destroy(&cname);
2810 sprintf(mdt_index, "-osc-MDT%04x", i);
2811 name_create(&cname, mti->mti_svname,
2813 name_destroy(&logname);
2814 sprintf(mdt_index, "-MDT%04x", i);
2815 name_create(&logname, mti->mti_fsname,
2817 if (!mgs_log_is_empty(obd, logname))
2818 rc = mgs_wlp_lcfg(obd, fsdb,
2826 name_destroy(&logname);
2827 name_destroy(&cname);
2828 GOTO(end_while, rc);
2831 /* All mdt., ost. params in proc */
2832 if ((class_match_param(ptr, PARAM_MDT, NULL) == 0) ||
2833 (class_match_param(ptr, PARAM_OST, NULL) == 0)) {
2834 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
2835 if (mgs_log_is_empty(obd, mti->mti_svname)) {
2839 rc = mgs_wlp_lcfg(obd, fsdb, mti, mti->mti_svname,
2840 &bufs, mti->mti_svname, ptr);
2841 GOTO(end_while, rc);
2844 LCONSOLE_WARN("Ignoring unrecognized param '%s'\n", ptr);
2848 CERROR("err %d on param '%s\n", rc, ptr);
2863 /* Not implementing automatic failover nid addition at this time. */
2864 int mgs_check_failnid(struct obd_device *obd, struct mgs_target_info *mti)
2871 rc = mgs_find_or_make_fsdb(obd, fsname, &fsdb);
2875 if (mgs_log_is_empty(obd, mti->mti_svname))
2876 /* should never happen */
2879 CDEBUG(D_MGS, "Checking for new failnids for %s\n", mti->mti_svname);
2881 /* FIXME We can just check mti->params to see if we're already in
2882 the failover list. Modify mti->params for rewriting back at
2883 server_register_target(). */
2885 down(&fsdb->fsdb_sem);
2886 rc = mgs_write_log_add_failnid(obd, fsdb, mti);
2887 up(&fsdb->fsdb_sem);
2894 int mgs_write_log_target(struct obd_device *obd,
2895 struct mgs_target_info *mti)
2901 /* set/check the new target index */
2902 rc = mgs_set_index(obd, mti);
2904 CERROR("Can't get index (%d)\n", rc);
2909 if (mti->mti_flags & LDD_F_UPGRADE14) {
2910 if (rc == EALREADY) {
2911 LCONSOLE_INFO("Found index %d for %s 1.4 log, "
2912 "upgrading\n", mti->mti_stripe_index,
2915 LCONSOLE_ERROR_MSG(0x149, "Failed to find %s in the old"
2916 " client log. Apparently it is not "
2917 "part of this filesystem, or the old"
2918 " log is wrong.\nUse 'writeconf' on "
2919 "the MDT to force log regeneration."
2920 "\n", mti->mti_svname);
2921 /* Not in client log? Upgrade anyhow...*/
2922 /* Argument against upgrading: reformat MDT,
2923 upgrade OST, then OST will start but will be SKIPped
2924 in client logs. Maybe error now is better. */
2925 /* RETURN(-EINVAL); */
2927 /* end COMPAT_146 */
2929 if (rc == EALREADY) {
2930 LCONSOLE_WARN("Found index %d for %s, updating log\n",
2931 mti->mti_stripe_index, mti->mti_svname);
2932 /* We would like to mark old log sections as invalid
2933 and add new log sections in the client and mdt logs.
2934 But if we add new sections, then live clients will
2935 get repeat setup instructions for already running
2936 osc's. So don't update the client/mdt logs. */
2937 mti->mti_flags &= ~LDD_F_UPDATE;
2941 rc = mgs_find_or_make_fsdb(obd, mti->mti_fsname, &fsdb);
2943 CERROR("Can't get db for %s\n", mti->mti_fsname);
2947 down(&fsdb->fsdb_sem);
2949 if (mti->mti_flags &
2950 (LDD_F_VIRGIN | LDD_F_UPGRADE14 | LDD_F_WRITECONF)) {
2951 /* Generate a log from scratch */
2952 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
2953 rc = mgs_write_log_mdt(obd, fsdb, mti);
2954 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2955 rc = mgs_write_log_ost(obd, fsdb, mti);
2957 CERROR("Unknown target type %#x, can't create log for "
2958 "%s\n", mti->mti_flags, mti->mti_svname);
2961 CERROR("Can't write logs for %s (%d)\n",
2962 mti->mti_svname, rc);
2966 /* Just update the params from tunefs in mgs_write_log_params */
2967 CDEBUG(D_MGS, "Update params for %s\n", mti->mti_svname);
2968 mti->mti_flags |= LDD_F_PARAM;
2971 rc = mgs_write_log_params(obd, fsdb, mti);
2974 up(&fsdb->fsdb_sem);
2979 /* verify that we can handle the old config logs */
2980 int mgs_upgrade_sv_14(struct obd_device *obd, struct mgs_target_info *mti)
2986 /* Create ost log normally, as servers register. Servers
2987 register with their old uuids (from last_rcvd), so old
2988 (MDT and client) logs should work.
2989 - new MDT won't know about old OSTs, only the ones that have
2990 registered, so we need the old MDT log to get the LOV right
2991 in order for old clients to work.
2992 - Old clients connect to the MDT, not the MGS, for their logs, and
2993 will therefore receive the old client log from the MDT /LOGS dir.
2994 - Old clients can continue to use and connect to old or new OSTs
2995 - New clients will contact the MGS for their log
2998 LCONSOLE_INFO("upgrading server %s from pre-1.6\n", mti->mti_svname);
2999 server_mti_print("upgrade", mti);
3001 rc = mgs_find_or_make_fsdb(obd, mti->mti_fsname, &fsdb);
3005 if (fsdb->fsdb_flags & FSDB_LOG_EMPTY) {
3006 LCONSOLE_ERROR_MSG(0x14a, "The old client log %s-client is "
3007 "missing. Was tunefs.lustre successful?\n",
3012 if (fsdb->fsdb_gen == 0) {
3013 /* There were no markers in the client log, meaning we have
3014 not updated the logs for this fs */
3015 CDEBUG(D_MGS, "found old, unupdated client log\n");
3018 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
3019 if (mgs_log_is_empty(obd, mti->mti_svname)) {
3020 LCONSOLE_ERROR_MSG(0x14b, "The old MDT log %s is "
3021 "missing. Was tunefs.lustre "
3026 /* We're starting with an old uuid. Assume old name for lov
3027 as well since the lov entry already exists in the log. */
3028 CDEBUG(D_MGS, "old mds uuid %s\n", mti->mti_uuid);
3029 if (strncmp(mti->mti_uuid, fsdb->fsdb_mdtlov + 4,
3030 strlen(fsdb->fsdb_mdtlov) - 4) != 0) {
3031 CERROR("old mds uuid %s doesn't match log %s (%s)\n",
3032 mti->mti_uuid, fsdb->fsdb_mdtlov,
3033 fsdb->fsdb_mdtlov + 4);
3038 if (!(fsdb->fsdb_flags & FSDB_OLDLOG14)) {
3039 LCONSOLE_ERROR_MSG(0x14c, "%s-client is supposedly an old "
3040 "log, but no old LOV or MDT was found. "
3041 "Consider updating the configuration with"
3042 " --writeconf.\n", mti->mti_fsname);
3047 /* end COMPAT_146 */
3049 int mgs_erase_log(struct obd_device *obd, char *name)
3051 struct lvfs_run_ctxt saved;
3052 struct llog_ctxt *ctxt;
3053 struct llog_handle *llh;
3056 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
3057 LASSERT(ctxt != NULL);
3059 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
3060 rc = llog_create(ctxt, &llh, NULL, name);
3062 llog_init_handle(llh, LLOG_F_IS_PLAIN, NULL);
3063 rc = llog_destroy(llh);
3064 llog_free_handle(llh);
3066 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
3067 llog_ctxt_put(ctxt);
3070 CERROR("failed to clear log %s: %d\n", name, rc);
3075 /* erase all logs for the given fs */
3076 int mgs_erase_logs(struct obd_device *obd, char *fsname)
3078 struct mgs_obd *mgs = &obd->u.mgs;
3079 static struct fs_db *fsdb;
3080 struct list_head dentry_list;
3081 struct l_linux_dirent *dirent, *n;
3082 int rc, len = strlen(fsname);
3085 /* Find all the logs in the CONFIGS directory */
3086 rc = class_dentry_readdir(obd, mgs->mgs_configs_dir,
3087 mgs->mgs_vfsmnt, &dentry_list);
3089 CERROR("Can't read %s dir\n", MOUNT_CONFIGS_DIR);
3093 down(&mgs->mgs_sem);
3095 /* Delete the fs db */
3096 fsdb = mgs_find_fsdb(obd, fsname);
3098 mgs_free_fsdb(obd, fsdb);
3100 list_for_each_entry_safe(dirent, n, &dentry_list, lld_list) {
3101 list_del(&dirent->lld_list);
3102 if (strncmp(fsname, dirent->lld_name, len) == 0) {
3103 CDEBUG(D_MGS, "Removing log %s\n", dirent->lld_name);
3104 mgs_erase_log(obd, dirent->lld_name);
3106 OBD_FREE(dirent, sizeof(*dirent));
3114 /* from llog_swab */
3115 static void print_lustre_cfg(struct lustre_cfg *lcfg)
3120 CDEBUG(D_MGS, "lustre_cfg: %p\n", lcfg);
3121 CDEBUG(D_MGS, "\tlcfg->lcfg_version: %#x\n", lcfg->lcfg_version);
3123 CDEBUG(D_MGS, "\tlcfg->lcfg_command: %#x\n", lcfg->lcfg_command);
3124 CDEBUG(D_MGS, "\tlcfg->lcfg_num: %#x\n", lcfg->lcfg_num);
3125 CDEBUG(D_MGS, "\tlcfg->lcfg_flags: %#x\n", lcfg->lcfg_flags);
3126 CDEBUG(D_MGS, "\tlcfg->lcfg_nid: %s\n", libcfs_nid2str(lcfg->lcfg_nid));
3128 CDEBUG(D_MGS, "\tlcfg->lcfg_bufcount: %d\n", lcfg->lcfg_bufcount);
3129 if (lcfg->lcfg_bufcount < LUSTRE_CFG_MAX_BUFCOUNT)
3130 for (i = 0; i < lcfg->lcfg_bufcount; i++) {
3131 CDEBUG(D_MGS, "\tlcfg->lcfg_buflens[%d]: %d %s\n",
3132 i, lcfg->lcfg_buflens[i],
3133 lustre_cfg_string(lcfg, i));
3138 /* Set a permanent (config log) param for a target or fs */
3139 int mgs_setparam(struct obd_device *obd, struct lustre_cfg *lcfg, char *fsname)
3142 struct mgs_target_info *mti;
3143 char *devname, *param;
3149 print_lustre_cfg(lcfg);
3151 /* lustre, lustre-mdtlov, lustre-client, lustre-MDT0000 */
3152 devname = lustre_cfg_string(lcfg, 0);
3153 param = lustre_cfg_string(lcfg, 1);
3155 /* Assume device name embedded in param:
3156 lustre-OST0000.osc.max_dirty_mb=32 */
3157 ptr = strchr(param, '.');
3165 LCONSOLE_ERROR_MSG(0x14d, "No target specified: %s\n", param);
3169 /* Extract fsname */
3170 ptr = strrchr(devname, '-');
3171 memset(fsname, 0, MTI_NAME_MAXLEN);
3172 if (ptr && (server_name2index(ptr, &index, NULL) >= 0)) {
3173 strncpy(fsname, devname, ptr - devname);
3175 /* assume devname is the fsname */
3176 strncpy(fsname, devname, MTI_NAME_MAXLEN);
3178 fsname[MTI_NAME_MAXLEN - 1] = 0;
3179 CDEBUG(D_MGS, "setparam on fs %s device %s\n", fsname, devname);
3181 rc = mgs_find_or_make_fsdb(obd, fsname, &fsdb);
3184 if (fsdb->fsdb_flags & FSDB_LOG_EMPTY) {
3185 CERROR("No filesystem targets for %s. cfg_device from lctl "
3186 "is '%s'\n", fsname, devname);
3187 mgs_free_fsdb(obd, fsdb);
3191 /* Create a fake mti to hold everything */
3194 GOTO(out, rc = -ENOMEM);
3195 strncpy(mti->mti_fsname, fsname, MTI_NAME_MAXLEN);
3196 strncpy(mti->mti_svname, devname, MTI_NAME_MAXLEN);
3197 strncpy(mti->mti_params, param, sizeof(mti->mti_params));
3198 rc = server_name2index(mti->mti_svname, &mti->mti_stripe_index, &tmp);
3200 /* Not a valid server; may be only fsname */
3203 /* Strip -osc or -mdc suffix from svname */
3204 if (server_make_name(rc, mti->mti_stripe_index, mti->mti_fsname,
3206 GOTO(out, rc = -EINVAL);
3208 mti->mti_flags = rc | LDD_F_PARAM;
3210 down(&fsdb->fsdb_sem);
3211 rc = mgs_write_log_params(obd, fsdb, mti);
3212 up(&fsdb->fsdb_sem);
3220 /******************** unused *********************/
3221 static int mgs_backup_llog(struct obd_device *obd, char* fsname)
3223 struct file *filp, *bak_filp;
3224 struct lvfs_run_ctxt saved;
3225 char *logname, *buf;
3226 loff_t soff = 0 , doff = 0;
3227 int count = 4096, len;
3230 OBD_ALLOC(logname, PATH_MAX);
3231 if (logname == NULL)
3234 OBD_ALLOC(buf, count);
3236 GOTO(out , rc = -ENOMEM);
3238 len = snprintf(logname, PATH_MAX, "%s/%s.bak",
3239 MOUNT_CONFIGS_DIR, fsname);
3241 if (len >= PATH_MAX - 1) {
3242 GOTO(out, -ENAMETOOLONG);
3245 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
3247 bak_filp = l_filp_open(logname, O_RDWR|O_CREAT|O_TRUNC, 0660);
3248 if (IS_ERR(bak_filp)) {
3249 rc = PTR_ERR(bak_filp);
3250 CERROR("backup logfile open %s: %d\n", logname, rc);
3253 sprintf(logname, "%s/%s", MOUNT_CONFIGS_DIR, fsname);
3254 filp = l_filp_open(logname, O_RDONLY, 0);
3257 CERROR("logfile open %s: %d\n", logname, rc);
3261 while ((rc = lustre_fread(filp, buf, count, &soff)) > 0) {
3262 rc = lustre_fwrite(bak_filp, buf, count, &doff);
3266 filp_close(filp, 0);
3268 filp_close(bak_filp, 0);
3270 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
3273 OBD_FREE(buf, count);
3274 OBD_FREE(logname, PATH_MAX);