Whamcloud - gitweb
LU-1347 style: removes obsolete EXPORT_SYMTAB macros
[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, 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         *ptr = sep;
2049         lustre_cfg_free(lcfg);
2050         return rc;
2051 }
2052
2053 static int mgs_srpc_set_param_disk(struct obd_device *obd,
2054                                    struct fs_db *fsdb,
2055                                    struct mgs_target_info *mti,
2056                                    char *param)
2057 {
2058         struct llog_handle     *llh = NULL;
2059         char                   *logname;
2060         char                   *comment, *ptr;
2061         struct lustre_cfg_bufs  bufs;
2062         struct lustre_cfg      *lcfg;
2063         int                     rc, len;
2064         ENTRY;
2065
2066         /* get comment */
2067         ptr = strchr(param, '=');
2068         LASSERT(ptr);
2069         len = ptr - param;
2070
2071         OBD_ALLOC(comment, len + 1);
2072         if (comment == NULL)
2073                 RETURN(-ENOMEM);
2074         strncpy(comment, param, len);
2075         comment[len] = '\0';
2076
2077         /* prepare lcfg */
2078         lustre_cfg_bufs_reset(&bufs, mti->mti_svname);
2079         lustre_cfg_bufs_set_string(&bufs, 1, param);
2080         lcfg = lustre_cfg_new(LCFG_SPTLRPC_CONF, &bufs);
2081         if (lcfg == NULL)
2082                 GOTO(out_comment, rc = -ENOMEM);
2083
2084         /* construct log name */
2085         rc = name_create(&logname, mti->mti_fsname, "-sptlrpc");
2086         if (rc)
2087                 GOTO(out_lcfg, rc);
2088
2089         if (mgs_log_is_empty(obd, logname)) {
2090                 rc = record_start_log(obd, &llh, logname);
2091                 record_end_log(obd, &llh);
2092                 if (rc)
2093                         GOTO(out, rc);
2094         }
2095
2096         /* obsolete old one */
2097         mgs_modify(obd, fsdb, mti, logname, mti->mti_svname, comment, CM_SKIP);
2098
2099         /* write the new one */
2100         rc = mgs_write_log_direct(obd, fsdb, logname, lcfg,
2101                                   mti->mti_svname, comment);
2102         if (rc)
2103                 CERROR("err %d writing log %s\n", rc, logname);
2104
2105 out:
2106         name_destroy(&logname);
2107 out_lcfg:
2108         lustre_cfg_free(lcfg);
2109 out_comment:
2110         OBD_FREE(comment, len + 1);
2111         RETURN(rc);
2112 }
2113
2114 static int mgs_srpc_set_param_udesc_mem(struct fs_db *fsdb,
2115                                         char *param)
2116 {
2117         char    *ptr;
2118
2119         /* disable the adjustable udesc parameter for now, i.e. use default
2120          * setting that client always ship udesc to MDT if possible. to enable
2121          * it simply remove the following line */
2122         goto error_out;
2123
2124         ptr = strchr(param, '=');
2125         if (ptr == NULL)
2126                 goto error_out;
2127         *ptr++ = '\0';
2128
2129         if (strcmp(param, PARAM_SRPC_UDESC))
2130                 goto error_out;
2131
2132         if (strcmp(ptr, "yes") == 0) {
2133                 cfs_set_bit(FSDB_UDESC, &fsdb->fsdb_flags);
2134                 CWARN("Enable user descriptor shipping from client to MDT\n");
2135         } else if (strcmp(ptr, "no") == 0) {
2136                 cfs_clear_bit(FSDB_UDESC, &fsdb->fsdb_flags);
2137                 CWARN("Disable user descriptor shipping from client to MDT\n");
2138         } else {
2139                 *(ptr - 1) = '=';
2140                 goto error_out;
2141         }
2142         return 0;
2143
2144 error_out:
2145         CERROR("Invalid param: %s\n", param);
2146         return -EINVAL;
2147 }
2148
2149 static int mgs_srpc_set_param_mem(struct fs_db *fsdb,
2150                                   const char *svname,
2151                                   char *param)
2152 {
2153         struct sptlrpc_rule      rule;
2154         struct sptlrpc_rule_set *rset;
2155         int                      rc;
2156         ENTRY;
2157
2158         if (strncmp(param, PARAM_SRPC, sizeof(PARAM_SRPC) - 1) != 0) {
2159                 CERROR("Invalid sptlrpc parameter: %s\n", param);
2160                 RETURN(-EINVAL);
2161         }
2162
2163         if (strncmp(param, PARAM_SRPC_UDESC,
2164                     sizeof(PARAM_SRPC_UDESC) - 1) == 0) {
2165                 RETURN(mgs_srpc_set_param_udesc_mem(fsdb, param));
2166         }
2167
2168         if (strncmp(param, PARAM_SRPC_FLVR, sizeof(PARAM_SRPC_FLVR) - 1) != 0) {
2169                 CERROR("Invalid sptlrpc flavor parameter: %s\n", param);
2170                 RETURN(-EINVAL);
2171         }
2172
2173         param += sizeof(PARAM_SRPC_FLVR) - 1;
2174
2175         rc = sptlrpc_parse_rule(param, &rule);
2176         if (rc)
2177                 RETURN(rc);
2178
2179         /* mgs rules implies must be mgc->mgs */
2180         if (cfs_test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
2181                 if ((rule.sr_from != LUSTRE_SP_MGC &&
2182                      rule.sr_from != LUSTRE_SP_ANY) ||
2183                     (rule.sr_to != LUSTRE_SP_MGS &&
2184                      rule.sr_to != LUSTRE_SP_ANY))
2185                         RETURN(-EINVAL);
2186         }
2187
2188         /* preapre room for this coming rule. svcname format should be:
2189          * - fsname: general rule
2190          * - fsname-tgtname: target-specific rule
2191          */
2192         if (strchr(svname, '-')) {
2193                 struct mgs_tgt_srpc_conf *tgtconf;
2194                 int                       found = 0;
2195
2196                 for (tgtconf = fsdb->fsdb_srpc_tgt; tgtconf != NULL;
2197                      tgtconf = tgtconf->mtsc_next) {
2198                         if (!strcmp(tgtconf->mtsc_tgt, svname)) {
2199                                 found = 1;
2200                                 break;
2201                         }
2202                 }
2203
2204                 if (!found) {
2205                         int name_len;
2206
2207                         OBD_ALLOC_PTR(tgtconf);
2208                         if (tgtconf == NULL)
2209                                 RETURN(-ENOMEM);
2210
2211                         name_len = strlen(svname);
2212
2213                         OBD_ALLOC(tgtconf->mtsc_tgt, name_len + 1);
2214                         if (tgtconf->mtsc_tgt == NULL) {
2215                                 OBD_FREE_PTR(tgtconf);
2216                                 RETURN(-ENOMEM);
2217                         }
2218                         memcpy(tgtconf->mtsc_tgt, svname, name_len);
2219
2220                         tgtconf->mtsc_next = fsdb->fsdb_srpc_tgt;
2221                         fsdb->fsdb_srpc_tgt = tgtconf;
2222                 }
2223
2224                 rset = &tgtconf->mtsc_rset;
2225         } else {
2226                 rset = &fsdb->fsdb_srpc_gen;
2227         }
2228
2229         rc = sptlrpc_rule_set_merge(rset, &rule);
2230
2231         RETURN(rc);
2232 }
2233
2234 static int mgs_srpc_set_param(struct obd_device *obd,
2235                               struct fs_db *fsdb,
2236                               struct mgs_target_info *mti,
2237                               char *param)
2238 {
2239         char                   *copy;
2240         int                     rc, copy_size;
2241         ENTRY;
2242
2243 #ifndef HAVE_GSS
2244         RETURN(-EINVAL);
2245 #endif
2246         /* keep a copy of original param, which could be destroied
2247          * during parsing */
2248         copy_size = strlen(param) + 1;
2249         OBD_ALLOC(copy, copy_size);
2250         if (copy == NULL)
2251                 return -ENOMEM;
2252         memcpy(copy, param, copy_size);
2253
2254         rc = mgs_srpc_set_param_mem(fsdb, mti->mti_svname, param);
2255         if (rc)
2256                 goto out_free;
2257
2258         /* previous steps guaranteed the syntax is correct */
2259         rc = mgs_srpc_set_param_disk(obd, fsdb, mti, copy);
2260         if (rc)
2261                 goto out_free;
2262
2263         if (cfs_test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
2264                 /*
2265                  * for mgs rules, make them effective immediately.
2266                  */
2267                 LASSERT(fsdb->fsdb_srpc_tgt == NULL);
2268                 sptlrpc_target_update_exp_flavor(obd, &fsdb->fsdb_srpc_gen);
2269         }
2270
2271 out_free:
2272         OBD_FREE(copy, copy_size);
2273         RETURN(rc);
2274 }
2275
2276 struct mgs_srpc_read_data {
2277         struct fs_db   *msrd_fsdb;
2278         int             msrd_skip;
2279 };
2280
2281 static int mgs_srpc_read_handler(struct llog_handle *llh,
2282                                  struct llog_rec_hdr *rec,
2283                                  void *data)
2284 {
2285         struct mgs_srpc_read_data *msrd = (struct mgs_srpc_read_data *) data;
2286         struct cfg_marker         *marker;
2287         struct lustre_cfg         *lcfg = (struct lustre_cfg *)(rec + 1);
2288         char                      *svname, *param;
2289         int                        cfg_len, rc;
2290         ENTRY;
2291
2292         if (rec->lrh_type != OBD_CFG_REC) {
2293                 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
2294                 RETURN(-EINVAL);
2295         }
2296
2297         cfg_len = rec->lrh_len - sizeof(struct llog_rec_hdr) -
2298                   sizeof(struct llog_rec_tail);
2299
2300         rc = lustre_cfg_sanity_check(lcfg, cfg_len);
2301         if (rc) {
2302                 CERROR("Insane cfg\n");
2303                 RETURN(rc);
2304         }
2305
2306         if (lcfg->lcfg_command == LCFG_MARKER) {
2307                 marker = lustre_cfg_buf(lcfg, 1);
2308
2309                 if (marker->cm_flags & CM_START &&
2310                     marker->cm_flags & CM_SKIP)
2311                         msrd->msrd_skip = 1;
2312                 if (marker->cm_flags & CM_END)
2313                         msrd->msrd_skip = 0;
2314
2315                 RETURN(0);
2316         }
2317
2318         if (msrd->msrd_skip)
2319                 RETURN(0);
2320
2321         if (lcfg->lcfg_command != LCFG_SPTLRPC_CONF) {
2322                 CERROR("invalid command (%x)\n", lcfg->lcfg_command);
2323                 RETURN(0);
2324         }
2325
2326         svname = lustre_cfg_string(lcfg, 0);
2327         if (svname == NULL) {
2328                 CERROR("svname is empty\n");
2329                 RETURN(0);
2330         }
2331
2332         param = lustre_cfg_string(lcfg, 1);
2333         if (param == NULL) {
2334                 CERROR("param is empty\n");
2335                 RETURN(0);
2336         }
2337
2338         rc = mgs_srpc_set_param_mem(msrd->msrd_fsdb, svname, param);
2339         if (rc)
2340                 CERROR("read sptlrpc record error (%d): %s\n", rc, param);
2341
2342         RETURN(0);
2343 }
2344
2345 int mgs_get_fsdb_srpc_from_llog(struct obd_device *obd,
2346                                 struct fs_db *fsdb)
2347 {
2348         struct llog_handle        *llh = NULL;
2349         struct lvfs_run_ctxt       saved;
2350         struct llog_ctxt          *ctxt;
2351         char                      *logname;
2352         struct mgs_srpc_read_data  msrd;
2353         int                        rc;
2354         ENTRY;
2355
2356         /* construct log name */
2357         rc = name_create(&logname, fsdb->fsdb_name, "-sptlrpc");
2358         if (rc)
2359                 RETURN(rc);
2360
2361         ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
2362         LASSERT(ctxt != NULL);
2363
2364         if (mgs_log_is_empty(obd, logname))
2365                 GOTO(out, rc = 0);
2366
2367         push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
2368
2369         rc = llog_create(ctxt, &llh, NULL, logname);
2370         if (rc)
2371                 GOTO(out_pop, rc);
2372
2373         rc = llog_init_handle(llh, LLOG_F_IS_PLAIN, NULL);
2374         if (rc)
2375                 GOTO(out_close, rc);
2376
2377         if (llog_get_size(llh) <= 1)
2378                 GOTO(out_close, rc = 0);
2379
2380         msrd.msrd_fsdb = fsdb;
2381         msrd.msrd_skip = 0;
2382
2383         rc = llog_process(llh, mgs_srpc_read_handler, (void *) &msrd, NULL);
2384
2385 out_close:
2386         llog_close(llh);
2387 out_pop:
2388         pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
2389 out:
2390         llog_ctxt_put(ctxt);
2391         name_destroy(&logname);
2392
2393         if (rc)
2394                 CERROR("failed to read sptlrpc config database: %d\n", rc);
2395         RETURN(rc);
2396 }
2397
2398 /* Permanent settings of all parameters by writing into the appropriate
2399  * configuration logs.
2400  * A parameter with null value ("<param>='\0'") means to erase it out of
2401  * the logs.
2402  */
2403 static int mgs_write_log_param(struct obd_device *obd, struct fs_db *fsdb,
2404                                struct mgs_target_info *mti, char *ptr)
2405 {
2406         struct lustre_cfg_bufs bufs;
2407         char *logname;
2408         char *tmp;
2409         int rc = 0, rc2 = 0;
2410         ENTRY;
2411
2412         /* For various parameter settings, we have to figure out which logs
2413            care about them (e.g. both mdt and client for lov settings) */
2414         CDEBUG(D_MGS, "next param '%s'\n", ptr);
2415
2416         /* The params are stored in MOUNT_DATA_FILE and modified via
2417            tunefs.lustre, or set using lctl conf_param */
2418
2419         /* Processed in lustre_start_mgc */
2420         if (class_match_param(ptr, PARAM_MGSNODE, NULL) == 0)
2421                 GOTO(end, rc);
2422
2423         /* Processed in ost/mdt */
2424         if (class_match_param(ptr, PARAM_NETWORK, NULL) == 0)
2425                 GOTO(end, rc);
2426
2427         /* Processed in mgs_write_log_ost */
2428         if (class_match_param(ptr, PARAM_FAILMODE, NULL) == 0) {
2429                 if (mti->mti_flags & LDD_F_PARAM) {
2430                         LCONSOLE_ERROR_MSG(0x169, "%s can only be "
2431                                            "changed with tunefs.lustre"
2432                                            "and --writeconf\n", ptr);
2433                         rc = -EPERM;
2434                 }
2435                 GOTO(end, rc);
2436         }
2437
2438         if (class_match_param(ptr, PARAM_SRPC, NULL) == 0) {
2439                 rc = mgs_srpc_set_param(obd, fsdb, mti, ptr);
2440                 GOTO(end, rc);
2441         }
2442
2443         if (class_match_param(ptr, PARAM_FAILNODE, NULL) == 0) {
2444                 /* Add a failover nidlist */
2445                 rc = 0;
2446                 /* We already processed failovers params for new
2447                    targets in mgs_write_log_target */
2448                 if (mti->mti_flags & LDD_F_PARAM) {
2449                         CDEBUG(D_MGS, "Adding failnode\n");
2450                         rc = mgs_write_log_add_failnid(obd, fsdb, mti);
2451                 }
2452                 GOTO(end, rc);
2453         }
2454
2455         if (class_match_param(ptr, PARAM_SYS, &tmp) == 0) {
2456                 rc = mgs_write_log_sys(obd, fsdb, mti, ptr, tmp);
2457                 GOTO(end, rc);
2458         }
2459
2460         if (class_match_param(ptr, PARAM_OSC""PARAM_ACTIVE, &tmp) == 0) {
2461                 /* active=0 means off, anything else means on */
2462                 int flag = (*tmp == '0') ? CM_EXCLUDE : 0;
2463                 int i;
2464
2465                 if (!(mti->mti_flags & LDD_F_SV_TYPE_OST)) {
2466                         LCONSOLE_ERROR_MSG(0x144, "%s: Only OSCs can "
2467                                            "be (de)activated.\n",
2468                                            mti->mti_svname);
2469                         GOTO(end, rc = -EINVAL);
2470                 }
2471                 LCONSOLE_WARN("Permanently %sactivating %s\n",
2472                               flag ? "de": "re", mti->mti_svname);
2473                 /* Modify clilov */
2474                 name_create(&logname, mti->mti_fsname, "-client");
2475                 rc = mgs_modify(obd, fsdb, mti, logname,
2476                                 mti->mti_svname, "add osc", flag);
2477                 name_destroy(&logname);
2478                 if (rc)
2479                         goto active_err;
2480                 /* Modify mdtlov */
2481                 /* Add to all MDT logs for CMD */
2482                 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2483                         if (!cfs_test_bit(i, fsdb->fsdb_mdt_index_map))
2484                                 continue;
2485                         name_create_mdt(&logname, mti->mti_fsname, i);
2486                         rc = mgs_modify(obd, fsdb, mti, logname,
2487                                         mti->mti_svname, "add osc", flag);
2488                         name_destroy(&logname);
2489                         if (rc)
2490                                 goto active_err;
2491                 }
2492         active_err:
2493                 if (rc) {
2494                         LCONSOLE_ERROR_MSG(0x145, "Couldn't find %s in"
2495                                            "log (%d). No permanent "
2496                                            "changes were made to the "
2497                                            "config log.\n",
2498                                            mti->mti_svname, rc);
2499                         if (cfs_test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags))
2500                                 LCONSOLE_ERROR_MSG(0x146, "This may be"
2501                                                    " because the log"
2502                                                    "is in the old 1.4"
2503                                                    "style. Consider "
2504                                                    " --writeconf to "
2505                                                    "update the logs.\n");
2506                         GOTO(end, rc);
2507                 }
2508                 /* Fall through to osc proc for deactivating live OSC
2509                    on running MDT / clients. */
2510         }
2511         /* Below here, let obd's XXX_process_config methods handle it */
2512
2513         /* All lov. in proc */
2514         if (class_match_param(ptr, PARAM_LOV, NULL) == 0) {
2515                 char *mdtlovname;
2516
2517                 CDEBUG(D_MGS, "lov param %s\n", ptr);
2518                 if (!(mti->mti_flags & LDD_F_SV_TYPE_MDT)) {
2519                         LCONSOLE_ERROR_MSG(0x147, "LOV params must be "
2520                                            "set on the MDT, not %s. "
2521                                            "Ignoring.\n",
2522                                            mti->mti_svname);
2523                         GOTO(end, rc = 0);
2524                 }
2525
2526                 /* Modify mdtlov */
2527                 if (mgs_log_is_empty(obd, mti->mti_svname))
2528                         GOTO(end, rc = -ENODEV);
2529
2530                 name_create_mdt_and_lov(&logname, &mdtlovname, fsdb,
2531                                         mti->mti_stripe_index);
2532                 rc = mgs_wlp_lcfg(obd, fsdb, mti, mti->mti_svname,
2533                                   &bufs, mdtlovname, ptr);
2534                 name_destroy(&logname);
2535                 name_destroy(&mdtlovname);
2536                 if (rc)
2537                         GOTO(end, rc);
2538
2539                 /* Modify clilov */
2540                 name_create(&logname, mti->mti_fsname, "-client");
2541                 rc = mgs_wlp_lcfg(obd, fsdb, mti, logname, &bufs,
2542                                   fsdb->fsdb_clilov, ptr);
2543                 name_destroy(&logname);
2544                 GOTO(end, rc);
2545         }
2546
2547         /* All osc., mdc., llite. params in proc */
2548         if ((class_match_param(ptr, PARAM_OSC, NULL) == 0) ||
2549             (class_match_param(ptr, PARAM_MDC, NULL) == 0) ||
2550             (class_match_param(ptr, PARAM_LLITE, NULL) == 0)) {
2551                 char *cname;
2552                 if (memcmp(ptr, PARAM_LLITE, strlen(PARAM_LLITE)) == 0) {
2553                         name_create(&cname, mti->mti_fsname, "-client");
2554                         /* Add the client type to match the obdname in
2555                            class_config_llog_handler */
2556                 } else if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
2557                         /* COMPAT_146 */
2558                         if (fsdb->fsdb_mdc)
2559                                 name_create(&cname, fsdb->fsdb_mdc, "");
2560                         else
2561                                 name_create(&cname, mti->mti_svname,
2562                                             "-mdc");
2563                 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2564                         /* COMPAT_146 */
2565                         if (cfs_test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
2566                                 LCONSOLE_ERROR_MSG(0x148, "Upgraded "
2567                                                    "client logs for %s"
2568                                                    " cannot be "
2569                                                    "modified. Consider"
2570                                                    " updating the "
2571                                                    "configuration with"
2572                                                    " --writeconf\n",
2573                                                    mti->mti_svname);
2574                                 /* We don't know the names of all the
2575                                    old oscs*/
2576                                 GOTO(end, rc = -EINVAL);
2577                         }
2578                         name_create(&cname, mti->mti_svname, "-osc");
2579                 } else {
2580                         GOTO(end, rc = -EINVAL);
2581                 }
2582
2583                 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
2584
2585                 /* Modify client */
2586                 name_create(&logname, mti->mti_fsname, "-client");
2587                 rc = mgs_wlp_lcfg(obd, fsdb, mti, logname, &bufs,
2588                                   cname, ptr);
2589
2590                 /* osc params affect the MDT as well */
2591                 if (!rc && (mti->mti_flags & LDD_F_SV_TYPE_OST)) {
2592                         int i;
2593
2594                         for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
2595                                 if (!cfs_test_bit(i, fsdb->fsdb_mdt_index_map))
2596                                         continue;
2597                                 name_destroy(&cname);
2598                                 name_create_mdt_osc(&cname, mti->mti_svname,
2599                                                     fsdb, i);
2600                                 name_destroy(&logname);
2601                                 name_create_mdt(&logname, mti->mti_fsname, i);
2602                                 if (!mgs_log_is_empty(obd, logname))
2603                                         rc = mgs_wlp_lcfg(obd, fsdb,mti,logname,
2604                                                           &bufs, cname, ptr);
2605                                 if (rc)
2606                                         break;
2607                         }
2608                 }
2609                 name_destroy(&logname);
2610                 name_destroy(&cname);
2611                 GOTO(end, rc);
2612         }
2613
2614         /* All mdt. params in proc */
2615         if (class_match_param(ptr, PARAM_MDT, NULL) == 0) {
2616                 int i;
2617                 __u32 idx;
2618
2619                 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
2620                 if (strncmp(mti->mti_svname, mti->mti_fsname,
2621                             MTI_NAME_MAXLEN) == 0)
2622                         /* device is unspecified completely? */
2623                         rc = LDD_F_SV_TYPE_MDT | LDD_F_SV_ALL;
2624                 else
2625                         rc = server_name2index(mti->mti_svname, &idx, NULL);
2626                 if (rc < 0)
2627                         goto active_err;
2628                 if ((rc & LDD_F_SV_TYPE_MDT) == 0)
2629                         goto active_err;
2630                 if (rc & LDD_F_SV_ALL) {
2631                         for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
2632                                 if (!cfs_test_bit(i,
2633                                                   fsdb->fsdb_mdt_index_map))
2634                                         continue;
2635                                 name_create_mdt(&logname, mti->mti_fsname, i);
2636                                 rc = mgs_wlp_lcfg(obd, fsdb, mti,
2637                                                   logname, &bufs,
2638                                                   logname, ptr);
2639                                 name_destroy(&logname);
2640                                 if (rc)
2641                                         goto active_err;
2642                         }
2643                 } else {
2644                         rc = mgs_wlp_lcfg(obd, fsdb, mti,
2645                                           mti->mti_svname, &bufs,
2646                                           mti->mti_svname, ptr);
2647                         if (rc)
2648                                 goto active_err;
2649                 }
2650                 GOTO(end, rc);
2651         }
2652
2653         /* All mdd., ost. params in proc */
2654         if ((class_match_param(ptr, PARAM_MDD, NULL) == 0) ||
2655             (class_match_param(ptr, PARAM_OST, NULL) == 0)) {
2656                 CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
2657                 if (mgs_log_is_empty(obd, mti->mti_svname))
2658                         GOTO(end, rc = -ENODEV);
2659
2660                 rc = mgs_wlp_lcfg(obd, fsdb, mti, mti->mti_svname,
2661                                   &bufs, mti->mti_svname, ptr);
2662                 GOTO(end, rc);
2663         }
2664
2665         LCONSOLE_WARN("Ignoring unrecognized param '%s'\n", ptr);
2666         rc2 = -ENOSYS;
2667
2668 end:
2669         if (rc)
2670                 CERROR("err %d on param '%s'\n", rc, ptr);
2671
2672         RETURN(rc ?: rc2);
2673 }
2674
2675 /* Not implementing automatic failover nid addition at this time. */
2676 int mgs_check_failnid(struct obd_device *obd, struct mgs_target_info *mti)
2677 {
2678 #if 0
2679         struct fs_db *fsdb;
2680         int rc;
2681         ENTRY;
2682
2683         rc = mgs_find_or_make_fsdb(obd, fsname, &fsdb);
2684         if (rc)
2685                 RETURN(rc);
2686
2687         if (mgs_log_is_empty(obd, mti->mti_svname))
2688                 /* should never happen */
2689                 RETURN(-ENOENT);
2690
2691         CDEBUG(D_MGS, "Checking for new failnids for %s\n", mti->mti_svname);
2692
2693         /* FIXME We can just check mti->params to see if we're already in
2694            the failover list.  Modify mti->params for rewriting back at
2695            server_register_target(). */
2696
2697         cfs_mutex_lock(&fsdb->fsdb_mutex);
2698         rc = mgs_write_log_add_failnid(obd, fsdb, mti);
2699         cfs_mutex_unlock(&fsdb->fsdb_mutex);
2700
2701         RETURN(rc);
2702 #endif
2703         return 0;
2704 }
2705
2706 int mgs_write_log_target(struct obd_device *obd,
2707                          struct mgs_target_info *mti,
2708                          struct fs_db *fsdb)
2709 {
2710         int rc = -EINVAL;
2711         char *buf, *params;
2712         ENTRY;
2713
2714         /* set/check the new target index */
2715         rc = mgs_set_index(obd, mti);
2716         if (rc < 0) {
2717                 CERROR("Can't get index (%d)\n", rc);
2718                 RETURN(rc);
2719         }
2720
2721         /* COMPAT_146 */
2722         if (mti->mti_flags & LDD_F_UPGRADE14) {
2723                 if (rc == EALREADY) {
2724                         LCONSOLE_INFO("Found index %d for %s 1.4 log, "
2725                                       "upgrading\n", mti->mti_stripe_index,
2726                                       mti->mti_svname);
2727                 } else {
2728                         LCONSOLE_ERROR_MSG(0x149, "Failed to find %s in the old"
2729                                            " client log. Apparently it is not "
2730                                            "part of this filesystem, or the old"
2731                                            " log is wrong.\nUse 'writeconf' on "
2732                                            "the MDT to force log regeneration."
2733                                            "\n", mti->mti_svname);
2734                         /* Not in client log?  Upgrade anyhow...*/
2735                         /* Argument against upgrading: reformat MDT,
2736                            upgrade OST, then OST will start but will be SKIPped
2737                            in client logs.  Maybe error now is better. */
2738                         /* RETURN(-EINVAL); */
2739                 }
2740                 /* end COMPAT_146 */
2741         } else {
2742                 if (rc == EALREADY) {
2743                         LCONSOLE_WARN("Found index %d for %s, updating log\n",
2744                                       mti->mti_stripe_index, mti->mti_svname);
2745                         /* We would like to mark old log sections as invalid
2746                            and add new log sections in the client and mdt logs.
2747                            But if we add new sections, then live clients will
2748                            get repeat setup instructions for already running
2749                            osc's. So don't update the client/mdt logs. */
2750                         mti->mti_flags &= ~LDD_F_UPDATE;
2751                 }
2752         }
2753
2754         cfs_mutex_lock(&fsdb->fsdb_mutex);
2755
2756         if (mti->mti_flags &
2757             (LDD_F_VIRGIN | LDD_F_UPGRADE14 | LDD_F_WRITECONF)) {
2758                 /* Generate a log from scratch */
2759                 if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
2760                         rc = mgs_write_log_mdt(obd, fsdb, mti);
2761                 } else if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
2762                         rc = mgs_write_log_ost(obd, fsdb, mti);
2763                 } else {
2764                         CERROR("Unknown target type %#x, can't create log for "
2765                                "%s\n", mti->mti_flags, mti->mti_svname);
2766                 }
2767                 if (rc) {
2768                         CERROR("Can't write logs for %s (%d)\n",
2769                                mti->mti_svname, rc);
2770                         GOTO(out_up, rc);
2771                 }
2772         } else {
2773                 /* Just update the params from tunefs in mgs_write_log_params */
2774                 CDEBUG(D_MGS, "Update params for %s\n", mti->mti_svname);
2775                 mti->mti_flags |= LDD_F_PARAM;
2776         }
2777
2778         /* allocate temporary buffer, where class_get_next_param will
2779            make copy of a current  parameter */
2780         OBD_ALLOC(buf, strlen(mti->mti_params) + 1);
2781         if (buf == NULL)
2782                 GOTO(out_up, rc = -ENOMEM);
2783         params = mti->mti_params;
2784         while (params != NULL) {
2785                 rc = class_get_next_param(&params, buf);
2786                 if (rc) {
2787                         if (rc == 1)
2788                                 /* there is no next parameter, that is
2789                                    not an error */
2790                                 rc = 0;
2791                         break;
2792                 }
2793                 CDEBUG(D_MGS, "remaining string: '%s', param: '%s'\n",
2794                        params, buf);
2795                 rc = mgs_write_log_param(obd, fsdb, mti, buf);
2796                 if (rc)
2797                         break;
2798         }
2799
2800         OBD_FREE(buf, strlen(mti->mti_params) + 1);
2801
2802 out_up:
2803         cfs_mutex_unlock(&fsdb->fsdb_mutex);
2804         RETURN(rc);
2805 }
2806
2807 /* COMPAT_146 */
2808 /* verify that we can handle the old config logs */
2809 int mgs_upgrade_sv_14(struct obd_device *obd, struct mgs_target_info *mti,
2810                       struct fs_db *fsdb)
2811 {
2812         int rc = 0;
2813         ENTRY;
2814
2815         /* Create ost log normally, as servers register.  Servers
2816            register with their old uuids (from last_rcvd), so old
2817            (MDT and client) logs should work.
2818          - new MDT won't know about old OSTs, only the ones that have
2819            registered, so we need the old MDT log to get the LOV right
2820            in order for old clients to work.
2821          - Old clients connect to the MDT, not the MGS, for their logs, and
2822            will therefore receive the old client log from the MDT /LOGS dir.
2823          - Old clients can continue to use and connect to old or new OSTs
2824          - New clients will contact the MGS for their log
2825         */
2826
2827         LCONSOLE_INFO("upgrading server %s from pre-1.6\n", mti->mti_svname);
2828         server_mti_print("upgrade", mti);
2829
2830         if (cfs_test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
2831                 LCONSOLE_ERROR_MSG(0x14a, "The old client log %s-client is "
2832                                    "missing.  Was tunefs.lustre successful?\n",
2833                                    mti->mti_fsname);
2834                 RETURN(-ENOENT);
2835         }
2836
2837         if (fsdb->fsdb_gen == 0) {
2838                 /* There were no markers in the client log, meaning we have
2839                    not updated the logs for this fs */
2840                 CDEBUG(D_MGS, "found old, unupdated client log\n");
2841         }
2842
2843         if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
2844                 if (mgs_log_is_empty(obd, mti->mti_svname)) {
2845                         LCONSOLE_ERROR_MSG(0x14b, "The old MDT log %s is "
2846                                            "missing. Was tunefs.lustre "
2847                                            "successful?\n",
2848                                            mti->mti_svname);
2849                         RETURN(-ENOENT);
2850                 }
2851                 /* We're starting with an old uuid.  Assume old name for lov
2852                    as well since the lov entry already exists in the log. */
2853                 CDEBUG(D_MGS, "old mds uuid %s\n", mti->mti_uuid);
2854                 if (strncmp(mti->mti_uuid, fsdb->fsdb_mdtlov + 4,
2855                             strlen(fsdb->fsdb_mdtlov) - 4) != 0) {
2856                         CERROR("old mds uuid %s doesn't match log %s (%s)\n",
2857                                mti->mti_uuid, fsdb->fsdb_mdtlov,
2858                                fsdb->fsdb_mdtlov + 4);
2859                         RETURN(-EINVAL);
2860                 }
2861         }
2862
2863         if (!cfs_test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
2864                 LCONSOLE_ERROR_MSG(0x14c, "%s-client is supposedly an old "
2865                                    "log, but no old LOV or MDT was found. "
2866                                    "Consider updating the configuration with"
2867                                    " --writeconf.\n", mti->mti_fsname);
2868         }
2869
2870         RETURN(rc);
2871 }
2872 /* end COMPAT_146 */
2873
2874 int mgs_erase_log(struct obd_device *obd, char *name)
2875 {
2876         struct lvfs_run_ctxt saved;
2877         struct llog_ctxt *ctxt;
2878         struct llog_handle *llh;
2879         int rc = 0;
2880
2881         ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
2882         LASSERT(ctxt != NULL);
2883
2884         push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
2885         rc = llog_create(ctxt, &llh, NULL, name);
2886         if (rc == 0) {
2887                 llog_init_handle(llh, LLOG_F_IS_PLAIN, NULL);
2888                 rc = llog_destroy(llh);
2889                 llog_free_handle(llh);
2890         }
2891         pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
2892         llog_ctxt_put(ctxt);
2893
2894         if (rc)
2895                 CERROR("failed to clear log %s: %d\n", name, rc);
2896
2897         return(rc);
2898 }
2899
2900 /* erase all logs for the given fs */
2901 int mgs_erase_logs(struct obd_device *obd, char *fsname)
2902 {
2903         struct mgs_obd *mgs = &obd->u.mgs;
2904         struct fs_db *fsdb;
2905         cfs_list_t dentry_list;
2906         struct l_linux_dirent *dirent, *n;
2907         int rc, len = strlen(fsname);
2908         char *suffix;
2909         ENTRY;
2910
2911         /* Find all the logs in the CONFIGS directory */
2912         rc = class_dentry_readdir(obd, mgs->mgs_configs_dir,
2913                                   mgs->mgs_vfsmnt, &dentry_list);
2914         if (rc) {
2915                 CERROR("Can't read %s dir\n", MOUNT_CONFIGS_DIR);
2916                 RETURN(rc);
2917         }
2918
2919         cfs_mutex_lock(&mgs->mgs_mutex);
2920
2921         /* Delete the fs db */
2922         fsdb = mgs_find_fsdb(obd, fsname);
2923         if (fsdb)
2924                 mgs_free_fsdb(obd, fsdb);
2925
2926         cfs_list_for_each_entry_safe(dirent, n, &dentry_list, lld_list) {
2927                 cfs_list_del(&dirent->lld_list);
2928                 suffix = strrchr(dirent->lld_name, '-');
2929                 if (suffix != NULL) {
2930                         if ((len == suffix - dirent->lld_name) &&
2931                             (strncmp(fsname, dirent->lld_name, len) == 0)) {
2932                                 CDEBUG(D_MGS, "Removing log %s\n",
2933                                        dirent->lld_name);
2934                                 mgs_erase_log(obd, dirent->lld_name);
2935                         }
2936                 }
2937                 OBD_FREE(dirent, sizeof(*dirent));
2938         }
2939
2940         cfs_mutex_unlock(&mgs->mgs_mutex);
2941
2942         RETURN(rc);
2943 }
2944
2945 /* from llog_swab */
2946 static void print_lustre_cfg(struct lustre_cfg *lcfg)
2947 {
2948         int i;
2949         ENTRY;
2950
2951         CDEBUG(D_MGS, "lustre_cfg: %p\n", lcfg);
2952         CDEBUG(D_MGS, "\tlcfg->lcfg_version: %#x\n", lcfg->lcfg_version);
2953
2954         CDEBUG(D_MGS, "\tlcfg->lcfg_command: %#x\n", lcfg->lcfg_command);
2955         CDEBUG(D_MGS, "\tlcfg->lcfg_num: %#x\n", lcfg->lcfg_num);
2956         CDEBUG(D_MGS, "\tlcfg->lcfg_flags: %#x\n", lcfg->lcfg_flags);
2957         CDEBUG(D_MGS, "\tlcfg->lcfg_nid: %s\n", libcfs_nid2str(lcfg->lcfg_nid));
2958
2959         CDEBUG(D_MGS, "\tlcfg->lcfg_bufcount: %d\n", lcfg->lcfg_bufcount);
2960         if (lcfg->lcfg_bufcount < LUSTRE_CFG_MAX_BUFCOUNT)
2961                 for (i = 0; i < lcfg->lcfg_bufcount; i++) {
2962                         CDEBUG(D_MGS, "\tlcfg->lcfg_buflens[%d]: %d %s\n",
2963                                i, lcfg->lcfg_buflens[i],
2964                                lustre_cfg_string(lcfg, i));
2965                 }
2966         EXIT;
2967 }
2968
2969 /* Set a permanent (config log) param for a target or fs
2970  * \param lcfg buf0 may contain the device (testfs-MDT0000) name
2971  *             buf1 contains the single parameter
2972  */
2973 int mgs_setparam(struct obd_device *obd, struct lustre_cfg *lcfg, char *fsname)
2974 {
2975         struct fs_db *fsdb;
2976         struct mgs_target_info *mti;
2977         char *devname, *param;
2978         char *ptr, *tmp;
2979         __u32 index;
2980         int rc = 0;
2981         ENTRY;
2982
2983         print_lustre_cfg(lcfg);
2984
2985         /* lustre, lustre-mdtlov, lustre-client, lustre-MDT0000 */
2986         devname = lustre_cfg_string(lcfg, 0);
2987         param = lustre_cfg_string(lcfg, 1);
2988         if (!devname) {
2989                 /* Assume device name embedded in param:
2990                    lustre-OST0000.osc.max_dirty_mb=32 */
2991                 ptr = strchr(param, '.');
2992                 if (ptr) {
2993                         devname = param;
2994                         *ptr = 0;
2995                         param = ptr + 1;
2996                 }
2997         }
2998         if (!devname) {
2999                 LCONSOLE_ERROR_MSG(0x14d, "No target specified: %s\n", param);
3000                 RETURN(-ENOSYS);
3001         }
3002
3003         /* Extract fsname */
3004         ptr = strrchr(devname, '-');
3005         memset(fsname, 0, MTI_NAME_MAXLEN);
3006         if (ptr && (server_name2index(ptr, &index, NULL) >= 0)) {
3007                 /* param related to llite isn't allowed to set by OST or MDT */
3008                 if (strncmp(param, PARAM_LLITE, sizeof(PARAM_LLITE)) == 0)
3009                         RETURN(-EINVAL);
3010
3011                 strncpy(fsname, devname, ptr - devname);
3012         } else {
3013                 /* assume devname is the fsname */
3014                 strncpy(fsname, devname, MTI_NAME_MAXLEN);
3015         }
3016         fsname[MTI_NAME_MAXLEN - 1] = 0;
3017         CDEBUG(D_MGS, "setparam fs='%s' device='%s'\n", fsname, devname);
3018
3019         rc = mgs_find_or_make_fsdb(obd, fsname, &fsdb);
3020         if (rc)
3021                 RETURN(rc);
3022         if (!cfs_test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags) &&
3023             cfs_test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
3024                 CERROR("No filesystem targets for %s.  cfg_device from lctl "
3025                        "is '%s'\n", fsname, devname);
3026                 mgs_free_fsdb(obd, fsdb);
3027                 RETURN(-EINVAL);
3028         }
3029
3030         /* Create a fake mti to hold everything */
3031         OBD_ALLOC_PTR(mti);
3032         if (!mti)
3033                 GOTO(out, rc = -ENOMEM);
3034         strncpy(mti->mti_fsname, fsname, MTI_NAME_MAXLEN);
3035         strncpy(mti->mti_svname, devname, MTI_NAME_MAXLEN);
3036         strncpy(mti->mti_params, param, sizeof(mti->mti_params));
3037         rc = server_name2index(mti->mti_svname, &mti->mti_stripe_index, &tmp);
3038         if (rc < 0)
3039                 /* Not a valid server; may be only fsname */
3040                 rc = 0;
3041         else
3042                 /* Strip -osc or -mdc suffix from svname */
3043                 if (server_make_name(rc, mti->mti_stripe_index, mti->mti_fsname,
3044                                      mti->mti_svname))
3045                         GOTO(out, rc = -EINVAL);
3046
3047         mti->mti_flags = rc | LDD_F_PARAM;
3048
3049         cfs_mutex_lock(&fsdb->fsdb_mutex);
3050         rc = mgs_write_log_param(obd, fsdb, mti, mti->mti_params);
3051         cfs_mutex_unlock(&fsdb->fsdb_mutex);
3052
3053         /*
3054          * Revoke lock so everyone updates.  Should be alright if
3055          * someone was already reading while we were updating the logs,
3056          * so we don't really need to hold the lock while we're
3057          * writing (above).
3058          */
3059         mgs_revoke_lock(obd, fsdb, CONFIG_T_CONFIG);
3060 out:
3061         OBD_FREE_PTR(mti);
3062         RETURN(rc);
3063 }
3064
3065 static int mgs_write_log_pool(struct obd_device *obd, char *logname,
3066                               struct fs_db *fsdb, char *lovname,
3067                               enum lcfg_command_type cmd,
3068                               char *poolname, char *fsname,
3069                               char *ostname, char *comment)
3070 {
3071         struct llog_handle *llh = NULL;
3072         int rc;
3073
3074         rc = record_start_log(obd, &llh, logname);
3075         if (rc)
3076                 return rc;
3077         rc = record_marker(obd, llh, fsdb, CM_START, lovname, comment);
3078         record_base(obd, llh, lovname, 0, cmd, poolname, fsname, ostname, 0);
3079         rc = record_marker(obd, llh, fsdb, CM_END, lovname, comment);
3080         rc = record_end_log(obd, &llh);
3081
3082         return rc;
3083 }
3084
3085 int mgs_pool_cmd(struct obd_device *obd, enum lcfg_command_type cmd,
3086                  char *fsname, char *poolname, char *ostname)
3087 {
3088         struct fs_db *fsdb;
3089         char *lovname;
3090         char *logname;
3091         char *label = NULL, *canceled_label = NULL;
3092         int label_sz;
3093         struct mgs_target_info *mti = NULL;
3094         int rc, i;
3095         ENTRY;
3096
3097         rc = mgs_find_or_make_fsdb(obd, fsname, &fsdb);
3098         if (rc) {
3099                 CERROR("Can't get db for %s\n", fsname);
3100                 RETURN(rc);
3101         }
3102         if (cfs_test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
3103                 CERROR("%s is not defined\n", fsname);
3104                 mgs_free_fsdb(obd, fsdb);
3105                 RETURN(-EINVAL);
3106         }
3107
3108         label_sz = 10 + strlen(fsname) + strlen(poolname);
3109
3110         /* check if ostname match fsname */
3111         if (ostname != NULL) {
3112                 char *ptr;
3113
3114                 ptr = strrchr(ostname, '-');
3115                 if ((ptr == NULL) ||
3116                     (strncmp(fsname, ostname, ptr-ostname) != 0))
3117                         RETURN(-EINVAL);
3118                 label_sz += strlen(ostname);
3119         }
3120
3121         OBD_ALLOC(label, label_sz);
3122         if (label == NULL)
3123                 GOTO(out, rc = -ENOMEM);
3124
3125         switch(cmd) {
3126         case LCFG_POOL_NEW: {
3127                 sprintf(label,
3128                         "new %s.%s", fsname, poolname);
3129                 break;
3130         }
3131         case LCFG_POOL_ADD: {
3132                 sprintf(label,
3133                         "add %s.%s.%s", fsname, poolname, ostname);
3134                 break;
3135         }
3136         case LCFG_POOL_REM: {
3137                 OBD_ALLOC(canceled_label, label_sz);
3138                 if (canceled_label == NULL)
3139                          GOTO(out, rc = -ENOMEM);
3140                 sprintf(label,
3141                         "rem %s.%s.%s", fsname, poolname, ostname);
3142                 sprintf(canceled_label,
3143                         "add %s.%s.%s", fsname, poolname, ostname);
3144                 break;
3145         }
3146         case LCFG_POOL_DEL: {
3147                 OBD_ALLOC(canceled_label, label_sz);
3148                 if (canceled_label == NULL)
3149                          GOTO(out, rc = -ENOMEM);
3150                 sprintf(label,
3151                         "del %s.%s", fsname, poolname);
3152                 sprintf(canceled_label,
3153                         "new %s.%s", fsname, poolname);
3154                 break;
3155         }
3156         default: {
3157                 break;
3158         }
3159         }
3160
3161         cfs_mutex_lock(&fsdb->fsdb_mutex);
3162
3163         if (canceled_label != NULL) {
3164                 OBD_ALLOC_PTR(mti);
3165                 if (mti == NULL)
3166                         GOTO(out, rc = -ENOMEM);
3167         }
3168
3169         /* write pool def to all MDT logs */
3170         for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
3171                  if (cfs_test_bit(i,  fsdb->fsdb_mdt_index_map)) {
3172                         name_create_mdt_and_lov(&logname, &lovname, fsdb, i);
3173
3174                         if (canceled_label != NULL) {
3175                                 strcpy(mti->mti_svname, "lov pool");
3176                                 mgs_modify(obd, fsdb, mti, logname, lovname,
3177                                            canceled_label, CM_SKIP);
3178                         }
3179
3180                         mgs_write_log_pool(obd, logname, fsdb, lovname,
3181                                            cmd, fsname, poolname, ostname,
3182                                            label);
3183                         name_destroy(&logname);
3184                         name_destroy(&lovname);
3185                 }
3186         }
3187
3188         name_create(&logname, fsname, "-client");
3189         if (canceled_label != NULL)
3190                 mgs_modify(obd, fsdb, mti, logname, fsdb->fsdb_clilov,
3191                            canceled_label, CM_SKIP);
3192
3193         mgs_write_log_pool(obd, logname, fsdb, fsdb->fsdb_clilov,
3194                            cmd, fsname, poolname, ostname, label);
3195         name_destroy(&logname);
3196
3197         cfs_mutex_unlock(&fsdb->fsdb_mutex);
3198         /* request for update */
3199         mgs_revoke_lock(obd, fsdb, CONFIG_T_CONFIG);
3200
3201         EXIT;
3202 out:
3203         if (label != NULL)
3204                 OBD_FREE(label, label_sz);
3205
3206         if (canceled_label != NULL)
3207                 OBD_FREE(canceled_label, label_sz);
3208
3209         if (mti != NULL)
3210                 OBD_FREE_PTR(mti);
3211
3212         return rc;
3213 }
3214
3215 #if 0
3216 /******************** unused *********************/
3217 static int mgs_backup_llog(struct obd_device *obd, char* fsname)
3218 {
3219         struct file *filp, *bak_filp;
3220         struct lvfs_run_ctxt saved;
3221         char *logname, *buf;
3222         loff_t soff = 0 , doff = 0;
3223         int count = 4096, len;
3224         int rc = 0;
3225
3226         OBD_ALLOC(logname, PATH_MAX);
3227         if (logname == NULL)
3228                 return -ENOMEM;
3229
3230         OBD_ALLOC(buf, count);
3231         if (!buf)
3232                 GOTO(out , rc = -ENOMEM);
3233
3234         len = snprintf(logname, PATH_MAX, "%s/%s.bak",
3235                        MOUNT_CONFIGS_DIR, fsname);
3236
3237         if (len >= PATH_MAX - 1) {
3238                 GOTO(out, -ENAMETOOLONG);
3239         }
3240
3241         push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
3242
3243         bak_filp = l_filp_open(logname, O_RDWR|O_CREAT|O_TRUNC, 0660);
3244         if (IS_ERR(bak_filp)) {
3245                 rc = PTR_ERR(bak_filp);
3246                 CERROR("backup logfile open %s: %d\n", logname, rc);
3247                 GOTO(pop, rc);
3248         }
3249         sprintf(logname, "%s/%s", MOUNT_CONFIGS_DIR, fsname);
3250         filp = l_filp_open(logname, O_RDONLY, 0);
3251         if (IS_ERR(filp)) {
3252                 rc = PTR_ERR(filp);
3253                 CERROR("logfile open %s: %d\n", logname, rc);
3254                 GOTO(close1f, rc);
3255         }
3256
3257         while ((rc = lustre_fread(filp, buf, count, &soff)) > 0) {
3258                 rc = lustre_fwrite(bak_filp, buf, count, &doff);
3259                 break;
3260         }
3261
3262         filp_close(filp, 0);
3263 close1f:
3264         filp_close(bak_filp, 0);
3265 pop:
3266         pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
3267 out:
3268         if (buf)
3269                 OBD_FREE(buf, count);
3270         OBD_FREE(logname, PATH_MAX);
3271         return rc;
3272 }
3273
3274 #endif