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.gnu.org/licenses/gpl-2.0.html
23 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
24 * Use is subject to license terms.
26 * Copyright (c) 2011, 2016, Intel Corporation.
29 * This file is part of Lustre, http://www.lustre.org/
30 * Lustre is a trademark of Sun Microsystems, Inc.
32 * lustre/mgs/mgs_llog.c
34 * Lustre Management Server (mgs) config llog creation
36 * Author: Nathan Rutman <nathan@clusterfs.com>
37 * Author: Alex Zhuravlev <bzzz@whamcloud.com>
38 * Author: Mikhail Pershin <tappro@whamcloud.com>
41 #define DEBUG_SUBSYSTEM S_MGS
42 #define D_MGS D_CONFIG
45 #include <lustre_ioctl.h>
46 #include <lustre_param.h>
47 #include <lustre_sec.h>
48 #include <lustre_quota.h>
50 #include "mgs_internal.h"
52 /********************** Class functions ********************/
55 * Find all logs in CONFIG directory and link then into list.
57 * \param[in] env pointer to the thread context
58 * \param[in] mgs pointer to the mgs device
59 * \param[out] log_list the list to hold the found llog name entry
61 * \retval 0 for success
62 * \retval negative error number on failure
64 int class_dentry_readdir(const struct lu_env *env, struct mgs_device *mgs,
65 struct list_head *log_list)
67 struct dt_object *dir = mgs->mgs_configs_dir;
68 const struct dt_it_ops *iops;
70 struct mgs_direntry *de;
74 INIT_LIST_HEAD(log_list);
77 LASSERT(dir->do_index_ops);
79 iops = &dir->do_index_ops->dio_it;
80 it = iops->init(env, dir, LUDA_64BITHASH);
84 rc = iops->load(env, it, 0);
90 key = (void *)iops->key(env, it);
92 CERROR("%s: key failed when listing %s: rc = %d\n",
93 mgs->mgs_obd->obd_name, MOUNT_CONFIGS_DIR,
97 key_sz = iops->key_size(env, it);
100 /* filter out "." and ".." entries */
104 if (key_sz == 2 && key[1] == '.')
108 /* filter out ".bak" files */
109 /* sizeof(".bak") - 1 == 3 */
111 !memcmp(".bak", key + key_sz - 3, 3)) {
112 CDEBUG(D_MGS, "Skipping backup file %.*s\n",
117 de = mgs_direntry_alloc(key_sz + 1);
123 memcpy(de->mde_name, key, key_sz);
124 de->mde_name[key_sz] = 0;
126 list_add(&de->mde_list, log_list);
129 rc = iops->next(env, it);
139 struct mgs_direntry *n;
141 CERROR("%s: key failed when listing %s: rc = %d\n",
142 mgs->mgs_obd->obd_name, MOUNT_CONFIGS_DIR, rc);
144 list_for_each_entry_safe(de, n, log_list, mde_list) {
145 list_del_init(&de->mde_list);
146 mgs_direntry_free(de);
153 /******************** DB functions *********************/
155 static inline int name_create(char **newname, char *prefix, char *suffix)
158 OBD_ALLOC(*newname, strlen(prefix) + strlen(suffix) + 1);
161 sprintf(*newname, "%s%s", prefix, suffix);
165 static inline void name_destroy(char **name)
168 OBD_FREE(*name, strlen(*name) + 1);
172 struct mgs_fsdb_handler_data
178 /* from the (client) config log, figure out:
179 1. which ost's/mdt's are configured (by index)
180 2. what the last config step is
181 3. COMPAT_18 osc name
183 /* It might be better to have a separate db file, instead of parsing the info
184 out of the client log. This is slow and potentially error-prone. */
185 static int mgs_fsdb_handler(const struct lu_env *env, struct llog_handle *llh,
186 struct llog_rec_hdr *rec, void *data)
188 struct mgs_fsdb_handler_data *d = data;
189 struct fs_db *fsdb = d->fsdb;
190 int cfg_len = rec->lrh_len;
191 char *cfg_buf = (char*) (rec + 1);
192 struct lustre_cfg *lcfg;
197 if (rec->lrh_type != OBD_CFG_REC) {
198 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
202 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
204 CERROR("Insane cfg\n");
208 lcfg = (struct lustre_cfg *)cfg_buf;
210 CDEBUG(D_INFO, "cmd %x %s %s\n", lcfg->lcfg_command,
211 lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));
213 /* Figure out ost indicies */
214 /* lov_modify_tgts add 0:lov1 1:ost1_UUID 2(index):0 3(gen):1 */
215 if (lcfg->lcfg_command == LCFG_LOV_ADD_OBD ||
216 lcfg->lcfg_command == LCFG_LOV_DEL_OBD) {
217 index = simple_strtoul(lustre_cfg_string(lcfg, 2),
219 CDEBUG(D_MGS, "OST index for %s is %u (%s)\n",
220 lustre_cfg_string(lcfg, 1), index,
221 lustre_cfg_string(lcfg, 2));
222 set_bit(index, fsdb->fsdb_ost_index_map);
225 /* Figure out mdt indicies */
226 /* attach 0:MDC_uml1_mdsA_MNT_client 1:mdc 2:1d834_MNT_client_03f */
227 if ((lcfg->lcfg_command == LCFG_ATTACH) &&
228 (strcmp(lustre_cfg_string(lcfg, 1), LUSTRE_MDC_NAME) == 0)) {
229 rc = server_name2index(lustre_cfg_string(lcfg, 0),
231 if (rc != LDD_F_SV_TYPE_MDT) {
232 CWARN("Unparsable MDC name %s, assuming index 0\n",
233 lustre_cfg_string(lcfg, 0));
237 CDEBUG(D_MGS, "MDT index is %u\n", index);
238 if (!test_bit(index, fsdb->fsdb_mdt_index_map)) {
239 set_bit(index, fsdb->fsdb_mdt_index_map);
240 fsdb->fsdb_mdt_count++;
245 * figure out the old config. fsdb_gen = 0 means old log
246 * It is obsoleted and not supported anymore
248 if (fsdb->fsdb_gen == 0) {
249 CERROR("Old config format is not supported\n");
254 * compat to 1.8, check osc name used by MDT0 to OSTs, bz18548.
256 if (!test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags) &&
257 lcfg->lcfg_command == LCFG_ATTACH &&
258 strcmp(lustre_cfg_string(lcfg, 1), LUSTRE_OSC_NAME) == 0) {
259 if (OBD_OCD_VERSION_MAJOR(d->ver) == 1 &&
260 OBD_OCD_VERSION_MINOR(d->ver) <= 8) {
261 CWARN("MDT using 1.8 OSC name scheme\n");
262 set_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags);
266 if (lcfg->lcfg_command == LCFG_MARKER) {
267 struct cfg_marker *marker;
268 marker = lustre_cfg_buf(lcfg, 1);
270 d->ver = marker->cm_vers;
272 /* Keep track of the latest marker step */
273 fsdb->fsdb_gen = max(fsdb->fsdb_gen, marker->cm_step);
279 /* fsdb->fsdb_mutex is already held in mgs_find_or_make_fsdb*/
280 static int mgs_get_fsdb_from_llog(const struct lu_env *env,
281 struct mgs_device *mgs,
285 struct llog_handle *loghandle;
286 struct llog_ctxt *ctxt;
287 struct mgs_fsdb_handler_data d = {
294 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
295 LASSERT(ctxt != NULL);
296 rc = name_create(&logname, fsdb->fsdb_name, "-client");
299 rc = llog_open_create(env, ctxt, &loghandle, NULL, logname);
303 rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL);
307 if (llog_get_size(loghandle) <= 1)
308 set_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags);
310 rc = llog_process(env, loghandle, mgs_fsdb_handler, (void *)&d, NULL);
311 CDEBUG(D_INFO, "get_db = %d\n", rc);
313 llog_close(env, loghandle);
315 name_destroy(&logname);
322 static void mgs_free_fsdb_srpc(struct fs_db *fsdb)
324 struct mgs_tgt_srpc_conf *tgtconf;
326 /* free target-specific rules */
327 while (fsdb->fsdb_srpc_tgt) {
328 tgtconf = fsdb->fsdb_srpc_tgt;
329 fsdb->fsdb_srpc_tgt = tgtconf->mtsc_next;
331 LASSERT(tgtconf->mtsc_tgt);
333 sptlrpc_rule_set_free(&tgtconf->mtsc_rset);
334 OBD_FREE(tgtconf->mtsc_tgt, strlen(tgtconf->mtsc_tgt) + 1);
335 OBD_FREE_PTR(tgtconf);
338 /* free general rules */
339 sptlrpc_rule_set_free(&fsdb->fsdb_srpc_gen);
342 static void mgs_unlink_fsdb(struct mgs_device *mgs, struct fs_db *fsdb)
344 mutex_lock(&mgs->mgs_mutex);
345 if (likely(!list_empty(&fsdb->fsdb_list))) {
346 LASSERTF(atomic_read(&fsdb->fsdb_ref) >= 2,
347 "Invalid ref %d on %s\n",
348 atomic_read(&fsdb->fsdb_ref),
351 list_del_init(&fsdb->fsdb_list);
352 /* Drop the reference on the list.*/
353 mgs_put_fsdb(mgs, fsdb);
355 mutex_unlock(&mgs->mgs_mutex);
358 /* The caller must hold mgs->mgs_mutex. */
359 static inline struct fs_db *
360 mgs_find_fsdb_noref(struct mgs_device *mgs, const char *fsname)
363 struct list_head *tmp;
365 list_for_each(tmp, &mgs->mgs_fs_db_list) {
366 fsdb = list_entry(tmp, struct fs_db, fsdb_list);
367 if (strcmp(fsdb->fsdb_name, fsname) == 0)
374 /* The caller must hold mgs->mgs_mutex. */
375 static void mgs_remove_fsdb_by_name(struct mgs_device *mgs, const char *name)
379 fsdb = mgs_find_fsdb_noref(mgs, name);
381 list_del_init(&fsdb->fsdb_list);
382 /* Drop the reference on the list.*/
383 mgs_put_fsdb(mgs, fsdb);
387 /* The caller must hold mgs->mgs_mutex. */
388 struct fs_db *mgs_find_fsdb(struct mgs_device *mgs, const char *fsname)
392 fsdb = mgs_find_fsdb_noref(mgs, fsname);
394 atomic_inc(&fsdb->fsdb_ref);
399 /* The caller must hold mgs->mgs_mutex. */
400 static struct fs_db *mgs_new_fsdb(const struct lu_env *env,
401 struct mgs_device *mgs, char *fsname)
407 if (strlen(fsname) >= sizeof(fsdb->fsdb_name)) {
408 CERROR("fsname %s is too long\n", fsname);
410 RETURN(ERR_PTR(-EINVAL));
415 RETURN(ERR_PTR(-ENOMEM));
417 strncpy(fsdb->fsdb_name, fsname, sizeof(fsdb->fsdb_name));
418 mutex_init(&fsdb->fsdb_mutex);
419 INIT_LIST_HEAD(&fsdb->fsdb_list);
420 set_bit(FSDB_UDESC, &fsdb->fsdb_flags);
422 INIT_LIST_HEAD(&fsdb->fsdb_clients);
423 atomic_set(&fsdb->fsdb_notify_phase, 0);
424 init_waitqueue_head(&fsdb->fsdb_notify_waitq);
425 init_completion(&fsdb->fsdb_notify_comp);
427 if (strcmp(fsname, MGSSELF_NAME) == 0) {
428 set_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags);
429 fsdb->fsdb_mgs = mgs;
430 if (logname_is_barrier(fsname))
433 OBD_ALLOC(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
434 if (!fsdb->fsdb_mdt_index_map) {
435 CERROR("No memory for MDT index maps\n");
437 GOTO(err, rc = -ENOMEM);
440 OBD_ALLOC(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
441 if (!fsdb->fsdb_ost_index_map) {
442 CERROR("No memory for OST index maps\n");
444 GOTO(err, rc = -ENOMEM);
447 if (logname_is_barrier(fsname))
450 rc = name_create(&fsdb->fsdb_clilov, fsname, "-clilov");
454 rc = name_create(&fsdb->fsdb_clilmv, fsname, "-clilmv");
458 /* initialise data for NID table */
459 mgs_ir_init_fs(env, mgs, fsdb);
460 lproc_mgs_add_live(mgs, fsdb);
463 if (!test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags) &&
464 strcmp(PARAMS_FILENAME, fsname) != 0) {
465 /* populate the db from the client llog */
466 rc = mgs_get_fsdb_from_llog(env, mgs, fsdb);
468 CERROR("Can't get db from client log %d\n", rc);
474 /* populate srpc rules from params llog */
475 rc = mgs_get_fsdb_srpc_from_llog(env, mgs, fsdb);
477 CERROR("Can't get db from params log %d\n", rc);
483 /* One ref is for the fsdb on the list.
484 * The other ref is for the caller. */
485 atomic_set(&fsdb->fsdb_ref, 2);
486 list_add(&fsdb->fsdb_list, &mgs->mgs_fs_db_list);
491 atomic_set(&fsdb->fsdb_ref, 1);
492 mgs_put_fsdb(mgs, fsdb);
497 static void mgs_free_fsdb(struct mgs_device *mgs, struct fs_db *fsdb)
499 LASSERT(list_empty(&fsdb->fsdb_list));
501 lproc_mgs_del_live(mgs, fsdb);
503 /* deinitialize fsr */
505 mgs_ir_fini_fs(mgs, fsdb);
507 if (fsdb->fsdb_ost_index_map)
508 OBD_FREE(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
509 if (fsdb->fsdb_mdt_index_map)
510 OBD_FREE(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
511 name_destroy(&fsdb->fsdb_clilov);
512 name_destroy(&fsdb->fsdb_clilmv);
513 mgs_free_fsdb_srpc(fsdb);
517 void mgs_put_fsdb(struct mgs_device *mgs, struct fs_db *fsdb)
519 if (atomic_dec_and_test(&fsdb->fsdb_ref))
520 mgs_free_fsdb(mgs, fsdb);
523 int mgs_init_fsdb_list(struct mgs_device *mgs)
525 INIT_LIST_HEAD(&mgs->mgs_fs_db_list);
529 int mgs_cleanup_fsdb_list(struct mgs_device *mgs)
532 struct list_head *tmp, *tmp2;
534 mutex_lock(&mgs->mgs_mutex);
535 list_for_each_safe(tmp, tmp2, &mgs->mgs_fs_db_list) {
536 fsdb = list_entry(tmp, struct fs_db, fsdb_list);
537 list_del_init(&fsdb->fsdb_list);
538 mgs_put_fsdb(mgs, fsdb);
540 mutex_unlock(&mgs->mgs_mutex);
544 int mgs_find_or_make_fsdb(const struct lu_env *env, struct mgs_device *mgs,
545 char *name, struct fs_db **dbh)
551 mutex_lock(&mgs->mgs_mutex);
552 fsdb = mgs_find_fsdb(mgs, name);
554 fsdb = mgs_new_fsdb(env, mgs, name);
558 CDEBUG(D_MGS, "Created new db: rc = %d\n", rc);
560 mutex_unlock(&mgs->mgs_mutex);
570 -1= empty client log */
571 int mgs_check_index(const struct lu_env *env,
572 struct mgs_device *mgs,
573 struct mgs_target_info *mti)
580 LASSERT(!(mti->mti_flags & LDD_F_NEED_INDEX));
582 rc = mgs_find_or_make_fsdb(env, mgs, mti->mti_fsname, &fsdb);
584 CERROR("Can't get db for %s\n", mti->mti_fsname);
588 if (test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags))
591 if (mti->mti_flags & LDD_F_SV_TYPE_OST)
592 imap = fsdb->fsdb_ost_index_map;
593 else if (mti->mti_flags & LDD_F_SV_TYPE_MDT)
594 imap = fsdb->fsdb_mdt_index_map;
596 GOTO(out, rc = -EINVAL);
598 if (test_bit(mti->mti_stripe_index, imap))
604 mgs_put_fsdb(mgs, fsdb);
608 static __inline__ int next_index(void *index_map, int map_len)
611 for (i = 0; i < map_len * 8; i++)
612 if (!test_bit(i, index_map)) {
615 CERROR("max index %d exceeded.\n", i);
620 0 newly marked as in use
622 +EALREADY for update of an old index */
623 static int mgs_set_index(const struct lu_env *env,
624 struct mgs_device *mgs,
625 struct mgs_target_info *mti)
632 rc = mgs_find_or_make_fsdb(env, mgs, mti->mti_fsname, &fsdb);
634 CERROR("Can't get db for %s\n", mti->mti_fsname);
638 mutex_lock(&fsdb->fsdb_mutex);
639 if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
640 imap = fsdb->fsdb_ost_index_map;
641 } else if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
642 imap = fsdb->fsdb_mdt_index_map;
644 GOTO(out_up, rc = -EINVAL);
647 if (mti->mti_flags & LDD_F_NEED_INDEX) {
648 rc = next_index(imap, INDEX_MAP_SIZE);
650 GOTO(out_up, rc = -ERANGE);
651 mti->mti_stripe_index = rc;
654 /* the last index(0xffff) is reserved for default value. */
655 if (mti->mti_stripe_index >= INDEX_MAP_SIZE * 8 - 1) {
656 LCONSOLE_ERROR_MSG(0x13f, "Server %s requested index %u, "
657 "but index must be less than %u.\n",
658 mti->mti_svname, mti->mti_stripe_index,
659 INDEX_MAP_SIZE * 8 - 1);
660 GOTO(out_up, rc = -ERANGE);
663 if (test_bit(mti->mti_stripe_index, imap)) {
664 if ((mti->mti_flags & LDD_F_VIRGIN) &&
665 !(mti->mti_flags & LDD_F_WRITECONF)) {
666 LCONSOLE_ERROR_MSG(0x140, "Server %s requested index "
667 "%d, but that index is already in "
668 "use. Use --writeconf to force\n",
670 mti->mti_stripe_index);
671 GOTO(out_up, rc = -EADDRINUSE);
673 CDEBUG(D_MGS, "Server %s updating index %d\n",
674 mti->mti_svname, mti->mti_stripe_index);
675 GOTO(out_up, rc = EALREADY);
678 set_bit(mti->mti_stripe_index, imap);
679 if (mti->mti_flags & LDD_F_SV_TYPE_MDT)
680 fsdb->fsdb_mdt_count++;
683 set_bit(mti->mti_stripe_index, imap);
684 clear_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags);
685 if (server_make_name(mti->mti_flags & ~(LDD_F_VIRGIN | LDD_F_WRITECONF),
686 mti->mti_stripe_index, mti->mti_fsname,
688 CERROR("unknown server type %#x\n", mti->mti_flags);
689 GOTO(out_up, rc = -EINVAL);
692 CDEBUG(D_MGS, "Set index for %s to %d\n", mti->mti_svname,
693 mti->mti_stripe_index);
695 GOTO(out_up, rc = 0);
698 mutex_unlock(&fsdb->fsdb_mutex);
699 mgs_put_fsdb(mgs, fsdb);
703 struct mgs_modify_lookup {
704 struct cfg_marker mml_marker;
708 static int mgs_check_record_match(const struct lu_env *env,
709 struct llog_handle *llh,
710 struct llog_rec_hdr *rec, void *data)
712 struct cfg_marker *mc_marker = data;
713 struct cfg_marker *marker;
714 struct lustre_cfg *lcfg = REC_DATA(rec);
715 int cfg_len = REC_DATA_LEN(rec);
720 if (rec->lrh_type != OBD_CFG_REC) {
721 CDEBUG(D_ERROR, "Unhandled lrh_type: %#x\n", rec->lrh_type);
725 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
727 CDEBUG(D_ERROR, "Insane cfg\n");
731 /* We only care about markers */
732 if (lcfg->lcfg_command != LCFG_MARKER)
735 marker = lustre_cfg_buf(lcfg, 1);
737 if (marker->cm_flags & CM_SKIP)
740 if ((strcmp(mc_marker->cm_comment, marker->cm_comment) == 0) &&
741 (strcmp(mc_marker->cm_tgtname, marker->cm_tgtname) == 0)) {
742 /* Found a non-skipped marker match */
743 CDEBUG(D_MGS, "Matched rec %u marker %d flag %x %s %s\n",
744 rec->lrh_index, marker->cm_step,
745 marker->cm_flags, marker->cm_tgtname,
747 rc = LLOG_PROC_BREAK;
754 * Check an existing config log record with matching comment and device
756 * 0 - checked successfully,
757 * LLOG_PROC_BREAK - record matches
760 static int mgs_check_marker(const struct lu_env *env, struct mgs_device *mgs,
761 struct fs_db *fsdb, struct mgs_target_info *mti,
762 char *logname, char *devname, char *comment)
764 struct llog_handle *loghandle;
765 struct llog_ctxt *ctxt;
766 struct cfg_marker *mc_marker;
771 LASSERT(mutex_is_locked(&fsdb->fsdb_mutex));
772 CDEBUG(D_MGS, "mgs check %s/%s/%s\n", logname, devname, comment);
774 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
775 LASSERT(ctxt != NULL);
776 rc = llog_open(env, ctxt, &loghandle, NULL, logname, LLOG_OPEN_EXISTS);
783 rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL);
787 if (llog_get_size(loghandle) <= 1)
788 GOTO(out_close, rc = 0);
790 OBD_ALLOC_PTR(mc_marker);
792 GOTO(out_close, rc = -ENOMEM);
793 if (strlcpy(mc_marker->cm_comment, comment,
794 sizeof(mc_marker->cm_comment)) >=
795 sizeof(mc_marker->cm_comment))
796 GOTO(out_free, rc = -E2BIG);
797 if (strlcpy(mc_marker->cm_tgtname, devname,
798 sizeof(mc_marker->cm_tgtname)) >=
799 sizeof(mc_marker->cm_tgtname))
800 GOTO(out_free, rc = -E2BIG);
802 rc = llog_process(env, loghandle, mgs_check_record_match,
803 (void *)mc_marker, NULL);
806 OBD_FREE_PTR(mc_marker);
809 llog_close(env, loghandle);
811 if (rc && rc != LLOG_PROC_BREAK)
812 CDEBUG(D_ERROR, "%s: mgs check %s/%s failed: rc = %d\n",
813 mgs->mgs_obd->obd_name, mti->mti_svname, comment, rc);
818 static int mgs_modify_handler(const struct lu_env *env,
819 struct llog_handle *llh,
820 struct llog_rec_hdr *rec, void *data)
822 struct mgs_modify_lookup *mml = data;
823 struct cfg_marker *marker;
824 struct lustre_cfg *lcfg = REC_DATA(rec);
825 int cfg_len = REC_DATA_LEN(rec);
829 if (rec->lrh_type != OBD_CFG_REC) {
830 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
834 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
836 CERROR("Insane cfg\n");
840 /* We only care about markers */
841 if (lcfg->lcfg_command != LCFG_MARKER)
844 marker = lustre_cfg_buf(lcfg, 1);
845 if ((strcmp(mml->mml_marker.cm_comment, marker->cm_comment) == 0) &&
846 (strcmp(mml->mml_marker.cm_tgtname, marker->cm_tgtname) == 0) &&
847 !(marker->cm_flags & CM_SKIP)) {
848 /* Found a non-skipped marker match */
849 CDEBUG(D_MGS, "Changing rec %u marker %d %x->%x: %s %s\n",
850 rec->lrh_index, marker->cm_step,
851 marker->cm_flags, mml->mml_marker.cm_flags,
852 marker->cm_tgtname, marker->cm_comment);
853 /* Overwrite the old marker llog entry */
854 marker->cm_flags &= ~CM_EXCLUDE; /* in case we're unexcluding */
855 marker->cm_flags |= mml->mml_marker.cm_flags;
856 marker->cm_canceltime = mml->mml_marker.cm_canceltime;
857 rc = llog_write(env, llh, rec, rec->lrh_index);
866 * Modify an existing config log record (for CM_SKIP or CM_EXCLUDE)
868 * 0 - modified successfully,
869 * 1 - no modification was done
872 static int mgs_modify(const struct lu_env *env, struct mgs_device *mgs,
873 struct fs_db *fsdb, struct mgs_target_info *mti,
874 char *logname, char *devname, char *comment, int flags)
876 struct llog_handle *loghandle;
877 struct llog_ctxt *ctxt;
878 struct mgs_modify_lookup *mml;
883 LASSERT(mutex_is_locked(&fsdb->fsdb_mutex));
884 CDEBUG(D_MGS, "modify %s/%s/%s fl=%x\n", logname, devname, comment,
887 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
888 LASSERT(ctxt != NULL);
889 rc = llog_open(env, ctxt, &loghandle, NULL, logname, LLOG_OPEN_EXISTS);
896 rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL);
900 if (llog_get_size(loghandle) <= 1)
901 GOTO(out_close, rc = 0);
905 GOTO(out_close, rc = -ENOMEM);
906 if (strlcpy(mml->mml_marker.cm_comment, comment,
907 sizeof(mml->mml_marker.cm_comment)) >=
908 sizeof(mml->mml_marker.cm_comment))
909 GOTO(out_free, rc = -E2BIG);
910 if (strlcpy(mml->mml_marker.cm_tgtname, devname,
911 sizeof(mml->mml_marker.cm_tgtname)) >=
912 sizeof(mml->mml_marker.cm_tgtname))
913 GOTO(out_free, rc = -E2BIG);
914 /* Modify mostly means cancel */
915 mml->mml_marker.cm_flags = flags;
916 mml->mml_marker.cm_canceltime = flags ? cfs_time_current_sec() : 0;
917 mml->mml_modified = 0;
918 rc = llog_process(env, loghandle, mgs_modify_handler, (void *)mml,
920 if (!rc && !mml->mml_modified)
927 llog_close(env, loghandle);
930 CERROR("%s: modify %s/%s failed: rc = %d\n",
931 mgs->mgs_obd->obd_name, mti->mti_svname, comment, rc);
936 /** This structure is passed to mgs_replace_handler */
937 struct mgs_replace_uuid_lookup {
938 /* Nids are replaced for this target device */
939 struct mgs_target_info target;
940 /* Temporary modified llog */
941 struct llog_handle *temp_llh;
942 /* Flag is set if in target block*/
943 int in_target_device;
944 /* Nids already added. Just skip (multiple nids) */
945 int device_nids_added;
946 /* Flag is set if this block should not be copied */
951 * Check: a) if block should be skipped
952 * b) is it target block
957 * \retval 0 should not to be skipped
958 * \retval 1 should to be skipped
960 static int check_markers(struct lustre_cfg *lcfg,
961 struct mgs_replace_uuid_lookup *mrul)
963 struct cfg_marker *marker;
965 /* Track markers. Find given device */
966 if (lcfg->lcfg_command == LCFG_MARKER) {
967 marker = lustre_cfg_buf(lcfg, 1);
968 /* Clean llog from records marked as CM_EXCLUDE.
969 CM_SKIP records are used for "active" command
970 and can be restored if needed */
971 if ((marker->cm_flags & (CM_EXCLUDE | CM_START)) ==
972 (CM_EXCLUDE | CM_START)) {
977 if ((marker->cm_flags & (CM_EXCLUDE | CM_END)) ==
978 (CM_EXCLUDE | CM_END)) {
983 if (strcmp(mrul->target.mti_svname, marker->cm_tgtname) == 0) {
984 LASSERT(!(marker->cm_flags & CM_START) ||
985 !(marker->cm_flags & CM_END));
986 if (marker->cm_flags & CM_START) {
987 mrul->in_target_device = 1;
988 mrul->device_nids_added = 0;
989 } else if (marker->cm_flags & CM_END)
990 mrul->in_target_device = 0;
997 static int record_base(const struct lu_env *env, struct llog_handle *llh,
998 char *cfgname, lnet_nid_t nid, int cmd,
999 char *s1, char *s2, char *s3, char *s4)
1001 struct mgs_thread_info *mgi = mgs_env_info(env);
1002 struct llog_cfg_rec *lcr;
1005 CDEBUG(D_MGS, "lcfg %s %#x %s %s %s %s\n", cfgname,
1006 cmd, s1, s2, s3, s4);
1008 lustre_cfg_bufs_reset(&mgi->mgi_bufs, cfgname);
1010 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, s1);
1012 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 2, s2);
1014 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 3, s3);
1016 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 4, s4);
1018 lcr = lustre_cfg_rec_new(cmd, &mgi->mgi_bufs);
1022 lcr->lcr_cfg.lcfg_nid = nid;
1023 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1025 lustre_cfg_rec_free(lcr);
1029 "failed to write lcfg %s %#x %s %s %s %s: rc = %d\n",
1030 cfgname, cmd, s1, s2, s3, s4, rc);
1034 static inline int record_add_uuid(const struct lu_env *env,
1035 struct llog_handle *llh,
1036 uint64_t nid, char *uuid)
1038 return record_base(env, llh, NULL, nid, LCFG_ADD_UUID, uuid,
1042 static inline int record_add_conn(const struct lu_env *env,
1043 struct llog_handle *llh,
1044 char *devname, char *uuid)
1046 return record_base(env, llh, devname, 0, LCFG_ADD_CONN, uuid,
1050 static inline int record_attach(const struct lu_env *env,
1051 struct llog_handle *llh, char *devname,
1052 char *type, char *uuid)
1054 return record_base(env, llh, devname, 0, LCFG_ATTACH, type, uuid,
1058 static inline int record_setup(const struct lu_env *env,
1059 struct llog_handle *llh, char *devname,
1060 char *s1, char *s2, char *s3, char *s4)
1062 return record_base(env, llh, devname, 0, LCFG_SETUP, s1, s2, s3, s4);
1066 * \retval <0 record processing error
1067 * \retval n record is processed. No need copy original one.
1068 * \retval 0 record is not processed.
1070 static int process_command(const struct lu_env *env, struct lustre_cfg *lcfg,
1071 struct mgs_replace_uuid_lookup *mrul)
1078 if (lcfg->lcfg_command == LCFG_ADD_UUID) {
1079 /* LCFG_ADD_UUID command found. Let's skip original command
1080 and add passed nids */
1081 ptr = mrul->target.mti_params;
1082 while (class_parse_nid(ptr, &nid, &ptr) == 0) {
1083 CDEBUG(D_MGS, "add nid %s with uuid %s, "
1084 "device %s\n", libcfs_nid2str(nid),
1085 mrul->target.mti_params,
1086 mrul->target.mti_svname);
1087 rc = record_add_uuid(env,
1088 mrul->temp_llh, nid,
1089 mrul->target.mti_params);
1094 if (nids_added == 0) {
1095 CERROR("No new nids were added, nid %s with uuid %s, "
1096 "device %s\n", libcfs_nid2str(nid),
1097 mrul->target.mti_params,
1098 mrul->target.mti_svname);
1101 mrul->device_nids_added = 1;
1107 if (mrul->device_nids_added && lcfg->lcfg_command == LCFG_SETUP) {
1108 /* LCFG_SETUP command found. UUID should be changed */
1109 rc = record_setup(env,
1111 /* devname the same */
1112 lustre_cfg_string(lcfg, 0),
1113 /* s1 is not changed */
1114 lustre_cfg_string(lcfg, 1),
1115 /* new uuid should be
1117 mrul->target.mti_params,
1118 /* s3 is not changed */
1119 lustre_cfg_string(lcfg, 3),
1120 /* s4 is not changed */
1121 lustre_cfg_string(lcfg, 4));
1125 /* Another commands in target device block */
1130 * Handler that called for every record in llog.
1131 * Records are processed in order they placed in llog.
1133 * \param[in] llh log to be processed
1134 * \param[in] rec current record
1135 * \param[in] data mgs_replace_uuid_lookup structure
1139 static int mgs_replace_handler(const struct lu_env *env,
1140 struct llog_handle *llh,
1141 struct llog_rec_hdr *rec,
1144 struct mgs_replace_uuid_lookup *mrul;
1145 struct lustre_cfg *lcfg = REC_DATA(rec);
1146 int cfg_len = REC_DATA_LEN(rec);
1150 mrul = (struct mgs_replace_uuid_lookup *)data;
1152 if (rec->lrh_type != OBD_CFG_REC) {
1153 CERROR("unhandled lrh_type: %#x, cmd %x %s %s\n",
1154 rec->lrh_type, lcfg->lcfg_command,
1155 lustre_cfg_string(lcfg, 0),
1156 lustre_cfg_string(lcfg, 1));
1160 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
1162 /* Do not copy any invalidated records */
1163 GOTO(skip_out, rc = 0);
1166 rc = check_markers(lcfg, mrul);
1167 if (rc || mrul->skip_it)
1168 GOTO(skip_out, rc = 0);
1170 /* Write to new log all commands outside target device block */
1171 if (!mrul->in_target_device)
1172 GOTO(copy_out, rc = 0);
1174 /* Skip all other LCFG_ADD_UUID and LCFG_ADD_CONN records
1175 (failover nids) for this target, assuming that if then
1176 primary is changing then so is the failover */
1177 if (mrul->device_nids_added &&
1178 (lcfg->lcfg_command == LCFG_ADD_UUID ||
1179 lcfg->lcfg_command == LCFG_ADD_CONN))
1180 GOTO(skip_out, rc = 0);
1182 rc = process_command(env, lcfg, mrul);
1189 /* Record is placed in temporary llog as is */
1190 rc = llog_write(env, mrul->temp_llh, rec, LLOG_NEXT_IDX);
1192 CDEBUG(D_MGS, "Copied idx=%d, rc=%d, len=%d, cmd %x %s %s\n",
1193 rec->lrh_index, rc, rec->lrh_len, lcfg->lcfg_command,
1194 lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));
1198 CDEBUG(D_MGS, "Skipped idx=%d, rc=%d, len=%d, cmd %x %s %s\n",
1199 rec->lrh_index, rc, rec->lrh_len, lcfg->lcfg_command,
1200 lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));
1204 static int mgs_log_is_empty(const struct lu_env *env,
1205 struct mgs_device *mgs, char *name)
1207 struct llog_ctxt *ctxt;
1210 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
1211 LASSERT(ctxt != NULL);
1213 rc = llog_is_empty(env, ctxt, name);
1214 llog_ctxt_put(ctxt);
1218 static int mgs_replace_nids_log(const struct lu_env *env,
1219 struct obd_device *mgs, struct fs_db *fsdb,
1220 char *logname, char *devname, char *nids)
1222 struct llog_handle *orig_llh, *backup_llh;
1223 struct llog_ctxt *ctxt;
1224 struct mgs_replace_uuid_lookup *mrul;
1225 struct mgs_device *mgs_dev = lu2mgs_dev(mgs->obd_lu_dev);
1226 static struct obd_uuid cfg_uuid = { .uuid = "config_uuid" };
1231 CDEBUG(D_MGS, "Replace nids for %s in %s\n", devname, logname);
1233 ctxt = llog_get_context(mgs, LLOG_CONFIG_ORIG_CTXT);
1234 LASSERT(ctxt != NULL);
1236 if (mgs_log_is_empty(env, mgs_dev, logname)) {
1237 /* Log is empty. Nothing to replace */
1238 GOTO(out_put, rc = 0);
1241 OBD_ALLOC(backup, strlen(logname) + strlen(".bak") + 1);
1243 GOTO(out_put, rc = -ENOMEM);
1245 sprintf(backup, "%s.bak", logname);
1247 rc = llog_backup(env, mgs, ctxt, ctxt, logname, backup);
1249 /* Now erase original log file. Connections are not allowed.
1250 Backup is already saved */
1251 rc = llog_erase(env, ctxt, NULL, logname);
1254 } else if (rc != -ENOENT) {
1255 CERROR("%s: can't make backup for %s: rc = %d\n",
1256 mgs->obd_name, logname, rc);
1260 /* open local log */
1261 rc = llog_open_create(env, ctxt, &orig_llh, NULL, logname);
1263 GOTO(out_restore, rc);
1265 rc = llog_init_handle(env, orig_llh, LLOG_F_IS_PLAIN, &cfg_uuid);
1267 GOTO(out_closel, rc);
1269 /* open backup llog */
1270 rc = llog_open(env, ctxt, &backup_llh, NULL, backup,
1273 GOTO(out_closel, rc);
1275 rc = llog_init_handle(env, backup_llh, LLOG_F_IS_PLAIN, NULL);
1277 GOTO(out_close, rc);
1279 if (llog_get_size(backup_llh) <= 1)
1280 GOTO(out_close, rc = 0);
1282 OBD_ALLOC_PTR(mrul);
1284 GOTO(out_close, rc = -ENOMEM);
1285 /* devname is only needed information to replace UUID records */
1286 strlcpy(mrul->target.mti_svname, devname,
1287 sizeof(mrul->target.mti_svname));
1288 /* parse nids later */
1289 strlcpy(mrul->target.mti_params, nids, sizeof(mrul->target.mti_params));
1290 /* Copy records to this temporary llog */
1291 mrul->temp_llh = orig_llh;
1293 rc = llog_process(env, backup_llh, mgs_replace_handler,
1294 (void *)mrul, NULL);
1297 rc2 = llog_close(NULL, backup_llh);
1301 rc2 = llog_close(NULL, orig_llh);
1307 CERROR("%s: llog should be restored: rc = %d\n",
1309 rc2 = llog_backup(env, mgs, ctxt, ctxt, backup,
1312 CERROR("%s: can't restore backup %s: rc = %d\n",
1313 mgs->obd_name, logname, rc2);
1317 OBD_FREE(backup, strlen(backup) + 1);
1320 llog_ctxt_put(ctxt);
1323 CERROR("%s: failed to replace nids in log %s: rc = %d\n",
1324 mgs->obd_name, logname, rc);
1330 * Parse device name and get file system name and/or device index
1332 * \param[in] devname device name (ex. lustre-MDT0000)
1333 * \param[out] fsname file system name(optional)
1334 * \param[out] index device index(optional)
1338 static int mgs_parse_devname(char *devname, char *fsname, __u32 *index)
1343 /* Extract fsname */
1345 rc = server_name2fsname(devname, fsname, NULL);
1347 CDEBUG(D_MGS, "Device name %s without fsname\n",
1354 rc = server_name2index(devname, index, NULL);
1356 CDEBUG(D_MGS, "Device name %s with wrong index\n",
1365 /* This is only called during replace_nids */
1366 static int only_mgs_is_running(struct obd_device *mgs_obd)
1368 /* TDB: Is global variable with devices count exists? */
1369 int num_devices = get_devices_count();
1370 int num_exports = 0;
1371 struct obd_export *exp;
1373 spin_lock(&mgs_obd->obd_dev_lock);
1374 list_for_each_entry(exp, &mgs_obd->obd_exports, exp_obd_chain) {
1375 /* skip self export */
1376 if (exp == mgs_obd->obd_self_export)
1378 if (exp_connect_flags(exp) & OBD_CONNECT_MDS_MDS)
1383 CERROR("%s: node %s still connected during replace_nids "
1384 "connect_flags:%llx\n",
1386 libcfs_nid2str(exp->exp_nid_stats->nid),
1387 exp_connect_flags(exp));
1390 spin_unlock(&mgs_obd->obd_dev_lock);
1392 /* osd, MGS and MGC + self_export
1393 (wc -l /proc/fs/lustre/devices <= 2) && (non self exports == 0) */
1394 return (num_devices <= 3) && (num_exports == 0);
1397 static int name_create_mdt(char **logname, char *fsname, int i)
1401 sprintf(mdt_index, "-MDT%04x", i);
1402 return name_create(logname, fsname, mdt_index);
1406 * Replace nids for \a device to \a nids values
1408 * \param obd MGS obd device
1409 * \param devname nids need to be replaced for this device
1410 * (ex. lustre-OST0000)
1411 * \param nids nids list (ex. nid1,nid2,nid3)
1415 int mgs_replace_nids(const struct lu_env *env,
1416 struct mgs_device *mgs,
1417 char *devname, char *nids)
1419 /* Assume fsname is part of device name */
1420 char fsname[MTI_NAME_MAXLEN];
1424 struct fs_db *fsdb = NULL;
1427 struct obd_device *mgs_obd = mgs->mgs_obd;
1430 /* We can only change NIDs if no other nodes are connected */
1431 spin_lock(&mgs_obd->obd_dev_lock);
1432 conn_state = mgs_obd->obd_no_conn;
1433 mgs_obd->obd_no_conn = 1;
1434 spin_unlock(&mgs_obd->obd_dev_lock);
1436 /* We can not change nids if not only MGS is started */
1437 if (!only_mgs_is_running(mgs_obd)) {
1438 CERROR("Only MGS is allowed to be started\n");
1439 GOTO(out, rc = -EINPROGRESS);
1442 /* Get fsname and index*/
1443 rc = mgs_parse_devname(devname, fsname, &index);
1447 rc = mgs_find_or_make_fsdb(env, mgs, fsname, &fsdb);
1449 CERROR("%s: can't find fsdb: rc = %d\n", fsname, rc);
1453 /* Process client llogs */
1454 name_create(&logname, fsname, "-client");
1455 rc = mgs_replace_nids_log(env, mgs_obd, fsdb, logname, devname, nids);
1456 name_destroy(&logname);
1458 CERROR("%s: error while replacing NIDs for %s: rc = %d\n",
1459 fsname, devname, rc);
1463 /* Process MDT llogs */
1464 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
1465 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
1467 name_create_mdt(&logname, fsname, i);
1468 rc = mgs_replace_nids_log(env, mgs_obd, fsdb, logname, devname, nids);
1469 name_destroy(&logname);
1475 spin_lock(&mgs_obd->obd_dev_lock);
1476 mgs_obd->obd_no_conn = conn_state;
1477 spin_unlock(&mgs_obd->obd_dev_lock);
1480 mgs_put_fsdb(mgs, fsdb);
1485 static int record_lov_setup(const struct lu_env *env, struct llog_handle *llh,
1486 char *devname, struct lov_desc *desc)
1488 struct mgs_thread_info *mgi = mgs_env_info(env);
1489 struct llog_cfg_rec *lcr;
1492 lustre_cfg_bufs_reset(&mgi->mgi_bufs, devname);
1493 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, desc, sizeof(*desc));
1494 lcr = lustre_cfg_rec_new(LCFG_SETUP, &mgi->mgi_bufs);
1498 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1499 lustre_cfg_rec_free(lcr);
1503 static int record_lmv_setup(const struct lu_env *env, struct llog_handle *llh,
1504 char *devname, struct lmv_desc *desc)
1506 struct mgs_thread_info *mgi = mgs_env_info(env);
1507 struct llog_cfg_rec *lcr;
1510 lustre_cfg_bufs_reset(&mgi->mgi_bufs, devname);
1511 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, desc, sizeof(*desc));
1512 lcr = lustre_cfg_rec_new(LCFG_SETUP, &mgi->mgi_bufs);
1516 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1517 lustre_cfg_rec_free(lcr);
1521 static inline int record_mdc_add(const struct lu_env *env,
1522 struct llog_handle *llh,
1523 char *logname, char *mdcuuid,
1524 char *mdtuuid, char *index,
1527 return record_base(env,llh,logname,0,LCFG_ADD_MDC,
1528 mdtuuid,index,gen,mdcuuid);
1531 static inline int record_lov_add(const struct lu_env *env,
1532 struct llog_handle *llh,
1533 char *lov_name, char *ost_uuid,
1534 char *index, char *gen)
1536 return record_base(env, llh, lov_name, 0, LCFG_LOV_ADD_OBD,
1537 ost_uuid, index, gen, NULL);
1540 static inline int record_mount_opt(const struct lu_env *env,
1541 struct llog_handle *llh,
1542 char *profile, char *lov_name,
1545 return record_base(env, llh, NULL, 0, LCFG_MOUNTOPT,
1546 profile, lov_name, mdc_name, NULL);
1549 static int record_marker(const struct lu_env *env,
1550 struct llog_handle *llh,
1551 struct fs_db *fsdb, __u32 flags,
1552 char *tgtname, char *comment)
1554 struct mgs_thread_info *mgi = mgs_env_info(env);
1555 struct llog_cfg_rec *lcr;
1559 if (flags & CM_START)
1561 mgi->mgi_marker.cm_step = fsdb->fsdb_gen;
1562 mgi->mgi_marker.cm_flags = flags;
1563 mgi->mgi_marker.cm_vers = LUSTRE_VERSION_CODE;
1564 cplen = strlcpy(mgi->mgi_marker.cm_tgtname, tgtname,
1565 sizeof(mgi->mgi_marker.cm_tgtname));
1566 if (cplen >= sizeof(mgi->mgi_marker.cm_tgtname))
1568 cplen = strlcpy(mgi->mgi_marker.cm_comment, comment,
1569 sizeof(mgi->mgi_marker.cm_comment));
1570 if (cplen >= sizeof(mgi->mgi_marker.cm_comment))
1572 mgi->mgi_marker.cm_createtime = cfs_time_current_sec();
1573 mgi->mgi_marker.cm_canceltime = 0;
1574 lustre_cfg_bufs_reset(&mgi->mgi_bufs, NULL);
1575 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, &mgi->mgi_marker,
1576 sizeof(mgi->mgi_marker));
1577 lcr = lustre_cfg_rec_new(LCFG_MARKER, &mgi->mgi_bufs);
1581 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1582 lustre_cfg_rec_free(lcr);
1586 static int record_start_log(const struct lu_env *env, struct mgs_device *mgs,
1587 struct llog_handle **llh, char *name)
1589 static struct obd_uuid cfg_uuid = { .uuid = "config_uuid" };
1590 struct llog_ctxt *ctxt;
1595 GOTO(out, rc = -EBUSY);
1597 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
1599 GOTO(out, rc = -ENODEV);
1600 LASSERT(ctxt->loc_obd == mgs->mgs_obd);
1602 rc = llog_open_create(env, ctxt, llh, NULL, name);
1605 rc = llog_init_handle(env, *llh, LLOG_F_IS_PLAIN, &cfg_uuid);
1607 llog_close(env, *llh);
1609 llog_ctxt_put(ctxt);
1612 CERROR("%s: can't start log %s: rc = %d\n",
1613 mgs->mgs_obd->obd_name, name, rc);
1619 static int record_end_log(const struct lu_env *env, struct llog_handle **llh)
1623 rc = llog_close(env, *llh);
1629 /******************** config "macros" *********************/
1631 /* write an lcfg directly into a log (with markers) */
1632 static int mgs_write_log_direct(const struct lu_env *env,
1633 struct mgs_device *mgs, struct fs_db *fsdb,
1634 char *logname, struct llog_cfg_rec *lcr,
1635 char *devname, char *comment)
1637 struct llog_handle *llh = NULL;
1642 rc = record_start_log(env, mgs, &llh, logname);
1646 /* FIXME These should be a single journal transaction */
1647 rc = record_marker(env, llh, fsdb, CM_START, devname, comment);
1650 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1653 rc = record_marker(env, llh, fsdb, CM_END, devname, comment);
1657 record_end_log(env, &llh);
1661 /* write the lcfg in all logs for the given fs */
1662 static int mgs_write_log_direct_all(const struct lu_env *env,
1663 struct mgs_device *mgs,
1665 struct mgs_target_info *mti,
1666 struct llog_cfg_rec *lcr, char *devname,
1667 char *comment, int server_only)
1669 struct list_head log_list;
1670 struct mgs_direntry *dirent, *n;
1671 char *fsname = mti->mti_fsname;
1672 int rc = 0, len = strlen(fsname);
1675 /* Find all the logs in the CONFIGS directory */
1676 rc = class_dentry_readdir(env, mgs, &log_list);
1680 /* Could use fsdb index maps instead of directory listing */
1681 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
1682 list_del_init(&dirent->mde_list);
1683 /* don't write to sptlrpc rule log */
1684 if (strstr(dirent->mde_name, "-sptlrpc") != NULL)
1687 /* caller wants write server logs only */
1688 if (server_only && strstr(dirent->mde_name, "-client") != NULL)
1691 if (strlen(dirent->mde_name) <= len ||
1692 strncmp(fsname, dirent->mde_name, len) != 0 ||
1693 dirent->mde_name[len] != '-')
1696 CDEBUG(D_MGS, "Changing log %s\n", dirent->mde_name);
1697 /* Erase any old settings of this same parameter */
1698 rc = mgs_modify(env, mgs, fsdb, mti, dirent->mde_name,
1699 devname, comment, CM_SKIP);
1701 CERROR("%s: Can't modify llog %s: rc = %d\n",
1702 mgs->mgs_obd->obd_name, dirent->mde_name, rc);
1705 /* Write the new one */
1706 rc = mgs_write_log_direct(env, mgs, fsdb, dirent->mde_name,
1707 lcr, devname, comment);
1709 CERROR("%s: writing log %s: rc = %d\n",
1710 mgs->mgs_obd->obd_name, dirent->mde_name, rc);
1712 mgs_direntry_free(dirent);
1718 static int mgs_write_log_osp_to_mdt(const struct lu_env *env,
1719 struct mgs_device *mgs,
1721 struct mgs_target_info *mti,
1722 int index, char *logname);
1723 static int mgs_write_log_osc_to_lov(const struct lu_env *env,
1724 struct mgs_device *mgs,
1726 struct mgs_target_info *mti,
1727 char *logname, char *suffix, char *lovname,
1728 enum lustre_sec_part sec_part, int flags);
1729 static int name_create_mdt_and_lov(char **logname, char **lovname,
1730 struct fs_db *fsdb, int i);
1732 static int add_param(char *params, char *key, char *val)
1734 char *start = params + strlen(params);
1735 char *end = params + sizeof(((struct mgs_target_info *)0)->mti_params);
1739 keylen = strlen(key);
1740 if (start + 1 + keylen + strlen(val) >= end) {
1741 CERROR("params are too long: %s %s%s\n",
1742 params, key != NULL ? key : "", val);
1746 sprintf(start, " %s%s", key != NULL ? key : "", val);
1751 * Walk through client config log record and convert the related records
1754 static int mgs_steal_client_llog_handler(const struct lu_env *env,
1755 struct llog_handle *llh,
1756 struct llog_rec_hdr *rec, void *data)
1758 struct mgs_device *mgs;
1759 struct obd_device *obd;
1760 struct mgs_target_info *mti, *tmti;
1762 int cfg_len = rec->lrh_len;
1763 char *cfg_buf = (char*) (rec + 1);
1764 struct lustre_cfg *lcfg;
1766 struct llog_handle *mdt_llh = NULL;
1767 static int got_an_osc_or_mdc = 0;
1768 /* 0: not found any osc/mdc;
1772 static int last_step = -1;
1777 mti = ((struct temp_comp*)data)->comp_mti;
1778 tmti = ((struct temp_comp*)data)->comp_tmti;
1779 fsdb = ((struct temp_comp*)data)->comp_fsdb;
1780 obd = ((struct temp_comp *)data)->comp_obd;
1781 mgs = lu2mgs_dev(obd->obd_lu_dev);
1784 if (rec->lrh_type != OBD_CFG_REC) {
1785 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
1789 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
1791 CERROR("Insane cfg\n");
1795 lcfg = (struct lustre_cfg *)cfg_buf;
1797 if (lcfg->lcfg_command == LCFG_MARKER) {
1798 struct cfg_marker *marker;
1799 marker = lustre_cfg_buf(lcfg, 1);
1800 if (!strncmp(marker->cm_comment, "add osc", 7) &&
1801 (marker->cm_flags & CM_START) &&
1802 !(marker->cm_flags & CM_SKIP)) {
1803 got_an_osc_or_mdc = 1;
1804 cplen = strlcpy(tmti->mti_svname, marker->cm_tgtname,
1805 sizeof(tmti->mti_svname));
1806 if (cplen >= sizeof(tmti->mti_svname))
1808 rc = record_start_log(env, mgs, &mdt_llh,
1812 rc = record_marker(env, mdt_llh, fsdb, CM_START,
1813 mti->mti_svname, "add osc(copied)");
1814 record_end_log(env, &mdt_llh);
1815 last_step = marker->cm_step;
1818 if (!strncmp(marker->cm_comment, "add osc", 7) &&
1819 (marker->cm_flags & CM_END) &&
1820 !(marker->cm_flags & CM_SKIP)) {
1821 LASSERT(last_step == marker->cm_step);
1823 got_an_osc_or_mdc = 0;
1824 memset(tmti, 0, sizeof(*tmti));
1825 rc = record_start_log(env, mgs, &mdt_llh,
1829 rc = record_marker(env, mdt_llh, fsdb, CM_END,
1830 mti->mti_svname, "add osc(copied)");
1831 record_end_log(env, &mdt_llh);
1834 if (!strncmp(marker->cm_comment, "add mdc", 7) &&
1835 (marker->cm_flags & CM_START) &&
1836 !(marker->cm_flags & CM_SKIP)) {
1837 got_an_osc_or_mdc = 2;
1838 last_step = marker->cm_step;
1839 memcpy(tmti->mti_svname, marker->cm_tgtname,
1840 strlen(marker->cm_tgtname));
1844 if (!strncmp(marker->cm_comment, "add mdc", 7) &&
1845 (marker->cm_flags & CM_END) &&
1846 !(marker->cm_flags & CM_SKIP)) {
1847 LASSERT(last_step == marker->cm_step);
1849 got_an_osc_or_mdc = 0;
1850 memset(tmti, 0, sizeof(*tmti));
1855 if (got_an_osc_or_mdc == 0 || last_step < 0)
1858 if (lcfg->lcfg_command == LCFG_ADD_UUID) {
1859 __u64 nodenid = lcfg->lcfg_nid;
1861 if (strlen(tmti->mti_uuid) == 0) {
1862 /* target uuid not set, this config record is before
1863 * LCFG_SETUP, this nid is one of target node nid.
1865 tmti->mti_nids[tmti->mti_nid_count] = nodenid;
1866 tmti->mti_nid_count++;
1868 char nidstr[LNET_NIDSTR_SIZE];
1870 /* failover node nid */
1871 libcfs_nid2str_r(nodenid, nidstr, sizeof(nidstr));
1872 rc = add_param(tmti->mti_params, PARAM_FAILNODE,
1879 if (lcfg->lcfg_command == LCFG_SETUP) {
1882 target = lustre_cfg_string(lcfg, 1);
1883 memcpy(tmti->mti_uuid, target, strlen(target));
1887 /* ignore client side sptlrpc_conf_log */
1888 if (lcfg->lcfg_command == LCFG_SPTLRPC_CONF)
1891 if (lcfg->lcfg_command == LCFG_ADD_MDC) {
1894 if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1)
1897 memcpy(tmti->mti_fsname, mti->mti_fsname,
1898 strlen(mti->mti_fsname));
1899 tmti->mti_stripe_index = index;
1901 rc = mgs_write_log_osp_to_mdt(env, mgs, fsdb, tmti,
1902 mti->mti_stripe_index,
1904 memset(tmti, 0, sizeof(*tmti));
1908 if (lcfg->lcfg_command == LCFG_LOV_ADD_OBD) {
1911 char *logname, *lovname;
1913 rc = name_create_mdt_and_lov(&logname, &lovname, fsdb,
1914 mti->mti_stripe_index);
1917 sprintf(mdt_index, "-MDT%04x", mti->mti_stripe_index);
1919 if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1) {
1920 name_destroy(&logname);
1921 name_destroy(&lovname);
1925 tmti->mti_stripe_index = index;
1926 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, tmti, logname,
1929 name_destroy(&logname);
1930 name_destroy(&lovname);
1936 /* fsdb->fsdb_mutex is already held in mgs_write_log_target*/
1937 /* stealed from mgs_get_fsdb_from_llog*/
1938 static int mgs_steal_llog_for_mdt_from_client(const struct lu_env *env,
1939 struct mgs_device *mgs,
1941 struct temp_comp* comp)
1943 struct llog_handle *loghandle;
1944 struct mgs_target_info *tmti;
1945 struct llog_ctxt *ctxt;
1950 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
1951 LASSERT(ctxt != NULL);
1953 OBD_ALLOC_PTR(tmti);
1955 GOTO(out_ctxt, rc = -ENOMEM);
1957 comp->comp_tmti = tmti;
1958 comp->comp_obd = mgs->mgs_obd;
1960 rc = llog_open(env, ctxt, &loghandle, NULL, client_name,
1968 rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL);
1970 GOTO(out_close, rc);
1972 rc = llog_process_or_fork(env, loghandle, mgs_steal_client_llog_handler,
1973 (void *)comp, NULL, false);
1974 CDEBUG(D_MGS, "steal llog re = %d\n", rc);
1976 llog_close(env, loghandle);
1980 llog_ctxt_put(ctxt);
1984 /* lmv is the second thing for client logs */
1985 /* copied from mgs_write_log_lov. Please refer to that. */
1986 static int mgs_write_log_lmv(const struct lu_env *env,
1987 struct mgs_device *mgs,
1989 struct mgs_target_info *mti,
1990 char *logname, char *lmvname)
1992 struct llog_handle *llh = NULL;
1993 struct lmv_desc *lmvdesc;
1998 CDEBUG(D_MGS, "Writing lmv(%s) log for %s\n", lmvname,logname);
2000 OBD_ALLOC_PTR(lmvdesc);
2001 if (lmvdesc == NULL)
2003 lmvdesc->ld_active_tgt_count = 0;
2004 lmvdesc->ld_tgt_count = 0;
2005 sprintf((char*)lmvdesc->ld_uuid.uuid, "%s_UUID", lmvname);
2006 uuid = (char *)lmvdesc->ld_uuid.uuid;
2008 rc = record_start_log(env, mgs, &llh, logname);
2011 rc = record_marker(env, llh, fsdb, CM_START, lmvname, "lmv setup");
2014 rc = record_attach(env, llh, lmvname, "lmv", uuid);
2017 rc = record_lmv_setup(env, llh, lmvname, lmvdesc);
2020 rc = record_marker(env, llh, fsdb, CM_END, lmvname, "lmv setup");
2024 record_end_log(env, &llh);
2026 OBD_FREE_PTR(lmvdesc);
2030 /* lov is the first thing in the mdt and client logs */
2031 static int mgs_write_log_lov(const struct lu_env *env, struct mgs_device *mgs,
2032 struct fs_db *fsdb, struct mgs_target_info *mti,
2033 char *logname, char *lovname)
2035 struct llog_handle *llh = NULL;
2036 struct lov_desc *lovdesc;
2041 CDEBUG(D_MGS, "Writing lov(%s) log for %s\n", lovname, logname);
2044 #01 L attach 0:lov_mdsA 1:lov 2:71ccb_lov_mdsA_19f961a9e1
2045 #02 L lov_setup 0:lov_mdsA 1:(struct lov_desc)
2046 uuid=lov1_UUID, stripe count=1, size=1048576, offset=0, pattern=0
2049 /* FIXME just make lov_setup accept empty desc (put uuid in buf 2) */
2050 OBD_ALLOC_PTR(lovdesc);
2051 if (lovdesc == NULL)
2053 lovdesc->ld_magic = LOV_DESC_MAGIC;
2054 lovdesc->ld_tgt_count = 0;
2055 /* Defaults. Can be changed later by lcfg config_param */
2056 lovdesc->ld_default_stripe_count = 1;
2057 lovdesc->ld_pattern = LOV_PATTERN_RAID0;
2058 lovdesc->ld_default_stripe_size = LOV_DESC_STRIPE_SIZE_DEFAULT;
2059 lovdesc->ld_default_stripe_offset = -1;
2060 lovdesc->ld_qos_maxage = LOV_DESC_QOS_MAXAGE_DEFAULT;
2061 sprintf((char*)lovdesc->ld_uuid.uuid, "%s_UUID", lovname);
2062 /* can these be the same? */
2063 uuid = (char *)lovdesc->ld_uuid.uuid;
2065 /* This should always be the first entry in a log.
2066 rc = mgs_clear_log(obd, logname); */
2067 rc = record_start_log(env, mgs, &llh, logname);
2070 /* FIXME these should be a single journal transaction */
2071 rc = record_marker(env, llh, fsdb, CM_START, lovname, "lov setup");
2074 rc = record_attach(env, llh, lovname, "lov", uuid);
2077 rc = record_lov_setup(env, llh, lovname, lovdesc);
2080 rc = record_marker(env, llh, fsdb, CM_END, lovname, "lov setup");
2085 record_end_log(env, &llh);
2087 OBD_FREE_PTR(lovdesc);
2091 /* add failnids to open log */
2092 static int mgs_write_log_failnids(const struct lu_env *env,
2093 struct mgs_target_info *mti,
2094 struct llog_handle *llh,
2097 char *failnodeuuid = NULL;
2098 char *ptr = mti->mti_params;
2103 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) nal=90 0: 1:uml1_UUID
2104 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
2105 #05 L setup 0:OSC_uml1_ost1_mdsA 1:ost1_UUID 2:uml1_UUID
2106 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) nal=90 0: 1:uml2_UUID
2107 #0x L add_uuid nid=2@elan(0x1000000000002) nal=90 0: 1:uml2_UUID
2108 #07 L add_conn 0:OSC_uml1_ost1_mdsA 1:uml2_UUID
2112 * Pull failnid info out of params string, which may contain something
2113 * like "<nid1>,<nid2>:<nid3>,<nid4>". class_parse_nid() does not
2114 * complain about abnormal inputs like ",:<nid1>", "<nid1>:,<nid2>",
2115 * etc. However, convert_hostnames() should have caught those.
2117 while (class_find_param(ptr, PARAM_FAILNODE, &ptr) == 0) {
2118 while (class_parse_nid(ptr, &nid, &ptr) == 0) {
2119 char nidstr[LNET_NIDSTR_SIZE];
2121 if (failnodeuuid == NULL) {
2122 /* We don't know the failover node name,
2123 * so just use the first nid as the uuid */
2124 libcfs_nid2str_r(nid, nidstr, sizeof(nidstr));
2125 rc = name_create(&failnodeuuid, nidstr, "");
2129 CDEBUG(D_MGS, "add nid %s for failover uuid %s, "
2131 libcfs_nid2str_r(nid, nidstr, sizeof(nidstr)),
2132 failnodeuuid, cliname);
2133 rc = record_add_uuid(env, llh, nid, failnodeuuid);
2135 * If *ptr is ':', we have added all NIDs for
2139 rc = record_add_conn(env, llh, cliname,
2141 name_destroy(&failnodeuuid);
2142 failnodeuuid = NULL;
2146 rc = record_add_conn(env, llh, cliname, failnodeuuid);
2147 name_destroy(&failnodeuuid);
2148 failnodeuuid = NULL;
2155 static int mgs_write_log_mdc_to_lmv(const struct lu_env *env,
2156 struct mgs_device *mgs,
2158 struct mgs_target_info *mti,
2159 char *logname, char *lmvname)
2161 struct llog_handle *llh = NULL;
2162 char *mdcname = NULL;
2163 char *nodeuuid = NULL;
2164 char *mdcuuid = NULL;
2165 char *lmvuuid = NULL;
2167 char nidstr[LNET_NIDSTR_SIZE];
2171 if (mgs_log_is_empty(env, mgs, logname)) {
2172 CERROR("log is empty! Logical error\n");
2176 CDEBUG(D_MGS, "adding mdc for %s to log %s:lmv(%s)\n",
2177 mti->mti_svname, logname, lmvname);
2179 libcfs_nid2str_r(mti->mti_nids[0], nidstr, sizeof(nidstr));
2180 rc = name_create(&nodeuuid, nidstr, "");
2183 rc = name_create(&mdcname, mti->mti_svname, "-mdc");
2186 rc = name_create(&mdcuuid, mdcname, "_UUID");
2189 rc = name_create(&lmvuuid, lmvname, "_UUID");
2193 rc = record_start_log(env, mgs, &llh, logname);
2196 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
2200 for (i = 0; i < mti->mti_nid_count; i++) {
2201 CDEBUG(D_MGS, "add nid %s for mdt\n",
2202 libcfs_nid2str_r(mti->mti_nids[i],
2203 nidstr, sizeof(nidstr)));
2205 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
2210 rc = record_attach(env, llh, mdcname, LUSTRE_MDC_NAME, lmvuuid);
2213 rc = record_setup(env, llh, mdcname, mti->mti_uuid, nodeuuid,
2217 rc = mgs_write_log_failnids(env, mti, llh, mdcname);
2220 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
2221 rc = record_mdc_add(env, llh, lmvname, mdcuuid, mti->mti_uuid,
2225 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname,
2230 record_end_log(env, &llh);
2232 name_destroy(&lmvuuid);
2233 name_destroy(&mdcuuid);
2234 name_destroy(&mdcname);
2235 name_destroy(&nodeuuid);
2239 static inline int name_create_lov(char **lovname, char *mdtname,
2240 struct fs_db *fsdb, int index)
2243 if (index == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2244 return name_create(lovname, fsdb->fsdb_name, "-mdtlov");
2246 return name_create(lovname, mdtname, "-mdtlov");
2249 static int name_create_mdt_and_lov(char **logname, char **lovname,
2250 struct fs_db *fsdb, int i)
2254 rc = name_create_mdt(logname, fsdb->fsdb_name, i);
2258 if (i == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2259 rc = name_create(lovname, fsdb->fsdb_name, "-mdtlov");
2261 rc = name_create(lovname, *logname, "-mdtlov");
2263 name_destroy(logname);
2269 static inline int name_create_mdt_osc(char **oscname, char *ostname,
2270 struct fs_db *fsdb, int i)
2274 if (i == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2275 sprintf(suffix, "-osc");
2277 sprintf(suffix, "-osc-MDT%04x", i);
2278 return name_create(oscname, ostname, suffix);
2281 /* add new mdc to already existent MDS */
2282 static int mgs_write_log_osp_to_mdt(const struct lu_env *env,
2283 struct mgs_device *mgs,
2285 struct mgs_target_info *mti,
2286 int mdt_index, char *logname)
2288 struct llog_handle *llh = NULL;
2289 char *nodeuuid = NULL;
2290 char *ospname = NULL;
2291 char *lovuuid = NULL;
2292 char *mdtuuid = NULL;
2293 char *svname = NULL;
2294 char *mdtname = NULL;
2295 char *lovname = NULL;
2297 char nidstr[LNET_NIDSTR_SIZE];
2301 if (mgs_log_is_empty(env, mgs, mti->mti_svname)) {
2302 CERROR("log is empty! Logical error\n");
2306 CDEBUG(D_MGS, "adding osp index %d to %s\n", mti->mti_stripe_index,
2309 rc = name_create_mdt(&mdtname, fsdb->fsdb_name, mti->mti_stripe_index);
2313 libcfs_nid2str_r(mti->mti_nids[0], nidstr, sizeof(nidstr));
2314 rc = name_create(&nodeuuid, nidstr, "");
2316 GOTO(out_destory, rc);
2318 rc = name_create(&svname, mdtname, "-osp");
2320 GOTO(out_destory, rc);
2322 sprintf(index_str, "-MDT%04x", mdt_index);
2323 rc = name_create(&ospname, svname, index_str);
2325 GOTO(out_destory, rc);
2327 rc = name_create_lov(&lovname, logname, fsdb, mdt_index);
2329 GOTO(out_destory, rc);
2331 rc = name_create(&lovuuid, lovname, "_UUID");
2333 GOTO(out_destory, rc);
2335 rc = name_create(&mdtuuid, mdtname, "_UUID");
2337 GOTO(out_destory, rc);
2339 rc = record_start_log(env, mgs, &llh, logname);
2341 GOTO(out_destory, rc);
2343 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
2346 GOTO(out_destory, rc);
2348 for (i = 0; i < mti->mti_nid_count; i++) {
2349 CDEBUG(D_MGS, "add nid %s for mdt\n",
2350 libcfs_nid2str_r(mti->mti_nids[i],
2351 nidstr, sizeof(nidstr)));
2352 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
2357 rc = record_attach(env, llh, ospname, LUSTRE_OSP_NAME, lovuuid);
2361 rc = record_setup(env, llh, ospname, mti->mti_uuid, nodeuuid,
2366 rc = mgs_write_log_failnids(env, mti, llh, ospname);
2370 /* Add mdc(osp) to lod */
2371 snprintf(index_str, sizeof(index_str), "%d", mti->mti_stripe_index);
2372 rc = record_base(env, llh, lovname, 0, LCFG_ADD_MDC, mti->mti_uuid,
2373 index_str, "1", NULL);
2377 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname, "add osp");
2382 record_end_log(env, &llh);
2385 name_destroy(&mdtuuid);
2386 name_destroy(&lovuuid);
2387 name_destroy(&lovname);
2388 name_destroy(&ospname);
2389 name_destroy(&svname);
2390 name_destroy(&nodeuuid);
2391 name_destroy(&mdtname);
2395 static int mgs_write_log_mdt0(const struct lu_env *env,
2396 struct mgs_device *mgs,
2398 struct mgs_target_info *mti)
2400 char *log = mti->mti_svname;
2401 struct llog_handle *llh = NULL;
2402 char *uuid, *lovname;
2404 char *ptr = mti->mti_params;
2405 int rc = 0, failout = 0;
2408 OBD_ALLOC(uuid, sizeof(struct obd_uuid));
2412 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
2413 failout = (strncmp(ptr, "failout", 7) == 0);
2415 rc = name_create(&lovname, log, "-mdtlov");
2418 if (mgs_log_is_empty(env, mgs, log)) {
2419 rc = mgs_write_log_lov(env, mgs, fsdb, mti, log, lovname);
2424 sprintf(mdt_index, "%d", mti->mti_stripe_index);
2426 rc = record_start_log(env, mgs, &llh, log);
2430 /* add MDT itself */
2432 /* FIXME this whole fn should be a single journal transaction */
2433 sprintf(uuid, "%s_UUID", log);
2434 rc = record_marker(env, llh, fsdb, CM_START, log, "add mdt");
2437 rc = record_attach(env, llh, log, LUSTRE_MDT_NAME, uuid);
2440 rc = record_mount_opt(env, llh, log, lovname, NULL);
2443 rc = record_setup(env, llh, log, uuid, mdt_index, lovname,
2444 failout ? "n" : "f");
2447 rc = record_marker(env, llh, fsdb, CM_END, log, "add mdt");
2451 record_end_log(env, &llh);
2453 name_destroy(&lovname);
2455 OBD_FREE(uuid, sizeof(struct obd_uuid));
2459 /* envelope method for all layers log */
2460 static int mgs_write_log_mdt(const struct lu_env *env,
2461 struct mgs_device *mgs,
2463 struct mgs_target_info *mti)
2465 struct mgs_thread_info *mgi = mgs_env_info(env);
2466 struct llog_handle *llh = NULL;
2471 CDEBUG(D_MGS, "writing new mdt %s\n", mti->mti_svname);
2473 if (mti->mti_uuid[0] == '\0') {
2474 /* Make up our own uuid */
2475 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
2476 "%s_UUID", mti->mti_svname);
2480 rc = mgs_write_log_mdt0(env, mgs, fsdb, mti);
2483 /* Append the mdt info to the client log */
2484 rc = name_create(&cliname, mti->mti_fsname, "-client");
2488 if (mgs_log_is_empty(env, mgs, cliname)) {
2489 /* Start client log */
2490 rc = mgs_write_log_lov(env, mgs, fsdb, mti, cliname,
2494 rc = mgs_write_log_lmv(env, mgs, fsdb, mti, cliname,
2501 #09 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
2502 #10 L attach 0:MDC_uml1_mdsA_MNT_client 1:mdc 2:1d834_MNT_client_03f
2503 #11 L setup 0:MDC_uml1_mdsA_MNT_client 1:mdsA_UUID 2:uml1_UUID
2504 #12 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
2505 #13 L add_conn 0:MDC_uml1_mdsA_MNT_client 1:uml2_UUID
2506 #14 L mount_option 0: 1:client 2:lov1 3:MDC_uml1_mdsA_MNT_client
2509 /* copy client info about lov/lmv */
2510 mgi->mgi_comp.comp_mti = mti;
2511 mgi->mgi_comp.comp_fsdb = fsdb;
2513 rc = mgs_steal_llog_for_mdt_from_client(env, mgs, cliname,
2517 rc = mgs_write_log_mdc_to_lmv(env, mgs, fsdb, mti, cliname,
2523 rc = record_start_log(env, mgs, &llh, cliname);
2527 rc = record_marker(env, llh, fsdb, CM_START, cliname,
2531 rc = record_mount_opt(env, llh, cliname, fsdb->fsdb_clilov,
2535 rc = record_marker(env, llh, fsdb, CM_END, cliname,
2541 /* for_all_existing_mdt except current one */
2542 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2543 if (i != mti->mti_stripe_index &&
2544 test_bit(i, fsdb->fsdb_mdt_index_map)) {
2547 rc = name_create_mdt(&logname, fsdb->fsdb_name, i);
2551 /* NB: If the log for the MDT is empty, it means
2552 * the MDT is only added to the index
2553 * map, and not being process yet, i.e. this
2554 * is an unregistered MDT, see mgs_write_log_target().
2555 * so we should skip it. Otherwise
2557 * 1. MGS get register request for MDT1 and MDT2.
2559 * 2. Then both MDT1 and MDT2 are added into
2560 * fsdb_mdt_index_map. (see mgs_set_index()).
2562 * 3. Then MDT1 get the lock of fsdb_mutex, then
2563 * generate the config log, here, it will regard MDT2
2564 * as an existent MDT, and generate "add osp" for
2565 * lustre-MDT0001-osp-MDT0002. Note: at the moment
2566 * MDT0002 config log is still empty, so it will
2567 * add "add osp" even before "lov setup", which
2568 * will definitly cause trouble.
2570 * 4. MDT1 registeration finished, fsdb_mutex is
2571 * released, then MDT2 get in, then in above
2572 * mgs_steal_llog_for_mdt_from_client(), it will
2573 * add another osp log for lustre-MDT0001-osp-MDT0002,
2574 * which will cause another trouble.*/
2575 if (!mgs_log_is_empty(env, mgs, logname))
2576 rc = mgs_write_log_osp_to_mdt(env, mgs, fsdb,
2579 name_destroy(&logname);
2585 record_end_log(env, &llh);
2587 name_destroy(&cliname);
2591 /* Add the ost info to the client/mdt lov */
2592 static int mgs_write_log_osc_to_lov(const struct lu_env *env,
2593 struct mgs_device *mgs, struct fs_db *fsdb,
2594 struct mgs_target_info *mti,
2595 char *logname, char *suffix, char *lovname,
2596 enum lustre_sec_part sec_part, int flags)
2598 struct llog_handle *llh = NULL;
2599 char *nodeuuid = NULL;
2600 char *oscname = NULL;
2601 char *oscuuid = NULL;
2602 char *lovuuid = NULL;
2603 char *svname = NULL;
2605 char nidstr[LNET_NIDSTR_SIZE];
2609 CDEBUG(D_INFO, "adding osc for %s to log %s\n",
2610 mti->mti_svname, logname);
2612 if (mgs_log_is_empty(env, mgs, logname)) {
2613 CERROR("log is empty! Logical error\n");
2617 libcfs_nid2str_r(mti->mti_nids[0], nidstr, sizeof(nidstr));
2618 rc = name_create(&nodeuuid, nidstr, "");
2621 rc = name_create(&svname, mti->mti_svname, "-osc");
2625 /* for the system upgraded from old 1.8, keep using the old osc naming
2626 * style for mdt, see name_create_mdt_osc(). LU-1257 */
2627 if (test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2628 rc = name_create(&oscname, svname, "");
2630 rc = name_create(&oscname, svname, suffix);
2634 rc = name_create(&oscuuid, oscname, "_UUID");
2637 rc = name_create(&lovuuid, lovname, "_UUID");
2643 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
2645 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
2646 #04 L attach 0:OSC_uml1_ost1_MNT_client 1:osc 2:89070_lov1_a41dff51a
2647 #05 L setup 0:OSC_uml1_ost1_MNT_client 1:ost1_UUID 2:uml1_UUID
2649 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
2650 #07 L add_conn 0:OSC_uml1_ost1_MNT_client 1:uml2_UUID
2651 #08 L lov_modify_tgts add 0:lov1 1:ost1_UUID 2(index):0 3(gen):1
2654 rc = record_start_log(env, mgs, &llh, logname);
2658 /* FIXME these should be a single journal transaction */
2659 rc = record_marker(env, llh, fsdb, CM_START | flags, mti->mti_svname,
2664 /* NB: don't change record order, because upon MDT steal OSC config
2665 * from client, it treats all nids before LCFG_SETUP as target nids
2666 * (multiple interfaces), while nids after as failover node nids.
2667 * See mgs_steal_client_llog_handler() LCFG_ADD_UUID.
2669 for (i = 0; i < mti->mti_nid_count; i++) {
2670 CDEBUG(D_MGS, "add nid %s\n",
2671 libcfs_nid2str_r(mti->mti_nids[i],
2672 nidstr, sizeof(nidstr)));
2673 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
2677 rc = record_attach(env, llh, oscname, LUSTRE_OSC_NAME, lovuuid);
2680 rc = record_setup(env, llh, oscname, mti->mti_uuid, nodeuuid,
2684 rc = mgs_write_log_failnids(env, mti, llh, oscname);
2688 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
2690 rc = record_lov_add(env, llh, lovname, mti->mti_uuid, index, "1");
2693 rc = record_marker(env, llh, fsdb, CM_END | flags, mti->mti_svname,
2698 record_end_log(env, &llh);
2700 name_destroy(&lovuuid);
2701 name_destroy(&oscuuid);
2702 name_destroy(&oscname);
2703 name_destroy(&svname);
2704 name_destroy(&nodeuuid);
2708 static int mgs_write_log_ost(const struct lu_env *env,
2709 struct mgs_device *mgs, struct fs_db *fsdb,
2710 struct mgs_target_info *mti)
2712 struct llog_handle *llh = NULL;
2713 char *logname, *lovname;
2714 char *ptr = mti->mti_params;
2715 int rc, flags = 0, failout = 0, i;
2718 CDEBUG(D_MGS, "writing new ost %s\n", mti->mti_svname);
2720 /* The ost startup log */
2722 /* If the ost log already exists, that means that someone reformatted
2723 the ost and it called target_add again. */
2724 if (!mgs_log_is_empty(env, mgs, mti->mti_svname)) {
2725 LCONSOLE_ERROR_MSG(0x141, "The config log for %s already "
2726 "exists, yet the server claims it never "
2727 "registered. It may have been reformatted, "
2728 "or the index changed. writeconf the MDT to "
2729 "regenerate all logs.\n", mti->mti_svname);
2734 attach obdfilter ost1 ost1_UUID
2735 setup /dev/loop2 ldiskfs f|n errors=remount-ro,user_xattr
2737 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
2738 failout = (strncmp(ptr, "failout", 7) == 0);
2739 rc = record_start_log(env, mgs, &llh, mti->mti_svname);
2742 /* FIXME these should be a single journal transaction */
2743 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,"add ost");
2746 if (*mti->mti_uuid == '\0')
2747 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
2748 "%s_UUID", mti->mti_svname);
2749 rc = record_attach(env, llh, mti->mti_svname,
2750 "obdfilter"/*LUSTRE_OST_NAME*/, mti->mti_uuid);
2753 rc = record_setup(env, llh, mti->mti_svname,
2754 "dev"/*ignored*/, "type"/*ignored*/,
2755 failout ? "n" : "f", NULL/*options*/);
2758 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname, "add ost");
2762 record_end_log(env, &llh);
2765 /* We also have to update the other logs where this osc is part of
2768 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
2769 /* If we're upgrading, the old mdt log already has our
2770 entry. Let's do a fake one for fun. */
2771 /* Note that we can't add any new failnids, since we don't
2772 know the old osc names. */
2773 flags = CM_SKIP | CM_UPGRADE146;
2775 } else if ((mti->mti_flags & LDD_F_UPDATE) != LDD_F_UPDATE) {
2776 /* If the update flag isn't set, don't update client/mdt
2779 LCONSOLE_WARN("Client log for %s was not updated; writeconf "
2780 "the MDT first to regenerate it.\n",
2784 /* Add ost to all MDT lov defs */
2785 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
2786 if (test_bit(i, fsdb->fsdb_mdt_index_map)) {
2789 rc = name_create_mdt_and_lov(&logname, &lovname, fsdb,
2793 sprintf(mdt_index, "-MDT%04x", i);
2794 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, mti,
2796 lovname, LUSTRE_SP_MDT,
2798 name_destroy(&logname);
2799 name_destroy(&lovname);
2805 /* Append ost info to the client log */
2806 rc = name_create(&logname, mti->mti_fsname, "-client");
2809 if (mgs_log_is_empty(env, mgs, logname)) {
2810 /* Start client log */
2811 rc = mgs_write_log_lov(env, mgs, fsdb, mti, logname,
2815 rc = mgs_write_log_lmv(env, mgs, fsdb, mti, logname,
2820 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, mti, logname, "",
2821 fsdb->fsdb_clilov, LUSTRE_SP_CLI, flags);
2823 name_destroy(&logname);
2827 static __inline__ int mgs_param_empty(char *ptr)
2831 if ((tmp = strchr(ptr, '=')) && (*(++tmp) == '\0'))
2836 static int mgs_write_log_failnid_internal(const struct lu_env *env,
2837 struct mgs_device *mgs,
2839 struct mgs_target_info *mti,
2840 char *logname, char *cliname)
2843 struct llog_handle *llh = NULL;
2845 if (mgs_param_empty(mti->mti_params)) {
2846 /* Remove _all_ failnids */
2847 rc = mgs_modify(env, mgs, fsdb, mti, logname,
2848 mti->mti_svname, "add failnid", CM_SKIP);
2849 return rc < 0 ? rc : 0;
2852 /* Otherwise failover nids are additive */
2853 rc = record_start_log(env, mgs, &llh, logname);
2856 /* FIXME this should be a single journal transaction */
2857 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
2861 rc = mgs_write_log_failnids(env, mti, llh, cliname);
2864 rc = record_marker(env, llh, fsdb, CM_END,
2865 mti->mti_svname, "add failnid");
2867 record_end_log(env, &llh);
2872 /* Add additional failnids to an existing log.
2873 The mdc/osc must have been added to logs first */
2874 /* tcp nids must be in dotted-quad ascii -
2875 we can't resolve hostnames from the kernel. */
2876 static int mgs_write_log_add_failnid(const struct lu_env *env,
2877 struct mgs_device *mgs,
2879 struct mgs_target_info *mti)
2881 char *logname, *cliname;
2885 /* FIXME we currently can't erase the failnids
2886 * given when a target first registers, since they aren't part of
2887 * an "add uuid" stanza */
2889 /* Verify that we know about this target */
2890 if (mgs_log_is_empty(env, mgs, mti->mti_svname)) {
2891 LCONSOLE_ERROR_MSG(0x142, "The target %s has not registered "
2892 "yet. It must be started before failnids "
2893 "can be added.\n", mti->mti_svname);
2897 /* Create mdc/osc client name (e.g. lustre-OST0001-osc) */
2898 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
2899 rc = name_create(&cliname, mti->mti_svname, "-mdc");
2900 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2901 rc = name_create(&cliname, mti->mti_svname, "-osc");
2907 /* Add failover nids to the client log */
2908 rc = name_create(&logname, mti->mti_fsname, "-client");
2910 name_destroy(&cliname);
2913 rc = mgs_write_log_failnid_internal(env, mgs, fsdb,mti,logname,cliname);
2914 name_destroy(&logname);
2915 name_destroy(&cliname);
2919 if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2920 /* Add OST failover nids to the MDT logs as well */
2923 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2924 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
2926 rc = name_create_mdt(&logname, mti->mti_fsname, i);
2929 rc = name_create_mdt_osc(&cliname, mti->mti_svname,
2932 name_destroy(&logname);
2935 rc = mgs_write_log_failnid_internal(env, mgs, fsdb,
2938 name_destroy(&cliname);
2939 name_destroy(&logname);
2948 static int mgs_wlp_lcfg(const struct lu_env *env,
2949 struct mgs_device *mgs, struct fs_db *fsdb,
2950 struct mgs_target_info *mti,
2951 char *logname, struct lustre_cfg_bufs *bufs,
2952 char *tgtname, char *ptr)
2954 char comment[MTI_NAME_MAXLEN];
2956 struct llog_cfg_rec *lcr;
2959 /* Erase any old settings of this same parameter */
2960 memcpy(comment, ptr, MTI_NAME_MAXLEN);
2961 comment[MTI_NAME_MAXLEN - 1] = 0;
2962 /* But don't try to match the value. */
2963 tmp = strchr(comment, '=');
2966 /* FIXME we should skip settings that are the same as old values */
2967 rc = mgs_modify(env, mgs, fsdb, mti, logname, tgtname, comment,CM_SKIP);
2970 del = mgs_param_empty(ptr);
2972 LCONSOLE_INFO("%s parameter %s.%s in log %s\n", del ? "Disabling" : rc ?
2973 "Setting" : "Modifying", tgtname, comment, logname);
2975 /* mgs_modify() will return 1 if nothing had to be done */
2981 lustre_cfg_bufs_reset(bufs, tgtname);
2982 lustre_cfg_bufs_set_string(bufs, 1, ptr);
2983 if (mti->mti_flags & LDD_F_PARAM2)
2984 lustre_cfg_bufs_set_string(bufs, 2, LCTL_UPCALL);
2986 lcr = lustre_cfg_rec_new((mti->mti_flags & LDD_F_PARAM2) ?
2987 LCFG_SET_PARAM : LCFG_PARAM, bufs);
2991 rc = mgs_write_log_direct(env, mgs, fsdb, logname, lcr, tgtname,
2993 lustre_cfg_rec_free(lcr);
2997 static int mgs_write_log_param2(const struct lu_env *env,
2998 struct mgs_device *mgs,
3000 struct mgs_target_info *mti, char *ptr)
3002 struct lustre_cfg_bufs bufs;
3006 CDEBUG(D_MGS, "next param '%s'\n", ptr);
3007 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, PARAMS_FILENAME, &bufs,
3008 mti->mti_svname, ptr);
3013 /* write global variable settings into log */
3014 static int mgs_write_log_sys(const struct lu_env *env,
3015 struct mgs_device *mgs, struct fs_db *fsdb,
3016 struct mgs_target_info *mti, char *sys, char *ptr)
3018 struct mgs_thread_info *mgi = mgs_env_info(env);
3019 struct lustre_cfg *lcfg;
3020 struct llog_cfg_rec *lcr;
3022 int rc, cmd, convert = 1;
3024 if (class_match_param(ptr, PARAM_TIMEOUT, &tmp) == 0) {
3025 cmd = LCFG_SET_TIMEOUT;
3026 } else if (class_match_param(ptr, PARAM_LDLM_TIMEOUT, &tmp) == 0) {
3027 cmd = LCFG_SET_LDLM_TIMEOUT;
3028 /* Check for known params here so we can return error to lctl */
3029 } else if ((class_match_param(ptr, PARAM_AT_MIN, &tmp) == 0) ||
3030 (class_match_param(ptr, PARAM_AT_MAX, &tmp) == 0) ||
3031 (class_match_param(ptr, PARAM_AT_EXTRA, &tmp) == 0) ||
3032 (class_match_param(ptr, PARAM_AT_EARLY_MARGIN, &tmp) == 0) ||
3033 (class_match_param(ptr, PARAM_AT_HISTORY, &tmp) == 0)) {
3035 } else if (class_match_param(ptr, PARAM_JOBID_VAR, &tmp) == 0) {
3036 convert = 0; /* Don't convert string value to integer */
3042 if (mgs_param_empty(ptr))
3043 CDEBUG(D_MGS, "global '%s' removed\n", sys);
3045 CDEBUG(D_MGS, "global '%s' val=%s\n", sys, tmp);
3047 lustre_cfg_bufs_reset(&mgi->mgi_bufs, NULL);
3048 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, sys);
3049 if (!convert && *tmp != '\0')
3050 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 2, tmp);
3051 lcr = lustre_cfg_rec_new(cmd, &mgi->mgi_bufs);
3055 lcfg = &lcr->lcr_cfg;
3056 lcfg->lcfg_num = convert ? simple_strtoul(tmp, NULL, 0) : 0;
3057 /* truncate the comment to the parameter name */
3061 /* modify all servers and clients */
3062 rc = mgs_write_log_direct_all(env, mgs, fsdb, mti,
3063 *tmp == '\0' ? NULL : lcr,
3064 mti->mti_fsname, sys, 0);
3065 if (rc == 0 && *tmp != '\0') {
3067 case LCFG_SET_TIMEOUT:
3068 if (!obd_timeout_set || lcfg->lcfg_num > obd_timeout)
3069 class_process_config(lcfg);
3071 case LCFG_SET_LDLM_TIMEOUT:
3072 if (!ldlm_timeout_set || lcfg->lcfg_num > ldlm_timeout)
3073 class_process_config(lcfg);
3080 lustre_cfg_rec_free(lcr);
3084 /* write quota settings into log */
3085 static int mgs_write_log_quota(const struct lu_env *env, struct mgs_device *mgs,
3086 struct fs_db *fsdb, struct mgs_target_info *mti,
3087 char *quota, char *ptr)
3089 struct mgs_thread_info *mgi = mgs_env_info(env);
3090 struct llog_cfg_rec *lcr;
3093 int rc, cmd = LCFG_PARAM;
3095 /* support only 'meta' and 'data' pools so far */
3096 if (class_match_param(ptr, QUOTA_METAPOOL_NAME, &tmp) != 0 &&
3097 class_match_param(ptr, QUOTA_DATAPOOL_NAME, &tmp) != 0) {
3098 CERROR("parameter quota.%s isn't supported (only quota.mdt "
3099 "& quota.ost are)\n", ptr);
3104 CDEBUG(D_MGS, "global '%s' removed\n", quota);
3106 CDEBUG(D_MGS, "global '%s'\n", quota);
3108 if (strchr(tmp, 'u') == NULL && strchr(tmp, 'g') == NULL &&
3109 strcmp(tmp, "none") != 0) {
3110 CERROR("enable option(%s) isn't supported\n", tmp);
3115 lustre_cfg_bufs_reset(&mgi->mgi_bufs, mti->mti_fsname);
3116 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, quota);
3117 lcr = lustre_cfg_rec_new(cmd, &mgi->mgi_bufs);
3121 /* truncate the comment to the parameter name */
3126 /* XXX we duplicated quota enable information in all server
3127 * config logs, it should be moved to a separate config
3128 * log once we cleanup the config log for global param. */
3129 /* modify all servers */
3130 rc = mgs_write_log_direct_all(env, mgs, fsdb, mti,
3131 *tmp == '\0' ? NULL : lcr,
3132 mti->mti_fsname, quota, 1);
3134 lustre_cfg_rec_free(lcr);
3135 return rc < 0 ? rc : 0;
3138 static int mgs_srpc_set_param_disk(const struct lu_env *env,
3139 struct mgs_device *mgs,
3141 struct mgs_target_info *mti,
3144 struct mgs_thread_info *mgi = mgs_env_info(env);
3145 struct llog_cfg_rec *lcr;
3146 struct llog_handle *llh = NULL;
3148 char *comment, *ptr;
3154 ptr = strchr(param, '=');
3155 LASSERT(ptr != NULL);
3158 OBD_ALLOC(comment, len + 1);
3159 if (comment == NULL)
3161 strncpy(comment, param, len);
3162 comment[len] = '\0';
3165 lustre_cfg_bufs_reset(&mgi->mgi_bufs, mti->mti_svname);
3166 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, param);
3167 lcr = lustre_cfg_rec_new(LCFG_SPTLRPC_CONF, &mgi->mgi_bufs);
3169 GOTO(out_comment, rc = -ENOMEM);
3171 /* construct log name */
3172 rc = name_create(&logname, mti->mti_fsname, "-sptlrpc");
3176 if (mgs_log_is_empty(env, mgs, logname)) {
3177 rc = record_start_log(env, mgs, &llh, logname);
3180 record_end_log(env, &llh);
3183 /* obsolete old one */
3184 rc = mgs_modify(env, mgs, fsdb, mti, logname, mti->mti_svname,
3188 /* write the new one */
3189 rc = mgs_write_log_direct(env, mgs, fsdb, logname, lcr,
3190 mti->mti_svname, comment);
3192 CERROR("%s: error writing log %s: rc = %d\n",
3193 mgs->mgs_obd->obd_name, logname, rc);
3195 name_destroy(&logname);
3197 lustre_cfg_rec_free(lcr);
3199 OBD_FREE(comment, len + 1);
3203 static int mgs_srpc_set_param_udesc_mem(struct fs_db *fsdb,
3208 /* disable the adjustable udesc parameter for now, i.e. use default
3209 * setting that client always ship udesc to MDT if possible. to enable
3210 * it simply remove the following line */
3213 ptr = strchr(param, '=');
3218 if (strcmp(param, PARAM_SRPC_UDESC))
3221 if (strcmp(ptr, "yes") == 0) {
3222 set_bit(FSDB_UDESC, &fsdb->fsdb_flags);
3223 CWARN("Enable user descriptor shipping from client to MDT\n");
3224 } else if (strcmp(ptr, "no") == 0) {
3225 clear_bit(FSDB_UDESC, &fsdb->fsdb_flags);
3226 CWARN("Disable user descriptor shipping from client to MDT\n");
3234 CERROR("Invalid param: %s\n", param);
3238 static int mgs_srpc_set_param_mem(struct fs_db *fsdb,
3242 struct sptlrpc_rule rule;
3243 struct sptlrpc_rule_set *rset;
3247 if (strncmp(param, PARAM_SRPC, sizeof(PARAM_SRPC) - 1) != 0) {
3248 CERROR("Invalid sptlrpc parameter: %s\n", param);
3252 if (strncmp(param, PARAM_SRPC_UDESC,
3253 sizeof(PARAM_SRPC_UDESC) - 1) == 0) {
3254 RETURN(mgs_srpc_set_param_udesc_mem(fsdb, param));
3257 if (strncmp(param, PARAM_SRPC_FLVR, sizeof(PARAM_SRPC_FLVR) - 1) != 0) {
3258 CERROR("Invalid sptlrpc flavor parameter: %s\n", param);
3262 param += sizeof(PARAM_SRPC_FLVR) - 1;
3264 rc = sptlrpc_parse_rule(param, &rule);
3268 /* mgs rules implies must be mgc->mgs */
3269 if (test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
3270 if ((rule.sr_from != LUSTRE_SP_MGC &&
3271 rule.sr_from != LUSTRE_SP_ANY) ||
3272 (rule.sr_to != LUSTRE_SP_MGS &&
3273 rule.sr_to != LUSTRE_SP_ANY))
3277 /* preapre room for this coming rule. svcname format should be:
3278 * - fsname: general rule
3279 * - fsname-tgtname: target-specific rule
3281 if (strchr(svname, '-')) {
3282 struct mgs_tgt_srpc_conf *tgtconf;
3285 for (tgtconf = fsdb->fsdb_srpc_tgt; tgtconf != NULL;
3286 tgtconf = tgtconf->mtsc_next) {
3287 if (!strcmp(tgtconf->mtsc_tgt, svname)) {
3296 OBD_ALLOC_PTR(tgtconf);
3297 if (tgtconf == NULL)
3300 name_len = strlen(svname);
3302 OBD_ALLOC(tgtconf->mtsc_tgt, name_len + 1);
3303 if (tgtconf->mtsc_tgt == NULL) {
3304 OBD_FREE_PTR(tgtconf);
3307 memcpy(tgtconf->mtsc_tgt, svname, name_len);
3309 tgtconf->mtsc_next = fsdb->fsdb_srpc_tgt;
3310 fsdb->fsdb_srpc_tgt = tgtconf;
3313 rset = &tgtconf->mtsc_rset;
3314 } else if (strcmp(svname, MGSSELF_NAME) == 0) {
3315 /* put _mgs related srpc rule directly in mgs ruleset */
3316 rset = &fsdb->fsdb_mgs->mgs_lut.lut_sptlrpc_rset;
3318 rset = &fsdb->fsdb_srpc_gen;
3321 rc = sptlrpc_rule_set_merge(rset, &rule);
3326 static int mgs_srpc_set_param(const struct lu_env *env,
3327 struct mgs_device *mgs,
3329 struct mgs_target_info *mti,
3339 /* keep a copy of original param, which could be destroied
3341 copy_size = strlen(param) + 1;
3342 OBD_ALLOC(copy, copy_size);
3345 memcpy(copy, param, copy_size);
3347 rc = mgs_srpc_set_param_mem(fsdb, mti->mti_svname, param);
3351 /* previous steps guaranteed the syntax is correct */
3352 rc = mgs_srpc_set_param_disk(env, mgs, fsdb, mti, copy);
3356 if (test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
3358 * for mgs rules, make them effective immediately.
3360 LASSERT(fsdb->fsdb_srpc_tgt == NULL);
3361 sptlrpc_target_update_exp_flavor(mgs->mgs_obd,
3362 &fsdb->fsdb_srpc_gen);
3366 OBD_FREE(copy, copy_size);
3370 struct mgs_srpc_read_data {
3371 struct fs_db *msrd_fsdb;
3375 static int mgs_srpc_read_handler(const struct lu_env *env,
3376 struct llog_handle *llh,
3377 struct llog_rec_hdr *rec, void *data)
3379 struct mgs_srpc_read_data *msrd = data;
3380 struct cfg_marker *marker;
3381 struct lustre_cfg *lcfg = REC_DATA(rec);
3382 char *svname, *param;
3386 if (rec->lrh_type != OBD_CFG_REC) {
3387 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
3391 cfg_len = REC_DATA_LEN(rec);
3393 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
3395 CERROR("Insane cfg\n");
3399 if (lcfg->lcfg_command == LCFG_MARKER) {
3400 marker = lustre_cfg_buf(lcfg, 1);
3402 if (marker->cm_flags & CM_START &&
3403 marker->cm_flags & CM_SKIP)
3404 msrd->msrd_skip = 1;
3405 if (marker->cm_flags & CM_END)
3406 msrd->msrd_skip = 0;
3411 if (msrd->msrd_skip)
3414 if (lcfg->lcfg_command != LCFG_SPTLRPC_CONF) {
3415 CERROR("invalid command (%x)\n", lcfg->lcfg_command);
3419 svname = lustre_cfg_string(lcfg, 0);
3420 if (svname == NULL) {
3421 CERROR("svname is empty\n");
3425 param = lustre_cfg_string(lcfg, 1);
3426 if (param == NULL) {
3427 CERROR("param is empty\n");
3431 rc = mgs_srpc_set_param_mem(msrd->msrd_fsdb, svname, param);
3433 CERROR("read sptlrpc record error (%d): %s\n", rc, param);
3438 int mgs_get_fsdb_srpc_from_llog(const struct lu_env *env,
3439 struct mgs_device *mgs,
3442 struct llog_handle *llh = NULL;
3443 struct llog_ctxt *ctxt;
3445 struct mgs_srpc_read_data msrd;
3449 /* construct log name */
3450 rc = name_create(&logname, fsdb->fsdb_name, "-sptlrpc");
3454 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
3455 LASSERT(ctxt != NULL);
3457 if (mgs_log_is_empty(env, mgs, logname))
3460 rc = llog_open(env, ctxt, &llh, NULL, logname,
3468 rc = llog_init_handle(env, llh, LLOG_F_IS_PLAIN, NULL);
3470 GOTO(out_close, rc);
3472 if (llog_get_size(llh) <= 1)
3473 GOTO(out_close, rc = 0);
3475 msrd.msrd_fsdb = fsdb;
3478 rc = llog_process(env, llh, mgs_srpc_read_handler, (void *)&msrd,
3482 llog_close(env, llh);
3484 llog_ctxt_put(ctxt);
3485 name_destroy(&logname);
3488 CERROR("failed to read sptlrpc config database: %d\n", rc);
3492 /* Permanent settings of all parameters by writing into the appropriate
3493 * configuration logs.
3494 * A parameter with null value ("<param>='\0'") means to erase it out of
3497 static int mgs_write_log_param(const struct lu_env *env,
3498 struct mgs_device *mgs, struct fs_db *fsdb,
3499 struct mgs_target_info *mti, char *ptr)
3501 struct mgs_thread_info *mgi = mgs_env_info(env);
3507 /* For various parameter settings, we have to figure out which logs
3508 care about them (e.g. both mdt and client for lov settings) */
3509 CDEBUG(D_MGS, "next param '%s'\n", ptr);
3511 /* The params are stored in MOUNT_DATA_FILE and modified via
3512 tunefs.lustre, or set using lctl conf_param */
3514 /* Processed in lustre_start_mgc */
3515 if (class_match_param(ptr, PARAM_MGSNODE, NULL) == 0)
3518 /* Processed in ost/mdt */
3519 if (class_match_param(ptr, PARAM_NETWORK, NULL) == 0)
3522 /* Processed in mgs_write_log_ost */
3523 if (class_match_param(ptr, PARAM_FAILMODE, NULL) == 0) {
3524 if (mti->mti_flags & LDD_F_PARAM) {
3525 LCONSOLE_ERROR_MSG(0x169, "%s can only be "
3526 "changed with tunefs.lustre"
3527 "and --writeconf\n", ptr);
3533 if (class_match_param(ptr, PARAM_SRPC, NULL) == 0) {
3534 rc = mgs_srpc_set_param(env, mgs, fsdb, mti, ptr);
3538 if (class_match_param(ptr, PARAM_FAILNODE, NULL) == 0) {
3539 /* Add a failover nidlist */
3541 /* We already processed failovers params for new
3542 targets in mgs_write_log_target */
3543 if (mti->mti_flags & LDD_F_PARAM) {
3544 CDEBUG(D_MGS, "Adding failnode\n");
3545 rc = mgs_write_log_add_failnid(env, mgs, fsdb, mti);
3550 if (class_match_param(ptr, PARAM_SYS, &tmp) == 0) {
3551 rc = mgs_write_log_sys(env, mgs, fsdb, mti, ptr, tmp);
3555 if (class_match_param(ptr, PARAM_QUOTA, &tmp) == 0) {
3556 rc = mgs_write_log_quota(env, mgs, fsdb, mti, ptr, tmp);
3560 if (class_match_param(ptr, PARAM_OSC PARAM_ACTIVE, &tmp) == 0 ||
3561 class_match_param(ptr, PARAM_MDC PARAM_ACTIVE, &tmp) == 0) {
3562 /* active=0 means off, anything else means on */
3563 int flag = (*tmp == '0') ? CM_EXCLUDE : 0;
3564 bool deactive_osc = memcmp(ptr, PARAM_OSC PARAM_ACTIVE,
3565 strlen(PARAM_OSC PARAM_ACTIVE)) == 0;
3568 if (!deactive_osc) {
3571 rc = server_name2index(mti->mti_svname, &index, NULL);
3576 LCONSOLE_ERROR_MSG(0x144, "%s: MDC0 can not be"
3577 " (de)activated.\n",
3579 GOTO(end, rc = -EINVAL);
3583 LCONSOLE_WARN("Permanently %sactivating %s\n",
3584 flag ? "de" : "re", mti->mti_svname);
3586 rc = name_create(&logname, mti->mti_fsname, "-client");
3589 rc = mgs_modify(env, mgs, fsdb, mti, logname,
3591 deactive_osc ? "add osc" : "add mdc", flag);
3592 name_destroy(&logname);
3597 /* Add to all MDT logs for DNE */
3598 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3599 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
3601 rc = name_create_mdt(&logname, mti->mti_fsname, i);
3604 rc = mgs_modify(env, mgs, fsdb, mti, logname,
3606 deactive_osc ? "add osc" : "add osp",
3608 name_destroy(&logname);
3614 LCONSOLE_ERROR_MSG(0x145, "Couldn't find %s in"
3615 "log (%d). No permanent "
3616 "changes were made to the "
3618 mti->mti_svname, rc);
3619 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags))
3620 LCONSOLE_ERROR_MSG(0x146, "This may be"
3625 "update the logs.\n");
3628 /* Fall through to osc/mdc proc for deactivating live
3629 OSC/OSP on running MDT / clients. */
3631 /* Below here, let obd's XXX_process_config methods handle it */
3633 /* All lov. in proc */
3634 if (class_match_param(ptr, PARAM_LOV, NULL) == 0) {
3637 CDEBUG(D_MGS, "lov param %s\n", ptr);
3638 if (!(mti->mti_flags & LDD_F_SV_TYPE_MDT)) {
3639 LCONSOLE_ERROR_MSG(0x147, "LOV params must be "
3640 "set on the MDT, not %s. "
3647 if (mgs_log_is_empty(env, mgs, mti->mti_svname))
3648 GOTO(end, rc = -ENODEV);
3650 rc = name_create_mdt_and_lov(&logname, &mdtlovname, fsdb,
3651 mti->mti_stripe_index);
3654 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, mti->mti_svname,
3655 &mgi->mgi_bufs, mdtlovname, ptr);
3656 name_destroy(&logname);
3657 name_destroy(&mdtlovname);
3662 rc = name_create(&logname, mti->mti_fsname, "-client");
3665 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname, &mgi->mgi_bufs,
3666 fsdb->fsdb_clilov, ptr);
3667 name_destroy(&logname);
3671 /* All osc., mdc., llite. params in proc */
3672 if ((class_match_param(ptr, PARAM_OSC, NULL) == 0) ||
3673 (class_match_param(ptr, PARAM_MDC, NULL) == 0) ||
3674 (class_match_param(ptr, PARAM_LLITE, NULL) == 0)) {
3677 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
3678 LCONSOLE_ERROR_MSG(0x148, "Upgraded client logs for %s"
3679 " cannot be modified. Consider"
3680 " updating the configuration with"
3683 GOTO(end, rc = -EINVAL);
3685 if (memcmp(ptr, PARAM_LLITE, strlen(PARAM_LLITE)) == 0) {
3686 rc = name_create(&cname, mti->mti_fsname, "-client");
3687 /* Add the client type to match the obdname in
3688 class_config_llog_handler */
3689 } else if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
3690 rc = name_create(&cname, mti->mti_svname, "-mdc");
3691 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
3692 rc = name_create(&cname, mti->mti_svname, "-osc");
3694 GOTO(end, rc = -EINVAL);
3699 /* Forbid direct update of llite root squash parameters.
3700 * These parameters are indirectly set via the MDT settings.
3702 if ((class_match_param(ptr, PARAM_LLITE, &tmp) == 0) &&
3703 ((memcmp(tmp, "root_squash=", 12) == 0) ||
3704 (memcmp(tmp, "nosquash_nids=", 14) == 0))) {
3705 LCONSOLE_ERROR("%s: root squash parameters can only "
3706 "be updated through MDT component\n",
3708 name_destroy(&cname);
3709 GOTO(end, rc = -EINVAL);
3712 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
3715 rc = name_create(&logname, mti->mti_fsname, "-client");
3717 name_destroy(&cname);
3720 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname, &mgi->mgi_bufs,
3723 /* osc params affect the MDT as well */
3724 if (!rc && (mti->mti_flags & LDD_F_SV_TYPE_OST)) {
3727 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
3728 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
3730 name_destroy(&cname);
3731 rc = name_create_mdt_osc(&cname, mti->mti_svname,
3733 name_destroy(&logname);
3736 rc = name_create_mdt(&logname,
3737 mti->mti_fsname, i);
3740 if (!mgs_log_is_empty(env, mgs, logname)) {
3741 rc = mgs_wlp_lcfg(env, mgs, fsdb,
3751 /* For mdc activate/deactivate, it affects OSP on MDT as well */
3752 if (class_match_param(ptr, PARAM_MDC PARAM_ACTIVE, &tmp) == 0 &&
3755 char *lodname = NULL;
3756 char *param_str = NULL;
3760 /* replace mdc with osp */
3761 memcpy(ptr, PARAM_OSP, strlen(PARAM_OSP));
3762 rc = server_name2index(mti->mti_svname, &index, NULL);
3764 memcpy(ptr, PARAM_MDC, strlen(PARAM_MDC));
3768 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3769 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
3775 name_destroy(&logname);
3776 rc = name_create_mdt(&logname, mti->mti_fsname,
3781 if (mgs_log_is_empty(env, mgs, logname))
3784 snprintf(suffix, sizeof(suffix), "-osp-MDT%04x",
3786 name_destroy(&cname);
3787 rc = name_create(&cname, mti->mti_svname,
3792 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname,
3793 &mgi->mgi_bufs, cname, ptr);
3797 /* Add configuration log for noitfying LOD
3798 * to active/deactive the OSP. */
3799 name_destroy(¶m_str);
3800 rc = name_create(¶m_str, cname,
3801 (*tmp == '0') ? ".active=0" :
3806 name_destroy(&lodname);
3807 rc = name_create(&lodname, logname, "-mdtlov");
3811 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname,
3812 &mgi->mgi_bufs, lodname,
3817 memcpy(ptr, PARAM_MDC, strlen(PARAM_MDC));
3818 name_destroy(&lodname);
3819 name_destroy(¶m_str);
3822 name_destroy(&logname);
3823 name_destroy(&cname);
3827 /* All mdt. params in proc */
3828 if (class_match_param(ptr, PARAM_MDT, &tmp) == 0) {
3832 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
3833 if (strncmp(mti->mti_svname, mti->mti_fsname,
3834 MTI_NAME_MAXLEN) == 0)
3835 /* device is unspecified completely? */
3836 rc = LDD_F_SV_TYPE_MDT | LDD_F_SV_ALL;
3838 rc = server_name2index(mti->mti_svname, &idx, NULL);
3841 if ((rc & LDD_F_SV_TYPE_MDT) == 0)
3843 if (rc & LDD_F_SV_ALL) {
3844 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3846 fsdb->fsdb_mdt_index_map))
3848 rc = name_create_mdt(&logname,
3849 mti->mti_fsname, i);
3852 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti,
3853 logname, &mgi->mgi_bufs,
3855 name_destroy(&logname);
3860 if ((memcmp(tmp, "root_squash=", 12) == 0) ||
3861 (memcmp(tmp, "nosquash_nids=", 14) == 0)) {
3862 LCONSOLE_ERROR("%s: root squash parameters "
3863 "cannot be applied to a single MDT\n",
3865 GOTO(end, rc = -EINVAL);
3867 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti,
3868 mti->mti_svname, &mgi->mgi_bufs,
3869 mti->mti_svname, ptr);
3874 /* root squash settings are also applied to llite
3875 * config log (see LU-1778) */
3877 ((memcmp(tmp, "root_squash=", 12) == 0) ||
3878 (memcmp(tmp, "nosquash_nids=", 14) == 0))) {
3882 rc = name_create(&cname, mti->mti_fsname, "-client");
3885 rc = name_create(&logname, mti->mti_fsname, "-client");
3887 name_destroy(&cname);
3890 rc = name_create(&ptr2, PARAM_LLITE, tmp);
3892 name_destroy(&cname);
3893 name_destroy(&logname);
3896 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname,
3897 &mgi->mgi_bufs, cname, ptr2);
3898 name_destroy(&ptr2);
3899 name_destroy(&logname);
3900 name_destroy(&cname);
3905 /* All mdd., ost. and osd. params in proc */
3906 if ((class_match_param(ptr, PARAM_MDD, NULL) == 0) ||
3907 (class_match_param(ptr, PARAM_OST, NULL) == 0) ||
3908 (class_match_param(ptr, PARAM_OSD, NULL) == 0)) {
3909 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
3910 if (mgs_log_is_empty(env, mgs, mti->mti_svname))
3911 GOTO(end, rc = -ENODEV);
3913 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, mti->mti_svname,
3914 &mgi->mgi_bufs, mti->mti_svname, ptr);
3918 LCONSOLE_WARN("Ignoring unrecognized param '%s'\n", ptr);
3922 CERROR("err %d on param '%s'\n", rc, ptr);
3927 int mgs_write_log_target(const struct lu_env *env, struct mgs_device *mgs,
3928 struct mgs_target_info *mti, struct fs_db *fsdb)
3935 /* set/check the new target index */
3936 rc = mgs_set_index(env, mgs, mti);
3940 if (rc == EALREADY) {
3941 LCONSOLE_WARN("Found index %d for %s, updating log\n",
3942 mti->mti_stripe_index, mti->mti_svname);
3943 /* We would like to mark old log sections as invalid
3944 and add new log sections in the client and mdt logs.
3945 But if we add new sections, then live clients will
3946 get repeat setup instructions for already running
3947 osc's. So don't update the client/mdt logs. */
3948 mti->mti_flags &= ~LDD_F_UPDATE;
3952 OBD_FAIL_TIMEOUT(OBD_FAIL_MGS_WRITE_TARGET_DELAY, cfs_fail_val > 0 ?
3955 mutex_lock(&fsdb->fsdb_mutex);
3957 if (mti->mti_flags &
3958 (LDD_F_VIRGIN | LDD_F_UPGRADE14 | LDD_F_WRITECONF)) {
3959 /* Generate a log from scratch */
3960 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
3961 rc = mgs_write_log_mdt(env, mgs, fsdb, mti);
3962 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
3963 rc = mgs_write_log_ost(env, mgs, fsdb, mti);
3965 CERROR("Unknown target type %#x, can't create log for "
3966 "%s\n", mti->mti_flags, mti->mti_svname);
3969 CERROR("Can't write logs for %s (%d)\n",
3970 mti->mti_svname, rc);
3974 /* Just update the params from tunefs in mgs_write_log_params */
3975 CDEBUG(D_MGS, "Update params for %s\n", mti->mti_svname);
3976 mti->mti_flags |= LDD_F_PARAM;
3979 /* allocate temporary buffer, where class_get_next_param will
3980 make copy of a current parameter */
3981 OBD_ALLOC(buf, strlen(mti->mti_params) + 1);
3983 GOTO(out_up, rc = -ENOMEM);
3984 params = mti->mti_params;
3985 while (params != NULL) {
3986 rc = class_get_next_param(¶ms, buf);
3989 /* there is no next parameter, that is
3994 CDEBUG(D_MGS, "remaining string: '%s', param: '%s'\n",
3996 rc = mgs_write_log_param(env, mgs, fsdb, mti, buf);
4001 OBD_FREE(buf, strlen(mti->mti_params) + 1);
4004 mutex_unlock(&fsdb->fsdb_mutex);
4008 int mgs_erase_log(const struct lu_env *env, struct mgs_device *mgs, char *name)
4010 struct llog_ctxt *ctxt;
4013 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
4015 CERROR("%s: MGS config context doesn't exist\n",
4016 mgs->mgs_obd->obd_name);
4019 rc = llog_erase(env, ctxt, NULL, name);
4020 /* llog may not exist */
4023 llog_ctxt_put(ctxt);
4027 CERROR("%s: failed to clear log %s: %d\n",
4028 mgs->mgs_obd->obd_name, name, rc);
4033 /* erase all logs for the given fs */
4034 int mgs_erase_logs(const struct lu_env *env, struct mgs_device *mgs,
4037 struct list_head log_list;
4038 struct mgs_direntry *dirent, *n;
4039 char barrier_name[20] = {};
4042 int rc, len = strlen(fsname);
4045 mutex_lock(&mgs->mgs_mutex);
4047 /* Find all the logs in the CONFIGS directory */
4048 rc = class_dentry_readdir(env, mgs, &log_list);
4050 mutex_unlock(&mgs->mgs_mutex);
4054 if (list_empty(&log_list)) {
4055 mutex_unlock(&mgs->mgs_mutex);
4059 snprintf(barrier_name, sizeof(barrier_name) - 1, "%s-%s",
4060 fsname, BARRIER_FILENAME);
4061 /* Delete the barrier fsdb */
4062 mgs_remove_fsdb_by_name(mgs, barrier_name);
4063 /* Delete the fs db */
4064 mgs_remove_fsdb_by_name(mgs, fsname);
4065 mutex_unlock(&mgs->mgs_mutex);
4067 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
4068 list_del_init(&dirent->mde_list);
4069 suffix = strrchr(dirent->mde_name, '-');
4070 if (suffix != NULL) {
4071 if ((len == suffix - dirent->mde_name) &&
4072 (strncmp(fsname, dirent->mde_name, len) == 0)) {
4073 CDEBUG(D_MGS, "Removing log %s\n",
4075 mgs_erase_log(env, mgs, dirent->mde_name);
4079 mgs_direntry_free(dirent);
4088 /* list all logs for the given fs */
4089 int mgs_list_logs(const struct lu_env *env, struct mgs_device *mgs,
4090 struct obd_ioctl_data *data)
4092 struct list_head log_list;
4093 struct mgs_direntry *dirent, *n;
4099 /* Find all the logs in the CONFIGS directory */
4100 rc = class_dentry_readdir(env, mgs, &log_list);
4104 out = data->ioc_bulk;
4105 remains = data->ioc_inllen1;
4106 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
4107 list_del_init(&dirent->mde_list);
4108 suffix = strrchr(dirent->mde_name, '-');
4109 if (suffix != NULL) {
4110 l = snprintf(out, remains, "config log: $%s\n",
4115 mgs_direntry_free(dirent);
4122 struct mgs_lcfg_fork_data {
4123 struct lustre_cfg_bufs mlfd_bufs;
4124 struct mgs_device *mlfd_mgs;
4125 struct llog_handle *mlfd_llh;
4126 const char *mlfd_oldname;
4127 const char *mlfd_newname;
4131 static bool contain_valid_fsname(char *buf, const char *fsname,
4132 int buflen, int namelen)
4134 if (buflen < namelen)
4137 if (memcmp(buf, fsname, namelen) != 0)
4140 if (buf[namelen] != '\0' && buf[namelen] != '-')
4146 static int mgs_lcfg_fork_handler(const struct lu_env *env,
4147 struct llog_handle *o_llh,
4148 struct llog_rec_hdr *o_rec, void *data)
4150 struct mgs_lcfg_fork_data *mlfd = data;
4151 struct lustre_cfg_bufs *n_bufs = &mlfd->mlfd_bufs;
4152 struct lustre_cfg *o_lcfg = (struct lustre_cfg *)(o_rec + 1);
4153 struct llog_cfg_rec *lcr;
4155 char *n_buf = mlfd->mlfd_data;
4157 int o_namelen = strlen(mlfd->mlfd_oldname);
4158 int n_namelen = strlen(mlfd->mlfd_newname);
4159 int diff = n_namelen - o_namelen;
4160 __u32 cmd = o_lcfg->lcfg_command;
4161 __u32 cnt = o_lcfg->lcfg_bufcount;
4167 o_buf = lustre_cfg_buf(o_lcfg, 0);
4168 o_buflen = o_lcfg->lcfg_buflens[0];
4169 if (contain_valid_fsname(o_buf, mlfd->mlfd_oldname, o_buflen,
4171 memcpy(n_buf, mlfd->mlfd_newname, n_namelen);
4172 memcpy(n_buf + n_namelen, o_buf + o_namelen,
4173 o_buflen - o_namelen);
4174 lustre_cfg_bufs_reset(n_bufs, n_buf);
4175 n_buf += cfs_size_round(o_buflen + diff);
4177 lustre_cfg_bufs_reset(n_bufs, o_buflen != 0 ? o_buf : NULL);
4182 struct cfg_marker *o_marker;
4183 struct cfg_marker *n_marker;
4187 CDEBUG(D_MGS, "Unknown cfg marker entry with %d "
4192 /* buf[1] is marker */
4193 o_buf = lustre_cfg_buf(o_lcfg, 1);
4194 o_buflen = o_lcfg->lcfg_buflens[1];
4195 o_marker = (struct cfg_marker *)o_buf;
4196 if (!contain_valid_fsname(o_marker->cm_tgtname,
4198 sizeof(o_marker->cm_tgtname),
4200 lustre_cfg_bufs_set(n_bufs, 1, o_marker,
4205 n_marker = (struct cfg_marker *)n_buf;
4206 *n_marker = *o_marker;
4207 memcpy(n_marker->cm_tgtname, mlfd->mlfd_newname, n_namelen);
4208 tgt_namelen = strlen(o_marker->cm_tgtname);
4209 if (tgt_namelen > o_namelen)
4210 memcpy(n_marker->cm_tgtname + n_namelen,
4211 o_marker->cm_tgtname + o_namelen,
4212 tgt_namelen - o_namelen);
4213 n_marker->cm_tgtname[tgt_namelen + diff] = '\0';
4214 lustre_cfg_bufs_set(n_bufs, 1, n_marker, sizeof(*n_marker));
4218 case LCFG_SET_PARAM: {
4219 for (i = 1; i < cnt; i++)
4220 /* buf[i] is the param value, reuse it directly */
4221 lustre_cfg_bufs_set(n_bufs, i,
4222 lustre_cfg_buf(o_lcfg, i),
4223 o_lcfg->lcfg_buflens[i]);
4229 case LCFG_POOL_DEL: {
4230 if (cnt < 3 || cnt > 4) {
4231 CDEBUG(D_MGS, "Unknown cfg pool (%x) entry with %d "
4232 "buffers\n", cmd, cnt);
4236 /* buf[1] is fsname */
4237 o_buf = lustre_cfg_buf(o_lcfg, 1);
4238 o_buflen = o_lcfg->lcfg_buflens[1];
4239 memcpy(n_buf, mlfd->mlfd_newname, n_namelen);
4240 memcpy(n_buf + n_namelen, o_buf + o_namelen,
4241 o_buflen - o_namelen);
4242 lustre_cfg_bufs_set(n_bufs, 1, n_buf, o_buflen + diff);
4243 n_buf += cfs_size_round(o_buflen + diff);
4245 /* buf[2] is the pool name, reuse it directly */
4246 lustre_cfg_bufs_set(n_bufs, 2, lustre_cfg_buf(o_lcfg, 2),
4247 o_lcfg->lcfg_buflens[2]);
4252 /* buf[3] is ostname */
4253 o_buf = lustre_cfg_buf(o_lcfg, 3);
4254 o_buflen = o_lcfg->lcfg_buflens[3];
4255 memcpy(n_buf, mlfd->mlfd_newname, n_namelen);
4256 memcpy(n_buf + n_namelen, o_buf + o_namelen,
4257 o_buflen - o_namelen);
4258 lustre_cfg_bufs_set(n_bufs, 3, n_buf, o_buflen + diff);
4263 o_buflen = o_lcfg->lcfg_buflens[1];
4264 if (o_buflen == sizeof(struct lov_desc) ||
4265 o_buflen == sizeof(struct lmv_desc)) {
4271 o_buf = lustre_cfg_buf(o_lcfg, 1);
4272 if (o_buflen == sizeof(struct lov_desc)) {
4273 struct lov_desc *o_desc =
4274 (struct lov_desc *)o_buf;
4275 struct lov_desc *n_desc =
4276 (struct lov_desc *)n_buf;
4279 o_uuid = o_desc->ld_uuid.uuid;
4280 n_uuid = n_desc->ld_uuid.uuid;
4281 uuid_len = sizeof(o_desc->ld_uuid.uuid);
4283 struct lmv_desc *o_desc =
4284 (struct lmv_desc *)o_buf;
4285 struct lmv_desc *n_desc =
4286 (struct lmv_desc *)n_buf;
4289 o_uuid = o_desc->ld_uuid.uuid;
4290 n_uuid = n_desc->ld_uuid.uuid;
4291 uuid_len = sizeof(o_desc->ld_uuid.uuid);
4294 if (unlikely(!contain_valid_fsname(o_uuid,
4295 mlfd->mlfd_oldname, uuid_len,
4297 lustre_cfg_bufs_set(n_bufs, 1, o_buf,
4302 memcpy(n_uuid, mlfd->mlfd_newname, n_namelen);
4303 uuid_len = strlen(o_uuid);
4304 if (uuid_len > o_namelen)
4305 memcpy(n_uuid + n_namelen,
4307 uuid_len - o_namelen);
4308 n_uuid[uuid_len + diff] = '\0';
4309 lustre_cfg_bufs_set(n_bufs, 1, n_buf, o_buflen);
4311 } /* else case fall through */
4312 } /* else case fall through */
4315 for (i = 1; i < cnt; i++) {
4316 o_buflen = o_lcfg->lcfg_buflens[i];
4320 o_buf = lustre_cfg_buf(o_lcfg, i);
4321 if (!contain_valid_fsname(o_buf, mlfd->mlfd_oldname,
4322 o_buflen, o_namelen)) {
4323 lustre_cfg_bufs_set(n_bufs, i, o_buf, o_buflen);
4327 memcpy(n_buf, mlfd->mlfd_newname, n_namelen);
4328 if (o_buflen == o_namelen) {
4329 lustre_cfg_bufs_set(n_bufs, i, n_buf,
4331 n_buf += cfs_size_round(n_namelen);
4335 memcpy(n_buf + n_namelen, o_buf + o_namelen,
4336 o_buflen - o_namelen);
4337 lustre_cfg_bufs_set(n_bufs, i, n_buf, o_buflen + diff);
4338 n_buf += cfs_size_round(o_buflen + diff);
4344 lcr = lustre_cfg_rec_new(cmd, n_bufs);
4348 lcr->lcr_cfg = *o_lcfg;
4349 rc = llog_write(env, mlfd->mlfd_llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
4350 lustre_cfg_rec_free(lcr);
4355 static int mgs_lcfg_fork_one(const struct lu_env *env, struct mgs_device *mgs,
4356 struct mgs_direntry *mde, const char *oldname,
4357 const char *newname)
4359 struct llog_handle *old_llh = NULL;
4360 struct llog_handle *new_llh = NULL;
4361 struct llog_ctxt *ctxt = NULL;
4362 struct mgs_lcfg_fork_data *mlfd = NULL;
4363 char *name_buf = NULL;
4365 int old_namelen = strlen(oldname);
4366 int new_namelen = strlen(newname);
4370 name_buflen = mde->mde_len + new_namelen - old_namelen;
4371 OBD_ALLOC(name_buf, name_buflen);
4375 memcpy(name_buf, newname, new_namelen);
4376 memcpy(name_buf + new_namelen, mde->mde_name + old_namelen,
4377 mde->mde_len - old_namelen);
4379 CDEBUG(D_MGS, "Fork the config-log from %s to %s\n",
4380 mde->mde_name, name_buf);
4382 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
4385 rc = llog_open_create(env, ctxt, &new_llh, NULL, name_buf);
4389 rc = llog_init_handle(env, new_llh, LLOG_F_IS_PLAIN, NULL);
4393 if (unlikely(mgs_log_is_empty(env, mgs, mde->mde_name)))
4396 rc = llog_open(env, ctxt, &old_llh, NULL, mde->mde_name,
4401 rc = llog_init_handle(env, old_llh, LLOG_F_IS_PLAIN, NULL);
4405 new_llh->lgh_hdr->llh_tgtuuid = old_llh->lgh_hdr->llh_tgtuuid;
4407 OBD_ALLOC(mlfd, LLOG_MIN_CHUNK_SIZE);
4409 GOTO(out, rc = -ENOMEM);
4411 mlfd->mlfd_mgs = mgs;
4412 mlfd->mlfd_llh = new_llh;
4413 mlfd->mlfd_oldname = oldname;
4414 mlfd->mlfd_newname = newname;
4416 rc = llog_process(env, old_llh, mgs_lcfg_fork_handler, mlfd, NULL);
4417 OBD_FREE(mlfd, LLOG_MIN_CHUNK_SIZE);
4423 llog_close(env, old_llh);
4425 llog_close(env, new_llh);
4427 OBD_FREE(name_buf, name_buflen);
4429 llog_ctxt_put(ctxt);
4434 int mgs_lcfg_fork(const struct lu_env *env, struct mgs_device *mgs,
4435 const char *oldname, const char *newname)
4437 struct list_head log_list;
4438 struct mgs_direntry *dirent, *n;
4439 int olen = strlen(oldname);
4440 int nlen = strlen(newname);
4445 if (strcmp(oldname, newname) == 0)
4448 /* lock it to prevent fork/erase/register in parallel. */
4449 mutex_lock(&mgs->mgs_mutex);
4451 rc = class_dentry_readdir(env, mgs, &log_list);
4453 mutex_unlock(&mgs->mgs_mutex);
4457 if (list_empty(&log_list)) {
4458 mutex_unlock(&mgs->mgs_mutex);
4462 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
4465 ptr = strrchr(dirent->mde_name, '-');
4467 int tlen = ptr - dirent->mde_name;
4470 strncmp(newname, dirent->mde_name, tlen) == 0)
4471 GOTO(out, rc = -EEXIST);
4474 strncmp(oldname, dirent->mde_name, tlen) == 0)
4478 list_del_init(&dirent->mde_list);
4479 mgs_direntry_free(dirent);
4482 if (list_empty(&log_list)) {
4483 mutex_unlock(&mgs->mgs_mutex);
4487 list_for_each_entry(dirent, &log_list, mde_list) {
4488 rc = mgs_lcfg_fork_one(env, mgs, dirent, oldname, newname);
4496 mutex_unlock(&mgs->mgs_mutex);
4498 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
4499 list_del_init(&dirent->mde_list);
4500 mgs_direntry_free(dirent);
4503 if (rc && count > 0)
4504 mgs_erase_logs(env, mgs, newname);
4509 int mgs_lcfg_erase(const struct lu_env *env, struct mgs_device *mgs,
4515 rc = mgs_erase_logs(env, mgs, fsname);
4520 /* from llog_swab */
4521 static void print_lustre_cfg(struct lustre_cfg *lcfg)
4526 CDEBUG(D_MGS, "lustre_cfg: %p\n", lcfg);
4527 CDEBUG(D_MGS, "\tlcfg->lcfg_version: %#x\n", lcfg->lcfg_version);
4529 CDEBUG(D_MGS, "\tlcfg->lcfg_command: %#x\n", lcfg->lcfg_command);
4530 CDEBUG(D_MGS, "\tlcfg->lcfg_num: %#x\n", lcfg->lcfg_num);
4531 CDEBUG(D_MGS, "\tlcfg->lcfg_flags: %#x\n", lcfg->lcfg_flags);
4532 CDEBUG(D_MGS, "\tlcfg->lcfg_nid: %s\n", libcfs_nid2str(lcfg->lcfg_nid));
4534 CDEBUG(D_MGS, "\tlcfg->lcfg_bufcount: %d\n", lcfg->lcfg_bufcount);
4535 if (lcfg->lcfg_bufcount < LUSTRE_CFG_MAX_BUFCOUNT)
4536 for (i = 0; i < lcfg->lcfg_bufcount; i++) {
4537 CDEBUG(D_MGS, "\tlcfg->lcfg_buflens[%d]: %d %s\n",
4538 i, lcfg->lcfg_buflens[i],
4539 lustre_cfg_string(lcfg, i));
4544 /* Setup _mgs fsdb and log
4546 int mgs__mgs_fsdb_setup(const struct lu_env *env, struct mgs_device *mgs)
4548 struct fs_db *fsdb = NULL;
4552 rc = mgs_find_or_make_fsdb(env, mgs, MGSSELF_NAME, &fsdb);
4554 mgs_put_fsdb(mgs, fsdb);
4559 /* Setup params fsdb and log
4561 int mgs_params_fsdb_setup(const struct lu_env *env, struct mgs_device *mgs)
4563 struct fs_db *fsdb = NULL;
4564 struct llog_handle *params_llh = NULL;
4568 rc = mgs_find_or_make_fsdb(env, mgs, PARAMS_FILENAME, &fsdb);
4570 mutex_lock(&fsdb->fsdb_mutex);
4571 rc = record_start_log(env, mgs, ¶ms_llh, PARAMS_FILENAME);
4573 rc = record_end_log(env, ¶ms_llh);
4574 mutex_unlock(&fsdb->fsdb_mutex);
4575 mgs_put_fsdb(mgs, fsdb);
4581 /* Cleanup params fsdb and log
4583 int mgs_params_fsdb_cleanup(const struct lu_env *env, struct mgs_device *mgs)
4587 rc = mgs_erase_logs(env, mgs, PARAMS_FILENAME);
4588 return rc == -ENOENT ? 0 : rc;
4591 /* Set a permanent (config log) param for a target or fs
4592 * \param lcfg buf0 may contain the device (testfs-MDT0000) name
4593 * buf1 contains the single parameter
4595 int mgs_setparam(const struct lu_env *env, struct mgs_device *mgs,
4596 struct lustre_cfg *lcfg, char *fsname)
4598 struct fs_db *fsdb = NULL;
4599 struct mgs_target_info *mti = NULL;
4600 char *devname, *param;
4608 print_lustre_cfg(lcfg);
4610 /* lustre, lustre-mdtlov, lustre-client, lustre-MDT0000 */
4611 devname = lustre_cfg_string(lcfg, 0);
4612 param = lustre_cfg_string(lcfg, 1);
4614 /* Assume device name embedded in param:
4615 lustre-OST0000.osc.max_dirty_mb=32 */
4616 ptr = strchr(param, '.');
4624 LCONSOLE_ERROR_MSG(0x14d, "No target specified: %s\n", param);
4628 rc = mgs_parse_devname(devname, fsname, NULL);
4629 if (rc == 0 && !mgs_parse_devname(devname, NULL, &index)) {
4630 /* param related to llite isn't allowed to set by OST or MDT */
4631 if (rc == 0 && strncmp(param, PARAM_LLITE,
4632 sizeof(PARAM_LLITE) - 1) == 0)
4635 /* assume devname is the fsname */
4636 strlcpy(fsname, devname, MTI_NAME_MAXLEN);
4638 CDEBUG(D_MGS, "setparam fs='%s' device='%s'\n", fsname, devname);
4640 rc = mgs_find_or_make_fsdb(env, mgs,
4641 lcfg->lcfg_command == LCFG_SET_PARAM ?
4642 PARAMS_FILENAME : fsname, &fsdb);
4646 if (lcfg->lcfg_command != LCFG_SET_PARAM &&
4647 !test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags) &&
4648 test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
4649 CERROR("No filesystem targets for %s. cfg_device from lctl "
4650 "is '%s'\n", fsname, devname);
4652 GOTO(out, rc = -EINVAL);
4655 /* Create a fake mti to hold everything */
4658 GOTO(out, rc = -ENOMEM);
4659 if (strlcpy(mti->mti_fsname, fsname, sizeof(mti->mti_fsname))
4660 >= sizeof(mti->mti_fsname))
4661 GOTO(out, rc = -E2BIG);
4662 if (strlcpy(mti->mti_svname, devname, sizeof(mti->mti_svname))
4663 >= sizeof(mti->mti_svname))
4664 GOTO(out, rc = -E2BIG);
4665 if (strlcpy(mti->mti_params, param, sizeof(mti->mti_params))
4666 >= sizeof(mti->mti_params))
4667 GOTO(out, rc = -E2BIG);
4668 rc = server_name2index(mti->mti_svname, &mti->mti_stripe_index, &tmp);
4670 /* Not a valid server; may be only fsname */
4673 /* Strip -osc or -mdc suffix from svname */
4674 if (server_make_name(rc, mti->mti_stripe_index, mti->mti_fsname,
4676 GOTO(out, rc = -EINVAL);
4678 * Revoke lock so everyone updates. Should be alright if
4679 * someone was already reading while we were updating the logs,
4680 * so we don't really need to hold the lock while we're
4683 if (lcfg->lcfg_command == LCFG_SET_PARAM) {
4684 mti->mti_flags = rc | LDD_F_PARAM2;
4685 mutex_lock(&fsdb->fsdb_mutex);
4686 rc = mgs_write_log_param2(env, mgs, fsdb, mti, mti->mti_params);
4687 mutex_unlock(&fsdb->fsdb_mutex);
4688 mgs_revoke_lock(mgs, fsdb, CONFIG_T_PARAMS);
4690 mti->mti_flags = rc | LDD_F_PARAM;
4691 mutex_lock(&fsdb->fsdb_mutex);
4692 rc = mgs_write_log_param(env, mgs, fsdb, mti, mti->mti_params);
4693 mutex_unlock(&fsdb->fsdb_mutex);
4694 mgs_revoke_lock(mgs, fsdb, CONFIG_T_CONFIG);
4703 mgs_unlink_fsdb(mgs, fsdb);
4704 mgs_put_fsdb(mgs, fsdb);
4710 static int mgs_write_log_pool(const struct lu_env *env,
4711 struct mgs_device *mgs, char *logname,
4712 struct fs_db *fsdb, char *tgtname,
4713 enum lcfg_command_type cmd,
4714 char *fsname, char *poolname,
4715 char *ostname, char *comment)
4717 struct llog_handle *llh = NULL;
4720 rc = record_start_log(env, mgs, &llh, logname);
4723 rc = record_marker(env, llh, fsdb, CM_START, tgtname, comment);
4726 rc = record_base(env, llh, tgtname, 0, cmd,
4727 fsname, poolname, ostname, NULL);
4730 rc = record_marker(env, llh, fsdb, CM_END, tgtname, comment);
4732 record_end_log(env, &llh);
4736 int mgs_nodemap_cmd(const struct lu_env *env, struct mgs_device *mgs,
4737 enum lcfg_command_type cmd, const char *nodemap_name,
4748 case LCFG_NODEMAP_ADD:
4749 rc = nodemap_add(nodemap_name);
4751 case LCFG_NODEMAP_DEL:
4752 rc = nodemap_del(nodemap_name);
4754 case LCFG_NODEMAP_ADD_RANGE:
4755 rc = nodemap_parse_range(param, nid);
4758 rc = nodemap_add_range(nodemap_name, nid);
4760 case LCFG_NODEMAP_DEL_RANGE:
4761 rc = nodemap_parse_range(param, nid);
4764 rc = nodemap_del_range(nodemap_name, nid);
4766 case LCFG_NODEMAP_ADMIN:
4767 bool_switch = simple_strtoul(param, NULL, 10);
4768 rc = nodemap_set_allow_root(nodemap_name, bool_switch);
4770 case LCFG_NODEMAP_DENY_UNKNOWN:
4771 bool_switch = simple_strtoul(param, NULL, 10);
4772 rc = nodemap_set_deny_unknown(nodemap_name, bool_switch);
4774 case LCFG_NODEMAP_TRUSTED:
4775 bool_switch = simple_strtoul(param, NULL, 10);
4776 rc = nodemap_set_trust_client_ids(nodemap_name, bool_switch);
4778 case LCFG_NODEMAP_SQUASH_UID:
4779 int_id = simple_strtoul(param, NULL, 10);
4780 rc = nodemap_set_squash_uid(nodemap_name, int_id);
4782 case LCFG_NODEMAP_SQUASH_GID:
4783 int_id = simple_strtoul(param, NULL, 10);
4784 rc = nodemap_set_squash_gid(nodemap_name, int_id);
4786 case LCFG_NODEMAP_ADD_UIDMAP:
4787 case LCFG_NODEMAP_ADD_GIDMAP:
4788 rc = nodemap_parse_idmap(param, idmap);
4791 if (cmd == LCFG_NODEMAP_ADD_UIDMAP)
4792 rc = nodemap_add_idmap(nodemap_name, NODEMAP_UID,
4795 rc = nodemap_add_idmap(nodemap_name, NODEMAP_GID,
4798 case LCFG_NODEMAP_DEL_UIDMAP:
4799 case LCFG_NODEMAP_DEL_GIDMAP:
4800 rc = nodemap_parse_idmap(param, idmap);
4803 if (cmd == LCFG_NODEMAP_DEL_UIDMAP)
4804 rc = nodemap_del_idmap(nodemap_name, NODEMAP_UID,
4807 rc = nodemap_del_idmap(nodemap_name, NODEMAP_GID,
4810 case LCFG_NODEMAP_SET_FILESET:
4811 rc = nodemap_set_fileset(nodemap_name, param);
4820 int mgs_pool_cmd(const struct lu_env *env, struct mgs_device *mgs,
4821 enum lcfg_command_type cmd, char *fsname,
4822 char *poolname, char *ostname)
4827 char *label = NULL, *canceled_label = NULL;
4829 struct mgs_target_info *mti = NULL;
4830 bool checked = false;
4831 bool locked = false;
4836 rc = mgs_find_or_make_fsdb(env, mgs, fsname, &fsdb);
4838 CERROR("Can't get db for %s\n", fsname);
4841 if (test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
4842 CERROR("%s is not defined\n", fsname);
4844 GOTO(out_fsdb, rc = -EINVAL);
4847 label_sz = 10 + strlen(fsname) + strlen(poolname);
4849 /* check if ostname match fsname */
4850 if (ostname != NULL) {
4853 ptr = strrchr(ostname, '-');
4854 if ((ptr == NULL) ||
4855 (strncmp(fsname, ostname, ptr-ostname) != 0))
4857 label_sz += strlen(ostname);
4860 OBD_ALLOC(label, label_sz);
4862 GOTO(out_fsdb, rc = -ENOMEM);
4867 "new %s.%s", fsname, poolname);
4871 "add %s.%s.%s", fsname, poolname, ostname);
4874 OBD_ALLOC(canceled_label, label_sz);
4875 if (canceled_label == NULL)
4876 GOTO(out_label, rc = -ENOMEM);
4878 "rem %s.%s.%s", fsname, poolname, ostname);
4879 sprintf(canceled_label,
4880 "add %s.%s.%s", fsname, poolname, ostname);
4883 OBD_ALLOC(canceled_label, label_sz);
4884 if (canceled_label == NULL)
4885 GOTO(out_label, rc = -ENOMEM);
4887 "del %s.%s", fsname, poolname);
4888 sprintf(canceled_label,
4889 "new %s.%s", fsname, poolname);
4897 GOTO(out_cancel, rc = -ENOMEM);
4898 strncpy(mti->mti_svname, "lov pool", sizeof(mti->mti_svname));
4900 mutex_lock(&fsdb->fsdb_mutex);
4902 /* write pool def to all MDT logs */
4903 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
4904 if (test_bit(i, fsdb->fsdb_mdt_index_map)) {
4905 rc = name_create_mdt_and_lov(&logname, &lovname,
4910 if (!checked && (canceled_label == NULL)) {
4911 rc = mgs_check_marker(env, mgs, fsdb, mti,
4912 logname, lovname, label);
4914 name_destroy(&logname);
4915 name_destroy(&lovname);
4917 rc = (rc == LLOG_PROC_BREAK ?
4922 if (canceled_label != NULL)
4923 rc = mgs_modify(env, mgs, fsdb, mti, logname,
4924 lovname, canceled_label,
4928 rc = mgs_write_log_pool(env, mgs, logname,
4932 name_destroy(&logname);
4933 name_destroy(&lovname);
4939 rc = name_create(&logname, fsname, "-client");
4943 if (!checked && (canceled_label == NULL)) {
4944 rc = mgs_check_marker(env, mgs, fsdb, mti, logname,
4945 fsdb->fsdb_clilov, label);
4947 name_destroy(&logname);
4948 GOTO(out_mti, rc = (rc == LLOG_PROC_BREAK ?
4952 if (canceled_label != NULL) {
4953 rc = mgs_modify(env, mgs, fsdb, mti, logname,
4954 fsdb->fsdb_clilov, canceled_label, CM_SKIP);
4956 name_destroy(&logname);
4961 rc = mgs_write_log_pool(env, mgs, logname, fsdb, fsdb->fsdb_clilov,
4962 cmd, fsname, poolname, ostname, label);
4963 mutex_unlock(&fsdb->fsdb_mutex);
4965 name_destroy(&logname);
4966 /* request for update */
4967 mgs_revoke_lock(mgs, fsdb, CONFIG_T_CONFIG);
4973 mutex_unlock(&fsdb->fsdb_mutex);
4977 if (canceled_label != NULL)
4978 OBD_FREE(canceled_label, label_sz);
4980 OBD_FREE(label, label_sz);
4983 mgs_unlink_fsdb(mgs, fsdb);
4984 mgs_put_fsdb(mgs, fsdb);