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>
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 mgs_steal_llog_handler(const struct lu_env *env,
1110 struct llog_handle *llh,
1111 struct llog_rec_hdr *rec, void *data)
1113 struct mgs_device *mgs;
1114 struct obd_device *obd;
1115 struct mgs_target_info *mti, *tmti;
1117 int cfg_len = rec->lrh_len;
1118 char *cfg_buf = (char*) (rec + 1);
1119 struct lustre_cfg *lcfg;
1121 struct llog_handle *mdt_llh = NULL;
1122 static int got_an_osc_or_mdc = 0;
1123 /* 0: not found any osc/mdc;
1127 static int last_step = -1;
1131 mti = ((struct temp_comp*)data)->comp_mti;
1132 tmti = ((struct temp_comp*)data)->comp_tmti;
1133 fsdb = ((struct temp_comp*)data)->comp_fsdb;
1134 obd = ((struct temp_comp *)data)->comp_obd;
1135 mgs = lu2mgs_dev(obd->obd_lu_dev);
1138 if (rec->lrh_type != OBD_CFG_REC) {
1139 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
1143 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
1145 CERROR("Insane cfg\n");
1149 lcfg = (struct lustre_cfg *)cfg_buf;
1151 if (lcfg->lcfg_command == LCFG_MARKER) {
1152 struct cfg_marker *marker;
1153 marker = lustre_cfg_buf(lcfg, 1);
1154 if (!strncmp(marker->cm_comment,"add osc",7) &&
1155 (marker->cm_flags & CM_START)){
1156 got_an_osc_or_mdc = 1;
1157 strncpy(tmti->mti_svname, marker->cm_tgtname,
1158 sizeof(tmti->mti_svname));
1159 rc = record_start_log(env, mgs, &mdt_llh,
1163 rc = record_marker(env, mdt_llh, fsdb, CM_START,
1164 mti->mti_svname,"add osc(copied)");
1165 record_end_log(env, &mdt_llh);
1166 last_step = marker->cm_step;
1169 if (!strncmp(marker->cm_comment,"add osc",7) &&
1170 (marker->cm_flags & CM_END)){
1171 LASSERT(last_step == marker->cm_step);
1173 got_an_osc_or_mdc = 0;
1174 rc = record_start_log(env, mgs, &mdt_llh,
1178 rc = record_marker(env, mdt_llh, fsdb, CM_END,
1179 mti->mti_svname,"add osc(copied)");
1180 record_end_log(env, &mdt_llh);
1183 if (!strncmp(marker->cm_comment,"add mdc",7) &&
1184 (marker->cm_flags & CM_START)){
1185 got_an_osc_or_mdc = 2;
1186 last_step = marker->cm_step;
1187 memcpy(tmti->mti_svname, marker->cm_tgtname,
1188 strlen(marker->cm_tgtname));
1192 if (!strncmp(marker->cm_comment,"add mdc",7) &&
1193 (marker->cm_flags & CM_END)){
1194 LASSERT(last_step == marker->cm_step);
1196 got_an_osc_or_mdc = 0;
1201 if (got_an_osc_or_mdc == 0 || last_step < 0)
1204 if (lcfg->lcfg_command == LCFG_ADD_UUID) {
1206 nodenid = lcfg->lcfg_nid;
1208 tmti->mti_nids[tmti->mti_nid_count] = nodenid;
1209 tmti->mti_nid_count++;
1214 if (lcfg->lcfg_command == LCFG_SETUP) {
1217 target = lustre_cfg_string(lcfg, 1);
1218 memcpy(tmti->mti_uuid, target, strlen(target));
1222 /* ignore client side sptlrpc_conf_log */
1223 if (lcfg->lcfg_command == LCFG_SPTLRPC_CONF)
1226 if (lcfg->lcfg_command == LCFG_ADD_MDC) {
1229 if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1)
1232 memcpy(tmti->mti_fsname, mti->mti_fsname,
1233 strlen(mti->mti_fsname));
1234 tmti->mti_stripe_index = index;
1236 rc = mgs_write_log_mdc_to_mdt(env, mgs, fsdb, tmti,
1238 memset(tmti, 0, sizeof(*tmti));
1242 if (lcfg->lcfg_command == LCFG_LOV_ADD_OBD) {
1245 char *logname, *lovname;
1247 rc = name_create_mdt_and_lov(&logname, &lovname, fsdb,
1248 mti->mti_stripe_index);
1251 sprintf(mdt_index, "-MDT%04x", mti->mti_stripe_index);
1253 if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1) {
1254 name_destroy(&logname);
1255 name_destroy(&lovname);
1259 tmti->mti_stripe_index = index;
1260 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, tmti, logname,
1263 name_destroy(&logname);
1264 name_destroy(&lovname);
1270 /* fsdb->fsdb_mutex is already held in mgs_write_log_target*/
1271 /* stealed from mgs_get_fsdb_from_llog*/
1272 static int mgs_steal_llog_for_mdt_from_client(const struct lu_env *env,
1273 struct mgs_device *mgs,
1275 struct temp_comp* comp)
1277 struct llog_handle *loghandle;
1278 struct mgs_target_info *tmti;
1279 struct llog_ctxt *ctxt;
1284 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
1285 LASSERT(ctxt != NULL);
1287 OBD_ALLOC_PTR(tmti);
1289 GOTO(out_ctxt, rc = -ENOMEM);
1291 comp->comp_tmti = tmti;
1292 comp->comp_obd = mgs->mgs_obd;
1294 rc = llog_open(env, ctxt, &loghandle, NULL, client_name,
1302 rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL);
1304 GOTO(out_close, rc);
1306 rc = llog_process_or_fork(env, loghandle, mgs_steal_llog_handler,
1307 (void *)comp, NULL, false);
1308 CDEBUG(D_MGS, "steal llog re = %d\n", rc);
1310 llog_close(env, loghandle);
1314 llog_ctxt_put(ctxt);
1318 /* lmv is the second thing for client logs */
1319 /* copied from mgs_write_log_lov. Please refer to that. */
1320 static int mgs_write_log_lmv(const struct lu_env *env,
1321 struct mgs_device *mgs,
1323 struct mgs_target_info *mti,
1324 char *logname, char *lmvname)
1326 struct llog_handle *llh = NULL;
1327 struct lmv_desc *lmvdesc;
1332 CDEBUG(D_MGS, "Writing lmv(%s) log for %s\n", lmvname,logname);
1334 OBD_ALLOC_PTR(lmvdesc);
1335 if (lmvdesc == NULL)
1337 lmvdesc->ld_active_tgt_count = 0;
1338 lmvdesc->ld_tgt_count = 0;
1339 sprintf((char*)lmvdesc->ld_uuid.uuid, "%s_UUID", lmvname);
1340 uuid = (char *)lmvdesc->ld_uuid.uuid;
1342 rc = record_start_log(env, mgs, &llh, logname);
1345 rc = record_marker(env, llh, fsdb, CM_START, lmvname, "lmv setup");
1348 rc = record_attach(env, llh, lmvname, "lmv", uuid);
1351 rc = record_lmv_setup(env, llh, lmvname, lmvdesc);
1354 rc = record_marker(env, llh, fsdb, CM_END, lmvname, "lmv setup");
1358 record_end_log(env, &llh);
1360 OBD_FREE_PTR(lmvdesc);
1364 /* lov is the first thing in the mdt and client logs */
1365 static int mgs_write_log_lov(const struct lu_env *env, struct mgs_device *mgs,
1366 struct fs_db *fsdb, struct mgs_target_info *mti,
1367 char *logname, char *lovname)
1369 struct llog_handle *llh = NULL;
1370 struct lov_desc *lovdesc;
1375 CDEBUG(D_MGS, "Writing lov(%s) log for %s\n", lovname, logname);
1378 #01 L attach 0:lov_mdsA 1:lov 2:71ccb_lov_mdsA_19f961a9e1
1379 #02 L lov_setup 0:lov_mdsA 1:(struct lov_desc)
1380 uuid=lov1_UUID, stripe count=1, size=1048576, offset=0, pattern=0
1383 /* FIXME just make lov_setup accept empty desc (put uuid in buf 2) */
1384 OBD_ALLOC_PTR(lovdesc);
1385 if (lovdesc == NULL)
1387 lovdesc->ld_magic = LOV_DESC_MAGIC;
1388 lovdesc->ld_tgt_count = 0;
1389 /* Defaults. Can be changed later by lcfg config_param */
1390 lovdesc->ld_default_stripe_count = 1;
1391 lovdesc->ld_pattern = LOV_PATTERN_RAID0;
1392 lovdesc->ld_default_stripe_size = 1024 * 1024;
1393 lovdesc->ld_default_stripe_offset = -1;
1394 lovdesc->ld_qos_maxage = QOS_DEFAULT_MAXAGE;
1395 sprintf((char*)lovdesc->ld_uuid.uuid, "%s_UUID", lovname);
1396 /* can these be the same? */
1397 uuid = (char *)lovdesc->ld_uuid.uuid;
1399 /* This should always be the first entry in a log.
1400 rc = mgs_clear_log(obd, logname); */
1401 rc = record_start_log(env, mgs, &llh, logname);
1404 /* FIXME these should be a single journal transaction */
1405 rc = record_marker(env, llh, fsdb, CM_START, lovname, "lov setup");
1408 rc = record_attach(env, llh, lovname, "lov", uuid);
1411 rc = record_lov_setup(env, llh, lovname, lovdesc);
1414 rc = record_marker(env, llh, fsdb, CM_END, lovname, "lov setup");
1419 record_end_log(env, &llh);
1421 OBD_FREE_PTR(lovdesc);
1425 /* add failnids to open log */
1426 static int mgs_write_log_failnids(const struct lu_env *env,
1427 struct mgs_target_info *mti,
1428 struct llog_handle *llh,
1431 char *failnodeuuid = NULL;
1432 char *ptr = mti->mti_params;
1437 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) nal=90 0: 1:uml1_UUID
1438 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
1439 #05 L setup 0:OSC_uml1_ost1_mdsA 1:ost1_UUID 2:uml1_UUID
1440 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) nal=90 0: 1:uml2_UUID
1441 #0x L add_uuid nid=2@elan(0x1000000000002) nal=90 0: 1:uml2_UUID
1442 #07 L add_conn 0:OSC_uml1_ost1_mdsA 1:uml2_UUID
1445 /* Pull failnid info out of params string */
1446 while (class_find_param(ptr, PARAM_FAILNODE, &ptr) == 0) {
1447 while (class_parse_nid(ptr, &nid, &ptr) == 0) {
1448 if (failnodeuuid == NULL) {
1449 /* We don't know the failover node name,
1450 so just use the first nid as the uuid */
1451 rc = name_create(&failnodeuuid,
1452 libcfs_nid2str(nid), "");
1456 CDEBUG(D_MGS, "add nid %s for failover uuid %s, "
1457 "client %s\n", libcfs_nid2str(nid),
1458 failnodeuuid, cliname);
1459 rc = record_add_uuid(env, llh, nid, failnodeuuid);
1462 rc = record_add_conn(env, llh, cliname, failnodeuuid);
1465 name_destroy(&failnodeuuid);
1469 static int mgs_write_log_mdc_to_lmv(const struct lu_env *env,
1470 struct mgs_device *mgs,
1472 struct mgs_target_info *mti,
1473 char *logname, char *lmvname)
1475 struct llog_handle *llh = NULL;
1476 char *mdcname = NULL;
1477 char *nodeuuid = NULL;
1478 char *mdcuuid = NULL;
1479 char *lmvuuid = NULL;
1484 if (mgs_log_is_empty(env, mgs, logname)) {
1485 CERROR("log is empty! Logical error\n");
1489 CDEBUG(D_MGS, "adding mdc for %s to log %s:lmv(%s)\n",
1490 mti->mti_svname, logname, lmvname);
1492 rc = name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
1495 rc = name_create(&mdcname, mti->mti_svname, "-mdc");
1498 rc = name_create(&mdcuuid, mdcname, "_UUID");
1501 rc = name_create(&lmvuuid, lmvname, "_UUID");
1505 rc = record_start_log(env, mgs, &llh, logname);
1508 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
1512 for (i = 0; i < mti->mti_nid_count; i++) {
1513 CDEBUG(D_MGS, "add nid %s for mdt\n",
1514 libcfs_nid2str(mti->mti_nids[i]));
1516 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
1521 rc = record_attach(env, llh, mdcname, LUSTRE_MDC_NAME, lmvuuid);
1524 rc = record_setup(env, llh, mdcname, mti->mti_uuid, nodeuuid, 0, 0);
1527 rc = mgs_write_log_failnids(env, mti, llh, mdcname);
1530 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
1531 rc = record_mdc_add(env, llh, lmvname, mdcuuid, mti->mti_uuid,
1535 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname,
1540 record_end_log(env, &llh);
1542 name_destroy(&lmvuuid);
1543 name_destroy(&mdcuuid);
1544 name_destroy(&mdcname);
1545 name_destroy(&nodeuuid);
1549 /* add new mdc to already existent MDS */
1550 static int mgs_write_log_mdc_to_mdt(const struct lu_env *env,
1551 struct mgs_device *mgs,
1553 struct mgs_target_info *mti,
1556 struct llog_handle *llh = NULL;
1557 char *nodeuuid = NULL;
1558 char *mdcname = NULL;
1559 char *mdcuuid = NULL;
1560 char *mdtuuid = NULL;
1561 int idx = mti->mti_stripe_index;
1566 if (mgs_log_is_empty(env, mgs, logname)) {
1567 CERROR("log is empty! Logical error\n");
1571 CDEBUG(D_MGS, "adding mdc index %d to %s\n", idx, logname);
1573 rc = name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
1576 snprintf(index, sizeof(index), "-mdc%04x", idx);
1577 rc = name_create(&mdcname, logname, index);
1580 rc = name_create(&mdcuuid, mdcname, "_UUID");
1583 rc = name_create(&mdtuuid, logname, "_UUID");
1587 rc = record_start_log(env, mgs, &llh, logname);
1590 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname, "add mdc");
1593 for (i = 0; i < mti->mti_nid_count; i++) {
1594 CDEBUG(D_MGS, "add nid %s for mdt\n",
1595 libcfs_nid2str(mti->mti_nids[i]));
1596 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
1600 rc = record_attach(env, llh, mdcname, LUSTRE_MDC_NAME, mdcuuid);
1603 rc = record_setup(env, llh, mdcname, mti->mti_uuid, nodeuuid, 0, 0);
1606 rc = mgs_write_log_failnids(env, mti, llh, mdcname);
1609 snprintf(index, sizeof(index), "%d", idx);
1611 rc = record_mdc_add(env, llh, logname, mdcuuid, mti->mti_uuid,
1615 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname, "add mdc");
1619 record_end_log(env, &llh);
1621 name_destroy(&mdtuuid);
1622 name_destroy(&mdcuuid);
1623 name_destroy(&mdcname);
1624 name_destroy(&nodeuuid);
1628 static int mgs_write_log_mdt0(const struct lu_env *env,
1629 struct mgs_device *mgs,
1631 struct mgs_target_info *mti)
1633 char *log = mti->mti_svname;
1634 struct llog_handle *llh = NULL;
1635 char *uuid, *lovname;
1637 char *ptr = mti->mti_params;
1638 int rc = 0, failout = 0;
1641 OBD_ALLOC(uuid, sizeof(struct obd_uuid));
1645 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
1646 failout = (strncmp(ptr, "failout", 7) == 0);
1648 rc = name_create(&lovname, log, "-mdtlov");
1651 if (mgs_log_is_empty(env, mgs, log)) {
1652 rc = mgs_write_log_lov(env, mgs, fsdb, mti, log, lovname);
1657 sprintf(mdt_index, "%d", mti->mti_stripe_index);
1659 rc = record_start_log(env, mgs, &llh, log);
1663 /* add MDT itself */
1665 /* FIXME this whole fn should be a single journal transaction */
1666 sprintf(uuid, "%s_UUID", log);
1667 rc = record_marker(env, llh, fsdb, CM_START, log, "add mdt");
1670 rc = record_attach(env, llh, log, LUSTRE_MDT_NAME, uuid);
1673 rc = record_mount_opt(env, llh, log, lovname, NULL);
1676 rc = record_setup(env, llh, log, uuid, mdt_index, lovname,
1677 failout ? "n" : "f");
1680 rc = record_marker(env, llh, fsdb, CM_END, log, "add mdt");
1684 record_end_log(env, &llh);
1686 name_destroy(&lovname);
1688 OBD_FREE(uuid, sizeof(struct obd_uuid));
1692 static inline int name_create_mdt(char **logname, char *fsname, int i)
1696 sprintf(mdt_index, "-MDT%04x", i);
1697 return name_create(logname, fsname, mdt_index);
1700 static int name_create_mdt_and_lov(char **logname, char **lovname,
1701 struct fs_db *fsdb, int i)
1705 rc = name_create_mdt(logname, fsdb->fsdb_name, i);
1709 if (i == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
1710 rc = name_create(lovname, fsdb->fsdb_name, "-mdtlov");
1712 rc = name_create(lovname, *logname, "-mdtlov");
1714 name_destroy(logname);
1720 static inline int name_create_mdt_osc(char **oscname, char *ostname,
1721 struct fs_db *fsdb, int i)
1725 if (i == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
1726 sprintf(suffix, "-osc");
1728 sprintf(suffix, "-osc-MDT%04x", i);
1729 return name_create(oscname, ostname, suffix);
1732 /* envelope method for all layers log */
1733 static int mgs_write_log_mdt(const struct lu_env *env,
1734 struct mgs_device *mgs,
1736 struct mgs_target_info *mti)
1738 struct mgs_thread_info *mgi = mgs_env_info(env);
1739 struct llog_handle *llh = NULL;
1744 CDEBUG(D_MGS, "writing new mdt %s\n", mti->mti_svname);
1746 if (mti->mti_uuid[0] == '\0') {
1747 /* Make up our own uuid */
1748 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
1749 "%s_UUID", mti->mti_svname);
1753 rc = mgs_write_log_mdt0(env, mgs, fsdb, mti);
1756 /* Append the mdt info to the client log */
1757 rc = name_create(&cliname, mti->mti_fsname, "-client");
1761 if (mgs_log_is_empty(env, mgs, cliname)) {
1762 /* Start client log */
1763 rc = mgs_write_log_lov(env, mgs, fsdb, mti, cliname,
1767 rc = mgs_write_log_lmv(env, mgs, fsdb, mti, cliname,
1774 #09 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
1775 #10 L attach 0:MDC_uml1_mdsA_MNT_client 1:mdc 2:1d834_MNT_client_03f
1776 #11 L setup 0:MDC_uml1_mdsA_MNT_client 1:mdsA_UUID 2:uml1_UUID
1777 #12 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
1778 #13 L add_conn 0:MDC_uml1_mdsA_MNT_client 1:uml2_UUID
1779 #14 L mount_option 0: 1:client 2:lov1 3:MDC_uml1_mdsA_MNT_client
1782 /* copy client info about lov/lmv */
1783 mgi->mgi_comp.comp_mti = mti;
1784 mgi->mgi_comp.comp_fsdb = fsdb;
1786 rc = mgs_steal_llog_for_mdt_from_client(env, mgs, cliname,
1790 rc = mgs_write_log_mdc_to_lmv(env, mgs, fsdb, mti, cliname,
1796 rc = record_start_log(env, mgs, &llh, cliname);
1800 rc = record_marker(env, llh, fsdb, CM_START, cliname,
1804 rc = record_mount_opt(env, llh, cliname, fsdb->fsdb_clilov,
1808 rc = record_marker(env, llh, fsdb, CM_END, cliname,
1813 /* for_all_existing_mdt except current one */
1814 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
1816 if (i != mti->mti_stripe_index &&
1817 test_bit(i, fsdb->fsdb_mdt_index_map)) {
1818 rc = name_create_mdt(&mdtname, mti->mti_fsname, i);
1821 rc = mgs_write_log_mdc_to_mdt(env, mgs, fsdb, mti, mdtname);
1822 name_destroy(&mdtname);
1828 record_end_log(env, &llh);
1830 name_destroy(&cliname);
1834 /* Add the ost info to the client/mdt lov */
1835 static int mgs_write_log_osc_to_lov(const struct lu_env *env,
1836 struct mgs_device *mgs, struct fs_db *fsdb,
1837 struct mgs_target_info *mti,
1838 char *logname, char *suffix, char *lovname,
1839 enum lustre_sec_part sec_part, int flags)
1841 struct llog_handle *llh = NULL;
1842 char *nodeuuid = NULL;
1843 char *oscname = NULL;
1844 char *oscuuid = NULL;
1845 char *lovuuid = NULL;
1846 char *svname = NULL;
1851 CDEBUG(D_INFO, "adding osc for %s to log %s\n",
1852 mti->mti_svname, logname);
1854 if (mgs_log_is_empty(env, mgs, logname)) {
1855 CERROR("log is empty! Logical error\n");
1859 rc = name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
1862 rc = name_create(&svname, mti->mti_svname, "-osc");
1865 /* for the system upgraded from old 1.8, keep using the old osc naming
1866 * style for mdt, see name_create_mdt_osc(). LU-1257 */
1867 if (test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
1868 rc = name_create(&oscname, svname, "");
1870 rc = name_create(&oscname, svname, suffix);
1873 rc = name_create(&oscuuid, oscname, "_UUID");
1876 rc = name_create(&lovuuid, lovname, "_UUID");
1881 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
1883 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
1884 #04 L attach 0:OSC_uml1_ost1_MNT_client 1:osc 2:89070_lov1_a41dff51a
1885 #05 L setup 0:OSC_uml1_ost1_MNT_client 1:ost1_UUID 2:uml1_UUID
1887 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
1888 #07 L add_conn 0:OSC_uml1_ost1_MNT_client 1:uml2_UUID
1889 #08 L lov_modify_tgts add 0:lov1 1:ost1_UUID 2(index):0 3(gen):1
1892 rc = record_start_log(env, mgs, &llh, logname);
1895 /* FIXME these should be a single journal transaction */
1896 rc = record_marker(env, llh, fsdb, CM_START | flags, mti->mti_svname,
1900 for (i = 0; i < mti->mti_nid_count; i++) {
1901 CDEBUG(D_MGS, "add nid %s\n", libcfs_nid2str(mti->mti_nids[i]));
1902 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
1906 rc = record_attach(env, llh, oscname, LUSTRE_OSC_NAME, lovuuid);
1909 rc = record_setup(env, llh, oscname, mti->mti_uuid, nodeuuid, 0, 0);
1912 rc = mgs_write_log_failnids(env, mti, llh, oscname);
1915 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
1916 rc = record_lov_add(env, llh, lovname, mti->mti_uuid, index, "1");
1919 rc = record_marker(env, llh, fsdb, CM_END | flags, mti->mti_svname,
1924 record_end_log(env, &llh);
1926 name_destroy(&lovuuid);
1927 name_destroy(&oscuuid);
1928 name_destroy(&oscname);
1929 name_destroy(&svname);
1930 name_destroy(&nodeuuid);
1934 static int mgs_write_log_ost(const struct lu_env *env,
1935 struct mgs_device *mgs, struct fs_db *fsdb,
1936 struct mgs_target_info *mti)
1938 struct llog_handle *llh = NULL;
1939 char *logname, *lovname;
1940 char *ptr = mti->mti_params;
1941 int rc, flags = 0, failout = 0, i;
1944 CDEBUG(D_MGS, "writing new ost %s\n", mti->mti_svname);
1946 /* The ost startup log */
1948 /* If the ost log already exists, that means that someone reformatted
1949 the ost and it called target_add again. */
1950 if (!mgs_log_is_empty(env, mgs, mti->mti_svname)) {
1951 LCONSOLE_ERROR_MSG(0x141, "The config log for %s already "
1952 "exists, yet the server claims it never "
1953 "registered. It may have been reformatted, "
1954 "or the index changed. writeconf the MDT to "
1955 "regenerate all logs.\n", mti->mti_svname);
1960 attach obdfilter ost1 ost1_UUID
1961 setup /dev/loop2 ldiskfs f|n errors=remount-ro,user_xattr
1963 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
1964 failout = (strncmp(ptr, "failout", 7) == 0);
1965 rc = record_start_log(env, mgs, &llh, mti->mti_svname);
1968 /* FIXME these should be a single journal transaction */
1969 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,"add ost");
1972 if (*mti->mti_uuid == '\0')
1973 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
1974 "%s_UUID", mti->mti_svname);
1975 rc = record_attach(env, llh, mti->mti_svname,
1976 "obdfilter"/*LUSTRE_OST_NAME*/, mti->mti_uuid);
1979 rc = record_setup(env, llh, mti->mti_svname,
1980 "dev"/*ignored*/, "type"/*ignored*/,
1981 failout ? "n" : "f", 0/*options*/);
1984 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname, "add ost");
1988 record_end_log(env, &llh);
1991 /* We also have to update the other logs where this osc is part of
1994 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
1995 /* If we're upgrading, the old mdt log already has our
1996 entry. Let's do a fake one for fun. */
1997 /* Note that we can't add any new failnids, since we don't
1998 know the old osc names. */
1999 flags = CM_SKIP | CM_UPGRADE146;
2001 } else if ((mti->mti_flags & LDD_F_UPDATE) != LDD_F_UPDATE) {
2002 /* If the update flag isn't set, don't update client/mdt
2005 LCONSOLE_WARN("Client log for %s was not updated; writeconf "
2006 "the MDT first to regenerate it.\n",
2010 /* Add ost to all MDT lov defs */
2011 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
2012 if (test_bit(i, fsdb->fsdb_mdt_index_map)) {
2015 rc = name_create_mdt_and_lov(&logname, &lovname, fsdb,
2019 sprintf(mdt_index, "-MDT%04x", i);
2020 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, mti,
2022 lovname, LUSTRE_SP_MDT,
2024 name_destroy(&logname);
2025 name_destroy(&lovname);
2031 /* Append ost info to the client log */
2032 rc = name_create(&logname, mti->mti_fsname, "-client");
2035 if (mgs_log_is_empty(env, mgs, logname)) {
2036 /* Start client log */
2037 rc = mgs_write_log_lov(env, mgs, fsdb, mti, logname,
2041 rc = mgs_write_log_lmv(env, mgs, fsdb, mti, logname,
2046 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, mti, logname, "",
2047 fsdb->fsdb_clilov, LUSTRE_SP_CLI, 0);
2049 name_destroy(&logname);
2053 static __inline__ int mgs_param_empty(char *ptr)
2057 if ((tmp = strchr(ptr, '=')) && (*(++tmp) == '\0'))
2062 static int mgs_write_log_failnid_internal(const struct lu_env *env,
2063 struct mgs_device *mgs,
2065 struct mgs_target_info *mti,
2066 char *logname, char *cliname)
2069 struct llog_handle *llh = NULL;
2071 if (mgs_param_empty(mti->mti_params)) {
2072 /* Remove _all_ failnids */
2073 rc = mgs_modify(env, mgs, fsdb, mti, logname,
2074 mti->mti_svname, "add failnid", CM_SKIP);
2075 return rc < 0 ? rc : 0;
2078 /* Otherwise failover nids are additive */
2079 rc = record_start_log(env, mgs, &llh, logname);
2082 /* FIXME this should be a single journal transaction */
2083 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
2087 rc = mgs_write_log_failnids(env, mti, llh, cliname);
2090 rc = record_marker(env, llh, fsdb, CM_END,
2091 mti->mti_svname, "add failnid");
2093 record_end_log(env, &llh);
2098 /* Add additional failnids to an existing log.
2099 The mdc/osc must have been added to logs first */
2100 /* tcp nids must be in dotted-quad ascii -
2101 we can't resolve hostnames from the kernel. */
2102 static int mgs_write_log_add_failnid(const struct lu_env *env,
2103 struct mgs_device *mgs,
2105 struct mgs_target_info *mti)
2107 char *logname, *cliname;
2111 /* FIXME we currently can't erase the failnids
2112 * given when a target first registers, since they aren't part of
2113 * an "add uuid" stanza */
2115 /* Verify that we know about this target */
2116 if (mgs_log_is_empty(env, mgs, mti->mti_svname)) {
2117 LCONSOLE_ERROR_MSG(0x142, "The target %s has not registered "
2118 "yet. It must be started before failnids "
2119 "can be added.\n", mti->mti_svname);
2123 /* Create mdc/osc client name (e.g. lustre-OST0001-osc) */
2124 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
2125 rc = name_create(&cliname, mti->mti_svname, "-mdc");
2126 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2127 rc = name_create(&cliname, mti->mti_svname, "-osc");
2133 /* Add failover nids to the client log */
2134 rc = name_create(&logname, mti->mti_fsname, "-client");
2136 name_destroy(&cliname);
2139 rc = mgs_write_log_failnid_internal(env, mgs, fsdb,mti,logname,cliname);
2140 name_destroy(&logname);
2141 name_destroy(&cliname);
2145 if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2146 /* Add OST failover nids to the MDT logs as well */
2149 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2150 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
2152 rc = name_create_mdt(&logname, mti->mti_fsname, i);
2155 rc = name_create_mdt_osc(&cliname, mti->mti_svname,
2158 name_destroy(&logname);
2161 rc = mgs_write_log_failnid_internal(env, mgs, fsdb,
2164 name_destroy(&cliname);
2165 name_destroy(&logname);
2174 static int mgs_wlp_lcfg(const struct lu_env *env,
2175 struct mgs_device *mgs, struct fs_db *fsdb,
2176 struct mgs_target_info *mti,
2177 char *logname, struct lustre_cfg_bufs *bufs,
2178 char *tgtname, char *ptr)
2180 char comment[MTI_NAME_MAXLEN];
2182 struct lustre_cfg *lcfg;
2185 /* Erase any old settings of this same parameter */
2186 memcpy(comment, ptr, MTI_NAME_MAXLEN);
2187 comment[MTI_NAME_MAXLEN - 1] = 0;
2188 /* But don't try to match the value. */
2189 if ((tmp = strchr(comment, '=')))
2191 /* FIXME we should skip settings that are the same as old values */
2192 rc = mgs_modify(env, mgs, fsdb, mti, logname, tgtname, comment,CM_SKIP);
2195 del = mgs_param_empty(ptr);
2197 LCONSOLE_INFO("%sing parameter %s.%s in log %s\n", del ? "Disabl" : rc ?
2198 "Sett" : "Modify", tgtname, comment, logname);
2202 lustre_cfg_bufs_reset(bufs, tgtname);
2203 lustre_cfg_bufs_set_string(bufs, 1, ptr);
2204 lcfg = lustre_cfg_new(LCFG_PARAM, bufs);
2207 rc = mgs_write_log_direct(env, mgs, fsdb, logname,lcfg,tgtname,comment);
2208 lustre_cfg_free(lcfg);
2212 /* write global variable settings into log */
2213 static int mgs_write_log_sys(const struct lu_env *env,
2214 struct mgs_device *mgs, struct fs_db *fsdb,
2215 struct mgs_target_info *mti, char *sys, char *ptr)
2217 struct mgs_thread_info *mgi = mgs_env_info(env);
2218 struct lustre_cfg *lcfg;
2220 int rc, cmd, convert = 1;
2222 if (class_match_param(ptr, PARAM_TIMEOUT, &tmp) == 0) {
2223 cmd = LCFG_SET_TIMEOUT;
2224 } else if (class_match_param(ptr, PARAM_LDLM_TIMEOUT, &tmp) == 0) {
2225 cmd = LCFG_SET_LDLM_TIMEOUT;
2226 /* Check for known params here so we can return error to lctl */
2227 } else if ((class_match_param(ptr, PARAM_AT_MIN, &tmp) == 0) ||
2228 (class_match_param(ptr, PARAM_AT_MAX, &tmp) == 0) ||
2229 (class_match_param(ptr, PARAM_AT_EXTRA, &tmp) == 0) ||
2230 (class_match_param(ptr, PARAM_AT_EARLY_MARGIN, &tmp) == 0) ||
2231 (class_match_param(ptr, PARAM_AT_HISTORY, &tmp) == 0)) {
2233 } else if (class_match_param(ptr, PARAM_JOBID_VAR, &tmp) == 0) {
2234 convert = 0; /* Don't convert string value to integer */
2240 if (mgs_param_empty(ptr))
2241 CDEBUG(D_MGS, "global '%s' removed\n", sys);
2243 CDEBUG(D_MGS, "global '%s' val=%s\n", sys, tmp);
2245 lustre_cfg_bufs_reset(&mgi->mgi_bufs, NULL);
2246 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, sys);
2247 if (!convert && *tmp != '\0')
2248 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 2, tmp);
2249 lcfg = lustre_cfg_new(cmd, &mgi->mgi_bufs);
2250 lcfg->lcfg_num = convert ? simple_strtoul(tmp, NULL, 0) : 0;
2251 /* truncate the comment to the parameter name */
2255 /* modify all servers and clients */
2256 rc = mgs_write_log_direct_all(env, mgs, fsdb, mti,
2257 *tmp == '\0' ? NULL : lcfg,
2258 mti->mti_fsname, sys, 0);
2259 if (rc == 0 && *tmp != '\0') {
2261 case LCFG_SET_TIMEOUT:
2262 if (!obd_timeout_set || lcfg->lcfg_num > obd_timeout)
2263 class_process_config(lcfg);
2265 case LCFG_SET_LDLM_TIMEOUT:
2266 if (!ldlm_timeout_set || lcfg->lcfg_num > ldlm_timeout)
2267 class_process_config(lcfg);
2274 lustre_cfg_free(lcfg);
2278 /* write quota settings into log */
2279 static int mgs_write_log_quota(const struct lu_env *env, struct mgs_device *mgs,
2280 struct fs_db *fsdb, struct mgs_target_info *mti,
2281 char *quota, char *ptr)
2283 struct mgs_thread_info *mgi = mgs_env_info(env);
2284 struct lustre_cfg *lcfg;
2287 int rc, cmd = LCFG_PARAM;
2289 /* support only 'meta' and 'data' pools so far */
2290 if (class_match_param(ptr, QUOTA_METAPOOL_NAME, &tmp) != 0 &&
2291 class_match_param(ptr, QUOTA_DATAPOOL_NAME, &tmp) != 0) {
2292 CERROR("parameter quota.%s isn't supported (only quota.mdt "
2293 "& quota.ost are)\n", ptr);
2298 CDEBUG(D_MGS, "global '%s' removed\n", quota);
2300 CDEBUG(D_MGS, "global '%s'\n", quota);
2302 if (strchr(tmp, 'u') == NULL && strchr(tmp, 'g') == NULL &&
2303 strcmp(tmp, "none") != 0) {
2304 CERROR("enable option(%s) isn't supported\n", tmp);
2309 lustre_cfg_bufs_reset(&mgi->mgi_bufs, mti->mti_fsname);
2310 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, quota);
2311 lcfg = lustre_cfg_new(cmd, &mgi->mgi_bufs);
2312 /* truncate the comment to the parameter name */
2317 /* XXX we duplicated quota enable information in all server
2318 * config logs, it should be moved to a separate config
2319 * log once we cleanup the config log for global param. */
2320 /* modify all servers */
2321 rc = mgs_write_log_direct_all(env, mgs, fsdb, mti,
2322 *tmp == '\0' ? NULL : lcfg,
2323 mti->mti_fsname, quota, 1);
2325 lustre_cfg_free(lcfg);
2329 static int mgs_srpc_set_param_disk(const struct lu_env *env,
2330 struct mgs_device *mgs,
2332 struct mgs_target_info *mti,
2335 struct mgs_thread_info *mgi = mgs_env_info(env);
2336 struct llog_handle *llh = NULL;
2338 char *comment, *ptr;
2339 struct lustre_cfg *lcfg;
2344 ptr = strchr(param, '=');
2348 OBD_ALLOC(comment, len + 1);
2349 if (comment == NULL)
2351 strncpy(comment, param, len);
2352 comment[len] = '\0';
2355 lustre_cfg_bufs_reset(&mgi->mgi_bufs, mti->mti_svname);
2356 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, param);
2357 lcfg = lustre_cfg_new(LCFG_SPTLRPC_CONF, &mgi->mgi_bufs);
2359 GOTO(out_comment, rc = -ENOMEM);
2361 /* construct log name */
2362 rc = name_create(&logname, mti->mti_fsname, "-sptlrpc");
2366 if (mgs_log_is_empty(env, mgs, logname)) {
2367 rc = record_start_log(env, mgs, &llh, logname);
2370 record_end_log(env, &llh);
2373 /* obsolete old one */
2374 rc = mgs_modify(env, mgs, fsdb, mti, logname, mti->mti_svname,
2378 /* write the new one */
2379 rc = mgs_write_log_direct(env, mgs, fsdb, logname, lcfg,
2380 mti->mti_svname, comment);
2382 CERROR("err %d writing log %s\n", rc, logname);
2384 name_destroy(&logname);
2386 lustre_cfg_free(lcfg);
2388 OBD_FREE(comment, len + 1);
2392 static int mgs_srpc_set_param_udesc_mem(struct fs_db *fsdb,
2397 /* disable the adjustable udesc parameter for now, i.e. use default
2398 * setting that client always ship udesc to MDT if possible. to enable
2399 * it simply remove the following line */
2402 ptr = strchr(param, '=');
2407 if (strcmp(param, PARAM_SRPC_UDESC))
2410 if (strcmp(ptr, "yes") == 0) {
2411 set_bit(FSDB_UDESC, &fsdb->fsdb_flags);
2412 CWARN("Enable user descriptor shipping from client to MDT\n");
2413 } else if (strcmp(ptr, "no") == 0) {
2414 clear_bit(FSDB_UDESC, &fsdb->fsdb_flags);
2415 CWARN("Disable user descriptor shipping from client to MDT\n");
2423 CERROR("Invalid param: %s\n", param);
2427 static int mgs_srpc_set_param_mem(struct fs_db *fsdb,
2431 struct sptlrpc_rule rule;
2432 struct sptlrpc_rule_set *rset;
2436 if (strncmp(param, PARAM_SRPC, sizeof(PARAM_SRPC) - 1) != 0) {
2437 CERROR("Invalid sptlrpc parameter: %s\n", param);
2441 if (strncmp(param, PARAM_SRPC_UDESC,
2442 sizeof(PARAM_SRPC_UDESC) - 1) == 0) {
2443 RETURN(mgs_srpc_set_param_udesc_mem(fsdb, param));
2446 if (strncmp(param, PARAM_SRPC_FLVR, sizeof(PARAM_SRPC_FLVR) - 1) != 0) {
2447 CERROR("Invalid sptlrpc flavor parameter: %s\n", param);
2451 param += sizeof(PARAM_SRPC_FLVR) - 1;
2453 rc = sptlrpc_parse_rule(param, &rule);
2457 /* mgs rules implies must be mgc->mgs */
2458 if (test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
2459 if ((rule.sr_from != LUSTRE_SP_MGC &&
2460 rule.sr_from != LUSTRE_SP_ANY) ||
2461 (rule.sr_to != LUSTRE_SP_MGS &&
2462 rule.sr_to != LUSTRE_SP_ANY))
2466 /* preapre room for this coming rule. svcname format should be:
2467 * - fsname: general rule
2468 * - fsname-tgtname: target-specific rule
2470 if (strchr(svname, '-')) {
2471 struct mgs_tgt_srpc_conf *tgtconf;
2474 for (tgtconf = fsdb->fsdb_srpc_tgt; tgtconf != NULL;
2475 tgtconf = tgtconf->mtsc_next) {
2476 if (!strcmp(tgtconf->mtsc_tgt, svname)) {
2485 OBD_ALLOC_PTR(tgtconf);
2486 if (tgtconf == NULL)
2489 name_len = strlen(svname);
2491 OBD_ALLOC(tgtconf->mtsc_tgt, name_len + 1);
2492 if (tgtconf->mtsc_tgt == NULL) {
2493 OBD_FREE_PTR(tgtconf);
2496 memcpy(tgtconf->mtsc_tgt, svname, name_len);
2498 tgtconf->mtsc_next = fsdb->fsdb_srpc_tgt;
2499 fsdb->fsdb_srpc_tgt = tgtconf;
2502 rset = &tgtconf->mtsc_rset;
2504 rset = &fsdb->fsdb_srpc_gen;
2507 rc = sptlrpc_rule_set_merge(rset, &rule);
2512 static int mgs_srpc_set_param(const struct lu_env *env,
2513 struct mgs_device *mgs,
2515 struct mgs_target_info *mti,
2525 /* keep a copy of original param, which could be destroied
2527 copy_size = strlen(param) + 1;
2528 OBD_ALLOC(copy, copy_size);
2531 memcpy(copy, param, copy_size);
2533 rc = mgs_srpc_set_param_mem(fsdb, mti->mti_svname, param);
2537 /* previous steps guaranteed the syntax is correct */
2538 rc = mgs_srpc_set_param_disk(env, mgs, fsdb, mti, copy);
2542 if (test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
2544 * for mgs rules, make them effective immediately.
2546 LASSERT(fsdb->fsdb_srpc_tgt == NULL);
2547 sptlrpc_target_update_exp_flavor(mgs->mgs_obd,
2548 &fsdb->fsdb_srpc_gen);
2552 OBD_FREE(copy, copy_size);
2556 struct mgs_srpc_read_data {
2557 struct fs_db *msrd_fsdb;
2561 static int mgs_srpc_read_handler(const struct lu_env *env,
2562 struct llog_handle *llh,
2563 struct llog_rec_hdr *rec, void *data)
2565 struct mgs_srpc_read_data *msrd = data;
2566 struct cfg_marker *marker;
2567 struct lustre_cfg *lcfg = (struct lustre_cfg *)(rec + 1);
2568 char *svname, *param;
2572 if (rec->lrh_type != OBD_CFG_REC) {
2573 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
2577 cfg_len = rec->lrh_len - sizeof(struct llog_rec_hdr) -
2578 sizeof(struct llog_rec_tail);
2580 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
2582 CERROR("Insane cfg\n");
2586 if (lcfg->lcfg_command == LCFG_MARKER) {
2587 marker = lustre_cfg_buf(lcfg, 1);
2589 if (marker->cm_flags & CM_START &&
2590 marker->cm_flags & CM_SKIP)
2591 msrd->msrd_skip = 1;
2592 if (marker->cm_flags & CM_END)
2593 msrd->msrd_skip = 0;
2598 if (msrd->msrd_skip)
2601 if (lcfg->lcfg_command != LCFG_SPTLRPC_CONF) {
2602 CERROR("invalid command (%x)\n", lcfg->lcfg_command);
2606 svname = lustre_cfg_string(lcfg, 0);
2607 if (svname == NULL) {
2608 CERROR("svname is empty\n");
2612 param = lustre_cfg_string(lcfg, 1);
2613 if (param == NULL) {
2614 CERROR("param is empty\n");
2618 rc = mgs_srpc_set_param_mem(msrd->msrd_fsdb, svname, param);
2620 CERROR("read sptlrpc record error (%d): %s\n", rc, param);
2625 int mgs_get_fsdb_srpc_from_llog(const struct lu_env *env,
2626 struct mgs_device *mgs,
2629 struct llog_handle *llh = NULL;
2630 struct llog_ctxt *ctxt;
2632 struct mgs_srpc_read_data msrd;
2636 /* construct log name */
2637 rc = name_create(&logname, fsdb->fsdb_name, "-sptlrpc");
2641 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
2642 LASSERT(ctxt != NULL);
2644 if (mgs_log_is_empty(env, mgs, logname))
2647 rc = llog_open(env, ctxt, &llh, NULL, logname,
2655 rc = llog_init_handle(env, llh, LLOG_F_IS_PLAIN, NULL);
2657 GOTO(out_close, rc);
2659 if (llog_get_size(llh) <= 1)
2660 GOTO(out_close, rc = 0);
2662 msrd.msrd_fsdb = fsdb;
2665 rc = llog_process(env, llh, mgs_srpc_read_handler, (void *)&msrd,
2669 llog_close(env, llh);
2671 llog_ctxt_put(ctxt);
2672 name_destroy(&logname);
2675 CERROR("failed to read sptlrpc config database: %d\n", rc);
2679 /* Permanent settings of all parameters by writing into the appropriate
2680 * configuration logs.
2681 * A parameter with null value ("<param>='\0'") means to erase it out of
2684 static int mgs_write_log_param(const struct lu_env *env,
2685 struct mgs_device *mgs, struct fs_db *fsdb,
2686 struct mgs_target_info *mti, char *ptr)
2688 struct mgs_thread_info *mgi = mgs_env_info(env);
2691 int rc = 0, rc2 = 0;
2694 /* For various parameter settings, we have to figure out which logs
2695 care about them (e.g. both mdt and client for lov settings) */
2696 CDEBUG(D_MGS, "next param '%s'\n", ptr);
2698 /* The params are stored in MOUNT_DATA_FILE and modified via
2699 tunefs.lustre, or set using lctl conf_param */
2701 /* Processed in lustre_start_mgc */
2702 if (class_match_param(ptr, PARAM_MGSNODE, NULL) == 0)
2705 /* Processed in ost/mdt */
2706 if (class_match_param(ptr, PARAM_NETWORK, NULL) == 0)
2709 /* Processed in mgs_write_log_ost */
2710 if (class_match_param(ptr, PARAM_FAILMODE, NULL) == 0) {
2711 if (mti->mti_flags & LDD_F_PARAM) {
2712 LCONSOLE_ERROR_MSG(0x169, "%s can only be "
2713 "changed with tunefs.lustre"
2714 "and --writeconf\n", ptr);
2720 if (class_match_param(ptr, PARAM_SRPC, NULL) == 0) {
2721 rc = mgs_srpc_set_param(env, mgs, fsdb, mti, ptr);
2725 if (class_match_param(ptr, PARAM_FAILNODE, NULL) == 0) {
2726 /* Add a failover nidlist */
2728 /* We already processed failovers params for new
2729 targets in mgs_write_log_target */
2730 if (mti->mti_flags & LDD_F_PARAM) {
2731 CDEBUG(D_MGS, "Adding failnode\n");
2732 rc = mgs_write_log_add_failnid(env, mgs, fsdb, mti);
2737 if (class_match_param(ptr, PARAM_SYS, &tmp) == 0) {
2738 rc = mgs_write_log_sys(env, mgs, fsdb, mti, ptr, tmp);
2742 if (class_match_param(ptr, PARAM_QUOTA, &tmp) == 0) {
2743 rc = mgs_write_log_quota(env, mgs, fsdb, mti, ptr, tmp);
2747 if (class_match_param(ptr, PARAM_OSC""PARAM_ACTIVE, &tmp) == 0) {
2748 /* active=0 means off, anything else means on */
2749 int flag = (*tmp == '0') ? CM_EXCLUDE : 0;
2752 if (!(mti->mti_flags & LDD_F_SV_TYPE_OST)) {
2753 LCONSOLE_ERROR_MSG(0x144, "%s: Only OSCs can "
2754 "be (de)activated.\n",
2756 GOTO(end, rc = -EINVAL);
2758 LCONSOLE_WARN("Permanently %sactivating %s\n",
2759 flag ? "de": "re", mti->mti_svname);
2761 rc = name_create(&logname, mti->mti_fsname, "-client");
2764 rc = mgs_modify(env, mgs, fsdb, mti, logname,
2765 mti->mti_svname, "add osc", flag);
2766 name_destroy(&logname);
2770 /* Add to all MDT logs for CMD */
2771 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2772 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
2774 rc = name_create_mdt(&logname, mti->mti_fsname, i);
2777 rc = mgs_modify(env, mgs, fsdb, mti, logname,
2778 mti->mti_svname, "add osc", flag);
2779 name_destroy(&logname);
2785 LCONSOLE_ERROR_MSG(0x145, "Couldn't find %s in"
2786 "log (%d). No permanent "
2787 "changes were made to the "
2789 mti->mti_svname, rc);
2790 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags))
2791 LCONSOLE_ERROR_MSG(0x146, "This may be"
2796 "update the logs.\n");
2799 /* Fall through to osc proc for deactivating live OSC
2800 on running MDT / clients. */
2802 /* Below here, let obd's XXX_process_config methods handle it */
2804 /* All lov. in proc */
2805 if (class_match_param(ptr, PARAM_LOV, NULL) == 0) {
2808 CDEBUG(D_MGS, "lov param %s\n", ptr);
2809 if (!(mti->mti_flags & LDD_F_SV_TYPE_MDT)) {
2810 LCONSOLE_ERROR_MSG(0x147, "LOV params must be "
2811 "set on the MDT, not %s. "
2818 if (mgs_log_is_empty(env, mgs, mti->mti_svname))
2819 GOTO(end, rc = -ENODEV);
2821 rc = name_create_mdt_and_lov(&logname, &mdtlovname, fsdb,
2822 mti->mti_stripe_index);
2825 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, mti->mti_svname,
2826 &mgi->mgi_bufs, mdtlovname, ptr);
2827 name_destroy(&logname);
2828 name_destroy(&mdtlovname);
2833 rc = name_create(&logname, mti->mti_fsname, "-client");
2836 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname, &mgi->mgi_bufs,
2837 fsdb->fsdb_clilov, ptr);
2838 name_destroy(&logname);
2842 /* All osc., mdc., llite. params in proc */
2843 if ((class_match_param(ptr, PARAM_OSC, NULL) == 0) ||
2844 (class_match_param(ptr, PARAM_MDC, NULL) == 0) ||
2845 (class_match_param(ptr, PARAM_LLITE, NULL) == 0)) {
2848 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
2849 LCONSOLE_ERROR_MSG(0x148, "Upgraded client logs for %s"
2850 " cannot be modified. Consider"
2851 " updating the configuration with"
2854 GOTO(end, rc = -EINVAL);
2856 if (memcmp(ptr, PARAM_LLITE, strlen(PARAM_LLITE)) == 0) {
2857 rc = name_create(&cname, mti->mti_fsname, "-client");
2858 /* Add the client type to match the obdname in
2859 class_config_llog_handler */
2860 } else if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
2861 rc = name_create(&cname, mti->mti_svname, "-mdc");
2862 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2863 rc = name_create(&cname, mti->mti_svname, "-osc");
2865 GOTO(end, rc = -EINVAL);
2870 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
2873 rc = name_create(&logname, mti->mti_fsname, "-client");
2875 name_destroy(&cname);
2878 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname, &mgi->mgi_bufs,
2881 /* osc params affect the MDT as well */
2882 if (!rc && (mti->mti_flags & LDD_F_SV_TYPE_OST)) {
2885 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
2886 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
2888 name_destroy(&cname);
2889 rc = name_create_mdt_osc(&cname, mti->mti_svname,
2891 name_destroy(&logname);
2894 rc = name_create_mdt(&logname,
2895 mti->mti_fsname, i);
2898 if (!mgs_log_is_empty(env, mgs, logname)) {
2899 rc = mgs_wlp_lcfg(env, mgs, fsdb,
2908 name_destroy(&logname);
2909 name_destroy(&cname);
2913 /* All mdt. params in proc */
2914 if (class_match_param(ptr, PARAM_MDT, NULL) == 0) {
2918 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
2919 if (strncmp(mti->mti_svname, mti->mti_fsname,
2920 MTI_NAME_MAXLEN) == 0)
2921 /* device is unspecified completely? */
2922 rc = LDD_F_SV_TYPE_MDT | LDD_F_SV_ALL;
2924 rc = server_name2index(mti->mti_svname, &idx, NULL);
2927 if ((rc & LDD_F_SV_TYPE_MDT) == 0)
2929 if (rc & LDD_F_SV_ALL) {
2930 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2932 fsdb->fsdb_mdt_index_map))
2934 rc = name_create_mdt(&logname,
2935 mti->mti_fsname, i);
2938 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti,
2939 logname, &mgi->mgi_bufs,
2941 name_destroy(&logname);
2946 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti,
2947 mti->mti_svname, &mgi->mgi_bufs,
2948 mti->mti_svname, ptr);
2955 /* All mdd., ost. params in proc */
2956 if ((class_match_param(ptr, PARAM_MDD, NULL) == 0) ||
2957 (class_match_param(ptr, PARAM_OST, NULL) == 0)) {
2958 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
2959 if (mgs_log_is_empty(env, mgs, mti->mti_svname))
2960 GOTO(end, rc = -ENODEV);
2962 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, mti->mti_svname,
2963 &mgi->mgi_bufs, mti->mti_svname, ptr);
2967 LCONSOLE_WARN("Ignoring unrecognized param '%s'\n", ptr);
2972 CERROR("err %d on param '%s'\n", rc, ptr);
2977 /* Not implementing automatic failover nid addition at this time. */
2978 int mgs_check_failnid(const struct lu_env *env, struct mgs_device *mgs,
2979 struct mgs_target_info *mti)
2986 rc = mgs_find_or_make_fsdb(obd, fsname, &fsdb);
2990 if (mgs_log_is_empty(obd, mti->mti_svname))
2991 /* should never happen */
2994 CDEBUG(D_MGS, "Checking for new failnids for %s\n", mti->mti_svname);
2996 /* FIXME We can just check mti->params to see if we're already in
2997 the failover list. Modify mti->params for rewriting back at
2998 server_register_target(). */
3000 mutex_lock(&fsdb->fsdb_mutex);
3001 rc = mgs_write_log_add_failnid(obd, fsdb, mti);
3002 mutex_unlock(&fsdb->fsdb_mutex);
3009 int mgs_write_log_target(const struct lu_env *env,
3010 struct mgs_device *mgs,
3011 struct mgs_target_info *mti,
3018 /* set/check the new target index */
3019 rc = mgs_set_index(env, mgs, mti);
3021 CERROR("Can't get index (%d)\n", rc);
3025 if (rc == EALREADY) {
3026 LCONSOLE_WARN("Found index %d for %s, updating log\n",
3027 mti->mti_stripe_index, mti->mti_svname);
3028 /* We would like to mark old log sections as invalid
3029 and add new log sections in the client and mdt logs.
3030 But if we add new sections, then live clients will
3031 get repeat setup instructions for already running
3032 osc's. So don't update the client/mdt logs. */
3033 mti->mti_flags &= ~LDD_F_UPDATE;
3036 mutex_lock(&fsdb->fsdb_mutex);
3038 if (mti->mti_flags &
3039 (LDD_F_VIRGIN | LDD_F_UPGRADE14 | LDD_F_WRITECONF)) {
3040 /* Generate a log from scratch */
3041 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
3042 rc = mgs_write_log_mdt(env, mgs, fsdb, mti);
3043 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
3044 rc = mgs_write_log_ost(env, mgs, fsdb, mti);
3046 CERROR("Unknown target type %#x, can't create log for "
3047 "%s\n", mti->mti_flags, mti->mti_svname);
3050 CERROR("Can't write logs for %s (%d)\n",
3051 mti->mti_svname, rc);
3055 /* Just update the params from tunefs in mgs_write_log_params */
3056 CDEBUG(D_MGS, "Update params for %s\n", mti->mti_svname);
3057 mti->mti_flags |= LDD_F_PARAM;
3060 /* allocate temporary buffer, where class_get_next_param will
3061 make copy of a current parameter */
3062 OBD_ALLOC(buf, strlen(mti->mti_params) + 1);
3064 GOTO(out_up, rc = -ENOMEM);
3065 params = mti->mti_params;
3066 while (params != NULL) {
3067 rc = class_get_next_param(¶ms, buf);
3070 /* there is no next parameter, that is
3075 CDEBUG(D_MGS, "remaining string: '%s', param: '%s'\n",
3077 rc = mgs_write_log_param(env, mgs, fsdb, mti, buf);
3082 OBD_FREE(buf, strlen(mti->mti_params) + 1);
3085 mutex_unlock(&fsdb->fsdb_mutex);
3089 int mgs_erase_log(const struct lu_env *env, struct mgs_device *mgs, char *name)
3091 struct llog_ctxt *ctxt;
3094 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
3096 CERROR("%s: MGS config context doesn't exist\n",
3097 mgs->mgs_obd->obd_name);
3100 rc = llog_erase(env, ctxt, NULL, name);
3101 /* llog may not exist */
3104 llog_ctxt_put(ctxt);
3108 CERROR("%s: failed to clear log %s: %d\n",
3109 mgs->mgs_obd->obd_name, name, rc);
3114 /* erase all logs for the given fs */
3115 int mgs_erase_logs(const struct lu_env *env, struct mgs_device *mgs, char *fsname)
3119 struct mgs_direntry *dirent, *n;
3120 int rc, len = strlen(fsname);
3124 /* Find all the logs in the CONFIGS directory */
3125 rc = class_dentry_readdir(env, mgs, &list);
3129 mutex_lock(&mgs->mgs_mutex);
3131 /* Delete the fs db */
3132 fsdb = mgs_find_fsdb(mgs, fsname);
3134 mgs_free_fsdb(mgs, fsdb);
3136 mutex_unlock(&mgs->mgs_mutex);
3138 cfs_list_for_each_entry_safe(dirent, n, &list, list) {
3139 cfs_list_del(&dirent->list);
3140 suffix = strrchr(dirent->name, '-');
3141 if (suffix != NULL) {
3142 if ((len == suffix - dirent->name) &&
3143 (strncmp(fsname, dirent->name, len) == 0)) {
3144 CDEBUG(D_MGS, "Removing log %s\n",
3146 mgs_erase_log(env, mgs, dirent->name);
3149 mgs_direntry_free(dirent);
3155 /* from llog_swab */
3156 static void print_lustre_cfg(struct lustre_cfg *lcfg)
3161 CDEBUG(D_MGS, "lustre_cfg: %p\n", lcfg);
3162 CDEBUG(D_MGS, "\tlcfg->lcfg_version: %#x\n", lcfg->lcfg_version);
3164 CDEBUG(D_MGS, "\tlcfg->lcfg_command: %#x\n", lcfg->lcfg_command);
3165 CDEBUG(D_MGS, "\tlcfg->lcfg_num: %#x\n", lcfg->lcfg_num);
3166 CDEBUG(D_MGS, "\tlcfg->lcfg_flags: %#x\n", lcfg->lcfg_flags);
3167 CDEBUG(D_MGS, "\tlcfg->lcfg_nid: %s\n", libcfs_nid2str(lcfg->lcfg_nid));
3169 CDEBUG(D_MGS, "\tlcfg->lcfg_bufcount: %d\n", lcfg->lcfg_bufcount);
3170 if (lcfg->lcfg_bufcount < LUSTRE_CFG_MAX_BUFCOUNT)
3171 for (i = 0; i < lcfg->lcfg_bufcount; i++) {
3172 CDEBUG(D_MGS, "\tlcfg->lcfg_buflens[%d]: %d %s\n",
3173 i, lcfg->lcfg_buflens[i],
3174 lustre_cfg_string(lcfg, i));
3179 /* Set a permanent (config log) param for a target or fs
3180 * \param lcfg buf0 may contain the device (testfs-MDT0000) name
3181 * buf1 contains the single parameter
3183 int mgs_setparam(const struct lu_env *env, struct mgs_device *mgs,
3184 struct lustre_cfg *lcfg, char *fsname)
3187 struct mgs_target_info *mti;
3188 char *devname, *param;
3194 print_lustre_cfg(lcfg);
3196 /* lustre, lustre-mdtlov, lustre-client, lustre-MDT0000 */
3197 devname = lustre_cfg_string(lcfg, 0);
3198 param = lustre_cfg_string(lcfg, 1);
3200 /* Assume device name embedded in param:
3201 lustre-OST0000.osc.max_dirty_mb=32 */
3202 ptr = strchr(param, '.');
3210 LCONSOLE_ERROR_MSG(0x14d, "No target specified: %s\n", param);
3214 /* Extract fsname */
3215 ptr = strrchr(devname, '-');
3216 memset(fsname, 0, MTI_NAME_MAXLEN);
3217 if (ptr && (server_name2index(ptr, &index, NULL) >= 0)) {
3218 /* param related to llite isn't allowed to set by OST or MDT */
3219 if (strncmp(param, PARAM_LLITE, sizeof(PARAM_LLITE)) == 0)
3222 strncpy(fsname, devname, ptr - devname);
3224 /* assume devname is the fsname */
3225 strncpy(fsname, devname, MTI_NAME_MAXLEN);
3227 fsname[MTI_NAME_MAXLEN - 1] = 0;
3228 CDEBUG(D_MGS, "setparam fs='%s' device='%s'\n", fsname, devname);
3230 rc = mgs_find_or_make_fsdb(env, mgs, fsname, &fsdb);
3233 if (!test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags) &&
3234 test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
3235 CERROR("No filesystem targets for %s. cfg_device from lctl "
3236 "is '%s'\n", fsname, devname);
3237 mgs_free_fsdb(mgs, fsdb);
3241 /* Create a fake mti to hold everything */
3244 GOTO(out, rc = -ENOMEM);
3245 strncpy(mti->mti_fsname, fsname, MTI_NAME_MAXLEN);
3246 strncpy(mti->mti_svname, devname, MTI_NAME_MAXLEN);
3247 strncpy(mti->mti_params, param, sizeof(mti->mti_params));
3248 rc = server_name2index(mti->mti_svname, &mti->mti_stripe_index, &tmp);
3250 /* Not a valid server; may be only fsname */
3253 /* Strip -osc or -mdc suffix from svname */
3254 if (server_make_name(rc, mti->mti_stripe_index, mti->mti_fsname,
3256 GOTO(out, rc = -EINVAL);
3258 mti->mti_flags = rc | LDD_F_PARAM;
3260 mutex_lock(&fsdb->fsdb_mutex);
3261 rc = mgs_write_log_param(env, mgs, fsdb, mti, mti->mti_params);
3262 mutex_unlock(&fsdb->fsdb_mutex);
3265 * Revoke lock so everyone updates. Should be alright if
3266 * someone was already reading while we were updating the logs,
3267 * so we don't really need to hold the lock while we're
3270 mgs_revoke_lock(mgs, fsdb, CONFIG_T_CONFIG);
3276 static int mgs_write_log_pool(const struct lu_env *env,
3277 struct mgs_device *mgs, char *logname,
3278 struct fs_db *fsdb, char *lovname,
3279 enum lcfg_command_type cmd,
3280 char *poolname, char *fsname,
3281 char *ostname, char *comment)
3283 struct llog_handle *llh = NULL;
3286 rc = record_start_log(env, mgs, &llh, logname);
3289 rc = record_marker(env, llh, fsdb, CM_START, lovname, comment);
3292 rc = record_base(env, llh, lovname, 0, cmd, poolname, fsname, ostname, 0);
3295 rc = record_marker(env, llh, fsdb, CM_END, lovname, comment);
3297 record_end_log(env, &llh);
3301 int mgs_pool_cmd(const struct lu_env *env, struct mgs_device *mgs,
3302 enum lcfg_command_type cmd, char *fsname,
3303 char *poolname, char *ostname)
3308 char *label = NULL, *canceled_label = NULL;
3310 struct mgs_target_info *mti = NULL;
3314 rc = mgs_find_or_make_fsdb(env, mgs, fsname, &fsdb);
3316 CERROR("Can't get db for %s\n", fsname);
3319 if (test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
3320 CERROR("%s is not defined\n", fsname);
3321 mgs_free_fsdb(mgs, fsdb);
3325 label_sz = 10 + strlen(fsname) + strlen(poolname);
3327 /* check if ostname match fsname */
3328 if (ostname != NULL) {
3331 ptr = strrchr(ostname, '-');
3332 if ((ptr == NULL) ||
3333 (strncmp(fsname, ostname, ptr-ostname) != 0))
3335 label_sz += strlen(ostname);
3338 OBD_ALLOC(label, label_sz);
3345 "new %s.%s", fsname, poolname);
3349 "add %s.%s.%s", fsname, poolname, ostname);
3352 OBD_ALLOC(canceled_label, label_sz);
3353 if (canceled_label == NULL)
3354 GOTO(out_label, rc = -ENOMEM);
3356 "rem %s.%s.%s", fsname, poolname, ostname);
3357 sprintf(canceled_label,
3358 "add %s.%s.%s", fsname, poolname, ostname);
3361 OBD_ALLOC(canceled_label, label_sz);
3362 if (canceled_label == NULL)
3363 GOTO(out_label, rc = -ENOMEM);
3365 "del %s.%s", fsname, poolname);
3366 sprintf(canceled_label,
3367 "new %s.%s", fsname, poolname);
3373 mutex_lock(&fsdb->fsdb_mutex);
3375 if (canceled_label != NULL) {
3378 GOTO(out_cancel, rc = -ENOMEM);
3381 /* write pool def to all MDT logs */
3382 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3383 if (test_bit(i, fsdb->fsdb_mdt_index_map)) {
3384 rc = name_create_mdt_and_lov(&logname, &lovname,
3387 mutex_unlock(&fsdb->fsdb_mutex);
3390 if (canceled_label != NULL) {
3391 strcpy(mti->mti_svname, "lov pool");
3392 rc = mgs_modify(env, mgs, fsdb, mti, logname,
3393 lovname, canceled_label,
3398 rc = mgs_write_log_pool(env, mgs, logname,
3402 name_destroy(&logname);
3403 name_destroy(&lovname);
3405 mutex_unlock(&fsdb->fsdb_mutex);
3411 rc = name_create(&logname, fsname, "-client");
3413 mutex_unlock(&fsdb->fsdb_mutex);
3416 if (canceled_label != NULL) {
3417 rc = mgs_modify(env, mgs, fsdb, mti, logname,
3418 fsdb->fsdb_clilov, canceled_label, CM_SKIP);
3420 mutex_unlock(&fsdb->fsdb_mutex);
3421 name_destroy(&logname);
3426 rc = mgs_write_log_pool(env, mgs, logname, fsdb, fsdb->fsdb_clilov,
3427 cmd, fsname, poolname, ostname, label);
3428 mutex_unlock(&fsdb->fsdb_mutex);
3429 name_destroy(&logname);
3430 /* request for update */
3431 mgs_revoke_lock(mgs, fsdb, CONFIG_T_CONFIG);
3438 if (canceled_label != NULL)
3439 OBD_FREE(canceled_label, label_sz);
3441 OBD_FREE(label, label_sz);
3446 /******************** unused *********************/
3447 static int mgs_backup_llog(struct obd_device *obd, char* fsname)
3449 struct file *filp, *bak_filp;
3450 struct lvfs_run_ctxt saved;
3451 char *logname, *buf;
3452 loff_t soff = 0 , doff = 0;
3453 int count = 4096, len;
3456 OBD_ALLOC(logname, PATH_MAX);
3457 if (logname == NULL)
3460 OBD_ALLOC(buf, count);
3462 GOTO(out , rc = -ENOMEM);
3464 len = snprintf(logname, PATH_MAX, "%s/%s.bak",
3465 MOUNT_CONFIGS_DIR, fsname);
3467 if (len >= PATH_MAX - 1) {
3468 GOTO(out, -ENAMETOOLONG);
3471 push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
3473 bak_filp = l_filp_open(logname, O_RDWR|O_CREAT|O_TRUNC, 0660);
3474 if (IS_ERR(bak_filp)) {
3475 rc = PTR_ERR(bak_filp);
3476 CERROR("backup logfile open %s: %d\n", logname, rc);
3479 sprintf(logname, "%s/%s", MOUNT_CONFIGS_DIR, fsname);
3480 filp = l_filp_open(logname, O_RDONLY, 0);
3483 CERROR("logfile open %s: %d\n", logname, rc);
3487 while ((rc = lustre_fread(filp, buf, count, &soff)) > 0) {
3488 rc = lustre_fwrite(bak_filp, buf, count, &doff);
3492 filp_close(filp, 0);
3494 filp_close(bak_filp, 0);
3496 pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
3499 OBD_FREE(buf, count);
3500 OBD_FREE(logname, PATH_MAX);