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)
1419 if (class_match_param(ptr, PARAM_FAILNODE, NULL) == 0) {
1420 /* Add a failover nidlist */
1422 /* We already processed failovers params for new
1423 targets in mgs_write_log_target */
1424 if (mti->mti_flags & LDD_F_PARAM_FNID) {
1425 CDEBUG(D_MGS, "Adding failnode\n");
1426 rc = mgs_write_log_add_failnid(obd, fsdb, mti);
1431 if (class_match_param(ptr, PARAM_SYS_TIMEOUT, &tmp) == 0) {
1432 /* Change obd timeout */
1434 timeout = simple_strtoul(tmp, NULL, 0);
1436 CDEBUG(D_MGS, "obd timeout %d\n", timeout);
1438 lustre_cfg_bufs_reset(&bufs, NULL);
1439 lcfg = lustre_cfg_new(LCFG_SET_TIMEOUT, &bufs);
1440 lcfg->lcfg_num = timeout;
1441 /* modify all servers and clients */
1442 rc = mgs_write_log_direct_all(obd, fsdb, mti, lcfg,
1445 lustre_cfg_free(lcfg);
1449 if (class_match_param(ptr, PARAM_OSC""PARAM_ACTIVE, &tmp) == 0){
1450 /* active=0 means off, anything else means on */
1451 int flag = (*tmp == '0') ? CM_EXCLUDE : 0;
1452 if (!(mti->mti_flags & LDD_F_SV_TYPE_OST)) {
1453 LCONSOLE_ERROR("%s: Only OSCs can be (de)activ"
1454 "ated.\n", mti->mti_svname);
1458 LCONSOLE_WARN("Permanently %sactivating %s\n",
1459 flag ? "de": "re", mti->mti_svname);
1461 name_create(&logname, mti->mti_fsname, "-client");
1462 rc = mgs_modify(obd, fsdb, mti, logname,
1463 mti->mti_svname, "add osc", flag);
1464 name_destroy(&logname);
1468 /* FIXME add to all MDT logs for CMD */
1469 name_create(&logname, mti->mti_fsname, "-MDT0000");
1470 rc = mgs_modify(obd, fsdb, mti, logname,
1471 mti->mti_svname, "add osc", flag);
1472 name_destroy(&logname);
1475 LCONSOLE_ERROR("Couldn't find %s in log (%d). "
1476 "No permanent changes were made to the "
1477 "config log.\n", mti->mti_svname, rc);
1478 if (fsdb->fsdb_flags & FSDB_OLDLOG14)
1479 LCONSOLE_ERROR("This may be because the"
1480 " log is in the old 1.4 style. Consider"
1481 " --writeconf to update the logs.\n");
1484 /* Fall through to osc proc for deactivating
1485 live OSC on running MDT / clients. */
1488 /* Below here, let obd's XXX_process_config methods handle it */
1490 /* All lov. in proc */
1491 if (class_match_param(ptr, PARAM_LOV, NULL) == 0) {
1492 CDEBUG(D_MGS, "lov param %s\n", ptr);
1493 if (!(mti->mti_flags & LDD_F_SV_TYPE_MDT)) {
1494 LCONSOLE_ERROR("LOV params must be set on the "
1495 "MDT, not %s. Ignoring.\n",
1502 if (mgs_log_is_empty(obd, mti->mti_svname)) {
1506 rc = mgs_wlp_lcfg(obd, fsdb, mti, mti->mti_svname,
1507 &bufs, fsdb->fsdb_mdtlov, ptr);
1512 name_create(&logname, mti->mti_fsname, "-client");
1513 rc = mgs_wlp_lcfg(obd, fsdb, mti, logname, &bufs,
1514 fsdb->fsdb_clilov, ptr);
1515 name_destroy(&logname);
1519 /* All osc., mdc., llite. params in proc */
1520 if ((class_match_param(ptr, PARAM_OSC, NULL) == 0) ||
1521 (class_match_param(ptr, PARAM_MDC, NULL) == 0) ||
1522 (class_match_param(ptr, PARAM_LLITE, NULL) == 0)) {
1524 if (memcmp(ptr, PARAM_LLITE, strlen(PARAM_LLITE)) == 0) {
1525 name_create(&cname, mti->mti_fsname, "-client");
1526 /* Add the client type to match the obdname
1527 in class_config_llog_handler */
1528 } else if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
1531 name_create(&cname, fsdb->fsdb_mdc, "");
1533 name_create(&cname, mti->mti_svname,
1535 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
1537 if (fsdb->fsdb_flags & FSDB_OLDLOG14) {
1538 LCONSOLE_ERROR("Upgraded client logs "
1539 "for %s cannot be modified. "
1540 "Consider updating the "
1541 "configuration with --writeconf\n",
1543 /* We don't know the names of all the
1548 name_create(&cname, mti->mti_svname, "-osc");
1554 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
1557 name_create(&logname, mti->mti_fsname, "-client");
1558 rc = mgs_wlp_lcfg(obd, fsdb, mti, logname, &bufs,
1560 name_destroy(&logname);
1562 /* osc params affect the MDT as well */
1563 if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
1564 /* FIXME add to all MDT logs for CMD */
1565 name_create(&logname, mti->mti_fsname,
1567 if (!mgs_log_is_empty(obd, logname))
1568 rc = mgs_wlp_lcfg(obd, fsdb, mti,
1571 name_destroy(&logname);
1573 name_destroy(&cname);
1577 /* All mdt., ost. params in proc */
1578 if ((class_match_param(ptr, PARAM_MDT, NULL) == 0) ||
1579 (class_match_param(ptr, PARAM_OST, NULL) == 0)) {
1580 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
1581 if (mgs_log_is_empty(obd, mti->mti_svname)) {
1585 rc = mgs_wlp_lcfg(obd, fsdb, mti, mti->mti_svname,
1586 &bufs, mti->mti_svname, ptr);
1590 LCONSOLE_WARN("Ignoring unrecognized param '%s'\n", ptr);
1594 CERROR("err %d on param '%s\n", rc, ptr);
1609 int mgs_check_failnid(struct obd_device *obd, struct mgs_target_info *mti)
1611 /* Not implementing automatic failover nid addition at this time. */
1618 rc = mgs_find_or_make_fsdb(obd, fsname, &fsdb);
1622 if (mgs_log_is_empty(obd, mti->mti_svname))
1623 /* should never happen */
1626 CDEBUG(D_MGS, "Checking for new failnids for %s\n", mti->mti_svname);
1628 /* FIXME We can just check mti->params to see if we're already in
1629 the failover list. Modify mti->params for rewriting back at
1630 server_register_target(). */
1632 down(&fsdb->fsdb_sem);
1633 rc = mgs_write_log_add_failnid(obd, fsdb, mti);
1634 up(&fsdb->fsdb_sem);
1640 int mgs_write_log_target(struct obd_device *obd,
1641 struct mgs_target_info *mti)
1647 /* set/check the new target index */
1648 rc = mgs_set_index(obd, mti);
1650 CERROR("Can't get index (%d)\n", rc);
1654 if (mti->mti_flags & LDD_F_UPGRADE14) {
1655 if (rc == EALREADY) {
1656 LCONSOLE_INFO("Found index %d for %s 1.4 log, "
1657 "upgrading\n", mti->mti_stripe_index,
1660 LCONSOLE_ERROR("Failed to find %s in the old client "
1661 "log. Apparently it is not part of this "
1662 "filesystem, or the old log is wrong.\n"
1663 "Use 'writeconf' on the MDT to force log"
1664 " regeneration.\n", mti->mti_svname);
1665 /* Not in client log? Upgrade anyhow...*/
1666 /* Argument against upgrading: reformat MDT,
1667 upgrade OST, then OST will start but will be SKIPped
1668 in client logs. Maybe error now is better. */
1669 /* RETURN(-EINVAL); */
1671 /* end COMPAT_146 */
1673 if (rc == EALREADY) {
1674 /* This might be a params update, or a
1675 local writeconf. (For "full" writeconf, the client
1676 log won't have an entry for this target, so we
1678 LCONSOLE_WARN("Found index %d for %s, updating log\n",
1679 mti->mti_stripe_index, mti->mti_svname);
1680 /* We would like to mark old log sections as invalid
1681 and add new log sections in the client and mdt logs.
1682 But if we add new sections, then live clients will
1683 get repeat setup instructions for already running
1684 osc's. So don't update the client/mdt logs. */
1685 mti->mti_flags &= ~LDD_F_UPDATE;
1689 rc = mgs_find_or_make_fsdb(obd, mti->mti_fsname, &fsdb);
1691 CERROR("Can't get db for %s\n", mti->mti_fsname);
1695 down(&fsdb->fsdb_sem);
1697 if (mti->mti_flags &
1698 (LDD_F_VIRGIN | LDD_F_UPGRADE14 | LDD_F_WRITECONF)) {
1699 /* Generate a log from scratch */
1700 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
1701 rc = mgs_write_log_mdt(obd, fsdb, mti);
1702 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
1703 rc = mgs_write_log_ost(obd, fsdb, mti);
1705 CERROR("Unknown target type %#x, can't create log for "
1706 "%s\n", mti->mti_flags, mti->mti_svname);
1709 CERROR("Can't write logs for %s (%d)\n",
1710 mti->mti_svname, rc);
1714 /* Just update the params from tunefs in mgs_write_log_params */
1715 CDEBUG(D_MGS, "Update params for %s\n", mti->mti_svname);
1716 mti->mti_flags |= LDD_F_PARAM_FNID;
1719 rc = mgs_write_log_params(obd, fsdb, mti);
1722 up(&fsdb->fsdb_sem);
1727 /* verify that we can handle the old config logs */
1728 int mgs_upgrade_sv_14(struct obd_device *obd, struct mgs_target_info *mti)
1734 /* Create ost log normally, as servers register. Servers
1735 register with their old uuids (from last_rcvd), so old
1736 (MDT and client) logs should work.
1737 - new MDT won't know about old OSTs, only the ones that have
1738 registered, so we need the old MDT log to get the LOV right
1739 in order for old clients to work.
1740 - Old clients connect to the MDT, not the MGS, for their logs, and
1741 will therefore receive the old client log from the MDT /LOGS dir.
1742 - Old clients can continue to use and connect to old or new OSTs
1743 - New clients will contact the MGS for their log
1746 LCONSOLE_INFO("upgrading server %s from pre-1.6\n", mti->mti_svname);
1747 server_mti_print("upgrade", mti);
1749 rc = mgs_find_or_make_fsdb(obd, mti->mti_fsname, &fsdb);
1753 if (fsdb->fsdb_flags & FSDB_LOG_EMPTY) {
1754 LCONSOLE_ERROR("The old client log %s-client is missing. Was "
1755 "tunefs.lustre successful?\n",
1760 if (fsdb->fsdb_gen == 0) {
1761 /* There were no markers in the client log, meaning we have
1762 not updated the logs for this fs */
1763 CDEBUG(D_MGS, "found old, unupdated client log\n");
1766 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
1767 if (mgs_log_is_empty(obd, mti->mti_svname)) {
1768 LCONSOLE_ERROR("The old MDT log %s is missing. Was "
1769 "tunefs.lustre successful?\n",
1774 /* We're starting with an old uuid. Assume old name for lov
1775 as well since the lov entry already exists in the log. */
1776 CDEBUG(D_MGS, "old mds uuid %s\n", mti->mti_uuid);
1777 if (strncmp(mti->mti_uuid, fsdb->fsdb_mdtlov + 4,
1778 strlen(fsdb->fsdb_mdtlov) - 4) != 0) {
1779 CERROR("old mds uuid %s doesn't match log %s (%s)\n",
1780 mti->mti_uuid, fsdb->fsdb_mdtlov,
1781 fsdb->fsdb_mdtlov + 4);
1786 if (!(fsdb->fsdb_flags & FSDB_OLDLOG14)) {
1787 LCONSOLE_ERROR("%s-client is supposedly an old log, but no old "
1788 "LOV or MDT was found. Consider updating the "
1789 "configuration with --writeconf.\n",
1795 /* end COMPAT_146 */
1797 int mgs_erase_log(struct obd_device *obd, char *name)
1799 struct lvfs_run_ctxt saved;
1800 struct llog_handle *llh;
1803 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
1804 rc = llog_create(llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT),
1807 llog_init_handle(llh, LLOG_F_IS_PLAIN, NULL);
1808 rc = llog_destroy(llh);
1809 llog_free_handle(llh);
1811 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
1814 CERROR("failed to clear log %s: %d\n", name, rc);
1819 /* erase all logs for the given fs */
1820 int mgs_erase_logs(struct obd_device *obd, char *fsname)
1822 struct mgs_obd *mgs = &obd->u.mgs;
1823 static struct fs_db *fsdb;
1824 struct list_head dentry_list;
1825 struct l_linux_dirent *dirent, *n;
1826 int rc, len = strlen(fsname);
1829 /* Find all the logs in the CONFIGS directory */
1830 rc = class_dentry_readdir(obd, mgs->mgs_configs_dir,
1831 mgs->mgs_vfsmnt, &dentry_list);
1833 CERROR("Can't read %s dir\n", MOUNT_CONFIGS_DIR);
1837 down(&mgs->mgs_sem);
1839 /* Delete the fs db */
1840 fsdb = mgs_find_fsdb(obd, fsname);
1842 mgs_free_fsdb(obd, fsdb);
1844 list_for_each_entry_safe(dirent, n, &dentry_list, lld_list) {
1845 list_del(&dirent->lld_list);
1846 if (strncmp(fsname, dirent->lld_name, len) == 0) {
1847 CDEBUG(D_MGS, "Removing log %s\n", dirent->lld_name);
1848 mgs_erase_log(obd, dirent->lld_name);
1850 OBD_FREE(dirent, sizeof(*dirent));
1858 /* from llog_swab */
1859 static void print_lustre_cfg(struct lustre_cfg *lcfg)
1864 CDEBUG(D_MGS, "lustre_cfg: %p\n", lcfg);
1865 CDEBUG(D_MGS, "\tlcfg->lcfg_version: %#x\n", lcfg->lcfg_version);
1867 CDEBUG(D_MGS, "\tlcfg->lcfg_command: %#x\n", lcfg->lcfg_command);
1868 CDEBUG(D_MGS, "\tlcfg->lcfg_num: %#x\n", lcfg->lcfg_num);
1869 CDEBUG(D_MGS, "\tlcfg->lcfg_flags: %#x\n", lcfg->lcfg_flags);
1870 CDEBUG(D_MGS, "\tlcfg->lcfg_nid: %s\n", libcfs_nid2str(lcfg->lcfg_nid));
1872 CDEBUG(D_MGS, "\tlcfg->lcfg_bufcount: %d\n", lcfg->lcfg_bufcount);
1873 if (lcfg->lcfg_bufcount < LUSTRE_CFG_MAX_BUFCOUNT)
1874 for (i = 0; i < lcfg->lcfg_bufcount; i++) {
1875 CDEBUG(D_MGS, "\tlcfg->lcfg_buflens[%d]: %d %s\n",
1876 i, lcfg->lcfg_buflens[i],
1877 lustre_cfg_string(lcfg, i));
1882 /* Set a permanent (config log) param for a target or fs */
1883 int mgs_setparam(struct obd_device *obd, struct lustre_cfg *lcfg, char *fsname)
1886 struct mgs_target_info *mti;
1887 char *devname, *param;
1892 print_lustre_cfg(lcfg);
1894 /* lustre, lustre-mdtlov, lustre-client, lustre-MDT0000 */
1895 devname = lustre_cfg_string(lcfg, 0);
1896 param = lustre_cfg_string(lcfg, 1);
1898 /* Assume device name embedded in param:
1899 lustre-OST0000.osc.max_dirty_mb=32 */
1900 ptr = strchr(param, '.');
1908 LCONSOLE_ERROR("No target specified: %s\n", param);
1912 /* Extract fsname */
1913 ptr = strchr(devname, '-');
1914 memset(fsname, 0, MTI_NAME_MAXLEN);
1916 /* assume devname is the fsname */
1917 strncpy(fsname, devname, MTI_NAME_MAXLEN);
1919 strncpy(fsname, devname, ptr - devname);
1921 fsname[MTI_NAME_MAXLEN - 1] = 0;
1922 CDEBUG(D_MGS, "setparam on fs %s device %s\n", fsname, devname);
1924 rc = mgs_find_or_make_fsdb(obd, fsname, &fsdb);
1927 if (fsdb->fsdb_flags & FSDB_LOG_EMPTY) {
1928 CERROR("No filesystem targets for %s. cfg_device from lctl "
1929 "is '%s'\n", fsname, devname);
1930 mgs_free_fsdb(obd, fsdb);
1934 /* Create a fake mti to hold everything */
1937 GOTO(out, rc = -ENOMEM);
1938 strncpy(mti->mti_fsname, fsname, MTI_NAME_MAXLEN);
1939 strncpy(mti->mti_svname, devname, MTI_NAME_MAXLEN);
1940 strncpy(mti->mti_params, param, sizeof(mti->mti_params));
1941 rc = server_name2index(mti->mti_svname, &mti->mti_stripe_index, &tmp);
1943 /* Not a valid server; may be only fsname */
1946 /* Strip -osc or -mdc suffix from svname */
1947 if (server_make_name(rc, mti->mti_stripe_index, mti->mti_fsname,
1949 GOTO(out, rc = -EINVAL);
1951 mti->mti_flags = rc | LDD_F_PARAM_FNID;
1953 down(&fsdb->fsdb_sem);
1954 rc = mgs_write_log_params(obd, fsdb, mti);
1955 up(&fsdb->fsdb_sem);
1964 /******************** unused *********************/
1965 static int mgs_backup_llog(struct obd_device *obd, char* fsname)
1967 struct file *filp, *bak_filp;
1968 struct lvfs_run_ctxt saved;
1969 char *logname, *buf;
1970 loff_t soff = 0 , doff = 0;
1971 int count = 4096, len;
1974 OBD_ALLOC(logname, PATH_MAX);
1975 if (logname == NULL)
1978 OBD_ALLOC(buf, count);
1980 GOTO(out , rc = -ENOMEM);
1982 len = snprintf(logname, PATH_MAX, "%s/%s.bak",
1983 MOUNT_CONFIGS_DIR, fsname);
1985 if (len >= PATH_MAX - 1) {
1986 GOTO(out, -ENAMETOOLONG);
1989 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
1991 bak_filp = l_filp_open(logname, O_RDWR|O_CREAT|O_TRUNC, 0660);
1992 if (IS_ERR(bak_filp)) {
1993 rc = PTR_ERR(bak_filp);
1994 CERROR("backup logfile open %s: %d\n", logname, rc);
1997 sprintf(logname, "%s/%s", MOUNT_CONFIGS_DIR, fsname);
1998 filp = l_filp_open(logname, O_RDONLY, 0);
2001 CERROR("logfile open %s: %d\n", logname, rc);
2005 while ((rc = lustre_fread(filp, buf, count, &soff)) > 0) {
2006 rc = lustre_fwrite(bak_filp, buf, count, &doff);
2010 filp_close(filp, 0);
2012 filp_close(bak_filp, 0);
2014 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
2017 OBD_FREE(buf, count);
2018 OBD_FREE(logname, PATH_MAX);