4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 only,
8 * as published by the Free Software Foundation.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License version 2 for more details (a copy is included
14 * in the LICENSE file that accompanied this code).
16 * You should have received a copy of the GNU General Public License
17 * version 2 along with this program; If not, see
18 * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
20 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
21 * CA 95054 USA or visit www.sun.com if you need additional information or
27 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
28 * Use is subject to license terms.
30 * Copyright (c) 2011, Whamcloud, Inc.
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>
41 * Author: Alex Zhuravlev <bzzz@whamcloud.com>
42 * Author: Mikhail Pershin <tappro@whamcloud.com>
45 #define DEBUG_SUBSYSTEM S_MGS
46 #define D_MGS D_CONFIG
50 #include <lustre_param.h>
51 #include <lustre_sec.h>
54 #include "mgs_internal.h"
56 /********************** Class functions ********************/
58 int class_dentry_readdir(const struct lu_env *env,
59 struct mgs_device *mgs, cfs_list_t *list)
61 struct dt_object *dir = mgs->mgs_configs_dir;
62 const struct dt_it_ops *iops;
64 struct mgs_direntry *de;
68 CFS_INIT_LIST_HEAD(list);
70 if (!dt_try_as_dir(env, dir))
71 GOTO(out, rc = -ENOTDIR);
74 LASSERT(dir->do_index_ops);
76 iops = &dir->do_index_ops->dio_it;
77 it = iops->init(env, dir, LUDA_64BITHASH, BYPASS_CAPA);
81 rc = iops->load(env, it, 0);
87 key = (void *)iops->key(env, it);
89 CERROR("%s: key failed when listing %s: rc = %d\n",
90 mgs->mgs_obd->obd_name, MOUNT_CONFIGS_DIR,
94 key_sz = iops->key_size(env, it);
97 /* filter out "." and ".." entries */
101 if (key_sz == 2 && key[1] == '.')
105 de = mgs_direntry_alloc(key_sz + 1);
111 memcpy(de->name, key, key_sz);
112 de->name[key_sz] = 0;
114 cfs_list_add(&de->list, list);
117 rc = iops->next(env, it);
127 CERROR("%s: key failed when listing %s: rc = %d\n",
128 mgs->mgs_obd->obd_name, MOUNT_CONFIGS_DIR, rc);
132 /******************** DB functions *********************/
134 static inline int name_create(char **newname, char *prefix, char *suffix)
137 OBD_ALLOC(*newname, strlen(prefix) + strlen(suffix) + 1);
140 sprintf(*newname, "%s%s", prefix, suffix);
144 static inline void name_destroy(char **name)
147 OBD_FREE(*name, strlen(*name) + 1);
151 struct mgs_fsdb_handler_data
157 /* from the (client) config log, figure out:
158 1. which ost's/mdt's are configured (by index)
159 2. what the last config step is
160 3. COMPAT_18 osc name
162 /* It might be better to have a separate db file, instead of parsing the info
163 out of the client log. This is slow and potentially error-prone. */
164 static int mgs_fsdb_handler(const struct lu_env *env, struct llog_handle *llh,
165 struct llog_rec_hdr *rec, void *data)
167 struct mgs_fsdb_handler_data *d = data;
168 struct fs_db *fsdb = d->fsdb;
169 int cfg_len = rec->lrh_len;
170 char *cfg_buf = (char*) (rec + 1);
171 struct lustre_cfg *lcfg;
176 if (rec->lrh_type != OBD_CFG_REC) {
177 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
181 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
183 CERROR("Insane cfg\n");
187 lcfg = (struct lustre_cfg *)cfg_buf;
189 CDEBUG(D_INFO, "cmd %x %s %s\n", lcfg->lcfg_command,
190 lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));
192 /* Figure out ost indicies */
193 /* lov_modify_tgts add 0:lov1 1:ost1_UUID 2(index):0 3(gen):1 */
194 if (lcfg->lcfg_command == LCFG_LOV_ADD_OBD ||
195 lcfg->lcfg_command == LCFG_LOV_DEL_OBD) {
196 index = simple_strtoul(lustre_cfg_string(lcfg, 2),
198 CDEBUG(D_MGS, "OST index for %s is %u (%s)\n",
199 lustre_cfg_string(lcfg, 1), index,
200 lustre_cfg_string(lcfg, 2));
201 cfs_set_bit(index, fsdb->fsdb_ost_index_map);
204 /* Figure out mdt indicies */
205 /* attach 0:MDC_uml1_mdsA_MNT_client 1:mdc 2:1d834_MNT_client_03f */
206 if ((lcfg->lcfg_command == LCFG_ATTACH) &&
207 (strcmp(lustre_cfg_string(lcfg, 1), LUSTRE_MDC_NAME) == 0)) {
208 rc = server_name2index(lustre_cfg_string(lcfg, 0),
210 if (rc != LDD_F_SV_TYPE_MDT) {
211 CWARN("Unparsable MDC name %s, assuming index 0\n",
212 lustre_cfg_string(lcfg, 0));
216 CDEBUG(D_MGS, "MDT index is %u\n", index);
217 cfs_set_bit(index, fsdb->fsdb_mdt_index_map);
218 fsdb->fsdb_mdt_count ++;
222 * figure out the old config. fsdb_gen = 0 means old log
223 * It is obsoleted and not supported anymore
225 if (fsdb->fsdb_gen == 0) {
226 CERROR("Old config format is not supported\n");
231 * compat to 1.8, check osc name used by MDT0 to OSTs, bz18548.
233 if (!cfs_test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags) &&
234 lcfg->lcfg_command == LCFG_ATTACH &&
235 strcmp(lustre_cfg_string(lcfg, 1), LUSTRE_OSC_NAME) == 0) {
236 if (OBD_OCD_VERSION_MAJOR(d->ver) == 1 &&
237 OBD_OCD_VERSION_MINOR(d->ver) <= 8) {
238 CWARN("MDT using 1.8 OSC name scheme\n");
239 cfs_set_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags);
243 if (lcfg->lcfg_command == LCFG_MARKER) {
244 struct cfg_marker *marker;
245 marker = lustre_cfg_buf(lcfg, 1);
247 d->ver = marker->cm_vers;
249 /* Keep track of the latest marker step */
250 fsdb->fsdb_gen = max(fsdb->fsdb_gen, marker->cm_step);
256 /* fsdb->fsdb_mutex is already held in mgs_find_or_make_fsdb*/
257 static int mgs_get_fsdb_from_llog(const struct lu_env *env,
258 struct mgs_device *mgs,
262 struct llog_handle *loghandle;
263 struct llog_ctxt *ctxt;
264 struct mgs_fsdb_handler_data d = { fsdb, 0 };
269 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
270 LASSERT(ctxt != NULL);
271 rc = name_create(&logname, fsdb->fsdb_name, "-client");
274 cfs_mutex_lock(&fsdb->fsdb_mutex);
275 rc = llog_open_create(env, ctxt, &loghandle, NULL, logname);
279 rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL);
283 if (llog_get_size(loghandle) <= 1)
284 cfs_set_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags);
286 rc = llog_process(env, loghandle, mgs_fsdb_handler, (void *)&d, NULL);
287 CDEBUG(D_INFO, "get_db = %d\n", rc);
289 llog_close(env, loghandle);
291 cfs_mutex_unlock(&fsdb->fsdb_mutex);
292 name_destroy(&logname);
299 static void mgs_free_fsdb_srpc(struct fs_db *fsdb)
301 struct mgs_tgt_srpc_conf *tgtconf;
303 /* free target-specific rules */
304 while (fsdb->fsdb_srpc_tgt) {
305 tgtconf = fsdb->fsdb_srpc_tgt;
306 fsdb->fsdb_srpc_tgt = tgtconf->mtsc_next;
308 LASSERT(tgtconf->mtsc_tgt);
310 sptlrpc_rule_set_free(&tgtconf->mtsc_rset);
311 OBD_FREE(tgtconf->mtsc_tgt, strlen(tgtconf->mtsc_tgt) + 1);
312 OBD_FREE_PTR(tgtconf);
315 /* free general rules */
316 sptlrpc_rule_set_free(&fsdb->fsdb_srpc_gen);
319 struct fs_db *mgs_find_fsdb(struct mgs_device *mgs, char *fsname)
324 cfs_list_for_each(tmp, &mgs->mgs_fs_db_list) {
325 fsdb = cfs_list_entry(tmp, struct fs_db, fsdb_list);
326 if (strcmp(fsdb->fsdb_name, fsname) == 0)
332 /* caller must hold the mgs->mgs_fs_db_lock */
333 static struct fs_db *mgs_new_fsdb(const struct lu_env *env,
334 struct mgs_device *mgs, char *fsname)
340 if (strlen(fsname) >= sizeof(fsdb->fsdb_name)) {
341 CERROR("fsname %s is too long\n", fsname);
349 strcpy(fsdb->fsdb_name, fsname);
350 cfs_mutex_init(&fsdb->fsdb_mutex);
351 cfs_set_bit(FSDB_UDESC, &fsdb->fsdb_flags);
354 if (strcmp(fsname, MGSSELF_NAME) == 0) {
355 cfs_set_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags);
357 OBD_ALLOC(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
358 OBD_ALLOC(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
359 if (!fsdb->fsdb_ost_index_map || !fsdb->fsdb_mdt_index_map) {
360 CERROR("No memory for index maps\n");
361 GOTO(err, rc = -ENOMEM);
364 rc = name_create(&fsdb->fsdb_clilov, fsname, "-clilov");
367 rc = name_create(&fsdb->fsdb_clilmv, fsname, "-clilmv");
371 /* initialise data for NID table */
372 mgs_ir_init_fs(env, mgs, fsdb);
374 lproc_mgs_add_live(mgs, fsdb);
377 cfs_list_add(&fsdb->fsdb_list, &mgs->mgs_fs_db_list);
381 if (fsdb->fsdb_ost_index_map)
382 OBD_FREE(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
383 if (fsdb->fsdb_mdt_index_map)
384 OBD_FREE(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
385 name_destroy(&fsdb->fsdb_clilov);
386 name_destroy(&fsdb->fsdb_clilmv);
391 static void mgs_free_fsdb(struct mgs_device *mgs, struct fs_db *fsdb)
393 /* wait for anyone with the sem */
394 cfs_mutex_lock(&fsdb->fsdb_mutex);
395 lproc_mgs_del_live(mgs, fsdb);
396 cfs_list_del(&fsdb->fsdb_list);
398 /* deinitialize fsr */
399 mgs_ir_fini_fs(mgs, fsdb);
401 if (fsdb->fsdb_ost_index_map)
402 OBD_FREE(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
403 if (fsdb->fsdb_mdt_index_map)
404 OBD_FREE(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
405 name_destroy(&fsdb->fsdb_clilov);
406 name_destroy(&fsdb->fsdb_clilmv);
407 mgs_free_fsdb_srpc(fsdb);
408 cfs_mutex_unlock(&fsdb->fsdb_mutex);
412 int mgs_init_fsdb_list(struct mgs_device *mgs)
414 CFS_INIT_LIST_HEAD(&mgs->mgs_fs_db_list);
418 int mgs_cleanup_fsdb_list(struct mgs_device *mgs)
421 cfs_list_t *tmp, *tmp2;
422 cfs_mutex_lock(&mgs->mgs_mutex);
423 cfs_list_for_each_safe(tmp, tmp2, &mgs->mgs_fs_db_list) {
424 fsdb = cfs_list_entry(tmp, struct fs_db, fsdb_list);
425 mgs_free_fsdb(mgs, fsdb);
427 cfs_mutex_unlock(&mgs->mgs_mutex);
431 int mgs_find_or_make_fsdb(const struct lu_env *env,
432 struct mgs_device *mgs, char *name,
438 cfs_mutex_lock(&mgs->mgs_mutex);
439 fsdb = mgs_find_fsdb(mgs, name);
441 cfs_mutex_unlock(&mgs->mgs_mutex);
446 CDEBUG(D_MGS, "Creating new db\n");
447 fsdb = mgs_new_fsdb(env, mgs, name);
448 cfs_mutex_unlock(&mgs->mgs_mutex);
452 if (!cfs_test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
453 /* populate the db from the client llog */
454 rc = mgs_get_fsdb_from_llog(env, mgs, fsdb);
456 CERROR("Can't get db from client log %d\n", rc);
457 mgs_free_fsdb(mgs, fsdb);
462 /* populate srpc rules from params llog */
463 rc = mgs_get_fsdb_srpc_from_llog(env, mgs, fsdb);
465 CERROR("Can't get db from params log %d\n", rc);
466 mgs_free_fsdb(mgs, fsdb);
477 -1= empty client log */
478 int mgs_check_index(const struct lu_env *env,
479 struct mgs_device *mgs,
480 struct mgs_target_info *mti)
487 LASSERT(!(mti->mti_flags & LDD_F_NEED_INDEX));
489 rc = mgs_find_or_make_fsdb(env, mgs, mti->mti_fsname, &fsdb);
491 CERROR("Can't get db for %s\n", mti->mti_fsname);
495 if (cfs_test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags))
498 if (mti->mti_flags & LDD_F_SV_TYPE_OST)
499 imap = fsdb->fsdb_ost_index_map;
500 else if (mti->mti_flags & LDD_F_SV_TYPE_MDT)
501 imap = fsdb->fsdb_mdt_index_map;
505 if (cfs_test_bit(mti->mti_stripe_index, imap))
510 static __inline__ int next_index(void *index_map, int map_len)
513 for (i = 0; i < map_len * 8; i++)
514 if (!cfs_test_bit(i, index_map)) {
517 CERROR("max index %d exceeded.\n", i);
522 0 newly marked as in use
524 +EALREADY for update of an old index */
525 static int mgs_set_index(const struct lu_env *env,
526 struct mgs_device *mgs,
527 struct mgs_target_info *mti)
534 rc = mgs_find_or_make_fsdb(env, mgs, mti->mti_fsname, &fsdb);
536 CERROR("Can't get db for %s\n", mti->mti_fsname);
540 if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
541 imap = fsdb->fsdb_ost_index_map;
542 } else if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
543 imap = fsdb->fsdb_mdt_index_map;
544 if (fsdb->fsdb_mdt_count >= MAX_MDT_COUNT) {
545 LCONSOLE_ERROR_MSG(0x13f, "The max mdt count"
546 "is %d\n", (int)MAX_MDT_COUNT);
553 if (mti->mti_flags & LDD_F_NEED_INDEX) {
554 rc = next_index(imap, INDEX_MAP_SIZE);
557 mti->mti_stripe_index = rc;
558 if (mti->mti_flags & LDD_F_SV_TYPE_MDT)
559 fsdb->fsdb_mdt_count ++;
562 if (mti->mti_stripe_index >= INDEX_MAP_SIZE * 8) {
563 LCONSOLE_ERROR_MSG(0x13f, "Server %s requested index %d, "
564 "but the max index is %d.\n",
565 mti->mti_svname, mti->mti_stripe_index,
570 if (cfs_test_bit(mti->mti_stripe_index, imap)) {
571 if ((mti->mti_flags & LDD_F_VIRGIN) &&
572 !(mti->mti_flags & LDD_F_WRITECONF)) {
573 LCONSOLE_ERROR_MSG(0x140, "Server %s requested index "
574 "%d, but that index is already in "
575 "use. Use --writeconf to force\n",
577 mti->mti_stripe_index);
580 CDEBUG(D_MGS, "Server %s updating index %d\n",
581 mti->mti_svname, mti->mti_stripe_index);
586 cfs_set_bit(mti->mti_stripe_index, imap);
587 cfs_clear_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags);
588 server_make_name(mti->mti_flags & ~(LDD_F_VIRGIN | LDD_F_WRITECONF),
589 mti->mti_stripe_index, 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(const struct lu_env *env,
603 struct llog_handle *llh,
604 struct llog_rec_hdr *rec, void *data)
606 struct mgs_modify_lookup *mml = data;
607 struct cfg_marker *marker;
608 struct lustre_cfg *lcfg = (struct lustre_cfg *)(rec + 1);
609 int cfg_len = rec->lrh_len - sizeof(struct llog_rec_hdr) -
610 sizeof(struct llog_rec_tail);
614 if (rec->lrh_type != OBD_CFG_REC) {
615 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
619 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
621 CERROR("Insane cfg\n");
625 /* We only care about markers */
626 if (lcfg->lcfg_command != LCFG_MARKER)
629 marker = lustre_cfg_buf(lcfg, 1);
630 if ((strcmp(mml->mml_marker.cm_comment, marker->cm_comment) == 0) &&
631 (strcmp(mml->mml_marker.cm_tgtname, marker->cm_tgtname) == 0) &&
632 !(marker->cm_flags & CM_SKIP)) {
633 /* Found a non-skipped marker match */
634 CDEBUG(D_MGS, "Changing rec %u marker %d %x->%x: %s %s\n",
635 rec->lrh_index, marker->cm_step,
636 marker->cm_flags, mml->mml_marker.cm_flags,
637 marker->cm_tgtname, marker->cm_comment);
638 /* Overwrite the old marker llog entry */
639 marker->cm_flags &= ~CM_EXCLUDE; /* in case we're unexcluding */
640 marker->cm_flags |= mml->mml_marker.cm_flags;
641 marker->cm_canceltime = mml->mml_marker.cm_canceltime;
642 /* Header and tail are added back to lrh_len in
643 llog_lvfs_write_rec */
644 rec->lrh_len = cfg_len;
645 rc = llog_write(env, llh, rec, NULL, 0, (void *)lcfg,
655 * Modify an existing config log record (for CM_SKIP or CM_EXCLUDE)
657 * 0 - modified successfully,
658 * 1 - no modification was done
661 static int mgs_modify(const struct lu_env *env, struct mgs_device *mgs,
662 struct fs_db *fsdb, struct mgs_target_info *mti,
663 char *logname, char *devname, char *comment, int flags)
665 struct llog_handle *loghandle;
666 struct llog_ctxt *ctxt;
667 struct mgs_modify_lookup *mml;
672 LASSERT(cfs_mutex_is_locked(&fsdb->fsdb_mutex));
673 CDEBUG(D_MGS, "modify %s/%s/%s fl=%x\n", logname, devname, comment,
676 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
677 LASSERT(ctxt != NULL);
678 rc = llog_open(env, ctxt, &loghandle, NULL, logname, LLOG_OPEN_EXISTS);
685 rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL);
689 if (llog_get_size(loghandle) <= 1)
690 GOTO(out_close, rc = 0);
694 GOTO(out_close, rc = -ENOMEM);
695 strcpy(mml->mml_marker.cm_comment, comment);
696 strcpy(mml->mml_marker.cm_tgtname, devname);
697 /* Modify mostly means cancel */
698 mml->mml_marker.cm_flags = flags;
699 mml->mml_marker.cm_canceltime = flags ? cfs_time_current_sec() : 0;
700 mml->mml_modified = 0;
701 rc = llog_process(env, loghandle, mgs_modify_handler, (void *)mml,
703 if (!rc && !mml->mml_modified)
708 llog_close(env, loghandle);
711 CERROR("%s: modify %s/%s failed: rc = %d\n",
712 mgs->mgs_obd->obd_name, mti->mti_svname, comment, rc);
717 /******************** config log recording functions *********************/
719 static int record_lcfg(const struct lu_env *env, struct llog_handle *llh,
720 struct lustre_cfg *lcfg)
722 struct llog_rec_hdr rec;
728 LASSERT(llh->lgh_ctxt);
730 buflen = lustre_cfg_len(lcfg->lcfg_bufcount,
732 rec.lrh_len = llog_data_len(buflen);
733 rec.lrh_type = OBD_CFG_REC;
735 /* idx = -1 means append */
736 rc = llog_write(env, llh, &rec, NULL, 0, (void *)lcfg, -1);
738 CERROR("failed %d\n", rc);
742 static int record_base(const struct lu_env *env, struct llog_handle *llh,
743 char *cfgname, lnet_nid_t nid, int cmd,
744 char *s1, char *s2, char *s3, char *s4)
746 struct mgs_thread_info *mgi = mgs_env_info(env);
747 struct lustre_cfg *lcfg;
750 CDEBUG(D_MGS, "lcfg %s %#x %s %s %s %s\n", cfgname,
751 cmd, s1, s2, s3, s4);
753 lustre_cfg_bufs_reset(&mgi->mgi_bufs, cfgname);
755 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, s1);
757 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 2, s2);
759 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 3, s3);
761 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 4, s4);
763 lcfg = lustre_cfg_new(cmd, &mgi->mgi_bufs);
766 lcfg->lcfg_nid = nid;
768 rc = record_lcfg(env, llh, lcfg);
770 lustre_cfg_free(lcfg);
773 CERROR("error %d: lcfg %s %#x %s %s %s %s\n", rc, cfgname,
774 cmd, s1, s2, s3, s4);
780 static inline int record_add_uuid(const struct lu_env *env,
781 struct llog_handle *llh,
782 uint64_t nid, char *uuid)
784 return record_base(env, llh, NULL, nid, LCFG_ADD_UUID, uuid, 0, 0, 0);
788 static inline int record_add_conn(const struct lu_env *env,
789 struct llog_handle *llh,
790 char *devname, char *uuid)
792 return record_base(env, llh, devname, 0, LCFG_ADD_CONN, uuid, 0, 0, 0);
795 static inline int record_attach(const struct lu_env *env,
796 struct llog_handle *llh, char *devname,
797 char *type, char *uuid)
799 return record_base(env, llh,devname, 0, LCFG_ATTACH, type, uuid, 0, 0);
802 static inline int record_setup(const struct lu_env *env,
803 struct llog_handle *llh, char *devname,
804 char *s1, char *s2, char *s3, char *s4)
806 return record_base(env, llh, devname, 0, LCFG_SETUP, s1, s2, s3, s4);
809 static int record_lov_setup(const struct lu_env *env, struct llog_handle *llh,
810 char *devname, struct lov_desc *desc)
812 struct mgs_thread_info *mgi = mgs_env_info(env);
813 struct lustre_cfg *lcfg;
816 lustre_cfg_bufs_reset(&mgi->mgi_bufs, devname);
817 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, desc, sizeof(*desc));
818 lcfg = lustre_cfg_new(LCFG_SETUP, &mgi->mgi_bufs);
821 rc = record_lcfg(env, llh, lcfg);
823 lustre_cfg_free(lcfg);
827 static int record_lmv_setup(const struct lu_env *env, struct llog_handle *llh,
828 char *devname, struct lmv_desc *desc)
830 struct mgs_thread_info *mgi = mgs_env_info(env);
831 struct lustre_cfg *lcfg;
834 lustre_cfg_bufs_reset(&mgi->mgi_bufs, devname);
835 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, desc, sizeof(*desc));
836 lcfg = lustre_cfg_new(LCFG_SETUP, &mgi->mgi_bufs);
838 rc = record_lcfg(env, llh, lcfg);
840 lustre_cfg_free(lcfg);
844 static inline int record_mdc_add(const struct lu_env *env,
845 struct llog_handle *llh,
846 char *logname, char *mdcuuid,
847 char *mdtuuid, char *index,
850 return record_base(env,llh,logname,0,LCFG_ADD_MDC,
851 mdtuuid,index,gen,mdcuuid);
854 static inline int record_lov_add(const struct lu_env *env,
855 struct llog_handle *llh,
856 char *lov_name, char *ost_uuid,
857 char *index, char *gen)
859 return record_base(env,llh,lov_name,0,LCFG_LOV_ADD_OBD,
860 ost_uuid,index,gen,0);
863 static inline int record_mount_opt(const struct lu_env *env,
864 struct llog_handle *llh,
865 char *profile, char *lov_name,
868 return record_base(env,llh,NULL,0,LCFG_MOUNTOPT,
869 profile,lov_name,mdc_name,0);
872 static int record_marker(const struct lu_env *env,
873 struct llog_handle *llh,
874 struct fs_db *fsdb, __u32 flags,
875 char *tgtname, char *comment)
877 struct mgs_thread_info *mgi = mgs_env_info(env);
878 struct lustre_cfg *lcfg;
881 if (flags & CM_START)
883 mgi->mgi_marker.cm_step = fsdb->fsdb_gen;
884 mgi->mgi_marker.cm_flags = flags;
885 mgi->mgi_marker.cm_vers = LUSTRE_VERSION_CODE;
886 strncpy(mgi->mgi_marker.cm_tgtname, tgtname,
887 sizeof(mgi->mgi_marker.cm_tgtname));
888 strncpy(mgi->mgi_marker.cm_comment, comment,
889 sizeof(mgi->mgi_marker.cm_comment));
890 mgi->mgi_marker.cm_createtime = cfs_time_current_sec();
891 mgi->mgi_marker.cm_canceltime = 0;
892 lustre_cfg_bufs_reset(&mgi->mgi_bufs, NULL);
893 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, &mgi->mgi_marker,
894 sizeof(mgi->mgi_marker));
895 lcfg = lustre_cfg_new(LCFG_MARKER, &mgi->mgi_bufs);
898 rc = record_lcfg(env, llh, lcfg);
900 lustre_cfg_free(lcfg);
904 static int record_start_log(const struct lu_env *env, struct mgs_device *mgs,
905 struct llog_handle **llh, char *name)
907 static struct obd_uuid cfg_uuid = { .uuid = "config_uuid" };
908 struct llog_ctxt *ctxt;
912 GOTO(out, rc = -EBUSY);
914 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
916 GOTO(out, rc = -ENODEV);
917 LASSERT(ctxt->loc_obd == mgs->mgs_obd);
919 rc = llog_open_create(env, ctxt, llh, NULL, name);
922 rc = llog_init_handle(env, *llh, LLOG_F_IS_PLAIN, &cfg_uuid);
924 llog_close(env, *llh);
929 CERROR("%s: can't start log %s: rc = %d\n",
930 mgs->mgs_obd->obd_name, name, rc);
936 static int record_end_log(const struct lu_env *env, struct llog_handle **llh)
940 rc = llog_close(env, *llh);
946 static int mgs_log_is_empty(const struct lu_env *env,
947 struct mgs_device *mgs, char *name)
949 struct llog_handle *llh;
950 struct llog_ctxt *ctxt;
953 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
954 LASSERT(ctxt != NULL);
955 rc = llog_open(env, ctxt, &llh, NULL, name, LLOG_OPEN_EXISTS);
962 llog_init_handle(env, llh, LLOG_F_IS_PLAIN, NULL);
965 rc = llog_get_size(llh);
968 llog_close(env, llh);
971 /* header is record 1 */
975 /******************** config "macros" *********************/
977 /* write an lcfg directly into a log (with markers) */
978 static int mgs_write_log_direct(const struct lu_env *env,
979 struct mgs_device *mgs, struct fs_db *fsdb,
980 char *logname, struct lustre_cfg *lcfg,
981 char *devname, char *comment)
983 struct llog_handle *llh = NULL;
990 rc = record_start_log(env, mgs, &llh, logname);
994 /* FIXME These should be a single journal transaction */
995 rc = record_marker(env, llh, fsdb, CM_START, devname, comment);
998 rc = record_lcfg(env, llh, lcfg);
1001 rc = record_marker(env, llh, fsdb, CM_END, devname, comment);
1005 record_end_log(env, &llh);
1009 /* write the lcfg in all logs for the given fs */
1010 int mgs_write_log_direct_all(const struct lu_env *env,
1011 struct mgs_device *mgs,
1013 struct mgs_target_info *mti,
1014 struct lustre_cfg *lcfg,
1015 char *devname, char *comment,
1019 struct mgs_direntry *dirent, *n;
1020 char *fsname = mti->mti_fsname;
1022 int rc = 0, len = strlen(fsname);
1025 /* We need to set params for any future logs
1026 as well. FIXME Append this file to every new log.
1027 Actually, we should store as params (text), not llogs. Or
1029 rc = name_create(&logname, fsname, "-params");
1032 if (mgs_log_is_empty(env, mgs, logname)) {
1033 struct llog_handle *llh = NULL;
1034 rc = record_start_log(env, mgs, &llh, logname);
1035 record_end_log(env, &llh);
1037 name_destroy(&logname);
1041 /* Find all the logs in the CONFIGS directory */
1042 rc = class_dentry_readdir(env, mgs, &list);
1046 /* Could use fsdb index maps instead of directory listing */
1047 cfs_list_for_each_entry_safe(dirent, n, &list, list) {
1048 cfs_list_del(&dirent->list);
1049 /* don't write to sptlrpc rule log */
1050 if (strstr(dirent->name, "-sptlrpc") != NULL)
1053 /* caller wants write server logs only */
1054 if (server_only && strstr(dirent->name, "-client") != NULL)
1057 if (strncmp(fsname, dirent->name, len) == 0) {
1058 CDEBUG(D_MGS, "Changing log %s\n", dirent->name);
1059 /* Erase any old settings of this same parameter */
1060 rc = mgs_modify(env, mgs, fsdb, mti, dirent->name,
1061 devname, comment, CM_SKIP);
1063 CERROR("%s: Can't modify llog %s: rc = %d\n",
1064 mgs->mgs_obd->obd_name, dirent->name,rc);
1065 /* Write the new one */
1067 rc = mgs_write_log_direct(env, mgs, fsdb,
1072 CERROR("%s: writing log %s: rc = %d\n",
1073 mgs->mgs_obd->obd_name,
1078 mgs_direntry_free(dirent);
1084 static int mgs_write_log_mdc_to_mdt(const struct lu_env *env,
1085 struct mgs_device *mgs,
1087 struct mgs_target_info *mti,
1089 static int mgs_write_log_osc_to_lov(const struct lu_env *env,
1090 struct mgs_device *mgs,
1092 struct mgs_target_info *mti,
1093 char *logname, char *suffix, char *lovname,
1094 enum lustre_sec_part sec_part, int flags);
1095 static int name_create_mdt_and_lov(char **logname, char **lovname,
1096 struct fs_db *fsdb, int i);
1098 static int mgs_steal_llog_handler(const struct lu_env *env,
1099 struct llog_handle *llh,
1100 struct llog_rec_hdr *rec, void *data)
1102 struct mgs_device *mgs;
1103 struct obd_device *obd;
1104 struct mgs_target_info *mti, *tmti;
1106 int cfg_len = rec->lrh_len;
1107 char *cfg_buf = (char*) (rec + 1);
1108 struct lustre_cfg *lcfg;
1110 struct llog_handle *mdt_llh = NULL;
1111 static int got_an_osc_or_mdc = 0;
1112 /* 0: not found any osc/mdc;
1116 static int last_step = -1;
1120 mti = ((struct temp_comp*)data)->comp_mti;
1121 tmti = ((struct temp_comp*)data)->comp_tmti;
1122 fsdb = ((struct temp_comp*)data)->comp_fsdb;
1123 obd = ((struct temp_comp *)data)->comp_obd;
1124 mgs = lu2mgs_dev(obd->obd_lu_dev);
1127 if (rec->lrh_type != OBD_CFG_REC) {
1128 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
1132 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
1134 CERROR("Insane cfg\n");
1138 lcfg = (struct lustre_cfg *)cfg_buf;
1140 if (lcfg->lcfg_command == LCFG_MARKER) {
1141 struct cfg_marker *marker;
1142 marker = lustre_cfg_buf(lcfg, 1);
1143 if (!strncmp(marker->cm_comment,"add osc",7) &&
1144 (marker->cm_flags & CM_START)){
1145 got_an_osc_or_mdc = 1;
1146 strncpy(tmti->mti_svname, marker->cm_tgtname,
1147 sizeof(tmti->mti_svname));
1148 rc = record_start_log(env, mgs, &mdt_llh,
1152 rc = record_marker(env, mdt_llh, fsdb, CM_START,
1153 mti->mti_svname,"add osc(copied)");
1154 record_end_log(env, &mdt_llh);
1155 last_step = marker->cm_step;
1158 if (!strncmp(marker->cm_comment,"add osc",7) &&
1159 (marker->cm_flags & CM_END)){
1160 LASSERT(last_step == marker->cm_step);
1162 got_an_osc_or_mdc = 0;
1163 rc = record_start_log(env, mgs, &mdt_llh,
1167 rc = record_marker(env, mdt_llh, fsdb, CM_END,
1168 mti->mti_svname,"add osc(copied)");
1169 record_end_log(env, &mdt_llh);
1172 if (!strncmp(marker->cm_comment,"add mdc",7) &&
1173 (marker->cm_flags & CM_START)){
1174 got_an_osc_or_mdc = 2;
1175 last_step = marker->cm_step;
1176 memcpy(tmti->mti_svname, marker->cm_tgtname,
1177 strlen(marker->cm_tgtname));
1181 if (!strncmp(marker->cm_comment,"add mdc",7) &&
1182 (marker->cm_flags & CM_END)){
1183 LASSERT(last_step == marker->cm_step);
1185 got_an_osc_or_mdc = 0;
1190 if (got_an_osc_or_mdc == 0 || last_step < 0)
1193 if (lcfg->lcfg_command == LCFG_ADD_UUID) {
1195 nodenid = lcfg->lcfg_nid;
1197 tmti->mti_nids[tmti->mti_nid_count] = nodenid;
1198 tmti->mti_nid_count++;
1203 if (lcfg->lcfg_command == LCFG_SETUP) {
1206 target = lustre_cfg_string(lcfg, 1);
1207 memcpy(tmti->mti_uuid, target, strlen(target));
1211 /* ignore client side sptlrpc_conf_log */
1212 if (lcfg->lcfg_command == LCFG_SPTLRPC_CONF)
1215 if (lcfg->lcfg_command == LCFG_ADD_MDC) {
1218 if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1)
1221 memcpy(tmti->mti_fsname, mti->mti_fsname,
1222 strlen(mti->mti_fsname));
1223 tmti->mti_stripe_index = index;
1225 rc = mgs_write_log_mdc_to_mdt(env, mgs, fsdb, tmti,
1227 memset(tmti, 0, sizeof(*tmti));
1231 if (lcfg->lcfg_command == LCFG_LOV_ADD_OBD) {
1234 char *logname, *lovname;
1236 rc = name_create_mdt_and_lov(&logname, &lovname, fsdb,
1237 mti->mti_stripe_index);
1240 sprintf(mdt_index, "-MDT%04x", mti->mti_stripe_index);
1242 if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1) {
1243 name_destroy(&logname);
1244 name_destroy(&lovname);
1248 tmti->mti_stripe_index = index;
1249 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, tmti, logname,
1252 name_destroy(&logname);
1253 name_destroy(&lovname);
1259 /* fsdb->fsdb_mutex is already held in mgs_write_log_target*/
1260 /* stealed from mgs_get_fsdb_from_llog*/
1261 static int mgs_steal_llog_for_mdt_from_client(const struct lu_env *env,
1262 struct mgs_device *mgs,
1264 struct temp_comp* comp)
1266 struct llog_handle *loghandle;
1267 struct mgs_target_info *tmti;
1268 struct llog_ctxt *ctxt;
1273 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
1274 LASSERT(ctxt != NULL);
1276 OBD_ALLOC_PTR(tmti);
1278 GOTO(out_ctxt, rc = -ENOMEM);
1280 comp->comp_tmti = tmti;
1281 comp->comp_obd = mgs->mgs_obd;
1283 rc = llog_open(env, ctxt, &loghandle, NULL, client_name,
1291 rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL);
1293 GOTO(out_close, rc);
1295 rc = llog_process_or_fork(env, loghandle, mgs_steal_llog_handler,
1296 (void *)comp, NULL, false);
1297 CDEBUG(D_MGS, "steal llog re = %d\n", rc);
1299 llog_close(env, loghandle);
1303 llog_ctxt_put(ctxt);
1307 /* lmv is the second thing for client logs */
1308 /* copied from mgs_write_log_lov. Please refer to that. */
1309 static int mgs_write_log_lmv(const struct lu_env *env,
1310 struct mgs_device *mgs,
1312 struct mgs_target_info *mti,
1313 char *logname, char *lmvname)
1315 struct llog_handle *llh = NULL;
1316 struct lmv_desc *lmvdesc;
1321 CDEBUG(D_MGS, "Writing lmv(%s) log for %s\n", lmvname,logname);
1323 OBD_ALLOC_PTR(lmvdesc);
1324 if (lmvdesc == NULL)
1326 lmvdesc->ld_active_tgt_count = 0;
1327 lmvdesc->ld_tgt_count = 0;
1328 sprintf((char*)lmvdesc->ld_uuid.uuid, "%s_UUID", lmvname);
1329 uuid = (char *)lmvdesc->ld_uuid.uuid;
1331 rc = record_start_log(env, mgs, &llh, logname);
1334 rc = record_marker(env, llh, fsdb, CM_START, lmvname, "lmv setup");
1337 rc = record_attach(env, llh, lmvname, "lmv", uuid);
1340 rc = record_lmv_setup(env, llh, lmvname, lmvdesc);
1343 rc = record_marker(env, llh, fsdb, CM_END, lmvname, "lmv setup");
1347 record_end_log(env, &llh);
1349 OBD_FREE_PTR(lmvdesc);
1353 /* lov is the first thing in the mdt and client logs */
1354 static int mgs_write_log_lov(const struct lu_env *env, struct mgs_device *mgs,
1355 struct fs_db *fsdb, struct mgs_target_info *mti,
1356 char *logname, char *lovname)
1358 struct llog_handle *llh = NULL;
1359 struct lov_desc *lovdesc;
1364 CDEBUG(D_MGS, "Writing lov(%s) log for %s\n", lovname, logname);
1367 #01 L attach 0:lov_mdsA 1:lov 2:71ccb_lov_mdsA_19f961a9e1
1368 #02 L lov_setup 0:lov_mdsA 1:(struct lov_desc)
1369 uuid=lov1_UUID, stripe count=1, size=1048576, offset=0, pattern=0
1372 /* FIXME just make lov_setup accept empty desc (put uuid in buf 2) */
1373 OBD_ALLOC_PTR(lovdesc);
1374 if (lovdesc == NULL)
1376 lovdesc->ld_magic = LOV_DESC_MAGIC;
1377 lovdesc->ld_tgt_count = 0;
1378 /* Defaults. Can be changed later by lcfg config_param */
1379 lovdesc->ld_default_stripe_count = 1;
1380 lovdesc->ld_pattern = LOV_PATTERN_RAID0;
1381 lovdesc->ld_default_stripe_size = 1024 * 1024;
1382 lovdesc->ld_default_stripe_offset = -1;
1383 lovdesc->ld_qos_maxage = QOS_DEFAULT_MAXAGE;
1384 sprintf((char*)lovdesc->ld_uuid.uuid, "%s_UUID", lovname);
1385 /* can these be the same? */
1386 uuid = (char *)lovdesc->ld_uuid.uuid;
1388 /* This should always be the first entry in a log.
1389 rc = mgs_clear_log(obd, logname); */
1390 rc = record_start_log(env, mgs, &llh, logname);
1393 /* FIXME these should be a single journal transaction */
1394 rc = record_marker(env, llh, fsdb, CM_START, lovname, "lov setup");
1397 rc = record_attach(env, llh, lovname, "lov", uuid);
1400 rc = record_lov_setup(env, llh, lovname, lovdesc);
1403 rc = record_marker(env, llh, fsdb, CM_END, lovname, "lov setup");
1408 record_end_log(env, &llh);
1410 OBD_FREE_PTR(lovdesc);
1414 /* add failnids to open log */
1415 static int mgs_write_log_failnids(const struct lu_env *env,
1416 struct mgs_target_info *mti,
1417 struct llog_handle *llh,
1420 char *failnodeuuid = NULL;
1421 char *ptr = mti->mti_params;
1426 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) nal=90 0: 1:uml1_UUID
1427 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
1428 #05 L setup 0:OSC_uml1_ost1_mdsA 1:ost1_UUID 2:uml1_UUID
1429 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) nal=90 0: 1:uml2_UUID
1430 #0x L add_uuid nid=2@elan(0x1000000000002) nal=90 0: 1:uml2_UUID
1431 #07 L add_conn 0:OSC_uml1_ost1_mdsA 1:uml2_UUID
1434 /* Pull failnid info out of params string */
1435 while (class_find_param(ptr, PARAM_FAILNODE, &ptr) == 0) {
1436 while (class_parse_nid(ptr, &nid, &ptr) == 0) {
1437 if (failnodeuuid == NULL) {
1438 /* We don't know the failover node name,
1439 so just use the first nid as the uuid */
1440 rc = name_create(&failnodeuuid,
1441 libcfs_nid2str(nid), "");
1445 CDEBUG(D_MGS, "add nid %s for failover uuid %s, "
1446 "client %s\n", libcfs_nid2str(nid),
1447 failnodeuuid, cliname);
1448 rc = record_add_uuid(env, llh, nid, failnodeuuid);
1451 rc = record_add_conn(env, llh, cliname, failnodeuuid);
1454 name_destroy(&failnodeuuid);
1458 static int mgs_write_log_mdc_to_lmv(const struct lu_env *env,
1459 struct mgs_device *mgs,
1461 struct mgs_target_info *mti,
1462 char *logname, char *lmvname)
1464 struct llog_handle *llh = NULL;
1465 char *mdcname = NULL;
1466 char *nodeuuid = NULL;
1467 char *mdcuuid = NULL;
1468 char *lmvuuid = NULL;
1473 if (mgs_log_is_empty(env, mgs, logname)) {
1474 CERROR("log is empty! Logical error\n");
1478 CDEBUG(D_MGS, "adding mdc for %s to log %s:lmv(%s)\n",
1479 mti->mti_svname, logname, lmvname);
1481 rc = name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
1484 rc = name_create(&mdcname, mti->mti_svname, "-mdc");
1487 rc = name_create(&mdcuuid, mdcname, "_UUID");
1490 rc = name_create(&lmvuuid, lmvname, "_UUID");
1494 rc = record_start_log(env, mgs, &llh, logname);
1497 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
1501 for (i = 0; i < mti->mti_nid_count; i++) {
1502 CDEBUG(D_MGS, "add nid %s for mdt\n",
1503 libcfs_nid2str(mti->mti_nids[i]));
1505 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
1510 rc = record_attach(env, llh, mdcname, LUSTRE_MDC_NAME, lmvuuid);
1513 rc = record_setup(env, llh, mdcname, mti->mti_uuid, nodeuuid, 0, 0);
1516 rc = mgs_write_log_failnids(env, mti, llh, mdcname);
1519 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
1520 rc = record_mdc_add(env, llh, lmvname, mdcuuid, mti->mti_uuid,
1524 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname,
1529 record_end_log(env, &llh);
1531 name_destroy(&lmvuuid);
1532 name_destroy(&mdcuuid);
1533 name_destroy(&mdcname);
1534 name_destroy(&nodeuuid);
1538 /* add new mdc to already existent MDS */
1539 static int mgs_write_log_mdc_to_mdt(const struct lu_env *env,
1540 struct mgs_device *mgs,
1542 struct mgs_target_info *mti,
1545 struct llog_handle *llh = NULL;
1546 char *nodeuuid = NULL;
1547 char *mdcname = NULL;
1548 char *mdcuuid = NULL;
1549 char *mdtuuid = NULL;
1550 int idx = mti->mti_stripe_index;
1555 if (mgs_log_is_empty(env, mgs, logname)) {
1556 CERROR("log is empty! Logical error\n");
1560 CDEBUG(D_MGS, "adding mdc index %d to %s\n", idx, logname);
1562 rc = name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
1565 snprintf(index, sizeof(index), "-mdc%04x", idx);
1566 rc = name_create(&mdcname, logname, index);
1569 rc = name_create(&mdcuuid, mdcname, "_UUID");
1572 rc = name_create(&mdtuuid, logname, "_UUID");
1576 rc = record_start_log(env, mgs, &llh, logname);
1579 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname, "add mdc");
1582 for (i = 0; i < mti->mti_nid_count; i++) {
1583 CDEBUG(D_MGS, "add nid %s for mdt\n",
1584 libcfs_nid2str(mti->mti_nids[i]));
1585 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
1589 rc = record_attach(env, llh, mdcname, LUSTRE_MDC_NAME, mdcuuid);
1592 rc = record_setup(env, llh, mdcname, mti->mti_uuid, nodeuuid, 0, 0);
1595 rc = mgs_write_log_failnids(env, mti, llh, mdcname);
1598 snprintf(index, sizeof(index), "%d", idx);
1600 rc = record_mdc_add(env, llh, logname, mdcuuid, mti->mti_uuid,
1604 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname, "add mdc");
1608 record_end_log(env, &llh);
1610 name_destroy(&mdtuuid);
1611 name_destroy(&mdcuuid);
1612 name_destroy(&mdcname);
1613 name_destroy(&nodeuuid);
1617 static int mgs_write_log_mdt0(const struct lu_env *env,
1618 struct mgs_device *mgs,
1620 struct mgs_target_info *mti)
1622 char *log = mti->mti_svname;
1623 struct llog_handle *llh = NULL;
1624 char *uuid, *lovname;
1626 char *ptr = mti->mti_params;
1627 int rc = 0, failout = 0;
1630 OBD_ALLOC(uuid, sizeof(struct obd_uuid));
1634 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
1635 failout = (strncmp(ptr, "failout", 7) == 0);
1637 rc = name_create(&lovname, log, "-mdtlov");
1640 if (mgs_log_is_empty(env, mgs, log)) {
1641 rc = mgs_write_log_lov(env, mgs, fsdb, mti, log, lovname);
1646 sprintf(mdt_index, "%d", mti->mti_stripe_index);
1648 rc = record_start_log(env, mgs, &llh, log);
1652 /* add MDT itself */
1654 /* FIXME this whole fn should be a single journal transaction */
1655 sprintf(uuid, "%s_UUID", log);
1656 rc = record_marker(env, llh, fsdb, CM_START, log, "add mdt");
1659 rc = record_attach(env, llh, log, LUSTRE_MDT_NAME, uuid);
1662 rc = record_mount_opt(env, llh, log, lovname, NULL);
1665 rc = record_setup(env, llh, log, uuid, mdt_index, lovname,
1666 failout ? "n" : "f");
1669 rc = record_marker(env, llh, fsdb, CM_END, log, "add mdt");
1673 record_end_log(env, &llh);
1675 name_destroy(&lovname);
1677 OBD_FREE(uuid, sizeof(struct obd_uuid));
1681 static inline int name_create_mdt(char **logname, char *fsname, int i)
1685 sprintf(mdt_index, "-MDT%04x", i);
1686 return name_create(logname, fsname, mdt_index);
1689 static int name_create_mdt_and_lov(char **logname, char **lovname,
1690 struct fs_db *fsdb, int i)
1694 rc = name_create_mdt(logname, fsdb->fsdb_name, i);
1698 if (i == 0 && cfs_test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
1699 rc = name_create(lovname, fsdb->fsdb_name, "-mdtlov");
1701 rc = name_create(lovname, *logname, "-mdtlov");
1703 name_destroy(logname);
1709 static inline int name_create_mdt_osc(char **oscname, char *ostname,
1710 struct fs_db *fsdb, int i)
1714 if (i == 0 && cfs_test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
1715 sprintf(suffix, "-osc");
1717 sprintf(suffix, "-osc-MDT%04x", i);
1718 return name_create(oscname, ostname, suffix);
1721 /* envelope method for all layers log */
1722 static int mgs_write_log_mdt(const struct lu_env *env,
1723 struct mgs_device *mgs,
1725 struct mgs_target_info *mti)
1727 struct mgs_thread_info *mgi = mgs_env_info(env);
1728 struct llog_handle *llh = NULL;
1733 CDEBUG(D_MGS, "writing new mdt %s\n", mti->mti_svname);
1735 if (mti->mti_uuid[0] == '\0') {
1736 /* Make up our own uuid */
1737 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
1738 "%s_UUID", mti->mti_svname);
1742 rc = mgs_write_log_mdt0(env, mgs, fsdb, mti);
1745 /* Append the mdt info to the client log */
1746 rc = name_create(&cliname, mti->mti_fsname, "-client");
1750 if (mgs_log_is_empty(env, mgs, cliname)) {
1751 /* Start client log */
1752 rc = mgs_write_log_lov(env, mgs, fsdb, mti, cliname,
1756 rc = mgs_write_log_lmv(env, mgs, fsdb, mti, cliname,
1763 #09 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
1764 #10 L attach 0:MDC_uml1_mdsA_MNT_client 1:mdc 2:1d834_MNT_client_03f
1765 #11 L setup 0:MDC_uml1_mdsA_MNT_client 1:mdsA_UUID 2:uml1_UUID
1766 #12 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
1767 #13 L add_conn 0:MDC_uml1_mdsA_MNT_client 1:uml2_UUID
1768 #14 L mount_option 0: 1:client 2:lov1 3:MDC_uml1_mdsA_MNT_client
1771 /* copy client info about lov/lmv */
1772 mgi->mgi_comp.comp_mti = mti;
1773 mgi->mgi_comp.comp_fsdb = fsdb;
1775 rc = mgs_steal_llog_for_mdt_from_client(env, mgs, cliname,
1779 rc = mgs_write_log_mdc_to_lmv(env, mgs, fsdb, mti, cliname,
1785 rc = record_start_log(env, mgs, &llh, cliname);
1789 rc = record_marker(env, llh, fsdb, CM_START, cliname,
1793 rc = record_mount_opt(env, llh, cliname, fsdb->fsdb_clilov,
1797 rc = record_marker(env, llh, fsdb, CM_END, cliname,
1802 /* for_all_existing_mdt except current one */
1803 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
1805 if (i != mti->mti_stripe_index &&
1806 cfs_test_bit(i, fsdb->fsdb_mdt_index_map)) {
1807 rc = name_create_mdt(&mdtname, mti->mti_fsname, i);
1810 rc = mgs_write_log_mdc_to_mdt(env, mgs, fsdb, mti, mdtname);
1811 name_destroy(&mdtname);
1817 record_end_log(env, &llh);
1819 name_destroy(&cliname);
1823 /* Add the ost info to the client/mdt lov */
1824 static int mgs_write_log_osc_to_lov(const struct lu_env *env,
1825 struct mgs_device *mgs, struct fs_db *fsdb,
1826 struct mgs_target_info *mti,
1827 char *logname, char *suffix, char *lovname,
1828 enum lustre_sec_part sec_part, int flags)
1830 struct llog_handle *llh = NULL;
1831 char *nodeuuid = NULL;
1832 char *oscname = NULL;
1833 char *oscuuid = NULL;
1834 char *lovuuid = NULL;
1835 char *svname = NULL;
1840 CDEBUG(D_INFO, "adding osc for %s to log %s\n",
1841 mti->mti_svname, logname);
1843 if (mgs_log_is_empty(env, mgs, logname)) {
1844 CERROR("log is empty! Logical error\n");
1848 rc = name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
1851 rc = name_create(&svname, mti->mti_svname, "-osc");
1854 rc = name_create(&oscname, svname, suffix);
1857 rc = name_create(&oscuuid, oscname, "_UUID");
1860 rc = name_create(&lovuuid, lovname, "_UUID");
1865 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
1867 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
1868 #04 L attach 0:OSC_uml1_ost1_MNT_client 1:osc 2:89070_lov1_a41dff51a
1869 #05 L setup 0:OSC_uml1_ost1_MNT_client 1:ost1_UUID 2:uml1_UUID
1871 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
1872 #07 L add_conn 0:OSC_uml1_ost1_MNT_client 1:uml2_UUID
1873 #08 L lov_modify_tgts add 0:lov1 1:ost1_UUID 2(index):0 3(gen):1
1876 rc = record_start_log(env, mgs, &llh, logname);
1879 /* FIXME these should be a single journal transaction */
1880 rc = record_marker(env, llh, fsdb, CM_START | flags, mti->mti_svname,
1884 for (i = 0; i < mti->mti_nid_count; i++) {
1885 CDEBUG(D_MGS, "add nid %s\n", libcfs_nid2str(mti->mti_nids[i]));
1886 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
1890 rc = record_attach(env, llh, oscname, LUSTRE_OSC_NAME, lovuuid);
1893 rc = record_setup(env, llh, oscname, mti->mti_uuid, nodeuuid, 0, 0);
1896 rc = mgs_write_log_failnids(env, mti, llh, oscname);
1899 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
1900 rc = record_lov_add(env, llh, lovname, mti->mti_uuid, index, "1");
1903 rc = record_marker(env, llh, fsdb, CM_END | flags, mti->mti_svname,
1908 record_end_log(env, &llh);
1910 name_destroy(&lovuuid);
1911 name_destroy(&oscuuid);
1912 name_destroy(&oscname);
1913 name_destroy(&svname);
1914 name_destroy(&nodeuuid);
1918 static int mgs_write_log_ost(const struct lu_env *env,
1919 struct mgs_device *mgs, struct fs_db *fsdb,
1920 struct mgs_target_info *mti)
1922 struct llog_handle *llh = NULL;
1923 char *logname, *lovname;
1924 char *ptr = mti->mti_params;
1925 int rc, flags = 0, failout = 0, i;
1928 CDEBUG(D_MGS, "writing new ost %s\n", mti->mti_svname);
1930 /* The ost startup log */
1932 /* If the ost log already exists, that means that someone reformatted
1933 the ost and it called target_add again. */
1934 if (!mgs_log_is_empty(env, mgs, mti->mti_svname)) {
1935 LCONSOLE_ERROR_MSG(0x141, "The config log for %s already "
1936 "exists, yet the server claims it never "
1937 "registered. It may have been reformatted, "
1938 "or the index changed. writeconf the MDT to "
1939 "regenerate all logs.\n", mti->mti_svname);
1944 attach obdfilter ost1 ost1_UUID
1945 setup /dev/loop2 ldiskfs f|n errors=remount-ro,user_xattr
1947 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
1948 failout = (strncmp(ptr, "failout", 7) == 0);
1949 rc = record_start_log(env, mgs, &llh, mti->mti_svname);
1952 /* FIXME these should be a single journal transaction */
1953 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,"add ost");
1956 if (*mti->mti_uuid == '\0')
1957 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
1958 "%s_UUID", mti->mti_svname);
1959 rc = record_attach(env, llh, mti->mti_svname,
1960 "obdfilter"/*LUSTRE_OST_NAME*/, mti->mti_uuid);
1963 rc = record_setup(env, llh, mti->mti_svname,
1964 "dev"/*ignored*/, "type"/*ignored*/,
1965 failout ? "n" : "f", 0/*options*/);
1968 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname, "add ost");
1972 record_end_log(env, &llh);
1975 /* We also have to update the other logs where this osc is part of
1978 if (cfs_test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
1979 /* If we're upgrading, the old mdt log already has our
1980 entry. Let's do a fake one for fun. */
1981 /* Note that we can't add any new failnids, since we don't
1982 know the old osc names. */
1983 flags = CM_SKIP | CM_UPGRADE146;
1985 } else if ((mti->mti_flags & LDD_F_UPDATE) != LDD_F_UPDATE) {
1986 /* If the update flag isn't set, don't update client/mdt
1989 LCONSOLE_WARN("Client log for %s was not updated; writeconf "
1990 "the MDT first to regenerate it.\n",
1994 /* Add ost to all MDT lov defs */
1995 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
1996 if (cfs_test_bit(i, fsdb->fsdb_mdt_index_map)) {
1999 rc = name_create_mdt_and_lov(&logname, &lovname, fsdb,
2003 sprintf(mdt_index, "-MDT%04x", i);
2004 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, mti,
2006 lovname, LUSTRE_SP_MDT,
2008 name_destroy(&logname);
2009 name_destroy(&lovname);
2015 /* Append ost info to the client log */
2016 rc = name_create(&logname, mti->mti_fsname, "-client");
2019 if (mgs_log_is_empty(env, mgs, logname)) {
2020 /* Start client log */
2021 rc = mgs_write_log_lov(env, mgs, fsdb, mti, logname,
2025 rc = mgs_write_log_lmv(env, mgs, fsdb, mti, logname,
2030 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, mti, logname, "",
2031 fsdb->fsdb_clilov, LUSTRE_SP_CLI, 0);
2033 name_destroy(&logname);
2037 static __inline__ int mgs_param_empty(char *ptr)
2041 if ((tmp = strchr(ptr, '=')) && (*(++tmp) == '\0'))
2046 static int mgs_write_log_failnid_internal(const struct lu_env *env,
2047 struct mgs_device *mgs,
2049 struct mgs_target_info *mti,
2050 char *logname, char *cliname)
2053 struct llog_handle *llh = NULL;
2055 if (mgs_param_empty(mti->mti_params)) {
2056 /* Remove _all_ failnids */
2057 rc = mgs_modify(env, mgs, fsdb, mti, logname,
2058 mti->mti_svname, "add failnid", CM_SKIP);
2059 return rc < 0 ? rc : 0;
2062 /* Otherwise failover nids are additive */
2063 rc = record_start_log(env, mgs, &llh, logname);
2066 /* FIXME this should be a single journal transaction */
2067 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
2071 rc = mgs_write_log_failnids(env, mti, llh, cliname);
2074 rc = record_marker(env, llh, fsdb, CM_END,
2075 mti->mti_svname, "add failnid");
2077 record_end_log(env, &llh);
2082 /* Add additional failnids to an existing log.
2083 The mdc/osc must have been added to logs first */
2084 /* tcp nids must be in dotted-quad ascii -
2085 we can't resolve hostnames from the kernel. */
2086 static int mgs_write_log_add_failnid(const struct lu_env *env,
2087 struct mgs_device *mgs,
2089 struct mgs_target_info *mti)
2091 char *logname, *cliname;
2095 /* FIXME we currently can't erase the failnids
2096 * given when a target first registers, since they aren't part of
2097 * an "add uuid" stanza */
2099 /* Verify that we know about this target */
2100 if (mgs_log_is_empty(env, mgs, mti->mti_svname)) {
2101 LCONSOLE_ERROR_MSG(0x142, "The target %s has not registered "
2102 "yet. It must be started before failnids "
2103 "can be added.\n", mti->mti_svname);
2107 /* Create mdc/osc client name (e.g. lustre-OST0001-osc) */
2108 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
2109 rc = name_create(&cliname, mti->mti_svname, "-mdc");
2110 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2111 rc = name_create(&cliname, mti->mti_svname, "-osc");
2117 /* Add failover nids to the client log */
2118 rc = name_create(&logname, mti->mti_fsname, "-client");
2120 name_destroy(&cliname);
2123 rc = mgs_write_log_failnid_internal(env, mgs, fsdb,mti,logname,cliname);
2124 name_destroy(&logname);
2125 name_destroy(&cliname);
2129 if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2130 /* Add OST failover nids to the MDT logs as well */
2133 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2134 if (!cfs_test_bit(i, fsdb->fsdb_mdt_index_map))
2136 rc = name_create_mdt(&logname, mti->mti_fsname, i);
2139 rc = name_create_mdt_osc(&cliname, mti->mti_svname,
2142 name_destroy(&logname);
2145 rc = mgs_write_log_failnid_internal(env, mgs, fsdb,
2148 name_destroy(&cliname);
2149 name_destroy(&logname);
2158 static int mgs_wlp_lcfg(const struct lu_env *env,
2159 struct mgs_device *mgs, struct fs_db *fsdb,
2160 struct mgs_target_info *mti,
2161 char *logname, struct lustre_cfg_bufs *bufs,
2162 char *tgtname, char *ptr)
2164 char comment[MTI_NAME_MAXLEN];
2166 struct lustre_cfg *lcfg;
2169 /* Erase any old settings of this same parameter */
2170 memcpy(comment, ptr, MTI_NAME_MAXLEN);
2171 comment[MTI_NAME_MAXLEN - 1] = 0;
2172 /* But don't try to match the value. */
2173 if ((tmp = strchr(comment, '=')))
2175 /* FIXME we should skip settings that are the same as old values */
2176 rc = mgs_modify(env, mgs, fsdb, mti, logname, tgtname, comment,CM_SKIP);
2179 del = mgs_param_empty(ptr);
2181 LCONSOLE_INFO("%sing parameter %s.%s in log %s\n", del ? "Disabl" : rc ?
2182 "Sett" : "Modify", tgtname, comment, logname);
2186 lustre_cfg_bufs_reset(bufs, tgtname);
2187 lustre_cfg_bufs_set_string(bufs, 1, ptr);
2188 lcfg = lustre_cfg_new(LCFG_PARAM, bufs);
2191 rc = mgs_write_log_direct(env, mgs, fsdb, logname,lcfg,tgtname,comment);
2192 lustre_cfg_free(lcfg);
2196 /* write global variable settings into log */
2197 static int mgs_write_log_sys(const struct lu_env *env,
2198 struct mgs_device *mgs, struct fs_db *fsdb,
2199 struct mgs_target_info *mti, char *sys, char *ptr)
2201 struct mgs_thread_info *mgi = mgs_env_info(env);
2202 struct lustre_cfg *lcfg;
2204 int rc, cmd, convert = 1;
2206 if (class_match_param(ptr, PARAM_TIMEOUT, &tmp) == 0) {
2207 cmd = LCFG_SET_TIMEOUT;
2208 } else if (class_match_param(ptr, PARAM_LDLM_TIMEOUT, &tmp) == 0) {
2209 cmd = LCFG_SET_LDLM_TIMEOUT;
2210 /* Check for known params here so we can return error to lctl */
2211 } else if ((class_match_param(ptr, PARAM_AT_MIN, &tmp) == 0) ||
2212 (class_match_param(ptr, PARAM_AT_MAX, &tmp) == 0) ||
2213 (class_match_param(ptr, PARAM_AT_EXTRA, &tmp) == 0) ||
2214 (class_match_param(ptr, PARAM_AT_EARLY_MARGIN, &tmp) == 0) ||
2215 (class_match_param(ptr, PARAM_AT_HISTORY, &tmp) == 0)) {
2217 } else if (class_match_param(ptr, PARAM_JOBID_VAR, &tmp) == 0) {
2218 convert = 0; /* Don't convert string value to integer */
2224 if (mgs_param_empty(ptr))
2225 CDEBUG(D_MGS, "global '%s' removed\n", sys);
2227 CDEBUG(D_MGS, "global '%s' val=%s\n", sys, tmp);
2229 lustre_cfg_bufs_reset(&mgi->mgi_bufs, NULL);
2230 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, sys);
2231 if (!convert && *tmp != '\0')
2232 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 2, tmp);
2233 lcfg = lustre_cfg_new(cmd, &mgi->mgi_bufs);
2234 lcfg->lcfg_num = convert ? simple_strtoul(tmp, NULL, 0) : 0;
2235 /* truncate the comment to the parameter name */
2239 /* modify all servers and clients */
2240 rc = mgs_write_log_direct_all(env, mgs, fsdb, mti,
2241 *tmp == '\0' ? NULL : lcfg,
2242 mti->mti_fsname, sys, 0);
2243 if (rc == 0 && *tmp != '\0') {
2245 case LCFG_SET_TIMEOUT:
2246 if (!obd_timeout_set || lcfg->lcfg_num > obd_timeout)
2247 class_process_config(lcfg);
2249 case LCFG_SET_LDLM_TIMEOUT:
2250 if (!ldlm_timeout_set || lcfg->lcfg_num > ldlm_timeout)
2251 class_process_config(lcfg);
2258 lustre_cfg_free(lcfg);
2262 /* write quota settings into log */
2263 static int mgs_write_log_quota(const struct lu_env *env, struct mgs_device *mgs,
2264 struct fs_db *fsdb, struct mgs_target_info *mti,
2265 char *quota, char *ptr)
2267 struct lustre_cfg_bufs bufs;
2268 struct lustre_cfg *lcfg;
2271 int cmd = LCFG_PARAM;
2274 /* support only 'meta' and 'data' pools so far */
2275 if (class_match_param(ptr, QUOTA_METAPOOL_NAME, &tmp) != 0 &&
2276 class_match_param(ptr, QUOTA_DATAPOOL_NAME, &tmp) != 0) {
2277 CERROR("parameter quota.%s isn't supported (only quota.mdt "
2278 "& quota.ost are)\n", ptr);
2283 CDEBUG(D_MGS, "global '%s' removed\n", quota);
2285 CDEBUG(D_MGS, "global '%s'\n", quota);
2287 if (strchr(tmp, 'u') == NULL && strchr(tmp, 'g') == NULL &&
2288 strcmp(tmp, "none") != 0) {
2289 CERROR("enable option(%s) isn't supported\n", tmp);
2294 lustre_cfg_bufs_reset(&bufs, NULL);
2295 lustre_cfg_bufs_set_string(&bufs, 1, quota);
2296 lcfg = lustre_cfg_new(cmd, &bufs);
2297 /* truncate the comment to the parameter name */
2302 /* XXX we duplicated quota enable information in all server
2303 * config logs, it should be moved to a separate config
2304 * log once we cleanup the config log for global param. */
2305 /* modify all servers */
2306 rc = mgs_write_log_direct_all(env, mgs, fsdb, mti,
2307 *tmp == '\0' ? NULL : lcfg,
2308 mti->mti_fsname, quota, 1);
2310 lustre_cfg_free(lcfg);
2314 static int mgs_srpc_set_param_disk(const struct lu_env *env,
2315 struct mgs_device *mgs,
2317 struct mgs_target_info *mti,
2320 struct mgs_thread_info *mgi = mgs_env_info(env);
2321 struct llog_handle *llh = NULL;
2323 char *comment, *ptr;
2324 struct lustre_cfg *lcfg;
2329 ptr = strchr(param, '=');
2333 OBD_ALLOC(comment, len + 1);
2334 if (comment == NULL)
2336 strncpy(comment, param, len);
2337 comment[len] = '\0';
2340 lustre_cfg_bufs_reset(&mgi->mgi_bufs, mti->mti_svname);
2341 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, param);
2342 lcfg = lustre_cfg_new(LCFG_SPTLRPC_CONF, &mgi->mgi_bufs);
2344 GOTO(out_comment, rc = -ENOMEM);
2346 /* construct log name */
2347 rc = name_create(&logname, mti->mti_fsname, "-sptlrpc");
2351 if (mgs_log_is_empty(env, mgs, logname)) {
2352 rc = record_start_log(env, mgs, &llh, logname);
2355 record_end_log(env, &llh);
2358 /* obsolete old one */
2359 rc = mgs_modify(env, mgs, fsdb, mti, logname, mti->mti_svname,
2363 /* write the new one */
2364 rc = mgs_write_log_direct(env, mgs, fsdb, logname, lcfg,
2365 mti->mti_svname, comment);
2367 CERROR("err %d writing log %s\n", rc, logname);
2369 name_destroy(&logname);
2371 lustre_cfg_free(lcfg);
2373 OBD_FREE(comment, len + 1);
2377 static int mgs_srpc_set_param_udesc_mem(struct fs_db *fsdb,
2382 /* disable the adjustable udesc parameter for now, i.e. use default
2383 * setting that client always ship udesc to MDT if possible. to enable
2384 * it simply remove the following line */
2387 ptr = strchr(param, '=');
2392 if (strcmp(param, PARAM_SRPC_UDESC))
2395 if (strcmp(ptr, "yes") == 0) {
2396 cfs_set_bit(FSDB_UDESC, &fsdb->fsdb_flags);
2397 CWARN("Enable user descriptor shipping from client to MDT\n");
2398 } else if (strcmp(ptr, "no") == 0) {
2399 cfs_clear_bit(FSDB_UDESC, &fsdb->fsdb_flags);
2400 CWARN("Disable user descriptor shipping from client to MDT\n");
2408 CERROR("Invalid param: %s\n", param);
2412 static int mgs_srpc_set_param_mem(struct fs_db *fsdb,
2416 struct sptlrpc_rule rule;
2417 struct sptlrpc_rule_set *rset;
2421 if (strncmp(param, PARAM_SRPC, sizeof(PARAM_SRPC) - 1) != 0) {
2422 CERROR("Invalid sptlrpc parameter: %s\n", param);
2426 if (strncmp(param, PARAM_SRPC_UDESC,
2427 sizeof(PARAM_SRPC_UDESC) - 1) == 0) {
2428 RETURN(mgs_srpc_set_param_udesc_mem(fsdb, param));
2431 if (strncmp(param, PARAM_SRPC_FLVR, sizeof(PARAM_SRPC_FLVR) - 1) != 0) {
2432 CERROR("Invalid sptlrpc flavor parameter: %s\n", param);
2436 param += sizeof(PARAM_SRPC_FLVR) - 1;
2438 rc = sptlrpc_parse_rule(param, &rule);
2442 /* mgs rules implies must be mgc->mgs */
2443 if (cfs_test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
2444 if ((rule.sr_from != LUSTRE_SP_MGC &&
2445 rule.sr_from != LUSTRE_SP_ANY) ||
2446 (rule.sr_to != LUSTRE_SP_MGS &&
2447 rule.sr_to != LUSTRE_SP_ANY))
2451 /* preapre room for this coming rule. svcname format should be:
2452 * - fsname: general rule
2453 * - fsname-tgtname: target-specific rule
2455 if (strchr(svname, '-')) {
2456 struct mgs_tgt_srpc_conf *tgtconf;
2459 for (tgtconf = fsdb->fsdb_srpc_tgt; tgtconf != NULL;
2460 tgtconf = tgtconf->mtsc_next) {
2461 if (!strcmp(tgtconf->mtsc_tgt, svname)) {
2470 OBD_ALLOC_PTR(tgtconf);
2471 if (tgtconf == NULL)
2474 name_len = strlen(svname);
2476 OBD_ALLOC(tgtconf->mtsc_tgt, name_len + 1);
2477 if (tgtconf->mtsc_tgt == NULL) {
2478 OBD_FREE_PTR(tgtconf);
2481 memcpy(tgtconf->mtsc_tgt, svname, name_len);
2483 tgtconf->mtsc_next = fsdb->fsdb_srpc_tgt;
2484 fsdb->fsdb_srpc_tgt = tgtconf;
2487 rset = &tgtconf->mtsc_rset;
2489 rset = &fsdb->fsdb_srpc_gen;
2492 rc = sptlrpc_rule_set_merge(rset, &rule);
2497 static int mgs_srpc_set_param(const struct lu_env *env,
2498 struct mgs_device *mgs,
2500 struct mgs_target_info *mti,
2510 /* keep a copy of original param, which could be destroied
2512 copy_size = strlen(param) + 1;
2513 OBD_ALLOC(copy, copy_size);
2516 memcpy(copy, param, copy_size);
2518 rc = mgs_srpc_set_param_mem(fsdb, mti->mti_svname, param);
2522 /* previous steps guaranteed the syntax is correct */
2523 rc = mgs_srpc_set_param_disk(env, mgs, fsdb, mti, copy);
2527 if (cfs_test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
2529 * for mgs rules, make them effective immediately.
2531 LASSERT(fsdb->fsdb_srpc_tgt == NULL);
2532 sptlrpc_target_update_exp_flavor(mgs->mgs_obd,
2533 &fsdb->fsdb_srpc_gen);
2537 OBD_FREE(copy, copy_size);
2541 struct mgs_srpc_read_data {
2542 struct fs_db *msrd_fsdb;
2546 static int mgs_srpc_read_handler(const struct lu_env *env,
2547 struct llog_handle *llh,
2548 struct llog_rec_hdr *rec, void *data)
2550 struct mgs_srpc_read_data *msrd = data;
2551 struct cfg_marker *marker;
2552 struct lustre_cfg *lcfg = (struct lustre_cfg *)(rec + 1);
2553 char *svname, *param;
2557 if (rec->lrh_type != OBD_CFG_REC) {
2558 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
2562 cfg_len = rec->lrh_len - sizeof(struct llog_rec_hdr) -
2563 sizeof(struct llog_rec_tail);
2565 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
2567 CERROR("Insane cfg\n");
2571 if (lcfg->lcfg_command == LCFG_MARKER) {
2572 marker = lustre_cfg_buf(lcfg, 1);
2574 if (marker->cm_flags & CM_START &&
2575 marker->cm_flags & CM_SKIP)
2576 msrd->msrd_skip = 1;
2577 if (marker->cm_flags & CM_END)
2578 msrd->msrd_skip = 0;
2583 if (msrd->msrd_skip)
2586 if (lcfg->lcfg_command != LCFG_SPTLRPC_CONF) {
2587 CERROR("invalid command (%x)\n", lcfg->lcfg_command);
2591 svname = lustre_cfg_string(lcfg, 0);
2592 if (svname == NULL) {
2593 CERROR("svname is empty\n");
2597 param = lustre_cfg_string(lcfg, 1);
2598 if (param == NULL) {
2599 CERROR("param is empty\n");
2603 rc = mgs_srpc_set_param_mem(msrd->msrd_fsdb, svname, param);
2605 CERROR("read sptlrpc record error (%d): %s\n", rc, param);
2610 int mgs_get_fsdb_srpc_from_llog(const struct lu_env *env,
2611 struct mgs_device *mgs,
2614 struct llog_handle *llh = NULL;
2615 struct llog_ctxt *ctxt;
2617 struct mgs_srpc_read_data msrd;
2621 /* construct log name */
2622 rc = name_create(&logname, fsdb->fsdb_name, "-sptlrpc");
2626 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
2627 LASSERT(ctxt != NULL);
2629 if (mgs_log_is_empty(env, mgs, logname))
2632 rc = llog_open(env, ctxt, &llh, NULL, logname,
2640 rc = llog_init_handle(env, llh, LLOG_F_IS_PLAIN, NULL);
2642 GOTO(out_close, rc);
2644 if (llog_get_size(llh) <= 1)
2645 GOTO(out_close, rc = 0);
2647 msrd.msrd_fsdb = fsdb;
2650 rc = llog_process(env, llh, mgs_srpc_read_handler, (void *)&msrd,
2654 llog_close(env, llh);
2656 llog_ctxt_put(ctxt);
2657 name_destroy(&logname);
2660 CERROR("failed to read sptlrpc config database: %d\n", rc);
2664 /* Permanent settings of all parameters by writing into the appropriate
2665 * configuration logs.
2666 * A parameter with null value ("<param>='\0'") means to erase it out of
2669 static int mgs_write_log_param(const struct lu_env *env,
2670 struct mgs_device *mgs, struct fs_db *fsdb,
2671 struct mgs_target_info *mti, char *ptr)
2673 struct mgs_thread_info *mgi = mgs_env_info(env);
2676 int rc = 0, rc2 = 0;
2679 /* For various parameter settings, we have to figure out which logs
2680 care about them (e.g. both mdt and client for lov settings) */
2681 CDEBUG(D_MGS, "next param '%s'\n", ptr);
2683 /* The params are stored in MOUNT_DATA_FILE and modified via
2684 tunefs.lustre, or set using lctl conf_param */
2686 /* Processed in lustre_start_mgc */
2687 if (class_match_param(ptr, PARAM_MGSNODE, NULL) == 0)
2690 /* Processed in ost/mdt */
2691 if (class_match_param(ptr, PARAM_NETWORK, NULL) == 0)
2694 /* Processed in mgs_write_log_ost */
2695 if (class_match_param(ptr, PARAM_FAILMODE, NULL) == 0) {
2696 if (mti->mti_flags & LDD_F_PARAM) {
2697 LCONSOLE_ERROR_MSG(0x169, "%s can only be "
2698 "changed with tunefs.lustre"
2699 "and --writeconf\n", ptr);
2705 if (class_match_param(ptr, PARAM_SRPC, NULL) == 0) {
2706 rc = mgs_srpc_set_param(env, mgs, fsdb, mti, ptr);
2710 if (class_match_param(ptr, PARAM_FAILNODE, NULL) == 0) {
2711 /* Add a failover nidlist */
2713 /* We already processed failovers params for new
2714 targets in mgs_write_log_target */
2715 if (mti->mti_flags & LDD_F_PARAM) {
2716 CDEBUG(D_MGS, "Adding failnode\n");
2717 rc = mgs_write_log_add_failnid(env, mgs, fsdb, mti);
2722 if (class_match_param(ptr, PARAM_SYS, &tmp) == 0) {
2723 rc = mgs_write_log_sys(env, mgs, fsdb, mti, ptr, tmp);
2727 if (class_match_param(ptr, PARAM_QUOTA, &tmp) == 0) {
2728 rc = mgs_write_log_quota(env, mgs, fsdb, mti, ptr, tmp);
2732 if (class_match_param(ptr, PARAM_OSC""PARAM_ACTIVE, &tmp) == 0) {
2733 /* active=0 means off, anything else means on */
2734 int flag = (*tmp == '0') ? CM_EXCLUDE : 0;
2737 if (!(mti->mti_flags & LDD_F_SV_TYPE_OST)) {
2738 LCONSOLE_ERROR_MSG(0x144, "%s: Only OSCs can "
2739 "be (de)activated.\n",
2741 GOTO(end, rc = -EINVAL);
2743 LCONSOLE_WARN("Permanently %sactivating %s\n",
2744 flag ? "de": "re", mti->mti_svname);
2746 rc = name_create(&logname, mti->mti_fsname, "-client");
2749 rc = mgs_modify(env, mgs, fsdb, mti, logname,
2750 mti->mti_svname, "add osc", flag);
2751 name_destroy(&logname);
2755 /* Add to all MDT logs for CMD */
2756 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2757 if (!cfs_test_bit(i, fsdb->fsdb_mdt_index_map))
2759 rc = name_create_mdt(&logname, mti->mti_fsname, i);
2762 rc = mgs_modify(env, mgs, fsdb, mti, logname,
2763 mti->mti_svname, "add osc", flag);
2764 name_destroy(&logname);
2770 LCONSOLE_ERROR_MSG(0x145, "Couldn't find %s in"
2771 "log (%d). No permanent "
2772 "changes were made to the "
2774 mti->mti_svname, rc);
2775 if (cfs_test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags))
2776 LCONSOLE_ERROR_MSG(0x146, "This may be"
2781 "update the logs.\n");
2784 /* Fall through to osc proc for deactivating live OSC
2785 on running MDT / clients. */
2787 /* Below here, let obd's XXX_process_config methods handle it */
2789 /* All lov. in proc */
2790 if (class_match_param(ptr, PARAM_LOV, NULL) == 0) {
2793 CDEBUG(D_MGS, "lov param %s\n", ptr);
2794 if (!(mti->mti_flags & LDD_F_SV_TYPE_MDT)) {
2795 LCONSOLE_ERROR_MSG(0x147, "LOV params must be "
2796 "set on the MDT, not %s. "
2803 if (mgs_log_is_empty(env, mgs, mti->mti_svname))
2804 GOTO(end, rc = -ENODEV);
2806 rc = name_create_mdt_and_lov(&logname, &mdtlovname, fsdb,
2807 mti->mti_stripe_index);
2810 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, mti->mti_svname,
2811 &mgi->mgi_bufs, mdtlovname, ptr);
2812 name_destroy(&logname);
2813 name_destroy(&mdtlovname);
2818 rc = name_create(&logname, mti->mti_fsname, "-client");
2821 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname, &mgi->mgi_bufs,
2822 fsdb->fsdb_clilov, ptr);
2823 name_destroy(&logname);
2827 /* All osc., mdc., llite. params in proc */
2828 if ((class_match_param(ptr, PARAM_OSC, NULL) == 0) ||
2829 (class_match_param(ptr, PARAM_MDC, NULL) == 0) ||
2830 (class_match_param(ptr, PARAM_LLITE, NULL) == 0)) {
2833 if (cfs_test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
2834 LCONSOLE_ERROR_MSG(0x148, "Upgraded client logs for %s"
2835 " cannot be modified. Consider"
2836 " updating the configuration with"
2839 GOTO(end, rc = -EINVAL);
2841 if (memcmp(ptr, PARAM_LLITE, strlen(PARAM_LLITE)) == 0) {
2842 rc = name_create(&cname, mti->mti_fsname, "-client");
2843 /* Add the client type to match the obdname in
2844 class_config_llog_handler */
2845 } else if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
2846 rc = name_create(&cname, mti->mti_svname, "-mdc");
2847 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2848 rc = name_create(&cname, mti->mti_svname, "-osc");
2850 GOTO(end, rc = -EINVAL);
2855 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
2858 rc = name_create(&logname, mti->mti_fsname, "-client");
2860 name_destroy(&cname);
2863 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname, &mgi->mgi_bufs,
2866 /* osc params affect the MDT as well */
2867 if (!rc && (mti->mti_flags & LDD_F_SV_TYPE_OST)) {
2870 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
2871 if (!cfs_test_bit(i, fsdb->fsdb_mdt_index_map))
2873 name_destroy(&cname);
2874 rc = name_create_mdt_osc(&cname, mti->mti_svname,
2876 name_destroy(&logname);
2879 rc = name_create_mdt(&logname,
2880 mti->mti_fsname, i);
2883 if (!mgs_log_is_empty(env, mgs, logname)) {
2884 rc = mgs_wlp_lcfg(env, mgs, fsdb,
2893 name_destroy(&logname);
2894 name_destroy(&cname);
2898 /* All mdt. params in proc */
2899 if (class_match_param(ptr, PARAM_MDT, NULL) == 0) {
2903 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
2904 if (strncmp(mti->mti_svname, mti->mti_fsname,
2905 MTI_NAME_MAXLEN) == 0)
2906 /* device is unspecified completely? */
2907 rc = LDD_F_SV_TYPE_MDT | LDD_F_SV_ALL;
2909 rc = server_name2index(mti->mti_svname, &idx, NULL);
2912 if ((rc & LDD_F_SV_TYPE_MDT) == 0)
2914 if (rc & LDD_F_SV_ALL) {
2915 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2916 if (!cfs_test_bit(i,
2917 fsdb->fsdb_mdt_index_map))
2919 rc = name_create_mdt(&logname,
2920 mti->mti_fsname, i);
2923 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti,
2924 logname, &mgi->mgi_bufs,
2926 name_destroy(&logname);
2931 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti,
2932 mti->mti_svname, &mgi->mgi_bufs,
2933 mti->mti_svname, ptr);
2940 /* All mdd., ost. params in proc */
2941 if ((class_match_param(ptr, PARAM_MDD, NULL) == 0) ||
2942 (class_match_param(ptr, PARAM_OST, NULL) == 0)) {
2943 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
2944 if (mgs_log_is_empty(env, mgs, mti->mti_svname))
2945 GOTO(end, rc = -ENODEV);
2947 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, mti->mti_svname,
2948 &mgi->mgi_bufs, mti->mti_svname, ptr);
2952 LCONSOLE_WARN("Ignoring unrecognized param '%s'\n", ptr);
2957 CERROR("err %d on param '%s'\n", rc, ptr);
2962 /* Not implementing automatic failover nid addition at this time. */
2963 int mgs_check_failnid(const struct lu_env *env, struct mgs_device *mgs,
2964 struct mgs_target_info *mti)
2971 rc = mgs_find_or_make_fsdb(obd, fsname, &fsdb);
2975 if (mgs_log_is_empty(obd, mti->mti_svname))
2976 /* should never happen */
2979 CDEBUG(D_MGS, "Checking for new failnids for %s\n", mti->mti_svname);
2981 /* FIXME We can just check mti->params to see if we're already in
2982 the failover list. Modify mti->params for rewriting back at
2983 server_register_target(). */
2985 cfs_mutex_lock(&fsdb->fsdb_mutex);
2986 rc = mgs_write_log_add_failnid(obd, fsdb, mti);
2987 cfs_mutex_unlock(&fsdb->fsdb_mutex);
2994 int mgs_write_log_target(const struct lu_env *env,
2995 struct mgs_device *mgs,
2996 struct mgs_target_info *mti,
3003 /* set/check the new target index */
3004 rc = mgs_set_index(env, mgs, mti);
3006 CERROR("Can't get index (%d)\n", rc);
3010 if (rc == EALREADY) {
3011 LCONSOLE_WARN("Found index %d for %s, updating log\n",
3012 mti->mti_stripe_index, mti->mti_svname);
3013 /* We would like to mark old log sections as invalid
3014 and add new log sections in the client and mdt logs.
3015 But if we add new sections, then live clients will
3016 get repeat setup instructions for already running
3017 osc's. So don't update the client/mdt logs. */
3018 mti->mti_flags &= ~LDD_F_UPDATE;
3021 cfs_mutex_lock(&fsdb->fsdb_mutex);
3023 if (mti->mti_flags &
3024 (LDD_F_VIRGIN | LDD_F_UPGRADE14 | LDD_F_WRITECONF)) {
3025 /* Generate a log from scratch */
3026 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
3027 rc = mgs_write_log_mdt(env, mgs, fsdb, mti);
3028 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
3029 rc = mgs_write_log_ost(env, mgs, fsdb, mti);
3031 CERROR("Unknown target type %#x, can't create log for "
3032 "%s\n", mti->mti_flags, mti->mti_svname);
3035 CERROR("Can't write logs for %s (%d)\n",
3036 mti->mti_svname, rc);
3040 /* Just update the params from tunefs in mgs_write_log_params */
3041 CDEBUG(D_MGS, "Update params for %s\n", mti->mti_svname);
3042 mti->mti_flags |= LDD_F_PARAM;
3045 /* allocate temporary buffer, where class_get_next_param will
3046 make copy of a current parameter */
3047 OBD_ALLOC(buf, strlen(mti->mti_params) + 1);
3049 GOTO(out_up, rc = -ENOMEM);
3050 params = mti->mti_params;
3051 while (params != NULL) {
3052 rc = class_get_next_param(¶ms, buf);
3055 /* there is no next parameter, that is
3060 CDEBUG(D_MGS, "remaining string: '%s', param: '%s'\n",
3062 rc = mgs_write_log_param(env, mgs, fsdb, mti, buf);
3067 OBD_FREE(buf, strlen(mti->mti_params) + 1);
3070 cfs_mutex_unlock(&fsdb->fsdb_mutex);
3074 int mgs_erase_log(const struct lu_env *env, struct mgs_device *mgs, char *name)
3076 struct llog_ctxt *ctxt;
3079 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
3081 CERROR("%s: MGS config context doesn't exist\n",
3082 mgs->mgs_obd->obd_name);
3085 rc = llog_erase(env, ctxt, NULL, name);
3086 /* llog may not exist */
3089 llog_ctxt_put(ctxt);
3093 CERROR("%s: failed to clear log %s: %d\n",
3094 mgs->mgs_obd->obd_name, name, rc);
3099 /* erase all logs for the given fs */
3100 int mgs_erase_logs(const struct lu_env *env, struct mgs_device *mgs, char *fsname)
3104 struct mgs_direntry *dirent, *n;
3105 int rc, len = strlen(fsname);
3109 /* Find all the logs in the CONFIGS directory */
3110 rc = class_dentry_readdir(env, mgs, &list);
3114 cfs_mutex_lock(&mgs->mgs_mutex);
3116 /* Delete the fs db */
3117 fsdb = mgs_find_fsdb(mgs, fsname);
3119 mgs_free_fsdb(mgs, fsdb);
3121 cfs_mutex_unlock(&mgs->mgs_mutex);
3123 cfs_list_for_each_entry_safe(dirent, n, &list, list) {
3124 cfs_list_del(&dirent->list);
3125 suffix = strrchr(dirent->name, '-');
3126 if (suffix != NULL) {
3127 if ((len == suffix - dirent->name) &&
3128 (strncmp(fsname, dirent->name, len) == 0)) {
3129 CDEBUG(D_MGS, "Removing log %s\n",
3131 mgs_erase_log(env, mgs, dirent->name);
3134 mgs_direntry_free(dirent);
3140 /* from llog_swab */
3141 static void print_lustre_cfg(struct lustre_cfg *lcfg)
3146 CDEBUG(D_MGS, "lustre_cfg: %p\n", lcfg);
3147 CDEBUG(D_MGS, "\tlcfg->lcfg_version: %#x\n", lcfg->lcfg_version);
3149 CDEBUG(D_MGS, "\tlcfg->lcfg_command: %#x\n", lcfg->lcfg_command);
3150 CDEBUG(D_MGS, "\tlcfg->lcfg_num: %#x\n", lcfg->lcfg_num);
3151 CDEBUG(D_MGS, "\tlcfg->lcfg_flags: %#x\n", lcfg->lcfg_flags);
3152 CDEBUG(D_MGS, "\tlcfg->lcfg_nid: %s\n", libcfs_nid2str(lcfg->lcfg_nid));
3154 CDEBUG(D_MGS, "\tlcfg->lcfg_bufcount: %d\n", lcfg->lcfg_bufcount);
3155 if (lcfg->lcfg_bufcount < LUSTRE_CFG_MAX_BUFCOUNT)
3156 for (i = 0; i < lcfg->lcfg_bufcount; i++) {
3157 CDEBUG(D_MGS, "\tlcfg->lcfg_buflens[%d]: %d %s\n",
3158 i, lcfg->lcfg_buflens[i],
3159 lustre_cfg_string(lcfg, i));
3164 /* Set a permanent (config log) param for a target or fs
3165 * \param lcfg buf0 may contain the device (testfs-MDT0000) name
3166 * buf1 contains the single parameter
3168 int mgs_setparam(const struct lu_env *env, struct mgs_device *mgs,
3169 struct lustre_cfg *lcfg, char *fsname)
3172 struct mgs_target_info *mti;
3173 char *devname, *param;
3179 print_lustre_cfg(lcfg);
3181 /* lustre, lustre-mdtlov, lustre-client, lustre-MDT0000 */
3182 devname = lustre_cfg_string(lcfg, 0);
3183 param = lustre_cfg_string(lcfg, 1);
3185 /* Assume device name embedded in param:
3186 lustre-OST0000.osc.max_dirty_mb=32 */
3187 ptr = strchr(param, '.');
3195 LCONSOLE_ERROR_MSG(0x14d, "No target specified: %s\n", param);
3199 /* Extract fsname */
3200 ptr = strrchr(devname, '-');
3201 memset(fsname, 0, MTI_NAME_MAXLEN);
3202 if (ptr && (server_name2index(ptr, &index, NULL) >= 0)) {
3203 /* param related to llite isn't allowed to set by OST or MDT */
3204 if (strncmp(param, PARAM_LLITE, sizeof(PARAM_LLITE)) == 0)
3207 strncpy(fsname, devname, ptr - devname);
3209 /* assume devname is the fsname */
3210 strncpy(fsname, devname, MTI_NAME_MAXLEN);
3212 fsname[MTI_NAME_MAXLEN - 1] = 0;
3213 CDEBUG(D_MGS, "setparam fs='%s' device='%s'\n", fsname, devname);
3215 rc = mgs_find_or_make_fsdb(env, mgs, fsname, &fsdb);
3218 if (!cfs_test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags) &&
3219 cfs_test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
3220 CERROR("No filesystem targets for %s. cfg_device from lctl "
3221 "is '%s'\n", fsname, devname);
3222 mgs_free_fsdb(mgs, fsdb);
3226 /* Create a fake mti to hold everything */
3229 GOTO(out, rc = -ENOMEM);
3230 strncpy(mti->mti_fsname, fsname, MTI_NAME_MAXLEN);
3231 strncpy(mti->mti_svname, devname, MTI_NAME_MAXLEN);
3232 strncpy(mti->mti_params, param, sizeof(mti->mti_params));
3233 rc = server_name2index(mti->mti_svname, &mti->mti_stripe_index, &tmp);
3235 /* Not a valid server; may be only fsname */
3238 /* Strip -osc or -mdc suffix from svname */
3239 if (server_make_name(rc, mti->mti_stripe_index, mti->mti_fsname,
3241 GOTO(out, rc = -EINVAL);
3243 mti->mti_flags = rc | LDD_F_PARAM;
3245 cfs_mutex_lock(&fsdb->fsdb_mutex);
3246 rc = mgs_write_log_param(env, mgs, fsdb, mti, mti->mti_params);
3247 cfs_mutex_unlock(&fsdb->fsdb_mutex);
3250 * Revoke lock so everyone updates. Should be alright if
3251 * someone was already reading while we were updating the logs,
3252 * so we don't really need to hold the lock while we're
3255 mgs_revoke_lock(mgs, fsdb, CONFIG_T_CONFIG);
3261 static int mgs_write_log_pool(const struct lu_env *env,
3262 struct mgs_device *mgs, char *logname,
3263 struct fs_db *fsdb, char *lovname,
3264 enum lcfg_command_type cmd,
3265 char *poolname, char *fsname,
3266 char *ostname, char *comment)
3268 struct llog_handle *llh = NULL;
3271 rc = record_start_log(env, mgs, &llh, logname);
3274 rc = record_marker(env, llh, fsdb, CM_START, lovname, comment);
3277 rc = record_base(env, llh, lovname, 0, cmd, poolname, fsname, ostname, 0);
3280 rc = record_marker(env, llh, fsdb, CM_END, lovname, comment);
3282 record_end_log(env, &llh);
3286 int mgs_pool_cmd(const struct lu_env *env, struct mgs_device *mgs,
3287 enum lcfg_command_type cmd, char *fsname,
3288 char *poolname, char *ostname)
3293 char *label = NULL, *canceled_label = NULL;
3295 struct mgs_target_info *mti = NULL;
3299 rc = mgs_find_or_make_fsdb(env, mgs, fsname, &fsdb);
3301 CERROR("Can't get db for %s\n", fsname);
3304 if (cfs_test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
3305 CERROR("%s is not defined\n", fsname);
3306 mgs_free_fsdb(mgs, fsdb);
3310 label_sz = 10 + strlen(fsname) + strlen(poolname);
3312 /* check if ostname match fsname */
3313 if (ostname != NULL) {
3316 ptr = strrchr(ostname, '-');
3317 if ((ptr == NULL) ||
3318 (strncmp(fsname, ostname, ptr-ostname) != 0))
3320 label_sz += strlen(ostname);
3323 OBD_ALLOC(label, label_sz);
3330 "new %s.%s", fsname, poolname);
3334 "add %s.%s.%s", fsname, poolname, ostname);
3337 OBD_ALLOC(canceled_label, label_sz);
3338 if (canceled_label == NULL)
3339 GOTO(out_label, rc = -ENOMEM);
3341 "rem %s.%s.%s", fsname, poolname, ostname);
3342 sprintf(canceled_label,
3343 "add %s.%s.%s", fsname, poolname, ostname);
3346 OBD_ALLOC(canceled_label, label_sz);
3347 if (canceled_label == NULL)
3348 GOTO(out_label, rc = -ENOMEM);
3350 "del %s.%s", fsname, poolname);
3351 sprintf(canceled_label,
3352 "new %s.%s", fsname, poolname);
3358 cfs_mutex_lock(&fsdb->fsdb_mutex);
3360 if (canceled_label != NULL) {
3363 GOTO(out_cancel, rc = -ENOMEM);
3366 /* write pool def to all MDT logs */
3367 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3368 if (cfs_test_bit(i, fsdb->fsdb_mdt_index_map)) {
3369 rc = name_create_mdt_and_lov(&logname, &lovname,
3372 cfs_mutex_unlock(&fsdb->fsdb_mutex);
3375 if (canceled_label != NULL) {
3376 strcpy(mti->mti_svname, "lov pool");
3377 rc = mgs_modify(env, mgs, fsdb, mti, logname,
3378 lovname, canceled_label,
3383 rc = mgs_write_log_pool(env, mgs, logname,
3387 name_destroy(&logname);
3388 name_destroy(&lovname);
3390 cfs_mutex_unlock(&fsdb->fsdb_mutex);
3396 rc = name_create(&logname, fsname, "-client");
3398 cfs_mutex_unlock(&fsdb->fsdb_mutex);
3401 if (canceled_label != NULL) {
3402 rc = mgs_modify(env, mgs, fsdb, mti, logname,
3403 fsdb->fsdb_clilov, canceled_label, CM_SKIP);
3405 cfs_mutex_unlock(&fsdb->fsdb_mutex);
3406 name_destroy(&logname);
3411 rc = mgs_write_log_pool(env, mgs, logname, fsdb, fsdb->fsdb_clilov,
3412 cmd, fsname, poolname, ostname, label);
3413 cfs_mutex_unlock(&fsdb->fsdb_mutex);
3414 name_destroy(&logname);
3415 /* request for update */
3416 mgs_revoke_lock(mgs, fsdb, CONFIG_T_CONFIG);
3423 if (canceled_label != NULL)
3424 OBD_FREE(canceled_label, label_sz);
3426 OBD_FREE(label, label_sz);
3431 /******************** unused *********************/
3432 static int mgs_backup_llog(struct obd_device *obd, char* fsname)
3434 struct file *filp, *bak_filp;
3435 struct lvfs_run_ctxt saved;
3436 char *logname, *buf;
3437 loff_t soff = 0 , doff = 0;
3438 int count = 4096, len;
3441 OBD_ALLOC(logname, PATH_MAX);
3442 if (logname == NULL)
3445 OBD_ALLOC(buf, count);
3447 GOTO(out , rc = -ENOMEM);
3449 len = snprintf(logname, PATH_MAX, "%s/%s.bak",
3450 MOUNT_CONFIGS_DIR, fsname);
3452 if (len >= PATH_MAX - 1) {
3453 GOTO(out, -ENAMETOOLONG);
3456 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
3458 bak_filp = l_filp_open(logname, O_RDWR|O_CREAT|O_TRUNC, 0660);
3459 if (IS_ERR(bak_filp)) {
3460 rc = PTR_ERR(bak_filp);
3461 CERROR("backup logfile open %s: %d\n", logname, rc);
3464 sprintf(logname, "%s/%s", MOUNT_CONFIGS_DIR, fsname);
3465 filp = l_filp_open(logname, O_RDONLY, 0);
3468 CERROR("logfile open %s: %d\n", logname, rc);
3472 while ((rc = lustre_fread(filp, buf, count, &soff)) > 0) {
3473 rc = lustre_fwrite(bak_filp, buf, count, &doff);
3477 filp_close(filp, 0);
3479 filp_close(bak_filp, 0);
3481 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
3484 OBD_FREE(buf, count);
3485 OBD_FREE(logname, PATH_MAX);