Whamcloud - gitweb
6440f2ff4f2ef67dd708e0dbdd934289da7570fc
[fs/lustre-release.git] / lustre / mgs / mgs_llog.c
1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=8:tabstop=8:
3  *
4  * GPL HEADER START
5  *
6  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License version 2 only,
10  * as published by the Free Software Foundation.
11  *
12  * This program is distributed in the hope that it will be useful, but
13  * WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * General Public License version 2 for more details (a copy is included
16  * in the LICENSE file that accompanied this code).
17  *
18  * You should have received a copy of the GNU General Public License
19  * version 2 along with this program; If not, see
20  * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
21  *
22  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
23  * CA 95054 USA or visit www.sun.com if you need additional information or
24  * have any questions.
25  *
26  * GPL HEADER END
27  */
28 /*
29  * Copyright  2008 Sun Microsystems, Inc. All rights reserved
30  * Use is subject to license terms.
31  */
32 /*
33  * This file is part of Lustre, http://www.lustre.org/
34  * Lustre is a trademark of Sun Microsystems, Inc.
35  *
36  * lustre/mgs/mgs_llog.c
37  *
38  * Lustre Management Server (mgs) config llog creation
39  *
40  * Author: Nathan Rutman <nathan@clusterfs.com>
41  */
42
43 #ifndef EXPORT_SYMTAB
44 #define EXPORT_SYMTAB
45 #endif
46 #define DEBUG_SUBSYSTEM S_MGS
47 #define D_MGS D_CONFIG /*|D_WARNING*/
48
49 #ifdef __KERNEL__
50 #include <linux/module.h>
51 #include <linux/pagemap.h>
52 #include <linux/fs.h>
53 #endif
54
55 #include <obd.h>
56 #include <obd_lov.h>
57 #include <obd_class.h>
58 #include <lustre_log.h>
59 #include <obd_ost.h>
60 #include <libcfs/list.h>
61 #include <linux/lvfs.h>
62 #include <lustre_fsfilt.h>
63 #include <lustre_disk.h>
64 #include <lustre_param.h>
65 #include <lustre_sec.h>
66 #include "mgs_internal.h"
67
68 /********************** Class functions ********************/
69
70 /* Caller must list_del and OBD_FREE each dentry from the list */
71 int class_dentry_readdir(struct obd_device *obd, struct dentry *dir,
72                                 struct vfsmount *inmnt,
73                                 struct list_head *dentry_list){
74         /* see mds_cleanup_pending */
75         struct lvfs_run_ctxt saved;
76         struct file *file;
77         struct dentry *dentry;
78         struct vfsmount *mnt;
79         int rc = 0;
80         ENTRY;
81
82         push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
83         dentry = dget(dir);
84         if (IS_ERR(dentry))
85                 GOTO(out_pop, rc = PTR_ERR(dentry));
86         mnt = mntget(inmnt);
87         if (IS_ERR(mnt)) {
88                 l_dput(dentry);
89                 GOTO(out_pop, rc = PTR_ERR(mnt));
90         }
91
92         file = dentry_open(dentry, mnt, O_RDONLY);
93         if (IS_ERR(file))
94                 /* dentry_open_it() drops the dentry, mnt refs */
95                 GOTO(out_pop, rc = PTR_ERR(file));
96
97         CFS_INIT_LIST_HEAD(dentry_list);
98         rc = l_readdir(file, dentry_list);
99         filp_close(file, 0);
100         /*  filp_close->fput() drops the dentry, mnt refs */
101
102 out_pop:
103         pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
104         RETURN(rc);
105 }
106
107 /******************** DB functions *********************/
108
109 static inline int name_create(char **newname, char *prefix, char *suffix)
110 {
111         LASSERT(newname);
112         OBD_ALLOC(*newname, strlen(prefix) + strlen(suffix) + 1);
113         if (!*newname)
114                 return -ENOMEM;
115         sprintf(*newname, "%s%s", prefix, suffix);
116         return 0;
117 }
118
119 static inline void name_destroy(char **name)
120 {
121         if (*name)
122                 OBD_FREE(*name, strlen(*name) + 1);
123         *name = NULL;
124 }
125
126 /* from the (client) config log, figure out:
127         1. which ost's/mdt's are configured (by index)
128         2. what the last config step is
129         3. COMPAT_146 lov name
130         4. COMPAT_146 mdt lov name
131         5. COMPAT_146 mdc name
132 */
133 /* It might be better to have a separate db file, instead of parsing the info
134    out of the client log.  This is slow and potentially error-prone. */
135 static int mgs_fsdb_handler(struct llog_handle *llh, struct llog_rec_hdr *rec,
136                             void *data)
137 {
138         struct fs_db *fsdb = (struct fs_db *)data;
139         int cfg_len = rec->lrh_len;
140         char *cfg_buf = (char*) (rec + 1);
141         struct lustre_cfg *lcfg;
142         __u32 index;
143         int rc = 0;
144         ENTRY;
145
146         if (rec->lrh_type != OBD_CFG_REC) {
147                 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
148                 RETURN(-EINVAL);
149         }
150
151         rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
152         if (rc) {
153                 CERROR("Insane cfg\n");
154                 RETURN(rc);
155         }
156
157         lcfg = (struct lustre_cfg *)cfg_buf;
158
159         CDEBUG(D_INFO, "cmd %x %s %s\n", lcfg->lcfg_command,
160                lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));
161
162         /* Figure out ost indicies */
163         /* lov_modify_tgts add 0:lov1  1:ost1_UUID  2(index):0  3(gen):1 */
164         if (lcfg->lcfg_command == LCFG_LOV_ADD_OBD ||
165             lcfg->lcfg_command == LCFG_LOV_DEL_OBD) {
166                 index = simple_strtoul(lustre_cfg_string(lcfg, 2),
167                                        NULL, 10);
168                 CDEBUG(D_MGS, "OST index for %s is %u (%s)\n",
169                        lustre_cfg_string(lcfg, 1), index,
170                        lustre_cfg_string(lcfg, 2));
171                 set_bit(index, fsdb->fsdb_ost_index_map);
172         }
173
174         /* Figure out mdt indicies */
175         /* attach   0:MDC_uml1_mdsA_MNT_client  1:mdc  2:1d834_MNT_client_03f */
176         if ((lcfg->lcfg_command == LCFG_ATTACH) &&
177             (strcmp(lustre_cfg_string(lcfg, 1), LUSTRE_MDC_NAME) == 0)) {
178                 rc = server_name2index(lustre_cfg_string(lcfg, 0),
179                                        &index, NULL);
180                 if (rc != LDD_F_SV_TYPE_MDT) {
181                         CWARN("Unparsable MDC name %s, assuming index 0\n",
182                               lustre_cfg_string(lcfg, 0));
183                         index = 0;
184                 }
185                 rc = 0;
186                 CDEBUG(D_MGS, "MDT index is %u\n", index);
187                 set_bit(index, fsdb->fsdb_mdt_index_map);
188         }
189
190         /* COMPAT_146 */
191         /* figure out the old LOV name. fsdb_gen = 0 means old log */
192         /* #01 L attach 0:lov_mdsA 1:lov 2:cdbe9_lov_mdsA_dc8cf7f3bb */
193         if ((fsdb->fsdb_gen == 0) && (lcfg->lcfg_command == LCFG_ATTACH) &&
194             (strcmp(lustre_cfg_string(lcfg, 1), LUSTRE_LOV_NAME) == 0)) {
195                 fsdb->fsdb_flags |= FSDB_OLDLOG14;
196                 name_destroy(&fsdb->fsdb_clilov);
197                 rc = name_create(&fsdb->fsdb_clilov,
198                                  lustre_cfg_string(lcfg, 0), "");
199                 if (rc)
200                         RETURN(rc);
201                 CDEBUG(D_MGS, "client lov name is %s\n", fsdb->fsdb_clilov);
202         }
203
204         /* figure out the old MDT lov name from the MDT uuid */
205         if ((fsdb->fsdb_gen == 0) && (lcfg->lcfg_command == LCFG_SETUP) &&
206             (strncmp(lustre_cfg_string(lcfg, 0), "MDC_", 4) == 0)) {
207                 char *ptr;
208                 fsdb->fsdb_flags |= FSDB_OLDLOG14;
209                 ptr = strstr(lustre_cfg_string(lcfg, 1), "_UUID");
210                 if (!ptr) {
211                         CERROR("Can't parse MDT uuid %s\n",
212                                lustre_cfg_string(lcfg, 1));
213                         RETURN(-EINVAL);
214                 }
215                 *ptr = '\0';
216                 name_destroy(&fsdb->fsdb_mdtlov);
217                 rc = name_create(&fsdb->fsdb_mdtlov,
218                                  "lov_", lustre_cfg_string(lcfg, 1));
219                 if (rc)
220                         RETURN(rc);
221                 name_destroy(&fsdb->fsdb_mdc);
222                 rc = name_create(&fsdb->fsdb_mdc,
223                                  lustre_cfg_string(lcfg, 0), "");
224                 if (rc)
225                         RETURN(rc);
226                 CDEBUG(D_MGS, "MDT lov name is %s\n", fsdb->fsdb_mdtlov);
227         }
228         /* end COMPAT_146 */
229
230         /* Keep track of the latest marker step */
231         if (lcfg->lcfg_command == LCFG_MARKER) {
232                 struct cfg_marker *marker;
233                 marker = lustre_cfg_buf(lcfg, 1);
234                 fsdb->fsdb_gen = max(fsdb->fsdb_gen, marker->cm_step);
235         }
236
237         RETURN(rc);
238 }
239
240 /* fsdb->fsdb_sem is already held  in mgs_find_or_make_fsdb*/
241 static int mgs_get_fsdb_from_llog(struct obd_device *obd, struct fs_db *fsdb)
242 {
243         char *logname;
244         struct llog_handle *loghandle;
245         struct lvfs_run_ctxt saved;
246         struct llog_ctxt *ctxt;
247         int rc, rc2;
248         ENTRY;
249
250         ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
251         LASSERT(ctxt != NULL);
252         name_create(&logname, fsdb->fsdb_name, "-client");
253         down(&fsdb->fsdb_sem);
254         push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
255         rc = llog_create(ctxt, &loghandle, NULL, logname);
256         if (rc)
257                 GOTO(out_pop, rc);
258
259         rc = llog_init_handle(loghandle, LLOG_F_IS_PLAIN, NULL);
260         if (rc)
261                 GOTO(out_close, rc);
262
263         if (llog_get_size(loghandle) <= 1)
264                 fsdb->fsdb_flags |= FSDB_LOG_EMPTY;
265
266         rc = llog_process(loghandle, mgs_fsdb_handler, (void *)fsdb, NULL);
267         CDEBUG(D_INFO, "get_db = %d\n", rc);
268 out_close:
269         rc2 = llog_close(loghandle);
270         if (!rc)
271                 rc = rc2;
272 out_pop:
273         pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
274         up(&fsdb->fsdb_sem);
275         name_destroy(&logname);
276         llog_ctxt_put(ctxt);
277
278         RETURN(rc);
279 }
280
281 static void mgs_free_fsdb_srpc(struct fs_db *fsdb)
282 {
283         struct mgs_tgt_srpc_conf *tgtconf;
284
285         /* free target-specific rules */
286         while (fsdb->fsdb_srpc_tgt) {
287                 tgtconf = fsdb->fsdb_srpc_tgt;
288                 fsdb->fsdb_srpc_tgt = tgtconf->mtsc_next;
289
290                 LASSERT(tgtconf->mtsc_tgt);
291
292                 sptlrpc_rule_set_free(&tgtconf->mtsc_rset);
293                 OBD_FREE(tgtconf->mtsc_tgt, strlen(tgtconf->mtsc_tgt) + 1);
294                 OBD_FREE_PTR(tgtconf);
295         }
296
297         /* free general rules */
298         sptlrpc_rule_set_free(&fsdb->fsdb_srpc_gen);
299 }
300
301 static struct fs_db *mgs_find_fsdb(struct obd_device *obd, char *fsname)
302 {
303         struct mgs_obd *mgs = &obd->u.mgs;
304         struct fs_db *fsdb;
305         struct list_head *tmp;
306
307         list_for_each(tmp, &mgs->mgs_fs_db_list) {
308                 fsdb = list_entry(tmp, struct fs_db, fsdb_list);
309                 if (strcmp(fsdb->fsdb_name, fsname) == 0)
310                         return fsdb;
311         }
312         return NULL;
313 }
314
315 /* caller must hold the mgs->mgs_fs_db_lock */
316 static struct fs_db *mgs_new_fsdb(struct obd_device *obd, char *fsname)
317 {
318         struct mgs_obd *mgs = &obd->u.mgs;
319         struct fs_db *fsdb;
320         int rc;
321         ENTRY;
322
323         OBD_ALLOC_PTR(fsdb);
324         if (!fsdb)
325                 RETURN(NULL);
326
327         OBD_ALLOC(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
328         OBD_ALLOC(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
329         if (!fsdb->fsdb_ost_index_map || !fsdb->fsdb_mdt_index_map) {
330                 CERROR("No memory for index maps\n");
331                 GOTO(err, 0);
332         }
333
334         strncpy(fsdb->fsdb_name, fsname, sizeof(fsdb->fsdb_name));
335         fsdb->fsdb_name[sizeof(fsdb->fsdb_name) - 1] = 0;
336         rc = name_create(&fsdb->fsdb_mdtlov, fsname, "-mdtlov");
337         if (rc)
338                 GOTO(err, rc);
339         rc = name_create(&fsdb->fsdb_mdtlmv, fsname, "-mdtlmv");
340         if (rc)
341                 GOTO(err, rc);
342         rc = name_create(&fsdb->fsdb_clilov, fsname, "-clilov");
343         if (rc)
344                 GOTO(err, rc);
345
346         rc = name_create(&fsdb->fsdb_clilmv, fsname, "-clilmv");
347         if (rc)
348                 GOTO(err, rc);
349
350         fsdb->fsdb_srpc_fl_udesc = 1;
351         sema_init(&fsdb->fsdb_sem, 1);
352         list_add(&fsdb->fsdb_list, &mgs->mgs_fs_db_list);
353         lproc_mgs_add_live(obd, fsdb);
354
355         RETURN(fsdb);
356 err:
357         if (fsdb->fsdb_ost_index_map)
358                 OBD_FREE(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
359         if (fsdb->fsdb_mdt_index_map)
360                 OBD_FREE(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
361         name_destroy(&fsdb->fsdb_clilov);
362         name_destroy(&fsdb->fsdb_clilmv);
363         name_destroy(&fsdb->fsdb_mdtlov);
364         name_destroy(&fsdb->fsdb_mdtlmv);
365         OBD_FREE_PTR(fsdb);
366         RETURN(NULL);
367 }
368
369 static void mgs_free_fsdb(struct obd_device *obd, struct fs_db *fsdb)
370 {
371         /* wait for anyone with the sem */
372         down(&fsdb->fsdb_sem);
373         lproc_mgs_del_live(obd, fsdb);
374         list_del(&fsdb->fsdb_list);
375         OBD_FREE(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
376         OBD_FREE(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
377         name_destroy(&fsdb->fsdb_clilov);
378         name_destroy(&fsdb->fsdb_clilmv);
379         name_destroy(&fsdb->fsdb_mdtlov);
380         name_destroy(&fsdb->fsdb_mdtlmv);
381         name_destroy(&fsdb->fsdb_mdc);
382         mgs_free_fsdb_srpc(fsdb);
383         OBD_FREE_PTR(fsdb);
384 }
385
386 int mgs_init_fsdb_list(struct obd_device *obd)
387 {
388         struct mgs_obd *mgs = &obd->u.mgs;
389         CFS_INIT_LIST_HEAD(&mgs->mgs_fs_db_list);
390         return 0;
391 }
392
393 int mgs_cleanup_fsdb_list(struct obd_device *obd)
394 {
395         struct mgs_obd *mgs = &obd->u.mgs;
396         struct fs_db *fsdb;
397         struct list_head *tmp, *tmp2;
398         down(&mgs->mgs_sem);
399         list_for_each_safe(tmp, tmp2, &mgs->mgs_fs_db_list) {
400                 fsdb = list_entry(tmp, struct fs_db, fsdb_list);
401                 mgs_free_fsdb(obd, fsdb);
402         }
403         up(&mgs->mgs_sem);
404         return 0;
405 }
406
407 static int mgs_find_or_make_fsdb(struct obd_device *obd, char *name,
408                                struct fs_db **dbh)
409 {
410         struct mgs_obd *mgs = &obd->u.mgs;
411         struct fs_db *fsdb;
412         int rc = 0;
413
414         down(&mgs->mgs_sem);
415         fsdb = mgs_find_fsdb(obd, name);
416         if (fsdb) {
417                 up(&mgs->mgs_sem);
418                 *dbh = fsdb;
419                 return 0;
420         }
421
422         CDEBUG(D_MGS, "Creating new db\n");
423         fsdb = mgs_new_fsdb(obd, name);
424         up(&mgs->mgs_sem);
425         if (!fsdb)
426                 return -ENOMEM;
427
428         /* populate the db from the client llog */
429         rc = mgs_get_fsdb_from_llog(obd, fsdb);
430         if (rc) {
431                 CERROR("Can't get db from client log %d\n", rc);
432                 mgs_free_fsdb(obd, fsdb);
433                 return rc;
434         }
435
436         /* populate srpc rules from params llog */
437         rc = mgs_get_fsdb_srpc_from_llog(obd, fsdb);
438         if (rc) {
439                 CERROR("Can't get db from params log %d\n", rc);
440                 mgs_free_fsdb(obd, fsdb);
441                 return rc;
442         }
443
444         *dbh = fsdb;
445
446         return 0;
447 }
448
449 /* 1 = index in use
450    0 = index unused
451    -1= empty client log */
452 int mgs_check_index(struct obd_device *obd, struct mgs_target_info *mti)
453 {
454         struct fs_db *fsdb;
455         void *imap;
456         int rc = 0;
457         ENTRY;
458
459         LASSERT(!(mti->mti_flags & LDD_F_NEED_INDEX));
460
461         rc = mgs_find_or_make_fsdb(obd, mti->mti_fsname, &fsdb);
462         if (rc) {
463                 CERROR("Can't get db for %s\n", mti->mti_fsname);
464                 RETURN(rc);
465         }
466
467         if (fsdb->fsdb_flags & FSDB_LOG_EMPTY)
468                 RETURN(-1);
469
470         if (mti->mti_flags & LDD_F_SV_TYPE_OST)
471                 imap = fsdb->fsdb_ost_index_map;
472         else if (mti->mti_flags & LDD_F_SV_TYPE_MDT)
473                 imap = fsdb->fsdb_mdt_index_map;
474         else
475                 RETURN(-EINVAL);
476
477         if (test_bit(mti->mti_stripe_index, imap))
478                 RETURN(1);
479         RETURN(0);
480 }
481
482 static __inline__ int next_index(void *index_map, int map_len)
483 {
484         int i;
485         for (i = 0; i < map_len * 8; i++)
486                  if (!test_bit(i, index_map)) {
487                          return i;
488                  }
489         CERROR("max index %d exceeded.\n", i);
490         return -1;
491 }
492
493 /* Return codes:
494         0  newly marked as in use
495         <0 err
496         +EALREADY for update of an old index */
497 int mgs_set_index(struct obd_device *obd, struct mgs_target_info *mti)
498 {
499         struct fs_db *fsdb;
500         void *imap;
501         int rc = 0;
502         ENTRY;
503
504         rc = mgs_find_or_make_fsdb(obd, mti->mti_fsname, &fsdb);
505         if (rc) {
506                 CERROR("Can't get db for %s\n", mti->mti_fsname);
507                 RETURN(rc);
508         }
509
510         if (mti->mti_flags & LDD_F_SV_TYPE_OST)
511                 imap = fsdb->fsdb_ost_index_map;
512         else if (mti->mti_flags & LDD_F_SV_TYPE_MDT)
513                 imap = fsdb->fsdb_mdt_index_map;
514         else
515                 RETURN(-EINVAL);
516
517         if (mti->mti_flags & LDD_F_NEED_INDEX) {
518                 rc = next_index(imap, INDEX_MAP_SIZE);
519                 if (rc == -1)
520                         RETURN(-ERANGE);
521                 mti->mti_stripe_index = rc;
522         }
523
524         if (mti->mti_stripe_index >= INDEX_MAP_SIZE * 8) {
525                 LCONSOLE_ERROR_MSG(0x13f, "Server %s requested index %d, "
526                                    "but the max index is %d.\n",
527                                    mti->mti_svname, mti->mti_stripe_index,
528                                    INDEX_MAP_SIZE * 8);
529                 RETURN(-ERANGE);
530         }
531
532         if (test_bit(mti->mti_stripe_index, imap)) {
533                 if ((mti->mti_flags & LDD_F_VIRGIN) &&
534                     !(mti->mti_flags & LDD_F_WRITECONF)) {
535                         LCONSOLE_ERROR_MSG(0x140, "Server %s requested index "
536                                            "%d, but that index is already in "
537                                            "use. Use --writeconf to force\n",
538                                            mti->mti_svname,
539                                            mti->mti_stripe_index);
540                         RETURN(-EADDRINUSE);
541                 } else {
542                         CDEBUG(D_MGS, "Server %s updating index %d\n",
543                                mti->mti_svname, mti->mti_stripe_index);
544                         RETURN(EALREADY);
545                 }
546         }
547
548         set_bit(mti->mti_stripe_index, imap);
549         fsdb->fsdb_flags &= ~FSDB_LOG_EMPTY;
550         server_make_name(mti->mti_flags, mti->mti_stripe_index,
551                          mti->mti_fsname, mti->mti_svname);
552
553         CDEBUG(D_MGS, "Set index for %s to %d\n", mti->mti_svname,
554                mti->mti_stripe_index);
555
556         RETURN(0);
557 }
558
559 struct mgs_modify_lookup {
560         struct cfg_marker mml_marker;
561         int               mml_modified;
562 };
563
564 static int mgs_modify_handler(struct llog_handle *llh, struct llog_rec_hdr *rec,
565                               void *data)
566 {
567         struct mgs_modify_lookup *mml = (struct mgs_modify_lookup *)data;
568         struct cfg_marker *marker;
569         struct lustre_cfg *lcfg = (struct lustre_cfg *)(rec + 1);
570         int cfg_len = rec->lrh_len - sizeof(struct llog_rec_hdr) -
571                 sizeof(struct llog_rec_tail);
572         int rc;
573         ENTRY;
574
575         if (rec->lrh_type != OBD_CFG_REC) {
576                 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
577                 RETURN(-EINVAL);
578         }
579
580         rc = lustre_cfg_sanity_check(lcfg, cfg_len);
581         if (rc) {
582                 CERROR("Insane cfg\n");
583                 RETURN(rc);
584         }
585
586         /* We only care about markers */
587         if (lcfg->lcfg_command != LCFG_MARKER)
588                 RETURN(0);
589
590         marker = lustre_cfg_buf(lcfg, 1);
591         if ((strcmp(mml->mml_marker.cm_comment, marker->cm_comment) == 0) &&
592             (strcmp(mml->mml_marker.cm_tgtname, marker->cm_tgtname) == 0) &&
593             !(marker->cm_flags & CM_SKIP)) {
594                 /* Found a non-skipped marker match */
595                 CDEBUG(D_MGS, "Changing rec %u marker %d %x->%x: %s %s\n",
596                        rec->lrh_index, marker->cm_step,
597                        marker->cm_flags, mml->mml_marker.cm_flags,
598                        marker->cm_tgtname, marker->cm_comment);
599                 /* Overwrite the old marker llog entry */
600                 marker->cm_flags &= ~CM_EXCLUDE; /* in case we're unexcluding */
601                 marker->cm_flags |= mml->mml_marker.cm_flags;
602                 marker->cm_canceltime = mml->mml_marker.cm_canceltime;
603                 /* Header and tail are added back to lrh_len in
604                    llog_lvfs_write_rec */
605                 rec->lrh_len = cfg_len;
606                 rc = llog_write_rec(llh, rec, NULL, 0, (void *)lcfg,
607                                     rec->lrh_index);
608                 if (!rc)
609                          mml->mml_modified++;
610         }
611
612         RETURN(rc);
613 }
614
615 /* Modify an existing config log record (for CM_SKIP or CM_EXCLUDE) */
616 static int mgs_modify(struct obd_device *obd, struct fs_db *fsdb,
617                       struct mgs_target_info *mti, char *logname,
618                       char *devname, char *comment, int flags)
619 {
620         struct llog_handle *loghandle;
621         struct lvfs_run_ctxt saved;
622         struct llog_ctxt *ctxt;
623         struct mgs_modify_lookup *mml;
624         int rc, rc2;
625         ENTRY;
626
627         CDEBUG(D_MGS, "modify %s/%s/%s\n", logname, devname, comment);
628
629         push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
630
631         ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
632         LASSERT(ctxt != NULL);
633         rc = llog_create(ctxt, &loghandle, NULL, logname);
634         if (rc)
635                 GOTO(out_pop, rc);
636
637         rc = llog_init_handle(loghandle, LLOG_F_IS_PLAIN, NULL);
638         if (rc)
639                 GOTO(out_close, rc);
640
641         if (llog_get_size(loghandle) <= 1)
642                 GOTO(out_close, rc = 0);
643
644         OBD_ALLOC_PTR(mml);
645         if (!mml)
646                 GOTO(out_close, rc = -ENOMEM);
647         strcpy(mml->mml_marker.cm_comment, comment);
648         strcpy(mml->mml_marker.cm_tgtname, devname);
649         /* Modify mostly means cancel */
650         mml->mml_marker.cm_flags = flags;
651         mml->mml_marker.cm_canceltime = flags ? cfs_time_current_sec() : 0;
652         mml->mml_modified = 0;
653         rc = llog_process(loghandle, mgs_modify_handler, (void *)mml, NULL);
654         if (!rc && !mml->mml_modified)
655                 rc = -ENODEV;
656         OBD_FREE_PTR(mml);
657
658 out_close:
659         rc2 = llog_close(loghandle);
660         if (!rc)
661                 rc = rc2;
662 out_pop:
663         pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
664         if (rc && rc != -ENODEV)
665                 CERROR("modify %s/%s failed %d\n",
666                        mti->mti_svname, comment, rc);
667         llog_ctxt_put(ctxt);
668         RETURN(rc);
669 }
670
671 /******************** config log recording functions *********************/
672
673 static int record_lcfg(struct obd_device *obd, struct llog_handle *llh,
674                          struct lustre_cfg *lcfg)
675 {
676         struct lvfs_run_ctxt   saved;
677         struct llog_rec_hdr    rec;
678         int buflen, rc;
679
680         if (!lcfg || !llh)
681                 return -ENOMEM;
682
683         LASSERT(llh->lgh_ctxt);
684
685         buflen = lustre_cfg_len(lcfg->lcfg_bufcount,
686                                 lcfg->lcfg_buflens);
687         rec.lrh_len = llog_data_len(buflen);
688         rec.lrh_type = OBD_CFG_REC;
689
690         push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
691         /* idx = -1 means append */
692         rc = llog_write_rec(llh, &rec, NULL, 0, (void *)lcfg, -1);
693         pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
694         if (rc)
695                 CERROR("failed %d\n", rc);
696         return rc;
697 }
698
699 static int record_base(struct obd_device *obd, struct llog_handle *llh,
700                      char *cfgname, lnet_nid_t nid, int cmd,
701                      char *s1, char *s2, char *s3, char *s4)
702 {
703         struct lustre_cfg_bufs bufs;
704         struct lustre_cfg     *lcfg;
705         int rc;
706
707         CDEBUG(D_MGS, "lcfg %s %#x %s %s %s %s\n", cfgname,
708                cmd, s1, s2, s3, s4);
709
710         lustre_cfg_bufs_reset(&bufs, cfgname);
711         if (s1)
712                 lustre_cfg_bufs_set_string(&bufs, 1, s1);
713         if (s2)
714                 lustre_cfg_bufs_set_string(&bufs, 2, s2);
715         if (s3)
716                 lustre_cfg_bufs_set_string(&bufs, 3, s3);
717         if (s4)
718                 lustre_cfg_bufs_set_string(&bufs, 4, s4);
719
720         lcfg = lustre_cfg_new(cmd, &bufs);
721         if (!lcfg)
722                 return -ENOMEM;
723         lcfg->lcfg_nid = nid;
724
725         rc = record_lcfg(obd, llh, lcfg);
726
727         lustre_cfg_free(lcfg);
728
729         if (rc) {
730                 CERROR("error %d: lcfg %s %#x %s %s %s %s\n", rc, cfgname,
731                        cmd, s1, s2, s3, s4);
732         }
733         return(rc);
734 }
735
736
737 static inline int record_add_uuid(struct obd_device *obd,
738                                   struct llog_handle *llh,
739                                   uint64_t nid, char *uuid)
740 {
741         return record_base(obd,llh,NULL,nid,LCFG_ADD_UUID,uuid,0,0,0);
742
743 }
744
745 static inline int record_add_conn(struct obd_device *obd,
746                                   struct llog_handle *llh,
747                                   char *devname,
748                                   char *uuid)
749 {
750         return record_base(obd,llh,devname,0,LCFG_ADD_CONN,uuid,0,0,0);
751 }
752
753 static inline int record_attach(struct obd_device *obd, struct llog_handle *llh,
754                                 char *devname, char *type, char *uuid)
755 {
756         return record_base(obd,llh,devname,0,LCFG_ATTACH,type,uuid,0,0);
757 }
758
759 static inline int record_setup(struct obd_device *obd, struct llog_handle *llh,
760                                char *devname,
761                                char *s1, char *s2, char *s3, char *s4)
762 {
763         return record_base(obd,llh,devname,0,LCFG_SETUP,s1,s2,s3,s4);
764 }
765
766 static int record_lov_setup(struct obd_device *obd, struct llog_handle *llh,
767                             char *devname, struct lov_desc *desc)
768 {
769         struct lustre_cfg_bufs bufs;
770         struct lustre_cfg *lcfg;
771         int rc;
772
773         lustre_cfg_bufs_reset(&bufs, devname);
774         lustre_cfg_bufs_set(&bufs, 1, desc, sizeof(*desc));
775         lcfg = lustre_cfg_new(LCFG_SETUP, &bufs);
776         if (!lcfg)
777                 return -ENOMEM;
778         rc = record_lcfg(obd, llh, lcfg);
779
780         lustre_cfg_free(lcfg);
781         return rc;
782 }
783
784 static int record_lmv_setup(struct obd_device *obd, struct llog_handle *llh,
785                             char *devname, struct lmv_desc *desc)
786 {
787         struct lustre_cfg_bufs bufs;
788         struct lustre_cfg *lcfg;
789         int rc;
790
791         lustre_cfg_bufs_reset(&bufs, devname);
792         lustre_cfg_bufs_set(&bufs, 1, desc, sizeof(*desc));
793         lcfg = lustre_cfg_new(LCFG_SETUP, &bufs);
794
795         rc = record_lcfg(obd, llh, lcfg);
796
797         lustre_cfg_free(lcfg);
798         return rc;
799 }
800
801 static inline int record_mdc_add(struct obd_device *obd,
802                                  struct llog_handle *llh,
803                                  char *logname, char *mdcuuid,
804                                  char *mdtuuid, char *index,
805                                  char *gen)
806 {
807         return record_base(obd,llh,logname,0,LCFG_ADD_MDC,
808                            mdtuuid,index,gen,mdcuuid);
809 }
810
811 static inline int record_lov_add(struct obd_device *obd,
812                                  struct llog_handle *llh,
813                                  char *lov_name, char *ost_uuid,
814                                  char *index, char *gen)
815 {
816         return record_base(obd,llh,lov_name,0,LCFG_LOV_ADD_OBD,
817                            ost_uuid,index,gen,0);
818 }
819
820 static inline int record_mount_opt(struct obd_device *obd,
821                                    struct llog_handle *llh,
822                                    char *profile, char *lov_name,
823                                    char *mdc_name)
824 {
825         return record_base(obd,llh,NULL,0,LCFG_MOUNTOPT,
826                            profile,lov_name,mdc_name,0);
827 }
828
829 static int record_marker(struct obd_device *obd, struct llog_handle *llh,
830                          struct fs_db *fsdb, __u32 flags,
831                          char *tgtname, char *comment)
832 {
833         struct cfg_marker marker;
834         struct lustre_cfg_bufs bufs;
835         struct lustre_cfg *lcfg;
836         int rc;
837
838         if (flags & CM_START)
839                 fsdb->fsdb_gen++;
840         marker.cm_step = fsdb->fsdb_gen;
841         marker.cm_flags = flags;
842         marker.cm_vers = LUSTRE_VERSION_CODE;
843         strncpy(marker.cm_tgtname, tgtname, sizeof(marker.cm_tgtname));
844         strncpy(marker.cm_comment, comment, sizeof(marker.cm_comment));
845         marker.cm_createtime = cfs_time_current_sec();
846         marker.cm_canceltime = 0;
847         lustre_cfg_bufs_reset(&bufs, NULL);
848         lustre_cfg_bufs_set(&bufs, 1, &marker, sizeof(marker));
849         lcfg = lustre_cfg_new(LCFG_MARKER, &bufs);
850         if (!lcfg)
851                 return -ENOMEM;
852         rc = record_lcfg(obd, llh, lcfg);
853
854         lustre_cfg_free(lcfg);
855         return rc;
856 }
857
858 static int record_start_log(struct obd_device *obd,
859                             struct llog_handle **llh, char *name)
860 {
861         static struct obd_uuid cfg_uuid = { .uuid = "config_uuid" };
862         struct lvfs_run_ctxt saved;
863         struct llog_ctxt *ctxt;
864         int rc = 0;
865
866         if (*llh)
867                 GOTO(out, rc = -EBUSY);
868
869         ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
870         if (!ctxt)
871                 GOTO(out, rc = -ENODEV);
872
873         push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
874         rc = llog_create(ctxt, llh, NULL, name);
875         if (rc == 0)
876                 llog_init_handle(*llh, LLOG_F_IS_PLAIN, &cfg_uuid);
877         else
878                 *llh = NULL;
879
880         pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
881         llog_ctxt_put(ctxt);
882
883 out:
884         if (rc) {
885                 CERROR("Can't start log %s: %d\n", name, rc);
886         }
887         RETURN(rc);
888 }
889
890 static int record_end_log(struct obd_device *obd, struct llog_handle **llh)
891 {
892         struct lvfs_run_ctxt saved;
893         int rc = 0;
894
895         push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
896
897         rc = llog_close(*llh);
898         *llh = NULL;
899
900         pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
901         RETURN(rc);
902 }
903
904 static int mgs_log_is_empty(struct obd_device *obd, char *name)
905 {
906         struct lvfs_run_ctxt saved;
907         struct llog_handle *llh;
908         struct llog_ctxt *ctxt;
909         int rc = 0;
910
911         ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
912         LASSERT(ctxt != NULL);
913         push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
914         rc = llog_create(ctxt, &llh, NULL, name);
915         if (rc == 0) {
916                 llog_init_handle(llh, LLOG_F_IS_PLAIN, NULL);
917                 rc = llog_get_size(llh);
918                 llog_close(llh);
919         }
920         pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
921         llog_ctxt_put(ctxt);
922         /* header is record 1 */
923         return(rc <= 1);
924 }
925
926 /******************** config "macros" *********************/
927
928 /* write an lcfg directly into a log (with markers) */
929 static int mgs_write_log_direct(struct obd_device *obd, struct fs_db *fsdb,
930                                 char *logname, struct lustre_cfg *lcfg,
931                                 char *devname, char *comment)
932 {
933         struct llog_handle *llh = NULL;
934         int rc;
935         ENTRY;
936
937         if (!lcfg)
938                 RETURN(-ENOMEM);
939
940         rc = record_start_log(obd, &llh, logname);
941         if (rc)
942                 RETURN(rc);
943
944         /* FIXME These should be a single journal transaction */
945         rc = record_marker(obd, llh, fsdb, CM_START, devname, comment);
946
947         rc = record_lcfg(obd, llh, lcfg);
948
949         rc = record_marker(obd, llh, fsdb, CM_END, devname, comment);
950         rc = record_end_log(obd, &llh);
951
952         RETURN(rc);
953 }
954
955 /* write the lcfg in all logs for the given fs */
956 int mgs_write_log_direct_all(struct obd_device *obd, struct fs_db *fsdb,
957                              struct mgs_target_info *mti,
958                              struct lustre_cfg *lcfg,
959                              char *devname, char *comment)
960 {
961         struct mgs_obd *mgs = &obd->u.mgs;
962         struct list_head dentry_list;
963         struct l_linux_dirent *dirent, *n;
964         char *fsname = mti->mti_fsname;
965         char *logname;
966         int rc = 0, len = strlen(fsname);
967         ENTRY;
968
969         /* We need to set params for any future logs
970            as well. FIXME Append this file to every new log.
971            Actually, we should store as params (text), not llogs.  Or
972            in a database. */
973         name_create(&logname, fsname, "-params");
974         if (mgs_log_is_empty(obd, logname)) {
975                 struct llog_handle *llh = NULL;
976                 rc = record_start_log(obd, &llh, logname);
977                 record_end_log(obd, &llh);
978         }
979         name_destroy(&logname);
980         if (rc)
981                 RETURN(rc);
982
983         /* Find all the logs in the CONFIGS directory */
984         rc = class_dentry_readdir(obd, mgs->mgs_configs_dir,
985                                   mgs->mgs_vfsmnt, &dentry_list);
986         if (rc) {
987                 CERROR("Can't read %s dir\n", MOUNT_CONFIGS_DIR);
988                 RETURN(rc);
989         }
990
991         /* Could use fsdb index maps instead of directory listing */
992         list_for_each_entry_safe(dirent, n, &dentry_list, lld_list) {
993                 list_del(&dirent->lld_list);
994                 /* don't write to sptlrpc rule log */
995                 if (strncmp(fsname, dirent->lld_name, len) == 0 &&
996                     strstr(dirent->lld_name, "-sptlrpc") == NULL) {
997                         CDEBUG(D_MGS, "Changing log %s\n", dirent->lld_name);
998                         /* Erase any old settings of this same parameter */
999                         mgs_modify(obd, fsdb, mti, dirent->lld_name, devname,
1000                                    comment, CM_SKIP);
1001                         /* Write the new one */
1002                         rc = mgs_write_log_direct(obd, fsdb, dirent->lld_name,
1003                                                   lcfg, devname, comment);
1004                         if (rc)
1005                                 CERROR("err %d writing log %s\n", rc,
1006                                        dirent->lld_name);
1007                 }
1008                 OBD_FREE(dirent, sizeof(*dirent));
1009         }
1010
1011         RETURN(rc);
1012 }
1013
1014 struct temp_comp
1015 {
1016         struct mgs_target_info   *comp_tmti;
1017         struct mgs_target_info   *comp_mti;
1018         struct fs_db             *comp_fsdb;
1019         struct obd_device        *comp_obd;
1020 };
1021
1022 static int mgs_write_log_mdc_to_mdt(struct obd_device *, struct fs_db *,
1023                                     struct mgs_target_info *, char *);
1024
1025 static int mgs_steal_llog_handler(struct llog_handle *llh,
1026                                   struct llog_rec_hdr *rec,
1027                                   void *data)
1028 {
1029         struct obd_device * obd;
1030         struct mgs_target_info *mti, *tmti;
1031         struct fs_db *fsdb;
1032         int cfg_len = rec->lrh_len;
1033         char *cfg_buf = (char*) (rec + 1);
1034         struct lustre_cfg *lcfg;
1035         int rc = 0;
1036         struct llog_handle *mdt_llh = NULL;
1037         static int got_an_osc_or_mdc = 0;
1038         /* 0: not found any osc/mdc;
1039            1: found osc;
1040            2: found mdc;
1041         */
1042         static int last_step = -1;
1043
1044         ENTRY;
1045
1046         mti = ((struct temp_comp*)data)->comp_mti;
1047         tmti = ((struct temp_comp*)data)->comp_tmti;
1048         fsdb = ((struct temp_comp*)data)->comp_fsdb;
1049         obd = ((struct temp_comp*)data)->comp_obd;
1050
1051         if (rec->lrh_type != OBD_CFG_REC) {
1052                 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
1053                 RETURN(-EINVAL);
1054         }
1055
1056         rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
1057         if (rc) {
1058                 CERROR("Insane cfg\n");
1059                 RETURN(rc);
1060         }
1061
1062         lcfg = (struct lustre_cfg *)cfg_buf;
1063
1064         if (lcfg->lcfg_command == LCFG_MARKER) {
1065                 struct cfg_marker *marker;
1066                 marker = lustre_cfg_buf(lcfg, 1);
1067                 if (!strncmp(marker->cm_comment,"add osc",7) &&
1068                     (marker->cm_flags & CM_START)){
1069                         got_an_osc_or_mdc = 1;
1070                         rc = record_start_log(obd, &mdt_llh, mti->mti_svname);
1071                         rc = record_marker(obd, mdt_llh, fsdb, CM_START,
1072                                            mti->mti_svname,"add osc(copied)");
1073                         rc = record_end_log(obd, &mdt_llh);
1074                         last_step = marker->cm_step;
1075                         RETURN(rc);
1076                 }
1077                 if (!strncmp(marker->cm_comment,"add osc",7) &&
1078                     (marker->cm_flags & CM_END)){
1079                         LASSERT(last_step == marker->cm_step);
1080                         last_step = -1;
1081                         got_an_osc_or_mdc = 0;
1082                         rc = record_start_log(obd, &mdt_llh, mti->mti_svname);
1083                         rc = record_marker(obd, mdt_llh, fsdb, CM_END,
1084                                            mti->mti_svname,"add osc(copied)");
1085                         rc = record_end_log(obd, &mdt_llh);
1086                         RETURN(rc);
1087                 }
1088                 if (!strncmp(marker->cm_comment,"add mdc",7) &&
1089                     (marker->cm_flags & CM_START)){
1090                         got_an_osc_or_mdc = 2;
1091                         last_step = marker->cm_step;
1092                         memcpy(tmti->mti_svname, marker->cm_tgtname,
1093                                strlen(marker->cm_tgtname));
1094
1095                         RETURN(rc);
1096                 }
1097                 if (!strncmp(marker->cm_comment,"add mdc",7) &&
1098                     (marker->cm_flags & CM_END)){
1099                         LASSERT(last_step == marker->cm_step);
1100                         last_step = -1;
1101                         got_an_osc_or_mdc = 0;
1102                         RETURN(rc);
1103                 }
1104         }
1105
1106         if (got_an_osc_or_mdc == 0 || last_step < 0)
1107                 RETURN(rc);
1108
1109         if (lcfg->lcfg_command == LCFG_ADD_UUID) {
1110                 uint64_t nodenid;
1111                 nodenid = lcfg->lcfg_nid;
1112
1113                 tmti->mti_nids[tmti->mti_nid_count] = nodenid;
1114                 tmti->mti_nid_count++;
1115
1116                 RETURN(rc);
1117         }
1118
1119         if (lcfg->lcfg_command == LCFG_SETUP) {
1120                 char *target;
1121
1122                 target = lustre_cfg_string(lcfg, 1);
1123                 memcpy(tmti->mti_uuid, target, strlen(target));
1124                 RETURN(rc);
1125         }
1126
1127         /* ignore client side sptlrpc_conf_log */
1128         if (lcfg->lcfg_command == LCFG_SPTLRPC_CONF)
1129                 RETURN(rc);
1130
1131         if (lcfg->lcfg_command == LCFG_ADD_MDC) {
1132                 int index;
1133
1134                 if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1)
1135                         RETURN (-EINVAL);
1136
1137                 memcpy(tmti->mti_fsname, mti->mti_fsname,
1138                        strlen(mti->mti_fsname));
1139                 tmti->mti_stripe_index = index;
1140
1141                 mgs_write_log_mdc_to_mdt(obd, fsdb, tmti, mti->mti_svname);
1142                 memset(tmti, 0, sizeof(*tmti));
1143                 RETURN(rc);
1144         }
1145         RETURN(rc);
1146 }
1147
1148 /* fsdb->fsdb_sem is already held  in mgs_write_log_target*/
1149 /* stealed from mgs_get_fsdb_from_llog*/
1150 static int mgs_steal_llog_for_mdt_from_client(struct obd_device *obd,
1151                                               char *client_name,
1152                                               struct temp_comp* comp)
1153 {
1154         struct llog_handle *loghandle;
1155         struct lvfs_run_ctxt saved;
1156         struct mgs_target_info *tmti;
1157         struct llog_ctxt *ctxt;
1158         int rc, rc2;
1159         ENTRY;
1160
1161         ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
1162         LASSERT(ctxt != NULL);
1163
1164         OBD_ALLOC_PTR(tmti);
1165         if (tmti == NULL)
1166                 RETURN(-ENOMEM);
1167
1168         comp->comp_tmti = tmti;
1169         comp->comp_obd = obd;
1170
1171         push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
1172
1173         rc = llog_create(ctxt, &loghandle, NULL, client_name);
1174         if (rc)
1175                 GOTO(out_pop, rc);
1176
1177         rc = llog_init_handle(loghandle, LLOG_F_IS_PLAIN, NULL);
1178         if (rc)
1179                 GOTO(out_close, rc);
1180
1181         rc = llog_process(loghandle, mgs_steal_llog_handler, (void *)comp, NULL);
1182         CDEBUG(D_MGS, "steal llog re = %d\n", rc);
1183 out_close:
1184         rc2 = llog_close(loghandle);
1185         if (!rc)
1186                 rc = rc2;
1187 out_pop:
1188         pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
1189         OBD_FREE_PTR(tmti);
1190         llog_ctxt_put(ctxt);
1191         RETURN(rc);
1192 }
1193
1194 /* lmv is the second thing for client logs */
1195 /* copied from mgs_write_log_lov. Please refer to that.  */
1196 static int mgs_write_log_lmv(struct obd_device *obd, struct fs_db *fsdb,
1197                              struct mgs_target_info *mti,
1198                              char *logname, char *lmvname)
1199 {
1200         struct llog_handle *llh = NULL;
1201         struct lmv_desc *lmvdesc;
1202         char *uuid;
1203         int rc = 0;
1204         ENTRY;
1205
1206         CDEBUG(D_MGS, "Writing lmv(%s) log for %s\n", lmvname,logname);
1207
1208         OBD_ALLOC_PTR(lmvdesc);
1209         if (lmvdesc == NULL)
1210                 RETURN(-ENOMEM);
1211         lmvdesc->ld_active_tgt_count = 0;
1212         lmvdesc->ld_tgt_count = 0;
1213         sprintf((char*)lmvdesc->ld_uuid.uuid, "%s_UUID", lmvname);
1214         uuid = (char *)lmvdesc->ld_uuid.uuid;
1215
1216         rc = record_start_log(obd, &llh, logname);
1217         rc = record_marker(obd, llh, fsdb, CM_START, lmvname, "lmv setup");
1218         rc = record_attach(obd, llh, lmvname, "lmv", uuid);
1219         rc = record_lmv_setup(obd, llh, lmvname, lmvdesc);
1220         rc = record_marker(obd, llh, fsdb, CM_END, lmvname, "lmv setup");
1221         rc = record_end_log(obd, &llh);
1222
1223         OBD_FREE_PTR(lmvdesc);
1224         RETURN(rc);
1225 }
1226
1227 /* lov is the first thing in the mdt and client logs */
1228 static int mgs_write_log_lov(struct obd_device *obd, struct fs_db *fsdb,
1229                              struct mgs_target_info *mti,
1230                              char *logname, char *lovname)
1231 {
1232         struct llog_handle *llh = NULL;
1233         struct lov_desc *lovdesc;
1234         char *uuid;
1235         int rc = 0;
1236         ENTRY;
1237
1238         CDEBUG(D_MGS, "Writing lov(%s) log for %s\n", lovname, logname);
1239
1240         /*
1241         #01 L attach   0:lov_mdsA  1:lov  2:71ccb_lov_mdsA_19f961a9e1
1242         #02 L lov_setup 0:lov_mdsA 1:(struct lov_desc)
1243               uuid=lov1_UUID, stripe count=1, size=1048576, offset=0, pattern=0
1244         */
1245
1246         /* FIXME just make lov_setup accept empty desc (put uuid in buf 2) */
1247         OBD_ALLOC_PTR(lovdesc);
1248         if (lovdesc == NULL)
1249                 RETURN(-ENOMEM);
1250         lovdesc->ld_magic = LOV_DESC_MAGIC;
1251         lovdesc->ld_tgt_count = 0;
1252         /* Defaults.  Can be changed later by lcfg config_param */
1253         lovdesc->ld_default_stripe_count = 1;
1254         lovdesc->ld_pattern = LOV_PATTERN_RAID0;
1255         lovdesc->ld_default_stripe_size = 1024 * 1024;
1256         lovdesc->ld_default_stripe_offset = 0;
1257         lovdesc->ld_qos_maxage = QOS_DEFAULT_MAXAGE;
1258         sprintf((char*)lovdesc->ld_uuid.uuid, "%s_UUID", lovname);
1259         /* can these be the same? */
1260         uuid = (char *)lovdesc->ld_uuid.uuid;
1261
1262         /* This should always be the first entry in a log.
1263         rc = mgs_clear_log(obd, logname); */
1264         rc = record_start_log(obd, &llh, logname);
1265         if (rc)
1266                 GOTO(out, rc);
1267         /* FIXME these should be a single journal transaction */
1268         rc = record_marker(obd, llh, fsdb, CM_START, lovname, "lov setup");
1269         rc = record_attach(obd, llh, lovname, "lov", uuid);
1270         rc = record_lov_setup(obd, llh, lovname, lovdesc);
1271         rc = record_marker(obd, llh, fsdb, CM_END, lovname, "lov setup");
1272         rc = record_end_log(obd, &llh);
1273
1274         EXIT;
1275 out:
1276         OBD_FREE_PTR(lovdesc);
1277         return rc;
1278 }
1279
1280 /* add failnids to open log */
1281 static int mgs_write_log_failnids(struct obd_device *obd,
1282                                   struct mgs_target_info *mti,
1283                                   struct llog_handle *llh,
1284                                   char *cliname)
1285 {
1286         char *failnodeuuid = NULL;
1287         char *ptr = mti->mti_params;
1288         lnet_nid_t nid;
1289         int rc = 0;
1290
1291         /*
1292         #03 L add_uuid  nid=uml1@tcp(0x20000c0a80201) nal=90 0:  1:uml1_UUID
1293         #04 L add_uuid  nid=1@elan(0x1000000000001)   nal=90 0:  1:uml1_UUID
1294         #05 L setup    0:OSC_uml1_ost1_mdsA  1:ost1_UUID  2:uml1_UUID
1295         #06 L add_uuid  nid=uml2@tcp(0x20000c0a80202) nal=90 0:  1:uml2_UUID
1296         #0x L add_uuid  nid=2@elan(0x1000000000002)   nal=90 0:  1:uml2_UUID
1297         #07 L add_conn 0:OSC_uml1_ost1_mdsA  1:uml2_UUID
1298         */
1299
1300         /* Pull failnid info out of params string */
1301         while (class_find_param(ptr, PARAM_FAILNODE, &ptr) == 0) {
1302                 while (class_parse_nid(ptr, &nid, &ptr) == 0) {
1303                         if (failnodeuuid == NULL) {
1304                                 /* We don't know the failover node name,
1305                                    so just use the first nid as the uuid */
1306                                 rc = name_create(&failnodeuuid,
1307                                                  libcfs_nid2str(nid), "");
1308                                 if (rc)
1309                                         return rc;
1310                         }
1311                         CDEBUG(D_MGS, "add nid %s for failover uuid %s, "
1312                                "client %s\n", libcfs_nid2str(nid),
1313                                failnodeuuid, cliname);
1314                         rc = record_add_uuid(obd, llh, nid, failnodeuuid);
1315                 }
1316                 if (failnodeuuid) {
1317                         rc = record_add_conn(obd, llh, cliname, failnodeuuid);
1318                         name_destroy(&failnodeuuid);
1319                         failnodeuuid = NULL;
1320                 }
1321         }
1322
1323         return rc;
1324 }
1325
1326 static int mgs_write_log_mdc_to_lmv(struct obd_device *obd, struct fs_db *fsdb,
1327                                     struct mgs_target_info *mti,
1328                                     char *logname, char *lmvname)
1329 {
1330         struct llog_handle *llh = NULL;
1331         char *mdcname, *nodeuuid, *mdcuuid, *lmvuuid;
1332         char index[5];
1333         int i, rc;
1334         ENTRY;
1335
1336         if (mgs_log_is_empty(obd, logname)) {
1337                 CERROR("log is empty! Logical error\n");
1338                 RETURN(-EINVAL);
1339         }
1340
1341         CDEBUG(D_MGS, "adding mdc for %s to log %s:lmv(%s)\n",
1342                mti->mti_svname, logname, lmvname);
1343
1344         name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
1345         name_create(&mdcname, mti->mti_svname, "-mdc");
1346         name_create(&mdcuuid, mdcname, "_UUID");
1347         name_create(&lmvuuid, lmvname, "_UUID");
1348
1349         rc = record_start_log(obd, &llh, logname);
1350         rc = record_marker(obd, llh, fsdb, CM_START, mti->mti_svname,
1351                            "add mdc");
1352
1353         for (i = 0; i < mti->mti_nid_count; i++) {
1354                 CDEBUG(D_MGS, "add nid %s for mdt\n",
1355                        libcfs_nid2str(mti->mti_nids[i]));
1356
1357                 rc = record_add_uuid(obd, llh, mti->mti_nids[i], nodeuuid);
1358         }
1359
1360         rc = record_attach(obd, llh, mdcname, LUSTRE_MDC_NAME, lmvuuid);
1361         rc = record_setup(obd, llh, mdcname, mti->mti_uuid, nodeuuid, 0, 0);
1362         rc = mgs_write_log_failnids(obd, mti, llh, mdcname);
1363         snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
1364         rc = record_mdc_add(obd, llh, lmvname, mdcuuid, mti->mti_uuid,
1365                             index, "1");
1366         rc = record_marker(obd, llh, fsdb, CM_END, mti->mti_svname,
1367                            "add mdc");
1368         rc = record_end_log(obd, &llh);
1369
1370         name_destroy(&lmvuuid);
1371         name_destroy(&mdcuuid);
1372         name_destroy(&mdcname);
1373         name_destroy(&nodeuuid);
1374         RETURN(rc);
1375 }
1376
1377 /* add new mdc to already existent MDS */
1378 static int mgs_write_log_mdc_to_mdt(struct obd_device *obd, struct fs_db *fsdb,
1379                                     struct mgs_target_info *mti, char *logname)
1380 {
1381         struct llog_handle *llh = NULL;
1382         char *nodeuuid, *mdcname, *mdcuuid, *mdtuuid;
1383         int idx = mti->mti_stripe_index;
1384         char index[9];
1385         int i, rc;
1386
1387         ENTRY;
1388         if (mgs_log_is_empty(obd, mti->mti_svname)) {
1389                 CERROR("log is empty! Logical error\n");
1390                 RETURN (-EINVAL);
1391         }
1392
1393         CDEBUG(D_MGS, "adding mdc index %d to %s\n", idx, logname);
1394
1395         name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
1396         snprintf(index, sizeof(index), "-mdc%04x", idx);
1397         name_create(&mdcname, logname, index);
1398         name_create(&mdcuuid, mdcname, "_UUID");
1399         name_create(&mdtuuid, logname, "_UUID");
1400
1401         rc = record_start_log(obd, &llh, logname);
1402         rc = record_marker(obd, llh, fsdb, CM_START, mti->mti_svname, "add mdc");
1403         for (i = 0; i < mti->mti_nid_count; i++) {
1404                 CDEBUG(D_MGS, "add nid %s for mdt\n",
1405                        libcfs_nid2str(mti->mti_nids[i]));
1406                 rc = record_add_uuid(obd, llh, mti->mti_nids[i], nodeuuid);
1407         }
1408         rc = record_attach(obd, llh, mdcname, LUSTRE_MDC_NAME, mdcuuid);
1409         rc = record_setup(obd, llh, mdcname, mti->mti_uuid, nodeuuid, 0, 0);
1410         rc = mgs_write_log_failnids(obd, mti, llh, mdcname);
1411         snprintf(index, sizeof(index), "%d", idx);
1412
1413         rc = record_mdc_add(obd, llh, logname, mdcuuid, mti->mti_uuid,
1414                             index, "1");
1415         rc = record_marker(obd, llh, fsdb, CM_END, mti->mti_svname, "add mdc");
1416         rc = record_end_log(obd, &llh);
1417
1418         name_destroy(&mdcuuid);
1419         name_destroy(&mdcname);
1420         name_destroy(&nodeuuid);
1421         name_destroy(&mdtuuid);
1422         RETURN(rc);
1423 }
1424
1425 static int mgs_write_log_mdt0(struct obd_device *obd, struct fs_db *fsdb,
1426                               struct mgs_target_info *mti)
1427 {
1428         char *log = mti->mti_svname;
1429         struct llog_handle *llh = NULL;
1430         char *uuid, *lovname;
1431         char mdt_index[5];
1432         char *ptr = mti->mti_params;
1433         int rc = 0, failout = 0;
1434         ENTRY;
1435
1436         OBD_ALLOC(uuid, sizeof(struct obd_uuid));
1437         if (uuid == NULL)
1438                 RETURN(-ENOMEM);
1439
1440         if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
1441                 failout = (strncmp(ptr, "failout", 7) == 0);
1442
1443         name_create(&lovname, log, "-mdtlov");
1444         if (mgs_log_is_empty(obd, log))
1445                 rc = mgs_write_log_lov(obd, fsdb, mti, log, lovname);
1446
1447         sprintf(uuid, "%s_UUID", log);
1448         sprintf(mdt_index,"%d",mti->mti_stripe_index);
1449
1450         /* add MDT itself */
1451         rc = record_start_log(obd, &llh, log);
1452         if (rc)
1453                 GOTO(out, rc);
1454
1455         /* FIXME this whole fn should be a single journal transaction */
1456         rc = record_marker(obd, llh, fsdb, CM_START, log, "add mdt");
1457         rc = record_attach(obd, llh, log, LUSTRE_MDT_NAME, uuid);
1458         rc = record_mount_opt(obd, llh, log, lovname, NULL);
1459         rc = record_setup(obd, llh, log, uuid, mdt_index, lovname,
1460                         failout ? "n" : "f");
1461         rc = record_marker(obd, llh, fsdb, CM_END, log, "add mdt");
1462         rc = record_end_log(obd, &llh);
1463 out:
1464         name_destroy(&lovname);
1465         OBD_FREE(uuid, sizeof(struct obd_uuid));
1466         RETURN(rc);
1467 }
1468
1469 /* envelope method for all layers log */
1470 static int mgs_write_log_mdt(struct obd_device *obd, struct fs_db *fsdb,
1471                               struct mgs_target_info *mti)
1472 {
1473         struct llog_handle *llh = NULL;
1474         char *cliname;
1475         struct temp_comp comp = { 0 };
1476         char mdt_index[9];
1477         int rc, i = 0;
1478         ENTRY;
1479
1480         CDEBUG(D_MGS, "writing new mdt %s\n", mti->mti_svname);
1481
1482 #if 0
1483         /* COMPAT_146 */
1484         if (mti->mti_flags & LDD_F_UPGRADE14) {
1485                 /* We're starting with an old uuid.  Assume old name for lov
1486                    as well since the lov entry already exists in the log. */
1487                 CDEBUG(D_MGS, "old mds uuid %s\n", mti->mti_uuid);
1488                 if (strncmp(mti->mti_uuid, fsdb->fsdb_mdtlov + 4,
1489                             strlen(fsdb->fsdb_mdtlov) - 4) != 0) {
1490                         CERROR("old mds uuid %s doesn't match log %s (%s)\n",
1491                                mti->mti_uuid, fsdb->fsdb_mdtlov,
1492                                fsdb->fsdb_mdtlov + 4);
1493                         RETURN(-EINVAL);
1494                 }
1495         }
1496         /* end COMPAT_146 */
1497 #endif
1498         if (mti->mti_uuid[0] == '\0') {
1499                 /* Make up our own uuid */
1500                 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
1501                          "%s_UUID", mti->mti_svname);
1502         }
1503
1504         /* add mdt */
1505         rc = mgs_write_log_mdt0(obd, fsdb, mti);
1506
1507         /* Append the mdt info to the client log */
1508         name_create(&cliname, mti->mti_fsname, "-client");
1509
1510         if (mgs_log_is_empty(obd, cliname)) {
1511                 /* Start client log */
1512                 rc = mgs_write_log_lov(obd, fsdb, mti, cliname,
1513                                        fsdb->fsdb_clilov);
1514                 rc = mgs_write_log_lmv(obd, fsdb, mti, cliname,
1515                                        fsdb->fsdb_clilmv);
1516         }
1517
1518         /*
1519         #09 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0:  1:uml1_UUID
1520         #10 L attach   0:MDC_uml1_mdsA_MNT_client  1:mdc  2:1d834_MNT_client_03f
1521         #11 L setup    0:MDC_uml1_mdsA_MNT_client  1:mdsA_UUID  2:uml1_UUID
1522         #12 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0:  1:uml2_UUID
1523         #13 L add_conn 0:MDC_uml1_mdsA_MNT_client  1:uml2_UUID
1524         #14 L mount_option 0:  1:client  2:lov1  3:MDC_uml1_mdsA_MNT_client
1525         */
1526
1527 #if 0
1528         /* COMPAT_146 */
1529         if (mti->mti_flags & LDD_F_UPGRADE14) {
1530                 rc = record_start_log(obd, &llh, cliname);
1531                 if (rc)
1532                         GOTO(out, rc);
1533
1534                 rc = record_marker(obd, llh, fsdb, CM_START,
1535                                    mti->mti_svname,"add mdc");
1536
1537                 /* Old client log already has MDC entry, but needs mount opt
1538                    for new client name (lustre-client) */
1539                 /* FIXME Old MDT log already has an old mount opt
1540                    which we should remove (currently handled by
1541                    class_del_profiles()) */
1542                 rc = record_mount_opt(obd, llh, cliname, fsdb->fsdb_clilov,
1543                                       fsdb->fsdb_mdc);
1544                 /* end COMPAT_146 */
1545
1546                 rc = record_marker(obd, llh, fsdb, CM_END,
1547                                    mti->mti_svname, "add mdc");
1548         } else
1549 #endif
1550         {
1551                 /* copy client info about lov/lmv */
1552                 comp.comp_mti = mti;
1553                 comp.comp_fsdb = fsdb;
1554
1555                 rc = mgs_steal_llog_for_mdt_from_client(obd, cliname,
1556                                                         &comp);
1557
1558                 rc = mgs_write_log_mdc_to_lmv(obd, fsdb, mti, cliname,
1559                                               fsdb->fsdb_clilmv);
1560                 /* add mountopts */
1561                 rc = record_start_log(obd, &llh, cliname);
1562                 if (rc)
1563                         GOTO(out, rc);
1564
1565                 rc = record_marker(obd, llh, fsdb, CM_START, cliname,
1566                                    "mount opts");
1567                 rc = record_mount_opt(obd, llh, cliname, fsdb->fsdb_clilov,
1568                                       fsdb->fsdb_clilmv);
1569                 rc = record_marker(obd, llh, fsdb, CM_END, cliname,
1570                                    "mount opts");
1571         }
1572
1573         rc = record_end_log(obd, &llh);
1574 out:
1575         name_destroy(&cliname);
1576
1577         // for_all_existing_mdt except current one
1578         for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
1579                 char *mdtname;
1580                 if (i !=  mti->mti_stripe_index &&
1581                     test_bit(i,  fsdb->fsdb_mdt_index_map)) {
1582                         sprintf(mdt_index,"-MDT%04x",i);
1583
1584                         name_create(&mdtname, mti->mti_fsname, mdt_index);
1585                         rc = mgs_write_log_mdc_to_mdt(obd, fsdb, mti, mdtname);
1586                         name_destroy(&mdtname);
1587                 }
1588         }
1589
1590         RETURN(rc);
1591 }
1592
1593 /* Add the ost info to the client/mdt lov */
1594 static int mgs_write_log_osc_to_lov(struct obd_device *obd, struct fs_db *fsdb,
1595                                     struct mgs_target_info *mti,
1596                                     char *logname, char *suffix, char *lovname,
1597                                     enum lustre_sec_part sec_part, int flags)
1598 {
1599         struct llog_handle *llh = NULL;
1600         char *nodeuuid, *oscname, *oscuuid, *lovuuid, *svname;
1601         char index[5];
1602         int i, rc;
1603
1604         ENTRY;
1605         CDEBUG(D_INFO, "adding osc for %s to log %s\n",
1606                mti->mti_svname, logname);
1607
1608         if (mgs_log_is_empty(obd, logname)) {
1609                 /* The first item in the log must be the lov, so we have
1610                    somewhere to add our osc. */
1611                 rc = mgs_write_log_lov(obd, fsdb, mti, logname, lovname);
1612         }
1613
1614         name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
1615         name_create(&svname, mti->mti_svname, "-osc");
1616         name_create(&oscname, svname, suffix);
1617         name_create(&oscuuid, oscname, "_UUID");
1618         name_create(&lovuuid, lovname, "_UUID");
1619
1620         /*
1621         #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0:  1:uml1_UUID
1622         multihomed (#4)
1623         #04 L add_uuid  nid=1@elan(0x1000000000001)  nal=90 0:  1:uml1_UUID
1624         #04 L attach   0:OSC_uml1_ost1_MNT_client  1:osc  2:89070_lov1_a41dff51a
1625         #05 L setup    0:OSC_uml1_ost1_MNT_client  1:ost1_UUID  2:uml1_UUID
1626         failover (#6,7)
1627         #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0:  1:uml2_UUID
1628         #07 L add_conn 0:OSC_uml1_ost1_MNT_client  1:uml2_UUID
1629         #08 L lov_modify_tgts add 0:lov1  1:ost1_UUID  2(index):0  3(gen):1
1630         */
1631
1632         rc = record_start_log(obd, &llh, logname);
1633         if (rc)
1634                 GOTO(out, rc);
1635         /* FIXME these should be a single journal transaction */
1636         rc = record_marker(obd, llh, fsdb, CM_START | flags, mti->mti_svname,
1637                            "add osc");
1638         for (i = 0; i < mti->mti_nid_count; i++) {
1639                 CDEBUG(D_MGS, "add nid %s\n", libcfs_nid2str(mti->mti_nids[i]));
1640                 rc = record_add_uuid(obd, llh, mti->mti_nids[i], nodeuuid);
1641         }
1642         rc = record_attach(obd, llh, oscname, LUSTRE_OSC_NAME, lovuuid);
1643         rc = record_setup(obd, llh, oscname, mti->mti_uuid, nodeuuid, 0, 0);
1644         rc = mgs_write_log_failnids(obd, mti, llh, oscname);
1645         snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
1646         rc = record_lov_add(obd, llh, lovname, mti->mti_uuid, index, "1");
1647         rc = record_marker(obd, llh, fsdb, CM_END | flags, mti->mti_svname,
1648                            "add osc");
1649         rc = record_end_log(obd, &llh);
1650 out:
1651         name_destroy(&lovuuid);
1652         name_destroy(&oscuuid);
1653         name_destroy(&oscname);
1654         name_destroy(&svname);
1655         name_destroy(&nodeuuid);
1656         RETURN(rc);
1657 }
1658
1659 static int mgs_write_log_ost(struct obd_device *obd, struct fs_db *fsdb,
1660                              struct mgs_target_info *mti)
1661 {
1662         struct llog_handle *llh = NULL;
1663         char *logname, *lovname;
1664         char mdt_index[9];
1665         char *ptr = mti->mti_params;
1666         int rc, flags = 0, failout = 0, i;
1667         ENTRY;
1668
1669         CDEBUG(D_MGS, "writing new ost %s\n", mti->mti_svname);
1670
1671         /* The ost startup log */
1672
1673         /* If the ost log already exists, that means that someone reformatted
1674            the ost and it called target_add again. */
1675         if (!mgs_log_is_empty(obd, mti->mti_svname)) {
1676                 LCONSOLE_ERROR_MSG(0x141, "The config log for %s already "
1677                                    "exists, yet the server claims it never "
1678                                    "registered. It may have been reformatted, "
1679                                    "or the index changed. writeconf the MDT to "
1680                                    "regenerate all logs.\n", mti->mti_svname);
1681                 RETURN(-EALREADY);
1682         }
1683
1684         /*
1685         attach obdfilter ost1 ost1_UUID
1686         setup /dev/loop2 ldiskfs f|n errors=remount-ro,user_xattr
1687         */
1688         if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
1689                 failout = (strncmp(ptr, "failout", 7) == 0);
1690         rc = record_start_log(obd, &llh, mti->mti_svname);
1691         if (rc)
1692                 RETURN(rc);
1693         /* FIXME these should be a single journal transaction */
1694         rc = record_marker(obd, llh, fsdb, CM_START, mti->mti_svname,"add ost");
1695         if (*mti->mti_uuid == '\0')
1696                 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
1697                          "%s_UUID", mti->mti_svname);
1698         rc = record_attach(obd, llh, mti->mti_svname,
1699                            "obdfilter"/*LUSTRE_OST_NAME*/, mti->mti_uuid);
1700         rc = record_setup(obd, llh, mti->mti_svname,
1701                           "dev"/*ignored*/, "type"/*ignored*/,
1702                           failout ? "n" : "f", 0/*options*/);
1703         rc = record_marker(obd, llh, fsdb, CM_END, mti->mti_svname, "add ost");
1704         rc = record_end_log(obd, &llh);
1705
1706         /* We also have to update the other logs where this osc is part of
1707            the lov */
1708
1709         if (fsdb->fsdb_flags & FSDB_OLDLOG14) {
1710                 /* If we're upgrading, the old mdt log already has our
1711                    entry. Let's do a fake one for fun. */
1712                 /* Note that we can't add any new failnids, since we don't
1713                    know the old osc names. */
1714                 flags = CM_SKIP | CM_UPGRADE146;
1715
1716         } else if ((mti->mti_flags & LDD_F_UPDATE) != LDD_F_UPDATE) {
1717                 /* If the update flag isn't set, don't update client/mdt
1718                    logs. */
1719                 flags |= CM_SKIP;
1720                 LCONSOLE_WARN("Client log for %s was not updated; writeconf "
1721                               "the MDT first to regenerate it.\n",
1722                               mti->mti_svname);
1723         }
1724
1725         // for_all_existing_mdt
1726         for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
1727                  if (test_bit(i,  fsdb->fsdb_mdt_index_map)) {
1728                         sprintf(mdt_index,"-MDT%04x",i);
1729                         name_create(&logname, mti->mti_fsname, mdt_index);
1730                         name_create(&lovname, logname, "-mdtlov");
1731                         mgs_write_log_osc_to_lov(obd, fsdb, mti, logname,
1732                                                  mdt_index, lovname,
1733                                                  LUSTRE_SP_MDT, flags);
1734                         name_destroy(&logname);
1735                         name_destroy(&lovname);
1736                 }
1737         }
1738
1739         /* Append ost info to the client log */
1740         name_create(&logname, mti->mti_fsname, "-client");
1741         mgs_write_log_osc_to_lov(obd, fsdb, mti, logname, "",
1742                                  fsdb->fsdb_clilov, LUSTRE_SP_CLI, 0);
1743         name_destroy(&logname);
1744         RETURN(rc);
1745 }
1746
1747 /* Add additional failnids to an existing log.
1748    The mdc/osc must have been added to logs first */
1749 /* tcp nids must be in dotted-quad ascii -
1750    we can't resolve hostnames from the kernel. */
1751 static int mgs_write_log_add_failnid(struct obd_device *obd, struct fs_db *fsdb,
1752                                      struct mgs_target_info *mti)
1753 {
1754         char *logname, *cliname;
1755         struct llog_handle *llh = NULL;
1756         int rc;
1757         ENTRY;
1758
1759         /* FIXME how do we delete a failnid? Currently --writeconf is the
1760            only way.  Maybe make --erase-params pass a flag to really
1761            erase all params from logs - except it can't erase the failnids
1762            given when a target first registers, since they aren't processed
1763            as params... */
1764
1765         /* Verify that we know about this target */
1766         if (mgs_log_is_empty(obd, mti->mti_svname)) {
1767                 LCONSOLE_ERROR_MSG(0x142, "The target %s has not registered "
1768                                    "yet. It must be started before failnids "
1769                                    "can be added.\n", mti->mti_svname);
1770                 RETURN(-ENOENT);
1771         }
1772
1773         /* Create mdc/osc client name (e.g. lustre-OST0001-osc) */
1774         if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
1775                 name_create(&cliname, mti->mti_svname, "-mdc");
1776         } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
1777                 name_create(&cliname, mti->mti_svname, "-osc");
1778         } else {
1779                 RETURN(-EINVAL);
1780         }
1781
1782         /* Add failover nids to client log */
1783         name_create(&logname, mti->mti_fsname, "-client");
1784         rc = record_start_log(obd, &llh, logname);
1785         if (!rc) {
1786                 /* FIXME this fn should be a single journal transaction */
1787                 rc = record_marker(obd, llh, fsdb, CM_START, mti->mti_svname,
1788                                    "add failnid");
1789                 rc = mgs_write_log_failnids(obd, mti, llh, cliname);
1790                 rc = record_marker(obd, llh, fsdb, CM_END, mti->mti_svname,
1791                                    "add failnid");
1792                 rc = record_end_log(obd, &llh);
1793         }
1794         name_destroy(&logname);
1795
1796         if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
1797                 /* Add OST failover nids to the MDT log as well */
1798                 name_create(&logname, mti->mti_fsname, "-MDT0000");
1799                 rc = record_start_log(obd, &llh, logname);
1800                 if (!rc) {
1801                         rc = record_marker(obd, llh, fsdb, CM_START,
1802                                            mti->mti_svname, "add failnid");
1803                         rc = mgs_write_log_failnids(obd, mti, llh, cliname);
1804                         rc = record_marker(obd, llh, fsdb, CM_END,
1805                                            mti->mti_svname, "add failnid");
1806                         rc = record_end_log(obd, &llh);
1807                 }
1808                 name_destroy(&logname);
1809         }
1810
1811         name_destroy(&cliname);
1812         RETURN(rc);
1813 }
1814
1815 static int mgs_wlp_lcfg(struct obd_device *obd, struct fs_db *fsdb,
1816                         struct mgs_target_info *mti,
1817                         char *logname, struct lustre_cfg_bufs *bufs,
1818                         char *tgtname, char *ptr)
1819 {
1820         char comment[MTI_NAME_MAXLEN];
1821         char *tmp;
1822         struct lustre_cfg *lcfg;
1823         int rc;
1824
1825         /* Erase any old settings of this same parameter */
1826         memcpy(comment, ptr, MTI_NAME_MAXLEN);
1827         comment[MTI_NAME_MAXLEN - 1] = 0;
1828         /* But don't try to match the value. */
1829         if ((tmp = strchr(comment, '=')))
1830             *tmp = 0;
1831         /* FIXME we should skip settings that are the same as old values */
1832         rc = mgs_modify(obd, fsdb, mti, logname, tgtname, comment, CM_SKIP);
1833         LCONSOLE_INFO("%sing parameter %s.%s in log %s\n", rc ?
1834                       "Sett" : "Modify", tgtname, comment, logname);
1835
1836         lustre_cfg_bufs_reset(bufs, tgtname);
1837         lustre_cfg_bufs_set_string(bufs, 1, ptr);
1838         lcfg = lustre_cfg_new(LCFG_PARAM, bufs);
1839         if (!lcfg)
1840                 return -ENOMEM;
1841         rc = mgs_write_log_direct(obd, fsdb, logname, lcfg, tgtname, comment);
1842         lustre_cfg_free(lcfg);
1843         return rc;
1844 }
1845
1846 static int mgs_srpc_set_param_disk(struct obd_device *obd,
1847                                    struct fs_db *fsdb,
1848                                    struct mgs_target_info *mti,
1849                                    char *param)
1850 {
1851         struct llog_handle     *llh = NULL;
1852         char                   *logname;
1853         char                   *comment, *ptr;
1854         struct lustre_cfg_bufs  bufs;
1855         struct lustre_cfg      *lcfg;
1856         int                     rc, len;
1857         ENTRY;
1858
1859         /* get comment */
1860         ptr = strchr(param, '=');
1861         LASSERT(ptr);
1862         len = ptr - param;
1863
1864         OBD_ALLOC(comment, len + 1);
1865         if (comment == NULL)
1866                 RETURN(-ENOMEM);
1867         strncpy(comment, param, len);
1868         comment[len] = '\0';
1869
1870         /* prepare lcfg */
1871         lustre_cfg_bufs_reset(&bufs, mti->mti_svname);
1872         lustre_cfg_bufs_set_string(&bufs, 1, param);
1873         lcfg = lustre_cfg_new(LCFG_SPTLRPC_CONF, &bufs);
1874         if (lcfg == NULL)
1875                 GOTO(out_comment, rc = -ENOMEM);
1876
1877         /* construct log name */
1878         rc = name_create(&logname, mti->mti_fsname, "-sptlrpc");
1879         if (rc)
1880                 GOTO(out_lcfg, rc);
1881
1882         if (mgs_log_is_empty(obd, logname)) {
1883                 rc = record_start_log(obd, &llh, logname);
1884                 record_end_log(obd, &llh);
1885                 if (rc)
1886                         GOTO(out, rc);
1887         }
1888
1889         /* obsolete old one */
1890         mgs_modify(obd, fsdb, mti, logname, mti->mti_svname, comment, CM_SKIP);
1891
1892         /* write the new one */
1893         rc = mgs_write_log_direct(obd, fsdb, logname, lcfg,
1894                                   mti->mti_svname, comment);
1895         if (rc)
1896                 CERROR("err %d writing log %s\n", rc, logname);
1897
1898 out:
1899         name_destroy(&logname);
1900 out_lcfg:
1901         lustre_cfg_free(lcfg);
1902 out_comment:
1903         OBD_FREE(comment, len + 1);
1904         RETURN(rc);
1905 }
1906
1907 static int mgs_srpc_set_param_udesc_mem(struct fs_db *fsdb,
1908                                         char *param)
1909 {
1910         char    *ptr;
1911
1912         /* disable the adjustable udesc parameter for now, i.e. use default
1913          * setting that client always ship udesc to MDT if possible. to enable
1914          * it simply remove the following line */
1915         goto error_out;
1916
1917         ptr = strchr(param, '=');
1918         if (ptr == NULL)
1919                 goto error_out;
1920         *ptr++ = '\0';
1921
1922         if (strcmp(param, PARAM_SRPC_UDESC))
1923                 goto error_out;
1924
1925         if (strcmp(ptr, "yes") == 0) {
1926                 fsdb->fsdb_srpc_fl_udesc = 1;
1927                 CWARN("Enable user descriptor shipping from client to MDT\n");
1928         } else if (strcmp(ptr, "no") == 0) {
1929                 fsdb->fsdb_srpc_fl_udesc = 0;
1930                 CWARN("Disable user descriptor shipping from client to MDT\n");
1931         } else {
1932                 *(ptr - 1) = '=';
1933                 goto error_out;
1934         }
1935         return 0;
1936
1937 error_out:
1938         CERROR("Invalid param: %s\n", param);
1939         return -EINVAL;
1940 }
1941
1942 static int mgs_srpc_set_param_mem(struct fs_db *fsdb,
1943                                   const char *svname,
1944                                   char *param)
1945 {
1946         struct sptlrpc_rule      rule;
1947         struct sptlrpc_rule_set *rset;
1948         int                      rc;
1949         ENTRY;
1950
1951         if (strncmp(param, PARAM_SRPC, sizeof(PARAM_SRPC) - 1) != 0) {
1952                 CERROR("Invalid sptlrpc parameter: %s\n", param);
1953                 RETURN(-EINVAL);
1954         }
1955
1956         if (strncmp(param, PARAM_SRPC_UDESC,
1957                     sizeof(PARAM_SRPC_UDESC) - 1) == 0) {
1958                 RETURN(mgs_srpc_set_param_udesc_mem(fsdb, param));
1959         }
1960
1961         if (strncmp(param, PARAM_SRPC_FLVR, sizeof(PARAM_SRPC_FLVR) - 1) != 0) {
1962                 CERROR("Invalid sptlrpc flavor parameter: %s\n", param);
1963                 RETURN(-EINVAL);
1964         }
1965
1966         param += sizeof(PARAM_SRPC_FLVR) - 1;
1967
1968         rc = sptlrpc_parse_rule(param, &rule);
1969         if (rc)
1970                 RETURN(rc);
1971
1972         /* preapre room for this coming rule. svcname format should be:
1973          * - fsname: general rule
1974          * - fsname-tgtname: target-specific rule
1975          */
1976         if (strchr(svname, '-')) {
1977                 struct mgs_tgt_srpc_conf *tgtconf;
1978                 int                       found = 0;
1979
1980                 for (tgtconf = fsdb->fsdb_srpc_tgt; tgtconf != NULL;
1981                      tgtconf = tgtconf->mtsc_next) {
1982                         if (!strcmp(tgtconf->mtsc_tgt, svname)) {
1983                                 found = 1;
1984                                 break;
1985                         }
1986                 }
1987
1988                 if (!found) {
1989                         int name_len;
1990
1991                         OBD_ALLOC_PTR(tgtconf);
1992                         if (tgtconf == NULL)
1993                                 RETURN(-ENOMEM);
1994
1995                         name_len = strlen(svname);
1996
1997                         OBD_ALLOC(tgtconf->mtsc_tgt, name_len + 1);
1998                         if (tgtconf->mtsc_tgt == NULL) {
1999                                 OBD_FREE_PTR(tgtconf);
2000                                 RETURN(-ENOMEM);
2001                         }
2002                         memcpy(tgtconf->mtsc_tgt, svname, name_len);
2003
2004                         tgtconf->mtsc_next = fsdb->fsdb_srpc_tgt;
2005                         fsdb->fsdb_srpc_tgt = tgtconf;
2006                 }
2007
2008                 rset = &tgtconf->mtsc_rset;
2009         } else {
2010                 rset = &fsdb->fsdb_srpc_gen;
2011         }
2012
2013         rc = sptlrpc_rule_set_merge(rset, &rule, 1);
2014
2015         RETURN(rc);
2016 }
2017
2018 static int mgs_srpc_set_param(struct obd_device *obd,
2019                               struct fs_db *fsdb,
2020                               struct mgs_target_info *mti,
2021                               char *param)
2022 {
2023         char                   *copy;
2024         int                     rc, copy_size;
2025         ENTRY;
2026
2027         /* keep a copy of original param, which could be destroied
2028          * during parsing */
2029         copy_size = strlen(param) + 1;
2030         OBD_ALLOC(copy, copy_size);
2031         if (copy == NULL)
2032                 return -ENOMEM;
2033         memcpy(copy, param, copy_size);
2034
2035         rc = mgs_srpc_set_param_mem(fsdb, mti->mti_svname, param);
2036         if (rc)
2037                 goto out_free;
2038
2039         /* previous steps guaranteed the syntax is correct */
2040         rc = mgs_srpc_set_param_disk(obd, fsdb, mti, copy);
2041 out_free:
2042         OBD_FREE(copy, copy_size);
2043         RETURN(rc);
2044 }
2045
2046 struct mgs_srpc_read_data {
2047         struct fs_db   *msrd_fsdb;
2048         int             msrd_skip;
2049 };
2050
2051 static int mgs_srpc_read_handler(struct llog_handle *llh,
2052                                  struct llog_rec_hdr *rec,
2053                                  void *data)
2054 {
2055         struct mgs_srpc_read_data *msrd = (struct mgs_srpc_read_data *) data;
2056         struct cfg_marker         *marker;
2057         struct lustre_cfg         *lcfg = (struct lustre_cfg *)(rec + 1);
2058         char                      *svname, *param;
2059         int                        cfg_len, rc;
2060         ENTRY;
2061
2062         if (rec->lrh_type != OBD_CFG_REC) {
2063                 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
2064                 RETURN(-EINVAL);
2065         }
2066
2067         cfg_len = rec->lrh_len - sizeof(struct llog_rec_hdr) -
2068                   sizeof(struct llog_rec_tail);
2069
2070         rc = lustre_cfg_sanity_check(lcfg, cfg_len);
2071         if (rc) {
2072                 CERROR("Insane cfg\n");
2073                 RETURN(rc);
2074         }
2075
2076         if (lcfg->lcfg_command == LCFG_MARKER) {
2077                 marker = lustre_cfg_buf(lcfg, 1);
2078
2079                 if (marker->cm_flags & CM_START &&
2080                     marker->cm_flags & CM_SKIP)
2081                         msrd->msrd_skip = 1;
2082                 if (marker->cm_flags & CM_END)
2083                         msrd->msrd_skip = 0;
2084
2085                 RETURN(0);
2086         }
2087
2088         if (msrd->msrd_skip)
2089                 RETURN(0);
2090
2091         if (lcfg->lcfg_command != LCFG_SPTLRPC_CONF) {
2092                 CERROR("invalid command (%x)\n", lcfg->lcfg_command);
2093                 RETURN(0);
2094         }
2095
2096         svname = lustre_cfg_string(lcfg, 0);
2097         if (svname == NULL) {
2098                 CERROR("svname is empty\n");
2099                 RETURN(0);
2100         }
2101
2102         param = lustre_cfg_string(lcfg, 1);
2103         if (param == NULL) {
2104                 CERROR("param is empty\n");
2105                 RETURN(0);
2106         }
2107
2108         rc = mgs_srpc_set_param_mem(msrd->msrd_fsdb, svname, param);
2109         if (rc)
2110                 CERROR("read sptlrpc record error (%d): %s\n", rc, param);
2111
2112         RETURN(0);
2113 }
2114
2115 int mgs_get_fsdb_srpc_from_llog(struct obd_device *obd,
2116                                 struct fs_db *fsdb)
2117 {
2118         struct llog_handle        *llh = NULL;
2119         struct lvfs_run_ctxt       saved;
2120         struct llog_ctxt          *ctxt;
2121         char                      *logname;
2122         struct mgs_srpc_read_data  msrd;
2123         int                        rc;
2124         ENTRY;
2125
2126         /* construct log name */
2127         rc = name_create(&logname, fsdb->fsdb_name, "-sptlrpc");
2128         if (rc)
2129                 RETURN(rc);
2130
2131         ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
2132         LASSERT(ctxt != NULL);
2133
2134         if (mgs_log_is_empty(obd, logname))
2135                 GOTO(out, rc = 0);
2136
2137         push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
2138
2139         rc = llog_create(ctxt, &llh, NULL, logname);
2140         if (rc)
2141                 GOTO(out_pop, rc);
2142
2143         rc = llog_init_handle(llh, LLOG_F_IS_PLAIN, NULL);
2144         if (rc)
2145                 GOTO(out_close, rc);
2146
2147         if (llog_get_size(llh) <= 1)
2148                 GOTO(out_close, rc = 0);
2149
2150         msrd.msrd_fsdb = fsdb;
2151         msrd.msrd_skip = 0;
2152
2153         rc = llog_process(llh, mgs_srpc_read_handler, (void *) &msrd, NULL);
2154
2155 out_close:
2156         llog_close(llh);
2157 out_pop:
2158         pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
2159 out:
2160         llog_ctxt_put(ctxt);
2161         name_destroy(&logname);
2162
2163         if (rc)
2164                 CERROR("failed to read sptlrpc config database: %d\n", rc);
2165         RETURN(rc);
2166 }
2167
2168 static int mgs_write_log_params(struct obd_device *obd, struct fs_db *fsdb,
2169                                 struct mgs_target_info *mti)
2170 {
2171         struct lustre_cfg_bufs bufs;
2172         struct lustre_cfg *lcfg;
2173         char *logname;
2174         char *ptr = mti->mti_params;
2175         char *endptr, *tmp;
2176         int rc = 0;
2177         ENTRY;
2178
2179         if (!mti->mti_params)
2180                 RETURN(0);
2181
2182         /* For various parameter settings, we have to figure out which logs
2183            care about them (e.g. both mdt and client for lov settings) */
2184         while (ptr) {
2185                 while (*ptr == ' ')
2186                         ptr++;
2187                 if (*ptr == '\0')
2188                         break;
2189                 endptr = strchr(ptr, ' ');
2190                 if (endptr)
2191                         *endptr = '\0';
2192                 CDEBUG(D_MGS, "next param '%s'\n", ptr);
2193
2194                 /* The params are stored in MOUNT_DATA_FILE and modified
2195                    via tunefs.lustre, or set using lctl conf_param */
2196
2197                 /* Processed in lustre_start_mgc */
2198                 if (class_match_param(ptr, PARAM_MGSNODE, NULL) == 0)
2199                         GOTO(end_while, rc);
2200
2201                 /* Processed in mgs_write_log_ost */
2202                 if (class_match_param(ptr, PARAM_FAILMODE, NULL) == 0) {
2203                         if (mti->mti_flags & LDD_F_PARAM) {
2204                                 LCONSOLE_ERROR_MSG(0x169, "%s can only be "
2205                                                    "changed with tunefs.lustre"
2206                                                    "and --writeconf\n", ptr);
2207                                 rc = -EPERM;
2208                         }
2209                         GOTO(end_while, rc);
2210                 }
2211
2212                 if (class_match_param(ptr, PARAM_SRPC, NULL) == 0) {
2213                         rc = mgs_srpc_set_param(obd, fsdb, mti, ptr);
2214                         GOTO(end_while, rc);
2215                 }
2216
2217                 if (class_match_param(ptr, PARAM_FAILNODE, NULL) == 0) {
2218                         /* Add a failover nidlist */
2219                         rc = 0;
2220                         /* We already processed failovers params for new
2221                            targets in mgs_write_log_target */
2222                         if (mti->mti_flags & LDD_F_PARAM) {
2223                                 CDEBUG(D_MGS, "Adding failnode\n");
2224                                 rc = mgs_write_log_add_failnid(obd, fsdb, mti);
2225                         }
2226                         GOTO(end_while, rc);
2227                 }
2228
2229                 if (class_match_param(ptr, PARAM_SYS_TIMEOUT, &tmp) == 0) {
2230                         /* Change obd timeout */
2231                         int timeout;
2232                         timeout = simple_strtoul(tmp, NULL, 0);
2233
2234                         CDEBUG(D_MGS, "obd timeout %d\n", timeout);
2235                         lustre_cfg_bufs_reset(&bufs, NULL);
2236                         lcfg = lustre_cfg_new(LCFG_SET_TIMEOUT, &bufs);
2237                         lcfg->lcfg_num = timeout;
2238                         /* modify all servers and clients */
2239                         rc = mgs_write_log_direct_all(obd, fsdb, mti, lcfg,
2240                                                       mti->mti_fsname,
2241                                                       "timeout");
2242                         lustre_cfg_free(lcfg);
2243                         GOTO(end_while, rc);
2244                 }
2245
2246                 if (class_match_param(ptr, PARAM_OSC""PARAM_ACTIVE, &tmp) == 0) {
2247                         /* active=0 means off, anything else means on */
2248                         char mdt_index[16];
2249                         int flag = (*tmp == '0') ? CM_EXCLUDE : 0;
2250                         int i;
2251
2252                         if (!(mti->mti_flags & LDD_F_SV_TYPE_OST)) {
2253                                 LCONSOLE_ERROR_MSG(0x144, "%s: Only OSCs can "
2254                                                    "be (de)activated.\n",
2255                                                    mti->mti_svname);
2256                                 rc = -EINVAL;
2257                                 goto end_while;
2258                         }
2259                         LCONSOLE_WARN("Permanently %sactivating %s\n",
2260                                       flag ? "de": "re", mti->mti_svname);
2261                         /* Modify clilov */
2262                         name_create(&logname, mti->mti_fsname, "-client");
2263                         rc = mgs_modify(obd, fsdb, mti, logname,
2264                                         mti->mti_svname, "add osc", flag);
2265                         name_destroy(&logname);
2266                         if (rc)
2267                                 goto active_err;
2268                         /* Modify mdtlov */
2269                         /* FIXME add to all MDT logs for CMD */
2270                         for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2271                                 if (!test_bit(i, fsdb->fsdb_mdt_index_map))
2272                                         continue;
2273                                 sprintf(mdt_index,"-MDT%04x", i);
2274                                 name_create(&logname, mti->mti_fsname, mdt_index);
2275                                 rc = mgs_modify(obd, fsdb, mti, logname,
2276                                                 mti->mti_svname, "add osc", flag);
2277                                 name_destroy(&logname);
2278                                 if (rc)
2279                                         goto active_err;
2280                         }
2281 active_err:
2282                         if (rc) {
2283                                 LCONSOLE_ERROR_MSG(0x145, "Couldn't find %s in"
2284                                                    "log (%d). No permanent "
2285                                                    "changes were made to the "
2286                                                    "config log.\n",
2287                                                    mti->mti_svname, rc);
2288                                 if (fsdb->fsdb_flags & FSDB_OLDLOG14)
2289                                         LCONSOLE_ERROR_MSG(0x146, "This may be"
2290                                                            " because the log "
2291                                                            "is in the old 1.4"
2292                                                            "style. Consider "
2293                                                            " --writeconf to "
2294                                                            "update the logs.\n");
2295                                 goto end_while;
2296                         }
2297                         /* Fall through to osc proc for deactivating
2298                            live OSC on running MDT / clients. */
2299                 }
2300                 /* Below here, let obd's XXX_process_config methods handle it */
2301
2302                 /* All lov. in proc */
2303                 if (class_match_param(ptr, PARAM_LOV, NULL) == 0) {
2304                         char mdt_index[16];
2305                         char *mdtlovname;
2306
2307                         CDEBUG(D_MGS, "lov param %s\n", ptr);
2308                         if (!(mti->mti_flags & LDD_F_SV_TYPE_MDT)) {
2309                                 LCONSOLE_ERROR_MSG(0x147, "LOV params must be "
2310                                                    "set on the MDT, not %s. "
2311                                                    "Ignoring.\n",
2312                                                    mti->mti_svname);
2313                                 rc = 0;
2314                                 goto end_while;
2315                         }
2316
2317                         /* Modify mdtlov */
2318                         if (mgs_log_is_empty(obd, mti->mti_svname))
2319                                 GOTO(end_while, rc = -ENODEV);
2320
2321                         sprintf(mdt_index,"-MDT%04x", mti->mti_stripe_index);
2322                         name_create(&logname, mti->mti_fsname, mdt_index);
2323                         name_create(&mdtlovname, logname, "-mdtlov");
2324                         rc = mgs_wlp_lcfg(obd, fsdb, mti, mti->mti_svname,
2325                                           &bufs, mdtlovname, ptr);
2326                         name_destroy(&logname);
2327                         name_destroy(&mdtlovname);
2328                         if (rc)
2329                                 GOTO(end_while, rc);
2330
2331                         /* Modify clilov */
2332                         name_create(&logname, mti->mti_fsname, "-client");
2333                         rc = mgs_wlp_lcfg(obd, fsdb, mti, logname, &bufs,
2334                                           fsdb->fsdb_clilov, ptr);
2335                         name_destroy(&logname);
2336                         GOTO(end_while, rc);
2337                 }
2338
2339                 /* All osc., mdc., llite. params in proc */
2340                 if ((class_match_param(ptr, PARAM_OSC, NULL) == 0) ||
2341                     (class_match_param(ptr, PARAM_MDC, NULL) == 0) ||
2342                     (class_match_param(ptr, PARAM_LLITE, NULL) == 0)) {
2343                         char *cname;
2344                         if (memcmp(ptr, PARAM_LLITE, strlen(PARAM_LLITE)) == 0) {
2345                                 name_create(&cname, mti->mti_fsname, "-client");
2346                         /* Add the client type to match the obdname
2347                            in class_config_llog_handler */
2348                         } else if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
2349                                 /* COMPAT_146 */
2350                                 if (fsdb->fsdb_mdc)
2351                                         name_create(&cname, fsdb->fsdb_mdc, "");
2352                                 else
2353                                         name_create(&cname, mti->mti_svname,
2354                                                     "-mdc");
2355                         } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2356                                 /* COMPAT_146 */
2357                                 if (fsdb->fsdb_flags & FSDB_OLDLOG14) {
2358                                         LCONSOLE_ERROR_MSG(0x148, "Upgraded "
2359                                                            "client logs for %s"
2360                                                            " cannot be "
2361                                                            "modified. Consider"
2362                                                            " updating the "
2363                                                            "configuration with"
2364                                                            " --writeconf\n",
2365                                                            mti->mti_svname);
2366                                         /* We don't know the names of all the
2367                                            old oscs*/
2368                                         rc = -EINVAL;
2369                                         goto end_while;
2370                                 }
2371                                 name_create(&cname, mti->mti_svname, "-osc");
2372                         } else {
2373                                 rc = -EINVAL;
2374                                 goto end_while;
2375                         }
2376
2377                         CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
2378
2379                         /* Modify client */
2380                         name_create(&logname, mti->mti_fsname, "-client");
2381                         rc = mgs_wlp_lcfg(obd, fsdb, mti, logname, &bufs,
2382                                           cname, ptr);
2383
2384                         /* osc params affect the MDT as well */
2385                         if (!rc && (mti->mti_flags & LDD_F_SV_TYPE_OST)) {
2386                                 char mdt_index[16];
2387                                 int i;
2388
2389                                 for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
2390                                         if (!test_bit(i, fsdb->fsdb_mdt_index_map))
2391                                                 continue;
2392                                         name_destroy(&cname);
2393                                         sprintf(mdt_index, "-osc-MDT%04x", i);
2394                                         name_create(&cname, mti->mti_svname,
2395                                                     mdt_index);
2396                                         name_destroy(&logname);
2397                                         sprintf(mdt_index, "-MDT%04x", i);
2398                                         name_create(&logname, mti->mti_fsname,
2399                                                     mdt_index);
2400                                         if (!mgs_log_is_empty(obd, logname))
2401                                                 rc = mgs_wlp_lcfg(obd, fsdb,
2402                                                                   mti, logname,
2403                                                                   &bufs, cname,
2404                                                                   ptr);
2405                                         if (rc)
2406                                                 break;
2407                                 }
2408                         }
2409                         name_destroy(&logname);
2410                         name_destroy(&cname);
2411                         GOTO(end_while, rc);
2412                 }
2413
2414                 /* All mdt., ost. params in proc */
2415                 if ((class_match_param(ptr, PARAM_MDT, NULL) == 0) ||
2416                     (class_match_param(ptr, PARAM_MDD, NULL) == 0) ||
2417                     (class_match_param(ptr, PARAM_OST, NULL) == 0)) {
2418                         CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
2419                         if (mgs_log_is_empty(obd, mti->mti_svname)) {
2420                                 rc = -ENODEV;
2421                                 goto end_while;
2422                         }
2423                         rc = mgs_wlp_lcfg(obd, fsdb, mti, mti->mti_svname,
2424                                           &bufs, mti->mti_svname, ptr);
2425                         GOTO(end_while, rc);
2426                 }
2427
2428                 LCONSOLE_WARN("Ignoring unrecognized param '%s'\n", ptr);
2429
2430 end_while:
2431                 if (rc) {
2432                         CERROR("err %d on param '%s\n", rc, ptr);
2433                         break;
2434                 }
2435
2436                 if (!endptr)
2437                         /* last param */
2438                         break;
2439
2440                 *endptr = ' ';
2441                 ptr = endptr + 1;
2442         }
2443
2444         RETURN(rc);
2445 }
2446
2447 /* Not implementing automatic failover nid addition at this time. */
2448 int mgs_check_failnid(struct obd_device *obd, struct mgs_target_info *mti)
2449 {
2450 #if 0
2451         struct fs_db *fsdb;
2452         int rc;
2453         ENTRY;
2454
2455         rc = mgs_find_or_make_fsdb(obd, fsname, &fsdb);
2456         if (rc)
2457                 RETURN(rc);
2458
2459         if (mgs_log_is_empty(obd, mti->mti_svname))
2460                 /* should never happen */
2461                 RETURN(-ENOENT);
2462
2463         CDEBUG(D_MGS, "Checking for new failnids for %s\n", mti->mti_svname);
2464
2465         /* FIXME We can just check mti->params to see if we're already in
2466            the failover list.  Modify mti->params for rewriting back at
2467            server_register_target(). */
2468
2469         down(&fsdb->fsdb_sem);
2470         rc = mgs_write_log_add_failnid(obd, fsdb, mti);
2471         up(&fsdb->fsdb_sem);
2472
2473         RETURN(rc);
2474 #endif
2475         return 0;
2476 }
2477
2478 int mgs_write_log_target(struct obd_device *obd,
2479                          struct mgs_target_info *mti)
2480 {
2481         struct fs_db *fsdb;
2482         int rc = -EINVAL;
2483         ENTRY;
2484
2485         /* set/check the new target index */
2486         rc = mgs_set_index(obd, mti);
2487         if (rc < 0) {
2488                 CERROR("Can't get index (%d)\n", rc);
2489                 RETURN(rc);
2490         }
2491
2492         /* COMPAT_146 */
2493         if (mti->mti_flags & LDD_F_UPGRADE14) {
2494                 if (rc == EALREADY) {
2495                         LCONSOLE_INFO("Found index %d for %s 1.4 log, "
2496                                       "upgrading\n", mti->mti_stripe_index,
2497                                       mti->mti_svname);
2498                 } else {
2499                         LCONSOLE_ERROR_MSG(0x149, "Failed to find %s in the old"
2500                                            " client log. Apparently it is not "
2501                                            "part of this filesystem, or the old"
2502                                            " log is wrong.\nUse 'writeconf' on "
2503                                            "the MDT to force log regeneration."
2504                                            "\n", mti->mti_svname);
2505                         /* Not in client log?  Upgrade anyhow...*/
2506                         /* Argument against upgrading: reformat MDT,
2507                            upgrade OST, then OST will start but will be SKIPped
2508                            in client logs.  Maybe error now is better. */
2509                         /* RETURN(-EINVAL); */
2510                 }
2511                 /* end COMPAT_146 */
2512         } else {
2513                 if (rc == EALREADY) {
2514                         LCONSOLE_WARN("Found index %d for %s, updating log\n",
2515                                       mti->mti_stripe_index, mti->mti_svname);
2516                         /* We would like to mark old log sections as invalid
2517                            and add new log sections in the client and mdt logs.
2518                            But if we add new sections, then live clients will
2519                            get repeat setup instructions for already running
2520                            osc's. So don't update the client/mdt logs. */
2521                         mti->mti_flags &= ~LDD_F_UPDATE;
2522                 }
2523         }
2524
2525         rc = mgs_find_or_make_fsdb(obd, mti->mti_fsname, &fsdb);
2526         if (rc) {
2527                 CERROR("Can't get db for %s\n", mti->mti_fsname);
2528                 RETURN(rc);
2529         }
2530
2531         down(&fsdb->fsdb_sem);
2532
2533         if (mti->mti_flags &
2534             (LDD_F_VIRGIN | LDD_F_UPGRADE14 | LDD_F_WRITECONF)) {
2535                 /* Generate a log from scratch */
2536                 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
2537                         rc = mgs_write_log_mdt(obd, fsdb, mti);
2538                 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2539                         rc = mgs_write_log_ost(obd, fsdb, mti);
2540                 } else {
2541                         CERROR("Unknown target type %#x, can't create log for "
2542                                "%s\n", mti->mti_flags, mti->mti_svname);
2543                 }
2544                 if (rc) {
2545                         CERROR("Can't write logs for %s (%d)\n",
2546                                mti->mti_svname, rc);
2547                         GOTO(out_up, rc);
2548                 }
2549         } else {
2550                 /* Just update the params from tunefs in mgs_write_log_params */
2551                 CDEBUG(D_MGS, "Update params for %s\n", mti->mti_svname);
2552                 mti->mti_flags |= LDD_F_PARAM;
2553         }
2554
2555         rc = mgs_write_log_params(obd, fsdb, mti);
2556
2557 out_up:
2558         up(&fsdb->fsdb_sem);
2559         RETURN(rc);
2560 }
2561
2562 /* COMPAT_146 */
2563 /* verify that we can handle the old config logs */
2564 int mgs_upgrade_sv_14(struct obd_device *obd, struct mgs_target_info *mti)
2565 {
2566         struct fs_db *fsdb;
2567         int rc = 0;
2568         ENTRY;
2569
2570         /* Create ost log normally, as servers register.  Servers
2571            register with their old uuids (from last_rcvd), so old
2572            (MDT and client) logs should work.
2573          - new MDT won't know about old OSTs, only the ones that have
2574            registered, so we need the old MDT log to get the LOV right
2575            in order for old clients to work.
2576          - Old clients connect to the MDT, not the MGS, for their logs, and
2577            will therefore receive the old client log from the MDT /LOGS dir.
2578          - Old clients can continue to use and connect to old or new OSTs
2579          - New clients will contact the MGS for their log
2580         */
2581
2582         LCONSOLE_INFO("upgrading server %s from pre-1.6\n", mti->mti_svname);
2583         server_mti_print("upgrade", mti);
2584
2585         rc = mgs_find_or_make_fsdb(obd, mti->mti_fsname, &fsdb);
2586         if (rc)
2587                 RETURN(rc);
2588
2589         if (fsdb->fsdb_flags & FSDB_LOG_EMPTY) {
2590                 LCONSOLE_ERROR_MSG(0x14a, "The old client log %s-client is "
2591                                    "missing.  Was tunefs.lustre successful?\n",
2592                                    mti->mti_fsname);
2593                 RETURN(-ENOENT);
2594         }
2595
2596         if (fsdb->fsdb_gen == 0) {
2597                 /* There were no markers in the client log, meaning we have
2598                    not updated the logs for this fs */
2599                 CDEBUG(D_MGS, "found old, unupdated client log\n");
2600         }
2601
2602         if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
2603                 if (mgs_log_is_empty(obd, mti->mti_svname)) {
2604                         LCONSOLE_ERROR_MSG(0x14b, "The old MDT log %s is "
2605                                            "missing. Was tunefs.lustre "
2606                                            "successful?\n",
2607                                            mti->mti_svname);
2608                         RETURN(-ENOENT);
2609                 }
2610                 /* We're starting with an old uuid.  Assume old name for lov
2611                    as well since the lov entry already exists in the log. */
2612                 CDEBUG(D_MGS, "old mds uuid %s\n", mti->mti_uuid);
2613                 if (strncmp(mti->mti_uuid, fsdb->fsdb_mdtlov + 4,
2614                             strlen(fsdb->fsdb_mdtlov) - 4) != 0) {
2615                         CERROR("old mds uuid %s doesn't match log %s (%s)\n",
2616                                mti->mti_uuid, fsdb->fsdb_mdtlov,
2617                                fsdb->fsdb_mdtlov + 4);
2618                         RETURN(-EINVAL);
2619                 }
2620         }
2621
2622         if (!(fsdb->fsdb_flags & FSDB_OLDLOG14)) {
2623                 LCONSOLE_ERROR_MSG(0x14c, "%s-client is supposedly an old "
2624                                    "log, but no old LOV or MDT was found. "
2625                                    "Consider updating the configuration with"
2626                                    " --writeconf.\n", mti->mti_fsname);
2627         }
2628
2629         RETURN(rc);
2630 }
2631 /* end COMPAT_146 */
2632
2633 int mgs_erase_log(struct obd_device *obd, char *name)
2634 {
2635         struct lvfs_run_ctxt saved;
2636         struct llog_ctxt *ctxt;
2637         struct llog_handle *llh;
2638         int rc = 0;
2639
2640         ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
2641         LASSERT(ctxt != NULL);
2642
2643         push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
2644         rc = llog_create(ctxt, &llh, NULL, name);
2645         if (rc == 0) {
2646                 llog_init_handle(llh, LLOG_F_IS_PLAIN, NULL);
2647                 rc = llog_destroy(llh);
2648                 llog_free_handle(llh);
2649         }
2650         pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
2651         llog_ctxt_put(ctxt);
2652
2653         if (rc)
2654                 CERROR("failed to clear log %s: %d\n", name, rc);
2655
2656         return(rc);
2657 }
2658
2659 /* erase all logs for the given fs */
2660 int mgs_erase_logs(struct obd_device *obd, char *fsname)
2661 {
2662         struct mgs_obd *mgs = &obd->u.mgs;
2663         static struct fs_db *fsdb;
2664         struct list_head dentry_list;
2665         struct l_linux_dirent *dirent, *n;
2666         int rc, len = strlen(fsname);
2667         ENTRY;
2668
2669         /* Find all the logs in the CONFIGS directory */
2670         rc = class_dentry_readdir(obd, mgs->mgs_configs_dir,
2671                                   mgs->mgs_vfsmnt, &dentry_list);
2672         if (rc) {
2673                 CERROR("Can't read %s dir\n", MOUNT_CONFIGS_DIR);
2674                 RETURN(rc);
2675         }
2676
2677         down(&mgs->mgs_sem);
2678
2679         /* Delete the fs db */
2680         fsdb = mgs_find_fsdb(obd, fsname);
2681         if (fsdb)
2682                 mgs_free_fsdb(obd, fsdb);
2683
2684         list_for_each_entry_safe(dirent, n, &dentry_list, lld_list) {
2685                 list_del(&dirent->lld_list);
2686                 if (strncmp(fsname, dirent->lld_name, len) == 0) {
2687                         CDEBUG(D_MGS, "Removing log %s\n", dirent->lld_name);
2688                         mgs_erase_log(obd, dirent->lld_name);
2689                 }
2690                 OBD_FREE(dirent, sizeof(*dirent));
2691         }
2692
2693         up(&mgs->mgs_sem);
2694
2695         RETURN(rc);
2696 }
2697
2698 /* from llog_swab */
2699 static void print_lustre_cfg(struct lustre_cfg *lcfg)
2700 {
2701         int i;
2702         ENTRY;
2703
2704         CDEBUG(D_MGS, "lustre_cfg: %p\n", lcfg);
2705         CDEBUG(D_MGS, "\tlcfg->lcfg_version: %#x\n", lcfg->lcfg_version);
2706
2707         CDEBUG(D_MGS, "\tlcfg->lcfg_command: %#x\n", lcfg->lcfg_command);
2708         CDEBUG(D_MGS, "\tlcfg->lcfg_num: %#x\n", lcfg->lcfg_num);
2709         CDEBUG(D_MGS, "\tlcfg->lcfg_flags: %#x\n", lcfg->lcfg_flags);
2710         CDEBUG(D_MGS, "\tlcfg->lcfg_nid: %s\n", libcfs_nid2str(lcfg->lcfg_nid));
2711
2712         CDEBUG(D_MGS, "\tlcfg->lcfg_bufcount: %d\n", lcfg->lcfg_bufcount);
2713         if (lcfg->lcfg_bufcount < LUSTRE_CFG_MAX_BUFCOUNT)
2714                 for (i = 0; i < lcfg->lcfg_bufcount; i++) {
2715                         CDEBUG(D_MGS, "\tlcfg->lcfg_buflens[%d]: %d %s\n",
2716                                i, lcfg->lcfg_buflens[i],
2717                                lustre_cfg_string(lcfg, i));
2718                 }
2719         EXIT;
2720 }
2721
2722 /* Set a permanent (config log) param for a target or fs */
2723 int mgs_setparam(struct obd_device *obd, struct lustre_cfg *lcfg, char *fsname)
2724 {
2725         struct fs_db *fsdb;
2726         struct mgs_target_info *mti;
2727         char *devname, *param;
2728         char *ptr, *tmp;
2729         __u32 index;
2730         int rc = 0;
2731         ENTRY;
2732
2733         print_lustre_cfg(lcfg);
2734
2735         /* lustre, lustre-mdtlov, lustre-client, lustre-MDT0000 */
2736         devname = lustre_cfg_string(lcfg, 0);
2737         param = lustre_cfg_string(lcfg, 1);
2738         if (!devname) {
2739                 /* Assume device name embedded in param:
2740                    lustre-OST0000.osc.max_dirty_mb=32 */
2741                 ptr = strchr(param, '.');
2742                 if (ptr) {
2743                         devname = param;
2744                         *ptr = 0;
2745                         param = ptr + 1;
2746                 }
2747         }
2748         if (!devname) {
2749                 LCONSOLE_ERROR_MSG(0x14d, "No target specified: %s\n", param);
2750                 RETURN(-ENOSYS);
2751         }
2752
2753         /* Extract fsname */
2754         ptr = strrchr(devname, '-');
2755         memset(fsname, 0, MTI_NAME_MAXLEN);
2756         if (ptr && (server_name2index(ptr, &index, NULL) >= 0)) {
2757                 strncpy(fsname, devname, ptr - devname);
2758         } else {
2759                 /* assume devname is the fsname */
2760                 strncpy(fsname, devname, MTI_NAME_MAXLEN);
2761         }
2762         fsname[MTI_NAME_MAXLEN - 1] = 0;
2763         CDEBUG(D_MGS, "setparam on fs %s device %s\n", fsname, devname);
2764
2765         rc = mgs_find_or_make_fsdb(obd, fsname, &fsdb);
2766         if (rc)
2767                 RETURN(rc);
2768         if (fsdb->fsdb_flags & FSDB_LOG_EMPTY) {
2769                 CERROR("No filesystem targets for %s.  cfg_device from lctl "
2770                        "is '%s'\n", fsname, devname);
2771                 mgs_free_fsdb(obd, fsdb);
2772                 RETURN(-EINVAL);
2773         }
2774
2775         /* Create a fake mti to hold everything */
2776         OBD_ALLOC_PTR(mti);
2777         if (!mti)
2778                 GOTO(out, rc = -ENOMEM);
2779         strncpy(mti->mti_fsname, fsname, MTI_NAME_MAXLEN);
2780         strncpy(mti->mti_svname, devname, MTI_NAME_MAXLEN);
2781         strncpy(mti->mti_params, param, sizeof(mti->mti_params));
2782         rc = server_name2index(mti->mti_svname, &mti->mti_stripe_index, &tmp);
2783         if (rc < 0)
2784                 /* Not a valid server; may be only fsname */
2785                 rc = 0;
2786         else
2787                 /* Strip -osc or -mdc suffix from svname */
2788                 if (server_make_name(rc, mti->mti_stripe_index, mti->mti_fsname,
2789                                      mti->mti_svname))
2790                         GOTO(out, rc = -EINVAL);
2791
2792         mti->mti_flags = rc | LDD_F_PARAM;
2793
2794         down(&fsdb->fsdb_sem);
2795         rc = mgs_write_log_params(obd, fsdb, mti);
2796         up(&fsdb->fsdb_sem);
2797
2798 out:
2799         OBD_FREE_PTR(mti);
2800         RETURN(rc);
2801 }
2802
2803 static int mgs_write_log_pool(struct obd_device *obd, char *logname,
2804                               struct fs_db *fsdb, char *lovname,
2805                               enum lcfg_command_type cmd,
2806                               char *poolname, char *fsname,
2807                               char *ostname, char *comment)
2808 {
2809         struct llog_handle *llh = NULL;
2810         int rc;
2811
2812         rc = record_start_log(obd, &llh, logname);
2813         if (rc)
2814                 return rc;
2815         rc = record_marker(obd, llh, fsdb, CM_START, lovname, comment);
2816         record_base(obd, llh, lovname, 0, cmd, poolname, fsname, ostname, 0);
2817         rc = record_marker(obd, llh, fsdb, CM_END, lovname, comment);
2818         rc = record_end_log(obd, &llh);
2819
2820         return rc;
2821 }
2822
2823 int mgs_pool_cmd(struct obd_device *obd, enum lcfg_command_type cmd,
2824                  char *fsname, char *poolname, char *ostname)
2825 {
2826         struct fs_db *fsdb;
2827         char mdt_index[16];
2828         char *lovname;
2829         char *logname;
2830         char *label = NULL, *canceled_label = NULL;
2831         int label_sz;
2832         struct mgs_target_info *mti = NULL;
2833         int rc, i;
2834         ENTRY;
2835
2836         rc = mgs_find_or_make_fsdb(obd, fsname, &fsdb);
2837         if (rc) {
2838                 CERROR("Can't get db for %s\n", fsname);
2839                 RETURN(rc);
2840         }
2841         if (fsdb->fsdb_flags & FSDB_LOG_EMPTY) {
2842                 CERROR("%s is not defined\n", fsname);
2843                 mgs_free_fsdb(obd, fsdb);
2844                 RETURN(-EINVAL);
2845         }
2846
2847         label_sz = 10 + strlen(fsname) + strlen(poolname);
2848
2849         /* check if ostname match fsname */
2850         if (ostname != NULL) {
2851                 char *ptr;
2852
2853                 ptr = strrchr(ostname, '-');
2854                 if ((ptr == NULL) ||
2855                     (strncmp(fsname, ostname, ptr-ostname) != 0))
2856                         RETURN(-EINVAL);
2857                 label_sz += strlen(ostname);
2858         }
2859
2860         OBD_ALLOC(label, label_sz);
2861         if (label == NULL)
2862                 GOTO(out, rc = -ENOMEM);
2863
2864         switch(cmd) {
2865         case LCFG_POOL_NEW: {
2866                 sprintf(label,
2867                         "new %s.%s", fsname, poolname);
2868                 break;
2869         }
2870         case LCFG_POOL_ADD: {
2871                 sprintf(label,
2872                         "add %s.%s.%s", fsname, poolname, ostname);
2873                 break;
2874         }
2875         case LCFG_POOL_REM: {
2876                 OBD_ALLOC(canceled_label, label_sz);
2877                 if (canceled_label == NULL)
2878                          GOTO(out, rc = -ENOMEM);
2879                 sprintf(label,
2880                         "rem %s.%s.%s", fsname, poolname, ostname);
2881                 sprintf(canceled_label,
2882                         "add %s.%s.%s", fsname, poolname, ostname);
2883                 break;
2884         }
2885         case LCFG_POOL_DEL: {
2886                 OBD_ALLOC(canceled_label, label_sz);
2887                 if (canceled_label == NULL)
2888                          GOTO(out, rc = -ENOMEM);
2889                 sprintf(label,
2890                         "del %s.%s", fsname, poolname);
2891                 sprintf(canceled_label,
2892                         "new %s.%s", fsname, poolname);
2893                 break;
2894         }
2895         default: {
2896                 break;
2897         }
2898         }
2899
2900         down(&fsdb->fsdb_sem);
2901
2902         if (canceled_label != NULL) {
2903                 OBD_ALLOC_PTR(mti);
2904                 if (mti == NULL)
2905                         GOTO(out, rc = -ENOMEM);
2906         }
2907
2908         /* loop on all potential MDT */
2909         for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2910                  if (test_bit(i,  fsdb->fsdb_mdt_index_map)) {
2911                         sprintf(mdt_index, "-MDT%04x", i);
2912                         name_create(&logname, fsname, mdt_index);
2913                         name_create(&lovname, logname, "-mdtlov");
2914
2915                         if (canceled_label != NULL) {
2916                                 strcpy(mti->mti_svname, "lov pool");
2917                                 mgs_modify(obd, fsdb, mti, logname, lovname,
2918                                            canceled_label, CM_SKIP);
2919                         }
2920
2921                         mgs_write_log_pool(obd, logname, fsdb, lovname,
2922                                            cmd, fsname, poolname, ostname,
2923                                            label);
2924                         name_destroy(&logname);
2925                         name_destroy(&lovname);
2926                 }
2927         }
2928
2929         name_create(&logname, fsname, "-client");
2930         if (canceled_label != NULL)
2931                 mgs_modify(obd, fsdb, mti, logname, fsdb->fsdb_clilov,
2932                            canceled_label, CM_SKIP);
2933
2934         mgs_write_log_pool(obd, logname, fsdb, fsdb->fsdb_clilov,
2935                            cmd, fsname, poolname, ostname, label);
2936         name_destroy(&logname);
2937
2938         up(&fsdb->fsdb_sem);
2939
2940         EXIT;
2941 out:
2942         if (label != NULL)
2943                 OBD_FREE(label, label_sz);
2944
2945         if (canceled_label != NULL)
2946                 OBD_FREE(canceled_label, label_sz);
2947
2948         if (mti != NULL)
2949                 OBD_FREE_PTR(mti);
2950
2951         return rc;
2952 }
2953
2954 #if 0
2955 /******************** unused *********************/
2956 static int mgs_backup_llog(struct obd_device *obd, char* fsname)
2957 {
2958         struct file *filp, *bak_filp;
2959         struct lvfs_run_ctxt saved;
2960         char *logname, *buf;
2961         loff_t soff = 0 , doff = 0;
2962         int count = 4096, len;
2963         int rc = 0;
2964
2965         OBD_ALLOC(logname, PATH_MAX);
2966         if (logname == NULL)
2967                 return -ENOMEM;
2968
2969         OBD_ALLOC(buf, count);
2970         if (!buf)
2971                 GOTO(out , rc = -ENOMEM);
2972
2973         len = snprintf(logname, PATH_MAX, "%s/%s.bak",
2974                        MOUNT_CONFIGS_DIR, fsname);
2975
2976         if (len >= PATH_MAX - 1) {
2977                 GOTO(out, -ENAMETOOLONG);
2978         }
2979
2980         push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
2981
2982         bak_filp = l_filp_open(logname, O_RDWR|O_CREAT|O_TRUNC, 0660);
2983         if (IS_ERR(bak_filp)) {
2984                 rc = PTR_ERR(bak_filp);
2985                 CERROR("backup logfile open %s: %d\n", logname, rc);
2986                 GOTO(pop, rc);
2987         }
2988         sprintf(logname, "%s/%s", MOUNT_CONFIGS_DIR, fsname);
2989         filp = l_filp_open(logname, O_RDONLY, 0);
2990         if (IS_ERR(filp)) {
2991                 rc = PTR_ERR(filp);
2992                 CERROR("logfile open %s: %d\n", logname, rc);
2993                 GOTO(close1f, rc);
2994         }
2995
2996         while ((rc = lustre_fread(filp, buf, count, &soff)) > 0) {
2997                 rc = lustre_fwrite(bak_filp, buf, count, &doff);
2998                 break;
2999         }
3000
3001         filp_close(filp, 0);
3002 close1f:
3003         filp_close(bak_filp, 0);
3004 pop:
3005         pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
3006 out:
3007         if (buf)
3008                 OBD_FREE(buf, count);
3009         OBD_FREE(logname, PATH_MAX);
3010         return rc;
3011 }
3012
3013 #endif