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 static inline void name_create_mdt_osc(char **oscname, char *ostname,
1527 struct fs_db *fsdb, int i)
1531 if (i == 0 && fsdb->fsdb_fl_oscname_18)
1532 sprintf(suffix, "-osc");
1534 sprintf(suffix, "-osc-MDT%04x", i);
1535 name_create(oscname, ostname, suffix);
1538 /* envelope method for all layers log */
1539 static int mgs_write_log_mdt(struct obd_device *obd, struct fs_db *fsdb,
1540 struct mgs_target_info *mti)
1542 struct llog_handle *llh = NULL;
1544 struct temp_comp comp = { 0 };
1548 CDEBUG(D_MGS, "writing new mdt %s\n", mti->mti_svname);
1552 if (mti->mti_flags & LDD_F_UPGRADE14) {
1553 /* We're starting with an old uuid. Assume old name for lov
1554 as well since the lov entry already exists in the log. */
1555 CDEBUG(D_MGS, "old mds uuid %s\n", mti->mti_uuid);
1556 if (strncmp(mti->mti_uuid, fsdb->fsdb_mdtlov + 4,
1557 strlen(fsdb->fsdb_mdtlov) - 4) != 0) {
1558 CERROR("old mds uuid %s doesn't match log %s (%s)\n",
1559 mti->mti_uuid, fsdb->fsdb_mdtlov,
1560 fsdb->fsdb_mdtlov + 4);
1564 /* end COMPAT_146 */
1566 if (mti->mti_uuid[0] == '\0') {
1567 /* Make up our own uuid */
1568 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
1569 "%s_UUID", mti->mti_svname);
1573 rc = mgs_write_log_mdt0(obd, fsdb, mti);
1575 /* Append the mdt info to the client log */
1576 name_create(&cliname, mti->mti_fsname, "-client");
1578 if (mgs_log_is_empty(obd, cliname)) {
1579 /* Start client log */
1580 rc = mgs_write_log_lov(obd, fsdb, mti, cliname,
1582 rc = mgs_write_log_lmv(obd, fsdb, mti, cliname,
1587 #09 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
1588 #10 L attach 0:MDC_uml1_mdsA_MNT_client 1:mdc 2:1d834_MNT_client_03f
1589 #11 L setup 0:MDC_uml1_mdsA_MNT_client 1:mdsA_UUID 2:uml1_UUID
1590 #12 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
1591 #13 L add_conn 0:MDC_uml1_mdsA_MNT_client 1:uml2_UUID
1592 #14 L mount_option 0: 1:client 2:lov1 3:MDC_uml1_mdsA_MNT_client
1597 if (mti->mti_flags & LDD_F_UPGRADE14) {
1598 rc = record_start_log(obd, &llh, cliname);
1602 rc = record_marker(obd, llh, fsdb, CM_START,
1603 mti->mti_svname,"add mdc");
1605 /* Old client log already has MDC entry, but needs mount opt
1606 for new client name (lustre-client) */
1607 /* FIXME Old MDT log already has an old mount opt
1608 which we should remove (currently handled by
1609 class_del_profiles()) */
1610 rc = record_mount_opt(obd, llh, cliname, fsdb->fsdb_clilov,
1612 /* end COMPAT_146 */
1614 rc = record_marker(obd, llh, fsdb, CM_END,
1615 mti->mti_svname, "add mdc");
1619 /* copy client info about lov/lmv */
1620 comp.comp_mti = mti;
1621 comp.comp_fsdb = fsdb;
1623 rc = mgs_steal_llog_for_mdt_from_client(obd, cliname,
1626 rc = mgs_write_log_mdc_to_lmv(obd, fsdb, mti, cliname,
1629 rc = record_start_log(obd, &llh, cliname);
1633 rc = record_marker(obd, llh, fsdb, CM_START, cliname,
1635 rc = record_mount_opt(obd, llh, cliname, fsdb->fsdb_clilov,
1637 rc = record_marker(obd, llh, fsdb, CM_END, cliname,
1641 rc = record_end_log(obd, &llh);
1643 name_destroy(&cliname);
1645 // for_all_existing_mdt except current one
1646 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
1648 if (i != mti->mti_stripe_index &&
1649 test_bit(i, fsdb->fsdb_mdt_index_map)) {
1650 name_create_mdt(&mdtname, mti->mti_fsname, i);
1651 rc = mgs_write_log_mdc_to_mdt(obd, fsdb, mti, mdtname);
1652 name_destroy(&mdtname);
1659 /* Add the ost info to the client/mdt lov */
1660 static int mgs_write_log_osc_to_lov(struct obd_device *obd, struct fs_db *fsdb,
1661 struct mgs_target_info *mti,
1662 char *logname, char *suffix, char *lovname,
1663 enum lustre_sec_part sec_part, int flags)
1665 struct llog_handle *llh = NULL;
1666 char *nodeuuid, *oscname, *oscuuid, *lovuuid, *svname;
1671 CDEBUG(D_INFO, "adding osc for %s to log %s\n",
1672 mti->mti_svname, logname);
1674 if (mgs_log_is_empty(obd, logname)) {
1675 /* The first item in the log must be the lov, so we have
1676 somewhere to add our osc. */
1677 rc = mgs_write_log_lov(obd, fsdb, mti, logname, lovname);
1680 name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
1681 name_create(&svname, mti->mti_svname, "-osc");
1682 name_create(&oscname, svname, suffix);
1683 name_create(&oscuuid, oscname, "_UUID");
1684 name_create(&lovuuid, lovname, "_UUID");
1687 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
1689 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
1690 #04 L attach 0:OSC_uml1_ost1_MNT_client 1:osc 2:89070_lov1_a41dff51a
1691 #05 L setup 0:OSC_uml1_ost1_MNT_client 1:ost1_UUID 2:uml1_UUID
1693 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
1694 #07 L add_conn 0:OSC_uml1_ost1_MNT_client 1:uml2_UUID
1695 #08 L lov_modify_tgts add 0:lov1 1:ost1_UUID 2(index):0 3(gen):1
1698 rc = record_start_log(obd, &llh, logname);
1701 /* FIXME these should be a single journal transaction */
1702 rc = record_marker(obd, llh, fsdb, CM_START | flags, mti->mti_svname,
1704 for (i = 0; i < mti->mti_nid_count; i++) {
1705 CDEBUG(D_MGS, "add nid %s\n", libcfs_nid2str(mti->mti_nids[i]));
1706 rc = record_add_uuid(obd, llh, mti->mti_nids[i], nodeuuid);
1708 rc = record_attach(obd, llh, oscname, LUSTRE_OSC_NAME, lovuuid);
1709 rc = record_setup(obd, llh, oscname, mti->mti_uuid, nodeuuid, 0, 0);
1710 rc = mgs_write_log_failnids(obd, mti, llh, oscname);
1711 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
1712 rc = record_lov_add(obd, llh, lovname, mti->mti_uuid, index, "1");
1713 rc = record_marker(obd, llh, fsdb, CM_END | flags, mti->mti_svname,
1715 rc = record_end_log(obd, &llh);
1717 name_destroy(&lovuuid);
1718 name_destroy(&oscuuid);
1719 name_destroy(&oscname);
1720 name_destroy(&svname);
1721 name_destroy(&nodeuuid);
1725 static int mgs_write_log_ost(struct obd_device *obd, struct fs_db *fsdb,
1726 struct mgs_target_info *mti)
1728 struct llog_handle *llh = NULL;
1729 char *logname, *lovname;
1730 char *ptr = mti->mti_params;
1731 int rc, flags = 0, failout = 0, i;
1734 CDEBUG(D_MGS, "writing new ost %s\n", mti->mti_svname);
1736 /* The ost startup log */
1738 /* If the ost log already exists, that means that someone reformatted
1739 the ost and it called target_add again. */
1740 if (!mgs_log_is_empty(obd, mti->mti_svname)) {
1741 LCONSOLE_ERROR_MSG(0x141, "The config log for %s already "
1742 "exists, yet the server claims it never "
1743 "registered. It may have been reformatted, "
1744 "or the index changed. writeconf the MDT to "
1745 "regenerate all logs.\n", mti->mti_svname);
1750 attach obdfilter ost1 ost1_UUID
1751 setup /dev/loop2 ldiskfs f|n errors=remount-ro,user_xattr
1753 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
1754 failout = (strncmp(ptr, "failout", 7) == 0);
1755 rc = record_start_log(obd, &llh, mti->mti_svname);
1758 /* FIXME these should be a single journal transaction */
1759 rc = record_marker(obd, llh, fsdb, CM_START, mti->mti_svname,"add ost");
1760 if (*mti->mti_uuid == '\0')
1761 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
1762 "%s_UUID", mti->mti_svname);
1763 rc = record_attach(obd, llh, mti->mti_svname,
1764 "obdfilter"/*LUSTRE_OST_NAME*/, mti->mti_uuid);
1765 rc = record_setup(obd, llh, mti->mti_svname,
1766 "dev"/*ignored*/, "type"/*ignored*/,
1767 failout ? "n" : "f", 0/*options*/);
1768 rc = record_marker(obd, llh, fsdb, CM_END, mti->mti_svname, "add ost");
1769 rc = record_end_log(obd, &llh);
1771 /* We also have to update the other logs where this osc is part of
1774 if (fsdb->fsdb_flags & FSDB_OLDLOG14) {
1775 /* If we're upgrading, the old mdt log already has our
1776 entry. Let's do a fake one for fun. */
1777 /* Note that we can't add any new failnids, since we don't
1778 know the old osc names. */
1779 flags = CM_SKIP | CM_UPGRADE146;
1781 } else if ((mti->mti_flags & LDD_F_UPDATE) != LDD_F_UPDATE) {
1782 /* If the update flag isn't set, don't update client/mdt
1785 LCONSOLE_WARN("Client log for %s was not updated; writeconf "
1786 "the MDT first to regenerate it.\n",
1790 /* Add ost to all MDT lov defs */
1791 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
1792 if (test_bit(i, fsdb->fsdb_mdt_index_map)) {
1795 name_create_mdt_and_lov(&logname, &lovname, fsdb, i);
1796 sprintf(mdt_index, "-MDT%04x", i);
1797 mgs_write_log_osc_to_lov(obd, fsdb, mti, logname,
1799 LUSTRE_SP_MDT, flags);
1800 name_destroy(&logname);
1801 name_destroy(&lovname);
1805 /* Append ost info to the client log */
1806 name_create(&logname, mti->mti_fsname, "-client");
1807 mgs_write_log_osc_to_lov(obd, fsdb, mti, logname, "",
1808 fsdb->fsdb_clilov, LUSTRE_SP_CLI, 0);
1809 name_destroy(&logname);
1813 /* Add additional failnids to an existing log.
1814 The mdc/osc must have been added to logs first */
1815 /* tcp nids must be in dotted-quad ascii -
1816 we can't resolve hostnames from the kernel. */
1817 static int mgs_write_log_add_failnid(struct obd_device *obd, struct fs_db *fsdb,
1818 struct mgs_target_info *mti)
1820 char *logname, *cliname;
1821 struct llog_handle *llh = NULL;
1825 /* FIXME how do we delete a failnid? Currently --writeconf is the
1826 only way. Maybe make --erase-params pass a flag to really
1827 erase all params from logs - except it can't erase the failnids
1828 given when a target first registers, since they aren't processed
1831 /* Verify that we know about this target */
1832 if (mgs_log_is_empty(obd, mti->mti_svname)) {
1833 LCONSOLE_ERROR_MSG(0x142, "The target %s has not registered "
1834 "yet. It must be started before failnids "
1835 "can be added.\n", mti->mti_svname);
1839 /* Create mdc/osc client name (e.g. lustre-OST0001-osc) */
1840 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
1841 name_create(&cliname, mti->mti_svname, "-mdc");
1842 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
1843 name_create(&cliname, mti->mti_svname, "-osc");
1848 /* Add failover nids to client log */
1849 name_create(&logname, mti->mti_fsname, "-client");
1850 rc = record_start_log(obd, &llh, logname);
1852 /* FIXME this fn should be a single journal transaction */
1853 rc = record_marker(obd, llh, fsdb, CM_START, mti->mti_svname,
1855 rc = mgs_write_log_failnids(obd, mti, llh, cliname);
1856 rc = record_marker(obd, llh, fsdb, CM_END, mti->mti_svname,
1858 rc = record_end_log(obd, &llh);
1860 name_destroy(&logname);
1861 name_destroy(&cliname);
1863 if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
1864 /* Add OST failover nids to the MDT logs as well */
1867 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
1868 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
1870 name_create_mdt(&logname, mti->mti_fsname, i);
1871 name_create_mdt_osc(&cliname, mti->mti_svname, fsdb, i);
1873 rc = record_start_log(obd, &llh, logname);
1875 rc = record_marker(obd, llh, fsdb, CM_START,
1878 rc = mgs_write_log_failnids(obd, mti, llh,
1880 rc = record_marker(obd, llh, fsdb, CM_END,
1883 rc = record_end_log(obd, &llh);
1885 name_destroy(&cliname);
1886 name_destroy(&logname);
1893 static int mgs_wlp_lcfg(struct obd_device *obd, struct fs_db *fsdb,
1894 struct mgs_target_info *mti,
1895 char *logname, struct lustre_cfg_bufs *bufs,
1896 char *tgtname, char *ptr)
1898 char comment[MTI_NAME_MAXLEN];
1900 struct lustre_cfg *lcfg;
1903 /* Erase any old settings of this same parameter */
1904 memcpy(comment, ptr, MTI_NAME_MAXLEN);
1905 comment[MTI_NAME_MAXLEN - 1] = 0;
1906 /* But don't try to match the value. */
1907 if ((tmp = strchr(comment, '=')))
1909 /* FIXME we should skip settings that are the same as old values */
1910 rc = mgs_modify(obd, fsdb, mti, logname, tgtname, comment, CM_SKIP);
1911 LCONSOLE_INFO("%sing parameter %s.%s in log %s\n", rc ?
1912 "Sett" : "Modify", tgtname, comment, logname);
1914 lustre_cfg_bufs_reset(bufs, tgtname);
1915 lustre_cfg_bufs_set_string(bufs, 1, ptr);
1916 lcfg = lustre_cfg_new(LCFG_PARAM, bufs);
1919 rc = mgs_write_log_direct(obd, fsdb, logname, lcfg, tgtname, comment);
1920 lustre_cfg_free(lcfg);
1924 /* write global variable settings into log */
1925 static int mgs_write_log_sys(struct obd_device *obd, struct fs_db *fsdb,
1926 struct mgs_target_info *mti, char *sys, char *ptr)
1928 struct lustre_cfg_bufs bufs;
1929 struct lustre_cfg *lcfg;
1934 if (class_match_param(ptr, PARAM_TIMEOUT, &tmp) == 0)
1935 cmd = LCFG_SET_TIMEOUT;
1936 else if (class_match_param(ptr, PARAM_LDLM_TIMEOUT, &tmp) == 0)
1937 cmd = LCFG_SET_LDLM_TIMEOUT;
1938 /* Check for known params here so we can return error to lctl */
1939 else if ((class_match_param(ptr, PARAM_AT_MIN, &tmp) == 0)
1940 || (class_match_param(ptr, PARAM_AT_MAX, &tmp) == 0)
1941 || (class_match_param(ptr, PARAM_AT_EXTRA, &tmp) == 0)
1942 || (class_match_param(ptr, PARAM_AT_EARLY_MARGIN, &tmp) == 0)
1943 || (class_match_param(ptr, PARAM_AT_HISTORY, &tmp) == 0))
1948 val = simple_strtoul(tmp, NULL, 0);
1949 CDEBUG(D_MGS, "global %s = %d\n", ptr, val);
1951 lustre_cfg_bufs_reset(&bufs, NULL);
1952 lustre_cfg_bufs_set_string(&bufs, 1, sys);
1953 lcfg = lustre_cfg_new(cmd, &bufs);
1954 lcfg->lcfg_num = val;
1955 /* modify all servers and clients */
1956 rc = mgs_write_log_direct_all(obd, fsdb, mti, lcfg, mti->mti_fsname,
1958 lustre_cfg_free(lcfg);
1962 static int mgs_srpc_set_param_disk(struct obd_device *obd,
1964 struct mgs_target_info *mti,
1967 struct llog_handle *llh = NULL;
1969 char *comment, *ptr;
1970 struct lustre_cfg_bufs bufs;
1971 struct lustre_cfg *lcfg;
1976 ptr = strchr(param, '=');
1980 OBD_ALLOC(comment, len + 1);
1981 if (comment == NULL)
1983 strncpy(comment, param, len);
1984 comment[len] = '\0';
1987 lustre_cfg_bufs_reset(&bufs, mti->mti_svname);
1988 lustre_cfg_bufs_set_string(&bufs, 1, param);
1989 lcfg = lustre_cfg_new(LCFG_SPTLRPC_CONF, &bufs);
1991 GOTO(out_comment, rc = -ENOMEM);
1993 /* construct log name */
1994 rc = name_create(&logname, mti->mti_fsname, "-sptlrpc");
1998 if (mgs_log_is_empty(obd, logname)) {
1999 rc = record_start_log(obd, &llh, logname);
2000 record_end_log(obd, &llh);
2005 /* obsolete old one */
2006 mgs_modify(obd, fsdb, mti, logname, mti->mti_svname, comment, CM_SKIP);
2008 /* write the new one */
2009 rc = mgs_write_log_direct(obd, fsdb, logname, lcfg,
2010 mti->mti_svname, comment);
2012 CERROR("err %d writing log %s\n", rc, logname);
2015 name_destroy(&logname);
2017 lustre_cfg_free(lcfg);
2019 OBD_FREE(comment, len + 1);
2023 static int mgs_srpc_set_param_udesc_mem(struct fs_db *fsdb,
2028 /* disable the adjustable udesc parameter for now, i.e. use default
2029 * setting that client always ship udesc to MDT if possible. to enable
2030 * it simply remove the following line */
2033 ptr = strchr(param, '=');
2038 if (strcmp(param, PARAM_SRPC_UDESC))
2041 if (strcmp(ptr, "yes") == 0) {
2042 fsdb->fsdb_fl_udesc = 1;
2043 CWARN("Enable user descriptor shipping from client to MDT\n");
2044 } else if (strcmp(ptr, "no") == 0) {
2045 fsdb->fsdb_fl_udesc = 0;
2046 CWARN("Disable user descriptor shipping from client to MDT\n");
2054 CERROR("Invalid param: %s\n", param);
2058 static int mgs_srpc_set_param_mem(struct fs_db *fsdb,
2062 struct sptlrpc_rule rule;
2063 struct sptlrpc_rule_set *rset;
2067 if (strncmp(param, PARAM_SRPC, sizeof(PARAM_SRPC) - 1) != 0) {
2068 CERROR("Invalid sptlrpc parameter: %s\n", param);
2072 if (strncmp(param, PARAM_SRPC_UDESC,
2073 sizeof(PARAM_SRPC_UDESC) - 1) == 0) {
2074 RETURN(mgs_srpc_set_param_udesc_mem(fsdb, param));
2077 if (strncmp(param, PARAM_SRPC_FLVR, sizeof(PARAM_SRPC_FLVR) - 1) != 0) {
2078 CERROR("Invalid sptlrpc flavor parameter: %s\n", param);
2082 param += sizeof(PARAM_SRPC_FLVR) - 1;
2084 rc = sptlrpc_parse_rule(param, &rule);
2088 /* mgs rules implies must be mgc->mgs */
2089 if (fsdb->fsdb_fl_mgsself) {
2090 if ((rule.sr_from != LUSTRE_SP_MGC &&
2091 rule.sr_from != LUSTRE_SP_ANY) ||
2092 (rule.sr_to != LUSTRE_SP_MGS &&
2093 rule.sr_to != LUSTRE_SP_ANY))
2097 /* preapre room for this coming rule. svcname format should be:
2098 * - fsname: general rule
2099 * - fsname-tgtname: target-specific rule
2101 if (strchr(svname, '-')) {
2102 struct mgs_tgt_srpc_conf *tgtconf;
2105 for (tgtconf = fsdb->fsdb_srpc_tgt; tgtconf != NULL;
2106 tgtconf = tgtconf->mtsc_next) {
2107 if (!strcmp(tgtconf->mtsc_tgt, svname)) {
2116 OBD_ALLOC_PTR(tgtconf);
2117 if (tgtconf == NULL)
2120 name_len = strlen(svname);
2122 OBD_ALLOC(tgtconf->mtsc_tgt, name_len + 1);
2123 if (tgtconf->mtsc_tgt == NULL) {
2124 OBD_FREE_PTR(tgtconf);
2127 memcpy(tgtconf->mtsc_tgt, svname, name_len);
2129 tgtconf->mtsc_next = fsdb->fsdb_srpc_tgt;
2130 fsdb->fsdb_srpc_tgt = tgtconf;
2133 rset = &tgtconf->mtsc_rset;
2135 rset = &fsdb->fsdb_srpc_gen;
2138 rc = sptlrpc_rule_set_merge(rset, &rule);
2143 static int mgs_srpc_set_param(struct obd_device *obd,
2145 struct mgs_target_info *mti,
2155 /* keep a copy of original param, which could be destroied
2157 copy_size = strlen(param) + 1;
2158 OBD_ALLOC(copy, copy_size);
2161 memcpy(copy, param, copy_size);
2163 rc = mgs_srpc_set_param_mem(fsdb, mti->mti_svname, param);
2167 /* previous steps guaranteed the syntax is correct */
2168 rc = mgs_srpc_set_param_disk(obd, fsdb, mti, copy);
2172 if (fsdb->fsdb_fl_mgsself) {
2174 * for mgs rules, make them effective immediately.
2176 LASSERT(fsdb->fsdb_srpc_tgt == NULL);
2177 sptlrpc_target_update_exp_flavor(obd, &fsdb->fsdb_srpc_gen);
2181 OBD_FREE(copy, copy_size);
2185 struct mgs_srpc_read_data {
2186 struct fs_db *msrd_fsdb;
2190 static int mgs_srpc_read_handler(struct llog_handle *llh,
2191 struct llog_rec_hdr *rec,
2194 struct mgs_srpc_read_data *msrd = (struct mgs_srpc_read_data *) data;
2195 struct cfg_marker *marker;
2196 struct lustre_cfg *lcfg = (struct lustre_cfg *)(rec + 1);
2197 char *svname, *param;
2201 if (rec->lrh_type != OBD_CFG_REC) {
2202 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
2206 cfg_len = rec->lrh_len - sizeof(struct llog_rec_hdr) -
2207 sizeof(struct llog_rec_tail);
2209 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
2211 CERROR("Insane cfg\n");
2215 if (lcfg->lcfg_command == LCFG_MARKER) {
2216 marker = lustre_cfg_buf(lcfg, 1);
2218 if (marker->cm_flags & CM_START &&
2219 marker->cm_flags & CM_SKIP)
2220 msrd->msrd_skip = 1;
2221 if (marker->cm_flags & CM_END)
2222 msrd->msrd_skip = 0;
2227 if (msrd->msrd_skip)
2230 if (lcfg->lcfg_command != LCFG_SPTLRPC_CONF) {
2231 CERROR("invalid command (%x)\n", lcfg->lcfg_command);
2235 svname = lustre_cfg_string(lcfg, 0);
2236 if (svname == NULL) {
2237 CERROR("svname is empty\n");
2241 param = lustre_cfg_string(lcfg, 1);
2242 if (param == NULL) {
2243 CERROR("param is empty\n");
2247 rc = mgs_srpc_set_param_mem(msrd->msrd_fsdb, svname, param);
2249 CERROR("read sptlrpc record error (%d): %s\n", rc, param);
2254 int mgs_get_fsdb_srpc_from_llog(struct obd_device *obd,
2257 struct llog_handle *llh = NULL;
2258 struct lvfs_run_ctxt saved;
2259 struct llog_ctxt *ctxt;
2261 struct mgs_srpc_read_data msrd;
2265 /* construct log name */
2266 rc = name_create(&logname, fsdb->fsdb_name, "-sptlrpc");
2270 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
2271 LASSERT(ctxt != NULL);
2273 if (mgs_log_is_empty(obd, logname))
2276 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
2278 rc = llog_create(ctxt, &llh, NULL, logname);
2282 rc = llog_init_handle(llh, LLOG_F_IS_PLAIN, NULL);
2284 GOTO(out_close, rc);
2286 if (llog_get_size(llh) <= 1)
2287 GOTO(out_close, rc = 0);
2289 msrd.msrd_fsdb = fsdb;
2292 rc = llog_process(llh, mgs_srpc_read_handler, (void *) &msrd, NULL);
2297 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
2299 llog_ctxt_put(ctxt);
2300 name_destroy(&logname);
2303 CERROR("failed to read sptlrpc config database: %d\n", rc);
2307 static int mgs_write_log_param(struct obd_device *obd, struct fs_db *fsdb,
2308 struct mgs_target_info *mti, char *ptr)
2310 struct lustre_cfg_bufs bufs;
2316 /* For various parameter settings, we have to figure out which logs
2317 care about them (e.g. both mdt and client for lov settings) */
2318 CDEBUG(D_MGS, "next param '%s'\n", ptr);
2320 /* The params are stored in MOUNT_DATA_FILE and modified via
2321 tunefs.lustre, or set using lctl conf_param */
2323 /* Processed in lustre_start_mgc */
2324 if (class_match_param(ptr, PARAM_MGSNODE, NULL) == 0)
2327 /* Processed in mgs_write_log_ost */
2328 if (class_match_param(ptr, PARAM_FAILMODE, NULL) == 0) {
2329 if (mti->mti_flags & LDD_F_PARAM) {
2330 LCONSOLE_ERROR_MSG(0x169, "%s can only be "
2331 "changed with tunefs.lustre"
2332 "and --writeconf\n", ptr);
2338 if (class_match_param(ptr, PARAM_SRPC, NULL) == 0) {
2339 rc = mgs_srpc_set_param(obd, fsdb, mti, ptr);
2343 if (class_match_param(ptr, PARAM_FAILNODE, NULL) == 0) {
2344 /* Add a failover nidlist */
2346 /* We already processed failovers params for new
2347 targets in mgs_write_log_target */
2348 if (mti->mti_flags & LDD_F_PARAM) {
2349 CDEBUG(D_MGS, "Adding failnode\n");
2350 rc = mgs_write_log_add_failnid(obd, fsdb, mti);
2355 if (class_match_param(ptr, PARAM_SYS, &tmp) == 0) {
2356 rc = mgs_write_log_sys(obd, fsdb, mti, ptr, tmp);
2360 if (class_match_param(ptr, PARAM_OSC""PARAM_ACTIVE, &tmp) == 0) {
2361 /* active=0 means off, anything else means on */
2362 int flag = (*tmp == '0') ? CM_EXCLUDE : 0;
2365 if (!(mti->mti_flags & LDD_F_SV_TYPE_OST)) {
2366 LCONSOLE_ERROR_MSG(0x144, "%s: Only OSCs can "
2367 "be (de)activated.\n",
2369 GOTO(end, rc = -EINVAL);
2371 LCONSOLE_WARN("Permanently %sactivating %s\n",
2372 flag ? "de": "re", mti->mti_svname);
2374 name_create(&logname, mti->mti_fsname, "-client");
2375 rc = mgs_modify(obd, fsdb, mti, logname,
2376 mti->mti_svname, "add osc", flag);
2377 name_destroy(&logname);
2381 /* Add to all MDT logs for CMD */
2382 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2383 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
2385 name_create_mdt(&logname, mti->mti_fsname, i);
2386 rc = mgs_modify(obd, fsdb, mti, logname,
2387 mti->mti_svname, "add osc", flag);
2388 name_destroy(&logname);
2394 LCONSOLE_ERROR_MSG(0x145, "Couldn't find %s in"
2395 "log (%d). No permanent "
2396 "changes were made to the "
2398 mti->mti_svname, rc);
2399 if (fsdb->fsdb_flags & FSDB_OLDLOG14)
2400 LCONSOLE_ERROR_MSG(0x146, "This may be"
2405 "update the logs.\n");
2408 /* Fall through to osc proc for deactivating live OSC
2409 on running MDT / clients. */
2411 /* Below here, let obd's XXX_process_config methods handle it */
2413 /* All lov. in proc */
2414 if (class_match_param(ptr, PARAM_LOV, NULL) == 0) {
2417 CDEBUG(D_MGS, "lov param %s\n", ptr);
2418 if (!(mti->mti_flags & LDD_F_SV_TYPE_MDT)) {
2419 LCONSOLE_ERROR_MSG(0x147, "LOV params must be "
2420 "set on the MDT, not %s. "
2427 if (mgs_log_is_empty(obd, mti->mti_svname))
2428 GOTO(end, rc = -ENODEV);
2430 name_create_mdt_and_lov(&logname, &mdtlovname, fsdb,
2431 mti->mti_stripe_index);
2432 rc = mgs_wlp_lcfg(obd, fsdb, mti, mti->mti_svname,
2433 &bufs, mdtlovname, ptr);
2434 name_destroy(&logname);
2435 name_destroy(&mdtlovname);
2440 name_create(&logname, mti->mti_fsname, "-client");
2441 rc = mgs_wlp_lcfg(obd, fsdb, mti, logname, &bufs,
2442 fsdb->fsdb_clilov, ptr);
2443 name_destroy(&logname);
2447 /* All osc., mdc., llite. params in proc */
2448 if ((class_match_param(ptr, PARAM_OSC, NULL) == 0) ||
2449 (class_match_param(ptr, PARAM_MDC, NULL) == 0) ||
2450 (class_match_param(ptr, PARAM_LLITE, NULL) == 0)) {
2452 if (memcmp(ptr, PARAM_LLITE, strlen(PARAM_LLITE)) == 0) {
2453 name_create(&cname, mti->mti_fsname, "-client");
2454 /* Add the client type to match the obdname in
2455 class_config_llog_handler */
2456 } else if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
2459 name_create(&cname, fsdb->fsdb_mdc, "");
2461 name_create(&cname, mti->mti_svname,
2463 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2465 if (fsdb->fsdb_flags & FSDB_OLDLOG14) {
2466 LCONSOLE_ERROR_MSG(0x148, "Upgraded "
2467 "client logs for %s"
2469 "modified. Consider"
2471 "configuration with"
2474 /* We don't know the names of all the
2476 GOTO(end, rc = -EINVAL);
2478 name_create(&cname, mti->mti_svname, "-osc");
2480 GOTO(end, rc = -EINVAL);
2483 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
2486 name_create(&logname, mti->mti_fsname, "-client");
2487 rc = mgs_wlp_lcfg(obd, fsdb, mti, logname, &bufs,
2490 /* osc params affect the MDT as well */
2491 if (!rc && (mti->mti_flags & LDD_F_SV_TYPE_OST)) {
2494 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
2495 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
2497 name_destroy(&cname);
2498 name_create_mdt_osc(&cname, mti->mti_svname,
2500 name_destroy(&logname);
2501 name_create_mdt(&logname, mti->mti_fsname, i);
2502 if (!mgs_log_is_empty(obd, logname))
2503 rc = mgs_wlp_lcfg(obd, fsdb,mti,logname,
2509 name_destroy(&logname);
2510 name_destroy(&cname);
2514 /* All mdt. params in proc */
2515 if (class_match_param(ptr, PARAM_MDT, NULL) == 0) {
2519 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
2520 if (strncmp(mti->mti_svname, mti->mti_fsname,
2521 MTI_NAME_MAXLEN) == 0)
2522 /* device is unspecified completely? */
2523 rc = LDD_F_SV_TYPE_MDT | LDD_F_SV_ALL;
2525 rc = server_name2index(mti->mti_svname, &idx, NULL);
2528 if ((rc & LDD_F_SV_TYPE_MDT) == 0)
2530 if (rc & LDD_F_SV_ALL) {
2531 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2533 fsdb->fsdb_mdt_index_map))
2535 name_create_mdt(&logname, mti->mti_fsname, i);
2536 rc = mgs_wlp_lcfg(obd, fsdb, mti,
2539 name_destroy(&logname);
2544 rc = mgs_wlp_lcfg(obd, fsdb, mti,
2545 mti->mti_svname, &bufs,
2546 mti->mti_svname, ptr);
2553 /* All mdd., ost. params in proc */
2554 if ((class_match_param(ptr, PARAM_MDD, NULL) == 0) ||
2555 (class_match_param(ptr, PARAM_OST, NULL) == 0)) {
2556 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
2557 if (mgs_log_is_empty(obd, mti->mti_svname))
2558 GOTO(end, rc = -ENODEV);
2560 rc = mgs_wlp_lcfg(obd, fsdb, mti, mti->mti_svname,
2561 &bufs, mti->mti_svname, ptr);
2565 LCONSOLE_WARN("Ignoring unrecognized param '%s'\n", ptr);
2569 CERROR("err %d on param '%s'\n", rc, ptr);
2574 /* Not implementing automatic failover nid addition at this time. */
2575 int mgs_check_failnid(struct obd_device *obd, struct mgs_target_info *mti)
2582 rc = mgs_find_or_make_fsdb(obd, fsname, &fsdb);
2586 if (mgs_log_is_empty(obd, mti->mti_svname))
2587 /* should never happen */
2590 CDEBUG(D_MGS, "Checking for new failnids for %s\n", mti->mti_svname);
2592 /* FIXME We can just check mti->params to see if we're already in
2593 the failover list. Modify mti->params for rewriting back at
2594 server_register_target(). */
2596 down(&fsdb->fsdb_sem);
2597 rc = mgs_write_log_add_failnid(obd, fsdb, mti);
2598 up(&fsdb->fsdb_sem);
2605 int mgs_write_log_target(struct obd_device *obd,
2606 struct mgs_target_info *mti)
2613 /* set/check the new target index */
2614 rc = mgs_set_index(obd, mti);
2616 CERROR("Can't get index (%d)\n", rc);
2621 if (mti->mti_flags & LDD_F_UPGRADE14) {
2622 if (rc == EALREADY) {
2623 LCONSOLE_INFO("Found index %d for %s 1.4 log, "
2624 "upgrading\n", mti->mti_stripe_index,
2627 LCONSOLE_ERROR_MSG(0x149, "Failed to find %s in the old"
2628 " client log. Apparently it is not "
2629 "part of this filesystem, or the old"
2630 " log is wrong.\nUse 'writeconf' on "
2631 "the MDT to force log regeneration."
2632 "\n", mti->mti_svname);
2633 /* Not in client log? Upgrade anyhow...*/
2634 /* Argument against upgrading: reformat MDT,
2635 upgrade OST, then OST will start but will be SKIPped
2636 in client logs. Maybe error now is better. */
2637 /* RETURN(-EINVAL); */
2639 /* end COMPAT_146 */
2641 if (rc == EALREADY) {
2642 LCONSOLE_WARN("Found index %d for %s, updating log\n",
2643 mti->mti_stripe_index, mti->mti_svname);
2644 /* We would like to mark old log sections as invalid
2645 and add new log sections in the client and mdt logs.
2646 But if we add new sections, then live clients will
2647 get repeat setup instructions for already running
2648 osc's. So don't update the client/mdt logs. */
2649 mti->mti_flags &= ~LDD_F_UPDATE;
2653 rc = mgs_find_or_make_fsdb(obd, mti->mti_fsname, &fsdb);
2655 CERROR("Can't get db for %s\n", mti->mti_fsname);
2659 down(&fsdb->fsdb_sem);
2661 if (mti->mti_flags &
2662 (LDD_F_VIRGIN | LDD_F_UPGRADE14 | LDD_F_WRITECONF)) {
2663 /* Generate a log from scratch */
2664 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
2665 rc = mgs_write_log_mdt(obd, fsdb, mti);
2666 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2667 rc = mgs_write_log_ost(obd, fsdb, mti);
2669 CERROR("Unknown target type %#x, can't create log for "
2670 "%s\n", mti->mti_flags, mti->mti_svname);
2673 CERROR("Can't write logs for %s (%d)\n",
2674 mti->mti_svname, rc);
2678 /* Just update the params from tunefs in mgs_write_log_params */
2679 CDEBUG(D_MGS, "Update params for %s\n", mti->mti_svname);
2680 mti->mti_flags |= LDD_F_PARAM;
2683 /* allocate temporary buffer, where class_get_next_param will
2684 make copy of a current parameter */
2685 OBD_ALLOC(buf, strlen(mti->mti_params) + 1);
2687 GOTO(out_up, rc = -ENOMEM);
2688 params = mti->mti_params;
2689 while (params != NULL) {
2690 rc = class_get_next_param(¶ms, buf);
2693 /* there is no next parameter, that is
2698 CDEBUG(D_MGS, "remaining string: '%s', param: '%s'\n",
2700 rc = mgs_write_log_param(obd, fsdb, mti, buf);
2705 OBD_FREE(buf, strlen(mti->mti_params) + 1);
2708 up(&fsdb->fsdb_sem);
2713 /* verify that we can handle the old config logs */
2714 int mgs_upgrade_sv_14(struct obd_device *obd, struct mgs_target_info *mti)
2720 /* Create ost log normally, as servers register. Servers
2721 register with their old uuids (from last_rcvd), so old
2722 (MDT and client) logs should work.
2723 - new MDT won't know about old OSTs, only the ones that have
2724 registered, so we need the old MDT log to get the LOV right
2725 in order for old clients to work.
2726 - Old clients connect to the MDT, not the MGS, for their logs, and
2727 will therefore receive the old client log from the MDT /LOGS dir.
2728 - Old clients can continue to use and connect to old or new OSTs
2729 - New clients will contact the MGS for their log
2732 LCONSOLE_INFO("upgrading server %s from pre-1.6\n", mti->mti_svname);
2733 server_mti_print("upgrade", mti);
2735 rc = mgs_find_or_make_fsdb(obd, mti->mti_fsname, &fsdb);
2739 if (fsdb->fsdb_flags & FSDB_LOG_EMPTY) {
2740 LCONSOLE_ERROR_MSG(0x14a, "The old client log %s-client is "
2741 "missing. Was tunefs.lustre successful?\n",
2746 if (fsdb->fsdb_gen == 0) {
2747 /* There were no markers in the client log, meaning we have
2748 not updated the logs for this fs */
2749 CDEBUG(D_MGS, "found old, unupdated client log\n");
2752 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
2753 if (mgs_log_is_empty(obd, mti->mti_svname)) {
2754 LCONSOLE_ERROR_MSG(0x14b, "The old MDT log %s is "
2755 "missing. Was tunefs.lustre "
2760 /* We're starting with an old uuid. Assume old name for lov
2761 as well since the lov entry already exists in the log. */
2762 CDEBUG(D_MGS, "old mds uuid %s\n", mti->mti_uuid);
2763 if (strncmp(mti->mti_uuid, fsdb->fsdb_mdtlov + 4,
2764 strlen(fsdb->fsdb_mdtlov) - 4) != 0) {
2765 CERROR("old mds uuid %s doesn't match log %s (%s)\n",
2766 mti->mti_uuid, fsdb->fsdb_mdtlov,
2767 fsdb->fsdb_mdtlov + 4);
2772 if (!(fsdb->fsdb_flags & FSDB_OLDLOG14)) {
2773 LCONSOLE_ERROR_MSG(0x14c, "%s-client is supposedly an old "
2774 "log, but no old LOV or MDT was found. "
2775 "Consider updating the configuration with"
2776 " --writeconf.\n", mti->mti_fsname);
2781 /* end COMPAT_146 */
2783 int mgs_erase_log(struct obd_device *obd, char *name)
2785 struct lvfs_run_ctxt saved;
2786 struct llog_ctxt *ctxt;
2787 struct llog_handle *llh;
2790 ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
2791 LASSERT(ctxt != NULL);
2793 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
2794 rc = llog_create(ctxt, &llh, NULL, name);
2796 llog_init_handle(llh, LLOG_F_IS_PLAIN, NULL);
2797 rc = llog_destroy(llh);
2798 llog_free_handle(llh);
2800 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
2801 llog_ctxt_put(ctxt);
2804 CERROR("failed to clear log %s: %d\n", name, rc);
2809 /* erase all logs for the given fs */
2810 int mgs_erase_logs(struct obd_device *obd, char *fsname)
2812 struct mgs_obd *mgs = &obd->u.mgs;
2813 static struct fs_db *fsdb;
2814 struct list_head dentry_list;
2815 struct l_linux_dirent *dirent, *n;
2816 int rc, len = strlen(fsname);
2819 /* Find all the logs in the CONFIGS directory */
2820 rc = class_dentry_readdir(obd, mgs->mgs_configs_dir,
2821 mgs->mgs_vfsmnt, &dentry_list);
2823 CERROR("Can't read %s dir\n", MOUNT_CONFIGS_DIR);
2827 down(&mgs->mgs_sem);
2829 /* Delete the fs db */
2830 fsdb = mgs_find_fsdb(obd, fsname);
2832 mgs_free_fsdb(obd, fsdb);
2834 list_for_each_entry_safe(dirent, n, &dentry_list, lld_list) {
2835 list_del(&dirent->lld_list);
2836 if (strncmp(fsname, dirent->lld_name, len) == 0) {
2837 CDEBUG(D_MGS, "Removing log %s\n", dirent->lld_name);
2838 mgs_erase_log(obd, dirent->lld_name);
2840 OBD_FREE(dirent, sizeof(*dirent));
2848 /* from llog_swab */
2849 static void print_lustre_cfg(struct lustre_cfg *lcfg)
2854 CDEBUG(D_MGS, "lustre_cfg: %p\n", lcfg);
2855 CDEBUG(D_MGS, "\tlcfg->lcfg_version: %#x\n", lcfg->lcfg_version);
2857 CDEBUG(D_MGS, "\tlcfg->lcfg_command: %#x\n", lcfg->lcfg_command);
2858 CDEBUG(D_MGS, "\tlcfg->lcfg_num: %#x\n", lcfg->lcfg_num);
2859 CDEBUG(D_MGS, "\tlcfg->lcfg_flags: %#x\n", lcfg->lcfg_flags);
2860 CDEBUG(D_MGS, "\tlcfg->lcfg_nid: %s\n", libcfs_nid2str(lcfg->lcfg_nid));
2862 CDEBUG(D_MGS, "\tlcfg->lcfg_bufcount: %d\n", lcfg->lcfg_bufcount);
2863 if (lcfg->lcfg_bufcount < LUSTRE_CFG_MAX_BUFCOUNT)
2864 for (i = 0; i < lcfg->lcfg_bufcount; i++) {
2865 CDEBUG(D_MGS, "\tlcfg->lcfg_buflens[%d]: %d %s\n",
2866 i, lcfg->lcfg_buflens[i],
2867 lustre_cfg_string(lcfg, i));
2872 /* Set a permanent (config log) param for a target or fs */
2873 int mgs_setparam(struct obd_device *obd, struct lustre_cfg *lcfg, char *fsname)
2876 struct mgs_target_info *mti;
2877 char *devname, *param;
2883 print_lustre_cfg(lcfg);
2885 /* lustre, lustre-mdtlov, lustre-client, lustre-MDT0000 */
2886 devname = lustre_cfg_string(lcfg, 0);
2887 param = lustre_cfg_string(lcfg, 1);
2889 /* Assume device name embedded in param:
2890 lustre-OST0000.osc.max_dirty_mb=32 */
2891 ptr = strchr(param, '.');
2899 LCONSOLE_ERROR_MSG(0x14d, "No target specified: %s\n", param);
2903 /* Extract fsname */
2904 ptr = strrchr(devname, '-');
2905 memset(fsname, 0, MTI_NAME_MAXLEN);
2906 if (ptr && (server_name2index(ptr, &index, NULL) >= 0)) {
2907 /* param related to llite isn't allowed to set by OST or MDT */
2908 if (strncmp(param, PARAM_LLITE, sizeof(PARAM_LLITE)) == 0)
2911 strncpy(fsname, devname, ptr - devname);
2913 /* assume devname is the fsname */
2914 strncpy(fsname, devname, MTI_NAME_MAXLEN);
2916 fsname[MTI_NAME_MAXLEN - 1] = 0;
2917 CDEBUG(D_MGS, "setparam on fs %s device %s\n", fsname, devname);
2919 rc = mgs_find_or_make_fsdb(obd, fsname, &fsdb);
2922 if (!fsdb->fsdb_fl_mgsself && fsdb->fsdb_flags & FSDB_LOG_EMPTY) {
2923 CERROR("No filesystem targets for %s. cfg_device from lctl "
2924 "is '%s'\n", fsname, devname);
2925 mgs_free_fsdb(obd, fsdb);
2929 /* Create a fake mti to hold everything */
2932 GOTO(out, rc = -ENOMEM);
2933 strncpy(mti->mti_fsname, fsname, MTI_NAME_MAXLEN);
2934 strncpy(mti->mti_svname, devname, MTI_NAME_MAXLEN);
2935 strncpy(mti->mti_params, param, sizeof(mti->mti_params));
2936 rc = server_name2index(mti->mti_svname, &mti->mti_stripe_index, &tmp);
2938 /* Not a valid server; may be only fsname */
2941 /* Strip -osc or -mdc suffix from svname */
2942 if (server_make_name(rc, mti->mti_stripe_index, mti->mti_fsname,
2944 GOTO(out, rc = -EINVAL);
2946 mti->mti_flags = rc | LDD_F_PARAM;
2948 down(&fsdb->fsdb_sem);
2949 /* this is lctl conf_param's single param path, there is not
2950 need to loop through parameters */
2951 rc = mgs_write_log_param(obd, fsdb, mti, mti->mti_params);
2952 up(&fsdb->fsdb_sem);
2959 static int mgs_write_log_pool(struct obd_device *obd, char *logname,
2960 struct fs_db *fsdb, char *lovname,
2961 enum lcfg_command_type cmd,
2962 char *poolname, char *fsname,
2963 char *ostname, char *comment)
2965 struct llog_handle *llh = NULL;
2968 rc = record_start_log(obd, &llh, logname);
2971 rc = record_marker(obd, llh, fsdb, CM_START, lovname, comment);
2972 record_base(obd, llh, lovname, 0, cmd, poolname, fsname, ostname, 0);
2973 rc = record_marker(obd, llh, fsdb, CM_END, lovname, comment);
2974 rc = record_end_log(obd, &llh);
2979 int mgs_pool_cmd(struct obd_device *obd, enum lcfg_command_type cmd,
2980 char *fsname, char *poolname, char *ostname)
2985 char *label = NULL, *canceled_label = NULL;
2987 struct mgs_target_info *mti = NULL;
2991 rc = mgs_find_or_make_fsdb(obd, fsname, &fsdb);
2993 CERROR("Can't get db for %s\n", fsname);
2996 if (fsdb->fsdb_flags & FSDB_LOG_EMPTY) {
2997 CERROR("%s is not defined\n", fsname);
2998 mgs_free_fsdb(obd, fsdb);
3002 label_sz = 10 + strlen(fsname) + strlen(poolname);
3004 /* check if ostname match fsname */
3005 if (ostname != NULL) {
3008 ptr = strrchr(ostname, '-');
3009 if ((ptr == NULL) ||
3010 (strncmp(fsname, ostname, ptr-ostname) != 0))
3012 label_sz += strlen(ostname);
3015 OBD_ALLOC(label, label_sz);
3017 GOTO(out, rc = -ENOMEM);
3020 case LCFG_POOL_NEW: {
3022 "new %s.%s", fsname, poolname);
3025 case LCFG_POOL_ADD: {
3027 "add %s.%s.%s", fsname, poolname, ostname);
3030 case LCFG_POOL_REM: {
3031 OBD_ALLOC(canceled_label, label_sz);
3032 if (canceled_label == NULL)
3033 GOTO(out, rc = -ENOMEM);
3035 "rem %s.%s.%s", fsname, poolname, ostname);
3036 sprintf(canceled_label,
3037 "add %s.%s.%s", fsname, poolname, ostname);
3040 case LCFG_POOL_DEL: {
3041 OBD_ALLOC(canceled_label, label_sz);
3042 if (canceled_label == NULL)
3043 GOTO(out, rc = -ENOMEM);
3045 "del %s.%s", fsname, poolname);
3046 sprintf(canceled_label,
3047 "new %s.%s", fsname, poolname);
3055 down(&fsdb->fsdb_sem);
3057 if (canceled_label != NULL) {
3060 GOTO(out, rc = -ENOMEM);
3063 /* write pool def to all MDT logs */
3064 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3065 if (test_bit(i, fsdb->fsdb_mdt_index_map)) {
3066 name_create_mdt_and_lov(&logname, &lovname, fsdb, i);
3068 if (canceled_label != NULL) {
3069 strcpy(mti->mti_svname, "lov pool");
3070 mgs_modify(obd, fsdb, mti, logname, lovname,
3071 canceled_label, CM_SKIP);
3074 mgs_write_log_pool(obd, logname, fsdb, lovname,
3075 cmd, fsname, poolname, ostname,
3077 name_destroy(&logname);
3078 name_destroy(&lovname);
3082 name_create(&logname, fsname, "-client");
3083 if (canceled_label != NULL)
3084 mgs_modify(obd, fsdb, mti, logname, fsdb->fsdb_clilov,
3085 canceled_label, CM_SKIP);
3087 mgs_write_log_pool(obd, logname, fsdb, fsdb->fsdb_clilov,
3088 cmd, fsname, poolname, ostname, label);
3089 name_destroy(&logname);
3091 up(&fsdb->fsdb_sem);
3096 OBD_FREE(label, label_sz);
3098 if (canceled_label != NULL)
3099 OBD_FREE(canceled_label, label_sz);
3108 /******************** unused *********************/
3109 static int mgs_backup_llog(struct obd_device *obd, char* fsname)
3111 struct file *filp, *bak_filp;
3112 struct lvfs_run_ctxt saved;
3113 char *logname, *buf;
3114 loff_t soff = 0 , doff = 0;
3115 int count = 4096, len;
3118 OBD_ALLOC(logname, PATH_MAX);
3119 if (logname == NULL)
3122 OBD_ALLOC(buf, count);
3124 GOTO(out , rc = -ENOMEM);
3126 len = snprintf(logname, PATH_MAX, "%s/%s.bak",
3127 MOUNT_CONFIGS_DIR, fsname);
3129 if (len >= PATH_MAX - 1) {
3130 GOTO(out, -ENAMETOOLONG);
3133 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
3135 bak_filp = l_filp_open(logname, O_RDWR|O_CREAT|O_TRUNC, 0660);
3136 if (IS_ERR(bak_filp)) {
3137 rc = PTR_ERR(bak_filp);
3138 CERROR("backup logfile open %s: %d\n", logname, rc);
3141 sprintf(logname, "%s/%s", MOUNT_CONFIGS_DIR, fsname);
3142 filp = l_filp_open(logname, O_RDONLY, 0);
3145 CERROR("logfile open %s: %d\n", logname, rc);
3149 while ((rc = lustre_fread(filp, buf, count, &soff)) > 0) {
3150 rc = lustre_fwrite(bak_filp, buf, count, &doff);
3154 filp_close(filp, 0);
3156 filp_close(bak_filp, 0);
3158 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
3161 OBD_FREE(buf, count);
3162 OBD_FREE(logname, PATH_MAX);