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
5da6c28aaSamw * Common Development and Distribution License (the "License").
6da6c28aaSamw * 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 /*
22*19397407SSherry Moore * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
237c478bd9Sstevel@tonic-gate * Use is subject to license terms.
247c478bd9Sstevel@tonic-gate */
257c478bd9Sstevel@tonic-gate
267c478bd9Sstevel@tonic-gate
277c478bd9Sstevel@tonic-gate /*
287c478bd9Sstevel@tonic-gate * System message redirection driver for Sun.
297c478bd9Sstevel@tonic-gate *
307c478bd9Sstevel@tonic-gate * Redirects system message output to the device designated as the underlying
317c478bd9Sstevel@tonic-gate * "hardware" console, as given by the value of sysmvp. The implementation
327c478bd9Sstevel@tonic-gate * assumes that sysmvp denotes a STREAMS device; the assumption is justified
337c478bd9Sstevel@tonic-gate * since consoles must be capable of effecting tty semantics.
347c478bd9Sstevel@tonic-gate */
357c478bd9Sstevel@tonic-gate
367c478bd9Sstevel@tonic-gate #include <sys/types.h>
377c478bd9Sstevel@tonic-gate #include <sys/kmem.h>
387c478bd9Sstevel@tonic-gate #include <sys/open.h>
397c478bd9Sstevel@tonic-gate #include <sys/param.h>
407c478bd9Sstevel@tonic-gate #include <sys/systm.h>
417c478bd9Sstevel@tonic-gate #include <sys/signal.h>
427c478bd9Sstevel@tonic-gate #include <sys/cred.h>
437c478bd9Sstevel@tonic-gate #include <sys/user.h>
447c478bd9Sstevel@tonic-gate #include <sys/proc.h>
457c478bd9Sstevel@tonic-gate #include <sys/vnode.h>
467c478bd9Sstevel@tonic-gate #include <sys/uio.h>
477c478bd9Sstevel@tonic-gate #include <sys/stat.h>
487c478bd9Sstevel@tonic-gate #include <sys/file.h>
49ad1660d0Smeem #include <sys/session.h>
507c478bd9Sstevel@tonic-gate #include <sys/stream.h>
517c478bd9Sstevel@tonic-gate #include <sys/strsubr.h>
527c478bd9Sstevel@tonic-gate #include <sys/poll.h>
537c478bd9Sstevel@tonic-gate #include <sys/debug.h>
547c478bd9Sstevel@tonic-gate #include <sys/sysmsg_impl.h>
557c478bd9Sstevel@tonic-gate #include <sys/conf.h>
567c478bd9Sstevel@tonic-gate #include <sys/termios.h>
577c478bd9Sstevel@tonic-gate #include <sys/errno.h>
587c478bd9Sstevel@tonic-gate #include <sys/modctl.h>
597c478bd9Sstevel@tonic-gate #include <sys/pathname.h>
607c478bd9Sstevel@tonic-gate #include <sys/ddi.h>
617c478bd9Sstevel@tonic-gate #include <sys/sunddi.h>
627c478bd9Sstevel@tonic-gate #include <sys/consdev.h>
637c478bd9Sstevel@tonic-gate #include <sys/policy.h>
647c478bd9Sstevel@tonic-gate
657c478bd9Sstevel@tonic-gate /*
667c478bd9Sstevel@tonic-gate * internal functions
677c478bd9Sstevel@tonic-gate */
687c478bd9Sstevel@tonic-gate static int sysmopen(dev_t *, int, int, cred_t *);
697c478bd9Sstevel@tonic-gate static int sysmclose(dev_t, int, int, cred_t *);
707c478bd9Sstevel@tonic-gate static int sysmread(dev_t, struct uio *, cred_t *);
717c478bd9Sstevel@tonic-gate static int sysmwrite(dev_t, struct uio *, cred_t *);
727c478bd9Sstevel@tonic-gate static int sysmioctl(dev_t, int, intptr_t, int, cred_t *, int *);
737c478bd9Sstevel@tonic-gate static int sysmpoll(dev_t, short, int, short *, struct pollhead **);
747c478bd9Sstevel@tonic-gate static int sysm_info(dev_info_t *, ddi_info_cmd_t, void *, void **);
757c478bd9Sstevel@tonic-gate static int sysm_attach(dev_info_t *, ddi_attach_cmd_t);
767c478bd9Sstevel@tonic-gate static int sysm_detach(dev_info_t *, ddi_detach_cmd_t);
777c478bd9Sstevel@tonic-gate static void bind_consadm_conf(char *);
787c478bd9Sstevel@tonic-gate static int checkarg(dev_t);
797c478bd9Sstevel@tonic-gate
807c478bd9Sstevel@tonic-gate static dev_info_t *sysm_dip; /* private copy of devinfo pointer */
817c478bd9Sstevel@tonic-gate
827c478bd9Sstevel@tonic-gate static struct cb_ops sysm_cb_ops = {
837c478bd9Sstevel@tonic-gate
847c478bd9Sstevel@tonic-gate sysmopen, /* open */
857c478bd9Sstevel@tonic-gate sysmclose, /* close */
867c478bd9Sstevel@tonic-gate nodev, /* strategy */
877c478bd9Sstevel@tonic-gate nodev, /* print */
887c478bd9Sstevel@tonic-gate nodev, /* dump */
897c478bd9Sstevel@tonic-gate sysmread, /* read */
907c478bd9Sstevel@tonic-gate sysmwrite, /* write */
917c478bd9Sstevel@tonic-gate sysmioctl, /* ioctl */
927c478bd9Sstevel@tonic-gate nodev, /* devmap */
937c478bd9Sstevel@tonic-gate nodev, /* mmap */
947c478bd9Sstevel@tonic-gate nodev, /* segmap */
957c478bd9Sstevel@tonic-gate sysmpoll, /* poll */
967c478bd9Sstevel@tonic-gate ddi_prop_op, /* cb_prop_op */
977c478bd9Sstevel@tonic-gate NULL, /* streamtab */
987c478bd9Sstevel@tonic-gate D_NEW | D_MP, /* Driver compatibility flag */
997c478bd9Sstevel@tonic-gate CB_REV, /* cb_rev */
1007c478bd9Sstevel@tonic-gate nodev, /* aread */
1017c478bd9Sstevel@tonic-gate nodev /* awrite */
1027c478bd9Sstevel@tonic-gate };
1037c478bd9Sstevel@tonic-gate
1047c478bd9Sstevel@tonic-gate static struct dev_ops sysm_ops = {
1057c478bd9Sstevel@tonic-gate
1067c478bd9Sstevel@tonic-gate DEVO_REV, /* devo_rev, */
1077c478bd9Sstevel@tonic-gate 0, /* refcnt */
1087c478bd9Sstevel@tonic-gate sysm_info, /* info */
1097c478bd9Sstevel@tonic-gate nulldev, /* identify */
1107c478bd9Sstevel@tonic-gate nulldev, /* probe */
1117c478bd9Sstevel@tonic-gate sysm_attach, /* attach */
1127c478bd9Sstevel@tonic-gate sysm_detach, /* detach */
1137c478bd9Sstevel@tonic-gate nodev, /* reset */
1147c478bd9Sstevel@tonic-gate &sysm_cb_ops, /* driver operations */
1157c478bd9Sstevel@tonic-gate (struct bus_ops *)0, /* bus operations */
116*19397407SSherry Moore nulldev, /* power */
117*19397407SSherry Moore ddi_quiesce_not_needed, /* quiesce */
1187c478bd9Sstevel@tonic-gate
1197c478bd9Sstevel@tonic-gate };
1207c478bd9Sstevel@tonic-gate
1217c478bd9Sstevel@tonic-gate /*
1227c478bd9Sstevel@tonic-gate * Global variables associated with the console device:
1237c478bd9Sstevel@tonic-gate */
1247c478bd9Sstevel@tonic-gate
1257c478bd9Sstevel@tonic-gate #define SYS_SYSMIN 0 /* sysmsg minor number */
1267c478bd9Sstevel@tonic-gate #define SYS_MSGMIN 1 /* msglog minor number */
1277c478bd9Sstevel@tonic-gate #define SYSPATHLEN 255 /* length of device path */
1287c478bd9Sstevel@tonic-gate
1297c478bd9Sstevel@tonic-gate /*
1307c478bd9Sstevel@tonic-gate * Private driver state:
1317c478bd9Sstevel@tonic-gate */
1327c478bd9Sstevel@tonic-gate
1337c478bd9Sstevel@tonic-gate #define MAXDEVS 5
1347c478bd9Sstevel@tonic-gate
1357c478bd9Sstevel@tonic-gate typedef struct {
1367c478bd9Sstevel@tonic-gate dev_t dca_devt;
1377c478bd9Sstevel@tonic-gate int dca_flags;
1387c478bd9Sstevel@tonic-gate vnode_t *dca_vp;
1397c478bd9Sstevel@tonic-gate krwlock_t dca_lock;
1407c478bd9Sstevel@tonic-gate char dca_name[SYSPATHLEN];
1417c478bd9Sstevel@tonic-gate } devicecache_t;
1427c478bd9Sstevel@tonic-gate
1437c478bd9Sstevel@tonic-gate /* list of dyn. + persist. config'ed dev's */
1447c478bd9Sstevel@tonic-gate static devicecache_t sysmcache[MAXDEVS];
1457c478bd9Sstevel@tonic-gate static kmutex_t dcvp_mutex;
1467c478bd9Sstevel@tonic-gate static vnode_t *dcvp = NULL;
14783d132f8Sfl147353 static boolean_t sysmsg_opened;
14883d132f8Sfl147353 static boolean_t msglog_opened;
1497c478bd9Sstevel@tonic-gate
1507c478bd9Sstevel@tonic-gate /* flags for device cache */
1517c478bd9Sstevel@tonic-gate #define SYSM_DISABLED 0x0
1527c478bd9Sstevel@tonic-gate #define SYSM_ENABLED 0x1
1537c478bd9Sstevel@tonic-gate
1547c478bd9Sstevel@tonic-gate /*
1557c478bd9Sstevel@tonic-gate * Module linkage information for the kernel.
1567c478bd9Sstevel@tonic-gate */
1577c478bd9Sstevel@tonic-gate
1587c478bd9Sstevel@tonic-gate static struct modldrv modldrv = {
1597c478bd9Sstevel@tonic-gate &mod_driverops, /* Type of module. This one is a pseudo driver */
160*19397407SSherry Moore "System message redirection (fanout) driver",
1617c478bd9Sstevel@tonic-gate &sysm_ops, /* driver ops */
1627c478bd9Sstevel@tonic-gate };
1637c478bd9Sstevel@tonic-gate
1647c478bd9Sstevel@tonic-gate static struct modlinkage modlinkage = {
1657c478bd9Sstevel@tonic-gate MODREV_1,
1667c478bd9Sstevel@tonic-gate &modldrv,
1677c478bd9Sstevel@tonic-gate NULL
1687c478bd9Sstevel@tonic-gate };
1697c478bd9Sstevel@tonic-gate
1707c478bd9Sstevel@tonic-gate int
_init(void)1717c478bd9Sstevel@tonic-gate _init(void)
1727c478bd9Sstevel@tonic-gate {
1737c478bd9Sstevel@tonic-gate return (mod_install(&modlinkage));
1747c478bd9Sstevel@tonic-gate }
1757c478bd9Sstevel@tonic-gate
1767c478bd9Sstevel@tonic-gate int
_fini(void)1777c478bd9Sstevel@tonic-gate _fini(void)
1787c478bd9Sstevel@tonic-gate {
1797c478bd9Sstevel@tonic-gate return (mod_remove(&modlinkage));
1807c478bd9Sstevel@tonic-gate }
1817c478bd9Sstevel@tonic-gate
1827c478bd9Sstevel@tonic-gate int
_info(struct modinfo * modinfop)1837c478bd9Sstevel@tonic-gate _info(struct modinfo *modinfop)
1847c478bd9Sstevel@tonic-gate {
1857c478bd9Sstevel@tonic-gate return (mod_info(&modlinkage, modinfop));
1867c478bd9Sstevel@tonic-gate }
1877c478bd9Sstevel@tonic-gate
1887c478bd9Sstevel@tonic-gate /*
1897c478bd9Sstevel@tonic-gate * DDI glue routines
1907c478bd9Sstevel@tonic-gate */
1917c478bd9Sstevel@tonic-gate static int
sysm_attach(dev_info_t * devi,ddi_attach_cmd_t cmd)1927c478bd9Sstevel@tonic-gate sysm_attach(dev_info_t *devi, ddi_attach_cmd_t cmd)
1937c478bd9Sstevel@tonic-gate {
1947c478bd9Sstevel@tonic-gate int i;
1957c478bd9Sstevel@tonic-gate
1967c478bd9Sstevel@tonic-gate switch (cmd) {
1977c478bd9Sstevel@tonic-gate case DDI_ATTACH:
1987c478bd9Sstevel@tonic-gate ASSERT(sysm_dip == NULL);
1997c478bd9Sstevel@tonic-gate
2007c478bd9Sstevel@tonic-gate if (ddi_create_minor_node(devi, "sysmsg", S_IFCHR,
2017c478bd9Sstevel@tonic-gate SYS_SYSMIN, DDI_PSEUDO, NULL) == DDI_FAILURE ||
2027c478bd9Sstevel@tonic-gate ddi_create_minor_node(devi, "msglog", S_IFCHR,
2037c478bd9Sstevel@tonic-gate SYS_MSGMIN, DDI_PSEUDO, NULL) == DDI_FAILURE) {
2047c478bd9Sstevel@tonic-gate ddi_remove_minor_node(devi, NULL);
2057c478bd9Sstevel@tonic-gate return (DDI_FAILURE);
2067c478bd9Sstevel@tonic-gate }
2077c478bd9Sstevel@tonic-gate
2087c478bd9Sstevel@tonic-gate for (i = 0; i < MAXDEVS; i++) {
2097c478bd9Sstevel@tonic-gate rw_init(&sysmcache[i].dca_lock, NULL, RW_DRIVER, NULL);
2107c478bd9Sstevel@tonic-gate }
2117c478bd9Sstevel@tonic-gate
2127c478bd9Sstevel@tonic-gate sysm_dip = devi;
2137c478bd9Sstevel@tonic-gate return (DDI_SUCCESS);
2147c478bd9Sstevel@tonic-gate case DDI_SUSPEND:
2157c478bd9Sstevel@tonic-gate case DDI_PM_SUSPEND:
2167c478bd9Sstevel@tonic-gate return (DDI_SUCCESS);
2177c478bd9Sstevel@tonic-gate default:
2187c478bd9Sstevel@tonic-gate return (DDI_FAILURE);
2197c478bd9Sstevel@tonic-gate }
2207c478bd9Sstevel@tonic-gate }
2217c478bd9Sstevel@tonic-gate
2227c478bd9Sstevel@tonic-gate static int
sysm_detach(dev_info_t * devi,ddi_detach_cmd_t cmd)2237c478bd9Sstevel@tonic-gate sysm_detach(dev_info_t *devi, ddi_detach_cmd_t cmd)
2247c478bd9Sstevel@tonic-gate {
2257c478bd9Sstevel@tonic-gate int i;
2267c478bd9Sstevel@tonic-gate
2277c478bd9Sstevel@tonic-gate switch (cmd) {
2287c478bd9Sstevel@tonic-gate case DDI_DETACH:
2297c478bd9Sstevel@tonic-gate ASSERT(sysm_dip == devi);
2307c478bd9Sstevel@tonic-gate
23183d132f8Sfl147353 for (i = 0; i < MAXDEVS; i++)
2327c478bd9Sstevel@tonic-gate rw_destroy(&sysmcache[i].dca_lock);
2337c478bd9Sstevel@tonic-gate
2347c478bd9Sstevel@tonic-gate ddi_remove_minor_node(devi, NULL);
2357c478bd9Sstevel@tonic-gate sysm_dip = NULL;
2367c478bd9Sstevel@tonic-gate return (DDI_SUCCESS);
2377c478bd9Sstevel@tonic-gate
2387c478bd9Sstevel@tonic-gate case DDI_SUSPEND:
2397c478bd9Sstevel@tonic-gate case DDI_PM_SUSPEND:
2407c478bd9Sstevel@tonic-gate return (DDI_SUCCESS);
2417c478bd9Sstevel@tonic-gate default:
2427c478bd9Sstevel@tonic-gate return (DDI_FAILURE);
2437c478bd9Sstevel@tonic-gate }
2447c478bd9Sstevel@tonic-gate
2457c478bd9Sstevel@tonic-gate }
2467c478bd9Sstevel@tonic-gate
2477c478bd9Sstevel@tonic-gate /* ARGSUSED */
2487c478bd9Sstevel@tonic-gate static int
sysm_info(dev_info_t * dip,ddi_info_cmd_t infocmd,void * arg,void ** result)2497c478bd9Sstevel@tonic-gate sysm_info(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, void **result)
2507c478bd9Sstevel@tonic-gate {
2517c478bd9Sstevel@tonic-gate int rval = DDI_FAILURE;
2527c478bd9Sstevel@tonic-gate minor_t instance;
2537c478bd9Sstevel@tonic-gate
2547c478bd9Sstevel@tonic-gate instance = getminor((dev_t)arg);
2557c478bd9Sstevel@tonic-gate
2567c478bd9Sstevel@tonic-gate switch (infocmd) {
2577c478bd9Sstevel@tonic-gate case DDI_INFO_DEVT2DEVINFO:
2587c478bd9Sstevel@tonic-gate if (sysm_dip != NULL &&
2597c478bd9Sstevel@tonic-gate (instance == SYS_SYSMIN || instance == SYS_MSGMIN)) {
2607c478bd9Sstevel@tonic-gate *result = sysm_dip;
2617c478bd9Sstevel@tonic-gate rval = DDI_SUCCESS;
2627c478bd9Sstevel@tonic-gate }
2637c478bd9Sstevel@tonic-gate break;
2647c478bd9Sstevel@tonic-gate
2657c478bd9Sstevel@tonic-gate case DDI_INFO_DEVT2INSTANCE:
2667c478bd9Sstevel@tonic-gate if (instance == SYS_SYSMIN || instance == SYS_MSGMIN) {
2677c478bd9Sstevel@tonic-gate *result = NULL;
2687c478bd9Sstevel@tonic-gate rval = DDI_SUCCESS;
2697c478bd9Sstevel@tonic-gate }
2707c478bd9Sstevel@tonic-gate break;
2717c478bd9Sstevel@tonic-gate
2727c478bd9Sstevel@tonic-gate default:
2737c478bd9Sstevel@tonic-gate break;
2747c478bd9Sstevel@tonic-gate }
2757c478bd9Sstevel@tonic-gate
2767c478bd9Sstevel@tonic-gate return (rval);
2777c478bd9Sstevel@tonic-gate }
2787c478bd9Sstevel@tonic-gate
2797c478bd9Sstevel@tonic-gate /*
2807c478bd9Sstevel@tonic-gate * Parse the contents of the buffer, and bind the named
2817c478bd9Sstevel@tonic-gate * devices as auxiliary consoles using our own ioctl routine.
2827c478bd9Sstevel@tonic-gate *
2837c478bd9Sstevel@tonic-gate * Comments begin with '#' and are terminated only by a newline
2847c478bd9Sstevel@tonic-gate * Device names begin with a '/', and are terminated by a newline,
2857c478bd9Sstevel@tonic-gate * space, '#' or tab.
2867c478bd9Sstevel@tonic-gate */
2877c478bd9Sstevel@tonic-gate static void
parse_buffer(char * buf,ssize_t fsize)2887c478bd9Sstevel@tonic-gate parse_buffer(char *buf, ssize_t fsize)
2897c478bd9Sstevel@tonic-gate {
2907c478bd9Sstevel@tonic-gate char *ebuf = buf + fsize;
2917c478bd9Sstevel@tonic-gate char *devname = NULL;
2927c478bd9Sstevel@tonic-gate int eatcomments = 0;
2937c478bd9Sstevel@tonic-gate
2947c478bd9Sstevel@tonic-gate while (buf < ebuf) {
2957c478bd9Sstevel@tonic-gate if (eatcomments) {
2967c478bd9Sstevel@tonic-gate if (*buf++ == '\n')
2977c478bd9Sstevel@tonic-gate eatcomments = 0;
2987c478bd9Sstevel@tonic-gate continue;
2997c478bd9Sstevel@tonic-gate }
3007c478bd9Sstevel@tonic-gate switch (*buf) {
3017c478bd9Sstevel@tonic-gate case '/':
3027c478bd9Sstevel@tonic-gate if (devname == NULL)
3037c478bd9Sstevel@tonic-gate devname = buf;
3047c478bd9Sstevel@tonic-gate break;
3057c478bd9Sstevel@tonic-gate case '#':
3067c478bd9Sstevel@tonic-gate eatcomments = 1;
3077c478bd9Sstevel@tonic-gate /*FALLTHROUGH*/
3087c478bd9Sstevel@tonic-gate case ' ':
3097c478bd9Sstevel@tonic-gate case '\t':
3107c478bd9Sstevel@tonic-gate case '\n':
3117c478bd9Sstevel@tonic-gate *buf = '\0';
3127c478bd9Sstevel@tonic-gate if (devname == NULL)
3137c478bd9Sstevel@tonic-gate break;
3147c478bd9Sstevel@tonic-gate (void) sysmioctl(NODEV, CIOCSETCONSOLE,
3157c478bd9Sstevel@tonic-gate (intptr_t)devname, FNATIVE|FKIOCTL|FREAD|FWRITE,
3167c478bd9Sstevel@tonic-gate kcred, NULL);
3177c478bd9Sstevel@tonic-gate devname = NULL;
3187c478bd9Sstevel@tonic-gate break;
3197c478bd9Sstevel@tonic-gate default:
3207c478bd9Sstevel@tonic-gate break;
3217c478bd9Sstevel@tonic-gate }
3227c478bd9Sstevel@tonic-gate buf++;
3237c478bd9Sstevel@tonic-gate }
3247c478bd9Sstevel@tonic-gate }
3257c478bd9Sstevel@tonic-gate
3267c478bd9Sstevel@tonic-gate #define CNSADM_BYTES_MAX 2000 /* XXX nasty fixed size */
3277c478bd9Sstevel@tonic-gate
3287c478bd9Sstevel@tonic-gate static void
bind_consadm_conf(char * path)3297c478bd9Sstevel@tonic-gate bind_consadm_conf(char *path)
3307c478bd9Sstevel@tonic-gate {
3317c478bd9Sstevel@tonic-gate struct vattr vattr;
3327c478bd9Sstevel@tonic-gate vnode_t *vp;
3337c478bd9Sstevel@tonic-gate void *buf;
3347c478bd9Sstevel@tonic-gate size_t size;
3357c478bd9Sstevel@tonic-gate ssize_t resid;
3367c478bd9Sstevel@tonic-gate int err = 0;
3377c478bd9Sstevel@tonic-gate
3387c478bd9Sstevel@tonic-gate if (vn_open(path, UIO_SYSSPACE, FREAD, 0, &vp, 0, 0) != 0)
3397c478bd9Sstevel@tonic-gate return;
3407c478bd9Sstevel@tonic-gate vattr.va_mask = AT_SIZE;
341da6c28aaSamw if ((err = VOP_GETATTR(vp, &vattr, 0, kcred, NULL)) != 0) {
3427c478bd9Sstevel@tonic-gate cmn_err(CE_WARN, "sysmsg: getattr: '%s': error %d",
3437c478bd9Sstevel@tonic-gate path, err);
3447c478bd9Sstevel@tonic-gate goto closevp;
3457c478bd9Sstevel@tonic-gate }
3467c478bd9Sstevel@tonic-gate
3477c478bd9Sstevel@tonic-gate size = vattr.va_size > CNSADM_BYTES_MAX ?
3487c478bd9Sstevel@tonic-gate CNSADM_BYTES_MAX : (ssize_t)vattr.va_size;
3497c478bd9Sstevel@tonic-gate buf = kmem_alloc(size, KM_SLEEP);
3507c478bd9Sstevel@tonic-gate
3517c478bd9Sstevel@tonic-gate if ((err = vn_rdwr(UIO_READ, vp, buf, size, (offset_t)0,
3527c478bd9Sstevel@tonic-gate UIO_SYSSPACE, 0, (rlim64_t)0, kcred, &resid)) != 0)
3537c478bd9Sstevel@tonic-gate cmn_err(CE_WARN, "sysmsg: vn_rdwr: '%s': error %d",
3547c478bd9Sstevel@tonic-gate path, err);
3557c478bd9Sstevel@tonic-gate else
3567c478bd9Sstevel@tonic-gate parse_buffer(buf, size - resid);
3577c478bd9Sstevel@tonic-gate
3587c478bd9Sstevel@tonic-gate kmem_free(buf, size);
3597c478bd9Sstevel@tonic-gate closevp:
360da6c28aaSamw (void) VOP_CLOSE(vp, FREAD, 1, (offset_t)0, kcred, NULL);
3617c478bd9Sstevel@tonic-gate VN_RELE(vp);
3627c478bd9Sstevel@tonic-gate }
3637c478bd9Sstevel@tonic-gate
3647c478bd9Sstevel@tonic-gate /* ARGSUSED */
3657c478bd9Sstevel@tonic-gate static int
sysmopen(dev_t * dev,int flag,int state,cred_t * cred)3667c478bd9Sstevel@tonic-gate sysmopen(dev_t *dev, int flag, int state, cred_t *cred)
3677c478bd9Sstevel@tonic-gate {
3687c478bd9Sstevel@tonic-gate int i;
3697c478bd9Sstevel@tonic-gate vnode_t *vp;
3707c478bd9Sstevel@tonic-gate minor_t instance;
37183d132f8Sfl147353 static boolean_t initialized;
3727c478bd9Sstevel@tonic-gate
3737c478bd9Sstevel@tonic-gate instance = getminor(*dev);
3747c478bd9Sstevel@tonic-gate
3757c478bd9Sstevel@tonic-gate if (state != OTYP_CHR || (instance != 0 && instance != 1))
3767c478bd9Sstevel@tonic-gate return (ENXIO);
3777c478bd9Sstevel@tonic-gate
3787c478bd9Sstevel@tonic-gate mutex_enter(&dcvp_mutex);
3797c478bd9Sstevel@tonic-gate if ((dcvp == NULL) && (vn_open("/dev/console",
3807c478bd9Sstevel@tonic-gate UIO_SYSSPACE, FWRITE, 0, &dcvp, 0, 0) != 0)) {
3817c478bd9Sstevel@tonic-gate mutex_exit(&dcvp_mutex);
3827c478bd9Sstevel@tonic-gate return (ENXIO);
3837c478bd9Sstevel@tonic-gate }
38483d132f8Sfl147353
38583d132f8Sfl147353 if (instance == SYS_SYSMIN)
38683d132f8Sfl147353 sysmsg_opened = B_TRUE;
38783d132f8Sfl147353 else
38883d132f8Sfl147353 msglog_opened = B_TRUE;
38983d132f8Sfl147353
39083d132f8Sfl147353 if (!initialized) {
39183d132f8Sfl147353 bind_consadm_conf("/etc/consadm.conf");
39283d132f8Sfl147353 initialized = B_TRUE;
39383d132f8Sfl147353 }
3947c478bd9Sstevel@tonic-gate mutex_exit(&dcvp_mutex);
3957c478bd9Sstevel@tonic-gate
3967c478bd9Sstevel@tonic-gate for (i = 0; i < MAXDEVS; i++) {
3977c478bd9Sstevel@tonic-gate rw_enter(&sysmcache[i].dca_lock, RW_WRITER);
3987c478bd9Sstevel@tonic-gate if ((sysmcache[i].dca_flags & SYSM_ENABLED) &&
3997c478bd9Sstevel@tonic-gate sysmcache[i].dca_vp == NULL) {
4007c478bd9Sstevel@tonic-gate /*
4017c478bd9Sstevel@tonic-gate * 4196476 - FTRUNC was causing E10K to return EINVAL
4027c478bd9Sstevel@tonic-gate * on open
4037c478bd9Sstevel@tonic-gate */
4047c478bd9Sstevel@tonic-gate flag = flag & ~FTRUNC;
4057c478bd9Sstevel@tonic-gate /*
4067c478bd9Sstevel@tonic-gate * Open failures on the auxiliary consoles are
4077c478bd9Sstevel@tonic-gate * not returned because we don't care if some
4087c478bd9Sstevel@tonic-gate * subset get an error. We know the default console
4097c478bd9Sstevel@tonic-gate * is okay, and preserve the semantics of the
4107c478bd9Sstevel@tonic-gate * open for the default console.
4117c478bd9Sstevel@tonic-gate * Set NONBLOCK|NDELAY in case there's no carrier.
4127c478bd9Sstevel@tonic-gate */
4137c478bd9Sstevel@tonic-gate if (vn_open(sysmcache[i].dca_name, UIO_SYSSPACE,
4147c478bd9Sstevel@tonic-gate flag | FNONBLOCK | FNDELAY, 0, &vp, 0, 0) == 0)
4157c478bd9Sstevel@tonic-gate sysmcache[i].dca_vp = vp;
4167c478bd9Sstevel@tonic-gate }
4177c478bd9Sstevel@tonic-gate rw_exit(&sysmcache[i].dca_lock);
4187c478bd9Sstevel@tonic-gate }
4197c478bd9Sstevel@tonic-gate
4207c478bd9Sstevel@tonic-gate return (0);
4217c478bd9Sstevel@tonic-gate }
4227c478bd9Sstevel@tonic-gate
4237c478bd9Sstevel@tonic-gate /* ARGSUSED */
4247c478bd9Sstevel@tonic-gate static int
sysmclose(dev_t dev,int flag,int state,cred_t * cred)4257c478bd9Sstevel@tonic-gate sysmclose(dev_t dev, int flag, int state, cred_t *cred)
4267c478bd9Sstevel@tonic-gate {
4277c478bd9Sstevel@tonic-gate int i;
42883d132f8Sfl147353 minor_t instance;
42983d132f8Sfl147353
43083d132f8Sfl147353 ASSERT(dcvp != NULL);
4317c478bd9Sstevel@tonic-gate
4327c478bd9Sstevel@tonic-gate if (state != OTYP_CHR)
4337c478bd9Sstevel@tonic-gate return (ENXIO);
4347c478bd9Sstevel@tonic-gate
43583d132f8Sfl147353 instance = getminor(dev);
43683d132f8Sfl147353
43783d132f8Sfl147353 mutex_enter(&dcvp_mutex);
43883d132f8Sfl147353 if (instance == SYS_SYSMIN)
43983d132f8Sfl147353 sysmsg_opened = B_FALSE;
44083d132f8Sfl147353 else
44183d132f8Sfl147353 msglog_opened = B_FALSE;
44283d132f8Sfl147353
44383d132f8Sfl147353 if (sysmsg_opened || msglog_opened) {
44483d132f8Sfl147353 mutex_exit(&dcvp_mutex);
44583d132f8Sfl147353 return (0);
44683d132f8Sfl147353 }
44783d132f8Sfl147353
448da6c28aaSamw (void) VOP_CLOSE(dcvp, FWRITE, 1, (offset_t)0, kcred, NULL);
44983d132f8Sfl147353 VN_RELE(dcvp);
45083d132f8Sfl147353 dcvp = NULL;
45183d132f8Sfl147353 mutex_exit(&dcvp_mutex);
45283d132f8Sfl147353
4537c478bd9Sstevel@tonic-gate /*
4547c478bd9Sstevel@tonic-gate * Close the auxiliary consoles, we're not concerned with
4557c478bd9Sstevel@tonic-gate * passing up the errors.
4567c478bd9Sstevel@tonic-gate */
4577c478bd9Sstevel@tonic-gate for (i = 0; i < MAXDEVS; i++) {
4587c478bd9Sstevel@tonic-gate rw_enter(&sysmcache[i].dca_lock, RW_WRITER);
4597c478bd9Sstevel@tonic-gate if (sysmcache[i].dca_vp != NULL) {
4607c478bd9Sstevel@tonic-gate (void) VOP_CLOSE(sysmcache[i].dca_vp, flag,
461da6c28aaSamw 1, (offset_t)0, cred, NULL);
4627c478bd9Sstevel@tonic-gate VN_RELE(sysmcache[i].dca_vp);
4637c478bd9Sstevel@tonic-gate sysmcache[i].dca_vp = NULL;
4647c478bd9Sstevel@tonic-gate }
4657c478bd9Sstevel@tonic-gate rw_exit(&sysmcache[i].dca_lock);
4667c478bd9Sstevel@tonic-gate }
4677c478bd9Sstevel@tonic-gate
4687c478bd9Sstevel@tonic-gate return (0);
4697c478bd9Sstevel@tonic-gate }
4707c478bd9Sstevel@tonic-gate
4717c478bd9Sstevel@tonic-gate /* Reads occur only on the default console */
4727c478bd9Sstevel@tonic-gate
4737c478bd9Sstevel@tonic-gate /* ARGSUSED */
4747c478bd9Sstevel@tonic-gate static int
sysmread(dev_t dev,struct uio * uio,cred_t * cred)4757c478bd9Sstevel@tonic-gate sysmread(dev_t dev, struct uio *uio, cred_t *cred)
4767c478bd9Sstevel@tonic-gate {
4777c478bd9Sstevel@tonic-gate ASSERT(dcvp != NULL);
4787c478bd9Sstevel@tonic-gate return (VOP_READ(dcvp, uio, 0, cred, NULL));
4797c478bd9Sstevel@tonic-gate }
4807c478bd9Sstevel@tonic-gate
4817c478bd9Sstevel@tonic-gate /* ARGSUSED */
4827c478bd9Sstevel@tonic-gate static int
sysmwrite(dev_t dev,struct uio * uio,cred_t * cred)4837c478bd9Sstevel@tonic-gate sysmwrite(dev_t dev, struct uio *uio, cred_t *cred)
4847c478bd9Sstevel@tonic-gate {
4857c478bd9Sstevel@tonic-gate int i = 0;
4867c478bd9Sstevel@tonic-gate iovec_t uio_iov;
4877c478bd9Sstevel@tonic-gate struct uio tuio;
4887c478bd9Sstevel@tonic-gate
4897c478bd9Sstevel@tonic-gate ASSERT(dcvp != NULL);
4907c478bd9Sstevel@tonic-gate ASSERT(uio != NULL);
4917c478bd9Sstevel@tonic-gate
4927c478bd9Sstevel@tonic-gate for (i = 0; i < MAXDEVS; i++) {
4937c478bd9Sstevel@tonic-gate rw_enter(&sysmcache[i].dca_lock, RW_READER);
4947c478bd9Sstevel@tonic-gate if (sysmcache[i].dca_vp != NULL &&
4957c478bd9Sstevel@tonic-gate (sysmcache[i].dca_flags & SYSM_ENABLED)) {
4967c478bd9Sstevel@tonic-gate tuio = *uio;
4977c478bd9Sstevel@tonic-gate uio_iov = *(uio->uio_iov);
4987c478bd9Sstevel@tonic-gate tuio.uio_iov = &uio_iov;
4997c478bd9Sstevel@tonic-gate (void) VOP_WRITE(sysmcache[i].dca_vp, &tuio, 0, cred,
5007c478bd9Sstevel@tonic-gate NULL);
5017c478bd9Sstevel@tonic-gate }
5027c478bd9Sstevel@tonic-gate rw_exit(&sysmcache[i].dca_lock);
5037c478bd9Sstevel@tonic-gate }
5047c478bd9Sstevel@tonic-gate return (VOP_WRITE(dcvp, uio, 0, cred, NULL));
5057c478bd9Sstevel@tonic-gate }
5067c478bd9Sstevel@tonic-gate
5077c478bd9Sstevel@tonic-gate /* ARGSUSED */
5087c478bd9Sstevel@tonic-gate static int
sysmioctl(dev_t dev,int cmd,intptr_t arg,int flag,cred_t * cred,int * rvalp)5097c478bd9Sstevel@tonic-gate sysmioctl(dev_t dev, int cmd, intptr_t arg, int flag, cred_t *cred, int *rvalp)
5107c478bd9Sstevel@tonic-gate {
5117c478bd9Sstevel@tonic-gate int rval = 0;
5127c478bd9Sstevel@tonic-gate int error = 0;
5137c478bd9Sstevel@tonic-gate size_t size = 0;
5147c478bd9Sstevel@tonic-gate int i;
5157c478bd9Sstevel@tonic-gate char *infop;
5167c478bd9Sstevel@tonic-gate char found = 0;
5177c478bd9Sstevel@tonic-gate dev_t newdevt = (dev_t)NODEV; /* because 0 == /dev/console */
5187c478bd9Sstevel@tonic-gate vnode_t *vp;
5197c478bd9Sstevel@tonic-gate
5207c478bd9Sstevel@tonic-gate switch (cmd) {
5217c478bd9Sstevel@tonic-gate case CIOCGETCONSOLE:
5227c478bd9Sstevel@tonic-gate /* Sum over the number of enabled devices */
5237c478bd9Sstevel@tonic-gate for (i = 0; i < MAXDEVS; i++) {
5247c478bd9Sstevel@tonic-gate if (sysmcache[i].dca_flags & SYSM_ENABLED)
5257c478bd9Sstevel@tonic-gate /* list is space separated, followed by NULL */
5267c478bd9Sstevel@tonic-gate size += strlen(sysmcache[i].dca_name) + 1;
5277c478bd9Sstevel@tonic-gate }
5287c478bd9Sstevel@tonic-gate if (size == 0)
5297c478bd9Sstevel@tonic-gate return (0);
5307c478bd9Sstevel@tonic-gate break;
5317c478bd9Sstevel@tonic-gate case CIOCSETCONSOLE:
5327c478bd9Sstevel@tonic-gate case CIOCRMCONSOLE:
5337c478bd9Sstevel@tonic-gate size = sizeof (sysmcache[0].dca_name);
5347c478bd9Sstevel@tonic-gate break;
5357c478bd9Sstevel@tonic-gate case CIOCTTYCONSOLE:
5367c478bd9Sstevel@tonic-gate {
5377c478bd9Sstevel@tonic-gate dev_t d;
5387c478bd9Sstevel@tonic-gate dev32_t d32;
5397c478bd9Sstevel@tonic-gate extern dev_t rwsconsdev, rconsdev, uconsdev;
5407c478bd9Sstevel@tonic-gate proc_t *p;
5417c478bd9Sstevel@tonic-gate
5427c478bd9Sstevel@tonic-gate if (drv_getparm(UPROCP, &p) != 0)
5437c478bd9Sstevel@tonic-gate return (ENODEV);
5447c478bd9Sstevel@tonic-gate else
5457c478bd9Sstevel@tonic-gate d = cttydev(p);
5467c478bd9Sstevel@tonic-gate /*
5477c478bd9Sstevel@tonic-gate * If the controlling terminal is the real
5487c478bd9Sstevel@tonic-gate * or workstation console device, map to what the
5497c478bd9Sstevel@tonic-gate * user thinks is the console device.
5507c478bd9Sstevel@tonic-gate */
5517c478bd9Sstevel@tonic-gate if (d == rwsconsdev || d == rconsdev)
5527c478bd9Sstevel@tonic-gate d = uconsdev;
5537c478bd9Sstevel@tonic-gate if ((flag & FMODELS) != FNATIVE) {
5547c478bd9Sstevel@tonic-gate if (!cmpldev(&d32, d))
5557c478bd9Sstevel@tonic-gate return (EOVERFLOW);
5567c478bd9Sstevel@tonic-gate if (ddi_copyout(&d32, (caddr_t)arg, sizeof (d32),
5577c478bd9Sstevel@tonic-gate flag))
5587c478bd9Sstevel@tonic-gate return (EFAULT);
5597c478bd9Sstevel@tonic-gate } else {
5607c478bd9Sstevel@tonic-gate if (ddi_copyout(&d, (caddr_t)arg, sizeof (d), flag))
5617c478bd9Sstevel@tonic-gate return (EFAULT);
5627c478bd9Sstevel@tonic-gate }
5637c478bd9Sstevel@tonic-gate return (0);
5647c478bd9Sstevel@tonic-gate }
5657c478bd9Sstevel@tonic-gate default:
5667c478bd9Sstevel@tonic-gate /* everything else is sent to the console device */
567da6c28aaSamw return (VOP_IOCTL(dcvp, cmd, arg, flag, cred, rvalp, NULL));
5687c478bd9Sstevel@tonic-gate }
5697c478bd9Sstevel@tonic-gate
5707c478bd9Sstevel@tonic-gate if ((rval = secpolicy_console(cred)) != 0)
5717c478bd9Sstevel@tonic-gate return (EPERM);
5727c478bd9Sstevel@tonic-gate
5737c478bd9Sstevel@tonic-gate infop = kmem_alloc(size, KM_SLEEP);
5747c478bd9Sstevel@tonic-gate if (flag & FKIOCTL)
5757c478bd9Sstevel@tonic-gate error = copystr((caddr_t)arg, infop, size, NULL);
5767c478bd9Sstevel@tonic-gate else
5777c478bd9Sstevel@tonic-gate error = copyinstr((caddr_t)arg, infop, size, NULL);
5787c478bd9Sstevel@tonic-gate
5797c478bd9Sstevel@tonic-gate if (error) {
5807c478bd9Sstevel@tonic-gate switch (cmd) {
5817c478bd9Sstevel@tonic-gate case CIOCGETCONSOLE:
5827c478bd9Sstevel@tonic-gate /*
5837c478bd9Sstevel@tonic-gate * If the buffer is null, then return a byte count
5847c478bd9Sstevel@tonic-gate * to user land.
5857c478bd9Sstevel@tonic-gate */
5867c478bd9Sstevel@tonic-gate *rvalp = size;
5877c478bd9Sstevel@tonic-gate goto err_exit;
5887c478bd9Sstevel@tonic-gate default:
5897c478bd9Sstevel@tonic-gate rval = EFAULT;
5907c478bd9Sstevel@tonic-gate goto err_exit;
5917c478bd9Sstevel@tonic-gate }
5927c478bd9Sstevel@tonic-gate }
5937c478bd9Sstevel@tonic-gate
5947c478bd9Sstevel@tonic-gate if (infop[0] != NULL) {
5957c478bd9Sstevel@tonic-gate if ((rval = lookupname(infop, UIO_SYSSPACE, FOLLOW,
5967c478bd9Sstevel@tonic-gate NULLVPP, &vp)) == 0) {
5977c478bd9Sstevel@tonic-gate if (vp->v_type != VCHR) {
5987c478bd9Sstevel@tonic-gate VN_RELE(vp);
5997c478bd9Sstevel@tonic-gate rval = EINVAL;
6007c478bd9Sstevel@tonic-gate goto err_exit;
6017c478bd9Sstevel@tonic-gate }
6027c478bd9Sstevel@tonic-gate newdevt = vp->v_rdev;
6037c478bd9Sstevel@tonic-gate VN_RELE(vp);
6047c478bd9Sstevel@tonic-gate } else
6057c478bd9Sstevel@tonic-gate goto err_exit;
6067c478bd9Sstevel@tonic-gate }
6077c478bd9Sstevel@tonic-gate
6087c478bd9Sstevel@tonic-gate switch (cmd) {
6097c478bd9Sstevel@tonic-gate case CIOCGETCONSOLE:
6107c478bd9Sstevel@tonic-gate /*
6117c478bd9Sstevel@tonic-gate * Return the list of device names that are enabled.
6127c478bd9Sstevel@tonic-gate */
6137c478bd9Sstevel@tonic-gate for (i = 0; i < MAXDEVS; i++) {
6147c478bd9Sstevel@tonic-gate rw_enter(&sysmcache[i].dca_lock, RW_READER);
6157c478bd9Sstevel@tonic-gate if (sysmcache[i].dca_flags & SYSM_ENABLED) {
6167c478bd9Sstevel@tonic-gate if (infop[0] != NULL)
6177c478bd9Sstevel@tonic-gate (void) strcat(infop, " ");
6187c478bd9Sstevel@tonic-gate (void) strcat(infop, sysmcache[i].dca_name);
6197c478bd9Sstevel@tonic-gate }
6207c478bd9Sstevel@tonic-gate rw_exit(&sysmcache[i].dca_lock);
6217c478bd9Sstevel@tonic-gate }
6227c478bd9Sstevel@tonic-gate if (rval == 0 && copyoutstr(infop, (void *)arg, size, NULL))
6237c478bd9Sstevel@tonic-gate rval = EFAULT;
6247c478bd9Sstevel@tonic-gate break;
6257c478bd9Sstevel@tonic-gate
6267c478bd9Sstevel@tonic-gate case CIOCSETCONSOLE:
6277c478bd9Sstevel@tonic-gate if ((rval = checkarg(newdevt)) != 0)
6287c478bd9Sstevel@tonic-gate break;
6297c478bd9Sstevel@tonic-gate /*
6307c478bd9Sstevel@tonic-gate * The device does not have to be open or disabled to
6317c478bd9Sstevel@tonic-gate * perform the set console.
6327c478bd9Sstevel@tonic-gate */
6337c478bd9Sstevel@tonic-gate for (i = 0; i < MAXDEVS; i++) {
6347c478bd9Sstevel@tonic-gate rw_enter(&sysmcache[i].dca_lock, RW_WRITER);
6357c478bd9Sstevel@tonic-gate if (sysmcache[i].dca_devt == newdevt &&
6367c478bd9Sstevel@tonic-gate (sysmcache[i].dca_flags & SYSM_ENABLED)) {
6377c478bd9Sstevel@tonic-gate (void) strcpy(sysmcache[i].dca_name, infop);
6387c478bd9Sstevel@tonic-gate rval = EEXIST;
6397c478bd9Sstevel@tonic-gate rw_exit(&sysmcache[i].dca_lock);
6407c478bd9Sstevel@tonic-gate break;
6417c478bd9Sstevel@tonic-gate } else if (sysmcache[i].dca_devt == newdevt &&
6427c478bd9Sstevel@tonic-gate sysmcache[i].dca_flags == SYSM_DISABLED) {
6437c478bd9Sstevel@tonic-gate sysmcache[i].dca_flags |= SYSM_ENABLED;
6447c478bd9Sstevel@tonic-gate (void) strcpy(sysmcache[i].dca_name, infop);
6457c478bd9Sstevel@tonic-gate rw_exit(&sysmcache[i].dca_lock);
6467c478bd9Sstevel@tonic-gate found = 1;
6477c478bd9Sstevel@tonic-gate break;
6487c478bd9Sstevel@tonic-gate } else if (sysmcache[i].dca_devt == 0) {
6497c478bd9Sstevel@tonic-gate ASSERT(sysmcache[i].dca_vp == NULL &&
6507c478bd9Sstevel@tonic-gate sysmcache[i].dca_flags == SYSM_DISABLED);
6517c478bd9Sstevel@tonic-gate (void) strcpy(sysmcache[i].dca_name, infop);
6527c478bd9Sstevel@tonic-gate sysmcache[i].dca_flags = SYSM_ENABLED;
6537c478bd9Sstevel@tonic-gate sysmcache[i].dca_devt = newdevt;
6547c478bd9Sstevel@tonic-gate rw_exit(&sysmcache[i].dca_lock);
6557c478bd9Sstevel@tonic-gate found = 1;
6567c478bd9Sstevel@tonic-gate break;
6577c478bd9Sstevel@tonic-gate }
6587c478bd9Sstevel@tonic-gate rw_exit(&sysmcache[i].dca_lock);
6597c478bd9Sstevel@tonic-gate }
6607c478bd9Sstevel@tonic-gate if (found == 0 && rval == 0)
6617c478bd9Sstevel@tonic-gate rval = ENOENT;
6627c478bd9Sstevel@tonic-gate break;
6637c478bd9Sstevel@tonic-gate
6647c478bd9Sstevel@tonic-gate case CIOCRMCONSOLE:
6657c478bd9Sstevel@tonic-gate for (i = 0; i < MAXDEVS; i++) {
6667c478bd9Sstevel@tonic-gate rw_enter(&sysmcache[i].dca_lock, RW_WRITER);
6677c478bd9Sstevel@tonic-gate if (sysmcache[i].dca_devt == newdevt) {
6687c478bd9Sstevel@tonic-gate sysmcache[i].dca_flags = SYSM_DISABLED;
6697c478bd9Sstevel@tonic-gate sysmcache[i].dca_name[0] = '\0';
6707c478bd9Sstevel@tonic-gate rw_exit(&sysmcache[i].dca_lock);
6717c478bd9Sstevel@tonic-gate found = 1;
6727c478bd9Sstevel@tonic-gate break;
6737c478bd9Sstevel@tonic-gate }
6747c478bd9Sstevel@tonic-gate rw_exit(&sysmcache[i].dca_lock);
6757c478bd9Sstevel@tonic-gate }
6767c478bd9Sstevel@tonic-gate if (found == 0)
6777c478bd9Sstevel@tonic-gate rval = ENOENT;
6787c478bd9Sstevel@tonic-gate break;
6797c478bd9Sstevel@tonic-gate
6807c478bd9Sstevel@tonic-gate default:
6817c478bd9Sstevel@tonic-gate break;
6827c478bd9Sstevel@tonic-gate }
6837c478bd9Sstevel@tonic-gate
6847c478bd9Sstevel@tonic-gate err_exit:
6857c478bd9Sstevel@tonic-gate kmem_free(infop, size);
6867c478bd9Sstevel@tonic-gate return (rval);
6877c478bd9Sstevel@tonic-gate }
6887c478bd9Sstevel@tonic-gate
6897c478bd9Sstevel@tonic-gate /* As with the read, we poll only the default console */
6907c478bd9Sstevel@tonic-gate
6917c478bd9Sstevel@tonic-gate /* ARGSUSED */
6927c478bd9Sstevel@tonic-gate static int
sysmpoll(dev_t dev,short events,int anyyet,short * reventsp,struct pollhead ** phpp)6937c478bd9Sstevel@tonic-gate sysmpoll(dev_t dev, short events, int anyyet, short *reventsp,
6947c478bd9Sstevel@tonic-gate struct pollhead **phpp)
6957c478bd9Sstevel@tonic-gate {
696da6c28aaSamw return (VOP_POLL(dcvp, events, anyyet, reventsp, phpp, NULL));
6977c478bd9Sstevel@tonic-gate }
6987c478bd9Sstevel@tonic-gate
6997c478bd9Sstevel@tonic-gate /* Sanity check that the device is good */
7007c478bd9Sstevel@tonic-gate static int
checkarg(dev_t devt)7017c478bd9Sstevel@tonic-gate checkarg(dev_t devt)
7027c478bd9Sstevel@tonic-gate {
7037c478bd9Sstevel@tonic-gate int rval = 0;
70483d132f8Sfl147353 dev_t sysmsg_dev, msglog_dev;
7057c478bd9Sstevel@tonic-gate extern dev_t rwsconsdev, rconsdev, uconsdev;
7067c478bd9Sstevel@tonic-gate
7077c478bd9Sstevel@tonic-gate if (devt == rconsdev || devt == rwsconsdev || devt == uconsdev) {
7087c478bd9Sstevel@tonic-gate rval = EBUSY;
70983d132f8Sfl147353 } else {
71083d132f8Sfl147353 sysmsg_dev = makedevice(ddi_driver_major(sysm_dip), SYS_SYSMIN);
71183d132f8Sfl147353 msglog_dev = makedevice(ddi_driver_major(sysm_dip), SYS_MSGMIN);
71283d132f8Sfl147353 if (devt == sysmsg_dev || devt == msglog_dev)
7137c478bd9Sstevel@tonic-gate rval = EINVAL;
7147c478bd9Sstevel@tonic-gate }
7157c478bd9Sstevel@tonic-gate
7167c478bd9Sstevel@tonic-gate return (rval);
7177c478bd9Sstevel@tonic-gate }
718