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