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 */
1214 rc = server_name2fsname(devname, fsname, NULL);
1216 CDEBUG(D_MGS, "Device name %s without fsname\n",
1223 rc = server_name2index(devname, index, NULL);
1225 CDEBUG(D_MGS, "Device name %s with wrong index\n",
1234 static int only_mgs_is_running(struct obd_device *mgs_obd)
1236 /* TDB: Is global variable with devices count exists? */
1237 int num_devices = get_devices_count();
1238 /* osd, MGS and MGC + self_export
1239 (wc -l /proc/fs/lustre/devices <= 2) && (num_exports <= 2) */
1240 return (num_devices <= 3) && (mgs_obd->obd_num_exports <= 2);
1243 static int name_create_mdt(char **logname, char *fsname, int i)
1247 sprintf(mdt_index, "-MDT%04x", i);
1248 return name_create(logname, fsname, mdt_index);
1252 * Replace nids for \a device to \a nids values
1254 * \param obd MGS obd device
1255 * \param devname nids need to be replaced for this device
1256 * (ex. lustre-OST0000)
1257 * \param nids nids list (ex. nid1,nid2,nid3)
1261 int mgs_replace_nids(const struct lu_env *env,
1262 struct mgs_device *mgs,
1263 char *devname, char *nids)
1265 /* Assume fsname is part of device name */
1266 char fsname[MTI_NAME_MAXLEN];
1273 struct obd_device *mgs_obd = mgs->mgs_obd;
1276 /* We can only change NIDs if no other nodes are connected */
1277 spin_lock(&mgs_obd->obd_dev_lock);
1278 conn_state = mgs_obd->obd_no_conn;
1279 mgs_obd->obd_no_conn = 1;
1280 spin_unlock(&mgs_obd->obd_dev_lock);
1282 /* We can not change nids if not only MGS is started */
1283 if (!only_mgs_is_running(mgs_obd)) {
1284 CERROR("Only MGS is allowed to be started\n");
1285 GOTO(out, rc = -EINPROGRESS);
1288 /* Get fsname and index*/
1289 rc = mgs_parse_devname(devname, fsname, &index);
1293 rc = mgs_find_or_make_fsdb(env, mgs, fsname, &fsdb);
1295 CERROR("%s: can't find fsdb: rc = %d\n", fsname, rc);
1299 /* Process client llogs */
1300 name_create(&logname, fsname, "-client");
1301 rc = mgs_replace_nids_log(env, mgs_obd, fsdb, logname, devname, nids);
1302 name_destroy(&logname);
1304 CERROR("%s: error while replacing NIDs for %s: rc = %d\n",
1305 fsname, devname, rc);
1309 /* Process MDT llogs */
1310 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
1311 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
1313 name_create_mdt(&logname, fsname, i);
1314 rc = mgs_replace_nids_log(env, mgs_obd, fsdb, logname, devname, nids);
1315 name_destroy(&logname);
1321 spin_lock(&mgs_obd->obd_dev_lock);
1322 mgs_obd->obd_no_conn = conn_state;
1323 spin_unlock(&mgs_obd->obd_dev_lock);
1328 static int record_lov_setup(const struct lu_env *env, struct llog_handle *llh,
1329 char *devname, struct lov_desc *desc)
1331 struct mgs_thread_info *mgi = mgs_env_info(env);
1332 struct lustre_cfg *lcfg;
1335 lustre_cfg_bufs_reset(&mgi->mgi_bufs, devname);
1336 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, desc, sizeof(*desc));
1337 lcfg = lustre_cfg_new(LCFG_SETUP, &mgi->mgi_bufs);
1340 rc = record_lcfg(env, llh, lcfg);
1342 lustre_cfg_free(lcfg);
1346 static int record_lmv_setup(const struct lu_env *env, struct llog_handle *llh,
1347 char *devname, struct lmv_desc *desc)
1349 struct mgs_thread_info *mgi = mgs_env_info(env);
1350 struct lustre_cfg *lcfg;
1353 lustre_cfg_bufs_reset(&mgi->mgi_bufs, devname);
1354 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, desc, sizeof(*desc));
1355 lcfg = lustre_cfg_new(LCFG_SETUP, &mgi->mgi_bufs);
1357 rc = record_lcfg(env, llh, lcfg);
1359 lustre_cfg_free(lcfg);
1363 static inline int record_mdc_add(const struct lu_env *env,
1364 struct llog_handle *llh,
1365 char *logname, char *mdcuuid,
1366 char *mdtuuid, char *index,
1369 return record_base(env,llh,logname,0,LCFG_ADD_MDC,
1370 mdtuuid,index,gen,mdcuuid);
1373 static inline int record_lov_add(const struct lu_env *env,
1374 struct llog_handle *llh,
1375 char *lov_name, char *ost_uuid,
1376 char *index, char *gen)
1378 return record_base(env,llh,lov_name,0,LCFG_LOV_ADD_OBD,
1379 ost_uuid, index, gen, 0);
1382 static inline int record_mount_opt(const struct lu_env *env,
1383 struct llog_handle *llh,
1384 char *profile, char *lov_name,
1387 return record_base(env,llh,NULL,0,LCFG_MOUNTOPT,
1388 profile,lov_name,mdc_name,0);
1391 static int record_marker(const struct lu_env *env,
1392 struct llog_handle *llh,
1393 struct fs_db *fsdb, __u32 flags,
1394 char *tgtname, char *comment)
1396 struct mgs_thread_info *mgi = mgs_env_info(env);
1397 struct lustre_cfg *lcfg;
1401 if (flags & CM_START)
1403 mgi->mgi_marker.cm_step = fsdb->fsdb_gen;
1404 mgi->mgi_marker.cm_flags = flags;
1405 mgi->mgi_marker.cm_vers = LUSTRE_VERSION_CODE;
1406 cplen = strlcpy(mgi->mgi_marker.cm_tgtname, tgtname,
1407 sizeof(mgi->mgi_marker.cm_tgtname));
1408 if (cplen >= sizeof(mgi->mgi_marker.cm_tgtname))
1410 cplen = strlcpy(mgi->mgi_marker.cm_comment, comment,
1411 sizeof(mgi->mgi_marker.cm_comment));
1412 if (cplen >= sizeof(mgi->mgi_marker.cm_comment))
1414 mgi->mgi_marker.cm_createtime = cfs_time_current_sec();
1415 mgi->mgi_marker.cm_canceltime = 0;
1416 lustre_cfg_bufs_reset(&mgi->mgi_bufs, NULL);
1417 lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, &mgi->mgi_marker,
1418 sizeof(mgi->mgi_marker));
1419 lcfg = lustre_cfg_new(LCFG_MARKER, &mgi->mgi_bufs);
1422 rc = record_lcfg(env, llh, lcfg);
1424 lustre_cfg_free(lcfg);
1428 static int record_start_log(const struct lu_env *env, struct mgs_device *mgs,
1429 struct llog_handle **llh, char *name)
1431 static struct obd_uuid cfg_uuid = { .uuid = "config_uuid" };
1432 struct llog_ctxt *ctxt;
1436 GOTO(out, rc = -EBUSY);
1438 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
1440 GOTO(out, rc = -ENODEV);
1441 LASSERT(ctxt->loc_obd == mgs->mgs_obd);
1443 rc = llog_open_create(env, ctxt, llh, NULL, name);
1446 rc = llog_init_handle(env, *llh, LLOG_F_IS_PLAIN, &cfg_uuid);
1448 llog_close(env, *llh);
1450 llog_ctxt_put(ctxt);
1453 CERROR("%s: can't start log %s: rc = %d\n",
1454 mgs->mgs_obd->obd_name, name, rc);
1460 static int record_end_log(const struct lu_env *env, struct llog_handle **llh)
1464 rc = llog_close(env, *llh);
1470 static int mgs_log_is_empty(const struct lu_env *env,
1471 struct mgs_device *mgs, char *name)
1473 struct llog_handle *llh;
1474 struct llog_ctxt *ctxt;
1477 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
1478 LASSERT(ctxt != NULL);
1479 rc = llog_open(env, ctxt, &llh, NULL, name, LLOG_OPEN_EXISTS);
1486 rc = llog_init_handle(env, llh, LLOG_F_IS_PLAIN, NULL);
1488 GOTO(out_close, rc);
1489 rc = llog_get_size(llh);
1492 llog_close(env, llh);
1494 llog_ctxt_put(ctxt);
1495 /* header is record 1 */
1499 /******************** config "macros" *********************/
1501 /* write an lcfg directly into a log (with markers) */
1502 static int mgs_write_log_direct(const struct lu_env *env,
1503 struct mgs_device *mgs, struct fs_db *fsdb,
1504 char *logname, struct lustre_cfg *lcfg,
1505 char *devname, char *comment)
1507 struct llog_handle *llh = NULL;
1514 rc = record_start_log(env, mgs, &llh, logname);
1518 /* FIXME These should be a single journal transaction */
1519 rc = record_marker(env, llh, fsdb, CM_START, devname, comment);
1522 rc = record_lcfg(env, llh, lcfg);
1525 rc = record_marker(env, llh, fsdb, CM_END, devname, comment);
1529 record_end_log(env, &llh);
1533 /* write the lcfg in all logs for the given fs */
1534 int mgs_write_log_direct_all(const struct lu_env *env,
1535 struct mgs_device *mgs,
1537 struct mgs_target_info *mti,
1538 struct lustre_cfg *lcfg,
1539 char *devname, char *comment,
1543 struct mgs_direntry *dirent, *n;
1544 char *fsname = mti->mti_fsname;
1546 int rc = 0, len = strlen(fsname);
1549 /* We need to set params for any future logs
1550 as well. FIXME Append this file to every new log.
1551 Actually, we should store as params (text), not llogs. Or
1553 rc = name_create(&logname, fsname, "-params");
1556 if (mgs_log_is_empty(env, mgs, logname)) {
1557 struct llog_handle *llh = NULL;
1558 rc = record_start_log(env, mgs, &llh, logname);
1559 record_end_log(env, &llh);
1561 name_destroy(&logname);
1565 /* Find all the logs in the CONFIGS directory */
1566 rc = class_dentry_readdir(env, mgs, &list);
1570 /* Could use fsdb index maps instead of directory listing */
1571 cfs_list_for_each_entry_safe(dirent, n, &list, list) {
1572 cfs_list_del(&dirent->list);
1573 /* don't write to sptlrpc rule log */
1574 if (strstr(dirent->name, "-sptlrpc") != NULL)
1577 /* caller wants write server logs only */
1578 if (server_only && strstr(dirent->name, "-client") != NULL)
1581 if (strncmp(fsname, dirent->name, len) == 0) {
1582 CDEBUG(D_MGS, "Changing log %s\n", dirent->name);
1583 /* Erase any old settings of this same parameter */
1584 rc = mgs_modify(env, mgs, fsdb, mti, dirent->name,
1585 devname, comment, CM_SKIP);
1587 CERROR("%s: Can't modify llog %s: rc = %d\n",
1588 mgs->mgs_obd->obd_name, dirent->name,rc);
1589 /* Write the new one */
1591 rc = mgs_write_log_direct(env, mgs, fsdb,
1596 CERROR("%s: writing log %s: rc = %d\n",
1597 mgs->mgs_obd->obd_name,
1602 mgs_direntry_free(dirent);
1608 static int mgs_write_log_osp_to_mdt(const struct lu_env *env,
1609 struct mgs_device *mgs,
1611 struct mgs_target_info *mti,
1612 int index, char *logname);
1613 static int mgs_write_log_osc_to_lov(const struct lu_env *env,
1614 struct mgs_device *mgs,
1616 struct mgs_target_info *mti,
1617 char *logname, char *suffix, char *lovname,
1618 enum lustre_sec_part sec_part, int flags);
1619 static int name_create_mdt_and_lov(char **logname, char **lovname,
1620 struct fs_db *fsdb, int i);
1622 static int add_param(char *params, char *key, char *val)
1624 char *start = params + strlen(params);
1625 char *end = params + sizeof(((struct mgs_target_info *)0)->mti_params);
1629 keylen = strlen(key);
1630 if (start + 1 + keylen + strlen(val) >= end) {
1631 CERROR("params are too long: %s %s%s\n",
1632 params, key != NULL ? key : "", val);
1636 sprintf(start, " %s%s", key != NULL ? key : "", val);
1641 * Walk through client config log record and convert the related records
1644 static int mgs_steal_client_llog_handler(const struct lu_env *env,
1645 struct llog_handle *llh,
1646 struct llog_rec_hdr *rec, void *data)
1648 struct mgs_device *mgs;
1649 struct obd_device *obd;
1650 struct mgs_target_info *mti, *tmti;
1652 int cfg_len = rec->lrh_len;
1653 char *cfg_buf = (char*) (rec + 1);
1654 struct lustre_cfg *lcfg;
1656 struct llog_handle *mdt_llh = NULL;
1657 static int got_an_osc_or_mdc = 0;
1658 /* 0: not found any osc/mdc;
1662 static int last_step = -1;
1667 mti = ((struct temp_comp*)data)->comp_mti;
1668 tmti = ((struct temp_comp*)data)->comp_tmti;
1669 fsdb = ((struct temp_comp*)data)->comp_fsdb;
1670 obd = ((struct temp_comp *)data)->comp_obd;
1671 mgs = lu2mgs_dev(obd->obd_lu_dev);
1674 if (rec->lrh_type != OBD_CFG_REC) {
1675 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
1679 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
1681 CERROR("Insane cfg\n");
1685 lcfg = (struct lustre_cfg *)cfg_buf;
1687 if (lcfg->lcfg_command == LCFG_MARKER) {
1688 struct cfg_marker *marker;
1689 marker = lustre_cfg_buf(lcfg, 1);
1690 if (!strncmp(marker->cm_comment, "add osc", 7) &&
1691 (marker->cm_flags & CM_START) &&
1692 !(marker->cm_flags & CM_SKIP)) {
1693 got_an_osc_or_mdc = 1;
1694 cplen = strlcpy(tmti->mti_svname, marker->cm_tgtname,
1695 sizeof(tmti->mti_svname));
1696 if (cplen >= sizeof(tmti->mti_svname))
1698 rc = record_start_log(env, mgs, &mdt_llh,
1702 rc = record_marker(env, mdt_llh, fsdb, CM_START,
1703 mti->mti_svname, "add osc(copied)");
1704 record_end_log(env, &mdt_llh);
1705 last_step = marker->cm_step;
1708 if (!strncmp(marker->cm_comment, "add osc", 7) &&
1709 (marker->cm_flags & CM_END) &&
1710 !(marker->cm_flags & CM_SKIP)) {
1711 LASSERT(last_step == marker->cm_step);
1713 got_an_osc_or_mdc = 0;
1714 memset(tmti, 0, sizeof(*tmti));
1715 rc = record_start_log(env, mgs, &mdt_llh,
1719 rc = record_marker(env, mdt_llh, fsdb, CM_END,
1720 mti->mti_svname, "add osc(copied)");
1721 record_end_log(env, &mdt_llh);
1724 if (!strncmp(marker->cm_comment, "add mdc", 7) &&
1725 (marker->cm_flags & CM_START) &&
1726 !(marker->cm_flags & CM_SKIP)) {
1727 got_an_osc_or_mdc = 2;
1728 last_step = marker->cm_step;
1729 memcpy(tmti->mti_svname, marker->cm_tgtname,
1730 strlen(marker->cm_tgtname));
1734 if (!strncmp(marker->cm_comment, "add mdc", 7) &&
1735 (marker->cm_flags & CM_END) &&
1736 !(marker->cm_flags & CM_SKIP)) {
1737 LASSERT(last_step == marker->cm_step);
1739 got_an_osc_or_mdc = 0;
1740 memset(tmti, 0, sizeof(*tmti));
1745 if (got_an_osc_or_mdc == 0 || last_step < 0)
1748 if (lcfg->lcfg_command == LCFG_ADD_UUID) {
1749 uint64_t nodenid = lcfg->lcfg_nid;
1751 if (strlen(tmti->mti_uuid) == 0) {
1752 /* target uuid not set, this config record is before
1753 * LCFG_SETUP, this nid is one of target node nid.
1755 tmti->mti_nids[tmti->mti_nid_count] = nodenid;
1756 tmti->mti_nid_count++;
1758 /* failover node nid */
1759 rc = add_param(tmti->mti_params, PARAM_FAILNODE,
1760 libcfs_nid2str(nodenid));
1766 if (lcfg->lcfg_command == LCFG_SETUP) {
1769 target = lustre_cfg_string(lcfg, 1);
1770 memcpy(tmti->mti_uuid, target, strlen(target));
1774 /* ignore client side sptlrpc_conf_log */
1775 if (lcfg->lcfg_command == LCFG_SPTLRPC_CONF)
1778 if (lcfg->lcfg_command == LCFG_ADD_MDC) {
1781 if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1)
1784 memcpy(tmti->mti_fsname, mti->mti_fsname,
1785 strlen(mti->mti_fsname));
1786 tmti->mti_stripe_index = index;
1788 rc = mgs_write_log_osp_to_mdt(env, mgs, fsdb, tmti,
1789 mti->mti_stripe_index,
1791 memset(tmti, 0, sizeof(*tmti));
1795 if (lcfg->lcfg_command == LCFG_LOV_ADD_OBD) {
1798 char *logname, *lovname;
1800 rc = name_create_mdt_and_lov(&logname, &lovname, fsdb,
1801 mti->mti_stripe_index);
1804 sprintf(mdt_index, "-MDT%04x", mti->mti_stripe_index);
1806 if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1) {
1807 name_destroy(&logname);
1808 name_destroy(&lovname);
1812 tmti->mti_stripe_index = index;
1813 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, tmti, logname,
1816 name_destroy(&logname);
1817 name_destroy(&lovname);
1823 /* fsdb->fsdb_mutex is already held in mgs_write_log_target*/
1824 /* stealed from mgs_get_fsdb_from_llog*/
1825 static int mgs_steal_llog_for_mdt_from_client(const struct lu_env *env,
1826 struct mgs_device *mgs,
1828 struct temp_comp* comp)
1830 struct llog_handle *loghandle;
1831 struct mgs_target_info *tmti;
1832 struct llog_ctxt *ctxt;
1837 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
1838 LASSERT(ctxt != NULL);
1840 OBD_ALLOC_PTR(tmti);
1842 GOTO(out_ctxt, rc = -ENOMEM);
1844 comp->comp_tmti = tmti;
1845 comp->comp_obd = mgs->mgs_obd;
1847 rc = llog_open(env, ctxt, &loghandle, NULL, client_name,
1855 rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL);
1857 GOTO(out_close, rc);
1859 rc = llog_process_or_fork(env, loghandle, mgs_steal_client_llog_handler,
1860 (void *)comp, NULL, false);
1861 CDEBUG(D_MGS, "steal llog re = %d\n", rc);
1863 llog_close(env, loghandle);
1867 llog_ctxt_put(ctxt);
1871 /* lmv is the second thing for client logs */
1872 /* copied from mgs_write_log_lov. Please refer to that. */
1873 static int mgs_write_log_lmv(const struct lu_env *env,
1874 struct mgs_device *mgs,
1876 struct mgs_target_info *mti,
1877 char *logname, char *lmvname)
1879 struct llog_handle *llh = NULL;
1880 struct lmv_desc *lmvdesc;
1885 CDEBUG(D_MGS, "Writing lmv(%s) log for %s\n", lmvname,logname);
1887 OBD_ALLOC_PTR(lmvdesc);
1888 if (lmvdesc == NULL)
1890 lmvdesc->ld_active_tgt_count = 0;
1891 lmvdesc->ld_tgt_count = 0;
1892 sprintf((char*)lmvdesc->ld_uuid.uuid, "%s_UUID", lmvname);
1893 uuid = (char *)lmvdesc->ld_uuid.uuid;
1895 rc = record_start_log(env, mgs, &llh, logname);
1898 rc = record_marker(env, llh, fsdb, CM_START, lmvname, "lmv setup");
1901 rc = record_attach(env, llh, lmvname, "lmv", uuid);
1904 rc = record_lmv_setup(env, llh, lmvname, lmvdesc);
1907 rc = record_marker(env, llh, fsdb, CM_END, lmvname, "lmv setup");
1911 record_end_log(env, &llh);
1913 OBD_FREE_PTR(lmvdesc);
1917 /* lov is the first thing in the mdt and client logs */
1918 static int mgs_write_log_lov(const struct lu_env *env, struct mgs_device *mgs,
1919 struct fs_db *fsdb, struct mgs_target_info *mti,
1920 char *logname, char *lovname)
1922 struct llog_handle *llh = NULL;
1923 struct lov_desc *lovdesc;
1928 CDEBUG(D_MGS, "Writing lov(%s) log for %s\n", lovname, logname);
1931 #01 L attach 0:lov_mdsA 1:lov 2:71ccb_lov_mdsA_19f961a9e1
1932 #02 L lov_setup 0:lov_mdsA 1:(struct lov_desc)
1933 uuid=lov1_UUID, stripe count=1, size=1048576, offset=0, pattern=0
1936 /* FIXME just make lov_setup accept empty desc (put uuid in buf 2) */
1937 OBD_ALLOC_PTR(lovdesc);
1938 if (lovdesc == NULL)
1940 lovdesc->ld_magic = LOV_DESC_MAGIC;
1941 lovdesc->ld_tgt_count = 0;
1942 /* Defaults. Can be changed later by lcfg config_param */
1943 lovdesc->ld_default_stripe_count = 1;
1944 lovdesc->ld_pattern = LOV_PATTERN_RAID0;
1945 lovdesc->ld_default_stripe_size = 1024 * 1024;
1946 lovdesc->ld_default_stripe_offset = -1;
1947 lovdesc->ld_qos_maxage = QOS_DEFAULT_MAXAGE;
1948 sprintf((char*)lovdesc->ld_uuid.uuid, "%s_UUID", lovname);
1949 /* can these be the same? */
1950 uuid = (char *)lovdesc->ld_uuid.uuid;
1952 /* This should always be the first entry in a log.
1953 rc = mgs_clear_log(obd, logname); */
1954 rc = record_start_log(env, mgs, &llh, logname);
1957 /* FIXME these should be a single journal transaction */
1958 rc = record_marker(env, llh, fsdb, CM_START, lovname, "lov setup");
1961 rc = record_attach(env, llh, lovname, "lov", uuid);
1964 rc = record_lov_setup(env, llh, lovname, lovdesc);
1967 rc = record_marker(env, llh, fsdb, CM_END, lovname, "lov setup");
1972 record_end_log(env, &llh);
1974 OBD_FREE_PTR(lovdesc);
1978 /* add failnids to open log */
1979 static int mgs_write_log_failnids(const struct lu_env *env,
1980 struct mgs_target_info *mti,
1981 struct llog_handle *llh,
1984 char *failnodeuuid = NULL;
1985 char *ptr = mti->mti_params;
1990 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) nal=90 0: 1:uml1_UUID
1991 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
1992 #05 L setup 0:OSC_uml1_ost1_mdsA 1:ost1_UUID 2:uml1_UUID
1993 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) nal=90 0: 1:uml2_UUID
1994 #0x L add_uuid nid=2@elan(0x1000000000002) nal=90 0: 1:uml2_UUID
1995 #07 L add_conn 0:OSC_uml1_ost1_mdsA 1:uml2_UUID
1998 /* Pull failnid info out of params string */
1999 while (class_find_param(ptr, PARAM_FAILNODE, &ptr) == 0) {
2000 while (class_parse_nid(ptr, &nid, &ptr) == 0) {
2001 if (failnodeuuid == NULL) {
2002 /* We don't know the failover node name,
2003 so just use the first nid as the uuid */
2004 rc = name_create(&failnodeuuid,
2005 libcfs_nid2str(nid), "");
2009 CDEBUG(D_MGS, "add nid %s for failover uuid %s, "
2010 "client %s\n", libcfs_nid2str(nid),
2011 failnodeuuid, cliname);
2012 rc = record_add_uuid(env, llh, nid, failnodeuuid);
2015 rc = record_add_conn(env, llh, cliname, failnodeuuid);
2018 name_destroy(&failnodeuuid);
2022 static int mgs_write_log_mdc_to_lmv(const struct lu_env *env,
2023 struct mgs_device *mgs,
2025 struct mgs_target_info *mti,
2026 char *logname, char *lmvname)
2028 struct llog_handle *llh = NULL;
2029 char *mdcname = NULL;
2030 char *nodeuuid = NULL;
2031 char *mdcuuid = NULL;
2032 char *lmvuuid = NULL;
2037 if (mgs_log_is_empty(env, mgs, logname)) {
2038 CERROR("log is empty! Logical error\n");
2042 CDEBUG(D_MGS, "adding mdc for %s to log %s:lmv(%s)\n",
2043 mti->mti_svname, logname, lmvname);
2045 rc = name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
2048 rc = name_create(&mdcname, mti->mti_svname, "-mdc");
2051 rc = name_create(&mdcuuid, mdcname, "_UUID");
2054 rc = name_create(&lmvuuid, lmvname, "_UUID");
2058 rc = record_start_log(env, mgs, &llh, logname);
2061 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
2065 for (i = 0; i < mti->mti_nid_count; i++) {
2066 CDEBUG(D_MGS, "add nid %s for mdt\n",
2067 libcfs_nid2str(mti->mti_nids[i]));
2069 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
2074 rc = record_attach(env, llh, mdcname, LUSTRE_MDC_NAME, lmvuuid);
2077 rc = record_setup(env, llh, mdcname, mti->mti_uuid, nodeuuid, 0, 0);
2080 rc = mgs_write_log_failnids(env, mti, llh, mdcname);
2083 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
2084 rc = record_mdc_add(env, llh, lmvname, mdcuuid, mti->mti_uuid,
2088 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname,
2093 record_end_log(env, &llh);
2095 name_destroy(&lmvuuid);
2096 name_destroy(&mdcuuid);
2097 name_destroy(&mdcname);
2098 name_destroy(&nodeuuid);
2102 static inline int name_create_lov(char **lovname, char *mdtname,
2103 struct fs_db *fsdb, int index)
2106 if (index == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2107 return name_create(lovname, fsdb->fsdb_name, "-mdtlov");
2109 return name_create(lovname, mdtname, "-mdtlov");
2112 static int name_create_mdt_and_lov(char **logname, char **lovname,
2113 struct fs_db *fsdb, int i)
2117 rc = name_create_mdt(logname, fsdb->fsdb_name, i);
2121 if (i == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2122 rc = name_create(lovname, fsdb->fsdb_name, "-mdtlov");
2124 rc = name_create(lovname, *logname, "-mdtlov");
2126 name_destroy(logname);
2132 static inline int name_create_mdt_osc(char **oscname, char *ostname,
2133 struct fs_db *fsdb, int i)
2137 if (i == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2138 sprintf(suffix, "-osc");
2140 sprintf(suffix, "-osc-MDT%04x", i);
2141 return name_create(oscname, ostname, suffix);
2144 /* add new mdc to already existent MDS */
2145 static int mgs_write_log_osp_to_mdt(const struct lu_env *env,
2146 struct mgs_device *mgs,
2148 struct mgs_target_info *mti,
2149 int mdt_index, char *logname)
2151 struct llog_handle *llh = NULL;
2152 char *nodeuuid = NULL;
2153 char *ospname = NULL;
2154 char *lovuuid = NULL;
2155 char *mdtuuid = NULL;
2156 char *svname = NULL;
2157 char *mdtname = NULL;
2158 char *lovname = NULL;
2163 if (mgs_log_is_empty(env, mgs, mti->mti_svname)) {
2164 CERROR("log is empty! Logical error\n");
2168 CDEBUG(D_MGS, "adding osp index %d to %s\n", mti->mti_stripe_index,
2171 rc = name_create_mdt(&mdtname, fsdb->fsdb_name, mti->mti_stripe_index);
2175 rc = name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
2177 GOTO(out_destory, rc);
2179 rc = name_create(&svname, mdtname, "-osp");
2181 GOTO(out_destory, rc);
2183 sprintf(index_str, "-MDT%04x", mdt_index);
2184 rc = name_create(&ospname, svname, index_str);
2186 GOTO(out_destory, rc);
2188 rc = name_create_lov(&lovname, logname, fsdb, mdt_index);
2190 GOTO(out_destory, rc);
2192 rc = name_create(&lovuuid, lovname, "_UUID");
2194 GOTO(out_destory, rc);
2196 rc = name_create(&mdtuuid, mdtname, "_UUID");
2198 GOTO(out_destory, rc);
2200 rc = record_start_log(env, mgs, &llh, logname);
2202 GOTO(out_destory, rc);
2204 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
2207 GOTO(out_destory, rc);
2209 for (i = 0; i < mti->mti_nid_count; i++) {
2210 CDEBUG(D_MGS, "add nid %s for mdt\n",
2211 libcfs_nid2str(mti->mti_nids[i]));
2212 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
2217 rc = record_attach(env, llh, ospname, LUSTRE_OSP_NAME, lovuuid);
2221 rc = record_setup(env, llh, ospname, mti->mti_uuid, nodeuuid,
2226 rc = mgs_write_log_failnids(env, mti, llh, ospname);
2230 /* Add mdc(osp) to lod */
2231 snprintf(index_str, sizeof(mti->mti_stripe_index), "%d",
2232 mti->mti_stripe_index);
2233 rc = record_base(env, llh, lovname, 0, LCFG_ADD_MDC, mti->mti_uuid,
2234 index_str, "1", NULL);
2238 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname, "add osp");
2243 record_end_log(env, &llh);
2246 name_destroy(&mdtuuid);
2247 name_destroy(&lovuuid);
2248 name_destroy(&lovname);
2249 name_destroy(&ospname);
2250 name_destroy(&svname);
2251 name_destroy(&nodeuuid);
2252 name_destroy(&mdtname);
2256 static int mgs_write_log_mdt0(const struct lu_env *env,
2257 struct mgs_device *mgs,
2259 struct mgs_target_info *mti)
2261 char *log = mti->mti_svname;
2262 struct llog_handle *llh = NULL;
2263 char *uuid, *lovname;
2265 char *ptr = mti->mti_params;
2266 int rc = 0, failout = 0;
2269 OBD_ALLOC(uuid, sizeof(struct obd_uuid));
2273 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
2274 failout = (strncmp(ptr, "failout", 7) == 0);
2276 rc = name_create(&lovname, log, "-mdtlov");
2279 if (mgs_log_is_empty(env, mgs, log)) {
2280 rc = mgs_write_log_lov(env, mgs, fsdb, mti, log, lovname);
2285 sprintf(mdt_index, "%d", mti->mti_stripe_index);
2287 rc = record_start_log(env, mgs, &llh, log);
2291 /* add MDT itself */
2293 /* FIXME this whole fn should be a single journal transaction */
2294 sprintf(uuid, "%s_UUID", log);
2295 rc = record_marker(env, llh, fsdb, CM_START, log, "add mdt");
2298 rc = record_attach(env, llh, log, LUSTRE_MDT_NAME, uuid);
2301 rc = record_mount_opt(env, llh, log, lovname, NULL);
2304 rc = record_setup(env, llh, log, uuid, mdt_index, lovname,
2305 failout ? "n" : "f");
2308 rc = record_marker(env, llh, fsdb, CM_END, log, "add mdt");
2312 record_end_log(env, &llh);
2314 name_destroy(&lovname);
2316 OBD_FREE(uuid, sizeof(struct obd_uuid));
2320 /* envelope method for all layers log */
2321 static int mgs_write_log_mdt(const struct lu_env *env,
2322 struct mgs_device *mgs,
2324 struct mgs_target_info *mti)
2326 struct mgs_thread_info *mgi = mgs_env_info(env);
2327 struct llog_handle *llh = NULL;
2332 CDEBUG(D_MGS, "writing new mdt %s\n", mti->mti_svname);
2334 if (mti->mti_uuid[0] == '\0') {
2335 /* Make up our own uuid */
2336 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
2337 "%s_UUID", mti->mti_svname);
2341 rc = mgs_write_log_mdt0(env, mgs, fsdb, mti);
2344 /* Append the mdt info to the client log */
2345 rc = name_create(&cliname, mti->mti_fsname, "-client");
2349 if (mgs_log_is_empty(env, mgs, cliname)) {
2350 /* Start client log */
2351 rc = mgs_write_log_lov(env, mgs, fsdb, mti, cliname,
2355 rc = mgs_write_log_lmv(env, mgs, fsdb, mti, cliname,
2362 #09 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
2363 #10 L attach 0:MDC_uml1_mdsA_MNT_client 1:mdc 2:1d834_MNT_client_03f
2364 #11 L setup 0:MDC_uml1_mdsA_MNT_client 1:mdsA_UUID 2:uml1_UUID
2365 #12 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
2366 #13 L add_conn 0:MDC_uml1_mdsA_MNT_client 1:uml2_UUID
2367 #14 L mount_option 0: 1:client 2:lov1 3:MDC_uml1_mdsA_MNT_client
2370 /* copy client info about lov/lmv */
2371 mgi->mgi_comp.comp_mti = mti;
2372 mgi->mgi_comp.comp_fsdb = fsdb;
2374 rc = mgs_steal_llog_for_mdt_from_client(env, mgs, cliname,
2378 rc = mgs_write_log_mdc_to_lmv(env, mgs, fsdb, mti, cliname,
2384 rc = record_start_log(env, mgs, &llh, cliname);
2388 rc = record_marker(env, llh, fsdb, CM_START, cliname,
2392 rc = record_mount_opt(env, llh, cliname, fsdb->fsdb_clilov,
2396 rc = record_marker(env, llh, fsdb, CM_END, cliname,
2402 /* for_all_existing_mdt except current one */
2403 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2404 if (i != mti->mti_stripe_index &&
2405 test_bit(i, fsdb->fsdb_mdt_index_map)) {
2408 rc = name_create_mdt(&logname, fsdb->fsdb_name, i);
2412 rc = mgs_write_log_osp_to_mdt(env, mgs, fsdb, mti,
2414 name_destroy(&logname);
2420 record_end_log(env, &llh);
2422 name_destroy(&cliname);
2426 /* Add the ost info to the client/mdt lov */
2427 static int mgs_write_log_osc_to_lov(const struct lu_env *env,
2428 struct mgs_device *mgs, struct fs_db *fsdb,
2429 struct mgs_target_info *mti,
2430 char *logname, char *suffix, char *lovname,
2431 enum lustre_sec_part sec_part, int flags)
2433 struct llog_handle *llh = NULL;
2434 char *nodeuuid = NULL;
2435 char *oscname = NULL;
2436 char *oscuuid = NULL;
2437 char *lovuuid = NULL;
2438 char *svname = NULL;
2443 CDEBUG(D_INFO, "adding osc for %s to log %s\n",
2444 mti->mti_svname, logname);
2446 if (mgs_log_is_empty(env, mgs, logname)) {
2447 CERROR("log is empty! Logical error\n");
2451 rc = name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
2454 rc = name_create(&svname, mti->mti_svname, "-osc");
2458 /* for the system upgraded from old 1.8, keep using the old osc naming
2459 * style for mdt, see name_create_mdt_osc(). LU-1257 */
2460 if (test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
2461 rc = name_create(&oscname, svname, "");
2463 rc = name_create(&oscname, svname, suffix);
2467 rc = name_create(&oscuuid, oscname, "_UUID");
2470 rc = name_create(&lovuuid, lovname, "_UUID");
2476 #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0: 1:uml1_UUID
2478 #04 L add_uuid nid=1@elan(0x1000000000001) nal=90 0: 1:uml1_UUID
2479 #04 L attach 0:OSC_uml1_ost1_MNT_client 1:osc 2:89070_lov1_a41dff51a
2480 #05 L setup 0:OSC_uml1_ost1_MNT_client 1:ost1_UUID 2:uml1_UUID
2482 #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0: 1:uml2_UUID
2483 #07 L add_conn 0:OSC_uml1_ost1_MNT_client 1:uml2_UUID
2484 #08 L lov_modify_tgts add 0:lov1 1:ost1_UUID 2(index):0 3(gen):1
2487 rc = record_start_log(env, mgs, &llh, logname);
2491 /* FIXME these should be a single journal transaction */
2492 rc = record_marker(env, llh, fsdb, CM_START | flags, mti->mti_svname,
2497 /* NB: don't change record order, because upon MDT steal OSC config
2498 * from client, it treats all nids before LCFG_SETUP as target nids
2499 * (multiple interfaces), while nids after as failover node nids.
2500 * See mgs_steal_client_llog_handler() LCFG_ADD_UUID.
2502 for (i = 0; i < mti->mti_nid_count; i++) {
2503 CDEBUG(D_MGS, "add nid %s\n", libcfs_nid2str(mti->mti_nids[i]));
2504 rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
2508 rc = record_attach(env, llh, oscname, LUSTRE_OSC_NAME, lovuuid);
2511 rc = record_setup(env, llh, oscname, mti->mti_uuid, nodeuuid, 0, 0);
2514 rc = mgs_write_log_failnids(env, mti, llh, oscname);
2518 snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
2520 rc = record_lov_add(env, llh, lovname, mti->mti_uuid, index, "1");
2523 rc = record_marker(env, llh, fsdb, CM_END | flags, mti->mti_svname,
2528 record_end_log(env, &llh);
2530 name_destroy(&lovuuid);
2531 name_destroy(&oscuuid);
2532 name_destroy(&oscname);
2533 name_destroy(&svname);
2534 name_destroy(&nodeuuid);
2538 static int mgs_write_log_ost(const struct lu_env *env,
2539 struct mgs_device *mgs, struct fs_db *fsdb,
2540 struct mgs_target_info *mti)
2542 struct llog_handle *llh = NULL;
2543 char *logname, *lovname;
2544 char *ptr = mti->mti_params;
2545 int rc, flags = 0, failout = 0, i;
2548 CDEBUG(D_MGS, "writing new ost %s\n", mti->mti_svname);
2550 /* The ost startup log */
2552 /* If the ost log already exists, that means that someone reformatted
2553 the ost and it called target_add again. */
2554 if (!mgs_log_is_empty(env, mgs, mti->mti_svname)) {
2555 LCONSOLE_ERROR_MSG(0x141, "The config log for %s already "
2556 "exists, yet the server claims it never "
2557 "registered. It may have been reformatted, "
2558 "or the index changed. writeconf the MDT to "
2559 "regenerate all logs.\n", mti->mti_svname);
2564 attach obdfilter ost1 ost1_UUID
2565 setup /dev/loop2 ldiskfs f|n errors=remount-ro,user_xattr
2567 if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
2568 failout = (strncmp(ptr, "failout", 7) == 0);
2569 rc = record_start_log(env, mgs, &llh, mti->mti_svname);
2572 /* FIXME these should be a single journal transaction */
2573 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,"add ost");
2576 if (*mti->mti_uuid == '\0')
2577 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
2578 "%s_UUID", mti->mti_svname);
2579 rc = record_attach(env, llh, mti->mti_svname,
2580 "obdfilter"/*LUSTRE_OST_NAME*/, mti->mti_uuid);
2583 rc = record_setup(env, llh, mti->mti_svname,
2584 "dev"/*ignored*/, "type"/*ignored*/,
2585 failout ? "n" : "f", 0/*options*/);
2588 rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname, "add ost");
2592 record_end_log(env, &llh);
2595 /* We also have to update the other logs where this osc is part of
2598 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
2599 /* If we're upgrading, the old mdt log already has our
2600 entry. Let's do a fake one for fun. */
2601 /* Note that we can't add any new failnids, since we don't
2602 know the old osc names. */
2603 flags = CM_SKIP | CM_UPGRADE146;
2605 } else if ((mti->mti_flags & LDD_F_UPDATE) != LDD_F_UPDATE) {
2606 /* If the update flag isn't set, don't update client/mdt
2609 LCONSOLE_WARN("Client log for %s was not updated; writeconf "
2610 "the MDT first to regenerate it.\n",
2614 /* Add ost to all MDT lov defs */
2615 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
2616 if (test_bit(i, fsdb->fsdb_mdt_index_map)) {
2619 rc = name_create_mdt_and_lov(&logname, &lovname, fsdb,
2623 sprintf(mdt_index, "-MDT%04x", i);
2624 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, mti,
2626 lovname, LUSTRE_SP_MDT,
2628 name_destroy(&logname);
2629 name_destroy(&lovname);
2635 /* Append ost info to the client log */
2636 rc = name_create(&logname, mti->mti_fsname, "-client");
2639 if (mgs_log_is_empty(env, mgs, logname)) {
2640 /* Start client log */
2641 rc = mgs_write_log_lov(env, mgs, fsdb, mti, logname,
2645 rc = mgs_write_log_lmv(env, mgs, fsdb, mti, logname,
2650 rc = mgs_write_log_osc_to_lov(env, mgs, fsdb, mti, logname, "",
2651 fsdb->fsdb_clilov, LUSTRE_SP_CLI, 0);
2653 name_destroy(&logname);
2657 static __inline__ int mgs_param_empty(char *ptr)
2661 if ((tmp = strchr(ptr, '=')) && (*(++tmp) == '\0'))
2666 static int mgs_write_log_failnid_internal(const struct lu_env *env,
2667 struct mgs_device *mgs,
2669 struct mgs_target_info *mti,
2670 char *logname, char *cliname)
2673 struct llog_handle *llh = NULL;
2675 if (mgs_param_empty(mti->mti_params)) {
2676 /* Remove _all_ failnids */
2677 rc = mgs_modify(env, mgs, fsdb, mti, logname,
2678 mti->mti_svname, "add failnid", CM_SKIP);
2679 return rc < 0 ? rc : 0;
2682 /* Otherwise failover nids are additive */
2683 rc = record_start_log(env, mgs, &llh, logname);
2686 /* FIXME this should be a single journal transaction */
2687 rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
2691 rc = mgs_write_log_failnids(env, mti, llh, cliname);
2694 rc = record_marker(env, llh, fsdb, CM_END,
2695 mti->mti_svname, "add failnid");
2697 record_end_log(env, &llh);
2702 /* Add additional failnids to an existing log.
2703 The mdc/osc must have been added to logs first */
2704 /* tcp nids must be in dotted-quad ascii -
2705 we can't resolve hostnames from the kernel. */
2706 static int mgs_write_log_add_failnid(const struct lu_env *env,
2707 struct mgs_device *mgs,
2709 struct mgs_target_info *mti)
2711 char *logname, *cliname;
2715 /* FIXME we currently can't erase the failnids
2716 * given when a target first registers, since they aren't part of
2717 * an "add uuid" stanza */
2719 /* Verify that we know about this target */
2720 if (mgs_log_is_empty(env, mgs, mti->mti_svname)) {
2721 LCONSOLE_ERROR_MSG(0x142, "The target %s has not registered "
2722 "yet. It must be started before failnids "
2723 "can be added.\n", mti->mti_svname);
2727 /* Create mdc/osc client name (e.g. lustre-OST0001-osc) */
2728 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
2729 rc = name_create(&cliname, mti->mti_svname, "-mdc");
2730 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2731 rc = name_create(&cliname, mti->mti_svname, "-osc");
2737 /* Add failover nids to the client log */
2738 rc = name_create(&logname, mti->mti_fsname, "-client");
2740 name_destroy(&cliname);
2743 rc = mgs_write_log_failnid_internal(env, mgs, fsdb,mti,logname,cliname);
2744 name_destroy(&logname);
2745 name_destroy(&cliname);
2749 if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2750 /* Add OST failover nids to the MDT logs as well */
2753 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2754 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
2756 rc = name_create_mdt(&logname, mti->mti_fsname, i);
2759 rc = name_create_mdt_osc(&cliname, mti->mti_svname,
2762 name_destroy(&logname);
2765 rc = mgs_write_log_failnid_internal(env, mgs, fsdb,
2768 name_destroy(&cliname);
2769 name_destroy(&logname);
2778 static int mgs_wlp_lcfg(const struct lu_env *env,
2779 struct mgs_device *mgs, struct fs_db *fsdb,
2780 struct mgs_target_info *mti,
2781 char *logname, struct lustre_cfg_bufs *bufs,
2782 char *tgtname, char *ptr)
2784 char comment[MTI_NAME_MAXLEN];
2786 struct lustre_cfg *lcfg;
2789 /* Erase any old settings of this same parameter */
2790 memcpy(comment, ptr, MTI_NAME_MAXLEN);
2791 comment[MTI_NAME_MAXLEN - 1] = 0;
2792 /* But don't try to match the value. */
2793 if ((tmp = strchr(comment, '=')))
2795 /* FIXME we should skip settings that are the same as old values */
2796 rc = mgs_modify(env, mgs, fsdb, mti, logname, tgtname, comment,CM_SKIP);
2799 del = mgs_param_empty(ptr);
2801 LCONSOLE_INFO("%sing parameter %s.%s in log %s\n", del ? "Disabl" : rc ?
2802 "Sett" : "Modify", tgtname, comment, logname);
2806 lustre_cfg_bufs_reset(bufs, tgtname);
2807 lustre_cfg_bufs_set_string(bufs, 1, ptr);
2808 lcfg = lustre_cfg_new(LCFG_PARAM, bufs);
2811 rc = mgs_write_log_direct(env, mgs, fsdb, logname,lcfg,tgtname,comment);
2812 lustre_cfg_free(lcfg);
2816 /* write global variable settings into log */
2817 static int mgs_write_log_sys(const struct lu_env *env,
2818 struct mgs_device *mgs, struct fs_db *fsdb,
2819 struct mgs_target_info *mti, char *sys, char *ptr)
2821 struct mgs_thread_info *mgi = mgs_env_info(env);
2822 struct lustre_cfg *lcfg;
2824 int rc, cmd, convert = 1;
2826 if (class_match_param(ptr, PARAM_TIMEOUT, &tmp) == 0) {
2827 cmd = LCFG_SET_TIMEOUT;
2828 } else if (class_match_param(ptr, PARAM_LDLM_TIMEOUT, &tmp) == 0) {
2829 cmd = LCFG_SET_LDLM_TIMEOUT;
2830 /* Check for known params here so we can return error to lctl */
2831 } else if ((class_match_param(ptr, PARAM_AT_MIN, &tmp) == 0) ||
2832 (class_match_param(ptr, PARAM_AT_MAX, &tmp) == 0) ||
2833 (class_match_param(ptr, PARAM_AT_EXTRA, &tmp) == 0) ||
2834 (class_match_param(ptr, PARAM_AT_EARLY_MARGIN, &tmp) == 0) ||
2835 (class_match_param(ptr, PARAM_AT_HISTORY, &tmp) == 0)) {
2837 } else if (class_match_param(ptr, PARAM_JOBID_VAR, &tmp) == 0) {
2838 convert = 0; /* Don't convert string value to integer */
2844 if (mgs_param_empty(ptr))
2845 CDEBUG(D_MGS, "global '%s' removed\n", sys);
2847 CDEBUG(D_MGS, "global '%s' val=%s\n", sys, tmp);
2849 lustre_cfg_bufs_reset(&mgi->mgi_bufs, NULL);
2850 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, sys);
2851 if (!convert && *tmp != '\0')
2852 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 2, tmp);
2853 lcfg = lustre_cfg_new(cmd, &mgi->mgi_bufs);
2854 lcfg->lcfg_num = convert ? simple_strtoul(tmp, NULL, 0) : 0;
2855 /* truncate the comment to the parameter name */
2859 /* modify all servers and clients */
2860 rc = mgs_write_log_direct_all(env, mgs, fsdb, mti,
2861 *tmp == '\0' ? NULL : lcfg,
2862 mti->mti_fsname, sys, 0);
2863 if (rc == 0 && *tmp != '\0') {
2865 case LCFG_SET_TIMEOUT:
2866 if (!obd_timeout_set || lcfg->lcfg_num > obd_timeout)
2867 class_process_config(lcfg);
2869 case LCFG_SET_LDLM_TIMEOUT:
2870 if (!ldlm_timeout_set || lcfg->lcfg_num > ldlm_timeout)
2871 class_process_config(lcfg);
2878 lustre_cfg_free(lcfg);
2882 /* write quota settings into log */
2883 static int mgs_write_log_quota(const struct lu_env *env, struct mgs_device *mgs,
2884 struct fs_db *fsdb, struct mgs_target_info *mti,
2885 char *quota, char *ptr)
2887 struct mgs_thread_info *mgi = mgs_env_info(env);
2888 struct lustre_cfg *lcfg;
2891 int rc, cmd = LCFG_PARAM;
2893 /* support only 'meta' and 'data' pools so far */
2894 if (class_match_param(ptr, QUOTA_METAPOOL_NAME, &tmp) != 0 &&
2895 class_match_param(ptr, QUOTA_DATAPOOL_NAME, &tmp) != 0) {
2896 CERROR("parameter quota.%s isn't supported (only quota.mdt "
2897 "& quota.ost are)\n", ptr);
2902 CDEBUG(D_MGS, "global '%s' removed\n", quota);
2904 CDEBUG(D_MGS, "global '%s'\n", quota);
2906 if (strchr(tmp, 'u') == NULL && strchr(tmp, 'g') == NULL &&
2907 strcmp(tmp, "none") != 0) {
2908 CERROR("enable option(%s) isn't supported\n", tmp);
2913 lustre_cfg_bufs_reset(&mgi->mgi_bufs, mti->mti_fsname);
2914 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, quota);
2915 lcfg = lustre_cfg_new(cmd, &mgi->mgi_bufs);
2916 /* truncate the comment to the parameter name */
2921 /* XXX we duplicated quota enable information in all server
2922 * config logs, it should be moved to a separate config
2923 * log once we cleanup the config log for global param. */
2924 /* modify all servers */
2925 rc = mgs_write_log_direct_all(env, mgs, fsdb, mti,
2926 *tmp == '\0' ? NULL : lcfg,
2927 mti->mti_fsname, quota, 1);
2929 lustre_cfg_free(lcfg);
2930 return rc < 0 ? rc : 0;
2933 static int mgs_srpc_set_param_disk(const struct lu_env *env,
2934 struct mgs_device *mgs,
2936 struct mgs_target_info *mti,
2939 struct mgs_thread_info *mgi = mgs_env_info(env);
2940 struct llog_handle *llh = NULL;
2942 char *comment, *ptr;
2943 struct lustre_cfg *lcfg;
2948 ptr = strchr(param, '=');
2952 OBD_ALLOC(comment, len + 1);
2953 if (comment == NULL)
2955 strncpy(comment, param, len);
2956 comment[len] = '\0';
2959 lustre_cfg_bufs_reset(&mgi->mgi_bufs, mti->mti_svname);
2960 lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, param);
2961 lcfg = lustre_cfg_new(LCFG_SPTLRPC_CONF, &mgi->mgi_bufs);
2963 GOTO(out_comment, rc = -ENOMEM);
2965 /* construct log name */
2966 rc = name_create(&logname, mti->mti_fsname, "-sptlrpc");
2970 if (mgs_log_is_empty(env, mgs, logname)) {
2971 rc = record_start_log(env, mgs, &llh, logname);
2974 record_end_log(env, &llh);
2977 /* obsolete old one */
2978 rc = mgs_modify(env, mgs, fsdb, mti, logname, mti->mti_svname,
2982 /* write the new one */
2983 rc = mgs_write_log_direct(env, mgs, fsdb, logname, lcfg,
2984 mti->mti_svname, comment);
2986 CERROR("err %d writing log %s\n", rc, logname);
2988 name_destroy(&logname);
2990 lustre_cfg_free(lcfg);
2992 OBD_FREE(comment, len + 1);
2996 static int mgs_srpc_set_param_udesc_mem(struct fs_db *fsdb,
3001 /* disable the adjustable udesc parameter for now, i.e. use default
3002 * setting that client always ship udesc to MDT if possible. to enable
3003 * it simply remove the following line */
3006 ptr = strchr(param, '=');
3011 if (strcmp(param, PARAM_SRPC_UDESC))
3014 if (strcmp(ptr, "yes") == 0) {
3015 set_bit(FSDB_UDESC, &fsdb->fsdb_flags);
3016 CWARN("Enable user descriptor shipping from client to MDT\n");
3017 } else if (strcmp(ptr, "no") == 0) {
3018 clear_bit(FSDB_UDESC, &fsdb->fsdb_flags);
3019 CWARN("Disable user descriptor shipping from client to MDT\n");
3027 CERROR("Invalid param: %s\n", param);
3031 static int mgs_srpc_set_param_mem(struct fs_db *fsdb,
3035 struct sptlrpc_rule rule;
3036 struct sptlrpc_rule_set *rset;
3040 if (strncmp(param, PARAM_SRPC, sizeof(PARAM_SRPC) - 1) != 0) {
3041 CERROR("Invalid sptlrpc parameter: %s\n", param);
3045 if (strncmp(param, PARAM_SRPC_UDESC,
3046 sizeof(PARAM_SRPC_UDESC) - 1) == 0) {
3047 RETURN(mgs_srpc_set_param_udesc_mem(fsdb, param));
3050 if (strncmp(param, PARAM_SRPC_FLVR, sizeof(PARAM_SRPC_FLVR) - 1) != 0) {
3051 CERROR("Invalid sptlrpc flavor parameter: %s\n", param);
3055 param += sizeof(PARAM_SRPC_FLVR) - 1;
3057 rc = sptlrpc_parse_rule(param, &rule);
3061 /* mgs rules implies must be mgc->mgs */
3062 if (test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
3063 if ((rule.sr_from != LUSTRE_SP_MGC &&
3064 rule.sr_from != LUSTRE_SP_ANY) ||
3065 (rule.sr_to != LUSTRE_SP_MGS &&
3066 rule.sr_to != LUSTRE_SP_ANY))
3070 /* preapre room for this coming rule. svcname format should be:
3071 * - fsname: general rule
3072 * - fsname-tgtname: target-specific rule
3074 if (strchr(svname, '-')) {
3075 struct mgs_tgt_srpc_conf *tgtconf;
3078 for (tgtconf = fsdb->fsdb_srpc_tgt; tgtconf != NULL;
3079 tgtconf = tgtconf->mtsc_next) {
3080 if (!strcmp(tgtconf->mtsc_tgt, svname)) {
3089 OBD_ALLOC_PTR(tgtconf);
3090 if (tgtconf == NULL)
3093 name_len = strlen(svname);
3095 OBD_ALLOC(tgtconf->mtsc_tgt, name_len + 1);
3096 if (tgtconf->mtsc_tgt == NULL) {
3097 OBD_FREE_PTR(tgtconf);
3100 memcpy(tgtconf->mtsc_tgt, svname, name_len);
3102 tgtconf->mtsc_next = fsdb->fsdb_srpc_tgt;
3103 fsdb->fsdb_srpc_tgt = tgtconf;
3106 rset = &tgtconf->mtsc_rset;
3108 rset = &fsdb->fsdb_srpc_gen;
3111 rc = sptlrpc_rule_set_merge(rset, &rule);
3116 static int mgs_srpc_set_param(const struct lu_env *env,
3117 struct mgs_device *mgs,
3119 struct mgs_target_info *mti,
3129 /* keep a copy of original param, which could be destroied
3131 copy_size = strlen(param) + 1;
3132 OBD_ALLOC(copy, copy_size);
3135 memcpy(copy, param, copy_size);
3137 rc = mgs_srpc_set_param_mem(fsdb, mti->mti_svname, param);
3141 /* previous steps guaranteed the syntax is correct */
3142 rc = mgs_srpc_set_param_disk(env, mgs, fsdb, mti, copy);
3146 if (test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
3148 * for mgs rules, make them effective immediately.
3150 LASSERT(fsdb->fsdb_srpc_tgt == NULL);
3151 sptlrpc_target_update_exp_flavor(mgs->mgs_obd,
3152 &fsdb->fsdb_srpc_gen);
3156 OBD_FREE(copy, copy_size);
3160 struct mgs_srpc_read_data {
3161 struct fs_db *msrd_fsdb;
3165 static int mgs_srpc_read_handler(const struct lu_env *env,
3166 struct llog_handle *llh,
3167 struct llog_rec_hdr *rec, void *data)
3169 struct mgs_srpc_read_data *msrd = data;
3170 struct cfg_marker *marker;
3171 struct lustre_cfg *lcfg = REC_DATA(rec);
3172 char *svname, *param;
3176 if (rec->lrh_type != OBD_CFG_REC) {
3177 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
3181 cfg_len = rec->lrh_len - sizeof(struct llog_rec_hdr) -
3182 sizeof(struct llog_rec_tail);
3184 rc = lustre_cfg_sanity_check(lcfg, cfg_len);
3186 CERROR("Insane cfg\n");
3190 if (lcfg->lcfg_command == LCFG_MARKER) {
3191 marker = lustre_cfg_buf(lcfg, 1);
3193 if (marker->cm_flags & CM_START &&
3194 marker->cm_flags & CM_SKIP)
3195 msrd->msrd_skip = 1;
3196 if (marker->cm_flags & CM_END)
3197 msrd->msrd_skip = 0;
3202 if (msrd->msrd_skip)
3205 if (lcfg->lcfg_command != LCFG_SPTLRPC_CONF) {
3206 CERROR("invalid command (%x)\n", lcfg->lcfg_command);
3210 svname = lustre_cfg_string(lcfg, 0);
3211 if (svname == NULL) {
3212 CERROR("svname is empty\n");
3216 param = lustre_cfg_string(lcfg, 1);
3217 if (param == NULL) {
3218 CERROR("param is empty\n");
3222 rc = mgs_srpc_set_param_mem(msrd->msrd_fsdb, svname, param);
3224 CERROR("read sptlrpc record error (%d): %s\n", rc, param);
3229 int mgs_get_fsdb_srpc_from_llog(const struct lu_env *env,
3230 struct mgs_device *mgs,
3233 struct llog_handle *llh = NULL;
3234 struct llog_ctxt *ctxt;
3236 struct mgs_srpc_read_data msrd;
3240 /* construct log name */
3241 rc = name_create(&logname, fsdb->fsdb_name, "-sptlrpc");
3245 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
3246 LASSERT(ctxt != NULL);
3248 if (mgs_log_is_empty(env, mgs, logname))
3251 rc = llog_open(env, ctxt, &llh, NULL, logname,
3259 rc = llog_init_handle(env, llh, LLOG_F_IS_PLAIN, NULL);
3261 GOTO(out_close, rc);
3263 if (llog_get_size(llh) <= 1)
3264 GOTO(out_close, rc = 0);
3266 msrd.msrd_fsdb = fsdb;
3269 rc = llog_process(env, llh, mgs_srpc_read_handler, (void *)&msrd,
3273 llog_close(env, llh);
3275 llog_ctxt_put(ctxt);
3276 name_destroy(&logname);
3279 CERROR("failed to read sptlrpc config database: %d\n", rc);
3283 /* Permanent settings of all parameters by writing into the appropriate
3284 * configuration logs.
3285 * A parameter with null value ("<param>='\0'") means to erase it out of
3288 static int mgs_write_log_param(const struct lu_env *env,
3289 struct mgs_device *mgs, struct fs_db *fsdb,
3290 struct mgs_target_info *mti, char *ptr)
3292 struct mgs_thread_info *mgi = mgs_env_info(env);
3295 int rc = 0, rc2 = 0;
3298 /* For various parameter settings, we have to figure out which logs
3299 care about them (e.g. both mdt and client for lov settings) */
3300 CDEBUG(D_MGS, "next param '%s'\n", ptr);
3302 /* The params are stored in MOUNT_DATA_FILE and modified via
3303 tunefs.lustre, or set using lctl conf_param */
3305 /* Processed in lustre_start_mgc */
3306 if (class_match_param(ptr, PARAM_MGSNODE, NULL) == 0)
3309 /* Processed in ost/mdt */
3310 if (class_match_param(ptr, PARAM_NETWORK, NULL) == 0)
3313 /* Processed in mgs_write_log_ost */
3314 if (class_match_param(ptr, PARAM_FAILMODE, NULL) == 0) {
3315 if (mti->mti_flags & LDD_F_PARAM) {
3316 LCONSOLE_ERROR_MSG(0x169, "%s can only be "
3317 "changed with tunefs.lustre"
3318 "and --writeconf\n", ptr);
3324 if (class_match_param(ptr, PARAM_SRPC, NULL) == 0) {
3325 rc = mgs_srpc_set_param(env, mgs, fsdb, mti, ptr);
3329 if (class_match_param(ptr, PARAM_FAILNODE, NULL) == 0) {
3330 /* Add a failover nidlist */
3332 /* We already processed failovers params for new
3333 targets in mgs_write_log_target */
3334 if (mti->mti_flags & LDD_F_PARAM) {
3335 CDEBUG(D_MGS, "Adding failnode\n");
3336 rc = mgs_write_log_add_failnid(env, mgs, fsdb, mti);
3341 if (class_match_param(ptr, PARAM_SYS, &tmp) == 0) {
3342 rc = mgs_write_log_sys(env, mgs, fsdb, mti, ptr, tmp);
3346 if (class_match_param(ptr, PARAM_QUOTA, &tmp) == 0) {
3347 rc = mgs_write_log_quota(env, mgs, fsdb, mti, ptr, tmp);
3351 if (class_match_param(ptr, PARAM_OSC""PARAM_ACTIVE, &tmp) == 0) {
3352 /* active=0 means off, anything else means on */
3353 int flag = (*tmp == '0') ? CM_EXCLUDE : 0;
3356 if (!(mti->mti_flags & LDD_F_SV_TYPE_OST)) {
3357 LCONSOLE_ERROR_MSG(0x144, "%s: Only OSCs can "
3358 "be (de)activated.\n",
3360 GOTO(end, rc = -EINVAL);
3362 LCONSOLE_WARN("Permanently %sactivating %s\n",
3363 flag ? "de": "re", mti->mti_svname);
3365 rc = name_create(&logname, mti->mti_fsname, "-client");
3368 rc = mgs_modify(env, mgs, fsdb, mti, logname,
3369 mti->mti_svname, "add osc", flag);
3370 name_destroy(&logname);
3374 /* Add to all MDT logs for CMD */
3375 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3376 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
3378 rc = name_create_mdt(&logname, mti->mti_fsname, i);
3381 rc = mgs_modify(env, mgs, fsdb, mti, logname,
3382 mti->mti_svname, "add osc", flag);
3383 name_destroy(&logname);
3389 LCONSOLE_ERROR_MSG(0x145, "Couldn't find %s in"
3390 "log (%d). No permanent "
3391 "changes were made to the "
3393 mti->mti_svname, rc);
3394 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags))
3395 LCONSOLE_ERROR_MSG(0x146, "This may be"
3400 "update the logs.\n");
3403 /* Fall through to osc proc for deactivating live OSC
3404 on running MDT / clients. */
3406 /* Below here, let obd's XXX_process_config methods handle it */
3408 /* All lov. in proc */
3409 if (class_match_param(ptr, PARAM_LOV, NULL) == 0) {
3412 CDEBUG(D_MGS, "lov param %s\n", ptr);
3413 if (!(mti->mti_flags & LDD_F_SV_TYPE_MDT)) {
3414 LCONSOLE_ERROR_MSG(0x147, "LOV params must be "
3415 "set on the MDT, not %s. "
3422 if (mgs_log_is_empty(env, mgs, mti->mti_svname))
3423 GOTO(end, rc = -ENODEV);
3425 rc = name_create_mdt_and_lov(&logname, &mdtlovname, fsdb,
3426 mti->mti_stripe_index);
3429 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, mti->mti_svname,
3430 &mgi->mgi_bufs, mdtlovname, ptr);
3431 name_destroy(&logname);
3432 name_destroy(&mdtlovname);
3437 rc = name_create(&logname, mti->mti_fsname, "-client");
3440 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname, &mgi->mgi_bufs,
3441 fsdb->fsdb_clilov, ptr);
3442 name_destroy(&logname);
3446 /* All osc., mdc., llite. params in proc */
3447 if ((class_match_param(ptr, PARAM_OSC, NULL) == 0) ||
3448 (class_match_param(ptr, PARAM_MDC, NULL) == 0) ||
3449 (class_match_param(ptr, PARAM_LLITE, NULL) == 0)) {
3452 if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
3453 LCONSOLE_ERROR_MSG(0x148, "Upgraded client logs for %s"
3454 " cannot be modified. Consider"
3455 " updating the configuration with"
3458 GOTO(end, rc = -EINVAL);
3460 if (memcmp(ptr, PARAM_LLITE, strlen(PARAM_LLITE)) == 0) {
3461 rc = name_create(&cname, mti->mti_fsname, "-client");
3462 /* Add the client type to match the obdname in
3463 class_config_llog_handler */
3464 } else if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
3465 rc = name_create(&cname, mti->mti_svname, "-mdc");
3466 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
3467 rc = name_create(&cname, mti->mti_svname, "-osc");
3469 GOTO(end, rc = -EINVAL);
3474 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
3477 rc = name_create(&logname, mti->mti_fsname, "-client");
3479 name_destroy(&cname);
3482 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname, &mgi->mgi_bufs,
3485 /* osc params affect the MDT as well */
3486 if (!rc && (mti->mti_flags & LDD_F_SV_TYPE_OST)) {
3489 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
3490 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
3492 name_destroy(&cname);
3493 rc = name_create_mdt_osc(&cname, mti->mti_svname,
3495 name_destroy(&logname);
3498 rc = name_create_mdt(&logname,
3499 mti->mti_fsname, i);
3502 if (!mgs_log_is_empty(env, mgs, logname)) {
3503 rc = mgs_wlp_lcfg(env, mgs, fsdb,
3512 name_destroy(&logname);
3513 name_destroy(&cname);
3517 /* All mdt. params in proc */
3518 if (class_match_param(ptr, PARAM_MDT, NULL) == 0) {
3522 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
3523 if (strncmp(mti->mti_svname, mti->mti_fsname,
3524 MTI_NAME_MAXLEN) == 0)
3525 /* device is unspecified completely? */
3526 rc = LDD_F_SV_TYPE_MDT | LDD_F_SV_ALL;
3528 rc = server_name2index(mti->mti_svname, &idx, NULL);
3531 if ((rc & LDD_F_SV_TYPE_MDT) == 0)
3533 if (rc & LDD_F_SV_ALL) {
3534 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3536 fsdb->fsdb_mdt_index_map))
3538 rc = name_create_mdt(&logname,
3539 mti->mti_fsname, i);
3542 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti,
3543 logname, &mgi->mgi_bufs,
3545 name_destroy(&logname);
3550 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti,
3551 mti->mti_svname, &mgi->mgi_bufs,
3552 mti->mti_svname, ptr);
3559 /* All mdd., ost. params in proc */
3560 if ((class_match_param(ptr, PARAM_MDD, NULL) == 0) ||
3561 (class_match_param(ptr, PARAM_OST, NULL) == 0)) {
3562 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
3563 if (mgs_log_is_empty(env, mgs, mti->mti_svname))
3564 GOTO(end, rc = -ENODEV);
3566 rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, mti->mti_svname,
3567 &mgi->mgi_bufs, mti->mti_svname, ptr);
3571 LCONSOLE_WARN("Ignoring unrecognized param '%s'\n", ptr);
3576 CERROR("err %d on param '%s'\n", rc, ptr);
3581 /* Not implementing automatic failover nid addition at this time. */
3582 int mgs_check_failnid(const struct lu_env *env, struct mgs_device *mgs,
3583 struct mgs_target_info *mti)
3590 rc = mgs_find_or_make_fsdb(obd, fsname, &fsdb);
3594 if (mgs_log_is_empty(obd, mti->mti_svname))
3595 /* should never happen */
3598 CDEBUG(D_MGS, "Checking for new failnids for %s\n", mti->mti_svname);
3600 /* FIXME We can just check mti->params to see if we're already in
3601 the failover list. Modify mti->params for rewriting back at
3602 server_register_target(). */
3604 mutex_lock(&fsdb->fsdb_mutex);
3605 rc = mgs_write_log_add_failnid(obd, fsdb, mti);
3606 mutex_unlock(&fsdb->fsdb_mutex);
3613 int mgs_write_log_target(const struct lu_env *env,
3614 struct mgs_device *mgs,
3615 struct mgs_target_info *mti,
3622 /* set/check the new target index */
3623 rc = mgs_set_index(env, mgs, mti);
3625 CERROR("Can't get index (%d)\n", rc);
3629 if (rc == EALREADY) {
3630 LCONSOLE_WARN("Found index %d for %s, updating log\n",
3631 mti->mti_stripe_index, mti->mti_svname);
3632 /* We would like to mark old log sections as invalid
3633 and add new log sections in the client and mdt logs.
3634 But if we add new sections, then live clients will
3635 get repeat setup instructions for already running
3636 osc's. So don't update the client/mdt logs. */
3637 mti->mti_flags &= ~LDD_F_UPDATE;
3641 mutex_lock(&fsdb->fsdb_mutex);
3643 if (mti->mti_flags &
3644 (LDD_F_VIRGIN | LDD_F_UPGRADE14 | LDD_F_WRITECONF)) {
3645 /* Generate a log from scratch */
3646 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
3647 rc = mgs_write_log_mdt(env, mgs, fsdb, mti);
3648 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
3649 rc = mgs_write_log_ost(env, mgs, fsdb, mti);
3651 CERROR("Unknown target type %#x, can't create log for "
3652 "%s\n", mti->mti_flags, mti->mti_svname);
3655 CERROR("Can't write logs for %s (%d)\n",
3656 mti->mti_svname, rc);
3660 /* Just update the params from tunefs in mgs_write_log_params */
3661 CDEBUG(D_MGS, "Update params for %s\n", mti->mti_svname);
3662 mti->mti_flags |= LDD_F_PARAM;
3665 /* allocate temporary buffer, where class_get_next_param will
3666 make copy of a current parameter */
3667 OBD_ALLOC(buf, strlen(mti->mti_params) + 1);
3669 GOTO(out_up, rc = -ENOMEM);
3670 params = mti->mti_params;
3671 while (params != NULL) {
3672 rc = class_get_next_param(¶ms, buf);
3675 /* there is no next parameter, that is
3680 CDEBUG(D_MGS, "remaining string: '%s', param: '%s'\n",
3682 rc = mgs_write_log_param(env, mgs, fsdb, mti, buf);
3687 OBD_FREE(buf, strlen(mti->mti_params) + 1);
3690 mutex_unlock(&fsdb->fsdb_mutex);
3694 int mgs_erase_log(const struct lu_env *env, struct mgs_device *mgs, char *name)
3696 struct llog_ctxt *ctxt;
3699 ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
3701 CERROR("%s: MGS config context doesn't exist\n",
3702 mgs->mgs_obd->obd_name);
3705 rc = llog_erase(env, ctxt, NULL, name);
3706 /* llog may not exist */
3709 llog_ctxt_put(ctxt);
3713 CERROR("%s: failed to clear log %s: %d\n",
3714 mgs->mgs_obd->obd_name, name, rc);
3719 /* erase all logs for the given fs */
3720 int mgs_erase_logs(const struct lu_env *env, struct mgs_device *mgs, char *fsname)
3724 struct mgs_direntry *dirent, *n;
3725 int rc, len = strlen(fsname);
3729 /* Find all the logs in the CONFIGS directory */
3730 rc = class_dentry_readdir(env, mgs, &list);
3734 mutex_lock(&mgs->mgs_mutex);
3736 /* Delete the fs db */
3737 fsdb = mgs_find_fsdb(mgs, fsname);
3739 mgs_free_fsdb(mgs, fsdb);
3741 mutex_unlock(&mgs->mgs_mutex);
3743 cfs_list_for_each_entry_safe(dirent, n, &list, list) {
3744 cfs_list_del(&dirent->list);
3745 suffix = strrchr(dirent->name, '-');
3746 if (suffix != NULL) {
3747 if ((len == suffix - dirent->name) &&
3748 (strncmp(fsname, dirent->name, len) == 0)) {
3749 CDEBUG(D_MGS, "Removing log %s\n",
3751 mgs_erase_log(env, mgs, dirent->name);
3754 mgs_direntry_free(dirent);
3760 /* from llog_swab */
3761 static void print_lustre_cfg(struct lustre_cfg *lcfg)
3766 CDEBUG(D_MGS, "lustre_cfg: %p\n", lcfg);
3767 CDEBUG(D_MGS, "\tlcfg->lcfg_version: %#x\n", lcfg->lcfg_version);
3769 CDEBUG(D_MGS, "\tlcfg->lcfg_command: %#x\n", lcfg->lcfg_command);
3770 CDEBUG(D_MGS, "\tlcfg->lcfg_num: %#x\n", lcfg->lcfg_num);
3771 CDEBUG(D_MGS, "\tlcfg->lcfg_flags: %#x\n", lcfg->lcfg_flags);
3772 CDEBUG(D_MGS, "\tlcfg->lcfg_nid: %s\n", libcfs_nid2str(lcfg->lcfg_nid));
3774 CDEBUG(D_MGS, "\tlcfg->lcfg_bufcount: %d\n", lcfg->lcfg_bufcount);
3775 if (lcfg->lcfg_bufcount < LUSTRE_CFG_MAX_BUFCOUNT)
3776 for (i = 0; i < lcfg->lcfg_bufcount; i++) {
3777 CDEBUG(D_MGS, "\tlcfg->lcfg_buflens[%d]: %d %s\n",
3778 i, lcfg->lcfg_buflens[i],
3779 lustre_cfg_string(lcfg, i));
3784 /* Set a permanent (config log) param for a target or fs
3785 * \param lcfg buf0 may contain the device (testfs-MDT0000) name
3786 * buf1 contains the single parameter
3788 int mgs_setparam(const struct lu_env *env, struct mgs_device *mgs,
3789 struct lustre_cfg *lcfg, char *fsname)
3792 struct mgs_target_info *mti;
3793 char *devname, *param;
3800 print_lustre_cfg(lcfg);
3802 /* lustre, lustre-mdtlov, lustre-client, lustre-MDT0000 */
3803 devname = lustre_cfg_string(lcfg, 0);
3804 param = lustre_cfg_string(lcfg, 1);
3806 /* Assume device name embedded in param:
3807 lustre-OST0000.osc.max_dirty_mb=32 */
3808 ptr = strchr(param, '.');
3816 LCONSOLE_ERROR_MSG(0x14d, "No target specified: %s\n", param);
3820 rc = mgs_parse_devname(devname, fsname, NULL);
3821 if (rc == 0 && !mgs_parse_devname(devname, NULL, &index)) {
3822 /* param related to llite isn't allowed to set by OST or MDT */
3823 if (rc == 0 && strncmp(param, PARAM_LLITE,
3824 sizeof(PARAM_LLITE)) == 0)
3827 /* assume devname is the fsname */
3828 memset(fsname, 0, MTI_NAME_MAXLEN);
3829 strncpy(fsname, devname, MTI_NAME_MAXLEN);
3830 fsname[MTI_NAME_MAXLEN - 1] = 0;
3832 CDEBUG(D_MGS, "setparam fs='%s' device='%s'\n", fsname, devname);
3834 rc = mgs_find_or_make_fsdb(env, mgs, fsname, &fsdb);
3837 if (!test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags) &&
3838 test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
3839 CERROR("No filesystem targets for %s. cfg_device from lctl "
3840 "is '%s'\n", fsname, devname);
3841 mgs_free_fsdb(mgs, fsdb);
3845 /* Create a fake mti to hold everything */
3848 GOTO(out, rc = -ENOMEM);
3849 if (strlcpy(mti->mti_fsname, fsname, sizeof(mti->mti_fsname))
3850 >= sizeof(mti->mti_fsname))
3851 GOTO(out, rc = -E2BIG);
3852 if (strlcpy(mti->mti_svname, devname, sizeof(mti->mti_svname))
3853 >= sizeof(mti->mti_svname))
3854 GOTO(out, rc = -E2BIG);
3855 if (strlcpy(mti->mti_params, param, sizeof(mti->mti_params))
3856 >= sizeof(mti->mti_params))
3857 GOTO(out, rc = -E2BIG);
3858 rc = server_name2index(mti->mti_svname, &mti->mti_stripe_index, &tmp);
3860 /* Not a valid server; may be only fsname */
3863 /* Strip -osc or -mdc suffix from svname */
3864 if (server_make_name(rc, mti->mti_stripe_index, mti->mti_fsname,
3866 GOTO(out, rc = -EINVAL);
3868 mti->mti_flags = rc | LDD_F_PARAM;
3870 mutex_lock(&fsdb->fsdb_mutex);
3871 rc = mgs_write_log_param(env, mgs, fsdb, mti, mti->mti_params);
3872 mutex_unlock(&fsdb->fsdb_mutex);
3875 * Revoke lock so everyone updates. Should be alright if
3876 * someone was already reading while we were updating the logs,
3877 * so we don't really need to hold the lock while we're
3880 mgs_revoke_lock(mgs, fsdb, CONFIG_T_CONFIG);
3886 static int mgs_write_log_pool(const struct lu_env *env,
3887 struct mgs_device *mgs, char *logname,
3888 struct fs_db *fsdb, char *lovname,
3889 enum lcfg_command_type cmd,
3890 char *poolname, char *fsname,
3891 char *ostname, char *comment)
3893 struct llog_handle *llh = NULL;
3896 rc = record_start_log(env, mgs, &llh, logname);
3899 rc = record_marker(env, llh, fsdb, CM_START, lovname, comment);
3902 rc = record_base(env, llh, lovname, 0, cmd, poolname, fsname, ostname, 0);
3905 rc = record_marker(env, llh, fsdb, CM_END, lovname, comment);
3907 record_end_log(env, &llh);
3911 int mgs_pool_cmd(const struct lu_env *env, struct mgs_device *mgs,
3912 enum lcfg_command_type cmd, char *fsname,
3913 char *poolname, char *ostname)
3918 char *label = NULL, *canceled_label = NULL;
3920 struct mgs_target_info *mti = NULL;
3924 rc = mgs_find_or_make_fsdb(env, mgs, fsname, &fsdb);
3926 CERROR("Can't get db for %s\n", fsname);
3929 if (test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
3930 CERROR("%s is not defined\n", fsname);
3931 mgs_free_fsdb(mgs, fsdb);
3935 label_sz = 10 + strlen(fsname) + strlen(poolname);
3937 /* check if ostname match fsname */
3938 if (ostname != NULL) {
3941 ptr = strrchr(ostname, '-');
3942 if ((ptr == NULL) ||
3943 (strncmp(fsname, ostname, ptr-ostname) != 0))
3945 label_sz += strlen(ostname);
3948 OBD_ALLOC(label, label_sz);
3955 "new %s.%s", fsname, poolname);
3959 "add %s.%s.%s", fsname, poolname, ostname);
3962 OBD_ALLOC(canceled_label, label_sz);
3963 if (canceled_label == NULL)
3964 GOTO(out_label, rc = -ENOMEM);
3966 "rem %s.%s.%s", fsname, poolname, ostname);
3967 sprintf(canceled_label,
3968 "add %s.%s.%s", fsname, poolname, ostname);
3971 OBD_ALLOC(canceled_label, label_sz);
3972 if (canceled_label == NULL)
3973 GOTO(out_label, rc = -ENOMEM);
3975 "del %s.%s", fsname, poolname);
3976 sprintf(canceled_label,
3977 "new %s.%s", fsname, poolname);
3983 if (canceled_label != NULL) {
3986 GOTO(out_cancel, rc = -ENOMEM);
3989 mutex_lock(&fsdb->fsdb_mutex);
3990 /* write pool def to all MDT logs */
3991 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3992 if (test_bit(i, fsdb->fsdb_mdt_index_map)) {
3993 rc = name_create_mdt_and_lov(&logname, &lovname,
3996 mutex_unlock(&fsdb->fsdb_mutex);
3999 if (canceled_label != NULL) {
4000 strcpy(mti->mti_svname, "lov pool");
4001 rc = mgs_modify(env, mgs, fsdb, mti, logname,
4002 lovname, canceled_label,
4007 rc = mgs_write_log_pool(env, mgs, logname,
4011 name_destroy(&logname);
4012 name_destroy(&lovname);
4014 mutex_unlock(&fsdb->fsdb_mutex);
4020 rc = name_create(&logname, fsname, "-client");
4022 mutex_unlock(&fsdb->fsdb_mutex);
4025 if (canceled_label != NULL) {
4026 rc = mgs_modify(env, mgs, fsdb, mti, logname,
4027 fsdb->fsdb_clilov, canceled_label, CM_SKIP);
4029 mutex_unlock(&fsdb->fsdb_mutex);
4030 name_destroy(&logname);
4035 rc = mgs_write_log_pool(env, mgs, logname, fsdb, fsdb->fsdb_clilov,
4036 cmd, fsname, poolname, ostname, label);
4037 mutex_unlock(&fsdb->fsdb_mutex);
4038 name_destroy(&logname);
4039 /* request for update */
4040 mgs_revoke_lock(mgs, fsdb, CONFIG_T_CONFIG);
4047 if (canceled_label != NULL)
4048 OBD_FREE(canceled_label, label_sz);
4050 OBD_FREE(label, label_sz);