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 "mgs_internal.h"
50 /******************** Class functions *********************/
52 /* Caller must list_del and OBD_FREE each dentry from the list */
53 int class_dentry_readdir(struct obd_device *obd, struct dentry *dir,
54 struct vfsmount *inmnt,
55 struct list_head *dentry_list){
56 /* see mds_cleanup_pending */
57 struct lvfs_run_ctxt saved;
59 struct dentry *dentry;
64 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
67 GOTO(out_pop, rc = PTR_ERR(dentry));
71 GOTO(out_pop, rc = PTR_ERR(mnt));
74 file = dentry_open(dentry, mnt, O_RDONLY);
76 /* dentry_open_it() drops the dentry, mnt refs */
77 GOTO(out_pop, rc = PTR_ERR(file));
79 INIT_LIST_HEAD(dentry_list);
80 rc = l_readdir(file, dentry_list);
82 /* filp_close->fput() drops the dentry, mnt refs */
85 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
89 /******************** DB functions *********************/
91 static inline int name_create(char **newname, char *prefix, char *suffix)
94 OBD_ALLOC(*newname, strlen(prefix) + strlen(suffix) + 1);
97 sprintf(*newname, "%s%s", prefix, suffix);
101 static inline void name_destroy(char **name)
104 OBD_FREE(*name, strlen(*name) + 1);
108 /* from the (client) config log, figure out:
109 1. which ost's/mdt's are configured (by index)
110 2. what the last config step is
111 3. COMPAT_146 lov name
112 4. COMPAT_146 mdt lov name
113 5. COMPAT_146 mdc name
115 /* It might be better to have a separate db file, instead of parsing the info
116 out of the client log. This is slow and potentially error-prone. */
117 static int mgs_fsdb_handler(struct llog_handle *llh, struct llog_rec_hdr *rec,
120 struct fs_db *fsdb = (struct fs_db *)data;
121 int cfg_len = rec->lrh_len;
122 char *cfg_buf = (char*) (rec + 1);
123 struct lustre_cfg *lcfg;
128 if (rec->lrh_type != OBD_CFG_REC) {
129 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
133 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
135 CERROR("Insane cfg\n");
139 lcfg = (struct lustre_cfg *)cfg_buf;
141 CDEBUG(D_INFO, "cmd %x %s %s\n", lcfg->lcfg_command,
142 lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));
144 /* Figure out ost indicies */
145 /* lov_modify_tgts add 0:lov1 1:ost1_UUID 2(index):0 3(gen):1 */
146 if (lcfg->lcfg_command == LCFG_LOV_ADD_OBD ||
147 lcfg->lcfg_command == LCFG_LOV_DEL_OBD) {
148 index = simple_strtoul(lustre_cfg_string(lcfg, 2),
150 CDEBUG(D_MGS, "OST index for %s is %u (%s)\n",
151 lustre_cfg_string(lcfg, 1), index,
152 lustre_cfg_string(lcfg, 2));
153 set_bit(index, fsdb->fsdb_ost_index_map);
156 /* Figure out mdt indicies */
157 /* attach 0:MDC_uml1_mdsA_MNT_client 1:mdc 2:1d834_MNT_client_03f */
158 if ((lcfg->lcfg_command == LCFG_ATTACH) &&
159 (strcmp(lustre_cfg_string(lcfg, 1), LUSTRE_MDC_NAME) == 0)) {
160 rc = server_name2index(lustre_cfg_string(lcfg, 0),
162 if (rc != LDD_F_SV_TYPE_MDT) {
163 CWARN("Unparsable MDC name %s, assuming index 0\n",
164 lustre_cfg_string(lcfg, 0));
168 CDEBUG(D_MGS, "MDT index is %u\n", index);
169 set_bit(index, fsdb->fsdb_mdt_index_map);
173 /* figure out the old LOV name. fsdb_gen = 0 means old log */
174 /* #01 L attach 0:lov_mdsA 1:lov 2:cdbe9_lov_mdsA_dc8cf7f3bb */
175 if ((fsdb->fsdb_gen == 0) && (lcfg->lcfg_command == LCFG_ATTACH) &&
176 (strcmp(lustre_cfg_string(lcfg, 1), LUSTRE_LOV_NAME) == 0)) {
177 fsdb->fsdb_flags |= FSDB_OLDLOG14;
178 name_destroy(&fsdb->fsdb_clilov);
179 rc = name_create(&fsdb->fsdb_clilov,
180 lustre_cfg_string(lcfg, 0), "");
183 CDEBUG(D_MGS, "client lov name is %s\n", fsdb->fsdb_clilov);
186 /* figure out the old MDT lov name from the MDT uuid */
187 if ((fsdb->fsdb_gen == 0) && (lcfg->lcfg_command == LCFG_SETUP) &&
188 (strncmp(lustre_cfg_string(lcfg, 0), "MDC_", 4) == 0)) {
190 fsdb->fsdb_flags |= FSDB_OLDLOG14;
191 ptr = strstr(lustre_cfg_string(lcfg, 1), "_UUID");
193 CERROR("Can't parse MDT uuid %s\n",
194 lustre_cfg_string(lcfg, 1));
198 name_destroy(&fsdb->fsdb_mdtlov);
199 rc = name_create(&fsdb->fsdb_mdtlov,
200 "lov_", lustre_cfg_string(lcfg, 1));
203 name_destroy(&fsdb->fsdb_mdc);
204 rc = name_create(&fsdb->fsdb_mdc,
205 lustre_cfg_string(lcfg, 0), "");
208 CDEBUG(D_MGS, "MDT lov name is %s\n", fsdb->fsdb_mdtlov);
212 /* Keep track of the latest marker step */
213 if (lcfg->lcfg_command == LCFG_MARKER) {
214 struct cfg_marker *marker;
215 marker = lustre_cfg_buf(lcfg, 1);
216 fsdb->fsdb_gen = max(fsdb->fsdb_gen, marker->cm_step);
222 static int mgs_get_fsdb_from_llog(struct obd_device *obd, struct fs_db *fsdb)
225 struct llog_handle *loghandle;
226 struct lvfs_run_ctxt saved;
230 name_create(&logname, fsdb->fsdb_name, "-client");
231 down(&fsdb->fsdb_sem);
232 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
234 rc = llog_create(llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT),
235 &loghandle, NULL, logname);
239 rc = llog_init_handle(loghandle, LLOG_F_IS_PLAIN, NULL);
243 if (llog_get_size(loghandle) <= 1)
244 fsdb->fsdb_flags |= FSDB_LOG_EMPTY;
246 rc = llog_process(loghandle, mgs_fsdb_handler, (void *)fsdb, NULL);
247 CDEBUG(D_INFO, "get_db = %d\n", rc);
249 rc2 = llog_close(loghandle);
254 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
256 name_destroy(&logname);
261 static struct fs_db *mgs_find_fsdb(struct obd_device *obd, char *fsname)
263 struct mgs_obd *mgs = &obd->u.mgs;
265 struct list_head *tmp;
267 list_for_each(tmp, &mgs->mgs_fs_db_list) {
268 fsdb = list_entry(tmp, struct fs_db, fsdb_list);
269 if (strcmp(fsdb->fsdb_name, fsname) == 0)
275 /* caller must hold the mgs->mgs_fs_db_lock */
276 static struct fs_db *mgs_new_fsdb(struct obd_device *obd, char *fsname)
278 struct mgs_obd *mgs = &obd->u.mgs;
287 OBD_ALLOC(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
288 OBD_ALLOC(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
289 if (!fsdb->fsdb_ost_index_map || !fsdb->fsdb_mdt_index_map) {
290 CERROR("No memory for index maps\n");
294 strncpy(fsdb->fsdb_name, fsname, sizeof(fsdb->fsdb_name));
295 rc = name_create(&fsdb->fsdb_mdtlov, fsname, "-mdtlov");
298 rc = name_create(&fsdb->fsdb_clilov, fsname, "-clilov");
302 sema_init(&fsdb->fsdb_sem, 1);
303 list_add(&fsdb->fsdb_list, &mgs->mgs_fs_db_list);
304 lproc_mgs_add_live(obd, fsdb);
308 if (fsdb->fsdb_ost_index_map)
309 OBD_FREE(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
310 if (fsdb->fsdb_mdt_index_map)
311 OBD_FREE(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
312 name_destroy(&fsdb->fsdb_clilov);
313 name_destroy(&fsdb->fsdb_mdtlov);
318 static void mgs_free_fsdb(struct obd_device *obd, struct fs_db *fsdb)
320 /* wait for anyone with the sem */
321 down(&fsdb->fsdb_sem);
322 lproc_mgs_del_live(obd, fsdb);
323 list_del(&fsdb->fsdb_list);
324 OBD_FREE(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
325 OBD_FREE(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
326 name_destroy(&fsdb->fsdb_clilov);
327 name_destroy(&fsdb->fsdb_mdtlov);
328 name_destroy(&fsdb->fsdb_mdc);
332 int mgs_init_fsdb_list(struct obd_device *obd)
334 struct mgs_obd *mgs = &obd->u.mgs;
335 INIT_LIST_HEAD(&mgs->mgs_fs_db_list);
339 int mgs_cleanup_fsdb_list(struct obd_device *obd)
341 struct mgs_obd *mgs = &obd->u.mgs;
343 struct list_head *tmp, *tmp2;
345 list_for_each_safe(tmp, tmp2, &mgs->mgs_fs_db_list) {
346 fsdb = list_entry(tmp, struct fs_db, fsdb_list);
347 mgs_free_fsdb(obd, fsdb);
353 static int mgs_find_or_make_fsdb(struct obd_device *obd, char *name,
356 struct mgs_obd *mgs = &obd->u.mgs;
361 fsdb = mgs_find_fsdb(obd, name);
368 CDEBUG(D_MGS, "Creating new db\n");
369 fsdb = mgs_new_fsdb(obd, name);
374 /* populate the db from the client llog */
375 rc = mgs_get_fsdb_from_llog(obd, fsdb);
377 CERROR("Can't get db from client log %d\n", rc);
378 mgs_free_fsdb(obd, fsdb);
389 -1= empty client log */
390 int mgs_check_index(struct obd_device *obd, struct mgs_target_info *mti)
397 LASSERT(!(mti->mti_flags & LDD_F_NEED_INDEX));
399 rc = mgs_find_or_make_fsdb(obd, mti->mti_fsname, &fsdb);
401 CERROR("Can't get db for %s\n", mti->mti_fsname);
405 if (fsdb->fsdb_flags & FSDB_LOG_EMPTY)
408 if (mti->mti_flags & LDD_F_SV_TYPE_OST)
409 imap = fsdb->fsdb_ost_index_map;
410 else if (mti->mti_flags & LDD_F_SV_TYPE_MDT)
411 imap = fsdb->fsdb_mdt_index_map;
415 if (test_bit(mti->mti_stripe_index, imap))
420 static __inline__ int next_index(void *index_map, int map_len)
423 for (i = 0; i < map_len * 8; i++)
424 if (!test_bit(i, index_map)) {
427 CERROR("max index %d exceeded.\n", i);
432 0 newly marked as in use
434 +EALREADY for update of an old index */
435 int mgs_set_index(struct obd_device *obd, struct mgs_target_info *mti)
442 rc = mgs_find_or_make_fsdb(obd, mti->mti_fsname, &fsdb);
444 CERROR("Can't get db for %s\n", mti->mti_fsname);
448 if (mti->mti_flags & LDD_F_SV_TYPE_OST)
449 imap = fsdb->fsdb_ost_index_map;
450 else if (mti->mti_flags & LDD_F_SV_TYPE_MDT)
451 imap = fsdb->fsdb_mdt_index_map;
455 if (mti->mti_flags & LDD_F_NEED_INDEX) {
456 rc = next_index(imap, INDEX_MAP_SIZE);
459 mti->mti_stripe_index = rc;
462 /* Remove after CMD */
463 if ((mti->mti_flags & LDD_F_SV_TYPE_MDT) &&
464 (mti->mti_stripe_index > 0)) {
465 LCONSOLE_ERROR("MDT index must = 0 (until Clustered MetaData "
466 "feature is ready.)\n");
467 mti->mti_stripe_index = 0;
470 if (mti->mti_stripe_index >= INDEX_MAP_SIZE * 8) {
471 LCONSOLE_ERROR("Server %s requested index %d, but the"
472 "max index is %d.\n",
473 mti->mti_svname, mti->mti_stripe_index,
478 if (test_bit(mti->mti_stripe_index, imap)) {
479 if (mti->mti_flags & LDD_F_VIRGIN) {
480 LCONSOLE_ERROR("Server %s requested index %d, but that "
481 "index is already in use\n",
482 mti->mti_svname, mti->mti_stripe_index);
485 CDEBUG(D_MGS, "Server %s updating index %d\n",
486 mti->mti_svname, mti->mti_stripe_index);
491 set_bit(mti->mti_stripe_index, imap);
492 fsdb->fsdb_flags &= ~FSDB_LOG_EMPTY;
493 server_make_name(mti->mti_flags, mti->mti_stripe_index,
494 mti->mti_fsname, mti->mti_svname);
496 CDEBUG(D_MGS, "Set index for %s to %d\n", mti->mti_svname,
497 mti->mti_stripe_index);
502 struct mgs_modify_lookup {
503 struct cfg_marker mml_marker;
507 static int mgs_modify_handler(struct llog_handle *llh, struct llog_rec_hdr *rec,
510 struct mgs_modify_lookup *mml = (struct mgs_modify_lookup *)data;
511 struct cfg_marker *marker;
512 struct lustre_cfg *lcfg = (struct lustre_cfg *)(rec + 1);
513 int cfg_len = rec->lrh_len - sizeof(struct llog_rec_hdr) -
514 sizeof(struct llog_rec_tail);
518 if (rec->lrh_type != OBD_CFG_REC) {
519 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
523 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
525 CERROR("Insane cfg\n");
529 /* We only care about markers */
530 if (lcfg->lcfg_command != LCFG_MARKER)
533 marker = lustre_cfg_buf(lcfg, 1);
534 if ((strcmp(mml->mml_marker.cm_comment, marker->cm_comment) == 0) &&
535 (strcmp(mml->mml_marker.cm_tgtname, marker->cm_tgtname) == 0) &&
536 !(marker->cm_flags & CM_SKIP)) {
537 /* Found a non-skipped marker match */
538 CDEBUG(D_MGS, "Changing rec %u marker %d %x->%x: %s %s\n",
539 rec->lrh_index, marker->cm_step,
540 marker->cm_flags, mml->mml_marker.cm_flags,
541 marker->cm_tgtname, marker->cm_comment);
542 /* Overwrite the old marker llog entry */
543 marker->cm_flags &= ~CM_EXCLUDE; /* in case we're unexcluding */
544 marker->cm_flags |= mml->mml_marker.cm_flags;
545 marker->cm_canceltime = mml->mml_marker.cm_canceltime;
546 /* Header and tail are added back to lrh_len in
547 llog_lvfs_write_rec */
548 rec->lrh_len = cfg_len;
549 rc = llog_write_rec(llh, rec, NULL, 0, (void *)lcfg,
558 /* Modify an existing config log record (for CM_SKIP or CM_EXCLUDE) */
559 static int mgs_modify(struct obd_device *obd, struct fs_db *fsdb,
560 struct mgs_target_info *mti, char *logname,
561 char *devname, char *comment, int flags)
563 struct llog_handle *loghandle;
564 struct lvfs_run_ctxt saved;
565 struct mgs_modify_lookup *mml;
569 CDEBUG(D_MGS, "modify %s/%s/%s\n", logname, devname, comment);
571 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
573 rc = llog_create(llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT),
574 &loghandle, NULL, logname);
578 rc = llog_init_handle(loghandle, LLOG_F_IS_PLAIN, NULL);
582 if (llog_get_size(loghandle) <= 1)
583 GOTO(out_close, rc = 0);
587 GOTO(out_close, rc = -ENOMEM);
588 strcpy(mml->mml_marker.cm_comment, comment);
589 strcpy(mml->mml_marker.cm_tgtname, devname);
590 /* Modify mostly means cancel */
591 mml->mml_marker.cm_flags = flags;
592 mml->mml_marker.cm_canceltime = flags ? cfs_time_current_sec() : 0;
593 mml->mml_modified = 0;
594 rc = llog_process(loghandle, mgs_modify_handler, (void *)mml, NULL);
595 if (!rc && !mml->mml_modified)
600 rc2 = llog_close(loghandle);
605 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
606 if (rc && rc != -ENODEV)
607 CERROR("modify %s/%s failed %d\n",
608 mti->mti_svname, comment, rc);
614 /******************** config log recording functions *********************/
616 static int record_lcfg(struct obd_device *obd, struct llog_handle *llh,
617 struct lustre_cfg *lcfg)
619 struct lvfs_run_ctxt saved;
620 struct llog_rec_hdr rec;
626 LASSERT(llh->lgh_ctxt);
628 buflen = lustre_cfg_len(lcfg->lcfg_bufcount,
630 rec.lrh_len = llog_data_len(buflen);
631 rec.lrh_type = OBD_CFG_REC;
632 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
633 /* idx = -1 means append */
634 rc = llog_write_rec(llh, &rec, NULL, 0, (void *)lcfg, -1);
635 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
637 CERROR("failed %d\n", rc);
641 static int record_base(struct obd_device *obd, struct llog_handle *llh,
642 char *cfgname, lnet_nid_t nid, int cmd,
643 char *s1, char *s2, char *s3, char *s4)
645 struct lustre_cfg_bufs bufs;
646 struct lustre_cfg *lcfg;
649 CDEBUG(D_MGS, "lcfg %s %#x %s %s %s %s\n", cfgname,
650 cmd, s1, s2, s3, s4);
652 lustre_cfg_bufs_reset(&bufs, cfgname);
654 lustre_cfg_bufs_set_string(&bufs, 1, s1);
656 lustre_cfg_bufs_set_string(&bufs, 2, s2);
658 lustre_cfg_bufs_set_string(&bufs, 3, s3);
660 lustre_cfg_bufs_set_string(&bufs, 4, s4);
662 lcfg = lustre_cfg_new(cmd, &bufs);
665 lcfg->lcfg_nid = nid;
667 rc = record_lcfg(obd, llh, lcfg);
669 lustre_cfg_free(lcfg);
672 CERROR("error %d: lcfg %s %#x %s %s %s %s\n", rc, cfgname,
673 cmd, s1, s2, s3, s4);
679 static inline int record_add_uuid(struct obd_device *obd,
680 struct llog_handle *llh,
681 uint64_t nid, char *uuid)
683 return record_base(obd,llh,NULL,nid,LCFG_ADD_UUID,uuid,0,0,0);
687 static inline int record_add_conn(struct obd_device *obd,
688 struct llog_handle *llh,
692 return record_base(obd,llh,devname,0,LCFG_ADD_CONN,uuid,0,0,0);
695 static inline int record_attach(struct obd_device *obd, struct llog_handle *llh,
696 char *devname, char *type, char *uuid)
698 return record_base(obd,llh,devname,0,LCFG_ATTACH,type,uuid,0,0);
701 static inline int record_setup(struct obd_device *obd, struct llog_handle *llh,
703 char *s1, char *s2, char *s3, char *s4)
705 return record_base(obd,llh,devname,0,LCFG_SETUP,s1,s2,s3,s4);
708 static int record_lov_setup(struct obd_device *obd, struct llog_handle *llh,
709 char *devname, struct lov_desc *desc)
711 struct lustre_cfg_bufs bufs;
712 struct lustre_cfg *lcfg;
715 lustre_cfg_bufs_reset(&bufs, devname);
716 lustre_cfg_bufs_set(&bufs, 1, desc, sizeof(*desc));
717 lcfg = lustre_cfg_new(LCFG_SETUP, &bufs);
720 rc = record_lcfg(obd, llh, lcfg);
722 lustre_cfg_free(lcfg);
726 static inline int record_lov_add(struct obd_device *obd,
727 struct llog_handle *llh,
728 char *lov_name, char *ost_uuid,
729 char *index, char *gen)
731 return record_base(obd,llh,lov_name,0,LCFG_LOV_ADD_OBD,
732 ost_uuid,index,gen,0);
735 static inline int record_mount_opt(struct obd_device *obd,
736 struct llog_handle *llh,
737 char *profile, char *lov_name,
740 return record_base(obd,llh,NULL,0,LCFG_MOUNTOPT,
741 profile,lov_name,mdc_name,0);
744 static int record_marker(struct obd_device *obd, struct llog_handle *llh,
745 struct fs_db *fsdb, __u32 flags,
746 char *tgtname, char *comment)
748 struct cfg_marker marker;
749 struct lustre_cfg_bufs bufs;
750 struct lustre_cfg *lcfg;
753 if (flags & CM_START)
755 marker.cm_step = fsdb->fsdb_gen;
756 marker.cm_flags = flags;
757 marker.cm_vers = LUSTRE_VERSION_CODE;
758 strncpy(marker.cm_tgtname, tgtname, sizeof(marker.cm_tgtname));
759 strncpy(marker.cm_comment, comment, sizeof(marker.cm_comment));
760 marker.cm_createtime = cfs_time_current_sec();
761 marker.cm_canceltime = 0;
762 lustre_cfg_bufs_reset(&bufs, NULL);
763 lustre_cfg_bufs_set(&bufs, 1, &marker, sizeof(marker));
764 lcfg = lustre_cfg_new(LCFG_MARKER, &bufs);
767 rc = record_lcfg(obd, llh, lcfg);
769 lustre_cfg_free(lcfg);
773 static int record_start_log(struct obd_device *obd,
774 struct llog_handle **llh, char *name)
776 static struct obd_uuid cfg_uuid = { .uuid = "config_uuid" };
777 struct lvfs_run_ctxt saved;
781 GOTO(out, rc = -EBUSY);
784 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
786 rc = llog_create(llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT),
789 llog_init_handle(*llh, LLOG_F_IS_PLAIN, &cfg_uuid);
793 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
797 CERROR("Can't start log %s: %d\n", name, rc);
802 static int record_end_log(struct obd_device *obd, struct llog_handle **llh)
804 struct lvfs_run_ctxt saved;
807 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
809 rc = llog_close(*llh);
812 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
816 static int mgs_log_is_empty(struct obd_device *obd, char *name)
818 struct lvfs_run_ctxt saved;
819 struct llog_handle *llh;
822 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
823 rc = llog_create(llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT),
826 llog_init_handle(llh, LLOG_F_IS_PLAIN, NULL);
827 rc = llog_get_size(llh);
830 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
831 /* header is record 1 */
835 /******************** config "macros" *********************/
837 /* write an lcfg directly into a log (with markers) */
838 static int mgs_write_log_direct(struct obd_device *obd, struct fs_db *fsdb,
839 char *logname, struct lustre_cfg *lcfg,
840 char *devname, char *comment)
842 struct llog_handle *llh = NULL;
849 rc = record_start_log(obd, &llh, logname);
853 /* FIXME These should be a single journal transaction */
854 rc = record_marker(obd, llh, fsdb, CM_START, devname, comment);
856 rc = record_lcfg(obd, llh, lcfg);
858 rc = record_marker(obd, llh, fsdb, CM_END, devname, comment);
859 rc = record_end_log(obd, &llh);
864 /* write the lcfg in all logs for the given fs */
865 int mgs_write_log_direct_all(struct obd_device *obd, struct fs_db *fsdb,
866 struct mgs_target_info *mti,
867 struct lustre_cfg *lcfg,
868 char *devname, char *comment)
870 struct mgs_obd *mgs = &obd->u.mgs;
871 struct list_head dentry_list;
872 struct l_linux_dirent *dirent, *n;
873 char *fsname = mti->mti_fsname;
875 int rc = 0, len = strlen(fsname);
878 /* We need to set params for any future logs
879 as well. FIXME Append this file to every new log.
880 Actually, we should store as params (text), not llogs. Or
882 name_create(&logname, fsname, "-params");
883 if (mgs_log_is_empty(obd, logname)) {
884 struct llog_handle *llh = NULL;
885 rc = record_start_log(obd, &llh, logname);
886 record_end_log(obd, &llh);
888 name_destroy(&logname);
892 /* Find all the logs in the CONFIGS directory */
893 rc = class_dentry_readdir(obd, mgs->mgs_configs_dir,
894 mgs->mgs_vfsmnt, &dentry_list);
896 CERROR("Can't read %s dir\n", MOUNT_CONFIGS_DIR);
900 /* Could use fsdb index maps instead of directory listing */
901 list_for_each_entry_safe(dirent, n, &dentry_list, lld_list) {
902 list_del(&dirent->lld_list);
903 if (strncmp(fsname, dirent->lld_name, len) == 0) {
904 CDEBUG(D_MGS, "Changing log %s\n", dirent->lld_name);
905 /* Erase any old settings of this same parameter */
906 mgs_modify(obd, fsdb, mti, dirent->lld_name, devname,
908 /* Write the new one */
909 rc = mgs_write_log_direct(obd, fsdb, dirent->lld_name,
910 lcfg, devname, comment);
912 CERROR("err %d writing log %s\n", rc,
915 OBD_FREE(dirent, sizeof(*dirent));
921 /* lov is the first thing in the mdt and client logs */
922 static int mgs_write_log_lov(struct obd_device *obd, struct fs_db *fsdb,
923 struct mgs_target_info *mti,
924 char *logname, char *lovname)
926 struct llog_handle *llh = NULL;
927 struct lov_desc *lovdesc;
932 CDEBUG(D_MGS, "Writing log %s\n", logname);
935 #01 L attach 0:lov_mdsA 1:lov 2:71ccb_lov_mdsA_19f961a9e1
936 #02 L lov_setup 0:lov_mdsA 1:(struct lov_desc)
937 uuid=lov1_UUID, stripe count=1, size=1048576, offset=0, pattern=0
940 /* FIXME just make lov_setup accept empty desc (put uuid in buf 2) */
941 OBD_ALLOC(lovdesc, sizeof(*lovdesc));
944 lovdesc->ld_magic = LOV_DESC_MAGIC;
945 lovdesc->ld_tgt_count = 0;
946 /* Defaults. Can be changed later by lcfg config_param */
947 lovdesc->ld_default_stripe_count = 1;
948 lovdesc->ld_pattern = LOV_PATTERN_RAID0;
949 lovdesc->ld_default_stripe_size = 1024 * 1024;
950 lovdesc->ld_default_stripe_offset = 0;
951 lovdesc->ld_qos_maxage = QOS_DEFAULT_MAXAGE;
952 sprintf((char*)lovdesc->ld_uuid.uuid, "%s_UUID", lovname);
953 /* can these be the same? */
954 uuid = (char *)lovdesc->ld_uuid.uuid;
956 /* This should always be the first entry in a log.
957 rc = mgs_clear_log(obd, logname); */
958 rc = record_start_log(obd, &llh, logname);
961 /* FIXME these should be a single journal transaction */
962 rc = record_marker(obd, llh, fsdb, CM_START, lovname, "lov setup");
963 rc = record_attach(obd, llh, lovname, "lov", uuid);
964 rc = record_lov_setup(obd, llh, lovname, lovdesc);
965 rc = record_marker(obd, llh, fsdb, CM_END, lovname, "lov setup");
966 rc = record_end_log(obd, &llh);
968 OBD_FREE(lovdesc, sizeof(*lovdesc));
972 /* add failnids to open log */
973 static int mgs_write_log_failnids(struct obd_device *obd,
974 struct mgs_target_info *mti,
975 struct llog_handle *llh,
978 char *failnodeuuid = NULL;
979 char *ptr = mti->mti_params;
984 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) nal=90 0: 1:uml1_UUID
985 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
986 #05 L setup 0:OSC_uml1_ost1_mdsA 1:ost1_UUID 2:uml1_UUID
987 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) nal=90 0: 1:uml2_UUID
988 #0x L add_uuid nid=2@elan(0x1000000000002) nal=90 0: 1:uml2_UUID
989 #07 L add_conn 0:OSC_uml1_ost1_mdsA 1:uml2_UUID
992 /* Pull failnid info out of params string */
993 while (class_find_param(ptr, PARAM_FAILNODE, &ptr) == 0) {
994 while (class_parse_nid(ptr, &nid, &ptr) == 0) {
995 if (failnodeuuid == NULL) {
996 /* We don't know the failover node name,
997 so just use the first nid as the uuid */
998 rc = name_create(&failnodeuuid,
999 libcfs_nid2str(nid), "");
1003 CDEBUG(D_MGS, "add nid %s for failover uuid %s, "
1004 "client %s\n", libcfs_nid2str(nid),
1005 failnodeuuid, cliname);
1006 rc = record_add_uuid(obd, llh, nid, failnodeuuid);
1009 rc = record_add_conn(obd, llh, cliname, failnodeuuid);
1010 name_destroy(&failnodeuuid);
1011 failnodeuuid = NULL;
1018 static int mgs_write_log_mdt(struct obd_device *obd, struct fs_db *fsdb,
1019 struct mgs_target_info *mti)
1021 struct llog_handle *llh = NULL;
1022 char *cliname, *mdcname, *nodeuuid, *mdcuuid;
1023 int rc, i, first_log = 0;
1026 CDEBUG(D_MGS, "writing new mdt %s\n", mti->mti_svname);
1029 if (mti->mti_flags & LDD_F_UPGRADE14) {
1030 /* We're starting with an old uuid. Assume old name for lov
1031 as well since the lov entry already exists in the log. */
1032 CDEBUG(D_MGS, "old mds uuid %s\n", mti->mti_uuid);
1033 if (strncmp(mti->mti_uuid, fsdb->fsdb_mdtlov + 4,
1034 strlen(fsdb->fsdb_mdtlov) - 4) != 0) {
1035 CERROR("old mds uuid %s doesn't match log %s (%s)\n",
1036 mti->mti_uuid, fsdb->fsdb_mdtlov,
1037 fsdb->fsdb_mdtlov + 4);
1041 /* end COMPAT_146 */
1043 if (mti->mti_uuid[0] == '\0') {
1044 /* Make up our own uuid */
1045 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
1046 "%s_UUID", mti->mti_svname);
1049 /* Append mdt info to mdt log */
1050 if (mgs_log_is_empty(obd, mti->mti_svname)) {
1051 /* This is the first time for all logs for this fs,
1052 since any ost should have already started the mdt log. */
1054 rc = mgs_write_log_lov(obd, fsdb, mti, mti->mti_svname,
1057 /* else there's already some ost entries in the mdt log. */
1059 /* We added the lov, maybe some osc's, now for the mdt.
1060 We might add more ost's after this. Note that during the parsing
1061 of this log, this is when the mdt will start. (This was not
1062 formerly part of the old mds log, it was directly executed by
1065 mount_option 0: 1:mdsA 2:lov_mdsA
1066 attach mds mdsA mdsA_UUID
1067 setup /dev/loop2 ldiskfs mdsA errors=remount-ro,user_xattr
1069 rc = record_start_log(obd, &llh, mti->mti_svname);
1072 /* FIXME this whole fn should be a single journal transaction */
1073 rc = record_marker(obd, llh, fsdb, CM_START, mti->mti_svname,"add mdt");
1074 rc = record_mount_opt(obd, llh, mti->mti_svname, fsdb->fsdb_mdtlov, 0);
1075 rc = record_attach(obd, llh, mti->mti_svname, LUSTRE_MDS_NAME,
1077 rc = record_setup(obd, llh, mti->mti_svname,
1078 "dev"/*ignored*/, "type"/*ignored*/,
1079 mti->mti_svname, 0/*options*/);
1080 rc = record_marker(obd, llh, fsdb, CM_END, mti->mti_svname, "add mdt");
1081 rc = record_end_log(obd, &llh);
1083 /* Append the mdt info to the client log */
1084 name_create(&cliname, mti->mti_fsname, "-client");
1086 /* Start client log */
1087 rc = mgs_write_log_lov(obd, fsdb, mti, cliname,
1091 name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]),/*"_UUID"*/"");
1092 name_create(&mdcname, mti->mti_svname, "-mdc");
1093 name_create(&mdcuuid, mdcname, "_UUID");
1095 #09 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
1096 #10 L attach 0:MDC_uml1_mdsA_MNT_client 1:mdc 2:1d834_MNT_client_03f
1097 #11 L setup 0:MDC_uml1_mdsA_MNT_client 1:mdsA_UUID 2:uml1_UUID
1098 #12 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
1099 #13 L add_conn 0:MDC_uml1_mdsA_MNT_client 1:uml2_UUID
1100 #14 L mount_option 0: 1:client 2:lov1 3:MDC_uml1_mdsA_MNT_client
1102 rc = record_start_log(obd, &llh, cliname);
1105 rc = record_marker(obd, llh, fsdb, CM_START, mti->mti_svname,"add mdc");
1107 if (mti->mti_flags & LDD_F_UPGRADE14) {
1108 /* Old client log already has MDC entry, but needs mount opt
1109 for new client name (lustre-client) */
1110 /* FIXME Old MDT log already has an old mount opt
1111 which we should remove (currently handled by
1112 class_del_profiles()) */
1113 rc = record_mount_opt(obd, llh, cliname, fsdb->fsdb_clilov,
1115 /* end COMPAT_146 */
1117 for (i = 0; i < mti->mti_nid_count; i++) {
1118 CDEBUG(D_MGS, "add nid %s\n",
1119 libcfs_nid2str(mti->mti_nids[i]));
1120 rc = record_add_uuid(obd, llh, mti->mti_nids[i],
1123 rc = record_attach(obd, llh, mdcname, LUSTRE_MDC_NAME, mdcuuid);
1124 rc = record_setup(obd, llh, mdcname, mti->mti_uuid,nodeuuid,
1126 rc = mgs_write_log_failnids(obd, mti, llh, mdcname);
1127 rc = record_mount_opt(obd, llh, cliname, fsdb->fsdb_clilov,
1130 rc = record_marker(obd, llh, fsdb, CM_END, mti->mti_svname, "add mdc");
1131 rc = record_end_log(obd, &llh);
1133 name_destroy(&mdcuuid);
1134 name_destroy(&mdcname);
1135 name_destroy(&nodeuuid);
1136 name_destroy(&cliname);
1140 /* Add the ost info to the client/mdt lov */
1141 static int mgs_write_log_osc(struct obd_device *obd, struct fs_db *fsdb,
1142 struct mgs_target_info *mti,
1143 char *logname, char *lovname, int flags)
1145 struct llog_handle *llh = NULL;
1146 char *nodeuuid, *oscname, *oscuuid, *lovuuid;
1150 if (mgs_log_is_empty(obd, logname)) {
1151 /* The first item in the log must be the lov, so we have
1152 somewhere to add our osc. */
1153 rc = mgs_write_log_lov(obd, fsdb, mti, logname, lovname);
1156 CDEBUG(D_MGS, "adding osc for %s to log %s\n",
1157 mti->mti_svname, logname);
1159 name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
1160 name_create(&oscname, mti->mti_svname, "-osc");
1161 name_create(&oscuuid, oscname, "_UUID");
1162 name_create(&lovuuid, lovname, "_UUID");
1165 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
1167 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
1168 #04 L attach 0:OSC_uml1_ost1_MNT_client 1:osc 2:89070_lov1_a41dff51a
1169 #05 L setup 0:OSC_uml1_ost1_MNT_client 1:ost1_UUID 2:uml1_UUID
1171 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
1172 #07 L add_conn 0:OSC_uml1_ost1_MNT_client 1:uml2_UUID
1173 #08 L lov_modify_tgts add 0:lov1 1:ost1_UUID 2(index):0 3(gen):1
1175 rc = record_start_log(obd, &llh, logname);
1178 /* FIXME these should be a single journal transaction */
1179 rc = record_marker(obd, llh, fsdb, CM_START | flags, mti->mti_svname,
1181 for (i = 0; i < mti->mti_nid_count; i++) {
1182 CDEBUG(D_MGS, "add nid %s\n", libcfs_nid2str(mti->mti_nids[i]));
1183 rc = record_add_uuid(obd, llh, mti->mti_nids[i], nodeuuid);
1185 rc = record_attach(obd, llh, oscname, LUSTRE_OSC_NAME, lovuuid);
1186 rc = record_setup(obd, llh, oscname, mti->mti_uuid, nodeuuid, 0, 0);
1187 rc = mgs_write_log_failnids(obd, mti, llh, oscname);
1188 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
1189 rc = record_lov_add(obd, llh, lovname, mti->mti_uuid, index, "1");
1190 rc = record_marker(obd, llh, fsdb, CM_END | flags, mti->mti_svname,
1192 rc = record_end_log(obd, &llh);
1194 name_destroy(&lovuuid);
1195 name_destroy(&oscuuid);
1196 name_destroy(&oscname);
1197 name_destroy(&nodeuuid);
1201 static int mgs_write_log_ost(struct obd_device *obd, struct fs_db *fsdb,
1202 struct mgs_target_info *mti)
1204 struct llog_handle *llh = NULL;
1206 char *ptr = mti->mti_params;
1207 int rc, flags = 0, failout = 0;
1210 CDEBUG(D_MGS, "writing new ost %s\n", mti->mti_svname);
1212 /* The ost startup log */
1214 /* If the ost log already exists, that means that someone reformatted
1215 the ost and it called target_add again. */
1216 if (!mgs_log_is_empty(obd, mti->mti_svname)) {
1217 LCONSOLE_ERROR("The config log for %s already exists, yet the "
1218 "server claims it never registered. It may have"
1219 " been reformatted, or the index changed. "
1220 "writeconf the MDT to regenerate all logs.\n",
1225 attach obdfilter ost1 ost1_UUID
1226 setup /dev/loop2 ldiskfs f|n errors=remount-ro,user_xattr
1228 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
1229 failout = (strncmp(ptr, "failout", 7) == 0);
1230 rc = record_start_log(obd, &llh, mti->mti_svname);
1233 /* FIXME these should be a single journal transaction */
1234 rc = record_marker(obd, llh, fsdb, CM_START, mti->mti_svname,"add ost");
1235 if (*mti->mti_uuid == '\0')
1236 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
1237 "%s_UUID", mti->mti_svname);
1238 rc = record_attach(obd, llh, mti->mti_svname,
1239 "obdfilter"/*LUSTRE_OST_NAME*/, mti->mti_uuid);
1240 rc = record_setup(obd, llh, mti->mti_svname,
1241 "dev"/*ignored*/, "type"/*ignored*/,
1242 failout ? "n" : "f", 0/*options*/);
1243 rc = record_marker(obd, llh, fsdb, CM_END, mti->mti_svname, "add ost");
1244 rc = record_end_log(obd, &llh);
1246 /* We also have to update the other logs where this osc is part of
1249 if (mti->mti_flags & LDD_F_UPGRADE14) {
1250 /* If we're upgrading, the old mdt log already has our
1251 entry. Let's do a fake one for fun. */
1252 flags = CM_SKIP | CM_UPGRADE146;
1253 } else if ((mti->mti_flags & LDD_F_UPDATE) != LDD_F_UPDATE) {
1254 /* If the update flag isn't set, don't really update
1257 LCONSOLE_WARN("Client log for %s was not updated; writeconf "
1258 "the MDT first to regenerate it.\n",
1262 /* Append ost info to mdt log */
1263 /* FIXME add to all MDT logs for CMD */
1264 /* FIXME need real MDT name, but MDT may not have registered yet! */
1265 name_create(&logname, mti->mti_fsname, "-MDT0000");
1266 rc = mgs_write_log_osc(obd, fsdb, mti, logname, fsdb->fsdb_mdtlov,
1268 name_destroy(&logname);
1270 /* Append ost info to the client log */
1271 name_create(&logname, mti->mti_fsname, "-client");
1272 rc = mgs_write_log_osc(obd, fsdb, mti, logname, fsdb->fsdb_clilov,
1274 name_destroy(&logname);
1279 /* Add additional failnids to an existing log.
1280 The mdc/osc must have been added to logs first */
1281 /* tcp nids must be in dotted-quad ascii -
1282 we can't resolve hostnames from the kernel. */
1283 static int mgs_write_log_add_failnid(struct obd_device *obd, struct fs_db *fsdb,
1284 struct mgs_target_info *mti)
1286 char *logname, *cliname;
1287 struct llog_handle *llh = NULL;
1291 /* Verify that we know about this target */
1292 if (mgs_log_is_empty(obd, mti->mti_svname)) {
1293 LCONSOLE_ERROR("The target %s has not registered yet. "
1294 "It must be started before failnids can "
1295 "be added.\n", mti->mti_svname);
1299 /* Create mdc/osc client name (e.g. lustre-OST0001-osc) */
1300 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
1301 name_create(&cliname, mti->mti_svname, "-mdc");
1302 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
1303 name_create(&cliname, mti->mti_svname, "-osc");
1308 /* Add failover nids to client log */
1309 name_create(&logname, mti->mti_fsname, "-client");
1310 rc = record_start_log(obd, &llh, logname);
1312 /* FIXME this fn should be a single journal transaction */
1313 rc = record_marker(obd, llh, fsdb, CM_START, mti->mti_svname,
1315 rc = mgs_write_log_failnids(obd, mti, llh, cliname);
1316 rc = record_marker(obd, llh, fsdb, CM_END, mti->mti_svname,
1318 rc = record_end_log(obd, &llh);
1320 name_destroy(&logname);
1322 if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
1323 /* Add OST failover nids to the MDT log as well */
1324 name_create(&logname, mti->mti_fsname, "-MDT0000");
1325 rc = record_start_log(obd, &llh, logname);
1327 rc = record_marker(obd, llh, fsdb, CM_START,
1328 mti->mti_svname, "add failnid");
1329 rc = mgs_write_log_failnids(obd, mti, llh, cliname);
1330 rc = record_marker(obd, llh, fsdb, CM_END,
1331 mti->mti_svname, "add failnid");
1332 rc = record_end_log(obd, &llh);
1334 name_destroy(&logname);
1337 name_destroy(&cliname);
1341 static int mgs_wlp_lcfg(struct obd_device *obd, struct fs_db *fsdb,
1342 struct mgs_target_info *mti,
1343 char *logname, struct lustre_cfg_bufs *bufs,
1344 char *tgtname, char *ptr)
1346 char comment[MTI_NAME_MAXLEN];
1348 struct lustre_cfg *lcfg;
1351 /* Erase any old settings of this same parameter */
1352 memcpy(comment, ptr, MTI_NAME_MAXLEN);
1353 comment[MTI_NAME_MAXLEN - 1] = 0;
1354 /* But don't try to match the value. */
1355 if ((tmp = strchr(comment, '=')))
1357 rc = mgs_modify(obd, fsdb, mti, logname, tgtname, comment, CM_SKIP);
1358 LCONSOLE_INFO("%sing parameter %s.%s in log %s\n", rc ?
1359 "Sett" : "Modify", tgtname, comment, logname);
1361 lustre_cfg_bufs_reset(bufs, tgtname);
1362 lustre_cfg_bufs_set_string(bufs, 1, ptr);
1363 lcfg = lustre_cfg_new(LCFG_PARAM, bufs);
1366 rc = mgs_write_log_direct(obd, fsdb, logname, lcfg, tgtname, comment);
1367 lustre_cfg_free(lcfg);
1371 static int mgs_write_log_params(struct obd_device *obd, struct fs_db *fsdb,
1372 struct mgs_target_info *mti)
1374 struct lustre_cfg_bufs bufs;
1375 struct lustre_cfg *lcfg;
1377 char *ptr = mti->mti_params;
1382 if (!mti->mti_params)
1385 /* FIXME we should cancel out old settings of the same parameters,
1386 and skip settings that are the same as old values */
1388 /* For various parameter settings, we have to figure out which logs
1389 care about them (e.g. both mdt and client for lov settings) */
1395 endptr = strchr(ptr, ' ');
1398 CDEBUG(D_MGS, "next param '%s'\n", ptr);
1400 /* The params are stored in MOUNT_DATA_FILE and modified
1401 via tunefs.lustre */
1403 /* Processed in lustre_start_mgc */
1404 if (class_match_param(ptr, PARAM_MGSNODE, NULL) == 0)
1407 /* Processed in mgs_write_log_ost */
1408 if (class_match_param(ptr, PARAM_FAILMODE, NULL) == 0)
1411 if (class_match_param(ptr, PARAM_FAILNODE, NULL) == 0) {
1412 /* Add a failover nidlist */
1414 /* We already processed failovers params for new
1415 targets in mgs_write_log_target */
1416 if (mti->mti_flags & LDD_F_PARAM_FNID) {
1417 CDEBUG(D_MGS, "Adding failnode\n");
1418 rc = mgs_write_log_add_failnid(obd, fsdb, mti);
1423 if (class_match_param(ptr, PARAM_SYS_TIMEOUT, &tmp) == 0) {
1424 /* Change obd timeout */
1426 timeout = simple_strtoul(tmp, NULL, 0);
1428 CDEBUG(D_MGS, "obd timeout %d\n", timeout);
1430 lustre_cfg_bufs_reset(&bufs, NULL);
1431 lcfg = lustre_cfg_new(LCFG_SET_TIMEOUT, &bufs);
1432 lcfg->lcfg_num = timeout;
1433 /* modify all servers and clients */
1434 rc = mgs_write_log_direct_all(obd, fsdb, mti, lcfg,
1437 lustre_cfg_free(lcfg);
1441 if (class_match_param(ptr, PARAM_OSC""PARAM_ACTIVE, &tmp) == 0){
1442 /* active=0 means off, anything else means on */
1443 int flag = (*tmp == '0') ? CM_EXCLUDE : 0;
1444 if (!(mti->mti_flags & LDD_F_SV_TYPE_OST)) {
1445 LCONSOLE_ERROR("%s: Only OSCs can be (de)activ"
1446 "ated.\n", mti->mti_svname);
1450 LCONSOLE_WARN("Permanently %sactivating %s\n",
1451 flag ? "de": "re", mti->mti_svname);
1453 name_create(&logname, mti->mti_fsname, "-client");
1454 rc = mgs_modify(obd, fsdb, mti, logname,
1455 mti->mti_svname, "add osc", flag);
1456 name_destroy(&logname);
1460 /* FIXME add to all MDT logs for CMD */
1461 name_create(&logname, mti->mti_fsname, "-MDT0000");
1462 rc = mgs_modify(obd, fsdb, mti, logname,
1463 mti->mti_svname, "add osc", flag);
1464 name_destroy(&logname);
1467 LCONSOLE_ERROR("Couldn't find %s in log (%d). "
1468 "No permanent changes were made to the "
1469 "config log.\n", mti->mti_svname, rc);
1470 if (fsdb->fsdb_flags & FSDB_OLDLOG14)
1471 LCONSOLE_ERROR("This may be because the"
1472 " log is in the old 1.4 style. Consider"
1473 " --writeconf to update the logs.\n");
1476 /* Fall through to osc proc for deactivating
1477 live OSC on running MDT / clients. */
1480 /* Below here, let obd's XXX_process_config methods handle it */
1482 /* All lov. in proc */
1483 if (class_match_param(ptr, PARAM_LOV, NULL) == 0) {
1484 CDEBUG(D_MGS, "lov param %s\n", ptr);
1485 if (!(mti->mti_flags & LDD_F_SV_TYPE_MDT)) {
1486 LCONSOLE_ERROR("LOV params must be set on the "
1487 "MDT, not %s. Ignoring.\n",
1494 if (mgs_log_is_empty(obd, mti->mti_svname)) {
1498 rc = mgs_wlp_lcfg(obd, fsdb, mti, mti->mti_svname,
1499 &bufs, fsdb->fsdb_mdtlov, ptr);
1504 name_create(&logname, mti->mti_fsname, "-client");
1505 rc = mgs_wlp_lcfg(obd, fsdb, mti, logname, &bufs,
1506 fsdb->fsdb_clilov, ptr);
1507 name_destroy(&logname);
1511 /* All osc., mdc., llite. params in proc */
1512 if ((class_match_param(ptr, PARAM_OSC, NULL) == 0) ||
1513 (class_match_param(ptr, PARAM_MDC, NULL) == 0) ||
1514 (class_match_param(ptr, PARAM_LLITE, NULL) == 0)) {
1516 if (memcmp(ptr, PARAM_LLITE, strlen(PARAM_LLITE)) == 0) {
1517 name_create(&cname, mti->mti_fsname, "-client");
1518 /* Add the client type to match the obdname
1519 in class_config_llog_handler */
1520 } else if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
1521 name_create(&cname, mti->mti_svname, "-mdc");
1522 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
1523 name_create(&cname, mti->mti_svname, "-osc");
1529 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
1532 name_create(&logname, mti->mti_fsname, "-client");
1533 rc = mgs_wlp_lcfg(obd, fsdb, mti, logname, &bufs,
1535 name_destroy(&logname);
1537 /* osc params affect the MDT as well */
1538 if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
1539 /* FIXME add to all MDT logs for CMD */
1540 name_create(&logname, mti->mti_fsname,
1542 if (!mgs_log_is_empty(obd, logname))
1543 rc = mgs_wlp_lcfg(obd, fsdb, mti,
1546 name_destroy(&logname);
1548 name_destroy(&cname);
1552 /* All mdt., ost. params in proc */
1553 if ((class_match_param(ptr, PARAM_MDT, NULL) == 0) ||
1554 (class_match_param(ptr, PARAM_OST, NULL) == 0)) {
1555 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
1556 if (mgs_log_is_empty(obd, mti->mti_svname)) {
1560 rc = mgs_wlp_lcfg(obd, fsdb, mti, mti->mti_svname,
1561 &bufs, mti->mti_svname, ptr);
1565 LCONSOLE_WARN("Ignoring unrecognized param '%s'\n", ptr);
1569 CERROR("err %d on param '%s\n", rc, ptr);
1584 int mgs_check_failnid(struct obd_device *obd, struct mgs_target_info *mti)
1586 /* Not implementing automatic failover nid addition at this time. */
1593 rc = mgs_find_or_make_fsdb(obd, fsname, &fsdb);
1597 if (mgs_log_is_empty(obd, mti->mti_svname))
1598 /* should never happen */
1601 CDEBUG(D_MGS, "Checking for new failnids for %s\n", mti->mti_svname);
1603 /* FIXME We can just check mti->params to see if we're already in
1604 the failover list. Modify mti->params for rewriting back at
1605 server_register_target(). */
1607 down(&fsdb->fsdb_sem);
1608 rc = mgs_write_log_add_failnid(obd, fsdb, mti);
1609 up(&fsdb->fsdb_sem);
1615 int mgs_write_log_target(struct obd_device *obd,
1616 struct mgs_target_info *mti)
1622 /* set/check the new target index */
1623 rc = mgs_set_index(obd, mti);
1625 CERROR("Can't get index (%d)\n", rc);
1629 if (mti->mti_flags & LDD_F_UPGRADE14) {
1630 if (rc == EALREADY) {
1631 LCONSOLE_INFO("Found index %d for %s 1.4 log, "
1632 "upgrading\n", mti->mti_stripe_index,
1635 LCONSOLE_ERROR("Failed to find %s in the old client "
1636 "log. Apparently it is not part of this "
1637 "filesystem, or the old log is wrong.\n"
1638 "Use 'writeconf' on the MDT to force log"
1639 " regeneration.\n", mti->mti_svname);
1640 /* Not in client log? Upgrade anyhow...*/
1641 /* Argument against upgrading: reformat MDT,
1642 upgrade OST, then OST will start but will be SKIPped
1643 in client logs. Maybe error now is better. */
1644 /* RETURN(-EINVAL); */
1646 /* end COMPAT_146 */
1648 if (rc == EALREADY) {
1649 /* This might be a params update, or a
1650 local writeconf. (For "full" writeconf, the client
1651 log won't have an entry for this target, so we
1653 LCONSOLE_WARN("Found index %d for %s, updating log\n",
1654 mti->mti_stripe_index, mti->mti_svname);
1655 /* We would like to mark old log sections as invalid
1656 and add new log sections in the client and mdt logs.
1657 But if we add new sections, then live clients will
1658 get repeat setup instructions for already running
1659 osc's. So don't update the client/mdt logs. */
1660 mti->mti_flags &= ~LDD_F_UPDATE;
1664 rc = mgs_find_or_make_fsdb(obd, mti->mti_fsname, &fsdb);
1666 CERROR("Can't get db for %s\n", mti->mti_fsname);
1670 down(&fsdb->fsdb_sem);
1672 if (mti->mti_flags &
1673 (LDD_F_VIRGIN | LDD_F_UPGRADE14 | LDD_F_WRITECONF)) {
1674 /* Generate a log from scratch */
1675 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
1676 rc = mgs_write_log_mdt(obd, fsdb, mti);
1677 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
1678 rc = mgs_write_log_ost(obd, fsdb, mti);
1680 CERROR("Unknown target type %#x, can't create log for "
1681 "%s\n", mti->mti_flags, mti->mti_svname);
1684 CERROR("Can't write logs for %s (%d)\n",
1685 mti->mti_svname, rc);
1689 /* Just update the params from tunefs in mgs_write_log_params */
1690 CDEBUG(D_MGS, "Update params for %s\n", mti->mti_svname);
1691 mti->mti_flags |= LDD_F_PARAM_FNID;
1694 rc = mgs_write_log_params(obd, fsdb, mti);
1697 up(&fsdb->fsdb_sem);
1702 /* upgrade pre-mountconf logs to mountconf at first connect */
1703 int mgs_upgrade_sv_14(struct obd_device *obd, struct mgs_target_info *mti)
1709 /* Create ost log normally, as servers register. Servers
1710 register with their old uuids (from last_rcvd), so old
1711 (MDT and client) logs should work.
1712 - new MDT won't know about old OSTs, only the ones that have
1713 registered, so we need the old MDT log to get the LOV right
1714 in order for old clients to work.
1715 - Old clients connect to the MDT, not the MGS, for their logs, and
1716 will therefore receive the old client log from the MDT /LOGS dir.
1717 - Old clients can continue to use and connect to old or new OSTs
1718 - New clients will contact the MGS for their log
1721 LCONSOLE_INFO("upgrading server %s from pre-1.6\n", mti->mti_svname);
1722 server_mti_print("upgrade", mti);
1724 rc = mgs_find_or_make_fsdb(obd, mti->mti_fsname, &fsdb);
1728 if (fsdb->fsdb_flags & FSDB_LOG_EMPTY) {
1729 LCONSOLE_ERROR("The old client log %s-client is missing. Was "
1730 "tunefs.lustre successful?\n",
1735 if (fsdb->fsdb_gen == 0) {
1736 /* There were no markers in the client log, meaning we have
1737 not updated the logs for this fs */
1738 CDEBUG(D_MGS, "found old, unupdated client log\n");
1741 if ((mti->mti_flags & LDD_F_SV_TYPE_MDT) &&
1742 mgs_log_is_empty(obd, mti->mti_svname)) {
1743 LCONSOLE_ERROR("The old MDT log %s is missing. Was "
1744 "tunefs.lustre successful?\n",
1749 rc = mgs_write_log_target(obd, mti);
1752 /* end COMPAT_146 */
1754 int mgs_erase_log(struct obd_device *obd, char *name)
1756 struct lvfs_run_ctxt saved;
1757 struct llog_handle *llh;
1760 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
1761 rc = llog_create(llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT),
1764 llog_init_handle(llh, LLOG_F_IS_PLAIN, NULL);
1765 rc = llog_destroy(llh);
1766 llog_free_handle(llh);
1768 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
1771 CERROR("failed to clear log %s: %d\n", name, rc);
1776 /* erase all logs for the given fs */
1777 int mgs_erase_logs(struct obd_device *obd, char *fsname)
1779 struct mgs_obd *mgs = &obd->u.mgs;
1780 static struct fs_db *fsdb;
1781 struct list_head dentry_list;
1782 struct l_linux_dirent *dirent, *n;
1783 int rc, len = strlen(fsname);
1786 /* Find all the logs in the CONFIGS directory */
1787 rc = class_dentry_readdir(obd, mgs->mgs_configs_dir,
1788 mgs->mgs_vfsmnt, &dentry_list);
1790 CERROR("Can't read %s dir\n", MOUNT_CONFIGS_DIR);
1794 down(&mgs->mgs_sem);
1796 /* Delete the fs db */
1797 fsdb = mgs_find_fsdb(obd, fsname);
1799 mgs_free_fsdb(obd, fsdb);
1801 list_for_each_entry_safe(dirent, n, &dentry_list, lld_list) {
1802 list_del(&dirent->lld_list);
1803 if (strncmp(fsname, dirent->lld_name, len) == 0) {
1804 CDEBUG(D_MGS, "Removing log %s\n", dirent->lld_name);
1805 mgs_erase_log(obd, dirent->lld_name);
1807 OBD_FREE(dirent, sizeof(*dirent));
1815 /* from llog_swab */
1816 static void print_lustre_cfg(struct lustre_cfg *lcfg)
1821 CDEBUG(D_MGS, "lustre_cfg: %p\n", lcfg);
1822 CDEBUG(D_MGS, "\tlcfg->lcfg_version: %#x\n", lcfg->lcfg_version);
1824 CDEBUG(D_MGS, "\tlcfg->lcfg_command: %#x\n", lcfg->lcfg_command);
1825 CDEBUG(D_MGS, "\tlcfg->lcfg_num: %#x\n", lcfg->lcfg_num);
1826 CDEBUG(D_MGS, "\tlcfg->lcfg_flags: %#x\n", lcfg->lcfg_flags);
1827 CDEBUG(D_MGS, "\tlcfg->lcfg_nid: %s\n", libcfs_nid2str(lcfg->lcfg_nid));
1829 CDEBUG(D_MGS, "\tlcfg->lcfg_bufcount: %d\n", lcfg->lcfg_bufcount);
1830 if (lcfg->lcfg_bufcount < LUSTRE_CFG_MAX_BUFCOUNT)
1831 for (i = 0; i < lcfg->lcfg_bufcount; i++) {
1832 CDEBUG(D_MGS, "\tlcfg->lcfg_buflens[%d]: %d %s\n",
1833 i, lcfg->lcfg_buflens[i],
1834 lustre_cfg_string(lcfg, i));
1839 /* Set a permanent (config log) param for a target or fs */
1840 int mgs_setparam(struct obd_device *obd, struct lustre_cfg *lcfg, char *fsname)
1843 struct mgs_target_info *mti;
1844 char *devname, *param;
1849 print_lustre_cfg(lcfg);
1851 /* lustre, lustre-mdtlov, lustre-client, lustre-MDT0000 */
1852 devname = lustre_cfg_string(lcfg, 0);
1853 param = lustre_cfg_string(lcfg, 1);
1855 /* Assume device name embedded in param:
1856 lustre-OST0000.osc.max_dirty_mb=32 */
1857 ptr = strchr(param, '.');
1865 LCONSOLE_ERROR("No target specified: %s\n", param);
1869 /* Extract fsname */
1870 ptr = strchr(devname, '-');
1871 memset(fsname, 0, MTI_NAME_MAXLEN);
1873 /* assume devname is the fsname */
1874 strncpy(fsname, devname, MTI_NAME_MAXLEN);
1876 strncpy(fsname, devname, ptr - devname);
1878 fsname[MTI_NAME_MAXLEN] = 0;
1879 CDEBUG(D_MGS, "setparam on fs %s device %s\n", fsname, devname);
1881 rc = mgs_find_or_make_fsdb(obd, fsname, &fsdb);
1884 if (fsdb->fsdb_flags & FSDB_LOG_EMPTY) {
1885 CERROR("No filesystem targets for %s\n", fsname);
1889 /* Create a fake mti to hold everything */
1892 GOTO(out, rc = -ENOMEM);
1893 strncpy(mti->mti_fsname, fsname, MTI_NAME_MAXLEN);
1894 strncpy(mti->mti_svname, devname, MTI_NAME_MAXLEN);
1895 strncpy(mti->mti_params, param, sizeof(mti->mti_params));
1896 rc = server_name2index(mti->mti_svname, &mti->mti_stripe_index, &tmp);
1898 /* Not a valid server; may be only fsname */
1901 /* Strip -osc or -mdc suffix from svname */
1902 if (server_make_name(rc, mti->mti_stripe_index, mti->mti_fsname,
1904 GOTO(out, rc = -EINVAL);
1906 mti->mti_flags = rc | LDD_F_PARAM_FNID;
1908 down(&fsdb->fsdb_sem);
1909 rc = mgs_write_log_params(obd, fsdb, mti);
1910 up(&fsdb->fsdb_sem);
1919 /******************** unused *********************/
1920 static int mgs_backup_llog(struct obd_device *obd, char* fsname)
1922 struct file *filp, *bak_filp;
1923 struct lvfs_run_ctxt saved;
1924 char *logname, *buf;
1925 loff_t soff = 0 , doff = 0;
1926 int count = 4096, len;
1929 OBD_ALLOC(logname, PATH_MAX);
1930 if (logname == NULL)
1933 OBD_ALLOC(buf, count);
1935 GOTO(out , rc = -ENOMEM);
1937 len = snprintf(logname, PATH_MAX, "%s/%s.bak",
1938 MOUNT_CONFIGS_DIR, fsname);
1940 if (len >= PATH_MAX - 1) {
1941 GOTO(out, -ENAMETOOLONG);
1944 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
1946 bak_filp = l_filp_open(logname, O_RDWR|O_CREAT|O_TRUNC, 0660);
1947 if (IS_ERR(bak_filp)) {
1948 rc = PTR_ERR(bak_filp);
1949 CERROR("backup logfile open %s: %d\n", logname, rc);
1952 sprintf(logname, "%s/%s", MOUNT_CONFIGS_DIR, fsname);
1953 filp = l_filp_open(logname, O_RDONLY, 0);
1956 CERROR("logfile open %s: %d\n", logname, rc);
1960 while ((rc = lustre_fread(filp, buf, count, &soff)) > 0) {
1961 rc = lustre_fwrite(bak_filp, buf, count, &doff);
1965 filp_close(filp, 0);
1967 filp_close(bak_filp, 0);
1969 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
1972 OBD_FREE(buf, count);
1973 OBD_FREE(logname, PATH_MAX);