[go: nahoru, domu]

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
50static cfs_hash_ops_t uuid_hash_ops;
51static cfs_hash_ops_t nid_hash_ops;
52static cfs_hash_ops_t nid_stat_hash_ops;
53
54/*********** string parsing utils *********/
55
56/* returns 0 if we find this key in the buffer, else 1 */
57int class_find_param(char *buf, char *key, char **valp)
58{
59	char *ptr;
60
61	if (!buf)
62		return 1;
63
64	ptr = strstr(buf, key);
65	if (ptr == NULL)
66		return 1;
67
68	if (valp)
69		*valp = ptr + strlen(key);
70
71	return 0;
72}
73EXPORT_SYMBOL(class_find_param);
74
75/**
76 * Check whether the proc parameter \a param is an old parameter or not from
77 * the array \a ptr which contains the mapping from old parameters to new ones.
78 * If it's an old one, then return the pointer to the cfg_interop_param struc-
79 * ture which contains both the old and new parameters.
80 *
81 * \param param			proc parameter
82 * \param ptr			an array which contains the mapping from
83 *				old parameters to new ones
84 *
85 * \retval valid-pointer	pointer to the cfg_interop_param structure
86 *				which contains the old and new parameters
87 * \retval NULL			\a param or \a ptr is NULL,
88 *				or \a param is not an old parameter
89 */
90struct cfg_interop_param *class_find_old_param(const char *param,
91					       struct cfg_interop_param *ptr)
92{
93	char *value = NULL;
94	int   name_len = 0;
95
96	if (param == NULL || ptr == NULL)
97		return NULL;
98
99	value = strchr(param, '=');
100	if (value == NULL)
101		name_len = strlen(param);
102	else
103		name_len = value - param;
104
105	while (ptr->old_param != NULL) {
106		if (strncmp(param, ptr->old_param, name_len) == 0 &&
107		    name_len == strlen(ptr->old_param))
108			return ptr;
109		ptr++;
110	}
111
112	return NULL;
113}
114EXPORT_SYMBOL(class_find_old_param);
115
116/**
117 * Finds a parameter in \a params and copies it to \a copy.
118 *
119 * Leading spaces are skipped. Next space or end of string is the
120 * parameter terminator with the exception that spaces inside single or double
121 * quotes get included into a parameter. The parameter is copied into \a copy
122 * which has to be allocated big enough by a caller, quotes are stripped in
123 * the copy and the copy is terminated by 0.
124 *
125 * On return \a params is set to next parameter or to NULL if last
126 * parameter is returned.
127 *
128 * \retval 0 if parameter is returned in \a copy
129 * \retval 1 otherwise
130 * \retval -EINVAL if unbalanced quota is found
131 */
132int class_get_next_param(char **params, char *copy)
133{
134	char *q1, *q2, *str;
135	int len;
136
137	str = *params;
138	while (*str == ' ')
139		str++;
140
141	if (*str == '\0') {
142		*params = NULL;
143		return 1;
144	}
145
146	while (1) {
147		q1 = strpbrk(str, " '\"");
148		if (q1 == NULL) {
149			len = strlen(str);
150			memcpy(copy, str, len);
151			copy[len] = '\0';
152			*params = NULL;
153			return 0;
154		}
155		len = q1 - str;
156		if (*q1 == ' ') {
157			memcpy(copy, str, len);
158			copy[len] = '\0';
159			*params = str + len;
160			return 0;
161		}
162
163		memcpy(copy, str, len);
164		copy += len;
165
166		/* search for the matching closing quote */
167		str = q1 + 1;
168		q2 = strchr(str, *q1);
169		if (q2 == NULL) {
170			CERROR("Unbalanced quota in parameters: \"%s\"\n",
171			       *params);
172			return -EINVAL;
173		}
174		len = q2 - str;
175		memcpy(copy, str, len);
176		copy += len;
177		str = q2 + 1;
178	}
179	return 1;
180}
181EXPORT_SYMBOL(class_get_next_param);
182
183/* returns 0 if this is the first key in the buffer, else 1.
184   valp points to first char after key. */
185int class_match_param(char *buf, char *key, char **valp)
186{
187	if (!buf)
188		return 1;
189
190	if (memcmp(buf, key, strlen(key)) != 0)
191		return 1;
192
193	if (valp)
194		*valp = buf + strlen(key);
195
196	return 0;
197}
198EXPORT_SYMBOL(class_match_param);
199
200static int parse_nid(char *buf, void *value, int quiet)
201{
202	lnet_nid_t *nid = (lnet_nid_t *)value;
203
204	*nid = libcfs_str2nid(buf);
205	if (*nid != LNET_NID_ANY)
206		return 0;
207
208	if (!quiet)
209		LCONSOLE_ERROR_MSG(0x159, "Can't parse NID '%s'\n", buf);
210	return -EINVAL;
211}
212
213static int parse_net(char *buf, void *value)
214{
215	__u32 *net = (__u32 *)value;
216
217	*net = libcfs_str2net(buf);
218	CDEBUG(D_INFO, "Net %s\n", libcfs_net2str(*net));
219	return 0;
220}
221
222enum {
223	CLASS_PARSE_NID = 1,
224	CLASS_PARSE_NET,
225};
226
227/* 0 is good nid,
228   1 not found
229   < 0 error
230   endh is set to next separator */
231static int class_parse_value(char *buf, int opc, void *value, char **endh,
232			     int quiet)
233{
234	char *endp;
235	char  tmp;
236	int   rc = 0;
237
238	if (!buf)
239		return 1;
240	while (*buf == ',' || *buf == ':')
241		buf++;
242	if (*buf == ' ' || *buf == '/' || *buf == '\0')
243		return 1;
244
245	/* nid separators or end of nids */
246	endp = strpbrk(buf, ",: /");
247	if (endp == NULL)
248		endp = buf + strlen(buf);
249
250	tmp = *endp;
251	*endp = '\0';
252	switch (opc) {
253	default:
254		LBUG();
255	case CLASS_PARSE_NID:
256		rc = parse_nid(buf, value, quiet);
257		break;
258	case CLASS_PARSE_NET:
259		rc = parse_net(buf, value);
260		break;
261	}
262	*endp = tmp;
263	if (rc != 0)
264		return rc;
265	if (endh)
266		*endh = endp;
267	return 0;
268}
269
270int class_parse_nid(char *buf, lnet_nid_t *nid, char **endh)
271{
272	return class_parse_value(buf, CLASS_PARSE_NID, (void *)nid, endh, 0);
273}
274EXPORT_SYMBOL(class_parse_nid);
275
276int class_parse_nid_quiet(char *buf, lnet_nid_t *nid, char **endh)
277{
278	return class_parse_value(buf, CLASS_PARSE_NID, (void *)nid, endh, 1);
279}
280EXPORT_SYMBOL(class_parse_nid_quiet);
281
282int class_parse_net(char *buf, __u32 *net, char **endh)
283{
284	return class_parse_value(buf, CLASS_PARSE_NET, (void *)net, endh, 0);
285}
286EXPORT_SYMBOL(class_parse_net);
287
288/* 1 param contains key and match
289 * 0 param contains key and not match
290 * -1 param does not contain key
291 */
292int class_match_nid(char *buf, char *key, lnet_nid_t nid)
293{
294	lnet_nid_t tmp;
295	int   rc = -1;
296
297	while (class_find_param(buf, key, &buf) == 0) {
298		/* please restrict to the nids pertaining to
299		 * the specified nids */
300		while (class_parse_nid(buf, &tmp, &buf) == 0) {
301			if (tmp == nid)
302				return 1;
303		}
304		rc = 0;
305	}
306	return rc;
307}
308EXPORT_SYMBOL(class_match_nid);
309
310int class_match_net(char *buf, char *key, __u32 net)
311{
312	__u32 tmp;
313	int   rc = -1;
314
315	while (class_find_param(buf, key, &buf) == 0) {
316		/* please restrict to the nids pertaining to
317		 * the specified networks */
318		while (class_parse_net(buf, &tmp, &buf) == 0) {
319			if (tmp == net)
320				return 1;
321		}
322		rc = 0;
323	}
324	return rc;
325}
326EXPORT_SYMBOL(class_match_net);
327
328/********************** class fns **********************/
329
330/**
331 * Create a new obd device and set the type, name and uuid.  If successful,
332 * the new device can be accessed by either name or uuid.
333 */
334int class_attach(struct lustre_cfg *lcfg)
335{
336	struct obd_device *obd = NULL;
337	char *typename, *name, *uuid;
338	int rc, len;
339
340	if (!LUSTRE_CFG_BUFLEN(lcfg, 1)) {
341		CERROR("No type passed!\n");
342		return -EINVAL;
343	}
344	typename = lustre_cfg_string(lcfg, 1);
345
346	if (!LUSTRE_CFG_BUFLEN(lcfg, 0)) {
347		CERROR("No name passed!\n");
348		return -EINVAL;
349	}
350	name = lustre_cfg_string(lcfg, 0);
351
352	if (!LUSTRE_CFG_BUFLEN(lcfg, 2)) {
353		CERROR("No UUID passed!\n");
354		return -EINVAL;
355	}
356	uuid = lustre_cfg_string(lcfg, 2);
357
358	CDEBUG(D_IOCTL, "attach type %s name: %s uuid: %s\n",
359	       MKSTR(typename), MKSTR(name), MKSTR(uuid));
360
361	obd = class_newdev(typename, name);
362	if (IS_ERR(obd)) {
363		/* Already exists or out of obds */
364		rc = PTR_ERR(obd);
365		obd = NULL;
366		CERROR("Cannot create device %s of type %s : %d\n",
367		       name, typename, rc);
368		goto out;
369	}
370	LASSERTF(obd != NULL, "Cannot get obd device %s of type %s\n",
371		 name, typename);
372	LASSERTF(obd->obd_magic == OBD_DEVICE_MAGIC,
373		 "obd %p obd_magic %08X != %08X\n",
374		 obd, obd->obd_magic, OBD_DEVICE_MAGIC);
375	LASSERTF(strncmp(obd->obd_name, name, strlen(name)) == 0,
376		 "%p obd_name %s != %s\n", obd, obd->obd_name, name);
377
378	rwlock_init(&obd->obd_pool_lock);
379	obd->obd_pool_limit = 0;
380	obd->obd_pool_slv = 0;
381
382	INIT_LIST_HEAD(&obd->obd_exports);
383	INIT_LIST_HEAD(&obd->obd_unlinked_exports);
384	INIT_LIST_HEAD(&obd->obd_delayed_exports);
385	INIT_LIST_HEAD(&obd->obd_exports_timed);
386	INIT_LIST_HEAD(&obd->obd_nid_stats);
387	spin_lock_init(&obd->obd_nid_lock);
388	spin_lock_init(&obd->obd_dev_lock);
389	mutex_init(&obd->obd_dev_mutex);
390	spin_lock_init(&obd->obd_osfs_lock);
391	/* obd->obd_osfs_age must be set to a value in the distant
392	 * past to guarantee a fresh statfs is fetched on mount. */
393	obd->obd_osfs_age = cfs_time_shift_64(-1000);
394
395	/* XXX belongs in setup not attach  */
396	init_rwsem(&obd->obd_observer_link_sem);
397	/* recovery data */
398	cfs_init_timer(&obd->obd_recovery_timer);
399	spin_lock_init(&obd->obd_recovery_task_lock);
400	init_waitqueue_head(&obd->obd_next_transno_waitq);
401	init_waitqueue_head(&obd->obd_evict_inprogress_waitq);
402	INIT_LIST_HEAD(&obd->obd_req_replay_queue);
403	INIT_LIST_HEAD(&obd->obd_lock_replay_queue);
404	INIT_LIST_HEAD(&obd->obd_final_req_queue);
405	INIT_LIST_HEAD(&obd->obd_evict_list);
406
407	llog_group_init(&obd->obd_olg, FID_SEQ_LLOG);
408
409	obd->obd_conn_inprogress = 0;
410
411	len = strlen(uuid);
412	if (len >= sizeof(obd->obd_uuid)) {
413		CERROR("uuid must be < %d bytes long\n",
414		       (int)sizeof(obd->obd_uuid));
415		rc = -EINVAL;
416		goto out;
417	}
418	memcpy(obd->obd_uuid.uuid, uuid, len);
419
420	/* do the attach */
421	if (OBP(obd, attach)) {
422		rc = OBP(obd, attach)(obd, sizeof(*lcfg), lcfg);
423		if (rc) {
424			rc = -EINVAL;
425			goto out;
426		}
427	}
428
429	/* Detach drops this */
430	spin_lock(&obd->obd_dev_lock);
431	atomic_set(&obd->obd_refcount, 1);
432	spin_unlock(&obd->obd_dev_lock);
433	lu_ref_init(&obd->obd_reference);
434	lu_ref_add(&obd->obd_reference, "attach", obd);
435
436	obd->obd_attached = 1;
437	CDEBUG(D_IOCTL, "OBD: dev %d attached type %s with refcount %d\n",
438	       obd->obd_minor, typename, atomic_read(&obd->obd_refcount));
439	return 0;
440 out:
441	if (obd != NULL) {
442		class_release_dev(obd);
443	}
444	return rc;
445}
446EXPORT_SYMBOL(class_attach);
447
448/** Create hashes, self-export, and call type-specific setup.
449 * Setup is effectively the "start this obd" call.
450 */
451int class_setup(struct obd_device *obd, struct lustre_cfg *lcfg)
452{
453	int err = 0;
454	struct obd_export *exp;
455
456	LASSERT(obd != NULL);
457	LASSERTF(obd == class_num2obd(obd->obd_minor),
458		 "obd %p != obd_devs[%d] %p\n",
459		 obd, obd->obd_minor, class_num2obd(obd->obd_minor));
460	LASSERTF(obd->obd_magic == OBD_DEVICE_MAGIC,
461		 "obd %p obd_magic %08x != %08x\n",
462		 obd, obd->obd_magic, OBD_DEVICE_MAGIC);
463
464	/* have we attached a type to this device? */
465	if (!obd->obd_attached) {
466		CERROR("Device %d not attached\n", obd->obd_minor);
467		return -ENODEV;
468	}
469
470	if (obd->obd_set_up) {
471		CERROR("Device %d already setup (type %s)\n",
472		       obd->obd_minor, obd->obd_type->typ_name);
473		return -EEXIST;
474	}
475
476	/* is someone else setting us up right now? (attach inits spinlock) */
477	spin_lock(&obd->obd_dev_lock);
478	if (obd->obd_starting) {
479		spin_unlock(&obd->obd_dev_lock);
480		CERROR("Device %d setup in progress (type %s)\n",
481		       obd->obd_minor, obd->obd_type->typ_name);
482		return -EEXIST;
483	}
484	/* just leave this on forever.  I can't use obd_set_up here because
485	   other fns check that status, and we're not actually set up yet. */
486	obd->obd_starting = 1;
487	obd->obd_uuid_hash = NULL;
488	obd->obd_nid_hash = NULL;
489	obd->obd_nid_stats_hash = NULL;
490	spin_unlock(&obd->obd_dev_lock);
491
492	/* create an uuid-export lustre hash */
493	obd->obd_uuid_hash = cfs_hash_create("UUID_HASH",
494					     HASH_UUID_CUR_BITS,
495					     HASH_UUID_MAX_BITS,
496					     HASH_UUID_BKT_BITS, 0,
497					     CFS_HASH_MIN_THETA,
498					     CFS_HASH_MAX_THETA,
499					     &uuid_hash_ops, CFS_HASH_DEFAULT);
500	if (!obd->obd_uuid_hash) {
501		err = -ENOMEM;
502		goto err_hash;
503	}
504
505	/* create a nid-export lustre hash */
506	obd->obd_nid_hash = cfs_hash_create("NID_HASH",
507					    HASH_NID_CUR_BITS,
508					    HASH_NID_MAX_BITS,
509					    HASH_NID_BKT_BITS, 0,
510					    CFS_HASH_MIN_THETA,
511					    CFS_HASH_MAX_THETA,
512					    &nid_hash_ops, CFS_HASH_DEFAULT);
513	if (!obd->obd_nid_hash) {
514		err = -ENOMEM;
515		goto err_hash;
516	}
517
518	/* create a nid-stats lustre hash */
519	obd->obd_nid_stats_hash = cfs_hash_create("NID_STATS",
520						  HASH_NID_STATS_CUR_BITS,
521						  HASH_NID_STATS_MAX_BITS,
522						  HASH_NID_STATS_BKT_BITS, 0,
523						  CFS_HASH_MIN_THETA,
524						  CFS_HASH_MAX_THETA,
525						  &nid_stat_hash_ops, CFS_HASH_DEFAULT);
526	if (!obd->obd_nid_stats_hash) {
527		err = -ENOMEM;
528		goto err_hash;
529	}
530
531	exp = class_new_export(obd, &obd->obd_uuid);
532	if (IS_ERR(exp)) {
533		err = PTR_ERR(exp);
534		goto err_hash;
535	}
536
537	obd->obd_self_export = exp;
538	list_del_init(&exp->exp_obd_chain_timed);
539	class_export_put(exp);
540
541	err = obd_setup(obd, lcfg);
542	if (err)
543		goto err_exp;
544
545	obd->obd_set_up = 1;
546
547	spin_lock(&obd->obd_dev_lock);
548	/* cleanup drops this */
549	class_incref(obd, "setup", obd);
550	spin_unlock(&obd->obd_dev_lock);
551
552	CDEBUG(D_IOCTL, "finished setup of obd %s (uuid %s)\n",
553	       obd->obd_name, obd->obd_uuid.uuid);
554
555	return 0;
556err_exp:
557	if (obd->obd_self_export) {
558		class_unlink_export(obd->obd_self_export);
559		obd->obd_self_export = NULL;
560	}
561err_hash:
562	if (obd->obd_uuid_hash) {
563		cfs_hash_putref(obd->obd_uuid_hash);
564		obd->obd_uuid_hash = NULL;
565	}
566	if (obd->obd_nid_hash) {
567		cfs_hash_putref(obd->obd_nid_hash);
568		obd->obd_nid_hash = NULL;
569	}
570	if (obd->obd_nid_stats_hash) {
571		cfs_hash_putref(obd->obd_nid_stats_hash);
572		obd->obd_nid_stats_hash = NULL;
573	}
574	obd->obd_starting = 0;
575	CERROR("setup %s failed (%d)\n", obd->obd_name, err);
576	return err;
577}
578EXPORT_SYMBOL(class_setup);
579
580/** We have finished using this obd and are ready to destroy it.
581 * There can be no more references to this obd.
582 */
583int class_detach(struct obd_device *obd, struct lustre_cfg *lcfg)
584{
585	if (obd->obd_set_up) {
586		CERROR("OBD device %d still set up\n", obd->obd_minor);
587		return -EBUSY;
588	}
589
590	spin_lock(&obd->obd_dev_lock);
591	if (!obd->obd_attached) {
592		spin_unlock(&obd->obd_dev_lock);
593		CERROR("OBD device %d not attached\n", obd->obd_minor);
594		return -ENODEV;
595	}
596	obd->obd_attached = 0;
597	spin_unlock(&obd->obd_dev_lock);
598
599	CDEBUG(D_IOCTL, "detach on obd %s (uuid %s)\n",
600	       obd->obd_name, obd->obd_uuid.uuid);
601
602	class_decref(obd, "attach", obd);
603	return 0;
604}
605EXPORT_SYMBOL(class_detach);
606
607/** Start shutting down the obd.  There may be in-progress ops when
608 * this is called.  We tell them to start shutting down with a call
609 * to class_disconnect_exports().
610 */
611int class_cleanup(struct obd_device *obd, struct lustre_cfg *lcfg)
612{
613	int err = 0;
614	char *flag;
615
616	OBD_RACE(OBD_FAIL_LDLM_RECOV_CLIENTS);
617
618	if (!obd->obd_set_up) {
619		CERROR("Device %d not setup\n", obd->obd_minor);
620		return -ENODEV;
621	}
622
623	spin_lock(&obd->obd_dev_lock);
624	if (obd->obd_stopping) {
625		spin_unlock(&obd->obd_dev_lock);
626		CERROR("OBD %d already stopping\n", obd->obd_minor);
627		return -ENODEV;
628	}
629	/* Leave this on forever */
630	obd->obd_stopping = 1;
631
632	/* wait for already-arrived-connections to finish. */
633	while (obd->obd_conn_inprogress > 0) {
634		spin_unlock(&obd->obd_dev_lock);
635
636		cond_resched();
637
638		spin_lock(&obd->obd_dev_lock);
639	}
640	spin_unlock(&obd->obd_dev_lock);
641
642	if (lcfg->lcfg_bufcount >= 2 && LUSTRE_CFG_BUFLEN(lcfg, 1) > 0) {
643		for (flag = lustre_cfg_string(lcfg, 1); *flag != 0; flag++)
644			switch (*flag) {
645			case 'F':
646				obd->obd_force = 1;
647				break;
648			case 'A':
649				LCONSOLE_WARN("Failing over %s\n",
650					      obd->obd_name);
651				obd->obd_fail = 1;
652				obd->obd_no_transno = 1;
653				obd->obd_no_recov = 1;
654				if (OBP(obd, iocontrol)) {
655					obd_iocontrol(OBD_IOC_SYNC,
656						      obd->obd_self_export,
657						      0, NULL, NULL);
658				}
659				break;
660			default:
661				CERROR("Unrecognised flag '%c'\n", *flag);
662			}
663	}
664
665	LASSERT(obd->obd_self_export);
666
667	/* The three references that should be remaining are the
668	 * obd_self_export and the attach and setup references. */
669	if (atomic_read(&obd->obd_refcount) > 3) {
670		/* refcount - 3 might be the number of real exports
671		   (excluding self export). But class_incref is called
672		   by other things as well, so don't count on it. */
673		CDEBUG(D_IOCTL, "%s: forcing exports to disconnect: %d\n",
674		       obd->obd_name, atomic_read(&obd->obd_refcount) - 3);
675		dump_exports(obd, 0);
676		class_disconnect_exports(obd);
677	}
678
679	/* Precleanup, we must make sure all exports get destroyed. */
680	err = obd_precleanup(obd, OBD_CLEANUP_EXPORTS);
681	if (err)
682		CERROR("Precleanup %s returned %d\n",
683		       obd->obd_name, err);
684
685	/* destroy an uuid-export hash body */
686	if (obd->obd_uuid_hash) {
687		cfs_hash_putref(obd->obd_uuid_hash);
688		obd->obd_uuid_hash = NULL;
689	}
690
691	/* destroy a nid-export hash body */
692	if (obd->obd_nid_hash) {
693		cfs_hash_putref(obd->obd_nid_hash);
694		obd->obd_nid_hash = NULL;
695	}
696
697	/* destroy a nid-stats hash body */
698	if (obd->obd_nid_stats_hash) {
699		cfs_hash_putref(obd->obd_nid_stats_hash);
700		obd->obd_nid_stats_hash = NULL;
701	}
702
703	class_decref(obd, "setup", obd);
704	obd->obd_set_up = 0;
705
706	return 0;
707}
708EXPORT_SYMBOL(class_cleanup);
709
710struct obd_device *class_incref(struct obd_device *obd,
711				const char *scope, const void *source)
712{
713	lu_ref_add_atomic(&obd->obd_reference, scope, source);
714	atomic_inc(&obd->obd_refcount);
715	CDEBUG(D_INFO, "incref %s (%p) now %d\n", obd->obd_name, obd,
716	       atomic_read(&obd->obd_refcount));
717
718	return obd;
719}
720EXPORT_SYMBOL(class_incref);
721
722void class_decref(struct obd_device *obd, const char *scope, const void *source)
723{
724	int err;
725	int refs;
726
727	spin_lock(&obd->obd_dev_lock);
728	atomic_dec(&obd->obd_refcount);
729	refs = atomic_read(&obd->obd_refcount);
730	spin_unlock(&obd->obd_dev_lock);
731	lu_ref_del(&obd->obd_reference, scope, source);
732
733	CDEBUG(D_INFO, "Decref %s (%p) now %d\n", obd->obd_name, obd, refs);
734
735	if ((refs == 1) && obd->obd_stopping) {
736		/* All exports have been destroyed; there should
737		   be no more in-progress ops by this point.*/
738
739		spin_lock(&obd->obd_self_export->exp_lock);
740		obd->obd_self_export->exp_flags |= exp_flags_from_obd(obd);
741		spin_unlock(&obd->obd_self_export->exp_lock);
742
743		/* note that we'll recurse into class_decref again */
744		class_unlink_export(obd->obd_self_export);
745		return;
746	}
747
748	if (refs == 0) {
749		CDEBUG(D_CONFIG, "finishing cleanup of obd %s (%s)\n",
750		       obd->obd_name, obd->obd_uuid.uuid);
751		LASSERT(!obd->obd_attached);
752		if (obd->obd_stopping) {
753			/* If we're not stopping, we were never set up */
754			err = obd_cleanup(obd);
755			if (err)
756				CERROR("Cleanup %s returned %d\n",
757				       obd->obd_name, err);
758		}
759		if (OBP(obd, detach)) {
760			err = OBP(obd, detach)(obd);
761			if (err)
762				CERROR("Detach returned %d\n", err);
763		}
764		class_release_dev(obd);
765	}
766}
767EXPORT_SYMBOL(class_decref);
768
769/** Add a failover nid location.
770 * Client obd types contact server obd types using this nid list.
771 */
772int class_add_conn(struct obd_device *obd, struct lustre_cfg *lcfg)
773{
774	struct obd_import *imp;
775	struct obd_uuid uuid;
776	int rc;
777
778	if (LUSTRE_CFG_BUFLEN(lcfg, 1) < 1 ||
779	    LUSTRE_CFG_BUFLEN(lcfg, 1) > sizeof(struct obd_uuid)) {
780		CERROR("invalid conn_uuid\n");
781		return -EINVAL;
782	}
783	if (strcmp(obd->obd_type->typ_name, LUSTRE_MDC_NAME) &&
784	    strcmp(obd->obd_type->typ_name, LUSTRE_OSC_NAME) &&
785	    strcmp(obd->obd_type->typ_name, LUSTRE_OSP_NAME) &&
786	    strcmp(obd->obd_type->typ_name, LUSTRE_LWP_NAME) &&
787	    strcmp(obd->obd_type->typ_name, LUSTRE_MGC_NAME)) {
788		CERROR("can't add connection on non-client dev\n");
789		return -EINVAL;
790	}
791
792	imp = obd->u.cli.cl_import;
793	if (!imp) {
794		CERROR("try to add conn on immature client dev\n");
795		return -EINVAL;
796	}
797
798	obd_str2uuid(&uuid, lustre_cfg_string(lcfg, 1));
799	rc = obd_add_conn(imp, &uuid, lcfg->lcfg_num);
800
801	return rc;
802}
803EXPORT_SYMBOL(class_add_conn);
804
805/** Remove a failover nid location.
806 */
807int class_del_conn(struct obd_device *obd, struct lustre_cfg *lcfg)
808{
809	struct obd_import *imp;
810	struct obd_uuid uuid;
811	int rc;
812
813	if (LUSTRE_CFG_BUFLEN(lcfg, 1) < 1 ||
814	    LUSTRE_CFG_BUFLEN(lcfg, 1) > sizeof(struct obd_uuid)) {
815		CERROR("invalid conn_uuid\n");
816		return -EINVAL;
817	}
818	if (strcmp(obd->obd_type->typ_name, LUSTRE_MDC_NAME) &&
819	    strcmp(obd->obd_type->typ_name, LUSTRE_OSC_NAME)) {
820		CERROR("can't del connection on non-client dev\n");
821		return -EINVAL;
822	}
823
824	imp = obd->u.cli.cl_import;
825	if (!imp) {
826		CERROR("try to del conn on immature client dev\n");
827		return -EINVAL;
828	}
829
830	obd_str2uuid(&uuid, lustre_cfg_string(lcfg, 1));
831	rc = obd_del_conn(imp, &uuid);
832
833	return rc;
834}
835
836LIST_HEAD(lustre_profile_list);
837
838struct lustre_profile *class_get_profile(const char * prof)
839{
840	struct lustre_profile *lprof;
841
842	list_for_each_entry(lprof, &lustre_profile_list, lp_list) {
843		if (!strcmp(lprof->lp_profile, prof)) {
844			return lprof;
845		}
846	}
847	return NULL;
848}
849EXPORT_SYMBOL(class_get_profile);
850
851/** Create a named "profile".
852 * This defines the mdc and osc names to use for a client.
853 * This also is used to define the lov to be used by a mdt.
854 */
855int class_add_profile(int proflen, char *prof, int osclen, char *osc,
856		      int mdclen, char *mdc)
857{
858	struct lustre_profile *lprof;
859	int err = 0;
860
861	CDEBUG(D_CONFIG, "Add profile %s\n", prof);
862
863	OBD_ALLOC(lprof, sizeof(*lprof));
864	if (lprof == NULL)
865		return -ENOMEM;
866	INIT_LIST_HEAD(&lprof->lp_list);
867
868	LASSERT(proflen == (strlen(prof) + 1));
869	OBD_ALLOC(lprof->lp_profile, proflen);
870	if (lprof->lp_profile == NULL) {
871		err = -ENOMEM;
872		goto out;
873	}
874	memcpy(lprof->lp_profile, prof, proflen);
875
876	LASSERT(osclen == (strlen(osc) + 1));
877	OBD_ALLOC(lprof->lp_dt, osclen);
878	if (lprof->lp_dt == NULL) {
879		err = -ENOMEM;
880		goto out;
881	}
882	memcpy(lprof->lp_dt, osc, osclen);
883
884	if (mdclen > 0) {
885		LASSERT(mdclen == (strlen(mdc) + 1));
886		OBD_ALLOC(lprof->lp_md, mdclen);
887		if (lprof->lp_md == NULL) {
888			err = -ENOMEM;
889			goto out;
890		}
891		memcpy(lprof->lp_md, mdc, mdclen);
892	}
893
894	list_add(&lprof->lp_list, &lustre_profile_list);
895	return err;
896
897out:
898	if (lprof->lp_md)
899		OBD_FREE(lprof->lp_md, mdclen);
900	if (lprof->lp_dt)
901		OBD_FREE(lprof->lp_dt, osclen);
902	if (lprof->lp_profile)
903		OBD_FREE(lprof->lp_profile, proflen);
904	OBD_FREE(lprof, sizeof(*lprof));
905	return err;
906}
907
908void class_del_profile(const char *prof)
909{
910	struct lustre_profile *lprof;
911
912	CDEBUG(D_CONFIG, "Del profile %s\n", prof);
913
914	lprof = class_get_profile(prof);
915	if (lprof) {
916		list_del(&lprof->lp_list);
917		OBD_FREE(lprof->lp_profile, strlen(lprof->lp_profile) + 1);
918		OBD_FREE(lprof->lp_dt, strlen(lprof->lp_dt) + 1);
919		if (lprof->lp_md)
920			OBD_FREE(lprof->lp_md, strlen(lprof->lp_md) + 1);
921		OBD_FREE(lprof, sizeof(*lprof));
922	}
923}
924EXPORT_SYMBOL(class_del_profile);
925
926/* COMPAT_146 */
927void class_del_profiles(void)
928{
929	struct lustre_profile *lprof, *n;
930
931	list_for_each_entry_safe(lprof, n, &lustre_profile_list, lp_list) {
932		list_del(&lprof->lp_list);
933		OBD_FREE(lprof->lp_profile, strlen(lprof->lp_profile) + 1);
934		OBD_FREE(lprof->lp_dt, strlen(lprof->lp_dt) + 1);
935		if (lprof->lp_md)
936			OBD_FREE(lprof->lp_md, strlen(lprof->lp_md) + 1);
937		OBD_FREE(lprof, sizeof(*lprof));
938	}
939}
940EXPORT_SYMBOL(class_del_profiles);
941
942static int class_set_global(char *ptr, int val, struct lustre_cfg *lcfg)
943{
944	if (class_match_param(ptr, PARAM_AT_MIN, NULL) == 0)
945		at_min = val;
946	else if (class_match_param(ptr, PARAM_AT_MAX, NULL) == 0)
947		at_max = val;
948	else if (class_match_param(ptr, PARAM_AT_EXTRA, NULL) == 0)
949		at_extra = val;
950	else if (class_match_param(ptr, PARAM_AT_EARLY_MARGIN, NULL) == 0)
951		at_early_margin = val;
952	else if (class_match_param(ptr, PARAM_AT_HISTORY, NULL) == 0)
953		at_history = val;
954	else if (class_match_param(ptr, PARAM_JOBID_VAR, NULL) == 0)
955		strlcpy(obd_jobid_var, lustre_cfg_string(lcfg, 2),
956			JOBSTATS_JOBID_VAR_MAX_LEN + 1);
957	else
958		return -EINVAL;
959
960	CDEBUG(D_IOCTL, "global %s = %d\n", ptr, val);
961	return 0;
962}
963
964
965/* We can't call ll_process_config or lquota_process_config directly because
966 * it lives in a module that must be loaded after this one. */
967static int (*client_process_config)(struct lustre_cfg *lcfg) = NULL;
968static int (*quota_process_config)(struct lustre_cfg *lcfg) = NULL;
969
970void lustre_register_client_process_config(int (*cpc)(struct lustre_cfg *lcfg))
971{
972	client_process_config = cpc;
973}
974EXPORT_SYMBOL(lustre_register_client_process_config);
975
976/**
977 * Rename the proc parameter in \a cfg with a new name \a new_name.
978 *
979 * \param cfg	   config structure which contains the proc parameter
980 * \param new_name new name of the proc parameter
981 *
982 * \retval valid-pointer    pointer to the newly-allocated config structure
983 *			    which contains the renamed proc parameter
984 * \retval ERR_PTR(-EINVAL) if \a cfg or \a new_name is NULL, or \a cfg does
985 *			    not contain a proc parameter
986 * \retval ERR_PTR(-ENOMEM) if memory allocation failure occurs
987 */
988struct lustre_cfg *lustre_cfg_rename(struct lustre_cfg *cfg,
989				     const char *new_name)
990{
991	struct lustre_cfg_bufs	*bufs = NULL;
992	struct lustre_cfg	*new_cfg = NULL;
993	char			*param = NULL;
994	char			*new_param = NULL;
995	char			*value = NULL;
996	int			 name_len = 0;
997	int			 new_len = 0;
998
999	if (cfg == NULL || new_name == NULL)
1000		return ERR_PTR(-EINVAL);
1001
1002	param = lustre_cfg_string(cfg, 1);
1003	if (param == NULL)
1004		return ERR_PTR(-EINVAL);
1005
1006	value = strchr(param, '=');
1007	if (value == NULL)
1008		name_len = strlen(param);
1009	else
1010		name_len = value - param;
1011
1012	new_len = LUSTRE_CFG_BUFLEN(cfg, 1) + strlen(new_name) - name_len;
1013
1014	OBD_ALLOC(new_param, new_len);
1015	if (new_param == NULL)
1016		return ERR_PTR(-ENOMEM);
1017
1018	strcpy(new_param, new_name);
1019	if (value != NULL)
1020		strcat(new_param, value);
1021
1022	OBD_ALLOC_PTR(bufs);
1023	if (bufs == NULL) {
1024		OBD_FREE(new_param, new_len);
1025		return ERR_PTR(-ENOMEM);
1026	}
1027
1028	lustre_cfg_bufs_reset(bufs, NULL);
1029	lustre_cfg_bufs_init(bufs, cfg);
1030	lustre_cfg_bufs_set_string(bufs, 1, new_param);
1031
1032	new_cfg = lustre_cfg_new(cfg->lcfg_command, bufs);
1033
1034	OBD_FREE(new_param, new_len);
1035	OBD_FREE_PTR(bufs);
1036	if (new_cfg == NULL)
1037		return ERR_PTR(-ENOMEM);
1038
1039	new_cfg->lcfg_num = cfg->lcfg_num;
1040	new_cfg->lcfg_flags = cfg->lcfg_flags;
1041	new_cfg->lcfg_nid = cfg->lcfg_nid;
1042	new_cfg->lcfg_nal = cfg->lcfg_nal;
1043
1044	return new_cfg;
1045}
1046EXPORT_SYMBOL(lustre_cfg_rename);
1047
1048static int process_param2_config(struct lustre_cfg *lcfg)
1049{
1050	char *param = lustre_cfg_string(lcfg, 1);
1051	char *upcall = lustre_cfg_string(lcfg, 2);
1052	char *argv[] = {
1053		[0] = "/usr/sbin/lctl",
1054		[1] = "set_param",
1055		[2] = param,
1056		[3] = NULL
1057	};
1058	struct timeval	start;
1059	struct timeval	end;
1060	int		rc;
1061
1062
1063	/* Add upcall processing here. Now only lctl is supported */
1064	if (strcmp(upcall, LCTL_UPCALL) != 0) {
1065		CERROR("Unsupported upcall %s\n", upcall);
1066		return -EINVAL;
1067	}
1068
1069	do_gettimeofday(&start);
1070	rc = call_usermodehelper(argv[0], argv, NULL, 1);
1071	do_gettimeofday(&end);
1072
1073	if (rc < 0) {
1074		CERROR(
1075		       "lctl: error invoking upcall %s %s %s: rc = %d; time %ldus\n",
1076		       argv[0], argv[1], argv[2], rc,
1077		       cfs_timeval_sub(&end, &start, NULL));
1078	} else {
1079		CDEBUG(D_HA, "lctl: invoked upcall %s %s %s, time %ldus\n",
1080		       argv[0], argv[1], argv[2],
1081		       cfs_timeval_sub(&end, &start, NULL));
1082		       rc = 0;
1083	}
1084
1085	return rc;
1086}
1087
1088void lustre_register_quota_process_config(int (*qpc)(struct lustre_cfg *lcfg))
1089{
1090	quota_process_config = qpc;
1091}
1092EXPORT_SYMBOL(lustre_register_quota_process_config);
1093
1094/** Process configuration commands given in lustre_cfg form.
1095 * These may come from direct calls (e.g. class_manual_cleanup)
1096 * or processing the config llog, or ioctl from lctl.
1097 */
1098int class_process_config(struct lustre_cfg *lcfg)
1099{
1100	struct obd_device *obd;
1101	int err;
1102
1103	LASSERT(lcfg && !IS_ERR(lcfg));
1104	CDEBUG(D_IOCTL, "processing cmd: %x\n", lcfg->lcfg_command);
1105
1106	/* Commands that don't need a device */
1107	switch (lcfg->lcfg_command) {
1108	case LCFG_ATTACH: {
1109		err = class_attach(lcfg);
1110		goto out;
1111	}
1112	case LCFG_ADD_UUID: {
1113		CDEBUG(D_IOCTL, "adding mapping from uuid %s to nid %#llx (%s)\n",
1114		       lustre_cfg_string(lcfg, 1), lcfg->lcfg_nid,
1115		       libcfs_nid2str(lcfg->lcfg_nid));
1116
1117		err = class_add_uuid(lustre_cfg_string(lcfg, 1), lcfg->lcfg_nid);
1118		goto out;
1119	}
1120	case LCFG_DEL_UUID: {
1121		CDEBUG(D_IOCTL, "removing mappings for uuid %s\n",
1122		       (lcfg->lcfg_bufcount < 2 || LUSTRE_CFG_BUFLEN(lcfg, 1) == 0)
1123		       ? "<all uuids>" : lustre_cfg_string(lcfg, 1));
1124
1125		err = class_del_uuid(lustre_cfg_string(lcfg, 1));
1126		goto out;
1127	}
1128	case LCFG_MOUNTOPT: {
1129		CDEBUG(D_IOCTL, "mountopt: profile %s osc %s mdc %s\n",
1130		       lustre_cfg_string(lcfg, 1),
1131		       lustre_cfg_string(lcfg, 2),
1132		       lustre_cfg_string(lcfg, 3));
1133		/* set these mount options somewhere, so ll_fill_super
1134		 * can find them. */
1135		err = class_add_profile(LUSTRE_CFG_BUFLEN(lcfg, 1),
1136					lustre_cfg_string(lcfg, 1),
1137					LUSTRE_CFG_BUFLEN(lcfg, 2),
1138					lustre_cfg_string(lcfg, 2),
1139					LUSTRE_CFG_BUFLEN(lcfg, 3),
1140					lustre_cfg_string(lcfg, 3));
1141		goto out;
1142	}
1143	case LCFG_DEL_MOUNTOPT: {
1144		CDEBUG(D_IOCTL, "mountopt: profile %s\n",
1145		       lustre_cfg_string(lcfg, 1));
1146		class_del_profile(lustre_cfg_string(lcfg, 1));
1147		err = 0;
1148		goto out;
1149	}
1150	case LCFG_SET_TIMEOUT: {
1151		CDEBUG(D_IOCTL, "changing lustre timeout from %d to %d\n",
1152		       obd_timeout, lcfg->lcfg_num);
1153		obd_timeout = max(lcfg->lcfg_num, 1U);
1154		obd_timeout_set = 1;
1155		err = 0;
1156		goto out;
1157	}
1158	case LCFG_SET_LDLM_TIMEOUT: {
1159		CDEBUG(D_IOCTL, "changing lustre ldlm_timeout from %d to %d\n",
1160		       ldlm_timeout, lcfg->lcfg_num);
1161		ldlm_timeout = max(lcfg->lcfg_num, 1U);
1162		if (ldlm_timeout >= obd_timeout)
1163			ldlm_timeout = max(obd_timeout / 3, 1U);
1164		ldlm_timeout_set = 1;
1165		err = 0;
1166		goto out;
1167	}
1168	case LCFG_SET_UPCALL: {
1169		LCONSOLE_ERROR_MSG(0x15a, "recovery upcall is deprecated\n");
1170		/* COMPAT_146 Don't fail on old configs */
1171		err = 0;
1172		goto out;
1173	}
1174	case LCFG_MARKER: {
1175		struct cfg_marker *marker;
1176		marker = lustre_cfg_buf(lcfg, 1);
1177		CDEBUG(D_IOCTL, "marker %d (%#x) %.16s %s\n", marker->cm_step,
1178		       marker->cm_flags, marker->cm_tgtname, marker->cm_comment);
1179		err = 0;
1180		goto out;
1181	}
1182	case LCFG_PARAM: {
1183		char *tmp;
1184		/* llite has no obd */
1185		if ((class_match_param(lustre_cfg_string(lcfg, 1),
1186				       PARAM_LLITE, NULL) == 0) &&
1187		    client_process_config) {
1188			err = (*client_process_config)(lcfg);
1189			goto out;
1190		} else if ((class_match_param(lustre_cfg_string(lcfg, 1),
1191					      PARAM_SYS, &tmp) == 0)) {
1192			/* Global param settings */
1193			err = class_set_global(tmp, lcfg->lcfg_num, lcfg);
1194			/*
1195			 * Client or server should not fail to mount if
1196			 * it hits an unknown configuration parameter.
1197			 */
1198			if (err != 0)
1199				CWARN("Ignoring unknown param %s\n", tmp);
1200
1201			err = 0;
1202			goto out;
1203		} else if ((class_match_param(lustre_cfg_string(lcfg, 1),
1204					      PARAM_QUOTA, &tmp) == 0) &&
1205			   quota_process_config) {
1206			err = (*quota_process_config)(lcfg);
1207			goto out;
1208		}
1209
1210		break;
1211	}
1212	case LCFG_SET_PARAM: {
1213		err = process_param2_config(lcfg);
1214		goto out;
1215	}
1216	}
1217	/* Commands that require a device */
1218	obd = class_name2obd(lustre_cfg_string(lcfg, 0));
1219	if (obd == NULL) {
1220		if (!LUSTRE_CFG_BUFLEN(lcfg, 0))
1221			CERROR("this lcfg command requires a device name\n");
1222		else
1223			CERROR("no device for: %s\n",
1224			       lustre_cfg_string(lcfg, 0));
1225
1226		err = -EINVAL;
1227		goto out;
1228	}
1229
1230	switch (lcfg->lcfg_command) {
1231	case LCFG_SETUP: {
1232		err = class_setup(obd, lcfg);
1233		goto out;
1234	}
1235	case LCFG_DETACH: {
1236		err = class_detach(obd, lcfg);
1237		err = 0;
1238		goto out;
1239	}
1240	case LCFG_CLEANUP: {
1241		err = class_cleanup(obd, lcfg);
1242		err = 0;
1243		goto out;
1244	}
1245	case LCFG_ADD_CONN: {
1246		err = class_add_conn(obd, lcfg);
1247		err = 0;
1248		goto out;
1249	}
1250	case LCFG_DEL_CONN: {
1251		err = class_del_conn(obd, lcfg);
1252		err = 0;
1253		goto out;
1254	}
1255	case LCFG_POOL_NEW: {
1256		err = obd_pool_new(obd, lustre_cfg_string(lcfg, 2));
1257		err = 0;
1258		goto out;
1259	}
1260	case LCFG_POOL_ADD: {
1261		err = obd_pool_add(obd, lustre_cfg_string(lcfg, 2),
1262				   lustre_cfg_string(lcfg, 3));
1263		err = 0;
1264		goto out;
1265	}
1266	case LCFG_POOL_REM: {
1267		err = obd_pool_rem(obd, lustre_cfg_string(lcfg, 2),
1268				   lustre_cfg_string(lcfg, 3));
1269		err = 0;
1270		goto out;
1271	}
1272	case LCFG_POOL_DEL: {
1273		err = obd_pool_del(obd, lustre_cfg_string(lcfg, 2));
1274		err = 0;
1275		goto out;
1276	}
1277	default: {
1278		err = obd_process_config(obd, sizeof(*lcfg), lcfg);
1279		goto out;
1280
1281	}
1282	}
1283out:
1284	if ((err < 0) && !(lcfg->lcfg_command & LCFG_REQUIRED)) {
1285		CWARN("Ignoring error %d on optional command %#x\n", err,
1286		      lcfg->lcfg_command);
1287		err = 0;
1288	}
1289	return err;
1290}
1291EXPORT_SYMBOL(class_process_config);
1292
1293int class_process_proc_param(char *prefix, struct lprocfs_vars *lvars,
1294			     struct lustre_cfg *lcfg, void *data)
1295{
1296	struct lprocfs_vars *var;
1297	struct file fakefile;
1298	struct seq_file fake_seqfile;
1299	char *key, *sval;
1300	int i, keylen, vallen;
1301	int matched = 0, j = 0;
1302	int rc = 0;
1303	int skip = 0;
1304
1305	if (lcfg->lcfg_command != LCFG_PARAM) {
1306		CERROR("Unknown command: %d\n", lcfg->lcfg_command);
1307		return -EINVAL;
1308	}
1309
1310	/* fake a seq file so that var->fops->write can work... */
1311	fakefile.private_data = &fake_seqfile;
1312	fake_seqfile.private = data;
1313	/* e.g. tunefs.lustre --param mdt.group_upcall=foo /r/tmp/lustre-mdt
1314	   or   lctl conf_param lustre-MDT0000.mdt.group_upcall=bar
1315	   or   lctl conf_param lustre-OST0000.osc.max_dirty_mb=36 */
1316	for (i = 1; i < lcfg->lcfg_bufcount; i++) {
1317		key = lustre_cfg_buf(lcfg, i);
1318		/* Strip off prefix */
1319		class_match_param(key, prefix, &key);
1320		sval = strchr(key, '=');
1321		if (!sval || (*(sval + 1) == 0)) {
1322			CERROR("Can't parse param %s (missing '=')\n", key);
1323			/* rc = -EINVAL;	continue parsing other params */
1324			continue;
1325		}
1326		keylen = sval - key;
1327		sval++;
1328		vallen = strlen(sval);
1329		matched = 0;
1330		j = 0;
1331		/* Search proc entries */
1332		while (lvars[j].name) {
1333			var = &lvars[j];
1334			if (class_match_param(key, (char *)var->name, NULL) == 0
1335			    && keylen == strlen(var->name)) {
1336				matched++;
1337				rc = -EROFS;
1338				if (var->fops && var->fops->write) {
1339					mm_segment_t oldfs;
1340					oldfs = get_fs();
1341					set_fs(KERNEL_DS);
1342					rc = (var->fops->write)(&fakefile, sval,
1343								vallen, NULL);
1344					set_fs(oldfs);
1345				}
1346				break;
1347			}
1348			j++;
1349		}
1350		if (!matched) {
1351			/* If the prefix doesn't match, return error so we
1352			   can pass it down the stack */
1353			if (strnchr(key, keylen, '.'))
1354			    return -ENOSYS;
1355			CERROR("%s: unknown param %s\n",
1356			       (char *)lustre_cfg_string(lcfg, 0), key);
1357			/* rc = -EINVAL;	continue parsing other params */
1358			skip++;
1359		} else if (rc < 0) {
1360			CERROR("writing proc entry %s err %d\n",
1361			       var->name, rc);
1362			rc = 0;
1363		} else {
1364			CDEBUG(D_CONFIG, "%s.%.*s: Set parameter %.*s=%s\n",
1365					 lustre_cfg_string(lcfg, 0),
1366					 (int)strlen(prefix) - 1, prefix,
1367					 (int)(sval - key - 1), key, sval);
1368		}
1369	}
1370
1371	if (rc > 0)
1372		rc = 0;
1373	if (!rc && skip)
1374		rc = skip;
1375	return rc;
1376}
1377EXPORT_SYMBOL(class_process_proc_param);
1378
1379extern int lustre_check_exclusion(struct super_block *sb, char *svname);
1380
1381/** Parse a configuration llog, doing various manipulations on them
1382 * for various reasons, (modifications for compatibility, skip obsolete
1383 * records, change uuids, etc), then class_process_config() resulting
1384 * net records.
1385 */
1386int class_config_llog_handler(const struct lu_env *env,
1387			      struct llog_handle *handle,
1388			      struct llog_rec_hdr *rec, void *data)
1389{
1390	struct config_llog_instance *clli = data;
1391	int cfg_len = rec->lrh_len;
1392	char *cfg_buf = (char *) (rec + 1);
1393	int rc = 0;
1394
1395	//class_config_dump_handler(handle, rec, data);
1396
1397	switch (rec->lrh_type) {
1398	case OBD_CFG_REC: {
1399		struct lustre_cfg *lcfg, *lcfg_new;
1400		struct lustre_cfg_bufs bufs;
1401		char *inst_name = NULL;
1402		int inst_len = 0;
1403		int inst = 0, swab = 0;
1404
1405		lcfg = (struct lustre_cfg *)cfg_buf;
1406		if (lcfg->lcfg_version == __swab32(LUSTRE_CFG_VERSION)) {
1407			lustre_swab_lustre_cfg(lcfg);
1408			swab = 1;
1409		}
1410
1411		rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
1412		if (rc)
1413			goto out;
1414
1415		/* Figure out config state info */
1416		if (lcfg->lcfg_command == LCFG_MARKER) {
1417			struct cfg_marker *marker = lustre_cfg_buf(lcfg, 1);
1418			lustre_swab_cfg_marker(marker, swab,
1419					       LUSTRE_CFG_BUFLEN(lcfg, 1));
1420			CDEBUG(D_CONFIG, "Marker, inst_flg=%#x mark_flg=%#x\n",
1421			       clli->cfg_flags, marker->cm_flags);
1422			if (marker->cm_flags & CM_START) {
1423				/* all previous flags off */
1424				clli->cfg_flags = CFG_F_MARKER;
1425				if (marker->cm_flags & CM_SKIP) {
1426					clli->cfg_flags |= CFG_F_SKIP;
1427					CDEBUG(D_CONFIG, "SKIP #%d\n",
1428					       marker->cm_step);
1429				} else if ((marker->cm_flags & CM_EXCLUDE) ||
1430					   (clli->cfg_sb &&
1431					    lustre_check_exclusion(clli->cfg_sb,
1432							 marker->cm_tgtname))) {
1433					clli->cfg_flags |= CFG_F_EXCLUDE;
1434					CDEBUG(D_CONFIG, "EXCLUDE %d\n",
1435					       marker->cm_step);
1436				}
1437			} else if (marker->cm_flags & CM_END) {
1438				clli->cfg_flags = 0;
1439			}
1440		}
1441		/* A config command without a start marker before it is
1442		   illegal (post 146) */
1443		if (!(clli->cfg_flags & CFG_F_COMPAT146) &&
1444		    !(clli->cfg_flags & CFG_F_MARKER) &&
1445		    (lcfg->lcfg_command != LCFG_MARKER)) {
1446			CWARN("Config not inside markers, ignoring! "
1447			      "(inst: %p, uuid: %s, flags: %#x)\n",
1448			      clli->cfg_instance,
1449			      clli->cfg_uuid.uuid, clli->cfg_flags);
1450			clli->cfg_flags |= CFG_F_SKIP;
1451		}
1452		if (clli->cfg_flags & CFG_F_SKIP) {
1453			CDEBUG(D_CONFIG, "skipping %#x\n",
1454			       clli->cfg_flags);
1455			rc = 0;
1456			/* No processing! */
1457			break;
1458		}
1459
1460		/*
1461		 * For interoperability between 1.8 and 2.0,
1462		 * rename "mds" obd device type to "mdt".
1463		 */
1464		{
1465			char *typename = lustre_cfg_string(lcfg, 1);
1466			char *index = lustre_cfg_string(lcfg, 2);
1467
1468			if ((lcfg->lcfg_command == LCFG_ATTACH && typename &&
1469			     strcmp(typename, "mds") == 0)) {
1470				CWARN("For 1.8 interoperability, rename obd "
1471				       "type from mds to mdt\n");
1472				typename[2] = 't';
1473			}
1474			if ((lcfg->lcfg_command == LCFG_SETUP && index &&
1475			     strcmp(index, "type") == 0)) {
1476				CDEBUG(D_INFO, "For 1.8 interoperability, "
1477				       "set this index to '0'\n");
1478				index[0] = '0';
1479				index[1] = 0;
1480			}
1481		}
1482
1483
1484		if (clli->cfg_flags & CFG_F_EXCLUDE) {
1485			CDEBUG(D_CONFIG, "cmd: %x marked EXCLUDED\n",
1486			       lcfg->lcfg_command);
1487			if (lcfg->lcfg_command == LCFG_LOV_ADD_OBD)
1488				/* Add inactive instead */
1489				lcfg->lcfg_command = LCFG_LOV_ADD_INA;
1490		}
1491
1492		lustre_cfg_bufs_init(&bufs, lcfg);
1493
1494		if (clli && clli->cfg_instance &&
1495		    LUSTRE_CFG_BUFLEN(lcfg, 0) > 0){
1496			inst = 1;
1497			inst_len = LUSTRE_CFG_BUFLEN(lcfg, 0) +
1498				   sizeof(clli->cfg_instance) * 2 + 4;
1499			OBD_ALLOC(inst_name, inst_len);
1500			if (inst_name == NULL) {
1501				rc = -ENOMEM;
1502				goto out;
1503			}
1504			sprintf(inst_name, "%s-%p",
1505				lustre_cfg_string(lcfg, 0),
1506				clli->cfg_instance);
1507			lustre_cfg_bufs_set_string(&bufs, 0, inst_name);
1508			CDEBUG(D_CONFIG, "cmd %x, instance name: %s\n",
1509			       lcfg->lcfg_command, inst_name);
1510		}
1511
1512		/* we override the llog's uuid for clients, to insure they
1513		are unique */
1514		if (clli && clli->cfg_instance != NULL &&
1515		    lcfg->lcfg_command == LCFG_ATTACH) {
1516			lustre_cfg_bufs_set_string(&bufs, 2,
1517						   clli->cfg_uuid.uuid);
1518		}
1519		/*
1520		 * sptlrpc config record, we expect 2 data segments:
1521		 *  [0]: fs_name/target_name,
1522		 *  [1]: rule string
1523		 * moving them to index [1] and [2], and insert MGC's
1524		 * obdname at index [0].
1525		 */
1526		if (clli && clli->cfg_instance == NULL &&
1527		    lcfg->lcfg_command == LCFG_SPTLRPC_CONF) {
1528			lustre_cfg_bufs_set(&bufs, 2, bufs.lcfg_buf[1],
1529					    bufs.lcfg_buflen[1]);
1530			lustre_cfg_bufs_set(&bufs, 1, bufs.lcfg_buf[0],
1531					    bufs.lcfg_buflen[0]);
1532			lustre_cfg_bufs_set_string(&bufs, 0,
1533						   clli->cfg_obdname);
1534		}
1535
1536		lcfg_new = lustre_cfg_new(lcfg->lcfg_command, &bufs);
1537
1538		lcfg_new->lcfg_num   = lcfg->lcfg_num;
1539		lcfg_new->lcfg_flags = lcfg->lcfg_flags;
1540
1541		/* XXX Hack to try to remain binary compatible with
1542		 * pre-newconfig logs */
1543		if (lcfg->lcfg_nal != 0 &&      /* pre-newconfig log? */
1544		    (lcfg->lcfg_nid >> 32) == 0) {
1545			__u32 addr = (__u32)(lcfg->lcfg_nid & 0xffffffff);
1546
1547			lcfg_new->lcfg_nid =
1548				LNET_MKNID(LNET_MKNET(lcfg->lcfg_nal, 0), addr);
1549			CWARN("Converted pre-newconfig NAL %d NID %x to %s\n",
1550			      lcfg->lcfg_nal, addr,
1551			      libcfs_nid2str(lcfg_new->lcfg_nid));
1552		} else {
1553			lcfg_new->lcfg_nid = lcfg->lcfg_nid;
1554		}
1555
1556		lcfg_new->lcfg_nal = 0; /* illegal value for obsolete field */
1557
1558		rc = class_process_config(lcfg_new);
1559		lustre_cfg_free(lcfg_new);
1560
1561		if (inst)
1562			OBD_FREE(inst_name, inst_len);
1563		break;
1564	}
1565	default:
1566		CERROR("Unknown llog record type %#x encountered\n",
1567		       rec->lrh_type);
1568		break;
1569	}
1570out:
1571	if (rc) {
1572		CERROR("%s: cfg command failed: rc = %d\n",
1573		       handle->lgh_ctxt->loc_obd->obd_name, rc);
1574		class_config_dump_handler(NULL, handle, rec, data);
1575	}
1576	return rc;
1577}
1578EXPORT_SYMBOL(class_config_llog_handler);
1579
1580int class_config_parse_llog(const struct lu_env *env, struct llog_ctxt *ctxt,
1581			    char *name, struct config_llog_instance *cfg)
1582{
1583	struct llog_process_cat_data	 cd = {0, 0};
1584	struct llog_handle		*llh;
1585	llog_cb_t			 callback;
1586	int				 rc;
1587
1588	CDEBUG(D_INFO, "looking up llog %s\n", name);
1589	rc = llog_open(env, ctxt, &llh, NULL, name, LLOG_OPEN_EXISTS);
1590	if (rc)
1591		return rc;
1592
1593	rc = llog_init_handle(env, llh, LLOG_F_IS_PLAIN, NULL);
1594	if (rc)
1595		goto parse_out;
1596
1597	/* continue processing from where we last stopped to end-of-log */
1598	if (cfg) {
1599		cd.lpcd_first_idx = cfg->cfg_last_idx;
1600		callback = cfg->cfg_callback;
1601		LASSERT(callback != NULL);
1602	} else {
1603		callback = class_config_llog_handler;
1604	}
1605
1606	cd.lpcd_last_idx = 0;
1607
1608	rc = llog_process(env, llh, callback, cfg, &cd);
1609
1610	CDEBUG(D_CONFIG, "Processed log %s gen %d-%d (rc=%d)\n", name,
1611	       cd.lpcd_first_idx + 1, cd.lpcd_last_idx, rc);
1612	if (cfg)
1613		cfg->cfg_last_idx = cd.lpcd_last_idx;
1614
1615parse_out:
1616	llog_close(env, llh);
1617	return rc;
1618}
1619EXPORT_SYMBOL(class_config_parse_llog);
1620
1621/**
1622 * parse config record and output dump in supplied buffer.
1623 * This is separated from class_config_dump_handler() to use
1624 * for ioctl needs as well
1625 */
1626int class_config_parse_rec(struct llog_rec_hdr *rec, char *buf, int size)
1627{
1628	struct lustre_cfg	*lcfg = (struct lustre_cfg *)(rec + 1);
1629	char			*ptr = buf;
1630	char			*end = buf + size;
1631	int			 rc = 0;
1632
1633	LASSERT(rec->lrh_type == OBD_CFG_REC);
1634	rc = lustre_cfg_sanity_check(lcfg, rec->lrh_len);
1635	if (rc < 0)
1636		return rc;
1637
1638	ptr += snprintf(ptr, end-ptr, "cmd=%05x ", lcfg->lcfg_command);
1639	if (lcfg->lcfg_flags)
1640		ptr += snprintf(ptr, end-ptr, "flags=%#08x ",
1641				lcfg->lcfg_flags);
1642
1643	if (lcfg->lcfg_num)
1644		ptr += snprintf(ptr, end-ptr, "num=%#08x ", lcfg->lcfg_num);
1645
1646	if (lcfg->lcfg_nid)
1647		ptr += snprintf(ptr, end-ptr, "nid=%s(%#llx)\n     ",
1648				libcfs_nid2str(lcfg->lcfg_nid),
1649				lcfg->lcfg_nid);
1650
1651	if (lcfg->lcfg_command == LCFG_MARKER) {
1652		struct cfg_marker *marker = lustre_cfg_buf(lcfg, 1);
1653
1654		ptr += snprintf(ptr, end-ptr, "marker=%d(%#x)%s '%s'",
1655				marker->cm_step, marker->cm_flags,
1656				marker->cm_tgtname, marker->cm_comment);
1657	} else {
1658		int i;
1659
1660		for (i = 0; i <  lcfg->lcfg_bufcount; i++) {
1661			ptr += snprintf(ptr, end-ptr, "%d:%s  ", i,
1662					lustre_cfg_string(lcfg, i));
1663		}
1664	}
1665	/* return consumed bytes */
1666	rc = ptr - buf;
1667	return rc;
1668}
1669
1670int class_config_dump_handler(const struct lu_env *env,
1671			      struct llog_handle *handle,
1672			      struct llog_rec_hdr *rec, void *data)
1673{
1674	char	*outstr;
1675	int	 rc = 0;
1676
1677	OBD_ALLOC(outstr, 256);
1678	if (outstr == NULL)
1679		return -ENOMEM;
1680
1681	if (rec->lrh_type == OBD_CFG_REC) {
1682		class_config_parse_rec(rec, outstr, 256);
1683		LCONSOLE(D_WARNING, "   %s\n", outstr);
1684	} else {
1685		LCONSOLE(D_WARNING, "unhandled lrh_type: %#x\n", rec->lrh_type);
1686		rc = -EINVAL;
1687	}
1688
1689	OBD_FREE(outstr, 256);
1690	return rc;
1691}
1692
1693int class_config_dump_llog(const struct lu_env *env, struct llog_ctxt *ctxt,
1694			   char *name, struct config_llog_instance *cfg)
1695{
1696	struct llog_handle	*llh;
1697	int			 rc;
1698
1699	LCONSOLE_INFO("Dumping config log %s\n", name);
1700
1701	rc = llog_open(env, ctxt, &llh, NULL, name, LLOG_OPEN_EXISTS);
1702	if (rc)
1703		return rc;
1704
1705	rc = llog_init_handle(env, llh, LLOG_F_IS_PLAIN, NULL);
1706	if (rc)
1707		goto parse_out;
1708
1709	rc = llog_process(env, llh, class_config_dump_handler, cfg, NULL);
1710parse_out:
1711	llog_close(env, llh);
1712
1713	LCONSOLE_INFO("End config log %s\n", name);
1714	return rc;
1715}
1716EXPORT_SYMBOL(class_config_dump_llog);
1717
1718/** Call class_cleanup and class_detach.
1719 * "Manual" only in the sense that we're faking lcfg commands.
1720 */
1721int class_manual_cleanup(struct obd_device *obd)
1722{
1723	char		    flags[3] = "";
1724	struct lustre_cfg      *lcfg;
1725	struct lustre_cfg_bufs  bufs;
1726	int		     rc;
1727
1728	if (!obd) {
1729		CERROR("empty cleanup\n");
1730		return -EALREADY;
1731	}
1732
1733	if (obd->obd_force)
1734		strcat(flags, "F");
1735	if (obd->obd_fail)
1736		strcat(flags, "A");
1737
1738	CDEBUG(D_CONFIG, "Manual cleanup of %s (flags='%s')\n",
1739	       obd->obd_name, flags);
1740
1741	lustre_cfg_bufs_reset(&bufs, obd->obd_name);
1742	lustre_cfg_bufs_set_string(&bufs, 1, flags);
1743	lcfg = lustre_cfg_new(LCFG_CLEANUP, &bufs);
1744	if (!lcfg)
1745		return -ENOMEM;
1746
1747	rc = class_process_config(lcfg);
1748	if (rc) {
1749		CERROR("cleanup failed %d: %s\n", rc, obd->obd_name);
1750		goto out;
1751	}
1752
1753	/* the lcfg is almost the same for both ops */
1754	lcfg->lcfg_command = LCFG_DETACH;
1755	rc = class_process_config(lcfg);
1756	if (rc)
1757		CERROR("detach failed %d: %s\n", rc, obd->obd_name);
1758out:
1759	lustre_cfg_free(lcfg);
1760	return rc;
1761}
1762EXPORT_SYMBOL(class_manual_cleanup);
1763
1764/*
1765 * uuid<->export lustre hash operations
1766 */
1767
1768static unsigned
1769uuid_hash(struct cfs_hash *hs, const void *key, unsigned mask)
1770{
1771	return cfs_hash_djb2_hash(((struct obd_uuid *)key)->uuid,
1772				  sizeof(((struct obd_uuid *)key)->uuid), mask);
1773}
1774
1775static void *
1776uuid_key(struct hlist_node *hnode)
1777{
1778	struct obd_export *exp;
1779
1780	exp = hlist_entry(hnode, struct obd_export, exp_uuid_hash);
1781
1782	return &exp->exp_client_uuid;
1783}
1784
1785/*
1786 * NOTE: It is impossible to find an export that is in failed
1787 *       state with this function
1788 */
1789static int
1790uuid_keycmp(const void *key, struct hlist_node *hnode)
1791{
1792	struct obd_export *exp;
1793
1794	LASSERT(key);
1795	exp = hlist_entry(hnode, struct obd_export, exp_uuid_hash);
1796
1797	return obd_uuid_equals(key, &exp->exp_client_uuid) &&
1798	       !exp->exp_failed;
1799}
1800
1801static void *
1802uuid_export_object(struct hlist_node *hnode)
1803{
1804	return hlist_entry(hnode, struct obd_export, exp_uuid_hash);
1805}
1806
1807static void
1808uuid_export_get(struct cfs_hash *hs, struct hlist_node *hnode)
1809{
1810	struct obd_export *exp;
1811
1812	exp = hlist_entry(hnode, struct obd_export, exp_uuid_hash);
1813	class_export_get(exp);
1814}
1815
1816static void
1817uuid_export_put_locked(struct cfs_hash *hs, struct hlist_node *hnode)
1818{
1819	struct obd_export *exp;
1820
1821	exp = hlist_entry(hnode, struct obd_export, exp_uuid_hash);
1822	class_export_put(exp);
1823}
1824
1825static cfs_hash_ops_t uuid_hash_ops = {
1826	.hs_hash	= uuid_hash,
1827	.hs_key	 = uuid_key,
1828	.hs_keycmp      = uuid_keycmp,
1829	.hs_object      = uuid_export_object,
1830	.hs_get	 = uuid_export_get,
1831	.hs_put_locked  = uuid_export_put_locked,
1832};
1833
1834
1835/*
1836 * nid<->export hash operations
1837 */
1838
1839static unsigned
1840nid_hash(struct cfs_hash *hs, const void *key, unsigned mask)
1841{
1842	return cfs_hash_djb2_hash(key, sizeof(lnet_nid_t), mask);
1843}
1844
1845static void *
1846nid_key(struct hlist_node *hnode)
1847{
1848	struct obd_export *exp;
1849
1850	exp = hlist_entry(hnode, struct obd_export, exp_nid_hash);
1851
1852	return &exp->exp_connection->c_peer.nid;
1853}
1854
1855/*
1856 * NOTE: It is impossible to find an export that is in failed
1857 *       state with this function
1858 */
1859static int
1860nid_kepcmp(const void *key, struct hlist_node *hnode)
1861{
1862	struct obd_export *exp;
1863
1864	LASSERT(key);
1865	exp = hlist_entry(hnode, struct obd_export, exp_nid_hash);
1866
1867	return exp->exp_connection->c_peer.nid == *(lnet_nid_t *)key &&
1868	       !exp->exp_failed;
1869}
1870
1871static void *
1872nid_export_object(struct hlist_node *hnode)
1873{
1874	return hlist_entry(hnode, struct obd_export, exp_nid_hash);
1875}
1876
1877static void
1878nid_export_get(struct cfs_hash *hs, struct hlist_node *hnode)
1879{
1880	struct obd_export *exp;
1881
1882	exp = hlist_entry(hnode, struct obd_export, exp_nid_hash);
1883	class_export_get(exp);
1884}
1885
1886static void
1887nid_export_put_locked(struct cfs_hash *hs, struct hlist_node *hnode)
1888{
1889	struct obd_export *exp;
1890
1891	exp = hlist_entry(hnode, struct obd_export, exp_nid_hash);
1892	class_export_put(exp);
1893}
1894
1895static cfs_hash_ops_t nid_hash_ops = {
1896	.hs_hash	= nid_hash,
1897	.hs_key	 = nid_key,
1898	.hs_keycmp      = nid_kepcmp,
1899	.hs_object      = nid_export_object,
1900	.hs_get	 = nid_export_get,
1901	.hs_put_locked  = nid_export_put_locked,
1902};
1903
1904
1905/*
1906 * nid<->nidstats hash operations
1907 */
1908
1909static void *
1910nidstats_key(struct hlist_node *hnode)
1911{
1912	struct nid_stat *ns;
1913
1914	ns = hlist_entry(hnode, struct nid_stat, nid_hash);
1915
1916	return &ns->nid;
1917}
1918
1919static int
1920nidstats_keycmp(const void *key, struct hlist_node *hnode)
1921{
1922	return *(lnet_nid_t *)nidstats_key(hnode) == *(lnet_nid_t *)key;
1923}
1924
1925static void *
1926nidstats_object(struct hlist_node *hnode)
1927{
1928	return hlist_entry(hnode, struct nid_stat, nid_hash);
1929}
1930
1931static void
1932nidstats_get(struct cfs_hash *hs, struct hlist_node *hnode)
1933{
1934	struct nid_stat *ns;
1935
1936	ns = hlist_entry(hnode, struct nid_stat, nid_hash);
1937	nidstat_getref(ns);
1938}
1939
1940static void
1941nidstats_put_locked(struct cfs_hash *hs, struct hlist_node *hnode)
1942{
1943	struct nid_stat *ns;
1944
1945	ns = hlist_entry(hnode, struct nid_stat, nid_hash);
1946	nidstat_putref(ns);
1947}
1948
1949static cfs_hash_ops_t nid_stat_hash_ops = {
1950	.hs_hash	= nid_hash,
1951	.hs_key	 = nidstats_key,
1952	.hs_keycmp      = nidstats_keycmp,
1953	.hs_object      = nidstats_object,
1954	.hs_get	 = nidstats_get,
1955	.hs_put_locked  = nidstats_put_locked,
1956};
1957