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