Whamcloud - gitweb
b=24128 mgs_write_log_ost() should not update client's log
[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 = ll_dentry_open(dentry, mnt, O_RDONLY, current_cred());
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 static int mgs_write_log_osc_to_lov(struct obd_device *obd, struct fs_db *fsdb,
1077                                     struct mgs_target_info *mti,
1078                                     char *logname, char *suffix, char *lovname,
1079                                     enum lustre_sec_part sec_part, int flags);
1080 static void name_create_mdt_and_lov(char **logname, char **lovname,
1081                                     struct fs_db *fsdb, int i);
1082
1083 static int mgs_steal_llog_handler(struct llog_handle *llh,
1084                                   struct llog_rec_hdr *rec,
1085                                   void *data)
1086 {
1087         struct obd_device * obd;
1088         struct mgs_target_info *mti, *tmti;
1089         struct fs_db *fsdb;
1090         int cfg_len = rec->lrh_len;
1091         char *cfg_buf = (char*) (rec + 1);
1092         struct lustre_cfg *lcfg;
1093         int rc = 0;
1094         struct llog_handle *mdt_llh = NULL;
1095         static int got_an_osc_or_mdc = 0;
1096         /* 0: not found any osc/mdc;
1097            1: found osc;
1098            2: found mdc;
1099         */
1100         static int last_step = -1;
1101
1102         ENTRY;
1103
1104         mti = ((struct temp_comp*)data)->comp_mti;
1105         tmti = ((struct temp_comp*)data)->comp_tmti;
1106         fsdb = ((struct temp_comp*)data)->comp_fsdb;
1107         obd = ((struct temp_comp*)data)->comp_obd;
1108
1109         if (rec->lrh_type != OBD_CFG_REC) {
1110                 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
1111                 RETURN(-EINVAL);
1112         }
1113
1114         rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
1115         if (rc) {
1116                 CERROR("Insane cfg\n");
1117                 RETURN(rc);
1118         }
1119
1120         lcfg = (struct lustre_cfg *)cfg_buf;
1121
1122         if (lcfg->lcfg_command == LCFG_MARKER) {
1123                 struct cfg_marker *marker;
1124                 marker = lustre_cfg_buf(lcfg, 1);
1125                 if (!strncmp(marker->cm_comment,"add osc",7) &&
1126                     (marker->cm_flags & CM_START)){
1127                         got_an_osc_or_mdc = 1;
1128                         rc = record_start_log(obd, &mdt_llh, mti->mti_svname);
1129                         rc = record_marker(obd, mdt_llh, fsdb, CM_START,
1130                                            mti->mti_svname,"add osc(copied)");
1131                         rc = record_end_log(obd, &mdt_llh);
1132                         last_step = marker->cm_step;
1133                         RETURN(rc);
1134                 }
1135                 if (!strncmp(marker->cm_comment,"add osc",7) &&
1136                     (marker->cm_flags & CM_END)){
1137                         LASSERT(last_step == marker->cm_step);
1138                         last_step = -1;
1139                         got_an_osc_or_mdc = 0;
1140                         rc = record_start_log(obd, &mdt_llh, mti->mti_svname);
1141                         rc = record_marker(obd, mdt_llh, fsdb, CM_END,
1142                                            mti->mti_svname,"add osc(copied)");
1143                         rc = record_end_log(obd, &mdt_llh);
1144                         RETURN(rc);
1145                 }
1146                 if (!strncmp(marker->cm_comment,"add mdc",7) &&
1147                     (marker->cm_flags & CM_START)){
1148                         got_an_osc_or_mdc = 2;
1149                         last_step = marker->cm_step;
1150                         memcpy(tmti->mti_svname, marker->cm_tgtname,
1151                                strlen(marker->cm_tgtname));
1152
1153                         RETURN(rc);
1154                 }
1155                 if (!strncmp(marker->cm_comment,"add mdc",7) &&
1156                     (marker->cm_flags & CM_END)){
1157                         LASSERT(last_step == marker->cm_step);
1158                         last_step = -1;
1159                         got_an_osc_or_mdc = 0;
1160                         RETURN(rc);
1161                 }
1162         }
1163
1164         if (got_an_osc_or_mdc == 0 || last_step < 0)
1165                 RETURN(rc);
1166
1167         if (lcfg->lcfg_command == LCFG_ADD_UUID) {
1168                 uint64_t nodenid;
1169                 nodenid = lcfg->lcfg_nid;
1170
1171                 tmti->mti_nids[tmti->mti_nid_count] = nodenid;
1172                 tmti->mti_nid_count++;
1173
1174                 RETURN(rc);
1175         }
1176
1177         if (lcfg->lcfg_command == LCFG_SETUP) {
1178                 char *target;
1179
1180                 target = lustre_cfg_string(lcfg, 1);
1181                 memcpy(tmti->mti_uuid, target, strlen(target));
1182                 RETURN(rc);
1183         }
1184
1185         /* ignore client side sptlrpc_conf_log */
1186         if (lcfg->lcfg_command == LCFG_SPTLRPC_CONF)
1187                 RETURN(rc);
1188
1189         if (lcfg->lcfg_command == LCFG_ADD_MDC) {
1190                 int index;
1191
1192                 if (sscanf(lustre_cfg_buf(lcfg, 2), "%d", &index) != 1)
1193                         RETURN (-EINVAL);
1194
1195                 memcpy(tmti->mti_fsname, mti->mti_fsname,
1196                        strlen(mti->mti_fsname));
1197                 tmti->mti_stripe_index = index;
1198
1199                 mgs_write_log_mdc_to_mdt(obd, fsdb, tmti, mti->mti_svname);
1200                 memset(tmti, 0, sizeof(*tmti));
1201                 RETURN(rc);
1202         }
1203
1204         if (lcfg->lcfg_command == LCFG_LOV_ADD_OBD) {
1205                 char mdt_index[9];
1206                 char *logname, *lovname;
1207
1208                 name_create_mdt_and_lov(&logname, &lovname, fsdb, mti->mti_stripe_index);
1209                 sprintf(mdt_index, "-MDT%04x", mti->mti_stripe_index);
1210
1211                 mgs_write_log_osc_to_lov(obd, fsdb, tmti, logname,
1212                                          mdt_index, lovname,
1213                                          LUSTRE_SP_MDT, 0);
1214                 name_destroy(&logname);
1215                 name_destroy(&lovname);
1216                 RETURN(rc);
1217         }
1218         RETURN(rc);
1219 }
1220
1221 /* fsdb->fsdb_sem is already held  in mgs_write_log_target*/
1222 /* stealed from mgs_get_fsdb_from_llog*/
1223 static int mgs_steal_llog_for_mdt_from_client(struct obd_device *obd,
1224                                               char *client_name,
1225                                               struct temp_comp* comp)
1226 {
1227         struct llog_handle *loghandle;
1228         struct lvfs_run_ctxt saved;
1229         struct mgs_target_info *tmti;
1230         struct llog_ctxt *ctxt;
1231         int rc, rc2;
1232         ENTRY;
1233
1234         ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
1235         LASSERT(ctxt != NULL);
1236
1237         OBD_ALLOC_PTR(tmti);
1238         if (tmti == NULL)
1239                 RETURN(-ENOMEM);
1240
1241         comp->comp_tmti = tmti;
1242         comp->comp_obd = obd;
1243
1244         push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
1245
1246         rc = llog_create(ctxt, &loghandle, NULL, client_name);
1247         if (rc)
1248                 GOTO(out_pop, rc);
1249
1250         rc = llog_init_handle(loghandle, LLOG_F_IS_PLAIN, NULL);
1251         if (rc)
1252                 GOTO(out_close, rc);
1253
1254         rc = llog_process(loghandle, mgs_steal_llog_handler, (void *)comp, NULL);
1255         CDEBUG(D_MGS, "steal llog re = %d\n", rc);
1256 out_close:
1257         rc2 = llog_close(loghandle);
1258         if (!rc)
1259                 rc = rc2;
1260 out_pop:
1261         pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
1262         OBD_FREE_PTR(tmti);
1263         llog_ctxt_put(ctxt);
1264         RETURN(rc);
1265 }
1266
1267 /* lmv is the second thing for client logs */
1268 /* copied from mgs_write_log_lov. Please refer to that.  */
1269 static int mgs_write_log_lmv(struct obd_device *obd, struct fs_db *fsdb,
1270                              struct mgs_target_info *mti,
1271                              char *logname, char *lmvname)
1272 {
1273         struct llog_handle *llh = NULL;
1274         struct lmv_desc *lmvdesc;
1275         char *uuid;
1276         int rc = 0;
1277         ENTRY;
1278
1279         CDEBUG(D_MGS, "Writing lmv(%s) log for %s\n", lmvname,logname);
1280
1281         OBD_ALLOC_PTR(lmvdesc);
1282         if (lmvdesc == NULL)
1283                 RETURN(-ENOMEM);
1284         lmvdesc->ld_active_tgt_count = 0;
1285         lmvdesc->ld_tgt_count = 0;
1286         sprintf((char*)lmvdesc->ld_uuid.uuid, "%s_UUID", lmvname);
1287         uuid = (char *)lmvdesc->ld_uuid.uuid;
1288
1289         rc = record_start_log(obd, &llh, logname);
1290         rc = record_marker(obd, llh, fsdb, CM_START, lmvname, "lmv setup");
1291         rc = record_attach(obd, llh, lmvname, "lmv", uuid);
1292         rc = record_lmv_setup(obd, llh, lmvname, lmvdesc);
1293         rc = record_marker(obd, llh, fsdb, CM_END, lmvname, "lmv setup");
1294         rc = record_end_log(obd, &llh);
1295
1296         OBD_FREE_PTR(lmvdesc);
1297         RETURN(rc);
1298 }
1299
1300 /* lov is the first thing in the mdt and client logs */
1301 static int mgs_write_log_lov(struct obd_device *obd, struct fs_db *fsdb,
1302                              struct mgs_target_info *mti,
1303                              char *logname, char *lovname)
1304 {
1305         struct llog_handle *llh = NULL;
1306         struct lov_desc *lovdesc;
1307         char *uuid;
1308         int rc = 0;
1309         ENTRY;
1310
1311         CDEBUG(D_MGS, "Writing lov(%s) log for %s\n", lovname, logname);
1312
1313         /*
1314         #01 L attach   0:lov_mdsA  1:lov  2:71ccb_lov_mdsA_19f961a9e1
1315         #02 L lov_setup 0:lov_mdsA 1:(struct lov_desc)
1316               uuid=lov1_UUID, stripe count=1, size=1048576, offset=0, pattern=0
1317         */
1318
1319         /* FIXME just make lov_setup accept empty desc (put uuid in buf 2) */
1320         OBD_ALLOC_PTR(lovdesc);
1321         if (lovdesc == NULL)
1322                 RETURN(-ENOMEM);
1323         lovdesc->ld_magic = LOV_DESC_MAGIC;
1324         lovdesc->ld_tgt_count = 0;
1325         /* Defaults.  Can be changed later by lcfg config_param */
1326         lovdesc->ld_default_stripe_count = 1;
1327         lovdesc->ld_pattern = LOV_PATTERN_RAID0;
1328         lovdesc->ld_default_stripe_size = 1024 * 1024;
1329         lovdesc->ld_default_stripe_offset = -1;
1330         lovdesc->ld_qos_maxage = QOS_DEFAULT_MAXAGE;
1331         sprintf((char*)lovdesc->ld_uuid.uuid, "%s_UUID", lovname);
1332         /* can these be the same? */
1333         uuid = (char *)lovdesc->ld_uuid.uuid;
1334
1335         /* This should always be the first entry in a log.
1336         rc = mgs_clear_log(obd, logname); */
1337         rc = record_start_log(obd, &llh, logname);
1338         if (rc)
1339                 GOTO(out, rc);
1340         /* FIXME these should be a single journal transaction */
1341         rc = record_marker(obd, llh, fsdb, CM_START, lovname, "lov setup");
1342         rc = record_attach(obd, llh, lovname, "lov", uuid);
1343         rc = record_lov_setup(obd, llh, lovname, lovdesc);
1344         rc = record_marker(obd, llh, fsdb, CM_END, lovname, "lov setup");
1345         rc = record_end_log(obd, &llh);
1346
1347         EXIT;
1348 out:
1349         OBD_FREE_PTR(lovdesc);
1350         return rc;
1351 }
1352
1353 /* add failnids to open log */
1354 static int mgs_write_log_failnids(struct obd_device *obd,
1355                                   struct mgs_target_info *mti,
1356                                   struct llog_handle *llh,
1357                                   char *cliname)
1358 {
1359         char *failnodeuuid = NULL;
1360         char *ptr = mti->mti_params;
1361         lnet_nid_t nid;
1362         int rc = 0;
1363
1364         /*
1365         #03 L add_uuid  nid=uml1@tcp(0x20000c0a80201) nal=90 0:  1:uml1_UUID
1366         #04 L add_uuid  nid=1@elan(0x1000000000001)   nal=90 0:  1:uml1_UUID
1367         #05 L setup    0:OSC_uml1_ost1_mdsA  1:ost1_UUID  2:uml1_UUID
1368         #06 L add_uuid  nid=uml2@tcp(0x20000c0a80202) nal=90 0:  1:uml2_UUID
1369         #0x L add_uuid  nid=2@elan(0x1000000000002)   nal=90 0:  1:uml2_UUID
1370         #07 L add_conn 0:OSC_uml1_ost1_mdsA  1:uml2_UUID
1371         */
1372
1373         /* Pull failnid info out of params string */
1374         while (class_find_param(ptr, PARAM_FAILNODE, &ptr) == 0) {
1375                 while (class_parse_nid(ptr, &nid, &ptr) == 0) {
1376                         if (failnodeuuid == NULL) {
1377                                 /* We don't know the failover node name,
1378                                    so just use the first nid as the uuid */
1379                                 rc = name_create(&failnodeuuid,
1380                                                  libcfs_nid2str(nid), "");
1381                                 if (rc)
1382                                         return rc;
1383                         }
1384                         CDEBUG(D_MGS, "add nid %s for failover uuid %s, "
1385                                "client %s\n", libcfs_nid2str(nid),
1386                                failnodeuuid, cliname);
1387                         rc = record_add_uuid(obd, llh, nid, failnodeuuid);
1388                 }
1389                 if (failnodeuuid) {
1390                         rc = record_add_conn(obd, llh, cliname, failnodeuuid);
1391                         name_destroy(&failnodeuuid);
1392                         failnodeuuid = NULL;
1393                 }
1394         }
1395
1396         return rc;
1397 }
1398
1399 static int mgs_write_log_mdc_to_lmv(struct obd_device *obd, struct fs_db *fsdb,
1400                                     struct mgs_target_info *mti,
1401                                     char *logname, char *lmvname)
1402 {
1403         struct llog_handle *llh = NULL;
1404         char *mdcname, *nodeuuid, *mdcuuid, *lmvuuid;
1405         char index[6];
1406         int i, rc;
1407         ENTRY;
1408
1409         if (mgs_log_is_empty(obd, logname)) {
1410                 CERROR("log is empty! Logical error\n");
1411                 RETURN(-EINVAL);
1412         }
1413
1414         CDEBUG(D_MGS, "adding mdc for %s to log %s:lmv(%s)\n",
1415                mti->mti_svname, logname, lmvname);
1416
1417         name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
1418         name_create(&mdcname, mti->mti_svname, "-mdc");
1419         name_create(&mdcuuid, mdcname, "_UUID");
1420         name_create(&lmvuuid, lmvname, "_UUID");
1421
1422         rc = record_start_log(obd, &llh, logname);
1423         rc = record_marker(obd, llh, fsdb, CM_START, mti->mti_svname,
1424                            "add mdc");
1425
1426         for (i = 0; i < mti->mti_nid_count; i++) {
1427                 CDEBUG(D_MGS, "add nid %s for mdt\n",
1428                        libcfs_nid2str(mti->mti_nids[i]));
1429
1430                 rc = record_add_uuid(obd, llh, mti->mti_nids[i], nodeuuid);
1431         }
1432
1433         rc = record_attach(obd, llh, mdcname, LUSTRE_MDC_NAME, lmvuuid);
1434         rc = record_setup(obd, llh, mdcname, mti->mti_uuid, nodeuuid, 0, 0);
1435         rc = mgs_write_log_failnids(obd, mti, llh, mdcname);
1436         snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
1437         rc = record_mdc_add(obd, llh, lmvname, mdcuuid, mti->mti_uuid,
1438                             index, "1");
1439         rc = record_marker(obd, llh, fsdb, CM_END, mti->mti_svname,
1440                            "add mdc");
1441         rc = record_end_log(obd, &llh);
1442
1443         name_destroy(&lmvuuid);
1444         name_destroy(&mdcuuid);
1445         name_destroy(&mdcname);
1446         name_destroy(&nodeuuid);
1447         RETURN(rc);
1448 }
1449
1450 /* add new mdc to already existent MDS */
1451 static int mgs_write_log_mdc_to_mdt(struct obd_device *obd, struct fs_db *fsdb,
1452                                     struct mgs_target_info *mti, char *logname)
1453 {
1454         struct llog_handle *llh = NULL;
1455         char *nodeuuid, *mdcname, *mdcuuid, *mdtuuid;
1456         int idx = mti->mti_stripe_index;
1457         char index[9];
1458         int i, rc;
1459
1460         ENTRY;
1461         if (mgs_log_is_empty(obd, logname)) {
1462                 CERROR("log is empty! Logical error\n");
1463                 RETURN (-EINVAL);
1464         }
1465
1466         CDEBUG(D_MGS, "adding mdc index %d to %s\n", idx, logname);
1467
1468         name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
1469         snprintf(index, sizeof(index), "-mdc%04x", idx);
1470         name_create(&mdcname, logname, index);
1471         name_create(&mdcuuid, mdcname, "_UUID");
1472         name_create(&mdtuuid, logname, "_UUID");
1473
1474         rc = record_start_log(obd, &llh, logname);
1475         rc = record_marker(obd, llh, fsdb, CM_START, mti->mti_svname, "add mdc");
1476         for (i = 0; i < mti->mti_nid_count; i++) {
1477                 CDEBUG(D_MGS, "add nid %s for mdt\n",
1478                        libcfs_nid2str(mti->mti_nids[i]));
1479                 rc = record_add_uuid(obd, llh, mti->mti_nids[i], nodeuuid);
1480         }
1481         rc = record_attach(obd, llh, mdcname, LUSTRE_MDC_NAME, mdcuuid);
1482         rc = record_setup(obd, llh, mdcname, mti->mti_uuid, nodeuuid, 0, 0);
1483         rc = mgs_write_log_failnids(obd, mti, llh, mdcname);
1484         snprintf(index, sizeof(index), "%d", idx);
1485
1486         rc = record_mdc_add(obd, llh, logname, mdcuuid, mti->mti_uuid,
1487                             index, "1");
1488         rc = record_marker(obd, llh, fsdb, CM_END, mti->mti_svname, "add mdc");
1489         rc = record_end_log(obd, &llh);
1490
1491         name_destroy(&mdcuuid);
1492         name_destroy(&mdcname);
1493         name_destroy(&nodeuuid);
1494         name_destroy(&mdtuuid);
1495         RETURN(rc);
1496 }
1497
1498 static int mgs_write_log_mdt0(struct obd_device *obd, struct fs_db *fsdb,
1499                               struct mgs_target_info *mti)
1500 {
1501         char *log = mti->mti_svname;
1502         struct llog_handle *llh = NULL;
1503         char *uuid, *lovname;
1504         char mdt_index[6];
1505         char *ptr = mti->mti_params;
1506         int rc = 0, failout = 0;
1507         ENTRY;
1508
1509         OBD_ALLOC(uuid, sizeof(struct obd_uuid));
1510         if (uuid == NULL)
1511                 RETURN(-ENOMEM);
1512
1513         if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
1514                 failout = (strncmp(ptr, "failout", 7) == 0);
1515
1516         name_create(&lovname, log, "-mdtlov");
1517         if (mgs_log_is_empty(obd, log))
1518                 rc = mgs_write_log_lov(obd, fsdb, mti, log, lovname);
1519
1520         sprintf(uuid, "%s_UUID", log);
1521         sprintf(mdt_index, "%d", mti->mti_stripe_index);
1522
1523         /* add MDT itself */
1524         rc = record_start_log(obd, &llh, log);
1525         if (rc)
1526                 GOTO(out, rc);
1527
1528         /* FIXME this whole fn should be a single journal transaction */
1529         rc = record_marker(obd, llh, fsdb, CM_START, log, "add mdt");
1530         rc = record_attach(obd, llh, log, LUSTRE_MDT_NAME, uuid);
1531         rc = record_mount_opt(obd, llh, log, lovname, NULL);
1532         rc = record_setup(obd, llh, log, uuid, mdt_index, lovname,
1533                         failout ? "n" : "f");
1534         rc = record_marker(obd, llh, fsdb, CM_END, log, "add mdt");
1535         rc = record_end_log(obd, &llh);
1536 out:
1537         name_destroy(&lovname);
1538         OBD_FREE(uuid, sizeof(struct obd_uuid));
1539         RETURN(rc);
1540 }
1541
1542 static inline void name_create_mdt(char **logname, char *fsname, int i)
1543 {
1544         char mdt_index[9];
1545
1546         sprintf(mdt_index, "-MDT%04x", i);
1547         name_create(logname, fsname, mdt_index);
1548 }
1549
1550 static void name_create_mdt_and_lov(char **logname, char **lovname,
1551                                     struct fs_db *fsdb, int i)
1552 {
1553         name_create_mdt(logname, fsdb->fsdb_name, i);
1554         /* COMPAT_180 */
1555         if (i == 0 && cfs_test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
1556                 name_create(lovname, fsdb->fsdb_name, "-mdtlov");
1557         else
1558                 name_create(lovname, *logname, "-mdtlov");
1559 }
1560
1561 static inline void name_create_mdt_osc(char **oscname, char *ostname,
1562                                        struct fs_db *fsdb, int i)
1563 {
1564         char suffix[16];
1565
1566         if (i == 0 && cfs_test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
1567                 sprintf(suffix, "-osc");
1568         else
1569                 sprintf(suffix, "-osc-MDT%04x", i);
1570         name_create(oscname, ostname, suffix);
1571 }
1572
1573 /* envelope method for all layers log */
1574 static int mgs_write_log_mdt(struct obd_device *obd, struct fs_db *fsdb,
1575                               struct mgs_target_info *mti)
1576 {
1577         struct llog_handle *llh = NULL;
1578         char *cliname;
1579         struct temp_comp comp = { 0 };
1580         int rc, i = 0;
1581         ENTRY;
1582
1583         CDEBUG(D_MGS, "writing new mdt %s\n", mti->mti_svname);
1584
1585 #if 0
1586         /* COMPAT_146 */
1587         if (mti->mti_flags & LDD_F_UPGRADE14) {
1588                 /* We're starting with an old uuid.  Assume old name for lov
1589                    as well since the lov entry already exists in the log. */
1590                 CDEBUG(D_MGS, "old mds uuid %s\n", mti->mti_uuid);
1591                 if (strncmp(mti->mti_uuid, fsdb->fsdb_mdtlov + 4,
1592                             strlen(fsdb->fsdb_mdtlov) - 4) != 0) {
1593                         CERROR("old mds uuid %s doesn't match log %s (%s)\n",
1594                                mti->mti_uuid, fsdb->fsdb_mdtlov,
1595                                fsdb->fsdb_mdtlov + 4);
1596                         RETURN(-EINVAL);
1597                 }
1598         }
1599         /* end COMPAT_146 */
1600 #endif
1601         if (mti->mti_uuid[0] == '\0') {
1602                 /* Make up our own uuid */
1603                 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
1604                          "%s_UUID", mti->mti_svname);
1605         }
1606
1607         /* add mdt */
1608         rc = mgs_write_log_mdt0(obd, fsdb, mti);
1609
1610         /* Append the mdt info to the client log */
1611         name_create(&cliname, mti->mti_fsname, "-client");
1612
1613         if (mgs_log_is_empty(obd, cliname)) {
1614                 /* Start client log */
1615                 rc = mgs_write_log_lov(obd, fsdb, mti, cliname,
1616                                        fsdb->fsdb_clilov);
1617                 rc = mgs_write_log_lmv(obd, fsdb, mti, cliname,
1618                                        fsdb->fsdb_clilmv);
1619         }
1620
1621         /*
1622         #09 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0:  1:uml1_UUID
1623         #10 L attach   0:MDC_uml1_mdsA_MNT_client  1:mdc  2:1d834_MNT_client_03f
1624         #11 L setup    0:MDC_uml1_mdsA_MNT_client  1:mdsA_UUID  2:uml1_UUID
1625         #12 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0:  1:uml2_UUID
1626         #13 L add_conn 0:MDC_uml1_mdsA_MNT_client  1:uml2_UUID
1627         #14 L mount_option 0:  1:client  2:lov1  3:MDC_uml1_mdsA_MNT_client
1628         */
1629
1630 #if 0
1631         /* COMPAT_146 */
1632         if (mti->mti_flags & LDD_F_UPGRADE14) {
1633                 rc = record_start_log(obd, &llh, cliname);
1634                 if (rc)
1635                         GOTO(out, rc);
1636
1637                 rc = record_marker(obd, llh, fsdb, CM_START,
1638                                    mti->mti_svname,"add mdc");
1639
1640                 /* Old client log already has MDC entry, but needs mount opt
1641                    for new client name (lustre-client) */
1642                 /* FIXME Old MDT log already has an old mount opt
1643                    which we should remove (currently handled by
1644                    class_del_profiles()) */
1645                 rc = record_mount_opt(obd, llh, cliname, fsdb->fsdb_clilov,
1646                                       fsdb->fsdb_mdc);
1647                 /* end COMPAT_146 */
1648
1649                 rc = record_marker(obd, llh, fsdb, CM_END,
1650                                    mti->mti_svname, "add mdc");
1651         } else
1652 #endif
1653         {
1654                 /* copy client info about lov/lmv */
1655                 comp.comp_mti = mti;
1656                 comp.comp_fsdb = fsdb;
1657
1658                 rc = mgs_steal_llog_for_mdt_from_client(obd, cliname,
1659                                                         &comp);
1660
1661                 rc = mgs_write_log_mdc_to_lmv(obd, fsdb, mti, cliname,
1662                                               fsdb->fsdb_clilmv);
1663                 /* add mountopts */
1664                 rc = record_start_log(obd, &llh, cliname);
1665                 if (rc)
1666                         GOTO(out, rc);
1667
1668                 rc = record_marker(obd, llh, fsdb, CM_START, cliname,
1669                                    "mount opts");
1670                 rc = record_mount_opt(obd, llh, cliname, fsdb->fsdb_clilov,
1671                                       fsdb->fsdb_clilmv);
1672                 rc = record_marker(obd, llh, fsdb, CM_END, cliname,
1673                                    "mount opts");
1674         }
1675
1676         rc = record_end_log(obd, &llh);
1677 out:
1678         name_destroy(&cliname);
1679
1680         // for_all_existing_mdt except current one
1681         for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
1682                 char *mdtname;
1683                 if (i !=  mti->mti_stripe_index &&
1684                     cfs_test_bit(i,  fsdb->fsdb_mdt_index_map)) {
1685                         name_create_mdt(&mdtname, mti->mti_fsname, i);
1686                         rc = mgs_write_log_mdc_to_mdt(obd, fsdb, mti, mdtname);
1687                         name_destroy(&mdtname);
1688                 }
1689         }
1690
1691         RETURN(rc);
1692 }
1693
1694 /* Add the ost info to the client/mdt lov */
1695 static int mgs_write_log_osc_to_lov(struct obd_device *obd, struct fs_db *fsdb,
1696                                     struct mgs_target_info *mti,
1697                                     char *logname, char *suffix, char *lovname,
1698                                     enum lustre_sec_part sec_part, int flags)
1699 {
1700         struct llog_handle *llh = NULL;
1701         char *nodeuuid, *oscname, *oscuuid, *lovuuid, *svname;
1702         char index[6];
1703         int i, rc;
1704
1705         ENTRY;
1706         CDEBUG(D_INFO, "adding osc for %s to log %s\n",
1707                mti->mti_svname, logname);
1708
1709         if (mgs_log_is_empty(obd, logname)) {
1710                 CERROR("log is empty! Logical error\n");
1711                 RETURN (-EINVAL);
1712         }
1713
1714         name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
1715         name_create(&svname, mti->mti_svname, "-osc");
1716         name_create(&oscname, svname, suffix);
1717         name_create(&oscuuid, oscname, "_UUID");
1718         name_create(&lovuuid, lovname, "_UUID");
1719
1720         /*
1721         #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0:  1:uml1_UUID
1722         multihomed (#4)
1723         #04 L add_uuid  nid=1@elan(0x1000000000001)  nal=90 0:  1:uml1_UUID
1724         #04 L attach   0:OSC_uml1_ost1_MNT_client  1:osc  2:89070_lov1_a41dff51a
1725         #05 L setup    0:OSC_uml1_ost1_MNT_client  1:ost1_UUID  2:uml1_UUID
1726         failover (#6,7)
1727         #06 L add_uuid nid=uml2@tcp(0x20000c0a80202) 0:  1:uml2_UUID
1728         #07 L add_conn 0:OSC_uml1_ost1_MNT_client  1:uml2_UUID
1729         #08 L lov_modify_tgts add 0:lov1  1:ost1_UUID  2(index):0  3(gen):1
1730         */
1731
1732         rc = record_start_log(obd, &llh, logname);
1733         if (rc)
1734                 GOTO(out, rc);
1735         /* FIXME these should be a single journal transaction */
1736         rc = record_marker(obd, llh, fsdb, CM_START | flags, mti->mti_svname,
1737                            "add osc");
1738         for (i = 0; i < mti->mti_nid_count; i++) {
1739                 CDEBUG(D_MGS, "add nid %s\n", libcfs_nid2str(mti->mti_nids[i]));
1740                 rc = record_add_uuid(obd, llh, mti->mti_nids[i], nodeuuid);
1741         }
1742         rc = record_attach(obd, llh, oscname, LUSTRE_OSC_NAME, lovuuid);
1743         rc = record_setup(obd, llh, oscname, mti->mti_uuid, nodeuuid, 0, 0);
1744         rc = mgs_write_log_failnids(obd, mti, llh, oscname);
1745         snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
1746         rc = record_lov_add(obd, llh, lovname, mti->mti_uuid, index, "1");
1747         rc = record_marker(obd, llh, fsdb, CM_END | flags, mti->mti_svname,
1748                            "add osc");
1749         rc = record_end_log(obd, &llh);
1750 out:
1751         name_destroy(&lovuuid);
1752         name_destroy(&oscuuid);
1753         name_destroy(&oscname);
1754         name_destroy(&svname);
1755         name_destroy(&nodeuuid);
1756         RETURN(rc);
1757 }
1758
1759 static int mgs_write_log_ost(struct obd_device *obd, struct fs_db *fsdb,
1760                              struct mgs_target_info *mti)
1761 {
1762         struct llog_handle *llh = NULL;
1763         char *logname, *lovname;
1764         char *ptr = mti->mti_params;
1765         int rc, flags = 0, failout = 0, i;
1766         ENTRY;
1767
1768         CDEBUG(D_MGS, "writing new ost %s\n", mti->mti_svname);
1769
1770         /* The ost startup log */
1771
1772         /* If the ost log already exists, that means that someone reformatted
1773            the ost and it called target_add again. */
1774         if (!mgs_log_is_empty(obd, mti->mti_svname)) {
1775                 LCONSOLE_ERROR_MSG(0x141, "The config log for %s already "
1776                                    "exists, yet the server claims it never "
1777                                    "registered. It may have been reformatted, "
1778                                    "or the index changed. writeconf the MDT to "
1779                                    "regenerate all logs.\n", mti->mti_svname);
1780                 RETURN(-EALREADY);
1781         }
1782
1783         /*
1784         attach obdfilter ost1 ost1_UUID
1785         setup /dev/loop2 ldiskfs f|n errors=remount-ro,user_xattr
1786         */
1787         if (class_find_param(ptr, PARAM_FAILMODE, &ptr) == 0)
1788                 failout = (strncmp(ptr, "failout", 7) == 0);
1789         rc = record_start_log(obd, &llh, mti->mti_svname);
1790         if (rc)
1791                 RETURN(rc);
1792         /* FIXME these should be a single journal transaction */
1793         rc = record_marker(obd, llh, fsdb, CM_START, mti->mti_svname,"add ost");
1794         if (*mti->mti_uuid == '\0')
1795                 snprintf(mti->mti_uuid, sizeof(mti->mti_uuid),
1796                          "%s_UUID", mti->mti_svname);
1797         rc = record_attach(obd, llh, mti->mti_svname,
1798                            "obdfilter"/*LUSTRE_OST_NAME*/, mti->mti_uuid);
1799         rc = record_setup(obd, llh, mti->mti_svname,
1800                           "dev"/*ignored*/, "type"/*ignored*/,
1801                           failout ? "n" : "f", 0/*options*/);
1802         rc = record_marker(obd, llh, fsdb, CM_END, mti->mti_svname, "add ost");
1803         rc = record_end_log(obd, &llh);
1804
1805         /* We also have to update the other logs where this osc is part of
1806            the lov */
1807
1808         if (cfs_test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
1809                 /* If we're upgrading, the old mdt log already has our
1810                    entry. Let's do a fake one for fun. */
1811                 /* Note that we can't add any new failnids, since we don't
1812                    know the old osc names. */
1813                 flags = CM_SKIP | CM_UPGRADE146;
1814
1815         } else if ((mti->mti_flags & LDD_F_UPDATE) != LDD_F_UPDATE) {
1816                 /* If the update flag isn't set, don't update client/mdt
1817                    logs. */
1818                 flags |= CM_SKIP;
1819                 LCONSOLE_WARN("Client log for %s was not updated; writeconf "
1820                               "the MDT first to regenerate it.\n",
1821                               mti->mti_svname);
1822         }
1823
1824         /* Add ost to all MDT lov defs */
1825         for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
1826                 if (cfs_test_bit(i, fsdb->fsdb_mdt_index_map)) {
1827                         char mdt_index[9];
1828
1829                         name_create_mdt_and_lov(&logname, &lovname, fsdb, i);
1830                         sprintf(mdt_index, "-MDT%04x", i);
1831                         mgs_write_log_osc_to_lov(obd, fsdb, mti, logname,
1832                                                  mdt_index, lovname,
1833                                                  LUSTRE_SP_MDT, flags);
1834                         name_destroy(&logname);
1835                         name_destroy(&lovname);
1836                 }
1837         }
1838
1839         /* Append ost info to the client log */
1840         name_create(&logname, mti->mti_fsname, "-client");
1841         if (mgs_log_is_empty(obd, logname)) {
1842                 /* Start client log */
1843                 rc = mgs_write_log_lov(obd, fsdb, mti, logname,
1844                                        fsdb->fsdb_clilov);
1845                 rc = mgs_write_log_lmv(obd, fsdb, mti, logname,
1846                                        fsdb->fsdb_clilmv);
1847         }
1848         mgs_write_log_osc_to_lov(obd, fsdb, mti, logname, "",
1849                                  fsdb->fsdb_clilov, LUSTRE_SP_CLI, flags);
1850         name_destroy(&logname);
1851         RETURN(rc);
1852 }
1853
1854 static __inline__ int mgs_param_empty(char *ptr)
1855 {
1856         char *tmp;
1857
1858         if ((tmp = strchr(ptr, '=')) && (*(++tmp) == '\0'))
1859                 return 1;
1860         return 0;
1861 }
1862
1863 static int mgs_write_log_failnid_internal(struct obd_device *obd,
1864                                           struct fs_db *fsdb,
1865                                           struct mgs_target_info *mti,
1866                                           char *logname, char *cliname)
1867 {
1868         int rc;
1869         struct llog_handle *llh = NULL;
1870
1871         if (mgs_param_empty(mti->mti_params)) {
1872                 /* Remove _all_ failnids */
1873                 rc = mgs_modify(obd, fsdb, mti, logname,
1874                                 mti->mti_svname, "add failnid", CM_SKIP);
1875                 return rc;
1876         }
1877
1878         /* Otherwise failover nids are additive */
1879         rc = record_start_log(obd, &llh, logname);
1880         if (!rc) {
1881                 /* FIXME this should be a single journal transaction */
1882                 rc = record_marker(obd, llh, fsdb, CM_START,
1883                                    mti->mti_svname, "add failnid");
1884                 rc = mgs_write_log_failnids(obd, mti, llh, cliname);
1885                 rc = record_marker(obd, llh, fsdb, CM_END,
1886                                    mti->mti_svname, "add failnid");
1887                 rc = record_end_log(obd, &llh);
1888         }
1889
1890         return rc;
1891 }
1892
1893
1894 /* Add additional failnids to an existing log.
1895    The mdc/osc must have been added to logs first */
1896 /* tcp nids must be in dotted-quad ascii -
1897    we can't resolve hostnames from the kernel. */
1898 static int mgs_write_log_add_failnid(struct obd_device *obd, struct fs_db *fsdb,
1899                                      struct mgs_target_info *mti)
1900 {
1901         char *logname, *cliname;
1902         int rc;
1903         ENTRY;
1904
1905         /* FIXME we currently can't erase the failnids
1906          * given when a target first registers, since they aren't part of
1907          * an "add uuid" stanza */
1908
1909         /* Verify that we know about this target */
1910         if (mgs_log_is_empty(obd, mti->mti_svname)) {
1911                 LCONSOLE_ERROR_MSG(0x142, "The target %s has not registered "
1912                                    "yet. It must be started before failnids "
1913                                    "can be added.\n", mti->mti_svname);
1914                 RETURN(-ENOENT);
1915         }
1916
1917         /* Create mdc/osc client name (e.g. lustre-OST0001-osc) */
1918         if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
1919                 name_create(&cliname, mti->mti_svname, "-mdc");
1920         } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
1921                 name_create(&cliname, mti->mti_svname, "-osc");
1922         } else {
1923                 RETURN(-EINVAL);
1924         }
1925
1926         /* Add failover nids to the client log */
1927         name_create(&logname, mti->mti_fsname, "-client");
1928         rc = mgs_write_log_failnid_internal(obd, fsdb, mti, logname, cliname);
1929         name_destroy(&logname);
1930         name_destroy(&cliname);
1931
1932         if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
1933                 /* Add OST failover nids to the MDT logs as well */
1934                 int i;
1935
1936                 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
1937                         if (!cfs_test_bit(i, fsdb->fsdb_mdt_index_map))
1938                                 continue;
1939                         name_create_mdt(&logname, mti->mti_fsname, i);
1940                         name_create_mdt_osc(&cliname, mti->mti_svname, fsdb, i);
1941                         rc = mgs_write_log_failnid_internal(obd, fsdb, mti,
1942                                                             logname, cliname);
1943                         name_destroy(&cliname);
1944                         name_destroy(&logname);
1945                 }
1946         }
1947
1948         RETURN(rc);
1949 }
1950
1951 static int mgs_wlp_lcfg(struct obd_device *obd, struct fs_db *fsdb,
1952                         struct mgs_target_info *mti,
1953                         char *logname, struct lustre_cfg_bufs *bufs,
1954                         char *tgtname, char *ptr)
1955 {
1956         char comment[MTI_NAME_MAXLEN];
1957         char *tmp;
1958         struct lustre_cfg *lcfg;
1959         int rc, del;
1960
1961         /* Erase any old settings of this same parameter */
1962         memcpy(comment, ptr, MTI_NAME_MAXLEN);
1963         comment[MTI_NAME_MAXLEN - 1] = 0;
1964         /* But don't try to match the value. */
1965         if ((tmp = strchr(comment, '=')))
1966             *tmp = 0;
1967         /* FIXME we should skip settings that are the same as old values */
1968         rc = mgs_modify(obd, fsdb, mti, logname, tgtname, comment, CM_SKIP);
1969         del = mgs_param_empty(ptr);
1970
1971         LCONSOLE_INFO("%sing parameter %s.%s in log %s\n", del ? "Disabl" : rc ?
1972                       "Sett" : "Modify", tgtname, comment, logname);
1973         if (del)
1974                 return rc;
1975
1976         lustre_cfg_bufs_reset(bufs, tgtname);
1977         lustre_cfg_bufs_set_string(bufs, 1, ptr);
1978         lcfg = lustre_cfg_new(LCFG_PARAM, bufs);
1979         if (!lcfg)
1980                 return -ENOMEM;
1981         rc = mgs_write_log_direct(obd, fsdb, logname, lcfg, tgtname, comment);
1982         lustre_cfg_free(lcfg);
1983         return rc;
1984 }
1985
1986 /* write global variable settings into log */
1987 static int mgs_write_log_sys(struct obd_device *obd, struct fs_db *fsdb,
1988                              struct mgs_target_info *mti, char *sys, char *ptr)
1989 {
1990         struct lustre_cfg_bufs bufs;
1991         struct lustre_cfg *lcfg;
1992         char *tmp;
1993         char sep;
1994         int cmd, val;
1995         int rc;
1996
1997         if (class_match_param(ptr, PARAM_TIMEOUT, &tmp) == 0)
1998                 cmd = LCFG_SET_TIMEOUT;
1999         else if (class_match_param(ptr, PARAM_LDLM_TIMEOUT, &tmp) == 0)
2000                 cmd = LCFG_SET_LDLM_TIMEOUT;
2001         /* Check for known params here so we can return error to lctl */
2002         else if ((class_match_param(ptr, PARAM_AT_MIN, &tmp) == 0)
2003                  || (class_match_param(ptr, PARAM_AT_MAX, &tmp) == 0)
2004                  || (class_match_param(ptr, PARAM_AT_EXTRA, &tmp) == 0)
2005                  || (class_match_param(ptr, PARAM_AT_EARLY_MARGIN, &tmp) == 0)
2006                  || (class_match_param(ptr, PARAM_AT_HISTORY, &tmp) == 0))
2007                 cmd = LCFG_PARAM;
2008         else
2009                 return -EINVAL;
2010
2011         /* separate the value */
2012         val = simple_strtoul(tmp, NULL, 0);
2013         if (*tmp == '\0')
2014                 CDEBUG(D_MGS, "global '%s' removed\n", sys);
2015         else
2016                 CDEBUG(D_MGS, "global '%s' val=%d\n", sys, val);
2017
2018         lustre_cfg_bufs_reset(&bufs, NULL);
2019         lustre_cfg_bufs_set_string(&bufs, 1, sys);
2020         lcfg = lustre_cfg_new(cmd, &bufs);
2021         lcfg->lcfg_num = val;
2022         /* truncate the comment to the parameter name */
2023         ptr = tmp - 1;
2024         sep = *ptr;
2025         *ptr = '\0';
2026         /* modify all servers and clients */
2027         rc = mgs_write_log_direct_all(obd, fsdb, mti,
2028                                       *tmp == '\0' ? NULL : lcfg,
2029                                       mti->mti_fsname, sys);
2030         *ptr = sep;
2031         lustre_cfg_free(lcfg);
2032         return rc;
2033 }
2034
2035 static int mgs_srpc_set_param_disk(struct obd_device *obd,
2036                                    struct fs_db *fsdb,
2037                                    struct mgs_target_info *mti,
2038                                    char *param)
2039 {
2040         struct llog_handle     *llh = NULL;
2041         char                   *logname;
2042         char                   *comment, *ptr;
2043         struct lustre_cfg_bufs  bufs;
2044         struct lustre_cfg      *lcfg;
2045         int                     rc, len;
2046         ENTRY;
2047
2048         /* get comment */
2049         ptr = strchr(param, '=');
2050         LASSERT(ptr);
2051         len = ptr - param;
2052
2053         OBD_ALLOC(comment, len + 1);
2054         if (comment == NULL)
2055                 RETURN(-ENOMEM);
2056         strncpy(comment, param, len);
2057         comment[len] = '\0';
2058
2059         /* prepare lcfg */
2060         lustre_cfg_bufs_reset(&bufs, mti->mti_svname);
2061         lustre_cfg_bufs_set_string(&bufs, 1, param);
2062         lcfg = lustre_cfg_new(LCFG_SPTLRPC_CONF, &bufs);
2063         if (lcfg == NULL)
2064                 GOTO(out_comment, rc = -ENOMEM);
2065
2066         /* construct log name */
2067         rc = name_create(&logname, mti->mti_fsname, "-sptlrpc");
2068         if (rc)
2069                 GOTO(out_lcfg, rc);
2070
2071         if (mgs_log_is_empty(obd, logname)) {
2072                 rc = record_start_log(obd, &llh, logname);
2073                 record_end_log(obd, &llh);
2074                 if (rc)
2075                         GOTO(out, rc);
2076         }
2077
2078         /* obsolete old one */
2079         mgs_modify(obd, fsdb, mti, logname, mti->mti_svname, comment, CM_SKIP);
2080
2081         /* write the new one */
2082         rc = mgs_write_log_direct(obd, fsdb, logname, lcfg,
2083                                   mti->mti_svname, comment);
2084         if (rc)
2085                 CERROR("err %d writing log %s\n", rc, logname);
2086
2087 out:
2088         name_destroy(&logname);
2089 out_lcfg:
2090         lustre_cfg_free(lcfg);
2091 out_comment:
2092         OBD_FREE(comment, len + 1);
2093         RETURN(rc);
2094 }
2095
2096 static int mgs_srpc_set_param_udesc_mem(struct fs_db *fsdb,
2097                                         char *param)
2098 {
2099         char    *ptr;
2100
2101         /* disable the adjustable udesc parameter for now, i.e. use default
2102          * setting that client always ship udesc to MDT if possible. to enable
2103          * it simply remove the following line */
2104         goto error_out;
2105
2106         ptr = strchr(param, '=');
2107         if (ptr == NULL)
2108                 goto error_out;
2109         *ptr++ = '\0';
2110
2111         if (strcmp(param, PARAM_SRPC_UDESC))
2112                 goto error_out;
2113
2114         if (strcmp(ptr, "yes") == 0) {
2115                 cfs_set_bit(FSDB_UDESC, &fsdb->fsdb_flags);
2116                 CWARN("Enable user descriptor shipping from client to MDT\n");
2117         } else if (strcmp(ptr, "no") == 0) {
2118                 cfs_clear_bit(FSDB_UDESC, &fsdb->fsdb_flags);
2119                 CWARN("Disable user descriptor shipping from client to MDT\n");
2120         } else {
2121                 *(ptr - 1) = '=';
2122                 goto error_out;
2123         }
2124         return 0;
2125
2126 error_out:
2127         CERROR("Invalid param: %s\n", param);
2128         return -EINVAL;
2129 }
2130
2131 static int mgs_srpc_set_param_mem(struct fs_db *fsdb,
2132                                   const char *svname,
2133                                   char *param)
2134 {
2135         struct sptlrpc_rule      rule;
2136         struct sptlrpc_rule_set *rset;
2137         int                      rc;
2138         ENTRY;
2139
2140         if (strncmp(param, PARAM_SRPC, sizeof(PARAM_SRPC) - 1) != 0) {
2141                 CERROR("Invalid sptlrpc parameter: %s\n", param);
2142                 RETURN(-EINVAL);
2143         }
2144
2145         if (strncmp(param, PARAM_SRPC_UDESC,
2146                     sizeof(PARAM_SRPC_UDESC) - 1) == 0) {
2147                 RETURN(mgs_srpc_set_param_udesc_mem(fsdb, param));
2148         }
2149
2150         if (strncmp(param, PARAM_SRPC_FLVR, sizeof(PARAM_SRPC_FLVR) - 1) != 0) {
2151                 CERROR("Invalid sptlrpc flavor parameter: %s\n", param);
2152                 RETURN(-EINVAL);
2153         }
2154
2155         param += sizeof(PARAM_SRPC_FLVR) - 1;
2156
2157         rc = sptlrpc_parse_rule(param, &rule);
2158         if (rc)
2159                 RETURN(rc);
2160
2161         /* mgs rules implies must be mgc->mgs */
2162         if (cfs_test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
2163                 if ((rule.sr_from != LUSTRE_SP_MGC &&
2164                      rule.sr_from != LUSTRE_SP_ANY) ||
2165                     (rule.sr_to != LUSTRE_SP_MGS &&
2166                      rule.sr_to != LUSTRE_SP_ANY))
2167                         RETURN(-EINVAL);
2168         }
2169
2170         /* preapre room for this coming rule. svcname format should be:
2171          * - fsname: general rule
2172          * - fsname-tgtname: target-specific rule
2173          */
2174         if (strchr(svname, '-')) {
2175                 struct mgs_tgt_srpc_conf *tgtconf;
2176                 int                       found = 0;
2177
2178                 for (tgtconf = fsdb->fsdb_srpc_tgt; tgtconf != NULL;
2179                      tgtconf = tgtconf->mtsc_next) {
2180                         if (!strcmp(tgtconf->mtsc_tgt, svname)) {
2181                                 found = 1;
2182                                 break;
2183                         }
2184                 }
2185
2186                 if (!found) {
2187                         int name_len;
2188
2189                         OBD_ALLOC_PTR(tgtconf);
2190                         if (tgtconf == NULL)
2191                                 RETURN(-ENOMEM);
2192
2193                         name_len = strlen(svname);
2194
2195                         OBD_ALLOC(tgtconf->mtsc_tgt, name_len + 1);
2196                         if (tgtconf->mtsc_tgt == NULL) {
2197                                 OBD_FREE_PTR(tgtconf);
2198                                 RETURN(-ENOMEM);
2199                         }
2200                         memcpy(tgtconf->mtsc_tgt, svname, name_len);
2201
2202                         tgtconf->mtsc_next = fsdb->fsdb_srpc_tgt;
2203                         fsdb->fsdb_srpc_tgt = tgtconf;
2204                 }
2205
2206                 rset = &tgtconf->mtsc_rset;
2207         } else {
2208                 rset = &fsdb->fsdb_srpc_gen;
2209         }
2210
2211         rc = sptlrpc_rule_set_merge(rset, &rule);
2212
2213         RETURN(rc);
2214 }
2215
2216 static int mgs_srpc_set_param(struct obd_device *obd,
2217                               struct fs_db *fsdb,
2218                               struct mgs_target_info *mti,
2219                               char *param)
2220 {
2221         char                   *copy;
2222         int                     rc, copy_size;
2223         ENTRY;
2224
2225 #ifndef HAVE_GSS
2226         RETURN(-EINVAL);
2227 #endif
2228         /* keep a copy of original param, which could be destroied
2229          * during parsing */
2230         copy_size = strlen(param) + 1;
2231         OBD_ALLOC(copy, copy_size);
2232         if (copy == NULL)
2233                 return -ENOMEM;
2234         memcpy(copy, param, copy_size);
2235
2236         rc = mgs_srpc_set_param_mem(fsdb, mti->mti_svname, param);
2237         if (rc)
2238                 goto out_free;
2239
2240         /* previous steps guaranteed the syntax is correct */
2241         rc = mgs_srpc_set_param_disk(obd, fsdb, mti, copy);
2242         if (rc)
2243                 goto out_free;
2244
2245         if (cfs_test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
2246                 /*
2247                  * for mgs rules, make them effective immediately.
2248                  */
2249                 LASSERT(fsdb->fsdb_srpc_tgt == NULL);
2250                 sptlrpc_target_update_exp_flavor(obd, &fsdb->fsdb_srpc_gen);
2251         }
2252
2253 out_free:
2254         OBD_FREE(copy, copy_size);
2255         RETURN(rc);
2256 }
2257
2258 struct mgs_srpc_read_data {
2259         struct fs_db   *msrd_fsdb;
2260         int             msrd_skip;
2261 };
2262
2263 static int mgs_srpc_read_handler(struct llog_handle *llh,
2264                                  struct llog_rec_hdr *rec,
2265                                  void *data)
2266 {
2267         struct mgs_srpc_read_data *msrd = (struct mgs_srpc_read_data *) data;
2268         struct cfg_marker         *marker;
2269         struct lustre_cfg         *lcfg = (struct lustre_cfg *)(rec + 1);
2270         char                      *svname, *param;
2271         int                        cfg_len, rc;
2272         ENTRY;
2273
2274         if (rec->lrh_type != OBD_CFG_REC) {
2275                 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
2276                 RETURN(-EINVAL);
2277         }
2278
2279         cfg_len = rec->lrh_len - sizeof(struct llog_rec_hdr) -
2280                   sizeof(struct llog_rec_tail);
2281
2282         rc = lustre_cfg_sanity_check(lcfg, cfg_len);
2283         if (rc) {
2284                 CERROR("Insane cfg\n");
2285                 RETURN(rc);
2286         }
2287
2288         if (lcfg->lcfg_command == LCFG_MARKER) {
2289                 marker = lustre_cfg_buf(lcfg, 1);
2290
2291                 if (marker->cm_flags & CM_START &&
2292                     marker->cm_flags & CM_SKIP)
2293                         msrd->msrd_skip = 1;
2294                 if (marker->cm_flags & CM_END)
2295                         msrd->msrd_skip = 0;
2296
2297                 RETURN(0);
2298         }
2299
2300         if (msrd->msrd_skip)
2301                 RETURN(0);
2302
2303         if (lcfg->lcfg_command != LCFG_SPTLRPC_CONF) {
2304                 CERROR("invalid command (%x)\n", lcfg->lcfg_command);
2305                 RETURN(0);
2306         }
2307
2308         svname = lustre_cfg_string(lcfg, 0);
2309         if (svname == NULL) {
2310                 CERROR("svname is empty\n");
2311                 RETURN(0);
2312         }
2313
2314         param = lustre_cfg_string(lcfg, 1);
2315         if (param == NULL) {
2316                 CERROR("param is empty\n");
2317                 RETURN(0);
2318         }
2319
2320         rc = mgs_srpc_set_param_mem(msrd->msrd_fsdb, svname, param);
2321         if (rc)
2322                 CERROR("read sptlrpc record error (%d): %s\n", rc, param);
2323
2324         RETURN(0);
2325 }
2326
2327 int mgs_get_fsdb_srpc_from_llog(struct obd_device *obd,
2328                                 struct fs_db *fsdb)
2329 {
2330         struct llog_handle        *llh = NULL;
2331         struct lvfs_run_ctxt       saved;
2332         struct llog_ctxt          *ctxt;
2333         char                      *logname;
2334         struct mgs_srpc_read_data  msrd;
2335         int                        rc;
2336         ENTRY;
2337
2338         /* construct log name */
2339         rc = name_create(&logname, fsdb->fsdb_name, "-sptlrpc");
2340         if (rc)
2341                 RETURN(rc);
2342
2343         ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
2344         LASSERT(ctxt != NULL);
2345
2346         if (mgs_log_is_empty(obd, logname))
2347                 GOTO(out, rc = 0);
2348
2349         push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
2350
2351         rc = llog_create(ctxt, &llh, NULL, logname);
2352         if (rc)
2353                 GOTO(out_pop, rc);
2354
2355         rc = llog_init_handle(llh, LLOG_F_IS_PLAIN, NULL);
2356         if (rc)
2357                 GOTO(out_close, rc);
2358
2359         if (llog_get_size(llh) <= 1)
2360                 GOTO(out_close, rc = 0);
2361
2362         msrd.msrd_fsdb = fsdb;
2363         msrd.msrd_skip = 0;
2364
2365         rc = llog_process(llh, mgs_srpc_read_handler, (void *) &msrd, NULL);
2366
2367 out_close:
2368         llog_close(llh);
2369 out_pop:
2370         pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
2371 out:
2372         llog_ctxt_put(ctxt);
2373         name_destroy(&logname);
2374
2375         if (rc)
2376                 CERROR("failed to read sptlrpc config database: %d\n", rc);
2377         RETURN(rc);
2378 }
2379
2380 /* Permanent settings of all parameters by writing into the appropriate
2381  * configuration logs.
2382  * A parameter with null value ("<param>='\0'") means to erase it out of
2383  * the logs.
2384  */
2385 static int mgs_write_log_param(struct obd_device *obd, struct fs_db *fsdb,
2386                                struct mgs_target_info *mti, char *ptr)
2387 {
2388         struct lustre_cfg_bufs bufs;
2389         char *logname;
2390         char *tmp;
2391         int rc = 0, rc2 = 0;
2392         ENTRY;
2393
2394         /* For various parameter settings, we have to figure out which logs
2395            care about them (e.g. both mdt and client for lov settings) */
2396         CDEBUG(D_MGS, "next param '%s'\n", ptr);
2397
2398         /* The params are stored in MOUNT_DATA_FILE and modified via
2399            tunefs.lustre, or set using lctl conf_param */
2400
2401         /* Processed in lustre_start_mgc */
2402         if (class_match_param(ptr, PARAM_MGSNODE, NULL) == 0)
2403                 GOTO(end, rc);
2404
2405         /* Processed in mgs_write_log_ost */
2406         if (class_match_param(ptr, PARAM_FAILMODE, NULL) == 0) {
2407                 if (mti->mti_flags & LDD_F_PARAM) {
2408                         LCONSOLE_ERROR_MSG(0x169, "%s can only be "
2409                                            "changed with tunefs.lustre"
2410                                            "and --writeconf\n", ptr);
2411                         rc = -EPERM;
2412                 }
2413                 GOTO(end, rc);
2414         }
2415
2416         if (class_match_param(ptr, PARAM_SRPC, NULL) == 0) {
2417                 rc = mgs_srpc_set_param(obd, fsdb, mti, ptr);
2418                 GOTO(end, rc);
2419         }
2420
2421         if (class_match_param(ptr, PARAM_FAILNODE, NULL) == 0) {
2422                 /* Add a failover nidlist */
2423                 rc = 0;
2424                 /* We already processed failovers params for new
2425                    targets in mgs_write_log_target */
2426                 if (mti->mti_flags & LDD_F_PARAM) {
2427                         CDEBUG(D_MGS, "Adding failnode\n");
2428                         rc = mgs_write_log_add_failnid(obd, fsdb, mti);
2429                 }
2430                 GOTO(end, rc);
2431         }
2432
2433         if (class_match_param(ptr, PARAM_SYS, &tmp) == 0) {
2434                 rc = mgs_write_log_sys(obd, fsdb, mti, ptr, tmp);
2435                 GOTO(end, rc);
2436         }
2437
2438         if (class_match_param(ptr, PARAM_OSC""PARAM_ACTIVE, &tmp) == 0) {
2439                 /* active=0 means off, anything else means on */
2440                 int flag = (*tmp == '0') ? CM_EXCLUDE : 0;
2441                 int i;
2442
2443                 if (!(mti->mti_flags & LDD_F_SV_TYPE_OST)) {
2444                         LCONSOLE_ERROR_MSG(0x144, "%s: Only OSCs can "
2445                                            "be (de)activated.\n",
2446                                            mti->mti_svname);
2447                         GOTO(end, rc = -EINVAL);
2448                 }
2449                 LCONSOLE_WARN("Permanently %sactivating %s\n",
2450                               flag ? "de": "re", mti->mti_svname);
2451                 /* Modify clilov */
2452                 name_create(&logname, mti->mti_fsname, "-client");
2453                 rc = mgs_modify(obd, fsdb, mti, logname,
2454                                 mti->mti_svname, "add osc", flag);
2455                 name_destroy(&logname);
2456                 if (rc)
2457                         goto active_err;
2458                 /* Modify mdtlov */
2459                 /* Add to all MDT logs for CMD */
2460                 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2461                         if (!cfs_test_bit(i, fsdb->fsdb_mdt_index_map))
2462                                 continue;
2463                         name_create_mdt(&logname, mti->mti_fsname, i);
2464                         rc = mgs_modify(obd, fsdb, mti, logname,
2465                                         mti->mti_svname, "add osc", flag);
2466                         name_destroy(&logname);
2467                         if (rc)
2468                                 goto active_err;
2469                 }
2470         active_err:
2471                 if (rc) {
2472                         LCONSOLE_ERROR_MSG(0x145, "Couldn't find %s in"
2473                                            "log (%d). No permanent "
2474                                            "changes were made to the "
2475                                            "config log.\n",
2476                                            mti->mti_svname, rc);
2477                         if (cfs_test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags))
2478                                 LCONSOLE_ERROR_MSG(0x146, "This may be"
2479                                                    " because the log"
2480                                                    "is in the old 1.4"
2481                                                    "style. Consider "
2482                                                    " --writeconf to "
2483                                                    "update the logs.\n");
2484                         GOTO(end, rc);
2485                 }
2486                 /* Fall through to osc proc for deactivating live OSC
2487                    on running MDT / clients. */
2488         }
2489         /* Below here, let obd's XXX_process_config methods handle it */
2490
2491         /* All lov. in proc */
2492         if (class_match_param(ptr, PARAM_LOV, NULL) == 0) {
2493                 char *mdtlovname;
2494
2495                 CDEBUG(D_MGS, "lov param %s\n", ptr);
2496                 if (!(mti->mti_flags & LDD_F_SV_TYPE_MDT)) {
2497                         LCONSOLE_ERROR_MSG(0x147, "LOV params must be "
2498                                            "set on the MDT, not %s. "
2499                                            "Ignoring.\n",
2500                                            mti->mti_svname);
2501                         GOTO(end, rc = 0);
2502                 }
2503
2504                 /* Modify mdtlov */
2505                 if (mgs_log_is_empty(obd, mti->mti_svname))
2506                         GOTO(end, rc = -ENODEV);
2507
2508                 name_create_mdt_and_lov(&logname, &mdtlovname, fsdb,
2509                                         mti->mti_stripe_index);
2510                 rc = mgs_wlp_lcfg(obd, fsdb, mti, mti->mti_svname,
2511                                   &bufs, mdtlovname, ptr);
2512                 name_destroy(&logname);
2513                 name_destroy(&mdtlovname);
2514                 if (rc)
2515                         GOTO(end, rc);
2516
2517                 /* Modify clilov */
2518                 name_create(&logname, mti->mti_fsname, "-client");
2519                 rc = mgs_wlp_lcfg(obd, fsdb, mti, logname, &bufs,
2520                                   fsdb->fsdb_clilov, ptr);
2521                 name_destroy(&logname);
2522                 GOTO(end, rc);
2523         }
2524
2525         /* All osc., mdc., llite. params in proc */
2526         if ((class_match_param(ptr, PARAM_OSC, NULL) == 0) ||
2527             (class_match_param(ptr, PARAM_MDC, NULL) == 0) ||
2528             (class_match_param(ptr, PARAM_LLITE, NULL) == 0)) {
2529                 char *cname;
2530                 if (memcmp(ptr, PARAM_LLITE, strlen(PARAM_LLITE)) == 0) {
2531                         name_create(&cname, mti->mti_fsname, "-client");
2532                         /* Add the client type to match the obdname in
2533                            class_config_llog_handler */
2534                 } else if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
2535                         /* COMPAT_146 */
2536                         if (fsdb->fsdb_mdc)
2537                                 name_create(&cname, fsdb->fsdb_mdc, "");
2538                         else
2539                                 name_create(&cname, mti->mti_svname,
2540                                             "-mdc");
2541                 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2542                         /* COMPAT_146 */
2543                         if (cfs_test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
2544                                 LCONSOLE_ERROR_MSG(0x148, "Upgraded "
2545                                                    "client logs for %s"
2546                                                    " cannot be "
2547                                                    "modified. Consider"
2548                                                    " updating the "
2549                                                    "configuration with"
2550                                                    " --writeconf\n",
2551                                                    mti->mti_svname);
2552                                 /* We don't know the names of all the
2553                                    old oscs*/
2554                                 GOTO(end, rc = -EINVAL);
2555                         }
2556                         name_create(&cname, mti->mti_svname, "-osc");
2557                 } else {
2558                         GOTO(end, rc = -EINVAL);
2559                 }
2560
2561                 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
2562
2563                 /* Modify client */
2564                 name_create(&logname, mti->mti_fsname, "-client");
2565                 rc = mgs_wlp_lcfg(obd, fsdb, mti, logname, &bufs,
2566                                   cname, ptr);
2567
2568                 /* osc params affect the MDT as well */
2569                 if (!rc && (mti->mti_flags & LDD_F_SV_TYPE_OST)) {
2570                         int i;
2571
2572                         for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
2573                                 if (!cfs_test_bit(i, fsdb->fsdb_mdt_index_map))
2574                                         continue;
2575                                 name_destroy(&cname);
2576                                 name_create_mdt_osc(&cname, mti->mti_svname,
2577                                                     fsdb, i);
2578                                 name_destroy(&logname);
2579                                 name_create_mdt(&logname, mti->mti_fsname, i);
2580                                 if (!mgs_log_is_empty(obd, logname))
2581                                         rc = mgs_wlp_lcfg(obd, fsdb,mti,logname,
2582                                                           &bufs, cname, ptr);
2583                                 if (rc)
2584                                         break;
2585                         }
2586                 }
2587                 name_destroy(&logname);
2588                 name_destroy(&cname);
2589                 GOTO(end, rc);
2590         }
2591
2592         /* All mdt. params in proc */
2593         if (class_match_param(ptr, PARAM_MDT, NULL) == 0) {
2594                 int i;
2595                 __u32 idx;
2596
2597                 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
2598                 if (strncmp(mti->mti_svname, mti->mti_fsname,
2599                             MTI_NAME_MAXLEN) == 0)
2600                         /* device is unspecified completely? */
2601                         rc = LDD_F_SV_TYPE_MDT | LDD_F_SV_ALL;
2602                 else
2603                         rc = server_name2index(mti->mti_svname, &idx, NULL);
2604                 if (rc < 0)
2605                         goto active_err;
2606                 if ((rc & LDD_F_SV_TYPE_MDT) == 0)
2607                         goto active_err;
2608                 if (rc & LDD_F_SV_ALL) {
2609                         for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2610                                 if (!cfs_test_bit(i,
2611                                                   fsdb->fsdb_mdt_index_map))
2612                                         continue;
2613                                 name_create_mdt(&logname, mti->mti_fsname, i);
2614                                 rc = mgs_wlp_lcfg(obd, fsdb, mti,
2615                                                   logname, &bufs,
2616                                                   logname, ptr);
2617                                 name_destroy(&logname);
2618                                 if (rc)
2619                                         goto active_err;
2620                         }
2621                 } else {
2622                         rc = mgs_wlp_lcfg(obd, fsdb, mti,
2623                                           mti->mti_svname, &bufs,
2624                                           mti->mti_svname, ptr);
2625                         if (rc)
2626                                 goto active_err;
2627                 }
2628                 GOTO(end, rc);
2629         }
2630
2631         /* All mdd., ost. params in proc */
2632         if ((class_match_param(ptr, PARAM_MDD, NULL) == 0) ||
2633             (class_match_param(ptr, PARAM_OST, NULL) == 0)) {
2634                 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
2635                 if (mgs_log_is_empty(obd, mti->mti_svname))
2636                         GOTO(end, rc = -ENODEV);
2637
2638                 rc = mgs_wlp_lcfg(obd, fsdb, mti, mti->mti_svname,
2639                                   &bufs, mti->mti_svname, ptr);
2640                 GOTO(end, rc);
2641         }
2642
2643         LCONSOLE_WARN("Ignoring unrecognized param '%s'\n", ptr);
2644         rc2 = -ENOSYS;
2645
2646 end:
2647         if (rc)
2648                 CERROR("err %d on param '%s'\n", rc, ptr);
2649
2650         RETURN(rc ?: rc2);
2651 }
2652
2653 /* Not implementing automatic failover nid addition at this time. */
2654 int mgs_check_failnid(struct obd_device *obd, struct mgs_target_info *mti)
2655 {
2656 #if 0
2657         struct fs_db *fsdb;
2658         int rc;
2659         ENTRY;
2660
2661         rc = mgs_find_or_make_fsdb(obd, fsname, &fsdb);
2662         if (rc)
2663                 RETURN(rc);
2664
2665         if (mgs_log_is_empty(obd, mti->mti_svname))
2666                 /* should never happen */
2667                 RETURN(-ENOENT);
2668
2669         CDEBUG(D_MGS, "Checking for new failnids for %s\n", mti->mti_svname);
2670
2671         /* FIXME We can just check mti->params to see if we're already in
2672            the failover list.  Modify mti->params for rewriting back at
2673            server_register_target(). */
2674
2675         cfs_down(&fsdb->fsdb_sem);
2676         rc = mgs_write_log_add_failnid(obd, fsdb, mti);
2677         cfs_up(&fsdb->fsdb_sem);
2678
2679         RETURN(rc);
2680 #endif
2681         return 0;
2682 }
2683
2684 int mgs_write_log_target(struct obd_device *obd,
2685                          struct mgs_target_info *mti,
2686                          struct fs_db *fsdb)
2687 {
2688         int rc = -EINVAL;
2689         char *buf, *params;
2690         ENTRY;
2691
2692         /* set/check the new target index */
2693         rc = mgs_set_index(obd, mti);
2694         if (rc < 0) {
2695                 CERROR("Can't get index (%d)\n", rc);
2696                 RETURN(rc);
2697         }
2698
2699         /* COMPAT_146 */
2700         if (mti->mti_flags & LDD_F_UPGRADE14) {
2701                 if (rc == EALREADY) {
2702                         LCONSOLE_INFO("Found index %d for %s 1.4 log, "
2703                                       "upgrading\n", mti->mti_stripe_index,
2704                                       mti->mti_svname);
2705                 } else {
2706                         LCONSOLE_ERROR_MSG(0x149, "Failed to find %s in the old"
2707                                            " client log. Apparently it is not "
2708                                            "part of this filesystem, or the old"
2709                                            " log is wrong.\nUse 'writeconf' on "
2710                                            "the MDT to force log regeneration."
2711                                            "\n", mti->mti_svname);
2712                         /* Not in client log?  Upgrade anyhow...*/
2713                         /* Argument against upgrading: reformat MDT,
2714                            upgrade OST, then OST will start but will be SKIPped
2715                            in client logs.  Maybe error now is better. */
2716                         /* RETURN(-EINVAL); */
2717                 }
2718                 /* end COMPAT_146 */
2719         } else {
2720                 if (rc == EALREADY) {
2721                         LCONSOLE_WARN("Found index %d for %s, updating log\n",
2722                                       mti->mti_stripe_index, mti->mti_svname);
2723                         /* We would like to mark old log sections as invalid
2724                            and add new log sections in the client and mdt logs.
2725                            But if we add new sections, then live clients will
2726                            get repeat setup instructions for already running
2727                            osc's. So don't update the client/mdt logs. */
2728                         mti->mti_flags &= ~LDD_F_UPDATE;
2729                 }
2730         }
2731
2732         cfs_down(&fsdb->fsdb_sem);
2733
2734         if (mti->mti_flags &
2735             (LDD_F_VIRGIN | LDD_F_UPGRADE14 | LDD_F_WRITECONF)) {
2736                 /* Generate a log from scratch */
2737                 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
2738                         rc = mgs_write_log_mdt(obd, fsdb, mti);
2739                 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2740                         rc = mgs_write_log_ost(obd, fsdb, mti);
2741                 } else {
2742                         CERROR("Unknown target type %#x, can't create log for "
2743                                "%s\n", mti->mti_flags, mti->mti_svname);
2744                 }
2745                 if (rc) {
2746                         CERROR("Can't write logs for %s (%d)\n",
2747                                mti->mti_svname, rc);
2748                         GOTO(out_up, rc);
2749                 }
2750         } else {
2751                 /* Just update the params from tunefs in mgs_write_log_params */
2752                 CDEBUG(D_MGS, "Update params for %s\n", mti->mti_svname);
2753                 mti->mti_flags |= LDD_F_PARAM;
2754         }
2755
2756         /* allocate temporary buffer, where class_get_next_param will
2757            make copy of a current  parameter */
2758         OBD_ALLOC(buf, strlen(mti->mti_params) + 1);
2759         if (buf == NULL)
2760                 GOTO(out_up, rc = -ENOMEM);
2761         params = mti->mti_params;
2762         while (params != NULL) {
2763                 rc = class_get_next_param(&params, buf);
2764                 if (rc) {
2765                         if (rc == 1)
2766                                 /* there is no next parameter, that is
2767                                    not an error */
2768                                 rc = 0;
2769                         break;
2770                 }
2771                 CDEBUG(D_MGS, "remaining string: '%s', param: '%s'\n",
2772                        params, buf);
2773                 rc = mgs_write_log_param(obd, fsdb, mti, buf);
2774                 if (rc)
2775                         break;
2776         }
2777
2778         OBD_FREE(buf, strlen(mti->mti_params) + 1);
2779
2780 out_up:
2781         cfs_up(&fsdb->fsdb_sem);
2782         RETURN(rc);
2783 }
2784
2785 /* COMPAT_146 */
2786 /* verify that we can handle the old config logs */
2787 int mgs_upgrade_sv_14(struct obd_device *obd, struct mgs_target_info *mti,
2788                       struct fs_db *fsdb)
2789 {
2790         int rc = 0;
2791         ENTRY;
2792
2793         /* Create ost log normally, as servers register.  Servers
2794            register with their old uuids (from last_rcvd), so old
2795            (MDT and client) logs should work.
2796          - new MDT won't know about old OSTs, only the ones that have
2797            registered, so we need the old MDT log to get the LOV right
2798            in order for old clients to work.
2799          - Old clients connect to the MDT, not the MGS, for their logs, and
2800            will therefore receive the old client log from the MDT /LOGS dir.
2801          - Old clients can continue to use and connect to old or new OSTs
2802          - New clients will contact the MGS for their log
2803         */
2804
2805         LCONSOLE_INFO("upgrading server %s from pre-1.6\n", mti->mti_svname);
2806         server_mti_print("upgrade", mti);
2807
2808         if (cfs_test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
2809                 LCONSOLE_ERROR_MSG(0x14a, "The old client log %s-client is "
2810                                    "missing.  Was tunefs.lustre successful?\n",
2811                                    mti->mti_fsname);
2812                 RETURN(-ENOENT);
2813         }
2814
2815         if (fsdb->fsdb_gen == 0) {
2816                 /* There were no markers in the client log, meaning we have
2817                    not updated the logs for this fs */
2818                 CDEBUG(D_MGS, "found old, unupdated client log\n");
2819         }
2820
2821         if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
2822                 if (mgs_log_is_empty(obd, mti->mti_svname)) {
2823                         LCONSOLE_ERROR_MSG(0x14b, "The old MDT log %s is "
2824                                            "missing. Was tunefs.lustre "
2825                                            "successful?\n",
2826                                            mti->mti_svname);
2827                         RETURN(-ENOENT);
2828                 }
2829                 /* We're starting with an old uuid.  Assume old name for lov
2830                    as well since the lov entry already exists in the log. */
2831                 CDEBUG(D_MGS, "old mds uuid %s\n", mti->mti_uuid);
2832                 if (strncmp(mti->mti_uuid, fsdb->fsdb_mdtlov + 4,
2833                             strlen(fsdb->fsdb_mdtlov) - 4) != 0) {
2834                         CERROR("old mds uuid %s doesn't match log %s (%s)\n",
2835                                mti->mti_uuid, fsdb->fsdb_mdtlov,
2836                                fsdb->fsdb_mdtlov + 4);
2837                         RETURN(-EINVAL);
2838                 }
2839         }
2840
2841         if (!cfs_test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
2842                 LCONSOLE_ERROR_MSG(0x14c, "%s-client is supposedly an old "
2843                                    "log, but no old LOV or MDT was found. "
2844                                    "Consider updating the configuration with"
2845                                    " --writeconf.\n", mti->mti_fsname);
2846         }
2847
2848         RETURN(rc);
2849 }
2850 /* end COMPAT_146 */
2851
2852 int mgs_erase_log(struct obd_device *obd, char *name)
2853 {
2854         struct lvfs_run_ctxt saved;
2855         struct llog_ctxt *ctxt;
2856         struct llog_handle *llh;
2857         int rc = 0;
2858
2859         ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
2860         LASSERT(ctxt != NULL);
2861
2862         push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
2863         rc = llog_create(ctxt, &llh, NULL, name);
2864         if (rc == 0) {
2865                 llog_init_handle(llh, LLOG_F_IS_PLAIN, NULL);
2866                 rc = llog_destroy(llh);
2867                 llog_free_handle(llh);
2868         }
2869         pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
2870         llog_ctxt_put(ctxt);
2871
2872         if (rc)
2873                 CERROR("failed to clear log %s: %d\n", name, rc);
2874
2875         return(rc);
2876 }
2877
2878 /* erase all logs for the given fs */
2879 int mgs_erase_logs(struct obd_device *obd, char *fsname)
2880 {
2881         struct mgs_obd *mgs = &obd->u.mgs;
2882         static struct fs_db *fsdb;
2883         cfs_list_t dentry_list;
2884         struct l_linux_dirent *dirent, *n;
2885         int rc, len = strlen(fsname);
2886         char *suffix;
2887         ENTRY;
2888
2889         /* Find all the logs in the CONFIGS directory */
2890         rc = class_dentry_readdir(obd, mgs->mgs_configs_dir,
2891                                   mgs->mgs_vfsmnt, &dentry_list);
2892         if (rc) {
2893                 CERROR("Can't read %s dir\n", MOUNT_CONFIGS_DIR);
2894                 RETURN(rc);
2895         }
2896
2897         cfs_down(&mgs->mgs_sem);
2898
2899         /* Delete the fs db */
2900         fsdb = mgs_find_fsdb(obd, fsname);
2901         if (fsdb)
2902                 mgs_free_fsdb(obd, fsdb);
2903
2904         cfs_list_for_each_entry_safe(dirent, n, &dentry_list, lld_list) {
2905                 cfs_list_del(&dirent->lld_list);
2906                 suffix = strrchr(dirent->lld_name, '-');
2907                 if (suffix != NULL) {
2908                         if ((len == suffix - dirent->lld_name) &&
2909                             (strncmp(fsname, dirent->lld_name, len) == 0)) {
2910                                 CDEBUG(D_MGS, "Removing log %s\n",
2911                                        dirent->lld_name);
2912                                 mgs_erase_log(obd, dirent->lld_name);
2913                         }
2914                 }
2915                 OBD_FREE(dirent, sizeof(*dirent));
2916         }
2917
2918         cfs_up(&mgs->mgs_sem);
2919
2920         RETURN(rc);
2921 }
2922
2923 /* from llog_swab */
2924 static void print_lustre_cfg(struct lustre_cfg *lcfg)
2925 {
2926         int i;
2927         ENTRY;
2928
2929         CDEBUG(D_MGS, "lustre_cfg: %p\n", lcfg);
2930         CDEBUG(D_MGS, "\tlcfg->lcfg_version: %#x\n", lcfg->lcfg_version);
2931
2932         CDEBUG(D_MGS, "\tlcfg->lcfg_command: %#x\n", lcfg->lcfg_command);
2933         CDEBUG(D_MGS, "\tlcfg->lcfg_num: %#x\n", lcfg->lcfg_num);
2934         CDEBUG(D_MGS, "\tlcfg->lcfg_flags: %#x\n", lcfg->lcfg_flags);
2935         CDEBUG(D_MGS, "\tlcfg->lcfg_nid: %s\n", libcfs_nid2str(lcfg->lcfg_nid));
2936
2937         CDEBUG(D_MGS, "\tlcfg->lcfg_bufcount: %d\n", lcfg->lcfg_bufcount);
2938         if (lcfg->lcfg_bufcount < LUSTRE_CFG_MAX_BUFCOUNT)
2939                 for (i = 0; i < lcfg->lcfg_bufcount; i++) {
2940                         CDEBUG(D_MGS, "\tlcfg->lcfg_buflens[%d]: %d %s\n",
2941                                i, lcfg->lcfg_buflens[i],
2942                                lustre_cfg_string(lcfg, i));
2943                 }
2944         EXIT;
2945 }
2946
2947 /* Set a permanent (config log) param for a target or fs
2948  * \param lcfg buf0 may contain the device (testfs-MDT0000) name
2949  *             buf1 contains the single parameter
2950  */
2951 int mgs_setparam(struct obd_device *obd, struct lustre_cfg *lcfg, char *fsname)
2952 {
2953         struct fs_db *fsdb;
2954         struct mgs_target_info *mti;
2955         char *devname, *param;
2956         char *ptr, *tmp;
2957         __u32 index;
2958         int rc = 0;
2959         ENTRY;
2960
2961         print_lustre_cfg(lcfg);
2962
2963         /* lustre, lustre-mdtlov, lustre-client, lustre-MDT0000 */
2964         devname = lustre_cfg_string(lcfg, 0);
2965         param = lustre_cfg_string(lcfg, 1);
2966         if (!devname) {
2967                 /* Assume device name embedded in param:
2968                    lustre-OST0000.osc.max_dirty_mb=32 */
2969                 ptr = strchr(param, '.');
2970                 if (ptr) {
2971                         devname = param;
2972                         *ptr = 0;
2973                         param = ptr + 1;
2974                 }
2975         }
2976         if (!devname) {
2977                 LCONSOLE_ERROR_MSG(0x14d, "No target specified: %s\n", param);
2978                 RETURN(-ENOSYS);
2979         }
2980
2981         /* Extract fsname */
2982         ptr = strrchr(devname, '-');
2983         memset(fsname, 0, MTI_NAME_MAXLEN);
2984         if (ptr && (server_name2index(ptr, &index, NULL) >= 0)) {
2985                 /* param related to llite isn't allowed to set by OST or MDT */
2986                 if (strncmp(param, PARAM_LLITE, sizeof(PARAM_LLITE)) == 0)
2987                         RETURN(-EINVAL);
2988
2989                 strncpy(fsname, devname, ptr - devname);
2990         } else {
2991                 /* assume devname is the fsname */
2992                 strncpy(fsname, devname, MTI_NAME_MAXLEN);
2993         }
2994         fsname[MTI_NAME_MAXLEN - 1] = 0;
2995         CDEBUG(D_MGS, "setparam fs='%s' device='%s'\n", fsname, devname);
2996
2997         rc = mgs_find_or_make_fsdb(obd, fsname, &fsdb);
2998         if (rc)
2999                 RETURN(rc);
3000         if (!cfs_test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags) &&
3001             cfs_test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
3002                 CERROR("No filesystem targets for %s.  cfg_device from lctl "
3003                        "is '%s'\n", fsname, devname);
3004                 mgs_free_fsdb(obd, fsdb);
3005                 RETURN(-EINVAL);
3006         }
3007
3008         /* Create a fake mti to hold everything */
3009         OBD_ALLOC_PTR(mti);
3010         if (!mti)
3011                 GOTO(out, rc = -ENOMEM);
3012         strncpy(mti->mti_fsname, fsname, MTI_NAME_MAXLEN);
3013         strncpy(mti->mti_svname, devname, MTI_NAME_MAXLEN);
3014         strncpy(mti->mti_params, param, sizeof(mti->mti_params));
3015         rc = server_name2index(mti->mti_svname, &mti->mti_stripe_index, &tmp);
3016         if (rc < 0)
3017                 /* Not a valid server; may be only fsname */
3018                 rc = 0;
3019         else
3020                 /* Strip -osc or -mdc suffix from svname */
3021                 if (server_make_name(rc, mti->mti_stripe_index, mti->mti_fsname,
3022                                      mti->mti_svname))
3023                         GOTO(out, rc = -EINVAL);
3024
3025         mti->mti_flags = rc | LDD_F_PARAM;
3026
3027         cfs_down(&fsdb->fsdb_sem);
3028         rc = mgs_write_log_param(obd, fsdb, mti, mti->mti_params);
3029         cfs_up(&fsdb->fsdb_sem);
3030
3031         /*
3032          * Revoke lock so everyone updates.  Should be alright if
3033          * someone was already reading while we were updating the logs,
3034          * so we don't really need to hold the lock while we're
3035          * writing (above).
3036          */
3037         mgs_revoke_lock(obd, fsdb);
3038 out:
3039         OBD_FREE_PTR(mti);
3040         RETURN(rc);
3041 }
3042
3043 static int mgs_write_log_pool(struct obd_device *obd, char *logname,
3044                               struct fs_db *fsdb, char *lovname,
3045                               enum lcfg_command_type cmd,
3046                               char *poolname, char *fsname,
3047                               char *ostname, char *comment)
3048 {
3049         struct llog_handle *llh = NULL;
3050         int rc;
3051
3052         rc = record_start_log(obd, &llh, logname);
3053         if (rc)
3054                 return rc;
3055         rc = record_marker(obd, llh, fsdb, CM_START, lovname, comment);
3056         record_base(obd, llh, lovname, 0, cmd, poolname, fsname, ostname, 0);
3057         rc = record_marker(obd, llh, fsdb, CM_END, lovname, comment);
3058         rc = record_end_log(obd, &llh);
3059
3060         return rc;
3061 }
3062
3063 int mgs_pool_cmd(struct obd_device *obd, enum lcfg_command_type cmd,
3064                  char *fsname, char *poolname, char *ostname)
3065 {
3066         struct fs_db *fsdb;
3067         char *lovname;
3068         char *logname;
3069         char *label = NULL, *canceled_label = NULL;
3070         int label_sz;
3071         struct mgs_target_info *mti = NULL;
3072         int rc, i;
3073         ENTRY;
3074
3075         rc = mgs_find_or_make_fsdb(obd, fsname, &fsdb);
3076         if (rc) {
3077                 CERROR("Can't get db for %s\n", fsname);
3078                 RETURN(rc);
3079         }
3080         if (cfs_test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
3081                 CERROR("%s is not defined\n", fsname);
3082                 mgs_free_fsdb(obd, fsdb);
3083                 RETURN(-EINVAL);
3084         }
3085
3086         label_sz = 10 + strlen(fsname) + strlen(poolname);
3087
3088         /* check if ostname match fsname */
3089         if (ostname != NULL) {
3090                 char *ptr;
3091
3092                 ptr = strrchr(ostname, '-');
3093                 if ((ptr == NULL) ||
3094                     (strncmp(fsname, ostname, ptr-ostname) != 0))
3095                         RETURN(-EINVAL);
3096                 label_sz += strlen(ostname);
3097         }
3098
3099         OBD_ALLOC(label, label_sz);
3100         if (label == NULL)
3101                 GOTO(out, rc = -ENOMEM);
3102
3103         switch(cmd) {
3104         case LCFG_POOL_NEW: {
3105                 sprintf(label,
3106                         "new %s.%s", fsname, poolname);
3107                 break;
3108         }
3109         case LCFG_POOL_ADD: {
3110                 sprintf(label,
3111                         "add %s.%s.%s", fsname, poolname, ostname);
3112                 break;
3113         }
3114         case LCFG_POOL_REM: {
3115                 OBD_ALLOC(canceled_label, label_sz);
3116                 if (canceled_label == NULL)
3117                          GOTO(out, rc = -ENOMEM);
3118                 sprintf(label,
3119                         "rem %s.%s.%s", fsname, poolname, ostname);
3120                 sprintf(canceled_label,
3121                         "add %s.%s.%s", fsname, poolname, ostname);
3122                 break;
3123         }
3124         case LCFG_POOL_DEL: {
3125                 OBD_ALLOC(canceled_label, label_sz);
3126                 if (canceled_label == NULL)
3127                          GOTO(out, rc = -ENOMEM);
3128                 sprintf(label,
3129                         "del %s.%s", fsname, poolname);
3130                 sprintf(canceled_label,
3131                         "new %s.%s", fsname, poolname);
3132                 break;
3133         }
3134         default: {
3135                 break;
3136         }
3137         }
3138
3139         cfs_down(&fsdb->fsdb_sem);
3140
3141         if (canceled_label != NULL) {
3142                 OBD_ALLOC_PTR(mti);
3143                 if (mti == NULL)
3144                         GOTO(out, rc = -ENOMEM);
3145         }
3146
3147         /* write pool def to all MDT logs */
3148         for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3149                  if (cfs_test_bit(i,  fsdb->fsdb_mdt_index_map)) {
3150                         name_create_mdt_and_lov(&logname, &lovname, fsdb, i);
3151
3152                         if (canceled_label != NULL) {
3153                                 strcpy(mti->mti_svname, "lov pool");
3154                                 mgs_modify(obd, fsdb, mti, logname, lovname,
3155                                            canceled_label, CM_SKIP);
3156                         }
3157
3158                         mgs_write_log_pool(obd, logname, fsdb, lovname,
3159                                            cmd, fsname, poolname, ostname,
3160                                            label);
3161                         name_destroy(&logname);
3162                         name_destroy(&lovname);
3163                 }
3164         }
3165
3166         name_create(&logname, fsname, "-client");
3167         if (canceled_label != NULL)
3168                 mgs_modify(obd, fsdb, mti, logname, fsdb->fsdb_clilov,
3169                            canceled_label, CM_SKIP);
3170
3171         mgs_write_log_pool(obd, logname, fsdb, fsdb->fsdb_clilov,
3172                            cmd, fsname, poolname, ostname, label);
3173         name_destroy(&logname);
3174
3175         cfs_up(&fsdb->fsdb_sem);
3176         /* request for update */
3177         mgs_revoke_lock(obd, fsdb);
3178
3179         EXIT;
3180 out:
3181         if (label != NULL)
3182                 OBD_FREE(label, label_sz);
3183
3184         if (canceled_label != NULL)
3185                 OBD_FREE(canceled_label, label_sz);
3186
3187         if (mti != NULL)
3188                 OBD_FREE_PTR(mti);
3189
3190         return rc;
3191 }
3192
3193 #if 0
3194 /******************** unused *********************/
3195 static int mgs_backup_llog(struct obd_device *obd, char* fsname)
3196 {
3197         struct file *filp, *bak_filp;
3198         struct lvfs_run_ctxt saved;
3199         char *logname, *buf;
3200         loff_t soff = 0 , doff = 0;
3201         int count = 4096, len;
3202         int rc = 0;
3203
3204         OBD_ALLOC(logname, PATH_MAX);
3205         if (logname == NULL)
3206                 return -ENOMEM;
3207
3208         OBD_ALLOC(buf, count);
3209         if (!buf)
3210                 GOTO(out , rc = -ENOMEM);
3211
3212         len = snprintf(logname, PATH_MAX, "%s/%s.bak",
3213                        MOUNT_CONFIGS_DIR, fsname);
3214
3215         if (len >= PATH_MAX - 1) {
3216                 GOTO(out, -ENAMETOOLONG);
3217         }
3218
3219         push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
3220
3221         bak_filp = l_filp_open(logname, O_RDWR|O_CREAT|O_TRUNC, 0660);
3222         if (IS_ERR(bak_filp)) {
3223                 rc = PTR_ERR(bak_filp);
3224                 CERROR("backup logfile open %s: %d\n", logname, rc);
3225