These changes are the raw update to linux-4.4.6-rt14. Kernel sources
[kvmfornfv.git] / kernel / drivers / staging / lustre / lustre / obdclass / obd_config.c
1 /*
2  * GPL HEADER START
3  *
4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 only,
8  * as published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * General Public License version 2 for more details (a copy is included
14  * in the LICENSE file that accompanied this code).
15  *
16  * You should have received a copy of the GNU General Public License
17  * version 2 along with this program; If not, see
18  * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
19  *
20  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
21  * CA 95054 USA or visit www.sun.com if you need additional information or
22  * have any questions.
23  *
24  * GPL HEADER END
25  */
26 /*
27  * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
28  * Use is subject to license terms.
29  *
30  * Copyright (c) 2011, 2012, Intel Corporation.
31  */
32 /*
33  * This file is part of Lustre, http://www.lustre.org/
34  * Lustre is a trademark of Sun Microsystems, Inc.
35  *
36  * lustre/obdclass/obd_config.c
37  *
38  * Config API
39  */
40
41 #define DEBUG_SUBSYSTEM S_CLASS
42 #include "../include/obd_class.h"
43 #include <linux/string.h>
44 #include "../include/lustre_log.h"
45 #include "../include/lprocfs_status.h"
46 #include "../include/lustre_param.h"
47
48 #include "llog_internal.h"
49
50 static struct cfs_hash_ops uuid_hash_ops;
51
52 /*********** string parsing utils *********/
53
54 /* returns 0 if we find this key in the buffer, else 1 */
55 int class_find_param(char *buf, char *key, char **valp)
56 {
57         char *ptr;
58
59         if (!buf)
60                 return 1;
61
62         ptr = strstr(buf, key);
63         if (!ptr)
64                 return 1;
65
66         if (valp)
67                 *valp = ptr + strlen(key);
68
69         return 0;
70 }
71 EXPORT_SYMBOL(class_find_param);
72
73 /* returns 0 if this is the first key in the buffer, else 1.
74    valp points to first char after key. */
75 static int class_match_param(char *buf, char *key, char **valp)
76 {
77         if (!buf)
78                 return 1;
79
80         if (memcmp(buf, key, strlen(key)) != 0)
81                 return 1;
82
83         if (valp)
84                 *valp = buf + strlen(key);
85
86         return 0;
87 }
88
89 static int parse_nid(char *buf, void *value, int quiet)
90 {
91         lnet_nid_t *nid = value;
92
93         *nid = libcfs_str2nid(buf);
94         if (*nid != LNET_NID_ANY)
95                 return 0;
96
97         if (!quiet)
98                 LCONSOLE_ERROR_MSG(0x159, "Can't parse NID '%s'\n", buf);
99         return -EINVAL;
100 }
101
102 static int parse_net(char *buf, void *value)
103 {
104         __u32 *net = value;
105
106         *net = libcfs_str2net(buf);
107         CDEBUG(D_INFO, "Net %s\n", libcfs_net2str(*net));
108         return 0;
109 }
110
111 enum {
112         CLASS_PARSE_NID = 1,
113         CLASS_PARSE_NET,
114 };
115
116 /* 0 is good nid,
117    1 not found
118    < 0 error
119    endh is set to next separator */
120 static int class_parse_value(char *buf, int opc, void *value, char **endh,
121                              int quiet)
122 {
123         char *endp;
124         char  tmp;
125         int   rc = 0;
126
127         if (!buf)
128                 return 1;
129         while (*buf == ',' || *buf == ':')
130                 buf++;
131         if (*buf == ' ' || *buf == '/' || *buf == '\0')
132                 return 1;
133
134         /* nid separators or end of nids */
135         endp = strpbrk(buf, ",: /");
136         if (!endp)
137                 endp = buf + strlen(buf);
138
139         tmp = *endp;
140         *endp = '\0';
141         switch (opc) {
142         default:
143                 LBUG();
144         case CLASS_PARSE_NID:
145                 rc = parse_nid(buf, value, quiet);
146                 break;
147         case CLASS_PARSE_NET:
148                 rc = parse_net(buf, value);
149                 break;
150         }
151         *endp = tmp;
152         if (rc != 0)
153                 return rc;
154         if (endh)
155                 *endh = endp;
156         return 0;
157 }
158
159 int class_parse_nid(char *buf, lnet_nid_t *nid, char **endh)
160 {
161         return class_parse_value(buf, CLASS_PARSE_NID, (void *)nid, endh, 0);
162 }
163 EXPORT_SYMBOL(class_parse_nid);
164
165 int class_parse_nid_quiet(char *buf, lnet_nid_t *nid, char **endh)
166 {
167         return class_parse_value(buf, CLASS_PARSE_NID, (void *)nid, endh, 1);
168 }
169 EXPORT_SYMBOL(class_parse_nid_quiet);
170
171 /********************** class fns **********************/
172
173 /**
174  * Create a new obd device and set the type, name and uuid.  If successful,
175  * the new device can be accessed by either name or uuid.
176  */
177 static int class_attach(struct lustre_cfg *lcfg)
178 {
179         struct obd_device *obd = NULL;
180         char *typename, *name, *uuid;
181         int rc, len;
182
183         if (!LUSTRE_CFG_BUFLEN(lcfg, 1)) {
184                 CERROR("No type passed!\n");
185                 return -EINVAL;
186         }
187         typename = lustre_cfg_string(lcfg, 1);
188
189         if (!LUSTRE_CFG_BUFLEN(lcfg, 0)) {
190                 CERROR("No name passed!\n");
191                 return -EINVAL;
192         }
193         name = lustre_cfg_string(lcfg, 0);
194
195         if (!LUSTRE_CFG_BUFLEN(lcfg, 2)) {
196                 CERROR("No UUID passed!\n");
197                 return -EINVAL;
198         }
199         uuid = lustre_cfg_string(lcfg, 2);
200
201         CDEBUG(D_IOCTL, "attach type %s name: %s uuid: %s\n",
202                MKSTR(typename), MKSTR(name), MKSTR(uuid));
203
204         obd = class_newdev(typename, name);
205         if (IS_ERR(obd)) {
206                 /* Already exists or out of obds */
207                 rc = PTR_ERR(obd);
208                 obd = NULL;
209                 CERROR("Cannot create device %s of type %s : %d\n",
210                        name, typename, rc);
211                 goto out;
212         }
213         LASSERTF(obd != NULL, "Cannot get obd device %s of type %s\n",
214                  name, typename);
215         LASSERTF(obd->obd_magic == OBD_DEVICE_MAGIC,
216                  "obd %p obd_magic %08X != %08X\n",
217                  obd, obd->obd_magic, OBD_DEVICE_MAGIC);
218         LASSERTF(strncmp(obd->obd_name, name, strlen(name)) == 0,
219                  "%p obd_name %s != %s\n", obd, obd->obd_name, name);
220
221         rwlock_init(&obd->obd_pool_lock);
222         obd->obd_pool_limit = 0;
223         obd->obd_pool_slv = 0;
224
225         INIT_LIST_HEAD(&obd->obd_exports);
226         INIT_LIST_HEAD(&obd->obd_unlinked_exports);
227         INIT_LIST_HEAD(&obd->obd_delayed_exports);
228         spin_lock_init(&obd->obd_nid_lock);
229         spin_lock_init(&obd->obd_dev_lock);
230         mutex_init(&obd->obd_dev_mutex);
231         spin_lock_init(&obd->obd_osfs_lock);
232         /* obd->obd_osfs_age must be set to a value in the distant
233          * past to guarantee a fresh statfs is fetched on mount. */
234         obd->obd_osfs_age = cfs_time_shift_64(-1000);
235
236         /* XXX belongs in setup not attach  */
237         init_rwsem(&obd->obd_observer_link_sem);
238         /* recovery data */
239         init_waitqueue_head(&obd->obd_evict_inprogress_waitq);
240
241         llog_group_init(&obd->obd_olg, FID_SEQ_LLOG);
242
243         obd->obd_conn_inprogress = 0;
244
245         len = strlen(uuid);
246         if (len >= sizeof(obd->obd_uuid)) {
247                 CERROR("uuid must be < %d bytes long\n",
248                        (int)sizeof(obd->obd_uuid));
249                 rc = -EINVAL;
250                 goto out;
251         }
252         memcpy(obd->obd_uuid.uuid, uuid, len);
253
254         /* do the attach */
255         if (OBP(obd, attach)) {
256                 rc = OBP(obd, attach)(obd, sizeof(*lcfg), lcfg);
257                 if (rc) {
258                         rc = -EINVAL;
259                         goto out;
260                 }
261         }
262
263         /* Detach drops this */
264         spin_lock(&obd->obd_dev_lock);
265         atomic_set(&obd->obd_refcount, 1);
266         spin_unlock(&obd->obd_dev_lock);
267         lu_ref_init(&obd->obd_reference);
268         lu_ref_add(&obd->obd_reference, "attach", obd);
269
270         obd->obd_attached = 1;
271         CDEBUG(D_IOCTL, "OBD: dev %d attached type %s with refcount %d\n",
272                obd->obd_minor, typename, atomic_read(&obd->obd_refcount));
273         return 0;
274  out:
275         if (obd != NULL) {
276                 class_release_dev(obd);
277         }
278         return rc;
279 }
280
281 /** Create hashes, self-export, and call type-specific setup.
282  * Setup is effectively the "start this obd" call.
283  */
284 static int class_setup(struct obd_device *obd, struct lustre_cfg *lcfg)
285 {
286         int err = 0;
287         struct obd_export *exp;
288
289         LASSERT(obd != NULL);
290         LASSERTF(obd == class_num2obd(obd->obd_minor),
291                  "obd %p != obd_devs[%d] %p\n",
292                  obd, obd->obd_minor, class_num2obd(obd->obd_minor));
293         LASSERTF(obd->obd_magic == OBD_DEVICE_MAGIC,
294                  "obd %p obd_magic %08x != %08x\n",
295                  obd, obd->obd_magic, OBD_DEVICE_MAGIC);
296
297         /* have we attached a type to this device? */
298         if (!obd->obd_attached) {
299                 CERROR("Device %d not attached\n", obd->obd_minor);
300                 return -ENODEV;
301         }
302
303         if (obd->obd_set_up) {
304                 CERROR("Device %d already setup (type %s)\n",
305                        obd->obd_minor, obd->obd_type->typ_name);
306                 return -EEXIST;
307         }
308
309         /* is someone else setting us up right now? (attach inits spinlock) */
310         spin_lock(&obd->obd_dev_lock);
311         if (obd->obd_starting) {
312                 spin_unlock(&obd->obd_dev_lock);
313                 CERROR("Device %d setup in progress (type %s)\n",
314                        obd->obd_minor, obd->obd_type->typ_name);
315                 return -EEXIST;
316         }
317         /* just leave this on forever.  I can't use obd_set_up here because
318            other fns check that status, and we're not actually set up yet. */
319         obd->obd_starting = 1;
320         obd->obd_uuid_hash = NULL;
321         spin_unlock(&obd->obd_dev_lock);
322
323         /* create an uuid-export lustre hash */
324         obd->obd_uuid_hash = cfs_hash_create("UUID_HASH",
325                                              HASH_UUID_CUR_BITS,
326                                              HASH_UUID_MAX_BITS,
327                                              HASH_UUID_BKT_BITS, 0,
328                                              CFS_HASH_MIN_THETA,
329                                              CFS_HASH_MAX_THETA,
330                                              &uuid_hash_ops, CFS_HASH_DEFAULT);
331         if (!obd->obd_uuid_hash) {
332                 err = -ENOMEM;
333                 goto err_hash;
334         }
335
336         exp = class_new_export(obd, &obd->obd_uuid);
337         if (IS_ERR(exp)) {
338                 err = PTR_ERR(exp);
339                 goto err_hash;
340         }
341
342         obd->obd_self_export = exp;
343         class_export_put(exp);
344
345         err = obd_setup(obd, lcfg);
346         if (err)
347                 goto err_exp;
348
349         obd->obd_set_up = 1;
350
351         spin_lock(&obd->obd_dev_lock);
352         /* cleanup drops this */
353         class_incref(obd, "setup", obd);
354         spin_unlock(&obd->obd_dev_lock);
355
356         CDEBUG(D_IOCTL, "finished setup of obd %s (uuid %s)\n",
357                obd->obd_name, obd->obd_uuid.uuid);
358
359         return 0;
360 err_exp:
361         if (obd->obd_self_export) {
362                 class_unlink_export(obd->obd_self_export);
363                 obd->obd_self_export = NULL;
364         }
365 err_hash:
366         if (obd->obd_uuid_hash) {
367                 cfs_hash_putref(obd->obd_uuid_hash);
368                 obd->obd_uuid_hash = NULL;
369         }
370         obd->obd_starting = 0;
371         CERROR("setup %s failed (%d)\n", obd->obd_name, err);
372         return err;
373 }
374
375 /** We have finished using this obd and are ready to destroy it.
376  * There can be no more references to this obd.
377  */
378 static int class_detach(struct obd_device *obd, struct lustre_cfg *lcfg)
379 {
380         if (obd->obd_set_up) {
381                 CERROR("OBD device %d still set up\n", obd->obd_minor);
382                 return -EBUSY;
383         }
384
385         spin_lock(&obd->obd_dev_lock);
386         if (!obd->obd_attached) {
387                 spin_unlock(&obd->obd_dev_lock);
388                 CERROR("OBD device %d not attached\n", obd->obd_minor);
389                 return -ENODEV;
390         }
391         obd->obd_attached = 0;
392         spin_unlock(&obd->obd_dev_lock);
393
394         CDEBUG(D_IOCTL, "detach on obd %s (uuid %s)\n",
395                obd->obd_name, obd->obd_uuid.uuid);
396
397         class_decref(obd, "attach", obd);
398         return 0;
399 }
400
401 /** Start shutting down the obd.  There may be in-progress ops when
402  * this is called.  We tell them to start shutting down with a call
403  * to class_disconnect_exports().
404  */
405 static int class_cleanup(struct obd_device *obd, struct lustre_cfg *lcfg)
406 {
407         int err = 0;
408         char *flag;
409
410         OBD_RACE(OBD_FAIL_LDLM_RECOV_CLIENTS);
411
412         if (!obd->obd_set_up) {
413                 CERROR("Device %d not setup\n", obd->obd_minor);
414                 return -ENODEV;
415         }
416
417         spin_lock(&obd->obd_dev_lock);
418         if (obd->obd_stopping) {
419                 spin_unlock(&obd->obd_dev_lock);
420                 CERROR("OBD %d already stopping\n", obd->obd_minor);
421                 return -ENODEV;
422         }
423         /* Leave this on forever */
424         obd->obd_stopping = 1;
425
426         /* wait for already-arrived-connections to finish. */
427         while (obd->obd_conn_inprogress > 0) {
428                 spin_unlock(&obd->obd_dev_lock);
429
430                 cond_resched();
431
432                 spin_lock(&obd->obd_dev_lock);
433         }
434         spin_unlock(&obd->obd_dev_lock);
435
436         if (lcfg->lcfg_bufcount >= 2 && LUSTRE_CFG_BUFLEN(lcfg, 1) > 0) {
437                 for (flag = lustre_cfg_string(lcfg, 1); *flag != 0; flag++)
438                         switch (*flag) {
439                         case 'F':
440                                 obd->obd_force = 1;
441                                 break;
442                         case 'A':
443                                 LCONSOLE_WARN("Failing over %s\n",
444                                               obd->obd_name);
445                                 obd->obd_fail = 1;
446                                 obd->obd_no_transno = 1;
447                                 obd->obd_no_recov = 1;
448                                 if (OBP(obd, iocontrol)) {
449                                         obd_iocontrol(OBD_IOC_SYNC,
450                                                       obd->obd_self_export,
451                                                       0, NULL, NULL);
452                                 }
453                                 break;
454                         default:
455                                 CERROR("Unrecognised flag '%c'\n", *flag);
456                         }
457         }
458
459         LASSERT(obd->obd_self_export);
460
461         /* Precleanup, we must make sure all exports get destroyed. */
462         err = obd_precleanup(obd, OBD_CLEANUP_EXPORTS);
463         if (err)
464                 CERROR("Precleanup %s returned %d\n",
465                        obd->obd_name, err);
466
467         /* destroy an uuid-export hash body */
468         if (obd->obd_uuid_hash) {
469                 cfs_hash_putref(obd->obd_uuid_hash);
470                 obd->obd_uuid_hash = NULL;
471         }
472
473         class_decref(obd, "setup", obd);
474         obd->obd_set_up = 0;
475
476         return 0;
477 }
478
479 struct obd_device *class_incref(struct obd_device *obd,
480                                 const char *scope, const void *source)
481 {
482         lu_ref_add_atomic(&obd->obd_reference, scope, source);
483         atomic_inc(&obd->obd_refcount);
484         CDEBUG(D_INFO, "incref %s (%p) now %d\n", obd->obd_name, obd,
485                atomic_read(&obd->obd_refcount));
486
487         return obd;
488 }
489 EXPORT_SYMBOL(class_incref);
490
491 void class_decref(struct obd_device *obd, const char *scope, const void *source)
492 {
493         int err;
494         int refs;
495
496         spin_lock(&obd->obd_dev_lock);
497         atomic_dec(&obd->obd_refcount);
498         refs = atomic_read(&obd->obd_refcount);
499         spin_unlock(&obd->obd_dev_lock);
500         lu_ref_del(&obd->obd_reference, scope, source);
501
502         CDEBUG(D_INFO, "Decref %s (%p) now %d\n", obd->obd_name, obd, refs);
503
504         if ((refs == 1) && obd->obd_stopping) {
505                 /* All exports have been destroyed; there should
506                    be no more in-progress ops by this point.*/
507
508                 spin_lock(&obd->obd_self_export->exp_lock);
509                 obd->obd_self_export->exp_flags |= exp_flags_from_obd(obd);
510                 spin_unlock(&obd->obd_self_export->exp_lock);
511
512                 /* note that we'll recurse into class_decref again */
513                 class_unlink_export(obd->obd_self_export);
514                 return;
515         }
516
517         if (refs == 0) {
518                 CDEBUG(D_CONFIG, "finishing cleanup of obd %s (%s)\n",
519                        obd->obd_name, obd->obd_uuid.uuid);
520                 LASSERT(!obd->obd_attached);
521                 if (obd->obd_stopping) {
522                         /* If we're not stopping, we were never set up */
523                         err = obd_cleanup(obd);
524                         if (err)
525                                 CERROR("Cleanup %s returned %d\n",
526                                        obd->obd_name, err);
527                 }
528                 if (OBP(obd, detach)) {
529                         err = OBP(obd, detach)(obd);
530                         if (err)
531                                 CERROR("Detach returned %d\n", err);
532                 }
533                 class_release_dev(obd);
534         }
535 }
536 EXPORT_SYMBOL(class_decref);
537
538 /** Add a failover nid location.
539  * Client obd types contact server obd types using this nid list.
540  */
541 static int class_add_conn(struct obd_device *obd, struct lustre_cfg *lcfg)
542 {
543         struct obd_import *imp;
544         struct obd_uuid uuid;
545         int rc;
546
547         if (LUSTRE_CFG_BUFLEN(lcfg, 1) < 1 ||
548             LUSTRE_CFG_BUFLEN(lcfg, 1) > sizeof(struct obd_uuid)) {
549                 CERROR("invalid conn_uuid\n");
550                 return -EINVAL;
551         }
552         if (strcmp(obd->obd_type->typ_name, LUSTRE_MDC_NAME) &&
553             strcmp(obd->obd_type->typ_name, LUSTRE_OSC_NAME) &&
554             strcmp(obd->obd_type->typ_name, LUSTRE_OSP_NAME) &&
555             strcmp(obd->obd_type->typ_name, LUSTRE_LWP_NAME) &&
556             strcmp(obd->obd_type->typ_name, LUSTRE_MGC_NAME)) {
557                 CERROR("can't add connection on non-client dev\n");
558                 return -EINVAL;
559         }
560
561         imp = obd->u.cli.cl_import;
562         if (!imp) {
563                 CERROR("try to add conn on immature client dev\n");
564                 return -EINVAL;
565         }
566
567         obd_str2uuid(&uuid, lustre_cfg_string(lcfg, 1));
568         rc = obd_add_conn(imp, &uuid, lcfg->lcfg_num);
569
570         return rc;
571 }
572
573 /** Remove a failover nid location.
574  */
575 static int class_del_conn(struct obd_device *obd, struct lustre_cfg *lcfg)
576 {
577         struct obd_import *imp;
578         struct obd_uuid uuid;
579         int rc;
580
581         if (LUSTRE_CFG_BUFLEN(lcfg, 1) < 1 ||
582             LUSTRE_CFG_BUFLEN(lcfg, 1) > sizeof(struct obd_uuid)) {
583                 CERROR("invalid conn_uuid\n");
584                 return -EINVAL;
585         }
586         if (strcmp(obd->obd_type->typ_name, LUSTRE_MDC_NAME) &&
587             strcmp(obd->obd_type->typ_name, LUSTRE_OSC_NAME)) {
588                 CERROR("can't del connection on non-client dev\n");
589                 return -EINVAL;
590         }
591
592         imp = obd->u.cli.cl_import;
593         if (!imp) {
594                 CERROR("try to del conn on immature client dev\n");
595                 return -EINVAL;
596         }
597
598         obd_str2uuid(&uuid, lustre_cfg_string(lcfg, 1));
599         rc = obd_del_conn(imp, &uuid);
600
601         return rc;
602 }
603
604 LIST_HEAD(lustre_profile_list);
605
606 struct lustre_profile *class_get_profile(const char *prof)
607 {
608         struct lustre_profile *lprof;
609
610         list_for_each_entry(lprof, &lustre_profile_list, lp_list) {
611                 if (!strcmp(lprof->lp_profile, prof)) {
612                         return lprof;
613                 }
614         }
615         return NULL;
616 }
617 EXPORT_SYMBOL(class_get_profile);
618
619 /** Create a named "profile".
620  * This defines the mdc and osc names to use for a client.
621  * This also is used to define the lov to be used by a mdt.
622  */
623 static int class_add_profile(int proflen, char *prof, int osclen, char *osc,
624                              int mdclen, char *mdc)
625 {
626         struct lustre_profile *lprof;
627         int err = 0;
628
629         CDEBUG(D_CONFIG, "Add profile %s\n", prof);
630
631         lprof = kzalloc(sizeof(*lprof), GFP_NOFS);
632         if (!lprof)
633                 return -ENOMEM;
634         INIT_LIST_HEAD(&lprof->lp_list);
635
636         LASSERT(proflen == (strlen(prof) + 1));
637         lprof->lp_profile = kmemdup(prof, proflen, GFP_NOFS);
638         if (!lprof->lp_profile) {
639                 err = -ENOMEM;
640                 goto free_lprof;
641         }
642
643         LASSERT(osclen == (strlen(osc) + 1));
644         lprof->lp_dt = kmemdup(osc, osclen, GFP_NOFS);
645         if (!lprof->lp_dt) {
646                 err = -ENOMEM;
647                 goto free_lp_profile;
648         }
649
650         if (mdclen > 0) {
651                 LASSERT(mdclen == (strlen(mdc) + 1));
652                 lprof->lp_md = kmemdup(mdc, mdclen, GFP_NOFS);
653                 if (!lprof->lp_md) {
654                         err = -ENOMEM;
655                         goto free_lp_dt;
656                 }
657         }
658
659         list_add(&lprof->lp_list, &lustre_profile_list);
660         return err;
661
662 free_lp_dt:
663         kfree(lprof->lp_dt);
664 free_lp_profile:
665         kfree(lprof->lp_profile);
666 free_lprof:
667         kfree(lprof);
668         return err;
669 }
670
671 void class_del_profile(const char *prof)
672 {
673         struct lustre_profile *lprof;
674
675         CDEBUG(D_CONFIG, "Del profile %s\n", prof);
676
677         lprof = class_get_profile(prof);
678         if (lprof) {
679                 list_del(&lprof->lp_list);
680                 kfree(lprof->lp_profile);
681                 kfree(lprof->lp_dt);
682                 kfree(lprof->lp_md);
683                 kfree(lprof);
684         }
685 }
686 EXPORT_SYMBOL(class_del_profile);
687
688 /* COMPAT_146 */
689 void class_del_profiles(void)
690 {
691         struct lustre_profile *lprof, *n;
692
693         list_for_each_entry_safe(lprof, n, &lustre_profile_list, lp_list) {
694                 list_del(&lprof->lp_list);
695                 kfree(lprof->lp_profile);
696                 kfree(lprof->lp_dt);
697                 kfree(lprof->lp_md);
698                 kfree(lprof);
699         }
700 }
701 EXPORT_SYMBOL(class_del_profiles);
702
703 static int class_set_global(char *ptr, int val, struct lustre_cfg *lcfg)
704 {
705         if (class_match_param(ptr, PARAM_AT_MIN, NULL) == 0)
706                 at_min = val;
707         else if (class_match_param(ptr, PARAM_AT_MAX, NULL) == 0)
708                 at_max = val;
709         else if (class_match_param(ptr, PARAM_AT_EXTRA, NULL) == 0)
710                 at_extra = val;
711         else if (class_match_param(ptr, PARAM_AT_EARLY_MARGIN, NULL) == 0)
712                 at_early_margin = val;
713         else if (class_match_param(ptr, PARAM_AT_HISTORY, NULL) == 0)
714                 at_history = val;
715         else if (class_match_param(ptr, PARAM_JOBID_VAR, NULL) == 0)
716                 strlcpy(obd_jobid_var, lustre_cfg_string(lcfg, 2),
717                         JOBSTATS_JOBID_VAR_MAX_LEN + 1);
718         else
719                 return -EINVAL;
720
721         CDEBUG(D_IOCTL, "global %s = %d\n", ptr, val);
722         return 0;
723 }
724
725 /* We can't call ll_process_config or lquota_process_config directly because
726  * it lives in a module that must be loaded after this one. */
727 static int (*client_process_config)(struct lustre_cfg *lcfg);
728 static int (*quota_process_config)(struct lustre_cfg *lcfg);
729
730 void lustre_register_client_process_config(int (*cpc)(struct lustre_cfg *lcfg))
731 {
732         client_process_config = cpc;
733 }
734 EXPORT_SYMBOL(lustre_register_client_process_config);
735
736 static int process_param2_config(struct lustre_cfg *lcfg)
737 {
738         char *param = lustre_cfg_string(lcfg, 1);
739         char *upcall = lustre_cfg_string(lcfg, 2);
740         char *argv[] = {
741                 [0] = "/usr/sbin/lctl",
742                 [1] = "set_param",
743                 [2] = param,
744                 [3] = NULL
745         };
746         ktime_t start;
747         ktime_t end;
748         int             rc;
749
750         /* Add upcall processing here. Now only lctl is supported */
751         if (strcmp(upcall, LCTL_UPCALL) != 0) {
752                 CERROR("Unsupported upcall %s\n", upcall);
753                 return -EINVAL;
754         }
755
756         start = ktime_get();
757         rc = call_usermodehelper(argv[0], argv, NULL, 1);
758         end = ktime_get();
759
760         if (rc < 0) {
761                 CERROR(
762                        "lctl: error invoking upcall %s %s %s: rc = %d; time %ldus\n",
763                        argv[0], argv[1], argv[2], rc,
764                        (long)ktime_us_delta(end, start));
765         } else {
766                 CDEBUG(D_HA, "lctl: invoked upcall %s %s %s, time %ldus\n",
767                        argv[0], argv[1], argv[2],
768                        (long)ktime_us_delta(end, start));
769                        rc = 0;
770         }
771
772         return rc;
773 }
774
775 /** Process configuration commands given in lustre_cfg form.
776  * These may come from direct calls (e.g. class_manual_cleanup)
777  * or processing the config llog, or ioctl from lctl.
778  */
779 int class_process_config(struct lustre_cfg *lcfg)
780 {
781         struct obd_device *obd;
782         int err;
783
784         LASSERT(lcfg && !IS_ERR(lcfg));
785         CDEBUG(D_IOCTL, "processing cmd: %x\n", lcfg->lcfg_command);
786
787         /* Commands that don't need a device */
788         switch (lcfg->lcfg_command) {
789         case LCFG_ATTACH: {
790                 err = class_attach(lcfg);
791                 goto out;
792         }
793         case LCFG_ADD_UUID: {
794                 CDEBUG(D_IOCTL, "adding mapping from uuid %s to nid %#llx (%s)\n",
795                        lustre_cfg_string(lcfg, 1), lcfg->lcfg_nid,
796                        libcfs_nid2str(lcfg->lcfg_nid));
797
798                 err = class_add_uuid(lustre_cfg_string(lcfg, 1), lcfg->lcfg_nid);
799                 goto out;
800         }
801         case LCFG_DEL_UUID: {
802                 CDEBUG(D_IOCTL, "removing mappings for uuid %s\n",
803                        (lcfg->lcfg_bufcount < 2 || LUSTRE_CFG_BUFLEN(lcfg, 1) == 0)
804                        ? "<all uuids>" : lustre_cfg_string(lcfg, 1));
805
806                 err = class_del_uuid(lustre_cfg_string(lcfg, 1));
807                 goto out;
808         }
809         case LCFG_MOUNTOPT: {
810                 CDEBUG(D_IOCTL, "mountopt: profile %s osc %s mdc %s\n",
811                        lustre_cfg_string(lcfg, 1),
812                        lustre_cfg_string(lcfg, 2),
813                        lustre_cfg_string(lcfg, 3));
814                 /* set these mount options somewhere, so ll_fill_super
815                  * can find them. */
816                 err = class_add_profile(LUSTRE_CFG_BUFLEN(lcfg, 1),
817                                         lustre_cfg_string(lcfg, 1),
818                                         LUSTRE_CFG_BUFLEN(lcfg, 2),
819                                         lustre_cfg_string(lcfg, 2),
820                                         LUSTRE_CFG_BUFLEN(lcfg, 3),
821                                         lustre_cfg_string(lcfg, 3));
822                 goto out;
823         }
824         case LCFG_DEL_MOUNTOPT: {
825                 CDEBUG(D_IOCTL, "mountopt: profile %s\n",
826                        lustre_cfg_string(lcfg, 1));
827                 class_del_profile(lustre_cfg_string(lcfg, 1));
828                 err = 0;
829                 goto out;
830         }
831         case LCFG_SET_TIMEOUT: {
832                 CDEBUG(D_IOCTL, "changing lustre timeout from %d to %d\n",
833                        obd_timeout, lcfg->lcfg_num);
834                 obd_timeout = max(lcfg->lcfg_num, 1U);
835                 obd_timeout_set = 1;
836                 err = 0;
837                 goto out;
838         }
839         case LCFG_SET_LDLM_TIMEOUT: {
840                 /* ldlm_timeout is not used on the client */
841                 err = 0;
842                 goto out;
843         }
844         case LCFG_SET_UPCALL: {
845                 LCONSOLE_ERROR_MSG(0x15a, "recovery upcall is deprecated\n");
846                 /* COMPAT_146 Don't fail on old configs */
847                 err = 0;
848                 goto out;
849         }
850         case LCFG_MARKER: {
851                 struct cfg_marker *marker;
852
853                 marker = lustre_cfg_buf(lcfg, 1);
854                 CDEBUG(D_IOCTL, "marker %d (%#x) %.16s %s\n", marker->cm_step,
855                        marker->cm_flags, marker->cm_tgtname, marker->cm_comment);
856                 err = 0;
857                 goto out;
858         }
859         case LCFG_PARAM: {
860                 char *tmp;
861                 /* llite has no obd */
862                 if ((class_match_param(lustre_cfg_string(lcfg, 1),
863                                        PARAM_LLITE, NULL) == 0) &&
864                     client_process_config) {
865                         err = (*client_process_config)(lcfg);
866                         goto out;
867                 } else if ((class_match_param(lustre_cfg_string(lcfg, 1),
868                                               PARAM_SYS, &tmp) == 0)) {
869                         /* Global param settings */
870                         err = class_set_global(tmp, lcfg->lcfg_num, lcfg);
871                         /*
872                          * Client or server should not fail to mount if
873                          * it hits an unknown configuration parameter.
874                          */
875                         if (err != 0)
876                                 CWARN("Ignoring unknown param %s\n", tmp);
877
878                         err = 0;
879                         goto out;
880                 } else if ((class_match_param(lustre_cfg_string(lcfg, 1),
881                                               PARAM_QUOTA, &tmp) == 0) &&
882                            quota_process_config) {
883                         err = (*quota_process_config)(lcfg);
884                         goto out;
885                 }
886
887                 break;
888         }
889         case LCFG_SET_PARAM: {
890                 err = process_param2_config(lcfg);
891                 goto out;
892         }
893         }
894         /* Commands that require a device */
895         obd = class_name2obd(lustre_cfg_string(lcfg, 0));
896         if (!obd) {
897                 if (!LUSTRE_CFG_BUFLEN(lcfg, 0))
898                         CERROR("this lcfg command requires a device name\n");
899                 else
900                         CERROR("no device for: %s\n",
901                                lustre_cfg_string(lcfg, 0));
902
903                 err = -EINVAL;
904                 goto out;
905         }
906
907         switch (lcfg->lcfg_command) {
908         case LCFG_SETUP: {
909                 err = class_setup(obd, lcfg);
910                 goto out;
911         }
912         case LCFG_DETACH: {
913                 err = class_detach(obd, lcfg);
914                 err = 0;
915                 goto out;
916         }
917         case LCFG_CLEANUP: {
918                 err = class_cleanup(obd, lcfg);
919                 err = 0;
920                 goto out;
921         }
922         case LCFG_ADD_CONN: {
923                 err = class_add_conn(obd, lcfg);
924                 err = 0;
925                 goto out;
926         }
927         case LCFG_DEL_CONN: {
928                 err = class_del_conn(obd, lcfg);
929                 err = 0;
930                 goto out;
931         }
932         case LCFG_POOL_NEW: {
933                 err = obd_pool_new(obd, lustre_cfg_string(lcfg, 2));
934                 err = 0;
935                 goto out;
936         }
937         case LCFG_POOL_ADD: {
938                 err = obd_pool_add(obd, lustre_cfg_string(lcfg, 2),
939                                    lustre_cfg_string(lcfg, 3));
940                 err = 0;
941                 goto out;
942         }
943         case LCFG_POOL_REM: {
944                 err = obd_pool_rem(obd, lustre_cfg_string(lcfg, 2),
945                                    lustre_cfg_string(lcfg, 3));
946                 err = 0;
947                 goto out;
948         }
949         case LCFG_POOL_DEL: {
950                 err = obd_pool_del(obd, lustre_cfg_string(lcfg, 2));
951                 err = 0;
952                 goto out;
953         }
954         default: {
955                 err = obd_process_config(obd, sizeof(*lcfg), lcfg);
956                 goto out;
957
958         }
959         }
960 out:
961         if ((err < 0) && !(lcfg->lcfg_command & LCFG_REQUIRED)) {
962                 CWARN("Ignoring error %d on optional command %#x\n", err,
963                       lcfg->lcfg_command);
964                 err = 0;
965         }
966         return err;
967 }
968 EXPORT_SYMBOL(class_process_config);
969
970 int class_process_proc_param(char *prefix, struct lprocfs_vars *lvars,
971                              struct lustre_cfg *lcfg, void *data)
972 {
973         struct lprocfs_vars *var;
974         struct file fakefile;
975         struct seq_file fake_seqfile;
976         char *key, *sval;
977         int i, keylen, vallen;
978         int matched = 0, j = 0;
979         int rc = 0;
980         int skip = 0;
981
982         if (lcfg->lcfg_command != LCFG_PARAM) {
983                 CERROR("Unknown command: %d\n", lcfg->lcfg_command);
984                 return -EINVAL;
985         }
986
987         /* fake a seq file so that var->fops->write can work... */
988         fakefile.private_data = &fake_seqfile;
989         fake_seqfile.private = data;
990         /* e.g. tunefs.lustre --param mdt.group_upcall=foo /r/tmp/lustre-mdt
991            or   lctl conf_param lustre-MDT0000.mdt.group_upcall=bar
992            or   lctl conf_param lustre-OST0000.osc.max_dirty_mb=36 */
993         for (i = 1; i < lcfg->lcfg_bufcount; i++) {
994                 key = lustre_cfg_buf(lcfg, i);
995                 /* Strip off prefix */
996                 class_match_param(key, prefix, &key);
997                 sval = strchr(key, '=');
998                 if (!sval || (*(sval + 1) == 0)) {
999                         CERROR("Can't parse param %s (missing '=')\n", key);
1000                         /* rc = -EINVAL;        continue parsing other params */
1001                         continue;
1002                 }
1003                 keylen = sval - key;
1004                 sval++;
1005                 vallen = strlen(sval);
1006                 matched = 0;
1007                 j = 0;
1008                 /* Search proc entries */
1009                 while (lvars[j].name) {
1010                         var = &lvars[j];
1011                         if (class_match_param(key, (char *)var->name, NULL) == 0
1012                             && keylen == strlen(var->name)) {
1013                                 matched++;
1014                                 rc = -EROFS;
1015                                 if (var->fops && var->fops->write) {
1016                                         mm_segment_t oldfs;
1017
1018                                         oldfs = get_fs();
1019                                         set_fs(KERNEL_DS);
1020                                         rc = (var->fops->write)(&fakefile, sval,
1021                                                                 vallen, NULL);
1022                                         set_fs(oldfs);
1023                                 }
1024                                 break;
1025                         }
1026                         j++;
1027                 }
1028                 if (!matched) {
1029                         /* If the prefix doesn't match, return error so we
1030                            can pass it down the stack */
1031                         if (strnchr(key, keylen, '.'))
1032                             return -ENOSYS;
1033                         CERROR("%s: unknown param %s\n",
1034                                (char *)lustre_cfg_string(lcfg, 0), key);
1035                         /* rc = -EINVAL;        continue parsing other params */
1036                         skip++;
1037                 } else if (rc < 0) {
1038                         CERROR("writing proc entry %s err %d\n",
1039                                var->name, rc);
1040                         rc = 0;
1041                 } else {
1042                         CDEBUG(D_CONFIG, "%s.%.*s: Set parameter %.*s=%s\n",
1043                                          lustre_cfg_string(lcfg, 0),
1044                                          (int)strlen(prefix) - 1, prefix,
1045                                          (int)(sval - key - 1), key, sval);
1046                 }
1047         }
1048
1049         if (rc > 0)
1050                 rc = 0;
1051         if (!rc && skip)
1052                 rc = skip;
1053         return rc;
1054 }
1055 EXPORT_SYMBOL(class_process_proc_param);
1056
1057 extern int lustre_check_exclusion(struct super_block *sb, char *svname);
1058
1059 /** Parse a configuration llog, doing various manipulations on them
1060  * for various reasons, (modifications for compatibility, skip obsolete
1061  * records, change uuids, etc), then class_process_config() resulting
1062  * net records.
1063  */
1064 int class_config_llog_handler(const struct lu_env *env,
1065                               struct llog_handle *handle,
1066                               struct llog_rec_hdr *rec, void *data)
1067 {
1068         struct config_llog_instance *clli = data;
1069         int cfg_len = rec->lrh_len;
1070         char *cfg_buf = (char *) (rec + 1);
1071         int rc = 0;
1072
1073         switch (rec->lrh_type) {
1074         case OBD_CFG_REC: {
1075                 struct lustre_cfg *lcfg, *lcfg_new;
1076                 struct lustre_cfg_bufs bufs;
1077                 char *inst_name = NULL;
1078                 int inst_len = 0;
1079                 int inst = 0, swab = 0;
1080
1081                 lcfg = (struct lustre_cfg *)cfg_buf;
1082                 if (lcfg->lcfg_version == __swab32(LUSTRE_CFG_VERSION)) {
1083                         lustre_swab_lustre_cfg(lcfg);
1084                         swab = 1;
1085                 }
1086
1087                 rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
1088                 if (rc)
1089                         goto out;
1090
1091                 /* Figure out config state info */
1092                 if (lcfg->lcfg_command == LCFG_MARKER) {
1093                         struct cfg_marker *marker = lustre_cfg_buf(lcfg, 1);
1094
1095                         lustre_swab_cfg_marker(marker, swab,
1096                                                LUSTRE_CFG_BUFLEN(lcfg, 1));
1097                         CDEBUG(D_CONFIG, "Marker, inst_flg=%#x mark_flg=%#x\n",
1098                                clli->cfg_flags, marker->cm_flags);
1099                         if (marker->cm_flags & CM_START) {
1100                                 /* all previous flags off */
1101                                 clli->cfg_flags = CFG_F_MARKER;
1102                                 if (marker->cm_flags & CM_SKIP) {
1103                                         clli->cfg_flags |= CFG_F_SKIP;
1104                                         CDEBUG(D_CONFIG, "SKIP #%d\n",
1105                                                marker->cm_step);
1106                                 } else if ((marker->cm_flags & CM_EXCLUDE) ||
1107                                            (clli->cfg_sb &&
1108                                             lustre_check_exclusion(clli->cfg_sb,
1109                                                          marker->cm_tgtname))) {
1110                                         clli->cfg_flags |= CFG_F_EXCLUDE;
1111                                         CDEBUG(D_CONFIG, "EXCLUDE %d\n",
1112                                                marker->cm_step);
1113                                 }
1114                         } else if (marker->cm_flags & CM_END) {
1115                                 clli->cfg_flags = 0;
1116                         }
1117                 }
1118                 /* A config command without a start marker before it is
1119                    illegal (post 146) */
1120                 if (!(clli->cfg_flags & CFG_F_COMPAT146) &&
1121                     !(clli->cfg_flags & CFG_F_MARKER) &&
1122                     (lcfg->lcfg_command != LCFG_MARKER)) {
1123                         CWARN("Config not inside markers, ignoring! (inst: %p, uuid: %s, flags: %#x)\n",
1124                               clli->cfg_instance,
1125                               clli->cfg_uuid.uuid, clli->cfg_flags);
1126                         clli->cfg_flags |= CFG_F_SKIP;
1127                 }
1128                 if (clli->cfg_flags & CFG_F_SKIP) {
1129                         CDEBUG(D_CONFIG, "skipping %#x\n",
1130                                clli->cfg_flags);
1131                         rc = 0;
1132                         /* No processing! */
1133                         break;
1134                 }
1135
1136                 /*
1137                  * For interoperability between 1.8 and 2.0,
1138                  * rename "mds" obd device type to "mdt".
1139                  */
1140                 {
1141                         char *typename = lustre_cfg_string(lcfg, 1);
1142                         char *index = lustre_cfg_string(lcfg, 2);
1143
1144                         if ((lcfg->lcfg_command == LCFG_ATTACH && typename &&
1145                              strcmp(typename, "mds") == 0)) {
1146                                 CWARN("For 1.8 interoperability, rename obd type from mds to mdt\n");
1147                                 typename[2] = 't';
1148                         }
1149                         if ((lcfg->lcfg_command == LCFG_SETUP && index &&
1150                              strcmp(index, "type") == 0)) {
1151                                 CDEBUG(D_INFO, "For 1.8 interoperability, set this index to '0'\n");
1152                                 index[0] = '0';
1153                                 index[1] = 0;
1154                         }
1155                 }
1156
1157                 if (clli->cfg_flags & CFG_F_EXCLUDE) {
1158                         CDEBUG(D_CONFIG, "cmd: %x marked EXCLUDED\n",
1159                                lcfg->lcfg_command);
1160                         if (lcfg->lcfg_command == LCFG_LOV_ADD_OBD)
1161                                 /* Add inactive instead */
1162                                 lcfg->lcfg_command = LCFG_LOV_ADD_INA;
1163                 }
1164
1165                 lustre_cfg_bufs_init(&bufs, lcfg);
1166
1167                 if (clli && clli->cfg_instance &&
1168                     LUSTRE_CFG_BUFLEN(lcfg, 0) > 0) {
1169                         inst = 1;
1170                         inst_len = LUSTRE_CFG_BUFLEN(lcfg, 0) +
1171                                    sizeof(clli->cfg_instance) * 2 + 4;
1172                         inst_name = kasprintf(GFP_NOFS, "%s-%p",
1173                                               lustre_cfg_string(lcfg, 0),
1174                                               clli->cfg_instance);
1175                         if (!inst_name) {
1176                                 rc = -ENOMEM;
1177                                 goto out;
1178                         }
1179                         lustre_cfg_bufs_set_string(&bufs, 0, inst_name);
1180                         CDEBUG(D_CONFIG, "cmd %x, instance name: %s\n",
1181                                lcfg->lcfg_command, inst_name);
1182                 }
1183
1184                 /* we override the llog's uuid for clients, to insure they
1185                 are unique */
1186                 if (clli && clli->cfg_instance != NULL &&
1187                     lcfg->lcfg_command == LCFG_ATTACH) {
1188                         lustre_cfg_bufs_set_string(&bufs, 2,
1189                                                    clli->cfg_uuid.uuid);
1190                 }
1191                 /*
1192                  * sptlrpc config record, we expect 2 data segments:
1193                  *  [0]: fs_name/target_name,
1194                  *  [1]: rule string
1195                  * moving them to index [1] and [2], and insert MGC's
1196                  * obdname at index [0].
1197                  */
1198                 if (clli && !clli->cfg_instance &&
1199                     lcfg->lcfg_command == LCFG_SPTLRPC_CONF) {
1200                         lustre_cfg_bufs_set(&bufs, 2, bufs.lcfg_buf[1],
1201                                             bufs.lcfg_buflen[1]);
1202                         lustre_cfg_bufs_set(&bufs, 1, bufs.lcfg_buf[0],
1203                                             bufs.lcfg_buflen[0]);
1204                         lustre_cfg_bufs_set_string(&bufs, 0,
1205                                                    clli->cfg_obdname);
1206                 }
1207
1208                 lcfg_new = lustre_cfg_new(lcfg->lcfg_command, &bufs);
1209
1210                 lcfg_new->lcfg_num   = lcfg->lcfg_num;
1211                 lcfg_new->lcfg_flags = lcfg->lcfg_flags;
1212
1213                 /* XXX Hack to try to remain binary compatible with
1214                  * pre-newconfig logs */
1215                 if (lcfg->lcfg_nal != 0 &&      /* pre-newconfig log? */
1216                     (lcfg->lcfg_nid >> 32) == 0) {
1217                         __u32 addr = (__u32)(lcfg->lcfg_nid & 0xffffffff);
1218
1219                         lcfg_new->lcfg_nid =
1220                                 LNET_MKNID(LNET_MKNET(lcfg->lcfg_nal, 0), addr);
1221                         CWARN("Converted pre-newconfig NAL %d NID %x to %s\n",
1222                               lcfg->lcfg_nal, addr,
1223                               libcfs_nid2str(lcfg_new->lcfg_nid));
1224                 } else {
1225                         lcfg_new->lcfg_nid = lcfg->lcfg_nid;
1226                 }
1227
1228                 lcfg_new->lcfg_nal = 0; /* illegal value for obsolete field */
1229
1230                 rc = class_process_config(lcfg_new);
1231                 lustre_cfg_free(lcfg_new);
1232
1233                 if (inst)
1234                         kfree(inst_name);
1235                 break;
1236         }
1237         default:
1238                 CERROR("Unknown llog record type %#x encountered\n",
1239                        rec->lrh_type);
1240                 break;
1241         }
1242 out:
1243         if (rc) {
1244                 CERROR("%s: cfg command failed: rc = %d\n",
1245                        handle->lgh_ctxt->loc_obd->obd_name, rc);
1246                 class_config_dump_handler(NULL, handle, rec, data);
1247         }
1248         return rc;
1249 }
1250 EXPORT_SYMBOL(class_config_llog_handler);
1251
1252 int class_config_parse_llog(const struct lu_env *env, struct llog_ctxt *ctxt,
1253                             char *name, struct config_llog_instance *cfg)
1254 {
1255         struct llog_process_cat_data     cd = {0, 0};
1256         struct llog_handle              *llh;
1257         llog_cb_t                        callback;
1258         int                              rc;
1259
1260         CDEBUG(D_INFO, "looking up llog %s\n", name);
1261         rc = llog_open(env, ctxt, &llh, NULL, name, LLOG_OPEN_EXISTS);
1262         if (rc)
1263                 return rc;
1264
1265         rc = llog_init_handle(env, llh, LLOG_F_IS_PLAIN, NULL);
1266         if (rc)
1267                 goto parse_out;
1268
1269         /* continue processing from where we last stopped to end-of-log */
1270         if (cfg) {
1271                 cd.lpcd_first_idx = cfg->cfg_last_idx;
1272                 callback = cfg->cfg_callback;
1273                 LASSERT(callback != NULL);
1274         } else {
1275                 callback = class_config_llog_handler;
1276         }
1277
1278         cd.lpcd_last_idx = 0;
1279
1280         rc = llog_process(env, llh, callback, cfg, &cd);
1281
1282         CDEBUG(D_CONFIG, "Processed log %s gen %d-%d (rc=%d)\n", name,
1283                cd.lpcd_first_idx + 1, cd.lpcd_last_idx, rc);
1284         if (cfg)
1285                 cfg->cfg_last_idx = cd.lpcd_last_idx;
1286
1287 parse_out:
1288         llog_close(env, llh);
1289         return rc;
1290 }
1291 EXPORT_SYMBOL(class_config_parse_llog);
1292
1293 /**
1294  * parse config record and output dump in supplied buffer.
1295  * This is separated from class_config_dump_handler() to use
1296  * for ioctl needs as well
1297  */
1298 static int class_config_parse_rec(struct llog_rec_hdr *rec, char *buf,
1299                                   int size)
1300 {
1301         struct lustre_cfg       *lcfg = (struct lustre_cfg *)(rec + 1);
1302         char                    *ptr = buf;
1303         char                    *end = buf + size;
1304         int                      rc = 0;
1305
1306         LASSERT(rec->lrh_type == OBD_CFG_REC);
1307         rc = lustre_cfg_sanity_check(lcfg, rec->lrh_len);
1308         if (rc < 0)
1309                 return rc;
1310
1311         ptr += snprintf(ptr, end-ptr, "cmd=%05x ", lcfg->lcfg_command);
1312         if (lcfg->lcfg_flags)
1313                 ptr += snprintf(ptr, end-ptr, "flags=%#08x ",
1314                                 lcfg->lcfg_flags);
1315
1316         if (lcfg->lcfg_num)
1317                 ptr += snprintf(ptr, end-ptr, "num=%#08x ", lcfg->lcfg_num);
1318
1319         if (lcfg->lcfg_nid) {
1320                 char nidstr[LNET_NIDSTR_SIZE];
1321
1322                 libcfs_nid2str_r(lcfg->lcfg_nid, nidstr, sizeof(nidstr));
1323                 ptr += snprintf(ptr, end-ptr, "nid=%s(%#llx)\n     ",
1324                                 nidstr, lcfg->lcfg_nid);
1325         }
1326
1327         if (lcfg->lcfg_command == LCFG_MARKER) {
1328                 struct cfg_marker *marker = lustre_cfg_buf(lcfg, 1);
1329
1330                 ptr += snprintf(ptr, end-ptr, "marker=%d(%#x)%s '%s'",
1331                                 marker->cm_step, marker->cm_flags,
1332                                 marker->cm_tgtname, marker->cm_comment);
1333         } else {
1334                 int i;
1335
1336                 for (i = 0; i <  lcfg->lcfg_bufcount; i++) {
1337                         ptr += snprintf(ptr, end-ptr, "%d:%s  ", i,
1338                                         lustre_cfg_string(lcfg, i));
1339                 }
1340         }
1341         /* return consumed bytes */
1342         rc = ptr - buf;
1343         return rc;
1344 }
1345
1346 int class_config_dump_handler(const struct lu_env *env,
1347                               struct llog_handle *handle,
1348                               struct llog_rec_hdr *rec, void *data)
1349 {
1350         char    *outstr;
1351         int      rc = 0;
1352
1353         outstr = kzalloc(256, GFP_NOFS);
1354         if (!outstr)
1355                 return -ENOMEM;
1356
1357         if (rec->lrh_type == OBD_CFG_REC) {
1358                 class_config_parse_rec(rec, outstr, 256);
1359                 LCONSOLE(D_WARNING, "   %s\n", outstr);
1360         } else {
1361                 LCONSOLE(D_WARNING, "unhandled lrh_type: %#x\n", rec->lrh_type);
1362                 rc = -EINVAL;
1363         }
1364
1365         kfree(outstr);
1366         return rc;
1367 }
1368
1369 /** Call class_cleanup and class_detach.
1370  * "Manual" only in the sense that we're faking lcfg commands.
1371  */
1372 int class_manual_cleanup(struct obd_device *obd)
1373 {
1374         char                flags[3] = "";
1375         struct lustre_cfg      *lcfg;
1376         struct lustre_cfg_bufs  bufs;
1377         int                  rc;
1378
1379         if (!obd) {
1380                 CERROR("empty cleanup\n");
1381                 return -EALREADY;
1382         }
1383
1384         if (obd->obd_force)
1385                 strcat(flags, "F");
1386         if (obd->obd_fail)
1387                 strcat(flags, "A");
1388
1389         CDEBUG(D_CONFIG, "Manual cleanup of %s (flags='%s')\n",
1390                obd->obd_name, flags);
1391
1392         lustre_cfg_bufs_reset(&bufs, obd->obd_name);
1393         lustre_cfg_bufs_set_string(&bufs, 1, flags);
1394         lcfg = lustre_cfg_new(LCFG_CLEANUP, &bufs);
1395         if (!lcfg)
1396                 return -ENOMEM;
1397
1398         rc = class_process_config(lcfg);
1399         if (rc) {
1400                 CERROR("cleanup failed %d: %s\n", rc, obd->obd_name);
1401                 goto out;
1402         }
1403
1404         /* the lcfg is almost the same for both ops */
1405         lcfg->lcfg_command = LCFG_DETACH;
1406         rc = class_process_config(lcfg);
1407         if (rc)
1408                 CERROR("detach failed %d: %s\n", rc, obd->obd_name);
1409 out:
1410         lustre_cfg_free(lcfg);
1411         return rc;
1412 }
1413 EXPORT_SYMBOL(class_manual_cleanup);
1414
1415 /*
1416  * uuid<->export lustre hash operations
1417  */
1418
1419 static unsigned
1420 uuid_hash(struct cfs_hash *hs, const void *key, unsigned mask)
1421 {
1422         return cfs_hash_djb2_hash(((struct obd_uuid *)key)->uuid,
1423                                   sizeof(((struct obd_uuid *)key)->uuid), mask);
1424 }
1425
1426 static void *
1427 uuid_key(struct hlist_node *hnode)
1428 {
1429         struct obd_export *exp;
1430
1431         exp = hlist_entry(hnode, struct obd_export, exp_uuid_hash);
1432
1433         return &exp->exp_client_uuid;
1434 }
1435
1436 /*
1437  * NOTE: It is impossible to find an export that is in failed
1438  *       state with this function
1439  */
1440 static int
1441 uuid_keycmp(const void *key, struct hlist_node *hnode)
1442 {
1443         struct obd_export *exp;
1444
1445         LASSERT(key);
1446         exp = hlist_entry(hnode, struct obd_export, exp_uuid_hash);
1447
1448         return obd_uuid_equals(key, &exp->exp_client_uuid) &&
1449                !exp->exp_failed;
1450 }
1451
1452 static void *
1453 uuid_export_object(struct hlist_node *hnode)
1454 {
1455         return hlist_entry(hnode, struct obd_export, exp_uuid_hash);
1456 }
1457
1458 static void
1459 uuid_export_get(struct cfs_hash *hs, struct hlist_node *hnode)
1460 {
1461         struct obd_export *exp;
1462
1463         exp = hlist_entry(hnode, struct obd_export, exp_uuid_hash);
1464         class_export_get(exp);
1465 }
1466
1467 static void
1468 uuid_export_put_locked(struct cfs_hash *hs, struct hlist_node *hnode)
1469 {
1470         struct obd_export *exp;
1471
1472         exp = hlist_entry(hnode, struct obd_export, exp_uuid_hash);
1473         class_export_put(exp);
1474 }
1475
1476 static struct cfs_hash_ops uuid_hash_ops = {
1477         .hs_hash        = uuid_hash,
1478         .hs_key         = uuid_key,
1479         .hs_keycmp      = uuid_keycmp,
1480         .hs_object      = uuid_export_object,
1481         .hs_get         = uuid_export_get,
1482         .hs_put_locked  = uuid_export_put_locked,
1483 };