Whamcloud - gitweb
Branch: HEAD
[fs/lustre-release.git] / lustre / obdclass / obd_config.c
1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=8:tabstop=8:
3  *
4  *  Copyright (c) 2001-2003 Cluster File Systems, Inc.
5  *
6  *   This file is part of Lustre, http://www.lustre.org.
7  *
8  *   Lustre is free software; you can redistribute it and/or
9  *   modify it under the terms of version 2 of the GNU General Public
10  *   License as published by the Free Software Foundation.
11  *
12  *   Lustre is distributed in the hope that it will be useful,
13  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  *   GNU General Public License for more details.
16  *
17  *   You should have received a copy of the GNU General Public License
18  *   along with Lustre; if not, write to the Free Software
19  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20  *
21  * Config API
22  *
23  */
24
25 #define DEBUG_SUBSYSTEM S_CLASS
26 #ifdef __KERNEL__
27 #include <linux/kmod.h>   /* for request_module() */
28 #include <linux/module.h>
29 #include <linux/obd_class.h>
30 #include <linux/random.h>
31 #include <linux/slab.h>
32 #include <linux/pagemap.h>
33 #else
34 #include <liblustre.h>
35 #include <linux/obd_class.h>
36 #include <linux/obd.h>
37 #endif
38 #include <linux/lustre_log.h>
39 #include <linux/lprocfs_status.h>
40 #include <libcfs/list.h>
41
42
43 /* Create a new device and set the type, name and uuid.  If
44  * successful, the new device can be accessed by either name or uuid.
45  */
46 static int class_attach(struct lustre_cfg *lcfg)
47 {
48         struct obd_type *type;
49         struct obd_device *obd;
50         char *typename, *name, *uuid;
51         int rc, len, cleanup_phase = 0;
52
53         if (!LUSTRE_CFG_BUFLEN(lcfg, 1)) {
54                 CERROR("No type passed!\n");
55                 RETURN(-EINVAL);
56         }
57         typename = lustre_cfg_string(lcfg, 1);
58
59         if (!LUSTRE_CFG_BUFLEN(lcfg, 0)) {
60                 CERROR("No name passed!\n");
61                 RETURN(-EINVAL);
62         }
63         name = lustre_cfg_string(lcfg, 0);
64
65         if (!LUSTRE_CFG_BUFLEN(lcfg, 2)) {
66                 CERROR("No UUID passed!\n");
67                 RETURN(-EINVAL);
68         }
69         uuid = lustre_cfg_string(lcfg, 2);
70
71         CDEBUG(D_CONFIG, "attach type %s name: %s uuid: %s\n",
72                MKSTR(typename), MKSTR(name), MKSTR(uuid));
73
74         /* find the type */
75         type = class_get_type(typename);
76         if (!type) {
77                 CERROR("OBD: unknown type: %s\n", typename);
78                 RETURN(-EINVAL);
79         }
80         cleanup_phase = 1;  /* class_put_type */
81
82         obd = class_name2obd(name);
83         if (obd != NULL) {
84                 CERROR("obd %s already attached\n", name);
85                 GOTO(out, rc = -EEXIST);
86         }
87
88         obd = class_newdev(type);
89         if (obd == NULL)
90                 GOTO(out, rc = -EINVAL);
91
92         cleanup_phase = 2;  /* class_release_dev */
93         
94         INIT_LIST_HEAD(&obd->obd_exports);
95         obd->obd_num_exports = 0;
96         spin_lock_init(&obd->obd_dev_lock);
97         spin_lock_init(&obd->obd_osfs_lock);
98         obd->obd_osfs_age = jiffies - 1000 * HZ;
99         init_waitqueue_head(&obd->obd_refcount_waitq);
100
101         /* XXX belongs in setup not attach  */
102         /* recovery data */
103         init_timer(&obd->obd_recovery_timer);
104         spin_lock_init(&obd->obd_processing_task_lock);
105         init_waitqueue_head(&obd->obd_next_transno_waitq);
106         INIT_LIST_HEAD(&obd->obd_req_replay_queue);
107         INIT_LIST_HEAD(&obd->obd_lock_replay_queue);
108         INIT_LIST_HEAD(&obd->obd_final_req_queue);
109
110         spin_lock_init(&obd->obd_uncommitted_replies_lock);
111         INIT_LIST_HEAD(&obd->obd_uncommitted_replies);
112
113         len = strlen(name) + 1;
114         OBD_ALLOC(obd->obd_name, len);
115         if (!obd->obd_name)
116                 GOTO(out, rc = -ENOMEM);
117         memcpy(obd->obd_name, name, len);
118         
119         cleanup_phase = 3; /* free obd_name */
120
121         len = strlen(uuid);
122         if (len >= sizeof(obd->obd_uuid)) {
123                 CERROR("uuid must be < "LPSZ" bytes long\n",
124                        sizeof(obd->obd_uuid));
125                 GOTO(out, rc = -EINVAL);
126         }
127         memcpy(obd->obd_uuid.uuid, uuid, len);
128
129         /* do the attach */
130         if (OBP(obd, attach)) {
131                 rc = OBP(obd,attach)(obd, sizeof *lcfg, lcfg);
132                 if (rc)
133                         GOTO(out, rc = -EINVAL);
134         }
135
136         obd->obd_attached = 1;
137         type->typ_refcnt++;
138         CDEBUG(D_IOCTL, "OBD: dev %d attached type %s\n",
139                obd->obd_minor, typename);
140         RETURN(0);
141  out:
142         switch (cleanup_phase) {
143         case 3:
144                 OBD_FREE(obd->obd_name, strlen(obd->obd_name) + 1);
145         case 2:
146                 class_release_dev(obd);
147         case 1:
148                 class_put_type(type);
149         }
150         return rc;
151 }
152
153 static int class_setup(struct obd_device *obd, struct lustre_cfg *lcfg)
154 {
155         int err = 0;
156         struct obd_export *exp;
157         ENTRY;
158
159         LASSERT(obd == (obd_dev + obd->obd_minor));
160
161         /* have we attached a type to this device? */
162         if (!obd->obd_attached) {
163                 CERROR("Device %d not attached\n", obd->obd_minor);
164                 RETURN(-ENODEV);
165         }
166
167         /* has this been done already? */
168         if (obd->obd_set_up) {
169                 CERROR("Device %d already setup (type %s)\n",
170                        obd->obd_minor, obd->obd_type->typ_name);
171                 RETURN(-EBUSY);
172         }
173
174         atomic_set(&obd->obd_refcount, 0);
175
176         exp = class_new_export(obd);
177         if (exp == NULL)
178                 RETURN(err);
179         memcpy(&exp->exp_client_uuid, &obd->obd_uuid,
180                sizeof(exp->exp_client_uuid));
181         obd->obd_self_export = exp;
182         class_export_put(exp);
183
184         err = obd_setup(obd, sizeof(*lcfg), lcfg);
185         if (err)
186                 GOTO(err_exp, err);
187
188         obd->obd_type->typ_refcnt++;
189         obd->obd_set_up = 1;
190
191         RETURN(err);
192
193 err_exp:
194         class_unlink_export(obd->obd_self_export);
195         obd->obd_self_export = NULL;
196         RETURN(err);
197 }
198
199 static int class_detach(struct obd_device *obd, struct lustre_cfg *lcfg)
200 {
201         int err = 0;
202
203         ENTRY;
204         if (obd->obd_set_up) {
205                 CERROR("OBD device %d still set up\n", obd->obd_minor);
206                 RETURN(-EBUSY);
207         }
208         if (!obd->obd_attached) {
209                 CERROR("OBD device %d not attached\n", obd->obd_minor);
210                 RETURN(-ENODEV);
211         }
212         if (OBP(obd, detach))
213                 err = OBP(obd,detach)(obd);
214
215         if (obd->obd_name) {
216                 OBD_FREE(obd->obd_name, strlen(obd->obd_name)+1);
217                 obd->obd_name = NULL;
218         } else {
219                 CERROR("device %d: no name at detach\n", obd->obd_minor);
220         }
221
222         obd->obd_attached = 0;
223         obd->obd_type->typ_refcnt--;
224         class_put_type(obd->obd_type);
225         class_release_dev(obd);
226         RETURN(err);
227 }
228
229 static void dump_exports(struct obd_device *obd)
230 {
231         struct obd_export *exp, *n;
232
233         list_for_each_entry_safe(exp, n, &obd->obd_exports, exp_obd_chain) {
234                 struct ptlrpc_reply_state *rs;
235                 struct ptlrpc_reply_state *first_reply = NULL;
236                 int                        nreplies = 0;
237
238                 list_for_each_entry (rs, &exp->exp_outstanding_replies,
239                                      rs_exp_list) {
240                         if (nreplies == 0)
241                                 first_reply = rs;
242                         nreplies++;
243                 }
244
245                 CERROR("%s: %p %s %d %d %d: %p %s\n",
246                        obd->obd_name, exp, exp->exp_client_uuid.uuid,
247                        atomic_read(&exp->exp_refcount),
248                        exp->exp_failed, nreplies, first_reply,
249                        nreplies > 3 ? "..." : "");
250         }
251 }
252
253 static int class_cleanup(struct obd_device *obd, struct lustre_cfg *lcfg)
254 {
255         int flags = 0;
256         int err = 0;
257         char *flag;
258
259         ENTRY;
260         if (!obd->obd_set_up) {
261                 CERROR("Device %d not setup\n", obd->obd_minor);
262                 RETURN(-ENODEV);
263         }
264         if (LUSTRE_CFG_BUFLEN(lcfg, 1) > 0) {
265                  for (flag = lustre_cfg_string(lcfg, 1); *flag != 0; flag++)
266                         switch (*flag) {
267                         case 'F':
268                                 flags |= OBD_OPT_FORCE;
269                                 break;
270                         case 'A':
271                                 flags |= OBD_OPT_FAILOVER;
272                                 break;
273                         default:
274                                 CERROR("unrecognised flag '%c'\n",
275                                        *flag);
276                         }
277         }
278
279         /* The one reference that should be remaining is the
280          * obd_self_export */
281         if (atomic_read(&obd->obd_refcount) <= 1 ||
282             flags & OBD_OPT_FORCE) {
283                 /* this will stop new connections, and need to
284                    do it before class_disconnect_exports() */
285                 obd->obd_stopping = 1;
286         }
287
288         if (atomic_read(&obd->obd_refcount) > 1) {
289                 struct l_wait_info lwi = LWI_TIMEOUT_INTR(1 * HZ, NULL,
290                                                           NULL, NULL);
291                 int rc;
292
293                 if (!(flags & OBD_OPT_FORCE)) {
294                         CERROR("OBD device %d (%p,%s) has refcount %d\n",
295                                obd->obd_minor, obd, obd->obd_name,
296                                atomic_read(&obd->obd_refcount));
297                         portals_debug_dumplog();
298                         dump_exports(obd);
299                         GOTO(out, err = -EBUSY);
300                 }
301                 class_disconnect_exports(obd, flags);
302                 CDEBUG(D_IOCTL,
303                        "%s: waiting for obd refs to go away: %d\n",
304                        obd->obd_name, atomic_read(&obd->obd_refcount));
305
306                 rc = l_wait_event(obd->obd_refcount_waitq,
307                                   atomic_read(&obd->obd_refcount) < 2, &lwi);
308                 if (rc == 0) {
309                         LASSERT(atomic_read(&obd->obd_refcount) == 1);
310                 } else {
311                         CERROR("wait cancelled cleaning anyway. "
312                                "refcount: %d\n",
313                                atomic_read(&obd->obd_refcount));
314                         dump_exports(obd);
315                 }
316                 CDEBUG(D_IOCTL, "%s: awake, now finishing cleanup\n",
317                        obd->obd_name);
318         }
319
320         if (obd->obd_self_export) {
321                 err = obd_precleanup(obd, flags);
322                 if (err)
323                         GOTO(out, err);
324                 class_unlink_export(obd->obd_self_export);
325                 obd->obd_self_export = NULL;
326         }
327
328         err = obd_cleanup(obd, flags);
329 out:
330         if (!err) {
331                 obd->obd_set_up = obd->obd_stopping = 0;
332                 obd->obd_type->typ_refcnt--;
333                 /* XXX this should be an LASSERT */
334                 if (atomic_read(&obd->obd_refcount) > 0) {
335                         CERROR("%s (%p) still has refcount %d after "
336                                "cleanup.\n", obd->obd_name, obd,
337                                atomic_read(&obd->obd_refcount));
338                         dump_exports(obd);
339                 }
340         }
341
342         RETURN(err);
343 }
344
345 int class_add_conn(struct obd_device *obd, struct lustre_cfg *lcfg)
346 {
347         struct obd_import *imp;
348         struct obd_uuid uuid;
349         int rc;
350         ENTRY;
351
352         if (LUSTRE_CFG_BUFLEN(lcfg, 1) < 1 ||
353             LUSTRE_CFG_BUFLEN(lcfg, 1) > sizeof(struct obd_uuid)) {
354                 CERROR("invalid conn_uuid\n");
355                 RETURN(-EINVAL);
356         }
357
358         if (strcmp(obd->obd_type->typ_name, OBD_MDC_DEVICENAME) &&
359             strcmp(obd->obd_type->typ_name, OBD_OSC_DEVICENAME)) {
360                 CERROR("can't add connection on non-client dev\n");
361                 RETURN(-EINVAL);
362         }
363
364         imp = obd->u.cli.cl_import;
365         if (!imp) {
366                 CERROR("try to add conn on immature client dev\n");
367                 RETURN(-EINVAL);
368         }
369
370         obd_str2uuid(&uuid, lustre_cfg_string(lcfg, 1));
371         rc = obd_add_conn(imp, &uuid, lcfg->lcfg_num);
372
373         RETURN(rc);
374 }
375
376 int class_del_conn(struct obd_device *obd, struct lustre_cfg *lcfg)
377 {
378         struct obd_import *imp;
379         struct obd_uuid uuid;
380         int rc;
381         ENTRY;
382
383         if (LUSTRE_CFG_BUFLEN(lcfg, 1) < 1 ||
384             LUSTRE_CFG_BUFLEN(lcfg, 1) > sizeof(struct obd_uuid)) {
385                 CERROR("invalid conn_uuid\n");
386                 RETURN(-EINVAL);
387         }
388
389         if (strcmp(obd->obd_type->typ_name, OBD_MDC_DEVICENAME) &&
390             strcmp(obd->obd_type->typ_name, OBD_OSC_DEVICENAME)) {
391                 CERROR("can't add connection on non-client dev\n");
392                 RETURN(-EINVAL);
393         }
394
395         imp = obd->u.cli.cl_import;
396         if (!imp) {
397                 CERROR("try to del conn on immature client dev\n");
398                 RETURN(-EINVAL);
399         }
400
401         obd_str2uuid(&uuid, lustre_cfg_string(lcfg, 1));
402         rc = obd_del_conn(imp, &uuid);
403
404         RETURN(rc);
405 }
406
407 LIST_HEAD(lustre_profile_list);
408
409 struct lustre_profile *class_get_profile(char * prof)
410 {
411         struct lustre_profile *lprof;
412
413         list_for_each_entry(lprof, &lustre_profile_list, lp_list) {
414                 if (!strcmp(lprof->lp_profile, prof)) {
415                         RETURN(lprof);
416                 }
417         }
418         RETURN(NULL);
419 }
420
421 int class_add_profile(int proflen, char *prof,
422                       int lovlen, char *lov,
423                       int lmvlen, char *lmv,
424                       int gkclen, char *gkc)
425 {
426         struct lustre_profile *lprof;
427         int err = 0;
428
429         OBD_ALLOC(lprof, sizeof(*lprof));
430         if (lprof == NULL)
431                 GOTO(out, err = -ENOMEM);
432         INIT_LIST_HEAD(&lprof->lp_list);
433
434         LASSERT(proflen == (strlen(prof) + 1));
435         OBD_ALLOC(lprof->lp_profile, proflen);
436         if (lprof->lp_profile == NULL)
437                 GOTO(out, err = -ENOMEM);
438         memcpy(lprof->lp_profile, prof, proflen);
439
440         LASSERT(lovlen == (strlen(lov) + 1));
441         OBD_ALLOC(lprof->lp_lov, lovlen);
442         if (lprof->lp_profile == NULL)
443                 GOTO(out, err = -ENOMEM);
444         memcpy(lprof->lp_lov, lov, lovlen);
445
446         if (lmvlen > 0) {
447                 LASSERT(lmvlen == (strlen(lmv) + 1));
448                 OBD_ALLOC(lprof->lp_lmv, lmvlen);
449                 if (lprof->lp_lmv == NULL)
450                         GOTO(out, err = -ENOMEM);
451                 memcpy(lprof->lp_lmv, lmv, lmvlen);
452         }
453         if (gkclen > 0 ) {
454                 LASSERT(gkclen == (strlen(gkc) + 1));
455                 OBD_ALLOC(lprof->lp_gkc, gkclen);
456                 if (lprof->lp_gkc == NULL)
457                         GOTO(out, err = -ENOMEM);
458                 memcpy(lprof->lp_gkc, gkc, gkclen);
459         }
460         
461         list_add(&lprof->lp_list, &lustre_profile_list);
462 out:
463         RETURN(err);
464 }
465
466 void class_del_profile(char *prof)
467 {
468         struct lustre_profile *lprof;
469
470         lprof = class_get_profile(prof);
471         if (lprof) {
472                 list_del(&lprof->lp_list);
473                 OBD_FREE(lprof->lp_profile, strlen(lprof->lp_profile) + 1);
474                 OBD_FREE(lprof->lp_lov, strlen(lprof->lp_lov) + 1);
475                 if (lprof->lp_lmv)
476                         OBD_FREE(lprof->lp_lmv, strlen(lprof->lp_lmv) + 1);
477                 if (lprof->lp_gkc)
478                         OBD_FREE(lprof->lp_gkc, strlen(lprof->lp_gkc) + 1);
479                 OBD_FREE(lprof, sizeof *lprof);
480         }
481 }
482
483 int class_process_config(struct lustre_cfg *lcfg)
484 {
485         struct obd_device *obd;
486         char str[PTL_NALFMT_SIZE];
487         int err;
488         ENTRY;
489
490         LASSERT(lcfg && !IS_ERR(lcfg));
491
492         CDEBUG(D_CONFIG, "processing cmd: %x\n", lcfg->lcfg_command);
493
494         /* Commands that don't need a device */
495         switch(lcfg->lcfg_command) {
496         case LCFG_ATTACH: {
497                 err = class_attach(lcfg);
498                 GOTO(out, err);
499         }
500         case LCFG_ADD_UUID: {
501                 CDEBUG(D_CONFIG, "adding mapping from uuid %s to nid "LPX64
502                        " (%s), nal %x\n", lustre_cfg_string(lcfg, 1),
503                        lcfg->lcfg_nid,
504                        portals_nid2str(lcfg->lcfg_nal, lcfg->lcfg_nid, str),
505                        lcfg->lcfg_nal);
506
507                err = class_add_uuid(lustre_cfg_string(lcfg, 1), lcfg->lcfg_nid,
508                                     lcfg->lcfg_nal);
509                GOTO(out, err);
510         }
511         case LCFG_DEL_UUID: {
512                 CDEBUG(D_CONFIG, "removing mappings for uuid %s\n",
513                        (lcfg->lcfg_bufcount < 2 || LUSTRE_CFG_BUFLEN(lcfg, 1) == 0)
514                        ? "<all uuids>" : lustre_cfg_string(lcfg, 1));
515
516                 err = class_del_uuid(lustre_cfg_string(lcfg, 1));
517                 GOTO(out, err);
518         }
519         case LCFG_MOUNTOPT: {
520                 CDEBUG(D_CONFIG, "mountopt: profile %s osc %s mdc %s gkc %s \n",
521                        lustre_cfg_string(lcfg, 1),
522                        lustre_cfg_string(lcfg, 2),
523                        lustre_cfg_string(lcfg, 3),
524                        lustre_cfg_string(lcfg, 4));
525                 /* set these mount options somewhere, so ll_fill_super
526                  * can find them. */
527                 err = class_add_profile(LUSTRE_CFG_BUFLEN(lcfg, 1),
528                                         lustre_cfg_string(lcfg, 1),
529                                         LUSTRE_CFG_BUFLEN(lcfg, 2),
530                                         lustre_cfg_string(lcfg, 2),
531                                         LUSTRE_CFG_BUFLEN(lcfg, 3),
532                                         lustre_cfg_string(lcfg, 3),
533                                         LUSTRE_CFG_BUFLEN(lcfg, 4),
534                                         lustre_cfg_string(lcfg, 4));
535                 GOTO(out, err);
536         }
537         case LCFG_DEL_MOUNTOPT: {
538                 CDEBUG(D_CONFIG, "mountopt: profile %s\n",
539                        lustre_cfg_string(lcfg, 1));
540                 /* set these mount options somewhere, so ll_fill_super
541                  * can find them. */
542                 class_del_profile(lustre_cfg_string(lcfg, 1));
543                 GOTO(out, err = 0);
544         }
545         case LCFG_SET_TIMEOUT: {
546                 CDEBUG(D_CONFIG, "changing lustre timeout from %d to %d\n",
547                        obd_timeout,
548                        lcfg->lcfg_num);
549                 obd_timeout = lcfg->lcfg_num;
550                 GOTO(out, err = 0);
551         }
552         case LCFG_SET_UPCALL: {
553                 CDEBUG(D_CONFIG, "setting lustre ucpall to: %s\n",
554                        lustre_cfg_string(lcfg, 1));
555                 if (LUSTRE_CFG_BUFLEN(lcfg, 1) > sizeof obd_lustre_upcall)
556                         GOTO(out, err = -EINVAL);
557                 strncpy(obd_lustre_upcall, lustre_cfg_string(lcfg, 1),
558                         sizeof (obd_lustre_upcall));
559                 GOTO(out, err = 0);
560         }
561         }
562         
563         /* Commands that require a device */
564         obd = class_name2obd(lustre_cfg_string(lcfg, 0));
565         if (obd == NULL) {
566                 if (!LUSTRE_CFG_BUFLEN(lcfg, 0))
567                         CERROR("this lcfg command %d requires a device name\n", 
568                                lcfg->lcfg_command);
569                 else
570                         CERROR("no device for: %s\n",
571                                lustre_cfg_string(lcfg, 0));
572
573                 GOTO(out, err = -EINVAL);
574         }
575
576         switch(lcfg->lcfg_command) {
577         case LCFG_SETUP: {
578                 err = class_setup(obd, lcfg);
579                 GOTO(out, err);
580         }
581         case LCFG_DETACH: {
582                 err = class_detach(obd, lcfg);
583                 GOTO(out, err = 0);
584         }
585         case LCFG_CLEANUP: {
586                 err = class_cleanup(obd, lcfg);
587                 GOTO(out, err = 0);
588         }
589         case LCFG_ADD_CONN: {
590                 err = class_add_conn(obd, lcfg);
591                 GOTO(out, err = 0);
592         }
593         case LCFG_DEL_CONN: {
594                 err = class_del_conn(obd, lcfg);
595                 GOTO(out, err = 0);
596         }
597         default: {
598                 err = obd_process_config(obd, sizeof(*lcfg), lcfg);
599                 GOTO(out, err);
600
601         }
602         }
603 out:
604         return err;
605 }
606
607 static int class_config_parse_handler(struct llog_handle * handle,
608                                       struct llog_rec_hdr *rec, void *data)
609 {
610         struct config_llog_instance *cfg = data;
611         int cfg_len = rec->lrh_len;
612         char *cfg_buf = (char*) (rec + 1);
613         int rc = 0;
614         ENTRY;
615
616         if (rec->lrh_type == OBD_CFG_REC) {
617                 struct lustre_cfg *lcfg, *lcfg_new;
618                 struct lustre_cfg_bufs bufs;
619                 char *inst_name = NULL;
620                 int inst_len = 0;
621
622                 lcfg = (struct lustre_cfg *)cfg_buf;
623                 if (lcfg->lcfg_version == __swab32(LUSTRE_CFG_VERSION))
624                         lustre_swab_lustre_cfg(lcfg);
625
626                 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
627                 if (rc)
628                         GOTO(out, rc);
629
630                 lustre_cfg_bufs_init(&bufs, lcfg);
631                 if (cfg && cfg->cfg_instance) {
632                         if (LUSTRE_CFG_BUFLEN(lcfg, 0) > 0) {
633                                 inst_len = LUSTRE_CFG_BUFLEN(lcfg, 0) +
634                                         strlen(cfg->cfg_instance) + 1;
635                                 OBD_ALLOC(inst_name, inst_len);
636                                 if (inst_name == NULL)
637                                         GOTO(out, rc = -ENOMEM);
638                                 sprintf(inst_name, "%s-%s",
639                                         lustre_cfg_string(lcfg, 0),
640                                         cfg->cfg_instance);
641                                 lustre_cfg_bufs_set_string(&bufs, 0, inst_name);
642                         }
643                         if (lcfg->lcfg_command == LCFG_SETUP) {
644                                 /*add cfg_instance to the end of lcfg buffers*/
645                                 lustre_cfg_bufs_set_string(&bufs,
646                                                            bufs.lcfg_bufcount, 
647                                                            cfg->cfg_instance); 
648                         }
649                 }
650
651                 if (cfg && (lcfg->lcfg_command == LCFG_ATTACH)){
652                         /*Very Dirty Hack fix here, for mds add, 
653                          *the mdc in mds should not 
654                          *change uuid FIXME: Wangdi
655                          */
656                          if (memcmp(lustre_cfg_string(lcfg, 1), OBD_MDC_DEVICENAME, 
657                                     strlen(OBD_MDC_DEVICENAME)) || 
658                              (cfg->cfg_flags & CFG_MODIFY_UUID_FL))
659                                 lustre_cfg_bufs_set_string(&bufs, 2,
660                                                    (char *)cfg->cfg_uuid.uuid);
661                 }
662                 lcfg_new = lustre_cfg_new(lcfg->lcfg_command, &bufs);
663
664                 lcfg_new->lcfg_num   = lcfg->lcfg_num;
665                 lcfg_new->lcfg_flags = lcfg->lcfg_flags;
666                 lcfg_new->lcfg_nid   = lcfg->lcfg_nid;
667                 lcfg_new->lcfg_nal   = lcfg->lcfg_nal;
668
669                 rc = class_process_config(lcfg_new);
670                 lustre_cfg_free(lcfg_new);
671
672                 if (inst_name)
673                         OBD_FREE(inst_name, inst_len);
674         } else if (rec->lrh_type == PTL_CFG_REC) {
675                 struct portals_cfg *pcfg = (struct portals_cfg *)cfg_buf;
676                 if (pcfg->pcfg_command == NAL_CMD_REGISTER_MYNID &&
677                     cfg->cfg_local_nid != PTL_NID_ANY) {
678                         pcfg->pcfg_nid = cfg->cfg_local_nid;
679                 }
680
681                 rc = libcfs_nal_cmd(pcfg);
682         } else {
683                 CERROR("unrecognized record type: 0x%x\n", rec->lrh_type);
684         }
685 out:
686         RETURN(rc);
687 }
688
689 int class_config_process_llog(struct llog_ctxt *ctxt, char *name,
690                               struct config_llog_instance *cfg)
691 {
692         struct llog_handle *llh;
693         int rc, rc2;
694         ENTRY;
695
696         rc = llog_open(ctxt, &llh, NULL, name, 0);
697         if (rc)
698                 RETURN(rc);
699
700         rc = llog_init_handle(llh, LLOG_F_IS_PLAIN, NULL);
701         if (rc == 0)
702                 rc = llog_process(llh, class_config_parse_handler, cfg, NULL);
703
704         rc2 = llog_close(llh);
705         if (rc == 0)
706                 rc = rc2;
707
708         RETURN(rc);
709 }
710
711 int class_config_dump_handler(struct llog_handle * handle,
712                               struct llog_rec_hdr *rec, void *data)
713 {
714         int cfg_len = rec->lrh_len;
715         char *cfg_buf = (char*) (rec + 1);
716         int rc = 0;
717         ENTRY;
718         if (rec->lrh_type == OBD_CFG_REC) {
719                 struct lustre_cfg *lcfg;
720                 int i;
721
722                 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
723                 if (rc)
724                         GOTO(out, rc);
725                 lcfg = (struct lustre_cfg *)cfg_buf;
726
727                 CDEBUG(D_INFO, "lcfg command: %x\n", lcfg->lcfg_command);
728                 if (LUSTRE_CFG_BUFLEN(lcfg, 0) > 0)
729                         CDEBUG(D_INFO, "     devname: %s\n",
730                                lustre_cfg_string(lcfg, 0));
731                 if (lcfg->lcfg_flags)
732                         CDEBUG(D_INFO, "       flags: %x\n", lcfg->lcfg_flags);
733                 if (lcfg->lcfg_nid)
734                         CDEBUG(D_INFO, "         nid: "LPX64"\n",
735                                lcfg->lcfg_nid);
736                 if (lcfg->lcfg_nal)
737                         CDEBUG(D_INFO, "         nal: %x\n", lcfg->lcfg_nal);
738                 if (lcfg->lcfg_num)
739                         CDEBUG(D_INFO, "         nal: %x\n", lcfg->lcfg_num);
740                 for (i = 1; i < lcfg->lcfg_bufcount; i++)
741                         if (LUSTRE_CFG_BUFLEN(lcfg, i) > 0)
742                                 CDEBUG(D_INFO, "     inlbuf%d: %s\n", i,
743                                        lustre_cfg_string(lcfg, i));
744         } else if (rec->lrh_type == PTL_CFG_REC) {
745                 struct portals_cfg *pcfg = (struct portals_cfg *)cfg_buf;
746                 CDEBUG(D_INFO, "pcfg command: %d\n", pcfg->pcfg_command);
747                 if (pcfg->pcfg_nal)
748                         CDEBUG(D_INFO, "         nal: %x\n",
749                                pcfg->pcfg_nal);
750                 if (pcfg->pcfg_gw_nal)
751                         CDEBUG(D_INFO, "      gw_nal: %x\n",
752                                pcfg->pcfg_gw_nal);
753                 if (pcfg->pcfg_nid)
754                         CDEBUG(D_INFO, "         nid: "LPX64"\n",
755                                pcfg->pcfg_nid);
756                 if (pcfg->pcfg_nid2)
757                         CDEBUG(D_INFO, "         nid: "LPX64"\n",
758                                pcfg->pcfg_nid2);
759                 if (pcfg->pcfg_nid3)
760                         CDEBUG(D_INFO, "         nid: "LPX64"\n",
761                                pcfg->pcfg_nid3);
762                 if (pcfg->pcfg_misc)
763                         CDEBUG(D_INFO, "         nid: %d\n",
764                                pcfg->pcfg_misc);
765                 if (pcfg->pcfg_id)
766                         CDEBUG(D_INFO, "          id: %x\n",
767                                pcfg->pcfg_id);
768                 if (pcfg->pcfg_flags)
769                         CDEBUG(D_INFO, "       flags: %x\n",
770                                pcfg->pcfg_flags);
771         } else {
772                 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
773                 rc = -EINVAL;
774         }
775 out:
776         RETURN(rc);
777 }
778
779 int class_config_dump_llog(struct llog_ctxt *ctxt, char *name,
780                            struct config_llog_instance *cfg)
781 {
782         struct llog_handle *llh;
783         int rc, rc2;
784         ENTRY;
785
786         rc = llog_open(ctxt, &llh, NULL, name, 0);
787         if (rc)
788                 RETURN(rc);
789
790         rc = llog_init_handle(llh, LLOG_F_IS_PLAIN, NULL);
791         if (rc == 0)
792                 rc = llog_process(llh, class_config_dump_handler, cfg, NULL);
793
794         rc2 = llog_close(llh);
795         if (rc == 0)
796                 rc = rc2;
797
798         RETURN(rc);
799 }