19512fe85Sahl /* 29512fe85Sahl * CDDL HEADER START 39512fe85Sahl * 49512fe85Sahl * The contents of this file are subject to the terms of the 59512fe85Sahl * Common Development and Distribution License (the "License"). 69512fe85Sahl * You may not use this file except in compliance with the License. 79512fe85Sahl * 89512fe85Sahl * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 99512fe85Sahl * or http://www.opensolaris.org/os/licensing. 109512fe85Sahl * See the License for the specific language governing permissions 119512fe85Sahl * and limitations under the License. 129512fe85Sahl * 139512fe85Sahl * When distributing Covered Code, include this CDDL HEADER in each 149512fe85Sahl * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 159512fe85Sahl * If applicable, add the following below this CDDL HEADER, with the 169512fe85Sahl * fields enclosed by brackets "[]" replaced with your own identifying 179512fe85Sahl * information: Portions Copyright [yyyy] [name of copyright owner] 189512fe85Sahl * 199512fe85Sahl * CDDL HEADER END 209512fe85Sahl */ 219512fe85Sahl 229512fe85Sahl /* 23*4fe01614Sraf * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 249512fe85Sahl * Use is subject to license terms. 259512fe85Sahl */ 269512fe85Sahl 279512fe85Sahl #pragma ident "%Z%%M% %I% %E% SMI" 289512fe85Sahl 299512fe85Sahl #include <sys/stat.h> 309512fe85Sahl #include <stdio.h> 319512fe85Sahl #include <stdlib.h> 329512fe85Sahl #include <fcntl.h> 339512fe85Sahl #include <sys/varargs.h> 349512fe85Sahl #include <errno.h> 359512fe85Sahl #include <sys/mman.h> 369512fe85Sahl #include <sys/wait.h> 379512fe85Sahl #include <unistd.h> 389512fe85Sahl 399512fe85Sahl #define DTRACEIOC (('d' << 24) | ('t' << 16) | ('r' << 8)) 409512fe85Sahl #define DTRACEIOC_MAX 17 419512fe85Sahl 429512fe85Sahl void 439512fe85Sahl fatal(char *fmt, ...) 449512fe85Sahl { 459512fe85Sahl va_list ap; 469512fe85Sahl 479512fe85Sahl va_start(ap, fmt); 489512fe85Sahl 499512fe85Sahl fprintf(stderr, "%s: ", "badioctl"); 509512fe85Sahl vfprintf(stderr, fmt, ap); 519512fe85Sahl 529512fe85Sahl if (fmt[strlen(fmt) - 1] != '\n') 539512fe85Sahl fprintf(stderr, ": %s\n", strerror(errno)); 549512fe85Sahl 559512fe85Sahl exit(1); 569512fe85Sahl } 579512fe85Sahl 589512fe85Sahl void 599512fe85Sahl badioctl(pid_t parent) 609512fe85Sahl { 619512fe85Sahl int fd = -1, random, ps = sysconf(_SC_PAGESIZE); 629512fe85Sahl int i = 0, seconds; 639512fe85Sahl caddr_t addr; 649512fe85Sahl hrtime_t now, last = 0, end; 659512fe85Sahl 669512fe85Sahl if ((random = open("/dev/random", O_RDONLY)) == -1) 679512fe85Sahl fatal("couldn't open /dev/random"); 689512fe85Sahl 699512fe85Sahl if ((addr = mmap(0, ps, PROT_READ | PROT_WRITE, 709512fe85Sahl MAP_ANON | MAP_PRIVATE, -1, 0)) == (caddr_t)-1) 719512fe85Sahl fatal("mmap"); 729512fe85Sahl 739512fe85Sahl for (;;) { 749512fe85Sahl unsigned int ioc; 759512fe85Sahl 769512fe85Sahl if ((now = gethrtime()) - last > NANOSEC) { 779512fe85Sahl if (kill(parent, 0) == -1 && errno == ESRCH) { 789512fe85Sahl /* 799512fe85Sahl * Our parent died. We will kill ourselves in 809512fe85Sahl * sympathy. 819512fe85Sahl */ 829512fe85Sahl exit(0); 839512fe85Sahl } 849512fe85Sahl 859512fe85Sahl /* 869512fe85Sahl * Once a second, we'll reopen the device. 879512fe85Sahl */ 889512fe85Sahl if (fd != -1) 899512fe85Sahl close(fd); 909512fe85Sahl 919512fe85Sahl fd = open("/devices/pseudo/dtrace@0:dtrace", O_RDONLY); 929512fe85Sahl 939512fe85Sahl if (fd == -1) 949512fe85Sahl fatal("couldn't open DTrace pseudo device"); 959512fe85Sahl 969512fe85Sahl last = now; 979512fe85Sahl } 989512fe85Sahl 999512fe85Sahl 1009512fe85Sahl if ((i++ % 1000) == 0) { 1019512fe85Sahl /* 1029512fe85Sahl * Every thousand iterations, change our random gunk. 1039512fe85Sahl */ 1049512fe85Sahl read(random, addr, ps); 1059512fe85Sahl } 1069512fe85Sahl 1079512fe85Sahl read(random, &ioc, sizeof (ioc)); 1089512fe85Sahl ioc %= DTRACEIOC_MAX; 1099512fe85Sahl ioc++; 1109512fe85Sahl ioctl(fd, DTRACEIOC | ioc, addr); 1119512fe85Sahl } 1129512fe85Sahl } 1139512fe85Sahl 114*4fe01614Sraf int 1159512fe85Sahl main() 1169512fe85Sahl { 1179512fe85Sahl pid_t child, parent = getpid(); 1189512fe85Sahl int status; 1199512fe85Sahl 1209512fe85Sahl for (;;) { 1219512fe85Sahl if ((child = fork()) == 0) 1229512fe85Sahl badioctl(parent); 1239512fe85Sahl 1249512fe85Sahl while (waitpid(child, &status, WEXITED) != child) 1259512fe85Sahl continue; 1269512fe85Sahl 1279512fe85Sahl if (WIFEXITED(status)) { 1289512fe85Sahl /* 1299512fe85Sahl * Our child exited by design -- we'll exit with 1309512fe85Sahl * the same status code. 1319512fe85Sahl */ 1329512fe85Sahl exit(WEXITSTATUS(status)); 1339512fe85Sahl } 1349512fe85Sahl 1359512fe85Sahl /* 1369512fe85Sahl * Our child died on a signal. Respawn it. 1379512fe85Sahl */ 1389512fe85Sahl printf("badioctl: child died on signal %d; respawning.\n", 1399512fe85Sahl WTERMSIG(status)); 1409512fe85Sahl fflush(stdout); 1419512fe85Sahl } 142*4fe01614Sraf 143*4fe01614Sraf /* NOTREACHED */ 144*4fe01614Sraf return (0); 1459512fe85Sahl } 146