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);
1029 if (mti->mti_uuid[0] == '\0') {
1030 /* Make up our own uuid */
1031 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
1032 "%s_UUID", mti->mti_svname);
1035 /* Append mdt info to mdt log */
1036 if (mgs_log_is_empty(obd, mti->mti_svname)) {
1037 /* This is the first time for all logs for this fs,
1038 since any ost should have already started the mdt log. */
1040 rc = mgs_write_log_lov(obd, fsdb, mti, mti->mti_svname,
1043 /* else there's already some ost entries in the mdt log. */
1045 /* We added the lov, maybe some osc's, now for the mdt.
1046 We might add more ost's after this. Note that during the parsing
1047 of this log, this is when the mdt will start. (This was not
1048 formerly part of the old mds log, it was directly executed by
1051 mount_option 0: 1:mdsA 2:lov_mdsA
1052 attach mds mdsA mdsA_UUID
1053 setup /dev/loop2 ldiskfs mdsA errors=remount-ro,user_xattr
1055 rc = record_start_log(obd, &llh, mti->mti_svname);
1058 /* FIXME this whole fn should be a single journal transaction */
1059 rc = record_marker(obd, llh, fsdb, CM_START, mti->mti_svname,"add mdt");
1060 rc = record_mount_opt(obd, llh, mti->mti_svname, fsdb->fsdb_mdtlov, 0);
1061 rc = record_attach(obd, llh, mti->mti_svname, LUSTRE_MDS_NAME,
1063 rc = record_setup(obd, llh, mti->mti_svname,
1064 "dev"/*ignored*/, "type"/*ignored*/,
1065 mti->mti_svname, 0/*options*/);
1066 rc = record_marker(obd, llh, fsdb, CM_END, mti->mti_svname, "add mdt");
1067 rc = record_end_log(obd, &llh);
1069 /* Append the mdt info to the client log */
1070 name_create(&cliname, mti->mti_fsname, "-client");
1072 /* Start client log */
1073 rc = mgs_write_log_lov(obd, fsdb, mti, cliname,
1077 name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]),/*"_UUID"*/"");
1078 name_create(&mdcname, mti->mti_svname, "-mdc");
1079 name_create(&mdcuuid, mdcname, "_UUID");
1081 #09 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
1082 #10 L attach 0:MDC_uml1_mdsA_MNT_client 1:mdc 2:1d834_MNT_client_03f
1083 #11 L setup 0:MDC_uml1_mdsA_MNT_client 1:mdsA_UUID 2:uml1_UUID
1084 #12 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
1085 #13 L add_conn 0:MDC_uml1_mdsA_MNT_client 1:uml2_UUID
1086 #14 L mount_option 0: 1:client 2:lov1 3:MDC_uml1_mdsA_MNT_client
1088 rc = record_start_log(obd, &llh, cliname);
1091 rc = record_marker(obd, llh, fsdb, CM_START, mti->mti_svname,"add mdc");
1093 if (fsdb->fsdb_flags & FSDB_OLDLOG14) {
1094 /* Old client log already has MDC entry, but needs mount opt
1095 for new client name (lustre-client) */
1096 /* FIXME Old MDT log already has an old mount opt
1097 which we should remove (currently handled by
1098 class_del_profiles()) */
1099 rc = record_mount_opt(obd, llh, cliname, fsdb->fsdb_clilov,
1101 /* Only add failnids with --writeconf
1102 rc = mgs_write_log_failnids(obd, mti, llh, fsdb->fsdb_mdc);
1104 /* end COMPAT_146 */
1106 for (i = 0; i < mti->mti_nid_count; i++) {
1107 CDEBUG(D_MGS, "add nid %s\n",
1108 libcfs_nid2str(mti->mti_nids[i]));
1109 rc = record_add_uuid(obd, llh, mti->mti_nids[i],
1112 rc = record_attach(obd, llh, mdcname, LUSTRE_MDC_NAME, mdcuuid);
1113 rc = record_setup(obd, llh, mdcname, mti->mti_uuid,nodeuuid,
1115 rc = mgs_write_log_failnids(obd, mti, llh, mdcname);
1116 rc = record_mount_opt(obd, llh, cliname, fsdb->fsdb_clilov,
1119 rc = record_marker(obd, llh, fsdb, CM_END, mti->mti_svname, "add mdc");
1120 rc = record_end_log(obd, &llh);
1122 name_destroy(&mdcuuid);
1123 name_destroy(&mdcname);
1124 name_destroy(&nodeuuid);
1125 name_destroy(&cliname);
1129 /* Add the ost info to the client/mdt lov */
1130 static int mgs_write_log_osc(struct obd_device *obd, struct fs_db *fsdb,
1131 struct mgs_target_info *mti,
1132 char *logname, char *lovname, int flags)
1134 struct llog_handle *llh = NULL;
1135 char *nodeuuid, *oscname, *oscuuid, *lovuuid;
1139 if (mgs_log_is_empty(obd, logname)) {
1140 /* The first item in the log must be the lov, so we have
1141 somewhere to add our osc. */
1142 rc = mgs_write_log_lov(obd, fsdb, mti, logname, lovname);
1145 CDEBUG(D_MGS, "adding osc for %s to log %s\n",
1146 mti->mti_svname, logname);
1148 name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
1149 name_create(&oscname, mti->mti_svname, "-osc");
1150 name_create(&oscuuid, oscname, "_UUID");
1151 name_create(&lovuuid, lovname, "_UUID");
1154 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
1156 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
1157 #04 L attach 0:OSC_uml1_ost1_MNT_client 1:osc 2:89070_lov1_a41dff51a
1158 #05 L setup 0:OSC_uml1_ost1_MNT_client 1:ost1_UUID 2:uml1_UUID
1160 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
1161 #07 L add_conn 0:OSC_uml1_ost1_MNT_client 1:uml2_UUID
1162 #08 L lov_modify_tgts add 0:lov1 1:ost1_UUID 2(index):0 3(gen):1
1164 rc = record_start_log(obd, &llh, logname);
1167 /* FIXME these should be a single journal transaction */
1168 rc = record_marker(obd, llh, fsdb, CM_START | flags, mti->mti_svname,
1170 for (i = 0; i < mti->mti_nid_count; i++) {
1171 CDEBUG(D_MGS, "add nid %s\n", libcfs_nid2str(mti->mti_nids[i]));
1172 rc = record_add_uuid(obd, llh, mti->mti_nids[i], nodeuuid);
1174 rc = record_attach(obd, llh, oscname, LUSTRE_OSC_NAME, lovuuid);
1175 rc = record_setup(obd, llh, oscname, mti->mti_uuid, nodeuuid, 0, 0);
1176 rc = mgs_write_log_failnids(obd, mti, llh, oscname);
1177 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
1178 rc = record_lov_add(obd, llh, lovname, mti->mti_uuid, index, "1");
1179 rc = record_marker(obd, llh, fsdb, CM_END | flags, mti->mti_svname,
1181 rc = record_end_log(obd, &llh);
1183 name_destroy(&lovuuid);
1184 name_destroy(&oscuuid);
1185 name_destroy(&oscname);
1186 name_destroy(&nodeuuid);
1190 static int mgs_write_log_ost(struct obd_device *obd, struct fs_db *fsdb,
1191 struct mgs_target_info *mti)
1193 struct llog_handle *llh = NULL;
1195 char *ptr = mti->mti_params;
1196 int rc, flags = 0, failout = 0;
1199 CDEBUG(D_MGS, "writing new ost %s\n", mti->mti_svname);
1201 /* The ost startup log */
1203 /* If the ost log already exists, that means that someone reformatted
1204 the ost and it called target_add again. */
1205 if (!mgs_log_is_empty(obd, mti->mti_svname)) {
1206 LCONSOLE_ERROR("The config log for %s already exists, yet the "
1207 "server claims it never registered. It may have"
1208 " been reformatted, or the index changed. "
1209 "writeconf the MDT to regenerate all logs.\n",
1214 attach obdfilter ost1 ost1_UUID
1215 setup /dev/loop2 ldiskfs f|n errors=remount-ro,user_xattr
1217 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
1218 failout = (strncmp(ptr, "failout", 7) == 0);
1219 rc = record_start_log(obd, &llh, mti->mti_svname);
1222 /* FIXME these should be a single journal transaction */
1223 rc = record_marker(obd, llh, fsdb, CM_START, mti->mti_svname,"add ost");
1224 if (*mti->mti_uuid == '\0')
1225 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
1226 "%s_UUID", mti->mti_svname);
1227 rc = record_attach(obd, llh, mti->mti_svname,
1228 "obdfilter"/*LUSTRE_OST_NAME*/, mti->mti_uuid);
1229 rc = record_setup(obd, llh, mti->mti_svname,
1230 "dev"/*ignored*/, "type"/*ignored*/,
1231 failout ? "n" : "f", 0/*options*/);
1232 rc = record_marker(obd, llh, fsdb, CM_END, mti->mti_svname, "add ost");
1233 rc = record_end_log(obd, &llh);
1235 /* We also have to update the other logs where this osc is part of
1238 if (fsdb->fsdb_flags & FSDB_OLDLOG14) {
1239 /* If we're upgrading, the old mdt log already has our
1240 entry. Let's do a fake one for fun. */
1241 /* Note that we can't add any new failnids, since we don't
1242 know the old osc names. */
1243 flags = CM_SKIP | CM_UPGRADE146;
1244 } else if ((mti->mti_flags & LDD_F_UPDATE) != LDD_F_UPDATE) {
1245 /* If the update flag isn't set, don't really update
1248 LCONSOLE_WARN("Client log for %s was not updated; writeconf "
1249 "the MDT first to regenerate it.\n",
1253 /* Append ost info to mdt log */
1254 /* FIXME add to all MDT logs for CMD */
1255 /* FIXME need real MDT name, but MDT may not have registered yet! */
1256 name_create(&logname, mti->mti_fsname, "-MDT0000");
1257 rc = mgs_write_log_osc(obd, fsdb, mti, logname, fsdb->fsdb_mdtlov,
1259 name_destroy(&logname);
1261 /* Append ost info to the client log */
1262 name_create(&logname, mti->mti_fsname, "-client");
1263 rc = mgs_write_log_osc(obd, fsdb, mti, logname, fsdb->fsdb_clilov,
1265 name_destroy(&logname);
1270 /* Add additional failnids to an existing log.
1271 The mdc/osc must have been added to logs first */
1272 /* tcp nids must be in dotted-quad ascii -
1273 we can't resolve hostnames from the kernel. */
1274 static int mgs_write_log_add_failnid(struct obd_device *obd, struct fs_db *fsdb,
1275 struct mgs_target_info *mti)
1277 char *logname, *cliname;
1278 struct llog_handle *llh = NULL;
1282 /* FIXME how do we delete a failnid? Currently --writeconf is the
1283 only way. Maybe make --erase-params pass a flag to really
1284 erase all params from logs - except it can't erase the failnids
1285 given when a target first registers, since they aren't processed
1288 /* Verify that we know about this target */
1289 if (mgs_log_is_empty(obd, mti->mti_svname)) {
1290 LCONSOLE_ERROR("The target %s has not registered yet. "
1291 "It must be started before failnids can "
1292 "be added.\n", mti->mti_svname);
1296 /* Create mdc/osc client name (e.g. lustre-OST0001-osc) */
1297 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
1300 name_create(&cliname, fsdb->fsdb_mdc, "");
1302 name_create(&cliname, mti->mti_svname, "-mdc");
1303 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
1305 if (fsdb->fsdb_flags & FSDB_OLDLOG14) {
1306 LCONSOLE_ERROR("Failover NIDs cannot be added to "
1307 "upgraded client logs for %s. Consider "
1308 "updating the configuration with "
1313 name_create(&cliname, mti->mti_svname, "-osc");
1318 /* Add failover nids to client log */
1319 name_create(&logname, mti->mti_fsname, "-client");
1320 rc = record_start_log(obd, &llh, logname);
1322 /* FIXME this fn should be a single journal transaction */
1323 rc = record_marker(obd, llh, fsdb, CM_START, mti->mti_svname,
1325 rc = mgs_write_log_failnids(obd, mti, llh, cliname);
1326 rc = record_marker(obd, llh, fsdb, CM_END, mti->mti_svname,
1328 rc = record_end_log(obd, &llh);
1330 name_destroy(&logname);
1332 if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
1333 /* Add OST failover nids to the MDT log as well */
1334 name_create(&logname, mti->mti_fsname, "-MDT0000");
1335 rc = record_start_log(obd, &llh, logname);
1337 rc = record_marker(obd, llh, fsdb, CM_START,
1338 mti->mti_svname, "add failnid");
1339 rc = mgs_write_log_failnids(obd, mti, llh, cliname);
1340 rc = record_marker(obd, llh, fsdb, CM_END,
1341 mti->mti_svname, "add failnid");
1342 rc = record_end_log(obd, &llh);
1344 name_destroy(&logname);
1347 name_destroy(&cliname);
1351 static int mgs_wlp_lcfg(struct obd_device *obd, struct fs_db *fsdb,
1352 struct mgs_target_info *mti,
1353 char *logname, struct lustre_cfg_bufs *bufs,
1354 char *tgtname, char *ptr)
1356 char comment[MTI_NAME_MAXLEN];
1358 struct lustre_cfg *lcfg;
1361 /* Erase any old settings of this same parameter */
1362 memcpy(comment, ptr, MTI_NAME_MAXLEN);
1363 comment[MTI_NAME_MAXLEN - 1] = 0;
1364 /* But don't try to match the value. */
1365 if ((tmp = strchr(comment, '=')))
1367 /* FIXME we should skip settings that are the same as old values */
1368 rc = mgs_modify(obd, fsdb, mti, logname, tgtname, comment, CM_SKIP);
1369 LCONSOLE_INFO("%sing parameter %s.%s in log %s\n", rc ?
1370 "Sett" : "Modify", tgtname, comment, logname);
1372 lustre_cfg_bufs_reset(bufs, tgtname);
1373 lustre_cfg_bufs_set_string(bufs, 1, ptr);
1374 lcfg = lustre_cfg_new(LCFG_PARAM, bufs);
1377 rc = mgs_write_log_direct(obd, fsdb, logname, lcfg, tgtname, comment);
1378 lustre_cfg_free(lcfg);
1382 static int mgs_write_log_params(struct obd_device *obd, struct fs_db *fsdb,
1383 struct mgs_target_info *mti)
1385 struct lustre_cfg_bufs bufs;
1386 struct lustre_cfg *lcfg;
1388 char *ptr = mti->mti_params;
1393 if (!mti->mti_params)
1396 /* For various parameter settings, we have to figure out which logs
1397 care about them (e.g. both mdt and client for lov settings) */
1403 endptr = strchr(ptr, ' ');
1406 CDEBUG(D_MGS, "next param '%s'\n", ptr);
1408 /* The params are stored in MOUNT_DATA_FILE and modified
1409 via tunefs.lustre */
1411 /* Processed in lustre_start_mgc */
1412 if (class_match_param(ptr, PARAM_MGSNODE, NULL) == 0)
1415 /* Processed in mgs_write_log_ost */
1416 if (class_match_param(ptr, PARAM_FAILMODE, NULL) == 0) {
1417 if (mti->mti_flags & LDD_F_PARAM) {
1418 LCONSOLE_ERROR("%s can only be changed with "
1419 "tunefs.lustre and --writeconf\n",
1426 if (class_match_param(ptr, PARAM_FAILNODE, NULL) == 0) {
1427 /* Add a failover nidlist */
1429 /* We already processed failovers params for new
1430 targets in mgs_write_log_target */
1431 if (mti->mti_flags & LDD_F_PARAM) {
1432 CDEBUG(D_MGS, "Adding failnode\n");
1433 rc = mgs_write_log_add_failnid(obd, fsdb, mti);
1438 if (class_match_param(ptr, PARAM_SYS_TIMEOUT, &tmp) == 0) {
1439 /* Change obd timeout */
1441 timeout = simple_strtoul(tmp, NULL, 0);
1443 CDEBUG(D_MGS, "obd timeout %d\n", timeout);
1445 lustre_cfg_bufs_reset(&bufs, NULL);
1446 lcfg = lustre_cfg_new(LCFG_SET_TIMEOUT, &bufs);
1447 lcfg->lcfg_num = timeout;
1448 /* modify all servers and clients */
1449 rc = mgs_write_log_direct_all(obd, fsdb, mti, lcfg,
1452 lustre_cfg_free(lcfg);
1456 if (class_match_param(ptr, PARAM_OSC""PARAM_ACTIVE, &tmp) == 0){
1457 /* active=0 means off, anything else means on */
1458 int flag = (*tmp == '0') ? CM_EXCLUDE : 0;
1459 if (!(mti->mti_flags & LDD_F_SV_TYPE_OST)) {
1460 LCONSOLE_ERROR("%s: Only OSCs can be (de)activ"
1461 "ated.\n", mti->mti_svname);
1465 LCONSOLE_WARN("Permanently %sactivating %s\n",
1466 flag ? "de": "re", mti->mti_svname);
1468 name_create(&logname, mti->mti_fsname, "-client");
1469 rc = mgs_modify(obd, fsdb, mti, logname,
1470 mti->mti_svname, "add osc", flag);
1471 name_destroy(&logname);
1475 /* FIXME add to all MDT logs for CMD */
1476 name_create(&logname, mti->mti_fsname, "-MDT0000");
1477 rc = mgs_modify(obd, fsdb, mti, logname,
1478 mti->mti_svname, "add osc", flag);
1479 name_destroy(&logname);
1482 LCONSOLE_ERROR("Couldn't find %s in log (%d). "
1483 "No permanent changes were made to the "
1484 "config log.\n", mti->mti_svname, rc);
1485 if (fsdb->fsdb_flags & FSDB_OLDLOG14)
1486 LCONSOLE_ERROR("This may be because the"
1487 " log is in the old 1.4 style. Consider"
1488 " --writeconf to update the logs.\n");
1491 /* Fall through to osc proc for deactivating
1492 live OSC on running MDT / clients. */
1495 /* Below here, let obd's XXX_process_config methods handle it */
1497 /* All lov. in proc */
1498 if (class_match_param(ptr, PARAM_LOV, NULL) == 0) {
1499 CDEBUG(D_MGS, "lov param %s\n", ptr);
1500 if (!(mti->mti_flags & LDD_F_SV_TYPE_MDT)) {
1501 LCONSOLE_ERROR("LOV params must be set on the "
1502 "MDT, not %s. Ignoring.\n",
1509 if (mgs_log_is_empty(obd, mti->mti_svname)) {
1513 rc = mgs_wlp_lcfg(obd, fsdb, mti, mti->mti_svname,
1514 &bufs, fsdb->fsdb_mdtlov, ptr);
1519 name_create(&logname, mti->mti_fsname, "-client");
1520 rc = mgs_wlp_lcfg(obd, fsdb, mti, logname, &bufs,
1521 fsdb->fsdb_clilov, ptr);
1522 name_destroy(&logname);
1526 /* All osc., mdc., llite. params in proc */
1527 if ((class_match_param(ptr, PARAM_OSC, NULL) == 0) ||
1528 (class_match_param(ptr, PARAM_MDC, NULL) == 0) ||
1529 (class_match_param(ptr, PARAM_LLITE, NULL) == 0)) {
1531 if (memcmp(ptr, PARAM_LLITE, strlen(PARAM_LLITE)) == 0) {
1532 name_create(&cname, mti->mti_fsname, "-client");
1533 /* Add the client type to match the obdname
1534 in class_config_llog_handler */
1535 } else if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
1538 name_create(&cname, fsdb->fsdb_mdc, "");
1540 name_create(&cname, mti->mti_svname,
1542 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
1544 if (fsdb->fsdb_flags & FSDB_OLDLOG14) {
1545 LCONSOLE_ERROR("Upgraded client logs "
1546 "for %s cannot be modified. "
1547 "Consider updating the "
1548 "configuration with --writeconf\n",
1550 /* We don't know the names of all the
1555 name_create(&cname, mti->mti_svname, "-osc");
1561 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
1564 name_create(&logname, mti->mti_fsname, "-client");
1565 rc = mgs_wlp_lcfg(obd, fsdb, mti, logname, &bufs,
1567 name_destroy(&logname);
1569 /* osc params affect the MDT as well */
1570 if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
1571 /* FIXME add to all MDT logs for CMD */
1572 name_create(&logname, mti->mti_fsname,
1574 if (!mgs_log_is_empty(obd, logname))
1575 rc = mgs_wlp_lcfg(obd, fsdb, mti,
1578 name_destroy(&logname);
1580 name_destroy(&cname);
1584 /* All mdt., ost. params in proc */
1585 if ((class_match_param(ptr, PARAM_MDT, NULL) == 0) ||
1586 (class_match_param(ptr, PARAM_OST, NULL) == 0)) {
1587 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
1588 if (mgs_log_is_empty(obd, mti->mti_svname)) {
1592 rc = mgs_wlp_lcfg(obd, fsdb, mti, mti->mti_svname,
1593 &bufs, mti->mti_svname, ptr);
1597 LCONSOLE_WARN("Ignoring unrecognized param '%s'\n", ptr);
1601 CERROR("err %d on param '%s\n", rc, ptr);
1616 int mgs_check_failnid(struct obd_device *obd, struct mgs_target_info *mti)
1618 /* Not implementing automatic failover nid addition at this time. */
1625 rc = mgs_find_or_make_fsdb(obd, fsname, &fsdb);
1629 if (mgs_log_is_empty(obd, mti->mti_svname))
1630 /* should never happen */
1633 CDEBUG(D_MGS, "Checking for new failnids for %s\n", mti->mti_svname);
1635 /* FIXME We can just check mti->params to see if we're already in
1636 the failover list. Modify mti->params for rewriting back at
1637 server_register_target(). */
1639 down(&fsdb->fsdb_sem);
1640 rc = mgs_write_log_add_failnid(obd, fsdb, mti);
1641 up(&fsdb->fsdb_sem);
1647 int mgs_write_log_target(struct obd_device *obd,
1648 struct mgs_target_info *mti)
1654 /* set/check the new target index */
1655 rc = mgs_set_index(obd, mti);
1657 CERROR("Can't get index (%d)\n", rc);
1661 if (mti->mti_flags & LDD_F_UPGRADE14) {
1662 if (rc == EALREADY) {
1663 LCONSOLE_INFO("Found index %d for %s 1.4 log, "
1664 "upgrading\n", mti->mti_stripe_index,
1667 LCONSOLE_ERROR("Failed to find %s in the old client "
1668 "log. Apparently it is not part of this "
1669 "filesystem, or the old log is wrong.\n"
1670 "Use 'writeconf' on the MDT to force log"
1671 " regeneration.\n", mti->mti_svname);
1672 /* Not in client log? Upgrade anyhow...*/
1673 /* Argument against upgrading: reformat MDT,
1674 upgrade OST, then OST will start but will be SKIPped
1675 in client logs. Maybe error now is better. */
1676 /* RETURN(-EINVAL); */
1678 /* end COMPAT_146 */
1680 if (rc == EALREADY) {
1681 /* This might be a params update, or a
1682 local writeconf. (For "full" writeconf, the client
1683 log won't have an entry for this target, so we
1685 LCONSOLE_WARN("Found index %d for %s, updating log\n",
1686 mti->mti_stripe_index, mti->mti_svname);
1687 /* We would like to mark old log sections as invalid
1688 and add new log sections in the client and mdt logs.
1689 But if we add new sections, then live clients will
1690 get repeat setup instructions for already running
1691 osc's. So don't update the client/mdt logs. */
1692 mti->mti_flags &= ~LDD_F_UPDATE;
1696 rc = mgs_find_or_make_fsdb(obd, mti->mti_fsname, &fsdb);
1698 CERROR("Can't get db for %s\n", mti->mti_fsname);
1702 down(&fsdb->fsdb_sem);
1704 if (mti->mti_flags &
1705 (LDD_F_VIRGIN | LDD_F_UPGRADE14 | LDD_F_WRITECONF)) {
1706 /* Generate a log from scratch */
1707 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
1708 rc = mgs_write_log_mdt(obd, fsdb, mti);
1709 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
1710 rc = mgs_write_log_ost(obd, fsdb, mti);
1712 CERROR("Unknown target type %#x, can't create log for "
1713 "%s\n", mti->mti_flags, mti->mti_svname);
1716 CERROR("Can't write logs for %s (%d)\n",
1717 mti->mti_svname, rc);
1721 /* Just update the params from tunefs in mgs_write_log_params */
1722 CDEBUG(D_MGS, "Update params for %s\n", mti->mti_svname);
1723 mti->mti_flags |= LDD_F_PARAM;
1726 rc = mgs_write_log_params(obd, fsdb, mti);
1729 up(&fsdb->fsdb_sem);
1734 /* verify that we can handle the old config logs */
1735 int mgs_upgrade_sv_14(struct obd_device *obd, struct mgs_target_info *mti)
1741 /* Create ost log normally, as servers register. Servers
1742 register with their old uuids (from last_rcvd), so old
1743 (MDT and client) logs should work.
1744 - new MDT won't know about old OSTs, only the ones that have
1745 registered, so we need the old MDT log to get the LOV right
1746 in order for old clients to work.
1747 - Old clients connect to the MDT, not the MGS, for their logs, and
1748 will therefore receive the old client log from the MDT /LOGS dir.
1749 - Old clients can continue to use and connect to old or new OSTs
1750 - New clients will contact the MGS for their log
1753 LCONSOLE_INFO("upgrading server %s from pre-1.6\n", mti->mti_svname);
1754 server_mti_print("upgrade", mti);
1756 rc = mgs_find_or_make_fsdb(obd, mti->mti_fsname, &fsdb);
1760 if (fsdb->fsdb_flags & FSDB_LOG_EMPTY) {
1761 LCONSOLE_ERROR("The old client log %s-client is missing. Was "
1762 "tunefs.lustre successful?\n",
1767 if (fsdb->fsdb_gen == 0) {
1768 /* There were no markers in the client log, meaning we have
1769 not updated the logs for this fs */
1770 CDEBUG(D_MGS, "found old, unupdated client log\n");
1773 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
1774 if (mgs_log_is_empty(obd, mti->mti_svname)) {
1775 LCONSOLE_ERROR("The old MDT log %s is missing. Was "
1776 "tunefs.lustre successful?\n",
1781 /* We're starting with an old uuid. Assume old name for lov
1782 as well since the lov entry already exists in the log. */
1783 CDEBUG(D_MGS, "old mds uuid %s\n", mti->mti_uuid);
1784 if (strncmp(mti->mti_uuid, fsdb->fsdb_mdtlov + 4,
1785 strlen(fsdb->fsdb_mdtlov) - 4) != 0) {
1786 CERROR("old mds uuid %s doesn't match log %s (%s)\n",
1787 mti->mti_uuid, fsdb->fsdb_mdtlov,
1788 fsdb->fsdb_mdtlov + 4);
1793 if (!(fsdb->fsdb_flags & FSDB_OLDLOG14)) {
1794 LCONSOLE_ERROR("%s-client is supposedly an old log, but no old "
1795 "LOV or MDT was found. Consider updating the "
1796 "configuration with --writeconf.\n",
1802 /* end COMPAT_146 */
1804 int mgs_erase_log(struct obd_device *obd, char *name)
1806 struct lvfs_run_ctxt saved;
1807 struct llog_handle *llh;
1810 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
1811 rc = llog_create(llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT),
1814 llog_init_handle(llh, LLOG_F_IS_PLAIN, NULL);
1815 rc = llog_destroy(llh);
1816 llog_free_handle(llh);
1818 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
1821 CERROR("failed to clear log %s: %d\n", name, rc);
1826 /* erase all logs for the given fs */
1827 int mgs_erase_logs(struct obd_device *obd, char *fsname)
1829 struct mgs_obd *mgs = &obd->u.mgs;
1830 static struct fs_db *fsdb;
1831 struct list_head dentry_list;
1832 struct l_linux_dirent *dirent, *n;
1833 int rc, len = strlen(fsname);
1836 /* Find all the logs in the CONFIGS directory */
1837 rc = class_dentry_readdir(obd, mgs->mgs_configs_dir,
1838 mgs->mgs_vfsmnt, &dentry_list);
1840 CERROR("Can't read %s dir\n", MOUNT_CONFIGS_DIR);
1844 down(&mgs->mgs_sem);
1846 /* Delete the fs db */
1847 fsdb = mgs_find_fsdb(obd, fsname);
1849 mgs_free_fsdb(obd, fsdb);
1851 list_for_each_entry_safe(dirent, n, &dentry_list, lld_list) {
1852 list_del(&dirent->lld_list);
1853 if (strncmp(fsname, dirent->lld_name, len) == 0) {
1854 CDEBUG(D_MGS, "Removing log %s\n", dirent->lld_name);
1855 mgs_erase_log(obd, dirent->lld_name);
1857 OBD_FREE(dirent, sizeof(*dirent));
1865 /* from llog_swab */
1866 static void print_lustre_cfg(struct lustre_cfg *lcfg)
1871 CDEBUG(D_MGS, "lustre_cfg: %p\n", lcfg);
1872 CDEBUG(D_MGS, "\tlcfg->lcfg_version: %#x\n", lcfg->lcfg_version);
1874 CDEBUG(D_MGS, "\tlcfg->lcfg_command: %#x\n", lcfg->lcfg_command);
1875 CDEBUG(D_MGS, "\tlcfg->lcfg_num: %#x\n", lcfg->lcfg_num);
1876 CDEBUG(D_MGS, "\tlcfg->lcfg_flags: %#x\n", lcfg->lcfg_flags);
1877 CDEBUG(D_MGS, "\tlcfg->lcfg_nid: %s\n", libcfs_nid2str(lcfg->lcfg_nid));
1879 CDEBUG(D_MGS, "\tlcfg->lcfg_bufcount: %d\n", lcfg->lcfg_bufcount);
1880 if (lcfg->lcfg_bufcount < LUSTRE_CFG_MAX_BUFCOUNT)
1881 for (i = 0; i < lcfg->lcfg_bufcount; i++) {
1882 CDEBUG(D_MGS, "\tlcfg->lcfg_buflens[%d]: %d %s\n",
1883 i, lcfg->lcfg_buflens[i],
1884 lustre_cfg_string(lcfg, i));
1889 /* Set a permanent (config log) param for a target or fs */
1890 int mgs_setparam(struct obd_device *obd, struct lustre_cfg *lcfg, char *fsname)
1893 struct mgs_target_info *mti;
1894 char *devname, *param;
1899 print_lustre_cfg(lcfg);
1901 /* lustre, lustre-mdtlov, lustre-client, lustre-MDT0000 */
1902 devname = lustre_cfg_string(lcfg, 0);
1903 param = lustre_cfg_string(lcfg, 1);
1905 /* Assume device name embedded in param:
1906 lustre-OST0000.osc.max_dirty_mb=32 */
1907 ptr = strchr(param, '.');
1915 LCONSOLE_ERROR("No target specified: %s\n", param);
1919 /* Extract fsname */
1920 ptr = strchr(devname, '-');
1921 memset(fsname, 0, MTI_NAME_MAXLEN);
1923 /* assume devname is the fsname */
1924 strncpy(fsname, devname, MTI_NAME_MAXLEN);
1926 strncpy(fsname, devname, ptr - devname);
1928 fsname[MTI_NAME_MAXLEN - 1] = 0;
1929 CDEBUG(D_MGS, "setparam on fs %s device %s\n", fsname, devname);
1931 rc = mgs_find_or_make_fsdb(obd, fsname, &fsdb);
1934 if (fsdb->fsdb_flags & FSDB_LOG_EMPTY) {
1935 CERROR("No filesystem targets for %s. cfg_device from lctl "
1936 "is '%s'\n", fsname, devname);
1937 mgs_free_fsdb(obd, fsdb);
1941 /* Create a fake mti to hold everything */
1944 GOTO(out, rc = -ENOMEM);
1945 strncpy(mti->mti_fsname, fsname, MTI_NAME_MAXLEN);
1946 strncpy(mti->mti_svname, devname, MTI_NAME_MAXLEN);
1947 strncpy(mti->mti_params, param, sizeof(mti->mti_params));
1948 rc = server_name2index(mti->mti_svname, &mti->mti_stripe_index, &tmp);
1950 /* Not a valid server; may be only fsname */
1953 /* Strip -osc or -mdc suffix from svname */
1954 if (server_make_name(rc, mti->mti_stripe_index, mti->mti_fsname,
1956 GOTO(out, rc = -EINVAL);
1958 mti->mti_flags = rc | LDD_F_PARAM;
1960 down(&fsdb->fsdb_sem);
1961 rc = mgs_write_log_params(obd, fsdb, mti);
1962 up(&fsdb->fsdb_sem);
1971 /******************** unused *********************/
1972 static int mgs_backup_llog(struct obd_device *obd, char* fsname)
1974 struct file *filp, *bak_filp;
1975 struct lvfs_run_ctxt saved;
1976 char *logname, *buf;
1977 loff_t soff = 0 , doff = 0;
1978 int count = 4096, len;
1981 OBD_ALLOC(logname, PATH_MAX);
1982 if (logname == NULL)
1985 OBD_ALLOC(buf, count);
1987 GOTO(out , rc = -ENOMEM);
1989 len = snprintf(logname, PATH_MAX, "%s/%s.bak",
1990 MOUNT_CONFIGS_DIR, fsname);
1992 if (len >= PATH_MAX - 1) {
1993 GOTO(out, -ENAMETOOLONG);
1996 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
1998 bak_filp = l_filp_open(logname, O_RDWR|O_CREAT|O_TRUNC, 0660);
1999 if (IS_ERR(bak_filp)) {
2000 rc = PTR_ERR(bak_filp);
2001 CERROR("backup logfile open %s: %d\n", logname, rc);
2004 sprintf(logname, "%s/%s", MOUNT_CONFIGS_DIR, fsname);
2005 filp = l_filp_open(logname, O_RDONLY, 0);
2008 CERROR("logfile open %s: %d\n", logname, rc);
2012 while ((rc = lustre_fread(filp, buf, count, &soff)) > 0) {
2013 rc = lustre_fwrite(bak_filp, buf, count, &doff);
2017 filp_close(filp, 0);
2019 filp_close(bak_filp, 0);
2021 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
2024 OBD_FREE(buf, count);
2025 OBD_FREE(logname, PATH_MAX);