xref: /illumos-gate/usr/src/cmd/fm/fmdump/common/scheme.c (revision 1743a90d)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
524db4641Seschrock  * Common Development and Distribution License (the "License").
624db4641Seschrock  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
217c478bd9Sstevel@tonic-gate /*
2224db4641Seschrock  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
237c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
247c478bd9Sstevel@tonic-gate  */
257c478bd9Sstevel@tonic-gate 
267c478bd9Sstevel@tonic-gate #include <sys/types.h>
277c478bd9Sstevel@tonic-gate #include <sys/systeminfo.h>
287c478bd9Sstevel@tonic-gate 
297c478bd9Sstevel@tonic-gate #include <limits.h>
307c478bd9Sstevel@tonic-gate #include <strings.h>
317c478bd9Sstevel@tonic-gate #include <stddef.h>
327c478bd9Sstevel@tonic-gate #include <unistd.h>
337c478bd9Sstevel@tonic-gate #include <dlfcn.h>
347c478bd9Sstevel@tonic-gate #include <errno.h>
357c478bd9Sstevel@tonic-gate 
367c478bd9Sstevel@tonic-gate #include <fmdump.h>
377c478bd9Sstevel@tonic-gate 
387c478bd9Sstevel@tonic-gate /*
397c478bd9Sstevel@tonic-gate  * fmdump loadable scheme support
407c478bd9Sstevel@tonic-gate  *
417c478bd9Sstevel@tonic-gate  * This file provides a pared-down implementation of fmd's fmd_fmri.c and
427c478bd9Sstevel@tonic-gate  * fmd_scheme.c and must be kept in sync with the set of service routines
437c478bd9Sstevel@tonic-gate  * required by scheme plug-ins.  At some point if other utilities want to
447c478bd9Sstevel@tonic-gate  * use this we can refactor it into a more general library.  (Note: fmd
457c478bd9Sstevel@tonic-gate  * cannot use such a library because it has its own internal locking, etc.)
467c478bd9Sstevel@tonic-gate  * As schemes are needed, we dlopen() them and cache a list of them which we
477c478bd9Sstevel@tonic-gate  * can search later.  We also use the list as a negative cache: if we fail to
487c478bd9Sstevel@tonic-gate  * load a scheme, we add an entry with sch_dlp = NULL and sch_err recording
497c478bd9Sstevel@tonic-gate  * the errno to be returned to the caller.
507c478bd9Sstevel@tonic-gate  */
517c478bd9Sstevel@tonic-gate 
527c478bd9Sstevel@tonic-gate typedef struct fmd_scheme_ops {
537c478bd9Sstevel@tonic-gate 	int (*sop_init)(void);
547c478bd9Sstevel@tonic-gate 	void (*sop_fini)(void);
557c478bd9Sstevel@tonic-gate 	ssize_t (*sop_nvl2str)(nvlist_t *, char *, size_t);
567c478bd9Sstevel@tonic-gate } fmd_scheme_ops_t;
577c478bd9Sstevel@tonic-gate 
587c478bd9Sstevel@tonic-gate typedef struct fmd_scheme_opd {
597c478bd9Sstevel@tonic-gate 	const char *opd_name;		/* symbol name of scheme function */
607c478bd9Sstevel@tonic-gate 	size_t opd_off;			/* offset within fmd_scheme_ops_t */
617c478bd9Sstevel@tonic-gate } fmd_scheme_opd_t;
627c478bd9Sstevel@tonic-gate 
637c478bd9Sstevel@tonic-gate typedef struct fmd_scheme {
647c478bd9Sstevel@tonic-gate 	struct fmd_scheme *sch_next;    /* next scheme on list of schemes */
657c478bd9Sstevel@tonic-gate 	char *sch_name;			/* name of this scheme (fmri prefix) */
667c478bd9Sstevel@tonic-gate 	void *sch_dlp;			/* libdl(3DL) shared library handle */
677c478bd9Sstevel@tonic-gate 	int sch_err;			/* if negative entry, errno to return */
687c478bd9Sstevel@tonic-gate 	fmd_scheme_ops_t sch_ops;	/* scheme function pointers */
697c478bd9Sstevel@tonic-gate } fmd_scheme_t;
707c478bd9Sstevel@tonic-gate 
717c478bd9Sstevel@tonic-gate static fmd_scheme_t *sch_list;		/* list of cached schemes */
727c478bd9Sstevel@tonic-gate 
737c478bd9Sstevel@tonic-gate static long
fmd_scheme_notsup(void)747c478bd9Sstevel@tonic-gate fmd_scheme_notsup(void)
757c478bd9Sstevel@tonic-gate {
767c478bd9Sstevel@tonic-gate 	errno = ENOTSUP;
777c478bd9Sstevel@tonic-gate 	return (-1);
787c478bd9Sstevel@tonic-gate }
797c478bd9Sstevel@tonic-gate 
80*1743a90dSToomas Soome static void
fmd_scheme_vnop(void)81*1743a90dSToomas Soome fmd_scheme_vnop(void)
82*1743a90dSToomas Soome {
83*1743a90dSToomas Soome }
84*1743a90dSToomas Soome 
857c478bd9Sstevel@tonic-gate static int
fmd_scheme_nop(void)867c478bd9Sstevel@tonic-gate fmd_scheme_nop(void)
877c478bd9Sstevel@tonic-gate {
887c478bd9Sstevel@tonic-gate 	return (0);
897c478bd9Sstevel@tonic-gate }
907c478bd9Sstevel@tonic-gate 
917c478bd9Sstevel@tonic-gate /*
927c478bd9Sstevel@tonic-gate  * Default values for the scheme ops.  If a scheme function is not defined in
937c478bd9Sstevel@tonic-gate  * the module, then this operation is implemented using the default function.
947c478bd9Sstevel@tonic-gate  */
957c478bd9Sstevel@tonic-gate static const fmd_scheme_ops_t _fmd_scheme_default_ops = {
967c478bd9Sstevel@tonic-gate 	(int (*)())fmd_scheme_nop,		/* sop_init */
97*1743a90dSToomas Soome 	(void (*)())fmd_scheme_vnop,		/* sop_fini */
987c478bd9Sstevel@tonic-gate 	(ssize_t (*)())fmd_scheme_notsup,	/* sop_nvl2str */
997c478bd9Sstevel@tonic-gate };
1007c478bd9Sstevel@tonic-gate 
1017c478bd9Sstevel@tonic-gate /*
1027c478bd9Sstevel@tonic-gate  * Scheme ops descriptions.  These names and offsets are used by the function
1037c478bd9Sstevel@tonic-gate  * fmd_scheme_rtld_init(), defined below, to load up a fmd_scheme_ops_t.
1047c478bd9Sstevel@tonic-gate  */
1057c478bd9Sstevel@tonic-gate static const fmd_scheme_opd_t _fmd_scheme_ops[] = {
1067c478bd9Sstevel@tonic-gate 	{ "fmd_fmri_init", offsetof(fmd_scheme_ops_t, sop_init) },
1077c478bd9Sstevel@tonic-gate 	{ "fmd_fmri_fini", offsetof(fmd_scheme_ops_t, sop_fini) },
1087c478bd9Sstevel@tonic-gate 	{ "fmd_fmri_nvl2str", offsetof(fmd_scheme_ops_t, sop_nvl2str) },
1097c478bd9Sstevel@tonic-gate 	{ NULL, 0 }
1107c478bd9Sstevel@tonic-gate };
1117c478bd9Sstevel@tonic-gate 
1127c478bd9Sstevel@tonic-gate static fmd_scheme_t *
fmd_scheme_create(const char * name)1137c478bd9Sstevel@tonic-gate fmd_scheme_create(const char *name)
1147c478bd9Sstevel@tonic-gate {
1157c478bd9Sstevel@tonic-gate 	fmd_scheme_t *sp;
1167c478bd9Sstevel@tonic-gate 
1177c478bd9Sstevel@tonic-gate 	if ((sp = malloc(sizeof (fmd_scheme_t))) == NULL ||
1187c478bd9Sstevel@tonic-gate 	    (sp->sch_name = strdup(name)) == NULL) {
1197c478bd9Sstevel@tonic-gate 		free(sp);
1207c478bd9Sstevel@tonic-gate 		return (NULL);
1217c478bd9Sstevel@tonic-gate 	}
1227c478bd9Sstevel@tonic-gate 
1237c478bd9Sstevel@tonic-gate 	sp->sch_next = sch_list;
1247c478bd9Sstevel@tonic-gate 	sp->sch_dlp = NULL;
1257c478bd9Sstevel@tonic-gate 	sp->sch_err = 0;
1267c478bd9Sstevel@tonic-gate 	sp->sch_ops = _fmd_scheme_default_ops;
1277c478bd9Sstevel@tonic-gate 
1287c478bd9Sstevel@tonic-gate 	sch_list = sp;
1297c478bd9Sstevel@tonic-gate 	return (sp);
1307c478bd9Sstevel@tonic-gate }
1317c478bd9Sstevel@tonic-gate 
1327c478bd9Sstevel@tonic-gate static int
fmd_scheme_rtld_init(fmd_scheme_t * sp)1337c478bd9Sstevel@tonic-gate fmd_scheme_rtld_init(fmd_scheme_t *sp)
1347c478bd9Sstevel@tonic-gate {
1357c478bd9Sstevel@tonic-gate 	const fmd_scheme_opd_t *opd;
1367c478bd9Sstevel@tonic-gate 	void *p;
1377c478bd9Sstevel@tonic-gate 
1387c478bd9Sstevel@tonic-gate 	for (opd = _fmd_scheme_ops; opd->opd_name != NULL; opd++) {
1397c478bd9Sstevel@tonic-gate 		if ((p = dlsym(sp->sch_dlp, opd->opd_name)) != NULL)
1407c478bd9Sstevel@tonic-gate 			*(void **)((uintptr_t)&sp->sch_ops + opd->opd_off) = p;
1417c478bd9Sstevel@tonic-gate 	}
1427c478bd9Sstevel@tonic-gate 
1437c478bd9Sstevel@tonic-gate 	return (sp->sch_ops.sop_init());
1447c478bd9Sstevel@tonic-gate }
1457c478bd9Sstevel@tonic-gate 
1467c478bd9Sstevel@tonic-gate static fmd_scheme_t *
fmd_scheme_lookup(const char * dir,const char * name)1477c478bd9Sstevel@tonic-gate fmd_scheme_lookup(const char *dir, const char *name)
1487c478bd9Sstevel@tonic-gate {
1497c478bd9Sstevel@tonic-gate 	fmd_scheme_t *sp;
1507c478bd9Sstevel@tonic-gate 	char path[PATH_MAX];
1517c478bd9Sstevel@tonic-gate 
1527c478bd9Sstevel@tonic-gate 	for (sp = sch_list; sp != NULL; sp = sp->sch_next) {
1537c478bd9Sstevel@tonic-gate 		if (strcmp(name, sp->sch_name) == 0)
1547c478bd9Sstevel@tonic-gate 			return (sp);
1557c478bd9Sstevel@tonic-gate 	}
1567c478bd9Sstevel@tonic-gate 
1577c478bd9Sstevel@tonic-gate 	if ((sp = fmd_scheme_create(name)) == NULL)
1587c478bd9Sstevel@tonic-gate 		return (NULL); /* errno is set for us */
1597c478bd9Sstevel@tonic-gate 
1607c478bd9Sstevel@tonic-gate 	(void) snprintf(path, sizeof (path), "%s%s/%s.so",
1617c478bd9Sstevel@tonic-gate 	    g_root ? g_root : "", dir, name);
1627c478bd9Sstevel@tonic-gate 
1637c478bd9Sstevel@tonic-gate 	if (access(path, F_OK) != 0) {
1647c478bd9Sstevel@tonic-gate 		sp->sch_err = errno;
1657c478bd9Sstevel@tonic-gate 		return (sp);
1667c478bd9Sstevel@tonic-gate 	}
1677c478bd9Sstevel@tonic-gate 
1687c478bd9Sstevel@tonic-gate 	if ((sp->sch_dlp = dlopen(path, RTLD_LOCAL | RTLD_NOW)) == NULL) {
1697c478bd9Sstevel@tonic-gate 		sp->sch_err = ELIBACC;
1707c478bd9Sstevel@tonic-gate 		return (sp);
1717c478bd9Sstevel@tonic-gate 	}
1727c478bd9Sstevel@tonic-gate 
1737c478bd9Sstevel@tonic-gate 	if (fmd_scheme_rtld_init(sp) != 0) {
1747c478bd9Sstevel@tonic-gate 		sp->sch_err = errno;
1757c478bd9Sstevel@tonic-gate 		(void) dlclose(sp->sch_dlp);
1767c478bd9Sstevel@tonic-gate 		sp->sch_dlp = NULL;
1777c478bd9Sstevel@tonic-gate 	}
1787c478bd9Sstevel@tonic-gate 
1797c478bd9Sstevel@tonic-gate 	return (sp);
1807c478bd9Sstevel@tonic-gate }
1817c478bd9Sstevel@tonic-gate 
1827c478bd9Sstevel@tonic-gate char *
fmdump_nvl2str(nvlist_t * nvl)1837c478bd9Sstevel@tonic-gate fmdump_nvl2str(nvlist_t *nvl)
1847c478bd9Sstevel@tonic-gate {
1857c478bd9Sstevel@tonic-gate 	fmd_scheme_t *sp;
1867c478bd9Sstevel@tonic-gate 	char c, *name, *s = NULL;
1877c478bd9Sstevel@tonic-gate 	ssize_t len;
1887c478bd9Sstevel@tonic-gate 
1897c478bd9Sstevel@tonic-gate 	if (nvlist_lookup_string(nvl, FM_FMRI_SCHEME, &name) != 0) {
1907c478bd9Sstevel@tonic-gate 		fmdump_warn("fmri does not contain required '%s' nvpair\n",
1917c478bd9Sstevel@tonic-gate 		    FM_FMRI_SCHEME);
1927c478bd9Sstevel@tonic-gate 		return (NULL);
1937c478bd9Sstevel@tonic-gate 	}
1947c478bd9Sstevel@tonic-gate 
1957c478bd9Sstevel@tonic-gate 	if ((sp = fmd_scheme_lookup("/usr/lib/fm/fmd/schemes", name)) == NULL ||
1967c478bd9Sstevel@tonic-gate 	    sp->sch_dlp == NULL || sp->sch_err != 0) {
1977c478bd9Sstevel@tonic-gate 		const char *msg =
1987c478bd9Sstevel@tonic-gate 		    sp->sch_err == ELIBACC ? dlerror() : strerror(sp->sch_err);
1997c478bd9Sstevel@tonic-gate 
2007c478bd9Sstevel@tonic-gate 		fmdump_warn("cannot init '%s' scheme library to "
2017c478bd9Sstevel@tonic-gate 		    "format fmri: %s\n", name, msg ? msg : "unknown error");
2027c478bd9Sstevel@tonic-gate 
2037c478bd9Sstevel@tonic-gate 		return (NULL);
2047c478bd9Sstevel@tonic-gate 	}
2057c478bd9Sstevel@tonic-gate 
2067c478bd9Sstevel@tonic-gate 	if ((len = sp->sch_ops.sop_nvl2str(nvl, &c, sizeof (c))) == -1 ||
2077c478bd9Sstevel@tonic-gate 	    (s = malloc(len + 1)) == NULL ||
2087c478bd9Sstevel@tonic-gate 	    sp->sch_ops.sop_nvl2str(nvl, s, len + 1) == -1) {
2097c478bd9Sstevel@tonic-gate 		fmdump_warn("cannot format fmri using scheme '%s'", name);
2107c478bd9Sstevel@tonic-gate 		free(s);
2117c478bd9Sstevel@tonic-gate 		return (NULL);
2127c478bd9Sstevel@tonic-gate 	}
2137c478bd9Sstevel@tonic-gate 
2147c478bd9Sstevel@tonic-gate 	return (s);
2157c478bd9Sstevel@tonic-gate }
2167c478bd9Sstevel@tonic-gate 
2177c478bd9Sstevel@tonic-gate 
2187c478bd9Sstevel@tonic-gate void *
fmd_fmri_alloc(size_t size)2197c478bd9Sstevel@tonic-gate fmd_fmri_alloc(size_t size)
2207c478bd9Sstevel@tonic-gate {
2217c478bd9Sstevel@tonic-gate 	return (malloc(size));
2227c478bd9Sstevel@tonic-gate }
2237c478bd9Sstevel@tonic-gate 
2247c478bd9Sstevel@tonic-gate void *
fmd_fmri_zalloc(size_t size)2257c478bd9Sstevel@tonic-gate fmd_fmri_zalloc(size_t size)
2267c478bd9Sstevel@tonic-gate {
2277c478bd9Sstevel@tonic-gate 	void *data;
2287c478bd9Sstevel@tonic-gate 
2297c478bd9Sstevel@tonic-gate 	if ((data = malloc(size)) != NULL)
2307c478bd9Sstevel@tonic-gate 		bzero(data, size);
2317c478bd9Sstevel@tonic-gate 
2327c478bd9Sstevel@tonic-gate 	return (data);
2337c478bd9Sstevel@tonic-gate }
2347c478bd9Sstevel@tonic-gate 
2357c478bd9Sstevel@tonic-gate /*ARGSUSED*/
2367c478bd9Sstevel@tonic-gate void
fmd_fmri_free(void * data,size_t size)2377c478bd9Sstevel@tonic-gate fmd_fmri_free(void *data, size_t size)
2387c478bd9Sstevel@tonic-gate {
2397c478bd9Sstevel@tonic-gate 	free(data);
2407c478bd9Sstevel@tonic-gate }
2417c478bd9Sstevel@tonic-gate 
2427c478bd9Sstevel@tonic-gate int
fmd_fmri_error(int err)2437c478bd9Sstevel@tonic-gate fmd_fmri_error(int err)
2447c478bd9Sstevel@tonic-gate {
2457c478bd9Sstevel@tonic-gate 	errno = err;
2467c478bd9Sstevel@tonic-gate 	return (-1);
2477c478bd9Sstevel@tonic-gate }
2487c478bd9Sstevel@tonic-gate 
2497c478bd9Sstevel@tonic-gate char *
fmd_fmri_strescape(const char * s)2507c478bd9Sstevel@tonic-gate fmd_fmri_strescape(const char *s)
2517c478bd9Sstevel@tonic-gate {
2527c478bd9Sstevel@tonic-gate 	return (strdup(s));
2537c478bd9Sstevel@tonic-gate }
2547c478bd9Sstevel@tonic-gate 
2557c478bd9Sstevel@tonic-gate char *
fmd_fmri_strdup(const char * s)2567c478bd9Sstevel@tonic-gate fmd_fmri_strdup(const char *s)
2577c478bd9Sstevel@tonic-gate {
2587c478bd9Sstevel@tonic-gate 	return (strdup(s));
2597c478bd9Sstevel@tonic-gate }
2607c478bd9Sstevel@tonic-gate 
2617c478bd9Sstevel@tonic-gate void
fmd_fmri_strfree(char * s)2627c478bd9Sstevel@tonic-gate fmd_fmri_strfree(char *s)
2637c478bd9Sstevel@tonic-gate {
2647c478bd9Sstevel@tonic-gate 	free(s);
2657c478bd9Sstevel@tonic-gate }
2667c478bd9Sstevel@tonic-gate 
2677c478bd9Sstevel@tonic-gate const char *
fmd_fmri_get_rootdir(void)2687c478bd9Sstevel@tonic-gate fmd_fmri_get_rootdir(void)
2697c478bd9Sstevel@tonic-gate {
2707c478bd9Sstevel@tonic-gate 	return (g_root ? g_root : "");
2717c478bd9Sstevel@tonic-gate }
2727c478bd9Sstevel@tonic-gate 
2737c478bd9Sstevel@tonic-gate const char *
fmd_fmri_get_platform(void)2747c478bd9Sstevel@tonic-gate fmd_fmri_get_platform(void)
2757c478bd9Sstevel@tonic-gate {
2767c478bd9Sstevel@tonic-gate 	static char platform[MAXNAMELEN];
2777c478bd9Sstevel@tonic-gate 
2787c478bd9Sstevel@tonic-gate 	if (platform[0] == '\0')
2797c478bd9Sstevel@tonic-gate 		(void) sysinfo(SI_PLATFORM, platform, sizeof (platform));
2807c478bd9Sstevel@tonic-gate 
2817c478bd9Sstevel@tonic-gate 	return (platform);
2827c478bd9Sstevel@tonic-gate }
2837c478bd9Sstevel@tonic-gate 
2847c478bd9Sstevel@tonic-gate uint64_t
fmd_fmri_get_drgen(void)2857c478bd9Sstevel@tonic-gate fmd_fmri_get_drgen(void)
2867c478bd9Sstevel@tonic-gate {
2877c478bd9Sstevel@tonic-gate 	return (0);
2887c478bd9Sstevel@tonic-gate }
2897c478bd9Sstevel@tonic-gate 
2907c478bd9Sstevel@tonic-gate int
fmd_fmri_set_errno(int err)2917c478bd9Sstevel@tonic-gate fmd_fmri_set_errno(int err)
2927c478bd9Sstevel@tonic-gate {
2937c478bd9Sstevel@tonic-gate 	errno = err;
2947c478bd9Sstevel@tonic-gate 	return (-1);
2957c478bd9Sstevel@tonic-gate }
2967c478bd9Sstevel@tonic-gate 
2977c478bd9Sstevel@tonic-gate void
fmd_fmri_warn(const char * format,...)2987c478bd9Sstevel@tonic-gate fmd_fmri_warn(const char *format, ...)
2997c478bd9Sstevel@tonic-gate {
3007c478bd9Sstevel@tonic-gate 	va_list ap;
3017c478bd9Sstevel@tonic-gate 
3027c478bd9Sstevel@tonic-gate 	va_start(ap, format);
3037c478bd9Sstevel@tonic-gate 	fmdump_vwarn(format, ap);
3047c478bd9Sstevel@tonic-gate 	va_end(ap);
3057c478bd9Sstevel@tonic-gate }
3067aec1d6eScindi 
3077aec1d6eScindi struct topo_hdl *
fmd_fmri_topo_hold(int version)30824db4641Seschrock fmd_fmri_topo_hold(int version)
3097aec1d6eScindi {
3107aec1d6eScindi 	int err;
3117aec1d6eScindi 
31224db4641Seschrock 	if (version != TOPO_VERSION)
31324db4641Seschrock 		return (NULL);
31424db4641Seschrock 
3157aec1d6eScindi 	if (g_thp == NULL) {
3167aec1d6eScindi 		if ((g_thp = topo_open(TOPO_VERSION, "/", &err)) == NULL) {
3177aec1d6eScindi 			(void) fprintf(stderr, "topo_open failed: %s\n",
3187aec1d6eScindi 			    topo_strerror(err));
3197aec1d6eScindi 			exit(1);
3207aec1d6eScindi 		}
3217aec1d6eScindi 	}
3227aec1d6eScindi 
3237aec1d6eScindi 	return (g_thp);
3247aec1d6eScindi }
32524db4641Seschrock 
32624db4641Seschrock /*ARGSUSED*/
32724db4641Seschrock void
fmd_fmri_topo_rele(struct topo_hdl * thp)32824db4641Seschrock fmd_fmri_topo_rele(struct topo_hdl *thp)
32924db4641Seschrock {
33024db4641Seschrock 	/* nothing to do */
33124db4641Seschrock }
332