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 /*|D_WARNING*/
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 struct list_head *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 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 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 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);
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;
330 struct list_head *tmp;
332 list_for_each(tmp, &mgs->mgs_fs_db_list) {
333 fsdb = 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 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 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 down(&fsdb->fsdb_sem);
407 lproc_mgs_del_live(obd, fsdb);
408 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 struct list_head *tmp, *tmp2;
435 list_for_each_safe(tmp, tmp2, &mgs->mgs_fs_db_list) {
436 fsdb = list_entry(tmp, struct fs_db, fsdb_list);
437 mgs_free_fsdb(obd, fsdb);
443 int mgs_find_or_make_fsdb(struct obd_device *obd, char *name,
446 struct mgs_obd *mgs = &obd->u.mgs;
451 fsdb = mgs_find_fsdb(obd, name);
458 CDEBUG(D_MGS, "Creating new db\n");
459 fsdb = mgs_new_fsdb(obd, name);
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 (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 (!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 (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 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\n", logname, devname, comment);
667 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
669 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
670 LASSERT(ctxt != NULL);
671 rc = llog_create(ctxt, &loghandle, NULL, logname);
675 rc = llog_init_handle(loghandle, LLOG_F_IS_PLAIN, NULL);
679 if (llog_get_size(loghandle) <= 1)
680 GOTO(out_close, rc = 0);
684 GOTO(out_close, rc = -ENOMEM);
685 strcpy(mml->mml_marker.cm_comment, comment);
686 strcpy(mml->mml_marker.cm_tgtname, devname);
687 /* Modify mostly means cancel */
688 mml->mml_marker.cm_flags = flags;
689 mml->mml_marker.cm_canceltime = flags ? cfs_time_current_sec() : 0;
690 mml->mml_modified = 0;
691 rc = llog_process(loghandle, mgs_modify_handler, (void *)mml, NULL);
692 if (!rc && !mml->mml_modified)
697 rc2 = llog_close(loghandle);
701 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
702 if (rc && rc != -ENODEV)
703 CERROR("modify %s/%s failed %d\n",
704 mti->mti_svname, comment, rc);
709 /******************** config log recording functions *********************/
711 static int record_lcfg(struct obd_device *obd, struct llog_handle *llh,
712 struct lustre_cfg *lcfg)
714 struct lvfs_run_ctxt saved;
715 struct llog_rec_hdr rec;
721 LASSERT(llh->lgh_ctxt);
723 buflen = lustre_cfg_len(lcfg->lcfg_bufcount,
725 rec.lrh_len = llog_data_len(buflen);
726 rec.lrh_type = OBD_CFG_REC;
728 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
729 /* idx = -1 means append */
730 rc = llog_write_rec(llh, &rec, NULL, 0, (void *)lcfg, -1);
731 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
733 CERROR("failed %d\n", rc);
737 static int record_base(struct obd_device *obd, struct llog_handle *llh,
738 char *cfgname, lnet_nid_t nid, int cmd,
739 char *s1, char *s2, char *s3, char *s4)
741 struct lustre_cfg_bufs bufs;
742 struct lustre_cfg *lcfg;
745 CDEBUG(D_MGS, "lcfg %s %#x %s %s %s %s\n", cfgname,
746 cmd, s1, s2, s3, s4);
748 lustre_cfg_bufs_reset(&bufs, cfgname);
750 lustre_cfg_bufs_set_string(&bufs, 1, s1);
752 lustre_cfg_bufs_set_string(&bufs, 2, s2);
754 lustre_cfg_bufs_set_string(&bufs, 3, s3);
756 lustre_cfg_bufs_set_string(&bufs, 4, s4);
758 lcfg = lustre_cfg_new(cmd, &bufs);
761 lcfg->lcfg_nid = nid;
763 rc = record_lcfg(obd, llh, lcfg);
765 lustre_cfg_free(lcfg);
768 CERROR("error %d: lcfg %s %#x %s %s %s %s\n", rc, cfgname,
769 cmd, s1, s2, s3, s4);
775 static inline int record_add_uuid(struct obd_device *obd,
776 struct llog_handle *llh,
777 uint64_t nid, char *uuid)
779 return record_base(obd,llh,NULL,nid,LCFG_ADD_UUID,uuid,0,0,0);
783 static inline int record_add_conn(struct obd_device *obd,
784 struct llog_handle *llh,
788 return record_base(obd,llh,devname,0,LCFG_ADD_CONN,uuid,0,0,0);
791 static inline int record_attach(struct obd_device *obd, struct llog_handle *llh,
792 char *devname, char *type, char *uuid)
794 return record_base(obd,llh,devname,0,LCFG_ATTACH,type,uuid,0,0);
797 static inline int record_setup(struct obd_device *obd, struct llog_handle *llh,
799 char *s1, char *s2, char *s3, char *s4)
801 return record_base(obd,llh,devname,0,LCFG_SETUP,s1,s2,s3,s4);
804 static int record_lov_setup(struct obd_device *obd, struct llog_handle *llh,
805 char *devname, struct lov_desc *desc)
807 struct lustre_cfg_bufs bufs;
808 struct lustre_cfg *lcfg;
811 lustre_cfg_bufs_reset(&bufs, devname);
812 lustre_cfg_bufs_set(&bufs, 1, desc, sizeof(*desc));
813 lcfg = lustre_cfg_new(LCFG_SETUP, &bufs);
816 rc = record_lcfg(obd, llh, lcfg);
818 lustre_cfg_free(lcfg);
822 static int record_lmv_setup(struct obd_device *obd, struct llog_handle *llh,
823 char *devname, struct lmv_desc *desc)
825 struct lustre_cfg_bufs bufs;
826 struct lustre_cfg *lcfg;
829 lustre_cfg_bufs_reset(&bufs, devname);
830 lustre_cfg_bufs_set(&bufs, 1, desc, sizeof(*desc));
831 lcfg = lustre_cfg_new(LCFG_SETUP, &bufs);
833 rc = record_lcfg(obd, llh, lcfg);
835 lustre_cfg_free(lcfg);
839 static inline int record_mdc_add(struct obd_device *obd,
840 struct llog_handle *llh,
841 char *logname, char *mdcuuid,
842 char *mdtuuid, char *index,
845 return record_base(obd,llh,logname,0,LCFG_ADD_MDC,
846 mdtuuid,index,gen,mdcuuid);
849 static inline int record_lov_add(struct obd_device *obd,
850 struct llog_handle *llh,
851 char *lov_name, char *ost_uuid,
852 char *index, char *gen)
854 return record_base(obd,llh,lov_name,0,LCFG_LOV_ADD_OBD,
855 ost_uuid,index,gen,0);
858 static inline int record_mount_opt(struct obd_device *obd,
859 struct llog_handle *llh,
860 char *profile, char *lov_name,
863 return record_base(obd,llh,NULL,0,LCFG_MOUNTOPT,
864 profile,lov_name,mdc_name,0);
867 static int record_marker(struct obd_device *obd, struct llog_handle *llh,
868 struct fs_db *fsdb, __u32 flags,
869 char *tgtname, char *comment)
871 struct cfg_marker marker;
872 struct lustre_cfg_bufs bufs;
873 struct lustre_cfg *lcfg;
876 if (flags & CM_START)
878 marker.cm_step = fsdb->fsdb_gen;
879 marker.cm_flags = flags;
880 marker.cm_vers = LUSTRE_VERSION_CODE;
881 strncpy(marker.cm_tgtname, tgtname, sizeof(marker.cm_tgtname));
882 strncpy(marker.cm_comment, comment, sizeof(marker.cm_comment));
883 marker.cm_createtime = cfs_time_current_sec();
884 marker.cm_canceltime = 0;
885 lustre_cfg_bufs_reset(&bufs, NULL);
886 lustre_cfg_bufs_set(&bufs, 1, &marker, sizeof(marker));
887 lcfg = lustre_cfg_new(LCFG_MARKER, &bufs);
890 rc = record_lcfg(obd, llh, lcfg);
892 lustre_cfg_free(lcfg);
896 static int record_start_log(struct obd_device *obd,
897 struct llog_handle **llh, char *name)
899 static struct obd_uuid cfg_uuid = { .uuid = "config_uuid" };
900 struct lvfs_run_ctxt saved;
901 struct llog_ctxt *ctxt;
905 GOTO(out, rc = -EBUSY);
907 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
909 GOTO(out, rc = -ENODEV);
911 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
912 rc = llog_create(ctxt, llh, NULL, name);
914 llog_init_handle(*llh, LLOG_F_IS_PLAIN, &cfg_uuid);
918 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
923 CERROR("Can't start log %s: %d\n", name, rc);
928 static int record_end_log(struct obd_device *obd, struct llog_handle **llh)
930 struct lvfs_run_ctxt saved;
933 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
935 rc = llog_close(*llh);
938 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
942 static int mgs_log_is_empty(struct obd_device *obd, char *name)
944 struct lvfs_run_ctxt saved;
945 struct llog_handle *llh;
946 struct llog_ctxt *ctxt;
949 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
950 LASSERT(ctxt != NULL);
951 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
952 rc = llog_create(ctxt, &llh, NULL, name);
954 llog_init_handle(llh, LLOG_F_IS_PLAIN, NULL);
955 rc = llog_get_size(llh);
958 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
960 /* header is record 1 */
964 /******************** config "macros" *********************/
966 /* write an lcfg directly into a log (with markers) */
967 static int mgs_write_log_direct(struct obd_device *obd, struct fs_db *fsdb,
968 char *logname, struct lustre_cfg *lcfg,
969 char *devname, char *comment)
971 struct llog_handle *llh = NULL;
978 rc = record_start_log(obd, &llh, logname);
982 /* FIXME These should be a single journal transaction */
983 rc = record_marker(obd, llh, fsdb, CM_START, devname, comment);
985 rc = record_lcfg(obd, llh, lcfg);
987 rc = record_marker(obd, llh, fsdb, CM_END, devname, comment);
988 rc = record_end_log(obd, &llh);
993 /* write the lcfg in all logs for the given fs */
994 int mgs_write_log_direct_all(struct obd_device *obd, struct fs_db *fsdb,
995 struct mgs_target_info *mti,
996 struct lustre_cfg *lcfg,
997 char *devname, char *comment)
999 struct mgs_obd *mgs = &obd->u.mgs;
1000 struct list_head dentry_list;
1001 struct l_linux_dirent *dirent, *n;
1002 char *fsname = mti->mti_fsname;
1004 int rc = 0, len = strlen(fsname);
1007 /* We need to set params for any future logs
1008 as well. FIXME Append this file to every new log.
1009 Actually, we should store as params (text), not llogs. Or
1011 name_create(&logname, fsname, "-params");
1012 if (mgs_log_is_empty(obd, logname)) {
1013 struct llog_handle *llh = NULL;
1014 rc = record_start_log(obd, &llh, logname);
1015 record_end_log(obd, &llh);
1017 name_destroy(&logname);
1021 /* Find all the logs in the CONFIGS directory */
1022 rc = class_dentry_readdir(obd, mgs->mgs_configs_dir,
1023 mgs->mgs_vfsmnt, &dentry_list);
1025 CERROR("Can't read %s dir\n", MOUNT_CONFIGS_DIR);
1029 /* Could use fsdb index maps instead of directory listing */
1030 list_for_each_entry_safe(dirent, n, &dentry_list, lld_list) {
1031 list_del(&dirent->lld_list);
1032 /* don't write to sptlrpc rule log */
1033 if (strncmp(fsname, dirent->lld_name, len) == 0 &&
1034 strstr(dirent->lld_name, "-sptlrpc") == NULL) {
1035 CDEBUG(D_MGS, "Changing log %s\n", dirent->lld_name);
1036 /* Erase any old settings of this same parameter */
1037 mgs_modify(obd, fsdb, mti, dirent->lld_name, devname,
1039 /* Write the new one */
1040 rc = mgs_write_log_direct(obd, fsdb, dirent->lld_name,
1041 lcfg, devname, comment);
1043 CERROR("err %d writing log %s\n", rc,
1046 OBD_FREE(dirent, sizeof(*dirent));
1054 struct mgs_target_info *comp_tmti;
1055 struct mgs_target_info *comp_mti;
1056 struct fs_db *comp_fsdb;
1057 struct obd_device *comp_obd;
1060 static int mgs_write_log_mdc_to_mdt(struct obd_device *, struct fs_db *,
1061 struct mgs_target_info *, char *);
1063 static int mgs_steal_llog_handler(struct llog_handle *llh,
1064 struct llog_rec_hdr *rec,
1067 struct obd_device * obd;
1068 struct mgs_target_info *mti, *tmti;
1070 int cfg_len = rec->lrh_len;
1071 char *cfg_buf = (char*) (rec + 1);
1072 struct lustre_cfg *lcfg;
1074 struct llog_handle *mdt_llh = NULL;
1075 static int got_an_osc_or_mdc = 0;
1076 /* 0: not found any osc/mdc;
1080 static int last_step = -1;
1084 mti = ((struct temp_comp*)data)->comp_mti;
1085 tmti = ((struct temp_comp*)data)->comp_tmti;
1086 fsdb = ((struct temp_comp*)data)->comp_fsdb;
1087 obd = ((struct temp_comp*)data)->comp_obd;
1089 if (rec->lrh_type != OBD_CFG_REC) {
1090 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
1094 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
1096 CERROR("Insane cfg\n");
1100 lcfg = (struct lustre_cfg *)cfg_buf;
1102 if (lcfg->lcfg_command == LCFG_MARKER) {
1103 struct cfg_marker *marker;
1104 marker = lustre_cfg_buf(lcfg, 1);
1105 if (!strncmp(marker->cm_comment,"add osc",7) &&
1106 (marker->cm_flags & CM_START)){
1107 got_an_osc_or_mdc = 1;
1108 rc = record_start_log(obd, &mdt_llh, mti->mti_svname);
1109 rc = record_marker(obd, mdt_llh, fsdb, CM_START,
1110 mti->mti_svname,"add osc(copied)");
1111 rc = record_end_log(obd, &mdt_llh);
1112 last_step = marker->cm_step;
1115 if (!strncmp(marker->cm_comment,"add osc",7) &&
1116 (marker->cm_flags & CM_END)){
1117 LASSERT(last_step == marker->cm_step);
1119 got_an_osc_or_mdc = 0;
1120 rc = record_start_log(obd, &mdt_llh, mti->mti_svname);
1121 rc = record_marker(obd, mdt_llh, fsdb, CM_END,
1122 mti->mti_svname,"add osc(copied)");
1123 rc = record_end_log(obd, &mdt_llh);
1126 if (!strncmp(marker->cm_comment,"add mdc",7) &&
1127 (marker->cm_flags & CM_START)){
1128 got_an_osc_or_mdc = 2;
1129 last_step = marker->cm_step;
1130 memcpy(tmti->mti_svname, marker->cm_tgtname,
1131 strlen(marker->cm_tgtname));
1135 if (!strncmp(marker->cm_comment,"add mdc",7) &&
1136 (marker->cm_flags & CM_END)){
1137 LASSERT(last_step == marker->cm_step);
1139 got_an_osc_or_mdc = 0;
1144 if (got_an_osc_or_mdc == 0 || last_step < 0)
1147 if (lcfg->lcfg_command == LCFG_ADD_UUID) {
1149 nodenid = lcfg->lcfg_nid;
1151 tmti->mti_nids[tmti->mti_nid_count] = nodenid;
1152 tmti->mti_nid_count++;
1157 if (lcfg->lcfg_command == LCFG_SETUP) {
1160 target = lustre_cfg_string(lcfg, 1);
1161 memcpy(tmti->mti_uuid, target, strlen(target));
1165 /* ignore client side sptlrpc_conf_log */
1166 if (lcfg->lcfg_command == LCFG_SPTLRPC_CONF)
1169 if (lcfg->lcfg_command == LCFG_ADD_MDC) {
1172 if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1)
1175 memcpy(tmti->mti_fsname, mti->mti_fsname,
1176 strlen(mti->mti_fsname));
1177 tmti->mti_stripe_index = index;
1179 mgs_write_log_mdc_to_mdt(obd, fsdb, tmti, mti->mti_svname);
1180 memset(tmti, 0, sizeof(*tmti));
1186 /* fsdb->fsdb_sem is already held in mgs_write_log_target*/
1187 /* stealed from mgs_get_fsdb_from_llog*/
1188 static int mgs_steal_llog_for_mdt_from_client(struct obd_device *obd,
1190 struct temp_comp* comp)
1192 struct llog_handle *loghandle;
1193 struct lvfs_run_ctxt saved;
1194 struct mgs_target_info *tmti;
1195 struct llog_ctxt *ctxt;
1199 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
1200 LASSERT(ctxt != NULL);
1202 OBD_ALLOC_PTR(tmti);
1206 comp->comp_tmti = tmti;
1207 comp->comp_obd = obd;
1209 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
1211 rc = llog_create(ctxt, &loghandle, NULL, client_name);
1215 rc = llog_init_handle(loghandle, LLOG_F_IS_PLAIN, NULL);
1217 GOTO(out_close, rc);
1219 rc = llog_process(loghandle, mgs_steal_llog_handler, (void *)comp, NULL);
1220 CDEBUG(D_MGS, "steal llog re = %d\n", rc);
1222 rc2 = llog_close(loghandle);
1226 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
1228 llog_ctxt_put(ctxt);
1232 /* lmv is the second thing for client logs */
1233 /* copied from mgs_write_log_lov. Please refer to that. */
1234 static int mgs_write_log_lmv(struct obd_device *obd, struct fs_db *fsdb,
1235 struct mgs_target_info *mti,
1236 char *logname, char *lmvname)
1238 struct llog_handle *llh = NULL;
1239 struct lmv_desc *lmvdesc;
1244 CDEBUG(D_MGS, "Writing lmv(%s) log for %s\n", lmvname,logname);
1246 OBD_ALLOC_PTR(lmvdesc);
1247 if (lmvdesc == NULL)
1249 lmvdesc->ld_active_tgt_count = 0;
1250 lmvdesc->ld_tgt_count = 0;
1251 sprintf((char*)lmvdesc->ld_uuid.uuid, "%s_UUID", lmvname);
1252 uuid = (char *)lmvdesc->ld_uuid.uuid;
1254 rc = record_start_log(obd, &llh, logname);
1255 rc = record_marker(obd, llh, fsdb, CM_START, lmvname, "lmv setup");
1256 rc = record_attach(obd, llh, lmvname, "lmv", uuid);
1257 rc = record_lmv_setup(obd, llh, lmvname, lmvdesc);
1258 rc = record_marker(obd, llh, fsdb, CM_END, lmvname, "lmv setup");
1259 rc = record_end_log(obd, &llh);
1261 OBD_FREE_PTR(lmvdesc);
1265 /* lov is the first thing in the mdt and client logs */
1266 static int mgs_write_log_lov(struct obd_device *obd, struct fs_db *fsdb,
1267 struct mgs_target_info *mti,
1268 char *logname, char *lovname)
1270 struct llog_handle *llh = NULL;
1271 struct lov_desc *lovdesc;
1276 CDEBUG(D_MGS, "Writing lov(%s) log for %s\n", lovname, logname);
1279 #01 L attach 0:lov_mdsA 1:lov 2:71ccb_lov_mdsA_19f961a9e1
1280 #02 L lov_setup 0:lov_mdsA 1:(struct lov_desc)
1281 uuid=lov1_UUID, stripe count=1, size=1048576, offset=0, pattern=0
1284 /* FIXME just make lov_setup accept empty desc (put uuid in buf 2) */
1285 OBD_ALLOC_PTR(lovdesc);
1286 if (lovdesc == NULL)
1288 lovdesc->ld_magic = LOV_DESC_MAGIC;
1289 lovdesc->ld_tgt_count = 0;
1290 /* Defaults. Can be changed later by lcfg config_param */
1291 lovdesc->ld_default_stripe_count = 1;
1292 lovdesc->ld_pattern = LOV_PATTERN_RAID0;
1293 lovdesc->ld_default_stripe_size = 1024 * 1024;
1294 lovdesc->ld_default_stripe_offset = 0;
1295 lovdesc->ld_qos_maxage = QOS_DEFAULT_MAXAGE;
1296 sprintf((char*)lovdesc->ld_uuid.uuid, "%s_UUID", lovname);
1297 /* can these be the same? */
1298 uuid = (char *)lovdesc->ld_uuid.uuid;
1300 /* This should always be the first entry in a log.
1301 rc = mgs_clear_log(obd, logname); */
1302 rc = record_start_log(obd, &llh, logname);
1305 /* FIXME these should be a single journal transaction */
1306 rc = record_marker(obd, llh, fsdb, CM_START, lovname, "lov setup");
1307 rc = record_attach(obd, llh, lovname, "lov", uuid);
1308 rc = record_lov_setup(obd, llh, lovname, lovdesc);
1309 rc = record_marker(obd, llh, fsdb, CM_END, lovname, "lov setup");
1310 rc = record_end_log(obd, &llh);
1314 OBD_FREE_PTR(lovdesc);
1318 /* add failnids to open log */
1319 static int mgs_write_log_failnids(struct obd_device *obd,
1320 struct mgs_target_info *mti,
1321 struct llog_handle *llh,
1324 char *failnodeuuid = NULL;
1325 char *ptr = mti->mti_params;
1330 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) nal=90 0: 1:uml1_UUID
1331 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
1332 #05 L setup 0:OSC_uml1_ost1_mdsA 1:ost1_UUID 2:uml1_UUID
1333 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) nal=90 0: 1:uml2_UUID
1334 #0x L add_uuid nid=2@elan(0x1000000000002) nal=90 0: 1:uml2_UUID
1335 #07 L add_conn 0:OSC_uml1_ost1_mdsA 1:uml2_UUID
1338 /* Pull failnid info out of params string */
1339 while (class_find_param(ptr, PARAM_FAILNODE, &ptr) == 0) {
1340 while (class_parse_nid(ptr, &nid, &ptr) == 0) {
1341 if (failnodeuuid == NULL) {
1342 /* We don't know the failover node name,
1343 so just use the first nid as the uuid */
1344 rc = name_create(&failnodeuuid,
1345 libcfs_nid2str(nid), "");
1349 CDEBUG(D_MGS, "add nid %s for failover uuid %s, "
1350 "client %s\n", libcfs_nid2str(nid),
1351 failnodeuuid, cliname);
1352 rc = record_add_uuid(obd, llh, nid, failnodeuuid);
1355 rc = record_add_conn(obd, llh, cliname, failnodeuuid);
1356 name_destroy(&failnodeuuid);
1357 failnodeuuid = NULL;
1364 static int mgs_write_log_mdc_to_lmv(struct obd_device *obd, struct fs_db *fsdb,
1365 struct mgs_target_info *mti,
1366 char *logname, char *lmvname)
1368 struct llog_handle *llh = NULL;
1369 char *mdcname, *nodeuuid, *mdcuuid, *lmvuuid;
1374 if (mgs_log_is_empty(obd, logname)) {
1375 CERROR("log is empty! Logical error\n");
1379 CDEBUG(D_MGS, "adding mdc for %s to log %s:lmv(%s)\n",
1380 mti->mti_svname, logname, lmvname);
1382 name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
1383 name_create(&mdcname, mti->mti_svname, "-mdc");
1384 name_create(&mdcuuid, mdcname, "_UUID");
1385 name_create(&lmvuuid, lmvname, "_UUID");
1387 rc = record_start_log(obd, &llh, logname);
1388 rc = record_marker(obd, llh, fsdb, CM_START, mti->mti_svname,
1391 for (i = 0; i < mti->mti_nid_count; i++) {
1392 CDEBUG(D_MGS, "add nid %s for mdt\n",
1393 libcfs_nid2str(mti->mti_nids[i]));
1395 rc = record_add_uuid(obd, llh, mti->mti_nids[i], nodeuuid);
1398 rc = record_attach(obd, llh, mdcname, LUSTRE_MDC_NAME, lmvuuid);
1399 rc = record_setup(obd, llh, mdcname, mti->mti_uuid, nodeuuid, 0, 0);
1400 rc = mgs_write_log_failnids(obd, mti, llh, mdcname);
1401 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
1402 rc = record_mdc_add(obd, llh, lmvname, mdcuuid, mti->mti_uuid,
1404 rc = record_marker(obd, llh, fsdb, CM_END, mti->mti_svname,
1406 rc = record_end_log(obd, &llh);
1408 name_destroy(&lmvuuid);
1409 name_destroy(&mdcuuid);
1410 name_destroy(&mdcname);
1411 name_destroy(&nodeuuid);
1415 /* add new mdc to already existent MDS */
1416 static int mgs_write_log_mdc_to_mdt(struct obd_device *obd, struct fs_db *fsdb,
1417 struct mgs_target_info *mti, char *logname)
1419 struct llog_handle *llh = NULL;
1420 char *nodeuuid, *mdcname, *mdcuuid, *mdtuuid;
1421 int idx = mti->mti_stripe_index;
1426 if (mgs_log_is_empty(obd, mti->mti_svname)) {
1427 CERROR("log is empty! Logical error\n");
1431 CDEBUG(D_MGS, "adding mdc index %d to %s\n", idx, logname);
1433 name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
1434 snprintf(index, sizeof(index), "-mdc%04x", idx);
1435 name_create(&mdcname, logname, index);
1436 name_create(&mdcuuid, mdcname, "_UUID");
1437 name_create(&mdtuuid, logname, "_UUID");
1439 rc = record_start_log(obd, &llh, logname);
1440 rc = record_marker(obd, llh, fsdb, CM_START, mti->mti_svname, "add mdc");
1441 for (i = 0; i < mti->mti_nid_count; i++) {
1442 CDEBUG(D_MGS, "add nid %s for mdt\n",
1443 libcfs_nid2str(mti->mti_nids[i]));
1444 rc = record_add_uuid(obd, llh, mti->mti_nids[i], nodeuuid);
1446 rc = record_attach(obd, llh, mdcname, LUSTRE_MDC_NAME, mdcuuid);
1447 rc = record_setup(obd, llh, mdcname, mti->mti_uuid, nodeuuid, 0, 0);
1448 rc = mgs_write_log_failnids(obd, mti, llh, mdcname);
1449 snprintf(index, sizeof(index), "%d", idx);
1451 rc = record_mdc_add(obd, llh, logname, mdcuuid, mti->mti_uuid,
1453 rc = record_marker(obd, llh, fsdb, CM_END, mti->mti_svname, "add mdc");
1454 rc = record_end_log(obd, &llh);
1456 name_destroy(&mdcuuid);
1457 name_destroy(&mdcname);
1458 name_destroy(&nodeuuid);
1459 name_destroy(&mdtuuid);
1463 static int mgs_write_log_mdt0(struct obd_device *obd, struct fs_db *fsdb,
1464 struct mgs_target_info *mti)
1466 char *log = mti->mti_svname;
1467 struct llog_handle *llh = NULL;
1468 char *uuid, *lovname;
1470 char *ptr = mti->mti_params;
1471 int rc = 0, failout = 0;
1474 OBD_ALLOC(uuid, sizeof(struct obd_uuid));
1478 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
1479 failout = (strncmp(ptr, "failout", 7) == 0);
1481 name_create(&lovname, log, "-mdtlov");
1482 if (mgs_log_is_empty(obd, log))
1483 rc = mgs_write_log_lov(obd, fsdb, mti, log, lovname);
1485 sprintf(uuid, "%s_UUID", log);
1486 sprintf(mdt_index,"%d",mti->mti_stripe_index);
1488 /* add MDT itself */
1489 rc = record_start_log(obd, &llh, log);
1493 /* FIXME this whole fn should be a single journal transaction */
1494 rc = record_marker(obd, llh, fsdb, CM_START, log, "add mdt");
1495 rc = record_attach(obd, llh, log, LUSTRE_MDT_NAME, uuid);
1496 rc = record_mount_opt(obd, llh, log, lovname, NULL);
1497 rc = record_setup(obd, llh, log, uuid, mdt_index, lovname,
1498 failout ? "n" : "f");
1499 rc = record_marker(obd, llh, fsdb, CM_END, log, "add mdt");
1500 rc = record_end_log(obd, &llh);
1502 name_destroy(&lovname);
1503 OBD_FREE(uuid, sizeof(struct obd_uuid));
1507 /* envelope method for all layers log */
1508 static int mgs_write_log_mdt(struct obd_device *obd, struct fs_db *fsdb,
1509 struct mgs_target_info *mti)
1511 struct llog_handle *llh = NULL;
1513 struct temp_comp comp = { 0 };
1518 CDEBUG(D_MGS, "writing new mdt %s\n", mti->mti_svname);
1522 if (mti->mti_flags & LDD_F_UPGRADE14) {
1523 /* We're starting with an old uuid. Assume old name for lov
1524 as well since the lov entry already exists in the log. */
1525 CDEBUG(D_MGS, "old mds uuid %s\n", mti->mti_uuid);
1526 if (strncmp(mti->mti_uuid, fsdb->fsdb_mdtlov + 4,
1527 strlen(fsdb->fsdb_mdtlov) - 4) != 0) {
1528 CERROR("old mds uuid %s doesn't match log %s (%s)\n",
1529 mti->mti_uuid, fsdb->fsdb_mdtlov,
1530 fsdb->fsdb_mdtlov + 4);
1534 /* end COMPAT_146 */
1536 if (mti->mti_uuid[0] == '\0') {
1537 /* Make up our own uuid */
1538 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
1539 "%s_UUID", mti->mti_svname);
1543 rc = mgs_write_log_mdt0(obd, fsdb, mti);
1545 /* Append the mdt info to the client log */
1546 name_create(&cliname, mti->mti_fsname, "-client");
1548 if (mgs_log_is_empty(obd, cliname)) {
1549 /* Start client log */
1550 rc = mgs_write_log_lov(obd, fsdb, mti, cliname,
1552 rc = mgs_write_log_lmv(obd, fsdb, mti, cliname,
1557 #09 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
1558 #10 L attach 0:MDC_uml1_mdsA_MNT_client 1:mdc 2:1d834_MNT_client_03f
1559 #11 L setup 0:MDC_uml1_mdsA_MNT_client 1:mdsA_UUID 2:uml1_UUID
1560 #12 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
1561 #13 L add_conn 0:MDC_uml1_mdsA_MNT_client 1:uml2_UUID
1562 #14 L mount_option 0: 1:client 2:lov1 3:MDC_uml1_mdsA_MNT_client
1567 if (mti->mti_flags & LDD_F_UPGRADE14) {
1568 rc = record_start_log(obd, &llh, cliname);
1572 rc = record_marker(obd, llh, fsdb, CM_START,
1573 mti->mti_svname,"add mdc");
1575 /* Old client log already has MDC entry, but needs mount opt
1576 for new client name (lustre-client) */
1577 /* FIXME Old MDT log already has an old mount opt
1578 which we should remove (currently handled by
1579 class_del_profiles()) */
1580 rc = record_mount_opt(obd, llh, cliname, fsdb->fsdb_clilov,
1582 /* end COMPAT_146 */
1584 rc = record_marker(obd, llh, fsdb, CM_END,
1585 mti->mti_svname, "add mdc");
1589 /* copy client info about lov/lmv */
1590 comp.comp_mti = mti;
1591 comp.comp_fsdb = fsdb;
1593 rc = mgs_steal_llog_for_mdt_from_client(obd, cliname,
1596 rc = mgs_write_log_mdc_to_lmv(obd, fsdb, mti, cliname,
1599 rc = record_start_log(obd, &llh, cliname);
1603 rc = record_marker(obd, llh, fsdb, CM_START, cliname,
1605 rc = record_mount_opt(obd, llh, cliname, fsdb->fsdb_clilov,
1607 rc = record_marker(obd, llh, fsdb, CM_END, cliname,
1611 rc = record_end_log(obd, &llh);
1613 name_destroy(&cliname);
1615 // for_all_existing_mdt except current one
1616 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
1618 if (i != mti->mti_stripe_index &&
1619 test_bit(i, fsdb->fsdb_mdt_index_map)) {
1620 sprintf(mdt_index,"-MDT%04x",i);
1622 name_create(&mdtname, mti->mti_fsname, mdt_index);
1623 rc = mgs_write_log_mdc_to_mdt(obd, fsdb, mti, mdtname);
1624 name_destroy(&mdtname);
1631 /* Add the ost info to the client/mdt lov */
1632 static int mgs_write_log_osc_to_lov(struct obd_device *obd, struct fs_db *fsdb,
1633 struct mgs_target_info *mti,
1634 char *logname, char *suffix, char *lovname,
1635 enum lustre_sec_part sec_part, int flags)
1637 struct llog_handle *llh = NULL;
1638 char *nodeuuid, *oscname, *oscuuid, *lovuuid, *svname;
1643 CDEBUG(D_INFO, "adding osc for %s to log %s\n",
1644 mti->mti_svname, logname);
1646 if (mgs_log_is_empty(obd, logname)) {
1647 /* The first item in the log must be the lov, so we have
1648 somewhere to add our osc. */
1649 rc = mgs_write_log_lov(obd, fsdb, mti, logname, lovname);
1652 name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
1653 name_create(&svname, mti->mti_svname, "-osc");
1654 name_create(&oscname, svname, suffix);
1655 name_create(&oscuuid, oscname, "_UUID");
1656 name_create(&lovuuid, lovname, "_UUID");
1659 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
1661 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
1662 #04 L attach 0:OSC_uml1_ost1_MNT_client 1:osc 2:89070_lov1_a41dff51a
1663 #05 L setup 0:OSC_uml1_ost1_MNT_client 1:ost1_UUID 2:uml1_UUID
1665 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
1666 #07 L add_conn 0:OSC_uml1_ost1_MNT_client 1:uml2_UUID
1667 #08 L lov_modify_tgts add 0:lov1 1:ost1_UUID 2(index):0 3(gen):1
1670 rc = record_start_log(obd, &llh, logname);
1673 /* FIXME these should be a single journal transaction */
1674 rc = record_marker(obd, llh, fsdb, CM_START | flags, mti->mti_svname,
1676 for (i = 0; i < mti->mti_nid_count; i++) {
1677 CDEBUG(D_MGS, "add nid %s\n", libcfs_nid2str(mti->mti_nids[i]));
1678 rc = record_add_uuid(obd, llh, mti->mti_nids[i], nodeuuid);
1680 rc = record_attach(obd, llh, oscname, LUSTRE_OSC_NAME, lovuuid);
1681 rc = record_setup(obd, llh, oscname, mti->mti_uuid, nodeuuid, 0, 0);
1682 rc = mgs_write_log_failnids(obd, mti, llh, oscname);
1683 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
1684 rc = record_lov_add(obd, llh, lovname, mti->mti_uuid, index, "1");
1685 rc = record_marker(obd, llh, fsdb, CM_END | flags, mti->mti_svname,
1687 rc = record_end_log(obd, &llh);
1689 name_destroy(&lovuuid);
1690 name_destroy(&oscuuid);
1691 name_destroy(&oscname);
1692 name_destroy(&svname);
1693 name_destroy(&nodeuuid);
1697 static int mgs_write_log_ost(struct obd_device *obd, struct fs_db *fsdb,
1698 struct mgs_target_info *mti)
1700 struct llog_handle *llh = NULL;
1701 char *logname, *lovname;
1703 char *ptr = mti->mti_params;
1704 int rc, flags = 0, failout = 0, i;
1707 CDEBUG(D_MGS, "writing new ost %s\n", mti->mti_svname);
1709 /* The ost startup log */
1711 /* If the ost log already exists, that means that someone reformatted
1712 the ost and it called target_add again. */
1713 if (!mgs_log_is_empty(obd, mti->mti_svname)) {
1714 LCONSOLE_ERROR_MSG(0x141, "The config log for %s already "
1715 "exists, yet the server claims it never "
1716 "registered. It may have been reformatted, "
1717 "or the index changed. writeconf the MDT to "
1718 "regenerate all logs.\n", mti->mti_svname);
1723 attach obdfilter ost1 ost1_UUID
1724 setup /dev/loop2 ldiskfs f|n errors=remount-ro,user_xattr
1726 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
1727 failout = (strncmp(ptr, "failout", 7) == 0);
1728 rc = record_start_log(obd, &llh, mti->mti_svname);
1731 /* FIXME these should be a single journal transaction */
1732 rc = record_marker(obd, llh, fsdb, CM_START, mti->mti_svname,"add ost");
1733 if (*mti->mti_uuid == '\0')
1734 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
1735 "%s_UUID", mti->mti_svname);
1736 rc = record_attach(obd, llh, mti->mti_svname,
1737 "obdfilter"/*LUSTRE_OST_NAME*/, mti->mti_uuid);
1738 rc = record_setup(obd, llh, mti->mti_svname,
1739 "dev"/*ignored*/, "type"/*ignored*/,
1740 failout ? "n" : "f", 0/*options*/);
1741 rc = record_marker(obd, llh, fsdb, CM_END, mti->mti_svname, "add ost");
1742 rc = record_end_log(obd, &llh);
1744 /* We also have to update the other logs where this osc is part of
1747 if (fsdb->fsdb_flags & FSDB_OLDLOG14) {
1748 /* If we're upgrading, the old mdt log already has our
1749 entry. Let's do a fake one for fun. */
1750 /* Note that we can't add any new failnids, since we don't
1751 know the old osc names. */
1752 flags = CM_SKIP | CM_UPGRADE146;
1754 } else if ((mti->mti_flags & LDD_F_UPDATE) != LDD_F_UPDATE) {
1755 /* If the update flag isn't set, don't update client/mdt
1758 LCONSOLE_WARN("Client log for %s was not updated; writeconf "
1759 "the MDT first to regenerate it.\n",
1763 // for_all_existing_mdt
1764 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
1765 if (test_bit(i, fsdb->fsdb_mdt_index_map)) {
1766 sprintf(mdt_index,"-MDT%04x",i);
1767 name_create(&logname, mti->mti_fsname, mdt_index);
1768 name_create(&lovname, logname, "-mdtlov");
1769 mgs_write_log_osc_to_lov(obd, fsdb, mti, logname,
1771 LUSTRE_SP_MDT, flags);
1772 name_destroy(&logname);
1773 name_destroy(&lovname);
1777 /* Append ost info to the client log */
1778 name_create(&logname, mti->mti_fsname, "-client");
1779 mgs_write_log_osc_to_lov(obd, fsdb, mti, logname, "",
1780 fsdb->fsdb_clilov, LUSTRE_SP_CLI, 0);
1781 name_destroy(&logname);
1785 /* Add additional failnids to an existing log.
1786 The mdc/osc must have been added to logs first */
1787 /* tcp nids must be in dotted-quad ascii -
1788 we can't resolve hostnames from the kernel. */
1789 static int mgs_write_log_add_failnid(struct obd_device *obd, struct fs_db *fsdb,
1790 struct mgs_target_info *mti)
1792 char *logname, *cliname;
1793 struct llog_handle *llh = NULL;
1797 /* FIXME how do we delete a failnid? Currently --writeconf is the
1798 only way. Maybe make --erase-params pass a flag to really
1799 erase all params from logs - except it can't erase the failnids
1800 given when a target first registers, since they aren't processed
1803 /* Verify that we know about this target */
1804 if (mgs_log_is_empty(obd, mti->mti_svname)) {
1805 LCONSOLE_ERROR_MSG(0x142, "The target %s has not registered "
1806 "yet. It must be started before failnids "
1807 "can be added.\n", mti->mti_svname);
1811 /* Create mdc/osc client name (e.g. lustre-OST0001-osc) */
1812 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
1813 name_create(&cliname, mti->mti_svname, "-mdc");
1814 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
1815 name_create(&cliname, mti->mti_svname, "-osc");
1820 /* Add failover nids to client log */
1821 name_create(&logname, mti->mti_fsname, "-client");
1822 rc = record_start_log(obd, &llh, logname);
1824 /* FIXME this fn should be a single journal transaction */
1825 rc = record_marker(obd, llh, fsdb, CM_START, mti->mti_svname,
1827 rc = mgs_write_log_failnids(obd, mti, llh, cliname);
1828 rc = record_marker(obd, llh, fsdb, CM_END, mti->mti_svname,
1830 rc = record_end_log(obd, &llh);
1832 name_destroy(&logname);
1834 if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
1835 /* Add OST failover nids to the MDT log as well */
1836 name_create(&logname, mti->mti_fsname, "-MDT0000");
1837 rc = record_start_log(obd, &llh, logname);
1839 rc = record_marker(obd, llh, fsdb, CM_START,
1840 mti->mti_svname, "add failnid");
1841 rc = mgs_write_log_failnids(obd, mti, llh, cliname);
1842 rc = record_marker(obd, llh, fsdb, CM_END,
1843 mti->mti_svname, "add failnid");
1844 rc = record_end_log(obd, &llh);
1846 name_destroy(&logname);
1849 name_destroy(&cliname);
1853 static int mgs_wlp_lcfg(struct obd_device *obd, struct fs_db *fsdb,
1854 struct mgs_target_info *mti,
1855 char *logname, struct lustre_cfg_bufs *bufs,
1856 char *tgtname, char *ptr)
1858 char comment[MTI_NAME_MAXLEN];
1860 struct lustre_cfg *lcfg;
1863 /* Erase any old settings of this same parameter */
1864 memcpy(comment, ptr, MTI_NAME_MAXLEN);
1865 comment[MTI_NAME_MAXLEN - 1] = 0;
1866 /* But don't try to match the value. */
1867 if ((tmp = strchr(comment, '=')))
1869 /* FIXME we should skip settings that are the same as old values */
1870 rc = mgs_modify(obd, fsdb, mti, logname, tgtname, comment, CM_SKIP);
1871 LCONSOLE_INFO("%sing parameter %s.%s in log %s\n", rc ?
1872 "Sett" : "Modify", tgtname, comment, logname);
1874 lustre_cfg_bufs_reset(bufs, tgtname);
1875 lustre_cfg_bufs_set_string(bufs, 1, ptr);
1876 lcfg = lustre_cfg_new(LCFG_PARAM, bufs);
1879 rc = mgs_write_log_direct(obd, fsdb, logname, lcfg, tgtname, comment);
1880 lustre_cfg_free(lcfg);
1884 /* write global variable settings into log */
1885 static int mgs_write_log_sys(struct obd_device *obd, struct fs_db *fsdb,
1886 struct mgs_target_info *mti, char *sys, char *ptr)
1888 struct lustre_cfg_bufs bufs;
1889 struct lustre_cfg *lcfg;
1894 if (class_match_param(ptr, PARAM_TIMEOUT, &tmp) == 0)
1895 cmd = LCFG_SET_TIMEOUT;
1896 else if (class_match_param(ptr, PARAM_LDLM_TIMEOUT, &tmp) == 0)
1897 cmd = LCFG_SET_LDLM_TIMEOUT;
1898 /* Check for known params here so we can return error to lctl */
1899 else if ((class_match_param(ptr, PARAM_AT_MIN, &tmp) == 0)
1900 || (class_match_param(ptr, PARAM_AT_MAX, &tmp) == 0)
1901 || (class_match_param(ptr, PARAM_AT_EXTRA, &tmp) == 0)
1902 || (class_match_param(ptr, PARAM_AT_EARLY_MARGIN, &tmp) == 0)
1903 || (class_match_param(ptr, PARAM_AT_HISTORY, &tmp) == 0))
1908 val = simple_strtoul(tmp, NULL, 0);
1909 CDEBUG(D_MGS, "global %s = %d\n", ptr, val);
1911 lustre_cfg_bufs_reset(&bufs, NULL);
1912 lustre_cfg_bufs_set_string(&bufs, 1, sys);
1913 lcfg = lustre_cfg_new(cmd, &bufs);
1914 lcfg->lcfg_num = val;
1915 /* modify all servers and clients */
1916 rc = mgs_write_log_direct_all(obd, fsdb, mti, lcfg, mti->mti_fsname,
1918 lustre_cfg_free(lcfg);
1922 static int mgs_srpc_set_param_disk(struct obd_device *obd,
1924 struct mgs_target_info *mti,
1927 struct llog_handle *llh = NULL;
1929 char *comment, *ptr;
1930 struct lustre_cfg_bufs bufs;
1931 struct lustre_cfg *lcfg;
1936 ptr = strchr(param, '=');
1940 OBD_ALLOC(comment, len + 1);
1941 if (comment == NULL)
1943 strncpy(comment, param, len);
1944 comment[len] = '\0';
1947 lustre_cfg_bufs_reset(&bufs, mti->mti_svname);
1948 lustre_cfg_bufs_set_string(&bufs, 1, param);
1949 lcfg = lustre_cfg_new(LCFG_SPTLRPC_CONF, &bufs);
1951 GOTO(out_comment, rc = -ENOMEM);
1953 /* construct log name */
1954 rc = name_create(&logname, mti->mti_fsname, "-sptlrpc");
1958 if (mgs_log_is_empty(obd, logname)) {
1959 rc = record_start_log(obd, &llh, logname);
1960 record_end_log(obd, &llh);
1965 /* obsolete old one */
1966 mgs_modify(obd, fsdb, mti, logname, mti->mti_svname, comment, CM_SKIP);
1968 /* write the new one */
1969 rc = mgs_write_log_direct(obd, fsdb, logname, lcfg,
1970 mti->mti_svname, comment);
1972 CERROR("err %d writing log %s\n", rc, logname);
1975 name_destroy(&logname);
1977 lustre_cfg_free(lcfg);
1979 OBD_FREE(comment, len + 1);
1983 static int mgs_srpc_set_param_udesc_mem(struct fs_db *fsdb,
1988 /* disable the adjustable udesc parameter for now, i.e. use default
1989 * setting that client always ship udesc to MDT if possible. to enable
1990 * it simply remove the following line */
1993 ptr = strchr(param, '=');
1998 if (strcmp(param, PARAM_SRPC_UDESC))
2001 if (strcmp(ptr, "yes") == 0) {
2002 fsdb->fsdb_fl_udesc = 1;
2003 CWARN("Enable user descriptor shipping from client to MDT\n");
2004 } else if (strcmp(ptr, "no") == 0) {
2005 fsdb->fsdb_fl_udesc = 0;
2006 CWARN("Disable user descriptor shipping from client to MDT\n");
2014 CERROR("Invalid param: %s\n", param);
2018 static int mgs_srpc_set_param_mem(struct fs_db *fsdb,
2022 struct sptlrpc_rule rule;
2023 struct sptlrpc_rule_set *rset;
2027 if (strncmp(param, PARAM_SRPC, sizeof(PARAM_SRPC) - 1) != 0) {
2028 CERROR("Invalid sptlrpc parameter: %s\n", param);
2032 if (strncmp(param, PARAM_SRPC_UDESC,
2033 sizeof(PARAM_SRPC_UDESC) - 1) == 0) {
2034 RETURN(mgs_srpc_set_param_udesc_mem(fsdb, param));
2037 if (strncmp(param, PARAM_SRPC_FLVR, sizeof(PARAM_SRPC_FLVR) - 1) != 0) {
2038 CERROR("Invalid sptlrpc flavor parameter: %s\n", param);
2042 param += sizeof(PARAM_SRPC_FLVR) - 1;
2044 rc = sptlrpc_parse_rule(param, &rule);
2048 /* mgs rules implies must be mgc->mgs */
2049 if (fsdb->fsdb_fl_mgsself) {
2050 if ((rule.sr_from != LUSTRE_SP_MGC &&
2051 rule.sr_from != LUSTRE_SP_ANY) ||
2052 (rule.sr_to != LUSTRE_SP_MGS &&
2053 rule.sr_to != LUSTRE_SP_ANY))
2057 /* preapre room for this coming rule. svcname format should be:
2058 * - fsname: general rule
2059 * - fsname-tgtname: target-specific rule
2061 if (strchr(svname, '-')) {
2062 struct mgs_tgt_srpc_conf *tgtconf;
2065 for (tgtconf = fsdb->fsdb_srpc_tgt; tgtconf != NULL;
2066 tgtconf = tgtconf->mtsc_next) {
2067 if (!strcmp(tgtconf->mtsc_tgt, svname)) {
2076 OBD_ALLOC_PTR(tgtconf);
2077 if (tgtconf == NULL)
2080 name_len = strlen(svname);
2082 OBD_ALLOC(tgtconf->mtsc_tgt, name_len + 1);
2083 if (tgtconf->mtsc_tgt == NULL) {
2084 OBD_FREE_PTR(tgtconf);
2087 memcpy(tgtconf->mtsc_tgt, svname, name_len);
2089 tgtconf->mtsc_next = fsdb->fsdb_srpc_tgt;
2090 fsdb->fsdb_srpc_tgt = tgtconf;
2093 rset = &tgtconf->mtsc_rset;
2095 rset = &fsdb->fsdb_srpc_gen;
2098 rc = sptlrpc_rule_set_merge(rset, &rule);
2103 static int mgs_srpc_set_param(struct obd_device *obd,
2105 struct mgs_target_info *mti,
2115 /* keep a copy of original param, which could be destroied
2117 copy_size = strlen(param) + 1;
2118 OBD_ALLOC(copy, copy_size);
2121 memcpy(copy, param, copy_size);
2123 rc = mgs_srpc_set_param_mem(fsdb, mti->mti_svname, param);
2127 /* previous steps guaranteed the syntax is correct */
2128 rc = mgs_srpc_set_param_disk(obd, fsdb, mti, copy);
2132 if (fsdb->fsdb_fl_mgsself) {
2134 * for mgs rules, make them effective immediately.
2136 LASSERT(fsdb->fsdb_srpc_tgt == NULL);
2137 sptlrpc_target_update_exp_flavor(obd, &fsdb->fsdb_srpc_gen);
2141 OBD_FREE(copy, copy_size);
2145 struct mgs_srpc_read_data {
2146 struct fs_db *msrd_fsdb;
2150 static int mgs_srpc_read_handler(struct llog_handle *llh,
2151 struct llog_rec_hdr *rec,
2154 struct mgs_srpc_read_data *msrd = (struct mgs_srpc_read_data *) data;
2155 struct cfg_marker *marker;
2156 struct lustre_cfg *lcfg = (struct lustre_cfg *)(rec + 1);
2157 char *svname, *param;
2161 if (rec->lrh_type != OBD_CFG_REC) {
2162 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
2166 cfg_len = rec->lrh_len - sizeof(struct llog_rec_hdr) -
2167 sizeof(struct llog_rec_tail);
2169 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
2171 CERROR("Insane cfg\n");
2175 if (lcfg->lcfg_command == LCFG_MARKER) {
2176 marker = lustre_cfg_buf(lcfg, 1);
2178 if (marker->cm_flags & CM_START &&
2179 marker->cm_flags & CM_SKIP)
2180 msrd->msrd_skip = 1;
2181 if (marker->cm_flags & CM_END)
2182 msrd->msrd_skip = 0;
2187 if (msrd->msrd_skip)
2190 if (lcfg->lcfg_command != LCFG_SPTLRPC_CONF) {
2191 CERROR("invalid command (%x)\n", lcfg->lcfg_command);
2195 svname = lustre_cfg_string(lcfg, 0);
2196 if (svname == NULL) {
2197 CERROR("svname is empty\n");
2201 param = lustre_cfg_string(lcfg, 1);
2202 if (param == NULL) {
2203 CERROR("param is empty\n");
2207 rc = mgs_srpc_set_param_mem(msrd->msrd_fsdb, svname, param);
2209 CERROR("read sptlrpc record error (%d): %s\n", rc, param);
2214 int mgs_get_fsdb_srpc_from_llog(struct obd_device *obd,
2217 struct llog_handle *llh = NULL;
2218 struct lvfs_run_ctxt saved;
2219 struct llog_ctxt *ctxt;
2221 struct mgs_srpc_read_data msrd;
2225 /* construct log name */
2226 rc = name_create(&logname, fsdb->fsdb_name, "-sptlrpc");
2230 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
2231 LASSERT(ctxt != NULL);
2233 if (mgs_log_is_empty(obd, logname))
2236 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
2238 rc = llog_create(ctxt, &llh, NULL, logname);
2242 rc = llog_init_handle(llh, LLOG_F_IS_PLAIN, NULL);
2244 GOTO(out_close, rc);
2246 if (llog_get_size(llh) <= 1)
2247 GOTO(out_close, rc = 0);
2249 msrd.msrd_fsdb = fsdb;
2252 rc = llog_process(llh, mgs_srpc_read_handler, (void *) &msrd, NULL);
2257 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
2259 llog_ctxt_put(ctxt);
2260 name_destroy(&logname);
2263 CERROR("failed to read sptlrpc config database: %d\n", rc);
2267 static int mgs_write_log_param(struct obd_device *obd, struct fs_db *fsdb,
2268 struct mgs_target_info *mti, char *ptr)
2270 struct lustre_cfg_bufs bufs;
2276 /* For various parameter settings, we have to figure out which logs
2277 care about them (e.g. both mdt and client for lov settings) */
2278 CDEBUG(D_MGS, "next param '%s'\n", ptr);
2280 /* The params are stored in MOUNT_DATA_FILE and modified via
2281 tunefs.lustre, or set using lctl conf_param */
2283 /* Processed in lustre_start_mgc */
2284 if (class_match_param(ptr, PARAM_MGSNODE, NULL) == 0)
2287 /* Processed in mgs_write_log_ost */
2288 if (class_match_param(ptr, PARAM_FAILMODE, NULL) == 0) {
2289 if (mti->mti_flags & LDD_F_PARAM) {
2290 LCONSOLE_ERROR_MSG(0x169, "%s can only be "
2291 "changed with tunefs.lustre"
2292 "and --writeconf\n", ptr);
2298 if (class_match_param(ptr, PARAM_SRPC, NULL) == 0) {
2299 rc = mgs_srpc_set_param(obd, fsdb, mti, ptr);
2303 if (class_match_param(ptr, PARAM_FAILNODE, NULL) == 0) {
2304 /* Add a failover nidlist */
2306 /* We already processed failovers params for new
2307 targets in mgs_write_log_target */
2308 if (mti->mti_flags & LDD_F_PARAM) {
2309 CDEBUG(D_MGS, "Adding failnode\n");
2310 rc = mgs_write_log_add_failnid(obd, fsdb, mti);
2315 if (class_match_param(ptr, PARAM_SYS, &tmp) == 0) {
2316 rc = mgs_write_log_sys(obd, fsdb, mti, ptr, tmp);
2320 if (class_match_param(ptr, PARAM_OSC""PARAM_ACTIVE, &tmp) == 0) {
2321 /* active=0 means off, anything else means on */
2323 int flag = (*tmp == '0') ? CM_EXCLUDE : 0;
2326 if (!(mti->mti_flags & LDD_F_SV_TYPE_OST)) {
2327 LCONSOLE_ERROR_MSG(0x144, "%s: Only OSCs can "
2328 "be (de)activated.\n",
2330 GOTO(end, rc = -EINVAL);
2332 LCONSOLE_WARN("Permanently %sactivating %s\n",
2333 flag ? "de": "re", mti->mti_svname);
2335 name_create(&logname, mti->mti_fsname, "-client");
2336 rc = mgs_modify(obd, fsdb, mti, logname,
2337 mti->mti_svname, "add osc", flag);
2338 name_destroy(&logname);
2342 /* FIXME add to all MDT logs for CMD */
2343 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2344 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
2346 sprintf(mdt_index,"-MDT%04x", i);
2347 name_create(&logname, mti->mti_fsname, mdt_index);
2348 rc = mgs_modify(obd, fsdb, mti, logname,
2349 mti->mti_svname, "add osc", flag);
2350 name_destroy(&logname);
2356 LCONSOLE_ERROR_MSG(0x145, "Couldn't find %s in"
2357 "log (%d). No permanent "
2358 "changes were made to the "
2360 mti->mti_svname, rc);
2361 if (fsdb->fsdb_flags & FSDB_OLDLOG14)
2362 LCONSOLE_ERROR_MSG(0x146, "This may be"
2367 "update the logs.\n");
2370 /* Fall through to osc proc for deactivating live OSC
2371 on running MDT / clients. */
2373 /* Below here, let obd's XXX_process_config methods handle it */
2375 /* All lov. in proc */
2376 if (class_match_param(ptr, PARAM_LOV, NULL) == 0) {
2380 CDEBUG(D_MGS, "lov param %s\n", ptr);
2381 if (!(mti->mti_flags & LDD_F_SV_TYPE_MDT)) {
2382 LCONSOLE_ERROR_MSG(0x147, "LOV params must be "
2383 "set on the MDT, not %s. "
2390 if (mgs_log_is_empty(obd, mti->mti_svname))
2391 GOTO(end, rc = -ENODEV);
2393 sprintf(mdt_index,"-MDT%04x", mti->mti_stripe_index);
2394 name_create(&logname, mti->mti_fsname, mdt_index);
2395 name_create(&mdtlovname, logname, "-mdtlov");
2396 rc = mgs_wlp_lcfg(obd, fsdb, mti, mti->mti_svname,
2397 &bufs, mdtlovname, ptr);
2398 name_destroy(&logname);
2399 name_destroy(&mdtlovname);
2404 name_create(&logname, mti->mti_fsname, "-client");
2405 rc = mgs_wlp_lcfg(obd, fsdb, mti, logname, &bufs,
2406 fsdb->fsdb_clilov, ptr);
2407 name_destroy(&logname);
2411 /* All osc., mdc., llite. params in proc */
2412 if ((class_match_param(ptr, PARAM_OSC, NULL) == 0) ||
2413 (class_match_param(ptr, PARAM_MDC, NULL) == 0) ||
2414 (class_match_param(ptr, PARAM_LLITE, NULL) == 0)) {
2416 if (memcmp(ptr, PARAM_LLITE, strlen(PARAM_LLITE)) == 0) {
2417 name_create(&cname, mti->mti_fsname, "-client");
2418 /* Add the client type to match the obdname in
2419 class_config_llog_handler */
2420 } else if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
2423 name_create(&cname, fsdb->fsdb_mdc, "");
2425 name_create(&cname, mti->mti_svname,
2427 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2429 if (fsdb->fsdb_flags & FSDB_OLDLOG14) {
2430 LCONSOLE_ERROR_MSG(0x148, "Upgraded "
2431 "client logs for %s"
2433 "modified. Consider"
2435 "configuration with"
2438 /* We don't know the names of all the
2440 GOTO(end, rc = -EINVAL);
2442 name_create(&cname, mti->mti_svname, "-osc");
2444 GOTO(end, rc = -EINVAL);
2447 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
2450 name_create(&logname, mti->mti_fsname, "-client");
2451 rc = mgs_wlp_lcfg(obd, fsdb, mti, logname, &bufs,
2454 /* osc params affect the MDT as well */
2455 if (!rc && (mti->mti_flags & LDD_F_SV_TYPE_OST)) {
2459 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
2460 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
2463 name_destroy(&cname);
2464 if (i == 0 && fsdb->fsdb_fl_oscname_18)
2465 sprintf(mdt_index, "-osc");
2467 sprintf(mdt_index, "-osc-MDT%04x", i);
2468 name_create(&cname, mti->mti_svname, mdt_index);
2470 name_destroy(&logname);
2471 sprintf(mdt_index, "-MDT%04x", i);
2472 name_create(&logname, mti->mti_fsname,
2474 if (!mgs_log_is_empty(obd, logname))
2475 rc = mgs_wlp_lcfg(obd, fsdb,
2483 name_destroy(&logname);
2484 name_destroy(&cname);
2488 /* All mdt. params in proc */
2489 if (class_match_param(ptr, PARAM_MDT, NULL) == 0) {
2494 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
2495 if (strncmp(mti->mti_svname, mti->mti_fsname,
2496 MTI_NAME_MAXLEN) == 0)
2497 /* device is unspecified completely? */
2498 rc = LDD_F_SV_TYPE_MDT | LDD_F_SV_ALL;
2500 rc = server_name2index(mti->mti_svname, &idx, NULL);
2503 if ((rc & LDD_F_SV_TYPE_MDT) == 0)
2505 if (rc & LDD_F_SV_ALL) {
2506 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2508 fsdb->fsdb_mdt_index_map))
2510 sprintf(mdt_index,"-MDT%04x", i);
2511 name_create(&logname, mti->mti_fsname,
2513 rc = mgs_wlp_lcfg(obd, fsdb, mti,
2516 name_destroy(&logname);
2521 rc = mgs_wlp_lcfg(obd, fsdb, mti,
2522 mti->mti_svname, &bufs,
2523 mti->mti_svname, ptr);
2530 /* All mdd., ost. params in proc */
2531 if ((class_match_param(ptr, PARAM_MDD, NULL) == 0) ||
2532 (class_match_param(ptr, PARAM_OST, NULL) == 0)) {
2533 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
2534 if (mgs_log_is_empty(obd, mti->mti_svname))
2535 GOTO(end, rc = -ENODEV);
2537 rc = mgs_wlp_lcfg(obd, fsdb, mti, mti->mti_svname,
2538 &bufs, mti->mti_svname, ptr);
2542 LCONSOLE_WARN("Ignoring unrecognized param '%s'\n", ptr);
2546 CERROR("err %d on param '%s'\n", rc, ptr);
2551 /* Not implementing automatic failover nid addition at this time. */
2552 int mgs_check_failnid(struct obd_device *obd, struct mgs_target_info *mti)
2559 rc = mgs_find_or_make_fsdb(obd, fsname, &fsdb);
2563 if (mgs_log_is_empty(obd, mti->mti_svname))
2564 /* should never happen */
2567 CDEBUG(D_MGS, "Checking for new failnids for %s\n", mti->mti_svname);
2569 /* FIXME We can just check mti->params to see if we're already in
2570 the failover list. Modify mti->params for rewriting back at
2571 server_register_target(). */
2573 down(&fsdb->fsdb_sem);
2574 rc = mgs_write_log_add_failnid(obd, fsdb, mti);
2575 up(&fsdb->fsdb_sem);
2582 int mgs_write_log_target(struct obd_device *obd,
2583 struct mgs_target_info *mti)
2590 /* set/check the new target index */
2591 rc = mgs_set_index(obd, mti);
2593 CERROR("Can't get index (%d)\n", rc);
2598 if (mti->mti_flags & LDD_F_UPGRADE14) {
2599 if (rc == EALREADY) {
2600 LCONSOLE_INFO("Found index %d for %s 1.4 log, "
2601 "upgrading\n", mti->mti_stripe_index,
2604 LCONSOLE_ERROR_MSG(0x149, "Failed to find %s in the old"
2605 " client log. Apparently it is not "
2606 "part of this filesystem, or the old"
2607 " log is wrong.\nUse 'writeconf' on "
2608 "the MDT to force log regeneration."
2609 "\n", mti->mti_svname);
2610 /* Not in client log? Upgrade anyhow...*/
2611 /* Argument against upgrading: reformat MDT,
2612 upgrade OST, then OST will start but will be SKIPped
2613 in client logs. Maybe error now is better. */
2614 /* RETURN(-EINVAL); */
2616 /* end COMPAT_146 */
2618 if (rc == EALREADY) {
2619 LCONSOLE_WARN("Found index %d for %s, updating log\n",
2620 mti->mti_stripe_index, mti->mti_svname);
2621 /* We would like to mark old log sections as invalid
2622 and add new log sections in the client and mdt logs.
2623 But if we add new sections, then live clients will
2624 get repeat setup instructions for already running
2625 osc's. So don't update the client/mdt logs. */
2626 mti->mti_flags &= ~LDD_F_UPDATE;
2630 rc = mgs_find_or_make_fsdb(obd, mti->mti_fsname, &fsdb);
2632 CERROR("Can't get db for %s\n", mti->mti_fsname);
2636 down(&fsdb->fsdb_sem);
2638 if (mti->mti_flags &
2639 (LDD_F_VIRGIN | LDD_F_UPGRADE14 | LDD_F_WRITECONF)) {
2640 /* Generate a log from scratch */
2641 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
2642 rc = mgs_write_log_mdt(obd, fsdb, mti);
2643 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2644 rc = mgs_write_log_ost(obd, fsdb, mti);
2646 CERROR("Unknown target type %#x, can't create log for "
2647 "%s\n", mti->mti_flags, mti->mti_svname);
2650 CERROR("Can't write logs for %s (%d)\n",
2651 mti->mti_svname, rc);
2655 /* Just update the params from tunefs in mgs_write_log_params */
2656 CDEBUG(D_MGS, "Update params for %s\n", mti->mti_svname);
2657 mti->mti_flags |= LDD_F_PARAM;
2660 /* allocate temporary buffer, where class_get_next_param will
2661 make copy of a current parameter */
2662 OBD_ALLOC(buf, strlen(mti->mti_params) + 1);
2664 GOTO(out_up, rc = -ENOMEM);
2665 params = mti->mti_params;
2666 while (params != NULL) {
2667 rc = class_get_next_param(¶ms, buf);
2670 /* there is no next parameter, that is
2675 CDEBUG(D_MGS, "remaining string: '%s', param: '%s'\n",
2677 rc = mgs_write_log_param(obd, fsdb, mti, buf);
2682 OBD_FREE(buf, strlen(mti->mti_params) + 1);
2685 up(&fsdb->fsdb_sem);
2690 /* verify that we can handle the old config logs */
2691 int mgs_upgrade_sv_14(struct obd_device *obd, struct mgs_target_info *mti)
2697 /* Create ost log normally, as servers register. Servers
2698 register with their old uuids (from last_rcvd), so old
2699 (MDT and client) logs should work.
2700 - new MDT won't know about old OSTs, only the ones that have
2701 registered, so we need the old MDT log to get the LOV right
2702 in order for old clients to work.
2703 - Old clients connect to the MDT, not the MGS, for their logs, and
2704 will therefore receive the old client log from the MDT /LOGS dir.
2705 - Old clients can continue to use and connect to old or new OSTs
2706 - New clients will contact the MGS for their log
2709 LCONSOLE_INFO("upgrading server %s from pre-1.6\n", mti->mti_svname);
2710 server_mti_print("upgrade", mti);
2712 rc = mgs_find_or_make_fsdb(obd, mti->mti_fsname, &fsdb);
2716 if (fsdb->fsdb_flags & FSDB_LOG_EMPTY) {
2717 LCONSOLE_ERROR_MSG(0x14a, "The old client log %s-client is "
2718 "missing. Was tunefs.lustre successful?\n",
2723 if (fsdb->fsdb_gen == 0) {
2724 /* There were no markers in the client log, meaning we have
2725 not updated the logs for this fs */
2726 CDEBUG(D_MGS, "found old, unupdated client log\n");
2729 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
2730 if (mgs_log_is_empty(obd, mti->mti_svname)) {
2731 LCONSOLE_ERROR_MSG(0x14b, "The old MDT log %s is "
2732 "missing. Was tunefs.lustre "
2737 /* We're starting with an old uuid. Assume old name for lov
2738 as well since the lov entry already exists in the log. */
2739 CDEBUG(D_MGS, "old mds uuid %s\n", mti->mti_uuid);
2740 if (strncmp(mti->mti_uuid, fsdb->fsdb_mdtlov + 4,
2741 strlen(fsdb->fsdb_mdtlov) - 4) != 0) {
2742 CERROR("old mds uuid %s doesn't match log %s (%s)\n",
2743 mti->mti_uuid, fsdb->fsdb_mdtlov,
2744 fsdb->fsdb_mdtlov + 4);
2749 if (!(fsdb->fsdb_flags & FSDB_OLDLOG14)) {
2750 LCONSOLE_ERROR_MSG(0x14c, "%s-client is supposedly an old "
2751 "log, but no old LOV or MDT was found. "
2752 "Consider updating the configuration with"
2753 " --writeconf.\n", mti->mti_fsname);
2758 /* end COMPAT_146 */
2760 int mgs_erase_log(struct obd_device *obd, char *name)
2762 struct lvfs_run_ctxt saved;
2763 struct llog_ctxt *ctxt;
2764 struct llog_handle *llh;
2767 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
2768 LASSERT(ctxt != NULL);
2770 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
2771 rc = llog_create(ctxt, &llh, NULL, name);
2773 llog_init_handle(llh, LLOG_F_IS_PLAIN, NULL);
2774 rc = llog_destroy(llh);
2775 llog_free_handle(llh);
2777 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
2778 llog_ctxt_put(ctxt);
2781 CERROR("failed to clear log %s: %d\n", name, rc);
2786 /* erase all logs for the given fs */
2787 int mgs_erase_logs(struct obd_device *obd, char *fsname)
2789 struct mgs_obd *mgs = &obd->u.mgs;
2790 static struct fs_db *fsdb;
2791 struct list_head dentry_list;
2792 struct l_linux_dirent *dirent, *n;
2793 int rc, len = strlen(fsname);
2796 /* Find all the logs in the CONFIGS directory */
2797 rc = class_dentry_readdir(obd, mgs->mgs_configs_dir,
2798 mgs->mgs_vfsmnt, &dentry_list);
2800 CERROR("Can't read %s dir\n", MOUNT_CONFIGS_DIR);
2804 down(&mgs->mgs_sem);
2806 /* Delete the fs db */
2807 fsdb = mgs_find_fsdb(obd, fsname);
2809 mgs_free_fsdb(obd, fsdb);
2811 list_for_each_entry_safe(dirent, n, &dentry_list, lld_list) {
2812 list_del(&dirent->lld_list);
2813 if (strncmp(fsname, dirent->lld_name, len) == 0) {
2814 CDEBUG(D_MGS, "Removing log %s\n", dirent->lld_name);
2815 mgs_erase_log(obd, dirent->lld_name);
2817 OBD_FREE(dirent, sizeof(*dirent));
2825 /* from llog_swab */
2826 static void print_lustre_cfg(struct lustre_cfg *lcfg)
2831 CDEBUG(D_MGS, "lustre_cfg: %p\n", lcfg);
2832 CDEBUG(D_MGS, "\tlcfg->lcfg_version: %#x\n", lcfg->lcfg_version);
2834 CDEBUG(D_MGS, "\tlcfg->lcfg_command: %#x\n", lcfg->lcfg_command);
2835 CDEBUG(D_MGS, "\tlcfg->lcfg_num: %#x\n", lcfg->lcfg_num);
2836 CDEBUG(D_MGS, "\tlcfg->lcfg_flags: %#x\n", lcfg->lcfg_flags);
2837 CDEBUG(D_MGS, "\tlcfg->lcfg_nid: %s\n", libcfs_nid2str(lcfg->lcfg_nid));
2839 CDEBUG(D_MGS, "\tlcfg->lcfg_bufcount: %d\n", lcfg->lcfg_bufcount);
2840 if (lcfg->lcfg_bufcount < LUSTRE_CFG_MAX_BUFCOUNT)
2841 for (i = 0; i < lcfg->lcfg_bufcount; i++) {
2842 CDEBUG(D_MGS, "\tlcfg->lcfg_buflens[%d]: %d %s\n",
2843 i, lcfg->lcfg_buflens[i],
2844 lustre_cfg_string(lcfg, i));
2849 /* Set a permanent (config log) param for a target or fs */
2850 int mgs_setparam(struct obd_device *obd, struct lustre_cfg *lcfg, char *fsname)
2853 struct mgs_target_info *mti;
2854 char *devname, *param;
2860 print_lustre_cfg(lcfg);
2862 /* lustre, lustre-mdtlov, lustre-client, lustre-MDT0000 */
2863 devname = lustre_cfg_string(lcfg, 0);
2864 param = lustre_cfg_string(lcfg, 1);
2866 /* Assume device name embedded in param:
2867 lustre-OST0000.osc.max_dirty_mb=32 */
2868 ptr = strchr(param, '.');
2876 LCONSOLE_ERROR_MSG(0x14d, "No target specified: %s\n", param);
2880 /* Extract fsname */
2881 ptr = strrchr(devname, '-');
2882 memset(fsname, 0, MTI_NAME_MAXLEN);
2883 if (ptr && (server_name2index(ptr, &index, NULL) >= 0)) {
2884 /* param related to llite isn't allowed to set by OST or MDT */
2885 if (strncmp(param, PARAM_LLITE, sizeof(PARAM_LLITE)) == 0)
2888 strncpy(fsname, devname, ptr - devname);
2890 /* assume devname is the fsname */
2891 strncpy(fsname, devname, MTI_NAME_MAXLEN);
2893 fsname[MTI_NAME_MAXLEN - 1] = 0;
2894 CDEBUG(D_MGS, "setparam on fs %s device %s\n", fsname, devname);
2896 rc = mgs_find_or_make_fsdb(obd, fsname, &fsdb);
2899 if (!fsdb->fsdb_fl_mgsself && fsdb->fsdb_flags & FSDB_LOG_EMPTY) {
2900 CERROR("No filesystem targets for %s. cfg_device from lctl "
2901 "is '%s'\n", fsname, devname);
2902 mgs_free_fsdb(obd, fsdb);
2906 /* Create a fake mti to hold everything */
2909 GOTO(out, rc = -ENOMEM);
2910 strncpy(mti->mti_fsname, fsname, MTI_NAME_MAXLEN);
2911 strncpy(mti->mti_svname, devname, MTI_NAME_MAXLEN);
2912 strncpy(mti->mti_params, param, sizeof(mti->mti_params));
2913 rc = server_name2index(mti->mti_svname, &mti->mti_stripe_index, &tmp);
2915 /* Not a valid server; may be only fsname */
2918 /* Strip -osc or -mdc suffix from svname */
2919 if (server_make_name(rc, mti->mti_stripe_index, mti->mti_fsname,
2921 GOTO(out, rc = -EINVAL);
2923 mti->mti_flags = rc | LDD_F_PARAM;
2925 down(&fsdb->fsdb_sem);
2926 /* this is lctl conf_param's single param path, there is not
2927 need to loop through parameters */
2928 rc = mgs_write_log_param(obd, fsdb, mti, mti->mti_params);
2929 up(&fsdb->fsdb_sem);
2936 static int mgs_write_log_pool(struct obd_device *obd, char *logname,
2937 struct fs_db *fsdb, char *lovname,
2938 enum lcfg_command_type cmd,
2939 char *poolname, char *fsname,
2940 char *ostname, char *comment)
2942 struct llog_handle *llh = NULL;
2945 rc = record_start_log(obd, &llh, logname);
2948 rc = record_marker(obd, llh, fsdb, CM_START, lovname, comment);
2949 record_base(obd, llh, lovname, 0, cmd, poolname, fsname, ostname, 0);
2950 rc = record_marker(obd, llh, fsdb, CM_END, lovname, comment);
2951 rc = record_end_log(obd, &llh);
2956 int mgs_pool_cmd(struct obd_device *obd, enum lcfg_command_type cmd,
2957 char *fsname, char *poolname, char *ostname)
2963 char *label = NULL, *canceled_label = NULL;
2965 struct mgs_target_info *mti = NULL;
2969 rc = mgs_find_or_make_fsdb(obd, fsname, &fsdb);
2971 CERROR("Can't get db for %s\n", fsname);
2974 if (fsdb->fsdb_flags & FSDB_LOG_EMPTY) {
2975 CERROR("%s is not defined\n", fsname);
2976 mgs_free_fsdb(obd, fsdb);
2980 label_sz = 10 + strlen(fsname) + strlen(poolname);
2982 /* check if ostname match fsname */
2983 if (ostname != NULL) {
2986 ptr = strrchr(ostname, '-');
2987 if ((ptr == NULL) ||
2988 (strncmp(fsname, ostname, ptr-ostname) != 0))
2990 label_sz += strlen(ostname);
2993 OBD_ALLOC(label, label_sz);
2995 GOTO(out, rc = -ENOMEM);
2998 case LCFG_POOL_NEW: {
3000 "new %s.%s", fsname, poolname);
3003 case LCFG_POOL_ADD: {
3005 "add %s.%s.%s", fsname, poolname, ostname);
3008 case LCFG_POOL_REM: {
3009 OBD_ALLOC(canceled_label, label_sz);
3010 if (canceled_label == NULL)
3011 GOTO(out, rc = -ENOMEM);
3013 "rem %s.%s.%s", fsname, poolname, ostname);
3014 sprintf(canceled_label,
3015 "add %s.%s.%s", fsname, poolname, ostname);
3018 case LCFG_POOL_DEL: {
3019 OBD_ALLOC(canceled_label, label_sz);
3020 if (canceled_label == NULL)
3021 GOTO(out, rc = -ENOMEM);
3023 "del %s.%s", fsname, poolname);
3024 sprintf(canceled_label,
3025 "new %s.%s", fsname, poolname);
3033 down(&fsdb->fsdb_sem);
3035 if (canceled_label != NULL) {
3038 GOTO(out, rc = -ENOMEM);
3041 /* loop on all potential MDT */
3042 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3043 if (test_bit(i, fsdb->fsdb_mdt_index_map)) {
3044 sprintf(mdt_index, "-MDT%04x", i);
3045 name_create(&logname, fsname, mdt_index);
3046 name_create(&lovname, logname, "-mdtlov");
3048 if (canceled_label != NULL) {
3049 strcpy(mti->mti_svname, "lov pool");
3050 mgs_modify(obd, fsdb, mti, logname, lovname,
3051 canceled_label, CM_SKIP);
3054 mgs_write_log_pool(obd, logname, fsdb, lovname,
3055 cmd, fsname, poolname, ostname,
3057 name_destroy(&logname);
3058 name_destroy(&lovname);
3062 name_create(&logname, fsname, "-client");
3063 if (canceled_label != NULL)
3064 mgs_modify(obd, fsdb, mti, logname, fsdb->fsdb_clilov,
3065 canceled_label, CM_SKIP);
3067 mgs_write_log_pool(obd, logname, fsdb, fsdb->fsdb_clilov,
3068 cmd, fsname, poolname, ostname, label);
3069 name_destroy(&logname);
3071 up(&fsdb->fsdb_sem);
3076 OBD_FREE(label, label_sz);
3078 if (canceled_label != NULL)
3079 OBD_FREE(canceled_label, label_sz);
3088 /******************** unused *********************/
3089 static int mgs_backup_llog(struct obd_device *obd, char* fsname)
3091 struct file *filp, *bak_filp;
3092 struct lvfs_run_ctxt saved;
3093 char *logname, *buf;
3094 loff_t soff = 0 , doff = 0;
3095 int count = 4096, len;
3098 OBD_ALLOC(logname, PATH_MAX);
3099 if (logname == NULL)
3102 OBD_ALLOC(buf, count);
3104 GOTO(out , rc = -ENOMEM);
3106 len = snprintf(logname, PATH_MAX, "%s/%s.bak",
3107 MOUNT_CONFIGS_DIR, fsname);
3109 if (len >= PATH_MAX - 1) {
3110 GOTO(out, -ENAMETOOLONG);
3113 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
3115 bak_filp = l_filp_open(logname, O_RDWR|O_CREAT|O_TRUNC, 0660);
3116 if (IS_ERR(bak_filp)) {
3117 rc = PTR_ERR(bak_filp);
3118 CERROR("backup logfile open %s: %d\n", logname, rc);
3121 sprintf(logname, "%s/%s", MOUNT_CONFIGS_DIR, fsname);
3122 filp = l_filp_open(logname, O_RDONLY, 0);
3125 CERROR("logfile open %s: %d\n", logname, rc);
3129 while ((rc = lustre_fread(filp, buf, count, &soff)) > 0) {
3130 rc = lustre_fwrite(bak_filp, buf, count, &doff);
3134 filp_close(filp, 0);
3136 filp_close(bak_filp, 0);
3138 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
3141 OBD_FREE(buf, count);
3142 OBD_FREE(logname, PATH_MAX);