Whamcloud - gitweb
oss capability fully works now.
[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-2006 Cluster File Systems, Inc.
5  *
6  *   This file is part of the Lustre file system, http://www.lustre.org
7  *   Lustre is a trademark of Cluster File Systems, Inc.
8  *
9  *   You may have signed or agreed to another license before downloading
10  *   this software.  If so, you are bound by the terms and conditions
11  *   of that agreement, and the following does not apply to you.  See the
12  *   LICENSE file included with this distribution for more information.
13  *
14  *   If you did not agree to a different license, then this copy of Lustre
15  *   is open source software; you can redistribute it and/or modify it
16  *   under the terms of version 2 of the GNU General Public License as
17  *   published by the Free Software Foundation.
18  *
19  *   In either case, Lustre is distributed in the hope that it will be
20  *   useful, but WITHOUT ANY WARRANTY; without even the implied warranty
21  *   of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22  *   license text for more details.
23  *
24  * Config API
25  *
26  */
27
28 #define DEBUG_SUBSYSTEM S_CLASS
29 #ifdef __KERNEL__
30 #include <obd_class.h>
31 #else
32 #include <liblustre.h>
33 #include <obd_class.h>
34 #include <obd.h>
35 #endif
36 #include <lustre_log.h>
37 #include <lprocfs_status.h>
38 #include <libcfs/list.h>
39 #include <lustre_param.h>
40
41 /*********** string parsing utils *********/
42
43 /* returns 0 if we find this key in the buffer, else 1 */
44 int class_find_param(char *buf, char *key, char **valp)
45 {
46         char *ptr;
47
48         if (!buf) 
49                 return 1;
50
51         if ((ptr = strstr(buf, key)) == NULL) 
52                 return 1;
53
54         if (valp) 
55                 *valp = ptr + strlen(key);
56         
57         return 0;
58 }
59
60 /* returns 0 if this is the first key in the buffer, else 1.
61    valp points to first char after key. */
62 int class_match_param(char *buf, char *key, char **valp)
63 {
64         if (!buf) 
65                 return 1;
66
67         if (memcmp(buf, key, strlen(key)) != 0) 
68                 return 1;
69
70         if (valp) 
71                 *valp = buf + strlen(key);
72         
73         return 0;
74 }
75
76 /* 0 is good nid, 
77    1 not found
78    < 0 error
79    endh is set to next separator */
80 int class_parse_nid(char *buf, lnet_nid_t *nid, char **endh)
81 {
82         char tmp, *endp;
83
84         if (!buf) 
85                 return 1;
86         while (*buf == ',' || *buf == ':') 
87                 buf++;
88         if (*buf == ' ' || *buf == '/' || *buf == '\0') 
89                 return 1;
90
91         /* nid separators or end of nids */
92         endp = strpbrk(buf, ",: /");
93         if (endp == NULL) 
94                 endp = buf + strlen(buf);
95
96         tmp = *endp;
97         *endp = '\0';
98         *nid = libcfs_str2nid(buf);
99         if (*nid == LNET_NID_ANY) {
100                 LCONSOLE_ERROR("Can't parse NID '%s'\n", buf);
101                 *endp = tmp;
102                 return -EINVAL;
103         }
104         *endp = tmp;
105
106         if (endh) 
107                 *endh = endp;
108         CDEBUG(D_INFO, "Nid %s\n", libcfs_nid2str(*nid));
109         return 0;
110 }
111
112 EXPORT_SYMBOL(class_find_param);
113 EXPORT_SYMBOL(class_match_param);
114 EXPORT_SYMBOL(class_parse_nid);
115
116 /********************** class fns **********************/
117
118 /* Create a new device and set the type, name and uuid.  If
119  * successful, the new device can be accessed by either name or uuid.
120  */
121 int class_attach(struct lustre_cfg *lcfg)
122 {
123         struct obd_device *obd = NULL;
124         char *typename, *name, *uuid;
125         int rc, len;
126         ENTRY;
127
128         if (!LUSTRE_CFG_BUFLEN(lcfg, 1)) {
129                 CERROR("No type passed!\n");
130                 RETURN(-EINVAL);
131         }
132         typename = lustre_cfg_string(lcfg, 1);
133
134         if (!LUSTRE_CFG_BUFLEN(lcfg, 0)) {
135                 CERROR("No name passed!\n");
136                 RETURN(-EINVAL);
137         }
138         name = lustre_cfg_string(lcfg, 0);
139
140         if (!LUSTRE_CFG_BUFLEN(lcfg, 2)) {
141                 CERROR("No UUID passed!\n");
142                 RETURN(-EINVAL);
143         }
144         uuid = lustre_cfg_string(lcfg, 2);
145
146         CDEBUG(D_IOCTL, "attach type %s name: %s uuid: %s\n",
147                MKSTR(typename), MKSTR(name), MKSTR(uuid));
148
149         /* Mountconf transitional hack, should go away after 1.6.
150            1.4.7 uses the old names, so translate back if the
151            mountconf flag is set.
152            1.6 should set this flag, and translate the other way here
153            if not set. */
154 #if 0
155         if (lcfg->lcfg_flags & LCFG_FLG_MOUNTCONF){
156                 char *tmp = NULL;
157                 if (strcmp(typename, "mds") == 0)
158                         tmp = "mds";
159                 if (strcmp(typename, "mdt") == 0)
160                         tmp = "mdt0";
161                 if (strcmp(typename, "osd") == 0)
162                         tmp = "obdfilter";
163                 if (tmp) {
164                         LCONSOLE_WARN("Using type %s for %s %s\n", tmp,
165                                       MKSTR(typename), MKSTR(name));
166                         typename = tmp;
167                 }
168         }
169 #endif
170         obd = class_newdev(typename, name);
171         if (IS_ERR(obd)) {
172                 /* Already exists or out of obds */
173                 rc = PTR_ERR(obd);
174                 obd = NULL;
175                 CERROR("Cannot create device %s of type %s : %d\n",
176                        name, typename, rc);
177                 GOTO(out, rc);
178         }
179         LASSERTF(obd != NULL, "Cannot get obd device %s of type %s\n",
180                  name, typename);
181         LASSERTF(obd->obd_magic == OBD_DEVICE_MAGIC, 
182                  "obd %p obd_magic %08X != %08X\n",
183                  obd, obd->obd_magic, OBD_DEVICE_MAGIC);
184         LASSERTF(strncmp(obd->obd_name, name, strlen(name)) == 0, "%p obd_name %s != %s\n",
185                  obd, obd->obd_name, name);
186
187         CFS_INIT_LIST_HEAD(&obd->obd_exports);
188         CFS_INIT_LIST_HEAD(&obd->obd_exports_timed);
189         spin_lock_init(&obd->obd_dev_lock);
190         sema_init(&obd->obd_dev_sem, 1);
191         spin_lock_init(&obd->obd_osfs_lock);
192         /* obd->obd_osfs_age must be set to a value in the distant
193          * past to guarantee a fresh statfs is fetched on mount. */
194         obd->obd_osfs_age = cfs_time_shift_64(-1000);
195
196         /* XXX belongs in setup not attach  */
197         /* recovery data */
198         cfs_init_timer(&obd->obd_recovery_timer);
199         spin_lock_init(&obd->obd_processing_task_lock);
200         cfs_waitq_init(&obd->obd_next_transno_waitq);
201         CFS_INIT_LIST_HEAD(&obd->obd_req_replay_queue);
202         CFS_INIT_LIST_HEAD(&obd->obd_lock_replay_queue);
203         CFS_INIT_LIST_HEAD(&obd->obd_final_req_queue);
204
205         spin_lock_init(&obd->obd_uncommitted_replies_lock);
206         CFS_INIT_LIST_HEAD(&obd->obd_uncommitted_replies);
207
208         len = strlen(uuid);
209         if (len >= sizeof(obd->obd_uuid)) {
210                 CERROR("uuid must be < "LPSZ" bytes long\n",
211                        sizeof(obd->obd_uuid));
212                 GOTO(out, rc = -EINVAL);
213         }
214         memcpy(obd->obd_uuid.uuid, uuid, len);
215
216         /* do the attach */
217         if (OBP(obd, attach)) {
218                 rc = OBP(obd,attach)(obd, sizeof *lcfg, lcfg);
219                 if (rc)
220                         GOTO(out, rc = -EINVAL);
221         }
222
223         /* Detach drops this */
224         spin_lock(&obd->obd_dev_lock);
225         atomic_set(&obd->obd_refcount, 1);
226         spin_unlock(&obd->obd_dev_lock);
227
228         obd->obd_attached = 1;
229         CDEBUG(D_IOCTL, "OBD: dev %d attached type %s with refcount %d\n",
230                obd->obd_minor, typename, atomic_read(&obd->obd_refcount));
231         RETURN(0);
232  out:
233         if (obd != NULL) {
234                 class_release_dev(obd);
235         }
236         return rc;
237 }
238
239 int class_setup(struct obd_device *obd, struct lustre_cfg *lcfg)
240 {
241         int err = 0;
242         struct obd_export *exp;
243         ENTRY;
244
245         LASSERT(obd != NULL);
246         LASSERTF(obd == class_num2obd(obd->obd_minor), "obd %p != obd_devs[%d] %p\n", 
247                  obd, obd->obd_minor, class_num2obd(obd->obd_minor));
248         LASSERTF(obd->obd_magic == OBD_DEVICE_MAGIC, "obd %p obd_magic %08x != %08x\n", 
249                  obd, obd->obd_magic, OBD_DEVICE_MAGIC);
250
251         /* have we attached a type to this device? */
252         if (!obd->obd_attached) {
253                 CERROR("Device %d not attached\n", obd->obd_minor);
254                 RETURN(-ENODEV);
255         }
256
257         if (obd->obd_set_up) {
258                 CERROR("Device %d already setup (type %s)\n",
259                        obd->obd_minor, obd->obd_type->typ_name);
260                 RETURN(-EEXIST);
261         }
262
263         /* is someone else setting us up right now? (attach inits spinlock) */
264         spin_lock(&obd->obd_dev_lock);
265         if (obd->obd_starting) {
266                 spin_unlock(&obd->obd_dev_lock);
267                 CERROR("Device %d setup in progress (type %s)\n",
268                        obd->obd_minor, obd->obd_type->typ_name);
269                 RETURN(-EEXIST);
270         }
271         /* just leave this on forever.  I can't use obd_set_up here because
272            other fns check that status, and we're not actually set up yet. */
273         obd->obd_starting = 1;
274         spin_unlock(&obd->obd_dev_lock);
275
276         exp = class_new_export(obd, &obd->obd_uuid);
277         if (IS_ERR(exp))
278                 RETURN(PTR_ERR(exp));
279         obd->obd_self_export = exp;
280         list_del_init(&exp->exp_obd_chain_timed);
281         class_export_put(exp);
282
283         err = obd_setup(obd, lcfg);
284         if (err)
285                 GOTO(err_exp, err);
286
287         obd->obd_set_up = 1;
288         spin_lock(&obd->obd_dev_lock);
289         /* cleanup drops this */
290         class_incref(obd);
291         spin_unlock(&obd->obd_dev_lock);
292
293         CDEBUG(D_IOCTL, "finished setup of obd %s (uuid %s)\n",
294                obd->obd_name, obd->obd_uuid.uuid);
295
296         RETURN(0);
297
298 err_exp:
299         CERROR("setup %s failed (%d)\n", obd->obd_name, err);
300         class_unlink_export(obd->obd_self_export);
301         obd->obd_self_export = NULL;
302         obd->obd_starting = 0;
303         RETURN(err);
304 }
305
306 int class_detach(struct obd_device *obd, struct lustre_cfg *lcfg)
307 {
308         ENTRY;
309
310         if (obd->obd_set_up) {
311                 CERROR("OBD device %d still set up\n", obd->obd_minor);
312                 RETURN(-EBUSY);
313         }
314
315         spin_lock(&obd->obd_dev_lock);
316         if (!obd->obd_attached) {
317                 spin_unlock(&obd->obd_dev_lock);
318                 CERROR("OBD device %d not attached\n", obd->obd_minor);
319                 RETURN(-ENODEV);
320         }
321         obd->obd_attached = 0;
322         spin_unlock(&obd->obd_dev_lock);
323
324         CDEBUG(D_IOCTL, "detach on obd %s (uuid %s)\n",
325                obd->obd_name, obd->obd_uuid.uuid);
326
327         class_decref(obd);
328         RETURN(0);
329 }
330
331 static void dump_exports(struct obd_device *obd)
332 {
333         struct obd_export *exp, *n;
334
335         list_for_each_entry_safe(exp, n, &obd->obd_exports, exp_obd_chain) {
336                 struct ptlrpc_reply_state *rs;
337                 struct ptlrpc_reply_state *first_reply = NULL;
338                 int                        nreplies = 0;
339
340                 list_for_each_entry (rs, &exp->exp_outstanding_replies,
341                                      rs_exp_list) {
342                         if (nreplies == 0)
343                                 first_reply = rs;
344                         nreplies++;
345                 }
346
347                 CDEBUG(D_IOCTL, "%s: %p %s %s %d %d %d: %p %s\n",
348                        obd->obd_name, exp, exp->exp_client_uuid.uuid,
349                        obd_export_nid2str(exp),
350                        atomic_read(&exp->exp_refcount),
351                        exp->exp_failed, nreplies, first_reply,
352                        nreplies > 3 ? "..." : "");
353         }
354 }
355
356 int class_cleanup(struct obd_device *obd, struct lustre_cfg *lcfg)
357 {
358         int err = 0;
359         char *flag;
360         ENTRY;
361
362         OBD_RACE(OBD_FAIL_LDLM_RECOV_CLIENTS);
363
364         if (!obd->obd_set_up) {
365                 CERROR("Device %d not setup\n", obd->obd_minor);
366                 RETURN(-ENODEV);
367         }
368
369         spin_lock(&obd->obd_dev_lock);
370         if (obd->obd_stopping) {
371                 spin_unlock(&obd->obd_dev_lock);
372                 CERROR("OBD %d already stopping\n", obd->obd_minor);
373                 RETURN(-ENODEV);
374         }
375         /* Leave this on forever */
376         obd->obd_stopping = 1;
377         spin_unlock(&obd->obd_dev_lock);
378
379         if (lcfg->lcfg_bufcount >= 2 && LUSTRE_CFG_BUFLEN(lcfg, 1) > 0) {
380                 for (flag = lustre_cfg_string(lcfg, 1); *flag != 0; flag++)
381                         switch (*flag) {
382                         case 'F':
383                                 obd->obd_force = 1;
384                                 break;
385                         case 'A':
386                                 LCONSOLE_WARN("Failing over %s\n",
387                                               obd->obd_name);
388                                 obd->obd_fail = 1;
389                                 obd->obd_no_transno = 1;
390                                 obd->obd_no_recov = 1;
391                                 /* Set the obd readonly if we can */
392                                 if (OBP(obd, iocontrol))
393                                         obd_iocontrol(OBD_IOC_SET_READONLY,
394                                                       obd->obd_self_export,
395                                                       0, NULL, NULL);
396                                 break;
397                         default:
398                                 CERROR("unrecognised flag '%c'\n",
399                                        *flag);
400                         }
401         }
402
403         /* The three references that should be remaining are the
404          * obd_self_export and the attach and setup references. */
405         if (atomic_read(&obd->obd_refcount) > 3) {
406                 if (!(obd->obd_fail || obd->obd_force)) {
407                         CERROR("OBD %s is still busy with %d references\n"
408                                "You should stop active file system users,"
409                                " or use the --force option to cleanup.\n",
410                                obd->obd_name, atomic_read(&obd->obd_refcount));
411                         dump_exports(obd);
412                         GOTO(out, err = -EBUSY);
413                 }
414                 /* refcounf - 3 might be the number of real exports 
415                    (excluding self export). But class_incref is called
416                    by other things as well, so don't count on it. */
417                 CDEBUG(D_IOCTL, "%s: forcing exports to disconnect: %d\n",
418                        obd->obd_name, atomic_read(&obd->obd_refcount) - 3);
419                 dump_exports(obd);
420                 class_disconnect_exports(obd);
421         }
422
423         LASSERT(obd->obd_self_export);
424
425         /* Precleanup stage 1, we must make sure all exports (other than the
426            self-export) get destroyed. */
427         err = obd_precleanup(obd, OBD_CLEANUP_EXPORTS);
428         if (err)
429                 CERROR("Precleanup %s returned %d\n",
430                        obd->obd_name, err);
431
432         class_decref(obd);
433         obd->obd_set_up = 0;
434
435         RETURN(0);
436 out:
437         /* Allow a failed cleanup to try again. */
438         obd->obd_stopping = 0;
439         RETURN(err);
440 }
441
442 struct obd_device *class_incref(struct obd_device *obd)
443 {
444         atomic_inc(&obd->obd_refcount);
445         CDEBUG(D_INFO, "incref %s (%p) now %d\n", obd->obd_name, obd,
446                atomic_read(&obd->obd_refcount));
447
448         return obd;
449 }
450
451 void class_decref(struct obd_device *obd)
452 {
453         int err;
454         int refs;
455
456         spin_lock(&obd->obd_dev_lock);
457         atomic_dec(&obd->obd_refcount);
458         refs = atomic_read(&obd->obd_refcount);
459         spin_unlock(&obd->obd_dev_lock);
460
461         CDEBUG(D_INFO, "Decref %s (%p) now %d\n", obd->obd_name, obd, refs);
462
463         if ((refs == 1) && obd->obd_stopping) {
464                 /* All exports (other than the self-export) have been
465                    destroyed; there should be no more in-progress ops
466                    by this point.*/
467                 /* if we're not stopping, we didn't finish setup */
468                 /* Precleanup stage 2,  do other type-specific
469                    cleanup requiring the self-export. */
470                 err = obd_precleanup(obd, OBD_CLEANUP_SELF_EXP);
471                 if (err)
472                         CERROR("Precleanup %s returned %d\n",
473                                obd->obd_name, err);
474                 obd->obd_self_export->exp_flags |=
475                         (obd->obd_fail ? OBD_OPT_FAILOVER : 0) |
476                         (obd->obd_force ? OBD_OPT_FORCE : 0);
477                 /* note that we'll recurse into class_decref again */
478                 class_unlink_export(obd->obd_self_export);
479                 return;
480         }
481
482         if (refs == 0) {
483                 CDEBUG(D_CONFIG, "finishing cleanup of obd %s (%s)\n",
484                        obd->obd_name, obd->obd_uuid.uuid);
485                 LASSERT(!obd->obd_attached);
486                 if (obd->obd_stopping) {
487                         /* If we're not stopping, we were never set up */
488                         err = obd_cleanup(obd);
489                         if (err)
490                                 CERROR("Cleanup %s returned %d\n",
491                                        obd->obd_name, err);
492                 }
493                 if (OBP(obd, detach)) {
494                         err = OBP(obd,detach)(obd);
495                         if (err)
496                                 CERROR("Detach returned %d\n", err);
497                 }
498                 class_release_dev(obd);
499         }
500 }
501
502 int class_add_conn(struct obd_device *obd, struct lustre_cfg *lcfg)
503 {
504         struct obd_import *imp;
505         struct obd_uuid uuid;
506         int rc;
507         ENTRY;
508
509         if (LUSTRE_CFG_BUFLEN(lcfg, 1) < 1 ||
510             LUSTRE_CFG_BUFLEN(lcfg, 1) > sizeof(struct obd_uuid)) {
511                 CERROR("invalid conn_uuid\n");
512                 RETURN(-EINVAL);
513         }
514         if (strcmp(obd->obd_type->typ_name, LUSTRE_MDC_NAME) &&
515             strcmp(obd->obd_type->typ_name, LUSTRE_OSC_NAME) &&
516             strcmp(obd->obd_type->typ_name, LUSTRE_MGC_NAME)) {
517                 CERROR("can't add connection on non-client dev\n");
518                 RETURN(-EINVAL);
519         }
520
521         imp = obd->u.cli.cl_import;
522         if (!imp) {
523                 CERROR("try to add conn on immature client dev\n");
524                 RETURN(-EINVAL);
525         }
526
527         obd_str2uuid(&uuid, lustre_cfg_string(lcfg, 1));
528         rc = obd_add_conn(imp, &uuid, lcfg->lcfg_num);
529
530         RETURN(rc);
531 }
532
533 int class_del_conn(struct obd_device *obd, struct lustre_cfg *lcfg)
534 {
535         struct obd_import *imp;
536         struct obd_uuid uuid;
537         int rc;
538         ENTRY;
539
540         if (LUSTRE_CFG_BUFLEN(lcfg, 1) < 1 ||
541             LUSTRE_CFG_BUFLEN(lcfg, 1) > sizeof(struct obd_uuid)) {
542                 CERROR("invalid conn_uuid\n");
543                 RETURN(-EINVAL);
544         }
545         if (strcmp(obd->obd_type->typ_name, LUSTRE_MDC_NAME) &&
546             strcmp(obd->obd_type->typ_name, LUSTRE_OSC_NAME)) {
547                 CERROR("can't del connection on non-client dev\n");
548                 RETURN(-EINVAL);
549         }
550
551         imp = obd->u.cli.cl_import;
552         if (!imp) {
553                 CERROR("try to del conn on immature client dev\n");
554                 RETURN(-EINVAL);
555         }
556
557         obd_str2uuid(&uuid, lustre_cfg_string(lcfg, 1));
558         rc = obd_del_conn(imp, &uuid);
559
560         RETURN(rc);
561 }
562
563 int class_sec_flavor(struct obd_device *obd, struct lustre_cfg *lcfg)
564 {
565         struct sec_flavor_config *conf;
566         ENTRY;
567
568         if (strcmp(obd->obd_type->typ_name, LUSTRE_MDC_NAME) &&
569             strcmp(obd->obd_type->typ_name, LUSTRE_OSC_NAME)) {
570                 CERROR("Can't set security flavor on obd %s\n",
571                        obd->obd_type->typ_name);
572                 RETURN(-EINVAL);
573         }
574
575         if (LUSTRE_CFG_BUFLEN(lcfg, 1) != sizeof(*conf)) {
576                 CERROR("invalid data\n");
577                 RETURN(-EINVAL);
578         }
579
580         conf = &obd->u.cli.cl_sec_conf;
581         memcpy(conf, lustre_cfg_buf(lcfg, 1), sizeof(*conf));
582
583 #ifdef __BIG_ENDIAN
584         __swab32s(&conf->sfc_rpc_flavor);
585         __swab32s(&conf->sfc_bulk_csum);
586         __swab32s(&conf->sfc_bulk_priv);
587         __swab32s(&conf->sfc_flags);
588 #endif
589
590         RETURN(0);
591 }
592
593 CFS_LIST_HEAD(lustre_profile_list);
594
595 struct lustre_profile *class_get_profile(const char * prof)
596 {
597         struct lustre_profile *lprof;
598
599         ENTRY;
600         list_for_each_entry(lprof, &lustre_profile_list, lp_list) {
601                 if (!strcmp(lprof->lp_profile, prof)) {
602                         RETURN(lprof);
603                 }
604         }
605         RETURN(NULL);
606 }
607
608 int class_add_profile(int proflen, char *prof, int osclen, char *osc,
609                       int mdclen, char *mdc)
610 {
611         struct lustre_profile *lprof;
612         int err = 0;
613         ENTRY;
614
615         CDEBUG(D_CONFIG, "Add profile %s\n", prof);
616
617         OBD_ALLOC(lprof, sizeof(*lprof));
618         if (lprof == NULL)
619                 RETURN(-ENOMEM);
620         CFS_INIT_LIST_HEAD(&lprof->lp_list);
621
622         LASSERT(proflen == (strlen(prof) + 1));
623         OBD_ALLOC(lprof->lp_profile, proflen);
624         if (lprof->lp_profile == NULL)
625                 GOTO(out, err = -ENOMEM);
626         memcpy(lprof->lp_profile, prof, proflen);
627
628         LASSERT(osclen == (strlen(osc) + 1));
629         OBD_ALLOC(lprof->lp_dt, osclen);
630         if (lprof->lp_dt == NULL)
631                 GOTO(out, err = -ENOMEM);
632         memcpy(lprof->lp_dt, osc, osclen);
633
634         if (mdclen > 0) {
635                 LASSERT(mdclen == (strlen(mdc) + 1));
636                 OBD_ALLOC(lprof->lp_md, mdclen);
637                 if (lprof->lp_md == NULL)
638                         GOTO(out, err = -ENOMEM);
639                 memcpy(lprof->lp_md, mdc, mdclen);
640         }
641
642         list_add(&lprof->lp_list, &lustre_profile_list);
643         RETURN(err);
644
645 out:
646         if (lprof->lp_md)
647                 OBD_FREE(lprof->lp_md, mdclen);
648         if (lprof->lp_dt)
649                 OBD_FREE(lprof->lp_dt, osclen);
650         if (lprof->lp_profile)
651                 OBD_FREE(lprof->lp_profile, proflen);
652         OBD_FREE(lprof, sizeof(*lprof));        
653         RETURN(err);
654 }
655
656 void class_del_profile(const char *prof)
657 {
658         struct lustre_profile *lprof;
659         ENTRY;
660
661         CDEBUG(D_CONFIG, "Del profile %s\n", prof);
662
663         lprof = class_get_profile(prof);
664         if (lprof) {
665                 list_del(&lprof->lp_list);
666                 OBD_FREE(lprof->lp_profile, strlen(lprof->lp_profile) + 1);
667                 OBD_FREE(lprof->lp_dt, strlen(lprof->lp_dt) + 1);
668                 if (lprof->lp_md)
669                         OBD_FREE(lprof->lp_md, strlen(lprof->lp_md) + 1);
670                 OBD_FREE(lprof, sizeof *lprof);
671         }
672         EXIT;
673 }
674
675 /* COMPAT_146 */
676 void class_del_profiles(void)
677 {
678         struct lustre_profile *lprof, *n;
679         ENTRY;
680
681         list_for_each_entry_safe(lprof, n, &lustre_profile_list, lp_list) {
682                 list_del(&lprof->lp_list);
683                 OBD_FREE(lprof->lp_profile, strlen(lprof->lp_profile) + 1);
684                 OBD_FREE(lprof->lp_dt, strlen(lprof->lp_dt) + 1);
685                 if (lprof->lp_md)
686                         OBD_FREE(lprof->lp_md, strlen(lprof->lp_md) + 1);
687                 OBD_FREE(lprof, sizeof *lprof);
688         }
689         EXIT;
690 }
691
692 /* We can't call ll_process_config directly because it lives in a module that
693    must be loaded after this one. */
694 static int (*client_process_config)(struct lustre_cfg *lcfg) = NULL;
695
696 void lustre_register_client_process_config(int (*cpc)(struct lustre_cfg *lcfg))
697 {
698         client_process_config = cpc;
699 }
700 EXPORT_SYMBOL(lustre_register_client_process_config);
701
702 int class_process_config(struct lustre_cfg *lcfg)
703 {
704         struct obd_device *obd;
705         int err;
706
707         LASSERT(lcfg && !IS_ERR(lcfg));
708         CDEBUG(D_IOCTL, "processing cmd: %x\n", lcfg->lcfg_command);
709
710         /* Commands that don't need a device */
711         switch(lcfg->lcfg_command) {
712         case LCFG_ATTACH: {
713                 err = class_attach(lcfg);
714                 GOTO(out, err);
715         }
716         case LCFG_ADD_UUID: {
717                 CDEBUG(D_IOCTL, "adding mapping from uuid %s to nid "LPX64
718                        " (%s)\n", lustre_cfg_string(lcfg, 1),
719                        lcfg->lcfg_nid, libcfs_nid2str(lcfg->lcfg_nid));
720
721                 err = class_add_uuid(lustre_cfg_string(lcfg, 1), lcfg->lcfg_nid);
722                 GOTO(out, err);
723         }
724         case LCFG_DEL_UUID: {
725                 CDEBUG(D_IOCTL, "removing mappings for uuid %s\n",
726                        (lcfg->lcfg_bufcount < 2 || LUSTRE_CFG_BUFLEN(lcfg, 1) == 0)
727                        ? "<all uuids>" : lustre_cfg_string(lcfg, 1));
728
729                 err = class_del_uuid(lustre_cfg_string(lcfg, 1));
730                 GOTO(out, err);
731         }
732         case LCFG_MOUNTOPT: {
733                 CDEBUG(D_IOCTL, "mountopt: profile %s osc %s mdc %s\n",
734                        lustre_cfg_string(lcfg, 1),
735                        lustre_cfg_string(lcfg, 2),
736                        lustre_cfg_string(lcfg, 3));
737                 /* set these mount options somewhere, so ll_fill_super
738                  * can find them. */
739                 err = class_add_profile(LUSTRE_CFG_BUFLEN(lcfg, 1),
740                                         lustre_cfg_string(lcfg, 1),
741                                         LUSTRE_CFG_BUFLEN(lcfg, 2),
742                                         lustre_cfg_string(lcfg, 2),
743                                         LUSTRE_CFG_BUFLEN(lcfg, 3),
744                                         lustre_cfg_string(lcfg, 3));
745                 GOTO(out, err);
746         }
747         case LCFG_DEL_MOUNTOPT: {
748                 CDEBUG(D_IOCTL, "mountopt: profile %s\n",
749                        lustre_cfg_string(lcfg, 1));
750                 class_del_profile(lustre_cfg_string(lcfg, 1));
751                 GOTO(out, err = 0);
752         }
753         case LCFG_SET_TIMEOUT: {
754                 CDEBUG(D_IOCTL, "changing lustre timeout from %d to %d\n",
755                        obd_timeout, lcfg->lcfg_num);
756                 obd_timeout = max(lcfg->lcfg_num, 1U);
757                 GOTO(out, err = 0);
758         }
759         case LCFG_SET_UPCALL: {
760                 LCONSOLE_ERROR("recovery upcall is deprecated\n");
761                 /* COMPAT_146 Don't fail on old configs */
762                 GOTO(out, err = 0);
763         }
764         case LCFG_MARKER: {
765                 struct cfg_marker *marker;
766                 marker = lustre_cfg_buf(lcfg, 1);
767                 CDEBUG(D_IOCTL, "marker %d (%#x) %.16s %s\n", marker->cm_step,
768                        marker->cm_flags, marker->cm_svname, marker->cm_comment);
769                 GOTO(out, err = 0);
770         }
771         case LCFG_PARAM: {
772                 /* llite has no obd */
773                 if ((class_match_param(lustre_cfg_string(lcfg, 1), 
774                                        PARAM_LLITE, 0) == 0) &&
775                     client_process_config) {
776                         err = (*client_process_config)(lcfg);
777                         GOTO(out, err);
778                 }
779                 /* Fall through */
780                 break;
781         }
782         }
783
784         /* Commands that require a device */
785         obd = class_name2obd(lustre_cfg_string(lcfg, 0));
786         if (obd == NULL) {
787                 if (!LUSTRE_CFG_BUFLEN(lcfg, 0))
788                         CERROR("this lcfg command requires a device name\n");
789                 else
790                         CERROR("no device for: %s\n",
791                                lustre_cfg_string(lcfg, 0));
792
793                 GOTO(out, err = -EINVAL);
794         }
795
796         switch(lcfg->lcfg_command) {
797         case LCFG_SETUP: {
798                 err = class_setup(obd, lcfg);
799                 GOTO(out, err);
800         }
801         case LCFG_DETACH: {
802                 err = class_detach(obd, lcfg);
803                 GOTO(out, err = 0);
804         }
805         case LCFG_CLEANUP: {
806                 err = class_cleanup(obd, lcfg);
807                 GOTO(out, err = 0);
808         }
809         case LCFG_ADD_CONN: {
810                 err = class_add_conn(obd, lcfg);
811                 GOTO(out, err = 0);
812         }
813         case LCFG_DEL_CONN: {
814                 err = class_del_conn(obd, lcfg);
815                 GOTO(out, err = 0);
816         }
817         case LCFG_SEC_FLAVOR: {
818                 err = class_sec_flavor(obd, lcfg);
819                 GOTO(out, err = 0);
820         }
821         default: {
822                 err = obd_process_config(obd, sizeof(*lcfg), lcfg);
823                 GOTO(out, err);
824
825         }
826         }
827 out:
828         if ((err < 0) && !(lcfg->lcfg_command & LCFG_REQUIRED)) {
829                 CWARN("Ignoring error %d on optional command %#x\n", err, 
830                       lcfg->lcfg_command);
831                 err = 0;
832         }
833         return err;
834 }
835
836 int class_process_proc_param(char *prefix, struct lprocfs_vars *lvars, 
837                              struct lustre_cfg *lcfg, void *data)
838 {
839 #ifdef __KERNEL__
840         struct lprocfs_vars *var;
841         char *key, *sval;
842         int i, keylen, vallen;
843         int matched = 0, j = 0;
844         int rc = 0;
845         ENTRY;
846
847         if (lcfg->lcfg_command != LCFG_PARAM) {
848                 CERROR("Unknown command: %d\n", lcfg->lcfg_command);
849                 RETURN(-EINVAL);
850         }
851
852         /* e.g. tunefs.lustre --param mdt.group_upcall=foo /r/tmp/lustre-mdt
853            or   lctl conf_param lustre-MDT0000.mdt.group_upcall=bar
854            or   lctl conf_param lustre-OST0000.osc.max_dirty_mb=36 */
855         for (i = 1; i < lcfg->lcfg_bufcount; i++) {
856                 key = lustre_cfg_buf(lcfg, i);
857                 /* Strip off prefix */
858                 class_match_param(key, prefix, &key);
859                 sval = strchr(key, '=');
860                 if (!sval || (*(sval + 1) == 0)) {
861                         CERROR("Can't parse param %s\n", key);
862                         rc = -EINVAL;
863                         /* continue parsing other params */
864                         continue;
865                 }
866                 keylen = sval - key;
867                 sval++;
868                 vallen = strlen(sval);
869                 matched = 0;
870                 j = 0;
871                 /* Search proc entries */
872                 while (lvars[j].name) {
873                         var = &lvars[j];
874                         if (class_match_param(key, (char *)var->name, 0) == 0 &&
875                             keylen == strlen(var->name)) {
876                                 matched++;
877                                 rc = -EROFS;
878                                 if (var->write_fptr) {
879                                         mm_segment_t oldfs;
880                                         oldfs = get_fs();
881                                         set_fs(KERNEL_DS);
882                                         rc = (var->write_fptr)(NULL, sval,
883                                                                vallen, data);
884                                         set_fs(oldfs);
885                                 }
886                                 if (rc < 0) 
887                                         CERROR("writing proc entry %s err %d\n", 
888                                                var->name, rc);
889                                 break;
890                         }
891                         j++;
892                 }    
893                 if (!matched) {
894                         CERROR("Unknown param %s\n", key);
895                         rc = -EINVAL;
896                         /* continue parsing other params */
897                 } else {
898                         LCONSOLE_INFO("%s: set %s to %s\n", prefix,
899                                       key, sval);
900                 }
901         }
902         
903         if (rc > 0) 
904                 rc = 0;
905         RETURN(rc);
906 #else
907         CDEBUG(D_CONFIG, "liblustre can't process params.\n");
908         return -ENOSYS;
909 #endif
910 }
911
912 int class_config_dump_handler(struct llog_handle * handle,
913                               struct llog_rec_hdr *rec, void *data);
914
915 #ifdef __KERNEL__
916 extern int lustre_check_exclusion(struct super_block *sb, char *svname);
917 #else
918 #define lustre_check_exclusion(a,b)  0
919 #endif
920
921 static int class_config_llog_handler(struct llog_handle * handle,
922                                      struct llog_rec_hdr *rec, void *data)
923 {
924         struct config_llog_instance *clli = data;
925         int cfg_len = rec->lrh_len;
926         char *cfg_buf = (char*) (rec + 1);
927         int rc = 0;
928         ENTRY;
929
930         //class_config_dump_handler(handle, rec, data);
931
932         switch (rec->lrh_type) {
933         case OBD_CFG_REC: {
934                 struct lustre_cfg *lcfg, *lcfg_new;
935                 struct lustre_cfg_bufs bufs;
936                 char *inst_name = NULL;
937                 int inst_len = 0;
938                 int inst = 0;
939
940                 lcfg = (struct lustre_cfg *)cfg_buf;
941                 if (lcfg->lcfg_version == __swab32(LUSTRE_CFG_VERSION))
942                         lustre_swab_lustre_cfg(lcfg);
943
944                 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
945                 if (rc)
946                         GOTO(out, rc);
947
948                 /* Figure out config state info */
949                 if (lcfg->lcfg_command == LCFG_MARKER) {
950                         struct cfg_marker *marker = lustre_cfg_buf(lcfg, 1);
951                         CDEBUG(D_CONFIG, "Marker, inst_flg=%#x mark_flg=%#x\n",
952                                clli->cfg_flags, marker->cm_flags);
953                         if (marker->cm_flags & CM_START) {
954                                 /* all previous flags off */
955                                 clli->cfg_flags = CFG_F_MARKER;
956                                 if (marker->cm_flags & CM_SKIP) { 
957                                         clli->cfg_flags |= CFG_F_SKIP;
958                                         CDEBUG(D_CONFIG, "SKIP #%d\n",
959                                                marker->cm_step);
960                                 } else if (lustre_check_exclusion(clli->cfg_sb, 
961                                                           marker->cm_svname)) {
962                                         clli->cfg_flags |= CFG_F_EXCLUDE;
963                                         CDEBUG(D_CONFIG, "EXCLUDE %d\n",
964                                                marker->cm_step);
965                                 }
966                         } else if (marker->cm_flags & CM_END) {
967                                 clli->cfg_flags = 0;
968                         }
969                 }
970                 /* A config command without a start marker before it is 
971                    illegal (post 146) */
972                 if (!(clli->cfg_flags & CFG_F_COMPAT146) &&
973                     !(clli->cfg_flags & CFG_F_MARKER) && 
974                     (lcfg->lcfg_command != LCFG_MARKER)) {
975                         CWARN("Config not inside markers, ignoring! (%#x)\n", 
976                               clli->cfg_flags);
977                         clli->cfg_flags |= CFG_F_SKIP;
978                 }
979                 if (clli->cfg_flags & CFG_F_SKIP) {
980                         CDEBUG(D_CONFIG, "skipping %#x\n",
981                                clli->cfg_flags);
982                         rc = 0;
983                         /* No processing! */
984                         break;
985                 }
986
987                 if ((clli->cfg_flags & CFG_F_EXCLUDE) && 
988                     (lcfg->lcfg_command == LCFG_LOV_ADD_OBD))
989                         /* Add inactive instead */
990                         lcfg->lcfg_command = LCFG_LOV_ADD_INA;
991
992                 lustre_cfg_bufs_init(&bufs, lcfg);
993
994                 if (clli && clli->cfg_instance && 
995                     LUSTRE_CFG_BUFLEN(lcfg, 0) > 0){
996                         inst = 1;
997                         inst_len = LUSTRE_CFG_BUFLEN(lcfg, 0) +
998                                 strlen(clli->cfg_instance) + 1;
999                         OBD_ALLOC(inst_name, inst_len);
1000                         if (inst_name == NULL)
1001                                 GOTO(out, rc = -ENOMEM);
1002                         sprintf(inst_name, "%s-%s",
1003                                 lustre_cfg_string(lcfg, 0),
1004                                 clli->cfg_instance);
1005                         lustre_cfg_bufs_set_string(&bufs, 0, inst_name);
1006                         CDEBUG(D_CONFIG, "cmd %x, instance name: %s\n",
1007                                lcfg->lcfg_command, inst_name);
1008                 }
1009
1010                 /* we override the llog's uuid for clients, to insure they
1011                 are unique */
1012                 if (clli && clli->cfg_instance && 
1013                     lcfg->lcfg_command == LCFG_ATTACH) {
1014                         lustre_cfg_bufs_set_string(&bufs, 2,
1015                                                    clli->cfg_uuid.uuid);
1016                 }
1017
1018                 lcfg_new = lustre_cfg_new(lcfg->lcfg_command, &bufs);
1019
1020                 lcfg_new->lcfg_num   = lcfg->lcfg_num;
1021                 lcfg_new->lcfg_flags = lcfg->lcfg_flags;
1022
1023                 /* XXX Hack to try to remain binary compatible with
1024                  * pre-newconfig logs */
1025                 if (lcfg->lcfg_nal != 0 &&      /* pre-newconfig log? */
1026                     (lcfg->lcfg_nid >> 32) == 0) {
1027                         __u32 addr = (__u32)(lcfg->lcfg_nid & 0xffffffff);
1028
1029                         lcfg_new->lcfg_nid =
1030                                 LNET_MKNID(LNET_MKNET(lcfg->lcfg_nal, 0), addr);
1031                         CWARN("Converted pre-newconfig NAL %d NID %x to %s\n",
1032                               lcfg->lcfg_nal, addr,
1033                               libcfs_nid2str(lcfg_new->lcfg_nid));
1034                 } else {
1035                         lcfg_new->lcfg_nid = lcfg->lcfg_nid;
1036                 }
1037
1038                 lcfg_new->lcfg_nal = 0; /* illegal value for obsolete field */
1039
1040                 rc = class_process_config(lcfg_new);
1041                 lustre_cfg_free(lcfg_new);
1042
1043                 if (inst)
1044                         OBD_FREE(inst_name, inst_len);
1045                 break;
1046         }
1047         default:
1048                 CERROR("Unknown llog record type %#x encountered\n",
1049                        rec->lrh_type);
1050                 break;
1051         }
1052 out:
1053         if (rc) {
1054                 CERROR("Err %d on cfg command:\n", rc);
1055                 class_config_dump_handler(handle, rec, data);
1056         }
1057         RETURN(rc);
1058 }
1059
1060 void class_config_notify_end(const char *name)
1061 {
1062         struct obd_device *obd;
1063         ENTRY;
1064
1065         /*XXX: This is fast fix to mountconf issue when osc are set up
1066          * while recovery is in progress already.
1067          * The MDS should wait the end of config llog parsing before starting
1068          * recovery. This is done via obd_configured flag for now
1069          */
1070         obd = class_name2obd(name);
1071         if (obd) {
1072                 obd->obd_configured = 1;
1073         }
1074         EXIT;
1075 }
1076
1077 int class_config_parse_llog(struct llog_ctxt *ctxt, char *name,
1078                             struct config_llog_instance *cfg)
1079 {
1080         struct llog_process_cat_data cd = {0, 0};
1081         struct llog_handle *llh;
1082         int rc, rc2;
1083         ENTRY;
1084
1085         CDEBUG(D_INFO, "looking up llog %s\n", name);
1086         rc = llog_create(ctxt, &llh, NULL, name);
1087         if (rc)
1088                 RETURN(rc);
1089
1090         rc = llog_init_handle(llh, LLOG_F_IS_PLAIN, NULL);
1091         if (rc)
1092                 GOTO(parse_out, rc);
1093
1094         /* continue processing from where we last stopped to end-of-log */
1095         if (cfg)
1096                 cd.first_idx = cfg->cfg_last_idx;
1097         cd.last_idx = 0;
1098
1099         rc = llog_process(llh, class_config_llog_handler, cfg, &cd);
1100
1101         class_config_notify_end(name);
1102
1103         CDEBUG(D_CONFIG, "Processed log %s gen %d-%d (rc=%d)\n", name, 
1104                cd.first_idx + 1, cd.last_idx, rc);
1105         if (cfg)
1106                 cfg->cfg_last_idx = cd.last_idx;
1107
1108 parse_out:
1109         rc2 = llog_close(llh);
1110         if (rc == 0)
1111                 rc = rc2;
1112
1113         RETURN(rc);
1114 }
1115
1116 int class_config_dump_handler(struct llog_handle * handle,
1117                               struct llog_rec_hdr *rec, void *data)
1118 {
1119         int cfg_len = rec->lrh_len;
1120         char *cfg_buf = (char*) (rec + 1);
1121         char *outstr, *ptr, *end;
1122         int rc = 0;
1123         ENTRY;
1124
1125         OBD_ALLOC(outstr, 256);
1126         end = outstr + 256;
1127         ptr = outstr;
1128         if (!outstr) {
1129                 RETURN(-ENOMEM);
1130         }
1131         if (rec->lrh_type == OBD_CFG_REC) {
1132                 struct lustre_cfg *lcfg;
1133                 int i;
1134
1135                 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
1136                 if (rc)
1137                         GOTO(out, rc);
1138                 lcfg = (struct lustre_cfg *)cfg_buf;
1139
1140                 ptr += snprintf(ptr, end-ptr, "cmd=%05x ",
1141                                 lcfg->lcfg_command);
1142                 if (lcfg->lcfg_flags) {
1143                         ptr += snprintf(ptr, end-ptr, "flags=%#08x ",
1144                                         lcfg->lcfg_flags);
1145                 }
1146                 if (lcfg->lcfg_num) {
1147                         ptr += snprintf(ptr, end-ptr, "num=%#08x ",
1148                                         lcfg->lcfg_num);
1149                 }
1150                 if (lcfg->lcfg_nid) {
1151                         ptr += snprintf(ptr, end-ptr, "nid=%s("LPX64")\n     ",
1152                                         libcfs_nid2str(lcfg->lcfg_nid),
1153                                         lcfg->lcfg_nid);
1154                 }
1155                 if (lcfg->lcfg_command == LCFG_MARKER) {
1156                         struct cfg_marker *marker = lustre_cfg_buf(lcfg, 1);
1157                         ptr += snprintf(ptr, end-ptr, "marker=%d(%#x)%s '%s'",
1158                                         marker->cm_step, marker->cm_flags,
1159                                         marker->cm_svname, marker->cm_comment);
1160                 } else {
1161                         for (i = 0; i <  lcfg->lcfg_bufcount; i++) {
1162                                 ptr += snprintf(ptr, end-ptr, "%d:%s  ", i,
1163                                                 lustre_cfg_string(lcfg, i));
1164                         }
1165                 }
1166                 LCONSOLE(D_WARNING, "   %s\n", outstr);
1167         } else {
1168                 LCONSOLE(D_WARNING, "unhandled lrh_type: %#x\n", rec->lrh_type);
1169                 rc = -EINVAL;
1170         }
1171 out:
1172         OBD_FREE(outstr, 256);
1173         RETURN(rc);
1174 }
1175
1176 int class_config_dump_llog(struct llog_ctxt *ctxt, char *name,
1177                            struct config_llog_instance *cfg)
1178 {
1179         struct llog_handle *llh;
1180         int rc, rc2;
1181         ENTRY;
1182
1183         LCONSOLE_INFO("Dumping config log %s\n", name);
1184
1185         rc = llog_create(ctxt, &llh, NULL, name);
1186         if (rc)
1187                 RETURN(rc);
1188
1189         rc = llog_init_handle(llh, LLOG_F_IS_PLAIN, NULL);
1190         if (rc)
1191                 GOTO(parse_out, rc);
1192
1193         rc = llog_process(llh, class_config_dump_handler, cfg, NULL);
1194 parse_out:
1195         rc2 = llog_close(llh);
1196         if (rc == 0)
1197                 rc = rc2;
1198
1199         LCONSOLE_INFO("End config log %s\n", name);
1200         RETURN(rc);
1201
1202 }
1203
1204 /* Cleanup and detach */
1205 int class_manual_cleanup(struct obd_device *obd)
1206 {
1207         struct lustre_cfg *lcfg;
1208         struct lustre_cfg_bufs bufs;
1209         int rc;
1210         char flags[3]="";
1211         ENTRY;
1212
1213         if (!obd) {
1214                 CERROR("empty cleanup\n");
1215                 RETURN(-EALREADY);
1216         }
1217
1218         if (obd->obd_force)
1219                 strcat(flags, "F");
1220         if (obd->obd_fail)
1221                 strcat(flags, "A");
1222
1223         CDEBUG(D_CONFIG, "Manual cleanup of %s (flags='%s')\n",
1224                obd->obd_name, flags);
1225
1226         lustre_cfg_bufs_reset(&bufs, obd->obd_name);
1227         lustre_cfg_bufs_set_string(&bufs, 1, flags);
1228         lcfg = lustre_cfg_new(LCFG_CLEANUP, &bufs);
1229
1230         rc = class_process_config(lcfg);
1231         if (rc) {
1232                 CERROR("cleanup failed %d: %s\n", rc, obd->obd_name);
1233                 GOTO(out, rc);
1234         }
1235
1236         /* the lcfg is almost the same for both ops */
1237         lcfg->lcfg_command = LCFG_DETACH;
1238         rc = class_process_config(lcfg);
1239         if (rc)
1240                 CERROR("detach failed %d: %s\n", rc, obd->obd_name);
1241 out:
1242         lustre_cfg_free(lcfg);
1243         RETURN(rc);
1244 }
1245