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, 2012, Intel Corporation.
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>
52 #include <lustre_quota.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 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 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 (!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 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 rc = llog_open_create(env, ctxt, &loghandle, NULL, logname);
278 rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL);
282 if (llog_get_size(loghandle) <= 1)
283 set_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags);
285 rc = llog_process(env, loghandle, mgs_fsdb_handler, (void *)&d, NULL);
286 CDEBUG(D_INFO, "get_db = %d\n", rc);
288 llog_close(env, loghandle);
290 name_destroy(&logname);
297 static void mgs_free_fsdb_srpc(struct fs_db *fsdb)
299 struct mgs_tgt_srpc_conf *tgtconf;
301 /* free target-specific rules */
302 while (fsdb->fsdb_srpc_tgt) {
303 tgtconf = fsdb->fsdb_srpc_tgt;
304 fsdb->fsdb_srpc_tgt = tgtconf->mtsc_next;
306 LASSERT(tgtconf->mtsc_tgt);
308 sptlrpc_rule_set_free(&tgtconf->mtsc_rset);
309 OBD_FREE(tgtconf->mtsc_tgt, strlen(tgtconf->mtsc_tgt) + 1);
310 OBD_FREE_PTR(tgtconf);
313 /* free general rules */
314 sptlrpc_rule_set_free(&fsdb->fsdb_srpc_gen);
317 struct fs_db *mgs_find_fsdb(struct mgs_device *mgs, char *fsname)
322 cfs_list_for_each(tmp, &mgs->mgs_fs_db_list) {
323 fsdb = cfs_list_entry(tmp, struct fs_db, fsdb_list);
324 if (strcmp(fsdb->fsdb_name, fsname) == 0)
330 /* caller must hold the mgs->mgs_fs_db_lock */
331 static struct fs_db *mgs_new_fsdb(const struct lu_env *env,
332 struct mgs_device *mgs, char *fsname)
338 if (strlen(fsname) >= sizeof(fsdb->fsdb_name)) {
339 CERROR("fsname %s is too long\n", fsname);
347 strcpy(fsdb->fsdb_name, fsname);
348 mutex_init(&fsdb->fsdb_mutex);
349 set_bit(FSDB_UDESC, &fsdb->fsdb_flags);
352 if (strcmp(fsname, MGSSELF_NAME) == 0) {
353 set_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags);
355 OBD_ALLOC(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
356 OBD_ALLOC(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
357 if (!fsdb->fsdb_ost_index_map || !fsdb->fsdb_mdt_index_map) {
358 CERROR("No memory for index maps\n");
359 GOTO(err, rc = -ENOMEM);
362 rc = name_create(&fsdb->fsdb_clilov, fsname, "-clilov");
365 rc = name_create(&fsdb->fsdb_clilmv, fsname, "-clilmv");
369 /* initialise data for NID table */
370 mgs_ir_init_fs(env, mgs, fsdb);
372 lproc_mgs_add_live(mgs, fsdb);
375 cfs_list_add(&fsdb->fsdb_list, &mgs->mgs_fs_db_list);
379 if (fsdb->fsdb_ost_index_map)
380 OBD_FREE(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
381 if (fsdb->fsdb_mdt_index_map)
382 OBD_FREE(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
383 name_destroy(&fsdb->fsdb_clilov);
384 name_destroy(&fsdb->fsdb_clilmv);
389 static void mgs_free_fsdb(struct mgs_device *mgs, struct fs_db *fsdb)
391 /* wait for anyone with the sem */
392 mutex_lock(&fsdb->fsdb_mutex);
393 lproc_mgs_del_live(mgs, fsdb);
394 cfs_list_del(&fsdb->fsdb_list);
396 /* deinitialize fsr */
397 mgs_ir_fini_fs(mgs, fsdb);
399 if (fsdb->fsdb_ost_index_map)
400 OBD_FREE(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
401 if (fsdb->fsdb_mdt_index_map)
402 OBD_FREE(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
403 name_destroy(&fsdb->fsdb_clilov);
404 name_destroy(&fsdb->fsdb_clilmv);
405 mgs_free_fsdb_srpc(fsdb);
406 mutex_unlock(&fsdb->fsdb_mutex);
410 int mgs_init_fsdb_list(struct mgs_device *mgs)
412 CFS_INIT_LIST_HEAD(&mgs->mgs_fs_db_list);
416 int mgs_cleanup_fsdb_list(struct mgs_device *mgs)
419 cfs_list_t *tmp, *tmp2;
420 mutex_lock(&mgs->mgs_mutex);
421 cfs_list_for_each_safe(tmp, tmp2, &mgs->mgs_fs_db_list) {
422 fsdb = cfs_list_entry(tmp, struct fs_db, fsdb_list);
423 mgs_free_fsdb(mgs, fsdb);
425 mutex_unlock(&mgs->mgs_mutex);
429 int mgs_find_or_make_fsdb(const struct lu_env *env,
430 struct mgs_device *mgs, char *name,
437 mutex_lock(&mgs->mgs_mutex);
438 fsdb = mgs_find_fsdb(mgs, name);
440 mutex_unlock(&mgs->mgs_mutex);
445 CDEBUG(D_MGS, "Creating new db\n");
446 fsdb = mgs_new_fsdb(env, mgs, name);
447 /* lock fsdb_mutex until the db is loaded from llogs */
449 mutex_lock(&fsdb->fsdb_mutex);
450 mutex_unlock(&mgs->mgs_mutex);
454 if (!test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
455 /* populate the db from the client llog */
456 rc = mgs_get_fsdb_from_llog(env, mgs, fsdb);
458 CERROR("Can't get db from client log %d\n", rc);
463 /* populate srpc rules from params llog */
464 rc = mgs_get_fsdb_srpc_from_llog(env, mgs, fsdb);
466 CERROR("Can't get db from params log %d\n", rc);
470 mutex_unlock(&fsdb->fsdb_mutex);
476 mutex_unlock(&fsdb->fsdb_mutex);
477 mgs_free_fsdb(mgs, fsdb);
483 -1= empty client log */
484 int mgs_check_index(const struct lu_env *env,
485 struct mgs_device *mgs,
486 struct mgs_target_info *mti)
493 LASSERT(!(mti->mti_flags & LDD_F_NEED_INDEX));
495 rc = mgs_find_or_make_fsdb(env, mgs, mti->mti_fsname, &fsdb);
497 CERROR("Can't get db for %s\n", mti->mti_fsname);
501 if (test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags))
504 if (mti->mti_flags & LDD_F_SV_TYPE_OST)
505 imap = fsdb->fsdb_ost_index_map;
506 else if (mti->mti_flags & LDD_F_SV_TYPE_MDT)
507 imap = fsdb->fsdb_mdt_index_map;
511 if (test_bit(mti->mti_stripe_index, imap))
516 static __inline__ int next_index(void *index_map, int map_len)
519 for (i = 0; i < map_len * 8; i++)
520 if (!test_bit(i, index_map)) {
523 CERROR("max index %d exceeded.\n", i);
528 0 newly marked as in use
530 +EALREADY for update of an old index */
531 static int mgs_set_index(const struct lu_env *env,
532 struct mgs_device *mgs,
533 struct mgs_target_info *mti)
540 rc = mgs_find_or_make_fsdb(env, mgs, mti->mti_fsname, &fsdb);
542 CERROR("Can't get db for %s\n", mti->mti_fsname);
546 mutex_lock(&fsdb->fsdb_mutex);
547 if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
548 imap = fsdb->fsdb_ost_index_map;
549 } else if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
550 imap = fsdb->fsdb_mdt_index_map;
551 if (fsdb->fsdb_mdt_count >= MAX_MDT_COUNT) {
552 LCONSOLE_ERROR_MSG(0x13f, "The max mdt count"
553 "is %d\n", (int)MAX_MDT_COUNT);
554 GOTO(out_up, rc = -ERANGE);
557 GOTO(out_up, rc = -EINVAL);
560 if (mti->mti_flags & LDD_F_NEED_INDEX) {
561 rc = next_index(imap, INDEX_MAP_SIZE);
563 GOTO(out_up, rc = -ERANGE);
564 mti->mti_stripe_index = rc;
565 if (mti->mti_flags & LDD_F_SV_TYPE_MDT)
566 fsdb->fsdb_mdt_count ++;
569 if (mti->mti_stripe_index >= INDEX_MAP_SIZE * 8) {
570 LCONSOLE_ERROR_MSG(0x13f, "Server %s requested index %d, "
571 "but the max index is %d.\n",
572 mti->mti_svname, mti->mti_stripe_index,
574 GOTO(out_up, rc = -ERANGE);
577 if (test_bit(mti->mti_stripe_index, imap)) {
578 if ((mti->mti_flags & LDD_F_VIRGIN) &&
579 !(mti->mti_flags & LDD_F_WRITECONF)) {
580 LCONSOLE_ERROR_MSG(0x140, "Server %s requested index "
581 "%d, but that index is already in "
582 "use. Use --writeconf to force\n",
584 mti->mti_stripe_index);
585 GOTO(out_up, rc = -EADDRINUSE);
587 CDEBUG(D_MGS, "Server %s updating index %d\n",
588 mti->mti_svname, mti->mti_stripe_index);
589 GOTO(out_up, rc = EALREADY);
593 set_bit(mti->mti_stripe_index, imap);
594 clear_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags);
595 mutex_unlock(&fsdb->fsdb_mutex);
596 server_make_name(mti->mti_flags & ~(LDD_F_VIRGIN | LDD_F_WRITECONF),
597 mti->mti_stripe_index, mti->mti_fsname, mti->mti_svname);
599 CDEBUG(D_MGS, "Set index for %s to %d\n", mti->mti_svname,
600 mti->mti_stripe_index);
604 mutex_unlock(&fsdb->fsdb_mutex);
608 struct mgs_modify_lookup {
609 struct cfg_marker mml_marker;
613 static int mgs_modify_handler(const struct lu_env *env,
614 struct llog_handle *llh,
615 struct llog_rec_hdr *rec, void *data)
617 struct mgs_modify_lookup *mml = data;
618 struct cfg_marker *marker;
619 struct lustre_cfg *lcfg = (struct lustre_cfg *)(rec + 1);
620 int cfg_len = rec->lrh_len - sizeof(struct llog_rec_hdr) -
621 sizeof(struct llog_rec_tail);
625 if (rec->lrh_type != OBD_CFG_REC) {
626 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
630 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
632 CERROR("Insane cfg\n");
636 /* We only care about markers */
637 if (lcfg->lcfg_command != LCFG_MARKER)
640 marker = lustre_cfg_buf(lcfg, 1);
641 if ((strcmp(mml->mml_marker.cm_comment, marker->cm_comment) == 0) &&
642 (strcmp(mml->mml_marker.cm_tgtname, marker->cm_tgtname) == 0) &&
643 !(marker->cm_flags & CM_SKIP)) {
644 /* Found a non-skipped marker match */
645 CDEBUG(D_MGS, "Changing rec %u marker %d %x->%x: %s %s\n",
646 rec->lrh_index, marker->cm_step,
647 marker->cm_flags, mml->mml_marker.cm_flags,
648 marker->cm_tgtname, marker->cm_comment);
649 /* Overwrite the old marker llog entry */
650 marker->cm_flags &= ~CM_EXCLUDE; /* in case we're unexcluding */
651 marker->cm_flags |= mml->mml_marker.cm_flags;
652 marker->cm_canceltime = mml->mml_marker.cm_canceltime;
653 /* Header and tail are added back to lrh_len in
654 llog_lvfs_write_rec */
655 rec->lrh_len = cfg_len;
656 rc = llog_write(env, llh, rec, NULL, 0, (void *)lcfg,
666 * Modify an existing config log record (for CM_SKIP or CM_EXCLUDE)
668 * 0 - modified successfully,
669 * 1 - no modification was done
672 static int mgs_modify(const struct lu_env *env, struct mgs_device *mgs,
673 struct fs_db *fsdb, struct mgs_target_info *mti,
674 char *logname, char *devname, char *comment, int flags)
676 struct llog_handle *loghandle;
677 struct llog_ctxt *ctxt;
678 struct mgs_modify_lookup *mml;
683 LASSERT(mutex_is_locked(&fsdb->fsdb_mutex));
684 CDEBUG(D_MGS, "modify %s/%s/%s fl=%x\n", logname, devname, comment,
687 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
688 LASSERT(ctxt != NULL);
689 rc = llog_open(env, ctxt, &loghandle, NULL, logname, LLOG_OPEN_EXISTS);
696 rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL);
700 if (llog_get_size(loghandle) <= 1)
701 GOTO(out_close, rc = 0);
705 GOTO(out_close, rc = -ENOMEM);
706 strcpy(mml->mml_marker.cm_comment, comment);
707 strcpy(mml->mml_marker.cm_tgtname, devname);
708 /* Modify mostly means cancel */
709 mml->mml_marker.cm_flags = flags;
710 mml->mml_marker.cm_canceltime = flags ? cfs_time_current_sec() : 0;
711 mml->mml_modified = 0;
712 rc = llog_process(env, loghandle, mgs_modify_handler, (void *)mml,
714 if (!rc && !mml->mml_modified)
719 llog_close(env, loghandle);
722 CERROR("%s: modify %s/%s failed: rc = %d\n",
723 mgs->mgs_obd->obd_name, mti->mti_svname, comment, rc);
728 /******************** config log recording functions *********************/
730 static int record_lcfg(const struct lu_env *env, struct llog_handle *llh,
731 struct lustre_cfg *lcfg)
733 struct llog_rec_hdr rec;
739 LASSERT(llh->lgh_ctxt);
741 buflen = lustre_cfg_len(lcfg->lcfg_bufcount,
743 rec.lrh_len = llog_data_len(buflen);
744 rec.lrh_type = OBD_CFG_REC;
746 /* idx = -1 means append */
747 rc = llog_write(env, llh, &rec, NULL, 0, (void *)lcfg, -1);
749 CERROR("failed %d\n", rc);
753 static int record_base(const struct lu_env *env, struct llog_handle *llh,
754 char *cfgname, lnet_nid_t nid, int cmd,
755 char *s1, char *s2, char *s3, char *s4)
757 struct mgs_thread_info *mgi = mgs_env_info(env);
758 struct lustre_cfg *lcfg;
761 CDEBUG(D_MGS, "lcfg %s %#x %s %s %s %s\n", cfgname,
762 cmd, s1, s2, s3, s4);
764 lustre_cfg_bufs_reset(&mgi->mgi_bufs, cfgname);
766 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, s1);
768 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 2, s2);
770 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 3, s3);
772 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 4, s4);
774 lcfg = lustre_cfg_new(cmd, &mgi->mgi_bufs);
777 lcfg->lcfg_nid = nid;
779 rc = record_lcfg(env, llh, lcfg);
781 lustre_cfg_free(lcfg);
784 CERROR("error %d: lcfg %s %#x %s %s %s %s\n", rc, cfgname,
785 cmd, s1, s2, s3, s4);
791 static inline int record_add_uuid(const struct lu_env *env,
792 struct llog_handle *llh,
793 uint64_t nid, char *uuid)
795 return record_base(env, llh, NULL, nid, LCFG_ADD_UUID, uuid, 0, 0, 0);
799 static inline int record_add_conn(const struct lu_env *env,
800 struct llog_handle *llh,
801 char *devname, char *uuid)
803 return record_base(env, llh, devname, 0, LCFG_ADD_CONN, uuid, 0, 0, 0);
806 static inline int record_attach(const struct lu_env *env,
807 struct llog_handle *llh, char *devname,
808 char *type, char *uuid)
810 return record_base(env, llh,devname, 0, LCFG_ATTACH, type, uuid, 0, 0);
813 static inline int record_setup(const struct lu_env *env,
814 struct llog_handle *llh, char *devname,
815 char *s1, char *s2, char *s3, char *s4)
817 return record_base(env, llh, devname, 0, LCFG_SETUP, s1, s2, s3, s4);
820 static int record_lov_setup(const struct lu_env *env, struct llog_handle *llh,
821 char *devname, struct lov_desc *desc)
823 struct mgs_thread_info *mgi = mgs_env_info(env);
824 struct lustre_cfg *lcfg;
827 lustre_cfg_bufs_reset(&mgi->mgi_bufs, devname);
828 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, desc, sizeof(*desc));
829 lcfg = lustre_cfg_new(LCFG_SETUP, &mgi->mgi_bufs);
832 rc = record_lcfg(env, llh, lcfg);
834 lustre_cfg_free(lcfg);
838 static int record_lmv_setup(const struct lu_env *env, struct llog_handle *llh,
839 char *devname, struct lmv_desc *desc)
841 struct mgs_thread_info *mgi = mgs_env_info(env);
842 struct lustre_cfg *lcfg;
845 lustre_cfg_bufs_reset(&mgi->mgi_bufs, devname);
846 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, desc, sizeof(*desc));
847 lcfg = lustre_cfg_new(LCFG_SETUP, &mgi->mgi_bufs);
849 rc = record_lcfg(env, llh, lcfg);
851 lustre_cfg_free(lcfg);
855 static inline int record_mdc_add(const struct lu_env *env,
856 struct llog_handle *llh,
857 char *logname, char *mdcuuid,
858 char *mdtuuid, char *index,
861 return record_base(env,llh,logname,0,LCFG_ADD_MDC,
862 mdtuuid,index,gen,mdcuuid);
865 static inline int record_lov_add(const struct lu_env *env,
866 struct llog_handle *llh,
867 char *lov_name, char *ost_uuid,
868 char *index, char *gen)
870 return record_base(env,llh,lov_name,0,LCFG_LOV_ADD_OBD,
871 ost_uuid,index,gen,0);
874 static inline int record_mount_opt(const struct lu_env *env,
875 struct llog_handle *llh,
876 char *profile, char *lov_name,
879 return record_base(env,llh,NULL,0,LCFG_MOUNTOPT,
880 profile,lov_name,mdc_name,0);
883 static int record_marker(const struct lu_env *env,
884 struct llog_handle *llh,
885 struct fs_db *fsdb, __u32 flags,
886 char *tgtname, char *comment)
888 struct mgs_thread_info *mgi = mgs_env_info(env);
889 struct lustre_cfg *lcfg;
892 if (flags & CM_START)
894 mgi->mgi_marker.cm_step = fsdb->fsdb_gen;
895 mgi->mgi_marker.cm_flags = flags;
896 mgi->mgi_marker.cm_vers = LUSTRE_VERSION_CODE;
897 strncpy(mgi->mgi_marker.cm_tgtname, tgtname,
898 sizeof(mgi->mgi_marker.cm_tgtname));
899 strncpy(mgi->mgi_marker.cm_comment, comment,
900 sizeof(mgi->mgi_marker.cm_comment));
901 mgi->mgi_marker.cm_createtime = cfs_time_current_sec();
902 mgi->mgi_marker.cm_canceltime = 0;
903 lustre_cfg_bufs_reset(&mgi->mgi_bufs, NULL);
904 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, &mgi->mgi_marker,
905 sizeof(mgi->mgi_marker));
906 lcfg = lustre_cfg_new(LCFG_MARKER, &mgi->mgi_bufs);
909 rc = record_lcfg(env, llh, lcfg);
911 lustre_cfg_free(lcfg);
915 static int record_start_log(const struct lu_env *env, struct mgs_device *mgs,
916 struct llog_handle **llh, char *name)
918 static struct obd_uuid cfg_uuid = { .uuid = "config_uuid" };
919 struct llog_ctxt *ctxt;
923 GOTO(out, rc = -EBUSY);
925 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
927 GOTO(out, rc = -ENODEV);
928 LASSERT(ctxt->loc_obd == mgs->mgs_obd);
930 rc = llog_open_create(env, ctxt, llh, NULL, name);
933 rc = llog_init_handle(env, *llh, LLOG_F_IS_PLAIN, &cfg_uuid);
935 llog_close(env, *llh);
940 CERROR("%s: can't start log %s: rc = %d\n",
941 mgs->mgs_obd->obd_name, name, rc);
947 static int record_end_log(const struct lu_env *env, struct llog_handle **llh)
951 rc = llog_close(env, *llh);
957 static int mgs_log_is_empty(const struct lu_env *env,
958 struct mgs_device *mgs, char *name)
960 struct llog_handle *llh;
961 struct llog_ctxt *ctxt;
964 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
965 LASSERT(ctxt != NULL);
966 rc = llog_open(env, ctxt, &llh, NULL, name, LLOG_OPEN_EXISTS);
973 llog_init_handle(env, llh, LLOG_F_IS_PLAIN, NULL);
976 rc = llog_get_size(llh);
979 llog_close(env, llh);
982 /* header is record 1 */
986 /******************** config "macros" *********************/
988 /* write an lcfg directly into a log (with markers) */
989 static int mgs_write_log_direct(const struct lu_env *env,
990 struct mgs_device *mgs, struct fs_db *fsdb,
991 char *logname, struct lustre_cfg *lcfg,
992 char *devname, char *comment)
994 struct llog_handle *llh = NULL;
1001 rc = record_start_log(env, mgs, &llh, logname);
1005 /* FIXME These should be a single journal transaction */
1006 rc = record_marker(env, llh, fsdb, CM_START, devname, comment);
1009 rc = record_lcfg(env, llh, lcfg);
1012 rc = record_marker(env, llh, fsdb, CM_END, devname, comment);
1016 record_end_log(env, &llh);
1020 /* write the lcfg in all logs for the given fs */
1021 int mgs_write_log_direct_all(const struct lu_env *env,
1022 struct mgs_device *mgs,
1024 struct mgs_target_info *mti,
1025 struct lustre_cfg *lcfg,
1026 char *devname, char *comment,
1030 struct mgs_direntry *dirent, *n;
1031 char *fsname = mti->mti_fsname;
1033 int rc = 0, len = strlen(fsname);
1036 /* We need to set params for any future logs
1037 as well. FIXME Append this file to every new log.
1038 Actually, we should store as params (text), not llogs. Or
1040 rc = name_create(&logname, fsname, "-params");
1043 if (mgs_log_is_empty(env, mgs, logname)) {
1044 struct llog_handle *llh = NULL;
1045 rc = record_start_log(env, mgs, &llh, logname);
1046 record_end_log(env, &llh);
1048 name_destroy(&logname);
1052 /* Find all the logs in the CONFIGS directory */
1053 rc = class_dentry_readdir(env, mgs, &list);
1057 /* Could use fsdb index maps instead of directory listing */
1058 cfs_list_for_each_entry_safe(dirent, n, &list, list) {
1059 cfs_list_del(&dirent->list);
1060 /* don't write to sptlrpc rule log */
1061 if (strstr(dirent->name, "-sptlrpc") != NULL)
1064 /* caller wants write server logs only */
1065 if (server_only && strstr(dirent->name, "-client") != NULL)
1068 if (strncmp(fsname, dirent->name, len) == 0) {
1069 CDEBUG(D_MGS, "Changing log %s\n", dirent->name);
1070 /* Erase any old settings of this same parameter */
1071 rc = mgs_modify(env, mgs, fsdb, mti, dirent->name,
1072 devname, comment, CM_SKIP);
1074 CERROR("%s: Can't modify llog %s: rc = %d\n",
1075 mgs->mgs_obd->obd_name, dirent->name,rc);
1076 /* Write the new one */
1078 rc = mgs_write_log_direct(env, mgs, fsdb,
1083 CERROR("%s: writing log %s: rc = %d\n",
1084 mgs->mgs_obd->obd_name,
1089 mgs_direntry_free(dirent);
1095 static int mgs_write_log_mdc_to_mdt(const struct lu_env *env,
1096 struct mgs_device *mgs,
1098 struct mgs_target_info *mti,
1100 static int mgs_write_log_osc_to_lov(const struct lu_env *env,
1101 struct mgs_device *mgs,
1103 struct mgs_target_info *mti,
1104 char *logname, char *suffix, char *lovname,
1105 enum lustre_sec_part sec_part, int flags);
1106 static int name_create_mdt_and_lov(char **logname, char **lovname,
1107 struct fs_db *fsdb, int i);
1109 static int add_param(char *params, char *key, char *val)
1111 char *start = params + strlen(params);
1112 char *end = params + sizeof(((struct mgs_target_info *)0)->mti_params);
1116 keylen = strlen(key);
1117 if (start + 1 + keylen + strlen(val) >= end) {
1118 CERROR("params are too long: %s %s%s\n",
1119 params, key != NULL ? key : "", val);
1123 sprintf(start, " %s%s", key != NULL ? key : "", val);
1127 static int mgs_steal_llog_handler(const struct lu_env *env,
1128 struct llog_handle *llh,
1129 struct llog_rec_hdr *rec, void *data)
1131 struct mgs_device *mgs;
1132 struct obd_device *obd;
1133 struct mgs_target_info *mti, *tmti;
1135 int cfg_len = rec->lrh_len;
1136 char *cfg_buf = (char*) (rec + 1);
1137 struct lustre_cfg *lcfg;
1139 struct llog_handle *mdt_llh = NULL;
1140 static int got_an_osc_or_mdc = 0;
1141 /* 0: not found any osc/mdc;
1145 static int last_step = -1;
1149 mti = ((struct temp_comp*)data)->comp_mti;
1150 tmti = ((struct temp_comp*)data)->comp_tmti;
1151 fsdb = ((struct temp_comp*)data)->comp_fsdb;
1152 obd = ((struct temp_comp *)data)->comp_obd;
1153 mgs = lu2mgs_dev(obd->obd_lu_dev);
1156 if (rec->lrh_type != OBD_CFG_REC) {
1157 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
1161 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
1163 CERROR("Insane cfg\n");
1167 lcfg = (struct lustre_cfg *)cfg_buf;
1169 if (lcfg->lcfg_command == LCFG_MARKER) {
1170 struct cfg_marker *marker;
1171 marker = lustre_cfg_buf(lcfg, 1);
1172 if (!strncmp(marker->cm_comment,"add osc",7) &&
1173 (marker->cm_flags & CM_START)){
1174 got_an_osc_or_mdc = 1;
1175 strncpy(tmti->mti_svname, marker->cm_tgtname,
1176 sizeof(tmti->mti_svname));
1177 rc = record_start_log(env, mgs, &mdt_llh,
1181 rc = record_marker(env, mdt_llh, fsdb, CM_START,
1182 mti->mti_svname,"add osc(copied)");
1183 record_end_log(env, &mdt_llh);
1184 last_step = marker->cm_step;
1187 if (!strncmp(marker->cm_comment,"add osc",7) &&
1188 (marker->cm_flags & CM_END)){
1189 LASSERT(last_step == marker->cm_step);
1191 got_an_osc_or_mdc = 0;
1192 rc = record_start_log(env, mgs, &mdt_llh,
1196 rc = record_marker(env, mdt_llh, fsdb, CM_END,
1197 mti->mti_svname,"add osc(copied)");
1198 record_end_log(env, &mdt_llh);
1201 if (!strncmp(marker->cm_comment,"add mdc",7) &&
1202 (marker->cm_flags & CM_START)){
1203 got_an_osc_or_mdc = 2;
1204 last_step = marker->cm_step;
1205 memcpy(tmti->mti_svname, marker->cm_tgtname,
1206 strlen(marker->cm_tgtname));
1210 if (!strncmp(marker->cm_comment,"add mdc",7) &&
1211 (marker->cm_flags & CM_END)){
1212 LASSERT(last_step == marker->cm_step);
1214 got_an_osc_or_mdc = 0;
1219 if (got_an_osc_or_mdc == 0 || last_step < 0)
1222 if (lcfg->lcfg_command == LCFG_ADD_UUID) {
1223 uint64_t nodenid = lcfg->lcfg_nid;
1225 if (strlen(tmti->mti_uuid) == 0) {
1226 /* target uuid not set, this config record is before
1227 * LCFG_SETUP, this nid is one of target node nid.
1229 tmti->mti_nids[tmti->mti_nid_count] = nodenid;
1230 tmti->mti_nid_count++;
1232 /* failover node nid */
1233 rc = add_param(tmti->mti_params, PARAM_FAILNODE,
1234 libcfs_nid2str(nodenid));
1240 if (lcfg->lcfg_command == LCFG_SETUP) {
1243 target = lustre_cfg_string(lcfg, 1);
1244 memcpy(tmti->mti_uuid, target, strlen(target));
1248 /* ignore client side sptlrpc_conf_log */
1249 if (lcfg->lcfg_command == LCFG_SPTLRPC_CONF)
1252 if (lcfg->lcfg_command == LCFG_ADD_MDC) {
1255 if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1)
1258 memcpy(tmti->mti_fsname, mti->mti_fsname,
1259 strlen(mti->mti_fsname));
1260 tmti->mti_stripe_index = index;
1262 rc = mgs_write_log_mdc_to_mdt(env, mgs, fsdb, tmti,
1264 memset(tmti, 0, sizeof(*tmti));
1268 if (lcfg->lcfg_command == LCFG_LOV_ADD_OBD) {
1271 char *logname, *lovname;
1273 rc = name_create_mdt_and_lov(&logname, &lovname, fsdb,
1274 mti->mti_stripe_index);
1277 sprintf(mdt_index, "-MDT%04x", mti->mti_stripe_index);
1279 if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1) {
1280 name_destroy(&logname);
1281 name_destroy(&lovname);
1285 tmti->mti_stripe_index = index;
1286 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, tmti, logname,
1289 name_destroy(&logname);
1290 name_destroy(&lovname);
1296 /* fsdb->fsdb_mutex is already held in mgs_write_log_target*/
1297 /* stealed from mgs_get_fsdb_from_llog*/
1298 static int mgs_steal_llog_for_mdt_from_client(const struct lu_env *env,
1299 struct mgs_device *mgs,
1301 struct temp_comp* comp)
1303 struct llog_handle *loghandle;
1304 struct mgs_target_info *tmti;
1305 struct llog_ctxt *ctxt;
1310 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
1311 LASSERT(ctxt != NULL);
1313 OBD_ALLOC_PTR(tmti);
1315 GOTO(out_ctxt, rc = -ENOMEM);
1317 comp->comp_tmti = tmti;
1318 comp->comp_obd = mgs->mgs_obd;
1320 rc = llog_open(env, ctxt, &loghandle, NULL, client_name,
1328 rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL);
1330 GOTO(out_close, rc);
1332 rc = llog_process_or_fork(env, loghandle, mgs_steal_llog_handler,
1333 (void *)comp, NULL, false);
1334 CDEBUG(D_MGS, "steal llog re = %d\n", rc);
1336 llog_close(env, loghandle);
1340 llog_ctxt_put(ctxt);
1344 /* lmv is the second thing for client logs */
1345 /* copied from mgs_write_log_lov. Please refer to that. */
1346 static int mgs_write_log_lmv(const struct lu_env *env,
1347 struct mgs_device *mgs,
1349 struct mgs_target_info *mti,
1350 char *logname, char *lmvname)
1352 struct llog_handle *llh = NULL;
1353 struct lmv_desc *lmvdesc;
1358 CDEBUG(D_MGS, "Writing lmv(%s) log for %s\n", lmvname,logname);
1360 OBD_ALLOC_PTR(lmvdesc);
1361 if (lmvdesc == NULL)
1363 lmvdesc->ld_active_tgt_count = 0;
1364 lmvdesc->ld_tgt_count = 0;
1365 sprintf((char*)lmvdesc->ld_uuid.uuid, "%s_UUID", lmvname);
1366 uuid = (char *)lmvdesc->ld_uuid.uuid;
1368 rc = record_start_log(env, mgs, &llh, logname);
1371 rc = record_marker(env, llh, fsdb, CM_START, lmvname, "lmv setup");
1374 rc = record_attach(env, llh, lmvname, "lmv", uuid);
1377 rc = record_lmv_setup(env, llh, lmvname, lmvdesc);
1380 rc = record_marker(env, llh, fsdb, CM_END, lmvname, "lmv setup");
1384 record_end_log(env, &llh);
1386 OBD_FREE_PTR(lmvdesc);
1390 /* lov is the first thing in the mdt and client logs */
1391 static int mgs_write_log_lov(const struct lu_env *env, struct mgs_device *mgs,
1392 struct fs_db *fsdb, struct mgs_target_info *mti,
1393 char *logname, char *lovname)
1395 struct llog_handle *llh = NULL;
1396 struct lov_desc *lovdesc;
1401 CDEBUG(D_MGS, "Writing lov(%s) log for %s\n", lovname, logname);
1404 #01 L attach 0:lov_mdsA 1:lov 2:71ccb_lov_mdsA_19f961a9e1
1405 #02 L lov_setup 0:lov_mdsA 1:(struct lov_desc)
1406 uuid=lov1_UUID, stripe count=1, size=1048576, offset=0, pattern=0
1409 /* FIXME just make lov_setup accept empty desc (put uuid in buf 2) */
1410 OBD_ALLOC_PTR(lovdesc);
1411 if (lovdesc == NULL)
1413 lovdesc->ld_magic = LOV_DESC_MAGIC;
1414 lovdesc->ld_tgt_count = 0;
1415 /* Defaults. Can be changed later by lcfg config_param */
1416 lovdesc->ld_default_stripe_count = 1;
1417 lovdesc->ld_pattern = LOV_PATTERN_RAID0;
1418 lovdesc->ld_default_stripe_size = 1024 * 1024;
1419 lovdesc->ld_default_stripe_offset = -1;
1420 lovdesc->ld_qos_maxage = QOS_DEFAULT_MAXAGE;
1421 sprintf((char*)lovdesc->ld_uuid.uuid, "%s_UUID", lovname);
1422 /* can these be the same? */
1423 uuid = (char *)lovdesc->ld_uuid.uuid;
1425 /* This should always be the first entry in a log.
1426 rc = mgs_clear_log(obd, logname); */
1427 rc = record_start_log(env, mgs, &llh, logname);
1430 /* FIXME these should be a single journal transaction */
1431 rc = record_marker(env, llh, fsdb, CM_START, lovname, "lov setup");
1434 rc = record_attach(env, llh, lovname, "lov", uuid);
1437 rc = record_lov_setup(env, llh, lovname, lovdesc);
1440 rc = record_marker(env, llh, fsdb, CM_END, lovname, "lov setup");
1445 record_end_log(env, &llh);
1447 OBD_FREE_PTR(lovdesc);
1451 /* add failnids to open log */
1452 static int mgs_write_log_failnids(const struct lu_env *env,
1453 struct mgs_target_info *mti,
1454 struct llog_handle *llh,
1457 char *failnodeuuid = NULL;
1458 char *ptr = mti->mti_params;
1463 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) nal=90 0: 1:uml1_UUID
1464 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
1465 #05 L setup 0:OSC_uml1_ost1_mdsA 1:ost1_UUID 2:uml1_UUID
1466 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) nal=90 0: 1:uml2_UUID
1467 #0x L add_uuid nid=2@elan(0x1000000000002) nal=90 0: 1:uml2_UUID
1468 #07 L add_conn 0:OSC_uml1_ost1_mdsA 1:uml2_UUID
1471 /* Pull failnid info out of params string */
1472 while (class_find_param(ptr, PARAM_FAILNODE, &ptr) == 0) {
1473 while (class_parse_nid(ptr, &nid, &ptr) == 0) {
1474 if (failnodeuuid == NULL) {
1475 /* We don't know the failover node name,
1476 so just use the first nid as the uuid */
1477 rc = name_create(&failnodeuuid,
1478 libcfs_nid2str(nid), "");
1482 CDEBUG(D_MGS, "add nid %s for failover uuid %s, "
1483 "client %s\n", libcfs_nid2str(nid),
1484 failnodeuuid, cliname);
1485 rc = record_add_uuid(env, llh, nid, failnodeuuid);
1488 rc = record_add_conn(env, llh, cliname, failnodeuuid);
1491 name_destroy(&failnodeuuid);
1495 static int mgs_write_log_mdc_to_lmv(const struct lu_env *env,
1496 struct mgs_device *mgs,
1498 struct mgs_target_info *mti,
1499 char *logname, char *lmvname)
1501 struct llog_handle *llh = NULL;
1502 char *mdcname = NULL;
1503 char *nodeuuid = NULL;
1504 char *mdcuuid = NULL;
1505 char *lmvuuid = NULL;
1510 if (mgs_log_is_empty(env, mgs, logname)) {
1511 CERROR("log is empty! Logical error\n");
1515 CDEBUG(D_MGS, "adding mdc for %s to log %s:lmv(%s)\n",
1516 mti->mti_svname, logname, lmvname);
1518 rc = name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
1521 rc = name_create(&mdcname, mti->mti_svname, "-mdc");
1524 rc = name_create(&mdcuuid, mdcname, "_UUID");
1527 rc = name_create(&lmvuuid, lmvname, "_UUID");
1531 rc = record_start_log(env, mgs, &llh, logname);
1534 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
1538 for (i = 0; i < mti->mti_nid_count; i++) {
1539 CDEBUG(D_MGS, "add nid %s for mdt\n",
1540 libcfs_nid2str(mti->mti_nids[i]));
1542 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
1547 rc = record_attach(env, llh, mdcname, LUSTRE_MDC_NAME, lmvuuid);
1550 rc = record_setup(env, llh, mdcname, mti->mti_uuid, nodeuuid, 0, 0);
1553 rc = mgs_write_log_failnids(env, mti, llh, mdcname);
1556 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
1557 rc = record_mdc_add(env, llh, lmvname, mdcuuid, mti->mti_uuid,
1561 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname,
1566 record_end_log(env, &llh);
1568 name_destroy(&lmvuuid);
1569 name_destroy(&mdcuuid);
1570 name_destroy(&mdcname);
1571 name_destroy(&nodeuuid);
1575 /* add new mdc to already existent MDS */
1576 static int mgs_write_log_mdc_to_mdt(const struct lu_env *env,
1577 struct mgs_device *mgs,
1579 struct mgs_target_info *mti,
1582 struct llog_handle *llh = NULL;
1583 char *nodeuuid = NULL;
1584 char *mdcname = NULL;
1585 char *mdcuuid = NULL;
1586 char *mdtuuid = NULL;
1587 int idx = mti->mti_stripe_index;
1592 if (mgs_log_is_empty(env, mgs, logname)) {
1593 CERROR("log is empty! Logical error\n");
1597 CDEBUG(D_MGS, "adding mdc index %d to %s\n", idx, logname);
1599 rc = name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
1602 snprintf(index, sizeof(index), "-mdc%04x", idx);
1603 rc = name_create(&mdcname, logname, index);
1606 rc = name_create(&mdcuuid, mdcname, "_UUID");
1609 rc = name_create(&mdtuuid, logname, "_UUID");
1613 rc = record_start_log(env, mgs, &llh, logname);
1616 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname, "add mdc");
1619 for (i = 0; i < mti->mti_nid_count; i++) {
1620 CDEBUG(D_MGS, "add nid %s for mdt\n",
1621 libcfs_nid2str(mti->mti_nids[i]));
1622 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
1626 rc = record_attach(env, llh, mdcname, LUSTRE_MDC_NAME, mdcuuid);
1629 rc = record_setup(env, llh, mdcname, mti->mti_uuid, nodeuuid, 0, 0);
1632 rc = mgs_write_log_failnids(env, mti, llh, mdcname);
1635 snprintf(index, sizeof(index), "%d", idx);
1637 rc = record_mdc_add(env, llh, logname, mdcuuid, mti->mti_uuid,
1641 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname, "add mdc");
1645 record_end_log(env, &llh);
1647 name_destroy(&mdtuuid);
1648 name_destroy(&mdcuuid);
1649 name_destroy(&mdcname);
1650 name_destroy(&nodeuuid);
1654 static int mgs_write_log_mdt0(const struct lu_env *env,
1655 struct mgs_device *mgs,
1657 struct mgs_target_info *mti)
1659 char *log = mti->mti_svname;
1660 struct llog_handle *llh = NULL;
1661 char *uuid, *lovname;
1663 char *ptr = mti->mti_params;
1664 int rc = 0, failout = 0;
1667 OBD_ALLOC(uuid, sizeof(struct obd_uuid));
1671 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
1672 failout = (strncmp(ptr, "failout", 7) == 0);
1674 rc = name_create(&lovname, log, "-mdtlov");
1677 if (mgs_log_is_empty(env, mgs, log)) {
1678 rc = mgs_write_log_lov(env, mgs, fsdb, mti, log, lovname);
1683 sprintf(mdt_index, "%d", mti->mti_stripe_index);
1685 rc = record_start_log(env, mgs, &llh, log);
1689 /* add MDT itself */
1691 /* FIXME this whole fn should be a single journal transaction */
1692 sprintf(uuid, "%s_UUID", log);
1693 rc = record_marker(env, llh, fsdb, CM_START, log, "add mdt");
1696 rc = record_attach(env, llh, log, LUSTRE_MDT_NAME, uuid);
1699 rc = record_mount_opt(env, llh, log, lovname, NULL);
1702 rc = record_setup(env, llh, log, uuid, mdt_index, lovname,
1703 failout ? "n" : "f");
1706 rc = record_marker(env, llh, fsdb, CM_END, log, "add mdt");
1710 record_end_log(env, &llh);
1712 name_destroy(&lovname);
1714 OBD_FREE(uuid, sizeof(struct obd_uuid));
1718 static inline int name_create_mdt(char **logname, char *fsname, int i)
1722 sprintf(mdt_index, "-MDT%04x", i);
1723 return name_create(logname, fsname, mdt_index);
1726 static int name_create_mdt_and_lov(char **logname, char **lovname,
1727 struct fs_db *fsdb, int i)
1731 rc = name_create_mdt(logname, fsdb->fsdb_name, i);
1735 if (i == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
1736 rc = name_create(lovname, fsdb->fsdb_name, "-mdtlov");
1738 rc = name_create(lovname, *logname, "-mdtlov");
1740 name_destroy(logname);
1746 static inline int name_create_mdt_osc(char **oscname, char *ostname,
1747 struct fs_db *fsdb, int i)
1751 if (i == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
1752 sprintf(suffix, "-osc");
1754 sprintf(suffix, "-osc-MDT%04x", i);
1755 return name_create(oscname, ostname, suffix);
1758 /* envelope method for all layers log */
1759 static int mgs_write_log_mdt(const struct lu_env *env,
1760 struct mgs_device *mgs,
1762 struct mgs_target_info *mti)
1764 struct mgs_thread_info *mgi = mgs_env_info(env);
1765 struct llog_handle *llh = NULL;
1770 CDEBUG(D_MGS, "writing new mdt %s\n", mti->mti_svname);
1772 if (mti->mti_uuid[0] == '\0') {
1773 /* Make up our own uuid */
1774 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
1775 "%s_UUID", mti->mti_svname);
1779 rc = mgs_write_log_mdt0(env, mgs, fsdb, mti);
1782 /* Append the mdt info to the client log */
1783 rc = name_create(&cliname, mti->mti_fsname, "-client");
1787 if (mgs_log_is_empty(env, mgs, cliname)) {
1788 /* Start client log */
1789 rc = mgs_write_log_lov(env, mgs, fsdb, mti, cliname,
1793 rc = mgs_write_log_lmv(env, mgs, fsdb, mti, cliname,
1800 #09 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
1801 #10 L attach 0:MDC_uml1_mdsA_MNT_client 1:mdc 2:1d834_MNT_client_03f
1802 #11 L setup 0:MDC_uml1_mdsA_MNT_client 1:mdsA_UUID 2:uml1_UUID
1803 #12 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
1804 #13 L add_conn 0:MDC_uml1_mdsA_MNT_client 1:uml2_UUID
1805 #14 L mount_option 0: 1:client 2:lov1 3:MDC_uml1_mdsA_MNT_client
1808 /* copy client info about lov/lmv */
1809 mgi->mgi_comp.comp_mti = mti;
1810 mgi->mgi_comp.comp_fsdb = fsdb;
1812 rc = mgs_steal_llog_for_mdt_from_client(env, mgs, cliname,
1816 rc = mgs_write_log_mdc_to_lmv(env, mgs, fsdb, mti, cliname,
1822 rc = record_start_log(env, mgs, &llh, cliname);
1826 rc = record_marker(env, llh, fsdb, CM_START, cliname,
1830 rc = record_mount_opt(env, llh, cliname, fsdb->fsdb_clilov,
1834 rc = record_marker(env, llh, fsdb, CM_END, cliname,
1839 /* for_all_existing_mdt except current one */
1840 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
1842 if (i != mti->mti_stripe_index &&
1843 test_bit(i, fsdb->fsdb_mdt_index_map)) {
1844 rc = name_create_mdt(&mdtname, mti->mti_fsname, i);
1847 rc = mgs_write_log_mdc_to_mdt(env, mgs, fsdb, mti, mdtname);
1848 name_destroy(&mdtname);
1854 record_end_log(env, &llh);
1856 name_destroy(&cliname);
1860 /* Add the ost info to the client/mdt lov */
1861 static int mgs_write_log_osc_to_lov(const struct lu_env *env,
1862 struct mgs_device *mgs, struct fs_db *fsdb,
1863 struct mgs_target_info *mti,
1864 char *logname, char *suffix, char *lovname,
1865 enum lustre_sec_part sec_part, int flags)
1867 struct llog_handle *llh = NULL;
1868 char *nodeuuid = NULL;
1869 char *oscname = NULL;
1870 char *oscuuid = NULL;
1871 char *lovuuid = NULL;
1872 char *svname = NULL;
1877 CDEBUG(D_INFO, "adding osc for %s to log %s\n",
1878 mti->mti_svname, logname);
1880 if (mgs_log_is_empty(env, mgs, logname)) {
1881 CERROR("log is empty! Logical error\n");
1885 rc = name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
1888 rc = name_create(&svname, mti->mti_svname, "-osc");
1891 /* for the system upgraded from old 1.8, keep using the old osc naming
1892 * style for mdt, see name_create_mdt_osc(). LU-1257 */
1893 if (test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
1894 rc = name_create(&oscname, svname, "");
1896 rc = name_create(&oscname, svname, suffix);
1899 rc = name_create(&oscuuid, oscname, "_UUID");
1902 rc = name_create(&lovuuid, lovname, "_UUID");
1907 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
1909 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
1910 #04 L attach 0:OSC_uml1_ost1_MNT_client 1:osc 2:89070_lov1_a41dff51a
1911 #05 L setup 0:OSC_uml1_ost1_MNT_client 1:ost1_UUID 2:uml1_UUID
1913 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
1914 #07 L add_conn 0:OSC_uml1_ost1_MNT_client 1:uml2_UUID
1915 #08 L lov_modify_tgts add 0:lov1 1:ost1_UUID 2(index):0 3(gen):1
1918 rc = record_start_log(env, mgs, &llh, logname);
1922 /* FIXME these should be a single journal transaction */
1923 rc = record_marker(env, llh, fsdb, CM_START | flags, mti->mti_svname,
1928 /* NB: don't change record order, because upon MDT steal OSC config
1929 * from client, it treats all nids before LCFG_SETUP as target nids
1930 * (multiple interfaces), while nids after as failover node nids.
1931 * See mgs_steal_llog_handler() LCFG_ADD_UUID.
1933 for (i = 0; i < mti->mti_nid_count; i++) {
1934 CDEBUG(D_MGS, "add nid %s\n", libcfs_nid2str(mti->mti_nids[i]));
1935 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
1939 rc = record_attach(env, llh, oscname, LUSTRE_OSC_NAME, lovuuid);
1942 rc = record_setup(env, llh, oscname, mti->mti_uuid, nodeuuid, 0, 0);
1945 rc = mgs_write_log_failnids(env, mti, llh, oscname);
1948 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
1949 rc = record_lov_add(env, llh, lovname, mti->mti_uuid, index, "1");
1952 rc = record_marker(env, llh, fsdb, CM_END | flags, mti->mti_svname,
1957 record_end_log(env, &llh);
1959 name_destroy(&lovuuid);
1960 name_destroy(&oscuuid);
1961 name_destroy(&oscname);
1962 name_destroy(&svname);
1963 name_destroy(&nodeuuid);
1967 static int mgs_write_log_ost(const struct lu_env *env,
1968 struct mgs_device *mgs, struct fs_db *fsdb,
1969 struct mgs_target_info *mti)
1971 struct llog_handle *llh = NULL;
1972 char *logname, *lovname;
1973 char *ptr = mti->mti_params;
1974 int rc, flags = 0, failout = 0, i;
1977 CDEBUG(D_MGS, "writing new ost %s\n", mti->mti_svname);
1979 /* The ost startup log */
1981 /* If the ost log already exists, that means that someone reformatted
1982 the ost and it called target_add again. */
1983 if (!mgs_log_is_empty(env, mgs, mti->mti_svname)) {
1984 LCONSOLE_ERROR_MSG(0x141, "The config log for %s already "
1985 "exists, yet the server claims it never "
1986 "registered. It may have been reformatted, "
1987 "or the index changed. writeconf the MDT to "
1988 "regenerate all logs.\n", mti->mti_svname);
1993 attach obdfilter ost1 ost1_UUID
1994 setup /dev/loop2 ldiskfs f|n errors=remount-ro,user_xattr
1996 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
1997 failout = (strncmp(ptr, "failout", 7) == 0);
1998 rc = record_start_log(env, mgs, &llh, mti->mti_svname);
2001 /* FIXME these should be a single journal transaction */
2002 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,"add ost");
2005 if (*mti->mti_uuid == '\0')
2006 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
2007 "%s_UUID", mti->mti_svname);
2008 rc = record_attach(env, llh, mti->mti_svname,
2009 "obdfilter"/*LUSTRE_OST_NAME*/, mti->mti_uuid);
2012 rc = record_setup(env, llh, mti->mti_svname,
2013 "dev"/*ignored*/, "type"/*ignored*/,
2014 failout ? "n" : "f", 0/*options*/);
2017 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname, "add ost");
2021 record_end_log(env, &llh);
2024 /* We also have to update the other logs where this osc is part of
2027 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
2028 /* If we're upgrading, the old mdt log already has our
2029 entry. Let's do a fake one for fun. */
2030 /* Note that we can't add any new failnids, since we don't
2031 know the old osc names. */
2032 flags = CM_SKIP | CM_UPGRADE146;
2034 } else if ((mti->mti_flags & LDD_F_UPDATE) != LDD_F_UPDATE) {
2035 /* If the update flag isn't set, don't update client/mdt
2038 LCONSOLE_WARN("Client log for %s was not updated; writeconf "
2039 "the MDT first to regenerate it.\n",
2043 /* Add ost to all MDT lov defs */
2044 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
2045 if (test_bit(i, fsdb->fsdb_mdt_index_map)) {
2048 rc = name_create_mdt_and_lov(&logname, &lovname, fsdb,
2052 sprintf(mdt_index, "-MDT%04x", i);
2053 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, mti,
2055 lovname, LUSTRE_SP_MDT,
2057 name_destroy(&logname);
2058 name_destroy(&lovname);
2064 /* Append ost info to the client log */
2065 rc = name_create(&logname, mti->mti_fsname, "-client");
2068 if (mgs_log_is_empty(env, mgs, logname)) {
2069 /* Start client log */
2070 rc = mgs_write_log_lov(env, mgs, fsdb, mti, logname,
2074 rc = mgs_write_log_lmv(env, mgs, fsdb, mti, logname,
2079 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, mti, logname, "",
2080 fsdb->fsdb_clilov, LUSTRE_SP_CLI, 0);
2082 name_destroy(&logname);
2086 static __inline__ int mgs_param_empty(char *ptr)
2090 if ((tmp = strchr(ptr, '=')) && (*(++tmp) == '\0'))
2095 static int mgs_write_log_failnid_internal(const struct lu_env *env,
2096 struct mgs_device *mgs,
2098 struct mgs_target_info *mti,
2099 char *logname, char *cliname)
2102 struct llog_handle *llh = NULL;
2104 if (mgs_param_empty(mti->mti_params)) {
2105 /* Remove _all_ failnids */
2106 rc = mgs_modify(env, mgs, fsdb, mti, logname,
2107 mti->mti_svname, "add failnid", CM_SKIP);
2108 return rc < 0 ? rc : 0;
2111 /* Otherwise failover nids are additive */
2112 rc = record_start_log(env, mgs, &llh, logname);
2115 /* FIXME this should be a single journal transaction */
2116 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
2120 rc = mgs_write_log_failnids(env, mti, llh, cliname);
2123 rc = record_marker(env, llh, fsdb, CM_END,
2124 mti->mti_svname, "add failnid");
2126 record_end_log(env, &llh);
2131 /* Add additional failnids to an existing log.
2132 The mdc/osc must have been added to logs first */
2133 /* tcp nids must be in dotted-quad ascii -
2134 we can't resolve hostnames from the kernel. */
2135 static int mgs_write_log_add_failnid(const struct lu_env *env,
2136 struct mgs_device *mgs,
2138 struct mgs_target_info *mti)
2140 char *logname, *cliname;
2144 /* FIXME we currently can't erase the failnids
2145 * given when a target first registers, since they aren't part of
2146 * an "add uuid" stanza */
2148 /* Verify that we know about this target */
2149 if (mgs_log_is_empty(env, mgs, mti->mti_svname)) {
2150 LCONSOLE_ERROR_MSG(0x142, "The target %s has not registered "
2151 "yet. It must be started before failnids "
2152 "can be added.\n", mti->mti_svname);
2156 /* Create mdc/osc client name (e.g. lustre-OST0001-osc) */
2157 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
2158 rc = name_create(&cliname, mti->mti_svname, "-mdc");
2159 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2160 rc = name_create(&cliname, mti->mti_svname, "-osc");
2166 /* Add failover nids to the client log */
2167 rc = name_create(&logname, mti->mti_fsname, "-client");
2169 name_destroy(&cliname);
2172 rc = mgs_write_log_failnid_internal(env, mgs, fsdb,mti,logname,cliname);
2173 name_destroy(&logname);
2174 name_destroy(&cliname);
2178 if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2179 /* Add OST failover nids to the MDT logs as well */
2182 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2183 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
2185 rc = name_create_mdt(&logname, mti->mti_fsname, i);
2188 rc = name_create_mdt_osc(&cliname, mti->mti_svname,
2191 name_destroy(&logname);
2194 rc = mgs_write_log_failnid_internal(env, mgs, fsdb,
2197 name_destroy(&cliname);
2198 name_destroy(&logname);
2207 static int mgs_wlp_lcfg(const struct lu_env *env,
2208 struct mgs_device *mgs, struct fs_db *fsdb,
2209 struct mgs_target_info *mti,
2210 char *logname, struct lustre_cfg_bufs *bufs,
2211 char *tgtname, char *ptr)
2213 char comment[MTI_NAME_MAXLEN];
2215 struct lustre_cfg *lcfg;
2218 /* Erase any old settings of this same parameter */
2219 memcpy(comment, ptr, MTI_NAME_MAXLEN);
2220 comment[MTI_NAME_MAXLEN - 1] = 0;
2221 /* But don't try to match the value. */
2222 if ((tmp = strchr(comment, '=')))
2224 /* FIXME we should skip settings that are the same as old values */
2225 rc = mgs_modify(env, mgs, fsdb, mti, logname, tgtname, comment,CM_SKIP);
2228 del = mgs_param_empty(ptr);
2230 LCONSOLE_INFO("%sing parameter %s.%s in log %s\n", del ? "Disabl" : rc ?
2231 "Sett" : "Modify", tgtname, comment, logname);
2235 lustre_cfg_bufs_reset(bufs, tgtname);
2236 lustre_cfg_bufs_set_string(bufs, 1, ptr);
2237 lcfg = lustre_cfg_new(LCFG_PARAM, bufs);
2240 rc = mgs_write_log_direct(env, mgs, fsdb, logname,lcfg,tgtname,comment);
2241 lustre_cfg_free(lcfg);
2245 /* write global variable settings into log */
2246 static int mgs_write_log_sys(const struct lu_env *env,
2247 struct mgs_device *mgs, struct fs_db *fsdb,
2248 struct mgs_target_info *mti, char *sys, char *ptr)
2250 struct mgs_thread_info *mgi = mgs_env_info(env);
2251 struct lustre_cfg *lcfg;
2253 int rc, cmd, convert = 1;
2255 if (class_match_param(ptr, PARAM_TIMEOUT, &tmp) == 0) {
2256 cmd = LCFG_SET_TIMEOUT;
2257 } else if (class_match_param(ptr, PARAM_LDLM_TIMEOUT, &tmp) == 0) {
2258 cmd = LCFG_SET_LDLM_TIMEOUT;
2259 /* Check for known params here so we can return error to lctl */
2260 } else if ((class_match_param(ptr, PARAM_AT_MIN, &tmp) == 0) ||
2261 (class_match_param(ptr, PARAM_AT_MAX, &tmp) == 0) ||
2262 (class_match_param(ptr, PARAM_AT_EXTRA, &tmp) == 0) ||
2263 (class_match_param(ptr, PARAM_AT_EARLY_MARGIN, &tmp) == 0) ||
2264 (class_match_param(ptr, PARAM_AT_HISTORY, &tmp) == 0)) {
2266 } else if (class_match_param(ptr, PARAM_JOBID_VAR, &tmp) == 0) {
2267 convert = 0; /* Don't convert string value to integer */
2273 if (mgs_param_empty(ptr))
2274 CDEBUG(D_MGS, "global '%s' removed\n", sys);
2276 CDEBUG(D_MGS, "global '%s' val=%s\n", sys, tmp);
2278 lustre_cfg_bufs_reset(&mgi->mgi_bufs, NULL);
2279 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, sys);
2280 if (!convert && *tmp != '\0')
2281 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 2, tmp);
2282 lcfg = lustre_cfg_new(cmd, &mgi->mgi_bufs);
2283 lcfg->lcfg_num = convert ? simple_strtoul(tmp, NULL, 0) : 0;
2284 /* truncate the comment to the parameter name */
2288 /* modify all servers and clients */
2289 rc = mgs_write_log_direct_all(env, mgs, fsdb, mti,
2290 *tmp == '\0' ? NULL : lcfg,
2291 mti->mti_fsname, sys, 0);
2292 if (rc == 0 && *tmp != '\0') {
2294 case LCFG_SET_TIMEOUT:
2295 if (!obd_timeout_set || lcfg->lcfg_num > obd_timeout)
2296 class_process_config(lcfg);
2298 case LCFG_SET_LDLM_TIMEOUT:
2299 if (!ldlm_timeout_set || lcfg->lcfg_num > ldlm_timeout)
2300 class_process_config(lcfg);
2307 lustre_cfg_free(lcfg);
2311 /* write quota settings into log */
2312 static int mgs_write_log_quota(const struct lu_env *env, struct mgs_device *mgs,
2313 struct fs_db *fsdb, struct mgs_target_info *mti,
2314 char *quota, char *ptr)
2316 struct mgs_thread_info *mgi = mgs_env_info(env);
2317 struct lustre_cfg *lcfg;
2320 int rc, cmd = LCFG_PARAM;
2322 /* support only 'meta' and 'data' pools so far */
2323 if (class_match_param(ptr, QUOTA_METAPOOL_NAME, &tmp) != 0 &&
2324 class_match_param(ptr, QUOTA_DATAPOOL_NAME, &tmp) != 0) {
2325 CERROR("parameter quota.%s isn't supported (only quota.mdt "
2326 "& quota.ost are)\n", ptr);
2331 CDEBUG(D_MGS, "global '%s' removed\n", quota);
2333 CDEBUG(D_MGS, "global '%s'\n", quota);
2335 if (strchr(tmp, 'u') == NULL && strchr(tmp, 'g') == NULL &&
2336 strcmp(tmp, "none") != 0) {
2337 CERROR("enable option(%s) isn't supported\n", tmp);
2342 lustre_cfg_bufs_reset(&mgi->mgi_bufs, mti->mti_fsname);
2343 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, quota);
2344 lcfg = lustre_cfg_new(cmd, &mgi->mgi_bufs);
2345 /* truncate the comment to the parameter name */
2350 /* XXX we duplicated quota enable information in all server
2351 * config logs, it should be moved to a separate config
2352 * log once we cleanup the config log for global param. */
2353 /* modify all servers */
2354 rc = mgs_write_log_direct_all(env, mgs, fsdb, mti,
2355 *tmp == '\0' ? NULL : lcfg,
2356 mti->mti_fsname, quota, 1);
2358 lustre_cfg_free(lcfg);
2362 static int mgs_srpc_set_param_disk(const struct lu_env *env,
2363 struct mgs_device *mgs,
2365 struct mgs_target_info *mti,
2368 struct mgs_thread_info *mgi = mgs_env_info(env);
2369 struct llog_handle *llh = NULL;
2371 char *comment, *ptr;
2372 struct lustre_cfg *lcfg;
2377 ptr = strchr(param, '=');
2381 OBD_ALLOC(comment, len + 1);
2382 if (comment == NULL)
2384 strncpy(comment, param, len);
2385 comment[len] = '\0';
2388 lustre_cfg_bufs_reset(&mgi->mgi_bufs, mti->mti_svname);
2389 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, param);
2390 lcfg = lustre_cfg_new(LCFG_SPTLRPC_CONF, &mgi->mgi_bufs);
2392 GOTO(out_comment, rc = -ENOMEM);
2394 /* construct log name */
2395 rc = name_create(&logname, mti->mti_fsname, "-sptlrpc");
2399 if (mgs_log_is_empty(env, mgs, logname)) {
2400 rc = record_start_log(env, mgs, &llh, logname);
2403 record_end_log(env, &llh);
2406 /* obsolete old one */
2407 rc = mgs_modify(env, mgs, fsdb, mti, logname, mti->mti_svname,
2411 /* write the new one */
2412 rc = mgs_write_log_direct(env, mgs, fsdb, logname, lcfg,
2413 mti->mti_svname, comment);
2415 CERROR("err %d writing log %s\n", rc, logname);
2417 name_destroy(&logname);
2419 lustre_cfg_free(lcfg);
2421 OBD_FREE(comment, len + 1);
2425 static int mgs_srpc_set_param_udesc_mem(struct fs_db *fsdb,
2430 /* disable the adjustable udesc parameter for now, i.e. use default
2431 * setting that client always ship udesc to MDT if possible. to enable
2432 * it simply remove the following line */
2435 ptr = strchr(param, '=');
2440 if (strcmp(param, PARAM_SRPC_UDESC))
2443 if (strcmp(ptr, "yes") == 0) {
2444 set_bit(FSDB_UDESC, &fsdb->fsdb_flags);
2445 CWARN("Enable user descriptor shipping from client to MDT\n");
2446 } else if (strcmp(ptr, "no") == 0) {
2447 clear_bit(FSDB_UDESC, &fsdb->fsdb_flags);
2448 CWARN("Disable user descriptor shipping from client to MDT\n");
2456 CERROR("Invalid param: %s\n", param);
2460 static int mgs_srpc_set_param_mem(struct fs_db *fsdb,
2464 struct sptlrpc_rule rule;
2465 struct sptlrpc_rule_set *rset;
2469 if (strncmp(param, PARAM_SRPC, sizeof(PARAM_SRPC) - 1) != 0) {
2470 CERROR("Invalid sptlrpc parameter: %s\n", param);
2474 if (strncmp(param, PARAM_SRPC_UDESC,
2475 sizeof(PARAM_SRPC_UDESC) - 1) == 0) {
2476 RETURN(mgs_srpc_set_param_udesc_mem(fsdb, param));
2479 if (strncmp(param, PARAM_SRPC_FLVR, sizeof(PARAM_SRPC_FLVR) - 1) != 0) {
2480 CERROR("Invalid sptlrpc flavor parameter: %s\n", param);
2484 param += sizeof(PARAM_SRPC_FLVR) - 1;
2486 rc = sptlrpc_parse_rule(param, &rule);
2490 /* mgs rules implies must be mgc->mgs */
2491 if (test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
2492 if ((rule.sr_from != LUSTRE_SP_MGC &&
2493 rule.sr_from != LUSTRE_SP_ANY) ||
2494 (rule.sr_to != LUSTRE_SP_MGS &&
2495 rule.sr_to != LUSTRE_SP_ANY))
2499 /* preapre room for this coming rule. svcname format should be:
2500 * - fsname: general rule
2501 * - fsname-tgtname: target-specific rule
2503 if (strchr(svname, '-')) {
2504 struct mgs_tgt_srpc_conf *tgtconf;
2507 for (tgtconf = fsdb->fsdb_srpc_tgt; tgtconf != NULL;
2508 tgtconf = tgtconf->mtsc_next) {
2509 if (!strcmp(tgtconf->mtsc_tgt, svname)) {
2518 OBD_ALLOC_PTR(tgtconf);
2519 if (tgtconf == NULL)
2522 name_len = strlen(svname);
2524 OBD_ALLOC(tgtconf->mtsc_tgt, name_len + 1);
2525 if (tgtconf->mtsc_tgt == NULL) {
2526 OBD_FREE_PTR(tgtconf);
2529 memcpy(tgtconf->mtsc_tgt, svname, name_len);
2531 tgtconf->mtsc_next = fsdb->fsdb_srpc_tgt;
2532 fsdb->fsdb_srpc_tgt = tgtconf;
2535 rset = &tgtconf->mtsc_rset;
2537 rset = &fsdb->fsdb_srpc_gen;
2540 rc = sptlrpc_rule_set_merge(rset, &rule);
2545 static int mgs_srpc_set_param(const struct lu_env *env,
2546 struct mgs_device *mgs,
2548 struct mgs_target_info *mti,
2558 /* keep a copy of original param, which could be destroied
2560 copy_size = strlen(param) + 1;
2561 OBD_ALLOC(copy, copy_size);
2564 memcpy(copy, param, copy_size);
2566 rc = mgs_srpc_set_param_mem(fsdb, mti->mti_svname, param);
2570 /* previous steps guaranteed the syntax is correct */
2571 rc = mgs_srpc_set_param_disk(env, mgs, fsdb, mti, copy);
2575 if (test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
2577 * for mgs rules, make them effective immediately.
2579 LASSERT(fsdb->fsdb_srpc_tgt == NULL);
2580 sptlrpc_target_update_exp_flavor(mgs->mgs_obd,
2581 &fsdb->fsdb_srpc_gen);
2585 OBD_FREE(copy, copy_size);
2589 struct mgs_srpc_read_data {
2590 struct fs_db *msrd_fsdb;
2594 static int mgs_srpc_read_handler(const struct lu_env *env,
2595 struct llog_handle *llh,
2596 struct llog_rec_hdr *rec, void *data)
2598 struct mgs_srpc_read_data *msrd = data;
2599 struct cfg_marker *marker;
2600 struct lustre_cfg *lcfg = (struct lustre_cfg *)(rec + 1);
2601 char *svname, *param;
2605 if (rec->lrh_type != OBD_CFG_REC) {
2606 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
2610 cfg_len = rec->lrh_len - sizeof(struct llog_rec_hdr) -
2611 sizeof(struct llog_rec_tail);
2613 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
2615 CERROR("Insane cfg\n");
2619 if (lcfg->lcfg_command == LCFG_MARKER) {
2620 marker = lustre_cfg_buf(lcfg, 1);
2622 if (marker->cm_flags & CM_START &&
2623 marker->cm_flags & CM_SKIP)
2624 msrd->msrd_skip = 1;
2625 if (marker->cm_flags & CM_END)
2626 msrd->msrd_skip = 0;
2631 if (msrd->msrd_skip)
2634 if (lcfg->lcfg_command != LCFG_SPTLRPC_CONF) {
2635 CERROR("invalid command (%x)\n", lcfg->lcfg_command);
2639 svname = lustre_cfg_string(lcfg, 0);
2640 if (svname == NULL) {
2641 CERROR("svname is empty\n");
2645 param = lustre_cfg_string(lcfg, 1);
2646 if (param == NULL) {
2647 CERROR("param is empty\n");
2651 rc = mgs_srpc_set_param_mem(msrd->msrd_fsdb, svname, param);
2653 CERROR("read sptlrpc record error (%d): %s\n", rc, param);
2658 int mgs_get_fsdb_srpc_from_llog(const struct lu_env *env,
2659 struct mgs_device *mgs,
2662 struct llog_handle *llh = NULL;
2663 struct llog_ctxt *ctxt;
2665 struct mgs_srpc_read_data msrd;
2669 /* construct log name */
2670 rc = name_create(&logname, fsdb->fsdb_name, "-sptlrpc");
2674 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
2675 LASSERT(ctxt != NULL);
2677 if (mgs_log_is_empty(env, mgs, logname))
2680 rc = llog_open(env, ctxt, &llh, NULL, logname,
2688 rc = llog_init_handle(env, llh, LLOG_F_IS_PLAIN, NULL);
2690 GOTO(out_close, rc);
2692 if (llog_get_size(llh) <= 1)
2693 GOTO(out_close, rc = 0);
2695 msrd.msrd_fsdb = fsdb;
2698 rc = llog_process(env, llh, mgs_srpc_read_handler, (void *)&msrd,
2702 llog_close(env, llh);
2704 llog_ctxt_put(ctxt);
2705 name_destroy(&logname);
2708 CERROR("failed to read sptlrpc config database: %d\n", rc);
2712 /* Permanent settings of all parameters by writing into the appropriate
2713 * configuration logs.
2714 * A parameter with null value ("<param>='\0'") means to erase it out of
2717 static int mgs_write_log_param(const struct lu_env *env,
2718 struct mgs_device *mgs, struct fs_db *fsdb,
2719 struct mgs_target_info *mti, char *ptr)
2721 struct mgs_thread_info *mgi = mgs_env_info(env);
2724 int rc = 0, rc2 = 0;
2727 /* For various parameter settings, we have to figure out which logs
2728 care about them (e.g. both mdt and client for lov settings) */
2729 CDEBUG(D_MGS, "next param '%s'\n", ptr);
2731 /* The params are stored in MOUNT_DATA_FILE and modified via
2732 tunefs.lustre, or set using lctl conf_param */
2734 /* Processed in lustre_start_mgc */
2735 if (class_match_param(ptr, PARAM_MGSNODE, NULL) == 0)
2738 /* Processed in ost/mdt */
2739 if (class_match_param(ptr, PARAM_NETWORK, NULL) == 0)
2742 /* Processed in mgs_write_log_ost */
2743 if (class_match_param(ptr, PARAM_FAILMODE, NULL) == 0) {
2744 if (mti->mti_flags & LDD_F_PARAM) {
2745 LCONSOLE_ERROR_MSG(0x169, "%s can only be "
2746 "changed with tunefs.lustre"
2747 "and --writeconf\n", ptr);
2753 if (class_match_param(ptr, PARAM_SRPC, NULL) == 0) {
2754 rc = mgs_srpc_set_param(env, mgs, fsdb, mti, ptr);
2758 if (class_match_param(ptr, PARAM_FAILNODE, NULL) == 0) {
2759 /* Add a failover nidlist */
2761 /* We already processed failovers params for new
2762 targets in mgs_write_log_target */
2763 if (mti->mti_flags & LDD_F_PARAM) {
2764 CDEBUG(D_MGS, "Adding failnode\n");
2765 rc = mgs_write_log_add_failnid(env, mgs, fsdb, mti);
2770 if (class_match_param(ptr, PARAM_SYS, &tmp) == 0) {
2771 rc = mgs_write_log_sys(env, mgs, fsdb, mti, ptr, tmp);
2775 if (class_match_param(ptr, PARAM_QUOTA, &tmp) == 0) {
2776 rc = mgs_write_log_quota(env, mgs, fsdb, mti, ptr, tmp);
2780 if (class_match_param(ptr, PARAM_OSC""PARAM_ACTIVE, &tmp) == 0) {
2781 /* active=0 means off, anything else means on */
2782 int flag = (*tmp == '0') ? CM_EXCLUDE : 0;
2785 if (!(mti->mti_flags & LDD_F_SV_TYPE_OST)) {
2786 LCONSOLE_ERROR_MSG(0x144, "%s: Only OSCs can "
2787 "be (de)activated.\n",
2789 GOTO(end, rc = -EINVAL);
2791 LCONSOLE_WARN("Permanently %sactivating %s\n",
2792 flag ? "de": "re", mti->mti_svname);
2794 rc = name_create(&logname, mti->mti_fsname, "-client");
2797 rc = mgs_modify(env, mgs, fsdb, mti, logname,
2798 mti->mti_svname, "add osc", flag);
2799 name_destroy(&logname);
2803 /* Add to all MDT logs for CMD */
2804 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2805 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
2807 rc = name_create_mdt(&logname, mti->mti_fsname, i);
2810 rc = mgs_modify(env, mgs, fsdb, mti, logname,
2811 mti->mti_svname, "add osc", flag);
2812 name_destroy(&logname);
2818 LCONSOLE_ERROR_MSG(0x145, "Couldn't find %s in"
2819 "log (%d). No permanent "
2820 "changes were made to the "
2822 mti->mti_svname, rc);
2823 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags))
2824 LCONSOLE_ERROR_MSG(0x146, "This may be"
2829 "update the logs.\n");
2832 /* Fall through to osc proc for deactivating live OSC
2833 on running MDT / clients. */
2835 /* Below here, let obd's XXX_process_config methods handle it */
2837 /* All lov. in proc */
2838 if (class_match_param(ptr, PARAM_LOV, NULL) == 0) {
2841 CDEBUG(D_MGS, "lov param %s\n", ptr);
2842 if (!(mti->mti_flags & LDD_F_SV_TYPE_MDT)) {
2843 LCONSOLE_ERROR_MSG(0x147, "LOV params must be "
2844 "set on the MDT, not %s. "
2851 if (mgs_log_is_empty(env, mgs, mti->mti_svname))
2852 GOTO(end, rc = -ENODEV);
2854 rc = name_create_mdt_and_lov(&logname, &mdtlovname, fsdb,
2855 mti->mti_stripe_index);
2858 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, mti->mti_svname,
2859 &mgi->mgi_bufs, mdtlovname, ptr);
2860 name_destroy(&logname);
2861 name_destroy(&mdtlovname);
2866 rc = name_create(&logname, mti->mti_fsname, "-client");
2869 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname, &mgi->mgi_bufs,
2870 fsdb->fsdb_clilov, ptr);
2871 name_destroy(&logname);
2875 /* All osc., mdc., llite. params in proc */
2876 if ((class_match_param(ptr, PARAM_OSC, NULL) == 0) ||
2877 (class_match_param(ptr, PARAM_MDC, NULL) == 0) ||
2878 (class_match_param(ptr, PARAM_LLITE, NULL) == 0)) {
2881 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
2882 LCONSOLE_ERROR_MSG(0x148, "Upgraded client logs for %s"
2883 " cannot be modified. Consider"
2884 " updating the configuration with"
2887 GOTO(end, rc = -EINVAL);
2889 if (memcmp(ptr, PARAM_LLITE, strlen(PARAM_LLITE)) == 0) {
2890 rc = name_create(&cname, mti->mti_fsname, "-client");
2891 /* Add the client type to match the obdname in
2892 class_config_llog_handler */
2893 } else if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
2894 rc = name_create(&cname, mti->mti_svname, "-mdc");
2895 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2896 rc = name_create(&cname, mti->mti_svname, "-osc");
2898 GOTO(end, rc = -EINVAL);
2903 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
2906 rc = name_create(&logname, mti->mti_fsname, "-client");
2908 name_destroy(&cname);
2911 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname, &mgi->mgi_bufs,
2914 /* osc params affect the MDT as well */
2915 if (!rc && (mti->mti_flags & LDD_F_SV_TYPE_OST)) {
2918 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
2919 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
2921 name_destroy(&cname);
2922 rc = name_create_mdt_osc(&cname, mti->mti_svname,
2924 name_destroy(&logname);
2927 rc = name_create_mdt(&logname,
2928 mti->mti_fsname, i);
2931 if (!mgs_log_is_empty(env, mgs, logname)) {
2932 rc = mgs_wlp_lcfg(env, mgs, fsdb,
2941 name_destroy(&logname);
2942 name_destroy(&cname);
2946 /* All mdt. params in proc */
2947 if (class_match_param(ptr, PARAM_MDT, NULL) == 0) {
2951 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
2952 if (strncmp(mti->mti_svname, mti->mti_fsname,
2953 MTI_NAME_MAXLEN) == 0)
2954 /* device is unspecified completely? */
2955 rc = LDD_F_SV_TYPE_MDT | LDD_F_SV_ALL;
2957 rc = server_name2index(mti->mti_svname, &idx, NULL);
2960 if ((rc & LDD_F_SV_TYPE_MDT) == 0)
2962 if (rc & LDD_F_SV_ALL) {
2963 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2965 fsdb->fsdb_mdt_index_map))
2967 rc = name_create_mdt(&logname,
2968 mti->mti_fsname, i);
2971 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti,
2972 logname, &mgi->mgi_bufs,
2974 name_destroy(&logname);
2979 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti,
2980 mti->mti_svname, &mgi->mgi_bufs,
2981 mti->mti_svname, ptr);
2988 /* All mdd., ost. params in proc */
2989 if ((class_match_param(ptr, PARAM_MDD, NULL) == 0) ||
2990 (class_match_param(ptr, PARAM_OST, NULL) == 0)) {
2991 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
2992 if (mgs_log_is_empty(env, mgs, mti->mti_svname))
2993 GOTO(end, rc = -ENODEV);
2995 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, mti->mti_svname,
2996 &mgi->mgi_bufs, mti->mti_svname, ptr);
3000 LCONSOLE_WARN("Ignoring unrecognized param '%s'\n", ptr);
3005 CERROR("err %d on param '%s'\n", rc, ptr);
3010 /* Not implementing automatic failover nid addition at this time. */
3011 int mgs_check_failnid(const struct lu_env *env, struct mgs_device *mgs,
3012 struct mgs_target_info *mti)
3019 rc = mgs_find_or_make_fsdb(obd, fsname, &fsdb);
3023 if (mgs_log_is_empty(obd, mti->mti_svname))
3024 /* should never happen */
3027 CDEBUG(D_MGS, "Checking for new failnids for %s\n", mti->mti_svname);
3029 /* FIXME We can just check mti->params to see if we're already in
3030 the failover list. Modify mti->params for rewriting back at
3031 server_register_target(). */
3033 mutex_lock(&fsdb->fsdb_mutex);
3034 rc = mgs_write_log_add_failnid(obd, fsdb, mti);
3035 mutex_unlock(&fsdb->fsdb_mutex);
3042 int mgs_write_log_target(const struct lu_env *env,
3043 struct mgs_device *mgs,
3044 struct mgs_target_info *mti,
3051 /* set/check the new target index */
3052 rc = mgs_set_index(env, mgs, mti);
3054 CERROR("Can't get index (%d)\n", rc);
3058 if (rc == EALREADY) {
3059 LCONSOLE_WARN("Found index %d for %s, updating log\n",
3060 mti->mti_stripe_index, mti->mti_svname);
3061 /* We would like to mark old log sections as invalid
3062 and add new log sections in the client and mdt logs.
3063 But if we add new sections, then live clients will
3064 get repeat setup instructions for already running
3065 osc's. So don't update the client/mdt logs. */
3066 mti->mti_flags &= ~LDD_F_UPDATE;
3069 mutex_lock(&fsdb->fsdb_mutex);
3071 if (mti->mti_flags &
3072 (LDD_F_VIRGIN | LDD_F_UPGRADE14 | LDD_F_WRITECONF)) {
3073 /* Generate a log from scratch */
3074 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
3075 rc = mgs_write_log_mdt(env, mgs, fsdb, mti);
3076 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
3077 rc = mgs_write_log_ost(env, mgs, fsdb, mti);
3079 CERROR("Unknown target type %#x, can't create log for "
3080 "%s\n", mti->mti_flags, mti->mti_svname);
3083 CERROR("Can't write logs for %s (%d)\n",
3084 mti->mti_svname, rc);
3088 /* Just update the params from tunefs in mgs_write_log_params */
3089 CDEBUG(D_MGS, "Update params for %s\n", mti->mti_svname);
3090 mti->mti_flags |= LDD_F_PARAM;
3093 /* allocate temporary buffer, where class_get_next_param will
3094 make copy of a current parameter */
3095 OBD_ALLOC(buf, strlen(mti->mti_params) + 1);
3097 GOTO(out_up, rc = -ENOMEM);
3098 params = mti->mti_params;
3099 while (params != NULL) {
3100 rc = class_get_next_param(¶ms, buf);
3103 /* there is no next parameter, that is
3108 CDEBUG(D_MGS, "remaining string: '%s', param: '%s'\n",
3110 rc = mgs_write_log_param(env, mgs, fsdb, mti, buf);
3115 OBD_FREE(buf, strlen(mti->mti_params) + 1);
3118 mutex_unlock(&fsdb->fsdb_mutex);
3122 int mgs_erase_log(const struct lu_env *env, struct mgs_device *mgs, char *name)
3124 struct llog_ctxt *ctxt;
3127 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
3129 CERROR("%s: MGS config context doesn't exist\n",
3130 mgs->mgs_obd->obd_name);
3133 rc = llog_erase(env, ctxt, NULL, name);
3134 /* llog may not exist */
3137 llog_ctxt_put(ctxt);
3141 CERROR("%s: failed to clear log %s: %d\n",
3142 mgs->mgs_obd->obd_name, name, rc);
3147 /* erase all logs for the given fs */
3148 int mgs_erase_logs(const struct lu_env *env, struct mgs_device *mgs, char *fsname)
3152 struct mgs_direntry *dirent, *n;
3153 int rc, len = strlen(fsname);
3157 /* Find all the logs in the CONFIGS directory */
3158 rc = class_dentry_readdir(env, mgs, &list);
3162 mutex_lock(&mgs->mgs_mutex);
3164 /* Delete the fs db */
3165 fsdb = mgs_find_fsdb(mgs, fsname);
3167 mgs_free_fsdb(mgs, fsdb);
3169 mutex_unlock(&mgs->mgs_mutex);
3171 cfs_list_for_each_entry_safe(dirent, n, &list, list) {
3172 cfs_list_del(&dirent->list);
3173 suffix = strrchr(dirent->name, '-');
3174 if (suffix != NULL) {
3175 if ((len == suffix - dirent->name) &&
3176 (strncmp(fsname, dirent->name, len) == 0)) {
3177 CDEBUG(D_MGS, "Removing log %s\n",
3179 mgs_erase_log(env, mgs, dirent->name);
3182 mgs_direntry_free(dirent);
3188 /* from llog_swab */
3189 static void print_lustre_cfg(struct lustre_cfg *lcfg)
3194 CDEBUG(D_MGS, "lustre_cfg: %p\n", lcfg);
3195 CDEBUG(D_MGS, "\tlcfg->lcfg_version: %#x\n", lcfg->lcfg_version);
3197 CDEBUG(D_MGS, "\tlcfg->lcfg_command: %#x\n", lcfg->lcfg_command);
3198 CDEBUG(D_MGS, "\tlcfg->lcfg_num: %#x\n", lcfg->lcfg_num);
3199 CDEBUG(D_MGS, "\tlcfg->lcfg_flags: %#x\n", lcfg->lcfg_flags);
3200 CDEBUG(D_MGS, "\tlcfg->lcfg_nid: %s\n", libcfs_nid2str(lcfg->lcfg_nid));
3202 CDEBUG(D_MGS, "\tlcfg->lcfg_bufcount: %d\n", lcfg->lcfg_bufcount);
3203 if (lcfg->lcfg_bufcount < LUSTRE_CFG_MAX_BUFCOUNT)
3204 for (i = 0; i < lcfg->lcfg_bufcount; i++) {
3205 CDEBUG(D_MGS, "\tlcfg->lcfg_buflens[%d]: %d %s\n",
3206 i, lcfg->lcfg_buflens[i],
3207 lustre_cfg_string(lcfg, i));
3212 /* Set a permanent (config log) param for a target or fs
3213 * \param lcfg buf0 may contain the device (testfs-MDT0000) name
3214 * buf1 contains the single parameter
3216 int mgs_setparam(const struct lu_env *env, struct mgs_device *mgs,
3217 struct lustre_cfg *lcfg, char *fsname)
3220 struct mgs_target_info *mti;
3221 char *devname, *param;
3227 print_lustre_cfg(lcfg);
3229 /* lustre, lustre-mdtlov, lustre-client, lustre-MDT0000 */
3230 devname = lustre_cfg_string(lcfg, 0);
3231 param = lustre_cfg_string(lcfg, 1);
3233 /* Assume device name embedded in param:
3234 lustre-OST0000.osc.max_dirty_mb=32 */
3235 ptr = strchr(param, '.');
3243 LCONSOLE_ERROR_MSG(0x14d, "No target specified: %s\n", param);
3247 /* Extract fsname */
3248 ptr = strrchr(devname, '-');
3249 memset(fsname, 0, MTI_NAME_MAXLEN);
3250 if (ptr && (server_name2index(ptr, &index, NULL) >= 0)) {
3251 /* param related to llite isn't allowed to set by OST or MDT */
3252 if (strncmp(param, PARAM_LLITE, sizeof(PARAM_LLITE)) == 0)
3255 strncpy(fsname, devname, ptr - devname);
3257 /* assume devname is the fsname */
3258 strncpy(fsname, devname, MTI_NAME_MAXLEN);
3260 fsname[MTI_NAME_MAXLEN - 1] = 0;
3261 CDEBUG(D_MGS, "setparam fs='%s' device='%s'\n", fsname, devname);
3263 rc = mgs_find_or_make_fsdb(env, mgs, fsname, &fsdb);
3266 if (!test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags) &&
3267 test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
3268 CERROR("No filesystem targets for %s. cfg_device from lctl "
3269 "is '%s'\n", fsname, devname);
3270 mgs_free_fsdb(mgs, fsdb);
3274 /* Create a fake mti to hold everything */
3277 GOTO(out, rc = -ENOMEM);
3278 strncpy(mti->mti_fsname, fsname, MTI_NAME_MAXLEN);
3279 strncpy(mti->mti_svname, devname, MTI_NAME_MAXLEN);
3280 strncpy(mti->mti_params, param, sizeof(mti->mti_params));
3281 rc = server_name2index(mti->mti_svname, &mti->mti_stripe_index, &tmp);
3283 /* Not a valid server; may be only fsname */
3286 /* Strip -osc or -mdc suffix from svname */
3287 if (server_make_name(rc, mti->mti_stripe_index, mti->mti_fsname,
3289 GOTO(out, rc = -EINVAL);
3291 mti->mti_flags = rc | LDD_F_PARAM;
3293 mutex_lock(&fsdb->fsdb_mutex);
3294 rc = mgs_write_log_param(env, mgs, fsdb, mti, mti->mti_params);
3295 mutex_unlock(&fsdb->fsdb_mutex);
3298 * Revoke lock so everyone updates. Should be alright if
3299 * someone was already reading while we were updating the logs,
3300 * so we don't really need to hold the lock while we're
3303 mgs_revoke_lock(mgs, fsdb, CONFIG_T_CONFIG);
3309 static int mgs_write_log_pool(const struct lu_env *env,
3310 struct mgs_device *mgs, char *logname,
3311 struct fs_db *fsdb, char *lovname,
3312 enum lcfg_command_type cmd,
3313 char *poolname, char *fsname,
3314 char *ostname, char *comment)
3316 struct llog_handle *llh = NULL;
3319 rc = record_start_log(env, mgs, &llh, logname);
3322 rc = record_marker(env, llh, fsdb, CM_START, lovname, comment);
3325 rc = record_base(env, llh, lovname, 0, cmd, poolname, fsname, ostname, 0);
3328 rc = record_marker(env, llh, fsdb, CM_END, lovname, comment);
3330 record_end_log(env, &llh);
3334 int mgs_pool_cmd(const struct lu_env *env, struct mgs_device *mgs,
3335 enum lcfg_command_type cmd, char *fsname,
3336 char *poolname, char *ostname)
3341 char *label = NULL, *canceled_label = NULL;
3343 struct mgs_target_info *mti = NULL;
3347 rc = mgs_find_or_make_fsdb(env, mgs, fsname, &fsdb);
3349 CERROR("Can't get db for %s\n", fsname);
3352 if (test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
3353 CERROR("%s is not defined\n", fsname);
3354 mgs_free_fsdb(mgs, fsdb);
3358 label_sz = 10 + strlen(fsname) + strlen(poolname);
3360 /* check if ostname match fsname */
3361 if (ostname != NULL) {
3364 ptr = strrchr(ostname, '-');
3365 if ((ptr == NULL) ||
3366 (strncmp(fsname, ostname, ptr-ostname) != 0))
3368 label_sz += strlen(ostname);
3371 OBD_ALLOC(label, label_sz);
3378 "new %s.%s", fsname, poolname);
3382 "add %s.%s.%s", fsname, poolname, ostname);
3385 OBD_ALLOC(canceled_label, label_sz);
3386 if (canceled_label == NULL)
3387 GOTO(out_label, rc = -ENOMEM);
3389 "rem %s.%s.%s", fsname, poolname, ostname);
3390 sprintf(canceled_label,
3391 "add %s.%s.%s", fsname, poolname, ostname);
3394 OBD_ALLOC(canceled_label, label_sz);
3395 if (canceled_label == NULL)
3396 GOTO(out_label, rc = -ENOMEM);
3398 "del %s.%s", fsname, poolname);
3399 sprintf(canceled_label,
3400 "new %s.%s", fsname, poolname);
3406 mutex_lock(&fsdb->fsdb_mutex);
3408 if (canceled_label != NULL) {
3411 GOTO(out_cancel, rc = -ENOMEM);
3414 /* write pool def to all MDT logs */
3415 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3416 if (test_bit(i, fsdb->fsdb_mdt_index_map)) {
3417 rc = name_create_mdt_and_lov(&logname, &lovname,
3420 mutex_unlock(&fsdb->fsdb_mutex);
3423 if (canceled_label != NULL) {
3424 strcpy(mti->mti_svname, "lov pool");
3425 rc = mgs_modify(env, mgs, fsdb, mti, logname,
3426 lovname, canceled_label,
3431 rc = mgs_write_log_pool(env, mgs, logname,
3435 name_destroy(&logname);
3436 name_destroy(&lovname);
3438 mutex_unlock(&fsdb->fsdb_mutex);
3444 rc = name_create(&logname, fsname, "-client");
3446 mutex_unlock(&fsdb->fsdb_mutex);
3449 if (canceled_label != NULL) {
3450 rc = mgs_modify(env, mgs, fsdb, mti, logname,
3451 fsdb->fsdb_clilov, canceled_label, CM_SKIP);
3453 mutex_unlock(&fsdb->fsdb_mutex);
3454 name_destroy(&logname);
3459 rc = mgs_write_log_pool(env, mgs, logname, fsdb, fsdb->fsdb_clilov,
3460 cmd, fsname, poolname, ostname, label);
3461 mutex_unlock(&fsdb->fsdb_mutex);
3462 name_destroy(&logname);
3463 /* request for update */
3464 mgs_revoke_lock(mgs, fsdb, CONFIG_T_CONFIG);
3471 if (canceled_label != NULL)
3472 OBD_FREE(canceled_label, label_sz);
3474 OBD_FREE(label, label_sz);
3479 /******************** unused *********************/
3480 static int mgs_backup_llog(struct obd_device *obd, char* fsname)
3482 struct file *filp, *bak_filp;
3483 struct lvfs_run_ctxt saved;
3484 char *logname, *buf;
3485 loff_t soff = 0 , doff = 0;
3486 int count = 4096, len;
3489 OBD_ALLOC(logname, PATH_MAX);
3490 if (logname == NULL)
3493 OBD_ALLOC(buf, count);
3495 GOTO(out , rc = -ENOMEM);
3497 len = snprintf(logname, PATH_MAX, "%s/%s.bak",
3498 MOUNT_CONFIGS_DIR, fsname);
3500 if (len >= PATH_MAX - 1) {
3501 GOTO(out, -ENAMETOOLONG);
3504 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
3506 bak_filp = l_filp_open(logname, O_RDWR|O_CREAT|O_TRUNC, 0660);
3507 if (IS_ERR(bak_filp)) {
3508 rc = PTR_ERR(bak_filp);
3509 CERROR("backup logfile open %s: %d\n", logname, rc);
3512 sprintf(logname, "%s/%s", MOUNT_CONFIGS_DIR, fsname);
3513 filp = l_filp_open(logname, O_RDONLY, 0);
3516 CERROR("logfile open %s: %d\n", logname, rc);
3520 while ((rc = lustre_fread(filp, buf, count, &soff)) > 0) {
3521 rc = lustre_fwrite(bak_filp, buf, count, &doff);
3525 filp_close(filp, 0);
3527 filp_close(bak_filp, 0);
3529 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
3532 OBD_FREE(buf, count);
3533 OBD_FREE(logname, PATH_MAX);