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