1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
6 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 only,
10 * as published by the Free Software Foundation.
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License version 2 for more details (a copy is included
16 * in the LICENSE file that accompanied this code).
18 * You should have received a copy of the GNU General Public License
19 * version 2 along with this program; If not, see
20 * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
22 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
23 * CA 95054 USA or visit www.sun.com if you need additional information or
29 * Copyright 2008 Sun Microsystems, Inc. All rights reserved
30 * Use is subject to license terms.
33 * This file is part of Lustre, http://www.lustre.org/
34 * Lustre is a trademark of Sun Microsystems, Inc.
36 * lustre/mgs/mgs_llog.c
38 * Lustre Management Server (mgs) config llog creation
40 * Author: Nathan Rutman <nathan@clusterfs.com>
46 #define DEBUG_SUBSYSTEM S_MGS
47 #define D_MGS D_CONFIG
50 #include <linux/module.h>
51 #include <linux/pagemap.h>
57 #include <obd_class.h>
58 #include <lustre_log.h>
60 #include <libcfs/list.h>
61 #include <linux/lvfs.h>
62 #include <lustre_fsfilt.h>
63 #include <lustre_disk.h>
64 #include <lustre_param.h>
65 #include <lustre_sec.h>
66 #include "mgs_internal.h"
68 /********************** Class functions ********************/
70 /* Caller must list_del and OBD_FREE each dentry from the list */
71 int class_dentry_readdir(struct obd_device *obd, struct dentry *dir,
72 struct vfsmount *inmnt,
73 cfs_list_t *dentry_list){
74 /* see mds_cleanup_pending */
75 struct lvfs_run_ctxt saved;
77 struct dentry *dentry;
82 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
85 GOTO(out_pop, rc = PTR_ERR(dentry));
89 GOTO(out_pop, rc = PTR_ERR(mnt));
92 file = dentry_open(dentry, mnt, O_RDONLY);
94 /* dentry_open_it() drops the dentry, mnt refs */
95 GOTO(out_pop, rc = PTR_ERR(file));
97 CFS_INIT_LIST_HEAD(dentry_list);
98 rc = l_readdir(file, dentry_list);
100 /* filp_close->fput() drops the dentry, mnt refs */
103 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
107 /******************** DB functions *********************/
109 static inline int name_create(char **newname, char *prefix, char *suffix)
112 OBD_ALLOC(*newname, strlen(prefix) + strlen(suffix) + 1);
115 sprintf(*newname, "%s%s", prefix, suffix);
119 static inline void name_destroy(char **name)
122 OBD_FREE(*name, strlen(*name) + 1);
126 struct mgs_fsdb_handler_data
132 /* from the (client) config log, figure out:
133 1. which ost's/mdt's are configured (by index)
134 2. what the last config step is
135 3. COMPAT_146 lov name
136 4. COMPAT_146 mdt lov name
137 5. COMPAT_146 mdc name
138 6. COMPAT_18 osc name
140 /* It might be better to have a separate db file, instead of parsing the info
141 out of the client log. This is slow and potentially error-prone. */
142 static int mgs_fsdb_handler(struct llog_handle *llh, struct llog_rec_hdr *rec,
145 struct mgs_fsdb_handler_data *d = (struct mgs_fsdb_handler_data *) data;
146 struct fs_db *fsdb = d->fsdb;
147 int cfg_len = rec->lrh_len;
148 char *cfg_buf = (char*) (rec + 1);
149 struct lustre_cfg *lcfg;
154 if (rec->lrh_type != OBD_CFG_REC) {
155 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
159 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
161 CERROR("Insane cfg\n");
165 lcfg = (struct lustre_cfg *)cfg_buf;
167 CDEBUG(D_INFO, "cmd %x %s %s\n", lcfg->lcfg_command,
168 lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));
170 /* Figure out ost indicies */
171 /* lov_modify_tgts add 0:lov1 1:ost1_UUID 2(index):0 3(gen):1 */
172 if (lcfg->lcfg_command == LCFG_LOV_ADD_OBD ||
173 lcfg->lcfg_command == LCFG_LOV_DEL_OBD) {
174 index = simple_strtoul(lustre_cfg_string(lcfg, 2),
176 CDEBUG(D_MGS, "OST index for %s is %u (%s)\n",
177 lustre_cfg_string(lcfg, 1), index,
178 lustre_cfg_string(lcfg, 2));
179 cfs_set_bit(index, fsdb->fsdb_ost_index_map);
182 /* Figure out mdt indicies */
183 /* attach 0:MDC_uml1_mdsA_MNT_client 1:mdc 2:1d834_MNT_client_03f */
184 if ((lcfg->lcfg_command == LCFG_ATTACH) &&
185 (strcmp(lustre_cfg_string(lcfg, 1), LUSTRE_MDC_NAME) == 0)) {
186 rc = server_name2index(lustre_cfg_string(lcfg, 0),
188 if (rc != LDD_F_SV_TYPE_MDT) {
189 CWARN("Unparsable MDC name %s, assuming index 0\n",
190 lustre_cfg_string(lcfg, 0));
194 CDEBUG(D_MGS, "MDT index is %u\n", index);
195 cfs_set_bit(index, fsdb->fsdb_mdt_index_map);
199 /* figure out the old LOV name. fsdb_gen = 0 means old log */
200 /* #01 L attach 0:lov_mdsA 1:lov 2:cdbe9_lov_mdsA_dc8cf7f3bb */
201 if ((fsdb->fsdb_gen == 0) && (lcfg->lcfg_command == LCFG_ATTACH) &&
202 (strcmp(lustre_cfg_string(lcfg, 1), LUSTRE_LOV_NAME) == 0)) {
203 fsdb->fsdb_flags |= FSDB_OLDLOG14;
204 name_destroy(&fsdb->fsdb_clilov);
205 rc = name_create(&fsdb->fsdb_clilov,
206 lustre_cfg_string(lcfg, 0), "");
209 CDEBUG(D_MGS, "client lov name is %s\n", fsdb->fsdb_clilov);
212 /* figure out the old MDT lov name from the MDT uuid */
213 if ((fsdb->fsdb_gen == 0) && (lcfg->lcfg_command == LCFG_SETUP) &&
214 (strncmp(lustre_cfg_string(lcfg, 0), "MDC_", 4) == 0)) {
216 fsdb->fsdb_flags |= FSDB_OLDLOG14;
217 ptr = strstr(lustre_cfg_string(lcfg, 1), "_UUID");
219 CERROR("Can't parse MDT uuid %s\n",
220 lustre_cfg_string(lcfg, 1));
224 name_destroy(&fsdb->fsdb_mdtlov);
225 rc = name_create(&fsdb->fsdb_mdtlov,
226 "lov_", lustre_cfg_string(lcfg, 1));
229 name_destroy(&fsdb->fsdb_mdc);
230 rc = name_create(&fsdb->fsdb_mdc,
231 lustre_cfg_string(lcfg, 0), "");
234 CDEBUG(D_MGS, "MDT lov name is %s\n", fsdb->fsdb_mdtlov);
239 * compat to 1.8, check osc name used by MDT0 to OSTs, bz18548.
241 if (fsdb->fsdb_fl_oscname_18 == 0 &&
242 lcfg->lcfg_command == LCFG_ATTACH &&
243 strcmp(lustre_cfg_string(lcfg, 1), LUSTRE_OSC_NAME) == 0) {
244 if (OBD_OCD_VERSION_MAJOR(d->ver) == 1 &&
245 OBD_OCD_VERSION_MINOR(d->ver) <= 8) {
246 CWARN("MDT using 1.8 OSC name scheme\n");
247 fsdb->fsdb_fl_oscname_18 = 1;
251 if (lcfg->lcfg_command == LCFG_MARKER) {
252 struct cfg_marker *marker;
253 marker = lustre_cfg_buf(lcfg, 1);
255 d->ver = marker->cm_vers;
257 /* Keep track of the latest marker step */
258 fsdb->fsdb_gen = max(fsdb->fsdb_gen, marker->cm_step);
264 /* fsdb->fsdb_sem is already held in mgs_find_or_make_fsdb*/
265 static int mgs_get_fsdb_from_llog(struct obd_device *obd, struct fs_db *fsdb)
268 struct llog_handle *loghandle;
269 struct lvfs_run_ctxt saved;
270 struct llog_ctxt *ctxt;
271 struct mgs_fsdb_handler_data d = { fsdb, 0 };
275 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
276 LASSERT(ctxt != NULL);
277 name_create(&logname, fsdb->fsdb_name, "-client");
278 cfs_down(&fsdb->fsdb_sem);
279 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
280 rc = llog_create(ctxt, &loghandle, NULL, logname);
284 rc = llog_init_handle(loghandle, LLOG_F_IS_PLAIN, NULL);
288 if (llog_get_size(loghandle) <= 1)
289 fsdb->fsdb_flags |= FSDB_LOG_EMPTY;
291 rc = llog_process(loghandle, mgs_fsdb_handler, (void *) &d, NULL);
292 CDEBUG(D_INFO, "get_db = %d\n", rc);
294 rc2 = llog_close(loghandle);
298 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
299 cfs_up(&fsdb->fsdb_sem);
300 name_destroy(&logname);
306 static void mgs_free_fsdb_srpc(struct fs_db *fsdb)
308 struct mgs_tgt_srpc_conf *tgtconf;
310 /* free target-specific rules */
311 while (fsdb->fsdb_srpc_tgt) {
312 tgtconf = fsdb->fsdb_srpc_tgt;
313 fsdb->fsdb_srpc_tgt = tgtconf->mtsc_next;
315 LASSERT(tgtconf->mtsc_tgt);
317 sptlrpc_rule_set_free(&tgtconf->mtsc_rset);
318 OBD_FREE(tgtconf->mtsc_tgt, strlen(tgtconf->mtsc_tgt) + 1);
319 OBD_FREE_PTR(tgtconf);
322 /* free general rules */
323 sptlrpc_rule_set_free(&fsdb->fsdb_srpc_gen);
326 static struct fs_db *mgs_find_fsdb(struct obd_device *obd, char *fsname)
328 struct mgs_obd *mgs = &obd->u.mgs;
332 cfs_list_for_each(tmp, &mgs->mgs_fs_db_list) {
333 fsdb = cfs_list_entry(tmp, struct fs_db, fsdb_list);
334 if (strcmp(fsdb->fsdb_name, fsname) == 0)
340 /* caller must hold the mgs->mgs_fs_db_lock */
341 static struct fs_db *mgs_new_fsdb(struct obd_device *obd, char *fsname)
343 struct mgs_obd *mgs = &obd->u.mgs;
348 if (strlen(fsname) >= sizeof(fsdb->fsdb_name)) {
349 CERROR("fsname %s is too long\n", fsname);
357 strcpy(fsdb->fsdb_name, fsname);
358 cfs_sema_init(&fsdb->fsdb_sem, 1);
359 fsdb->fsdb_fl_udesc = 1;
361 if (strcmp(fsname, MGSSELF_NAME) == 0) {
362 fsdb->fsdb_fl_mgsself = 1;
364 OBD_ALLOC(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
365 OBD_ALLOC(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
366 if (!fsdb->fsdb_ost_index_map || !fsdb->fsdb_mdt_index_map) {
367 CERROR("No memory for index maps\n");
371 rc = name_create(&fsdb->fsdb_mdtlov, fsname, "-mdtlov");
374 rc = name_create(&fsdb->fsdb_mdtlmv, fsname, "-mdtlmv");
377 rc = name_create(&fsdb->fsdb_clilov, fsname, "-clilov");
380 rc = name_create(&fsdb->fsdb_clilmv, fsname, "-clilmv");
384 lproc_mgs_add_live(obd, fsdb);
387 cfs_list_add(&fsdb->fsdb_list, &mgs->mgs_fs_db_list);
391 if (fsdb->fsdb_ost_index_map)
392 OBD_FREE(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
393 if (fsdb->fsdb_mdt_index_map)
394 OBD_FREE(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
395 name_destroy(&fsdb->fsdb_clilov);
396 name_destroy(&fsdb->fsdb_clilmv);
397 name_destroy(&fsdb->fsdb_mdtlov);
398 name_destroy(&fsdb->fsdb_mdtlmv);
403 static void mgs_free_fsdb(struct obd_device *obd, struct fs_db *fsdb)
405 /* wait for anyone with the sem */
406 cfs_down(&fsdb->fsdb_sem);
407 lproc_mgs_del_live(obd, fsdb);
408 cfs_list_del(&fsdb->fsdb_list);
409 if (fsdb->fsdb_ost_index_map)
410 OBD_FREE(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
411 if (fsdb->fsdb_mdt_index_map)
412 OBD_FREE(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
413 name_destroy(&fsdb->fsdb_clilov);
414 name_destroy(&fsdb->fsdb_clilmv);
415 name_destroy(&fsdb->fsdb_mdtlov);
416 name_destroy(&fsdb->fsdb_mdtlmv);
417 name_destroy(&fsdb->fsdb_mdc);
418 mgs_free_fsdb_srpc(fsdb);
422 int mgs_init_fsdb_list(struct obd_device *obd)
424 struct mgs_obd *mgs = &obd->u.mgs;
425 CFS_INIT_LIST_HEAD(&mgs->mgs_fs_db_list);
429 int mgs_cleanup_fsdb_list(struct obd_device *obd)
431 struct mgs_obd *mgs = &obd->u.mgs;
433 cfs_list_t *tmp, *tmp2;
434 cfs_down(&mgs->mgs_sem);
435 cfs_list_for_each_safe(tmp, tmp2, &mgs->mgs_fs_db_list) {
436 fsdb = cfs_list_entry(tmp, struct fs_db, fsdb_list);
437 mgs_free_fsdb(obd, fsdb);
439 cfs_up(&mgs->mgs_sem);
443 int mgs_find_or_make_fsdb(struct obd_device *obd, char *name,
446 struct mgs_obd *mgs = &obd->u.mgs;
450 cfs_down(&mgs->mgs_sem);
451 fsdb = mgs_find_fsdb(obd, name);
453 cfs_up(&mgs->mgs_sem);
458 CDEBUG(D_MGS, "Creating new db\n");
459 fsdb = mgs_new_fsdb(obd, name);
460 cfs_up(&mgs->mgs_sem);
464 if (!fsdb->fsdb_fl_mgsself) {
465 /* populate the db from the client llog */
466 rc = mgs_get_fsdb_from_llog(obd, fsdb);
468 CERROR("Can't get db from client log %d\n", rc);
469 mgs_free_fsdb(obd, fsdb);
474 /* populate srpc rules from params llog */
475 rc = mgs_get_fsdb_srpc_from_llog(obd, fsdb);
477 CERROR("Can't get db from params log %d\n", rc);
478 mgs_free_fsdb(obd, fsdb);
489 -1= empty client log */
490 int mgs_check_index(struct obd_device *obd, struct mgs_target_info *mti)
497 LASSERT(!(mti->mti_flags & LDD_F_NEED_INDEX));
499 rc = mgs_find_or_make_fsdb(obd, mti->mti_fsname, &fsdb);
501 CERROR("Can't get db for %s\n", mti->mti_fsname);
505 if (fsdb->fsdb_flags & FSDB_LOG_EMPTY)
508 if (mti->mti_flags & LDD_F_SV_TYPE_OST)
509 imap = fsdb->fsdb_ost_index_map;
510 else if (mti->mti_flags & LDD_F_SV_TYPE_MDT)
511 imap = fsdb->fsdb_mdt_index_map;
515 if (cfs_test_bit(mti->mti_stripe_index, imap))
520 static __inline__ int next_index(void *index_map, int map_len)
523 for (i = 0; i < map_len * 8; i++)
524 if (!cfs_test_bit(i, index_map)) {
527 CERROR("max index %d exceeded.\n", i);
532 0 newly marked as in use
534 +EALREADY for update of an old index */
535 int mgs_set_index(struct obd_device *obd, struct mgs_target_info *mti)
542 rc = mgs_find_or_make_fsdb(obd, mti->mti_fsname, &fsdb);
544 CERROR("Can't get db for %s\n", mti->mti_fsname);
548 if (mti->mti_flags & LDD_F_SV_TYPE_OST)
549 imap = fsdb->fsdb_ost_index_map;
550 else if (mti->mti_flags & LDD_F_SV_TYPE_MDT)
551 imap = fsdb->fsdb_mdt_index_map;
555 if (mti->mti_flags & LDD_F_NEED_INDEX) {
556 rc = next_index(imap, INDEX_MAP_SIZE);
559 mti->mti_stripe_index = rc;
562 if (mti->mti_stripe_index >= INDEX_MAP_SIZE * 8) {
563 LCONSOLE_ERROR_MSG(0x13f, "Server %s requested index %d, "
564 "but the max index is %d.\n",
565 mti->mti_svname, mti->mti_stripe_index,
570 if (cfs_test_bit(mti->mti_stripe_index, imap)) {
571 if ((mti->mti_flags & LDD_F_VIRGIN) &&
572 !(mti->mti_flags & LDD_F_WRITECONF)) {
573 LCONSOLE_ERROR_MSG(0x140, "Server %s requested index "
574 "%d, but that index is already in "
575 "use. Use --writeconf to force\n",
577 mti->mti_stripe_index);
580 CDEBUG(D_MGS, "Server %s updating index %d\n",
581 mti->mti_svname, mti->mti_stripe_index);
586 cfs_set_bit(mti->mti_stripe_index, imap);
587 fsdb->fsdb_flags &= ~FSDB_LOG_EMPTY;
588 server_make_name(mti->mti_flags, mti->mti_stripe_index,
589 mti->mti_fsname, mti->mti_svname);
591 CDEBUG(D_MGS, "Set index for %s to %d\n", mti->mti_svname,
592 mti->mti_stripe_index);
597 struct mgs_modify_lookup {
598 struct cfg_marker mml_marker;
602 static int mgs_modify_handler(struct llog_handle *llh, struct llog_rec_hdr *rec,
605 struct mgs_modify_lookup *mml = (struct mgs_modify_lookup *)data;
606 struct cfg_marker *marker;
607 struct lustre_cfg *lcfg = (struct lustre_cfg *)(rec + 1);
608 int cfg_len = rec->lrh_len - sizeof(struct llog_rec_hdr) -
609 sizeof(struct llog_rec_tail);
613 if (rec->lrh_type != OBD_CFG_REC) {
614 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
618 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
620 CERROR("Insane cfg\n");
624 /* We only care about markers */
625 if (lcfg->lcfg_command != LCFG_MARKER)
628 marker = lustre_cfg_buf(lcfg, 1);
629 if ((strcmp(mml->mml_marker.cm_comment, marker->cm_comment) == 0) &&
630 (strcmp(mml->mml_marker.cm_tgtname, marker->cm_tgtname) == 0) &&
631 !(marker->cm_flags & CM_SKIP)) {
632 /* Found a non-skipped marker match */
633 CDEBUG(D_MGS, "Changing rec %u marker %d %x->%x: %s %s\n",
634 rec->lrh_index, marker->cm_step,
635 marker->cm_flags, mml->mml_marker.cm_flags,
636 marker->cm_tgtname, marker->cm_comment);
637 /* Overwrite the old marker llog entry */
638 marker->cm_flags &= ~CM_EXCLUDE; /* in case we're unexcluding */
639 marker->cm_flags |= mml->mml_marker.cm_flags;
640 marker->cm_canceltime = mml->mml_marker.cm_canceltime;
641 /* Header and tail are added back to lrh_len in
642 llog_lvfs_write_rec */
643 rec->lrh_len = cfg_len;
644 rc = llog_write_rec(llh, rec, NULL, 0, (void *)lcfg,
653 /* Modify an existing config log record (for CM_SKIP or CM_EXCLUDE) */
654 static int mgs_modify(struct obd_device *obd, struct fs_db *fsdb,
655 struct mgs_target_info *mti, char *logname,
656 char *devname, char *comment, int flags)
658 struct llog_handle *loghandle;
659 struct lvfs_run_ctxt saved;
660 struct llog_ctxt *ctxt;
661 struct mgs_modify_lookup *mml;
665 CDEBUG(D_MGS, "modify %s/%s/%s fl=%x\n", logname, devname, comment,
668 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
670 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
671 LASSERT(ctxt != NULL);
672 rc = llog_create(ctxt, &loghandle, NULL, logname);
676 rc = llog_init_handle(loghandle, LLOG_F_IS_PLAIN, NULL);
680 if (llog_get_size(loghandle) <= 1)
681 GOTO(out_close, rc = 0);
685 GOTO(out_close, rc = -ENOMEM);
686 strcpy(mml->mml_marker.cm_comment, comment);
687 strcpy(mml->mml_marker.cm_tgtname, devname);
688 /* Modify mostly means cancel */
689 mml->mml_marker.cm_flags = flags;
690 mml->mml_marker.cm_canceltime = flags ? cfs_time_current_sec() : 0;
691 mml->mml_modified = 0;
692 rc = llog_process(loghandle, mgs_modify_handler, (void *)mml, NULL);
693 if (!rc && !mml->mml_modified)
698 rc2 = llog_close(loghandle);
702 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
703 if (rc && rc != -ENODEV)
704 CERROR("modify %s/%s failed %d\n",
705 mti->mti_svname, comment, rc);
710 /******************** config log recording functions *********************/
712 static int record_lcfg(struct obd_device *obd, struct llog_handle *llh,
713 struct lustre_cfg *lcfg)
715 struct lvfs_run_ctxt saved;
716 struct llog_rec_hdr rec;
722 LASSERT(llh->lgh_ctxt);
724 buflen = lustre_cfg_len(lcfg->lcfg_bufcount,
726 rec.lrh_len = llog_data_len(buflen);
727 rec.lrh_type = OBD_CFG_REC;
729 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
730 /* idx = -1 means append */
731 rc = llog_write_rec(llh, &rec, NULL, 0, (void *)lcfg, -1);
732 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
734 CERROR("failed %d\n", rc);
738 static int record_base(struct obd_device *obd, struct llog_handle *llh,
739 char *cfgname, lnet_nid_t nid, int cmd,
740 char *s1, char *s2, char *s3, char *s4)
742 struct lustre_cfg_bufs bufs;
743 struct lustre_cfg *lcfg;
746 CDEBUG(D_MGS, "lcfg %s %#x %s %s %s %s\n", cfgname,
747 cmd, s1, s2, s3, s4);
749 lustre_cfg_bufs_reset(&bufs, cfgname);
751 lustre_cfg_bufs_set_string(&bufs, 1, s1);
753 lustre_cfg_bufs_set_string(&bufs, 2, s2);
755 lustre_cfg_bufs_set_string(&bufs, 3, s3);
757 lustre_cfg_bufs_set_string(&bufs, 4, s4);
759 lcfg = lustre_cfg_new(cmd, &bufs);
762 lcfg->lcfg_nid = nid;
764 rc = record_lcfg(obd, llh, lcfg);
766 lustre_cfg_free(lcfg);
769 CERROR("error %d: lcfg %s %#x %s %s %s %s\n", rc, cfgname,
770 cmd, s1, s2, s3, s4);
776 static inline int record_add_uuid(struct obd_device *obd,
777 struct llog_handle *llh,
778 uint64_t nid, char *uuid)
780 return record_base(obd,llh,NULL,nid,LCFG_ADD_UUID,uuid,0,0,0);
784 static inline int record_add_conn(struct obd_device *obd,
785 struct llog_handle *llh,
789 return record_base(obd,llh,devname,0,LCFG_ADD_CONN,uuid,0,0,0);
792 static inline int record_attach(struct obd_device *obd, struct llog_handle *llh,
793 char *devname, char *type, char *uuid)
795 return record_base(obd,llh,devname,0,LCFG_ATTACH,type,uuid,0,0);
798 static inline int record_setup(struct obd_device *obd, struct llog_handle *llh,
800 char *s1, char *s2, char *s3, char *s4)
802 return record_base(obd,llh,devname,0,LCFG_SETUP,s1,s2,s3,s4);
805 static int record_lov_setup(struct obd_device *obd, struct llog_handle *llh,
806 char *devname, struct lov_desc *desc)
808 struct lustre_cfg_bufs bufs;
809 struct lustre_cfg *lcfg;
812 lustre_cfg_bufs_reset(&bufs, devname);
813 lustre_cfg_bufs_set(&bufs, 1, desc, sizeof(*desc));
814 lcfg = lustre_cfg_new(LCFG_SETUP, &bufs);
817 rc = record_lcfg(obd, llh, lcfg);
819 lustre_cfg_free(lcfg);
823 static int record_lmv_setup(struct obd_device *obd, struct llog_handle *llh,
824 char *devname, struct lmv_desc *desc)
826 struct lustre_cfg_bufs bufs;
827 struct lustre_cfg *lcfg;
830 lustre_cfg_bufs_reset(&bufs, devname);
831 lustre_cfg_bufs_set(&bufs, 1, desc, sizeof(*desc));
832 lcfg = lustre_cfg_new(LCFG_SETUP, &bufs);
834 rc = record_lcfg(obd, llh, lcfg);
836 lustre_cfg_free(lcfg);
840 static inline int record_mdc_add(struct obd_device *obd,
841 struct llog_handle *llh,
842 char *logname, char *mdcuuid,
843 char *mdtuuid, char *index,
846 return record_base(obd,llh,logname,0,LCFG_ADD_MDC,
847 mdtuuid,index,gen,mdcuuid);
850 static inline int record_lov_add(struct obd_device *obd,
851 struct llog_handle *llh,
852 char *lov_name, char *ost_uuid,
853 char *index, char *gen)
855 return record_base(obd,llh,lov_name,0,LCFG_LOV_ADD_OBD,
856 ost_uuid,index,gen,0);
859 static inline int record_mount_opt(struct obd_device *obd,
860 struct llog_handle *llh,
861 char *profile, char *lov_name,
864 return record_base(obd,llh,NULL,0,LCFG_MOUNTOPT,
865 profile,lov_name,mdc_name,0);
868 static int record_marker(struct obd_device *obd, struct llog_handle *llh,
869 struct fs_db *fsdb, __u32 flags,
870 char *tgtname, char *comment)
872 struct cfg_marker marker;
873 struct lustre_cfg_bufs bufs;
874 struct lustre_cfg *lcfg;
877 if (flags & CM_START)
879 marker.cm_step = fsdb->fsdb_gen;
880 marker.cm_flags = flags;
881 marker.cm_vers = LUSTRE_VERSION_CODE;
882 strncpy(marker.cm_tgtname, tgtname, sizeof(marker.cm_tgtname));
883 strncpy(marker.cm_comment, comment, sizeof(marker.cm_comment));
884 marker.cm_createtime = cfs_time_current_sec();
885 marker.cm_canceltime = 0;
886 lustre_cfg_bufs_reset(&bufs, NULL);
887 lustre_cfg_bufs_set(&bufs, 1, &marker, sizeof(marker));
888 lcfg = lustre_cfg_new(LCFG_MARKER, &bufs);
891 rc = record_lcfg(obd, llh, lcfg);
893 lustre_cfg_free(lcfg);
897 static int record_start_log(struct obd_device *obd,
898 struct llog_handle **llh, char *name)
900 static struct obd_uuid cfg_uuid = { .uuid = "config_uuid" };
901 struct lvfs_run_ctxt saved;
902 struct llog_ctxt *ctxt;
906 GOTO(out, rc = -EBUSY);
908 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
910 GOTO(out, rc = -ENODEV);
912 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
913 rc = llog_create(ctxt, llh, NULL, name);
915 llog_init_handle(*llh, LLOG_F_IS_PLAIN, &cfg_uuid);
919 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
924 CERROR("Can't start log %s: %d\n", name, rc);
929 static int record_end_log(struct obd_device *obd, struct llog_handle **llh)
931 struct lvfs_run_ctxt saved;
934 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
936 rc = llog_close(*llh);
939 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
943 static int mgs_log_is_empty(struct obd_device *obd, char *name)
945 struct lvfs_run_ctxt saved;
946 struct llog_handle *llh;
947 struct llog_ctxt *ctxt;
950 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
951 LASSERT(ctxt != NULL);
952 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
953 rc = llog_create(ctxt, &llh, NULL, name);
955 llog_init_handle(llh, LLOG_F_IS_PLAIN, NULL);
956 rc = llog_get_size(llh);
959 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
961 /* header is record 1 */
965 /******************** config "macros" *********************/
967 /* write an lcfg directly into a log (with markers) */
968 static int mgs_write_log_direct(struct obd_device *obd, struct fs_db *fsdb,
969 char *logname, struct lustre_cfg *lcfg,
970 char *devname, char *comment)
972 struct llog_handle *llh = NULL;
979 rc = record_start_log(obd, &llh, logname);
983 /* FIXME These should be a single journal transaction */
984 rc = record_marker(obd, llh, fsdb, CM_START, devname, comment);
986 rc = record_lcfg(obd, llh, lcfg);
988 rc = record_marker(obd, llh, fsdb, CM_END, devname, comment);
989 rc = record_end_log(obd, &llh);
994 /* write the lcfg in all logs for the given fs */
995 int mgs_write_log_direct_all(struct obd_device *obd, struct fs_db *fsdb,
996 struct mgs_target_info *mti,
997 struct lustre_cfg *lcfg,
998 char *devname, char *comment)
1000 struct mgs_obd *mgs = &obd->u.mgs;
1001 cfs_list_t dentry_list;
1002 struct l_linux_dirent *dirent, *n;
1003 char *fsname = mti->mti_fsname;
1005 int rc = 0, len = strlen(fsname);
1008 /* We need to set params for any future logs
1009 as well. FIXME Append this file to every new log.
1010 Actually, we should store as params (text), not llogs. Or
1012 name_create(&logname, fsname, "-params");
1013 if (mgs_log_is_empty(obd, logname)) {
1014 struct llog_handle *llh = NULL;
1015 rc = record_start_log(obd, &llh, logname);
1016 record_end_log(obd, &llh);
1018 name_destroy(&logname);
1022 /* Find all the logs in the CONFIGS directory */
1023 rc = class_dentry_readdir(obd, mgs->mgs_configs_dir,
1024 mgs->mgs_vfsmnt, &dentry_list);
1026 CERROR("Can't read %s dir\n", MOUNT_CONFIGS_DIR);
1030 /* Could use fsdb index maps instead of directory listing */
1031 cfs_list_for_each_entry_safe(dirent, n, &dentry_list, lld_list) {
1032 cfs_list_del(&dirent->lld_list);
1033 /* don't write to sptlrpc rule log */
1034 if (strncmp(fsname, dirent->lld_name, len) == 0 &&
1035 strstr(dirent->lld_name, "-sptlrpc") == NULL) {
1036 CDEBUG(D_MGS, "Changing log %s\n", dirent->lld_name);
1037 /* Erase any old settings of this same parameter */
1038 mgs_modify(obd, fsdb, mti, dirent->lld_name, devname,
1040 /* Write the new one */
1042 rc = mgs_write_log_direct(obd, fsdb,
1047 CERROR("err %d writing log %s\n", rc,
1051 OBD_FREE(dirent, sizeof(*dirent));
1059 struct mgs_target_info *comp_tmti;
1060 struct mgs_target_info *comp_mti;
1061 struct fs_db *comp_fsdb;
1062 struct obd_device *comp_obd;
1065 static int mgs_write_log_mdc_to_mdt(struct obd_device *, struct fs_db *,
1066 struct mgs_target_info *, char *);
1068 static int mgs_steal_llog_handler(struct llog_handle *llh,
1069 struct llog_rec_hdr *rec,
1072 struct obd_device * obd;
1073 struct mgs_target_info *mti, *tmti;
1075 int cfg_len = rec->lrh_len;
1076 char *cfg_buf = (char*) (rec + 1);
1077 struct lustre_cfg *lcfg;
1079 struct llog_handle *mdt_llh = NULL;
1080 static int got_an_osc_or_mdc = 0;
1081 /* 0: not found any osc/mdc;
1085 static int last_step = -1;
1089 mti = ((struct temp_comp*)data)->comp_mti;
1090 tmti = ((struct temp_comp*)data)->comp_tmti;
1091 fsdb = ((struct temp_comp*)data)->comp_fsdb;
1092 obd = ((struct temp_comp*)data)->comp_obd;
1094 if (rec->lrh_type != OBD_CFG_REC) {
1095 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
1099 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
1101 CERROR("Insane cfg\n");
1105 lcfg = (struct lustre_cfg *)cfg_buf;
1107 if (lcfg->lcfg_command == LCFG_MARKER) {
1108 struct cfg_marker *marker;
1109 marker = lustre_cfg_buf(lcfg, 1);
1110 if (!strncmp(marker->cm_comment,"add osc",7) &&
1111 (marker->cm_flags & CM_START)){
1112 got_an_osc_or_mdc = 1;
1113 rc = record_start_log(obd, &mdt_llh, mti->mti_svname);
1114 rc = record_marker(obd, mdt_llh, fsdb, CM_START,
1115 mti->mti_svname,"add osc(copied)");
1116 rc = record_end_log(obd, &mdt_llh);
1117 last_step = marker->cm_step;
1120 if (!strncmp(marker->cm_comment,"add osc",7) &&
1121 (marker->cm_flags & CM_END)){
1122 LASSERT(last_step == marker->cm_step);
1124 got_an_osc_or_mdc = 0;
1125 rc = record_start_log(obd, &mdt_llh, mti->mti_svname);
1126 rc = record_marker(obd, mdt_llh, fsdb, CM_END,
1127 mti->mti_svname,"add osc(copied)");
1128 rc = record_end_log(obd, &mdt_llh);
1131 if (!strncmp(marker->cm_comment,"add mdc",7) &&
1132 (marker->cm_flags & CM_START)){
1133 got_an_osc_or_mdc = 2;
1134 last_step = marker->cm_step;
1135 memcpy(tmti->mti_svname, marker->cm_tgtname,
1136 strlen(marker->cm_tgtname));
1140 if (!strncmp(marker->cm_comment,"add mdc",7) &&
1141 (marker->cm_flags & CM_END)){
1142 LASSERT(last_step == marker->cm_step);
1144 got_an_osc_or_mdc = 0;
1149 if (got_an_osc_or_mdc == 0 || last_step < 0)
1152 if (lcfg->lcfg_command == LCFG_ADD_UUID) {
1154 nodenid = lcfg->lcfg_nid;
1156 tmti->mti_nids[tmti->mti_nid_count] = nodenid;
1157 tmti->mti_nid_count++;
1162 if (lcfg->lcfg_command == LCFG_SETUP) {
1165 target = lustre_cfg_string(lcfg, 1);
1166 memcpy(tmti->mti_uuid, target, strlen(target));
1170 /* ignore client side sptlrpc_conf_log */
1171 if (lcfg->lcfg_command == LCFG_SPTLRPC_CONF)
1174 if (lcfg->lcfg_command == LCFG_ADD_MDC) {
1177 if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1)
1180 memcpy(tmti->mti_fsname, mti->mti_fsname,
1181 strlen(mti->mti_fsname));
1182 tmti->mti_stripe_index = index;
1184 mgs_write_log_mdc_to_mdt(obd, fsdb, tmti, mti->mti_svname);
1185 memset(tmti, 0, sizeof(*tmti));
1191 /* fsdb->fsdb_sem is already held in mgs_write_log_target*/
1192 /* stealed from mgs_get_fsdb_from_llog*/
1193 static int mgs_steal_llog_for_mdt_from_client(struct obd_device *obd,
1195 struct temp_comp* comp)
1197 struct llog_handle *loghandle;
1198 struct lvfs_run_ctxt saved;
1199 struct mgs_target_info *tmti;
1200 struct llog_ctxt *ctxt;
1204 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
1205 LASSERT(ctxt != NULL);
1207 OBD_ALLOC_PTR(tmti);
1211 comp->comp_tmti = tmti;
1212 comp->comp_obd = obd;
1214 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
1216 rc = llog_create(ctxt, &loghandle, NULL, client_name);
1220 rc = llog_init_handle(loghandle, LLOG_F_IS_PLAIN, NULL);
1222 GOTO(out_close, rc);
1224 rc = llog_process(loghandle, mgs_steal_llog_handler, (void *)comp, NULL);
1225 CDEBUG(D_MGS, "steal llog re = %d\n", rc);
1227 rc2 = llog_close(loghandle);
1231 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
1233 llog_ctxt_put(ctxt);
1237 /* lmv is the second thing for client logs */
1238 /* copied from mgs_write_log_lov. Please refer to that. */
1239 static int mgs_write_log_lmv(struct obd_device *obd, struct fs_db *fsdb,
1240 struct mgs_target_info *mti,
1241 char *logname, char *lmvname)
1243 struct llog_handle *llh = NULL;
1244 struct lmv_desc *lmvdesc;
1249 CDEBUG(D_MGS, "Writing lmv(%s) log for %s\n", lmvname,logname);
1251 OBD_ALLOC_PTR(lmvdesc);
1252 if (lmvdesc == NULL)
1254 lmvdesc->ld_active_tgt_count = 0;
1255 lmvdesc->ld_tgt_count = 0;
1256 sprintf((char*)lmvdesc->ld_uuid.uuid, "%s_UUID", lmvname);
1257 uuid = (char *)lmvdesc->ld_uuid.uuid;
1259 rc = record_start_log(obd, &llh, logname);
1260 rc = record_marker(obd, llh, fsdb, CM_START, lmvname, "lmv setup");
1261 rc = record_attach(obd, llh, lmvname, "lmv", uuid);
1262 rc = record_lmv_setup(obd, llh, lmvname, lmvdesc);
1263 rc = record_marker(obd, llh, fsdb, CM_END, lmvname, "lmv setup");
1264 rc = record_end_log(obd, &llh);
1266 OBD_FREE_PTR(lmvdesc);
1270 /* lov is the first thing in the mdt and client logs */
1271 static int mgs_write_log_lov(struct obd_device *obd, struct fs_db *fsdb,
1272 struct mgs_target_info *mti,
1273 char *logname, char *lovname)
1275 struct llog_handle *llh = NULL;
1276 struct lov_desc *lovdesc;
1281 CDEBUG(D_MGS, "Writing lov(%s) log for %s\n", lovname, logname);
1284 #01 L attach 0:lov_mdsA 1:lov 2:71ccb_lov_mdsA_19f961a9e1
1285 #02 L lov_setup 0:lov_mdsA 1:(struct lov_desc)
1286 uuid=lov1_UUID, stripe count=1, size=1048576, offset=0, pattern=0
1289 /* FIXME just make lov_setup accept empty desc (put uuid in buf 2) */
1290 OBD_ALLOC_PTR(lovdesc);
1291 if (lovdesc == NULL)
1293 lovdesc->ld_magic = LOV_DESC_MAGIC;
1294 lovdesc->ld_tgt_count = 0;
1295 /* Defaults. Can be changed later by lcfg config_param */
1296 lovdesc->ld_default_stripe_count = 1;
1297 lovdesc->ld_pattern = LOV_PATTERN_RAID0;
1298 lovdesc->ld_default_stripe_size = 1024 * 1024;
1299 lovdesc->ld_default_stripe_offset = 0;
1300 lovdesc->ld_qos_maxage = QOS_DEFAULT_MAXAGE;
1301 sprintf((char*)lovdesc->ld_uuid.uuid, "%s_UUID", lovname);
1302 /* can these be the same? */
1303 uuid = (char *)lovdesc->ld_uuid.uuid;
1305 /* This should always be the first entry in a log.
1306 rc = mgs_clear_log(obd, logname); */
1307 rc = record_start_log(obd, &llh, logname);
1310 /* FIXME these should be a single journal transaction */
1311 rc = record_marker(obd, llh, fsdb, CM_START, lovname, "lov setup");
1312 rc = record_attach(obd, llh, lovname, "lov", uuid);
1313 rc = record_lov_setup(obd, llh, lovname, lovdesc);
1314 rc = record_marker(obd, llh, fsdb, CM_END, lovname, "lov setup");
1315 rc = record_end_log(obd, &llh);
1319 OBD_FREE_PTR(lovdesc);
1323 /* add failnids to open log */
1324 static int mgs_write_log_failnids(struct obd_device *obd,
1325 struct mgs_target_info *mti,
1326 struct llog_handle *llh,
1329 char *failnodeuuid = NULL;
1330 char *ptr = mti->mti_params;
1335 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) nal=90 0: 1:uml1_UUID
1336 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
1337 #05 L setup 0:OSC_uml1_ost1_mdsA 1:ost1_UUID 2:uml1_UUID
1338 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) nal=90 0: 1:uml2_UUID
1339 #0x L add_uuid nid=2@elan(0x1000000000002) nal=90 0: 1:uml2_UUID
1340 #07 L add_conn 0:OSC_uml1_ost1_mdsA 1:uml2_UUID
1343 /* Pull failnid info out of params string */
1344 while (class_find_param(ptr, PARAM_FAILNODE, &ptr) == 0) {
1345 while (class_parse_nid(ptr, &nid, &ptr) == 0) {
1346 if (failnodeuuid == NULL) {
1347 /* We don't know the failover node name,
1348 so just use the first nid as the uuid */
1349 rc = name_create(&failnodeuuid,
1350 libcfs_nid2str(nid), "");
1354 CDEBUG(D_MGS, "add nid %s for failover uuid %s, "
1355 "client %s\n", libcfs_nid2str(nid),
1356 failnodeuuid, cliname);
1357 rc = record_add_uuid(obd, llh, nid, failnodeuuid);
1360 rc = record_add_conn(obd, llh, cliname, failnodeuuid);
1361 name_destroy(&failnodeuuid);
1362 failnodeuuid = NULL;
1369 static int mgs_write_log_mdc_to_lmv(struct obd_device *obd, struct fs_db *fsdb,
1370 struct mgs_target_info *mti,
1371 char *logname, char *lmvname)
1373 struct llog_handle *llh = NULL;
1374 char *mdcname, *nodeuuid, *mdcuuid, *lmvuuid;
1379 if (mgs_log_is_empty(obd, logname)) {
1380 CERROR("log is empty! Logical error\n");
1384 CDEBUG(D_MGS, "adding mdc for %s to log %s:lmv(%s)\n",
1385 mti->mti_svname, logname, lmvname);
1387 name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
1388 name_create(&mdcname, mti->mti_svname, "-mdc");
1389 name_create(&mdcuuid, mdcname, "_UUID");
1390 name_create(&lmvuuid, lmvname, "_UUID");
1392 rc = record_start_log(obd, &llh, logname);
1393 rc = record_marker(obd, llh, fsdb, CM_START, mti->mti_svname,
1396 for (i = 0; i < mti->mti_nid_count; i++) {
1397 CDEBUG(D_MGS, "add nid %s for mdt\n",
1398 libcfs_nid2str(mti->mti_nids[i]));
1400 rc = record_add_uuid(obd, llh, mti->mti_nids[i], nodeuuid);
1403 rc = record_attach(obd, llh, mdcname, LUSTRE_MDC_NAME, lmvuuid);
1404 rc = record_setup(obd, llh, mdcname, mti->mti_uuid, nodeuuid, 0, 0);
1405 rc = mgs_write_log_failnids(obd, mti, llh, mdcname);
1406 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
1407 rc = record_mdc_add(obd, llh, lmvname, mdcuuid, mti->mti_uuid,
1409 rc = record_marker(obd, llh, fsdb, CM_END, mti->mti_svname,
1411 rc = record_end_log(obd, &llh);
1413 name_destroy(&lmvuuid);
1414 name_destroy(&mdcuuid);
1415 name_destroy(&mdcname);
1416 name_destroy(&nodeuuid);
1420 /* add new mdc to already existent MDS */
1421 static int mgs_write_log_mdc_to_mdt(struct obd_device *obd, struct fs_db *fsdb,
1422 struct mgs_target_info *mti, char *logname)
1424 struct llog_handle *llh = NULL;
1425 char *nodeuuid, *mdcname, *mdcuuid, *mdtuuid;
1426 int idx = mti->mti_stripe_index;
1431 if (mgs_log_is_empty(obd, mti->mti_svname)) {
1432 CERROR("log is empty! Logical error\n");
1436 CDEBUG(D_MGS, "adding mdc index %d to %s\n", idx, logname);
1438 name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
1439 snprintf(index, sizeof(index), "-mdc%04x", idx);
1440 name_create(&mdcname, logname, index);
1441 name_create(&mdcuuid, mdcname, "_UUID");
1442 name_create(&mdtuuid, logname, "_UUID");
1444 rc = record_start_log(obd, &llh, logname);
1445 rc = record_marker(obd, llh, fsdb, CM_START, mti->mti_svname, "add mdc");
1446 for (i = 0; i < mti->mti_nid_count; i++) {
1447 CDEBUG(D_MGS, "add nid %s for mdt\n",
1448 libcfs_nid2str(mti->mti_nids[i]));
1449 rc = record_add_uuid(obd, llh, mti->mti_nids[i], nodeuuid);
1451 rc = record_attach(obd, llh, mdcname, LUSTRE_MDC_NAME, mdcuuid);
1452 rc = record_setup(obd, llh, mdcname, mti->mti_uuid, nodeuuid, 0, 0);
1453 rc = mgs_write_log_failnids(obd, mti, llh, mdcname);
1454 snprintf(index, sizeof(index), "%d", idx);
1456 rc = record_mdc_add(obd, llh, logname, mdcuuid, mti->mti_uuid,
1458 rc = record_marker(obd, llh, fsdb, CM_END, mti->mti_svname, "add mdc");
1459 rc = record_end_log(obd, &llh);
1461 name_destroy(&mdcuuid);
1462 name_destroy(&mdcname);
1463 name_destroy(&nodeuuid);
1464 name_destroy(&mdtuuid);
1468 static int mgs_write_log_mdt0(struct obd_device *obd, struct fs_db *fsdb,
1469 struct mgs_target_info *mti)
1471 char *log = mti->mti_svname;
1472 struct llog_handle *llh = NULL;
1473 char *uuid, *lovname;
1475 char *ptr = mti->mti_params;
1476 int rc = 0, failout = 0;
1479 OBD_ALLOC(uuid, sizeof(struct obd_uuid));
1483 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
1484 failout = (strncmp(ptr, "failout", 7) == 0);
1486 name_create(&lovname, log, "-mdtlov");
1487 if (mgs_log_is_empty(obd, log))
1488 rc = mgs_write_log_lov(obd, fsdb, mti, log, lovname);
1490 sprintf(uuid, "%s_UUID", log);
1491 sprintf(mdt_index, "%d", mti->mti_stripe_index);
1493 /* add MDT itself */
1494 rc = record_start_log(obd, &llh, log);
1498 /* FIXME this whole fn should be a single journal transaction */
1499 rc = record_marker(obd, llh, fsdb, CM_START, log, "add mdt");
1500 rc = record_attach(obd, llh, log, LUSTRE_MDT_NAME, uuid);
1501 rc = record_mount_opt(obd, llh, log, lovname, NULL);
1502 rc = record_setup(obd, llh, log, uuid, mdt_index, lovname,
1503 failout ? "n" : "f");
1504 rc = record_marker(obd, llh, fsdb, CM_END, log, "add mdt");
1505 rc = record_end_log(obd, &llh);
1507 name_destroy(&lovname);
1508 OBD_FREE(uuid, sizeof(struct obd_uuid));
1512 static inline void name_create_mdt(char **logname, char *fsname, int i)
1516 sprintf(mdt_index, "-MDT%04x", i);
1517 name_create(logname, fsname, mdt_index);
1520 static void name_create_mdt_and_lov(char **logname, char **lovname,
1521 struct fs_db *fsdb, int i)
1523 name_create_mdt(logname, fsdb->fsdb_name, i);
1525 if (i == 0 && fsdb->fsdb_fl_oscname_18)
1526 name_create(lovname, fsdb->fsdb_name, "-mdtlov");
1528 name_create(lovname, *logname, "-mdtlov");
1531 static inline void name_create_mdt_osc(char **oscname, char *ostname,
1532 struct fs_db *fsdb, int i)
1536 if (i == 0 && fsdb->fsdb_fl_oscname_18)
1537 sprintf(suffix, "-osc");
1539 sprintf(suffix, "-osc-MDT%04x", i);
1540 name_create(oscname, ostname, suffix);
1543 /* envelope method for all layers log */
1544 static int mgs_write_log_mdt(struct obd_device *obd, struct fs_db *fsdb,
1545 struct mgs_target_info *mti)
1547 struct llog_handle *llh = NULL;
1549 struct temp_comp comp = { 0 };
1553 CDEBUG(D_MGS, "writing new mdt %s\n", mti->mti_svname);
1557 if (mti->mti_flags & LDD_F_UPGRADE14) {
1558 /* We're starting with an old uuid. Assume old name for lov
1559 as well since the lov entry already exists in the log. */
1560 CDEBUG(D_MGS, "old mds uuid %s\n", mti->mti_uuid);
1561 if (strncmp(mti->mti_uuid, fsdb->fsdb_mdtlov + 4,
1562 strlen(fsdb->fsdb_mdtlov) - 4) != 0) {
1563 CERROR("old mds uuid %s doesn't match log %s (%s)\n",
1564 mti->mti_uuid, fsdb->fsdb_mdtlov,
1565 fsdb->fsdb_mdtlov + 4);
1569 /* end COMPAT_146 */
1571 if (mti->mti_uuid[0] == '\0') {
1572 /* Make up our own uuid */
1573 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
1574 "%s_UUID", mti->mti_svname);
1578 rc = mgs_write_log_mdt0(obd, fsdb, mti);
1580 /* Append the mdt info to the client log */
1581 name_create(&cliname, mti->mti_fsname, "-client");
1583 if (mgs_log_is_empty(obd, cliname)) {
1584 /* Start client log */
1585 rc = mgs_write_log_lov(obd, fsdb, mti, cliname,
1587 rc = mgs_write_log_lmv(obd, fsdb, mti, cliname,
1592 #09 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
1593 #10 L attach 0:MDC_uml1_mdsA_MNT_client 1:mdc 2:1d834_MNT_client_03f
1594 #11 L setup 0:MDC_uml1_mdsA_MNT_client 1:mdsA_UUID 2:uml1_UUID
1595 #12 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
1596 #13 L add_conn 0:MDC_uml1_mdsA_MNT_client 1:uml2_UUID
1597 #14 L mount_option 0: 1:client 2:lov1 3:MDC_uml1_mdsA_MNT_client
1602 if (mti->mti_flags & LDD_F_UPGRADE14) {
1603 rc = record_start_log(obd, &llh, cliname);
1607 rc = record_marker(obd, llh, fsdb, CM_START,
1608 mti->mti_svname,"add mdc");
1610 /* Old client log already has MDC entry, but needs mount opt
1611 for new client name (lustre-client) */
1612 /* FIXME Old MDT log already has an old mount opt
1613 which we should remove (currently handled by
1614 class_del_profiles()) */
1615 rc = record_mount_opt(obd, llh, cliname, fsdb->fsdb_clilov,
1617 /* end COMPAT_146 */
1619 rc = record_marker(obd, llh, fsdb, CM_END,
1620 mti->mti_svname, "add mdc");
1624 /* copy client info about lov/lmv */
1625 comp.comp_mti = mti;
1626 comp.comp_fsdb = fsdb;
1628 rc = mgs_steal_llog_for_mdt_from_client(obd, cliname,
1631 rc = mgs_write_log_mdc_to_lmv(obd, fsdb, mti, cliname,
1634 rc = record_start_log(obd, &llh, cliname);
1638 rc = record_marker(obd, llh, fsdb, CM_START, cliname,
1640 rc = record_mount_opt(obd, llh, cliname, fsdb->fsdb_clilov,
1642 rc = record_marker(obd, llh, fsdb, CM_END, cliname,
1646 rc = record_end_log(obd, &llh);
1648 name_destroy(&cliname);
1650 // for_all_existing_mdt except current one
1651 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
1653 if (i != mti->mti_stripe_index &&
1654 cfs_test_bit(i, fsdb->fsdb_mdt_index_map)) {
1655 name_create_mdt(&mdtname, mti->mti_fsname, i);
1656 rc = mgs_write_log_mdc_to_mdt(obd, fsdb, mti, mdtname);
1657 name_destroy(&mdtname);
1664 /* Add the ost info to the client/mdt lov */
1665 static int mgs_write_log_osc_to_lov(struct obd_device *obd, struct fs_db *fsdb,
1666 struct mgs_target_info *mti,
1667 char *logname, char *suffix, char *lovname,
1668 enum lustre_sec_part sec_part, int flags)
1670 struct llog_handle *llh = NULL;
1671 char *nodeuuid, *oscname, *oscuuid, *lovuuid, *svname;
1676 CDEBUG(D_INFO, "adding osc for %s to log %s\n",
1677 mti->mti_svname, logname);
1679 if (mgs_log_is_empty(obd, logname)) {
1680 /* The first item in the log must be the lov, so we have
1681 somewhere to add our osc. */
1682 rc = mgs_write_log_lov(obd, fsdb, mti, logname, lovname);
1685 name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
1686 name_create(&svname, mti->mti_svname, "-osc");
1687 name_create(&oscname, svname, suffix);
1688 name_create(&oscuuid, oscname, "_UUID");
1689 name_create(&lovuuid, lovname, "_UUID");
1692 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
1694 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
1695 #04 L attach 0:OSC_uml1_ost1_MNT_client 1:osc 2:89070_lov1_a41dff51a
1696 #05 L setup 0:OSC_uml1_ost1_MNT_client 1:ost1_UUID 2:uml1_UUID
1698 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
1699 #07 L add_conn 0:OSC_uml1_ost1_MNT_client 1:uml2_UUID
1700 #08 L lov_modify_tgts add 0:lov1 1:ost1_UUID 2(index):0 3(gen):1
1703 rc = record_start_log(obd, &llh, logname);
1706 /* FIXME these should be a single journal transaction */
1707 rc = record_marker(obd, llh, fsdb, CM_START | flags, mti->mti_svname,
1709 for (i = 0; i < mti->mti_nid_count; i++) {
1710 CDEBUG(D_MGS, "add nid %s\n", libcfs_nid2str(mti->mti_nids[i]));
1711 rc = record_add_uuid(obd, llh, mti->mti_nids[i], nodeuuid);
1713 rc = record_attach(obd, llh, oscname, LUSTRE_OSC_NAME, lovuuid);
1714 rc = record_setup(obd, llh, oscname, mti->mti_uuid, nodeuuid, 0, 0);
1715 rc = mgs_write_log_failnids(obd, mti, llh, oscname);
1716 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
1717 rc = record_lov_add(obd, llh, lovname, mti->mti_uuid, index, "1");
1718 rc = record_marker(obd, llh, fsdb, CM_END | flags, mti->mti_svname,
1720 rc = record_end_log(obd, &llh);
1722 name_destroy(&lovuuid);
1723 name_destroy(&oscuuid);
1724 name_destroy(&oscname);
1725 name_destroy(&svname);
1726 name_destroy(&nodeuuid);
1730 static int mgs_write_log_ost(struct obd_device *obd, struct fs_db *fsdb,
1731 struct mgs_target_info *mti)
1733 struct llog_handle *llh = NULL;
1734 char *logname, *lovname;
1735 char *ptr = mti->mti_params;
1736 int rc, flags = 0, failout = 0, i;
1739 CDEBUG(D_MGS, "writing new ost %s\n", mti->mti_svname);
1741 /* The ost startup log */
1743 /* If the ost log already exists, that means that someone reformatted
1744 the ost and it called target_add again. */
1745 if (!mgs_log_is_empty(obd, mti->mti_svname)) {
1746 LCONSOLE_ERROR_MSG(0x141, "The config log for %s already "
1747 "exists, yet the server claims it never "
1748 "registered. It may have been reformatted, "
1749 "or the index changed. writeconf the MDT to "
1750 "regenerate all logs.\n", mti->mti_svname);
1755 attach obdfilter ost1 ost1_UUID
1756 setup /dev/loop2 ldiskfs f|n errors=remount-ro,user_xattr
1758 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
1759 failout = (strncmp(ptr, "failout", 7) == 0);
1760 rc = record_start_log(obd, &llh, mti->mti_svname);
1763 /* FIXME these should be a single journal transaction */
1764 rc = record_marker(obd, llh, fsdb, CM_START, mti->mti_svname,"add ost");
1765 if (*mti->mti_uuid == '\0')
1766 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
1767 "%s_UUID", mti->mti_svname);
1768 rc = record_attach(obd, llh, mti->mti_svname,
1769 "obdfilter"/*LUSTRE_OST_NAME*/, mti->mti_uuid);
1770 rc = record_setup(obd, llh, mti->mti_svname,
1771 "dev"/*ignored*/, "type"/*ignored*/,
1772 failout ? "n" : "f", 0/*options*/);
1773 rc = record_marker(obd, llh, fsdb, CM_END, mti->mti_svname, "add ost");
1774 rc = record_end_log(obd, &llh);
1776 /* We also have to update the other logs where this osc is part of
1779 if (fsdb->fsdb_flags & FSDB_OLDLOG14) {
1780 /* If we're upgrading, the old mdt log already has our
1781 entry. Let's do a fake one for fun. */
1782 /* Note that we can't add any new failnids, since we don't
1783 know the old osc names. */
1784 flags = CM_SKIP | CM_UPGRADE146;
1786 } else if ((mti->mti_flags & LDD_F_UPDATE) != LDD_F_UPDATE) {
1787 /* If the update flag isn't set, don't update client/mdt
1790 LCONSOLE_WARN("Client log for %s was not updated; writeconf "
1791 "the MDT first to regenerate it.\n",
1795 /* Add ost to all MDT lov defs */
1796 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
1797 if (cfs_test_bit(i, fsdb->fsdb_mdt_index_map)) {
1800 name_create_mdt_and_lov(&logname, &lovname, fsdb, i);
1801 sprintf(mdt_index, "-MDT%04x", i);
1802 mgs_write_log_osc_to_lov(obd, fsdb, mti, logname,
1804 LUSTRE_SP_MDT, flags);
1805 name_destroy(&logname);
1806 name_destroy(&lovname);
1810 /* Append ost info to the client log */
1811 name_create(&logname, mti->mti_fsname, "-client");
1812 mgs_write_log_osc_to_lov(obd, fsdb, mti, logname, "",
1813 fsdb->fsdb_clilov, LUSTRE_SP_CLI, 0);
1814 name_destroy(&logname);
1818 static __inline__ int mgs_param_empty(char *ptr)
1822 if ((tmp = strchr(ptr, '=')) && (*(++tmp) == '\0'))
1827 static int mgs_write_log_failnid_internal(struct obd_device *obd,
1829 struct mgs_target_info *mti,
1830 char *logname, char *cliname)
1833 struct llog_handle *llh = NULL;
1835 if (mgs_param_empty(mti->mti_params)) {
1836 /* Remove _all_ failnids */
1837 rc = mgs_modify(obd, fsdb, mti, logname,
1838 mti->mti_svname, "add failnid", CM_SKIP);
1842 /* Otherwise failover nids are additive */
1843 rc = record_start_log(obd, &llh, logname);
1845 /* FIXME this should be a single journal transaction */
1846 rc = record_marker(obd, llh, fsdb, CM_START,
1847 mti->mti_svname, "add failnid");
1848 rc = mgs_write_log_failnids(obd, mti, llh, cliname);
1849 rc = record_marker(obd, llh, fsdb, CM_END,
1850 mti->mti_svname, "add failnid");
1851 rc = record_end_log(obd, &llh);
1858 /* Add additional failnids to an existing log.
1859 The mdc/osc must have been added to logs first */
1860 /* tcp nids must be in dotted-quad ascii -
1861 we can't resolve hostnames from the kernel. */
1862 static int mgs_write_log_add_failnid(struct obd_device *obd, struct fs_db *fsdb,
1863 struct mgs_target_info *mti)
1865 char *logname, *cliname;
1869 /* FIXME we currently can't erase the failnids
1870 * given when a target first registers, since they aren't part of
1871 * an "add uuid" stanza */
1873 /* Verify that we know about this target */
1874 if (mgs_log_is_empty(obd, mti->mti_svname)) {
1875 LCONSOLE_ERROR_MSG(0x142, "The target %s has not registered "
1876 "yet. It must be started before failnids "
1877 "can be added.\n", mti->mti_svname);
1881 /* Create mdc/osc client name (e.g. lustre-OST0001-osc) */
1882 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
1883 name_create(&cliname, mti->mti_svname, "-mdc");
1884 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
1885 name_create(&cliname, mti->mti_svname, "-osc");
1890 /* Add failover nids to the client log */
1891 name_create(&logname, mti->mti_fsname, "-client");
1892 rc = mgs_write_log_failnid_internal(obd, fsdb, mti, logname, cliname);
1893 name_destroy(&logname);
1894 name_destroy(&cliname);
1896 if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
1897 /* Add OST failover nids to the MDT logs as well */
1900 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
1901 if (!cfs_test_bit(i, fsdb->fsdb_mdt_index_map))
1903 name_create_mdt(&logname, mti->mti_fsname, i);
1904 name_create_mdt_osc(&cliname, mti->mti_svname, fsdb, i);
1905 rc = mgs_write_log_failnid_internal(obd, fsdb, mti,
1907 name_destroy(&cliname);
1908 name_destroy(&logname);
1915 static int mgs_wlp_lcfg(struct obd_device *obd, struct fs_db *fsdb,
1916 struct mgs_target_info *mti,
1917 char *logname, struct lustre_cfg_bufs *bufs,
1918 char *tgtname, char *ptr)
1920 char comment[MTI_NAME_MAXLEN];
1922 struct lustre_cfg *lcfg;
1925 /* Erase any old settings of this same parameter */
1926 memcpy(comment, ptr, MTI_NAME_MAXLEN);
1927 comment[MTI_NAME_MAXLEN - 1] = 0;
1928 /* But don't try to match the value. */
1929 if ((tmp = strchr(comment, '=')))
1931 /* FIXME we should skip settings that are the same as old values */
1932 rc = mgs_modify(obd, fsdb, mti, logname, tgtname, comment, CM_SKIP);
1933 del = mgs_param_empty(ptr);
1935 LCONSOLE_INFO("%sing parameter %s.%s in log %s\n", del ? "Disabl" : rc ?
1936 "Sett" : "Modify", tgtname, comment, logname);
1940 lustre_cfg_bufs_reset(bufs, tgtname);
1941 lustre_cfg_bufs_set_string(bufs, 1, ptr);
1942 lcfg = lustre_cfg_new(LCFG_PARAM, bufs);
1945 rc = mgs_write_log_direct(obd, fsdb, logname, lcfg, tgtname, comment);
1946 lustre_cfg_free(lcfg);
1950 /* write global variable settings into log */
1951 static int mgs_write_log_sys(struct obd_device *obd, struct fs_db *fsdb,
1952 struct mgs_target_info *mti, char *sys, char *ptr)
1954 struct lustre_cfg_bufs bufs;
1955 struct lustre_cfg *lcfg;
1961 if (class_match_param(ptr, PARAM_TIMEOUT, &tmp) == 0)
1962 cmd = LCFG_SET_TIMEOUT;
1963 else if (class_match_param(ptr, PARAM_LDLM_TIMEOUT, &tmp) == 0)
1964 cmd = LCFG_SET_LDLM_TIMEOUT;
1965 /* Check for known params here so we can return error to lctl */
1966 else if ((class_match_param(ptr, PARAM_AT_MIN, &tmp) == 0)
1967 || (class_match_param(ptr, PARAM_AT_MAX, &tmp) == 0)
1968 || (class_match_param(ptr, PARAM_AT_EXTRA, &tmp) == 0)
1969 || (class_match_param(ptr, PARAM_AT_EARLY_MARGIN, &tmp) == 0)
1970 || (class_match_param(ptr, PARAM_AT_HISTORY, &tmp) == 0))
1975 /* separate the value */
1976 val = simple_strtoul(tmp, NULL, 0);
1978 CDEBUG(D_MGS, "global '%s' removed\n", sys);
1980 CDEBUG(D_MGS, "global '%s' val=%d\n", sys, val);
1982 lustre_cfg_bufs_reset(&bufs, NULL);
1983 lustre_cfg_bufs_set_string(&bufs, 1, sys);
1984 lcfg = lustre_cfg_new(cmd, &bufs);
1985 lcfg->lcfg_num = val;
1986 /* truncate the comment to the parameter name */
1990 /* modify all servers and clients */
1991 rc = mgs_write_log_direct_all(obd, fsdb, mti,
1992 *tmp == '\0' ? NULL : lcfg,
1993 mti->mti_fsname, sys);
1995 lustre_cfg_free(lcfg);
1999 static int mgs_srpc_set_param_disk(struct obd_device *obd,
2001 struct mgs_target_info *mti,
2004 struct llog_handle *llh = NULL;
2006 char *comment, *ptr;
2007 struct lustre_cfg_bufs bufs;
2008 struct lustre_cfg *lcfg;
2013 ptr = strchr(param, '=');
2017 OBD_ALLOC(comment, len + 1);
2018 if (comment == NULL)
2020 strncpy(comment, param, len);
2021 comment[len] = '\0';
2024 lustre_cfg_bufs_reset(&bufs, mti->mti_svname);
2025 lustre_cfg_bufs_set_string(&bufs, 1, param);
2026 lcfg = lustre_cfg_new(LCFG_SPTLRPC_CONF, &bufs);
2028 GOTO(out_comment, rc = -ENOMEM);
2030 /* construct log name */
2031 rc = name_create(&logname, mti->mti_fsname, "-sptlrpc");
2035 if (mgs_log_is_empty(obd, logname)) {
2036 rc = record_start_log(obd, &llh, logname);
2037 record_end_log(obd, &llh);
2042 /* obsolete old one */
2043 mgs_modify(obd, fsdb, mti, logname, mti->mti_svname, comment, CM_SKIP);
2045 if (!mgs_param_empty(param)) {
2046 /* write the new one */
2047 rc = mgs_write_log_direct(obd, fsdb, logname, lcfg,
2048 mti->mti_svname, comment);
2050 CERROR("err %d writing log %s\n", rc, logname);
2053 name_destroy(&logname);
2055 lustre_cfg_free(lcfg);
2057 OBD_FREE(comment, len + 1);
2061 static int mgs_srpc_set_param_udesc_mem(struct fs_db *fsdb,
2066 /* disable the adjustable udesc parameter for now, i.e. use default
2067 * setting that client always ship udesc to MDT if possible. to enable
2068 * it simply remove the following line */
2071 ptr = strchr(param, '=');
2076 if (strcmp(param, PARAM_SRPC_UDESC))
2079 if (strcmp(ptr, "yes") == 0) {
2080 fsdb->fsdb_fl_udesc = 1;
2081 CWARN("Enable user descriptor shipping from client to MDT\n");
2082 } else if (strcmp(ptr, "no") == 0) {
2083 fsdb->fsdb_fl_udesc = 0;
2084 CWARN("Disable user descriptor shipping from client to MDT\n");
2092 CERROR("Invalid param: %s\n", param);
2096 static int mgs_srpc_set_param_mem(struct fs_db *fsdb,
2100 struct sptlrpc_rule rule;
2101 struct sptlrpc_rule_set *rset;
2105 if (strncmp(param, PARAM_SRPC, sizeof(PARAM_SRPC) - 1) != 0) {
2106 CERROR("Invalid sptlrpc parameter: %s\n", param);
2110 if (strncmp(param, PARAM_SRPC_UDESC,
2111 sizeof(PARAM_SRPC_UDESC) - 1) == 0) {
2112 RETURN(mgs_srpc_set_param_udesc_mem(fsdb, param));
2115 if (strncmp(param, PARAM_SRPC_FLVR, sizeof(PARAM_SRPC_FLVR) - 1) != 0) {
2116 CERROR("Invalid sptlrpc flavor parameter: %s\n", param);
2120 param += sizeof(PARAM_SRPC_FLVR) - 1;
2122 rc = sptlrpc_parse_rule(param, &rule);
2126 /* mgs rules implies must be mgc->mgs */
2127 if (fsdb->fsdb_fl_mgsself) {
2128 if ((rule.sr_from != LUSTRE_SP_MGC &&
2129 rule.sr_from != LUSTRE_SP_ANY) ||
2130 (rule.sr_to != LUSTRE_SP_MGS &&
2131 rule.sr_to != LUSTRE_SP_ANY))
2135 /* preapre room for this coming rule. svcname format should be:
2136 * - fsname: general rule
2137 * - fsname-tgtname: target-specific rule
2139 if (strchr(svname, '-')) {
2140 struct mgs_tgt_srpc_conf *tgtconf;
2143 for (tgtconf = fsdb->fsdb_srpc_tgt; tgtconf != NULL;
2144 tgtconf = tgtconf->mtsc_next) {
2145 if (!strcmp(tgtconf->mtsc_tgt, svname)) {
2154 OBD_ALLOC_PTR(tgtconf);
2155 if (tgtconf == NULL)
2158 name_len = strlen(svname);
2160 OBD_ALLOC(tgtconf->mtsc_tgt, name_len + 1);
2161 if (tgtconf->mtsc_tgt == NULL) {
2162 OBD_FREE_PTR(tgtconf);
2165 memcpy(tgtconf->mtsc_tgt, svname, name_len);
2167 tgtconf->mtsc_next = fsdb->fsdb_srpc_tgt;
2168 fsdb->fsdb_srpc_tgt = tgtconf;
2171 rset = &tgtconf->mtsc_rset;
2173 rset = &fsdb->fsdb_srpc_gen;
2176 rc = sptlrpc_rule_set_merge(rset, &rule);
2181 static int mgs_srpc_set_param(struct obd_device *obd,
2183 struct mgs_target_info *mti,
2187 int rc, copy_size, del;
2193 /* keep a copy of original param, which could be destroied
2195 copy_size = strlen(param) + 1;
2196 OBD_ALLOC(copy, copy_size);
2199 memcpy(copy, param, copy_size);
2201 del = mgs_param_empty(param);
2203 rc = mgs_srpc_set_param_mem(fsdb, mti->mti_svname, param);
2208 /* previous steps guaranteed the syntax is correct */
2209 rc = mgs_srpc_set_param_disk(obd, fsdb, mti, copy);
2213 if (fsdb->fsdb_fl_mgsself) {
2215 * for mgs rules, make them effective immediately.
2217 LASSERT(fsdb->fsdb_srpc_tgt == NULL);
2218 sptlrpc_target_update_exp_flavor(obd, &fsdb->fsdb_srpc_gen);
2222 OBD_FREE(copy, copy_size);
2226 struct mgs_srpc_read_data {
2227 struct fs_db *msrd_fsdb;
2231 static int mgs_srpc_read_handler(struct llog_handle *llh,
2232 struct llog_rec_hdr *rec,
2235 struct mgs_srpc_read_data *msrd = (struct mgs_srpc_read_data *) data;
2236 struct cfg_marker *marker;
2237 struct lustre_cfg *lcfg = (struct lustre_cfg *)(rec + 1);
2238 char *svname, *param;
2242 if (rec->lrh_type != OBD_CFG_REC) {
2243 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
2247 cfg_len = rec->lrh_len - sizeof(struct llog_rec_hdr) -
2248 sizeof(struct llog_rec_tail);
2250 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
2252 CERROR("Insane cfg\n");
2256 if (lcfg->lcfg_command == LCFG_MARKER) {
2257 marker = lustre_cfg_buf(lcfg, 1);
2259 if (marker->cm_flags & CM_START &&
2260 marker->cm_flags & CM_SKIP)
2261 msrd->msrd_skip = 1;
2262 if (marker->cm_flags & CM_END)
2263 msrd->msrd_skip = 0;
2268 if (msrd->msrd_skip)
2271 if (lcfg->lcfg_command != LCFG_SPTLRPC_CONF) {
2272 CERROR("invalid command (%x)\n", lcfg->lcfg_command);
2276 svname = lustre_cfg_string(lcfg, 0);
2277 if (svname == NULL) {
2278 CERROR("svname is empty\n");
2282 param = lustre_cfg_string(lcfg, 1);
2283 if (param == NULL) {
2284 CERROR("param is empty\n");
2288 rc = mgs_srpc_set_param_mem(msrd->msrd_fsdb, svname, param);
2290 CERROR("read sptlrpc record error (%d): %s\n", rc, param);
2295 int mgs_get_fsdb_srpc_from_llog(struct obd_device *obd,
2298 struct llog_handle *llh = NULL;
2299 struct lvfs_run_ctxt saved;
2300 struct llog_ctxt *ctxt;
2302 struct mgs_srpc_read_data msrd;
2306 /* construct log name */
2307 rc = name_create(&logname, fsdb->fsdb_name, "-sptlrpc");
2311 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
2312 LASSERT(ctxt != NULL);
2314 if (mgs_log_is_empty(obd, logname))
2317 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
2319 rc = llog_create(ctxt, &llh, NULL, logname);
2323 rc = llog_init_handle(llh, LLOG_F_IS_PLAIN, NULL);
2325 GOTO(out_close, rc);
2327 if (llog_get_size(llh) <= 1)
2328 GOTO(out_close, rc = 0);
2330 msrd.msrd_fsdb = fsdb;
2333 rc = llog_process(llh, mgs_srpc_read_handler, (void *) &msrd, NULL);
2338 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
2340 llog_ctxt_put(ctxt);
2341 name_destroy(&logname);
2344 CERROR("failed to read sptlrpc config database: %d\n", rc);
2348 /* Permanent settings of all parameters by writing into the appropriate
2349 * configuration logs.
2350 * A parameter with null value ("<param>='\0'") means to erase it out of
2353 static int mgs_write_log_param(struct obd_device *obd, struct fs_db *fsdb,
2354 struct mgs_target_info *mti, char *ptr)
2356 struct lustre_cfg_bufs bufs;
2362 /* For various parameter settings, we have to figure out which logs
2363 care about them (e.g. both mdt and client for lov settings) */
2364 CDEBUG(D_MGS, "next param '%s'\n", ptr);
2366 /* The params are stored in MOUNT_DATA_FILE and modified via
2367 tunefs.lustre, or set using lctl conf_param */
2369 /* Processed in lustre_start_mgc */
2370 if (class_match_param(ptr, PARAM_MGSNODE, NULL) == 0)
2373 /* Processed in mgs_write_log_ost */
2374 if (class_match_param(ptr, PARAM_FAILMODE, NULL) == 0) {
2375 if (mti->mti_flags & LDD_F_PARAM) {
2376 LCONSOLE_ERROR_MSG(0x169, "%s can only be "
2377 "changed with tunefs.lustre"
2378 "and --writeconf\n", ptr);
2384 if (class_match_param(ptr, PARAM_SRPC, NULL) == 0) {
2385 rc = mgs_srpc_set_param(obd, fsdb, mti, ptr);
2389 if (class_match_param(ptr, PARAM_FAILNODE, NULL) == 0) {
2390 /* Add a failover nidlist */
2392 /* We already processed failovers params for new
2393 targets in mgs_write_log_target */
2394 if (mti->mti_flags & LDD_F_PARAM) {
2395 CDEBUG(D_MGS, "Adding failnode\n");
2396 rc = mgs_write_log_add_failnid(obd, fsdb, mti);
2401 if (class_match_param(ptr, PARAM_SYS, &tmp) == 0) {
2402 rc = mgs_write_log_sys(obd, fsdb, mti, ptr, tmp);
2406 if (class_match_param(ptr, PARAM_OSC""PARAM_ACTIVE, &tmp) == 0) {
2407 /* active=0 means off, anything else means on */
2408 int flag = (*tmp == '0') ? CM_EXCLUDE : 0;
2411 if (!(mti->mti_flags & LDD_F_SV_TYPE_OST)) {
2412 LCONSOLE_ERROR_MSG(0x144, "%s: Only OSCs can "
2413 "be (de)activated.\n",
2415 GOTO(end, rc = -EINVAL);
2417 LCONSOLE_WARN("Permanently %sactivating %s\n",
2418 flag ? "de": "re", mti->mti_svname);
2420 name_create(&logname, mti->mti_fsname, "-client");
2421 rc = mgs_modify(obd, fsdb, mti, logname,
2422 mti->mti_svname, "add osc", flag);
2423 name_destroy(&logname);
2427 /* Add to all MDT logs for CMD */
2428 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2429 if (!cfs_test_bit(i, fsdb->fsdb_mdt_index_map))
2431 name_create_mdt(&logname, mti->mti_fsname, i);
2432 rc = mgs_modify(obd, fsdb, mti, logname,
2433 mti->mti_svname, "add osc", flag);
2434 name_destroy(&logname);
2440 LCONSOLE_ERROR_MSG(0x145, "Couldn't find %s in"
2441 "log (%d). No permanent "
2442 "changes were made to the "
2444 mti->mti_svname, rc);
2445 if (fsdb->fsdb_flags & FSDB_OLDLOG14)
2446 LCONSOLE_ERROR_MSG(0x146, "This may be"
2451 "update the logs.\n");
2454 /* Fall through to osc proc for deactivating live OSC
2455 on running MDT / clients. */
2457 /* Below here, let obd's XXX_process_config methods handle it */
2459 /* All lov. in proc */
2460 if (class_match_param(ptr, PARAM_LOV, NULL) == 0) {
2463 CDEBUG(D_MGS, "lov param %s\n", ptr);
2464 if (!(mti->mti_flags & LDD_F_SV_TYPE_MDT)) {
2465 LCONSOLE_ERROR_MSG(0x147, "LOV params must be "
2466 "set on the MDT, not %s. "
2473 if (mgs_log_is_empty(obd, mti->mti_svname))
2474 GOTO(end, rc = -ENODEV);
2476 name_create_mdt_and_lov(&logname, &mdtlovname, fsdb,
2477 mti->mti_stripe_index);
2478 rc = mgs_wlp_lcfg(obd, fsdb, mti, mti->mti_svname,
2479 &bufs, mdtlovname, ptr);
2480 name_destroy(&logname);
2481 name_destroy(&mdtlovname);
2486 name_create(&logname, mti->mti_fsname, "-client");
2487 rc = mgs_wlp_lcfg(obd, fsdb, mti, logname, &bufs,
2488 fsdb->fsdb_clilov, ptr);
2489 name_destroy(&logname);
2493 /* All osc., mdc., llite. params in proc */
2494 if ((class_match_param(ptr, PARAM_OSC, NULL) == 0) ||
2495 (class_match_param(ptr, PARAM_MDC, NULL) == 0) ||
2496 (class_match_param(ptr, PARAM_LLITE, NULL) == 0)) {
2498 if (memcmp(ptr, PARAM_LLITE, strlen(PARAM_LLITE)) == 0) {
2499 name_create(&cname, mti->mti_fsname, "-client");
2500 /* Add the client type to match the obdname in
2501 class_config_llog_handler */
2502 } else if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
2505 name_create(&cname, fsdb->fsdb_mdc, "");
2507 name_create(&cname, mti->mti_svname,
2509 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2511 if (fsdb->fsdb_flags & FSDB_OLDLOG14) {
2512 LCONSOLE_ERROR_MSG(0x148, "Upgraded "
2513 "client logs for %s"
2515 "modified. Consider"
2517 "configuration with"
2520 /* We don't know the names of all the
2522 GOTO(end, rc = -EINVAL);
2524 name_create(&cname, mti->mti_svname, "-osc");
2526 GOTO(end, rc = -EINVAL);
2529 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
2532 name_create(&logname, mti->mti_fsname, "-client");
2533 rc = mgs_wlp_lcfg(obd, fsdb, mti, logname, &bufs,
2536 /* osc params affect the MDT as well */
2537 if (!rc && (mti->mti_flags & LDD_F_SV_TYPE_OST)) {
2540 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
2541 if (!cfs_test_bit(i, fsdb->fsdb_mdt_index_map))
2543 name_destroy(&cname);
2544 name_create_mdt_osc(&cname, mti->mti_svname,
2546 name_destroy(&logname);
2547 name_create_mdt(&logname, mti->mti_fsname, i);
2548 if (!mgs_log_is_empty(obd, logname))
2549 rc = mgs_wlp_lcfg(obd, fsdb,mti,logname,
2555 name_destroy(&logname);
2556 name_destroy(&cname);
2560 /* All mdt. params in proc */
2561 if (class_match_param(ptr, PARAM_MDT, NULL) == 0) {
2565 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
2566 if (strncmp(mti->mti_svname, mti->mti_fsname,
2567 MTI_NAME_MAXLEN) == 0)
2568 /* device is unspecified completely? */
2569 rc = LDD_F_SV_TYPE_MDT | LDD_F_SV_ALL;
2571 rc = server_name2index(mti->mti_svname, &idx, NULL);
2574 if ((rc & LDD_F_SV_TYPE_MDT) == 0)
2576 if (rc & LDD_F_SV_ALL) {
2577 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2578 if (!cfs_test_bit(i,
2579 fsdb->fsdb_mdt_index_map))
2581 name_create_mdt(&logname, mti->mti_fsname, i);
2582 rc = mgs_wlp_lcfg(obd, fsdb, mti,
2585 name_destroy(&logname);
2590 rc = mgs_wlp_lcfg(obd, fsdb, mti,
2591 mti->mti_svname, &bufs,
2592 mti->mti_svname, ptr);
2599 /* All mdd., ost. params in proc */
2600 if ((class_match_param(ptr, PARAM_MDD, NULL) == 0) ||
2601 (class_match_param(ptr, PARAM_OST, NULL) == 0)) {
2602 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
2603 if (mgs_log_is_empty(obd, mti->mti_svname))
2604 GOTO(end, rc = -ENODEV);
2606 rc = mgs_wlp_lcfg(obd, fsdb, mti, mti->mti_svname,
2607 &bufs, mti->mti_svname, ptr);
2611 LCONSOLE_WARN("Ignoring unrecognized param '%s'\n", ptr);
2615 CERROR("err %d on param '%s'\n", rc, ptr);
2620 /* Not implementing automatic failover nid addition at this time. */
2621 int mgs_check_failnid(struct obd_device *obd, struct mgs_target_info *mti)
2628 rc = mgs_find_or_make_fsdb(obd, fsname, &fsdb);
2632 if (mgs_log_is_empty(obd, mti->mti_svname))
2633 /* should never happen */
2636 CDEBUG(D_MGS, "Checking for new failnids for %s\n", mti->mti_svname);
2638 /* FIXME We can just check mti->params to see if we're already in
2639 the failover list. Modify mti->params for rewriting back at
2640 server_register_target(). */
2642 cfs_down(&fsdb->fsdb_sem);
2643 rc = mgs_write_log_add_failnid(obd, fsdb, mti);
2644 cfs_up(&fsdb->fsdb_sem);
2651 int mgs_write_log_target(struct obd_device *obd,
2652 struct mgs_target_info *mti,
2659 /* set/check the new target index */
2660 rc = mgs_set_index(obd, mti);
2662 CERROR("Can't get index (%d)\n", rc);
2667 if (mti->mti_flags & LDD_F_UPGRADE14) {
2668 if (rc == EALREADY) {
2669 LCONSOLE_INFO("Found index %d for %s 1.4 log, "
2670 "upgrading\n", mti->mti_stripe_index,
2673 LCONSOLE_ERROR_MSG(0x149, "Failed to find %s in the old"
2674 " client log. Apparently it is not "
2675 "part of this filesystem, or the old"
2676 " log is wrong.\nUse 'writeconf' on "
2677 "the MDT to force log regeneration."
2678 "\n", mti->mti_svname);
2679 /* Not in client log? Upgrade anyhow...*/
2680 /* Argument against upgrading: reformat MDT,
2681 upgrade OST, then OST will start but will be SKIPped
2682 in client logs. Maybe error now is better. */
2683 /* RETURN(-EINVAL); */
2685 /* end COMPAT_146 */
2687 if (rc == EALREADY) {
2688 LCONSOLE_WARN("Found index %d for %s, updating log\n",
2689 mti->mti_stripe_index, mti->mti_svname);
2690 /* We would like to mark old log sections as invalid
2691 and add new log sections in the client and mdt logs.
2692 But if we add new sections, then live clients will
2693 get repeat setup instructions for already running
2694 osc's. So don't update the client/mdt logs. */
2695 mti->mti_flags &= ~LDD_F_UPDATE;
2699 cfs_down(&fsdb->fsdb_sem);
2701 if (mti->mti_flags &
2702 (LDD_F_VIRGIN | LDD_F_UPGRADE14 | LDD_F_WRITECONF)) {
2703 /* Generate a log from scratch */
2704 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
2705 rc = mgs_write_log_mdt(obd, fsdb, mti);
2706 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2707 rc = mgs_write_log_ost(obd, fsdb, mti);
2709 CERROR("Unknown target type %#x, can't create log for "
2710 "%s\n", mti->mti_flags, mti->mti_svname);
2713 CERROR("Can't write logs for %s (%d)\n",
2714 mti->mti_svname, rc);
2718 /* Just update the params from tunefs in mgs_write_log_params */
2719 CDEBUG(D_MGS, "Update params for %s\n", mti->mti_svname);
2720 mti->mti_flags |= LDD_F_PARAM;
2723 /* allocate temporary buffer, where class_get_next_param will
2724 make copy of a current parameter */
2725 OBD_ALLOC(buf, strlen(mti->mti_params) + 1);
2727 GOTO(out_up, rc = -ENOMEM);
2728 params = mti->mti_params;
2729 while (params != NULL) {
2730 rc = class_get_next_param(¶ms, buf);
2733 /* there is no next parameter, that is
2738 CDEBUG(D_MGS, "remaining string: '%s', param: '%s'\n",
2740 rc = mgs_write_log_param(obd, fsdb, mti, buf);
2745 OBD_FREE(buf, strlen(mti->mti_params) + 1);
2748 cfs_up(&fsdb->fsdb_sem);
2753 /* verify that we can handle the old config logs */
2754 int mgs_upgrade_sv_14(struct obd_device *obd, struct mgs_target_info *mti,
2760 /* Create ost log normally, as servers register. Servers
2761 register with their old uuids (from last_rcvd), so old
2762 (MDT and client) logs should work.
2763 - new MDT won't know about old OSTs, only the ones that have
2764 registered, so we need the old MDT log to get the LOV right
2765 in order for old clients to work.
2766 - Old clients connect to the MDT, not the MGS, for their logs, and
2767 will therefore receive the old client log from the MDT /LOGS dir.
2768 - Old clients can continue to use and connect to old or new OSTs
2769 - New clients will contact the MGS for their log
2772 LCONSOLE_INFO("upgrading server %s from pre-1.6\n", mti->mti_svname);
2773 server_mti_print("upgrade", mti);
2775 if (fsdb->fsdb_flags & FSDB_LOG_EMPTY) {
2776 LCONSOLE_ERROR_MSG(0x14a, "The old client log %s-client is "
2777 "missing. Was tunefs.lustre successful?\n",
2782 if (fsdb->fsdb_gen == 0) {
2783 /* There were no markers in the client log, meaning we have
2784 not updated the logs for this fs */
2785 CDEBUG(D_MGS, "found old, unupdated client log\n");
2788 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
2789 if (mgs_log_is_empty(obd, mti->mti_svname)) {
2790 LCONSOLE_ERROR_MSG(0x14b, "The old MDT log %s is "
2791 "missing. Was tunefs.lustre "
2796 /* We're starting with an old uuid. Assume old name for lov
2797 as well since the lov entry already exists in the log. */
2798 CDEBUG(D_MGS, "old mds uuid %s\n", mti->mti_uuid);
2799 if (strncmp(mti->mti_uuid, fsdb->fsdb_mdtlov + 4,
2800 strlen(fsdb->fsdb_mdtlov) - 4) != 0) {
2801 CERROR("old mds uuid %s doesn't match log %s (%s)\n",
2802 mti->mti_uuid, fsdb->fsdb_mdtlov,
2803 fsdb->fsdb_mdtlov + 4);
2808 if (!(fsdb->fsdb_flags & FSDB_OLDLOG14)) {
2809 LCONSOLE_ERROR_MSG(0x14c, "%s-client is supposedly an old "
2810 "log, but no old LOV or MDT was found. "
2811 "Consider updating the configuration with"
2812 " --writeconf.\n", mti->mti_fsname);
2817 /* end COMPAT_146 */
2819 int mgs_erase_log(struct obd_device *obd, char *name)
2821 struct lvfs_run_ctxt saved;
2822 struct llog_ctxt *ctxt;
2823 struct llog_handle *llh;
2826 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
2827 LASSERT(ctxt != NULL);
2829 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
2830 rc = llog_create(ctxt, &llh, NULL, name);
2832 llog_init_handle(llh, LLOG_F_IS_PLAIN, NULL);
2833 rc = llog_destroy(llh);
2834 llog_free_handle(llh);
2836 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
2837 llog_ctxt_put(ctxt);
2840 CERROR("failed to clear log %s: %d\n", name, rc);
2845 /* erase all logs for the given fs */
2846 int mgs_erase_logs(struct obd_device *obd, char *fsname)
2848 struct mgs_obd *mgs = &obd->u.mgs;
2849 static struct fs_db *fsdb;
2850 cfs_list_t dentry_list;
2851 struct l_linux_dirent *dirent, *n;
2852 int rc, len = strlen(fsname);
2856 /* Find all the logs in the CONFIGS directory */
2857 rc = class_dentry_readdir(obd, mgs->mgs_configs_dir,
2858 mgs->mgs_vfsmnt, &dentry_list);
2860 CERROR("Can't read %s dir\n", MOUNT_CONFIGS_DIR);
2864 cfs_down(&mgs->mgs_sem);
2866 /* Delete the fs db */
2867 fsdb = mgs_find_fsdb(obd, fsname);
2869 mgs_free_fsdb(obd, fsdb);
2871 cfs_list_for_each_entry_safe(dirent, n, &dentry_list, lld_list) {
2872 cfs_list_del(&dirent->lld_list);
2873 suffix = strrchr(dirent->lld_name, '-');
2874 if (suffix != NULL) {
2875 if ((len == suffix - dirent->lld_name) &&
2876 (strncmp(fsname, dirent->lld_name, len) == 0)) {
2877 CDEBUG(D_MGS, "Removing log %s\n",
2879 mgs_erase_log(obd, dirent->lld_name);
2882 OBD_FREE(dirent, sizeof(*dirent));
2885 cfs_up(&mgs->mgs_sem);
2890 /* from llog_swab */
2891 static void print_lustre_cfg(struct lustre_cfg *lcfg)
2896 CDEBUG(D_MGS, "lustre_cfg: %p\n", lcfg);
2897 CDEBUG(D_MGS, "\tlcfg->lcfg_version: %#x\n", lcfg->lcfg_version);
2899 CDEBUG(D_MGS, "\tlcfg->lcfg_command: %#x\n", lcfg->lcfg_command);
2900 CDEBUG(D_MGS, "\tlcfg->lcfg_num: %#x\n", lcfg->lcfg_num);
2901 CDEBUG(D_MGS, "\tlcfg->lcfg_flags: %#x\n", lcfg->lcfg_flags);
2902 CDEBUG(D_MGS, "\tlcfg->lcfg_nid: %s\n", libcfs_nid2str(lcfg->lcfg_nid));
2904 CDEBUG(D_MGS, "\tlcfg->lcfg_bufcount: %d\n", lcfg->lcfg_bufcount);
2905 if (lcfg->lcfg_bufcount < LUSTRE_CFG_MAX_BUFCOUNT)
2906 for (i = 0; i < lcfg->lcfg_bufcount; i++) {
2907 CDEBUG(D_MGS, "\tlcfg->lcfg_buflens[%d]: %d %s\n",
2908 i, lcfg->lcfg_buflens[i],
2909 lustre_cfg_string(lcfg, i));
2914 /* Set a permanent (config log) param for a target or fs
2915 * \param lcfg buf0 may contain the device (testfs-MDT0000) name
2916 * buf1 contains the single parameter
2918 int mgs_setparam(struct obd_device *obd, struct lustre_cfg *lcfg, char *fsname)
2921 struct mgs_target_info *mti;
2922 char *devname, *param;
2928 print_lustre_cfg(lcfg);
2930 /* lustre, lustre-mdtlov, lustre-client, lustre-MDT0000 */
2931 devname = lustre_cfg_string(lcfg, 0);
2932 param = lustre_cfg_string(lcfg, 1);
2934 /* Assume device name embedded in param:
2935 lustre-OST0000.osc.max_dirty_mb=32 */
2936 ptr = strchr(param, '.');
2944 LCONSOLE_ERROR_MSG(0x14d, "No target specified: %s\n", param);
2948 /* Extract fsname */
2949 ptr = strrchr(devname, '-');
2950 memset(fsname, 0, MTI_NAME_MAXLEN);
2951 if (ptr && (server_name2index(ptr, &index, NULL) >= 0)) {
2952 /* param related to llite isn't allowed to set by OST or MDT */
2953 if (strncmp(param, PARAM_LLITE, sizeof(PARAM_LLITE)) == 0)
2956 strncpy(fsname, devname, ptr - devname);
2958 /* assume devname is the fsname */
2959 strncpy(fsname, devname, MTI_NAME_MAXLEN);
2961 fsname[MTI_NAME_MAXLEN - 1] = 0;
2962 CDEBUG(D_MGS, "setparam fs='%s' device='%s'\n", fsname, devname);
2964 rc = mgs_find_or_make_fsdb(obd, fsname, &fsdb);
2967 if (!fsdb->fsdb_fl_mgsself && fsdb->fsdb_flags & FSDB_LOG_EMPTY) {
2968 CERROR("No filesystem targets for %s. cfg_device from lctl "
2969 "is '%s'\n", fsname, devname);
2970 mgs_free_fsdb(obd, fsdb);
2974 /* Create a fake mti to hold everything */
2977 GOTO(out, rc = -ENOMEM);
2978 strncpy(mti->mti_fsname, fsname, MTI_NAME_MAXLEN);
2979 strncpy(mti->mti_svname, devname, MTI_NAME_MAXLEN);
2980 strncpy(mti->mti_params, param, sizeof(mti->mti_params));
2981 rc = server_name2index(mti->mti_svname, &mti->mti_stripe_index, &tmp);
2983 /* Not a valid server; may be only fsname */
2986 /* Strip -osc or -mdc suffix from svname */
2987 if (server_make_name(rc, mti->mti_stripe_index, mti->mti_fsname,
2989 GOTO(out, rc = -EINVAL);
2991 mti->mti_flags = rc | LDD_F_PARAM;
2993 cfs_down(&fsdb->fsdb_sem);
2994 rc = mgs_write_log_param(obd, fsdb, mti, mti->mti_params);
2995 cfs_up(&fsdb->fsdb_sem);
2998 * Revoke lock so everyone updates. Should be alright if
2999 * someone was already reading while we were updating the logs,
3000 * so we don't really need to hold the lock while we're
3003 mgs_revoke_lock(obd, fsdb);
3009 static int mgs_write_log_pool(struct obd_device *obd, char *logname,
3010 struct fs_db *fsdb, char *lovname,
3011 enum lcfg_command_type cmd,
3012 char *poolname, char *fsname,
3013 char *ostname, char *comment)
3015 struct llog_handle *llh = NULL;
3018 rc = record_start_log(obd, &llh, logname);
3021 rc = record_marker(obd, llh, fsdb, CM_START, lovname, comment);
3022 record_base(obd, llh, lovname, 0, cmd, poolname, fsname, ostname, 0);
3023 rc = record_marker(obd, llh, fsdb, CM_END, lovname, comment);
3024 rc = record_end_log(obd, &llh);
3029 int mgs_pool_cmd(struct obd_device *obd, enum lcfg_command_type cmd,
3030 char *fsname, char *poolname, char *ostname)
3035 char *label = NULL, *canceled_label = NULL;
3037 struct mgs_target_info *mti = NULL;
3041 rc = mgs_find_or_make_fsdb(obd, fsname, &fsdb);
3043 CERROR("Can't get db for %s\n", fsname);
3046 if (fsdb->fsdb_flags & FSDB_LOG_EMPTY) {
3047 CERROR("%s is not defined\n", fsname);
3048 mgs_free_fsdb(obd, fsdb);
3052 label_sz = 10 + strlen(fsname) + strlen(poolname);
3054 /* check if ostname match fsname */
3055 if (ostname != NULL) {
3058 ptr = strrchr(ostname, '-');
3059 if ((ptr == NULL) ||
3060 (strncmp(fsname, ostname, ptr-ostname) != 0))
3062 label_sz += strlen(ostname);
3065 OBD_ALLOC(label, label_sz);
3067 GOTO(out, rc = -ENOMEM);
3070 case LCFG_POOL_NEW: {
3072 "new %s.%s", fsname, poolname);
3075 case LCFG_POOL_ADD: {
3077 "add %s.%s.%s", fsname, poolname, ostname);
3080 case LCFG_POOL_REM: {
3081 OBD_ALLOC(canceled_label, label_sz);
3082 if (canceled_label == NULL)
3083 GOTO(out, rc = -ENOMEM);
3085 "rem %s.%s.%s", fsname, poolname, ostname);
3086 sprintf(canceled_label,
3087 "add %s.%s.%s", fsname, poolname, ostname);
3090 case LCFG_POOL_DEL: {
3091 OBD_ALLOC(canceled_label, label_sz);
3092 if (canceled_label == NULL)
3093 GOTO(out, rc = -ENOMEM);
3095 "del %s.%s", fsname, poolname);
3096 sprintf(canceled_label,
3097 "new %s.%s", fsname, poolname);
3105 cfs_down(&fsdb->fsdb_sem);
3107 if (canceled_label != NULL) {
3110 GOTO(out, rc = -ENOMEM);
3113 /* write pool def to all MDT logs */
3114 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3115 if (cfs_test_bit(i, fsdb->fsdb_mdt_index_map)) {
3116 name_create_mdt_and_lov(&logname, &lovname, fsdb, i);
3118 if (canceled_label != NULL) {
3119 strcpy(mti->mti_svname, "lov pool");
3120 mgs_modify(obd, fsdb, mti, logname, lovname,
3121 canceled_label, CM_SKIP);
3124 mgs_write_log_pool(obd, logname, fsdb, lovname,
3125 cmd, fsname, poolname, ostname,
3127 name_destroy(&logname);
3128 name_destroy(&lovname);
3132 name_create(&logname, fsname, "-client");
3133 if (canceled_label != NULL)
3134 mgs_modify(obd, fsdb, mti, logname, fsdb->fsdb_clilov,
3135 canceled_label, CM_SKIP);
3137 mgs_write_log_pool(obd, logname, fsdb, fsdb->fsdb_clilov,
3138 cmd, fsname, poolname, ostname, label);
3139 name_destroy(&logname);
3141 cfs_up(&fsdb->fsdb_sem);
3142 /* request for update */
3143 mgs_revoke_lock(obd, fsdb);
3148 OBD_FREE(label, label_sz);
3150 if (canceled_label != NULL)
3151 OBD_FREE(canceled_label, label_sz);
3160 /******************** unused *********************/
3161 static int mgs_backup_llog(struct obd_device *obd, char* fsname)
3163 struct file *filp, *bak_filp;
3164 struct lvfs_run_ctxt saved;
3165 char *logname, *buf;
3166 loff_t soff = 0 , doff = 0;
3167 int count = 4096, len;
3170 OBD_ALLOC(logname, PATH_MAX);
3171 if (logname == NULL)
3174 OBD_ALLOC(buf, count);
3176 GOTO(out , rc = -ENOMEM);
3178 len = snprintf(logname, PATH_MAX, "%s/%s.bak",
3179 MOUNT_CONFIGS_DIR, fsname);
3181 if (len >= PATH_MAX - 1) {
3182 GOTO(out, -ENAMETOOLONG);
3185 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
3187 bak_filp = l_filp_open(logname, O_RDWR|O_CREAT|O_TRUNC, 0660);
3188 if (IS_ERR(bak_filp)) {
3189 rc = PTR_ERR(bak_filp);
3190 CERROR("backup logfile open %s: %d\n", logname, rc);
3193 sprintf(logname, "%s/%s", MOUNT_CONFIGS_DIR, fsname);
3194 filp = l_filp_open(logname, O_RDONLY, 0);
3197 CERROR("logfile open %s: %d\n", logname, rc);
3201 while ((rc = lustre_fread(filp, buf, count, &soff)) > 0) {
3202 rc = lustre_fwrite(bak_filp, buf, count, &doff);
3206 filp_close(filp, 0);
3208 filp_close(bak_filp, 0);
3210 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
3213 OBD_FREE(buf, count);
3214 OBD_FREE(logname, PATH_MAX);