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 fsdb->fsdb_name[sizeof(fsdb->fsdb_name) - 1] = 0;
296 rc = name_create(&fsdb->fsdb_mdtlov, fsname, "-mdtlov");
299 rc = name_create(&fsdb->fsdb_clilov, fsname, "-clilov");
303 sema_init(&fsdb->fsdb_sem, 1);
304 list_add(&fsdb->fsdb_list, &mgs->mgs_fs_db_list);
305 lproc_mgs_add_live(obd, fsdb);
309 if (fsdb->fsdb_ost_index_map)
310 OBD_FREE(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
311 if (fsdb->fsdb_mdt_index_map)
312 OBD_FREE(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
313 name_destroy(&fsdb->fsdb_clilov);
314 name_destroy(&fsdb->fsdb_mdtlov);
319 static void mgs_free_fsdb(struct obd_device *obd, struct fs_db *fsdb)
321 /* wait for anyone with the sem */
322 down(&fsdb->fsdb_sem);
323 lproc_mgs_del_live(obd, fsdb);
324 list_del(&fsdb->fsdb_list);
325 OBD_FREE(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
326 OBD_FREE(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
327 name_destroy(&fsdb->fsdb_clilov);
328 name_destroy(&fsdb->fsdb_mdtlov);
329 name_destroy(&fsdb->fsdb_mdc);
333 int mgs_init_fsdb_list(struct obd_device *obd)
335 struct mgs_obd *mgs = &obd->u.mgs;
336 INIT_LIST_HEAD(&mgs->mgs_fs_db_list);
340 int mgs_cleanup_fsdb_list(struct obd_device *obd)
342 struct mgs_obd *mgs = &obd->u.mgs;
344 struct list_head *tmp, *tmp2;
346 list_for_each_safe(tmp, tmp2, &mgs->mgs_fs_db_list) {
347 fsdb = list_entry(tmp, struct fs_db, fsdb_list);
348 mgs_free_fsdb(obd, fsdb);
354 static int mgs_find_or_make_fsdb(struct obd_device *obd, char *name,
357 struct mgs_obd *mgs = &obd->u.mgs;
362 fsdb = mgs_find_fsdb(obd, name);
369 CDEBUG(D_MGS, "Creating new db\n");
370 fsdb = mgs_new_fsdb(obd, name);
375 /* populate the db from the client llog */
376 rc = mgs_get_fsdb_from_llog(obd, fsdb);
378 CERROR("Can't get db from client log %d\n", rc);
379 mgs_free_fsdb(obd, fsdb);
390 -1= empty client log */
391 int mgs_check_index(struct obd_device *obd, struct mgs_target_info *mti)
398 LASSERT(!(mti->mti_flags & LDD_F_NEED_INDEX));
400 rc = mgs_find_or_make_fsdb(obd, mti->mti_fsname, &fsdb);
402 CERROR("Can't get db for %s\n", mti->mti_fsname);
406 if (fsdb->fsdb_flags & FSDB_LOG_EMPTY)
409 if (mti->mti_flags & LDD_F_SV_TYPE_OST)
410 imap = fsdb->fsdb_ost_index_map;
411 else if (mti->mti_flags & LDD_F_SV_TYPE_MDT)
412 imap = fsdb->fsdb_mdt_index_map;
416 if (test_bit(mti->mti_stripe_index, imap))
421 static __inline__ int next_index(void *index_map, int map_len)
424 for (i = 0; i < map_len * 8; i++)
425 if (!test_bit(i, index_map)) {
428 CERROR("max index %d exceeded.\n", i);
433 0 newly marked as in use
435 +EALREADY for update of an old index */
436 int mgs_set_index(struct obd_device *obd, struct mgs_target_info *mti)
443 rc = mgs_find_or_make_fsdb(obd, mti->mti_fsname, &fsdb);
445 CERROR("Can't get db for %s\n", mti->mti_fsname);
449 if (mti->mti_flags & LDD_F_SV_TYPE_OST)
450 imap = fsdb->fsdb_ost_index_map;
451 else if (mti->mti_flags & LDD_F_SV_TYPE_MDT)
452 imap = fsdb->fsdb_mdt_index_map;
456 if (mti->mti_flags & LDD_F_NEED_INDEX) {
457 rc = next_index(imap, INDEX_MAP_SIZE);
460 mti->mti_stripe_index = rc;
463 /* Remove after CMD */
464 if ((mti->mti_flags & LDD_F_SV_TYPE_MDT) &&
465 (mti->mti_stripe_index > 0)) {
466 LCONSOLE_ERROR("MDT index must = 0 (until Clustered MetaData "
467 "feature is ready.)\n");
468 mti->mti_stripe_index = 0;
471 if (mti->mti_stripe_index >= INDEX_MAP_SIZE * 8) {
472 LCONSOLE_ERROR("Server %s requested index %d, but the"
473 "max index is %d.\n",
474 mti->mti_svname, mti->mti_stripe_index,
479 if (test_bit(mti->mti_stripe_index, imap)) {
480 if (mti->mti_flags & LDD_F_VIRGIN) {
481 LCONSOLE_ERROR("Server %s requested index %d, but that "
482 "index is already in use\n",
483 mti->mti_svname, mti->mti_stripe_index);
486 CDEBUG(D_MGS, "Server %s updating index %d\n",
487 mti->mti_svname, mti->mti_stripe_index);
492 set_bit(mti->mti_stripe_index, imap);
493 fsdb->fsdb_flags &= ~FSDB_LOG_EMPTY;
494 server_make_name(mti->mti_flags, mti->mti_stripe_index,
495 mti->mti_fsname, mti->mti_svname);
497 CDEBUG(D_MGS, "Set index for %s to %d\n", mti->mti_svname,
498 mti->mti_stripe_index);
503 struct mgs_modify_lookup {
504 struct cfg_marker mml_marker;
508 static int mgs_modify_handler(struct llog_handle *llh, struct llog_rec_hdr *rec,
511 struct mgs_modify_lookup *mml = (struct mgs_modify_lookup *)data;
512 struct cfg_marker *marker;
513 struct lustre_cfg *lcfg = (struct lustre_cfg *)(rec + 1);
514 int cfg_len = rec->lrh_len - sizeof(struct llog_rec_hdr) -
515 sizeof(struct llog_rec_tail);
519 if (rec->lrh_type != OBD_CFG_REC) {
520 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
524 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
526 CERROR("Insane cfg\n");
530 /* We only care about markers */
531 if (lcfg->lcfg_command != LCFG_MARKER)
534 marker = lustre_cfg_buf(lcfg, 1);
535 if ((strcmp(mml->mml_marker.cm_comment, marker->cm_comment) == 0) &&
536 (strcmp(mml->mml_marker.cm_tgtname, marker->cm_tgtname) == 0) &&
537 !(marker->cm_flags & CM_SKIP)) {
538 /* Found a non-skipped marker match */
539 CDEBUG(D_MGS, "Changing rec %u marker %d %x->%x: %s %s\n",
540 rec->lrh_index, marker->cm_step,
541 marker->cm_flags, mml->mml_marker.cm_flags,
542 marker->cm_tgtname, marker->cm_comment);
543 /* Overwrite the old marker llog entry */
544 marker->cm_flags &= ~CM_EXCLUDE; /* in case we're unexcluding */
545 marker->cm_flags |= mml->mml_marker.cm_flags;
546 marker->cm_canceltime = mml->mml_marker.cm_canceltime;
547 /* Header and tail are added back to lrh_len in
548 llog_lvfs_write_rec */
549 rec->lrh_len = cfg_len;
550 rc = llog_write_rec(llh, rec, NULL, 0, (void *)lcfg,
559 /* Modify an existing config log record (for CM_SKIP or CM_EXCLUDE) */
560 static int mgs_modify(struct obd_device *obd, struct fs_db *fsdb,
561 struct mgs_target_info *mti, char *logname,
562 char *devname, char *comment, int flags)
564 struct llog_handle *loghandle;
565 struct lvfs_run_ctxt saved;
566 struct mgs_modify_lookup *mml;
570 CDEBUG(D_MGS, "modify %s/%s/%s\n", logname, devname, comment);
572 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
574 rc = llog_create(llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT),
575 &loghandle, NULL, logname);
579 rc = llog_init_handle(loghandle, LLOG_F_IS_PLAIN, NULL);
583 if (llog_get_size(loghandle) <= 1)
584 GOTO(out_close, rc = 0);
588 GOTO(out_close, rc = -ENOMEM);
589 strcpy(mml->mml_marker.cm_comment, comment);
590 strcpy(mml->mml_marker.cm_tgtname, devname);
591 /* Modify mostly means cancel */
592 mml->mml_marker.cm_flags = flags;
593 mml->mml_marker.cm_canceltime = flags ? cfs_time_current_sec() : 0;
594 mml->mml_modified = 0;
595 rc = llog_process(loghandle, mgs_modify_handler, (void *)mml, NULL);
596 if (!rc && !mml->mml_modified)
601 rc2 = llog_close(loghandle);
606 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
607 if (rc && rc != -ENODEV)
608 CERROR("modify %s/%s failed %d\n",
609 mti->mti_svname, comment, rc);
615 /******************** config log recording functions *********************/
617 static int record_lcfg(struct obd_device *obd, struct llog_handle *llh,
618 struct lustre_cfg *lcfg)
620 struct lvfs_run_ctxt saved;
621 struct llog_rec_hdr rec;
627 LASSERT(llh->lgh_ctxt);
629 buflen = lustre_cfg_len(lcfg->lcfg_bufcount,
631 rec.lrh_len = llog_data_len(buflen);
632 rec.lrh_type = OBD_CFG_REC;
633 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
634 /* idx = -1 means append */
635 rc = llog_write_rec(llh, &rec, NULL, 0, (void *)lcfg, -1);
636 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
638 CERROR("failed %d\n", rc);
642 static int record_base(struct obd_device *obd, struct llog_handle *llh,
643 char *cfgname, lnet_nid_t nid, int cmd,
644 char *s1, char *s2, char *s3, char *s4)
646 struct lustre_cfg_bufs bufs;
647 struct lustre_cfg *lcfg;
650 CDEBUG(D_MGS, "lcfg %s %#x %s %s %s %s\n", cfgname,
651 cmd, s1, s2, s3, s4);
653 lustre_cfg_bufs_reset(&bufs, cfgname);
655 lustre_cfg_bufs_set_string(&bufs, 1, s1);
657 lustre_cfg_bufs_set_string(&bufs, 2, s2);
659 lustre_cfg_bufs_set_string(&bufs, 3, s3);
661 lustre_cfg_bufs_set_string(&bufs, 4, s4);
663 lcfg = lustre_cfg_new(cmd, &bufs);
666 lcfg->lcfg_nid = nid;
668 rc = record_lcfg(obd, llh, lcfg);
670 lustre_cfg_free(lcfg);
673 CERROR("error %d: lcfg %s %#x %s %s %s %s\n", rc, cfgname,
674 cmd, s1, s2, s3, s4);
680 static inline int record_add_uuid(struct obd_device *obd,
681 struct llog_handle *llh,
682 uint64_t nid, char *uuid)
684 return record_base(obd,llh,NULL,nid,LCFG_ADD_UUID,uuid,0,0,0);
688 static inline int record_add_conn(struct obd_device *obd,
689 struct llog_handle *llh,
693 return record_base(obd,llh,devname,0,LCFG_ADD_CONN,uuid,0,0,0);
696 static inline int record_attach(struct obd_device *obd, struct llog_handle *llh,
697 char *devname, char *type, char *uuid)
699 return record_base(obd,llh,devname,0,LCFG_ATTACH,type,uuid,0,0);
702 static inline int record_setup(struct obd_device *obd, struct llog_handle *llh,
704 char *s1, char *s2, char *s3, char *s4)
706 return record_base(obd,llh,devname,0,LCFG_SETUP,s1,s2,s3,s4);
709 static int record_lov_setup(struct obd_device *obd, struct llog_handle *llh,
710 char *devname, struct lov_desc *desc)
712 struct lustre_cfg_bufs bufs;
713 struct lustre_cfg *lcfg;
716 lustre_cfg_bufs_reset(&bufs, devname);
717 lustre_cfg_bufs_set(&bufs, 1, desc, sizeof(*desc));
718 lcfg = lustre_cfg_new(LCFG_SETUP, &bufs);
721 rc = record_lcfg(obd, llh, lcfg);
723 lustre_cfg_free(lcfg);
727 static inline int record_lov_add(struct obd_device *obd,
728 struct llog_handle *llh,
729 char *lov_name, char *ost_uuid,
730 char *index, char *gen)
732 return record_base(obd,llh,lov_name,0,LCFG_LOV_ADD_OBD,
733 ost_uuid,index,gen,0);
736 static inline int record_mount_opt(struct obd_device *obd,
737 struct llog_handle *llh,
738 char *profile, char *lov_name,
741 return record_base(obd,llh,NULL,0,LCFG_MOUNTOPT,
742 profile,lov_name,mdc_name,0);
745 static int record_marker(struct obd_device *obd, struct llog_handle *llh,
746 struct fs_db *fsdb, __u32 flags,
747 char *tgtname, char *comment)
749 struct cfg_marker marker;
750 struct lustre_cfg_bufs bufs;
751 struct lustre_cfg *lcfg;
754 if (flags & CM_START)
756 marker.cm_step = fsdb->fsdb_gen;
757 marker.cm_flags = flags;
758 marker.cm_vers = LUSTRE_VERSION_CODE;
759 strncpy(marker.cm_tgtname, tgtname, sizeof(marker.cm_tgtname));
760 strncpy(marker.cm_comment, comment, sizeof(marker.cm_comment));
761 marker.cm_createtime = cfs_time_current_sec();
762 marker.cm_canceltime = 0;
763 lustre_cfg_bufs_reset(&bufs, NULL);
764 lustre_cfg_bufs_set(&bufs, 1, &marker, sizeof(marker));
765 lcfg = lustre_cfg_new(LCFG_MARKER, &bufs);
768 rc = record_lcfg(obd, llh, lcfg);
770 lustre_cfg_free(lcfg);
774 static int record_start_log(struct obd_device *obd,
775 struct llog_handle **llh, char *name)
777 static struct obd_uuid cfg_uuid = { .uuid = "config_uuid" };
778 struct lvfs_run_ctxt saved;
782 GOTO(out, rc = -EBUSY);
785 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
787 rc = llog_create(llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT),
790 llog_init_handle(*llh, LLOG_F_IS_PLAIN, &cfg_uuid);
794 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
798 CERROR("Can't start log %s: %d\n", name, rc);
803 static int record_end_log(struct obd_device *obd, struct llog_handle **llh)
805 struct lvfs_run_ctxt saved;
808 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
810 rc = llog_close(*llh);
813 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
817 static int mgs_log_is_empty(struct obd_device *obd, char *name)
819 struct lvfs_run_ctxt saved;
820 struct llog_handle *llh;
823 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
824 rc = llog_create(llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT),
827 llog_init_handle(llh, LLOG_F_IS_PLAIN, NULL);
828 rc = llog_get_size(llh);
831 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
832 /* header is record 1 */
836 /******************** config "macros" *********************/
838 /* write an lcfg directly into a log (with markers) */
839 static int mgs_write_log_direct(struct obd_device *obd, struct fs_db *fsdb,
840 char *logname, struct lustre_cfg *lcfg,
841 char *devname, char *comment)
843 struct llog_handle *llh = NULL;
850 rc = record_start_log(obd, &llh, logname);
854 /* FIXME These should be a single journal transaction */
855 rc = record_marker(obd, llh, fsdb, CM_START, devname, comment);
857 rc = record_lcfg(obd, llh, lcfg);
859 rc = record_marker(obd, llh, fsdb, CM_END, devname, comment);
860 rc = record_end_log(obd, &llh);
865 /* write the lcfg in all logs for the given fs */
866 int mgs_write_log_direct_all(struct obd_device *obd, struct fs_db *fsdb,
867 struct mgs_target_info *mti,
868 struct lustre_cfg *lcfg,
869 char *devname, char *comment)
871 struct mgs_obd *mgs = &obd->u.mgs;
872 struct list_head dentry_list;
873 struct l_linux_dirent *dirent, *n;
874 char *fsname = mti->mti_fsname;
876 int rc = 0, len = strlen(fsname);
879 /* We need to set params for any future logs
880 as well. FIXME Append this file to every new log.
881 Actually, we should store as params (text), not llogs. Or
883 name_create(&logname, fsname, "-params");
884 if (mgs_log_is_empty(obd, logname)) {
885 struct llog_handle *llh = NULL;
886 rc = record_start_log(obd, &llh, logname);
887 record_end_log(obd, &llh);
889 name_destroy(&logname);
893 /* Find all the logs in the CONFIGS directory */
894 rc = class_dentry_readdir(obd, mgs->mgs_configs_dir,
895 mgs->mgs_vfsmnt, &dentry_list);
897 CERROR("Can't read %s dir\n", MOUNT_CONFIGS_DIR);
901 /* Could use fsdb index maps instead of directory listing */
902 list_for_each_entry_safe(dirent, n, &dentry_list, lld_list) {
903 list_del(&dirent->lld_list);
904 if (strncmp(fsname, dirent->lld_name, len) == 0) {
905 CDEBUG(D_MGS, "Changing log %s\n", dirent->lld_name);
906 /* Erase any old settings of this same parameter */
907 mgs_modify(obd, fsdb, mti, dirent->lld_name, devname,
909 /* Write the new one */
910 rc = mgs_write_log_direct(obd, fsdb, dirent->lld_name,
911 lcfg, devname, comment);
913 CERROR("err %d writing log %s\n", rc,
916 OBD_FREE(dirent, sizeof(*dirent));
922 /* lov is the first thing in the mdt and client logs */
923 static int mgs_write_log_lov(struct obd_device *obd, struct fs_db *fsdb,
924 struct mgs_target_info *mti,
925 char *logname, char *lovname)
927 struct llog_handle *llh = NULL;
928 struct lov_desc *lovdesc;
933 CDEBUG(D_MGS, "Writing log %s\n", logname);
936 #01 L attach 0:lov_mdsA 1:lov 2:71ccb_lov_mdsA_19f961a9e1
937 #02 L lov_setup 0:lov_mdsA 1:(struct lov_desc)
938 uuid=lov1_UUID, stripe count=1, size=1048576, offset=0, pattern=0
941 /* FIXME just make lov_setup accept empty desc (put uuid in buf 2) */
942 OBD_ALLOC(lovdesc, sizeof(*lovdesc));
945 lovdesc->ld_magic = LOV_DESC_MAGIC;
946 lovdesc->ld_tgt_count = 0;
947 /* Defaults. Can be changed later by lcfg config_param */
948 lovdesc->ld_default_stripe_count = 1;
949 lovdesc->ld_pattern = LOV_PATTERN_RAID0;
950 lovdesc->ld_default_stripe_size = 1024 * 1024;
951 lovdesc->ld_default_stripe_offset = 0;
952 lovdesc->ld_qos_maxage = QOS_DEFAULT_MAXAGE;
953 sprintf((char*)lovdesc->ld_uuid.uuid, "%s_UUID", lovname);
954 /* can these be the same? */
955 uuid = (char *)lovdesc->ld_uuid.uuid;
957 /* This should always be the first entry in a log.
958 rc = mgs_clear_log(obd, logname); */
959 rc = record_start_log(obd, &llh, logname);
962 /* FIXME these should be a single journal transaction */
963 rc = record_marker(obd, llh, fsdb, CM_START, lovname, "lov setup");
964 rc = record_attach(obd, llh, lovname, "lov", uuid);
965 rc = record_lov_setup(obd, llh, lovname, lovdesc);
966 rc = record_marker(obd, llh, fsdb, CM_END, lovname, "lov setup");
967 rc = record_end_log(obd, &llh);
969 OBD_FREE(lovdesc, sizeof(*lovdesc));
973 /* add failnids to open log */
974 static int mgs_write_log_failnids(struct obd_device *obd,
975 struct mgs_target_info *mti,
976 struct llog_handle *llh,
979 char *failnodeuuid = NULL;
980 char *ptr = mti->mti_params;
985 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) nal=90 0: 1:uml1_UUID
986 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
987 #05 L setup 0:OSC_uml1_ost1_mdsA 1:ost1_UUID 2:uml1_UUID
988 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) nal=90 0: 1:uml2_UUID
989 #0x L add_uuid nid=2@elan(0x1000000000002) nal=90 0: 1:uml2_UUID
990 #07 L add_conn 0:OSC_uml1_ost1_mdsA 1:uml2_UUID
993 /* Pull failnid info out of params string */
994 while (class_find_param(ptr, PARAM_FAILNODE, &ptr) == 0) {
995 while (class_parse_nid(ptr, &nid, &ptr) == 0) {
996 if (failnodeuuid == NULL) {
997 /* We don't know the failover node name,
998 so just use the first nid as the uuid */
999 rc = name_create(&failnodeuuid,
1000 libcfs_nid2str(nid), "");
1004 CDEBUG(D_MGS, "add nid %s for failover uuid %s, "
1005 "client %s\n", libcfs_nid2str(nid),
1006 failnodeuuid, cliname);
1007 rc = record_add_uuid(obd, llh, nid, failnodeuuid);
1010 rc = record_add_conn(obd, llh, cliname, failnodeuuid);
1011 name_destroy(&failnodeuuid);
1012 failnodeuuid = NULL;
1019 static int mgs_write_log_mdt(struct obd_device *obd, struct fs_db *fsdb,
1020 struct mgs_target_info *mti)
1022 struct llog_handle *llh = NULL;
1023 char *cliname, *mdcname, *nodeuuid, *mdcuuid;
1024 int rc, i, first_log = 0;
1027 CDEBUG(D_MGS, "writing new mdt %s\n", mti->mti_svname);
1030 if (mti->mti_flags & LDD_F_UPGRADE14) {
1031 /* We're starting with an old uuid. Assume old name for lov
1032 as well since the lov entry already exists in the log. */
1033 CDEBUG(D_MGS, "old mds uuid %s\n", mti->mti_uuid);
1034 if (strncmp(mti->mti_uuid, fsdb->fsdb_mdtlov + 4,
1035 strlen(fsdb->fsdb_mdtlov) - 4) != 0) {
1036 CERROR("old mds uuid %s doesn't match log %s (%s)\n",
1037 mti->mti_uuid, fsdb->fsdb_mdtlov,
1038 fsdb->fsdb_mdtlov + 4);
1042 /* end COMPAT_146 */
1044 if (mti->mti_uuid[0] == '\0') {
1045 /* Make up our own uuid */
1046 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
1047 "%s_UUID", mti->mti_svname);
1050 /* Append mdt info to mdt log */
1051 if (mgs_log_is_empty(obd, mti->mti_svname)) {
1052 /* This is the first time for all logs for this fs,
1053 since any ost should have already started the mdt log. */
1055 rc = mgs_write_log_lov(obd, fsdb, mti, mti->mti_svname,
1058 /* else there's already some ost entries in the mdt log. */
1060 /* We added the lov, maybe some osc's, now for the mdt.
1061 We might add more ost's after this. Note that during the parsing
1062 of this log, this is when the mdt will start. (This was not
1063 formerly part of the old mds log, it was directly executed by
1066 mount_option 0: 1:mdsA 2:lov_mdsA
1067 attach mds mdsA mdsA_UUID
1068 setup /dev/loop2 ldiskfs mdsA errors=remount-ro,user_xattr
1070 rc = record_start_log(obd, &llh, mti->mti_svname);
1073 /* FIXME this whole fn should be a single journal transaction */
1074 rc = record_marker(obd, llh, fsdb, CM_START, mti->mti_svname,"add mdt");
1075 rc = record_mount_opt(obd, llh, mti->mti_svname, fsdb->fsdb_mdtlov, 0);
1076 rc = record_attach(obd, llh, mti->mti_svname, LUSTRE_MDS_NAME,
1078 rc = record_setup(obd, llh, mti->mti_svname,
1079 "dev"/*ignored*/, "type"/*ignored*/,
1080 mti->mti_svname, 0/*options*/);
1081 rc = record_marker(obd, llh, fsdb, CM_END, mti->mti_svname, "add mdt");
1082 rc = record_end_log(obd, &llh);
1084 /* Append the mdt info to the client log */
1085 name_create(&cliname, mti->mti_fsname, "-client");
1087 /* Start client log */
1088 rc = mgs_write_log_lov(obd, fsdb, mti, cliname,
1092 name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]),/*"_UUID"*/"");
1093 name_create(&mdcname, mti->mti_svname, "-mdc");
1094 name_create(&mdcuuid, mdcname, "_UUID");
1096 #09 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
1097 #10 L attach 0:MDC_uml1_mdsA_MNT_client 1:mdc 2:1d834_MNT_client_03f
1098 #11 L setup 0:MDC_uml1_mdsA_MNT_client 1:mdsA_UUID 2:uml1_UUID
1099 #12 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
1100 #13 L add_conn 0:MDC_uml1_mdsA_MNT_client 1:uml2_UUID
1101 #14 L mount_option 0: 1:client 2:lov1 3:MDC_uml1_mdsA_MNT_client
1103 rc = record_start_log(obd, &llh, cliname);
1106 rc = record_marker(obd, llh, fsdb, CM_START, mti->mti_svname,"add mdc");
1108 if (mti->mti_flags & LDD_F_UPGRADE14) {
1109 /* Old client log already has MDC entry, but needs mount opt
1110 for new client name (lustre-client) */
1111 /* FIXME Old MDT log already has an old mount opt
1112 which we should remove (currently handled by
1113 class_del_profiles()) */
1114 rc = record_mount_opt(obd, llh, cliname, fsdb->fsdb_clilov,
1116 /* end COMPAT_146 */
1118 for (i = 0; i < mti->mti_nid_count; i++) {
1119 CDEBUG(D_MGS, "add nid %s\n",
1120 libcfs_nid2str(mti->mti_nids[i]));
1121 rc = record_add_uuid(obd, llh, mti->mti_nids[i],
1124 rc = record_attach(obd, llh, mdcname, LUSTRE_MDC_NAME, mdcuuid);
1125 rc = record_setup(obd, llh, mdcname, mti->mti_uuid,nodeuuid,
1127 rc = mgs_write_log_failnids(obd, mti, llh, mdcname);
1128 rc = record_mount_opt(obd, llh, cliname, fsdb->fsdb_clilov,
1131 rc = record_marker(obd, llh, fsdb, CM_END, mti->mti_svname, "add mdc");
1132 rc = record_end_log(obd, &llh);
1134 name_destroy(&mdcuuid);
1135 name_destroy(&mdcname);
1136 name_destroy(&nodeuuid);
1137 name_destroy(&cliname);
1141 /* Add the ost info to the client/mdt lov */
1142 static int mgs_write_log_osc(struct obd_device *obd, struct fs_db *fsdb,
1143 struct mgs_target_info *mti,
1144 char *logname, char *lovname, int flags)
1146 struct llog_handle *llh = NULL;
1147 char *nodeuuid, *oscname, *oscuuid, *lovuuid;
1151 if (mgs_log_is_empty(obd, logname)) {
1152 /* The first item in the log must be the lov, so we have
1153 somewhere to add our osc. */
1154 rc = mgs_write_log_lov(obd, fsdb, mti, logname, lovname);
1157 CDEBUG(D_MGS, "adding osc for %s to log %s\n",
1158 mti->mti_svname, logname);
1160 name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
1161 name_create(&oscname, mti->mti_svname, "-osc");
1162 name_create(&oscuuid, oscname, "_UUID");
1163 name_create(&lovuuid, lovname, "_UUID");
1166 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
1168 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
1169 #04 L attach 0:OSC_uml1_ost1_MNT_client 1:osc 2:89070_lov1_a41dff51a
1170 #05 L setup 0:OSC_uml1_ost1_MNT_client 1:ost1_UUID 2:uml1_UUID
1172 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
1173 #07 L add_conn 0:OSC_uml1_ost1_MNT_client 1:uml2_UUID
1174 #08 L lov_modify_tgts add 0:lov1 1:ost1_UUID 2(index):0 3(gen):1
1176 rc = record_start_log(obd, &llh, logname);
1179 /* FIXME these should be a single journal transaction */
1180 rc = record_marker(obd, llh, fsdb, CM_START | flags, mti->mti_svname,
1182 for (i = 0; i < mti->mti_nid_count; i++) {
1183 CDEBUG(D_MGS, "add nid %s\n", libcfs_nid2str(mti->mti_nids[i]));
1184 rc = record_add_uuid(obd, llh, mti->mti_nids[i], nodeuuid);
1186 rc = record_attach(obd, llh, oscname, LUSTRE_OSC_NAME, lovuuid);
1187 rc = record_setup(obd, llh, oscname, mti->mti_uuid, nodeuuid, 0, 0);
1188 rc = mgs_write_log_failnids(obd, mti, llh, oscname);
1189 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
1190 rc = record_lov_add(obd, llh, lovname, mti->mti_uuid, index, "1");
1191 rc = record_marker(obd, llh, fsdb, CM_END | flags, mti->mti_svname,
1193 rc = record_end_log(obd, &llh);
1195 name_destroy(&lovuuid);
1196 name_destroy(&oscuuid);
1197 name_destroy(&oscname);
1198 name_destroy(&nodeuuid);
1202 static int mgs_write_log_ost(struct obd_device *obd, struct fs_db *fsdb,
1203 struct mgs_target_info *mti)
1205 struct llog_handle *llh = NULL;
1207 char *ptr = mti->mti_params;
1208 int rc, flags = 0, failout = 0;
1211 CDEBUG(D_MGS, "writing new ost %s\n", mti->mti_svname);
1213 /* The ost startup log */
1215 /* If the ost log already exists, that means that someone reformatted
1216 the ost and it called target_add again. */
1217 if (!mgs_log_is_empty(obd, mti->mti_svname)) {
1218 LCONSOLE_ERROR("The config log for %s already exists, yet the "
1219 "server claims it never registered. It may have"
1220 " been reformatted, or the index changed. "
1221 "writeconf the MDT to regenerate all logs.\n",
1226 attach obdfilter ost1 ost1_UUID
1227 setup /dev/loop2 ldiskfs f|n errors=remount-ro,user_xattr
1229 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
1230 failout = (strncmp(ptr, "failout", 7) == 0);
1231 rc = record_start_log(obd, &llh, mti->mti_svname);
1234 /* FIXME these should be a single journal transaction */
1235 rc = record_marker(obd, llh, fsdb, CM_START, mti->mti_svname,"add ost");
1236 if (*mti->mti_uuid == '\0')
1237 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
1238 "%s_UUID", mti->mti_svname);
1239 rc = record_attach(obd, llh, mti->mti_svname,
1240 "obdfilter"/*LUSTRE_OST_NAME*/, mti->mti_uuid);
1241 rc = record_setup(obd, llh, mti->mti_svname,
1242 "dev"/*ignored*/, "type"/*ignored*/,
1243 failout ? "n" : "f", 0/*options*/);
1244 rc = record_marker(obd, llh, fsdb, CM_END, mti->mti_svname, "add ost");
1245 rc = record_end_log(obd, &llh);
1247 /* We also have to update the other logs where this osc is part of
1250 if (mti->mti_flags & LDD_F_UPGRADE14) {
1251 /* If we're upgrading, the old mdt log already has our
1252 entry. Let's do a fake one for fun. */
1253 flags = CM_SKIP | CM_UPGRADE146;
1254 } else if ((mti->mti_flags & LDD_F_UPDATE) != LDD_F_UPDATE) {
1255 /* If the update flag isn't set, don't really update
1258 LCONSOLE_WARN("Client log for %s was not updated; writeconf "
1259 "the MDT first to regenerate it.\n",
1263 /* Append ost info to mdt log */
1264 /* FIXME add to all MDT logs for CMD */
1265 /* FIXME need real MDT name, but MDT may not have registered yet! */
1266 name_create(&logname, mti->mti_fsname, "-MDT0000");
1267 rc = mgs_write_log_osc(obd, fsdb, mti, logname, fsdb->fsdb_mdtlov,
1269 name_destroy(&logname);
1271 /* Append ost info to the client log */
1272 name_create(&logname, mti->mti_fsname, "-client");
1273 rc = mgs_write_log_osc(obd, fsdb, mti, logname, fsdb->fsdb_clilov,
1275 name_destroy(&logname);
1280 /* Add additional failnids to an existing log.
1281 The mdc/osc must have been added to logs first */
1282 /* tcp nids must be in dotted-quad ascii -
1283 we can't resolve hostnames from the kernel. */
1284 static int mgs_write_log_add_failnid(struct obd_device *obd, struct fs_db *fsdb,
1285 struct mgs_target_info *mti)
1287 char *logname, *cliname;
1288 struct llog_handle *llh = NULL;
1292 /* Verify that we know about this target */
1293 if (mgs_log_is_empty(obd, mti->mti_svname)) {
1294 LCONSOLE_ERROR("The target %s has not registered yet. "
1295 "It must be started before failnids can "
1296 "be added.\n", mti->mti_svname);
1300 /* Create mdc/osc client name (e.g. lustre-OST0001-osc) */
1301 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
1302 name_create(&cliname, mti->mti_svname, "-mdc");
1303 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
1304 name_create(&cliname, mti->mti_svname, "-osc");
1309 /* Add failover nids to client log */
1310 name_create(&logname, mti->mti_fsname, "-client");
1311 rc = record_start_log(obd, &llh, logname);
1313 /* FIXME this fn should be a single journal transaction */
1314 rc = record_marker(obd, llh, fsdb, CM_START, mti->mti_svname,
1316 rc = mgs_write_log_failnids(obd, mti, llh, cliname);
1317 rc = record_marker(obd, llh, fsdb, CM_END, mti->mti_svname,
1319 rc = record_end_log(obd, &llh);
1321 name_destroy(&logname);
1323 if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
1324 /* Add OST failover nids to the MDT log as well */
1325 name_create(&logname, mti->mti_fsname, "-MDT0000");
1326 rc = record_start_log(obd, &llh, logname);
1328 rc = record_marker(obd, llh, fsdb, CM_START,
1329 mti->mti_svname, "add failnid");
1330 rc = mgs_write_log_failnids(obd, mti, llh, cliname);
1331 rc = record_marker(obd, llh, fsdb, CM_END,
1332 mti->mti_svname, "add failnid");
1333 rc = record_end_log(obd, &llh);
1335 name_destroy(&logname);
1338 name_destroy(&cliname);
1342 static int mgs_wlp_lcfg(struct obd_device *obd, struct fs_db *fsdb,
1343 struct mgs_target_info *mti,
1344 char *logname, struct lustre_cfg_bufs *bufs,
1345 char *tgtname, char *ptr)
1347 char comment[MTI_NAME_MAXLEN];
1349 struct lustre_cfg *lcfg;
1352 /* Erase any old settings of this same parameter */
1353 memcpy(comment, ptr, MTI_NAME_MAXLEN);
1354 comment[MTI_NAME_MAXLEN - 1] = 0;
1355 /* But don't try to match the value. */
1356 if ((tmp = strchr(comment, '=')))
1358 rc = mgs_modify(obd, fsdb, mti, logname, tgtname, comment, CM_SKIP);
1359 LCONSOLE_INFO("%sing parameter %s.%s in log %s\n", rc ?
1360 "Sett" : "Modify", tgtname, comment, logname);
1362 lustre_cfg_bufs_reset(bufs, tgtname);
1363 lustre_cfg_bufs_set_string(bufs, 1, ptr);
1364 lcfg = lustre_cfg_new(LCFG_PARAM, bufs);
1367 rc = mgs_write_log_direct(obd, fsdb, logname, lcfg, tgtname, comment);
1368 lustre_cfg_free(lcfg);
1372 static int mgs_write_log_params(struct obd_device *obd, struct fs_db *fsdb,
1373 struct mgs_target_info *mti)
1375 struct lustre_cfg_bufs bufs;
1376 struct lustre_cfg *lcfg;
1378 char *ptr = mti->mti_params;
1383 if (!mti->mti_params)
1386 /* FIXME we should cancel out old settings of the same parameters,
1387 and skip settings that are the same as old values */
1389 /* For various parameter settings, we have to figure out which logs
1390 care about them (e.g. both mdt and client for lov settings) */
1396 endptr = strchr(ptr, ' ');
1399 CDEBUG(D_MGS, "next param '%s'\n", ptr);
1401 /* The params are stored in MOUNT_DATA_FILE and modified
1402 via tunefs.lustre */
1404 /* Processed in lustre_start_mgc */
1405 if (class_match_param(ptr, PARAM_MGSNODE, NULL) == 0)
1408 /* Processed in mgs_write_log_ost */
1409 if (class_match_param(ptr, PARAM_FAILMODE, NULL) == 0)
1412 if (class_match_param(ptr, PARAM_FAILNODE, NULL) == 0) {
1413 /* Add a failover nidlist */
1415 /* We already processed failovers params for new
1416 targets in mgs_write_log_target */
1417 if (mti->mti_flags & LDD_F_PARAM_FNID) {
1418 CDEBUG(D_MGS, "Adding failnode\n");
1419 rc = mgs_write_log_add_failnid(obd, fsdb, mti);
1424 if (class_match_param(ptr, PARAM_SYS_TIMEOUT, &tmp) == 0) {
1425 /* Change obd timeout */
1427 timeout = simple_strtoul(tmp, NULL, 0);
1429 CDEBUG(D_MGS, "obd timeout %d\n", timeout);
1431 lustre_cfg_bufs_reset(&bufs, NULL);
1432 lcfg = lustre_cfg_new(LCFG_SET_TIMEOUT, &bufs);
1433 lcfg->lcfg_num = timeout;
1434 /* modify all servers and clients */
1435 rc = mgs_write_log_direct_all(obd, fsdb, mti, lcfg,
1438 lustre_cfg_free(lcfg);
1442 if (class_match_param(ptr, PARAM_OSC""PARAM_ACTIVE, &tmp) == 0){
1443 /* active=0 means off, anything else means on */
1444 int flag = (*tmp == '0') ? CM_EXCLUDE : 0;
1445 if (!(mti->mti_flags & LDD_F_SV_TYPE_OST)) {
1446 LCONSOLE_ERROR("%s: Only OSCs can be (de)activ"
1447 "ated.\n", mti->mti_svname);
1451 LCONSOLE_WARN("Permanently %sactivating %s\n",
1452 flag ? "de": "re", mti->mti_svname);
1454 name_create(&logname, mti->mti_fsname, "-client");
1455 rc = mgs_modify(obd, fsdb, mti, logname,
1456 mti->mti_svname, "add osc", flag);
1457 name_destroy(&logname);
1461 /* FIXME add to all MDT logs for CMD */
1462 name_create(&logname, mti->mti_fsname, "-MDT0000");
1463 rc = mgs_modify(obd, fsdb, mti, logname,
1464 mti->mti_svname, "add osc", flag);
1465 name_destroy(&logname);
1468 LCONSOLE_ERROR("Couldn't find %s in log (%d). "
1469 "No permanent changes were made to the "
1470 "config log.\n", mti->mti_svname, rc);
1471 if (fsdb->fsdb_flags & FSDB_OLDLOG14)
1472 LCONSOLE_ERROR("This may be because the"
1473 " log is in the old 1.4 style. Consider"
1474 " --writeconf to update the logs.\n");
1477 /* Fall through to osc proc for deactivating
1478 live OSC on running MDT / clients. */
1481 /* Below here, let obd's XXX_process_config methods handle it */
1483 /* All lov. in proc */
1484 if (class_match_param(ptr, PARAM_LOV, NULL) == 0) {
1485 CDEBUG(D_MGS, "lov param %s\n", ptr);
1486 if (!(mti->mti_flags & LDD_F_SV_TYPE_MDT)) {
1487 LCONSOLE_ERROR("LOV params must be set on the "
1488 "MDT, not %s. Ignoring.\n",
1495 if (mgs_log_is_empty(obd, mti->mti_svname)) {
1499 rc = mgs_wlp_lcfg(obd, fsdb, mti, mti->mti_svname,
1500 &bufs, fsdb->fsdb_mdtlov, ptr);
1505 name_create(&logname, mti->mti_fsname, "-client");
1506 rc = mgs_wlp_lcfg(obd, fsdb, mti, logname, &bufs,
1507 fsdb->fsdb_clilov, ptr);
1508 name_destroy(&logname);
1512 /* All osc., mdc., llite. params in proc */
1513 if ((class_match_param(ptr, PARAM_OSC, NULL) == 0) ||
1514 (class_match_param(ptr, PARAM_MDC, NULL) == 0) ||
1515 (class_match_param(ptr, PARAM_LLITE, NULL) == 0)) {
1517 if (memcmp(ptr, PARAM_LLITE, strlen(PARAM_LLITE)) == 0) {
1518 name_create(&cname, mti->mti_fsname, "-client");
1519 /* Add the client type to match the obdname
1520 in class_config_llog_handler */
1521 } else if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
1522 name_create(&cname, mti->mti_svname, "-mdc");
1523 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
1524 name_create(&cname, mti->mti_svname, "-osc");
1530 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
1533 name_create(&logname, mti->mti_fsname, "-client");
1534 rc = mgs_wlp_lcfg(obd, fsdb, mti, logname, &bufs,
1536 name_destroy(&logname);
1538 /* osc params affect the MDT as well */
1539 if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
1540 /* FIXME add to all MDT logs for CMD */
1541 name_create(&logname, mti->mti_fsname,
1543 if (!mgs_log_is_empty(obd, logname))
1544 rc = mgs_wlp_lcfg(obd, fsdb, mti,
1547 name_destroy(&logname);
1549 name_destroy(&cname);
1553 /* All mdt., ost. params in proc */
1554 if ((class_match_param(ptr, PARAM_MDT, NULL) == 0) ||
1555 (class_match_param(ptr, PARAM_OST, NULL) == 0)) {
1556 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
1557 if (mgs_log_is_empty(obd, mti->mti_svname)) {
1561 rc = mgs_wlp_lcfg(obd, fsdb, mti, mti->mti_svname,
1562 &bufs, mti->mti_svname, ptr);
1566 LCONSOLE_WARN("Ignoring unrecognized param '%s'\n", ptr);
1570 CERROR("err %d on param '%s\n", rc, ptr);
1585 int mgs_check_failnid(struct obd_device *obd, struct mgs_target_info *mti)
1587 /* Not implementing automatic failover nid addition at this time. */
1594 rc = mgs_find_or_make_fsdb(obd, fsname, &fsdb);
1598 if (mgs_log_is_empty(obd, mti->mti_svname))
1599 /* should never happen */
1602 CDEBUG(D_MGS, "Checking for new failnids for %s\n", mti->mti_svname);
1604 /* FIXME We can just check mti->params to see if we're already in
1605 the failover list. Modify mti->params for rewriting back at
1606 server_register_target(). */
1608 down(&fsdb->fsdb_sem);
1609 rc = mgs_write_log_add_failnid(obd, fsdb, mti);
1610 up(&fsdb->fsdb_sem);
1616 int mgs_write_log_target(struct obd_device *obd,
1617 struct mgs_target_info *mti)
1623 /* set/check the new target index */
1624 rc = mgs_set_index(obd, mti);
1626 CERROR("Can't get index (%d)\n", rc);
1630 if (mti->mti_flags & LDD_F_UPGRADE14) {
1631 if (rc == EALREADY) {
1632 LCONSOLE_INFO("Found index %d for %s 1.4 log, "
1633 "upgrading\n", mti->mti_stripe_index,
1636 LCONSOLE_ERROR("Failed to find %s in the old client "
1637 "log. Apparently it is not part of this "
1638 "filesystem, or the old log is wrong.\n"
1639 "Use 'writeconf' on the MDT to force log"
1640 " regeneration.\n", mti->mti_svname);
1641 /* Not in client log? Upgrade anyhow...*/
1642 /* Argument against upgrading: reformat MDT,
1643 upgrade OST, then OST will start but will be SKIPped
1644 in client logs. Maybe error now is better. */
1645 /* RETURN(-EINVAL); */
1647 /* end COMPAT_146 */
1649 if (rc == EALREADY) {
1650 /* This might be a params update, or a
1651 local writeconf. (For "full" writeconf, the client
1652 log won't have an entry for this target, so we
1654 LCONSOLE_WARN("Found index %d for %s, updating log\n",
1655 mti->mti_stripe_index, mti->mti_svname);
1656 /* We would like to mark old log sections as invalid
1657 and add new log sections in the client and mdt logs.
1658 But if we add new sections, then live clients will
1659 get repeat setup instructions for already running
1660 osc's. So don't update the client/mdt logs. */
1661 mti->mti_flags &= ~LDD_F_UPDATE;
1665 rc = mgs_find_or_make_fsdb(obd, mti->mti_fsname, &fsdb);
1667 CERROR("Can't get db for %s\n", mti->mti_fsname);
1671 down(&fsdb->fsdb_sem);
1673 if (mti->mti_flags &
1674 (LDD_F_VIRGIN | LDD_F_UPGRADE14 | LDD_F_WRITECONF)) {
1675 /* Generate a log from scratch */
1676 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
1677 rc = mgs_write_log_mdt(obd, fsdb, mti);
1678 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
1679 rc = mgs_write_log_ost(obd, fsdb, mti);
1681 CERROR("Unknown target type %#x, can't create log for "
1682 "%s\n", mti->mti_flags, mti->mti_svname);
1685 CERROR("Can't write logs for %s (%d)\n",
1686 mti->mti_svname, rc);
1690 /* Just update the params from tunefs in mgs_write_log_params */
1691 CDEBUG(D_MGS, "Update params for %s\n", mti->mti_svname);
1692 mti->mti_flags |= LDD_F_PARAM_FNID;
1695 rc = mgs_write_log_params(obd, fsdb, mti);
1698 up(&fsdb->fsdb_sem);
1703 /* upgrade pre-mountconf logs to mountconf at first connect */
1704 int mgs_upgrade_sv_14(struct obd_device *obd, struct mgs_target_info *mti)
1710 /* Create ost log normally, as servers register. Servers
1711 register with their old uuids (from last_rcvd), so old
1712 (MDT and client) logs should work.
1713 - new MDT won't know about old OSTs, only the ones that have
1714 registered, so we need the old MDT log to get the LOV right
1715 in order for old clients to work.
1716 - Old clients connect to the MDT, not the MGS, for their logs, and
1717 will therefore receive the old client log from the MDT /LOGS dir.
1718 - Old clients can continue to use and connect to old or new OSTs
1719 - New clients will contact the MGS for their log
1722 LCONSOLE_INFO("upgrading server %s from pre-1.6\n", mti->mti_svname);
1723 server_mti_print("upgrade", mti);
1725 rc = mgs_find_or_make_fsdb(obd, mti->mti_fsname, &fsdb);
1729 if (fsdb->fsdb_flags & FSDB_LOG_EMPTY) {
1730 LCONSOLE_ERROR("The old client log %s-client is missing. Was "
1731 "tunefs.lustre successful?\n",
1736 if (fsdb->fsdb_gen == 0) {
1737 /* There were no markers in the client log, meaning we have
1738 not updated the logs for this fs */
1739 CDEBUG(D_MGS, "found old, unupdated client log\n");
1742 if ((mti->mti_flags & LDD_F_SV_TYPE_MDT) &&
1743 mgs_log_is_empty(obd, mti->mti_svname)) {
1744 LCONSOLE_ERROR("The old MDT log %s is missing. Was "
1745 "tunefs.lustre successful?\n",
1750 rc = mgs_write_log_target(obd, mti);
1753 /* end COMPAT_146 */
1755 int mgs_erase_log(struct obd_device *obd, char *name)
1757 struct lvfs_run_ctxt saved;
1758 struct llog_handle *llh;
1761 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
1762 rc = llog_create(llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT),
1765 llog_init_handle(llh, LLOG_F_IS_PLAIN, NULL);
1766 rc = llog_destroy(llh);
1767 llog_free_handle(llh);
1769 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
1772 CERROR("failed to clear log %s: %d\n", name, rc);
1777 /* erase all logs for the given fs */
1778 int mgs_erase_logs(struct obd_device *obd, char *fsname)
1780 struct mgs_obd *mgs = &obd->u.mgs;
1781 static struct fs_db *fsdb;
1782 struct list_head dentry_list;
1783 struct l_linux_dirent *dirent, *n;
1784 int rc, len = strlen(fsname);
1787 /* Find all the logs in the CONFIGS directory */
1788 rc = class_dentry_readdir(obd, mgs->mgs_configs_dir,
1789 mgs->mgs_vfsmnt, &dentry_list);
1791 CERROR("Can't read %s dir\n", MOUNT_CONFIGS_DIR);
1795 down(&mgs->mgs_sem);
1797 /* Delete the fs db */
1798 fsdb = mgs_find_fsdb(obd, fsname);
1800 mgs_free_fsdb(obd, fsdb);
1802 list_for_each_entry_safe(dirent, n, &dentry_list, lld_list) {
1803 list_del(&dirent->lld_list);
1804 if (strncmp(fsname, dirent->lld_name, len) == 0) {
1805 CDEBUG(D_MGS, "Removing log %s\n", dirent->lld_name);
1806 mgs_erase_log(obd, dirent->lld_name);
1808 OBD_FREE(dirent, sizeof(*dirent));
1816 /* from llog_swab */
1817 static void print_lustre_cfg(struct lustre_cfg *lcfg)
1822 CDEBUG(D_MGS, "lustre_cfg: %p\n", lcfg);
1823 CDEBUG(D_MGS, "\tlcfg->lcfg_version: %#x\n", lcfg->lcfg_version);
1825 CDEBUG(D_MGS, "\tlcfg->lcfg_command: %#x\n", lcfg->lcfg_command);
1826 CDEBUG(D_MGS, "\tlcfg->lcfg_num: %#x\n", lcfg->lcfg_num);
1827 CDEBUG(D_MGS, "\tlcfg->lcfg_flags: %#x\n", lcfg->lcfg_flags);
1828 CDEBUG(D_MGS, "\tlcfg->lcfg_nid: %s\n", libcfs_nid2str(lcfg->lcfg_nid));
1830 CDEBUG(D_MGS, "\tlcfg->lcfg_bufcount: %d\n", lcfg->lcfg_bufcount);
1831 if (lcfg->lcfg_bufcount < LUSTRE_CFG_MAX_BUFCOUNT)
1832 for (i = 0; i < lcfg->lcfg_bufcount; i++) {
1833 CDEBUG(D_MGS, "\tlcfg->lcfg_buflens[%d]: %d %s\n",
1834 i, lcfg->lcfg_buflens[i],
1835 lustre_cfg_string(lcfg, i));
1840 /* Set a permanent (config log) param for a target or fs */
1841 int mgs_setparam(struct obd_device *obd, struct lustre_cfg *lcfg, char *fsname)
1844 struct mgs_target_info *mti;
1845 char *devname, *param;
1850 print_lustre_cfg(lcfg);
1852 /* lustre, lustre-mdtlov, lustre-client, lustre-MDT0000 */
1853 devname = lustre_cfg_string(lcfg, 0);
1854 param = lustre_cfg_string(lcfg, 1);
1856 /* Assume device name embedded in param:
1857 lustre-OST0000.osc.max_dirty_mb=32 */
1858 ptr = strchr(param, '.');
1866 LCONSOLE_ERROR("No target specified: %s\n", param);
1870 /* Extract fsname */
1871 ptr = strchr(devname, '-');
1872 memset(fsname, 0, MTI_NAME_MAXLEN);
1874 /* assume devname is the fsname */
1875 strncpy(fsname, devname, MTI_NAME_MAXLEN);
1877 strncpy(fsname, devname, ptr - devname);
1879 fsname[MTI_NAME_MAXLEN] = 0;
1880 CDEBUG(D_MGS, "setparam on fs %s device %s\n", fsname, devname);
1882 rc = mgs_find_or_make_fsdb(obd, fsname, &fsdb);
1885 if (fsdb->fsdb_flags & FSDB_LOG_EMPTY) {
1886 CERROR("No filesystem targets for %s\n", fsname);
1890 /* Create a fake mti to hold everything */
1893 GOTO(out, rc = -ENOMEM);
1894 strncpy(mti->mti_fsname, fsname, MTI_NAME_MAXLEN);
1895 strncpy(mti->mti_svname, devname, MTI_NAME_MAXLEN);
1896 strncpy(mti->mti_params, param, sizeof(mti->mti_params));
1897 rc = server_name2index(mti->mti_svname, &mti->mti_stripe_index, &tmp);
1899 /* Not a valid server; may be only fsname */
1902 /* Strip -osc or -mdc suffix from svname */
1903 if (server_make_name(rc, mti->mti_stripe_index, mti->mti_fsname,
1905 GOTO(out, rc = -EINVAL);
1907 mti->mti_flags = rc | LDD_F_PARAM_FNID;
1909 down(&fsdb->fsdb_sem);
1910 rc = mgs_write_log_params(obd, fsdb, mti);
1911 up(&fsdb->fsdb_sem);
1920 /******************** unused *********************/
1921 static int mgs_backup_llog(struct obd_device *obd, char* fsname)
1923 struct file *filp, *bak_filp;
1924 struct lvfs_run_ctxt saved;
1925 char *logname, *buf;
1926 loff_t soff = 0 , doff = 0;
1927 int count = 4096, len;
1930 OBD_ALLOC(logname, PATH_MAX);
1931 if (logname == NULL)
1934 OBD_ALLOC(buf, count);
1936 GOTO(out , rc = -ENOMEM);
1938 len = snprintf(logname, PATH_MAX, "%s/%s.bak",
1939 MOUNT_CONFIGS_DIR, fsname);
1941 if (len >= PATH_MAX - 1) {
1942 GOTO(out, -ENAMETOOLONG);
1945 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
1947 bak_filp = l_filp_open(logname, O_RDWR|O_CREAT|O_TRUNC, 0660);
1948 if (IS_ERR(bak_filp)) {
1949 rc = PTR_ERR(bak_filp);
1950 CERROR("backup logfile open %s: %d\n", logname, rc);
1953 sprintf(logname, "%s/%s", MOUNT_CONFIGS_DIR, fsname);
1954 filp = l_filp_open(logname, O_RDONLY, 0);
1957 CERROR("logfile open %s: %d\n", logname, rc);
1961 while ((rc = lustre_fread(filp, buf, count, &soff)) > 0) {
1962 rc = lustre_fwrite(bak_filp, buf, count, &doff);
1966 filp_close(filp, 0);
1968 filp_close(bak_filp, 0);
1970 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
1973 OBD_FREE(buf, count);
1974 OBD_FREE(logname, PATH_MAX);