Whamcloud - gitweb
Landing b_bug974 onto HEAD (20040213_1538).
[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 <portals/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 int class_attach(struct lustre_cfg *lcfg)
47 {
48         int minor;
49         struct obd_type *type;
50         int err = 0;
51         int len;
52         char *typename;
53         char *name;
54         char *uuid;
55         struct obd_device *obd;
56         int dev;
57
58         if (!lcfg->lcfg_inllen1 || !lcfg->lcfg_inlbuf1) {
59                 CERROR("No type passed!\n");
60                 RETURN(-EINVAL);
61         }
62         if (lcfg->lcfg_inlbuf1[lcfg->lcfg_inllen1 - 1] != 0) {
63                 CERROR("Type not nul terminated!\n");
64                 RETURN(-EINVAL);
65         }
66         typename = lcfg->lcfg_inlbuf1;
67
68         if (!lcfg->lcfg_dev_namelen || !lcfg->lcfg_dev_name) {
69                 CERROR("No name passed!\n");
70                 RETURN(-EINVAL);
71         }
72         if (lcfg->lcfg_dev_name[lcfg->lcfg_dev_namelen - 1] != 0) {
73                 CERROR("Name not nul terminated!\n");
74                 RETURN(-EINVAL);
75         }
76         name = lcfg->lcfg_dev_name;
77
78         if (!lcfg->lcfg_inllen2 || !lcfg->lcfg_inlbuf2) {
79                 CERROR("No UUID passed!\n");
80                 RETURN(-EINVAL);
81         }
82         if (lcfg->lcfg_inlbuf2[lcfg->lcfg_inllen2 - 1] != 0) {
83                 CERROR("UUID not nul terminated!\n");
84                 RETURN(-EINVAL);
85         }
86         uuid = lcfg->lcfg_inlbuf2;
87
88         CDEBUG(D_IOCTL, "attach type %s name: %s uuid: %s\n",
89                MKSTR(lcfg->lcfg_inlbuf1),
90                MKSTR(lcfg->lcfg_dev_name), MKSTR(lcfg->lcfg_inlbuf2));
91
92         /* find the type */
93         type = class_get_type(typename);
94         if (!type) {
95                 CERROR("OBD: unknown type: %s\n", typename);
96                 RETURN(-EINVAL);
97         }
98
99         obd = class_name2obd(name);
100         if (obd != NULL) {
101                 CERROR("obd %s already attached\n", name);
102                 RETURN(-EEXIST);
103         }
104
105         obd = class_newdev(&dev);
106         if (obd == NULL)
107                 RETURN(-EINVAL);
108
109         /* have we attached a type to this device */
110         if (obd->obd_attached || obd->obd_type) {
111                 CERROR("OBD: Device %d already typed as %s.\n",
112                        obd->obd_minor, MKSTR(obd->obd_type->typ_name));
113                 RETURN(-EBUSY);
114         }
115
116         LASSERT(obd == (obd_dev + obd->obd_minor));
117
118         minor = obd->obd_minor;
119         memset(obd, 0, sizeof(*obd));
120         obd->obd_minor = minor;
121         obd->obd_type = type;
122         INIT_LIST_HEAD(&obd->obd_exports);
123         obd->obd_num_exports = 0;
124         spin_lock_init(&obd->obd_dev_lock);
125         spin_lock_init(&obd->obd_osfs_lock);
126         obd->obd_osfs_age = jiffies - 1000 * HZ;
127         init_waitqueue_head(&obd->obd_refcount_waitq);
128
129         /* XXX belongs in setup not attach  */
130         /* recovery data */
131         spin_lock_init(&obd->obd_processing_task_lock);
132         init_waitqueue_head(&obd->obd_next_transno_waitq);
133         INIT_LIST_HEAD(&obd->obd_recovery_queue);
134         INIT_LIST_HEAD(&obd->obd_delayed_reply_queue);
135
136         init_waitqueue_head(&obd->obd_commit_waitq);
137
138         len = strlen(name) + 1;
139         OBD_ALLOC(obd->obd_name, len);
140         if (!obd->obd_name) {
141                 class_put_type(obd->obd_type);
142                 obd->obd_type = NULL;
143                 RETURN(-ENOMEM);
144         }
145         memcpy(obd->obd_name, name, len);
146
147         len = strlen(uuid);
148         if (len >= sizeof(obd->obd_uuid)) {
149                 CERROR("uuid must be < "LPSZ" bytes long\n",
150                        sizeof(obd->obd_uuid));
151                 OBD_FREE(obd->obd_name, strlen(obd->obd_name) + 1);
152                 class_put_type(obd->obd_type);
153                 obd->obd_type = NULL;
154                 RETURN(-EINVAL);
155         }
156         memcpy(obd->obd_uuid.uuid, uuid, len);
157
158         /* do the attach */
159         if (OBP(obd, attach))
160                 err = OBP(obd,attach)(obd, sizeof *lcfg, lcfg);
161
162         if (err) {
163                 OBD_FREE(obd->obd_name, strlen(obd->obd_name) + 1);
164                 class_put_type(obd->obd_type);
165                 obd->obd_type = NULL;
166         } else {
167                 obd->obd_attached = 1;
168                 type->typ_refcnt++;
169                 CDEBUG(D_IOCTL, "OBD: dev %d attached type %s\n",
170                        obd->obd_minor, typename);
171         }
172         RETURN(err);
173 }
174
175 int class_setup(struct obd_device *obd, struct lustre_cfg *lcfg)
176 {
177         int err = 0;
178         struct obd_export *exp;
179         ENTRY;
180
181         LASSERT(obd == (obd_dev + obd->obd_minor));
182
183         /* have we attached a type to this device? */
184         if (!obd->obd_attached) {
185                 CERROR("Device %d not attached\n", obd->obd_minor);
186                 RETURN(-ENODEV);
187         }
188
189         /* has this been done already? */
190         if (obd->obd_set_up) {
191                 CERROR("Device %d already setup (type %s)\n",
192                        obd->obd_minor, obd->obd_type->typ_name);
193                 RETURN(-EBUSY);
194         }
195
196         atomic_set(&obd->obd_refcount, 0);
197
198         exp = class_new_export(obd);
199         if (exp == NULL)
200                 RETURN(err);
201         memcpy(&exp->exp_client_uuid, &obd->obd_uuid,
202                sizeof(exp->exp_client_uuid));
203         obd->obd_self_export = exp;
204         class_export_put(exp);
205
206         err = obd_setup(obd, sizeof(*lcfg), lcfg);
207         if (err)
208                 GOTO(err_exp, err);
209
210         obd->obd_type->typ_refcnt++;
211         obd->obd_set_up = 1;
212
213         RETURN(err);
214
215 err_exp:
216         class_unlink_export(obd->obd_self_export);
217         obd->obd_self_export = NULL;
218         RETURN(err);
219 }
220
221 int class_detach(struct obd_device *obd, struct lustre_cfg *lcfg)
222 {
223         int minor;
224         int err = 0;
225
226         ENTRY;
227         if (obd->obd_set_up) {
228                 CERROR("OBD device %d still set up\n", obd->obd_minor);
229                 RETURN(-EBUSY);
230         }
231         if (!obd->obd_attached) {
232                 CERROR("OBD device %d not attached\n", obd->obd_minor);
233                 RETURN(-ENODEV);
234         }
235         if (OBP(obd, detach))
236                 err = OBP(obd,detach)(obd);
237
238         if (obd->obd_name) {
239                 OBD_FREE(obd->obd_name, strlen(obd->obd_name)+1);
240                 obd->obd_name = NULL;
241         } else {
242                 CERROR("device %d: no name at detach\n", obd->obd_minor);
243         }
244
245         obd->obd_attached = 0;
246         obd->obd_type->typ_refcnt--;
247         class_put_type(obd->obd_type);
248         obd->obd_type = NULL;
249         minor = obd->obd_minor;
250         memset(obd, 0, sizeof(*obd));
251         obd->obd_minor = minor;
252         RETURN(err);
253 }
254
255 static void dump_exports(struct obd_device *obd)
256 {
257         struct obd_export *exp, *n;
258
259         list_for_each_entry_safe(exp, n, &obd->obd_exports, exp_obd_chain) {
260                 CERROR("%s: %p %s %d %d %p\n",
261                        obd->obd_name, exp, exp->exp_client_uuid.uuid,
262                        atomic_read(&exp->exp_refcount),
263                        exp->exp_failed, exp->exp_outstanding_reply );
264         }
265 }
266
267 int class_cleanup(struct obd_device *obd, struct lustre_cfg *lcfg)
268 {
269         int flags = 0;
270         int err = 0;
271         char *flag;
272
273         ENTRY;
274         if (!obd->obd_set_up) {
275                 CERROR("Device %d not setup\n", obd->obd_minor);
276                 RETURN(-ENODEV);
277         }
278
279         if (lcfg->lcfg_inlbuf1) {
280                 for (flag = lcfg->lcfg_inlbuf1; *flag != 0; flag++)
281                         switch (*flag) {
282                         case 'F':
283                                 flags |= OBD_OPT_FORCE;
284                                 break;
285                         case 'A':
286                                 flags |= OBD_OPT_FAILOVER;
287                                 break;
288                         default:
289                                 CERROR("unrecognised flag '%c'\n",
290                                        *flag);
291                         }
292         }
293
294         /* The one reference that should be remaining is the
295          * obd_self_export */
296         if (atomic_read(&obd->obd_refcount) <= 1 ||
297             flags & OBD_OPT_FORCE) {
298                 /* this will stop new connections, and need to
299                    do it before class_disconnect_exports() */
300                 obd->obd_stopping = 1;
301         }
302
303         if (atomic_read(&obd->obd_refcount) > 1) {
304                 struct l_wait_info lwi = LWI_TIMEOUT_INTR(1 * HZ, NULL,
305                                                           NULL, NULL);
306                 int rc;
307
308                 if (!(flags & OBD_OPT_FORCE)) {
309                         CERROR("OBD device %d (%p) has refcount %d\n",
310                                obd->obd_minor, obd,
311                                atomic_read(&obd->obd_refcount));
312                         dump_exports(obd);
313                         GOTO(out, err = -EBUSY);
314                 }
315                 class_disconnect_exports(obd, flags);
316                 CDEBUG(D_IOCTL,
317                        "%s: waiting for obd refs to go away: %d\n",
318                        obd->obd_name, atomic_read(&obd->obd_refcount));
319
320                 rc = l_wait_event(obd->obd_refcount_waitq,
321                                   atomic_read(&obd->obd_refcount) < 2, &lwi);
322                 if (rc == 0) {
323                         LASSERT(atomic_read(&obd->obd_refcount) == 1);
324                 } else {
325                         CERROR("wait cancelled cleaning anyway. "
326                                "refcount: %d\n",
327                                atomic_read(&obd->obd_refcount));
328                         dump_exports(obd);
329                 }
330                 CDEBUG(D_IOCTL, "%s: awake, now finishing cleanup\n",
331                        obd->obd_name);
332         }
333
334         if (obd->obd_self_export) {
335                 err = obd_precleanup(obd, flags);
336                 if (err)
337                         GOTO(out, err);
338                 class_unlink_export(obd->obd_self_export);
339                 obd->obd_self_export = NULL;
340         }
341
342         err = obd_cleanup(obd, flags);
343 out:
344         if (!err) {
345                 obd->obd_set_up = obd->obd_stopping = 0;
346                 obd->obd_type->typ_refcnt--;
347                 /* XXX this should be an LASSERT */
348                 if (atomic_read(&obd->obd_refcount) > 0)
349                         CERROR("%s still has refcount %d after "
350                                "cleanup.\n", obd->obd_name,
351                                atomic_read(&obd->obd_refcount));
352         }
353
354         RETURN(err);
355
356 }
357
358 LIST_HEAD(lustre_profile_list);
359
360 struct lustre_profile *class_get_profile(char * prof)
361 {
362         struct lustre_profile *lprof;
363
364         list_for_each_entry(lprof, &lustre_profile_list, lp_list) {
365                 if (!strcmp(lprof->lp_profile, prof)) {
366                         RETURN(lprof);
367                 }
368         }
369         RETURN(NULL);
370 }
371
372 int class_add_profile(int proflen, char *prof, int osclen, char *osc,
373                       int mdclen, char *mdc)
374 {
375         struct lustre_profile *lprof;
376         int err = 0;
377
378         OBD_ALLOC(lprof, sizeof(*lprof));
379         if (lprof == NULL)
380                 GOTO(out, err = -ENOMEM);
381         INIT_LIST_HEAD(&lprof->lp_list);
382
383         LASSERT(proflen == (strlen(prof) + 1));
384         OBD_ALLOC(lprof->lp_profile, proflen);
385         if (lprof->lp_profile == NULL)
386                 GOTO(out, err = -ENOMEM);
387         memcpy(lprof->lp_profile, prof, proflen);
388
389         LASSERT(osclen == (strlen(osc) + 1));
390         OBD_ALLOC(lprof->lp_osc, osclen);
391         if (lprof->lp_profile == NULL)
392                 GOTO(out, err = -ENOMEM);
393         memcpy(lprof->lp_osc, osc, osclen);
394
395         if (mdclen > 0) {
396                 LASSERT(mdclen == (strlen(mdc) + 1));
397                 OBD_ALLOC(lprof->lp_mdc, mdclen);
398                 if (lprof->lp_mdc == NULL)
399                         GOTO(out, err = -ENOMEM);
400                 memcpy(lprof->lp_mdc, mdc, mdclen);
401         }
402
403         list_add(&lprof->lp_list, &lustre_profile_list);
404
405 out:
406         RETURN(err);
407 }
408
409 void class_del_profile(char *prof)
410 {
411         struct lustre_profile *lprof;
412
413         lprof = class_get_profile(prof);
414         if (lprof) {
415                 list_del(&lprof->lp_list);
416                 OBD_FREE(lprof->lp_profile, strlen(lprof->lp_profile) + 1);
417                 OBD_FREE(lprof->lp_osc, strlen(lprof->lp_osc) + 1);
418                 if (lprof->lp_mdc)
419                         OBD_FREE(lprof->lp_mdc, strlen(lprof->lp_mdc) + 1);
420                 OBD_FREE(lprof, sizeof *lprof);
421         }
422 }
423
424 int class_process_config(struct lustre_cfg *lcfg)
425 {
426         struct obd_device *obd;
427         char str[PTL_NALFMT_SIZE];
428         int err;
429
430         LASSERT(lcfg && !IS_ERR(lcfg));
431
432         CDEBUG(D_IOCTL, "processing cmd: %x\n", lcfg->lcfg_command);
433
434         /* Commands that don't need a device */
435         switch(lcfg->lcfg_command) {
436         case LCFG_ATTACH: {
437                 err = class_attach(lcfg);
438                 GOTO(out, err);
439         }
440         case LCFG_ADD_UUID: {
441                 CDEBUG(D_IOCTL, "adding mapping from uuid %s to nid "LPX64
442                        " (%s), nal %d\n", lcfg->lcfg_inlbuf1, lcfg->lcfg_nid,
443                        portals_nid2str(lcfg->lcfg_nal, lcfg->lcfg_nid, str),
444                        lcfg->lcfg_nal);
445
446                 err = class_add_uuid(lcfg->lcfg_inlbuf1, lcfg->lcfg_nid,
447                                      lcfg->lcfg_nal);
448                 GOTO(out, err);
449         }
450         case LCFG_DEL_UUID: {
451                 CDEBUG(D_IOCTL, "removing mappings for uuid %s\n",
452                        lcfg->lcfg_inlbuf1 == NULL ? "<all uuids>" :
453                        lcfg->lcfg_inlbuf1);
454
455                 err = class_del_uuid(lcfg->lcfg_inlbuf1);
456                 GOTO(out, err);
457         }
458         case LCFG_MOUNTOPT: {
459                 CDEBUG(D_IOCTL, "mountopt: profile %s osc %s mdc %s\n",
460                        lcfg->lcfg_inlbuf1, lcfg->lcfg_inlbuf2,
461                        lcfg->lcfg_inlbuf3);
462                 /* set these mount options somewhere, so ll_fill_super
463                  * can find them. */
464                 err = class_add_profile(lcfg->lcfg_inllen1, lcfg->lcfg_inlbuf1,
465                                         lcfg->lcfg_inllen2, lcfg->lcfg_inlbuf2,
466                                         lcfg->lcfg_inllen3, lcfg->lcfg_inlbuf3);
467                 GOTO(out, err);
468         }
469         case LCFG_DEL_MOUNTOPT: {
470                 CDEBUG(D_IOCTL, "mountopt: profile %s\n", lcfg->lcfg_inlbuf1);
471                 /* set these mount options somewhere, so ll_fill_super
472                  * can find them. */
473                 class_del_profile(lcfg->lcfg_inlbuf1);
474                 GOTO(out, err = 0);
475         }
476         case LCFG_SET_TIMEOUT: {
477                 CDEBUG(D_IOCTL, "changing lustre timeout from %d to %d\n",
478                        obd_timeout,
479                        lcfg->lcfg_num);
480                 obd_timeout = lcfg->lcfg_num;
481                 GOTO(out, err = 0);
482         }
483         case LCFG_SET_UPCALL: {
484                 CDEBUG(D_IOCTL, "setting lustre ucpall to: %s\n",
485                        lcfg->lcfg_inlbuf1);
486                 if (lcfg->lcfg_inllen1 > sizeof obd_lustre_upcall)
487                         GOTO(out, err = -EINVAL);
488                 memcpy(obd_lustre_upcall, lcfg->lcfg_inlbuf1,
489                        lcfg->lcfg_inllen1);
490                 GOTO(out, err = 0);
491         }
492         }
493
494         /* Commands that require a device */
495         obd = class_name2obd(lcfg->lcfg_dev_name);
496         if (obd == NULL) {
497                 if (lcfg->lcfg_dev_name == NULL)
498                         CERROR("this lcfg command requires a device name\n");
499                 else
500                         CERROR("no device for: %s\n", lcfg->lcfg_dev_name);
501
502                 GOTO(out, err = -EINVAL);
503         }
504
505         switch(lcfg->lcfg_command) {
506         case LCFG_SETUP: {
507                 err = class_setup(obd, lcfg);
508                 GOTO(out, err);
509         }
510         case LCFG_DETACH: {
511                 err = class_detach(obd, lcfg);
512                 GOTO(out, err = 0);
513         }
514         case LCFG_CLEANUP: {
515                 err = class_cleanup(obd, lcfg);
516                 GOTO(out, err = 0);
517         }
518         default: {
519                 CERROR("Unknown command: %d\n", lcfg->lcfg_command);
520                 GOTO(out, err = -EINVAL);
521
522         }
523         }
524 out:
525         RETURN(err);
526 }
527
528 static int class_config_llog_handler(struct llog_handle * handle,
529                                      struct llog_rec_hdr *rec, void *data)
530 {
531         struct config_llog_instance *cfg = data;
532         int cfg_len = rec->lrh_len;
533         char *cfg_buf = (char*) (rec + 1);
534         int rc = 0;
535
536         if (rec->lrh_type == OBD_CFG_REC) {
537                 char *buf;
538                 struct lustre_cfg *lcfg;
539                 char *old_name = NULL;
540                 int old_len = 0;
541                 char *old_uuid = NULL;
542                 int old_uuid_len = 0;
543                 char *inst_name = NULL;
544                 int inst_len = 0;
545
546                 rc = lustre_cfg_getdata(&buf, cfg_len, cfg_buf, 1);
547                 if (rc)
548                         GOTO(out, rc);
549                 lcfg = (struct lustre_cfg* ) buf;
550
551                 if (cfg && cfg->cfg_instance && lcfg->lcfg_dev_name) {
552                         inst_len = strlen(lcfg->lcfg_dev_name) +
553                                 strlen(cfg->cfg_instance) + 2;
554                         OBD_ALLOC(inst_name, inst_len);
555                         if (inst_name == NULL)
556                                 GOTO(out, rc = -ENOMEM);
557                         sprintf(inst_name, "%s-%s", lcfg->lcfg_dev_name,
558                                 cfg->cfg_instance);
559                         old_name = lcfg->lcfg_dev_name;
560                         old_len = lcfg->lcfg_dev_namelen;
561                         lcfg->lcfg_dev_name = inst_name;
562                         lcfg->lcfg_dev_namelen = strlen(inst_name) + 1;
563                 }
564
565                 if (cfg && lcfg->lcfg_command == LCFG_ATTACH) {
566                         old_uuid = lcfg->lcfg_inlbuf2;
567                         old_uuid_len = lcfg->lcfg_inllen2;
568
569                         lcfg->lcfg_inlbuf2 = (char*)&cfg->cfg_uuid.uuid;
570                         lcfg->lcfg_inllen2 = sizeof(cfg->cfg_uuid);
571                 }
572
573                 rc = class_process_config(lcfg);
574
575                 if (old_name) {
576                         lcfg->lcfg_dev_name = old_name;
577                         lcfg->lcfg_dev_namelen = old_len;
578                         OBD_FREE(inst_name, inst_len);
579                 }
580
581                 if (old_uuid) {
582                         lcfg->lcfg_inlbuf2 = old_uuid;
583                         lcfg->lcfg_inllen2 = old_uuid_len;
584                 }
585
586                 lustre_cfg_freedata(buf, cfg_len);
587         } else if (rec->lrh_type == PTL_CFG_REC) {
588                 struct portals_cfg *pcfg = (struct portals_cfg *)cfg_buf;
589                 if (pcfg->pcfg_command ==NAL_CMD_REGISTER_MYNID &&
590                     cfg->cfg_local_nid != PTL_NID_ANY) {
591                         pcfg->pcfg_nid = cfg->cfg_local_nid;
592                 }
593
594                 rc = kportal_nal_cmd(pcfg);
595         }
596 out:
597         RETURN(rc);
598 }
599
600 int class_config_parse_llog(struct llog_ctxt *ctxt, char *name,
601                             struct config_llog_instance *cfg)
602 {
603         struct llog_handle *llh;
604         int rc, rc2;
605         ENTRY;
606
607         rc = llog_create(ctxt, &llh, NULL, name);
608         if (rc)
609                 RETURN(rc);
610
611         rc = llog_init_handle(llh, LLOG_F_IS_PLAIN, NULL);
612         if (rc)
613                 GOTO(parse_out, rc);
614
615         rc = llog_process(llh, class_config_llog_handler, cfg, NULL);
616 parse_out:
617         rc2 = llog_close(llh);
618         if (rc == 0)
619                 rc = rc2;
620
621         RETURN(rc);
622
623 }
624
625 static int class_config_dump_handler(struct llog_handle * handle,
626                                      struct llog_rec_hdr *rec, void *data)
627 {
628         int cfg_len = rec->lrh_len;
629         char *cfg_buf = (char*) (rec + 1);
630         int rc = 0;
631
632         if (rec->lrh_type == OBD_CFG_REC) {
633                 char *buf;
634                 struct lustre_cfg *lcfg;
635
636                 rc = lustre_cfg_getdata(&buf, cfg_len, cfg_buf, 1);
637                 if (rc)
638                         GOTO(out, rc);
639                 lcfg = (struct lustre_cfg* ) buf;
640
641                 CDEBUG(D_INFO, "lcfg command: %x\n", lcfg->lcfg_command);
642                 if (lcfg->lcfg_dev_name)
643                         CDEBUG(D_INFO, "     devname: %s\n",
644                                lcfg->lcfg_dev_name);
645                 if (lcfg->lcfg_flags)
646                         CDEBUG(D_INFO, "       flags: %x\n", lcfg->lcfg_flags);
647                 if (lcfg->lcfg_nid)
648                         CDEBUG(D_INFO, "         nid: "LPX64"\n",
649                                lcfg->lcfg_nid);
650                 if (lcfg->lcfg_nal)
651                         CDEBUG(D_INFO, "         nal: %x\n", lcfg->lcfg_nal);
652                 if (lcfg->lcfg_num)
653                         CDEBUG(D_INFO, "         nal: %x\n", lcfg->lcfg_num);
654                 if (lcfg->lcfg_inlbuf1)
655                         CDEBUG(D_INFO, "     inlbuf1: %s\n",lcfg->lcfg_inlbuf1);
656                 if (lcfg->lcfg_inlbuf2)
657                         CDEBUG(D_INFO, "     inlbuf1: %s\n",lcfg->lcfg_inlbuf2);
658                 if (lcfg->lcfg_inlbuf3)
659                         CDEBUG(D_INFO, "     inlbuf1: %s\n",lcfg->lcfg_inlbuf3);
660                 if (lcfg->lcfg_inlbuf4)
661                         CDEBUG(D_INFO, "     inlbuf1: %s\n",lcfg->lcfg_inlbuf4);
662
663                 lustre_cfg_freedata(buf, cfg_len);
664         } else if (rec->lrh_type == PTL_CFG_REC) {
665                 struct portals_cfg *pcfg = (struct portals_cfg *)cfg_buf;
666
667                 CDEBUG(D_INFO, "pcfg command: %d\n", pcfg->pcfg_command);
668                 if (pcfg->pcfg_nal)
669                         CDEBUG(D_INFO, "         nal: %d\n",
670                                pcfg->pcfg_nal);
671                 if (pcfg->pcfg_gw_nal)
672                         CDEBUG(D_INFO, "      gw_nal: %d\n",
673                                pcfg->pcfg_gw_nal);
674                 if (pcfg->pcfg_nid)
675                         CDEBUG(D_INFO, "         nid: "LPX64"\n",
676                                pcfg->pcfg_nid);
677                 if (pcfg->pcfg_nid2)
678                         CDEBUG(D_INFO, "         nid: "LPX64"\n",
679                                pcfg->pcfg_nid2);
680                 if (pcfg->pcfg_nid3)
681                         CDEBUG(D_INFO, "         nid: "LPX64"\n",
682                                pcfg->pcfg_nid3);
683                 if (pcfg->pcfg_misc)
684                         CDEBUG(D_INFO, "         nid: %d\n",
685                                pcfg->pcfg_misc);
686                 if (pcfg->pcfg_id)
687                         CDEBUG(D_INFO, "          id: %x\n",
688                                pcfg->pcfg_id);
689                 if (pcfg->pcfg_flags)
690                         CDEBUG(D_INFO, "       flags: %x\n",
691                                pcfg->pcfg_flags);
692         }
693 out:
694         RETURN(rc);
695 }
696
697 int class_config_dump_llog(struct llog_ctxt *ctxt, char *name,
698                            struct config_llog_instance *cfg)
699 {
700         struct llog_handle *llh;
701         int rc, rc2;
702         ENTRY;
703
704         rc = llog_create(ctxt, &llh, NULL, name);
705         if (rc)
706                 RETURN(rc);
707
708         rc = llog_init_handle(llh, LLOG_F_IS_PLAIN, NULL);
709         if (rc)
710                 GOTO(parse_out, rc);
711
712         rc = llog_process(llh, class_config_dump_handler, cfg, NULL);
713 parse_out:
714         rc2 = llog_close(llh);
715         if (rc == 0)
716                 rc = rc2;
717
718         RETURN(rc);
719
720 }