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, 2017, Intel Corporation.
29 * This file is part of Lustre, http://www.lustre.org/
31 * lustre/mgs/mgs_llog.c
33 * Lustre Management Server (mgs) config llog creation
35 * Author: Nathan Rutman <nathan@clusterfs.com>
36 * Author: Alex Zhuravlev <bzzz@whamcloud.com>
37 * Author: Mikhail Pershin <tappro@whamcloud.com>
40 #define DEBUG_SUBSYSTEM S_MGS
41 #define D_MGS D_CONFIG
44 #include <uapi/linux/lustre/lustre_ioctl.h>
45 #include <uapi/linux/lustre/lustre_param.h>
46 #include <lustre_sec.h>
47 #include <lustre_quota.h>
48 #include <lustre_sec.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 backup files */
109 if (lu_name_is_backup_file(key, key_sz, NULL)) {
110 CDEBUG(D_MGS, "Skipping backup file %.*s\n",
115 de = mgs_direntry_alloc(key_sz + 1);
121 memcpy(de->mde_name, key, key_sz);
122 de->mde_name[key_sz] = 0;
124 list_add(&de->mde_list, log_list);
127 rc = iops->next(env, it);
137 struct mgs_direntry *n;
139 CERROR("%s: key failed when listing %s: rc = %d\n",
140 mgs->mgs_obd->obd_name, MOUNT_CONFIGS_DIR, rc);
142 list_for_each_entry_safe(de, n, log_list, mde_list) {
143 list_del_init(&de->mde_list);
144 mgs_direntry_free(de);
151 /******************** DB functions *********************/
153 static inline int name_create(char **newname, char *prefix, char *suffix)
156 OBD_ALLOC(*newname, strlen(prefix) + strlen(suffix) + 1);
159 sprintf(*newname, "%s%s", prefix, suffix);
163 static inline void name_destroy(char **name)
166 OBD_FREE(*name, strlen(*name) + 1);
170 struct mgs_fsdb_handler_data
176 /* from the (client) config log, figure out:
177 * 1. which ost's/mdt's are configured (by index)
178 * 2. what the last config step is
179 * 3. COMPAT_18 osc name
181 /* It might be better to have a separate db file, instead of parsing the info
182 out of the client log. This is slow and potentially error-prone. */
183 static int mgs_fsdb_handler(const struct lu_env *env, struct llog_handle *llh,
184 struct llog_rec_hdr *rec, void *data)
186 struct mgs_fsdb_handler_data *d = data;
187 struct fs_db *fsdb = d->fsdb;
188 int cfg_len = rec->lrh_len;
189 char *cfg_buf = (char *)(rec + 1);
190 struct lustre_cfg *lcfg;
195 if (rec->lrh_type != OBD_CFG_REC) {
196 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
200 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
202 CERROR("Insane cfg\n");
206 lcfg = (struct lustre_cfg *)cfg_buf;
208 CDEBUG(D_INFO, "cmd %x %s %s\n", lcfg->lcfg_command,
209 lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));
211 /* Figure out ost indicies */
212 /* lov_modify_tgts add 0:lov1 1:ost1_UUID 2(index):0 3(gen):1 */
213 if (lcfg->lcfg_command == LCFG_LOV_ADD_OBD ||
214 lcfg->lcfg_command == LCFG_LOV_DEL_OBD) {
215 rc = kstrtouint(lustre_cfg_string(lcfg, 2), 10, &index);
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;
269 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 /* The caller must hold mgs->mgs_mutex. */
545 int mgs_find_or_make_fsdb_nolock(const struct lu_env *env,
546 struct mgs_device *mgs,
547 char *name, struct fs_db **dbh)
553 fsdb = mgs_find_fsdb(mgs, name);
555 fsdb = mgs_new_fsdb(env, mgs, name);
559 CDEBUG(D_MGS, "Created new db: rc = %d\n", rc);
568 int mgs_find_or_make_fsdb(const struct lu_env *env, struct mgs_device *mgs,
569 char *name, struct fs_db **dbh)
574 mutex_lock(&mgs->mgs_mutex);
575 rc = mgs_find_or_make_fsdb_nolock(env, mgs, name, dbh);
576 mutex_unlock(&mgs->mgs_mutex);
583 * -1= empty client log
585 int mgs_check_index(const struct lu_env *env,
586 struct mgs_device *mgs,
587 struct mgs_target_info *mti)
594 LASSERT(!(mti->mti_flags & LDD_F_NEED_INDEX));
596 rc = mgs_find_or_make_fsdb(env, mgs, mti->mti_fsname, &fsdb);
598 CERROR("Can't get db for %s\n", mti->mti_fsname);
602 if (test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags))
605 if (mti->mti_flags & LDD_F_SV_TYPE_OST)
606 imap = fsdb->fsdb_ost_index_map;
607 else if (mti->mti_flags & LDD_F_SV_TYPE_MDT)
608 imap = fsdb->fsdb_mdt_index_map;
610 GOTO(out, rc = -EINVAL);
612 if (test_bit(mti->mti_stripe_index, imap))
618 mgs_put_fsdb(mgs, fsdb);
622 static __inline__ int next_index(void *index_map, int map_len)
626 for (i = 0; i < map_len * 8; i++)
627 if (!test_bit(i, index_map))
629 CERROR("max index %d exceeded.\n", i);
633 /* Make the mdt/ost server obd name based on the filesystem name */
634 static bool server_make_name(u32 flags, u16 index, const char *fs,
635 char *name_buf, size_t name_buf_size)
637 bool invalid_flag = false;
639 if (flags & (LDD_F_SV_TYPE_MDT | LDD_F_SV_TYPE_OST)) {
642 if (flags & LDD_F_WRITECONF)
644 else if (flags & LDD_F_VIRGIN)
647 if (!(flags & LDD_F_SV_ALL))
648 snprintf(name_buf, name_buf_size, "%.8s%c%s%04x", fs,
650 (flags & LDD_F_SV_TYPE_MDT) ? "MDT" : "OST",
652 } else if (flags & LDD_F_SV_TYPE_MGS) {
653 snprintf(name_buf, name_buf_size, "MGS");
655 CERROR("unknown server type %#x\n", flags);
662 * 0 newly marked as in use
664 * +EALREADY for update of an old index
666 static int mgs_set_index(const struct lu_env *env,
667 struct mgs_device *mgs,
668 struct mgs_target_info *mti)
676 rc = mgs_find_or_make_fsdb(env, mgs, mti->mti_fsname, &fsdb);
678 CERROR("Can't get db for %s\n", mti->mti_fsname);
682 mutex_lock(&fsdb->fsdb_mutex);
683 if (mti->mti_flags & LDD_F_SV_TYPE_OST)
684 imap = fsdb->fsdb_ost_index_map;
685 else if (mti->mti_flags & LDD_F_SV_TYPE_MDT)
686 imap = fsdb->fsdb_mdt_index_map;
688 GOTO(out_up, rc = -EINVAL);
690 if (mti->mti_flags & LDD_F_NEED_INDEX) {
691 rc = next_index(imap, INDEX_MAP_SIZE);
693 GOTO(out_up, rc = -ERANGE);
694 mti->mti_stripe_index = rc;
697 /* the last index(0xffff) is reserved for default value. */
698 if (mti->mti_stripe_index >= INDEX_MAP_SIZE * 8 - 1) {
699 LCONSOLE_ERROR_MSG(0x13f, "Server %s requested index %u, "
700 "but index must be less than %u.\n",
701 mti->mti_svname, mti->mti_stripe_index,
702 INDEX_MAP_SIZE * 8 - 1);
703 GOTO(out_up, rc = -ERANGE);
706 if (test_bit(mti->mti_stripe_index, imap)) {
707 if ((mti->mti_flags & LDD_F_VIRGIN) &&
708 !(mti->mti_flags & LDD_F_WRITECONF)) {
711 "Server %s requested index %d, but that index is already in use. Use --writeconf to force\n",
713 mti->mti_stripe_index);
714 GOTO(out_up, rc = -EADDRINUSE);
716 CDEBUG(D_MGS, "Server %s updating index %d\n",
717 mti->mti_svname, mti->mti_stripe_index);
718 GOTO(out_up, rc = EALREADY);
721 set_bit(mti->mti_stripe_index, imap);
722 if (mti->mti_flags & LDD_F_SV_TYPE_MDT)
723 fsdb->fsdb_mdt_count++;
726 set_bit(mti->mti_stripe_index, imap);
727 clear_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags);
728 if (server_make_name(mti->mti_flags & ~(LDD_F_VIRGIN | LDD_F_WRITECONF),
729 mti->mti_stripe_index, mti->mti_fsname,
730 mti->mti_svname, sizeof(mti->mti_svname))) {
731 CERROR("unknown server type %#x\n", mti->mti_flags);
732 GOTO(out_up, rc = -EINVAL);
735 CDEBUG(D_MGS, "Set index for %s to %d\n", mti->mti_svname,
736 mti->mti_stripe_index);
738 GOTO(out_up, rc = 0);
741 mutex_unlock(&fsdb->fsdb_mutex);
742 mgs_put_fsdb(mgs, fsdb);
746 struct mgs_modify_lookup {
747 struct cfg_marker mml_marker;
751 static int mgs_check_record_match(const struct lu_env *env,
752 struct llog_handle *llh,
753 struct llog_rec_hdr *rec, void *data)
755 struct cfg_marker *mc_marker = data;
756 struct cfg_marker *marker;
757 struct lustre_cfg *lcfg = REC_DATA(rec);
758 int cfg_len = REC_DATA_LEN(rec);
762 if (rec->lrh_type != OBD_CFG_REC) {
763 CDEBUG(D_ERROR, "Unhandled lrh_type: %#x\n", rec->lrh_type);
767 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
769 CDEBUG(D_ERROR, "Insane cfg\n");
773 /* We only care about markers */
774 if (lcfg->lcfg_command != LCFG_MARKER)
777 marker = lustre_cfg_buf(lcfg, 1);
779 if (marker->cm_flags & CM_SKIP)
782 if ((strcmp(mc_marker->cm_comment, marker->cm_comment) == 0) &&
783 (strcmp(mc_marker->cm_tgtname, marker->cm_tgtname) == 0)) {
784 /* Found a non-skipped marker match */
785 CDEBUG(D_MGS, "Matched rec %u marker %d flag %x %s %s\n",
786 rec->lrh_index, marker->cm_step,
787 marker->cm_flags, marker->cm_tgtname,
789 rc = LLOG_PROC_BREAK;
796 * Check an existing config log record with matching comment and device
798 * 0 - checked successfully,
799 * LLOG_PROC_BREAK - record matches
802 static int mgs_check_marker(const struct lu_env *env, struct mgs_device *mgs,
803 struct fs_db *fsdb, struct mgs_target_info *mti,
804 char *logname, char *devname, char *comment)
806 struct llog_handle *loghandle;
807 struct llog_ctxt *ctxt;
808 struct cfg_marker *mc_marker;
813 LASSERT(mutex_is_locked(&fsdb->fsdb_mutex));
814 CDEBUG(D_MGS, "mgs check %s/%s/%s\n", logname, devname, comment);
816 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
817 LASSERT(ctxt != NULL);
818 rc = llog_open(env, ctxt, &loghandle, NULL, logname, LLOG_OPEN_EXISTS);
825 rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL);
829 if (llog_get_size(loghandle) <= 1)
830 GOTO(out_close, rc = 0);
832 OBD_ALLOC_PTR(mc_marker);
834 GOTO(out_close, rc = -ENOMEM);
835 if (strlcpy(mc_marker->cm_comment, comment,
836 sizeof(mc_marker->cm_comment)) >=
837 sizeof(mc_marker->cm_comment))
838 GOTO(out_free, rc = -E2BIG);
839 if (strlcpy(mc_marker->cm_tgtname, devname,
840 sizeof(mc_marker->cm_tgtname)) >=
841 sizeof(mc_marker->cm_tgtname))
842 GOTO(out_free, rc = -E2BIG);
844 rc = llog_process(env, loghandle, mgs_check_record_match,
845 (void *)mc_marker, NULL);
848 OBD_FREE_PTR(mc_marker);
851 llog_close(env, loghandle);
853 if (rc && rc != LLOG_PROC_BREAK)
854 CDEBUG(D_ERROR, "%s: mgs check %s/%s failed: rc = %d\n",
855 mgs->mgs_obd->obd_name, mti->mti_svname, comment, rc);
860 static int mgs_modify_handler(const struct lu_env *env,
861 struct llog_handle *llh,
862 struct llog_rec_hdr *rec, void *data)
864 struct mgs_modify_lookup *mml = data;
865 struct cfg_marker *marker;
866 struct lustre_cfg *lcfg = REC_DATA(rec);
867 int cfg_len = REC_DATA_LEN(rec);
871 if (rec->lrh_type != OBD_CFG_REC) {
872 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
876 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
878 CERROR("Insane cfg\n");
882 /* We only care about markers */
883 if (lcfg->lcfg_command != LCFG_MARKER)
886 marker = lustre_cfg_buf(lcfg, 1);
887 if ((strcmp(mml->mml_marker.cm_comment, marker->cm_comment) == 0) &&
888 (strcmp(mml->mml_marker.cm_tgtname, marker->cm_tgtname) == 0) &&
889 !(marker->cm_flags & CM_SKIP)) {
890 /* Found a non-skipped marker match */
891 CDEBUG(D_MGS, "Changing rec %u marker %d %x->%x: %s %s\n",
892 rec->lrh_index, marker->cm_step,
893 marker->cm_flags, mml->mml_marker.cm_flags,
894 marker->cm_tgtname, marker->cm_comment);
895 /* Overwrite the old marker llog entry */
896 marker->cm_flags &= ~CM_EXCLUDE; /* in case we're unexcluding */
897 marker->cm_flags |= mml->mml_marker.cm_flags;
898 marker->cm_canceltime = mml->mml_marker.cm_canceltime;
899 rc = llog_write(env, llh, rec, rec->lrh_index);
908 * Modify an existing config log record (for CM_SKIP or CM_EXCLUDE)
910 * 0 - modified successfully,
911 * 1 - no modification was done
914 static int mgs_modify(const struct lu_env *env, struct mgs_device *mgs,
915 struct fs_db *fsdb, struct mgs_target_info *mti,
916 char *logname, char *devname, char *comment, int flags)
918 struct llog_handle *loghandle;
919 struct llog_ctxt *ctxt;
920 struct mgs_modify_lookup *mml;
925 LASSERT(mutex_is_locked(&fsdb->fsdb_mutex));
926 CDEBUG(D_MGS, "modify %s/%s/%s fl=%x\n", logname, devname, comment,
929 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
930 LASSERT(ctxt != NULL);
931 rc = llog_open(env, ctxt, &loghandle, NULL, logname, LLOG_OPEN_EXISTS);
938 rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL);
942 if (llog_get_size(loghandle) <= 1)
943 GOTO(out_close, rc = 0);
947 GOTO(out_close, rc = -ENOMEM);
948 if (strlcpy(mml->mml_marker.cm_comment, comment,
949 sizeof(mml->mml_marker.cm_comment)) >=
950 sizeof(mml->mml_marker.cm_comment))
951 GOTO(out_free, rc = -E2BIG);
952 if (strlcpy(mml->mml_marker.cm_tgtname, devname,
953 sizeof(mml->mml_marker.cm_tgtname)) >=
954 sizeof(mml->mml_marker.cm_tgtname))
955 GOTO(out_free, rc = -E2BIG);
956 /* Modify mostly means cancel */
957 mml->mml_marker.cm_flags = flags;
958 mml->mml_marker.cm_canceltime = flags ? ktime_get_real_seconds() : 0;
959 mml->mml_modified = 0;
960 rc = llog_process(env, loghandle, mgs_modify_handler, (void *)mml,
962 if (!rc && !mml->mml_modified)
969 llog_close(env, loghandle);
972 CERROR("%s: modify %s/%s failed: rc = %d\n",
973 mgs->mgs_obd->obd_name, mti->mti_svname, comment, rc);
986 /** This structure is passed to mgs_replace_handler */
987 struct mgs_replace_data {
988 /* Nids are replaced for this target device */
989 struct mgs_target_info target;
990 /* Temporary modified llog */
991 struct llog_handle *temp_llh;
992 enum replace_state state;
998 * Check: a) if block should be skipped
999 * b) is it target block
1004 * \retval 0 should not to be skipped
1005 * \retval 1 should to be skipped
1007 static int check_markers(struct lustre_cfg *lcfg,
1008 struct mgs_replace_data *mrd)
1010 struct cfg_marker *marker;
1012 /* Track markers. Find given device */
1013 if (lcfg->lcfg_command == LCFG_MARKER) {
1014 marker = lustre_cfg_buf(lcfg, 1);
1015 /* Clean llog from records marked as CM_SKIP.
1016 CM_EXCLUDE records are used for "active" command
1017 and can be restored if needed */
1018 if ((marker->cm_flags & (CM_SKIP | CM_START)) ==
1019 (CM_SKIP | CM_START)) {
1020 mrd->state = REPLACE_SKIP;
1024 if ((marker->cm_flags & (CM_SKIP | CM_END)) ==
1025 (CM_SKIP | CM_END)) {
1026 mrd->state = REPLACE_COPY;
1030 if (strcmp(mrd->target.mti_svname, marker->cm_tgtname) == 0) {
1031 LASSERT(!(marker->cm_flags & CM_START) ||
1032 !(marker->cm_flags & CM_END));
1033 if (marker->cm_flags & CM_START) {
1034 if (!strncmp(marker->cm_comment,
1035 "add failnid", 11)) {
1036 mrd->state = REPLACE_SKIP;
1038 mrd->state = REPLACE_UUID;
1039 mrd->failover = NULL;
1041 } else if (marker->cm_flags & CM_END)
1042 mrd->state = REPLACE_COPY;
1044 if (!strncmp(marker->cm_comment,
1053 static int record_base(const struct lu_env *env, struct llog_handle *llh,
1054 char *cfgname, lnet_nid_t nid, int cmd,
1055 char *s1, char *s2, char *s3, char *s4)
1057 struct mgs_thread_info *mgi = mgs_env_info(env);
1058 struct llog_cfg_rec *lcr;
1061 CDEBUG(D_MGS, "lcfg %s %#x %s %s %s %s\n", cfgname,
1062 cmd, s1, s2, s3, s4);
1064 lustre_cfg_bufs_reset(&mgi->mgi_bufs, cfgname);
1066 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, s1);
1068 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 2, s2);
1070 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 3, s3);
1072 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 4, s4);
1074 lcr = lustre_cfg_rec_new(cmd, &mgi->mgi_bufs);
1078 lcr->lcr_cfg.lcfg_nid = nid;
1079 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1081 lustre_cfg_rec_free(lcr);
1085 "failed to write lcfg %s %#x %s %s %s %s: rc = %d\n",
1086 cfgname, cmd, s1, s2, s3, s4, rc);
1090 static inline int record_add_uuid(const struct lu_env *env,
1091 struct llog_handle *llh,
1092 uint64_t nid, char *uuid)
1094 return record_base(env, llh, NULL, nid, LCFG_ADD_UUID, uuid,
1098 static inline int record_add_conn(const struct lu_env *env,
1099 struct llog_handle *llh,
1100 char *devname, char *uuid)
1102 return record_base(env, llh, devname, 0, LCFG_ADD_CONN, uuid,
1106 static inline int record_attach(const struct lu_env *env,
1107 struct llog_handle *llh, char *devname,
1108 char *type, char *uuid)
1110 return record_base(env, llh, devname, 0, LCFG_ATTACH, type, uuid,
1114 static inline int record_setup(const struct lu_env *env,
1115 struct llog_handle *llh, char *devname,
1116 char *s1, char *s2, char *s3, char *s4)
1118 return record_base(env, llh, devname, 0, LCFG_SETUP, s1, s2, s3, s4);
1122 * \retval <0 record processing error
1123 * \retval n record is processed. No need copy original one.
1124 * \retval 0 record is not processed.
1126 static int process_command(const struct lu_env *env, struct lustre_cfg *lcfg,
1127 struct mgs_replace_data *mrd)
1134 if (mrd->state == REPLACE_UUID &&
1135 lcfg->lcfg_command == LCFG_ADD_UUID) {
1136 /* LCFG_ADD_UUID command found. Let's skip original command
1137 and add passed nids */
1138 ptr = mrd->target.mti_params;
1139 while (class_parse_nid4(ptr, &nid, &ptr) == 0) {
1140 if (!mrd->nodeuuid) {
1141 rc = name_create(&mrd->nodeuuid,
1142 libcfs_nid2str(nid), "");
1144 CERROR("Can't create uuid for "
1145 "nid %s, device %s\n",
1146 libcfs_nid2str(nid),
1147 mrd->target.mti_svname);
1151 CDEBUG(D_MGS, "add nid %s with uuid %s, "
1152 "device %s\n", libcfs_nid2str(nid),
1153 mrd->target.mti_params,
1155 rc = record_add_uuid(env,
1159 CWARN("%s: Can't add nid %s for uuid %s :rc=%d\n",
1160 mrd->target.mti_svname,
1161 libcfs_nid2str(nid),
1167 mrd->failover = ptr;
1172 if (nids_added == 0) {
1173 CERROR("No new nids were added, nid %s with uuid %s, "
1174 "device %s\n", libcfs_nid2str(nid),
1175 mrd->nodeuuid ? mrd->nodeuuid : "NULL",
1176 mrd->target.mti_svname);
1177 name_destroy(&mrd->nodeuuid);
1180 mrd->state = REPLACE_SETUP;
1186 if (mrd->state == REPLACE_SETUP && lcfg->lcfg_command == LCFG_SETUP) {
1187 /* LCFG_SETUP command found. UUID should be changed */
1188 rc = record_setup(env,
1190 /* devname the same */
1191 lustre_cfg_string(lcfg, 0),
1192 /* s1 is not changed */
1193 lustre_cfg_string(lcfg, 1),
1195 /* s3 is not changed */
1196 lustre_cfg_string(lcfg, 3),
1197 /* s4 is not changed */
1198 lustre_cfg_string(lcfg, 4));
1200 name_destroy(&mrd->nodeuuid);
1204 if (mrd->failover) {
1205 ptr = mrd->failover;
1206 while (class_parse_nid4(ptr, &nid, &ptr) == 0) {
1207 if (mrd->nodeuuid == NULL) {
1208 rc = name_create(&mrd->nodeuuid,
1209 libcfs_nid2str(nid),
1215 CDEBUG(D_MGS, "add nid %s for failover %s\n",
1216 libcfs_nid2str(nid), mrd->nodeuuid);
1217 rc = record_add_uuid(env, mrd->temp_llh, nid,
1220 CWARN("%s: Can't add nid %s for failover %s :rc = %d\n",
1221 mrd->target.mti_svname,
1222 libcfs_nid2str(nid),
1224 name_destroy(&mrd->nodeuuid);
1228 rc = record_add_conn(env,
1230 lustre_cfg_string(lcfg, 0),
1232 name_destroy(&mrd->nodeuuid);
1237 if (mrd->nodeuuid) {
1238 rc = record_add_conn(env, mrd->temp_llh,
1239 lustre_cfg_string(lcfg, 0),
1241 name_destroy(&mrd->nodeuuid);
1246 mrd->state = REPLACE_DONE;
1250 /* All new UUID are added. Skip. */
1251 if (mrd->state == REPLACE_SETUP &&
1252 lcfg->lcfg_command == LCFG_ADD_UUID)
1255 /* Another commands in target device block */
1260 * Handler that called for every record in llog.
1261 * Records are processed in order they placed in llog.
1263 * \param[in] llh log to be processed
1264 * \param[in] rec current record
1265 * \param[in] data mgs_replace_data structure
1269 static int mgs_replace_nids_handler(const struct lu_env *env,
1270 struct llog_handle *llh,
1271 struct llog_rec_hdr *rec,
1274 struct mgs_replace_data *mrd;
1275 struct lustre_cfg *lcfg = REC_DATA(rec);
1276 int cfg_len = REC_DATA_LEN(rec);
1280 mrd = (struct mgs_replace_data *)data;
1282 if (rec->lrh_type != OBD_CFG_REC) {
1283 CERROR("unhandled lrh_type: %#x, cmd %x %s %s\n",
1284 rec->lrh_type, lcfg->lcfg_command,
1285 lustre_cfg_string(lcfg, 0),
1286 lustre_cfg_string(lcfg, 1));
1290 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
1292 /* Do not copy any invalidated records */
1293 GOTO(skip_out, rc = 0);
1296 rc = check_markers(lcfg, mrd);
1297 if (rc || mrd->state == REPLACE_SKIP)
1298 GOTO(skip_out, rc = 0);
1300 /* Write to new log all commands outside target device block */
1301 if (mrd->state == REPLACE_COPY)
1302 GOTO(copy_out, rc = 0);
1304 if (mrd->state == REPLACE_DONE &&
1305 (lcfg->lcfg_command == LCFG_ADD_UUID ||
1306 lcfg->lcfg_command == LCFG_ADD_CONN)) {
1308 CWARN("Previous failover is deleted, but new one is "
1309 "not set. This means you configure system "
1310 "without failover or passed wrong replace_nids "
1311 "command parameters. Device %s, passed nids %s\n",
1312 mrd->target.mti_svname, mrd->target.mti_params);
1313 GOTO(skip_out, rc = 0);
1316 rc = process_command(env, lcfg, mrd);
1323 /* Record is placed in temporary llog as is */
1324 rc = llog_write(env, mrd->temp_llh, rec, LLOG_NEXT_IDX);
1326 CDEBUG(D_MGS, "Copied idx=%d, rc=%d, len=%d, cmd %x %s %s\n",
1327 rec->lrh_index, rc, rec->lrh_len, lcfg->lcfg_command,
1328 lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));
1332 CDEBUG(D_MGS, "Skipped idx=%d, rc=%d, len=%d, cmd %x %s %s\n",
1333 rec->lrh_index, rc, rec->lrh_len, lcfg->lcfg_command,
1334 lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));
1338 static int mgs_log_is_empty(const struct lu_env *env,
1339 struct mgs_device *mgs, char *name)
1341 struct llog_ctxt *ctxt;
1344 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
1345 LASSERT(ctxt != NULL);
1347 rc = llog_is_empty(env, ctxt, name);
1348 llog_ctxt_put(ctxt);
1352 static int mgs_replace_log(const struct lu_env *env,
1353 struct obd_device *mgs,
1354 char *logname, char *devname,
1355 llog_cb_t replace_handler, void *data)
1357 struct llog_handle *orig_llh, *backup_llh;
1358 struct llog_ctxt *ctxt;
1359 struct mgs_replace_data *mrd;
1360 struct mgs_device *mgs_dev = lu2mgs_dev(mgs->obd_lu_dev);
1361 static struct obd_uuid cfg_uuid = { .uuid = "config_uuid" };
1363 int rc, rc2, buf_size;
1367 ctxt = llog_get_context(mgs, LLOG_CONFIG_ORIG_CTXT);
1368 LASSERT(ctxt != NULL);
1370 if (mgs_log_is_empty(env, mgs_dev, logname)) {
1371 /* Log is empty. Nothing to replace */
1372 GOTO(out_put, rc = 0);
1375 now = ktime_get_real_seconds();
1377 /* max time64_t in decimal fits into 20 bytes long string */
1378 buf_size = strlen(logname) + 1 + 20 + 1 + strlen(".bak") + 1;
1379 OBD_ALLOC(backup, buf_size);
1381 GOTO(out_put, rc = -ENOMEM);
1383 snprintf(backup, buf_size, "%s.%llu.bak", logname, now);
1385 rc = llog_backup(env, mgs, ctxt, ctxt, logname, backup);
1387 /* Now erase original log file. Connections are not allowed.
1388 Backup is already saved */
1389 rc = llog_erase(env, ctxt, NULL, logname);
1392 } else if (rc != -ENOENT) {
1393 CERROR("%s: can't make backup for %s: rc = %d\n",
1394 mgs->obd_name, logname, rc);
1398 /* open local log */
1399 rc = llog_open_create(env, ctxt, &orig_llh, NULL, logname);
1401 GOTO(out_restore, rc);
1403 rc = llog_init_handle(env, orig_llh, LLOG_F_IS_PLAIN, &cfg_uuid);
1405 GOTO(out_closel, rc);
1407 /* open backup llog */
1408 rc = llog_open(env, ctxt, &backup_llh, NULL, backup,
1411 GOTO(out_closel, rc);
1413 rc = llog_init_handle(env, backup_llh, LLOG_F_IS_PLAIN, NULL);
1415 GOTO(out_close, rc);
1417 if (llog_get_size(backup_llh) <= 1)
1418 GOTO(out_close, rc = 0);
1422 GOTO(out_close, rc = -ENOMEM);
1423 /* devname is only needed information to replace UUID records */
1425 strlcpy(mrd->target.mti_svname, devname,
1426 sizeof(mrd->target.mti_svname));
1427 /* data is parsed in llog callback */
1429 strlcpy(mrd->target.mti_params, data,
1430 sizeof(mrd->target.mti_params));
1431 /* Copy records to this temporary llog */
1432 mrd->temp_llh = orig_llh;
1434 rc = llog_process(env, backup_llh, replace_handler,
1438 rc2 = llog_close(NULL, backup_llh);
1442 rc2 = llog_close(NULL, orig_llh);
1448 CERROR("%s: llog should be restored: rc = %d\n",
1450 rc2 = llog_backup(env, mgs, ctxt, ctxt, backup,
1453 CERROR("%s: can't restore backup %s: rc = %d\n",
1454 mgs->obd_name, logname, rc2);
1458 OBD_FREE(backup, buf_size);
1461 llog_ctxt_put(ctxt);
1464 CERROR("%s: failed to replace log %s: rc = %d\n",
1465 mgs->obd_name, logname, rc);
1470 static int mgs_replace_nids_log(const struct lu_env *env,
1471 struct obd_device *obd,
1472 char *logname, char *devname, char *nids)
1474 CDEBUG(D_MGS, "Replace NIDs for %s in %s\n", devname, logname);
1475 return mgs_replace_log(env, obd, logname, devname,
1476 mgs_replace_nids_handler, nids);
1480 * Parse device name and get file system name and/or device index
1482 * @devname device name (ex. lustre-MDT0000)
1483 * @fsname file system name extracted from @devname and returned
1484 * to the caller (optional)
1485 * @index device index extracted from @devname and returned to
1486 * the caller (optional)
1488 * RETURN 0 success if we are only interested in
1489 * extracting fsname from devname.
1492 * LDD_F_SV_TYPE_* Besides extracting the fsname the
1493 * user also wants the index. Report to
1494 * the user the type of obd device the
1495 * returned index belongs too.
1497 * -EINVAL The obd device name is improper so
1498 * fsname could not be extracted.
1500 * -ENXIO Failed to extract the index out of
1501 * the obd device name. Most likely an
1502 * invalid obd device name
1504 static int mgs_parse_devname(char *devname, char *fsname, u32 *index)
1509 /* Extract fsname */
1511 rc = server_name2fsname(devname, fsname, NULL);
1513 CDEBUG(D_MGS, "Device name %s without fsname\n",
1520 rc = server_name2index(devname, index, NULL);
1522 CDEBUG(D_MGS, "Device name %s with wrong index\n",
1528 /* server_name2index can return LDD_F_SV_TYPE_* so always return rc */
1532 /* This is only called during replace_nids */
1533 static int only_mgs_is_running(struct obd_device *mgs_obd)
1535 /* TDB: Is global variable with devices count exists? */
1536 int num_devices = get_devices_count();
1537 int num_exports = 0;
1538 struct obd_export *exp;
1540 spin_lock(&mgs_obd->obd_dev_lock);
1541 list_for_each_entry(exp, &mgs_obd->obd_exports, exp_obd_chain) {
1542 /* skip self export */
1543 if (exp == mgs_obd->obd_self_export)
1548 if (num_exports > 1)
1549 CERROR("%s: node %s still connected during replace_nids connect_flags:%llx\n",
1551 libcfs_nidstr(&exp->exp_nid_stats->nid),
1552 exp_connect_flags(exp));
1554 spin_unlock(&mgs_obd->obd_dev_lock);
1556 /* osd, MGS and MGC + MGC export (nosvc starts MGC)
1557 * (wc -l /proc/fs/lustre/devices <= 3) && (non self exports == 1)
1559 return (num_devices <= 3) && (num_exports <= 1);
1562 static int name_create_mdt(char **logname, char *fsname, int mdt_idx)
1566 if (mdt_idx > INDEX_MAP_MAX_VALUE)
1569 snprintf(postfix, sizeof(postfix), "-MDT%04x", mdt_idx);
1570 return name_create(logname, fsname, postfix);
1574 * Replace nids for \a device to \a nids values
1576 * \param obd MGS obd device
1577 * \param devname nids need to be replaced for this device
1578 * (ex. lustre-OST0000)
1579 * \param nids nids list (ex. nid1,nid2,nid3)
1583 int mgs_replace_nids(const struct lu_env *env,
1584 struct mgs_device *mgs,
1585 char *devname, char *nids)
1587 /* Assume fsname is part of device name */
1588 char fsname[MTI_NAME_MAXLEN];
1592 struct fs_db *fsdb = NULL;
1595 struct obd_device *mgs_obd = mgs->mgs_obd;
1598 /* We can only change NIDs if no other nodes are connected */
1599 spin_lock(&mgs_obd->obd_dev_lock);
1600 conn_state = mgs_obd->obd_no_conn;
1601 mgs_obd->obd_no_conn = 1;
1602 spin_unlock(&mgs_obd->obd_dev_lock);
1604 /* We can not change nids if not only MGS is started */
1605 if (!only_mgs_is_running(mgs_obd)) {
1606 CERROR("Only MGS is allowed to be started\n");
1607 GOTO(out, rc = -EINPROGRESS);
1610 /* Get fsname and index */
1611 rc = mgs_parse_devname(devname, fsname, &index);
1615 rc = mgs_find_or_make_fsdb(env, mgs, fsname, &fsdb);
1617 CERROR("%s: can't find fsdb: rc = %d\n", fsname, rc);
1621 /* Process client llogs */
1622 rc = name_create(&logname, fsname, "-client");
1625 rc = mgs_replace_nids_log(env, mgs_obd, logname, devname, nids);
1626 name_destroy(&logname);
1628 CERROR("%s: error while replacing NIDs for %s: rc = %d\n",
1629 fsname, devname, rc);
1633 /* Process MDT llogs */
1634 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
1635 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
1637 rc = name_create_mdt(&logname, fsname, i);
1640 rc = mgs_replace_nids_log(env, mgs_obd, logname, devname, nids);
1641 name_destroy(&logname);
1647 spin_lock(&mgs_obd->obd_dev_lock);
1648 mgs_obd->obd_no_conn = conn_state;
1649 spin_unlock(&mgs_obd->obd_dev_lock);
1652 mgs_put_fsdb(mgs, fsdb);
1658 * This is called for every record in llog. Some of records are
1659 * skipped, others are copied to new log as is.
1660 * Records to be skipped are
1661 * marker records marked SKIP
1662 * records enclosed between SKIP markers
1664 * \param[in] llh log to be processed
1665 * \param[in] rec current record
1666 * \param[in] data mgs_replace_data structure
1670 static int mgs_clear_config_handler(const struct lu_env *env,
1671 struct llog_handle *llh,
1672 struct llog_rec_hdr *rec, void *data)
1674 struct mgs_replace_data *mrd;
1675 struct lustre_cfg *lcfg = REC_DATA(rec);
1676 int cfg_len = REC_DATA_LEN(rec);
1681 mrd = (struct mgs_replace_data *)data;
1683 if (rec->lrh_type != OBD_CFG_REC) {
1684 CDEBUG(D_MGS, "Config llog Name=%s, Record Index=%u, "
1685 "Unhandled Record Type=%#x\n", llh->lgh_name,
1686 rec->lrh_index, rec->lrh_type);
1690 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
1692 CDEBUG(D_MGS, "Config llog Name=%s, Invalid config file.",
1697 if (lcfg->lcfg_command == LCFG_MARKER) {
1698 struct cfg_marker *marker;
1700 marker = lustre_cfg_buf(lcfg, 1);
1701 if (marker->cm_flags & CM_SKIP) {
1702 if (marker->cm_flags & CM_START)
1703 mrd->state = REPLACE_SKIP;
1704 if (marker->cm_flags & CM_END)
1705 mrd->state = REPLACE_COPY;
1706 /* SKIP section started or finished */
1707 CDEBUG(D_MGS, "Skip idx=%d, rc=%d, len=%d, "
1708 "cmd %x %s %s\n", rec->lrh_index, rc,
1709 rec->lrh_len, lcfg->lcfg_command,
1710 lustre_cfg_string(lcfg, 0),
1711 lustre_cfg_string(lcfg, 1));
1715 if (mrd->state == REPLACE_SKIP) {
1716 /* record enclosed between SKIP markers, skip it */
1717 CDEBUG(D_MGS, "Skip idx=%d, rc=%d, len=%d, "
1718 "cmd %x %s %s\n", rec->lrh_index, rc,
1719 rec->lrh_len, lcfg->lcfg_command,
1720 lustre_cfg_string(lcfg, 0),
1721 lustre_cfg_string(lcfg, 1));
1726 /* Record is placed in temporary llog as is */
1727 rc = llog_write(env, mrd->temp_llh, rec, LLOG_NEXT_IDX);
1729 CDEBUG(D_MGS, "Copied idx=%d, rc=%d, len=%d, cmd %x %s %s\n",
1730 rec->lrh_index, rc, rec->lrh_len, lcfg->lcfg_command,
1731 lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));
1736 * Directory CONFIGS/ may contain files which are not config logs to
1737 * be cleared. Skip any llogs with a non-alphanumeric character after
1738 * the last '-'. For example, fsname-MDT0000.sav, fsname-MDT0000.bak,
1739 * fsname-MDT0000.orig, fsname-MDT0000~, fsname-MDT0000.20150516, etc.
1741 static bool config_to_clear(const char *logname)
1746 str = strrchr(logname, '-');
1751 while (isalnum(str[++i]));
1752 return str[i] == '\0';
1756 * Clear config logs for \a name
1759 * \param mgs MGS device
1760 * \param name name of device or of filesystem
1761 * (ex. lustre-OST0000 or lustre) in later case all logs
1766 int mgs_clear_configs(const struct lu_env *env,
1767 struct mgs_device *mgs, const char *name)
1769 struct list_head dentry_list;
1770 struct mgs_direntry *dirent, *n;
1773 struct obd_device *mgs_obd = mgs->mgs_obd;
1778 /* Prevent clients and servers from connecting to mgs */
1779 spin_lock(&mgs_obd->obd_dev_lock);
1780 conn_state = mgs_obd->obd_no_conn;
1781 mgs_obd->obd_no_conn = 1;
1782 spin_unlock(&mgs_obd->obd_dev_lock);
1785 * config logs cannot be cleaned if anything other than
1788 if (!only_mgs_is_running(mgs_obd)) {
1789 CERROR("Only MGS is allowed to be started\n");
1790 GOTO(out, rc = -EBUSY);
1793 /* Find all the logs in the CONFIGS directory */
1794 rc = class_dentry_readdir(env, mgs, &dentry_list);
1796 CERROR("%s: cannot read config directory '%s': rc = %d\n",
1797 mgs_obd->obd_name, MOUNT_CONFIGS_DIR, rc);
1801 if (list_empty(&dentry_list)) {
1802 CERROR("%s: list empty reading config dir '%s': rc = %d\n",
1803 mgs_obd->obd_name, MOUNT_CONFIGS_DIR, -ENOENT);
1804 GOTO(out, rc = -ENOENT);
1807 OBD_ALLOC(namedash, strlen(name) + 2);
1808 if (namedash == NULL)
1809 GOTO(out, rc = -ENOMEM);
1810 snprintf(namedash, strlen(name) + 2, "%s-", name);
1812 list_for_each_entry(dirent, &dentry_list, mde_list) {
1813 if (strcmp(name, dirent->mde_name) &&
1814 strncmp(namedash, dirent->mde_name, strlen(namedash)))
1816 if (!config_to_clear(dirent->mde_name))
1818 CDEBUG(D_MGS, "%s: Clear config log %s\n",
1819 mgs_obd->obd_name, dirent->mde_name);
1820 rc = mgs_replace_log(env, mgs_obd, dirent->mde_name, NULL,
1821 mgs_clear_config_handler, NULL);
1826 list_for_each_entry_safe(dirent, n, &dentry_list, mde_list) {
1827 list_del_init(&dirent->mde_list);
1828 mgs_direntry_free(dirent);
1830 OBD_FREE(namedash, strlen(name) + 2);
1832 spin_lock(&mgs_obd->obd_dev_lock);
1833 mgs_obd->obd_no_conn = conn_state;
1834 spin_unlock(&mgs_obd->obd_dev_lock);
1839 static int record_lov_setup(const struct lu_env *env, struct llog_handle *llh,
1840 char *devname, struct lov_desc *desc)
1842 struct mgs_thread_info *mgi = mgs_env_info(env);
1843 struct llog_cfg_rec *lcr;
1846 lustre_cfg_bufs_reset(&mgi->mgi_bufs, devname);
1847 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, desc, sizeof(*desc));
1848 lcr = lustre_cfg_rec_new(LCFG_SETUP, &mgi->mgi_bufs);
1852 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1853 lustre_cfg_rec_free(lcr);
1857 static int record_lmv_setup(const struct lu_env *env, struct llog_handle *llh,
1858 char *devname, struct lmv_desc *desc)
1860 struct mgs_thread_info *mgi = mgs_env_info(env);
1861 struct llog_cfg_rec *lcr;
1864 lustre_cfg_bufs_reset(&mgi->mgi_bufs, devname);
1865 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, desc, sizeof(*desc));
1866 lcr = lustre_cfg_rec_new(LCFG_SETUP, &mgi->mgi_bufs);
1870 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1871 lustre_cfg_rec_free(lcr);
1875 static inline int record_mdc_add(const struct lu_env *env,
1876 struct llog_handle *llh,
1877 char *logname, char *mdcuuid,
1878 char *mdtuuid, char *index,
1881 return record_base(env,llh,logname,0,LCFG_ADD_MDC,
1882 mdtuuid, index, gen, mdcuuid);
1885 static inline int record_lov_add(const struct lu_env *env,
1886 struct llog_handle *llh,
1887 char *lov_name, char *ost_uuid,
1888 char *index, char *gen)
1890 return record_base(env, llh, lov_name, 0, LCFG_LOV_ADD_OBD,
1891 ost_uuid, index, gen, NULL);
1894 static inline int record_mount_opt(const struct lu_env *env,
1895 struct llog_handle *llh,
1896 char *profile, char *lov_name,
1899 return record_base(env, llh, NULL, 0, LCFG_MOUNTOPT,
1900 profile, lov_name, mdc_name, NULL);
1903 static int record_marker(const struct lu_env *env,
1904 struct llog_handle *llh,
1905 struct fs_db *fsdb, __u32 flags,
1906 char *tgtname, char *comment)
1908 struct mgs_thread_info *mgi = mgs_env_info(env);
1909 struct llog_cfg_rec *lcr;
1913 if (flags & CM_START)
1915 mgi->mgi_marker.cm_step = fsdb->fsdb_gen;
1916 mgi->mgi_marker.cm_flags = flags;
1917 mgi->mgi_marker.cm_vers = LUSTRE_VERSION_CODE;
1918 cplen = strlcpy(mgi->mgi_marker.cm_tgtname, tgtname,
1919 sizeof(mgi->mgi_marker.cm_tgtname));
1920 if (cplen >= sizeof(mgi->mgi_marker.cm_tgtname))
1922 cplen = strlcpy(mgi->mgi_marker.cm_comment, comment,
1923 sizeof(mgi->mgi_marker.cm_comment));
1924 if (cplen >= sizeof(mgi->mgi_marker.cm_comment))
1926 mgi->mgi_marker.cm_createtime = ktime_get_real_seconds();
1927 mgi->mgi_marker.cm_canceltime = 0;
1928 lustre_cfg_bufs_reset(&mgi->mgi_bufs, NULL);
1929 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, &mgi->mgi_marker,
1930 sizeof(mgi->mgi_marker));
1931 lcr = lustre_cfg_rec_new(LCFG_MARKER, &mgi->mgi_bufs);
1935 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
1936 lustre_cfg_rec_free(lcr);
1940 static int record_start_log(const struct lu_env *env, struct mgs_device *mgs,
1941 struct llog_handle **llh, char *name)
1943 static struct obd_uuid cfg_uuid = { .uuid = "config_uuid" };
1944 struct llog_ctxt *ctxt;
1949 GOTO(out, rc = -EBUSY);
1951 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
1953 GOTO(out, rc = -ENODEV);
1954 LASSERT(ctxt->loc_obd == mgs->mgs_obd);
1956 rc = llog_open_create(env, ctxt, llh, NULL, name);
1959 rc = llog_init_handle(env, *llh, LLOG_F_IS_PLAIN, &cfg_uuid);
1961 llog_close(env, *llh);
1963 llog_ctxt_put(ctxt);
1966 CERROR("%s: can't start log %s: rc = %d\n",
1967 mgs->mgs_obd->obd_name, name, rc);
1973 static int record_end_log(const struct lu_env *env, struct llog_handle **llh)
1977 rc = llog_close(env, *llh);
1983 /******************** config "macros" *********************/
1985 /* write an lcfg directly into a log (with markers) */
1986 static int mgs_write_log_direct(const struct lu_env *env,
1987 struct mgs_device *mgs, struct fs_db *fsdb,
1988 char *logname, struct llog_cfg_rec *lcr,
1989 char *devname, char *comment)
1991 struct llog_handle *llh = NULL;
1996 rc = record_start_log(env, mgs, &llh, logname);
2000 /* FIXME These should be a single journal transaction */
2001 rc = record_marker(env, llh, fsdb, CM_START, devname, comment);
2004 rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
2007 rc = record_marker(env, llh, fsdb, CM_END, devname, comment);
2011 record_end_log(env, &llh);
2015 /* write the lcfg in all logs for the given fs */
2016 static int mgs_write_log_direct_all(const struct lu_env *env,
2017 struct mgs_device *mgs,
2019 struct mgs_target_info *mti,
2020 struct llog_cfg_rec *lcr, char *devname,
2021 char *comment, int server_only)
2023 struct list_head log_list;
2024 struct mgs_direntry *dirent, *n;
2025 char *fsname = mti->mti_fsname;
2026 int rc = 0, len = strlen(fsname);
2029 /* Find all the logs in the CONFIGS directory */
2030 rc = class_dentry_readdir(env, mgs, &log_list);
2034 /* Could use fsdb index maps instead of directory listing */
2035 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
2036 list_del_init(&dirent->mde_list);
2037 /* don't write to sptlrpc rule log */
2038 if (strstr(dirent->mde_name, "-sptlrpc") != NULL)
2041 /* caller wants write server logs only */
2042 if (server_only && strstr(dirent->mde_name, "-client") != NULL)
2045 if (strlen(dirent->mde_name) <= len ||
2046 strncmp(fsname, dirent->mde_name, len) != 0 ||
2047 dirent->mde_name[len] != '-')
2050 CDEBUG(D_MGS, "Changing log %s\n", dirent->mde_name);
2051 /* Erase any old settings of this same parameter */
2052 rc = mgs_modify(env, mgs, fsdb, mti, dirent->mde_name,
2053 devname, comment, CM_SKIP);
2055 CERROR("%s: Can't modify llog %s: rc = %d\n",
2056 mgs->mgs_obd->obd_name, dirent->mde_name, rc);
2059 /* Write the new one */
2060 rc = mgs_write_log_direct(env, mgs, fsdb, dirent->mde_name,
2061 lcr, devname, comment);
2063 CERROR("%s: writing log %s: rc = %d\n",
2064 mgs->mgs_obd->obd_name, dirent->mde_name, rc);
2066 mgs_direntry_free(dirent);
2072 static int mgs_write_log_osp_to_mdt(const struct lu_env *env,
2073 struct mgs_device *mgs,
2075 struct mgs_target_info *mti,
2076 int index, char *logname);
2077 static int mgs_write_log_osc_to_lov(const struct lu_env *env,
2078 struct mgs_device *mgs,
2080 struct mgs_target_info *mti,
2081 char *logname, char *suffix, char *lovname,
2082 enum lustre_sec_part sec_part, int flags);
2083 static int name_create_mdt_and_lov(char **logname, char **lovname,
2084 struct fs_db *fsdb, int i);
2086 static int add_param(char *params, char *key, char *val)
2088 char *start = params + strlen(params);
2089 char *end = params + sizeof(((struct mgs_target_info *)0)->mti_params);
2093 keylen = strlen(key);
2094 if (start + 1 + keylen + strlen(val) >= end) {
2095 CERROR("params are too long: %s %s%s\n",
2096 params, key != NULL ? key : "", val);
2100 sprintf(start, " %s%s", key != NULL ? key : "", val);
2105 * Walk through client config log record and convert the related records
2108 static int mgs_steal_client_llog_handler(const struct lu_env *env,
2109 struct llog_handle *llh,
2110 struct llog_rec_hdr *rec, void *data)
2112 struct mgs_device *mgs;
2113 struct obd_device *obd;
2114 struct mgs_target_info *mti, *tmti;
2116 int cfg_len = rec->lrh_len;
2117 char *cfg_buf = (char *)(rec + 1);
2118 struct lustre_cfg *lcfg;
2120 struct llog_handle *mdt_llh = NULL;
2121 static int got_an_osc_or_mdc = 0;
2122 /* 0: not found any osc/mdc;
2126 static int last_step = -1;
2131 mti = ((struct temp_comp *)data)->comp_mti;
2132 tmti = ((struct temp_comp *)data)->comp_tmti;
2133 fsdb = ((struct temp_comp *)data)->comp_fsdb;
2134 obd = ((struct temp_comp *)data)->comp_obd;
2135 mgs = lu2mgs_dev(obd->obd_lu_dev);
2138 if (rec->lrh_type != OBD_CFG_REC) {
2139 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
2143 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
2145 CERROR("Insane cfg\n");
2149 lcfg = (struct lustre_cfg *)cfg_buf;
2151 if (lcfg->lcfg_command == LCFG_MARKER) {
2152 struct cfg_marker *marker;
2153 marker = lustre_cfg_buf(lcfg, 1);
2154 if (!strncmp(marker->cm_comment, "add osc", 7) &&
2155 (marker->cm_flags & CM_START) &&
2156 !(marker->cm_flags & CM_SKIP)) {
2157 got_an_osc_or_mdc = 1;
2158 cplen = strlcpy(tmti->mti_svname, marker->cm_tgtname,
2159 sizeof(tmti->mti_svname));
2160 if (cplen >= sizeof(tmti->mti_svname))
2162 rc = record_start_log(env, mgs, &mdt_llh,
2166 rc = record_marker(env, mdt_llh, fsdb, CM_START,
2167 mti->mti_svname, "add osc(copied)");
2168 record_end_log(env, &mdt_llh);
2169 last_step = marker->cm_step;
2172 if (!strncmp(marker->cm_comment, "add osc", 7) &&
2173 (marker->cm_flags & CM_END) &&
2174 !(marker->cm_flags & CM_SKIP)) {
2175 LASSERT(last_step == marker->cm_step);
2177 got_an_osc_or_mdc = 0;
2178 memset(tmti, 0, sizeof(*tmti));
2179 rc = record_start_log(env, mgs, &mdt_llh,
2183 rc = record_marker(env, mdt_llh, fsdb, CM_END,
2184 mti->mti_svname, "add osc(copied)");
2185 record_end_log(env, &mdt_llh);
2188 if (!strncmp(marker->cm_comment, "add mdc", 7) &&
2189 (marker->cm_flags & CM_START) &&
2190 !(marker->cm_flags & CM_SKIP)) {
2191 got_an_osc_or_mdc = 2;
2192 last_step = marker->cm_step;
2193 memcpy(tmti->mti_svname, marker->cm_tgtname,
2194 strlen(marker->cm_tgtname));
2198 if (!strncmp(marker->cm_comment, "add mdc", 7) &&
2199 (marker->cm_flags & CM_END) &&
2200 !(marker->cm_flags & CM_SKIP)) {
2201 LASSERT(last_step == marker->cm_step);
2203 got_an_osc_or_mdc = 0;
2204 memset(tmti, 0, sizeof(*tmti));
2209 if (got_an_osc_or_mdc == 0 || last_step < 0)
2212 if (lcfg->lcfg_command == LCFG_ADD_UUID) {
2213 __u64 nodenid = lcfg->lcfg_nid;
2215 if (strlen(tmti->mti_uuid) == 0) {
2216 /* target uuid not set, this config record is before
2217 * LCFG_SETUP, this nid is one of target node nid.
2219 tmti->mti_nids[tmti->mti_nid_count] = nodenid;
2220 tmti->mti_nid_count++;
2222 char nidstr[LNET_NIDSTR_SIZE];
2224 /* failover node nid */
2225 libcfs_nid2str_r(nodenid, nidstr, sizeof(nidstr));
2226 rc = add_param(tmti->mti_params, PARAM_FAILNODE,
2233 if (lcfg->lcfg_command == LCFG_SETUP) {
2236 target = lustre_cfg_string(lcfg, 1);
2237 memcpy(tmti->mti_uuid, target, strlen(target));
2241 /* ignore client side sptlrpc_conf_log */
2242 if (lcfg->lcfg_command == LCFG_SPTLRPC_CONF)
2245 if (lcfg->lcfg_command == LCFG_ADD_MDC &&
2246 strstr(lustre_cfg_string(lcfg, 0), "-clilmv") != NULL) {
2249 if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1)
2251 if (index == mti->mti_stripe_index) {
2253 "attempt to create MDT%04x->MDT%04x osp device\n",
2257 memcpy(tmti->mti_fsname, mti->mti_fsname,
2258 strlen(mti->mti_fsname));
2259 tmti->mti_stripe_index = index;
2261 rc = mgs_write_log_osp_to_mdt(env, mgs, fsdb, tmti,
2262 mti->mti_stripe_index,
2264 memset(tmti, 0, sizeof(*tmti));
2268 if (lcfg->lcfg_command == LCFG_LOV_ADD_OBD) {
2271 char *logname, *lovname;
2273 rc = name_create_mdt_and_lov(&logname, &lovname, fsdb,
2274 mti->mti_stripe_index);
2277 sprintf(mdt_index, "-MDT%04x", mti->mti_stripe_index);
2279 if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1) {
2280 name_destroy(&logname);
2281 name_destroy(&lovname);
2285 tmti->mti_stripe_index = index;
2286 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, tmti, logname,
2289 name_destroy(&logname);
2290 name_destroy(&lovname);
2296 /* fsdb->fsdb_mutex is already held in mgs_write_log_target*/
2297 /* stealed from mgs_get_fsdb_from_llog*/
2298 static int mgs_steal_llog_for_mdt_from_client(const struct lu_env *env,
2299 struct mgs_device *mgs,
2301 struct temp_comp *comp)
2303 struct llog_handle *loghandle;
2304 struct mgs_target_info *tmti;
2305 struct llog_ctxt *ctxt;
2310 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
2311 LASSERT(ctxt != NULL);
2313 OBD_ALLOC_PTR(tmti);
2315 GOTO(out_ctxt, rc = -ENOMEM);
2317 comp->comp_tmti = tmti;
2318 comp->comp_obd = mgs->mgs_obd;
2320 rc = llog_open(env, ctxt, &loghandle, NULL, client_name,
2328 rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL);
2330 GOTO(out_close, rc);
2332 rc = llog_process_or_fork(env, loghandle, mgs_steal_client_llog_handler,
2333 (void *)comp, NULL, false);
2334 CDEBUG(D_MGS, "steal llog re = %d\n", rc);
2336 llog_close(env, loghandle);
2340 llog_ctxt_put(ctxt);
2344 /* mount opt is the third thing in client logs */
2345 static int mgs_write_log_mount_opt(const struct lu_env *env,
2346 struct mgs_device *mgs, struct fs_db *fsdb,
2349 struct llog_handle *llh = NULL;
2354 CDEBUG(D_MGS, "Writing mount options log for %s\n", logname);
2356 rc = record_start_log(env, mgs, &llh, logname);
2360 rc = record_marker(env, llh, fsdb, CM_START, logname, "mount opts");
2363 rc = record_mount_opt(env, llh, logname, fsdb->fsdb_clilov,
2367 rc = record_marker(env, llh, fsdb, CM_END, logname, "mount opts");
2371 record_end_log(env, &llh);
2375 /* lmv is the second thing for client logs */
2376 /* copied from mgs_write_log_lov. Please refer to that. */
2377 static int mgs_write_log_lmv(const struct lu_env *env,
2378 struct mgs_device *mgs,
2380 struct mgs_target_info *mti,
2381 char *logname, char *lmvname)
2383 struct llog_handle *llh = NULL;
2384 struct lmv_desc *lmvdesc;
2389 CDEBUG(D_MGS, "Writing lmv(%s) log for %s\n", lmvname, logname);
2391 OBD_ALLOC_PTR(lmvdesc);
2392 if (lmvdesc == NULL)
2394 lmvdesc->ld_active_tgt_count = 0;
2395 lmvdesc->ld_tgt_count = 0;
2396 sprintf((char *)lmvdesc->ld_uuid.uuid, "%s_UUID", lmvname);
2397 uuid = (char *)lmvdesc->ld_uuid.uuid;
2399 rc = record_start_log(env, mgs, &llh, logname);
2402 rc = record_marker(env, llh, fsdb, CM_START, lmvname, "lmv setup");
2405 rc = record_attach(env, llh, lmvname, "lmv", uuid);
2408 rc = record_lmv_setup(env, llh, lmvname, lmvdesc);
2411 rc = record_marker(env, llh, fsdb, CM_END, lmvname, "lmv setup");
2415 record_end_log(env, &llh);
2417 OBD_FREE_PTR(lmvdesc);
2421 /* lov is the first thing in the mdt and client logs */
2422 static int mgs_write_log_lov(const struct lu_env *env, struct mgs_device *mgs,
2423 struct fs_db *fsdb, struct mgs_target_info *mti,
2424 char *logname, char *lovname)
2426 struct llog_handle *llh = NULL;
2427 struct lov_desc *lovdesc;
2432 CDEBUG(D_MGS, "Writing lov(%s) log for %s\n", lovname, logname);
2435 * #01 L attach 0:lov_mdsA 1:lov 2:71ccb_lov_mdsA_19f961a9e1
2436 * #02 L lov_setup 0:lov_mdsA 1:(struct lov_desc)
2437 * uuid=lov1_UUID, stripe count=1, size=1048576, offset=0, pattern=0
2440 /* FIXME just make lov_setup accept empty desc (put uuid in buf 2) */
2441 OBD_ALLOC_PTR(lovdesc);
2442 if (lovdesc == NULL)
2444 lovdesc->ld_magic = LOV_DESC_MAGIC;
2445 lovdesc->ld_tgt_count = 0;
2446 /* Defaults. Can be changed later by lcfg config_param */
2447 lovdesc->ld_default_stripe_count = 1;
2448 lovdesc->ld_pattern = LOV_PATTERN_RAID0;
2449 lovdesc->ld_default_stripe_size = LOV_DESC_STRIPE_SIZE_DEFAULT;
2450 lovdesc->ld_default_stripe_offset = -1;
2451 lovdesc->ld_qos_maxage = LOV_DESC_QOS_MAXAGE_DEFAULT;
2452 sprintf((char *)lovdesc->ld_uuid.uuid, "%s_UUID", lovname);
2453 /* can these be the same? */
2454 uuid = (char *)lovdesc->ld_uuid.uuid;
2456 /* This should always be the first entry in a log.
2457 * rc = mgs_clear_log(obd, logname);
2459 rc = record_start_log(env, mgs, &llh, logname);
2462 /* FIXME these should be a single journal transaction */
2463 rc = record_marker(env, llh, fsdb, CM_START, lovname, "lov setup");
2466 rc = record_attach(env, llh, lovname, "lov", uuid);
2469 rc = record_lov_setup(env, llh, lovname, lovdesc);
2472 rc = record_marker(env, llh, fsdb, CM_END, lovname, "lov setup");
2477 record_end_log(env, &llh);
2479 OBD_FREE_PTR(lovdesc);
2483 /* add failnids to open log */
2484 static int mgs_write_log_failnids(const struct lu_env *env,
2485 struct mgs_target_info *mti,
2486 struct llog_handle *llh,
2489 char *failnodeuuid = NULL;
2490 char *ptr = mti->mti_params;
2495 * #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) nal=90 0: 1:uml1_UUID
2496 * #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
2497 * #05 L setup 0:OSC_uml1_ost1_mdsA 1:ost1_UUID 2:uml1_UUID
2498 * #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) nal=90 0: 1:uml2_UUID
2499 * #0x L add_uuid nid=2@elan(0x1000000000002) nal=90 0: 1:uml2_UUID
2500 * #07 L add_conn 0:OSC_uml1_ost1_mdsA 1:uml2_UUID
2504 * Pull failnid info out of params string, which may contain something
2505 * like "<nid1>,<nid2>:<nid3>,<nid4>". class_parse_nid4() does not
2506 * complain about abnormal inputs like ",:<nid1>", "<nid1>:,<nid2>",
2507 * etc. However, convert_hostnames() should have caught those.
2509 while (class_find_param(ptr, PARAM_FAILNODE, &ptr) == 0) {
2510 while (class_parse_nid4(ptr, &nid, &ptr) == 0) {
2511 char nidstr[LNET_NIDSTR_SIZE];
2513 if (failnodeuuid == NULL) {
2514 /* We don't know the failover node name,
2515 * so just use the first nid as the uuid */
2516 libcfs_nid2str_r(nid, nidstr, sizeof(nidstr));
2517 rc = name_create(&failnodeuuid, nidstr, "");
2522 "add nid %s for failover uuid %s, client %s\n",
2523 libcfs_nid2str_r(nid, nidstr, sizeof(nidstr)),
2524 failnodeuuid, cliname);
2525 rc = record_add_uuid(env, llh, nid, failnodeuuid);
2527 * If *ptr is ':', we have added all NIDs for
2531 rc = record_add_conn(env, llh, cliname,
2533 name_destroy(&failnodeuuid);
2534 failnodeuuid = NULL;
2538 rc = record_add_conn(env, llh, cliname, failnodeuuid);
2539 name_destroy(&failnodeuuid);
2540 failnodeuuid = NULL;
2547 static int mgs_write_log_mdc_to_lmv(const struct lu_env *env,
2548 struct mgs_device *mgs,
2550 struct mgs_target_info *mti,
2551 char *logname, char *lmvname)
2553 struct llog_handle *llh = NULL;
2554 char *mdcname = NULL;
2555 char *nodeuuid = NULL;
2556 char *mdcuuid = NULL;
2557 char *lmvuuid = NULL;
2559 char nidstr[LNET_NIDSTR_SIZE];
2563 if (mgs_log_is_empty(env, mgs, logname)) {
2564 CERROR("log is empty! Logical error\n");
2568 CDEBUG(D_MGS, "adding mdc for %s to log %s:lmv(%s)\n",
2569 mti->mti_svname, logname, lmvname);
2571 libcfs_nid2str_r(mti->mti_nids[0], nidstr, sizeof(nidstr));
2572 rc = name_create(&nodeuuid, nidstr, "");
2575 rc = name_create(&mdcname, mti->mti_svname, "-mdc");
2578 rc = name_create(&mdcuuid, mdcname, "_UUID");
2581 rc = name_create(&lmvuuid, lmvname, "_UUID");
2585 rc = mgs_modify(env, mgs, fsdb, mti, logname, mti->mti_svname,
2586 "add mdc", CM_SKIP);
2590 rc = record_start_log(env, mgs, &llh, logname);
2593 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
2597 for (i = 0; i < mti->mti_nid_count; i++) {
2598 CDEBUG(D_MGS, "add nid %s for mdt\n",
2599 libcfs_nid2str_r(mti->mti_nids[i],
2600 nidstr, sizeof(nidstr)));
2602 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
2607 rc = record_attach(env, llh, mdcname, LUSTRE_MDC_NAME, lmvuuid);
2610 rc = record_setup(env, llh, mdcname, mti->mti_uuid, nodeuuid,
2614 rc = mgs_write_log_failnids(env, mti, llh, mdcname);
2617 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
2618 rc = record_mdc_add(env, llh, lmvname, mdcuuid, mti->mti_uuid,
2622 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname,
2627 record_end_log(env, &llh);
2629 name_destroy(&lmvuuid);
2630 name_destroy(&mdcuuid);
2631 name_destroy(&mdcname);
2632 name_destroy(&nodeuuid);
2636 static inline int name_create_lov(char **lovname, char *mdtname,
2637 struct fs_db *fsdb, int index)
2640 if (index == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2641 return name_create(lovname, fsdb->fsdb_name, "-mdtlov");
2643 return name_create(lovname, mdtname, "-mdtlov");
2646 static int name_create_mdt_and_lov(char **logname, char **lovname,
2647 struct fs_db *fsdb, int i)
2651 rc = name_create_mdt(logname, fsdb->fsdb_name, i);
2655 if (i == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2656 rc = name_create(lovname, fsdb->fsdb_name, "-mdtlov");
2658 rc = name_create(lovname, *logname, "-mdtlov");
2660 name_destroy(logname);
2666 static inline int name_create_mdt_osc(char **oscname, char *ostname,
2667 struct fs_db *fsdb, int i)
2671 if (i == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2672 sprintf(suffix, "-osc");
2674 sprintf(suffix, "-osc-MDT%04x", i);
2675 return name_create(oscname, ostname, suffix);
2678 /* add new mdc to already existent MDS */
2679 static int mgs_write_log_osp_to_mdt(const struct lu_env *env,
2680 struct mgs_device *mgs,
2682 struct mgs_target_info *mti,
2683 int mdt_index, char *logname)
2685 struct llog_handle *llh = NULL;
2686 char *nodeuuid = NULL;
2687 char *ospname = NULL;
2688 char *lovuuid = NULL;
2689 char *mdtuuid = NULL;
2690 char *svname = NULL;
2691 char *mdtname = NULL;
2692 char *lovname = NULL;
2694 char nidstr[LNET_NIDSTR_SIZE];
2698 if (mgs_log_is_empty(env, mgs, mti->mti_svname)) {
2699 CERROR("log is empty! Logical error\n");
2703 CDEBUG(D_MGS, "adding osp index %d to %s\n", mti->mti_stripe_index,
2706 rc = name_create_mdt(&mdtname, fsdb->fsdb_name, mti->mti_stripe_index);
2710 libcfs_nid2str_r(mti->mti_nids[0], nidstr, sizeof(nidstr));
2711 rc = name_create(&nodeuuid, nidstr, "");
2713 GOTO(out_destory, rc);
2715 rc = name_create(&svname, mdtname, "-osp");
2717 GOTO(out_destory, rc);
2719 sprintf(index_str, "-MDT%04x", mdt_index);
2720 rc = name_create(&ospname, svname, index_str);
2722 GOTO(out_destory, rc);
2724 rc = name_create_lov(&lovname, logname, fsdb, mdt_index);
2726 GOTO(out_destory, rc);
2728 rc = name_create(&lovuuid, lovname, "_UUID");
2730 GOTO(out_destory, rc);
2732 rc = name_create(&mdtuuid, mdtname, "_UUID");
2734 GOTO(out_destory, rc);
2736 rc = mgs_modify(env, mgs, fsdb, mti, logname, mti->mti_svname,
2737 "add osp", CM_SKIP);
2739 GOTO(out_destory, rc);
2741 rc = record_start_log(env, mgs, &llh, logname);
2743 GOTO(out_destory, rc);
2745 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
2748 GOTO(out_destory, rc);
2750 for (i = 0; i < mti->mti_nid_count; i++) {
2751 CDEBUG(D_MGS, "add nid %s for mdt\n",
2752 libcfs_nid2str_r(mti->mti_nids[i],
2753 nidstr, sizeof(nidstr)));
2754 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
2759 rc = record_attach(env, llh, ospname, LUSTRE_OSP_NAME, lovuuid);
2763 rc = record_setup(env, llh, ospname, mti->mti_uuid, nodeuuid,
2768 rc = mgs_write_log_failnids(env, mti, llh, ospname);
2772 /* Add mdc(osp) to lod */
2773 snprintf(index_str, sizeof(index_str), "%d", mti->mti_stripe_index);
2774 rc = record_base(env, llh, lovname, 0, LCFG_ADD_MDC, mti->mti_uuid,
2775 index_str, "1", NULL);
2779 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname, "add osp");
2784 record_end_log(env, &llh);
2787 name_destroy(&mdtuuid);
2788 name_destroy(&lovuuid);
2789 name_destroy(&lovname);
2790 name_destroy(&ospname);
2791 name_destroy(&svname);
2792 name_destroy(&nodeuuid);
2793 name_destroy(&mdtname);
2797 static int mgs_write_log_mdt0(const struct lu_env *env,
2798 struct mgs_device *mgs,
2800 struct mgs_target_info *mti)
2802 char *log = mti->mti_svname;
2803 struct llog_handle *llh = NULL;
2804 struct obd_uuid *uuid;
2807 char *ptr = mti->mti_params;
2808 int rc = 0, failout = 0;
2811 OBD_ALLOC_PTR(uuid);
2815 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
2816 failout = (strncmp(ptr, "failout", 7) == 0);
2818 rc = name_create(&lovname, log, "-mdtlov");
2821 if (mgs_log_is_empty(env, mgs, log)) {
2822 rc = mgs_write_log_lov(env, mgs, fsdb, mti, log, lovname);
2827 sprintf(mdt_index, "%d", mti->mti_stripe_index);
2829 rc = record_start_log(env, mgs, &llh, log);
2833 /* add MDT itself */
2835 /* FIXME this whole fn should be a single journal transaction */
2836 sprintf(uuid->uuid, "%s_UUID", log);
2837 rc = record_marker(env, llh, fsdb, CM_START, log, "add mdt");
2840 rc = record_attach(env, llh, log, LUSTRE_MDT_NAME, uuid->uuid);
2843 rc = record_mount_opt(env, llh, log, lovname, NULL);
2846 rc = record_setup(env, llh, log, uuid->uuid, mdt_index, lovname,
2847 failout ? "n" : "f");
2850 rc = record_marker(env, llh, fsdb, CM_END, log, "add mdt");
2854 record_end_log(env, &llh);
2856 name_destroy(&lovname);
2862 /* envelope method for all layers log */
2863 static int mgs_write_log_mdt(const struct lu_env *env,
2864 struct mgs_device *mgs,
2866 struct mgs_target_info *mti)
2868 struct mgs_thread_info *mgi = mgs_env_info(env);
2869 struct llog_handle *llh = NULL;
2874 CDEBUG(D_MGS, "writing new mdt %s\n", mti->mti_svname);
2876 if (mti->mti_uuid[0] == '\0') {
2877 /* Make up our own uuid */
2878 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
2879 "%s_UUID", mti->mti_svname);
2883 rc = mgs_write_log_mdt0(env, mgs, fsdb, mti);
2886 /* Append the mdt info to the client log */
2887 rc = name_create(&cliname, mti->mti_fsname, "-client");
2891 if (mgs_log_is_empty(env, mgs, cliname)) {
2892 /* Start client log */
2893 rc = mgs_write_log_lov(env, mgs, fsdb, mti, cliname,
2897 rc = mgs_write_log_lmv(env, mgs, fsdb, mti, cliname,
2901 rc = mgs_write_log_mount_opt(env, mgs, fsdb, cliname);
2907 * #09 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
2908 * #10 L attach 0:MDC_uml1_mdsA_MNT_client 1:mdc 2:1d834_MNT_client_03f
2909 * #11 L setup 0:MDC_uml1_mdsA_MNT_client 1:mdsA_UUID 2:uml1_UUID
2910 * #12 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
2911 * #13 L add_conn 0:MDC_uml1_mdsA_MNT_client 1:uml2_UUID
2914 /* copy client info about lov/lmv */
2915 mgi->mgi_comp.comp_mti = mti;
2916 mgi->mgi_comp.comp_fsdb = fsdb;
2918 rc = mgs_steal_llog_for_mdt_from_client(env, mgs, cliname,
2922 rc = mgs_write_log_mdc_to_lmv(env, mgs, fsdb, mti, cliname,
2927 rc = record_start_log(env, mgs, &llh, cliname);
2931 /* for_all_existing_mdt except current one */
2932 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2933 if (i != mti->mti_stripe_index &&
2934 test_bit(i, fsdb->fsdb_mdt_index_map)) {
2937 rc = name_create_mdt(&logname, fsdb->fsdb_name, i);
2941 /* NB: If the log for the MDT is empty, it means
2942 * the MDT is only added to the index
2943 * map, and not being process yet, i.e. this
2944 * is an unregistered MDT, see mgs_write_log_target().
2945 * so we should skip it. Otherwise
2947 * 1. MGS get register request for MDT1 and MDT2.
2949 * 2. Then both MDT1 and MDT2 are added into
2950 * fsdb_mdt_index_map. (see mgs_set_index()).
2952 * 3. Then MDT1 get the lock of fsdb_mutex, then
2953 * generate the config log, here, it will regard MDT2
2954 * as an existent MDT, and generate "add osp" for
2955 * lustre-MDT0001-osp-MDT0002. Note: at the moment
2956 * MDT0002 config log is still empty, so it will
2957 * add "add osp" even before "lov setup", which
2958 * will definitly cause trouble.
2960 * 4. MDT1 registeration finished, fsdb_mutex is
2961 * released, then MDT2 get in, then in above
2962 * mgs_steal_llog_for_mdt_from_client(), it will
2963 * add another osp log for lustre-MDT0001-osp-MDT0002,
2964 * which will cause another trouble.*/
2965 if (!mgs_log_is_empty(env, mgs, logname))
2966 rc = mgs_write_log_osp_to_mdt(env, mgs, fsdb,
2969 name_destroy(&logname);
2975 record_end_log(env, &llh);
2977 name_destroy(&cliname);
2981 /* Add the ost info to the client/mdt lov */
2982 static int mgs_write_log_osc_to_lov(const struct lu_env *env,
2983 struct mgs_device *mgs, struct fs_db *fsdb,
2984 struct mgs_target_info *mti,
2985 char *logname, char *suffix, char *lovname,
2986 enum lustre_sec_part sec_part, int flags)
2988 struct llog_handle *llh = NULL;
2989 char *nodeuuid = NULL;
2990 char *oscname = NULL;
2991 char *oscuuid = NULL;
2992 char *lovuuid = NULL;
2993 char *svname = NULL;
2995 char nidstr[LNET_NIDSTR_SIZE];
2999 CDEBUG(D_INFO, "adding osc for %s to log %s\n",
3000 mti->mti_svname, logname);
3002 if (mgs_log_is_empty(env, mgs, logname)) {
3003 CERROR("log is empty! Logical error\n");
3007 libcfs_nid2str_r(mti->mti_nids[0], nidstr, sizeof(nidstr));
3008 rc = name_create(&nodeuuid, nidstr, "");
3011 rc = name_create(&svname, mti->mti_svname, "-osc");
3015 /* for the system upgraded from old 1.8, keep using the old osc naming
3016 * style for mdt, see name_create_mdt_osc(). LU-1257 */
3017 if (test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
3018 rc = name_create(&oscname, svname, "");
3020 rc = name_create(&oscname, svname, suffix);
3024 rc = name_create(&oscuuid, oscname, "_UUID");
3027 rc = name_create(&lovuuid, lovname, "_UUID");
3032 * #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
3034 * #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
3035 * #04 L attach 0:OSC_uml1_ost1_MNT_client 1:osc 2:89070_lov1_a41dff51a
3036 * #05 L setup 0:OSC_uml1_ost1_MNT_client 1:ost1_UUID 2:uml1_UUID
3038 * #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
3039 * #07 L add_conn 0:OSC_uml1_ost1_MNT_client 1:uml2_UUID
3040 * #08 L lov_modify_tgts add 0:lov1 1:ost1_UUID 2(index):0 3(gen):1
3043 rc = record_start_log(env, mgs, &llh, logname);
3047 /* FIXME these should be a single journal transaction */
3048 rc = record_marker(env, llh, fsdb, CM_START | flags, mti->mti_svname,
3053 /* NB: don't change record order, because upon MDT steal OSC config
3054 * from client, it treats all nids before LCFG_SETUP as target nids
3055 * (multiple interfaces), while nids after as failover node nids.
3056 * See mgs_steal_client_llog_handler() LCFG_ADD_UUID.
3058 for (i = 0; i < mti->mti_nid_count; i++) {
3059 CDEBUG(D_MGS, "add nid %s\n",
3060 libcfs_nid2str_r(mti->mti_nids[i],
3061 nidstr, sizeof(nidstr)));
3062 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
3066 rc = record_attach(env, llh, oscname, LUSTRE_OSC_NAME, lovuuid);
3069 rc = record_setup(env, llh, oscname, mti->mti_uuid, nodeuuid,
3073 rc = mgs_write_log_failnids(env, mti, llh, oscname);
3077 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
3079 rc = record_lov_add(env, llh, lovname, mti->mti_uuid, index, "1");
3082 rc = record_marker(env, llh, fsdb, CM_END | flags, mti->mti_svname,
3087 record_end_log(env, &llh);
3089 name_destroy(&lovuuid);
3090 name_destroy(&oscuuid);
3091 name_destroy(&oscname);
3092 name_destroy(&svname);
3093 name_destroy(&nodeuuid);
3097 static int mgs_write_log_ost(const struct lu_env *env,
3098 struct mgs_device *mgs, struct fs_db *fsdb,
3099 struct mgs_target_info *mti)
3101 struct llog_handle *llh = NULL;
3102 char *logname, *lovname;
3103 char *ptr = mti->mti_params;
3104 int rc, flags = 0, failout = 0, i;
3107 CDEBUG(D_MGS, "writing new ost %s\n", mti->mti_svname);
3109 /* The ost startup log */
3111 /* If the ost log already exists, that means that someone reformatted
3112 * the ost and it called target_add again.
3114 if (!mgs_log_is_empty(env, mgs, mti->mti_svname)) {
3115 LCONSOLE_ERROR_MSG(0x141,
3116 "The config log for %s already exists, yet the server claims it never registered. It may have been reformatted, or the index changed. writeconf the MDT to regenerate all logs.\n",
3122 * attach obdfilter ost1 ost1_UUID
3123 * setup /dev/loop2 ldiskfs f|n errors=remount-ro,user_xattr
3125 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
3126 failout = (strncmp(ptr, "failout", 7) == 0);
3127 rc = record_start_log(env, mgs, &llh, mti->mti_svname);
3130 /* FIXME these should be a single journal transaction */
3131 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,"add ost");
3134 if (*mti->mti_uuid == '\0')
3135 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
3136 "%s_UUID", mti->mti_svname);
3137 rc = record_attach(env, llh, mti->mti_svname,
3138 "obdfilter"/*LUSTRE_OST_NAME*/, mti->mti_uuid);
3141 rc = record_setup(env, llh, mti->mti_svname,
3142 "dev"/*ignored*/, "type"/*ignored*/,
3143 failout ? "n" : "f", NULL/*options*/);
3146 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname, "add ost");
3150 record_end_log(env, &llh);
3153 /* We also have to update the other logs where this osc is part of
3157 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
3158 /* If we're upgrading, the old mdt log already has our
3159 * entry. Let's do a fake one for fun.
3161 /* Note that we can't add any new failnids, since we don't
3162 * know the old osc names.
3164 flags = CM_SKIP | CM_UPGRADE146;
3165 } else if ((mti->mti_flags & LDD_F_UPDATE) != LDD_F_UPDATE) {
3166 /* If the update flag isn't set, don't update client/mdt
3170 LCONSOLE_WARN("Client log for %s was not updated; writeconf the MDT first to regenerate it.\n",
3174 /* Add ost to all MDT lov defs */
3175 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3176 if (test_bit(i, fsdb->fsdb_mdt_index_map)) {
3179 rc = name_create_mdt_and_lov(&logname, &lovname, fsdb,
3184 snprintf(mdt_index, sizeof(mdt_index), "-MDT%04x", i);
3185 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, mti,
3187 lovname, LUSTRE_SP_MDT,
3189 name_destroy(&logname);
3190 name_destroy(&lovname);
3196 /* Append ost info to the client log */
3197 rc = name_create(&logname, mti->mti_fsname, "-client");
3200 if (mgs_log_is_empty(env, mgs, logname)) {
3201 /* Start client log */
3202 rc = mgs_write_log_lov(env, mgs, fsdb, mti, logname,
3206 rc = mgs_write_log_lmv(env, mgs, fsdb, mti, logname,
3210 rc = mgs_write_log_mount_opt(env, mgs, fsdb, logname);
3214 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, mti, logname, "",
3215 fsdb->fsdb_clilov, LUSTRE_SP_CLI, flags);
3217 name_destroy(&logname);
3221 static __inline__ int mgs_param_empty(char *ptr)
3223 char *tmp = strchr(ptr, '=');
3225 if (tmp && tmp[1] == '\0')
3230 static int mgs_write_log_failnid_internal(const struct lu_env *env,
3231 struct mgs_device *mgs,
3233 struct mgs_target_info *mti,
3234 char *logname, char *cliname)
3237 struct llog_handle *llh = NULL;
3239 if (mgs_param_empty(mti->mti_params)) {
3240 /* Remove _all_ failnids */
3241 rc = mgs_modify(env, mgs, fsdb, mti, logname,
3242 mti->mti_svname, "add failnid", CM_SKIP);
3243 return rc < 0 ? rc : 0;
3246 /* Otherwise failover nids are additive */
3247 rc = record_start_log(env, mgs, &llh, logname);
3250 /* FIXME this should be a single journal transaction */
3251 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
3255 rc = mgs_write_log_failnids(env, mti, llh, cliname);
3258 rc = record_marker(env, llh, fsdb, CM_END,
3259 mti->mti_svname, "add failnid");
3261 record_end_log(env, &llh);
3265 /* Add additional failnids to an existing log.
3266 The mdc/osc must have been added to logs first */
3267 /* tcp nids must be in dotted-quad ascii -
3268 we can't resolve hostnames from the kernel. */
3269 static int mgs_write_log_add_failnid(const struct lu_env *env,
3270 struct mgs_device *mgs,
3272 struct mgs_target_info *mti)
3274 char *logname, *cliname;
3278 /* FIXME we currently can't erase the failnids
3279 * given when a target first registers, since they aren't part of
3280 * an "add uuid" stanza
3283 /* Verify that we know about this target */
3284 if (mgs_log_is_empty(env, mgs, mti->mti_svname)) {
3285 LCONSOLE_ERROR_MSG(0x142,
3286 "The target %s has not registered yet. It must be started before failnids can be added.\n",
3291 /* Create mdc/osc client name (e.g. lustre-OST0001-osc) */
3292 if (mti->mti_flags & LDD_F_SV_TYPE_MDT)
3293 rc = name_create(&cliname, mti->mti_svname, "-mdc");
3294 else if (mti->mti_flags & LDD_F_SV_TYPE_OST)
3295 rc = name_create(&cliname, mti->mti_svname, "-osc");
3302 /* Add failover nids to the client log */
3303 rc = name_create(&logname, mti->mti_fsname, "-client");
3305 name_destroy(&cliname);
3309 rc = mgs_write_log_failnid_internal(env, mgs, fsdb,mti,logname,cliname);
3310 name_destroy(&logname);
3311 name_destroy(&cliname);
3315 if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
3316 /* Add OST failover nids to the MDT logs as well */
3319 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3320 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
3322 rc = name_create_mdt(&logname, mti->mti_fsname, i);
3325 rc = name_create_mdt_osc(&cliname, mti->mti_svname,
3328 name_destroy(&logname);
3331 rc = mgs_write_log_failnid_internal(env, mgs, fsdb,
3334 name_destroy(&cliname);
3335 name_destroy(&logname);
3344 static int mgs_wlp_lcfg(const struct lu_env *env,
3345 struct mgs_device *mgs, struct fs_db *fsdb,
3346 struct mgs_target_info *mti,
3347 char *logname, struct lustre_cfg_bufs *bufs,
3348 char *tgtname, char *ptr)
3350 char comment[MTI_NAME_MAXLEN];
3352 struct llog_cfg_rec *lcr;
3355 /* Erase any old settings of this same parameter */
3356 strlcpy(comment, ptr, sizeof(comment));
3357 /* But don't try to match the value. */
3358 tmp = strchr(comment, '=');
3361 /* FIXME we should skip settings that are the same as old values */
3362 rc = mgs_modify(env, mgs, fsdb, mti, logname, tgtname, comment,CM_SKIP);
3365 del = mgs_param_empty(ptr);
3367 LCONSOLE_INFO("%s parameter %s.%s in log %s\n", del ? "Disabling" : rc ?
3368 "Setting" : "Modifying", tgtname, comment, logname);
3370 /* mgs_modify() will return 1 if nothing had to be done */
3376 lustre_cfg_bufs_reset(bufs, tgtname);
3377 lustre_cfg_bufs_set_string(bufs, 1, ptr);
3378 if (mti->mti_flags & LDD_F_PARAM2)
3379 lustre_cfg_bufs_set_string(bufs, 2, LCTL_UPCALL);
3381 lcr = lustre_cfg_rec_new((mti->mti_flags & LDD_F_PARAM2) ?
3382 LCFG_SET_PARAM : LCFG_PARAM, bufs);
3386 rc = mgs_write_log_direct(env, mgs, fsdb, logname, lcr, tgtname,
3388 lustre_cfg_rec_free(lcr);
3392 /* write global variable settings into log */
3393 static int mgs_write_log_sys(const struct lu_env *env,
3394 struct mgs_device *mgs, struct fs_db *fsdb,
3395 struct mgs_target_info *mti, char *sys, char *ptr)
3397 struct mgs_thread_info *mgi = mgs_env_info(env);
3398 struct lustre_cfg *lcfg;
3399 struct llog_cfg_rec *lcr;
3401 int rc, cmd, convert = 1;
3403 if (class_match_param(ptr, PARAM_TIMEOUT, &tmp) == 0) {
3404 cmd = LCFG_SET_TIMEOUT;
3405 } else if (class_match_param(ptr, PARAM_LDLM_TIMEOUT, &tmp) == 0) {
3406 cmd = LCFG_SET_LDLM_TIMEOUT;
3407 /* Check for known params here so we can return error to lctl */
3408 } else if ((class_match_param(ptr, PARAM_AT_MIN, &tmp) == 0) ||
3409 (class_match_param(ptr, PARAM_AT_MAX, &tmp) == 0) ||
3410 (class_match_param(ptr, PARAM_AT_EXTRA, &tmp) == 0) ||
3411 (class_match_param(ptr, PARAM_AT_EARLY_MARGIN, &tmp) == 0) ||
3412 (class_match_param(ptr, PARAM_AT_HISTORY, &tmp) == 0)) {
3414 } else if (class_match_param(ptr, PARAM_JOBID_VAR, &tmp) == 0) {
3415 convert = 0; /* Don't convert string value to integer */
3421 if (mgs_param_empty(ptr))
3422 CDEBUG(D_MGS, "global '%s' removed\n", sys);
3424 CDEBUG(D_MGS, "global '%s' val=%s\n", sys, tmp);
3426 lustre_cfg_bufs_reset(&mgi->mgi_bufs, NULL);
3427 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, sys);
3428 if (!convert && *tmp != '\0')
3429 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 2, tmp);
3430 lcr = lustre_cfg_rec_new(cmd, &mgi->mgi_bufs);
3434 lcfg = &lcr->lcr_cfg;
3436 rc = kstrtouint(tmp, 0, &lcfg->lcfg_num);
3438 GOTO(out_rec_free, rc);
3443 /* truncate the comment to the parameter name */
3447 /* modify all servers and clients */
3448 rc = mgs_write_log_direct_all(env, mgs, fsdb, mti,
3449 *tmp == '\0' ? NULL : lcr,
3450 mti->mti_fsname, sys, 0);
3451 if (rc == 0 && *tmp != '\0') {
3453 case LCFG_SET_TIMEOUT:
3454 if (!obd_timeout_set || lcfg->lcfg_num > obd_timeout)
3455 class_process_config(lcfg);
3457 case LCFG_SET_LDLM_TIMEOUT:
3458 if (!ldlm_timeout_set || lcfg->lcfg_num > ldlm_timeout)
3459 class_process_config(lcfg);
3467 lustre_cfg_rec_free(lcr);
3471 /* write quota settings into log */
3472 static int mgs_write_log_quota(const struct lu_env *env, struct mgs_device *mgs,
3473 struct fs_db *fsdb, struct mgs_target_info *mti,
3474 char *quota, char *ptr)
3476 struct mgs_thread_info *mgi = mgs_env_info(env);
3477 struct llog_cfg_rec *lcr;
3480 int rc, cmd = LCFG_PARAM;
3482 /* support only 'meta' and 'data' pools so far */
3483 if (class_match_param(ptr, QUOTA_METAPOOL_NAME, &tmp) != 0 &&
3484 class_match_param(ptr, QUOTA_DATAPOOL_NAME, &tmp) != 0) {
3485 CERROR("parameter quota.%s isn't supported (only quota.mdt "
3486 "& quota.ost are)\n", ptr);
3491 CDEBUG(D_MGS, "global '%s' removed\n", quota);
3493 CDEBUG(D_MGS, "global '%s'\n", quota);
3495 if (strchr(tmp, 'u') == NULL && strchr(tmp, 'g') == NULL &&
3496 strchr(tmp, 'p') == NULL &&
3497 strcmp(tmp, "none") != 0) {
3498 CERROR("enable option(%s) isn't supported\n", tmp);
3503 lustre_cfg_bufs_reset(&mgi->mgi_bufs, mti->mti_fsname);
3504 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, quota);
3505 lcr = lustre_cfg_rec_new(cmd, &mgi->mgi_bufs);
3509 /* truncate the comment to the parameter name */
3514 /* XXX we duplicated quota enable information in all server
3515 * config logs, it should be moved to a separate config
3516 * log once we cleanup the config log for global param. */
3517 /* modify all servers */
3518 rc = mgs_write_log_direct_all(env, mgs, fsdb, mti,
3519 *tmp == '\0' ? NULL : lcr,
3520 mti->mti_fsname, quota, 1);
3522 lustre_cfg_rec_free(lcr);
3523 return rc < 0 ? rc : 0;
3526 static int mgs_srpc_set_param_disk(const struct lu_env *env,
3527 struct mgs_device *mgs,
3529 struct mgs_target_info *mti,
3532 struct mgs_thread_info *mgi = mgs_env_info(env);
3533 struct llog_cfg_rec *lcr;
3534 struct llog_handle *llh = NULL;
3536 char *comment, *ptr;
3542 ptr = strchr(param, '=');
3543 LASSERT(ptr != NULL);
3546 OBD_ALLOC(comment, len + 1);
3547 if (comment == NULL)
3549 strncpy(comment, param, len);
3550 comment[len] = '\0';
3553 lustre_cfg_bufs_reset(&mgi->mgi_bufs, mti->mti_svname);
3554 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, param);
3555 lcr = lustre_cfg_rec_new(LCFG_SPTLRPC_CONF, &mgi->mgi_bufs);
3557 GOTO(out_comment, rc = -ENOMEM);
3559 /* construct log name */
3560 rc = name_create(&logname, mti->mti_fsname, "-sptlrpc");
3564 if (mgs_log_is_empty(env, mgs, logname)) {
3565 rc = record_start_log(env, mgs, &llh, logname);
3568 record_end_log(env, &llh);
3571 /* obsolete old one */
3572 rc = mgs_modify(env, mgs, fsdb, mti, logname, mti->mti_svname,
3576 /* write the new one */
3577 rc = mgs_write_log_direct(env, mgs, fsdb, logname, lcr,
3578 mti->mti_svname, comment);
3580 CERROR("%s: error writing log %s: rc = %d\n",
3581 mgs->mgs_obd->obd_name, logname, rc);
3583 name_destroy(&logname);
3585 lustre_cfg_rec_free(lcr);
3587 OBD_FREE(comment, len + 1);
3591 static int mgs_srpc_set_param_udesc_mem(struct fs_db *fsdb,
3596 /* disable the adjustable udesc parameter for now, i.e. use default
3597 * setting that client always ship udesc to MDT if possible. to enable
3598 * it simply remove the following line
3602 ptr = strchr(param, '=');
3607 if (strcmp(param, PARAM_SRPC_UDESC))
3610 if (strcmp(ptr, "yes") == 0) {
3611 set_bit(FSDB_UDESC, &fsdb->fsdb_flags);
3612 CWARN("Enable user descriptor shipping from client to MDT\n");
3613 } else if (strcmp(ptr, "no") == 0) {
3614 clear_bit(FSDB_UDESC, &fsdb->fsdb_flags);
3615 CWARN("Disable user descriptor shipping from client to MDT\n");
3623 CERROR("Invalid param: %s\n", param);
3627 static int mgs_srpc_set_param_mem(struct fs_db *fsdb,
3631 struct sptlrpc_rule rule;
3632 struct sptlrpc_rule_set *rset;
3636 if (strncmp(param, PARAM_SRPC, sizeof(PARAM_SRPC) - 1) != 0) {
3637 CERROR("Invalid sptlrpc parameter: %s\n", param);
3641 if (strncmp(param, PARAM_SRPC_UDESC,
3642 sizeof(PARAM_SRPC_UDESC) - 1) == 0) {
3643 RETURN(mgs_srpc_set_param_udesc_mem(fsdb, param));
3646 if (strncmp(param, PARAM_SRPC_FLVR, sizeof(PARAM_SRPC_FLVR) - 1) != 0) {
3647 CERROR("Invalid sptlrpc flavor parameter: %s\n", param);
3651 param += sizeof(PARAM_SRPC_FLVR) - 1;
3653 rc = sptlrpc_parse_rule(param, &rule);
3657 /* mgs rules implies must be mgc->mgs */
3658 if (test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
3659 if ((rule.sr_from != LUSTRE_SP_MGC &&
3660 rule.sr_from != LUSTRE_SP_ANY) ||
3661 (rule.sr_to != LUSTRE_SP_MGS &&
3662 rule.sr_to != LUSTRE_SP_ANY))
3666 /* preapre room for this coming rule. svcname format should be:
3667 * - fsname: general rule
3668 * - fsname-tgtname: target-specific rule
3670 if (strchr(svname, '-')) {
3671 struct mgs_tgt_srpc_conf *tgtconf;
3674 for (tgtconf = fsdb->fsdb_srpc_tgt; tgtconf != NULL;
3675 tgtconf = tgtconf->mtsc_next) {
3676 if (!strcmp(tgtconf->mtsc_tgt, svname)) {
3685 OBD_ALLOC_PTR(tgtconf);
3686 if (tgtconf == NULL)
3689 name_len = strlen(svname);
3691 OBD_ALLOC(tgtconf->mtsc_tgt, name_len + 1);
3692 if (tgtconf->mtsc_tgt == NULL) {
3693 OBD_FREE_PTR(tgtconf);
3696 memcpy(tgtconf->mtsc_tgt, svname, name_len);
3698 tgtconf->mtsc_next = fsdb->fsdb_srpc_tgt;
3699 fsdb->fsdb_srpc_tgt = tgtconf;
3702 rset = &tgtconf->mtsc_rset;
3703 } else if (strcmp(svname, MGSSELF_NAME) == 0) {
3704 /* put _mgs related srpc rule directly in mgs ruleset */
3705 rset = &fsdb->fsdb_mgs->mgs_lut.lut_sptlrpc_rset;
3707 rset = &fsdb->fsdb_srpc_gen;
3710 rc = sptlrpc_rule_set_merge(rset, &rule);
3715 static int mgs_srpc_set_param(const struct lu_env *env,
3716 struct mgs_device *mgs,
3718 struct mgs_target_info *mti,
3728 /* keep a copy of original param, which could be destroied
3731 copy_size = strlen(param) + 1;
3732 OBD_ALLOC(copy, copy_size);
3735 memcpy(copy, param, copy_size);
3737 rc = mgs_srpc_set_param_mem(fsdb, mti->mti_svname, param);
3741 /* previous steps guaranteed the syntax is correct */
3742 rc = mgs_srpc_set_param_disk(env, mgs, fsdb, mti, copy);
3746 if (test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
3748 * for mgs rules, make them effective immediately.
3750 LASSERT(fsdb->fsdb_srpc_tgt == NULL);
3751 sptlrpc_target_update_exp_flavor(mgs->mgs_obd,
3752 &fsdb->fsdb_srpc_gen);
3756 OBD_FREE(copy, copy_size);
3760 struct mgs_srpc_read_data {
3761 struct fs_db *msrd_fsdb;
3765 static int mgs_srpc_read_handler(const struct lu_env *env,
3766 struct llog_handle *llh,
3767 struct llog_rec_hdr *rec, void *data)
3769 struct mgs_srpc_read_data *msrd = data;
3770 struct cfg_marker *marker;
3771 struct lustre_cfg *lcfg = REC_DATA(rec);
3772 char *svname, *param;
3776 if (rec->lrh_type != OBD_CFG_REC) {
3777 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
3781 cfg_len = REC_DATA_LEN(rec);
3783 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
3785 CERROR("Insane cfg\n");
3789 if (lcfg->lcfg_command == LCFG_MARKER) {
3790 marker = lustre_cfg_buf(lcfg, 1);
3792 if (marker->cm_flags & CM_START &&
3793 marker->cm_flags & CM_SKIP)
3794 msrd->msrd_skip = 1;
3795 if (marker->cm_flags & CM_END)
3796 msrd->msrd_skip = 0;
3801 if (msrd->msrd_skip)
3804 if (lcfg->lcfg_command != LCFG_SPTLRPC_CONF) {
3805 CERROR("invalid command (%x)\n", lcfg->lcfg_command);
3809 svname = lustre_cfg_string(lcfg, 0);
3810 if (svname == NULL) {
3811 CERROR("svname is empty\n");
3815 param = lustre_cfg_string(lcfg, 1);
3816 if (param == NULL) {
3817 CERROR("param is empty\n");
3821 rc = mgs_srpc_set_param_mem(msrd->msrd_fsdb, svname, param);
3823 CERROR("read sptlrpc record error (%d): %s\n", rc, param);
3828 int mgs_get_fsdb_srpc_from_llog(const struct lu_env *env,
3829 struct mgs_device *mgs,
3832 struct llog_handle *llh = NULL;
3833 struct llog_ctxt *ctxt;
3835 struct mgs_srpc_read_data msrd;
3839 /* construct log name */
3840 rc = name_create(&logname, fsdb->fsdb_name, "-sptlrpc");
3844 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
3845 LASSERT(ctxt != NULL);
3847 if (mgs_log_is_empty(env, mgs, logname))
3850 rc = llog_open(env, ctxt, &llh, NULL, logname,
3858 rc = llog_init_handle(env, llh, LLOG_F_IS_PLAIN, NULL);
3860 GOTO(out_close, rc);
3862 if (llog_get_size(llh) <= 1)
3863 GOTO(out_close, rc = 0);
3865 msrd.msrd_fsdb = fsdb;
3868 rc = llog_process(env, llh, mgs_srpc_read_handler, (void *)&msrd,
3872 llog_close(env, llh);
3874 llog_ctxt_put(ctxt);
3875 name_destroy(&logname);
3878 CERROR("failed to read sptlrpc config database: %d\n", rc);
3882 static int mgs_write_log_param2(const struct lu_env *env,
3883 struct mgs_device *mgs,
3885 struct mgs_target_info *mti, char *ptr)
3887 struct lustre_cfg_bufs bufs;
3891 CDEBUG(D_MGS, "next param '%s'\n", ptr);
3893 /* PARAM_MGSNODE and PARAM_NETWORK are set only when formating
3894 * or during the inital mount. It can never change after that.
3896 if (!class_match_param(ptr, PARAM_MGSNODE, NULL) ||
3897 !class_match_param(ptr, PARAM_NETWORK, NULL)) {
3902 /* Processed in mgs_write_log_ost. Another value that can't
3903 * be changed by lctl set_param -P.
3905 if (!class_match_param(ptr, PARAM_FAILMODE, NULL)) {
3906 LCONSOLE_ERROR_MSG(0x169,
3907 "%s can only be changed with tunefs.lustre and --writeconf\n",
3913 /* FIXME !!! Support for sptlrpc is incomplete. Currently the change
3914 * doesn't transmit to the client. See LU-7183.
3916 if (!class_match_param(ptr, PARAM_SRPC, NULL)) {
3917 rc = mgs_srpc_set_param(env, mgs, fsdb, mti, ptr);
3921 /* Can't use class_match_param since ptr doesn't start with
3922 * PARAM_FAILNODE. So we look for PARAM_FAILNODE contained in ptr.
3924 if (strstr(ptr, PARAM_FAILNODE)) {
3925 /* Add a failover nidlist. We already processed failovers
3926 * params for new targets in mgs_write_log_target.
3930 /* can't use wildcards with failover.node */
3931 if (strchr(ptr, '*')) {
3936 param = strstr(ptr, PARAM_FAILNODE);
3937 if (strlcpy(mti->mti_params, param, sizeof(mti->mti_params)) >=
3938 sizeof(mti->mti_params)) {
3943 CDEBUG(D_MGS, "Adding failnode with param %s\n",
3945 rc = mgs_write_log_add_failnid(env, mgs, fsdb, mti);
3949 /* root squash parameters must not be set on llite subsystem, this can
3950 * lead to inconsistencies between client and server values
3952 if ((strstr(ptr, PARAM_NOSQUASHNIDS) ||
3953 strstr(ptr, PARAM_ROOTSQUASH)) &&
3954 strncmp(ptr, "llite.", strlen("llite.")) == 0) {
3956 CWARN("%s: cannot add %s param to llite subsystem, use mdt instead: rc=%d\n",
3957 mgs->mgs_obd->obd_name,
3958 strstr(ptr, PARAM_ROOTSQUASH) ?
3959 PARAM_ROOTSQUASH : PARAM_NOSQUASHNIDS,
3964 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, PARAMS_FILENAME, &bufs,
3965 mti->mti_svname, ptr);
3970 /* Permanent settings of all parameters by writing into the appropriate
3971 * configuration logs.
3972 * A parameter with null value ("<param>='\0'") means to erase it out of
3975 static int mgs_write_log_param(const struct lu_env *env,
3976 struct mgs_device *mgs, struct fs_db *fsdb,
3977 struct mgs_target_info *mti, char *ptr)
3979 struct mgs_thread_info *mgi = mgs_env_info(env);
3985 /* For various parameter settings, we have to figure out which logs
3986 * care about them (e.g. both mdt and client for lov settings)
3988 CDEBUG(D_MGS, "next param '%s'\n", ptr);
3990 /* The params are stored in MOUNT_DATA_FILE and modified via
3991 * tunefs.lustre, or set using lctl conf_param
3994 /* Processed in lustre_start_mgc */
3995 if (class_match_param(ptr, PARAM_MGSNODE, NULL) == 0)
3998 /* Processed in ost/mdt */
3999 if (class_match_param(ptr, PARAM_NETWORK, NULL) == 0)
4002 /* Processed in mgs_write_log_ost */
4003 if (class_match_param(ptr, PARAM_FAILMODE, NULL) == 0) {
4004 if (mti->mti_flags & LDD_F_PARAM) {
4005 LCONSOLE_ERROR_MSG(0x169,
4006 "%s can only be changed with tunefs.lustre and --writeconf\n",
4013 if (class_match_param(ptr, PARAM_SRPC, NULL) == 0) {
4014 rc = mgs_srpc_set_param(env, mgs, fsdb, mti, ptr);
4018 if (class_match_param(ptr, PARAM_FAILNODE, NULL) == 0) {
4019 /* Add a failover nidlist */
4021 /* We already processed failovers params for new
4022 * targets in mgs_write_log_target
4024 if (mti->mti_flags & LDD_F_PARAM) {
4025 CDEBUG(D_MGS, "Adding failnode\n");
4026 rc = mgs_write_log_add_failnid(env, mgs, fsdb, mti);
4031 if (class_match_param(ptr, PARAM_SYS, &tmp) == 0) {
4032 rc = mgs_write_log_sys(env, mgs, fsdb, mti, ptr, tmp);
4036 if (class_match_param(ptr, PARAM_QUOTA, &tmp) == 0) {
4037 rc = mgs_write_log_quota(env, mgs, fsdb, mti, ptr, tmp);
4041 if (class_match_param(ptr, PARAM_OSC PARAM_ACTIVE, &tmp) == 0 ||
4042 class_match_param(ptr, PARAM_MDC PARAM_ACTIVE, &tmp) == 0) {
4043 /* active=0 means off, anything else means on */
4044 int flag = (*tmp == '0') ? CM_EXCLUDE : 0;
4045 bool deactive_osc = memcmp(ptr, PARAM_OSC PARAM_ACTIVE,
4046 strlen(PARAM_OSC PARAM_ACTIVE)) == 0;
4049 if (!deactive_osc) {
4052 rc = server_name2index(mti->mti_svname, &index, NULL);
4057 LCONSOLE_ERROR_MSG(0x144, "%s: MDC0 can not be"
4058 " (de)activated.\n",
4060 GOTO(end, rc = -EPERM);
4064 LCONSOLE_WARN("Permanently %sactivating %s\n",
4065 flag ? "de" : "re", mti->mti_svname);
4067 rc = name_create(&logname, mti->mti_fsname, "-client");
4070 rc = mgs_modify(env, mgs, fsdb, mti, logname,
4072 deactive_osc ? "add osc" : "add mdc", flag);
4073 name_destroy(&logname);
4078 /* Add to all MDT logs for DNE */
4079 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
4080 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
4082 rc = name_create_mdt(&logname, mti->mti_fsname, i);
4085 rc = mgs_modify(env, mgs, fsdb, mti, logname,
4087 deactive_osc ? "add osc" : "add osp",
4089 name_destroy(&logname);
4095 LCONSOLE_ERROR_MSG(0x145,
4096 "Couldn't find %s in log (%d). No permanent changes were made to the config log.\n",
4097 mti->mti_svname, rc);
4098 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags))
4099 LCONSOLE_ERROR_MSG(0x146,
4100 "This may be because the log is in the old 1.4 style. Consider --writeconf to update the logs.\n");
4103 /* Fall through to osc/mdc proc for deactivating live
4104 * OSC/OSP on running MDT / clients.
4107 /* Below here, let obd's XXX_process_config methods handle it */
4109 /* All lov. in proc */
4110 if (class_match_param(ptr, PARAM_LOV, NULL) == 0) {
4113 CDEBUG(D_MGS, "lov param %s\n", ptr);
4114 if (!(mti->mti_flags & LDD_F_SV_TYPE_MDT)) {
4115 LCONSOLE_ERROR_MSG(0x147,
4116 "LOV params must be set on the MDT, not %s. Ignoring.\n",
4122 if (mgs_log_is_empty(env, mgs, mti->mti_svname))
4123 GOTO(end, rc = -ENODEV);
4125 rc = name_create_mdt_and_lov(&logname, &mdtlovname, fsdb,
4126 mti->mti_stripe_index);
4129 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, mti->mti_svname,
4130 &mgi->mgi_bufs, mdtlovname, ptr);
4131 name_destroy(&logname);
4132 name_destroy(&mdtlovname);
4137 rc = name_create(&logname, mti->mti_fsname, "-client");
4140 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname, &mgi->mgi_bufs,
4141 fsdb->fsdb_clilov, ptr);
4142 name_destroy(&logname);
4146 /* All osc., mdc., llite. params in proc */
4147 if ((class_match_param(ptr, PARAM_OSC, NULL) == 0) ||
4148 (class_match_param(ptr, PARAM_MDC, NULL) == 0) ||
4149 (class_match_param(ptr, PARAM_LLITE, NULL) == 0)) {
4152 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
4153 LCONSOLE_ERROR_MSG(0x148, "Upgraded client logs for %s"
4154 " cannot be modified. Consider"
4155 " updating the configuration with"
4158 GOTO(end, rc = -EINVAL);
4160 if (memcmp(ptr, PARAM_LLITE, strlen(PARAM_LLITE)) == 0) {
4161 rc = name_create(&cname, mti->mti_fsname, "-client");
4162 /* Add the client type to match the obdname in
4163 * class_config_llog_handler
4165 } else if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
4166 rc = name_create(&cname, mti->mti_svname, "-mdc");
4167 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
4168 rc = name_create(&cname, mti->mti_svname, "-osc");
4170 GOTO(end, rc = -EINVAL);
4175 /* Forbid direct update of llite root squash parameters.
4176 * These parameters are indirectly set via the MDT settings.
4178 if ((class_match_param(ptr, PARAM_LLITE, &tmp) == 0) &&
4179 ((memcmp(tmp, "root_squash=", 12) == 0) ||
4180 (memcmp(tmp, "nosquash_nids=", 14) == 0))) {
4181 LCONSOLE_ERROR("%s: root squash parameters can only "
4182 "be updated through MDT component\n",
4184 name_destroy(&cname);
4185 GOTO(end, rc = -EINVAL);
4188 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
4191 rc = name_create(&logname, mti->mti_fsname, "-client");
4193 name_destroy(&cname);
4196 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname, &mgi->mgi_bufs,
4199 /* osc params affect the MDT as well */
4200 if (!rc && (mti->mti_flags & LDD_F_SV_TYPE_OST)) {
4203 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
4204 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
4206 name_destroy(&cname);
4207 rc = name_create_mdt_osc(&cname, mti->mti_svname,
4209 name_destroy(&logname);
4212 rc = name_create_mdt(&logname,
4213 mti->mti_fsname, i);
4216 if (!mgs_log_is_empty(env, mgs, logname)) {
4217 rc = mgs_wlp_lcfg(env, mgs, fsdb,
4227 /* For mdc activate/deactivate, it affects OSP on MDT as well */
4228 if (class_match_param(ptr, PARAM_MDC PARAM_ACTIVE, &tmp) == 0 &&
4231 char *lodname = NULL;
4232 char *param_str = NULL;
4236 /* replace mdc with osp */
4237 memcpy(ptr, PARAM_OSP, strlen(PARAM_OSP));
4238 rc = server_name2index(mti->mti_svname, &index, NULL);
4240 memcpy(ptr, PARAM_MDC, strlen(PARAM_MDC));
4244 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
4245 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
4251 name_destroy(&logname);
4252 rc = name_create_mdt(&logname, mti->mti_fsname,
4257 if (mgs_log_is_empty(env, mgs, logname))
4260 snprintf(suffix, sizeof(suffix), "-osp-MDT%04x",
4262 name_destroy(&cname);
4263 rc = name_create(&cname, mti->mti_svname,
4268 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname,
4269 &mgi->mgi_bufs, cname, ptr);
4273 /* Add configuration log for noitfying LOD
4274 * to active/deactive the OSP. */
4275 name_destroy(¶m_str);
4276 rc = name_create(¶m_str, cname,
4277 (*tmp == '0') ? ".active=0" :
4282 name_destroy(&lodname);
4283 rc = name_create(&lodname, logname, "-mdtlov");
4287 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname,
4288 &mgi->mgi_bufs, lodname,
4293 memcpy(ptr, PARAM_MDC, strlen(PARAM_MDC));
4294 name_destroy(&lodname);
4295 name_destroy(¶m_str);
4298 name_destroy(&logname);
4299 name_destroy(&cname);
4303 /* All mdt. params in proc */
4304 if (class_match_param(ptr, PARAM_MDT, &tmp) == 0) {
4308 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
4309 if (strncmp(mti->mti_svname, mti->mti_fsname,
4310 MTI_NAME_MAXLEN) == 0)
4311 /* device is unspecified completely? */
4312 rc = LDD_F_SV_TYPE_MDT | LDD_F_SV_ALL;
4314 rc = server_name2index(mti->mti_svname, &idx, NULL);
4317 if ((rc & LDD_F_SV_TYPE_MDT) == 0)
4319 if (rc & LDD_F_SV_ALL) {
4320 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
4322 fsdb->fsdb_mdt_index_map))
4324 rc = name_create_mdt(&logname,
4325 mti->mti_fsname, i);
4328 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti,
4329 logname, &mgi->mgi_bufs,
4331 name_destroy(&logname);
4336 if ((memcmp(tmp, "root_squash=", 12) == 0) ||
4337 (memcmp(tmp, "nosquash_nids=", 14) == 0)) {
4338 LCONSOLE_ERROR("%s: root squash parameters "
4339 "cannot be applied to a single MDT\n",
4341 GOTO(end, rc = -EINVAL);
4343 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti,
4344 mti->mti_svname, &mgi->mgi_bufs,
4345 mti->mti_svname, ptr);
4350 /* root squash settings are also applied to llite
4351 * config log (see LU-1778) */
4353 ((memcmp(tmp, "root_squash=", 12) == 0) ||
4354 (memcmp(tmp, "nosquash_nids=", 14) == 0))) {
4358 rc = name_create(&cname, mti->mti_fsname, "-client");
4361 rc = name_create(&logname, mti->mti_fsname, "-client");
4363 name_destroy(&cname);
4366 rc = name_create(&ptr2, PARAM_LLITE, tmp);
4368 name_destroy(&cname);
4369 name_destroy(&logname);
4372 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname,
4373 &mgi->mgi_bufs, cname, ptr2);
4374 name_destroy(&ptr2);
4375 name_destroy(&logname);
4376 name_destroy(&cname);
4381 /* All mdd., ost. and osd. params in proc */
4382 if ((class_match_param(ptr, PARAM_MDD, NULL) == 0) ||
4383 (class_match_param(ptr, PARAM_LOD, NULL) == 0) ||
4384 (class_match_param(ptr, PARAM_OST, NULL) == 0) ||
4385 (class_match_param(ptr, PARAM_OSD, NULL) == 0)) {
4386 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
4387 if (mgs_log_is_empty(env, mgs, mti->mti_svname))
4388 GOTO(end, rc = -ENODEV);
4390 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, mti->mti_svname,
4391 &mgi->mgi_bufs, mti->mti_svname, ptr);
4395 /* For handling degraded zfs OST */
4396 if (class_match_param(ptr, PARAM_AUTODEGRADE, NULL) == 0)
4399 LCONSOLE_WARN("Ignoring unrecognized param '%s'\n", ptr);
4403 CERROR("err %d on param '%s'\n", rc, ptr);
4408 int mgs_write_log_target(const struct lu_env *env, struct mgs_device *mgs,
4409 struct mgs_target_info *mti, struct fs_db *fsdb)
4416 /* set/check the new target index */
4417 rc = mgs_set_index(env, mgs, mti);
4421 if (rc == EALREADY) {
4422 LCONSOLE_WARN("Found index %d for %s, updating log\n",
4423 mti->mti_stripe_index, mti->mti_svname);
4424 /* We would like to mark old log sections as invalid
4425 and add new log sections in the client and mdt logs.
4426 But if we add new sections, then live clients will
4427 get repeat setup instructions for already running
4428 osc's. So don't update the client/mdt logs. */
4429 mti->mti_flags &= ~LDD_F_UPDATE;
4433 OBD_FAIL_TIMEOUT(OBD_FAIL_MGS_WRITE_TARGET_DELAY, cfs_fail_val > 0 ?
4436 mutex_lock(&fsdb->fsdb_mutex);
4438 if (mti->mti_flags & (LDD_F_VIRGIN | LDD_F_WRITECONF)) {
4439 /* Generate a log from scratch */
4440 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
4441 rc = mgs_write_log_mdt(env, mgs, fsdb, mti);
4442 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
4443 rc = mgs_write_log_ost(env, mgs, fsdb, mti);
4445 CERROR("Unknown target type %#x, can't create log for %s\n",
4446 mti->mti_flags, mti->mti_svname);
4449 CERROR("Can't write logs for %s (%d)\n",
4450 mti->mti_svname, rc);
4454 /* Just update the params from tunefs in mgs_write_log_params */
4455 CDEBUG(D_MGS, "Update params for %s\n", mti->mti_svname);
4456 mti->mti_flags |= LDD_F_PARAM;
4459 /* allocate temporary buffer, where class_get_next_param will
4460 * make copy of a current parameter
4462 OBD_ALLOC(buf, strlen(mti->mti_params) + 1);
4464 GOTO(out_up, rc = -ENOMEM);
4465 params = mti->mti_params;
4466 while (params != NULL) {
4467 rc = class_get_next_param(¶ms, buf);
4470 /* there is no next parameter, that is
4476 CDEBUG(D_MGS, "remaining string: '%s', param: '%s'\n",
4478 rc = mgs_write_log_param(env, mgs, fsdb, mti, buf);
4483 OBD_FREE(buf, strlen(mti->mti_params) + 1);
4486 mutex_unlock(&fsdb->fsdb_mutex);
4490 int mgs_erase_log(const struct lu_env *env, struct mgs_device *mgs, char *name)
4492 struct llog_ctxt *ctxt;
4495 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
4497 CERROR("%s: MGS config context doesn't exist\n",
4498 mgs->mgs_obd->obd_name);
4501 rc = llog_erase(env, ctxt, NULL, name);
4502 /* llog may not exist */
4505 llog_ctxt_put(ctxt);
4509 CERROR("%s: failed to clear log %s: %d\n",
4510 mgs->mgs_obd->obd_name, name, rc);
4515 /* erase all logs for the given fs */
4516 int mgs_erase_logs(const struct lu_env *env, struct mgs_device *mgs,
4519 struct list_head log_list;
4520 struct mgs_direntry *dirent, *n;
4521 char barrier_name[20] = {};
4524 int rc, len = strlen(fsname);
4527 mutex_lock(&mgs->mgs_mutex);
4529 /* Find all the logs in the CONFIGS directory */
4530 rc = class_dentry_readdir(env, mgs, &log_list);
4532 mutex_unlock(&mgs->mgs_mutex);
4536 if (list_empty(&log_list)) {
4537 mutex_unlock(&mgs->mgs_mutex);
4541 snprintf(barrier_name, sizeof(barrier_name) - 1, "%s-%s",
4542 fsname, BARRIER_FILENAME);
4543 /* Delete the barrier fsdb */
4544 mgs_remove_fsdb_by_name(mgs, barrier_name);
4545 /* Delete the fs db */
4546 mgs_remove_fsdb_by_name(mgs, fsname);
4547 mutex_unlock(&mgs->mgs_mutex);
4549 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
4550 list_del_init(&dirent->mde_list);
4551 suffix = strrchr(dirent->mde_name, '-');
4552 if (suffix != NULL) {
4553 if ((len == suffix - dirent->mde_name) &&
4554 (strncmp(fsname, dirent->mde_name, len) == 0)) {
4555 CDEBUG(D_MGS, "Removing log %s\n",
4557 mgs_erase_log(env, mgs, dirent->mde_name);
4561 mgs_direntry_free(dirent);
4570 /* list all logs for the given fs */
4571 int mgs_list_logs(const struct lu_env *env, struct mgs_device *mgs,
4572 struct obd_ioctl_data *data)
4574 struct list_head log_list;
4575 struct mgs_direntry *dirent, *n;
4576 char *out, *suffix, prefix[] = "config_log: ";
4577 int prefix_len = strlen(prefix);
4578 int len, remains, start = 0, rc;
4582 /* Find all the logs in the CONFIGS directory */
4583 rc = class_dentry_readdir(env, mgs, &log_list);
4587 out = data->ioc_bulk;
4588 remains = data->ioc_inllen1;
4589 /* OBD_FAIL: fetch the config_log records from the specified one */
4590 if (OBD_FAIL_CHECK(OBD_FAIL_CATLIST))
4591 data->ioc_count = cfs_fail_val;
4593 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
4594 list_del_init(&dirent->mde_list);
4595 suffix = strrchr(dirent->mde_name, '-');
4596 if (suffix != NULL) {
4597 len = prefix_len + dirent->mde_len + 1;
4598 if (remains - len < 0) {
4599 /* No enough space for this record */
4600 mgs_direntry_free(dirent);
4604 if (start < data->ioc_count) {
4605 mgs_direntry_free(dirent);
4608 len = scnprintf(out, remains, "%s%s\n", prefix,
4613 mgs_direntry_free(dirent);
4621 data->ioc_count = start;
4625 struct mgs_lcfg_fork_data {
4626 struct lustre_cfg_bufs mlfd_bufs;
4627 struct mgs_device *mlfd_mgs;
4628 struct llog_handle *mlfd_llh;
4629 const char *mlfd_oldname;
4630 const char *mlfd_newname;
4634 static bool contain_valid_fsname(char *buf, const char *fsname,
4635 int buflen, int namelen)
4637 if (buflen < namelen)
4640 if (memcmp(buf, fsname, namelen) != 0)
4643 if (buf[namelen] != '\0' && buf[namelen] != '-')
4649 static int mgs_lcfg_fork_handler(const struct lu_env *env,
4650 struct llog_handle *o_llh,
4651 struct llog_rec_hdr *o_rec, void *data)
4653 struct mgs_lcfg_fork_data *mlfd = data;
4654 struct lustre_cfg_bufs *n_bufs = &mlfd->mlfd_bufs;
4655 struct lustre_cfg *o_lcfg = (struct lustre_cfg *)(o_rec + 1);
4656 struct llog_cfg_rec *lcr;
4658 char *n_buf = mlfd->mlfd_data;
4660 int o_namelen = strlen(mlfd->mlfd_oldname);
4661 int n_namelen = strlen(mlfd->mlfd_newname);
4662 int diff = n_namelen - o_namelen;
4663 __u32 cmd = o_lcfg->lcfg_command;
4664 __u32 cnt = o_lcfg->lcfg_bufcount;
4670 o_buf = lustre_cfg_buf(o_lcfg, 0);
4671 o_buflen = o_lcfg->lcfg_buflens[0];
4672 if (contain_valid_fsname(o_buf, mlfd->mlfd_oldname, o_buflen,
4674 memcpy(n_buf, mlfd->mlfd_newname, n_namelen);
4675 memcpy(n_buf + n_namelen, o_buf + o_namelen,
4676 o_buflen - o_namelen);
4677 lustre_cfg_bufs_reset(n_bufs, n_buf);
4678 n_buf += cfs_size_round(o_buflen + diff);
4680 lustre_cfg_bufs_reset(n_bufs, o_buflen != 0 ? o_buf : NULL);
4685 struct cfg_marker *o_marker;
4686 struct cfg_marker *n_marker;
4690 CDEBUG(D_MGS, "Unknown cfg marker entry with %d "
4695 /* buf[1] is marker */
4696 o_buf = lustre_cfg_buf(o_lcfg, 1);
4697 o_buflen = o_lcfg->lcfg_buflens[1];
4698 o_marker = (struct cfg_marker *)o_buf;
4699 if (!contain_valid_fsname(o_marker->cm_tgtname,
4701 sizeof(o_marker->cm_tgtname),
4703 lustre_cfg_bufs_set(n_bufs, 1, o_marker,
4708 n_marker = (struct cfg_marker *)n_buf;
4709 *n_marker = *o_marker;
4710 memcpy(n_marker->cm_tgtname, mlfd->mlfd_newname, n_namelen);
4711 tgt_namelen = strlen(o_marker->cm_tgtname);
4712 if (tgt_namelen > o_namelen)
4713 memcpy(n_marker->cm_tgtname + n_namelen,
4714 o_marker->cm_tgtname + o_namelen,
4715 tgt_namelen - o_namelen);
4716 n_marker->cm_tgtname[tgt_namelen + diff] = '\0';
4717 lustre_cfg_bufs_set(n_bufs, 1, n_marker, sizeof(*n_marker));
4721 case LCFG_SET_PARAM: {
4722 for (i = 1; i < cnt; i++)
4723 /* buf[i] is the param value, reuse it directly */
4724 lustre_cfg_bufs_set(n_bufs, i,
4725 lustre_cfg_buf(o_lcfg, i),
4726 o_lcfg->lcfg_buflens[i]);
4732 case LCFG_POOL_DEL: {
4733 if (cnt < 3 || cnt > 4) {
4734 CDEBUG(D_MGS, "Unknown cfg pool (%x) entry with %d "
4735 "buffers\n", cmd, cnt);
4739 /* buf[1] is fsname */
4740 o_buf = lustre_cfg_buf(o_lcfg, 1);
4741 o_buflen = o_lcfg->lcfg_buflens[1];
4742 memcpy(n_buf, mlfd->mlfd_newname, n_namelen);
4743 memcpy(n_buf + n_namelen, o_buf + o_namelen,
4744 o_buflen - o_namelen);
4745 lustre_cfg_bufs_set(n_bufs, 1, n_buf, o_buflen + diff);
4746 n_buf += cfs_size_round(o_buflen + diff);
4748 /* buf[2] is the pool name, reuse it directly */
4749 lustre_cfg_bufs_set(n_bufs, 2, lustre_cfg_buf(o_lcfg, 2),
4750 o_lcfg->lcfg_buflens[2]);
4755 /* buf[3] is ostname */
4756 o_buf = lustre_cfg_buf(o_lcfg, 3);
4757 o_buflen = o_lcfg->lcfg_buflens[3];
4758 memcpy(n_buf, mlfd->mlfd_newname, n_namelen);
4759 memcpy(n_buf + n_namelen, o_buf + o_namelen,
4760 o_buflen - o_namelen);
4761 lustre_cfg_bufs_set(n_bufs, 3, n_buf, o_buflen + diff);
4766 o_buflen = o_lcfg->lcfg_buflens[1];
4767 if (o_buflen == sizeof(struct lov_desc) ||
4768 o_buflen == sizeof(struct lmv_desc)) {
4774 o_buf = lustre_cfg_buf(o_lcfg, 1);
4775 if (o_buflen == sizeof(struct lov_desc)) {
4776 struct lov_desc *o_desc =
4777 (struct lov_desc *)o_buf;
4778 struct lov_desc *n_desc =
4779 (struct lov_desc *)n_buf;
4782 o_uuid = o_desc->ld_uuid.uuid;
4783 n_uuid = n_desc->ld_uuid.uuid;
4784 uuid_len = sizeof(o_desc->ld_uuid.uuid);
4786 struct lmv_desc *o_desc =
4787 (struct lmv_desc *)o_buf;
4788 struct lmv_desc *n_desc =
4789 (struct lmv_desc *)n_buf;
4792 o_uuid = o_desc->ld_uuid.uuid;
4793 n_uuid = n_desc->ld_uuid.uuid;
4794 uuid_len = sizeof(o_desc->ld_uuid.uuid);
4797 if (unlikely(!contain_valid_fsname(o_uuid,
4798 mlfd->mlfd_oldname, uuid_len,
4800 lustre_cfg_bufs_set(n_bufs, 1, o_buf,
4805 memcpy(n_uuid, mlfd->mlfd_newname, n_namelen);
4806 uuid_len = strlen(o_uuid);
4807 if (uuid_len > o_namelen)
4808 memcpy(n_uuid + n_namelen,
4810 uuid_len - o_namelen);
4811 n_uuid[uuid_len + diff] = '\0';
4812 lustre_cfg_bufs_set(n_bufs, 1, n_buf, o_buflen);
4814 } /* else case fall through */
4815 } /* else case fall through */
4819 for (i = 1; i < cnt; i++) {
4820 o_buflen = o_lcfg->lcfg_buflens[i];
4824 o_buf = lustre_cfg_buf(o_lcfg, i);
4825 if (!contain_valid_fsname(o_buf, mlfd->mlfd_oldname,
4826 o_buflen, o_namelen)) {
4827 lustre_cfg_bufs_set(n_bufs, i, o_buf, o_buflen);
4831 memcpy(n_buf, mlfd->mlfd_newname, n_namelen);
4832 if (o_buflen == o_namelen) {
4833 lustre_cfg_bufs_set(n_bufs, i, n_buf,
4835 n_buf += cfs_size_round(n_namelen);
4839 memcpy(n_buf + n_namelen, o_buf + o_namelen,
4840 o_buflen - o_namelen);
4841 lustre_cfg_bufs_set(n_bufs, i, n_buf, o_buflen + diff);
4842 n_buf += cfs_size_round(o_buflen + diff);
4848 lcr = lustre_cfg_rec_new(cmd, n_bufs);
4852 lcr->lcr_cfg = *o_lcfg;
4853 rc = llog_write(env, mlfd->mlfd_llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
4854 lustre_cfg_rec_free(lcr);
4859 static int mgs_lcfg_fork_one(const struct lu_env *env, struct mgs_device *mgs,
4860 struct mgs_direntry *mde, const char *oldname,
4861 const char *newname)
4863 struct llog_handle *old_llh = NULL;
4864 struct llog_handle *new_llh = NULL;
4865 struct llog_ctxt *ctxt = NULL;
4866 struct mgs_lcfg_fork_data *mlfd = NULL;
4867 char *name_buf = NULL;
4869 int old_namelen = strlen(oldname);
4870 int new_namelen = strlen(newname);
4874 name_buflen = mde->mde_len + new_namelen - old_namelen;
4875 OBD_ALLOC(name_buf, name_buflen);
4879 memcpy(name_buf, newname, new_namelen);
4880 memcpy(name_buf + new_namelen, mde->mde_name + old_namelen,
4881 mde->mde_len - old_namelen);
4883 CDEBUG(D_MGS, "Fork the config-log from %s to %s\n",
4884 mde->mde_name, name_buf);
4886 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
4889 rc = llog_open_create(env, ctxt, &new_llh, NULL, name_buf);
4893 rc = llog_init_handle(env, new_llh, LLOG_F_IS_PLAIN, NULL);
4897 if (unlikely(mgs_log_is_empty(env, mgs, mde->mde_name)))
4900 rc = llog_open(env, ctxt, &old_llh, NULL, mde->mde_name,
4905 rc = llog_init_handle(env, old_llh, LLOG_F_IS_PLAIN, NULL);
4909 new_llh->lgh_hdr->llh_tgtuuid = old_llh->lgh_hdr->llh_tgtuuid;
4911 OBD_ALLOC(mlfd, LLOG_MIN_CHUNK_SIZE);
4913 GOTO(out, rc = -ENOMEM);
4915 mlfd->mlfd_mgs = mgs;
4916 mlfd->mlfd_llh = new_llh;
4917 mlfd->mlfd_oldname = oldname;
4918 mlfd->mlfd_newname = newname;
4920 rc = llog_process(env, old_llh, mgs_lcfg_fork_handler, mlfd, NULL);
4921 OBD_FREE(mlfd, LLOG_MIN_CHUNK_SIZE);
4927 llog_close(env, old_llh);
4929 llog_close(env, new_llh);
4931 OBD_FREE(name_buf, name_buflen);
4933 llog_ctxt_put(ctxt);
4938 int mgs_lcfg_fork(const struct lu_env *env, struct mgs_device *mgs,
4939 const char *oldname, const char *newname)
4941 struct list_head log_list;
4942 struct mgs_direntry *dirent, *n;
4943 int olen = strlen(oldname);
4944 int nlen = strlen(newname);
4949 if (unlikely(!oldname || oldname[0] == '\0' ||
4950 !newname || newname[0] == '\0'))
4953 if (strcmp(oldname, newname) == 0)
4956 /* lock it to prevent fork/erase/register in parallel. */
4957 mutex_lock(&mgs->mgs_mutex);
4959 rc = class_dentry_readdir(env, mgs, &log_list);
4961 mutex_unlock(&mgs->mgs_mutex);
4965 if (list_empty(&log_list)) {
4966 mutex_unlock(&mgs->mgs_mutex);
4970 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
4973 ptr = strrchr(dirent->mde_name, '-');
4975 int tlen = ptr - dirent->mde_name;
4978 strncmp(newname, dirent->mde_name, tlen) == 0)
4979 GOTO(out, rc = -EEXIST);
4982 strncmp(oldname, dirent->mde_name, tlen) == 0)
4986 list_del_init(&dirent->mde_list);
4987 mgs_direntry_free(dirent);
4990 if (list_empty(&log_list)) {
4991 mutex_unlock(&mgs->mgs_mutex);
4995 list_for_each_entry(dirent, &log_list, mde_list) {
4996 rc = mgs_lcfg_fork_one(env, mgs, dirent, oldname, newname);
5004 mutex_unlock(&mgs->mgs_mutex);
5006 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
5007 list_del_init(&dirent->mde_list);
5008 mgs_direntry_free(dirent);
5011 if (rc && count > 0)
5012 mgs_erase_logs(env, mgs, newname);
5017 int mgs_lcfg_erase(const struct lu_env *env, struct mgs_device *mgs,
5023 if (unlikely(!fsname || fsname[0] == '\0'))
5026 rc = mgs_erase_logs(env, mgs, fsname);
5031 static int mgs_xattr_del(const struct lu_env *env, struct dt_object *obj)
5033 struct dt_device *dev;
5034 struct thandle *th = NULL;
5039 dev = container_of(obj->do_lu.lo_dev, struct dt_device, dd_lu_dev);
5040 th = dt_trans_create(env, dev);
5042 RETURN(PTR_ERR(th));
5044 rc = dt_declare_xattr_del(env, obj, XATTR_TARGET_RENAME, th);
5048 rc = dt_trans_start_local(env, dev, th);
5052 dt_write_lock(env, obj, 0);
5053 rc = dt_xattr_del(env, obj, XATTR_TARGET_RENAME, th);
5058 dt_write_unlock(env, obj);
5061 dt_trans_stop(env, dev, th);
5066 int mgs_lcfg_rename(const struct lu_env *env, struct mgs_device *mgs)
5068 struct list_head log_list;
5069 struct mgs_direntry *dirent, *n;
5071 struct lu_buf buf = {
5073 .lb_len = sizeof(fsname)
5079 rc = class_dentry_readdir(env, mgs, &log_list);
5083 if (list_empty(&log_list))
5086 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
5087 struct dt_object *o = NULL;
5092 list_del_init(&dirent->mde_list);
5093 ptr = strrchr(dirent->mde_name, '-');
5097 len = ptr - dirent->mde_name;
5098 if (unlikely(len >= sizeof(oldname))) {
5099 CDEBUG(D_MGS, "Skip invalid configuration file %s\n",
5104 o = local_file_find(env, mgs->mgs_los, mgs->mgs_configs_dir,
5108 CDEBUG(D_MGS, "Fail to locate file %s: rc = %d\n",
5109 dirent->mde_name, rc);
5113 rc = dt_xattr_get(env, o, &buf, XATTR_TARGET_RENAME);
5119 "Fail to get EA for %s: rc = %d\n",
5120 dirent->mde_name, rc);
5124 if (unlikely(rc == len &&
5125 memcmp(fsname, dirent->mde_name, len) == 0)) {
5126 /* The new fsname is the same as the old one. */
5127 rc = mgs_xattr_del(env, o);
5131 memcpy(oldname, dirent->mde_name, len);
5132 oldname[len] = '\0';
5134 rc = mgs_lcfg_fork_one(env, mgs, dirent, oldname, fsname);
5135 if (rc && rc != -EEXIST) {
5136 CDEBUG(D_MGS, "Fail to fork %s: rc = %d\n",
5137 dirent->mde_name, rc);
5141 rc = mgs_erase_log(env, mgs, dirent->mde_name);
5143 CDEBUG(D_MGS, "Fail to erase old %s: rc = %d\n",
5144 dirent->mde_name, rc);
5145 /* keep it there if failed to remove it. */
5150 if (o && !IS_ERR(o))
5151 lu_object_put(env, &o->do_lu);
5153 mgs_direntry_free(dirent);
5158 list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
5159 list_del_init(&dirent->mde_list);
5160 mgs_direntry_free(dirent);
5166 /* Setup _mgs fsdb and log
5168 int mgs__mgs_fsdb_setup(const struct lu_env *env, struct mgs_device *mgs)
5170 struct fs_db *fsdb = NULL;
5174 rc = mgs_find_or_make_fsdb(env, mgs, MGSSELF_NAME, &fsdb);
5176 mgs_put_fsdb(mgs, fsdb);
5181 /* Setup params fsdb and log
5183 int mgs_params_fsdb_setup(const struct lu_env *env, struct mgs_device *mgs)
5185 struct fs_db *fsdb = NULL;
5186 struct llog_handle *params_llh = NULL;
5190 rc = mgs_find_or_make_fsdb(env, mgs, PARAMS_FILENAME, &fsdb);
5192 mutex_lock(&fsdb->fsdb_mutex);
5193 rc = record_start_log(env, mgs, ¶ms_llh, PARAMS_FILENAME);
5195 rc = record_end_log(env, ¶ms_llh);
5196 mutex_unlock(&fsdb->fsdb_mutex);
5197 mgs_put_fsdb(mgs, fsdb);
5203 /* Cleanup params fsdb and log
5205 int mgs_params_fsdb_cleanup(const struct lu_env *env, struct mgs_device *mgs)
5209 rc = mgs_erase_logs(env, mgs, PARAMS_FILENAME);
5210 return rc == -ENOENT ? 0 : rc;
5214 * Fill in the mgs_target_info based on data devname and param provide.
5216 * @env thread context
5218 * @mti mgs target info. We want to set this based other paramters
5219 * passed to this function. Once setup we write it to the config
5221 * @devname optional OBD device name
5222 * @param string that contains both what tunable to set and the value to
5225 * RETURN 0 for success
5226 * negative error number on failure
5228 static int mgs_set_conf_param(const struct lu_env *env, struct mgs_device *mgs,
5229 struct mgs_target_info *mti, const char *devname,
5232 struct fs_db *fsdb = NULL;
5237 /* lustre, lustre-mdtlov, lustre-client, lustre-MDT0000 */
5241 /* We have two possible cases here:
5243 * 1) the device name embedded in the param:
5244 * lustre-OST0000.osc.max_dirty_mb=32
5246 * 2) the file system name is embedded in
5247 * the param: lustre.sys.at.min=0
5249 len = strcspn(param, ".=");
5250 if (!len || param[len] == '=')
5253 if (len >= sizeof(mti->mti_svname))
5256 snprintf(mti->mti_svname, sizeof(mti->mti_svname),
5257 "%.*s", (int)len, param);
5260 if (strlcpy(mti->mti_svname, devname, sizeof(mti->mti_svname)) >=
5261 sizeof(mti->mti_svname))
5265 if (!strlen(mti->mti_svname)) {
5266 LCONSOLE_ERROR_MSG(0x14d, "No target specified: %s\n", param);
5270 dev_type = mgs_parse_devname(mti->mti_svname, mti->mti_fsname,
5271 &mti->mti_stripe_index);
5273 /* For this case we have an invalid obd device name */
5275 CDEBUG(D_MGS, "%s don't contain an index\n", mti->mti_svname);
5276 strlcpy(mti->mti_fsname, mti->mti_svname, MTI_NAME_MAXLEN);
5279 /* Not an obd device, assume devname is the fsname.
5280 * User might of only provided fsname and not obd device
5283 CDEBUG(D_MGS, "%s is seen as a file system name\n", mti->mti_svname);
5284 strlcpy(mti->mti_fsname, mti->mti_svname, MTI_NAME_MAXLEN);
5289 GOTO(out, rc = dev_type);
5291 /* param related to llite isn't allowed to set by OST or MDT */
5292 if (dev_type & LDD_F_SV_TYPE_OST ||
5293 dev_type & LDD_F_SV_TYPE_MDT) {
5294 /* param related to llite isn't allowed to set by OST
5297 if (!strncmp(param, PARAM_LLITE,
5298 sizeof(PARAM_LLITE) - 1))
5299 GOTO(out, rc = -EINVAL);
5301 /* Strip -osc or -mdc suffix from svname */
5302 if (server_make_name(dev_type, mti->mti_stripe_index,
5303 mti->mti_fsname, mti->mti_svname,
5304 sizeof(mti->mti_svname)))
5305 GOTO(out, rc = -EINVAL);
5310 if (strlcpy(mti->mti_params, param, sizeof(mti->mti_params)) >=
5311 sizeof(mti->mti_params))
5312 GOTO(out, rc = -E2BIG);
5314 CDEBUG(D_MGS, "set_conf_param fs='%s' device='%s' param='%s'\n",
5315 mti->mti_fsname, mti->mti_svname, mti->mti_params);
5317 rc = mgs_find_or_make_fsdb(env, mgs, mti->mti_fsname, &fsdb);
5321 if (!test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags) &&
5322 test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
5323 CERROR("No filesystem targets for %s. cfg_device from lctl "
5324 "is '%s'\n", mti->mti_fsname, mti->mti_svname);
5325 mgs_unlink_fsdb(mgs, fsdb);
5326 GOTO(out, rc = -EINVAL);
5330 * Revoke lock so everyone updates. Should be alright if
5331 * someone was already reading while we were updating the logs,
5332 * so we don't really need to hold the lock while we're
5335 mti->mti_flags = dev_type | LDD_F_PARAM;
5336 mutex_lock(&fsdb->fsdb_mutex);
5337 rc = mgs_write_log_param(env, mgs, fsdb, mti, mti->mti_params);
5338 mutex_unlock(&fsdb->fsdb_mutex);
5339 mgs_revoke_lock(mgs, fsdb, MGS_CFG_T_CONFIG);
5343 mgs_put_fsdb(mgs, fsdb);
5348 static int mgs_set_param2(const struct lu_env *env, struct mgs_device *mgs,
5349 struct mgs_target_info *mti, const char *param)
5351 struct fs_db *fsdb = NULL;
5356 if (strlcpy(mti->mti_params, param, sizeof(mti->mti_params)) >=
5357 sizeof(mti->mti_params))
5358 GOTO(out, rc = -E2BIG);
5360 len = strcspn(param, ".=");
5361 if (len && param[len] != '=') {
5362 struct list_head *tmp;
5366 ptr = strchr(param, '.');
5368 len = strlen(param);
5371 if (len >= sizeof(mti->mti_svname))
5372 GOTO(out, rc = -E2BIG);
5374 snprintf(mti->mti_svname, sizeof(mti->mti_svname), "%.*s",
5377 mutex_lock(&mgs->mgs_mutex);
5378 if (unlikely(list_empty(&mgs->mgs_fs_db_list))) {
5379 mutex_unlock(&mgs->mgs_mutex);
5380 GOTO(out, rc = -ENODEV);
5383 list_for_each(tmp, &mgs->mgs_fs_db_list) {
5384 fsdb = list_entry(tmp, struct fs_db, fsdb_list);
5385 if (fsdb->fsdb_has_lproc_entry &&
5386 strcmp(fsdb->fsdb_name, "params") != 0 &&
5387 strstr(param, fsdb->fsdb_name)) {
5388 snprintf(mti->mti_svname,
5389 sizeof(mti->mti_svname), "%s",
5397 snprintf(mti->mti_svname, sizeof(mti->mti_svname),
5400 mutex_unlock(&mgs->mgs_mutex);
5402 snprintf(mti->mti_svname, sizeof(mti->mti_svname), "general");
5405 CDEBUG(D_MGS, "set_param2 fs='%s' device='%s' param='%s'\n",
5406 mti->mti_fsname, mti->mti_svname, mti->mti_params);
5408 /* The return value should be the device type i.e LDD_F_SV_TYPE_XXX.
5409 * A returned error tells us we don't have a target obd device.
5411 dev_type = server_name2index(mti->mti_svname, &mti->mti_stripe_index,
5416 /* the return value should be the device type i.e LDD_F_SV_TYPE_XXX.
5417 * Strip -osc or -mdc suffix from svname
5419 if ((dev_type & LDD_F_SV_TYPE_OST || dev_type & LDD_F_SV_TYPE_MDT) &&
5420 server_make_name(dev_type, mti->mti_stripe_index,
5421 mti->mti_fsname, mti->mti_svname,
5422 sizeof(mti->mti_svname)))
5423 GOTO(out, rc = -EINVAL);
5425 rc = mgs_find_or_make_fsdb(env, mgs, PARAMS_FILENAME, &fsdb);
5429 * Revoke lock so everyone updates. Should be alright if
5430 * someone was already reading while we were updating the logs,
5431 * so we don't really need to hold the lock while we're
5434 mti->mti_flags = dev_type | LDD_F_PARAM2;
5435 mutex_lock(&fsdb->fsdb_mutex);
5436 rc = mgs_write_log_param2(env, mgs, fsdb, mti, mti->mti_params);
5437 mutex_unlock(&fsdb->fsdb_mutex);
5438 mgs_revoke_lock(mgs, fsdb, MGS_CFG_T_PARAMS);
5439 mgs_put_fsdb(mgs, fsdb);
5444 /* Set a permanent (config log) param for a target or fs
5446 * @lcfg buf0 may contain the device (testfs-MDT0000) name
5447 * buf1 contains the single parameter
5449 int mgs_set_param(const struct lu_env *env, struct mgs_device *mgs,
5450 struct lustre_cfg *lcfg)
5452 const char *param = lustre_cfg_string(lcfg, 1);
5453 struct mgs_target_info *mti;
5456 /* Create a fake mti to hold everything */
5461 print_lustre_cfg(lcfg);
5463 if (lcfg->lcfg_command == LCFG_PARAM) {
5464 /* For the case of lctl conf_param devname can be
5465 * lustre, lustre-mdtlov, lustre-client, lustre-MDT0000
5467 const char *devname = lustre_cfg_string(lcfg, 0);
5469 rc = mgs_set_conf_param(env, mgs, mti, devname, param);
5471 /* In the case of lctl set_param -P lcfg[0] will always
5472 * be 'general'. At least for now.
5474 rc = mgs_set_param2(env, mgs, mti, param);
5482 static int mgs_write_log_pool(const struct lu_env *env,
5483 struct mgs_device *mgs, char *logname,
5484 struct fs_db *fsdb, char *tgtname,
5485 enum lcfg_command_type cmd,
5486 char *fsname, char *poolname,
5487 char *ostname, char *comment)
5489 struct llog_handle *llh = NULL;
5492 rc = record_start_log(env, mgs, &llh, logname);
5495 rc = record_marker(env, llh, fsdb, CM_START, tgtname, comment);
5498 rc = record_base(env, llh, tgtname, 0, cmd,
5499 fsname, poolname, ostname, NULL);
5502 rc = record_marker(env, llh, fsdb, CM_END, tgtname, comment);
5504 record_end_log(env, &llh);
5508 int mgs_nodemap_cmd(const struct lu_env *env, struct mgs_device *mgs,
5509 enum lcfg_command_type cmd, const char *nodemap_name,
5520 case LCFG_NODEMAP_ADD:
5521 rc = nodemap_add(nodemap_name);
5523 case LCFG_NODEMAP_DEL:
5524 rc = nodemap_del(nodemap_name);
5526 case LCFG_NODEMAP_ADD_RANGE:
5527 rc = nodemap_parse_range(param, nid);
5530 rc = nodemap_add_range(nodemap_name, nid);
5532 case LCFG_NODEMAP_DEL_RANGE:
5533 rc = nodemap_parse_range(param, nid);
5536 rc = nodemap_del_range(nodemap_name, nid);
5538 case LCFG_NODEMAP_ADMIN:
5539 rc = kstrtobool(param, &bool_switch);
5542 rc = nodemap_set_allow_root(nodemap_name, bool_switch);
5544 case LCFG_NODEMAP_DENY_UNKNOWN:
5545 rc = kstrtobool(param, &bool_switch);
5548 rc = nodemap_set_deny_unknown(nodemap_name, bool_switch);
5550 case LCFG_NODEMAP_AUDIT_MODE:
5551 rc = kstrtobool(param, &bool_switch);
5553 rc = nodemap_set_audit_mode(nodemap_name, bool_switch);
5555 case LCFG_NODEMAP_FORBID_ENCRYPT:
5556 rc = kstrtobool(param, &bool_switch);
5558 rc = nodemap_set_forbid_encryption(nodemap_name,
5561 case LCFG_NODEMAP_READONLY_MOUNT:
5562 rc = kstrtobool(param, &bool_switch);
5564 rc = nodemap_set_readonly_mount(nodemap_name,
5567 case LCFG_NODEMAP_MAP_MODE:
5572 if ((p = strstr(param, "all")) != NULL) {
5573 if ((p == param || *(p-1) == ',') &&
5574 (*(p+3) == '\0' || *(p+3) == ',')) {
5575 map_mode = NODEMAP_MAP_ALL;
5581 while ((p = strsep(¶m, ",")) != NULL) {
5585 if (strcmp("both", p) == 0)
5586 map_mode |= NODEMAP_MAP_BOTH;
5587 else if (strcmp("uid_only", p) == 0 ||
5588 strcmp("uid", p) == 0)
5589 map_mode |= NODEMAP_MAP_UID;
5590 else if (strcmp("gid_only", p) == 0 ||
5591 strcmp("gid", p) == 0)
5592 map_mode |= NODEMAP_MAP_GID;
5593 else if (strcmp("projid_only", p) == 0 ||
5594 strcmp("projid", p) == 0)
5595 map_mode |= NODEMAP_MAP_PROJID;
5605 rc = nodemap_set_mapping_mode(nodemap_name, map_mode);
5608 case LCFG_NODEMAP_RBAC:
5610 enum nodemap_rbac_roles rbac;
5613 if (strcmp(param, "all") == 0) {
5614 rbac = NODEMAP_RBAC_ALL;
5615 } else if (strcmp(param, "none") == 0) {
5616 rbac = NODEMAP_RBAC_NONE;
5618 rbac = NODEMAP_RBAC_NONE;
5619 while ((p = strsep(¶m, ",")) != NULL) {
5625 for (i = 0; i < ARRAY_SIZE(nodemap_rbac_names);
5628 nodemap_rbac_names[i].nrn_name)
5631 nodemap_rbac_names[i].nrn_mode;
5635 if (i == ARRAY_SIZE(nodemap_rbac_names))
5644 rc = nodemap_set_rbac(nodemap_name, rbac);
5647 case LCFG_NODEMAP_TRUSTED:
5648 rc = kstrtobool(param, &bool_switch);
5651 rc = nodemap_set_trust_client_ids(nodemap_name, bool_switch);
5653 case LCFG_NODEMAP_SQUASH_UID:
5654 rc = kstrtouint(param, 10, &int_id);
5657 rc = nodemap_set_squash_uid(nodemap_name, int_id);
5659 case LCFG_NODEMAP_SQUASH_GID:
5660 rc = kstrtouint(param, 10, &int_id);
5663 rc = nodemap_set_squash_gid(nodemap_name, int_id);
5665 case LCFG_NODEMAP_SQUASH_PROJID:
5666 rc = kstrtouint(param, 10, &int_id);
5669 rc = nodemap_set_squash_projid(nodemap_name, int_id);
5671 case LCFG_NODEMAP_ADD_UIDMAP:
5672 case LCFG_NODEMAP_ADD_GIDMAP:
5673 case LCFG_NODEMAP_ADD_PROJIDMAP:
5674 rc = nodemap_parse_idmap(param, idmap);
5677 if (cmd == LCFG_NODEMAP_ADD_UIDMAP)
5678 rc = nodemap_add_idmap(nodemap_name, NODEMAP_UID,
5680 else if (cmd == LCFG_NODEMAP_ADD_GIDMAP)
5681 rc = nodemap_add_idmap(nodemap_name, NODEMAP_GID,
5683 else if (cmd == LCFG_NODEMAP_ADD_PROJIDMAP)
5684 rc = nodemap_add_idmap(nodemap_name, NODEMAP_PROJID,
5689 case LCFG_NODEMAP_DEL_UIDMAP:
5690 case LCFG_NODEMAP_DEL_GIDMAP:
5691 case LCFG_NODEMAP_DEL_PROJIDMAP:
5692 rc = nodemap_parse_idmap(param, idmap);
5695 if (cmd == LCFG_NODEMAP_DEL_UIDMAP)
5696 rc = nodemap_del_idmap(nodemap_name, NODEMAP_UID,
5698 else if (cmd == LCFG_NODEMAP_DEL_GIDMAP)
5699 rc = nodemap_del_idmap(nodemap_name, NODEMAP_GID,
5701 else if (cmd == LCFG_NODEMAP_DEL_PROJIDMAP)
5702 rc = nodemap_del_idmap(nodemap_name, NODEMAP_PROJID,
5707 case LCFG_NODEMAP_SET_FILESET:
5708 rc = nodemap_set_fileset(nodemap_name, param);
5710 case LCFG_NODEMAP_SET_SEPOL:
5711 rc = nodemap_set_sepol(nodemap_name, param);
5720 int mgs_pool_cmd(const struct lu_env *env, struct mgs_device *mgs,
5721 enum lcfg_command_type cmd, char *fsname,
5722 char *poolname, char *ostname)
5727 char *label = NULL, *canceled_label = NULL;
5729 struct mgs_target_info *mti = NULL;
5730 bool checked = false;
5731 bool locked = false;
5736 rc = mgs_find_or_make_fsdb(env, mgs, fsname, &fsdb);
5738 CERROR("Can't get db for %s\n", fsname);
5741 if (test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
5742 CERROR("%s is not defined\n", fsname);
5744 GOTO(out_fsdb, rc = -EINVAL);
5747 label_sz = 10 + strlen(fsname) + strlen(poolname);
5749 /* check if ostname match fsname */
5750 if (ostname != NULL) {
5753 ptr = strrchr(ostname, '-');
5754 if ((ptr == NULL) ||
5755 (strncmp(fsname, ostname, ptr-ostname) != 0))
5757 label_sz += strlen(ostname);
5760 OBD_ALLOC(label, label_sz);
5762 GOTO(out_fsdb, rc = -ENOMEM);
5766 sprintf(label, "new %s.%s", fsname, poolname);
5769 sprintf(label, "add %s.%s.%s", fsname, poolname, ostname);
5772 OBD_ALLOC(canceled_label, label_sz);
5773 if (canceled_label == NULL)
5774 GOTO(out_label, rc = -ENOMEM);
5775 sprintf(label, "rem %s.%s.%s", fsname, poolname, ostname);
5776 sprintf(canceled_label, "add %s.%s.%s",
5777 fsname, poolname, ostname);
5780 OBD_ALLOC(canceled_label, label_sz);
5781 if (canceled_label == NULL)
5782 GOTO(out_label, rc = -ENOMEM);
5783 sprintf(label, "del %s.%s", fsname, poolname);
5784 sprintf(canceled_label, "new %s.%s", fsname, poolname);
5792 GOTO(out_cancel, rc = -ENOMEM);
5793 strncpy(mti->mti_svname, "lov pool", sizeof(mti->mti_svname));
5795 mutex_lock(&fsdb->fsdb_mutex);
5797 /* write pool def to all MDT logs */
5798 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
5799 if (test_bit(i, fsdb->fsdb_mdt_index_map)) {
5800 rc = name_create_mdt_and_lov(&logname, &lovname,
5805 if (!checked && (canceled_label == NULL)) {
5806 rc = mgs_check_marker(env, mgs, fsdb, mti,
5807 logname, lovname, label);
5809 name_destroy(&logname);
5810 name_destroy(&lovname);
5812 rc = (rc == LLOG_PROC_BREAK ?
5817 if (canceled_label != NULL)
5818 rc = mgs_modify(env, mgs, fsdb, mti, logname,
5819 lovname, canceled_label,
5823 rc = mgs_write_log_pool(env, mgs, logname,
5827 name_destroy(&logname);
5828 name_destroy(&lovname);
5834 rc = name_create(&logname, fsname, "-client");
5838 if (!checked && (canceled_label == NULL)) {
5839 rc = mgs_check_marker(env, mgs, fsdb, mti, logname,
5840 fsdb->fsdb_clilov, label);
5842 name_destroy(&logname);
5843 GOTO(out_mti, rc = (rc == LLOG_PROC_BREAK ?
5847 if (canceled_label != NULL) {
5848 rc = mgs_modify(env, mgs, fsdb, mti, logname,
5849 fsdb->fsdb_clilov, canceled_label, CM_SKIP);
5851 name_destroy(&logname);
5856 rc = mgs_write_log_pool(env, mgs, logname, fsdb, fsdb->fsdb_clilov,
5857 cmd, fsname, poolname, ostname, label);
5858 mutex_unlock(&fsdb->fsdb_mutex);
5860 name_destroy(&logname);
5861 /* request for update */
5862 mgs_revoke_lock(mgs, fsdb, MGS_CFG_T_CONFIG);
5868 mutex_unlock(&fsdb->fsdb_mutex);
5872 if (canceled_label != NULL)
5873 OBD_FREE(canceled_label, label_sz);
5875 OBD_FREE(label, label_sz);
5878 mgs_unlink_fsdb(mgs, fsdb);
5879 mgs_put_fsdb(mgs, fsdb);