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