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 static inline void name_create_mdt(char **logname, char *fsname, int i)
1511 sprintf(mdt_index, "-MDT%04x", i);
1512 name_create(logname, fsname, mdt_index);
1515 static void name_create_mdt_and_lov(char **logname, char **lovname,
1516 struct fs_db *fsdb, int i)
1518 name_create_mdt(logname, fsdb->fsdb_name, i);
1520 if (i == 0 && fsdb->fsdb_fl_oscname_18)
1521 name_create(lovname, fsdb->fsdb_name, "-mdtlov");
1523 name_create(lovname, *logname, "-mdtlov");
1526 /* envelope method for all layers log */
1527 static int mgs_write_log_mdt(struct obd_device *obd, struct fs_db *fsdb,
1528 struct mgs_target_info *mti)
1530 struct llog_handle *llh = NULL;
1532 struct temp_comp comp = { 0 };
1536 CDEBUG(D_MGS, "writing new mdt %s\n", mti->mti_svname);
1540 if (mti->mti_flags & LDD_F_UPGRADE14) {
1541 /* We're starting with an old uuid. Assume old name for lov
1542 as well since the lov entry already exists in the log. */
1543 CDEBUG(D_MGS, "old mds uuid %s\n", mti->mti_uuid);
1544 if (strncmp(mti->mti_uuid, fsdb->fsdb_mdtlov + 4,
1545 strlen(fsdb->fsdb_mdtlov) - 4) != 0) {
1546 CERROR("old mds uuid %s doesn't match log %s (%s)\n",
1547 mti->mti_uuid, fsdb->fsdb_mdtlov,
1548 fsdb->fsdb_mdtlov + 4);
1552 /* end COMPAT_146 */
1554 if (mti->mti_uuid[0] == '\0') {
1555 /* Make up our own uuid */
1556 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
1557 "%s_UUID", mti->mti_svname);
1561 rc = mgs_write_log_mdt0(obd, fsdb, mti);
1563 /* Append the mdt info to the client log */
1564 name_create(&cliname, mti->mti_fsname, "-client");
1566 if (mgs_log_is_empty(obd, cliname)) {
1567 /* Start client log */
1568 rc = mgs_write_log_lov(obd, fsdb, mti, cliname,
1570 rc = mgs_write_log_lmv(obd, fsdb, mti, cliname,
1575 #09 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
1576 #10 L attach 0:MDC_uml1_mdsA_MNT_client 1:mdc 2:1d834_MNT_client_03f
1577 #11 L setup 0:MDC_uml1_mdsA_MNT_client 1:mdsA_UUID 2:uml1_UUID
1578 #12 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
1579 #13 L add_conn 0:MDC_uml1_mdsA_MNT_client 1:uml2_UUID
1580 #14 L mount_option 0: 1:client 2:lov1 3:MDC_uml1_mdsA_MNT_client
1585 if (mti->mti_flags & LDD_F_UPGRADE14) {
1586 rc = record_start_log(obd, &llh, cliname);
1590 rc = record_marker(obd, llh, fsdb, CM_START,
1591 mti->mti_svname,"add mdc");
1593 /* Old client log already has MDC entry, but needs mount opt
1594 for new client name (lustre-client) */
1595 /* FIXME Old MDT log already has an old mount opt
1596 which we should remove (currently handled by
1597 class_del_profiles()) */
1598 rc = record_mount_opt(obd, llh, cliname, fsdb->fsdb_clilov,
1600 /* end COMPAT_146 */
1602 rc = record_marker(obd, llh, fsdb, CM_END,
1603 mti->mti_svname, "add mdc");
1607 /* copy client info about lov/lmv */
1608 comp.comp_mti = mti;
1609 comp.comp_fsdb = fsdb;
1611 rc = mgs_steal_llog_for_mdt_from_client(obd, cliname,
1614 rc = mgs_write_log_mdc_to_lmv(obd, fsdb, mti, cliname,
1617 rc = record_start_log(obd, &llh, cliname);
1621 rc = record_marker(obd, llh, fsdb, CM_START, cliname,
1623 rc = record_mount_opt(obd, llh, cliname, fsdb->fsdb_clilov,
1625 rc = record_marker(obd, llh, fsdb, CM_END, cliname,
1629 rc = record_end_log(obd, &llh);
1631 name_destroy(&cliname);
1633 // for_all_existing_mdt except current one
1634 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
1636 if (i != mti->mti_stripe_index &&
1637 test_bit(i, fsdb->fsdb_mdt_index_map)) {
1638 name_create_mdt(&mdtname, mti->mti_fsname, i);
1639 rc = mgs_write_log_mdc_to_mdt(obd, fsdb, mti, mdtname);
1640 name_destroy(&mdtname);
1647 /* Add the ost info to the client/mdt lov */
1648 static int mgs_write_log_osc_to_lov(struct obd_device *obd, struct fs_db *fsdb,
1649 struct mgs_target_info *mti,
1650 char *logname, char *suffix, char *lovname,
1651 enum lustre_sec_part sec_part, int flags)
1653 struct llog_handle *llh = NULL;
1654 char *nodeuuid, *oscname, *oscuuid, *lovuuid, *svname;
1659 CDEBUG(D_INFO, "adding osc for %s to log %s\n",
1660 mti->mti_svname, logname);
1662 if (mgs_log_is_empty(obd, logname)) {
1663 /* The first item in the log must be the lov, so we have
1664 somewhere to add our osc. */
1665 rc = mgs_write_log_lov(obd, fsdb, mti, logname, lovname);
1668 name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
1669 name_create(&svname, mti->mti_svname, "-osc");
1670 name_create(&oscname, svname, suffix);
1671 name_create(&oscuuid, oscname, "_UUID");
1672 name_create(&lovuuid, lovname, "_UUID");
1675 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
1677 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
1678 #04 L attach 0:OSC_uml1_ost1_MNT_client 1:osc 2:89070_lov1_a41dff51a
1679 #05 L setup 0:OSC_uml1_ost1_MNT_client 1:ost1_UUID 2:uml1_UUID
1681 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
1682 #07 L add_conn 0:OSC_uml1_ost1_MNT_client 1:uml2_UUID
1683 #08 L lov_modify_tgts add 0:lov1 1:ost1_UUID 2(index):0 3(gen):1
1686 rc = record_start_log(obd, &llh, logname);
1689 /* FIXME these should be a single journal transaction */
1690 rc = record_marker(obd, llh, fsdb, CM_START | flags, mti->mti_svname,
1692 for (i = 0; i < mti->mti_nid_count; i++) {
1693 CDEBUG(D_MGS, "add nid %s\n", libcfs_nid2str(mti->mti_nids[i]));
1694 rc = record_add_uuid(obd, llh, mti->mti_nids[i], nodeuuid);
1696 rc = record_attach(obd, llh, oscname, LUSTRE_OSC_NAME, lovuuid);
1697 rc = record_setup(obd, llh, oscname, mti->mti_uuid, nodeuuid, 0, 0);
1698 rc = mgs_write_log_failnids(obd, mti, llh, oscname);
1699 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
1700 rc = record_lov_add(obd, llh, lovname, mti->mti_uuid, index, "1");
1701 rc = record_marker(obd, llh, fsdb, CM_END | flags, mti->mti_svname,
1703 rc = record_end_log(obd, &llh);
1705 name_destroy(&lovuuid);
1706 name_destroy(&oscuuid);
1707 name_destroy(&oscname);
1708 name_destroy(&svname);
1709 name_destroy(&nodeuuid);
1713 static int mgs_write_log_ost(struct obd_device *obd, struct fs_db *fsdb,
1714 struct mgs_target_info *mti)
1716 struct llog_handle *llh = NULL;
1717 char *logname, *lovname;
1718 char *ptr = mti->mti_params;
1719 int rc, flags = 0, failout = 0, i;
1722 CDEBUG(D_MGS, "writing new ost %s\n", mti->mti_svname);
1724 /* The ost startup log */
1726 /* If the ost log already exists, that means that someone reformatted
1727 the ost and it called target_add again. */
1728 if (!mgs_log_is_empty(obd, mti->mti_svname)) {
1729 LCONSOLE_ERROR_MSG(0x141, "The config log for %s already "
1730 "exists, yet the server claims it never "
1731 "registered. It may have been reformatted, "
1732 "or the index changed. writeconf the MDT to "
1733 "regenerate all logs.\n", mti->mti_svname);
1738 attach obdfilter ost1 ost1_UUID
1739 setup /dev/loop2 ldiskfs f|n errors=remount-ro,user_xattr
1741 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
1742 failout = (strncmp(ptr, "failout", 7) == 0);
1743 rc = record_start_log(obd, &llh, mti->mti_svname);
1746 /* FIXME these should be a single journal transaction */
1747 rc = record_marker(obd, llh, fsdb, CM_START, mti->mti_svname,"add ost");
1748 if (*mti->mti_uuid == '\0')
1749 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
1750 "%s_UUID", mti->mti_svname);
1751 rc = record_attach(obd, llh, mti->mti_svname,
1752 "obdfilter"/*LUSTRE_OST_NAME*/, mti->mti_uuid);
1753 rc = record_setup(obd, llh, mti->mti_svname,
1754 "dev"/*ignored*/, "type"/*ignored*/,
1755 failout ? "n" : "f", 0/*options*/);
1756 rc = record_marker(obd, llh, fsdb, CM_END, mti->mti_svname, "add ost");
1757 rc = record_end_log(obd, &llh);
1759 /* We also have to update the other logs where this osc is part of
1762 if (fsdb->fsdb_flags & FSDB_OLDLOG14) {
1763 /* If we're upgrading, the old mdt log already has our
1764 entry. Let's do a fake one for fun. */
1765 /* Note that we can't add any new failnids, since we don't
1766 know the old osc names. */
1767 flags = CM_SKIP | CM_UPGRADE146;
1769 } else if ((mti->mti_flags & LDD_F_UPDATE) != LDD_F_UPDATE) {
1770 /* If the update flag isn't set, don't update client/mdt
1773 LCONSOLE_WARN("Client log for %s was not updated; writeconf "
1774 "the MDT first to regenerate it.\n",
1778 /* Add ost to all MDT lov defs */
1779 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
1780 if (test_bit(i, fsdb->fsdb_mdt_index_map)) {
1783 name_create_mdt_and_lov(&logname, &lovname, fsdb, i);
1784 sprintf(mdt_index, "-MDT%04x", i);
1785 mgs_write_log_osc_to_lov(obd, fsdb, mti, logname,
1787 LUSTRE_SP_MDT, flags);
1788 name_destroy(&logname);
1789 name_destroy(&lovname);
1793 /* Append ost info to the client log */
1794 name_create(&logname, mti->mti_fsname, "-client");
1795 mgs_write_log_osc_to_lov(obd, fsdb, mti, logname, "",
1796 fsdb->fsdb_clilov, LUSTRE_SP_CLI, 0);
1797 name_destroy(&logname);
1801 /* Add additional failnids to an existing log.
1802 The mdc/osc must have been added to logs first */
1803 /* tcp nids must be in dotted-quad ascii -
1804 we can't resolve hostnames from the kernel. */
1805 static int mgs_write_log_add_failnid(struct obd_device *obd, struct fs_db *fsdb,
1806 struct mgs_target_info *mti)
1808 char *logname, *cliname;
1809 struct llog_handle *llh = NULL;
1813 /* FIXME how do we delete a failnid? Currently --writeconf is the
1814 only way. Maybe make --erase-params pass a flag to really
1815 erase all params from logs - except it can't erase the failnids
1816 given when a target first registers, since they aren't processed
1819 /* Verify that we know about this target */
1820 if (mgs_log_is_empty(obd, mti->mti_svname)) {
1821 LCONSOLE_ERROR_MSG(0x142, "The target %s has not registered "
1822 "yet. It must be started before failnids "
1823 "can be added.\n", mti->mti_svname);
1827 /* Create mdc/osc client name (e.g. lustre-OST0001-osc) */
1828 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
1829 name_create(&cliname, mti->mti_svname, "-mdc");
1830 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
1831 name_create(&cliname, mti->mti_svname, "-osc");
1836 /* Add failover nids to client log */
1837 name_create(&logname, mti->mti_fsname, "-client");
1838 rc = record_start_log(obd, &llh, logname);
1840 /* FIXME this fn should be a single journal transaction */
1841 rc = record_marker(obd, llh, fsdb, CM_START, mti->mti_svname,
1843 rc = mgs_write_log_failnids(obd, mti, llh, cliname);
1844 rc = record_marker(obd, llh, fsdb, CM_END, mti->mti_svname,
1846 rc = record_end_log(obd, &llh);
1848 name_destroy(&logname);
1850 if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
1851 /* Add OST failover nids to the MDT log as well */
1852 name_create(&logname, mti->mti_fsname, "-MDT0000");
1853 rc = record_start_log(obd, &llh, logname);
1855 rc = record_marker(obd, llh, fsdb, CM_START,
1856 mti->mti_svname, "add failnid");
1857 rc = mgs_write_log_failnids(obd, mti, llh, cliname);
1858 rc = record_marker(obd, llh, fsdb, CM_END,
1859 mti->mti_svname, "add failnid");
1860 rc = record_end_log(obd, &llh);
1862 name_destroy(&logname);
1865 name_destroy(&cliname);
1869 static int mgs_wlp_lcfg(struct obd_device *obd, struct fs_db *fsdb,
1870 struct mgs_target_info *mti,
1871 char *logname, struct lustre_cfg_bufs *bufs,
1872 char *tgtname, char *ptr)
1874 char comment[MTI_NAME_MAXLEN];
1876 struct lustre_cfg *lcfg;
1879 /* Erase any old settings of this same parameter */
1880 memcpy(comment, ptr, MTI_NAME_MAXLEN);
1881 comment[MTI_NAME_MAXLEN - 1] = 0;
1882 /* But don't try to match the value. */
1883 if ((tmp = strchr(comment, '=')))
1885 /* FIXME we should skip settings that are the same as old values */
1886 rc = mgs_modify(obd, fsdb, mti, logname, tgtname, comment, CM_SKIP);
1887 LCONSOLE_INFO("%sing parameter %s.%s in log %s\n", rc ?
1888 "Sett" : "Modify", tgtname, comment, logname);
1890 lustre_cfg_bufs_reset(bufs, tgtname);
1891 lustre_cfg_bufs_set_string(bufs, 1, ptr);
1892 lcfg = lustre_cfg_new(LCFG_PARAM, bufs);
1895 rc = mgs_write_log_direct(obd, fsdb, logname, lcfg, tgtname, comment);
1896 lustre_cfg_free(lcfg);
1900 /* write global variable settings into log */
1901 static int mgs_write_log_sys(struct obd_device *obd, struct fs_db *fsdb,
1902 struct mgs_target_info *mti, char *sys, char *ptr)
1904 struct lustre_cfg_bufs bufs;
1905 struct lustre_cfg *lcfg;
1910 if (class_match_param(ptr, PARAM_TIMEOUT, &tmp) == 0)
1911 cmd = LCFG_SET_TIMEOUT;
1912 else if (class_match_param(ptr, PARAM_LDLM_TIMEOUT, &tmp) == 0)
1913 cmd = LCFG_SET_LDLM_TIMEOUT;
1914 /* Check for known params here so we can return error to lctl */
1915 else if ((class_match_param(ptr, PARAM_AT_MIN, &tmp) == 0)
1916 || (class_match_param(ptr, PARAM_AT_MAX, &tmp) == 0)
1917 || (class_match_param(ptr, PARAM_AT_EXTRA, &tmp) == 0)
1918 || (class_match_param(ptr, PARAM_AT_EARLY_MARGIN, &tmp) == 0)
1919 || (class_match_param(ptr, PARAM_AT_HISTORY, &tmp) == 0))
1924 val = simple_strtoul(tmp, NULL, 0);
1925 CDEBUG(D_MGS, "global %s = %d\n", ptr, val);
1927 lustre_cfg_bufs_reset(&bufs, NULL);
1928 lustre_cfg_bufs_set_string(&bufs, 1, sys);
1929 lcfg = lustre_cfg_new(cmd, &bufs);
1930 lcfg->lcfg_num = val;
1931 /* modify all servers and clients */
1932 rc = mgs_write_log_direct_all(obd, fsdb, mti, lcfg, mti->mti_fsname,
1934 lustre_cfg_free(lcfg);
1938 static int mgs_srpc_set_param_disk(struct obd_device *obd,
1940 struct mgs_target_info *mti,
1943 struct llog_handle *llh = NULL;
1945 char *comment, *ptr;
1946 struct lustre_cfg_bufs bufs;
1947 struct lustre_cfg *lcfg;
1952 ptr = strchr(param, '=');
1956 OBD_ALLOC(comment, len + 1);
1957 if (comment == NULL)
1959 strncpy(comment, param, len);
1960 comment[len] = '\0';
1963 lustre_cfg_bufs_reset(&bufs, mti->mti_svname);
1964 lustre_cfg_bufs_set_string(&bufs, 1, param);
1965 lcfg = lustre_cfg_new(LCFG_SPTLRPC_CONF, &bufs);
1967 GOTO(out_comment, rc = -ENOMEM);
1969 /* construct log name */
1970 rc = name_create(&logname, mti->mti_fsname, "-sptlrpc");
1974 if (mgs_log_is_empty(obd, logname)) {
1975 rc = record_start_log(obd, &llh, logname);
1976 record_end_log(obd, &llh);
1981 /* obsolete old one */
1982 mgs_modify(obd, fsdb, mti, logname, mti->mti_svname, comment, CM_SKIP);
1984 /* write the new one */
1985 rc = mgs_write_log_direct(obd, fsdb, logname, lcfg,
1986 mti->mti_svname, comment);
1988 CERROR("err %d writing log %s\n", rc, logname);
1991 name_destroy(&logname);
1993 lustre_cfg_free(lcfg);
1995 OBD_FREE(comment, len + 1);
1999 static int mgs_srpc_set_param_udesc_mem(struct fs_db *fsdb,
2004 /* disable the adjustable udesc parameter for now, i.e. use default
2005 * setting that client always ship udesc to MDT if possible. to enable
2006 * it simply remove the following line */
2009 ptr = strchr(param, '=');
2014 if (strcmp(param, PARAM_SRPC_UDESC))
2017 if (strcmp(ptr, "yes") == 0) {
2018 fsdb->fsdb_fl_udesc = 1;
2019 CWARN("Enable user descriptor shipping from client to MDT\n");
2020 } else if (strcmp(ptr, "no") == 0) {
2021 fsdb->fsdb_fl_udesc = 0;
2022 CWARN("Disable user descriptor shipping from client to MDT\n");
2030 CERROR("Invalid param: %s\n", param);
2034 static int mgs_srpc_set_param_mem(struct fs_db *fsdb,
2038 struct sptlrpc_rule rule;
2039 struct sptlrpc_rule_set *rset;
2043 if (strncmp(param, PARAM_SRPC, sizeof(PARAM_SRPC) - 1) != 0) {
2044 CERROR("Invalid sptlrpc parameter: %s\n", param);
2048 if (strncmp(param, PARAM_SRPC_UDESC,
2049 sizeof(PARAM_SRPC_UDESC) - 1) == 0) {
2050 RETURN(mgs_srpc_set_param_udesc_mem(fsdb, param));
2053 if (strncmp(param, PARAM_SRPC_FLVR, sizeof(PARAM_SRPC_FLVR) - 1) != 0) {
2054 CERROR("Invalid sptlrpc flavor parameter: %s\n", param);
2058 param += sizeof(PARAM_SRPC_FLVR) - 1;
2060 rc = sptlrpc_parse_rule(param, &rule);
2064 /* mgs rules implies must be mgc->mgs */
2065 if (fsdb->fsdb_fl_mgsself) {
2066 if ((rule.sr_from != LUSTRE_SP_MGC &&
2067 rule.sr_from != LUSTRE_SP_ANY) ||
2068 (rule.sr_to != LUSTRE_SP_MGS &&
2069 rule.sr_to != LUSTRE_SP_ANY))
2073 /* preapre room for this coming rule. svcname format should be:
2074 * - fsname: general rule
2075 * - fsname-tgtname: target-specific rule
2077 if (strchr(svname, '-')) {
2078 struct mgs_tgt_srpc_conf *tgtconf;
2081 for (tgtconf = fsdb->fsdb_srpc_tgt; tgtconf != NULL;
2082 tgtconf = tgtconf->mtsc_next) {
2083 if (!strcmp(tgtconf->mtsc_tgt, svname)) {
2092 OBD_ALLOC_PTR(tgtconf);
2093 if (tgtconf == NULL)
2096 name_len = strlen(svname);
2098 OBD_ALLOC(tgtconf->mtsc_tgt, name_len + 1);
2099 if (tgtconf->mtsc_tgt == NULL) {
2100 OBD_FREE_PTR(tgtconf);
2103 memcpy(tgtconf->mtsc_tgt, svname, name_len);
2105 tgtconf->mtsc_next = fsdb->fsdb_srpc_tgt;
2106 fsdb->fsdb_srpc_tgt = tgtconf;
2109 rset = &tgtconf->mtsc_rset;
2111 rset = &fsdb->fsdb_srpc_gen;
2114 rc = sptlrpc_rule_set_merge(rset, &rule);
2119 static int mgs_srpc_set_param(struct obd_device *obd,
2121 struct mgs_target_info *mti,
2131 /* keep a copy of original param, which could be destroied
2133 copy_size = strlen(param) + 1;
2134 OBD_ALLOC(copy, copy_size);
2137 memcpy(copy, param, copy_size);
2139 rc = mgs_srpc_set_param_mem(fsdb, mti->mti_svname, param);
2143 /* previous steps guaranteed the syntax is correct */
2144 rc = mgs_srpc_set_param_disk(obd, fsdb, mti, copy);
2148 if (fsdb->fsdb_fl_mgsself) {
2150 * for mgs rules, make them effective immediately.
2152 LASSERT(fsdb->fsdb_srpc_tgt == NULL);
2153 sptlrpc_target_update_exp_flavor(obd, &fsdb->fsdb_srpc_gen);
2157 OBD_FREE(copy, copy_size);
2161 struct mgs_srpc_read_data {
2162 struct fs_db *msrd_fsdb;
2166 static int mgs_srpc_read_handler(struct llog_handle *llh,
2167 struct llog_rec_hdr *rec,
2170 struct mgs_srpc_read_data *msrd = (struct mgs_srpc_read_data *) data;
2171 struct cfg_marker *marker;
2172 struct lustre_cfg *lcfg = (struct lustre_cfg *)(rec + 1);
2173 char *svname, *param;
2177 if (rec->lrh_type != OBD_CFG_REC) {
2178 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
2182 cfg_len = rec->lrh_len - sizeof(struct llog_rec_hdr) -
2183 sizeof(struct llog_rec_tail);
2185 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
2187 CERROR("Insane cfg\n");
2191 if (lcfg->lcfg_command == LCFG_MARKER) {
2192 marker = lustre_cfg_buf(lcfg, 1);
2194 if (marker->cm_flags & CM_START &&
2195 marker->cm_flags & CM_SKIP)
2196 msrd->msrd_skip = 1;
2197 if (marker->cm_flags & CM_END)
2198 msrd->msrd_skip = 0;
2203 if (msrd->msrd_skip)
2206 if (lcfg->lcfg_command != LCFG_SPTLRPC_CONF) {
2207 CERROR("invalid command (%x)\n", lcfg->lcfg_command);
2211 svname = lustre_cfg_string(lcfg, 0);
2212 if (svname == NULL) {
2213 CERROR("svname is empty\n");
2217 param = lustre_cfg_string(lcfg, 1);
2218 if (param == NULL) {
2219 CERROR("param is empty\n");
2223 rc = mgs_srpc_set_param_mem(msrd->msrd_fsdb, svname, param);
2225 CERROR("read sptlrpc record error (%d): %s\n", rc, param);
2230 int mgs_get_fsdb_srpc_from_llog(struct obd_device *obd,
2233 struct llog_handle *llh = NULL;
2234 struct lvfs_run_ctxt saved;
2235 struct llog_ctxt *ctxt;
2237 struct mgs_srpc_read_data msrd;
2241 /* construct log name */
2242 rc = name_create(&logname, fsdb->fsdb_name, "-sptlrpc");
2246 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
2247 LASSERT(ctxt != NULL);
2249 if (mgs_log_is_empty(obd, logname))
2252 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
2254 rc = llog_create(ctxt, &llh, NULL, logname);
2258 rc = llog_init_handle(llh, LLOG_F_IS_PLAIN, NULL);
2260 GOTO(out_close, rc);
2262 if (llog_get_size(llh) <= 1)
2263 GOTO(out_close, rc = 0);
2265 msrd.msrd_fsdb = fsdb;
2268 rc = llog_process(llh, mgs_srpc_read_handler, (void *) &msrd, NULL);
2273 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
2275 llog_ctxt_put(ctxt);
2276 name_destroy(&logname);
2279 CERROR("failed to read sptlrpc config database: %d\n", rc);
2283 static int mgs_write_log_param(struct obd_device *obd, struct fs_db *fsdb,
2284 struct mgs_target_info *mti, char *ptr)
2286 struct lustre_cfg_bufs bufs;
2292 /* For various parameter settings, we have to figure out which logs
2293 care about them (e.g. both mdt and client for lov settings) */
2294 CDEBUG(D_MGS, "next param '%s'\n", ptr);
2296 /* The params are stored in MOUNT_DATA_FILE and modified via
2297 tunefs.lustre, or set using lctl conf_param */
2299 /* Processed in lustre_start_mgc */
2300 if (class_match_param(ptr, PARAM_MGSNODE, NULL) == 0)
2303 /* Processed in mgs_write_log_ost */
2304 if (class_match_param(ptr, PARAM_FAILMODE, NULL) == 0) {
2305 if (mti->mti_flags & LDD_F_PARAM) {
2306 LCONSOLE_ERROR_MSG(0x169, "%s can only be "
2307 "changed with tunefs.lustre"
2308 "and --writeconf\n", ptr);
2314 if (class_match_param(ptr, PARAM_SRPC, NULL) == 0) {
2315 rc = mgs_srpc_set_param(obd, fsdb, mti, ptr);
2319 if (class_match_param(ptr, PARAM_FAILNODE, NULL) == 0) {
2320 /* Add a failover nidlist */
2322 /* We already processed failovers params for new
2323 targets in mgs_write_log_target */
2324 if (mti->mti_flags & LDD_F_PARAM) {
2325 CDEBUG(D_MGS, "Adding failnode\n");
2326 rc = mgs_write_log_add_failnid(obd, fsdb, mti);
2331 if (class_match_param(ptr, PARAM_SYS, &tmp) == 0) {
2332 rc = mgs_write_log_sys(obd, fsdb, mti, ptr, tmp);
2336 if (class_match_param(ptr, PARAM_OSC""PARAM_ACTIVE, &tmp) == 0) {
2337 /* active=0 means off, anything else means on */
2338 int flag = (*tmp == '0') ? CM_EXCLUDE : 0;
2341 if (!(mti->mti_flags & LDD_F_SV_TYPE_OST)) {
2342 LCONSOLE_ERROR_MSG(0x144, "%s: Only OSCs can "
2343 "be (de)activated.\n",
2345 GOTO(end, rc = -EINVAL);
2347 LCONSOLE_WARN("Permanently %sactivating %s\n",
2348 flag ? "de": "re", mti->mti_svname);
2350 name_create(&logname, mti->mti_fsname, "-client");
2351 rc = mgs_modify(obd, fsdb, mti, logname,
2352 mti->mti_svname, "add osc", flag);
2353 name_destroy(&logname);
2357 /* FIXME add to all MDT logs for CMD */
2358 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2359 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
2361 name_create_mdt(&logname, mti->mti_fsname, i);
2362 rc = mgs_modify(obd, fsdb, mti, logname,
2363 mti->mti_svname, "add osc", flag);
2364 name_destroy(&logname);
2370 LCONSOLE_ERROR_MSG(0x145, "Couldn't find %s in"
2371 "log (%d). No permanent "
2372 "changes were made to the "
2374 mti->mti_svname, rc);
2375 if (fsdb->fsdb_flags & FSDB_OLDLOG14)
2376 LCONSOLE_ERROR_MSG(0x146, "This may be"
2381 "update the logs.\n");
2384 /* Fall through to osc proc for deactivating live OSC
2385 on running MDT / clients. */
2387 /* Below here, let obd's XXX_process_config methods handle it */
2389 /* All lov. in proc */
2390 if (class_match_param(ptr, PARAM_LOV, NULL) == 0) {
2393 CDEBUG(D_MGS, "lov param %s\n", ptr);
2394 if (!(mti->mti_flags & LDD_F_SV_TYPE_MDT)) {
2395 LCONSOLE_ERROR_MSG(0x147, "LOV params must be "
2396 "set on the MDT, not %s. "
2403 if (mgs_log_is_empty(obd, mti->mti_svname))
2404 GOTO(end, rc = -ENODEV);
2406 name_create_mdt_and_lov(&logname, &mdtlovname, fsdb,
2407 mti->mti_stripe_index);
2408 rc = mgs_wlp_lcfg(obd, fsdb, mti, mti->mti_svname,
2409 &bufs, mdtlovname, ptr);
2410 name_destroy(&logname);
2411 name_destroy(&mdtlovname);
2416 name_create(&logname, mti->mti_fsname, "-client");
2417 rc = mgs_wlp_lcfg(obd, fsdb, mti, logname, &bufs,
2418 fsdb->fsdb_clilov, ptr);
2419 name_destroy(&logname);
2423 /* All osc., mdc., llite. params in proc */
2424 if ((class_match_param(ptr, PARAM_OSC, NULL) == 0) ||
2425 (class_match_param(ptr, PARAM_MDC, NULL) == 0) ||
2426 (class_match_param(ptr, PARAM_LLITE, NULL) == 0)) {
2428 if (memcmp(ptr, PARAM_LLITE, strlen(PARAM_LLITE)) == 0) {
2429 name_create(&cname, mti->mti_fsname, "-client");
2430 /* Add the client type to match the obdname in
2431 class_config_llog_handler */
2432 } else if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
2435 name_create(&cname, fsdb->fsdb_mdc, "");
2437 name_create(&cname, mti->mti_svname,
2439 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2441 if (fsdb->fsdb_flags & FSDB_OLDLOG14) {
2442 LCONSOLE_ERROR_MSG(0x148, "Upgraded "
2443 "client logs for %s"
2445 "modified. Consider"
2447 "configuration with"
2450 /* We don't know the names of all the
2452 GOTO(end, rc = -EINVAL);
2454 name_create(&cname, mti->mti_svname, "-osc");
2456 GOTO(end, rc = -EINVAL);
2459 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
2462 name_create(&logname, mti->mti_fsname, "-client");
2463 rc = mgs_wlp_lcfg(obd, fsdb, mti, logname, &bufs,
2466 /* osc params affect the MDT as well */
2467 if (!rc && (mti->mti_flags & LDD_F_SV_TYPE_OST)) {
2471 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
2472 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
2475 name_destroy(&cname);
2476 if (i == 0 && fsdb->fsdb_fl_oscname_18)
2477 sprintf(mdt_index, "-osc");
2479 sprintf(mdt_index, "-osc-MDT%04x", i);
2480 name_create(&cname, mti->mti_svname, mdt_index);
2482 name_destroy(&logname);
2483 name_create_mdt(&logname, mti->mti_fsname, i);
2484 if (!mgs_log_is_empty(obd, logname))
2485 rc = mgs_wlp_lcfg(obd, fsdb,
2493 name_destroy(&logname);
2494 name_destroy(&cname);
2498 /* All mdt. params in proc */
2499 if (class_match_param(ptr, PARAM_MDT, NULL) == 0) {
2503 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
2504 if (strncmp(mti->mti_svname, mti->mti_fsname,
2505 MTI_NAME_MAXLEN) == 0)
2506 /* device is unspecified completely? */
2507 rc = LDD_F_SV_TYPE_MDT | LDD_F_SV_ALL;
2509 rc = server_name2index(mti->mti_svname, &idx, NULL);
2512 if ((rc & LDD_F_SV_TYPE_MDT) == 0)
2514 if (rc & LDD_F_SV_ALL) {
2515 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2517 fsdb->fsdb_mdt_index_map))
2519 name_create_mdt(&logname, mti->mti_fsname, i);
2520 rc = mgs_wlp_lcfg(obd, fsdb, mti,
2523 name_destroy(&logname);
2528 rc = mgs_wlp_lcfg(obd, fsdb, mti,
2529 mti->mti_svname, &bufs,
2530 mti->mti_svname, ptr);
2537 /* All mdd., ost. params in proc */
2538 if ((class_match_param(ptr, PARAM_MDD, NULL) == 0) ||
2539 (class_match_param(ptr, PARAM_OST, NULL) == 0)) {
2540 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
2541 if (mgs_log_is_empty(obd, mti->mti_svname))
2542 GOTO(end, rc = -ENODEV);
2544 rc = mgs_wlp_lcfg(obd, fsdb, mti, mti->mti_svname,
2545 &bufs, mti->mti_svname, ptr);
2549 LCONSOLE_WARN("Ignoring unrecognized param '%s'\n", ptr);
2553 CERROR("err %d on param '%s'\n", rc, ptr);
2558 /* Not implementing automatic failover nid addition at this time. */
2559 int mgs_check_failnid(struct obd_device *obd, struct mgs_target_info *mti)
2566 rc = mgs_find_or_make_fsdb(obd, fsname, &fsdb);
2570 if (mgs_log_is_empty(obd, mti->mti_svname))
2571 /* should never happen */
2574 CDEBUG(D_MGS, "Checking for new failnids for %s\n", mti->mti_svname);
2576 /* FIXME We can just check mti->params to see if we're already in
2577 the failover list. Modify mti->params for rewriting back at
2578 server_register_target(). */
2580 down(&fsdb->fsdb_sem);
2581 rc = mgs_write_log_add_failnid(obd, fsdb, mti);
2582 up(&fsdb->fsdb_sem);
2589 int mgs_write_log_target(struct obd_device *obd,
2590 struct mgs_target_info *mti)
2597 /* set/check the new target index */
2598 rc = mgs_set_index(obd, mti);
2600 CERROR("Can't get index (%d)\n", rc);
2605 if (mti->mti_flags & LDD_F_UPGRADE14) {
2606 if (rc == EALREADY) {
2607 LCONSOLE_INFO("Found index %d for %s 1.4 log, "
2608 "upgrading\n", mti->mti_stripe_index,
2611 LCONSOLE_ERROR_MSG(0x149, "Failed to find %s in the old"
2612 " client log. Apparently it is not "
2613 "part of this filesystem, or the old"
2614 " log is wrong.\nUse 'writeconf' on "
2615 "the MDT to force log regeneration."
2616 "\n", mti->mti_svname);
2617 /* Not in client log? Upgrade anyhow...*/
2618 /* Argument against upgrading: reformat MDT,
2619 upgrade OST, then OST will start but will be SKIPped
2620 in client logs. Maybe error now is better. */
2621 /* RETURN(-EINVAL); */
2623 /* end COMPAT_146 */
2625 if (rc == EALREADY) {
2626 LCONSOLE_WARN("Found index %d for %s, updating log\n",
2627 mti->mti_stripe_index, mti->mti_svname);
2628 /* We would like to mark old log sections as invalid
2629 and add new log sections in the client and mdt logs.
2630 But if we add new sections, then live clients will
2631 get repeat setup instructions for already running
2632 osc's. So don't update the client/mdt logs. */
2633 mti->mti_flags &= ~LDD_F_UPDATE;
2637 rc = mgs_find_or_make_fsdb(obd, mti->mti_fsname, &fsdb);
2639 CERROR("Can't get db for %s\n", mti->mti_fsname);
2643 down(&fsdb->fsdb_sem);
2645 if (mti->mti_flags &
2646 (LDD_F_VIRGIN | LDD_F_UPGRADE14 | LDD_F_WRITECONF)) {
2647 /* Generate a log from scratch */
2648 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
2649 rc = mgs_write_log_mdt(obd, fsdb, mti);
2650 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2651 rc = mgs_write_log_ost(obd, fsdb, mti);
2653 CERROR("Unknown target type %#x, can't create log for "
2654 "%s\n", mti->mti_flags, mti->mti_svname);
2657 CERROR("Can't write logs for %s (%d)\n",
2658 mti->mti_svname, rc);
2662 /* Just update the params from tunefs in mgs_write_log_params */
2663 CDEBUG(D_MGS, "Update params for %s\n", mti->mti_svname);
2664 mti->mti_flags |= LDD_F_PARAM;
2667 /* allocate temporary buffer, where class_get_next_param will
2668 make copy of a current parameter */
2669 OBD_ALLOC(buf, strlen(mti->mti_params) + 1);
2671 GOTO(out_up, rc = -ENOMEM);
2672 params = mti->mti_params;
2673 while (params != NULL) {
2674 rc = class_get_next_param(¶ms, buf);
2677 /* there is no next parameter, that is
2682 CDEBUG(D_MGS, "remaining string: '%s', param: '%s'\n",
2684 rc = mgs_write_log_param(obd, fsdb, mti, buf);
2689 OBD_FREE(buf, strlen(mti->mti_params) + 1);
2692 up(&fsdb->fsdb_sem);
2697 /* verify that we can handle the old config logs */
2698 int mgs_upgrade_sv_14(struct obd_device *obd, struct mgs_target_info *mti)
2704 /* Create ost log normally, as servers register. Servers
2705 register with their old uuids (from last_rcvd), so old
2706 (MDT and client) logs should work.
2707 - new MDT won't know about old OSTs, only the ones that have
2708 registered, so we need the old MDT log to get the LOV right
2709 in order for old clients to work.
2710 - Old clients connect to the MDT, not the MGS, for their logs, and
2711 will therefore receive the old client log from the MDT /LOGS dir.
2712 - Old clients can continue to use and connect to old or new OSTs
2713 - New clients will contact the MGS for their log
2716 LCONSOLE_INFO("upgrading server %s from pre-1.6\n", mti->mti_svname);
2717 server_mti_print("upgrade", mti);
2719 rc = mgs_find_or_make_fsdb(obd, mti->mti_fsname, &fsdb);
2723 if (fsdb->fsdb_flags & FSDB_LOG_EMPTY) {
2724 LCONSOLE_ERROR_MSG(0x14a, "The old client log %s-client is "
2725 "missing. Was tunefs.lustre successful?\n",
2730 if (fsdb->fsdb_gen == 0) {
2731 /* There were no markers in the client log, meaning we have
2732 not updated the logs for this fs */
2733 CDEBUG(D_MGS, "found old, unupdated client log\n");
2736 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
2737 if (mgs_log_is_empty(obd, mti->mti_svname)) {
2738 LCONSOLE_ERROR_MSG(0x14b, "The old MDT log %s is "
2739 "missing. Was tunefs.lustre "
2744 /* We're starting with an old uuid. Assume old name for lov
2745 as well since the lov entry already exists in the log. */
2746 CDEBUG(D_MGS, "old mds uuid %s\n", mti->mti_uuid);
2747 if (strncmp(mti->mti_uuid, fsdb->fsdb_mdtlov + 4,
2748 strlen(fsdb->fsdb_mdtlov) - 4) != 0) {
2749 CERROR("old mds uuid %s doesn't match log %s (%s)\n",
2750 mti->mti_uuid, fsdb->fsdb_mdtlov,
2751 fsdb->fsdb_mdtlov + 4);
2756 if (!(fsdb->fsdb_flags & FSDB_OLDLOG14)) {
2757 LCONSOLE_ERROR_MSG(0x14c, "%s-client is supposedly an old "
2758 "log, but no old LOV or MDT was found. "
2759 "Consider updating the configuration with"
2760 " --writeconf.\n", mti->mti_fsname);
2765 /* end COMPAT_146 */
2767 int mgs_erase_log(struct obd_device *obd, char *name)
2769 struct lvfs_run_ctxt saved;
2770 struct llog_ctxt *ctxt;
2771 struct llog_handle *llh;
2774 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
2775 LASSERT(ctxt != NULL);
2777 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
2778 rc = llog_create(ctxt, &llh, NULL, name);
2780 llog_init_handle(llh, LLOG_F_IS_PLAIN, NULL);
2781 rc = llog_destroy(llh);
2782 llog_free_handle(llh);
2784 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
2785 llog_ctxt_put(ctxt);
2788 CERROR("failed to clear log %s: %d\n", name, rc);
2793 /* erase all logs for the given fs */
2794 int mgs_erase_logs(struct obd_device *obd, char *fsname)
2796 struct mgs_obd *mgs = &obd->u.mgs;
2797 static struct fs_db *fsdb;
2798 struct list_head dentry_list;
2799 struct l_linux_dirent *dirent, *n;
2800 int rc, len = strlen(fsname);
2803 /* Find all the logs in the CONFIGS directory */
2804 rc = class_dentry_readdir(obd, mgs->mgs_configs_dir,
2805 mgs->mgs_vfsmnt, &dentry_list);
2807 CERROR("Can't read %s dir\n", MOUNT_CONFIGS_DIR);
2811 down(&mgs->mgs_sem);
2813 /* Delete the fs db */
2814 fsdb = mgs_find_fsdb(obd, fsname);
2816 mgs_free_fsdb(obd, fsdb);
2818 list_for_each_entry_safe(dirent, n, &dentry_list, lld_list) {
2819 list_del(&dirent->lld_list);
2820 if (strncmp(fsname, dirent->lld_name, len) == 0) {
2821 CDEBUG(D_MGS, "Removing log %s\n", dirent->lld_name);
2822 mgs_erase_log(obd, dirent->lld_name);
2824 OBD_FREE(dirent, sizeof(*dirent));
2832 /* from llog_swab */
2833 static void print_lustre_cfg(struct lustre_cfg *lcfg)
2838 CDEBUG(D_MGS, "lustre_cfg: %p\n", lcfg);
2839 CDEBUG(D_MGS, "\tlcfg->lcfg_version: %#x\n", lcfg->lcfg_version);
2841 CDEBUG(D_MGS, "\tlcfg->lcfg_command: %#x\n", lcfg->lcfg_command);
2842 CDEBUG(D_MGS, "\tlcfg->lcfg_num: %#x\n", lcfg->lcfg_num);
2843 CDEBUG(D_MGS, "\tlcfg->lcfg_flags: %#x\n", lcfg->lcfg_flags);
2844 CDEBUG(D_MGS, "\tlcfg->lcfg_nid: %s\n", libcfs_nid2str(lcfg->lcfg_nid));
2846 CDEBUG(D_MGS, "\tlcfg->lcfg_bufcount: %d\n", lcfg->lcfg_bufcount);
2847 if (lcfg->lcfg_bufcount < LUSTRE_CFG_MAX_BUFCOUNT)
2848 for (i = 0; i < lcfg->lcfg_bufcount; i++) {
2849 CDEBUG(D_MGS, "\tlcfg->lcfg_buflens[%d]: %d %s\n",
2850 i, lcfg->lcfg_buflens[i],
2851 lustre_cfg_string(lcfg, i));
2856 /* Set a permanent (config log) param for a target or fs */
2857 int mgs_setparam(struct obd_device *obd, struct lustre_cfg *lcfg, char *fsname)
2860 struct mgs_target_info *mti;
2861 char *devname, *param;
2867 print_lustre_cfg(lcfg);
2869 /* lustre, lustre-mdtlov, lustre-client, lustre-MDT0000 */
2870 devname = lustre_cfg_string(lcfg, 0);
2871 param = lustre_cfg_string(lcfg, 1);
2873 /* Assume device name embedded in param:
2874 lustre-OST0000.osc.max_dirty_mb=32 */
2875 ptr = strchr(param, '.');
2883 LCONSOLE_ERROR_MSG(0x14d, "No target specified: %s\n", param);
2887 /* Extract fsname */
2888 ptr = strrchr(devname, '-');
2889 memset(fsname, 0, MTI_NAME_MAXLEN);
2890 if (ptr && (server_name2index(ptr, &index, NULL) >= 0)) {
2891 /* param related to llite isn't allowed to set by OST or MDT */
2892 if (strncmp(param, PARAM_LLITE, sizeof(PARAM_LLITE)) == 0)
2895 strncpy(fsname, devname, ptr - devname);
2897 /* assume devname is the fsname */
2898 strncpy(fsname, devname, MTI_NAME_MAXLEN);
2900 fsname[MTI_NAME_MAXLEN - 1] = 0;
2901 CDEBUG(D_MGS, "setparam on fs %s device %s\n", fsname, devname);
2903 rc = mgs_find_or_make_fsdb(obd, fsname, &fsdb);
2906 if (!fsdb->fsdb_fl_mgsself && fsdb->fsdb_flags & FSDB_LOG_EMPTY) {
2907 CERROR("No filesystem targets for %s. cfg_device from lctl "
2908 "is '%s'\n", fsname, devname);
2909 mgs_free_fsdb(obd, fsdb);
2913 /* Create a fake mti to hold everything */
2916 GOTO(out, rc = -ENOMEM);
2917 strncpy(mti->mti_fsname, fsname, MTI_NAME_MAXLEN);
2918 strncpy(mti->mti_svname, devname, MTI_NAME_MAXLEN);
2919 strncpy(mti->mti_params, param, sizeof(mti->mti_params));
2920 rc = server_name2index(mti->mti_svname, &mti->mti_stripe_index, &tmp);
2922 /* Not a valid server; may be only fsname */
2925 /* Strip -osc or -mdc suffix from svname */
2926 if (server_make_name(rc, mti->mti_stripe_index, mti->mti_fsname,
2928 GOTO(out, rc = -EINVAL);
2930 mti->mti_flags = rc | LDD_F_PARAM;
2932 down(&fsdb->fsdb_sem);
2933 /* this is lctl conf_param's single param path, there is not
2934 need to loop through parameters */
2935 rc = mgs_write_log_param(obd, fsdb, mti, mti->mti_params);
2936 up(&fsdb->fsdb_sem);
2943 static int mgs_write_log_pool(struct obd_device *obd, char *logname,
2944 struct fs_db *fsdb, char *lovname,
2945 enum lcfg_command_type cmd,
2946 char *poolname, char *fsname,
2947 char *ostname, char *comment)
2949 struct llog_handle *llh = NULL;
2952 rc = record_start_log(obd, &llh, logname);
2955 rc = record_marker(obd, llh, fsdb, CM_START, lovname, comment);
2956 record_base(obd, llh, lovname, 0, cmd, poolname, fsname, ostname, 0);
2957 rc = record_marker(obd, llh, fsdb, CM_END, lovname, comment);
2958 rc = record_end_log(obd, &llh);
2963 int mgs_pool_cmd(struct obd_device *obd, enum lcfg_command_type cmd,
2964 char *fsname, char *poolname, char *ostname)
2969 char *label = NULL, *canceled_label = NULL;
2971 struct mgs_target_info *mti = NULL;
2975 rc = mgs_find_or_make_fsdb(obd, fsname, &fsdb);
2977 CERROR("Can't get db for %s\n", fsname);
2980 if (fsdb->fsdb_flags & FSDB_LOG_EMPTY) {
2981 CERROR("%s is not defined\n", fsname);
2982 mgs_free_fsdb(obd, fsdb);
2986 label_sz = 10 + strlen(fsname) + strlen(poolname);
2988 /* check if ostname match fsname */
2989 if (ostname != NULL) {
2992 ptr = strrchr(ostname, '-');
2993 if ((ptr == NULL) ||
2994 (strncmp(fsname, ostname, ptr-ostname) != 0))
2996 label_sz += strlen(ostname);
2999 OBD_ALLOC(label, label_sz);
3001 GOTO(out, rc = -ENOMEM);
3004 case LCFG_POOL_NEW: {
3006 "new %s.%s", fsname, poolname);
3009 case LCFG_POOL_ADD: {
3011 "add %s.%s.%s", fsname, poolname, ostname);
3014 case LCFG_POOL_REM: {
3015 OBD_ALLOC(canceled_label, label_sz);
3016 if (canceled_label == NULL)
3017 GOTO(out, rc = -ENOMEM);
3019 "rem %s.%s.%s", fsname, poolname, ostname);
3020 sprintf(canceled_label,
3021 "add %s.%s.%s", fsname, poolname, ostname);
3024 case LCFG_POOL_DEL: {
3025 OBD_ALLOC(canceled_label, label_sz);
3026 if (canceled_label == NULL)
3027 GOTO(out, rc = -ENOMEM);
3029 "del %s.%s", fsname, poolname);
3030 sprintf(canceled_label,
3031 "new %s.%s", fsname, poolname);
3039 down(&fsdb->fsdb_sem);
3041 if (canceled_label != NULL) {
3044 GOTO(out, rc = -ENOMEM);
3047 /* write pool def to all MDT logs */
3048 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3049 if (test_bit(i, fsdb->fsdb_mdt_index_map)) {
3050 name_create_mdt_and_lov(&logname, &lovname, fsdb, i);
3052 if (canceled_label != NULL) {
3053 strcpy(mti->mti_svname, "lov pool");
3054 mgs_modify(obd, fsdb, mti, logname, lovname,
3055 canceled_label, CM_SKIP);
3058 mgs_write_log_pool(obd, logname, fsdb, lovname,
3059 cmd, fsname, poolname, ostname,
3061 name_destroy(&logname);
3062 name_destroy(&lovname);
3066 name_create(&logname, fsname, "-client");
3067 if (canceled_label != NULL)
3068 mgs_modify(obd, fsdb, mti, logname, fsdb->fsdb_clilov,
3069 canceled_label, CM_SKIP);
3071 mgs_write_log_pool(obd, logname, fsdb, fsdb->fsdb_clilov,
3072 cmd, fsname, poolname, ostname, label);
3073 name_destroy(&logname);
3075 up(&fsdb->fsdb_sem);
3080 OBD_FREE(label, label_sz);
3082 if (canceled_label != NULL)
3083 OBD_FREE(canceled_label, label_sz);
3092 /******************** unused *********************/
3093 static int mgs_backup_llog(struct obd_device *obd, char* fsname)
3095 struct file *filp, *bak_filp;
3096 struct lvfs_run_ctxt saved;
3097 char *logname, *buf;
3098 loff_t soff = 0 , doff = 0;
3099 int count = 4096, len;
3102 OBD_ALLOC(logname, PATH_MAX);
3103 if (logname == NULL)
3106 OBD_ALLOC(buf, count);
3108 GOTO(out , rc = -ENOMEM);
3110 len = snprintf(logname, PATH_MAX, "%s/%s.bak",
3111 MOUNT_CONFIGS_DIR, fsname);
3113 if (len >= PATH_MAX - 1) {
3114 GOTO(out, -ENAMETOOLONG);
3117 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
3119 bak_filp = l_filp_open(logname, O_RDWR|O_CREAT|O_TRUNC, 0660);
3120 if (IS_ERR(bak_filp)) {
3121 rc = PTR_ERR(bak_filp);
3122 CERROR("backup logfile open %s: %d\n", logname, rc);
3125 sprintf(logname, "%s/%s", MOUNT_CONFIGS_DIR, fsname);
3126 filp = l_filp_open(logname, O_RDONLY, 0);
3129 CERROR("logfile open %s: %d\n", logname, rc);
3133 while ((rc = lustre_fread(filp, buf, count, &soff)) > 0) {
3134 rc = lustre_fwrite(bak_filp, buf, count, &doff);
3138 filp_close(filp, 0);
3140 filp_close(bak_filp, 0);
3142 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
3145 OBD_FREE(buf, count);
3146 OBD_FREE(logname, PATH_MAX);