diff options
Diffstat (limited to 'usr/src/lib/libfakekernel/common/printf.c')
-rw-r--r-- | usr/src/lib/libfakekernel/common/printf.c | 154 |
1 files changed, 154 insertions, 0 deletions
diff --git a/usr/src/lib/libfakekernel/common/printf.c b/usr/src/lib/libfakekernel/common/printf.c new file mode 100644 index 0000000000..1bcef683d1 --- /dev/null +++ b/usr/src/lib/libfakekernel/common/printf.c @@ -0,0 +1,154 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012 by Delphix. All rights reserved. + * Copyright 2013 Nexenta Systems, Inc. All rights reserved. + */ + +#include <sys/param.h> +#include <sys/types.h> +#include <sys/varargs.h> +#include <sys/systm.h> +#include <sys/cmn_err.h> +#include <sys/log.h> + +#include <fakekernel.h> + +void abort(void) __NORETURN; + +char *volatile panicstr; +va_list panicargs; +char panicbuf[512]; + +volatile int aok; + +static const int +ce_flags[CE_IGNORE] = { SL_NOTE, SL_NOTE, SL_WARN, SL_FATAL }; +static const char +ce_prefix[CE_IGNORE][10] = { "", "NOTICE: ", "WARNING: ", "" }; +static const char +ce_suffix[CE_IGNORE][2] = { "", "\n", "\n", "" }; + + +/* + * This function is just a stub, exported NODIRECT so that + * comsumers like fksmbd can provide their own. + * (One that actually prints the messages.) + * + * It's used by fakekernel_cprintf() below. + * The flags are SL_... from strlog.h + */ +/* ARGSUSED */ +void +fakekernel_putlog(char *msg, size_t len, int flags) +{ +} + +/* + * fakekernel_cprintf() corresponds to os/printf.c:cprintf() + * This formats the message and calls fakekernel_putlog(). + * It's exported NODIRECT to allow replacment. + * The flags are SL_... from strlog.h + */ +void +fakekernel_cprintf(const char *fmt, va_list adx, int flags, + const char *prefix, const char *suffix) +{ + size_t bufsize = LOG_MSGSIZE; + char buf[LOG_MSGSIZE]; + char *bufp = buf; + char *msgp, *bufend; + size_t len; + + if (strchr("^!?", fmt[0]) != NULL) { + if (fmt[0] == '^') + flags |= SL_CONSONLY; + else if (fmt[0] == '!') + flags |= SL_LOGONLY; + fmt++; + } + + bufend = bufp + bufsize; + msgp = bufp; + msgp += snprintf(msgp, bufend - msgp, "[fake_kernel] "); + msgp += snprintf(msgp, bufend - msgp, prefix); + msgp += vsnprintf(msgp, bufend - msgp, fmt, adx); + msgp += snprintf(msgp, bufend - msgp, suffix); + len = msgp - bufp; + + fakekernel_putlog(bufp, len, flags); +} + +/* + * "User-level crash dump", if you will. + */ +void +vpanic(const char *fmt, va_list adx) +{ + va_list tmpargs; + + panicstr = (char *)fmt; + va_copy(panicargs, adx); + + va_copy(tmpargs, adx); + fakekernel_cprintf(fmt, tmpargs, SL_FATAL, "fatal: ", "\n"); + + /* Call libc`assfail() so that mdb ::status works */ + (void) vsnprintf(panicbuf, sizeof (panicbuf), fmt, adx); + assfail(panicbuf, "(panic)", 0); + + abort(); /* avoid "noreturn" warnings */ +} + +void +panic(const char *fmt, ...) +{ + va_list adx; + + va_start(adx, fmt); + vpanic(fmt, adx); + va_end(adx); +} + +void +vcmn_err(int ce, const char *fmt, va_list adx) +{ + + if (ce == CE_PANIC) + vpanic(fmt, adx); + if (ce >= CE_IGNORE) + return; + + fakekernel_cprintf(fmt, adx, ce_flags[ce] | SL_CONSOLE, + ce_prefix[ce], ce_suffix[ce]); +} + +/*PRINTFLIKE2*/ +void +cmn_err(int ce, const char *fmt, ...) +{ + va_list adx; + + va_start(adx, fmt); + vcmn_err(ce, fmt, adx); + va_end(adx); +} |