1178476Sjb/* 2178476Sjb * CDDL HEADER START 3178476Sjb * 4178476Sjb * The contents of this file are subject to the terms of the 5178476Sjb * Common Development and Distribution License (the "License"). 6178476Sjb * You may not use this file except in compliance with the License. 7178476Sjb * 8178476Sjb * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9178476Sjb * or http://www.opensolaris.org/os/licensing. 10178476Sjb * See the License for the specific language governing permissions 11178476Sjb * and limitations under the License. 12178476Sjb * 13178476Sjb * When distributing Covered Code, include this CDDL HEADER in each 14178476Sjb * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15178476Sjb * If applicable, add the following below this CDDL HEADER, with the 16178476Sjb * fields enclosed by brackets "[]" replaced with your own identifying 17178476Sjb * information: Portions Copyright [yyyy] [name of copyright owner] 18178476Sjb * 19178476Sjb * CDDL HEADER END 20178476Sjb */ 21178476Sjb 22178476Sjb/* 23178476Sjb * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 24178476Sjb * Use is subject to license terms. 25178476Sjb */ 26178476Sjb 27178476Sjb#pragma ident "%Z%%M% %I% %E% SMI" 28178476Sjb 29178476Sjb#include <sys/stat.h> 30178476Sjb#include <stdio.h> 31178476Sjb#include <stdlib.h> 32178476Sjb#include <fcntl.h> 33178476Sjb#include <sys/varargs.h> 34178476Sjb#include <errno.h> 35178476Sjb#include <sys/mman.h> 36178476Sjb#include <sys/wait.h> 37178476Sjb#include <unistd.h> 38178476Sjb 39178476Sjb#define DTRACEIOC (('d' << 24) | ('t' << 16) | ('r' << 8)) 40178476Sjb#define DTRACEIOC_MAX 17 41178476Sjb 42178476Sjbvoid 43178476Sjbfatal(char *fmt, ...) 44178476Sjb{ 45178476Sjb va_list ap; 46178476Sjb 47178476Sjb va_start(ap, fmt); 48178476Sjb 49178476Sjb fprintf(stderr, "%s: ", "badioctl"); 50178476Sjb vfprintf(stderr, fmt, ap); 51178476Sjb 52178476Sjb if (fmt[strlen(fmt) - 1] != '\n') 53178476Sjb fprintf(stderr, ": %s\n", strerror(errno)); 54178476Sjb 55178476Sjb exit(1); 56178476Sjb} 57178476Sjb 58178476Sjbvoid 59178476Sjbbadioctl(pid_t parent) 60178476Sjb{ 61178476Sjb int fd = -1, random, ps = sysconf(_SC_PAGESIZE); 62178476Sjb int i = 0, seconds; 63178476Sjb caddr_t addr; 64178476Sjb hrtime_t now, last = 0, end; 65178476Sjb 66178476Sjb if ((random = open("/dev/random", O_RDONLY)) == -1) 67178476Sjb fatal("couldn't open /dev/random"); 68178476Sjb 69178476Sjb if ((addr = mmap(0, ps, PROT_READ | PROT_WRITE, 70178476Sjb MAP_ANON | MAP_PRIVATE, -1, 0)) == (caddr_t)-1) 71178476Sjb fatal("mmap"); 72178476Sjb 73178476Sjb for (;;) { 74178476Sjb unsigned int ioc; 75178476Sjb 76178476Sjb if ((now = gethrtime()) - last > NANOSEC) { 77178476Sjb if (kill(parent, 0) == -1 && errno == ESRCH) { 78178476Sjb /* 79178476Sjb * Our parent died. We will kill ourselves in 80178476Sjb * sympathy. 81178476Sjb */ 82178476Sjb exit(0); 83178476Sjb } 84178476Sjb 85178476Sjb /* 86178476Sjb * Once a second, we'll reopen the device. 87178476Sjb */ 88178476Sjb if (fd != -1) 89178476Sjb close(fd); 90178476Sjb 91178476Sjb fd = open("/devices/pseudo/dtrace@0:dtrace", O_RDONLY); 92178476Sjb 93178476Sjb if (fd == -1) 94178476Sjb fatal("couldn't open DTrace pseudo device"); 95178476Sjb 96178476Sjb last = now; 97178476Sjb } 98178476Sjb 99178476Sjb 100178476Sjb if ((i++ % 1000) == 0) { 101178476Sjb /* 102178476Sjb * Every thousand iterations, change our random gunk. 103178476Sjb */ 104178476Sjb read(random, addr, ps); 105178476Sjb } 106178476Sjb 107178476Sjb read(random, &ioc, sizeof (ioc)); 108178476Sjb ioc %= DTRACEIOC_MAX; 109178476Sjb ioc++; 110178476Sjb ioctl(fd, DTRACEIOC | ioc, addr); 111178476Sjb } 112178476Sjb} 113178476Sjb 114178476Sjbint 115178476Sjbmain() 116178476Sjb{ 117178476Sjb pid_t child, parent = getpid(); 118178476Sjb int status; 119178476Sjb 120178476Sjb for (;;) { 121178476Sjb if ((child = fork()) == 0) 122178476Sjb badioctl(parent); 123178476Sjb 124178476Sjb while (waitpid(child, &status, WEXITED) != child) 125178476Sjb continue; 126178476Sjb 127178476Sjb if (WIFEXITED(status)) { 128178476Sjb /* 129178476Sjb * Our child exited by design -- we'll exit with 130178476Sjb * the same status code. 131178476Sjb */ 132178476Sjb exit(WEXITSTATUS(status)); 133178476Sjb } 134178476Sjb 135178476Sjb /* 136178476Sjb * Our child died on a signal. Respawn it. 137178476Sjb */ 138178476Sjb printf("badioctl: child died on signal %d; respawning.\n", 139178476Sjb WTERMSIG(status)); 140178476Sjb fflush(stdout); 141178476Sjb } 142178476Sjb 143178476Sjb /* NOTREACHED */ 144178476Sjb return (0); 145178476Sjb} 146