4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 only,
8 * as published by the Free Software Foundation.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License version 2 for more details (a copy is included
14 * in the LICENSE file that accompanied this code).
16 * You should have received a copy of the GNU General Public License
17 * version 2 along with this program; If not, see
18 * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
20 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
21 * CA 95054 USA or visit www.sun.com if you need additional information or
27 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
28 * Use is subject to license terms.
30 * Copyright (c) 2011, 2013, Intel Corporation.
33 * This file is part of Lustre, http://www.lustre.org/
34 * Lustre is a trademark of Sun Microsystems, Inc.
36 * lustre/mgs/mgs_llog.c
38 * Lustre Management Server (mgs) config llog creation
40 * Author: Nathan Rutman <nathan@clusterfs.com>
41 * Author: Alex Zhuravlev <bzzz@whamcloud.com>
42 * Author: Mikhail Pershin <tappro@whamcloud.com>
45 #define DEBUG_SUBSYSTEM S_MGS
46 #define D_MGS D_CONFIG
50 #include <lustre_param.h>
51 #include <lustre_sec.h>
52 #include <lustre_quota.h>
54 #include "mgs_internal.h"
56 /********************** Class functions ********************/
58 int class_dentry_readdir(const struct lu_env *env,
59 struct mgs_device *mgs, cfs_list_t *list)
61 struct dt_object *dir = mgs->mgs_configs_dir;
62 const struct dt_it_ops *iops;
64 struct mgs_direntry *de;
68 CFS_INIT_LIST_HEAD(list);
70 if (!dt_try_as_dir(env, dir))
71 GOTO(out, rc = -ENOTDIR);
74 LASSERT(dir->do_index_ops);
76 iops = &dir->do_index_ops->dio_it;
77 it = iops->init(env, dir, LUDA_64BITHASH, BYPASS_CAPA);
81 rc = iops->load(env, it, 0);
87 key = (void *)iops->key(env, it);
89 CERROR("%s: key failed when listing %s: rc = %d\n",
90 mgs->mgs_obd->obd_name, MOUNT_CONFIGS_DIR,
94 key_sz = iops->key_size(env, it);
97 /* filter out "." and ".." entries */
101 if (key_sz == 2 && key[1] == '.')
105 de = mgs_direntry_alloc(key_sz + 1);
111 memcpy(de->name, key, key_sz);
112 de->name[key_sz] = 0;
114 cfs_list_add(&de->list, list);
117 rc = iops->next(env, it);
127 CERROR("%s: key failed when listing %s: rc = %d\n",
128 mgs->mgs_obd->obd_name, MOUNT_CONFIGS_DIR, rc);
132 /******************** DB functions *********************/
134 static inline int name_create(char **newname, char *prefix, char *suffix)
137 OBD_ALLOC(*newname, strlen(prefix) + strlen(suffix) + 1);
140 sprintf(*newname, "%s%s", prefix, suffix);
144 static inline void name_destroy(char **name)
147 OBD_FREE(*name, strlen(*name) + 1);
151 struct mgs_fsdb_handler_data
157 /* from the (client) config log, figure out:
158 1. which ost's/mdt's are configured (by index)
159 2. what the last config step is
160 3. COMPAT_18 osc name
162 /* It might be better to have a separate db file, instead of parsing the info
163 out of the client log. This is slow and potentially error-prone. */
164 static int mgs_fsdb_handler(const struct lu_env *env, struct llog_handle *llh,
165 struct llog_rec_hdr *rec, void *data)
167 struct mgs_fsdb_handler_data *d = data;
168 struct fs_db *fsdb = d->fsdb;
169 int cfg_len = rec->lrh_len;
170 char *cfg_buf = (char*) (rec + 1);
171 struct lustre_cfg *lcfg;
176 if (rec->lrh_type != OBD_CFG_REC) {
177 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
181 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
183 CERROR("Insane cfg\n");
187 lcfg = (struct lustre_cfg *)cfg_buf;
189 CDEBUG(D_INFO, "cmd %x %s %s\n", lcfg->lcfg_command,
190 lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));
192 /* Figure out ost indicies */
193 /* lov_modify_tgts add 0:lov1 1:ost1_UUID 2(index):0 3(gen):1 */
194 if (lcfg->lcfg_command == LCFG_LOV_ADD_OBD ||
195 lcfg->lcfg_command == LCFG_LOV_DEL_OBD) {
196 index = simple_strtoul(lustre_cfg_string(lcfg, 2),
198 CDEBUG(D_MGS, "OST index for %s is %u (%s)\n",
199 lustre_cfg_string(lcfg, 1), index,
200 lustre_cfg_string(lcfg, 2));
201 set_bit(index, fsdb->fsdb_ost_index_map);
204 /* Figure out mdt indicies */
205 /* attach 0:MDC_uml1_mdsA_MNT_client 1:mdc 2:1d834_MNT_client_03f */
206 if ((lcfg->lcfg_command == LCFG_ATTACH) &&
207 (strcmp(lustre_cfg_string(lcfg, 1), LUSTRE_MDC_NAME) == 0)) {
208 rc = server_name2index(lustre_cfg_string(lcfg, 0),
210 if (rc != LDD_F_SV_TYPE_MDT) {
211 CWARN("Unparsable MDC name %s, assuming index 0\n",
212 lustre_cfg_string(lcfg, 0));
216 CDEBUG(D_MGS, "MDT index is %u\n", index);
217 set_bit(index, fsdb->fsdb_mdt_index_map);
218 fsdb->fsdb_mdt_count ++;
222 * figure out the old config. fsdb_gen = 0 means old log
223 * It is obsoleted and not supported anymore
225 if (fsdb->fsdb_gen == 0) {
226 CERROR("Old config format is not supported\n");
231 * compat to 1.8, check osc name used by MDT0 to OSTs, bz18548.
233 if (!test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags) &&
234 lcfg->lcfg_command == LCFG_ATTACH &&
235 strcmp(lustre_cfg_string(lcfg, 1), LUSTRE_OSC_NAME) == 0) {
236 if (OBD_OCD_VERSION_MAJOR(d->ver) == 1 &&
237 OBD_OCD_VERSION_MINOR(d->ver) <= 8) {
238 CWARN("MDT using 1.8 OSC name scheme\n");
239 set_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags);
243 if (lcfg->lcfg_command == LCFG_MARKER) {
244 struct cfg_marker *marker;
245 marker = lustre_cfg_buf(lcfg, 1);
247 d->ver = marker->cm_vers;
249 /* Keep track of the latest marker step */
250 fsdb->fsdb_gen = max(fsdb->fsdb_gen, marker->cm_step);
256 /* fsdb->fsdb_mutex is already held in mgs_find_or_make_fsdb*/
257 static int mgs_get_fsdb_from_llog(const struct lu_env *env,
258 struct mgs_device *mgs,
262 struct llog_handle *loghandle;
263 struct llog_ctxt *ctxt;
264 struct mgs_fsdb_handler_data d = { fsdb, 0 };
269 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
270 LASSERT(ctxt != NULL);
271 rc = name_create(&logname, fsdb->fsdb_name, "-client");
274 rc = llog_open_create(env, ctxt, &loghandle, NULL, logname);
278 rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL);
282 if (llog_get_size(loghandle) <= 1)
283 set_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags);
285 rc = llog_process(env, loghandle, mgs_fsdb_handler, (void *)&d, NULL);
286 CDEBUG(D_INFO, "get_db = %d\n", rc);
288 llog_close(env, loghandle);
290 name_destroy(&logname);
297 static void mgs_free_fsdb_srpc(struct fs_db *fsdb)
299 struct mgs_tgt_srpc_conf *tgtconf;
301 /* free target-specific rules */
302 while (fsdb->fsdb_srpc_tgt) {
303 tgtconf = fsdb->fsdb_srpc_tgt;
304 fsdb->fsdb_srpc_tgt = tgtconf->mtsc_next;
306 LASSERT(tgtconf->mtsc_tgt);
308 sptlrpc_rule_set_free(&tgtconf->mtsc_rset);
309 OBD_FREE(tgtconf->mtsc_tgt, strlen(tgtconf->mtsc_tgt) + 1);
310 OBD_FREE_PTR(tgtconf);
313 /* free general rules */
314 sptlrpc_rule_set_free(&fsdb->fsdb_srpc_gen);
317 struct fs_db *mgs_find_fsdb(struct mgs_device *mgs, char *fsname)
322 cfs_list_for_each(tmp, &mgs->mgs_fs_db_list) {
323 fsdb = cfs_list_entry(tmp, struct fs_db, fsdb_list);
324 if (strcmp(fsdb->fsdb_name, fsname) == 0)
330 /* caller must hold the mgs->mgs_fs_db_lock */
331 static struct fs_db *mgs_new_fsdb(const struct lu_env *env,
332 struct mgs_device *mgs, char *fsname)
338 if (strlen(fsname) >= sizeof(fsdb->fsdb_name)) {
339 CERROR("fsname %s is too long\n", fsname);
347 strcpy(fsdb->fsdb_name, fsname);
348 mutex_init(&fsdb->fsdb_mutex);
349 set_bit(FSDB_UDESC, &fsdb->fsdb_flags);
352 if (strcmp(fsname, MGSSELF_NAME) == 0) {
353 set_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags);
355 OBD_ALLOC(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
356 OBD_ALLOC(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
357 if (!fsdb->fsdb_ost_index_map || !fsdb->fsdb_mdt_index_map) {
358 CERROR("No memory for index maps\n");
359 GOTO(err, rc = -ENOMEM);
362 rc = name_create(&fsdb->fsdb_clilov, fsname, "-clilov");
365 rc = name_create(&fsdb->fsdb_clilmv, fsname, "-clilmv");
369 /* initialise data for NID table */
370 mgs_ir_init_fs(env, mgs, fsdb);
372 lproc_mgs_add_live(mgs, fsdb);
375 cfs_list_add(&fsdb->fsdb_list, &mgs->mgs_fs_db_list);
379 if (fsdb->fsdb_ost_index_map)
380 OBD_FREE(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
381 if (fsdb->fsdb_mdt_index_map)
382 OBD_FREE(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
383 name_destroy(&fsdb->fsdb_clilov);
384 name_destroy(&fsdb->fsdb_clilmv);
389 static void mgs_free_fsdb(struct mgs_device *mgs, struct fs_db *fsdb)
391 /* wait for anyone with the sem */
392 mutex_lock(&fsdb->fsdb_mutex);
393 lproc_mgs_del_live(mgs, fsdb);
394 cfs_list_del(&fsdb->fsdb_list);
396 /* deinitialize fsr */
397 mgs_ir_fini_fs(mgs, fsdb);
399 if (fsdb->fsdb_ost_index_map)
400 OBD_FREE(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
401 if (fsdb->fsdb_mdt_index_map)
402 OBD_FREE(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
403 name_destroy(&fsdb->fsdb_clilov);
404 name_destroy(&fsdb->fsdb_clilmv);
405 mgs_free_fsdb_srpc(fsdb);
406 mutex_unlock(&fsdb->fsdb_mutex);
410 int mgs_init_fsdb_list(struct mgs_device *mgs)
412 CFS_INIT_LIST_HEAD(&mgs->mgs_fs_db_list);
416 int mgs_cleanup_fsdb_list(struct mgs_device *mgs)
419 cfs_list_t *tmp, *tmp2;
420 mutex_lock(&mgs->mgs_mutex);
421 cfs_list_for_each_safe(tmp, tmp2, &mgs->mgs_fs_db_list) {
422 fsdb = cfs_list_entry(tmp, struct fs_db, fsdb_list);
423 mgs_free_fsdb(mgs, fsdb);
425 mutex_unlock(&mgs->mgs_mutex);
429 int mgs_find_or_make_fsdb(const struct lu_env *env,
430 struct mgs_device *mgs, char *name,
437 mutex_lock(&mgs->mgs_mutex);
438 fsdb = mgs_find_fsdb(mgs, name);
440 mutex_unlock(&mgs->mgs_mutex);
445 CDEBUG(D_MGS, "Creating new db\n");
446 fsdb = mgs_new_fsdb(env, mgs, name);
447 /* lock fsdb_mutex until the db is loaded from llogs */
449 mutex_lock(&fsdb->fsdb_mutex);
450 mutex_unlock(&mgs->mgs_mutex);
454 if (!test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
455 /* populate the db from the client llog */
456 rc = mgs_get_fsdb_from_llog(env, mgs, fsdb);
458 CERROR("Can't get db from client log %d\n", rc);
463 /* populate srpc rules from params llog */
464 rc = mgs_get_fsdb_srpc_from_llog(env, mgs, fsdb);
466 CERROR("Can't get db from params log %d\n", rc);
470 mutex_unlock(&fsdb->fsdb_mutex);
476 mutex_unlock(&fsdb->fsdb_mutex);
477 mgs_free_fsdb(mgs, fsdb);
483 -1= empty client log */
484 int mgs_check_index(const struct lu_env *env,
485 struct mgs_device *mgs,
486 struct mgs_target_info *mti)
493 LASSERT(!(mti->mti_flags & LDD_F_NEED_INDEX));
495 rc = mgs_find_or_make_fsdb(env, mgs, mti->mti_fsname, &fsdb);
497 CERROR("Can't get db for %s\n", mti->mti_fsname);
501 if (test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags))
504 if (mti->mti_flags & LDD_F_SV_TYPE_OST)
505 imap = fsdb->fsdb_ost_index_map;
506 else if (mti->mti_flags & LDD_F_SV_TYPE_MDT)
507 imap = fsdb->fsdb_mdt_index_map;
511 if (test_bit(mti->mti_stripe_index, imap))
516 static __inline__ int next_index(void *index_map, int map_len)
519 for (i = 0; i < map_len * 8; i++)
520 if (!test_bit(i, index_map)) {
523 CERROR("max index %d exceeded.\n", i);
528 0 newly marked as in use
530 +EALREADY for update of an old index */
531 static int mgs_set_index(const struct lu_env *env,
532 struct mgs_device *mgs,
533 struct mgs_target_info *mti)
540 rc = mgs_find_or_make_fsdb(env, mgs, mti->mti_fsname, &fsdb);
542 CERROR("Can't get db for %s\n", mti->mti_fsname);
546 mutex_lock(&fsdb->fsdb_mutex);
547 if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
548 imap = fsdb->fsdb_ost_index_map;
549 } else if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
550 imap = fsdb->fsdb_mdt_index_map;
552 GOTO(out_up, rc = -EINVAL);
555 if (mti->mti_flags & LDD_F_NEED_INDEX) {
556 rc = next_index(imap, INDEX_MAP_SIZE);
558 GOTO(out_up, rc = -ERANGE);
559 mti->mti_stripe_index = rc;
560 if (mti->mti_flags & LDD_F_SV_TYPE_MDT)
561 fsdb->fsdb_mdt_count ++;
564 if (mti->mti_stripe_index >= INDEX_MAP_SIZE * 8) {
565 LCONSOLE_ERROR_MSG(0x13f, "Server %s requested index %d, "
566 "but the max index is %d.\n",
567 mti->mti_svname, mti->mti_stripe_index,
569 GOTO(out_up, rc = -ERANGE);
572 if (test_bit(mti->mti_stripe_index, imap)) {
573 if ((mti->mti_flags & LDD_F_VIRGIN) &&
574 !(mti->mti_flags & LDD_F_WRITECONF)) {
575 LCONSOLE_ERROR_MSG(0x140, "Server %s requested index "
576 "%d, but that index is already in "
577 "use. Use --writeconf to force\n",
579 mti->mti_stripe_index);
580 GOTO(out_up, rc = -EADDRINUSE);
582 CDEBUG(D_MGS, "Server %s updating index %d\n",
583 mti->mti_svname, mti->mti_stripe_index);
584 GOTO(out_up, rc = EALREADY);
588 set_bit(mti->mti_stripe_index, imap);
589 clear_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags);
590 mutex_unlock(&fsdb->fsdb_mutex);
591 server_make_name(mti->mti_flags & ~(LDD_F_VIRGIN | LDD_F_WRITECONF),
592 mti->mti_stripe_index, mti->mti_fsname, mti->mti_svname);
594 CDEBUG(D_MGS, "Set index for %s to %d\n", mti->mti_svname,
595 mti->mti_stripe_index);
599 mutex_unlock(&fsdb->fsdb_mutex);
603 struct mgs_modify_lookup {
604 struct cfg_marker mml_marker;
608 static int mgs_modify_handler(const struct lu_env *env,
609 struct llog_handle *llh,
610 struct llog_rec_hdr *rec, void *data)
612 struct mgs_modify_lookup *mml = data;
613 struct cfg_marker *marker;
614 struct lustre_cfg *lcfg = REC_DATA(rec);
615 int cfg_len = REC_DATA_LEN(rec);
619 if (rec->lrh_type != OBD_CFG_REC) {
620 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
624 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
626 CERROR("Insane cfg\n");
630 /* We only care about markers */
631 if (lcfg->lcfg_command != LCFG_MARKER)
634 marker = lustre_cfg_buf(lcfg, 1);
635 if ((strcmp(mml->mml_marker.cm_comment, marker->cm_comment) == 0) &&
636 (strcmp(mml->mml_marker.cm_tgtname, marker->cm_tgtname) == 0) &&
637 !(marker->cm_flags & CM_SKIP)) {
638 /* Found a non-skipped marker match */
639 CDEBUG(D_MGS, "Changing rec %u marker %d %x->%x: %s %s\n",
640 rec->lrh_index, marker->cm_step,
641 marker->cm_flags, mml->mml_marker.cm_flags,
642 marker->cm_tgtname, marker->cm_comment);
643 /* Overwrite the old marker llog entry */
644 marker->cm_flags &= ~CM_EXCLUDE; /* in case we're unexcluding */
645 marker->cm_flags |= mml->mml_marker.cm_flags;
646 marker->cm_canceltime = mml->mml_marker.cm_canceltime;
647 /* Header and tail are added back to lrh_len in
648 llog_lvfs_write_rec */
649 rec->lrh_len = cfg_len;
650 rc = llog_write(env, llh, rec, NULL, 0, (void *)lcfg,
660 * Modify an existing config log record (for CM_SKIP or CM_EXCLUDE)
662 * 0 - modified successfully,
663 * 1 - no modification was done
666 static int mgs_modify(const struct lu_env *env, struct mgs_device *mgs,
667 struct fs_db *fsdb, struct mgs_target_info *mti,
668 char *logname, char *devname, char *comment, int flags)
670 struct llog_handle *loghandle;
671 struct llog_ctxt *ctxt;
672 struct mgs_modify_lookup *mml;
677 LASSERT(mutex_is_locked(&fsdb->fsdb_mutex));
678 CDEBUG(D_MGS, "modify %s/%s/%s fl=%x\n", logname, devname, comment,
681 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
682 LASSERT(ctxt != NULL);
683 rc = llog_open(env, ctxt, &loghandle, NULL, logname, LLOG_OPEN_EXISTS);
690 rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL);
694 if (llog_get_size(loghandle) <= 1)
695 GOTO(out_close, rc = 0);
699 GOTO(out_close, rc = -ENOMEM);
700 strcpy(mml->mml_marker.cm_comment, comment);
701 strcpy(mml->mml_marker.cm_tgtname, devname);
702 /* Modify mostly means cancel */
703 mml->mml_marker.cm_flags = flags;
704 mml->mml_marker.cm_canceltime = flags ? cfs_time_current_sec() : 0;
705 mml->mml_modified = 0;
706 rc = llog_process(env, loghandle, mgs_modify_handler, (void *)mml,
708 if (!rc && !mml->mml_modified)
713 llog_close(env, loghandle);
716 CERROR("%s: modify %s/%s failed: rc = %d\n",
717 mgs->mgs_obd->obd_name, mti->mti_svname, comment, rc);
722 /** This structure is passed to mgs_replace_handler */
723 struct mgs_replace_uuid_lookup {
724 /* Nids are replaced for this target device */
725 struct mgs_target_info target;
726 /* Temporary modified llog */
727 struct llog_handle *temp_llh;
728 /* Flag is set if in target block*/
729 int in_target_device;
730 /* Nids already added. Just skip (multiple nids) */
731 int device_nids_added;
732 /* Flag is set if this block should not be copied */
737 * Check: a) if block should be skipped
738 * b) is it target block
743 * \retval 0 should not to be skipped
744 * \retval 1 should to be skipped
746 static int check_markers(struct lustre_cfg *lcfg,
747 struct mgs_replace_uuid_lookup *mrul)
749 struct cfg_marker *marker;
751 /* Track markers. Find given device */
752 if (lcfg->lcfg_command == LCFG_MARKER) {
753 marker = lustre_cfg_buf(lcfg, 1);
754 /* Clean llog from records marked as CM_EXCLUDE.
755 CM_SKIP records are used for "active" command
756 and can be restored if needed */
757 if ((marker->cm_flags & (CM_EXCLUDE | CM_START)) ==
758 (CM_EXCLUDE | CM_START)) {
763 if ((marker->cm_flags & (CM_EXCLUDE | CM_END)) ==
764 (CM_EXCLUDE | CM_END)) {
769 if (strcmp(mrul->target.mti_svname, marker->cm_tgtname) == 0) {
770 LASSERT(!(marker->cm_flags & CM_START) ||
771 !(marker->cm_flags & CM_END));
772 if (marker->cm_flags & CM_START) {
773 mrul->in_target_device = 1;
774 mrul->device_nids_added = 0;
775 } else if (marker->cm_flags & CM_END)
776 mrul->in_target_device = 0;
783 static int record_lcfg(const struct lu_env *env, struct llog_handle *llh,
784 struct lustre_cfg *lcfg)
786 struct llog_rec_hdr rec;
792 LASSERT(llh->lgh_ctxt);
794 buflen = lustre_cfg_len(lcfg->lcfg_bufcount,
796 rec.lrh_len = llog_data_len(buflen);
797 rec.lrh_type = OBD_CFG_REC;
799 /* idx = -1 means append */
800 rc = llog_write(env, llh, &rec, NULL, 0, (void *)lcfg, -1);
802 CERROR("failed %d\n", rc);
806 static int record_base(const struct lu_env *env, struct llog_handle *llh,
807 char *cfgname, lnet_nid_t nid, int cmd,
808 char *s1, char *s2, char *s3, char *s4)
810 struct mgs_thread_info *mgi = mgs_env_info(env);
811 struct lustre_cfg *lcfg;
814 CDEBUG(D_MGS, "lcfg %s %#x %s %s %s %s\n", cfgname,
815 cmd, s1, s2, s3, s4);
817 lustre_cfg_bufs_reset(&mgi->mgi_bufs, cfgname);
819 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, s1);
821 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 2, s2);
823 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 3, s3);
825 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 4, s4);
827 lcfg = lustre_cfg_new(cmd, &mgi->mgi_bufs);
830 lcfg->lcfg_nid = nid;
832 rc = record_lcfg(env, llh, lcfg);
834 lustre_cfg_free(lcfg);
837 CERROR("error %d: lcfg %s %#x %s %s %s %s\n", rc, cfgname,
838 cmd, s1, s2, s3, s4);
843 static inline int record_add_uuid(const struct lu_env *env,
844 struct llog_handle *llh,
845 uint64_t nid, char *uuid)
847 return record_base(env, llh, NULL, nid, LCFG_ADD_UUID, uuid, 0, 0, 0);
850 static inline int record_add_conn(const struct lu_env *env,
851 struct llog_handle *llh,
852 char *devname, char *uuid)
854 return record_base(env, llh, devname, 0, LCFG_ADD_CONN, uuid, 0, 0, 0);
857 static inline int record_attach(const struct lu_env *env,
858 struct llog_handle *llh, char *devname,
859 char *type, char *uuid)
861 return record_base(env, llh,devname, 0, LCFG_ATTACH, type, uuid, 0, 0);
864 static inline int record_setup(const struct lu_env *env,
865 struct llog_handle *llh, char *devname,
866 char *s1, char *s2, char *s3, char *s4)
868 return record_base(env, llh, devname, 0, LCFG_SETUP, s1, s2, s3, s4);
872 * \retval <0 record processing error
873 * \retval n record is processed. No need copy original one.
874 * \retval 0 record is not processed.
876 static int process_command(const struct lu_env *env, struct lustre_cfg *lcfg,
877 struct mgs_replace_uuid_lookup *mrul)
884 if (lcfg->lcfg_command == LCFG_ADD_UUID) {
885 /* LCFG_ADD_UUID command found. Let's skip original command
886 and add passed nids */
887 ptr = mrul->target.mti_params;
888 while (class_parse_nid(ptr, &nid, &ptr) == 0) {
889 CDEBUG(D_MGS, "add nid %s with uuid %s, "
890 "device %s\n", libcfs_nid2str(nid),
891 mrul->target.mti_params,
892 mrul->target.mti_svname);
893 rc = record_add_uuid(env,
895 mrul->target.mti_params);
900 if (nids_added == 0) {
901 CERROR("No new nids were added, nid %s with uuid %s, "
902 "device %s\n", libcfs_nid2str(nid),
903 mrul->target.mti_params,
904 mrul->target.mti_svname);
907 mrul->device_nids_added = 1;
913 if (mrul->device_nids_added && lcfg->lcfg_command == LCFG_SETUP) {
914 /* LCFG_SETUP command found. UUID should be changed */
915 rc = record_setup(env,
917 /* devname the same */
918 lustre_cfg_string(lcfg, 0),
919 /* s1 is not changed */
920 lustre_cfg_string(lcfg, 1),
921 /* new uuid should be
923 mrul->target.mti_params,
924 /* s3 is not changed */
925 lustre_cfg_string(lcfg, 3),
926 /* s4 is not changed */
927 lustre_cfg_string(lcfg, 4));
931 /* Another commands in target device block */
936 * Handler that called for every record in llog.
937 * Records are processed in order they placed in llog.
939 * \param[in] llh log to be processed
940 * \param[in] rec current record
941 * \param[in] data mgs_replace_uuid_lookup structure
945 static int mgs_replace_handler(const struct lu_env *env,
946 struct llog_handle *llh,
947 struct llog_rec_hdr *rec,
950 struct llog_rec_hdr local_rec = *rec;
951 struct mgs_replace_uuid_lookup *mrul;
952 struct lustre_cfg *lcfg = REC_DATA(rec);
953 int cfg_len = REC_DATA_LEN(rec);
957 mrul = (struct mgs_replace_uuid_lookup *)data;
959 if (rec->lrh_type != OBD_CFG_REC) {
960 CERROR("unhandled lrh_type: %#x, cmd %x %s %s\n",
961 rec->lrh_type, lcfg->lcfg_command,
962 lustre_cfg_string(lcfg, 0),
963 lustre_cfg_string(lcfg, 1));
967 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
969 /* Do not copy any invalidated records */
970 GOTO(skip_out, rc = 0);
973 rc = check_markers(lcfg, mrul);
974 if (rc || mrul->skip_it)
975 GOTO(skip_out, rc = 0);
977 /* Write to new log all commands outside target device block */
978 if (!mrul->in_target_device)
979 GOTO(copy_out, rc = 0);
981 /* Skip all other LCFG_ADD_UUID and LCFG_ADD_CONN records
982 (failover nids) for this target, assuming that if then
983 primary is changing then so is the failover */
984 if (mrul->device_nids_added &&
985 (lcfg->lcfg_command == LCFG_ADD_UUID ||
986 lcfg->lcfg_command == LCFG_ADD_CONN))
987 GOTO(skip_out, rc = 0);
989 rc = process_command(env, lcfg, mrul);
996 /* Record is placed in temporary llog as is */
997 local_rec.lrh_len -= sizeof(*rec) + sizeof(struct llog_rec_tail);
998 rc = llog_write(env, mrul->temp_llh, &local_rec, NULL, 0,
1001 CDEBUG(D_MGS, "Copied idx=%d, rc=%d, len=%d, cmd %x %s %s\n",
1002 rec->lrh_index, rc, rec->lrh_len, lcfg->lcfg_command,
1003 lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));
1007 CDEBUG(D_MGS, "Skipped idx=%d, rc=%d, len=%d, cmd %x %s %s\n",
1008 rec->lrh_index, rc, rec->lrh_len, lcfg->lcfg_command,
1009 lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));
1013 static int mgs_backup_llog(const struct lu_env *env,
1014 struct obd_device *mgs,
1015 char *fsname, char *backup)
1017 struct obd_uuid *uuid;
1018 struct llog_handle *orig_llh, *bak_llh;
1019 struct llog_ctxt *lctxt;
1023 lctxt = llog_get_context(mgs, LLOG_CONFIG_ORIG_CTXT);
1025 CERROR("%s: missing llog context\n", mgs->obd_name);
1026 GOTO(out, rc = -EINVAL);
1029 /* Make sure there's no old backup log */
1030 rc = llog_erase(env, lctxt, NULL, backup);
1031 if (rc < 0 && rc != -ENOENT)
1034 /* open backup log */
1035 rc = llog_open_create(env, lctxt, &bak_llh, NULL, backup);
1037 CERROR("%s: backup logfile open %s: rc = %d\n",
1038 mgs->obd_name, backup, rc);
1042 /* set the log header uuid */
1043 OBD_ALLOC_PTR(uuid);
1045 GOTO(out_put, rc = -ENOMEM);
1046 obd_str2uuid(uuid, backup);
1047 rc = llog_init_handle(env, bak_llh, LLOG_F_IS_PLAIN, uuid);
1050 GOTO(out_close1, rc);
1052 /* open original log */
1053 rc = llog_open(env, lctxt, &orig_llh, NULL, fsname,
1058 GOTO(out_close1, rc);
1061 rc = llog_init_handle(env, orig_llh, LLOG_F_IS_PLAIN, NULL);
1063 GOTO(out_close2, rc);
1065 /* Copy remote log */
1066 rc = llog_process(env, orig_llh, llog_copy_handler,
1067 (void *)bak_llh, NULL);
1070 rc2 = llog_close(env, orig_llh);
1074 rc2 = llog_close(env, bak_llh);
1079 llog_ctxt_put(lctxt);
1082 CERROR("%s: Failed to backup log %s: rc = %d\n",
1083 mgs->obd_name, fsname, rc);
1087 static int mgs_log_is_empty(const struct lu_env *env, struct mgs_device *mgs,
1090 static int mgs_replace_nids_log(const struct lu_env *env,
1091 struct obd_device *mgs, struct fs_db *fsdb,
1092 char *logname, char *devname, char *nids)
1094 struct llog_handle *orig_llh, *backup_llh;
1095 struct llog_ctxt *ctxt;
1096 struct mgs_replace_uuid_lookup *mrul;
1097 struct mgs_device *mgs_dev = lu2mgs_dev(mgs->obd_lu_dev);
1102 CDEBUG(D_MGS, "Replace nids for %s in %s\n", devname, logname);
1104 ctxt = llog_get_context(mgs, LLOG_CONFIG_ORIG_CTXT);
1105 LASSERT(ctxt != NULL);
1107 if (mgs_log_is_empty(env, mgs_dev, logname)) {
1108 /* Log is empty. Nothing to replace */
1109 GOTO(out_put, rc = 0);
1112 OBD_ALLOC(backup, strlen(logname) + strlen(".bak") + 1);
1114 GOTO(out_put, rc = -ENOMEM);
1116 sprintf(backup, "%s.bak", logname);
1118 rc = mgs_backup_llog(env, mgs, logname, backup);
1120 CERROR("%s: can't make backup for %s: rc = %d\n",
1121 mgs->obd_name, logname, rc);
1125 /* Now erase original log file. Connections are not allowed.
1126 Backup is already saved */
1127 rc = llog_erase(env, ctxt, NULL, logname);
1128 if (rc < 0 && rc != -ENOENT)
1131 /* open local log */
1132 rc = llog_open_create(env, ctxt, &orig_llh, NULL, logname);
1134 GOTO(out_restore, rc);
1136 rc = llog_init_handle(env, orig_llh, LLOG_F_IS_PLAIN, NULL);
1138 GOTO(out_closel, rc);
1140 /* open backup llog */
1141 rc = llog_open(env, ctxt, &backup_llh, NULL, backup,
1144 GOTO(out_closel, rc);
1146 rc = llog_init_handle(env, backup_llh, LLOG_F_IS_PLAIN, NULL);
1148 GOTO(out_close, rc);
1150 if (llog_get_size(backup_llh) <= 1)
1151 GOTO(out_close, rc = 0);
1153 OBD_ALLOC_PTR(mrul);
1155 GOTO(out_close, rc = -ENOMEM);
1156 /* devname is only needed information to replace UUID records */
1157 strncpy(mrul->target.mti_svname, devname, MTI_NAME_MAXLEN);
1158 /* parse nids later */
1159 strncpy(mrul->target.mti_params, nids, MTI_PARAM_MAXLEN);
1160 /* Copy records to this temporary llog */
1161 mrul->temp_llh = orig_llh;
1163 rc = llog_process(env, backup_llh, mgs_replace_handler,
1164 (void *)mrul, NULL);
1167 rc2 = llog_close(NULL, backup_llh);
1171 rc2 = llog_close(NULL, orig_llh);
1177 CERROR("%s: llog should be restored: rc = %d\n",
1179 rc2 = mgs_backup_llog(env, mgs, backup, logname);
1181 CERROR("%s: can't restore backup %s: rc = %d\n",
1182 mgs->obd_name, logname, rc2);
1186 OBD_FREE(backup, strlen(backup) + 1);
1189 llog_ctxt_put(ctxt);
1192 CERROR("%s: failed to replace nids in log %s: rc = %d\n",
1193 mgs->obd_name, logname, rc);
1199 * Parse device name and get file system name and/or device index
1201 * \param[in] devname device name (ex. lustre-MDT0000)
1202 * \param[out] fsname file system name(optional)
1203 * \param[out] index device index(optional)
1207 static int mgs_parse_devname(char *devname, char *fsname, __u32 *index)
1212 /* Extract fsname */
1213 ptr = strrchr(devname, '-');
1217 CDEBUG(D_MGS, "Device name %s without fsname\n",
1221 memset(fsname, 0, MTI_NAME_MAXLEN);
1222 strncpy(fsname, devname, ptr - devname);
1223 fsname[MTI_NAME_MAXLEN - 1] = 0;
1227 if (server_name2index(ptr, index, NULL) < 0) {
1228 CDEBUG(D_MGS, "Device name with wrong index\n");
1236 static int only_mgs_is_running(struct obd_device *mgs_obd)
1238 /* TDB: Is global variable with devices count exists? */
1239 int num_devices = get_devices_count();
1240 /* osd, MGS and MGC + self_export
1241 (wc -l /proc/fs/lustre/devices <= 2) && (num_exports <= 2) */
1242 return (num_devices <= 3) && (mgs_obd->obd_num_exports <= 2);
1245 static int name_create_mdt(char **logname, char *fsname, int i)
1249 sprintf(mdt_index, "-MDT%04x", i);
1250 return name_create(logname, fsname, mdt_index);
1254 * Replace nids for \a device to \a nids values
1256 * \param obd MGS obd device
1257 * \param devname nids need to be replaced for this device
1258 * (ex. lustre-OST0000)
1259 * \param nids nids list (ex. nid1,nid2,nid3)
1263 int mgs_replace_nids(const struct lu_env *env,
1264 struct mgs_device *mgs,
1265 char *devname, char *nids)
1267 /* Assume fsname is part of device name */
1268 char fsname[MTI_NAME_MAXLEN];
1275 struct obd_device *mgs_obd = mgs->mgs_obd;
1278 /* We can only change NIDs if no other nodes are connected */
1279 spin_lock(&mgs_obd->obd_dev_lock);
1280 conn_state = mgs_obd->obd_no_conn;
1281 mgs_obd->obd_no_conn = 1;
1282 spin_unlock(&mgs_obd->obd_dev_lock);
1284 /* We can not change nids if not only MGS is started */
1285 if (!only_mgs_is_running(mgs_obd)) {
1286 CERROR("Only MGS is allowed to be started\n");
1287 GOTO(out, rc = -EINPROGRESS);
1290 /* Get fsname and index*/
1291 rc = mgs_parse_devname(devname, fsname, &index);
1295 rc = mgs_find_or_make_fsdb(env, mgs, fsname, &fsdb);
1297 CERROR("%s: can't find fsdb: rc = %d\n", fsname, rc);
1301 /* Process client llogs */
1302 name_create(&logname, fsname, "-client");
1303 rc = mgs_replace_nids_log(env, mgs_obd, fsdb, logname, devname, nids);
1304 name_destroy(&logname);
1306 CERROR("%s: error while replacing NIDs for %s: rc = %d\n",
1307 fsname, devname, rc);
1311 /* Process MDT llogs */
1312 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
1313 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
1315 name_create_mdt(&logname, fsname, i);
1316 rc = mgs_replace_nids_log(env, mgs_obd, fsdb, logname, devname, nids);
1317 name_destroy(&logname);
1323 spin_lock(&mgs_obd->obd_dev_lock);
1324 mgs_obd->obd_no_conn = conn_state;
1325 spin_unlock(&mgs_obd->obd_dev_lock);
1330 static int record_lov_setup(const struct lu_env *env, struct llog_handle *llh,
1331 char *devname, struct lov_desc *desc)
1333 struct mgs_thread_info *mgi = mgs_env_info(env);
1334 struct lustre_cfg *lcfg;
1337 lustre_cfg_bufs_reset(&mgi->mgi_bufs, devname);
1338 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, desc, sizeof(*desc));
1339 lcfg = lustre_cfg_new(LCFG_SETUP, &mgi->mgi_bufs);
1342 rc = record_lcfg(env, llh, lcfg);
1344 lustre_cfg_free(lcfg);
1348 static int record_lmv_setup(const struct lu_env *env, struct llog_handle *llh,
1349 char *devname, struct lmv_desc *desc)
1351 struct mgs_thread_info *mgi = mgs_env_info(env);
1352 struct lustre_cfg *lcfg;
1355 lustre_cfg_bufs_reset(&mgi->mgi_bufs, devname);
1356 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, desc, sizeof(*desc));
1357 lcfg = lustre_cfg_new(LCFG_SETUP, &mgi->mgi_bufs);
1359 rc = record_lcfg(env, llh, lcfg);
1361 lustre_cfg_free(lcfg);
1365 static inline int record_mdc_add(const struct lu_env *env,
1366 struct llog_handle *llh,
1367 char *logname, char *mdcuuid,
1368 char *mdtuuid, char *index,
1371 return record_base(env,llh,logname,0,LCFG_ADD_MDC,
1372 mdtuuid,index,gen,mdcuuid);
1375 static inline int record_lov_add(const struct lu_env *env,
1376 struct llog_handle *llh,
1377 char *lov_name, char *ost_uuid,
1378 char *index, char *gen)
1380 return record_base(env,llh,lov_name,0,LCFG_LOV_ADD_OBD,
1381 ost_uuid, index, gen, 0);
1384 static inline int record_mount_opt(const struct lu_env *env,
1385 struct llog_handle *llh,
1386 char *profile, char *lov_name,
1389 return record_base(env,llh,NULL,0,LCFG_MOUNTOPT,
1390 profile,lov_name,mdc_name,0);
1393 static int record_marker(const struct lu_env *env,
1394 struct llog_handle *llh,
1395 struct fs_db *fsdb, __u32 flags,
1396 char *tgtname, char *comment)
1398 struct mgs_thread_info *mgi = mgs_env_info(env);
1399 struct lustre_cfg *lcfg;
1403 if (flags & CM_START)
1405 mgi->mgi_marker.cm_step = fsdb->fsdb_gen;
1406 mgi->mgi_marker.cm_flags = flags;
1407 mgi->mgi_marker.cm_vers = LUSTRE_VERSION_CODE;
1408 cplen = strlcpy(mgi->mgi_marker.cm_tgtname, tgtname,
1409 sizeof(mgi->mgi_marker.cm_tgtname));
1410 if (cplen >= sizeof(mgi->mgi_marker.cm_tgtname))
1412 cplen = strlcpy(mgi->mgi_marker.cm_comment, comment,
1413 sizeof(mgi->mgi_marker.cm_comment));
1414 if (cplen >= sizeof(mgi->mgi_marker.cm_comment))
1416 mgi->mgi_marker.cm_createtime = cfs_time_current_sec();
1417 mgi->mgi_marker.cm_canceltime = 0;
1418 lustre_cfg_bufs_reset(&mgi->mgi_bufs, NULL);
1419 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, &mgi->mgi_marker,
1420 sizeof(mgi->mgi_marker));
1421 lcfg = lustre_cfg_new(LCFG_MARKER, &mgi->mgi_bufs);
1424 rc = record_lcfg(env, llh, lcfg);
1426 lustre_cfg_free(lcfg);
1430 static int record_start_log(const struct lu_env *env, struct mgs_device *mgs,
1431 struct llog_handle **llh, char *name)
1433 static struct obd_uuid cfg_uuid = { .uuid = "config_uuid" };
1434 struct llog_ctxt *ctxt;
1438 GOTO(out, rc = -EBUSY);
1440 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
1442 GOTO(out, rc = -ENODEV);
1443 LASSERT(ctxt->loc_obd == mgs->mgs_obd);
1445 rc = llog_open_create(env, ctxt, llh, NULL, name);
1448 rc = llog_init_handle(env, *llh, LLOG_F_IS_PLAIN, &cfg_uuid);
1450 llog_close(env, *llh);
1452 llog_ctxt_put(ctxt);
1455 CERROR("%s: can't start log %s: rc = %d\n",
1456 mgs->mgs_obd->obd_name, name, rc);
1462 static int record_end_log(const struct lu_env *env, struct llog_handle **llh)
1466 rc = llog_close(env, *llh);
1472 static int mgs_log_is_empty(const struct lu_env *env,
1473 struct mgs_device *mgs, char *name)
1475 struct llog_handle *llh;
1476 struct llog_ctxt *ctxt;
1479 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
1480 LASSERT(ctxt != NULL);
1481 rc = llog_open(env, ctxt, &llh, NULL, name, LLOG_OPEN_EXISTS);
1488 rc = llog_init_handle(env, llh, LLOG_F_IS_PLAIN, NULL);
1490 GOTO(out_close, rc);
1491 rc = llog_get_size(llh);
1494 llog_close(env, llh);
1496 llog_ctxt_put(ctxt);
1497 /* header is record 1 */
1501 /******************** config "macros" *********************/
1503 /* write an lcfg directly into a log (with markers) */
1504 static int mgs_write_log_direct(const struct lu_env *env,
1505 struct mgs_device *mgs, struct fs_db *fsdb,
1506 char *logname, struct lustre_cfg *lcfg,
1507 char *devname, char *comment)
1509 struct llog_handle *llh = NULL;
1516 rc = record_start_log(env, mgs, &llh, logname);
1520 /* FIXME These should be a single journal transaction */
1521 rc = record_marker(env, llh, fsdb, CM_START, devname, comment);
1524 rc = record_lcfg(env, llh, lcfg);
1527 rc = record_marker(env, llh, fsdb, CM_END, devname, comment);
1531 record_end_log(env, &llh);
1535 /* write the lcfg in all logs for the given fs */
1536 int mgs_write_log_direct_all(const struct lu_env *env,
1537 struct mgs_device *mgs,
1539 struct mgs_target_info *mti,
1540 struct lustre_cfg *lcfg,
1541 char *devname, char *comment,
1545 struct mgs_direntry *dirent, *n;
1546 char *fsname = mti->mti_fsname;
1548 int rc = 0, len = strlen(fsname);
1551 /* We need to set params for any future logs
1552 as well. FIXME Append this file to every new log.
1553 Actually, we should store as params (text), not llogs. Or
1555 rc = name_create(&logname, fsname, "-params");
1558 if (mgs_log_is_empty(env, mgs, logname)) {
1559 struct llog_handle *llh = NULL;
1560 rc = record_start_log(env, mgs, &llh, logname);
1561 record_end_log(env, &llh);
1563 name_destroy(&logname);
1567 /* Find all the logs in the CONFIGS directory */
1568 rc = class_dentry_readdir(env, mgs, &list);
1572 /* Could use fsdb index maps instead of directory listing */
1573 cfs_list_for_each_entry_safe(dirent, n, &list, list) {
1574 cfs_list_del(&dirent->list);
1575 /* don't write to sptlrpc rule log */
1576 if (strstr(dirent->name, "-sptlrpc") != NULL)
1579 /* caller wants write server logs only */
1580 if (server_only && strstr(dirent->name, "-client") != NULL)
1583 if (strncmp(fsname, dirent->name, len) == 0) {
1584 CDEBUG(D_MGS, "Changing log %s\n", dirent->name);
1585 /* Erase any old settings of this same parameter */
1586 rc = mgs_modify(env, mgs, fsdb, mti, dirent->name,
1587 devname, comment, CM_SKIP);
1589 CERROR("%s: Can't modify llog %s: rc = %d\n",
1590 mgs->mgs_obd->obd_name, dirent->name,rc);
1591 /* Write the new one */
1593 rc = mgs_write_log_direct(env, mgs, fsdb,
1598 CERROR("%s: writing log %s: rc = %d\n",
1599 mgs->mgs_obd->obd_name,
1604 mgs_direntry_free(dirent);
1610 static int mgs_write_log_osp_to_mdt(const struct lu_env *env,
1611 struct mgs_device *mgs,
1613 struct mgs_target_info *mti,
1614 int index, char *logname);
1615 static int mgs_write_log_osc_to_lov(const struct lu_env *env,
1616 struct mgs_device *mgs,
1618 struct mgs_target_info *mti,
1619 char *logname, char *suffix, char *lovname,
1620 enum lustre_sec_part sec_part, int flags);
1621 static int name_create_mdt_and_lov(char **logname, char **lovname,
1622 struct fs_db *fsdb, int i);
1624 static int add_param(char *params, char *key, char *val)
1626 char *start = params + strlen(params);
1627 char *end = params + sizeof(((struct mgs_target_info *)0)->mti_params);
1631 keylen = strlen(key);
1632 if (start + 1 + keylen + strlen(val) >= end) {
1633 CERROR("params are too long: %s %s%s\n",
1634 params, key != NULL ? key : "", val);
1638 sprintf(start, " %s%s", key != NULL ? key : "", val);
1643 * Walk through client config log record and convert the related records
1646 static int mgs_steal_client_llog_handler(const struct lu_env *env,
1647 struct llog_handle *llh,
1648 struct llog_rec_hdr *rec, void *data)
1650 struct mgs_device *mgs;
1651 struct obd_device *obd;
1652 struct mgs_target_info *mti, *tmti;
1654 int cfg_len = rec->lrh_len;
1655 char *cfg_buf = (char*) (rec + 1);
1656 struct lustre_cfg *lcfg;
1658 struct llog_handle *mdt_llh = NULL;
1659 static int got_an_osc_or_mdc = 0;
1660 /* 0: not found any osc/mdc;
1664 static int last_step = -1;
1669 mti = ((struct temp_comp*)data)->comp_mti;
1670 tmti = ((struct temp_comp*)data)->comp_tmti;
1671 fsdb = ((struct temp_comp*)data)->comp_fsdb;
1672 obd = ((struct temp_comp *)data)->comp_obd;
1673 mgs = lu2mgs_dev(obd->obd_lu_dev);
1676 if (rec->lrh_type != OBD_CFG_REC) {
1677 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
1681 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
1683 CERROR("Insane cfg\n");
1687 lcfg = (struct lustre_cfg *)cfg_buf;
1689 if (lcfg->lcfg_command == LCFG_MARKER) {
1690 struct cfg_marker *marker;
1691 marker = lustre_cfg_buf(lcfg, 1);
1692 if (!strncmp(marker->cm_comment, "add osc", 7) &&
1693 (marker->cm_flags & CM_START) &&
1694 !(marker->cm_flags & CM_SKIP)) {
1695 got_an_osc_or_mdc = 1;
1696 cplen = strlcpy(tmti->mti_svname, marker->cm_tgtname,
1697 sizeof(tmti->mti_svname));
1698 if (cplen >= sizeof(tmti->mti_svname))
1700 rc = record_start_log(env, mgs, &mdt_llh,
1704 rc = record_marker(env, mdt_llh, fsdb, CM_START,
1705 mti->mti_svname, "add osc(copied)");
1706 record_end_log(env, &mdt_llh);
1707 last_step = marker->cm_step;
1710 if (!strncmp(marker->cm_comment, "add osc", 7) &&
1711 (marker->cm_flags & CM_END) &&
1712 !(marker->cm_flags & CM_SKIP)) {
1713 LASSERT(last_step == marker->cm_step);
1715 got_an_osc_or_mdc = 0;
1716 memset(tmti, 0, sizeof(*tmti));
1717 rc = record_start_log(env, mgs, &mdt_llh,
1721 rc = record_marker(env, mdt_llh, fsdb, CM_END,
1722 mti->mti_svname, "add osc(copied)");
1723 record_end_log(env, &mdt_llh);
1726 if (!strncmp(marker->cm_comment, "add mdc", 7) &&
1727 (marker->cm_flags & CM_START) &&
1728 !(marker->cm_flags & CM_SKIP)) {
1729 got_an_osc_or_mdc = 2;
1730 last_step = marker->cm_step;
1731 memcpy(tmti->mti_svname, marker->cm_tgtname,
1732 strlen(marker->cm_tgtname));
1736 if (!strncmp(marker->cm_comment, "add mdc", 7) &&
1737 (marker->cm_flags & CM_END) &&
1738 !(marker->cm_flags & CM_SKIP)) {
1739 LASSERT(last_step == marker->cm_step);
1741 got_an_osc_or_mdc = 0;
1742 memset(tmti, 0, sizeof(*tmti));
1747 if (got_an_osc_or_mdc == 0 || last_step < 0)
1750 if (lcfg->lcfg_command == LCFG_ADD_UUID) {
1751 uint64_t nodenid = lcfg->lcfg_nid;
1753 if (strlen(tmti->mti_uuid) == 0) {
1754 /* target uuid not set, this config record is before
1755 * LCFG_SETUP, this nid is one of target node nid.
1757 tmti->mti_nids[tmti->mti_nid_count] = nodenid;
1758 tmti->mti_nid_count++;
1760 /* failover node nid */
1761 rc = add_param(tmti->mti_params, PARAM_FAILNODE,
1762 libcfs_nid2str(nodenid));
1768 if (lcfg->lcfg_command == LCFG_SETUP) {
1771 target = lustre_cfg_string(lcfg, 1);
1772 memcpy(tmti->mti_uuid, target, strlen(target));
1776 /* ignore client side sptlrpc_conf_log */
1777 if (lcfg->lcfg_command == LCFG_SPTLRPC_CONF)
1780 if (lcfg->lcfg_command == LCFG_ADD_MDC) {
1783 if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1)
1786 memcpy(tmti->mti_fsname, mti->mti_fsname,
1787 strlen(mti->mti_fsname));
1788 tmti->mti_stripe_index = index;
1790 rc = mgs_write_log_osp_to_mdt(env, mgs, fsdb, tmti,
1791 mti->mti_stripe_index,
1793 memset(tmti, 0, sizeof(*tmti));
1797 if (lcfg->lcfg_command == LCFG_LOV_ADD_OBD) {
1800 char *logname, *lovname;
1802 rc = name_create_mdt_and_lov(&logname, &lovname, fsdb,
1803 mti->mti_stripe_index);
1806 sprintf(mdt_index, "-MDT%04x", mti->mti_stripe_index);
1808 if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1) {
1809 name_destroy(&logname);
1810 name_destroy(&lovname);
1814 tmti->mti_stripe_index = index;
1815 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, tmti, logname,
1818 name_destroy(&logname);
1819 name_destroy(&lovname);
1825 /* fsdb->fsdb_mutex is already held in mgs_write_log_target*/
1826 /* stealed from mgs_get_fsdb_from_llog*/
1827 static int mgs_steal_llog_for_mdt_from_client(const struct lu_env *env,
1828 struct mgs_device *mgs,
1830 struct temp_comp* comp)
1832 struct llog_handle *loghandle;
1833 struct mgs_target_info *tmti;
1834 struct llog_ctxt *ctxt;
1839 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
1840 LASSERT(ctxt != NULL);
1842 OBD_ALLOC_PTR(tmti);
1844 GOTO(out_ctxt, rc = -ENOMEM);
1846 comp->comp_tmti = tmti;
1847 comp->comp_obd = mgs->mgs_obd;
1849 rc = llog_open(env, ctxt, &loghandle, NULL, client_name,
1857 rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL);
1859 GOTO(out_close, rc);
1861 rc = llog_process_or_fork(env, loghandle, mgs_steal_client_llog_handler,
1862 (void *)comp, NULL, false);
1863 CDEBUG(D_MGS, "steal llog re = %d\n", rc);
1865 llog_close(env, loghandle);
1869 llog_ctxt_put(ctxt);
1873 /* lmv is the second thing for client logs */
1874 /* copied from mgs_write_log_lov. Please refer to that. */
1875 static int mgs_write_log_lmv(const struct lu_env *env,
1876 struct mgs_device *mgs,
1878 struct mgs_target_info *mti,
1879 char *logname, char *lmvname)
1881 struct llog_handle *llh = NULL;
1882 struct lmv_desc *lmvdesc;
1887 CDEBUG(D_MGS, "Writing lmv(%s) log for %s\n", lmvname,logname);
1889 OBD_ALLOC_PTR(lmvdesc);
1890 if (lmvdesc == NULL)
1892 lmvdesc->ld_active_tgt_count = 0;
1893 lmvdesc->ld_tgt_count = 0;
1894 sprintf((char*)lmvdesc->ld_uuid.uuid, "%s_UUID", lmvname);
1895 uuid = (char *)lmvdesc->ld_uuid.uuid;
1897 rc = record_start_log(env, mgs, &llh, logname);
1900 rc = record_marker(env, llh, fsdb, CM_START, lmvname, "lmv setup");
1903 rc = record_attach(env, llh, lmvname, "lmv", uuid);
1906 rc = record_lmv_setup(env, llh, lmvname, lmvdesc);
1909 rc = record_marker(env, llh, fsdb, CM_END, lmvname, "lmv setup");
1913 record_end_log(env, &llh);
1915 OBD_FREE_PTR(lmvdesc);
1919 /* lov is the first thing in the mdt and client logs */
1920 static int mgs_write_log_lov(const struct lu_env *env, struct mgs_device *mgs,
1921 struct fs_db *fsdb, struct mgs_target_info *mti,
1922 char *logname, char *lovname)
1924 struct llog_handle *llh = NULL;
1925 struct lov_desc *lovdesc;
1930 CDEBUG(D_MGS, "Writing lov(%s) log for %s\n", lovname, logname);
1933 #01 L attach 0:lov_mdsA 1:lov 2:71ccb_lov_mdsA_19f961a9e1
1934 #02 L lov_setup 0:lov_mdsA 1:(struct lov_desc)
1935 uuid=lov1_UUID, stripe count=1, size=1048576, offset=0, pattern=0
1938 /* FIXME just make lov_setup accept empty desc (put uuid in buf 2) */
1939 OBD_ALLOC_PTR(lovdesc);
1940 if (lovdesc == NULL)
1942 lovdesc->ld_magic = LOV_DESC_MAGIC;
1943 lovdesc->ld_tgt_count = 0;
1944 /* Defaults. Can be changed later by lcfg config_param */
1945 lovdesc->ld_default_stripe_count = 1;
1946 lovdesc->ld_pattern = LOV_PATTERN_RAID0;
1947 lovdesc->ld_default_stripe_size = 1024 * 1024;
1948 lovdesc->ld_default_stripe_offset = -1;
1949 lovdesc->ld_qos_maxage = QOS_DEFAULT_MAXAGE;
1950 sprintf((char*)lovdesc->ld_uuid.uuid, "%s_UUID", lovname);
1951 /* can these be the same? */
1952 uuid = (char *)lovdesc->ld_uuid.uuid;
1954 /* This should always be the first entry in a log.
1955 rc = mgs_clear_log(obd, logname); */
1956 rc = record_start_log(env, mgs, &llh, logname);
1959 /* FIXME these should be a single journal transaction */
1960 rc = record_marker(env, llh, fsdb, CM_START, lovname, "lov setup");
1963 rc = record_attach(env, llh, lovname, "lov", uuid);
1966 rc = record_lov_setup(env, llh, lovname, lovdesc);
1969 rc = record_marker(env, llh, fsdb, CM_END, lovname, "lov setup");
1974 record_end_log(env, &llh);
1976 OBD_FREE_PTR(lovdesc);
1980 /* add failnids to open log */
1981 static int mgs_write_log_failnids(const struct lu_env *env,
1982 struct mgs_target_info *mti,
1983 struct llog_handle *llh,
1986 char *failnodeuuid = NULL;
1987 char *ptr = mti->mti_params;
1992 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) nal=90 0: 1:uml1_UUID
1993 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
1994 #05 L setup 0:OSC_uml1_ost1_mdsA 1:ost1_UUID 2:uml1_UUID
1995 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) nal=90 0: 1:uml2_UUID
1996 #0x L add_uuid nid=2@elan(0x1000000000002) nal=90 0: 1:uml2_UUID
1997 #07 L add_conn 0:OSC_uml1_ost1_mdsA 1:uml2_UUID
2000 /* Pull failnid info out of params string */
2001 while (class_find_param(ptr, PARAM_FAILNODE, &ptr) == 0) {
2002 while (class_parse_nid(ptr, &nid, &ptr) == 0) {
2003 if (failnodeuuid == NULL) {
2004 /* We don't know the failover node name,
2005 so just use the first nid as the uuid */
2006 rc = name_create(&failnodeuuid,
2007 libcfs_nid2str(nid), "");
2011 CDEBUG(D_MGS, "add nid %s for failover uuid %s, "
2012 "client %s\n", libcfs_nid2str(nid),
2013 failnodeuuid, cliname);
2014 rc = record_add_uuid(env, llh, nid, failnodeuuid);
2017 rc = record_add_conn(env, llh, cliname, failnodeuuid);
2020 name_destroy(&failnodeuuid);
2024 static int mgs_write_log_mdc_to_lmv(const struct lu_env *env,
2025 struct mgs_device *mgs,
2027 struct mgs_target_info *mti,
2028 char *logname, char *lmvname)
2030 struct llog_handle *llh = NULL;
2031 char *mdcname = NULL;
2032 char *nodeuuid = NULL;
2033 char *mdcuuid = NULL;
2034 char *lmvuuid = NULL;
2039 if (mgs_log_is_empty(env, mgs, logname)) {
2040 CERROR("log is empty! Logical error\n");
2044 CDEBUG(D_MGS, "adding mdc for %s to log %s:lmv(%s)\n",
2045 mti->mti_svname, logname, lmvname);
2047 rc = name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
2050 rc = name_create(&mdcname, mti->mti_svname, "-mdc");
2053 rc = name_create(&mdcuuid, mdcname, "_UUID");
2056 rc = name_create(&lmvuuid, lmvname, "_UUID");
2060 rc = record_start_log(env, mgs, &llh, logname);
2063 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
2067 for (i = 0; i < mti->mti_nid_count; i++) {
2068 CDEBUG(D_MGS, "add nid %s for mdt\n",
2069 libcfs_nid2str(mti->mti_nids[i]));
2071 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
2076 rc = record_attach(env, llh, mdcname, LUSTRE_MDC_NAME, lmvuuid);
2079 rc = record_setup(env, llh, mdcname, mti->mti_uuid, nodeuuid, 0, 0);
2082 rc = mgs_write_log_failnids(env, mti, llh, mdcname);
2085 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
2086 rc = record_mdc_add(env, llh, lmvname, mdcuuid, mti->mti_uuid,
2090 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname,
2095 record_end_log(env, &llh);
2097 name_destroy(&lmvuuid);
2098 name_destroy(&mdcuuid);
2099 name_destroy(&mdcname);
2100 name_destroy(&nodeuuid);
2104 static inline int name_create_lov(char **lovname, char *mdtname,
2105 struct fs_db *fsdb, int index)
2108 if (index == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2109 return name_create(lovname, fsdb->fsdb_name, "-mdtlov");
2111 return name_create(lovname, mdtname, "-mdtlov");
2114 static int name_create_mdt_and_lov(char **logname, char **lovname,
2115 struct fs_db *fsdb, int i)
2119 rc = name_create_mdt(logname, fsdb->fsdb_name, i);
2123 if (i == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2124 rc = name_create(lovname, fsdb->fsdb_name, "-mdtlov");
2126 rc = name_create(lovname, *logname, "-mdtlov");
2128 name_destroy(logname);
2134 static inline int name_create_mdt_osc(char **oscname, char *ostname,
2135 struct fs_db *fsdb, int i)
2139 if (i == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2140 sprintf(suffix, "-osc");
2142 sprintf(suffix, "-osc-MDT%04x", i);
2143 return name_create(oscname, ostname, suffix);
2146 /* add new mdc to already existent MDS */
2147 static int mgs_write_log_osp_to_mdt(const struct lu_env *env,
2148 struct mgs_device *mgs,
2150 struct mgs_target_info *mti,
2151 int mdt_index, char *logname)
2153 struct llog_handle *llh = NULL;
2154 char *nodeuuid = NULL;
2155 char *ospname = NULL;
2156 char *lovuuid = NULL;
2157 char *mdtuuid = NULL;
2158 char *svname = NULL;
2159 char *mdtname = NULL;
2160 char *lovname = NULL;
2165 if (mgs_log_is_empty(env, mgs, mti->mti_svname)) {
2166 CERROR("log is empty! Logical error\n");
2170 CDEBUG(D_MGS, "adding osp index %d to %s\n", mti->mti_stripe_index,
2173 rc = name_create_mdt(&mdtname, fsdb->fsdb_name, mti->mti_stripe_index);
2177 rc = name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
2179 GOTO(out_destory, rc);
2181 rc = name_create(&svname, mdtname, "-osp");
2183 GOTO(out_destory, rc);
2185 sprintf(index_str, "-MDT%04x", mdt_index);
2186 rc = name_create(&ospname, svname, index_str);
2188 GOTO(out_destory, rc);
2190 rc = name_create_lov(&lovname, logname, fsdb, mdt_index);
2192 GOTO(out_destory, rc);
2194 rc = name_create(&lovuuid, lovname, "_UUID");
2196 GOTO(out_destory, rc);
2198 rc = name_create(&mdtuuid, mdtname, "_UUID");
2200 GOTO(out_destory, rc);
2202 rc = record_start_log(env, mgs, &llh, logname);
2204 GOTO(out_destory, rc);
2206 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
2209 GOTO(out_destory, rc);
2211 for (i = 0; i < mti->mti_nid_count; i++) {
2212 CDEBUG(D_MGS, "add nid %s for mdt\n",
2213 libcfs_nid2str(mti->mti_nids[i]));
2214 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
2219 rc = record_attach(env, llh, ospname, LUSTRE_OSP_NAME, lovuuid);
2223 rc = record_setup(env, llh, ospname, mti->mti_uuid, nodeuuid,
2228 rc = mgs_write_log_failnids(env, mti, llh, ospname);
2232 /* Add mdc(osp) to lod */
2233 snprintf(index_str, sizeof(mti->mti_stripe_index), "%d",
2234 mti->mti_stripe_index);
2235 rc = record_base(env, llh, lovname, 0, LCFG_ADD_MDC, mti->mti_uuid,
2236 index_str, "1", NULL);
2240 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname, "add osp");
2245 record_end_log(env, &llh);
2248 name_destroy(&mdtuuid);
2249 name_destroy(&lovuuid);
2250 name_destroy(&lovname);
2251 name_destroy(&ospname);
2252 name_destroy(&svname);
2253 name_destroy(&nodeuuid);
2254 name_destroy(&mdtname);
2258 static int mgs_write_log_mdt0(const struct lu_env *env,
2259 struct mgs_device *mgs,
2261 struct mgs_target_info *mti)
2263 char *log = mti->mti_svname;
2264 struct llog_handle *llh = NULL;
2265 char *uuid, *lovname;
2267 char *ptr = mti->mti_params;
2268 int rc = 0, failout = 0;
2271 OBD_ALLOC(uuid, sizeof(struct obd_uuid));
2275 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
2276 failout = (strncmp(ptr, "failout", 7) == 0);
2278 rc = name_create(&lovname, log, "-mdtlov");
2281 if (mgs_log_is_empty(env, mgs, log)) {
2282 rc = mgs_write_log_lov(env, mgs, fsdb, mti, log, lovname);
2287 sprintf(mdt_index, "%d", mti->mti_stripe_index);
2289 rc = record_start_log(env, mgs, &llh, log);
2293 /* add MDT itself */
2295 /* FIXME this whole fn should be a single journal transaction */
2296 sprintf(uuid, "%s_UUID", log);
2297 rc = record_marker(env, llh, fsdb, CM_START, log, "add mdt");
2300 rc = record_attach(env, llh, log, LUSTRE_MDT_NAME, uuid);
2303 rc = record_mount_opt(env, llh, log, lovname, NULL);
2306 rc = record_setup(env, llh, log, uuid, mdt_index, lovname,
2307 failout ? "n" : "f");
2310 rc = record_marker(env, llh, fsdb, CM_END, log, "add mdt");
2314 record_end_log(env, &llh);
2316 name_destroy(&lovname);
2318 OBD_FREE(uuid, sizeof(struct obd_uuid));
2322 /* envelope method for all layers log */
2323 static int mgs_write_log_mdt(const struct lu_env *env,
2324 struct mgs_device *mgs,
2326 struct mgs_target_info *mti)
2328 struct mgs_thread_info *mgi = mgs_env_info(env);
2329 struct llog_handle *llh = NULL;
2334 CDEBUG(D_MGS, "writing new mdt %s\n", mti->mti_svname);
2336 if (mti->mti_uuid[0] == '\0') {
2337 /* Make up our own uuid */
2338 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
2339 "%s_UUID", mti->mti_svname);
2343 rc = mgs_write_log_mdt0(env, mgs, fsdb, mti);
2346 /* Append the mdt info to the client log */
2347 rc = name_create(&cliname, mti->mti_fsname, "-client");
2351 if (mgs_log_is_empty(env, mgs, cliname)) {
2352 /* Start client log */
2353 rc = mgs_write_log_lov(env, mgs, fsdb, mti, cliname,
2357 rc = mgs_write_log_lmv(env, mgs, fsdb, mti, cliname,
2364 #09 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
2365 #10 L attach 0:MDC_uml1_mdsA_MNT_client 1:mdc 2:1d834_MNT_client_03f
2366 #11 L setup 0:MDC_uml1_mdsA_MNT_client 1:mdsA_UUID 2:uml1_UUID
2367 #12 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
2368 #13 L add_conn 0:MDC_uml1_mdsA_MNT_client 1:uml2_UUID
2369 #14 L mount_option 0: 1:client 2:lov1 3:MDC_uml1_mdsA_MNT_client
2372 /* copy client info about lov/lmv */
2373 mgi->mgi_comp.comp_mti = mti;
2374 mgi->mgi_comp.comp_fsdb = fsdb;
2376 rc = mgs_steal_llog_for_mdt_from_client(env, mgs, cliname,
2380 rc = mgs_write_log_mdc_to_lmv(env, mgs, fsdb, mti, cliname,
2386 rc = record_start_log(env, mgs, &llh, cliname);
2390 rc = record_marker(env, llh, fsdb, CM_START, cliname,
2394 rc = record_mount_opt(env, llh, cliname, fsdb->fsdb_clilov,
2398 rc = record_marker(env, llh, fsdb, CM_END, cliname,
2404 /* for_all_existing_mdt except current one */
2405 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2406 if (i != mti->mti_stripe_index &&
2407 test_bit(i, fsdb->fsdb_mdt_index_map)) {
2410 rc = name_create_mdt(&logname, fsdb->fsdb_name, i);
2414 rc = mgs_write_log_osp_to_mdt(env, mgs, fsdb, mti,
2416 name_destroy(&logname);
2422 record_end_log(env, &llh);
2424 name_destroy(&cliname);
2428 /* Add the ost info to the client/mdt lov */
2429 static int mgs_write_log_osc_to_lov(const struct lu_env *env,
2430 struct mgs_device *mgs, struct fs_db *fsdb,
2431 struct mgs_target_info *mti,
2432 char *logname, char *suffix, char *lovname,
2433 enum lustre_sec_part sec_part, int flags)
2435 struct llog_handle *llh = NULL;
2436 char *nodeuuid = NULL;
2437 char *oscname = NULL;
2438 char *oscuuid = NULL;
2439 char *lovuuid = NULL;
2440 char *svname = NULL;
2445 CDEBUG(D_INFO, "adding osc for %s to log %s\n",
2446 mti->mti_svname, logname);
2448 if (mgs_log_is_empty(env, mgs, logname)) {
2449 CERROR("log is empty! Logical error\n");
2453 rc = name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
2456 rc = name_create(&svname, mti->mti_svname, "-osc");
2460 /* for the system upgraded from old 1.8, keep using the old osc naming
2461 * style for mdt, see name_create_mdt_osc(). LU-1257 */
2462 if (test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2463 rc = name_create(&oscname, svname, "");
2465 rc = name_create(&oscname, svname, suffix);
2469 rc = name_create(&oscuuid, oscname, "_UUID");
2472 rc = name_create(&lovuuid, lovname, "_UUID");
2478 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
2480 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
2481 #04 L attach 0:OSC_uml1_ost1_MNT_client 1:osc 2:89070_lov1_a41dff51a
2482 #05 L setup 0:OSC_uml1_ost1_MNT_client 1:ost1_UUID 2:uml1_UUID
2484 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
2485 #07 L add_conn 0:OSC_uml1_ost1_MNT_client 1:uml2_UUID
2486 #08 L lov_modify_tgts add 0:lov1 1:ost1_UUID 2(index):0 3(gen):1
2489 rc = record_start_log(env, mgs, &llh, logname);
2493 /* FIXME these should be a single journal transaction */
2494 rc = record_marker(env, llh, fsdb, CM_START | flags, mti->mti_svname,
2499 /* NB: don't change record order, because upon MDT steal OSC config
2500 * from client, it treats all nids before LCFG_SETUP as target nids
2501 * (multiple interfaces), while nids after as failover node nids.
2502 * See mgs_steal_client_llog_handler() LCFG_ADD_UUID.
2504 for (i = 0; i < mti->mti_nid_count; i++) {
2505 CDEBUG(D_MGS, "add nid %s\n", libcfs_nid2str(mti->mti_nids[i]));
2506 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
2510 rc = record_attach(env, llh, oscname, LUSTRE_OSC_NAME, lovuuid);
2513 rc = record_setup(env, llh, oscname, mti->mti_uuid, nodeuuid, 0, 0);
2516 rc = mgs_write_log_failnids(env, mti, llh, oscname);
2520 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
2522 rc = record_lov_add(env, llh, lovname, mti->mti_uuid, index, "1");
2525 rc = record_marker(env, llh, fsdb, CM_END | flags, mti->mti_svname,
2530 record_end_log(env, &llh);
2532 name_destroy(&lovuuid);
2533 name_destroy(&oscuuid);
2534 name_destroy(&oscname);
2535 name_destroy(&svname);
2536 name_destroy(&nodeuuid);
2540 static int mgs_write_log_ost(const struct lu_env *env,
2541 struct mgs_device *mgs, struct fs_db *fsdb,
2542 struct mgs_target_info *mti)
2544 struct llog_handle *llh = NULL;
2545 char *logname, *lovname;
2546 char *ptr = mti->mti_params;
2547 int rc, flags = 0, failout = 0, i;
2550 CDEBUG(D_MGS, "writing new ost %s\n", mti->mti_svname);
2552 /* The ost startup log */
2554 /* If the ost log already exists, that means that someone reformatted
2555 the ost and it called target_add again. */
2556 if (!mgs_log_is_empty(env, mgs, mti->mti_svname)) {
2557 LCONSOLE_ERROR_MSG(0x141, "The config log for %s already "
2558 "exists, yet the server claims it never "
2559 "registered. It may have been reformatted, "
2560 "or the index changed. writeconf the MDT to "
2561 "regenerate all logs.\n", mti->mti_svname);
2566 attach obdfilter ost1 ost1_UUID
2567 setup /dev/loop2 ldiskfs f|n errors=remount-ro,user_xattr
2569 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
2570 failout = (strncmp(ptr, "failout", 7) == 0);
2571 rc = record_start_log(env, mgs, &llh, mti->mti_svname);
2574 /* FIXME these should be a single journal transaction */
2575 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,"add ost");
2578 if (*mti->mti_uuid == '\0')
2579 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
2580 "%s_UUID", mti->mti_svname);
2581 rc = record_attach(env, llh, mti->mti_svname,
2582 "obdfilter"/*LUSTRE_OST_NAME*/, mti->mti_uuid);
2585 rc = record_setup(env, llh, mti->mti_svname,
2586 "dev"/*ignored*/, "type"/*ignored*/,
2587 failout ? "n" : "f", 0/*options*/);
2590 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname, "add ost");
2594 record_end_log(env, &llh);
2597 /* We also have to update the other logs where this osc is part of
2600 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
2601 /* If we're upgrading, the old mdt log already has our
2602 entry. Let's do a fake one for fun. */
2603 /* Note that we can't add any new failnids, since we don't
2604 know the old osc names. */
2605 flags = CM_SKIP | CM_UPGRADE146;
2607 } else if ((mti->mti_flags & LDD_F_UPDATE) != LDD_F_UPDATE) {
2608 /* If the update flag isn't set, don't update client/mdt
2611 LCONSOLE_WARN("Client log for %s was not updated; writeconf "
2612 "the MDT first to regenerate it.\n",
2616 /* Add ost to all MDT lov defs */
2617 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
2618 if (test_bit(i, fsdb->fsdb_mdt_index_map)) {
2621 rc = name_create_mdt_and_lov(&logname, &lovname, fsdb,
2625 sprintf(mdt_index, "-MDT%04x", i);
2626 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, mti,
2628 lovname, LUSTRE_SP_MDT,
2630 name_destroy(&logname);
2631 name_destroy(&lovname);
2637 /* Append ost info to the client log */
2638 rc = name_create(&logname, mti->mti_fsname, "-client");
2641 if (mgs_log_is_empty(env, mgs, logname)) {
2642 /* Start client log */
2643 rc = mgs_write_log_lov(env, mgs, fsdb, mti, logname,
2647 rc = mgs_write_log_lmv(env, mgs, fsdb, mti, logname,
2652 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, mti, logname, "",
2653 fsdb->fsdb_clilov, LUSTRE_SP_CLI, 0);
2655 name_destroy(&logname);
2659 static __inline__ int mgs_param_empty(char *ptr)
2663 if ((tmp = strchr(ptr, '=')) && (*(++tmp) == '\0'))
2668 static int mgs_write_log_failnid_internal(const struct lu_env *env,
2669 struct mgs_device *mgs,
2671 struct mgs_target_info *mti,
2672 char *logname, char *cliname)
2675 struct llog_handle *llh = NULL;
2677 if (mgs_param_empty(mti->mti_params)) {
2678 /* Remove _all_ failnids */
2679 rc = mgs_modify(env, mgs, fsdb, mti, logname,
2680 mti->mti_svname, "add failnid", CM_SKIP);
2681 return rc < 0 ? rc : 0;
2684 /* Otherwise failover nids are additive */
2685 rc = record_start_log(env, mgs, &llh, logname);
2688 /* FIXME this should be a single journal transaction */
2689 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
2693 rc = mgs_write_log_failnids(env, mti, llh, cliname);
2696 rc = record_marker(env, llh, fsdb, CM_END,
2697 mti->mti_svname, "add failnid");
2699 record_end_log(env, &llh);
2704 /* Add additional failnids to an existing log.
2705 The mdc/osc must have been added to logs first */
2706 /* tcp nids must be in dotted-quad ascii -
2707 we can't resolve hostnames from the kernel. */
2708 static int mgs_write_log_add_failnid(const struct lu_env *env,
2709 struct mgs_device *mgs,
2711 struct mgs_target_info *mti)
2713 char *logname, *cliname;
2717 /* FIXME we currently can't erase the failnids
2718 * given when a target first registers, since they aren't part of
2719 * an "add uuid" stanza */
2721 /* Verify that we know about this target */
2722 if (mgs_log_is_empty(env, mgs, mti->mti_svname)) {
2723 LCONSOLE_ERROR_MSG(0x142, "The target %s has not registered "
2724 "yet. It must be started before failnids "
2725 "can be added.\n", mti->mti_svname);
2729 /* Create mdc/osc client name (e.g. lustre-OST0001-osc) */
2730 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
2731 rc = name_create(&cliname, mti->mti_svname, "-mdc");
2732 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2733 rc = name_create(&cliname, mti->mti_svname, "-osc");
2739 /* Add failover nids to the client log */
2740 rc = name_create(&logname, mti->mti_fsname, "-client");
2742 name_destroy(&cliname);
2745 rc = mgs_write_log_failnid_internal(env, mgs, fsdb,mti,logname,cliname);
2746 name_destroy(&logname);
2747 name_destroy(&cliname);
2751 if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2752 /* Add OST failover nids to the MDT logs as well */
2755 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2756 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
2758 rc = name_create_mdt(&logname, mti->mti_fsname, i);
2761 rc = name_create_mdt_osc(&cliname, mti->mti_svname,
2764 name_destroy(&logname);
2767 rc = mgs_write_log_failnid_internal(env, mgs, fsdb,
2770 name_destroy(&cliname);
2771 name_destroy(&logname);
2780 static int mgs_wlp_lcfg(const struct lu_env *env,
2781 struct mgs_device *mgs, struct fs_db *fsdb,
2782 struct mgs_target_info *mti,
2783 char *logname, struct lustre_cfg_bufs *bufs,
2784 char *tgtname, char *ptr)
2786 char comment[MTI_NAME_MAXLEN];
2788 struct lustre_cfg *lcfg;
2791 /* Erase any old settings of this same parameter */
2792 memcpy(comment, ptr, MTI_NAME_MAXLEN);
2793 comment[MTI_NAME_MAXLEN - 1] = 0;
2794 /* But don't try to match the value. */
2795 if ((tmp = strchr(comment, '=')))
2797 /* FIXME we should skip settings that are the same as old values */
2798 rc = mgs_modify(env, mgs, fsdb, mti, logname, tgtname, comment,CM_SKIP);
2801 del = mgs_param_empty(ptr);
2803 LCONSOLE_INFO("%sing parameter %s.%s in log %s\n", del ? "Disabl" : rc ?
2804 "Sett" : "Modify", tgtname, comment, logname);
2808 lustre_cfg_bufs_reset(bufs, tgtname);
2809 lustre_cfg_bufs_set_string(bufs, 1, ptr);
2810 lcfg = lustre_cfg_new(LCFG_PARAM, bufs);
2813 rc = mgs_write_log_direct(env, mgs, fsdb, logname,lcfg,tgtname,comment);
2814 lustre_cfg_free(lcfg);
2818 /* write global variable settings into log */
2819 static int mgs_write_log_sys(const struct lu_env *env,
2820 struct mgs_device *mgs, struct fs_db *fsdb,
2821 struct mgs_target_info *mti, char *sys, char *ptr)
2823 struct mgs_thread_info *mgi = mgs_env_info(env);
2824 struct lustre_cfg *lcfg;
2826 int rc, cmd, convert = 1;
2828 if (class_match_param(ptr, PARAM_TIMEOUT, &tmp) == 0) {
2829 cmd = LCFG_SET_TIMEOUT;
2830 } else if (class_match_param(ptr, PARAM_LDLM_TIMEOUT, &tmp) == 0) {
2831 cmd = LCFG_SET_LDLM_TIMEOUT;
2832 /* Check for known params here so we can return error to lctl */
2833 } else if ((class_match_param(ptr, PARAM_AT_MIN, &tmp) == 0) ||
2834 (class_match_param(ptr, PARAM_AT_MAX, &tmp) == 0) ||
2835 (class_match_param(ptr, PARAM_AT_EXTRA, &tmp) == 0) ||
2836 (class_match_param(ptr, PARAM_AT_EARLY_MARGIN, &tmp) == 0) ||
2837 (class_match_param(ptr, PARAM_AT_HISTORY, &tmp) == 0)) {
2839 } else if (class_match_param(ptr, PARAM_JOBID_VAR, &tmp) == 0) {
2840 convert = 0; /* Don't convert string value to integer */
2846 if (mgs_param_empty(ptr))
2847 CDEBUG(D_MGS, "global '%s' removed\n", sys);
2849 CDEBUG(D_MGS, "global '%s' val=%s\n", sys, tmp);
2851 lustre_cfg_bufs_reset(&mgi->mgi_bufs, NULL);
2852 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, sys);
2853 if (!convert && *tmp != '\0')
2854 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 2, tmp);
2855 lcfg = lustre_cfg_new(cmd, &mgi->mgi_bufs);
2856 lcfg->lcfg_num = convert ? simple_strtoul(tmp, NULL, 0) : 0;
2857 /* truncate the comment to the parameter name */
2861 /* modify all servers and clients */
2862 rc = mgs_write_log_direct_all(env, mgs, fsdb, mti,
2863 *tmp == '\0' ? NULL : lcfg,
2864 mti->mti_fsname, sys, 0);
2865 if (rc == 0 && *tmp != '\0') {
2867 case LCFG_SET_TIMEOUT:
2868 if (!obd_timeout_set || lcfg->lcfg_num > obd_timeout)
2869 class_process_config(lcfg);
2871 case LCFG_SET_LDLM_TIMEOUT:
2872 if (!ldlm_timeout_set || lcfg->lcfg_num > ldlm_timeout)
2873 class_process_config(lcfg);
2880 lustre_cfg_free(lcfg);
2884 /* write quota settings into log */
2885 static int mgs_write_log_quota(const struct lu_env *env, struct mgs_device *mgs,
2886 struct fs_db *fsdb, struct mgs_target_info *mti,
2887 char *quota, char *ptr)
2889 struct mgs_thread_info *mgi = mgs_env_info(env);
2890 struct lustre_cfg *lcfg;
2893 int rc, cmd = LCFG_PARAM;
2895 /* support only 'meta' and 'data' pools so far */
2896 if (class_match_param(ptr, QUOTA_METAPOOL_NAME, &tmp) != 0 &&
2897 class_match_param(ptr, QUOTA_DATAPOOL_NAME, &tmp) != 0) {
2898 CERROR("parameter quota.%s isn't supported (only quota.mdt "
2899 "& quota.ost are)\n", ptr);
2904 CDEBUG(D_MGS, "global '%s' removed\n", quota);
2906 CDEBUG(D_MGS, "global '%s'\n", quota);
2908 if (strchr(tmp, 'u') == NULL && strchr(tmp, 'g') == NULL &&
2909 strcmp(tmp, "none") != 0) {
2910 CERROR("enable option(%s) isn't supported\n", tmp);
2915 lustre_cfg_bufs_reset(&mgi->mgi_bufs, mti->mti_fsname);
2916 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, quota);
2917 lcfg = lustre_cfg_new(cmd, &mgi->mgi_bufs);
2918 /* truncate the comment to the parameter name */
2923 /* XXX we duplicated quota enable information in all server
2924 * config logs, it should be moved to a separate config
2925 * log once we cleanup the config log for global param. */
2926 /* modify all servers */
2927 rc = mgs_write_log_direct_all(env, mgs, fsdb, mti,
2928 *tmp == '\0' ? NULL : lcfg,
2929 mti->mti_fsname, quota, 1);
2931 lustre_cfg_free(lcfg);
2932 return rc < 0 ? rc : 0;
2935 static int mgs_srpc_set_param_disk(const struct lu_env *env,
2936 struct mgs_device *mgs,
2938 struct mgs_target_info *mti,
2941 struct mgs_thread_info *mgi = mgs_env_info(env);
2942 struct llog_handle *llh = NULL;
2944 char *comment, *ptr;
2945 struct lustre_cfg *lcfg;
2950 ptr = strchr(param, '=');
2954 OBD_ALLOC(comment, len + 1);
2955 if (comment == NULL)
2957 strncpy(comment, param, len);
2958 comment[len] = '\0';
2961 lustre_cfg_bufs_reset(&mgi->mgi_bufs, mti->mti_svname);
2962 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, param);
2963 lcfg = lustre_cfg_new(LCFG_SPTLRPC_CONF, &mgi->mgi_bufs);
2965 GOTO(out_comment, rc = -ENOMEM);
2967 /* construct log name */
2968 rc = name_create(&logname, mti->mti_fsname, "-sptlrpc");
2972 if (mgs_log_is_empty(env, mgs, logname)) {
2973 rc = record_start_log(env, mgs, &llh, logname);
2976 record_end_log(env, &llh);
2979 /* obsolete old one */
2980 rc = mgs_modify(env, mgs, fsdb, mti, logname, mti->mti_svname,
2984 /* write the new one */
2985 rc = mgs_write_log_direct(env, mgs, fsdb, logname, lcfg,
2986 mti->mti_svname, comment);
2988 CERROR("err %d writing log %s\n", rc, logname);
2990 name_destroy(&logname);
2992 lustre_cfg_free(lcfg);
2994 OBD_FREE(comment, len + 1);
2998 static int mgs_srpc_set_param_udesc_mem(struct fs_db *fsdb,
3003 /* disable the adjustable udesc parameter for now, i.e. use default
3004 * setting that client always ship udesc to MDT if possible. to enable
3005 * it simply remove the following line */
3008 ptr = strchr(param, '=');
3013 if (strcmp(param, PARAM_SRPC_UDESC))
3016 if (strcmp(ptr, "yes") == 0) {
3017 set_bit(FSDB_UDESC, &fsdb->fsdb_flags);
3018 CWARN("Enable user descriptor shipping from client to MDT\n");
3019 } else if (strcmp(ptr, "no") == 0) {
3020 clear_bit(FSDB_UDESC, &fsdb->fsdb_flags);
3021 CWARN("Disable user descriptor shipping from client to MDT\n");
3029 CERROR("Invalid param: %s\n", param);
3033 static int mgs_srpc_set_param_mem(struct fs_db *fsdb,
3037 struct sptlrpc_rule rule;
3038 struct sptlrpc_rule_set *rset;
3042 if (strncmp(param, PARAM_SRPC, sizeof(PARAM_SRPC) - 1) != 0) {
3043 CERROR("Invalid sptlrpc parameter: %s\n", param);
3047 if (strncmp(param, PARAM_SRPC_UDESC,
3048 sizeof(PARAM_SRPC_UDESC) - 1) == 0) {
3049 RETURN(mgs_srpc_set_param_udesc_mem(fsdb, param));
3052 if (strncmp(param, PARAM_SRPC_FLVR, sizeof(PARAM_SRPC_FLVR) - 1) != 0) {
3053 CERROR("Invalid sptlrpc flavor parameter: %s\n", param);
3057 param += sizeof(PARAM_SRPC_FLVR) - 1;
3059 rc = sptlrpc_parse_rule(param, &rule);
3063 /* mgs rules implies must be mgc->mgs */
3064 if (test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
3065 if ((rule.sr_from != LUSTRE_SP_MGC &&
3066 rule.sr_from != LUSTRE_SP_ANY) ||
3067 (rule.sr_to != LUSTRE_SP_MGS &&
3068 rule.sr_to != LUSTRE_SP_ANY))
3072 /* preapre room for this coming rule. svcname format should be:
3073 * - fsname: general rule
3074 * - fsname-tgtname: target-specific rule
3076 if (strchr(svname, '-')) {
3077 struct mgs_tgt_srpc_conf *tgtconf;
3080 for (tgtconf = fsdb->fsdb_srpc_tgt; tgtconf != NULL;
3081 tgtconf = tgtconf->mtsc_next) {
3082 if (!strcmp(tgtconf->mtsc_tgt, svname)) {
3091 OBD_ALLOC_PTR(tgtconf);
3092 if (tgtconf == NULL)
3095 name_len = strlen(svname);
3097 OBD_ALLOC(tgtconf->mtsc_tgt, name_len + 1);
3098 if (tgtconf->mtsc_tgt == NULL) {
3099 OBD_FREE_PTR(tgtconf);
3102 memcpy(tgtconf->mtsc_tgt, svname, name_len);
3104 tgtconf->mtsc_next = fsdb->fsdb_srpc_tgt;
3105 fsdb->fsdb_srpc_tgt = tgtconf;
3108 rset = &tgtconf->mtsc_rset;
3110 rset = &fsdb->fsdb_srpc_gen;
3113 rc = sptlrpc_rule_set_merge(rset, &rule);
3118 static int mgs_srpc_set_param(const struct lu_env *env,
3119 struct mgs_device *mgs,
3121 struct mgs_target_info *mti,
3131 /* keep a copy of original param, which could be destroied
3133 copy_size = strlen(param) + 1;
3134 OBD_ALLOC(copy, copy_size);
3137 memcpy(copy, param, copy_size);
3139 rc = mgs_srpc_set_param_mem(fsdb, mti->mti_svname, param);
3143 /* previous steps guaranteed the syntax is correct */
3144 rc = mgs_srpc_set_param_disk(env, mgs, fsdb, mti, copy);
3148 if (test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
3150 * for mgs rules, make them effective immediately.
3152 LASSERT(fsdb->fsdb_srpc_tgt == NULL);
3153 sptlrpc_target_update_exp_flavor(mgs->mgs_obd,
3154 &fsdb->fsdb_srpc_gen);
3158 OBD_FREE(copy, copy_size);
3162 struct mgs_srpc_read_data {
3163 struct fs_db *msrd_fsdb;
3167 static int mgs_srpc_read_handler(const struct lu_env *env,
3168 struct llog_handle *llh,
3169 struct llog_rec_hdr *rec, void *data)
3171 struct mgs_srpc_read_data *msrd = data;
3172 struct cfg_marker *marker;
3173 struct lustre_cfg *lcfg = REC_DATA(rec);
3174 char *svname, *param;
3178 if (rec->lrh_type != OBD_CFG_REC) {
3179 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
3183 cfg_len = rec->lrh_len - sizeof(struct llog_rec_hdr) -
3184 sizeof(struct llog_rec_tail);
3186 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
3188 CERROR("Insane cfg\n");
3192 if (lcfg->lcfg_command == LCFG_MARKER) {
3193 marker = lustre_cfg_buf(lcfg, 1);
3195 if (marker->cm_flags & CM_START &&
3196 marker->cm_flags & CM_SKIP)
3197 msrd->msrd_skip = 1;
3198 if (marker->cm_flags & CM_END)
3199 msrd->msrd_skip = 0;
3204 if (msrd->msrd_skip)
3207 if (lcfg->lcfg_command != LCFG_SPTLRPC_CONF) {
3208 CERROR("invalid command (%x)\n", lcfg->lcfg_command);
3212 svname = lustre_cfg_string(lcfg, 0);
3213 if (svname == NULL) {
3214 CERROR("svname is empty\n");
3218 param = lustre_cfg_string(lcfg, 1);
3219 if (param == NULL) {
3220 CERROR("param is empty\n");
3224 rc = mgs_srpc_set_param_mem(msrd->msrd_fsdb, svname, param);
3226 CERROR("read sptlrpc record error (%d): %s\n", rc, param);
3231 int mgs_get_fsdb_srpc_from_llog(const struct lu_env *env,
3232 struct mgs_device *mgs,
3235 struct llog_handle *llh = NULL;
3236 struct llog_ctxt *ctxt;
3238 struct mgs_srpc_read_data msrd;
3242 /* construct log name */
3243 rc = name_create(&logname, fsdb->fsdb_name, "-sptlrpc");
3247 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
3248 LASSERT(ctxt != NULL);
3250 if (mgs_log_is_empty(env, mgs, logname))
3253 rc = llog_open(env, ctxt, &llh, NULL, logname,
3261 rc = llog_init_handle(env, llh, LLOG_F_IS_PLAIN, NULL);
3263 GOTO(out_close, rc);
3265 if (llog_get_size(llh) <= 1)
3266 GOTO(out_close, rc = 0);
3268 msrd.msrd_fsdb = fsdb;
3271 rc = llog_process(env, llh, mgs_srpc_read_handler, (void *)&msrd,
3275 llog_close(env, llh);
3277 llog_ctxt_put(ctxt);
3278 name_destroy(&logname);
3281 CERROR("failed to read sptlrpc config database: %d\n", rc);
3285 /* Permanent settings of all parameters by writing into the appropriate
3286 * configuration logs.
3287 * A parameter with null value ("<param>='\0'") means to erase it out of
3290 static int mgs_write_log_param(const struct lu_env *env,
3291 struct mgs_device *mgs, struct fs_db *fsdb,
3292 struct mgs_target_info *mti, char *ptr)
3294 struct mgs_thread_info *mgi = mgs_env_info(env);
3297 int rc = 0, rc2 = 0;
3300 /* For various parameter settings, we have to figure out which logs
3301 care about them (e.g. both mdt and client for lov settings) */
3302 CDEBUG(D_MGS, "next param '%s'\n", ptr);
3304 /* The params are stored in MOUNT_DATA_FILE and modified via
3305 tunefs.lustre, or set using lctl conf_param */
3307 /* Processed in lustre_start_mgc */
3308 if (class_match_param(ptr, PARAM_MGSNODE, NULL) == 0)
3311 /* Processed in ost/mdt */
3312 if (class_match_param(ptr, PARAM_NETWORK, NULL) == 0)
3315 /* Processed in mgs_write_log_ost */
3316 if (class_match_param(ptr, PARAM_FAILMODE, NULL) == 0) {
3317 if (mti->mti_flags & LDD_F_PARAM) {
3318 LCONSOLE_ERROR_MSG(0x169, "%s can only be "
3319 "changed with tunefs.lustre"
3320 "and --writeconf\n", ptr);
3326 if (class_match_param(ptr, PARAM_SRPC, NULL) == 0) {
3327 rc = mgs_srpc_set_param(env, mgs, fsdb, mti, ptr);
3331 if (class_match_param(ptr, PARAM_FAILNODE, NULL) == 0) {
3332 /* Add a failover nidlist */
3334 /* We already processed failovers params for new
3335 targets in mgs_write_log_target */
3336 if (mti->mti_flags & LDD_F_PARAM) {
3337 CDEBUG(D_MGS, "Adding failnode\n");
3338 rc = mgs_write_log_add_failnid(env, mgs, fsdb, mti);
3343 if (class_match_param(ptr, PARAM_SYS, &tmp) == 0) {
3344 rc = mgs_write_log_sys(env, mgs, fsdb, mti, ptr, tmp);
3348 if (class_match_param(ptr, PARAM_QUOTA, &tmp) == 0) {
3349 rc = mgs_write_log_quota(env, mgs, fsdb, mti, ptr, tmp);
3353 if (class_match_param(ptr, PARAM_OSC""PARAM_ACTIVE, &tmp) == 0) {
3354 /* active=0 means off, anything else means on */
3355 int flag = (*tmp == '0') ? CM_EXCLUDE : 0;
3358 if (!(mti->mti_flags & LDD_F_SV_TYPE_OST)) {
3359 LCONSOLE_ERROR_MSG(0x144, "%s: Only OSCs can "
3360 "be (de)activated.\n",
3362 GOTO(end, rc = -EINVAL);
3364 LCONSOLE_WARN("Permanently %sactivating %s\n",
3365 flag ? "de": "re", mti->mti_svname);
3367 rc = name_create(&logname, mti->mti_fsname, "-client");
3370 rc = mgs_modify(env, mgs, fsdb, mti, logname,
3371 mti->mti_svname, "add osc", flag);
3372 name_destroy(&logname);
3376 /* Add to all MDT logs for CMD */
3377 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3378 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
3380 rc = name_create_mdt(&logname, mti->mti_fsname, i);
3383 rc = mgs_modify(env, mgs, fsdb, mti, logname,
3384 mti->mti_svname, "add osc", flag);
3385 name_destroy(&logname);
3391 LCONSOLE_ERROR_MSG(0x145, "Couldn't find %s in"
3392 "log (%d). No permanent "
3393 "changes were made to the "
3395 mti->mti_svname, rc);
3396 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags))
3397 LCONSOLE_ERROR_MSG(0x146, "This may be"
3402 "update the logs.\n");
3405 /* Fall through to osc proc for deactivating live OSC
3406 on running MDT / clients. */
3408 /* Below here, let obd's XXX_process_config methods handle it */
3410 /* All lov. in proc */
3411 if (class_match_param(ptr, PARAM_LOV, NULL) == 0) {
3414 CDEBUG(D_MGS, "lov param %s\n", ptr);
3415 if (!(mti->mti_flags & LDD_F_SV_TYPE_MDT)) {
3416 LCONSOLE_ERROR_MSG(0x147, "LOV params must be "
3417 "set on the MDT, not %s. "
3424 if (mgs_log_is_empty(env, mgs, mti->mti_svname))
3425 GOTO(end, rc = -ENODEV);
3427 rc = name_create_mdt_and_lov(&logname, &mdtlovname, fsdb,
3428 mti->mti_stripe_index);
3431 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, mti->mti_svname,
3432 &mgi->mgi_bufs, mdtlovname, ptr);
3433 name_destroy(&logname);
3434 name_destroy(&mdtlovname);
3439 rc = name_create(&logname, mti->mti_fsname, "-client");
3442 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname, &mgi->mgi_bufs,
3443 fsdb->fsdb_clilov, ptr);
3444 name_destroy(&logname);
3448 /* All osc., mdc., llite. params in proc */
3449 if ((class_match_param(ptr, PARAM_OSC, NULL) == 0) ||
3450 (class_match_param(ptr, PARAM_MDC, NULL) == 0) ||
3451 (class_match_param(ptr, PARAM_LLITE, NULL) == 0)) {
3454 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
3455 LCONSOLE_ERROR_MSG(0x148, "Upgraded client logs for %s"
3456 " cannot be modified. Consider"
3457 " updating the configuration with"
3460 GOTO(end, rc = -EINVAL);
3462 if (memcmp(ptr, PARAM_LLITE, strlen(PARAM_LLITE)) == 0) {
3463 rc = name_create(&cname, mti->mti_fsname, "-client");
3464 /* Add the client type to match the obdname in
3465 class_config_llog_handler */
3466 } else if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
3467 rc = name_create(&cname, mti->mti_svname, "-mdc");
3468 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
3469 rc = name_create(&cname, mti->mti_svname, "-osc");
3471 GOTO(end, rc = -EINVAL);
3476 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
3479 rc = name_create(&logname, mti->mti_fsname, "-client");
3481 name_destroy(&cname);
3484 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname, &mgi->mgi_bufs,
3487 /* osc params affect the MDT as well */
3488 if (!rc && (mti->mti_flags & LDD_F_SV_TYPE_OST)) {
3491 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
3492 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
3494 name_destroy(&cname);
3495 rc = name_create_mdt_osc(&cname, mti->mti_svname,
3497 name_destroy(&logname);
3500 rc = name_create_mdt(&logname,
3501 mti->mti_fsname, i);
3504 if (!mgs_log_is_empty(env, mgs, logname)) {
3505 rc = mgs_wlp_lcfg(env, mgs, fsdb,
3514 name_destroy(&logname);
3515 name_destroy(&cname);
3519 /* All mdt. params in proc */
3520 if (class_match_param(ptr, PARAM_MDT, NULL) == 0) {
3524 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
3525 if (strncmp(mti->mti_svname, mti->mti_fsname,
3526 MTI_NAME_MAXLEN) == 0)
3527 /* device is unspecified completely? */
3528 rc = LDD_F_SV_TYPE_MDT | LDD_F_SV_ALL;
3530 rc = server_name2index(mti->mti_svname, &idx, NULL);
3533 if ((rc & LDD_F_SV_TYPE_MDT) == 0)
3535 if (rc & LDD_F_SV_ALL) {
3536 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3538 fsdb->fsdb_mdt_index_map))
3540 rc = name_create_mdt(&logname,
3541 mti->mti_fsname, i);
3544 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti,
3545 logname, &mgi->mgi_bufs,
3547 name_destroy(&logname);
3552 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti,
3553 mti->mti_svname, &mgi->mgi_bufs,
3554 mti->mti_svname, ptr);
3561 /* All mdd., ost. params in proc */
3562 if ((class_match_param(ptr, PARAM_MDD, NULL) == 0) ||
3563 (class_match_param(ptr, PARAM_OST, NULL) == 0)) {
3564 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
3565 if (mgs_log_is_empty(env, mgs, mti->mti_svname))
3566 GOTO(end, rc = -ENODEV);
3568 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, mti->mti_svname,
3569 &mgi->mgi_bufs, mti->mti_svname, ptr);
3573 LCONSOLE_WARN("Ignoring unrecognized param '%s'\n", ptr);
3578 CERROR("err %d on param '%s'\n", rc, ptr);
3583 /* Not implementing automatic failover nid addition at this time. */
3584 int mgs_check_failnid(const struct lu_env *env, struct mgs_device *mgs,
3585 struct mgs_target_info *mti)
3592 rc = mgs_find_or_make_fsdb(obd, fsname, &fsdb);
3596 if (mgs_log_is_empty(obd, mti->mti_svname))
3597 /* should never happen */
3600 CDEBUG(D_MGS, "Checking for new failnids for %s\n", mti->mti_svname);
3602 /* FIXME We can just check mti->params to see if we're already in
3603 the failover list. Modify mti->params for rewriting back at
3604 server_register_target(). */
3606 mutex_lock(&fsdb->fsdb_mutex);
3607 rc = mgs_write_log_add_failnid(obd, fsdb, mti);
3608 mutex_unlock(&fsdb->fsdb_mutex);
3615 int mgs_write_log_target(const struct lu_env *env,
3616 struct mgs_device *mgs,
3617 struct mgs_target_info *mti,
3624 /* set/check the new target index */
3625 rc = mgs_set_index(env, mgs, mti);
3627 CERROR("Can't get index (%d)\n", rc);
3631 if (rc == EALREADY) {
3632 LCONSOLE_WARN("Found index %d for %s, updating log\n",
3633 mti->mti_stripe_index, mti->mti_svname);
3634 /* We would like to mark old log sections as invalid
3635 and add new log sections in the client and mdt logs.
3636 But if we add new sections, then live clients will
3637 get repeat setup instructions for already running
3638 osc's. So don't update the client/mdt logs. */
3639 mti->mti_flags &= ~LDD_F_UPDATE;
3643 mutex_lock(&fsdb->fsdb_mutex);
3645 if (mti->mti_flags &
3646 (LDD_F_VIRGIN | LDD_F_UPGRADE14 | LDD_F_WRITECONF)) {
3647 /* Generate a log from scratch */
3648 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
3649 rc = mgs_write_log_mdt(env, mgs, fsdb, mti);
3650 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
3651 rc = mgs_write_log_ost(env, mgs, fsdb, mti);
3653 CERROR("Unknown target type %#x, can't create log for "
3654 "%s\n", mti->mti_flags, mti->mti_svname);
3657 CERROR("Can't write logs for %s (%d)\n",
3658 mti->mti_svname, rc);
3662 /* Just update the params from tunefs in mgs_write_log_params */
3663 CDEBUG(D_MGS, "Update params for %s\n", mti->mti_svname);
3664 mti->mti_flags |= LDD_F_PARAM;
3667 /* allocate temporary buffer, where class_get_next_param will
3668 make copy of a current parameter */
3669 OBD_ALLOC(buf, strlen(mti->mti_params) + 1);
3671 GOTO(out_up, rc = -ENOMEM);
3672 params = mti->mti_params;
3673 while (params != NULL) {
3674 rc = class_get_next_param(¶ms, buf);
3677 /* there is no next parameter, that is
3682 CDEBUG(D_MGS, "remaining string: '%s', param: '%s'\n",
3684 rc = mgs_write_log_param(env, mgs, fsdb, mti, buf);
3689 OBD_FREE(buf, strlen(mti->mti_params) + 1);
3692 mutex_unlock(&fsdb->fsdb_mutex);
3696 int mgs_erase_log(const struct lu_env *env, struct mgs_device *mgs, char *name)
3698 struct llog_ctxt *ctxt;
3701 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
3703 CERROR("%s: MGS config context doesn't exist\n",
3704 mgs->mgs_obd->obd_name);
3707 rc = llog_erase(env, ctxt, NULL, name);
3708 /* llog may not exist */
3711 llog_ctxt_put(ctxt);
3715 CERROR("%s: failed to clear log %s: %d\n",
3716 mgs->mgs_obd->obd_name, name, rc);
3721 /* erase all logs for the given fs */
3722 int mgs_erase_logs(const struct lu_env *env, struct mgs_device *mgs, char *fsname)
3726 struct mgs_direntry *dirent, *n;
3727 int rc, len = strlen(fsname);
3731 /* Find all the logs in the CONFIGS directory */
3732 rc = class_dentry_readdir(env, mgs, &list);
3736 mutex_lock(&mgs->mgs_mutex);
3738 /* Delete the fs db */
3739 fsdb = mgs_find_fsdb(mgs, fsname);
3741 mgs_free_fsdb(mgs, fsdb);
3743 mutex_unlock(&mgs->mgs_mutex);
3745 cfs_list_for_each_entry_safe(dirent, n, &list, list) {
3746 cfs_list_del(&dirent->list);
3747 suffix = strrchr(dirent->name, '-');
3748 if (suffix != NULL) {
3749 if ((len == suffix - dirent->name) &&
3750 (strncmp(fsname, dirent->name, len) == 0)) {
3751 CDEBUG(D_MGS, "Removing log %s\n",
3753 mgs_erase_log(env, mgs, dirent->name);
3756 mgs_direntry_free(dirent);
3762 /* from llog_swab */
3763 static void print_lustre_cfg(struct lustre_cfg *lcfg)
3768 CDEBUG(D_MGS, "lustre_cfg: %p\n", lcfg);
3769 CDEBUG(D_MGS, "\tlcfg->lcfg_version: %#x\n", lcfg->lcfg_version);
3771 CDEBUG(D_MGS, "\tlcfg->lcfg_command: %#x\n", lcfg->lcfg_command);
3772 CDEBUG(D_MGS, "\tlcfg->lcfg_num: %#x\n", lcfg->lcfg_num);
3773 CDEBUG(D_MGS, "\tlcfg->lcfg_flags: %#x\n", lcfg->lcfg_flags);
3774 CDEBUG(D_MGS, "\tlcfg->lcfg_nid: %s\n", libcfs_nid2str(lcfg->lcfg_nid));
3776 CDEBUG(D_MGS, "\tlcfg->lcfg_bufcount: %d\n", lcfg->lcfg_bufcount);
3777 if (lcfg->lcfg_bufcount < LUSTRE_CFG_MAX_BUFCOUNT)
3778 for (i = 0; i < lcfg->lcfg_bufcount; i++) {
3779 CDEBUG(D_MGS, "\tlcfg->lcfg_buflens[%d]: %d %s\n",
3780 i, lcfg->lcfg_buflens[i],
3781 lustre_cfg_string(lcfg, i));
3786 /* Set a permanent (config log) param for a target or fs
3787 * \param lcfg buf0 may contain the device (testfs-MDT0000) name
3788 * buf1 contains the single parameter
3790 int mgs_setparam(const struct lu_env *env, struct mgs_device *mgs,
3791 struct lustre_cfg *lcfg, char *fsname)
3794 struct mgs_target_info *mti;
3795 char *devname, *param;
3802 print_lustre_cfg(lcfg);
3804 /* lustre, lustre-mdtlov, lustre-client, lustre-MDT0000 */
3805 devname = lustre_cfg_string(lcfg, 0);
3806 param = lustre_cfg_string(lcfg, 1);
3808 /* Assume device name embedded in param:
3809 lustre-OST0000.osc.max_dirty_mb=32 */
3810 ptr = strchr(param, '.');
3818 LCONSOLE_ERROR_MSG(0x14d, "No target specified: %s\n", param);
3822 rc = mgs_parse_devname(devname, fsname, NULL);
3823 if (rc == 0 && !mgs_parse_devname(devname, NULL, &index)) {
3824 /* param related to llite isn't allowed to set by OST or MDT */
3825 if (rc == 0 && strncmp(param, PARAM_LLITE,
3826 sizeof(PARAM_LLITE)) == 0)
3829 /* assume devname is the fsname */
3830 memset(fsname, 0, MTI_NAME_MAXLEN);
3831 strncpy(fsname, devname, MTI_NAME_MAXLEN);
3832 fsname[MTI_NAME_MAXLEN - 1] = 0;
3834 CDEBUG(D_MGS, "setparam fs='%s' device='%s'\n", fsname, devname);
3836 rc = mgs_find_or_make_fsdb(env, mgs, fsname, &fsdb);
3839 if (!test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags) &&
3840 test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
3841 CERROR("No filesystem targets for %s. cfg_device from lctl "
3842 "is '%s'\n", fsname, devname);
3843 mgs_free_fsdb(mgs, fsdb);
3847 /* Create a fake mti to hold everything */
3850 GOTO(out, rc = -ENOMEM);
3851 if (strlcpy(mti->mti_fsname, fsname, sizeof(mti->mti_fsname))
3852 >= sizeof(mti->mti_fsname))
3853 GOTO(out, rc = -E2BIG);
3854 if (strlcpy(mti->mti_svname, devname, sizeof(mti->mti_svname))
3855 >= sizeof(mti->mti_svname))
3856 GOTO(out, rc = -E2BIG);
3857 if (strlcpy(mti->mti_params, param, sizeof(mti->mti_params))
3858 >= sizeof(mti->mti_params))
3859 GOTO(out, rc = -E2BIG);
3860 rc = server_name2index(mti->mti_svname, &mti->mti_stripe_index, &tmp);
3862 /* Not a valid server; may be only fsname */
3865 /* Strip -osc or -mdc suffix from svname */
3866 if (server_make_name(rc, mti->mti_stripe_index, mti->mti_fsname,
3868 GOTO(out, rc = -EINVAL);
3870 mti->mti_flags = rc | LDD_F_PARAM;
3872 mutex_lock(&fsdb->fsdb_mutex);
3873 rc = mgs_write_log_param(env, mgs, fsdb, mti, mti->mti_params);
3874 mutex_unlock(&fsdb->fsdb_mutex);
3877 * Revoke lock so everyone updates. Should be alright if
3878 * someone was already reading while we were updating the logs,
3879 * so we don't really need to hold the lock while we're
3882 mgs_revoke_lock(mgs, fsdb, CONFIG_T_CONFIG);
3888 static int mgs_write_log_pool(const struct lu_env *env,
3889 struct mgs_device *mgs, char *logname,
3890 struct fs_db *fsdb, char *lovname,
3891 enum lcfg_command_type cmd,
3892 char *poolname, char *fsname,
3893 char *ostname, char *comment)
3895 struct llog_handle *llh = NULL;
3898 rc = record_start_log(env, mgs, &llh, logname);
3901 rc = record_marker(env, llh, fsdb, CM_START, lovname, comment);
3904 rc = record_base(env, llh, lovname, 0, cmd, poolname, fsname, ostname, 0);
3907 rc = record_marker(env, llh, fsdb, CM_END, lovname, comment);
3909 record_end_log(env, &llh);
3913 int mgs_pool_cmd(const struct lu_env *env, struct mgs_device *mgs,
3914 enum lcfg_command_type cmd, char *fsname,
3915 char *poolname, char *ostname)
3920 char *label = NULL, *canceled_label = NULL;
3922 struct mgs_target_info *mti = NULL;
3926 rc = mgs_find_or_make_fsdb(env, mgs, fsname, &fsdb);
3928 CERROR("Can't get db for %s\n", fsname);
3931 if (test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
3932 CERROR("%s is not defined\n", fsname);
3933 mgs_free_fsdb(mgs, fsdb);
3937 label_sz = 10 + strlen(fsname) + strlen(poolname);
3939 /* check if ostname match fsname */
3940 if (ostname != NULL) {
3943 ptr = strrchr(ostname, '-');
3944 if ((ptr == NULL) ||
3945 (strncmp(fsname, ostname, ptr-ostname) != 0))
3947 label_sz += strlen(ostname);
3950 OBD_ALLOC(label, label_sz);
3957 "new %s.%s", fsname, poolname);
3961 "add %s.%s.%s", fsname, poolname, ostname);
3964 OBD_ALLOC(canceled_label, label_sz);
3965 if (canceled_label == NULL)
3966 GOTO(out_label, rc = -ENOMEM);
3968 "rem %s.%s.%s", fsname, poolname, ostname);
3969 sprintf(canceled_label,
3970 "add %s.%s.%s", fsname, poolname, ostname);
3973 OBD_ALLOC(canceled_label, label_sz);
3974 if (canceled_label == NULL)
3975 GOTO(out_label, rc = -ENOMEM);
3977 "del %s.%s", fsname, poolname);
3978 sprintf(canceled_label,
3979 "new %s.%s", fsname, poolname);
3985 mutex_lock(&fsdb->fsdb_mutex);
3987 if (canceled_label != NULL) {
3990 GOTO(out_cancel, rc = -ENOMEM);
3993 /* write pool def to all MDT logs */
3994 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3995 if (test_bit(i, fsdb->fsdb_mdt_index_map)) {
3996 rc = name_create_mdt_and_lov(&logname, &lovname,
3999 mutex_unlock(&fsdb->fsdb_mutex);
4002 if (canceled_label != NULL) {
4003 strcpy(mti->mti_svname, "lov pool");
4004 rc = mgs_modify(env, mgs, fsdb, mti, logname,
4005 lovname, canceled_label,
4010 rc = mgs_write_log_pool(env, mgs, logname,
4014 name_destroy(&logname);
4015 name_destroy(&lovname);
4017 mutex_unlock(&fsdb->fsdb_mutex);
4023 rc = name_create(&logname, fsname, "-client");
4025 mutex_unlock(&fsdb->fsdb_mutex);
4028 if (canceled_label != NULL) {
4029 rc = mgs_modify(env, mgs, fsdb, mti, logname,
4030 fsdb->fsdb_clilov, canceled_label, CM_SKIP);
4032 mutex_unlock(&fsdb->fsdb_mutex);
4033 name_destroy(&logname);
4038 rc = mgs_write_log_pool(env, mgs, logname, fsdb, fsdb->fsdb_clilov,
4039 cmd, fsname, poolname, ostname, label);
4040 mutex_unlock(&fsdb->fsdb_mutex);
4041 name_destroy(&logname);
4042 /* request for update */
4043 mgs_revoke_lock(mgs, fsdb, CONFIG_T_CONFIG);
4050 if (canceled_label != NULL)
4051 OBD_FREE(canceled_label, label_sz);
4053 OBD_FREE(label, label_sz);