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 /********************** Class functions ********************/
53 /* Caller must list_del and OBD_FREE each dentry from the list */
54 int class_dentry_readdir(struct obd_device *obd, struct dentry *dir,
55 struct vfsmount *inmnt,
56 struct list_head *dentry_list){
57 /* see mds_cleanup_pending */
58 struct lvfs_run_ctxt saved;
60 struct dentry *dentry;
65 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
68 GOTO(out_pop, rc = PTR_ERR(dentry));
72 GOTO(out_pop, rc = PTR_ERR(mnt));
75 file = dentry_open(dentry, mnt, O_RDONLY);
77 /* dentry_open_it() drops the dentry, mnt refs */
78 GOTO(out_pop, rc = PTR_ERR(file));
80 INIT_LIST_HEAD(dentry_list);
81 rc = l_readdir(file, dentry_list);
83 /* filp_close->fput() drops the dentry, mnt refs */
86 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
90 /******************** DB functions *********************/
92 static inline int name_create(char **newname, char *prefix, char *suffix)
95 OBD_ALLOC(*newname, strlen(prefix) + strlen(suffix) + 1);
98 sprintf(*newname, "%s%s", prefix, suffix);
102 static inline void name_destroy(char **name)
105 OBD_FREE(*name, strlen(*name) + 1);
109 /* from the (client) config log, figure out:
110 1. which ost's/mdt's are configured (by index)
111 2. what the last config step is
112 3. COMPAT_146 lov name
113 4. COMPAT_146 mdt lov name
114 5. COMPAT_146 mdc name
116 /* It might be better to have a separate db file, instead of parsing the info
117 out of the client log. This is slow and potentially error-prone. */
118 static int mgs_fsdb_handler(struct llog_handle *llh, struct llog_rec_hdr *rec,
121 struct fs_db *fsdb = (struct fs_db *)data;
122 int cfg_len = rec->lrh_len;
123 char *cfg_buf = (char*) (rec + 1);
124 struct lustre_cfg *lcfg;
129 if (rec->lrh_type != OBD_CFG_REC) {
130 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
134 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
136 CERROR("Insane cfg\n");
140 lcfg = (struct lustre_cfg *)cfg_buf;
142 CDEBUG(D_INFO, "cmd %x %s %s\n", lcfg->lcfg_command,
143 lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));
145 /* Figure out ost indicies */
146 /* lov_modify_tgts add 0:lov1 1:ost1_UUID 2(index):0 3(gen):1 */
147 if (lcfg->lcfg_command == LCFG_LOV_ADD_OBD ||
148 lcfg->lcfg_command == LCFG_LOV_DEL_OBD) {
149 index = simple_strtoul(lustre_cfg_string(lcfg, 2),
151 CDEBUG(D_MGS, "OST index for %s is %u (%s)\n",
152 lustre_cfg_string(lcfg, 1), index,
153 lustre_cfg_string(lcfg, 2));
154 set_bit(index, fsdb->fsdb_ost_index_map);
157 /* Figure out mdt indicies */
158 /* attach 0:MDC_uml1_mdsA_MNT_client 1:mdc 2:1d834_MNT_client_03f */
159 if ((lcfg->lcfg_command == LCFG_ATTACH) &&
160 (strcmp(lustre_cfg_string(lcfg, 1), LUSTRE_MDC_NAME) == 0)) {
161 rc = server_name2index(lustre_cfg_string(lcfg, 0),
163 if (rc != LDD_F_SV_TYPE_MDT) {
164 CWARN("Unparsable MDC name %s, assuming index 0\n",
165 lustre_cfg_string(lcfg, 0));
169 CDEBUG(D_MGS, "MDT index is %u\n", index);
170 set_bit(index, fsdb->fsdb_mdt_index_map);
174 /* figure out the old LOV name. fsdb_gen = 0 means old log */
175 /* #01 L attach 0:lov_mdsA 1:lov 2:cdbe9_lov_mdsA_dc8cf7f3bb */
176 if ((fsdb->fsdb_gen == 0) && (lcfg->lcfg_command == LCFG_ATTACH) &&
177 (strcmp(lustre_cfg_string(lcfg, 1), LUSTRE_LOV_NAME) == 0)) {
178 fsdb->fsdb_flags |= FSDB_OLDLOG14;
179 name_destroy(&fsdb->fsdb_clilov);
180 rc = name_create(&fsdb->fsdb_clilov,
181 lustre_cfg_string(lcfg, 0), "");
184 CDEBUG(D_MGS, "client lov name is %s\n", fsdb->fsdb_clilov);
187 /* figure out the old MDT lov name from the MDT uuid */
188 if ((fsdb->fsdb_gen == 0) && (lcfg->lcfg_command == LCFG_SETUP) &&
189 (strncmp(lustre_cfg_string(lcfg, 0), "MDC_", 4) == 0)) {
191 fsdb->fsdb_flags |= FSDB_OLDLOG14;
192 ptr = strstr(lustre_cfg_string(lcfg, 1), "_UUID");
194 CERROR("Can't parse MDT uuid %s\n",
195 lustre_cfg_string(lcfg, 1));
199 name_destroy(&fsdb->fsdb_mdtlov);
200 rc = name_create(&fsdb->fsdb_mdtlov,
201 "lov_", lustre_cfg_string(lcfg, 1));
204 name_destroy(&fsdb->fsdb_mdc);
205 rc = name_create(&fsdb->fsdb_mdc,
206 lustre_cfg_string(lcfg, 0), "");
209 CDEBUG(D_MGS, "MDT lov name is %s\n", fsdb->fsdb_mdtlov);
213 /* Keep track of the latest marker step */
214 if (lcfg->lcfg_command == LCFG_MARKER) {
215 struct cfg_marker *marker;
216 marker = lustre_cfg_buf(lcfg, 1);
217 fsdb->fsdb_gen = max(fsdb->fsdb_gen, marker->cm_step);
223 /* fsdb->fsdb_sem is already held in mgs_find_or_make_fsdb*/
224 static int mgs_get_fsdb_from_llog(struct obd_device *obd, struct fs_db *fsdb)
227 struct llog_handle *loghandle;
228 struct lvfs_run_ctxt saved;
232 name_create(&logname, fsdb->fsdb_name, "-client");
233 down(&fsdb->fsdb_sem);
234 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
236 rc = llog_create(llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT),
237 &loghandle, NULL, logname);
241 rc = llog_init_handle(loghandle, LLOG_F_IS_PLAIN, NULL);
245 if (llog_get_size(loghandle) <= 1)
246 fsdb->fsdb_flags |= FSDB_LOG_EMPTY;
248 rc = llog_process(loghandle, mgs_fsdb_handler, (void *)fsdb, NULL);
249 CDEBUG(D_INFO, "get_db = %d\n", rc);
251 rc2 = llog_close(loghandle);
256 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
258 name_destroy(&logname);
263 static struct fs_db *mgs_find_fsdb(struct obd_device *obd, char *fsname)
265 struct mgs_obd *mgs = &obd->u.mgs;
267 struct list_head *tmp;
269 list_for_each(tmp, &mgs->mgs_fs_db_list) {
270 fsdb = list_entry(tmp, struct fs_db, fsdb_list);
271 if (strcmp(fsdb->fsdb_name, fsname) == 0)
277 /* caller must hold the mgs->mgs_fs_db_lock */
278 static struct fs_db *mgs_new_fsdb(struct obd_device *obd, char *fsname)
280 struct mgs_obd *mgs = &obd->u.mgs;
289 OBD_ALLOC(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
290 OBD_ALLOC(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
291 if (!fsdb->fsdb_ost_index_map || !fsdb->fsdb_mdt_index_map) {
292 CERROR("No memory for index maps\n");
296 strncpy(fsdb->fsdb_name, fsname, sizeof(fsdb->fsdb_name));
297 fsdb->fsdb_name[sizeof(fsdb->fsdb_name) - 1] = 0;
298 rc = name_create(&fsdb->fsdb_mdtlov, fsname, "-mdtlov");
301 rc = name_create(&fsdb->fsdb_mdtlmv, fsname, "-mdtlmv");
304 rc = name_create(&fsdb->fsdb_clilov, fsname, "-clilov");
308 rc = name_create(&fsdb->fsdb_clilmv, fsname, "-clilmv");
312 sema_init(&fsdb->fsdb_sem, 1);
313 list_add(&fsdb->fsdb_list, &mgs->mgs_fs_db_list);
314 lproc_mgs_add_live(obd, fsdb);
318 if (fsdb->fsdb_ost_index_map)
319 OBD_FREE(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
320 if (fsdb->fsdb_mdt_index_map)
321 OBD_FREE(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
322 name_destroy(&fsdb->fsdb_clilov);
323 name_destroy(&fsdb->fsdb_clilmv);
324 name_destroy(&fsdb->fsdb_mdtlov);
325 name_destroy(&fsdb->fsdb_mdtlmv);
330 static void mgs_free_fsdb(struct obd_device *obd, struct fs_db *fsdb)
332 /* wait for anyone with the sem */
333 down(&fsdb->fsdb_sem);
334 lproc_mgs_del_live(obd, fsdb);
335 list_del(&fsdb->fsdb_list);
336 OBD_FREE(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
337 OBD_FREE(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
338 name_destroy(&fsdb->fsdb_clilov);
339 name_destroy(&fsdb->fsdb_clilmv);
340 name_destroy(&fsdb->fsdb_mdtlov);
341 name_destroy(&fsdb->fsdb_mdtlmv);
342 name_destroy(&fsdb->fsdb_mdc);
346 int mgs_init_fsdb_list(struct obd_device *obd)
348 struct mgs_obd *mgs = &obd->u.mgs;
349 INIT_LIST_HEAD(&mgs->mgs_fs_db_list);
353 int mgs_cleanup_fsdb_list(struct obd_device *obd)
355 struct mgs_obd *mgs = &obd->u.mgs;
357 struct list_head *tmp, *tmp2;
359 list_for_each_safe(tmp, tmp2, &mgs->mgs_fs_db_list) {
360 fsdb = list_entry(tmp, struct fs_db, fsdb_list);
361 mgs_free_fsdb(obd, fsdb);
367 static int mgs_find_or_make_fsdb(struct obd_device *obd, char *name,
370 struct mgs_obd *mgs = &obd->u.mgs;
375 fsdb = mgs_find_fsdb(obd, name);
382 CDEBUG(D_MGS, "Creating new db\n");
383 fsdb = mgs_new_fsdb(obd, name);
388 /* populate the db from the client llog */
389 rc = mgs_get_fsdb_from_llog(obd, fsdb);
391 CERROR("Can't get db from client log %d\n", rc);
392 mgs_free_fsdb(obd, fsdb);
403 -1= empty client log */
404 int mgs_check_index(struct obd_device *obd, struct mgs_target_info *mti)
411 LASSERT(!(mti->mti_flags & LDD_F_NEED_INDEX));
413 rc = mgs_find_or_make_fsdb(obd, mti->mti_fsname, &fsdb);
415 CERROR("Can't get db for %s\n", mti->mti_fsname);
419 if (fsdb->fsdb_flags & FSDB_LOG_EMPTY)
422 if (mti->mti_flags & LDD_F_SV_TYPE_OST)
423 imap = fsdb->fsdb_ost_index_map;
424 else if (mti->mti_flags & LDD_F_SV_TYPE_MDT)
425 imap = fsdb->fsdb_mdt_index_map;
429 if (test_bit(mti->mti_stripe_index, imap))
434 static __inline__ int next_index(void *index_map, int map_len)
437 for (i = 0; i < map_len * 8; i++)
438 if (!test_bit(i, index_map)) {
441 CERROR("max index %d exceeded.\n", i);
446 0 newly marked as in use
448 +EALREADY for update of an old index */
449 int mgs_set_index(struct obd_device *obd, struct mgs_target_info *mti)
456 rc = mgs_find_or_make_fsdb(obd, mti->mti_fsname, &fsdb);
458 CERROR("Can't get db for %s\n", mti->mti_fsname);
462 if (mti->mti_flags & LDD_F_SV_TYPE_OST)
463 imap = fsdb->fsdb_ost_index_map;
464 else if (mti->mti_flags & LDD_F_SV_TYPE_MDT)
465 imap = fsdb->fsdb_mdt_index_map;
469 if (mti->mti_flags & LDD_F_NEED_INDEX) {
470 rc = next_index(imap, INDEX_MAP_SIZE);
473 mti->mti_stripe_index = rc;
476 if (mti->mti_stripe_index >= INDEX_MAP_SIZE * 8) {
477 LCONSOLE_ERROR_MSG(0x13f, "Server %s requested index %d, "
478 "but the max index is %d.\n",
479 mti->mti_svname, mti->mti_stripe_index,
484 if (test_bit(mti->mti_stripe_index, imap)) {
485 if (mti->mti_flags & LDD_F_VIRGIN) {
486 LCONSOLE_ERROR_MSG(0x140, "Server %s requested index "
487 "%d, but that index is already in "
488 "use\n", mti->mti_svname,
489 mti->mti_stripe_index);
492 CDEBUG(D_MGS, "Server %s updating index %d\n",
493 mti->mti_svname, mti->mti_stripe_index);
498 set_bit(mti->mti_stripe_index, imap);
499 fsdb->fsdb_flags &= ~FSDB_LOG_EMPTY;
500 server_make_name(mti->mti_flags, mti->mti_stripe_index,
501 mti->mti_fsname, mti->mti_svname);
503 CDEBUG(D_MGS, "Set index for %s to %d\n", mti->mti_svname,
504 mti->mti_stripe_index);
509 struct mgs_modify_lookup {
510 struct cfg_marker mml_marker;
514 static int mgs_modify_handler(struct llog_handle *llh, struct llog_rec_hdr *rec,
517 struct mgs_modify_lookup *mml = (struct mgs_modify_lookup *)data;
518 struct cfg_marker *marker;
519 struct lustre_cfg *lcfg = (struct lustre_cfg *)(rec + 1);
520 int cfg_len = rec->lrh_len - sizeof(struct llog_rec_hdr) -
521 sizeof(struct llog_rec_tail);
525 if (rec->lrh_type != OBD_CFG_REC) {
526 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
530 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
532 CERROR("Insane cfg\n");
536 /* We only care about markers */
537 if (lcfg->lcfg_command != LCFG_MARKER)
540 marker = lustre_cfg_buf(lcfg, 1);
541 if ((strcmp(mml->mml_marker.cm_comment, marker->cm_comment) == 0) &&
542 (strcmp(mml->mml_marker.cm_tgtname, marker->cm_tgtname) == 0) &&
543 !(marker->cm_flags & CM_SKIP)) {
544 /* Found a non-skipped marker match */
545 CDEBUG(D_MGS, "Changing rec %u marker %d %x->%x: %s %s\n",
546 rec->lrh_index, marker->cm_step,
547 marker->cm_flags, mml->mml_marker.cm_flags,
548 marker->cm_tgtname, marker->cm_comment);
549 /* Overwrite the old marker llog entry */
550 marker->cm_flags &= ~CM_EXCLUDE; /* in case we're unexcluding */
551 marker->cm_flags |= mml->mml_marker.cm_flags;
552 marker->cm_canceltime = mml->mml_marker.cm_canceltime;
553 /* Header and tail are added back to lrh_len in
554 llog_lvfs_write_rec */
555 rec->lrh_len = cfg_len;
556 rc = llog_write_rec(llh, rec, NULL, 0, (void *)lcfg,
565 /* Modify an existing config log record (for CM_SKIP or CM_EXCLUDE) */
566 static int mgs_modify(struct obd_device *obd, struct fs_db *fsdb,
567 struct mgs_target_info *mti, char *logname,
568 char *devname, char *comment, int flags)
570 struct llog_handle *loghandle;
571 struct lvfs_run_ctxt saved;
572 struct mgs_modify_lookup *mml;
576 CDEBUG(D_MGS, "modify %s/%s/%s\n", logname, devname, comment);
578 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
580 rc = llog_create(llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT),
581 &loghandle, NULL, logname);
585 rc = llog_init_handle(loghandle, LLOG_F_IS_PLAIN, NULL);
589 if (llog_get_size(loghandle) <= 1)
590 GOTO(out_close, rc = 0);
594 GOTO(out_close, rc = -ENOMEM);
595 strcpy(mml->mml_marker.cm_comment, comment);
596 strcpy(mml->mml_marker.cm_tgtname, devname);
597 /* Modify mostly means cancel */
598 mml->mml_marker.cm_flags = flags;
599 mml->mml_marker.cm_canceltime = flags ? cfs_time_current_sec() : 0;
600 mml->mml_modified = 0;
601 rc = llog_process(loghandle, mgs_modify_handler, (void *)mml, NULL);
602 if (!rc && !mml->mml_modified)
607 rc2 = llog_close(loghandle);
612 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
613 if (rc && rc != -ENODEV)
614 CERROR("modify %s/%s failed %d\n",
615 mti->mti_svname, comment, rc);
620 /******************** config log recording functions *********************/
622 static int record_lcfg(struct obd_device *obd, struct llog_handle *llh,
623 struct lustre_cfg *lcfg)
625 struct lvfs_run_ctxt saved;
626 struct llog_rec_hdr rec;
632 LASSERT(llh->lgh_ctxt);
634 buflen = lustre_cfg_len(lcfg->lcfg_bufcount,
636 rec.lrh_len = llog_data_len(buflen);
637 rec.lrh_type = OBD_CFG_REC;
639 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
640 /* idx = -1 means append */
641 rc = llog_write_rec(llh, &rec, NULL, 0, (void *)lcfg, -1);
642 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
644 CERROR("failed %d\n", rc);
648 static int record_base(struct obd_device *obd, struct llog_handle *llh,
649 char *cfgname, lnet_nid_t nid, int cmd,
650 char *s1, char *s2, char *s3, char *s4)
652 struct lustre_cfg_bufs bufs;
653 struct lustre_cfg *lcfg;
656 CDEBUG(D_MGS, "lcfg %s %#x %s %s %s %s\n", cfgname,
657 cmd, s1, s2, s3, s4);
659 lustre_cfg_bufs_reset(&bufs, cfgname);
661 lustre_cfg_bufs_set_string(&bufs, 1, s1);
663 lustre_cfg_bufs_set_string(&bufs, 2, s2);
665 lustre_cfg_bufs_set_string(&bufs, 3, s3);
667 lustre_cfg_bufs_set_string(&bufs, 4, s4);
669 lcfg = lustre_cfg_new(cmd, &bufs);
672 lcfg->lcfg_nid = nid;
674 rc = record_lcfg(obd, llh, lcfg);
676 lustre_cfg_free(lcfg);
679 CERROR("error %d: lcfg %s %#x %s %s %s %s\n", rc, cfgname,
680 cmd, s1, s2, s3, s4);
686 static inline int record_add_uuid(struct obd_device *obd,
687 struct llog_handle *llh,
688 uint64_t nid, char *uuid)
690 return record_base(obd,llh,NULL,nid,LCFG_ADD_UUID,uuid,0,0,0);
694 static inline int record_add_conn(struct obd_device *obd,
695 struct llog_handle *llh,
699 return record_base(obd,llh,devname,0,LCFG_ADD_CONN,uuid,0,0,0);
702 static inline int record_attach(struct obd_device *obd, struct llog_handle *llh,
703 char *devname, char *type, char *uuid)
705 return record_base(obd,llh,devname,0,LCFG_ATTACH,type,uuid,0,0);
708 static inline int record_setup(struct obd_device *obd, struct llog_handle *llh,
710 char *s1, char *s2, char *s3, char *s4)
712 return record_base(obd,llh,devname,0,LCFG_SETUP,s1,s2,s3,s4);
715 static inline int record_sec_flavor(struct obd_device *obd,
716 struct llog_handle *llh, char *devname,
717 struct sec_flavor_config *conf)
719 struct lustre_cfg_bufs bufs;
720 struct lustre_cfg *lcfg;
723 lustre_cfg_bufs_reset(&bufs, devname);
724 lustre_cfg_bufs_set(&bufs, 1, conf, sizeof(*conf));
725 lcfg = lustre_cfg_new(LCFG_SEC_FLAVOR, &bufs);
727 rc = record_lcfg(obd, llh, lcfg);
729 lustre_cfg_free(lcfg);
733 static int record_lov_setup(struct obd_device *obd, struct llog_handle *llh,
734 char *devname, struct lov_desc *desc)
736 struct lustre_cfg_bufs bufs;
737 struct lustre_cfg *lcfg;
740 lustre_cfg_bufs_reset(&bufs, devname);
741 lustre_cfg_bufs_set(&bufs, 1, desc, sizeof(*desc));
742 lcfg = lustre_cfg_new(LCFG_SETUP, &bufs);
745 rc = record_lcfg(obd, llh, lcfg);
747 lustre_cfg_free(lcfg);
751 static int record_lmv_setup(struct obd_device *obd, struct llog_handle *llh,
752 char *devname, struct lmv_desc *desc)
754 struct lustre_cfg_bufs bufs;
755 struct lustre_cfg *lcfg;
758 lustre_cfg_bufs_reset(&bufs, devname);
759 lustre_cfg_bufs_set(&bufs, 1, desc, sizeof(*desc));
760 lcfg = lustre_cfg_new(LCFG_SETUP, &bufs);
762 rc = record_lcfg(obd, llh, lcfg);
764 lustre_cfg_free(lcfg);
768 static inline int record_mdc_add(struct obd_device *obd,
769 struct llog_handle *llh,
770 char *logname, char *mdcuuid,
771 char *mdtuuid, char *index,
774 return record_base(obd,llh,logname,0,LCFG_ADD_MDC,
775 mdtuuid,index,gen,mdcuuid);
778 static inline int record_lov_add(struct obd_device *obd,
779 struct llog_handle *llh,
780 char *lov_name, char *ost_uuid,
781 char *index, char *gen)
783 return record_base(obd,llh,lov_name,0,LCFG_LOV_ADD_OBD,
784 ost_uuid,index,gen,0);
787 static inline int record_mount_opt(struct obd_device *obd,
788 struct llog_handle *llh,
789 char *profile, char *lov_name,
792 return record_base(obd,llh,NULL,0,LCFG_MOUNTOPT,
793 profile,lov_name,mdc_name,0);
796 static int record_marker(struct obd_device *obd, struct llog_handle *llh,
797 struct fs_db *fsdb, __u32 flags,
798 char *tgtname, char *comment)
800 struct cfg_marker marker;
801 struct lustre_cfg_bufs bufs;
802 struct lustre_cfg *lcfg;
805 if (flags & CM_START)
807 marker.cm_step = fsdb->fsdb_gen;
808 marker.cm_flags = flags;
809 marker.cm_vers = LUSTRE_VERSION_CODE;
810 strncpy(marker.cm_tgtname, tgtname, sizeof(marker.cm_tgtname));
811 strncpy(marker.cm_comment, comment, sizeof(marker.cm_comment));
812 marker.cm_createtime = cfs_time_current_sec();
813 marker.cm_canceltime = 0;
814 lustre_cfg_bufs_reset(&bufs, NULL);
815 lustre_cfg_bufs_set(&bufs, 1, &marker, sizeof(marker));
816 lcfg = lustre_cfg_new(LCFG_MARKER, &bufs);
819 rc = record_lcfg(obd, llh, lcfg);
821 lustre_cfg_free(lcfg);
825 static int record_start_log(struct obd_device *obd,
826 struct llog_handle **llh, char *name)
828 static struct obd_uuid cfg_uuid = { .uuid = "config_uuid" };
829 struct lvfs_run_ctxt saved;
833 GOTO(out, rc = -EBUSY);
836 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
838 rc = llog_create(llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT),
841 llog_init_handle(*llh, LLOG_F_IS_PLAIN, &cfg_uuid);
845 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
849 CERROR("Can't start log %s: %d\n", name, rc);
854 static int record_end_log(struct obd_device *obd, struct llog_handle **llh)
856 struct lvfs_run_ctxt saved;
859 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
861 rc = llog_close(*llh);
864 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
868 static int mgs_log_is_empty(struct obd_device *obd, char *name)
870 struct lvfs_run_ctxt saved;
871 struct llog_handle *llh;
874 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
875 rc = llog_create(llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT),
878 llog_init_handle(llh, LLOG_F_IS_PLAIN, NULL);
879 rc = llog_get_size(llh);
882 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
883 /* header is record 1 */
887 /******************** config "macros" *********************/
889 /* write an lcfg directly into a log (with markers) */
890 static int mgs_write_log_direct(struct obd_device *obd, struct fs_db *fsdb,
891 char *logname, struct lustre_cfg *lcfg,
892 char *devname, char *comment)
894 struct llog_handle *llh = NULL;
901 rc = record_start_log(obd, &llh, logname);
905 /* FIXME These should be a single journal transaction */
906 rc = record_marker(obd, llh, fsdb, CM_START, devname, comment);
908 rc = record_lcfg(obd, llh, lcfg);
910 rc = record_marker(obd, llh, fsdb, CM_END, devname, comment);
911 rc = record_end_log(obd, &llh);
916 /* write the lcfg in all logs for the given fs */
917 int mgs_write_log_direct_all(struct obd_device *obd, struct fs_db *fsdb,
918 struct mgs_target_info *mti,
919 struct lustre_cfg *lcfg,
920 char *devname, char *comment)
922 struct mgs_obd *mgs = &obd->u.mgs;
923 struct list_head dentry_list;
924 struct l_linux_dirent *dirent, *n;
925 char *fsname = mti->mti_fsname;
927 int rc = 0, len = strlen(fsname);
930 /* We need to set params for any future logs
931 as well. FIXME Append this file to every new log.
932 Actually, we should store as params (text), not llogs. Or
934 name_create(&logname, fsname, "-params");
935 if (mgs_log_is_empty(obd, logname)) {
936 struct llog_handle *llh = NULL;
937 rc = record_start_log(obd, &llh, logname);
938 record_end_log(obd, &llh);
940 name_destroy(&logname);
944 /* Find all the logs in the CONFIGS directory */
945 rc = class_dentry_readdir(obd, mgs->mgs_configs_dir,
946 mgs->mgs_vfsmnt, &dentry_list);
948 CERROR("Can't read %s dir\n", MOUNT_CONFIGS_DIR);
952 /* Could use fsdb index maps instead of directory listing */
953 list_for_each_entry_safe(dirent, n, &dentry_list, lld_list) {
954 list_del(&dirent->lld_list);
955 if (strncmp(fsname, dirent->lld_name, len) == 0) {
956 CDEBUG(D_MGS, "Changing log %s\n", dirent->lld_name);
957 /* Erase any old settings of this same parameter */
958 mgs_modify(obd, fsdb, mti, dirent->lld_name, devname,
960 /* Write the new one */
961 rc = mgs_write_log_direct(obd, fsdb, dirent->lld_name,
962 lcfg, devname, comment);
964 CERROR("err %d writing log %s\n", rc,
967 OBD_FREE(dirent, sizeof(*dirent));
975 struct mgs_target_info *comp_tmti;
976 struct mgs_target_info *comp_mti;
977 struct fs_db *comp_fsdb;
978 struct obd_device *comp_obd;
979 struct sec_flavor_config comp_sec;
982 static int mgs_write_log_mdc_to_mdt(struct obd_device *, struct fs_db *,
983 struct mgs_target_info *,
984 struct sec_flavor_config *, char *);
986 static int mgs_steal_llog_handler(struct llog_handle *llh,
987 struct llog_rec_hdr *rec,
990 struct obd_device * obd;
991 struct mgs_target_info *mti, *tmti;
993 int cfg_len = rec->lrh_len;
994 char *cfg_buf = (char*) (rec + 1);
995 struct lustre_cfg *lcfg;
996 struct sec_flavor_config *sec_conf;
998 struct llog_handle *mdt_llh = NULL;
999 static int got_an_osc_or_mdc = 0;
1000 /* 0: not found any osc/mdc;
1004 static int last_step = -1;
1008 mti = ((struct temp_comp*)data)->comp_mti;
1009 tmti = ((struct temp_comp*)data)->comp_tmti;
1010 fsdb = ((struct temp_comp*)data)->comp_fsdb;
1011 obd = ((struct temp_comp*)data)->comp_obd;
1012 sec_conf = &((struct temp_comp*)data)->comp_sec;
1014 if (rec->lrh_type != OBD_CFG_REC) {
1015 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
1019 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
1021 CERROR("Insane cfg\n");
1025 lcfg = (struct lustre_cfg *)cfg_buf;
1027 if (lcfg->lcfg_command == LCFG_MARKER) {
1028 struct cfg_marker *marker;
1029 marker = lustre_cfg_buf(lcfg, 1);
1030 if (!strncmp(marker->cm_comment,"add osc",7) &&
1031 (marker->cm_flags & CM_START)){
1032 got_an_osc_or_mdc = 1;
1033 rc = record_start_log(obd, &mdt_llh, mti->mti_svname);
1034 rc = record_marker(obd, mdt_llh, fsdb, CM_START,
1035 mti->mti_svname,"add osc(copied)");
1036 rc = record_end_log(obd, &mdt_llh);
1037 last_step = marker->cm_step;
1040 if (!strncmp(marker->cm_comment,"add osc",7) &&
1041 (marker->cm_flags & CM_END)){
1042 LASSERT(last_step == marker->cm_step);
1044 got_an_osc_or_mdc = 0;
1045 rc = record_start_log(obd, &mdt_llh, mti->mti_svname);
1046 rc = record_marker(obd, mdt_llh, fsdb, CM_END,
1047 mti->mti_svname,"add osc(copied)");
1048 rc = record_end_log(obd, &mdt_llh);
1051 if (!strncmp(marker->cm_comment,"add mdc",7) &&
1052 (marker->cm_flags & CM_START)){
1053 got_an_osc_or_mdc = 2;
1054 last_step = marker->cm_step;
1055 memcpy(tmti->mti_svname, marker->cm_tgtname,
1056 strlen(marker->cm_tgtname));
1060 if (!strncmp(marker->cm_comment,"add mdc",7) &&
1061 (marker->cm_flags & CM_END)){
1062 LASSERT(last_step == marker->cm_step);
1064 got_an_osc_or_mdc = 0;
1069 if (got_an_osc_or_mdc == 0 || last_step < 0)
1072 if (lcfg->lcfg_command == LCFG_ADD_UUID) {
1074 nodenid = lcfg->lcfg_nid;
1076 tmti->mti_nids[tmti->mti_nid_count] = nodenid;
1077 tmti->mti_nid_count++;
1082 if (lcfg->lcfg_command == LCFG_SETUP) {
1085 target = lustre_cfg_string(lcfg, 1);
1086 memcpy(tmti->mti_uuid, target, strlen(target));
1090 if (lcfg->lcfg_command == LCFG_SEC_FLAVOR) {
1091 memcpy(sec_conf, lustre_cfg_buf(lcfg, 1), sizeof(*sec_conf));
1095 if (lcfg->lcfg_command == LCFG_ADD_MDC) {
1098 if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1)
1101 memcpy(tmti->mti_fsname, mti->mti_fsname,
1102 strlen(mti->mti_fsname));
1103 tmti->mti_stripe_index = index;
1105 mgs_write_log_mdc_to_mdt(obd, fsdb, tmti, sec_conf,
1107 memset(tmti, 0, sizeof(*tmti));
1113 /* fsdb->fsdb_sem is already held in mgs_write_log_target*/
1114 /* stealed from mgs_get_fsdb_from_llog*/
1115 static int mgs_steal_llog_for_mdt_from_client(struct obd_device *obd,
1117 struct temp_comp* comp)
1119 struct llog_handle *loghandle;
1120 struct lvfs_run_ctxt saved;
1121 struct mgs_target_info *tmti;
1125 OBD_ALLOC_PTR(tmti);
1129 comp->comp_tmti = tmti;
1130 comp->comp_obd = obd;
1132 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
1134 rc = llog_create(llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT),
1135 &loghandle, NULL, client_name);
1139 rc = llog_init_handle(loghandle, LLOG_F_IS_PLAIN, NULL);
1141 GOTO(out_close, rc);
1143 rc = llog_process(loghandle, mgs_steal_llog_handler, (void *)comp, NULL);
1144 CDEBUG(D_MGS, "steal llog re = %d\n", rc);
1146 rc2 = llog_close(loghandle);
1150 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
1155 /* lmv is the second thing for client logs */
1156 /* copied from mgs_write_log_lov. Please refer to that. */
1157 static int mgs_write_log_lmv(struct obd_device *obd, struct fs_db *fsdb,
1158 struct mgs_target_info *mti,
1159 char *logname, char *lmvname)
1161 struct llog_handle *llh = NULL;
1162 struct lmv_desc *lmvdesc;
1167 CDEBUG(D_MGS, "Writing lmv(%s) log for %s\n", lmvname,logname);
1169 OBD_ALLOC(lmvdesc, sizeof(*lmvdesc));
1170 if (lmvdesc == NULL)
1172 lmvdesc->ld_active_tgt_count = 0;
1173 lmvdesc->ld_tgt_count = 0;
1174 sprintf((char*)lmvdesc->ld_uuid.uuid, "%s_UUID", lmvname);
1175 uuid = (char *)lmvdesc->ld_uuid.uuid;
1177 rc = record_start_log(obd, &llh, logname);
1178 rc = record_marker(obd, llh, fsdb, CM_START, lmvname, "lmv setup");
1179 rc = record_attach(obd, llh, lmvname, "lmv", uuid);
1180 rc = record_lmv_setup(obd, llh, lmvname, lmvdesc);
1181 rc = record_marker(obd, llh, fsdb, CM_END, lmvname, "lmv setup");
1182 rc = record_end_log(obd, &llh);
1184 OBD_FREE(lmvdesc, sizeof(*lmvdesc));
1187 /***************************************END PROTO**********************/
1189 /* lov is the first thing in the mdt and client logs */
1190 static int mgs_write_log_lov(struct obd_device *obd, struct fs_db *fsdb,
1191 struct mgs_target_info *mti,
1192 char *logname, char *lovname)
1194 struct llog_handle *llh = NULL;
1195 struct lov_desc *lovdesc;
1200 CDEBUG(D_MGS, "Writing lov(%s) log for %s\n", lovname, logname);
1203 #01 L attach 0:lov_mdsA 1:lov 2:71ccb_lov_mdsA_19f961a9e1
1204 #02 L lov_setup 0:lov_mdsA 1:(struct lov_desc)
1205 uuid=lov1_UUID, stripe count=1, size=1048576, offset=0, pattern=0
1208 /* FIXME just make lov_setup accept empty desc (put uuid in buf 2) */
1209 OBD_ALLOC(lovdesc, sizeof(*lovdesc));
1210 if (lovdesc == NULL)
1212 lovdesc->ld_magic = LOV_DESC_MAGIC;
1213 lovdesc->ld_tgt_count = 0;
1214 /* Defaults. Can be changed later by lcfg config_param */
1215 lovdesc->ld_default_stripe_count = 1;
1216 lovdesc->ld_pattern = LOV_PATTERN_RAID0;
1217 lovdesc->ld_default_stripe_size = 1024 * 1024;
1218 lovdesc->ld_default_stripe_offset = 0;
1219 lovdesc->ld_qos_maxage = QOS_DEFAULT_MAXAGE;
1220 sprintf((char*)lovdesc->ld_uuid.uuid, "%s_UUID", lovname);
1221 /* can these be the same? */
1222 uuid = (char *)lovdesc->ld_uuid.uuid;
1224 /* This should always be the first entry in a log.
1225 rc = mgs_clear_log(obd, logname); */
1226 rc = record_start_log(obd, &llh, logname);
1229 /* FIXME these should be a single journal transaction */
1230 rc = record_marker(obd, llh, fsdb, CM_START, lovname, "lov setup");
1231 rc = record_attach(obd, llh, lovname, "lov", uuid);
1232 rc = record_lov_setup(obd, llh, lovname, lovdesc);
1233 rc = record_marker(obd, llh, fsdb, CM_END, lovname, "lov setup");
1234 rc = record_end_log(obd, &llh);
1236 OBD_FREE(lovdesc, sizeof(*lovdesc));
1240 /* add failnids to open log */
1241 static int mgs_write_log_failnids(struct obd_device *obd,
1242 struct mgs_target_info *mti,
1243 struct llog_handle *llh,
1246 char *failnodeuuid = NULL;
1247 char *ptr = mti->mti_params;
1252 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) nal=90 0: 1:uml1_UUID
1253 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
1254 #05 L setup 0:OSC_uml1_ost1_mdsA 1:ost1_UUID 2:uml1_UUID
1255 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) nal=90 0: 1:uml2_UUID
1256 #0x L add_uuid nid=2@elan(0x1000000000002) nal=90 0: 1:uml2_UUID
1257 #07 L add_conn 0:OSC_uml1_ost1_mdsA 1:uml2_UUID
1260 /* Pull failnid info out of params string */
1261 while (class_find_param(ptr, PARAM_FAILNODE, &ptr) == 0) {
1262 while (class_parse_nid(ptr, &nid, &ptr) == 0) {
1263 if (failnodeuuid == NULL) {
1264 /* We don't know the failover node name,
1265 so just use the first nid as the uuid */
1266 rc = name_create(&failnodeuuid,
1267 libcfs_nid2str(nid), "");
1271 CDEBUG(D_MGS, "add nid %s for failover uuid %s, "
1272 "client %s\n", libcfs_nid2str(nid),
1273 failnodeuuid, cliname);
1274 rc = record_add_uuid(obd, llh, nid, failnodeuuid);
1277 rc = record_add_conn(obd, llh, cliname, failnodeuuid);
1278 name_destroy(&failnodeuuid);
1279 failnodeuuid = NULL;
1287 void extract_sec_flavor(char *params, char *key, char **ptr)
1289 char *val = NULL, *tail;
1294 if (class_find_param(params, key, &val))
1297 tail = strchr(val, ' ');
1303 OBD_ALLOC(*ptr, len + 1);
1307 memcpy(*ptr, val, len);
1311 static int mgs_write_log_mdc_to_lmv(struct obd_device *obd, struct fs_db *fsdb,
1312 struct mgs_target_info *mti,
1313 struct sec_flavor_config *sec_conf,
1314 char *logname, char *lmvname)
1316 struct llog_handle *llh = NULL;
1317 char *mdcname, *nodeuuid, *mdcuuid, *lmvuuid;
1322 if (mgs_log_is_empty(obd, logname)) {
1323 CERROR("log is empty! Logical error\n");
1327 CDEBUG(D_MGS, "adding mdc for %s to log %s:lmv(%s)\n",
1328 mti->mti_svname, logname, lmvname);
1330 name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
1331 name_create(&mdcname, mti->mti_svname, "-mdc");
1332 name_create(&mdcuuid, mdcname, "_UUID");
1333 name_create(&lmvuuid, lmvname, "_UUID");
1335 rc = record_start_log(obd, &llh, logname);
1336 rc = record_marker(obd, llh, fsdb, CM_START, mti->mti_svname,
1339 for (i = 0; i < mti->mti_nid_count; i++) {
1340 CDEBUG(D_MGS, "add nid %s for mdt\n",
1341 libcfs_nid2str(mti->mti_nids[i]));
1343 rc = record_add_uuid(obd, llh, mti->mti_nids[i], nodeuuid);
1346 rc = record_attach(obd, llh, mdcname, LUSTRE_MDC_NAME, lmvuuid);
1347 rc = record_setup(obd, llh, mdcname, mti->mti_uuid, nodeuuid, 0, 0);
1348 rc = record_sec_flavor(obd, llh, mdcname, sec_conf);
1349 rc = mgs_write_log_failnids(obd, mti, llh, mdcname);
1350 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
1351 rc = record_mdc_add(obd, llh, lmvname, mdcuuid, mti->mti_uuid,
1353 rc = record_marker(obd, llh, fsdb, CM_END, mti->mti_svname,
1355 rc = record_end_log(obd, &llh);
1357 name_destroy(&lmvuuid);
1358 name_destroy(&mdcuuid);
1359 name_destroy(&mdcname);
1360 name_destroy(&nodeuuid);
1364 /* add new mdc to already existent MDS */
1365 static int mgs_write_log_mdc_to_mdt(struct obd_device *obd, struct fs_db *fsdb,
1366 struct mgs_target_info *mti,
1367 struct sec_flavor_config *sec_conf,
1370 struct llog_handle *llh = NULL;
1371 char *nodeuuid, *mdcname, *mdcuuid, *mdtuuid;
1372 int idx = mti->mti_stripe_index;
1377 if (mgs_log_is_empty(obd, mti->mti_svname)) {
1378 CERROR("log is empty! Logical error\n");
1382 CDEBUG(D_MGS, "adding mdc index %d to %s\n", idx, logname);
1384 name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
1385 snprintf(index, sizeof(index), "-mdc%04x", idx);
1386 name_create(&mdcname, logname, index);
1387 name_create(&mdcuuid, mdcname, "_UUID");
1388 name_create(&mdtuuid, logname, "_UUID");
1390 rc = record_start_log(obd, &llh, logname);
1391 rc = record_marker(obd, llh, fsdb, CM_START, mti->mti_svname, "add mdc");
1392 for (i = 0; i < mti->mti_nid_count; i++) {
1393 CDEBUG(D_MGS, "add nid %s for mdt\n",
1394 libcfs_nid2str(mti->mti_nids[i]));
1395 rc = record_add_uuid(obd, llh, mti->mti_nids[i], nodeuuid);
1397 rc = record_attach(obd, llh, mdcname, LUSTRE_MDC_NAME, mdcuuid);
1398 rc = record_setup(obd, llh, mdcname, mti->mti_uuid, nodeuuid, 0, 0);
1399 rc = record_sec_flavor(obd, llh, mdcname, sec_conf);
1400 rc = mgs_write_log_failnids(obd, mti, llh, mdcname);
1401 snprintf(index, sizeof(index), "%d", idx);
1403 rc = record_mdc_add(obd, llh, logname, mdcuuid, mti->mti_uuid,
1405 rc = record_marker(obd, llh, fsdb, CM_END, mti->mti_svname, "add mdc");
1406 rc = record_end_log(obd, &llh);
1408 name_destroy(&mdcuuid);
1409 name_destroy(&mdcname);
1410 name_destroy(&nodeuuid);
1411 name_destroy(&mdtuuid);
1415 static int mgs_write_log_mdt0(struct obd_device *obd, struct fs_db *fsdb,
1416 struct mgs_target_info *mti)
1418 char *log = mti->mti_svname;
1419 struct llog_handle *llh = NULL;
1420 char *uuid, *lovname;
1422 char *ptr = mti->mti_params;
1423 int rc = 0, failout = 0;
1426 OBD_ALLOC(uuid, sizeof(struct obd_uuid));
1430 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
1431 failout = (strncmp(ptr, "failout", 7) == 0);
1433 name_create(&lovname, log, "-mdtlov");
1434 if (mgs_log_is_empty(obd, log))
1435 rc = mgs_write_log_lov(obd, fsdb, mti, log, lovname);
1437 sprintf(uuid, "%s_UUID", log);
1438 sprintf(mdt_index,"%d",mti->mti_stripe_index);
1440 /* add MDT itself */
1441 rc = record_start_log(obd, &llh, log);
1445 /* FIXME this whole fn should be a single journal transaction */
1446 rc = record_marker(obd, llh, fsdb, CM_START, log, "add mdt");
1447 rc = record_attach(obd, llh, log, LUSTRE_MDT_NAME, uuid);
1448 rc = record_mount_opt(obd, llh, log, lovname, NULL);
1449 rc = record_setup(obd, llh, log, uuid, mdt_index, lovname,
1450 failout ? "n" : "f");
1451 rc = record_marker(obd, llh, fsdb, CM_END, log, "add mdt");
1452 rc = record_end_log(obd, &llh);
1454 name_destroy(&lovname);
1455 OBD_FREE(uuid, sizeof(struct obd_uuid));
1459 /* envelope method for all layers log */
1460 static int mgs_write_log_mdt(struct obd_device *obd, struct fs_db *fsdb,
1461 struct mgs_target_info *mti)
1463 char *cliname, *sec;
1464 struct llog_handle *llh = NULL;
1465 struct temp_comp comp = { 0 };
1466 struct sec_flavor_config sec_conf_mdt, sec_conf_cli;
1471 CDEBUG(D_MGS, "writing new mdt %s\n", mti->mti_svname);
1475 if (mti->mti_flags & LDD_F_UPGRADE14) {
1476 /* We're starting with an old uuid. Assume old name for lov
1477 as well since the lov entry already exists in the log. */
1478 CDEBUG(D_MGS, "old mds uuid %s\n", mti->mti_uuid);
1479 if (strncmp(mti->mti_uuid, fsdb->fsdb_mdtlov + 4,
1480 strlen(fsdb->fsdb_mdtlov) - 4) != 0) {
1481 CERROR("old mds uuid %s doesn't match log %s (%s)\n",
1482 mti->mti_uuid, fsdb->fsdb_mdtlov,
1483 fsdb->fsdb_mdtlov + 4);
1487 /* end COMPAT_146 */
1489 if (mti->mti_uuid[0] == '\0') {
1490 /* Make up our own uuid */
1491 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
1492 "%s_UUID", mti->mti_svname);
1495 /* security flavor */
1496 extract_sec_flavor(mti->mti_params, PARAM_SEC_RPC_MDT, &sec);
1497 rc = sptlrpc_parse_flavor(LUSTRE_MDT, LUSTRE_MDT, sec, &sec_conf_mdt);
1502 extract_sec_flavor(mti->mti_params, PARAM_SEC_RPC_CLI, &sec);
1503 rc = sptlrpc_parse_flavor(LUSTRE_CLI, LUSTRE_MDT, sec, &sec_conf_cli);
1509 rc = mgs_write_log_mdt0(obd, fsdb, mti);
1511 /* Append the mdt info to the client log */
1512 name_create(&cliname, mti->mti_fsname, "-client");
1514 if (mgs_log_is_empty(obd, cliname)) {
1515 /* Start client log */
1516 rc = mgs_write_log_lov(obd, fsdb, mti, cliname,
1518 rc = mgs_write_log_lmv(obd, fsdb, mti, cliname,
1523 #09 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
1524 #10 L attach 0:MDC_uml1_mdsA_MNT_client 1:mdc 2:1d834_MNT_client_03f
1525 #11 L setup 0:MDC_uml1_mdsA_MNT_client 1:mdsA_UUID 2:uml1_UUID
1526 #12 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
1527 #13 L add_conn 0:MDC_uml1_mdsA_MNT_client 1:uml2_UUID
1528 #14 L mount_option 0: 1:client 2:lov1 3:MDC_uml1_mdsA_MNT_client
1533 if (mti->mti_flags & LDD_F_UPGRADE14) {
1534 rc = record_start_log(obd, &llh, cliname);
1538 rc = record_marker(obd, llh, fsdb, CM_START,
1539 mti->mti_svname,"add mdc");
1541 /* Old client log already has MDC entry, but needs mount opt
1542 for new client name (lustre-client) */
1543 /* FIXME Old MDT log already has an old mount opt
1544 which we should remove (currently handled by
1545 class_del_profiles()) */
1546 rc = record_mount_opt(obd, llh, cliname, fsdb->fsdb_clilov,
1548 /* end COMPAT_146 */
1550 rc = record_marker(obd, llh, fsdb, CM_END,
1551 mti->mti_svname, "add mdc");
1555 /* copy client info about lov/lmv */
1556 comp.comp_mti = mti;
1557 comp.comp_fsdb = fsdb;
1559 rc = mgs_steal_llog_for_mdt_from_client(obd, cliname,
1562 rc = mgs_write_log_mdc_to_lmv(obd, fsdb, mti, &sec_conf_cli,
1563 cliname, fsdb->fsdb_clilmv);
1565 rc = record_start_log(obd, &llh, cliname);
1569 rc = record_marker(obd, llh, fsdb, CM_START, cliname,
1571 rc = record_mount_opt(obd, llh, cliname, fsdb->fsdb_clilov,
1573 rc = record_marker(obd, llh, fsdb, CM_END, cliname,
1577 rc = record_end_log(obd, &llh);
1579 name_destroy(&cliname);
1581 // for_all_existing_mdt except current one
1582 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
1584 if (i != mti->mti_stripe_index &&
1585 test_bit(i, fsdb->fsdb_mdt_index_map)) {
1586 sprintf(mdt_index,"-MDT%04x",i);
1588 name_create(&mdtname, mti->mti_fsname, mdt_index);
1589 rc = mgs_write_log_mdc_to_mdt(obd, fsdb, mti,
1590 &sec_conf_mdt, mdtname);
1591 name_destroy(&mdtname);
1598 /* Add the ost info to the client/mdt lov */
1599 static int mgs_write_log_osc_to_lov(struct obd_device *obd, struct fs_db *fsdb,
1600 struct mgs_target_info *mti,
1601 char *logname, char *suffix, char *lovname,
1602 struct sec_flavor_config *sec_conf,
1605 struct llog_handle *llh = NULL;
1606 char *nodeuuid, *oscname, *oscuuid, *lovuuid, *svname;
1611 CDEBUG(D_INFO, "adding osc for %s to log %s\n",
1612 mti->mti_svname, logname);
1614 if (mgs_log_is_empty(obd, logname)) {
1615 /* The first item in the log must be the lov, so we have
1616 somewhere to add our osc. */
1617 rc = mgs_write_log_lov(obd, fsdb, mti, logname, lovname);
1620 name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
1621 name_create(&svname, mti->mti_svname, "-osc");
1622 name_create(&oscname, svname, suffix);
1623 name_create(&oscuuid, oscname, "_UUID");
1624 name_create(&lovuuid, lovname, "_UUID");
1627 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
1629 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
1630 #04 L attach 0:OSC_uml1_ost1_MNT_client 1:osc 2:89070_lov1_a41dff51a
1631 #05 L setup 0:OSC_uml1_ost1_MNT_client 1:ost1_UUID 2:uml1_UUID
1633 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
1634 #07 L add_conn 0:OSC_uml1_ost1_MNT_client 1:uml2_UUID
1635 #08 L lov_modify_tgts add 0:lov1 1:ost1_UUID 2(index):0 3(gen):1
1638 rc = record_start_log(obd, &llh, logname);
1641 /* FIXME these should be a single journal transaction */
1642 rc = record_marker(obd, llh, fsdb, CM_START | flags, mti->mti_svname,
1644 for (i = 0; i < mti->mti_nid_count; i++) {
1645 CDEBUG(D_MGS, "add nid %s\n", libcfs_nid2str(mti->mti_nids[i]));
1646 rc = record_add_uuid(obd, llh, mti->mti_nids[i], nodeuuid);
1648 rc = record_attach(obd, llh, oscname, LUSTRE_OSC_NAME, lovuuid);
1649 rc = record_setup(obd, llh, oscname, mti->mti_uuid, nodeuuid, 0, 0);
1650 rc = record_sec_flavor(obd, llh, oscname, sec_conf);
1651 rc = mgs_write_log_failnids(obd, mti, llh, oscname);
1652 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
1653 rc = record_lov_add(obd, llh, lovname, mti->mti_uuid, index, "1");
1654 rc = record_marker(obd, llh, fsdb, CM_END | flags, mti->mti_svname,
1656 rc = record_end_log(obd, &llh);
1658 name_destroy(&lovuuid);
1659 name_destroy(&oscuuid);
1660 name_destroy(&oscname);
1661 name_destroy(&svname);
1662 name_destroy(&nodeuuid);
1666 static int mgs_write_log_ost(struct obd_device *obd, struct fs_db *fsdb,
1667 struct mgs_target_info *mti)
1669 struct llog_handle *llh = NULL;
1670 char *logname, *lovname, *sec;
1672 char *ptr = mti->mti_params;
1673 struct sec_flavor_config sec_conf_mdt, sec_conf_cli;
1674 int rc, flags = 0, failout = 0, i;
1677 CDEBUG(D_MGS, "writing new ost %s\n", mti->mti_svname);
1679 /* The ost startup log */
1681 /* If the ost log already exists, that means that someone reformatted
1682 the ost and it called target_add again. */
1683 if (!mgs_log_is_empty(obd, mti->mti_svname)) {
1684 LCONSOLE_ERROR_MSG(0x141, "The config log for %s already "
1685 "exists, yet the server claims it never "
1686 "registered. It may have been reformatted, "
1687 "or the index changed. writeconf the MDT to "
1688 "regenerate all logs.\n", mti->mti_svname);
1692 /* security flavors */
1693 extract_sec_flavor(mti->mti_params, PARAM_SEC_RPC_MDT, &sec);
1694 rc = sptlrpc_parse_flavor(LUSTRE_MDT, LUSTRE_OST, sec, &sec_conf_mdt);
1699 extract_sec_flavor(mti->mti_params, PARAM_SEC_RPC_CLI, &sec);
1700 rc = sptlrpc_parse_flavor(LUSTRE_CLI, LUSTRE_OST, sec, &sec_conf_cli);
1706 attach obdfilter ost1 ost1_UUID
1707 setup /dev/loop2 ldiskfs f|n errors=remount-ro,user_xattr
1709 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
1710 failout = (strncmp(ptr, "failout", 7) == 0);
1711 rc = record_start_log(obd, &llh, mti->mti_svname);
1714 /* FIXME these should be a single journal transaction */
1715 rc = record_marker(obd, llh, fsdb, CM_START, mti->mti_svname,"add ost");
1716 if (*mti->mti_uuid == '\0')
1717 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
1718 "%s_UUID", mti->mti_svname);
1719 rc = record_attach(obd, llh, mti->mti_svname,
1720 "obdfilter"/*LUSTRE_OST_NAME*/, mti->mti_uuid);
1721 rc = record_setup(obd, llh, mti->mti_svname,
1722 "dev"/*ignored*/, "type"/*ignored*/,
1723 failout ? "n" : "f", 0/*options*/);
1724 rc = record_marker(obd, llh, fsdb, CM_END, mti->mti_svname, "add ost");
1725 rc = record_end_log(obd, &llh);
1727 /* We also have to update the other logs where this osc is part of
1730 if (fsdb->fsdb_flags & FSDB_OLDLOG14) {
1731 /* If we're upgrading, the old mdt log already has our
1732 entry. Let's do a fake one for fun. */
1733 /* Note that we can't add any new failnids, since we don't
1734 know the old osc names. */
1735 flags = CM_SKIP | CM_UPGRADE146;
1737 } else if ((mti->mti_flags & LDD_F_UPDATE) != LDD_F_UPDATE) {
1738 /* If the update flag isn't set, don't update client/mdt
1741 LCONSOLE_WARN("Client log for %s was not updated; writeconf "
1742 "the MDT first to regenerate it.\n",
1746 // for_all_existing_mdt
1747 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
1748 if (test_bit(i, fsdb->fsdb_mdt_index_map)) {
1749 sprintf(mdt_index,"-MDT%04x",i);
1750 name_create(&logname, mti->mti_fsname, mdt_index);
1751 name_create(&lovname, logname, "-mdtlov");
1752 mgs_write_log_osc_to_lov(obd, fsdb, mti, logname,
1754 &sec_conf_mdt, flags);
1755 name_destroy(&logname);
1756 name_destroy(&lovname);
1760 /* Append ost info to the client log */
1761 name_create(&logname, mti->mti_fsname, "-client");
1762 mgs_write_log_osc_to_lov(obd, fsdb, mti, logname, "",
1763 fsdb->fsdb_clilov, &sec_conf_cli, 0);
1764 name_destroy(&logname);
1769 /* Add additional failnids to an existing log.
1770 The mdc/osc must have been added to logs first */
1771 /* tcp nids must be in dotted-quad ascii -
1772 we can't resolve hostnames from the kernel. */
1773 static int mgs_write_log_add_failnid(struct obd_device *obd, struct fs_db *fsdb,
1774 struct mgs_target_info *mti)
1776 char *logname, *cliname;
1777 struct llog_handle *llh = NULL;
1781 /* FIXME how do we delete a failnid? Currently --writeconf is the
1782 only way. Maybe make --erase-params pass a flag to really
1783 erase all params from logs - except it can't erase the failnids
1784 given when a target first registers, since they aren't processed
1787 /* Verify that we know about this target */
1788 if (mgs_log_is_empty(obd, mti->mti_svname)) {
1789 LCONSOLE_ERROR_MSG(0x142, "The target %s has not registered "
1790 "yet. It must be started before failnids "
1791 "can be added.\n", mti->mti_svname);
1795 /* Create mdc/osc client name (e.g. lustre-OST0001-osc) */
1796 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
1797 name_create(&cliname, mti->mti_svname, "-mdc");
1798 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
1799 name_create(&cliname, mti->mti_svname, "-osc");
1804 /* Add failover nids to client log */
1805 name_create(&logname, mti->mti_fsname, "-client");
1806 rc = record_start_log(obd, &llh, logname);
1808 /* FIXME this fn should be a single journal transaction */
1809 rc = record_marker(obd, llh, fsdb, CM_START, mti->mti_svname,
1811 rc = mgs_write_log_failnids(obd, mti, llh, cliname);
1812 rc = record_marker(obd, llh, fsdb, CM_END, mti->mti_svname,
1814 rc = record_end_log(obd, &llh);
1816 name_destroy(&logname);
1818 if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
1819 /* Add OST failover nids to the MDT log as well */
1820 name_create(&logname, mti->mti_fsname, "-MDT0000");
1821 rc = record_start_log(obd, &llh, logname);
1823 rc = record_marker(obd, llh, fsdb, CM_START,
1824 mti->mti_svname, "add failnid");
1825 rc = mgs_write_log_failnids(obd, mti, llh, cliname);
1826 rc = record_marker(obd, llh, fsdb, CM_END,
1827 mti->mti_svname, "add failnid");
1828 rc = record_end_log(obd, &llh);
1830 name_destroy(&logname);
1833 name_destroy(&cliname);
1837 static int mgs_wlp_lcfg(struct obd_device *obd, struct fs_db *fsdb,
1838 struct mgs_target_info *mti,
1839 char *logname, struct lustre_cfg_bufs *bufs,
1840 char *tgtname, char *ptr)
1842 char comment[MTI_NAME_MAXLEN];
1844 struct lustre_cfg *lcfg;
1847 /* Erase any old settings of this same parameter */
1848 memcpy(comment, ptr, MTI_NAME_MAXLEN);
1849 comment[MTI_NAME_MAXLEN - 1] = 0;
1850 /* But don't try to match the value. */
1851 if ((tmp = strchr(comment, '=')))
1853 /* FIXME we should skip settings that are the same as old values */
1854 rc = mgs_modify(obd, fsdb, mti, logname, tgtname, comment, CM_SKIP);
1855 LCONSOLE_INFO("%sing parameter %s.%s in log %s\n", rc ?
1856 "Sett" : "Modify", tgtname, comment, logname);
1858 lustre_cfg_bufs_reset(bufs, tgtname);
1859 lustre_cfg_bufs_set_string(bufs, 1, ptr);
1860 lcfg = lustre_cfg_new(LCFG_PARAM, bufs);
1863 rc = mgs_write_log_direct(obd, fsdb, logname, lcfg, tgtname, comment);
1864 lustre_cfg_free(lcfg);
1868 static int mgs_write_log_params(struct obd_device *obd, struct fs_db *fsdb,
1869 struct mgs_target_info *mti)
1871 struct lustre_cfg_bufs bufs;
1872 struct lustre_cfg *lcfg;
1874 char *ptr = mti->mti_params;
1879 if (!mti->mti_params)
1882 /* For various parameter settings, we have to figure out which logs
1883 care about them (e.g. both mdt and client for lov settings) */
1889 endptr = strchr(ptr, ' ');
1892 CDEBUG(D_MGS, "next param '%s'\n", ptr);
1894 /* The params are stored in MOUNT_DATA_FILE and modified
1895 via tunefs.lustre */
1897 /* Processed in lustre_start_mgc */
1898 if (class_match_param(ptr, PARAM_MGSNODE, NULL) == 0)
1899 GOTO(end_while, rc);
1901 /* Processed in mgs_write_log_ost */
1902 if (class_match_param(ptr, PARAM_FAILMODE, NULL) == 0) {
1903 if (mti->mti_flags & LDD_F_PARAM) {
1904 LCONSOLE_ERROR_MSG(0x169, "%s can only be "
1905 "changed with tunefs.lustre"
1906 "and --writeconf\n", ptr);
1909 GOTO(end_while, rc);
1911 /* Processed in mgs_write_log_mdt/mgs_write_log_ost */
1912 if (class_match_param(ptr, PARAM_SEC_RPC_MDT, NULL) == 0 ||
1913 class_match_param(ptr, PARAM_SEC_RPC_CLI, NULL) == 0)
1914 GOTO(end_while, rc);
1916 if (class_match_param(ptr, PARAM_FAILNODE, NULL) == 0) {
1917 /* Add a failover nidlist */
1919 /* We already processed failovers params for new
1920 targets in mgs_write_log_target */
1921 if (mti->mti_flags & LDD_F_PARAM) {
1922 CDEBUG(D_MGS, "Adding failnode\n");
1923 rc = mgs_write_log_add_failnid(obd, fsdb, mti);
1925 GOTO(end_while, rc);
1928 if (class_match_param(ptr, PARAM_SYS_TIMEOUT, &tmp) == 0) {
1929 /* Change obd timeout */
1931 timeout = simple_strtoul(tmp, NULL, 0);
1933 CDEBUG(D_MGS, "obd timeout %d\n", timeout);
1934 lustre_cfg_bufs_reset(&bufs, NULL);
1935 lcfg = lustre_cfg_new(LCFG_SET_TIMEOUT, &bufs);
1936 lcfg->lcfg_num = timeout;
1937 /* modify all servers and clients */
1938 rc = mgs_write_log_direct_all(obd, fsdb, mti, lcfg,
1941 lustre_cfg_free(lcfg);
1942 GOTO(end_while, rc);
1945 if (class_match_param(ptr, PARAM_OSC""PARAM_ACTIVE, &tmp) == 0) {
1946 /* active=0 means off, anything else means on */
1948 int flag = (*tmp == '0') ? CM_EXCLUDE : 0;
1951 if (!(mti->mti_flags & LDD_F_SV_TYPE_OST)) {
1952 LCONSOLE_ERROR_MSG(0x144, "%s: Only OSCs can "
1953 "be (de)activated.\n",
1958 LCONSOLE_WARN("Permanently %sactivating %s\n",
1959 flag ? "de": "re", mti->mti_svname);
1961 name_create(&logname, mti->mti_fsname, "-client");
1962 rc = mgs_modify(obd, fsdb, mti, logname,
1963 mti->mti_svname, "add osc", flag);
1964 name_destroy(&logname);
1968 /* FIXME add to all MDT logs for CMD */
1969 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
1970 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
1972 sprintf(mdt_index,"-MDT%04x", i);
1973 name_create(&logname, mti->mti_fsname, mdt_index);
1974 rc = mgs_modify(obd, fsdb, mti, logname,
1975 mti->mti_svname, "add osc", flag);
1976 name_destroy(&logname);
1982 LCONSOLE_ERROR_MSG(0x145, "Couldn't find %s in"
1983 "log (%d). No permanent "
1984 "changes were made to the "
1986 mti->mti_svname, rc);
1987 if (fsdb->fsdb_flags & FSDB_OLDLOG14)
1988 LCONSOLE_ERROR_MSG(0x146, "This may be"
1993 "update the logs.\n");
1996 /* Fall through to osc proc for deactivating
1997 live OSC on running MDT / clients. */
1999 /* Below here, let obd's XXX_process_config methods handle it */
2001 /* All lov. in proc */
2002 if (class_match_param(ptr, PARAM_LOV, NULL) == 0) {
2006 CDEBUG(D_MGS, "lov param %s\n", ptr);
2007 if (!(mti->mti_flags & LDD_F_SV_TYPE_MDT)) {
2008 LCONSOLE_ERROR_MSG(0x147, "LOV params must be "
2009 "set on the MDT, not %s. "
2017 if (mgs_log_is_empty(obd, mti->mti_svname))
2018 GOTO(end_while, rc = -ENODEV);
2020 sprintf(mdt_index,"-MDT%04x", mti->mti_stripe_index);
2021 name_create(&logname, mti->mti_fsname, mdt_index);
2022 name_create(&mdtlovname, logname, "-mdtlov");
2023 rc = mgs_wlp_lcfg(obd, fsdb, mti, mti->mti_svname,
2024 &bufs, mdtlovname, ptr);
2025 name_destroy(&logname);
2026 name_destroy(&mdtlovname);
2028 GOTO(end_while, rc);
2031 name_create(&logname, mti->mti_fsname, "-client");
2032 rc = mgs_wlp_lcfg(obd, fsdb, mti, logname, &bufs,
2033 fsdb->fsdb_clilov, ptr);
2034 name_destroy(&logname);
2035 GOTO(end_while, rc);
2038 /* All osc., mdc., llite. params in proc */
2039 if ((class_match_param(ptr, PARAM_OSC, NULL) == 0) ||
2040 (class_match_param(ptr, PARAM_MDC, NULL) == 0) ||
2041 (class_match_param(ptr, PARAM_LLITE, NULL) == 0)) {
2043 if (memcmp(ptr, PARAM_LLITE, strlen(PARAM_LLITE)) == 0) {
2044 name_create(&cname, mti->mti_fsname, "-client");
2045 /* Add the client type to match the obdname
2046 in class_config_llog_handler */
2047 } else if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
2050 name_create(&cname, fsdb->fsdb_mdc, "");
2052 name_create(&cname, mti->mti_svname,
2054 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2056 if (fsdb->fsdb_flags & FSDB_OLDLOG14) {
2057 LCONSOLE_ERROR_MSG(0x148, "Upgraded "
2058 "client logs for %s"
2060 "modified. Consider"
2062 "configuration with"
2065 /* We don't know the names of all the
2070 name_create(&cname, mti->mti_svname, "-osc");
2076 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
2079 name_create(&logname, mti->mti_fsname, "-client");
2080 rc = mgs_wlp_lcfg(obd, fsdb, mti, logname, &bufs,
2083 /* osc params affect the MDT as well */
2084 if (!rc && (mti->mti_flags & LDD_F_SV_TYPE_OST)) {
2088 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
2089 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
2091 name_destroy(&cname);
2092 sprintf(mdt_index, "-osc-MDT%04x", i);
2093 name_create(&cname, mti->mti_svname,
2095 name_destroy(&logname);
2096 sprintf(mdt_index, "-MDT%04x", i);
2097 name_create(&logname, mti->mti_fsname,
2099 if (!mgs_log_is_empty(obd, logname))
2100 rc = mgs_wlp_lcfg(obd, fsdb,
2108 name_destroy(&logname);
2109 name_destroy(&cname);
2110 GOTO(end_while, rc);
2113 /* All mdt., ost. params in proc */
2114 if ((class_match_param(ptr, PARAM_MDT, NULL) == 0) ||
2115 (class_match_param(ptr, PARAM_OST, NULL) == 0)) {
2116 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
2117 if (mgs_log_is_empty(obd, mti->mti_svname)) {
2121 rc = mgs_wlp_lcfg(obd, fsdb, mti, mti->mti_svname,
2122 &bufs, mti->mti_svname, ptr);
2123 GOTO(end_while, rc);
2126 LCONSOLE_WARN("Ignoring unrecognized param '%s'\n", ptr);
2130 CERROR("err %d on param '%s\n", rc, ptr);
2145 /* Not implementing automatic failover nid addition at this time. */
2146 int mgs_check_failnid(struct obd_device *obd, struct mgs_target_info *mti)
2153 rc = mgs_find_or_make_fsdb(obd, fsname, &fsdb);
2157 if (mgs_log_is_empty(obd, mti->mti_svname))
2158 /* should never happen */
2161 CDEBUG(D_MGS, "Checking for new failnids for %s\n", mti->mti_svname);
2163 /* FIXME We can just check mti->params to see if we're already in
2164 the failover list. Modify mti->params for rewriting back at
2165 server_register_target(). */
2167 down(&fsdb->fsdb_sem);
2168 rc = mgs_write_log_add_failnid(obd, fsdb, mti);
2169 up(&fsdb->fsdb_sem);
2176 int mgs_write_log_target(struct obd_device *obd,
2177 struct mgs_target_info *mti)
2183 /* set/check the new target index */
2184 rc = mgs_set_index(obd, mti);
2186 CERROR("Can't get index (%d)\n", rc);
2191 if (mti->mti_flags & LDD_F_UPGRADE14) {
2192 if (rc == EALREADY) {
2193 LCONSOLE_INFO("Found index %d for %s 1.4 log, "
2194 "upgrading\n", mti->mti_stripe_index,
2197 LCONSOLE_ERROR_MSG(0x149, "Failed to find %s in the old"
2198 " client log. Apparently it is not "
2199 "part of this filesystem, or the old"
2200 " log is wrong.\nUse 'writeconf' on "
2201 "the MDT to force log regeneration."
2202 "\n", mti->mti_svname);
2203 /* Not in client log? Upgrade anyhow...*/
2204 /* Argument against upgrading: reformat MDT,
2205 upgrade OST, then OST will start but will be SKIPped
2206 in client logs. Maybe error now is better. */
2207 /* RETURN(-EINVAL); */
2209 /* end COMPAT_146 */
2211 if (rc == EALREADY) {
2212 LCONSOLE_WARN("Found index %d for %s, updating log\n",
2213 mti->mti_stripe_index, mti->mti_svname);
2214 /* We would like to mark old log sections as invalid
2215 and add new log sections in the client and mdt logs.
2216 But if we add new sections, then live clients will
2217 get repeat setup instructions for already running
2218 osc's. So don't update the client/mdt logs. */
2219 mti->mti_flags &= ~LDD_F_UPDATE;
2223 rc = mgs_find_or_make_fsdb(obd, mti->mti_fsname, &fsdb);
2225 CERROR("Can't get db for %s\n", mti->mti_fsname);
2229 down(&fsdb->fsdb_sem);
2231 if (mti->mti_flags &
2232 (LDD_F_VIRGIN | LDD_F_UPGRADE14 | LDD_F_WRITECONF)) {
2233 /* Generate a log from scratch */
2234 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
2235 rc = mgs_write_log_mdt(obd, fsdb, mti);
2236 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2237 rc = mgs_write_log_ost(obd, fsdb, mti);
2239 CERROR("Unknown target type %#x, can't create log for "
2240 "%s\n", mti->mti_flags, mti->mti_svname);
2243 CERROR("Can't write logs for %s (%d)\n",
2244 mti->mti_svname, rc);
2248 /* Just update the params from tunefs in mgs_write_log_params */
2249 CDEBUG(D_MGS, "Update params for %s\n", mti->mti_svname);
2250 mti->mti_flags |= LDD_F_PARAM;
2253 rc = mgs_write_log_params(obd, fsdb, mti);
2256 up(&fsdb->fsdb_sem);
2261 /* verify that we can handle the old config logs */
2262 int mgs_upgrade_sv_14(struct obd_device *obd, struct mgs_target_info *mti)
2268 /* Create ost log normally, as servers register. Servers
2269 register with their old uuids (from last_rcvd), so old
2270 (MDT and client) logs should work.
2271 - new MDT won't know about old OSTs, only the ones that have
2272 registered, so we need the old MDT log to get the LOV right
2273 in order for old clients to work.
2274 - Old clients connect to the MDT, not the MGS, for their logs, and
2275 will therefore receive the old client log from the MDT /LOGS dir.
2276 - Old clients can continue to use and connect to old or new OSTs
2277 - New clients will contact the MGS for their log
2280 LCONSOLE_INFO("upgrading server %s from pre-1.6\n", mti->mti_svname);
2281 server_mti_print("upgrade", mti);
2283 rc = mgs_find_or_make_fsdb(obd, mti->mti_fsname, &fsdb);
2287 if (fsdb->fsdb_flags & FSDB_LOG_EMPTY) {
2288 LCONSOLE_ERROR_MSG(0x14a, "The old client log %s-client is "
2289 "missing. Was tunefs.lustre successful?\n",
2294 if (fsdb->fsdb_gen == 0) {
2295 /* There were no markers in the client log, meaning we have
2296 not updated the logs for this fs */
2297 CDEBUG(D_MGS, "found old, unupdated client log\n");
2300 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
2301 if (mgs_log_is_empty(obd, mti->mti_svname)) {
2302 LCONSOLE_ERROR_MSG(0x14b, "The old MDT log %s is "
2303 "missing. Was tunefs.lustre "
2308 /* We're starting with an old uuid. Assume old name for lov
2309 as well since the lov entry already exists in the log. */
2310 CDEBUG(D_MGS, "old mds uuid %s\n", mti->mti_uuid);
2311 if (strncmp(mti->mti_uuid, fsdb->fsdb_mdtlov + 4,
2312 strlen(fsdb->fsdb_mdtlov) - 4) != 0) {
2313 CERROR("old mds uuid %s doesn't match log %s (%s)\n",
2314 mti->mti_uuid, fsdb->fsdb_mdtlov,
2315 fsdb->fsdb_mdtlov + 4);
2320 if (!(fsdb->fsdb_flags & FSDB_OLDLOG14)) {
2321 LCONSOLE_ERROR_MSG(0x14c, "%s-client is supposedly an old "
2322 "log, but no old LOV or MDT was found. "
2323 "Consider updating the configuration with"
2324 " --writeconf.\n", mti->mti_fsname);
2329 /* end COMPAT_146 */
2331 int mgs_erase_log(struct obd_device *obd, char *name)
2333 struct lvfs_run_ctxt saved;
2334 struct llog_handle *llh;
2337 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
2338 rc = llog_create(llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT),
2341 llog_init_handle(llh, LLOG_F_IS_PLAIN, NULL);
2342 rc = llog_destroy(llh);
2343 llog_free_handle(llh);
2345 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
2348 CERROR("failed to clear log %s: %d\n", name, rc);
2353 /* erase all logs for the given fs */
2354 int mgs_erase_logs(struct obd_device *obd, char *fsname)
2356 struct mgs_obd *mgs = &obd->u.mgs;
2357 static struct fs_db *fsdb;
2358 struct list_head dentry_list;
2359 struct l_linux_dirent *dirent, *n;
2360 int rc, len = strlen(fsname);
2363 /* Find all the logs in the CONFIGS directory */
2364 rc = class_dentry_readdir(obd, mgs->mgs_configs_dir,
2365 mgs->mgs_vfsmnt, &dentry_list);
2367 CERROR("Can't read %s dir\n", MOUNT_CONFIGS_DIR);
2371 down(&mgs->mgs_sem);
2373 /* Delete the fs db */
2374 fsdb = mgs_find_fsdb(obd, fsname);
2376 mgs_free_fsdb(obd, fsdb);
2378 list_for_each_entry_safe(dirent, n, &dentry_list, lld_list) {
2379 list_del(&dirent->lld_list);
2380 if (strncmp(fsname, dirent->lld_name, len) == 0) {
2381 CDEBUG(D_MGS, "Removing log %s\n", dirent->lld_name);
2382 mgs_erase_log(obd, dirent->lld_name);
2384 OBD_FREE(dirent, sizeof(*dirent));
2392 /* from llog_swab */
2393 static void print_lustre_cfg(struct lustre_cfg *lcfg)
2398 CDEBUG(D_MGS, "lustre_cfg: %p\n", lcfg);
2399 CDEBUG(D_MGS, "\tlcfg->lcfg_version: %#x\n", lcfg->lcfg_version);
2401 CDEBUG(D_MGS, "\tlcfg->lcfg_command: %#x\n", lcfg->lcfg_command);
2402 CDEBUG(D_MGS, "\tlcfg->lcfg_num: %#x\n", lcfg->lcfg_num);
2403 CDEBUG(D_MGS, "\tlcfg->lcfg_flags: %#x\n", lcfg->lcfg_flags);
2404 CDEBUG(D_MGS, "\tlcfg->lcfg_nid: %s\n", libcfs_nid2str(lcfg->lcfg_nid));
2406 CDEBUG(D_MGS, "\tlcfg->lcfg_bufcount: %d\n", lcfg->lcfg_bufcount);
2407 if (lcfg->lcfg_bufcount < LUSTRE_CFG_MAX_BUFCOUNT)
2408 for (i = 0; i < lcfg->lcfg_bufcount; i++) {
2409 CDEBUG(D_MGS, "\tlcfg->lcfg_buflens[%d]: %d %s\n",
2410 i, lcfg->lcfg_buflens[i],
2411 lustre_cfg_string(lcfg, i));
2416 /* Set a permanent (config log) param for a target or fs */
2417 int mgs_setparam(struct obd_device *obd, struct lustre_cfg *lcfg, char *fsname)
2420 struct mgs_target_info *mti;
2421 char *devname, *param;
2427 print_lustre_cfg(lcfg);
2429 /* lustre, lustre-mdtlov, lustre-client, lustre-MDT0000 */
2430 devname = lustre_cfg_string(lcfg, 0);
2431 param = lustre_cfg_string(lcfg, 1);
2433 /* Assume device name embedded in param:
2434 lustre-OST0000.osc.max_dirty_mb=32 */
2435 ptr = strchr(param, '.');
2443 LCONSOLE_ERROR_MSG(0x14d, "No target specified: %s\n", param);
2447 /* Extract fsname */
2448 ptr = strrchr(devname, '-');
2449 memset(fsname, 0, MTI_NAME_MAXLEN);
2450 if (ptr && (server_name2index(ptr, &index, NULL) >= 0)) {
2451 strncpy(fsname, devname, ptr - devname);
2453 /* assume devname is the fsname */
2454 strncpy(fsname, devname, MTI_NAME_MAXLEN);
2456 fsname[MTI_NAME_MAXLEN - 1] = 0;
2457 CDEBUG(D_MGS, "setparam on fs %s device %s\n", fsname, devname);
2459 rc = mgs_find_or_make_fsdb(obd, fsname, &fsdb);
2462 if (fsdb->fsdb_flags & FSDB_LOG_EMPTY) {
2463 CERROR("No filesystem targets for %s. cfg_device from lctl "
2464 "is '%s'\n", fsname, devname);
2465 mgs_free_fsdb(obd, fsdb);
2469 /* Create a fake mti to hold everything */
2472 GOTO(out, rc = -ENOMEM);
2473 strncpy(mti->mti_fsname, fsname, MTI_NAME_MAXLEN);
2474 strncpy(mti->mti_svname, devname, MTI_NAME_MAXLEN);
2475 strncpy(mti->mti_params, param, sizeof(mti->mti_params));
2476 rc = server_name2index(mti->mti_svname, &mti->mti_stripe_index, &tmp);
2478 /* Not a valid server; may be only fsname */
2481 /* Strip -osc or -mdc suffix from svname */
2482 if (server_make_name(rc, mti->mti_stripe_index, mti->mti_fsname,
2484 GOTO(out, rc = -EINVAL);
2486 mti->mti_flags = rc | LDD_F_PARAM;
2488 down(&fsdb->fsdb_sem);
2489 rc = mgs_write_log_params(obd, fsdb, mti);
2490 up(&fsdb->fsdb_sem);
2498 /******************** unused *********************/
2499 static int mgs_backup_llog(struct obd_device *obd, char* fsname)
2501 struct file *filp, *bak_filp;
2502 struct lvfs_run_ctxt saved;
2503 char *logname, *buf;
2504 loff_t soff = 0 , doff = 0;
2505 int count = 4096, len;
2508 OBD_ALLOC(logname, PATH_MAX);
2509 if (logname == NULL)
2512 OBD_ALLOC(buf, count);
2514 GOTO(out , rc = -ENOMEM);
2516 len = snprintf(logname, PATH_MAX, "%s/%s.bak",
2517 MOUNT_CONFIGS_DIR, fsname);
2519 if (len >= PATH_MAX - 1) {
2520 GOTO(out, -ENAMETOOLONG);
2523 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
2525 bak_filp = l_filp_open(logname, O_RDWR|O_CREAT|O_TRUNC, 0660);
2526 if (IS_ERR(bak_filp)) {
2527 rc = PTR_ERR(bak_filp);
2528 CERROR("backup logfile open %s: %d\n", logname, rc);
2531 sprintf(logname, "%s/%s", MOUNT_CONFIGS_DIR, fsname);
2532 filp = l_filp_open(logname, O_RDONLY, 0);
2535 CERROR("logfile open %s: %d\n", logname, rc);
2539 while ((rc = lustre_fread(filp, buf, count, &soff)) > 0) {
2540 rc = lustre_fwrite(bak_filp, buf, count, &doff);
2544 filp_close(filp, 0);
2546 filp_close(bak_filp, 0);
2548 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
2551 OBD_FREE(buf, count);
2552 OBD_FREE(logname, PATH_MAX);