10Sstevel@tonic-gate /*
20Sstevel@tonic-gate * CDDL HEADER START
30Sstevel@tonic-gate *
40Sstevel@tonic-gate * The contents of this file are subject to the terms of the
5*1914Scasper * Common Development and Distribution License (the "License").
6*1914Scasper * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate *
80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate * See the License for the specific language governing permissions
110Sstevel@tonic-gate * and limitations under the License.
120Sstevel@tonic-gate *
130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate *
190Sstevel@tonic-gate * CDDL HEADER END
200Sstevel@tonic-gate */
210Sstevel@tonic-gate /*
22*1914Scasper * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
23*1914Scasper * Use is subject to license terms.
240Sstevel@tonic-gate */
250Sstevel@tonic-gate
260Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI"
270Sstevel@tonic-gate
280Sstevel@tonic-gate #include <stdio.h>
29*1914Scasper #include <stdio_ext.h>
300Sstevel@tonic-gate #include <stdlib.h>
310Sstevel@tonic-gate #include <unistd.h>
320Sstevel@tonic-gate #include <sys/types.h>
330Sstevel@tonic-gate #include <sys/time.h>
340Sstevel@tonic-gate #include <fcntl.h>
350Sstevel@tonic-gate #include <sys/fcntl.h>
360Sstevel@tonic-gate #include <errno.h>
370Sstevel@tonic-gate #include <string.h>
380Sstevel@tonic-gate #include <limits.h>
390Sstevel@tonic-gate #include <sys/socket.h>
400Sstevel@tonic-gate #include <net/if.h>
410Sstevel@tonic-gate #include <netinet/in.h>
420Sstevel@tonic-gate #include <arpa/inet.h>
430Sstevel@tonic-gate #include <thread.h>
440Sstevel@tonic-gate #include <tnf/probe.h>
450Sstevel@tonic-gate
460Sstevel@tonic-gate #include <netinet/dhcp.h>
470Sstevel@tonic-gate #include <locale.h>
480Sstevel@tonic-gate #include <signal.h>
490Sstevel@tonic-gate #include <tnf/probe.h>
500Sstevel@tonic-gate
510Sstevel@tonic-gate #include <dhcp_svc_confopt.h>
520Sstevel@tonic-gate #include <dhcp_svc_private.h>
530Sstevel@tonic-gate #include <dhcp_impl.h>
540Sstevel@tonic-gate
550Sstevel@tonic-gate #ifdef DEBUG
560Sstevel@tonic-gate #include <mtmalloc.h>
570Sstevel@tonic-gate #endif /* DEBUG */
580Sstevel@tonic-gate
590Sstevel@tonic-gate /*
600Sstevel@tonic-gate * Global variables.
610Sstevel@tonic-gate */
620Sstevel@tonic-gate int verbose = 0;
630Sstevel@tonic-gate thread_t *tp;
640Sstevel@tonic-gate cond_t never;
650Sstevel@tonic-gate volatile time_t *timp;
660Sstevel@tonic-gate volatile int tms;
670Sstevel@tonic-gate char *fl;
680Sstevel@tonic-gate mutex_t mtx;
690Sstevel@tonic-gate mutex_t thread_mtx;
700Sstevel@tonic-gate volatile ulong_t ops_outstanding;
710Sstevel@tonic-gate
720Sstevel@tonic-gate static volatile ulong_t tops, otops;
730Sstevel@tonic-gate static volatile ulong_t minops[6];
740Sstevel@tonic-gate static volatile time_t mintim[6];
750Sstevel@tonic-gate static volatile int minind;
760Sstevel@tonic-gate long sample_time = 10L;
770Sstevel@tonic-gate long nsamples = 2;
780Sstevel@tonic-gate
790Sstevel@tonic-gate static volatile time_t start, ostart;
800Sstevel@tonic-gate volatile time_t ustart;
810Sstevel@tonic-gate volatile int time_to_go;
820Sstevel@tonic-gate volatile int spawn_helper;
830Sstevel@tonic-gate char b[1024 * 1024];
840Sstevel@tonic-gate volatile double slp;
850Sstevel@tonic-gate volatile int worktype;
860Sstevel@tonic-gate thread_t sigthread;
870Sstevel@tonic-gate volatile int old, new, unstarted;
880Sstevel@tonic-gate volatile uint_t threads;
890Sstevel@tonic-gate volatile unsigned int douwork = 0;
900Sstevel@tonic-gate volatile int dofsync = 0;
910Sstevel@tonic-gate volatile int domalloc = 0;
920Sstevel@tonic-gate volatile int dofork = 0;
930Sstevel@tonic-gate thread_t opnthread;
940Sstevel@tonic-gate volatile int doopen = 0;
950Sstevel@tonic-gate
960Sstevel@tonic-gate dsvc_datastore_t datastore; /* Datastore for container access */
970Sstevel@tonic-gate
980Sstevel@tonic-gate #define MAXTABLE 1024
990Sstevel@tonic-gate int ntable;
1000Sstevel@tonic-gate
1010Sstevel@tonic-gate dn_rec_list_t *thread_dncp[MAXTABLE];
1020Sstevel@tonic-gate dsvc_handle_t dh[MAXTABLE]; /* data handle */
1030Sstevel@tonic-gate struct in_addr net[MAXTABLE];
1040Sstevel@tonic-gate uint_t nrecords[MAXTABLE];
1050Sstevel@tonic-gate char *network;
1060Sstevel@tonic-gate
1070Sstevel@tonic-gate typedef struct work {
1080Sstevel@tonic-gate boolean_t isthreaded;
1090Sstevel@tonic-gate int thread;
1100Sstevel@tonic-gate cond_t cv;
1110Sstevel@tonic-gate mutex_t mtx;
1120Sstevel@tonic-gate dn_rec_t *dnp;
1130Sstevel@tonic-gate }work_t;
1140Sstevel@tonic-gate
1150Sstevel@tonic-gate void
free_work_t(work_t * wptr)1160Sstevel@tonic-gate free_work_t(work_t *wptr) {
1170Sstevel@tonic-gate free(wptr->dnp);
1180Sstevel@tonic-gate free(wptr);
1190Sstevel@tonic-gate }
1200Sstevel@tonic-gate /*
1210Sstevel@tonic-gate * Simulated binary datastore work
1220Sstevel@tonic-gate */
1230Sstevel@tonic-gate /* ARGSUSED */
1240Sstevel@tonic-gate static void *
uwork(void * argp)1250Sstevel@tonic-gate uwork(void *argp)
1260Sstevel@tonic-gate {
1270Sstevel@tonic-gate int i;
1280Sstevel@tonic-gate int err;
1290Sstevel@tonic-gate int fd;
1300Sstevel@tonic-gate long block;
1310Sstevel@tonic-gate work_t *wptr = argp;
1320Sstevel@tonic-gate char *ptr;
1330Sstevel@tonic-gate size_t size = ((random() & (domalloc - 1)) + 0x200) &
1340Sstevel@tonic-gate ~(0x200 - 1);
1350Sstevel@tonic-gate int wtype;
1360Sstevel@tonic-gate
1370Sstevel@tonic-gate if (domalloc)
1380Sstevel@tonic-gate ptr = malloc(size);
1390Sstevel@tonic-gate else
1400Sstevel@tonic-gate ptr = b;
1410Sstevel@tonic-gate
1420Sstevel@tonic-gate if (wptr->isthreaded) {
1430Sstevel@tonic-gate (void) mutex_lock(&wptr->mtx);
1440Sstevel@tonic-gate }
1450Sstevel@tonic-gate i = wptr->thread;
1460Sstevel@tonic-gate
1470Sstevel@tonic-gate TNF_PROBE_1(uwork, "work", "uwork%debug 'in function work'",
1480Sstevel@tonic-gate tnf_long, size, size);
1490Sstevel@tonic-gate
1500Sstevel@tonic-gate wtype = worktype == 0 ? random() & 0x7 : worktype;
1510Sstevel@tonic-gate block = (random() & (douwork - 1)) + (tms / 0x200) + 1;
1520Sstevel@tonic-gate
1530Sstevel@tonic-gate /* prewrite legal records */
1540Sstevel@tonic-gate if (timp[i] == NULL && ustart == 0) {
1550Sstevel@tonic-gate ustart = time(NULL);
1560Sstevel@tonic-gate wtype = 4;
1570Sstevel@tonic-gate block = (tms / 0x200) + 1;
1580Sstevel@tonic-gate size = sizeof (b);
1590Sstevel@tonic-gate ptr = b;
1600Sstevel@tonic-gate }
1610Sstevel@tonic-gate timp[i] = time(NULL);
1620Sstevel@tonic-gate fd = open(fl, O_RDWR);
1630Sstevel@tonic-gate (void) write(fd, (char *)timp, tms);
1640Sstevel@tonic-gate (void) close(fd);
1650Sstevel@tonic-gate
1660Sstevel@tonic-gate if (wtype == 4) {
1670Sstevel@tonic-gate
1680Sstevel@tonic-gate TNF_PROBE_2(uwork_write, "work",
1690Sstevel@tonic-gate "uwork_write%debug 'in function work'",
1700Sstevel@tonic-gate tnf_long, block, block,
1710Sstevel@tonic-gate tnf_long, size, size);
1720Sstevel@tonic-gate
1730Sstevel@tonic-gate fd = open(fl, O_RDWR);
1740Sstevel@tonic-gate (void) lseek(fd, block * 0x200, 0L);
1750Sstevel@tonic-gate err = write(fd, ptr, size);
1760Sstevel@tonic-gate (void) close(fd);
1770Sstevel@tonic-gate
1780Sstevel@tonic-gate TNF_PROBE_1(uwork_write_end, "work",
1790Sstevel@tonic-gate "uwork_write_end%debug 'in function work'",
1800Sstevel@tonic-gate tnf_long, err, err);
1810Sstevel@tonic-gate
1820Sstevel@tonic-gate } else if (wtype == 3 && dofsync) {
1830Sstevel@tonic-gate
1840Sstevel@tonic-gate TNF_PROBE_0(uwork_fsync, "work",
1850Sstevel@tonic-gate "uwork_fsync%debug 'in function work'");
1860Sstevel@tonic-gate
1870Sstevel@tonic-gate fd = open(fl, O_RDWR);
1880Sstevel@tonic-gate err = fsync(fd);
1890Sstevel@tonic-gate (void) close(fd);
1900Sstevel@tonic-gate
1910Sstevel@tonic-gate TNF_PROBE_1(uwork_fsync_end, "work",
1920Sstevel@tonic-gate "uwork_fsync_end%debug 'in function work'",
1930Sstevel@tonic-gate tnf_long, err, err);
1940Sstevel@tonic-gate } else {
1950Sstevel@tonic-gate TNF_PROBE_2(uwork_read, "work",
1960Sstevel@tonic-gate "uwork_read%debug 'in function work'",
1970Sstevel@tonic-gate tnf_long, block, block,
1980Sstevel@tonic-gate tnf_long, size, size);
1990Sstevel@tonic-gate
2000Sstevel@tonic-gate fd = open(fl, O_RDWR);
2010Sstevel@tonic-gate (void) lseek(fd, block * 0x200, 0L);
2020Sstevel@tonic-gate err = read(fd, ptr, size);
2030Sstevel@tonic-gate (void) close(fd);
2040Sstevel@tonic-gate
2050Sstevel@tonic-gate TNF_PROBE_1(uwork_read_end, "work",
2060Sstevel@tonic-gate "uwork_read_end%debug 'in function work'",
2070Sstevel@tonic-gate tnf_long, err, err);
2080Sstevel@tonic-gate
2090Sstevel@tonic-gate }
2100Sstevel@tonic-gate if (domalloc && ptr != b)
2110Sstevel@tonic-gate free(ptr);
2120Sstevel@tonic-gate
2130Sstevel@tonic-gate if (wptr->isthreaded) {
2140Sstevel@tonic-gate (void) mutex_unlock(&wptr->mtx);
2150Sstevel@tonic-gate cond_signal(&wptr->cv);
2160Sstevel@tonic-gate TNF_PROBE_0(work_end, "work", "");
2170Sstevel@tonic-gate thr_exit(NULL);
2180Sstevel@tonic-gate }
2190Sstevel@tonic-gate TNF_PROBE_0(uwork_end, "work", "");
2200Sstevel@tonic-gate
2210Sstevel@tonic-gate return ((void *) NULL);
2220Sstevel@tonic-gate }
2230Sstevel@tonic-gate
2240Sstevel@tonic-gate /*
2250Sstevel@tonic-gate * Simulated datastore work
2260Sstevel@tonic-gate */
2270Sstevel@tonic-gate static void *
work(void * argp)2280Sstevel@tonic-gate work(void *argp)
2290Sstevel@tonic-gate {
2300Sstevel@tonic-gate int i, j;
2310Sstevel@tonic-gate dn_rec_t *dnp;
2320Sstevel@tonic-gate int err;
2330Sstevel@tonic-gate work_t *wptr = argp;
2340Sstevel@tonic-gate uchar_t cid_len;
2350Sstevel@tonic-gate char *ptr;
2360Sstevel@tonic-gate uint32_t query;
2370Sstevel@tonic-gate dn_rec_t dn, ndn;
2380Sstevel@tonic-gate dn_rec_list_t *dncp = NULL;
2390Sstevel@tonic-gate uint_t crecords, irecords;
2400Sstevel@tonic-gate int wtype;
2410Sstevel@tonic-gate int firsttime = 0;
2420Sstevel@tonic-gate int op;
2430Sstevel@tonic-gate size_t size = ((random() & (domalloc - 1)) + 0x100) &
2440Sstevel@tonic-gate ~(0x1000 - 1);
2450Sstevel@tonic-gate int table;
2460Sstevel@tonic-gate
2470Sstevel@tonic-gate if (domalloc)
2480Sstevel@tonic-gate ptr = malloc(size);
2490Sstevel@tonic-gate else
2500Sstevel@tonic-gate ptr = b;
2510Sstevel@tonic-gate
2520Sstevel@tonic-gate irecords = (random() & 0xff) + 1;
2530Sstevel@tonic-gate if (irecords == 12) {
2540Sstevel@tonic-gate irecords = (uint_t)-1;
2550Sstevel@tonic-gate }
2560Sstevel@tonic-gate if (wptr->isthreaded) {
2570Sstevel@tonic-gate (void) mutex_lock(&wptr->mtx);
2580Sstevel@tonic-gate }
2590Sstevel@tonic-gate i = wptr->thread;
2600Sstevel@tonic-gate dnp = wptr->dnp;
2610Sstevel@tonic-gate
2620Sstevel@tonic-gate table = i % ntable;
2630Sstevel@tonic-gate dn = *dnp;
2640Sstevel@tonic-gate
2650Sstevel@tonic-gate cid_len = 7;
2660Sstevel@tonic-gate
2670Sstevel@tonic-gate if (worktype == 0) {
2680Sstevel@tonic-gate wtype = random() & 0x7;
2690Sstevel@tonic-gate if (wtype == 4)
2700Sstevel@tonic-gate wtype--;
2710Sstevel@tonic-gate } else
2720Sstevel@tonic-gate wtype = worktype;
2730Sstevel@tonic-gate
2740Sstevel@tonic-gate /* preload a legal record */
2750Sstevel@tonic-gate if (timp[i] == NULL) {
2760Sstevel@tonic-gate wtype = 3;
2770Sstevel@tonic-gate firsttime = 1;
2780Sstevel@tonic-gate irecords = threads * 2;
2790Sstevel@tonic-gate (void) mutex_lock(&thread_mtx);
2800Sstevel@tonic-gate if ((dncp = thread_dncp[table]) != NULL) {
2810Sstevel@tonic-gate thread_dncp[table] = dncp->dnl_next;
2820Sstevel@tonic-gate *dnp = *(dncp->dnl_rec);
2830Sstevel@tonic-gate dncp->dnl_next = NULL;
2840Sstevel@tonic-gate wtype = -1;
2850Sstevel@tonic-gate (void) mutex_unlock(&thread_mtx);
2860Sstevel@tonic-gate }
2870Sstevel@tonic-gate }
2880Sstevel@tonic-gate TNF_PROBE_2(work, "work", "work%debug 'in function work'",
2890Sstevel@tonic-gate tnf_ulong, worktype, wtype,
2900Sstevel@tonic-gate tnf_ulong, irecords, irecords);
2910Sstevel@tonic-gate
2920Sstevel@tonic-gate timp[i] = time(NULL);
2930Sstevel@tonic-gate crecords = 0;
2940Sstevel@tonic-gate DSVC_QINIT(query);
2950Sstevel@tonic-gate switch (wtype) {
2960Sstevel@tonic-gate case -1:
2970Sstevel@tonic-gate break;
2980Sstevel@tonic-gate case 1:
2990Sstevel@tonic-gate switch (random() & 0x7) {
3000Sstevel@tonic-gate case 1:
3010Sstevel@tonic-gate for (j = 0; j < cid_len; j++)
3020Sstevel@tonic-gate dn.dn_cid[j] = random() & 0xff;
3030Sstevel@tonic-gate break;
3040Sstevel@tonic-gate case 2:
3050Sstevel@tonic-gate for (j = 0; j < cid_len; j++)
3060Sstevel@tonic-gate dn.dn_cid[j] = '\0';
3070Sstevel@tonic-gate dn.dn_cid_len = 1;
3080Sstevel@tonic-gate break;
3090Sstevel@tonic-gate }
3100Sstevel@tonic-gate DSVC_QEQ(query, DN_QCID);
3110Sstevel@tonic-gate
3120Sstevel@tonic-gate /* LINTED */
3130Sstevel@tonic-gate TNF_PROBE_2(work_cid, "work work_cid",
3140Sstevel@tonic-gate "work_cid%debug 'in function work'",
3150Sstevel@tonic-gate tnf_ulong, cid, *(ulong_t *)&dn.dn_cid,
3160Sstevel@tonic-gate tnf_ulong, cid_len, dn.dn_cid_len);
3170Sstevel@tonic-gate
3180Sstevel@tonic-gate err = lookup_dd(dh[table], B_TRUE, query, -1,
3190Sstevel@tonic-gate (const void *)&dn, (void **)&dncp, &crecords);
3200Sstevel@tonic-gate
3210Sstevel@tonic-gate TNF_PROBE_2(work_cid_end, "work work_cid",
3220Sstevel@tonic-gate "work_cid_end%debug 'in function work'",
3230Sstevel@tonic-gate tnf_ulong, err, err,
3240Sstevel@tonic-gate tnf_ulong, crecords, crecords);
3250Sstevel@tonic-gate
3260Sstevel@tonic-gate if (crecords > 0 && dncp)
3270Sstevel@tonic-gate *dnp = *(dncp->dnl_rec);
3280Sstevel@tonic-gate break;
3290Sstevel@tonic-gate
3300Sstevel@tonic-gate case 2:
3310Sstevel@tonic-gate switch (random() & 0x7) {
3320Sstevel@tonic-gate case 1:
3330Sstevel@tonic-gate dn.dn_cip.s_addr = random();
3340Sstevel@tonic-gate break;
3350Sstevel@tonic-gate case 2:
3360Sstevel@tonic-gate dn.dn_cip.s_addr = net[table].s_addr |
3370Sstevel@tonic-gate (random() & (nrecords[table] - 1));
3380Sstevel@tonic-gate break;
3390Sstevel@tonic-gate }
3400Sstevel@tonic-gate
3410Sstevel@tonic-gate DSVC_QEQ(query, DN_QCIP);
3420Sstevel@tonic-gate
3430Sstevel@tonic-gate TNF_PROBE_1(work_cip, "work work_cip",
3440Sstevel@tonic-gate "work_cip%debug 'in function work'",
3450Sstevel@tonic-gate tnf_ulong, cip, dn.dn_cip.s_addr);
3460Sstevel@tonic-gate
3470Sstevel@tonic-gate err = lookup_dd(dh[table], B_TRUE, query, -1,
3480Sstevel@tonic-gate (const void *)&dn, (void **)&dncp, &crecords);
3490Sstevel@tonic-gate
3500Sstevel@tonic-gate TNF_PROBE_2(work_cip_end, "work work_cip",
3510Sstevel@tonic-gate "work_cip_end%debug 'in function work'",
3520Sstevel@tonic-gate tnf_ulong, err, err,
3530Sstevel@tonic-gate tnf_ulong, crecords, crecords);
3540Sstevel@tonic-gate
3550Sstevel@tonic-gate if (crecords > 0 && dncp)
3560Sstevel@tonic-gate *dnp = *(dncp->dnl_rec);
3570Sstevel@tonic-gate break;
3580Sstevel@tonic-gate case 3:
3590Sstevel@tonic-gate op = random() & 0x7;
3600Sstevel@tonic-gate if (firsttime)
3610Sstevel@tonic-gate op = 2;
3620Sstevel@tonic-gate
3630Sstevel@tonic-gate switch (op) {
3640Sstevel@tonic-gate case 1:
3650Sstevel@tonic-gate DSVC_QNEQ(query, DN_QLEASE);
3660Sstevel@tonic-gate dn.dn_lease = 0;
3670Sstevel@tonic-gate break;
3680Sstevel@tonic-gate case 2:
3690Sstevel@tonic-gate DSVC_QEQ(query, DN_QCID);
3700Sstevel@tonic-gate for (j = 0; j < cid_len; j++)
3710Sstevel@tonic-gate dn.dn_cid[j] = '\0';
3720Sstevel@tonic-gate dn.dn_cid_len = 1;
3730Sstevel@tonic-gate break;
3740Sstevel@tonic-gate }
3750Sstevel@tonic-gate
3760Sstevel@tonic-gate TNF_PROBE_2(work_read, "work work_read",
3770Sstevel@tonic-gate "work_read%debug 'in function work'",
3780Sstevel@tonic-gate tnf_ulong, query, query,
3790Sstevel@tonic-gate tnf_ulong, cid_len, dn.dn_cid_len);
3800Sstevel@tonic-gate
3810Sstevel@tonic-gate err = lookup_dd(dh[table], B_TRUE, query, irecords,
3820Sstevel@tonic-gate (const void *)&dn, (void **)&dncp, &crecords);
3830Sstevel@tonic-gate
3840Sstevel@tonic-gate TNF_PROBE_2(work_read_end, "work work_read",
3850Sstevel@tonic-gate "work_read_end%debug 'in function work'",
3860Sstevel@tonic-gate tnf_ulong, err, err,
3870Sstevel@tonic-gate tnf_ulong, crecords, crecords);
3880Sstevel@tonic-gate
3890Sstevel@tonic-gate if (crecords > 0 && dncp) {
3900Sstevel@tonic-gate *dnp = *(dncp->dnl_rec);
3910Sstevel@tonic-gate if (firsttime) {
3920Sstevel@tonic-gate thread_dncp[table] = dncp->dnl_next;
3930Sstevel@tonic-gate dncp->dnl_next = NULL;
3940Sstevel@tonic-gate mutex_unlock(&thread_mtx);
3950Sstevel@tonic-gate }
3960Sstevel@tonic-gate }
3970Sstevel@tonic-gate break;
3980Sstevel@tonic-gate case 4:
3990Sstevel@tonic-gate op = dnp->dn_lease & 0x3;
4000Sstevel@tonic-gate switch (op) {
4010Sstevel@tonic-gate case 0:
4020Sstevel@tonic-gate /* write record w/ cid */
4030Sstevel@tonic-gate ndn = *dnp;
4040Sstevel@tonic-gate ndn.dn_lease = (htonl(time(NULL)) & ~0x3) + 1;
4050Sstevel@tonic-gate ndn.dn_cid_len = 14;
4060Sstevel@tonic-gate for (j = 0; j < ndn.dn_cid_len; j++)
4070Sstevel@tonic-gate ndn.dn_cid[j] = random() & 0xff;
4080Sstevel@tonic-gate
4090Sstevel@tonic-gate /* LINTED */
4100Sstevel@tonic-gate TNF_PROBE_2(work1_modify, "work work1_modify",
4110Sstevel@tonic-gate "work1_modify%debug 'in function work'",
4120Sstevel@tonic-gate tnf_ulong, cid, *(ulong_t *)&ndn.dn_cid,
4130Sstevel@tonic-gate tnf_ulong, cid_len, ndn.dn_cid_len);
4140Sstevel@tonic-gate
4150Sstevel@tonic-gate err = modify_dd_entry(dh[table], dnp, &ndn);
4160Sstevel@tonic-gate if (err != DSVC_SUCCESS && verbose) {
4170Sstevel@tonic-gate fprintf(stderr, "work: %d %d error %d\n",
4180Sstevel@tonic-gate wtype, op, err);
4190Sstevel@tonic-gate }
4200Sstevel@tonic-gate
4210Sstevel@tonic-gate TNF_PROBE_1(work1_modify_end, "work work1_modify_end",
4220Sstevel@tonic-gate "work1_modify_end%debug 'in function work'",
4230Sstevel@tonic-gate tnf_ulong, err, err);
4240Sstevel@tonic-gate *dnp = ndn;
4250Sstevel@tonic-gate break;
4260Sstevel@tonic-gate case 1:
4270Sstevel@tonic-gate /* re-read record w/ cid */
4280Sstevel@tonic-gate DSVC_QEQ(query, DN_QCID);
4290Sstevel@tonic-gate TNF_PROBE_2(work_read1, "work work_read1",
4300Sstevel@tonic-gate "work_read1%debug 'in function work'",
4310Sstevel@tonic-gate tnf_ulong, query, query,
4320Sstevel@tonic-gate tnf_ulong, cid_len, dn.dn_cid_len);
4330Sstevel@tonic-gate
4340Sstevel@tonic-gate err = lookup_dd(dh[table], B_TRUE, query, - 1,
4350Sstevel@tonic-gate (const void *)dnp, (void **)&dncp,
4360Sstevel@tonic-gate &crecords);
4370Sstevel@tonic-gate TNF_PROBE_2(work_read1_end, "work work_read1",
4380Sstevel@tonic-gate "work_read1_end%debug 'in function work'",
4390Sstevel@tonic-gate tnf_ulong, err, err,
4400Sstevel@tonic-gate tnf_ulong, crecords, crecords);
4410Sstevel@tonic-gate
4420Sstevel@tonic-gate if ((err != DSVC_SUCCESS || crecords < 1) && verbose) {
4430Sstevel@tonic-gate fprintf(stderr, "work: %d %d error %d %d\n",
4440Sstevel@tonic-gate wtype, op, err, crecords);
4450Sstevel@tonic-gate }
4460Sstevel@tonic-gate dnp->dn_lease++;
4470Sstevel@tonic-gate break;
4480Sstevel@tonic-gate case 2:
4490Sstevel@tonic-gate /* write free record */
4500Sstevel@tonic-gate dnp->dn_lease--;
4510Sstevel@tonic-gate ndn = *dnp;
4520Sstevel@tonic-gate DSVC_QEQ(query, DN_QCID);
4530Sstevel@tonic-gate for (j = 0; j < cid_len; j++)
4540Sstevel@tonic-gate ndn.dn_cid[j] = '\0';
4550Sstevel@tonic-gate ndn.dn_cid_len = 1;
4560Sstevel@tonic-gate ndn.dn_lease = 0;
4570Sstevel@tonic-gate
4580Sstevel@tonic-gate TNF_PROBE_2(work_modify2, "work work_modify2",
4590Sstevel@tonic-gate "work_modify2%debug 'in function work'",
4600Sstevel@tonic-gate tnf_ulong, cid, *(ulong_t *)&ndn.dn_cid,
4610Sstevel@tonic-gate tnf_ulong, cid_len, ndn.dn_cid_len);
4620Sstevel@tonic-gate
4630Sstevel@tonic-gate err = modify_dd_entry(dh[table], dnp, &ndn);
4640Sstevel@tonic-gate
4650Sstevel@tonic-gate TNF_PROBE_1(work_modify2_end, "work work_modify2_end",
4660Sstevel@tonic-gate "work_modify2_end%debug 'in function work'",
4670Sstevel@tonic-gate tnf_ulong, err, err);
4680Sstevel@tonic-gate
4690Sstevel@tonic-gate if (err != DSVC_SUCCESS && verbose) {
4700Sstevel@tonic-gate fprintf(stderr, "work: %d %d error %d\n",
4710Sstevel@tonic-gate wtype, op, err);
4720Sstevel@tonic-gate }
4730Sstevel@tonic-gate *dnp = ndn;
4740Sstevel@tonic-gate break;
4750Sstevel@tonic-gate }
4760Sstevel@tonic-gate break;
4770Sstevel@tonic-gate
4780Sstevel@tonic-gate
4790Sstevel@tonic-gate default:
4800Sstevel@tonic-gate ndn = *dnp;
4810Sstevel@tonic-gate ndn.dn_cid_len = cid_len;
4820Sstevel@tonic-gate switch (random() & 0x1) {
4830Sstevel@tonic-gate case 0:
4840Sstevel@tonic-gate for (j = 0; j < cid_len; j++)
4850Sstevel@tonic-gate ndn.dn_cid[j] = random() & 0xff;
4860Sstevel@tonic-gate break;
4870Sstevel@tonic-gate case 1:
4880Sstevel@tonic-gate for (j = 0; j < cid_len; j++)
4890Sstevel@tonic-gate ndn.dn_cid[j] = '\0';
4900Sstevel@tonic-gate ndn.dn_cid_len = 1;
4910Sstevel@tonic-gate break;
4920Sstevel@tonic-gate }
4930Sstevel@tonic-gate ndn.dn_lease = htonl(time(NULL));
4940Sstevel@tonic-gate
4950Sstevel@tonic-gate /* LINTED */
4960Sstevel@tonic-gate TNF_PROBE_2(work_modify, "work work_modify",
4970Sstevel@tonic-gate "work_modify%debug 'in function work'",
4980Sstevel@tonic-gate tnf_ulong, cid, *(ulong_t *)&ndn.dn_cid,
4990Sstevel@tonic-gate tnf_ulong, cid_len, ndn.dn_cid_len);
5000Sstevel@tonic-gate
5010Sstevel@tonic-gate err = modify_dd_entry(dh[table], dnp, &ndn);
5020Sstevel@tonic-gate if (err != DSVC_SUCCESS && err != DSVC_COLLISION) {
5030Sstevel@tonic-gate if (verbose)
5040Sstevel@tonic-gate fprintf(stderr, "modify: error %d\n", err);
5050Sstevel@tonic-gate }
5060Sstevel@tonic-gate
5070Sstevel@tonic-gate TNF_PROBE_1(work_modify_end, "work work_modify_end",
5080Sstevel@tonic-gate "work_modify_end%debug 'in function work'",
5090Sstevel@tonic-gate tnf_ulong, err, err);
5100Sstevel@tonic-gate
5110Sstevel@tonic-gate *dnp = ndn;
5120Sstevel@tonic-gate break;
5130Sstevel@tonic-gate }
5140Sstevel@tonic-gate
5150Sstevel@tonic-gate if (domalloc)
5160Sstevel@tonic-gate free(ptr);
5170Sstevel@tonic-gate
5180Sstevel@tonic-gate if (wptr->isthreaded) {
5190Sstevel@tonic-gate (void) mutex_unlock(&wptr->mtx);
5200Sstevel@tonic-gate cond_signal(&wptr->cv);
5210Sstevel@tonic-gate TNF_PROBE_2(work_end, "work", "work_end%debug 'in function "
5220Sstevel@tonic-gate "work'", tnf_ulong, err, err,
5230Sstevel@tonic-gate tnf_ulong, crecords, crecords);
5240Sstevel@tonic-gate thr_exit(NULL);
5250Sstevel@tonic-gate }
5260Sstevel@tonic-gate if (dncp)
5270Sstevel@tonic-gate free_dd_list(dh[table], dncp);
5280Sstevel@tonic-gate
5290Sstevel@tonic-gate TNF_PROBE_2(work_end, "work", "work_end%debug 'in function work'",
5300Sstevel@tonic-gate tnf_ulong, err, err,
5310Sstevel@tonic-gate tnf_ulong, crecords, crecords);
5320Sstevel@tonic-gate
5330Sstevel@tonic-gate return ((void *) NULL);
5340Sstevel@tonic-gate }
5350Sstevel@tonic-gate
5360Sstevel@tonic-gate /*
5370Sstevel@tonic-gate * Worker thread.
5380Sstevel@tonic-gate */
5390Sstevel@tonic-gate static void *
dowork(void * argp)5400Sstevel@tonic-gate dowork(void *argp)
5410Sstevel@tonic-gate {
5420Sstevel@tonic-gate int i = (int)argp;
5430Sstevel@tonic-gate timestruc_t to;
5440Sstevel@tonic-gate work_t *wptr;
5450Sstevel@tonic-gate dn_rec_t dn;
5460Sstevel@tonic-gate
5470Sstevel@tonic-gate (void) memset((char *)&dn, '\0', sizeof (dn));
5480Sstevel@tonic-gate (void) mutex_lock(&mtx);
5490Sstevel@tonic-gate for (; time_to_go == 0; ) {
5500Sstevel@tonic-gate TNF_PROBE_1(dowork, "dowork",
5510Sstevel@tonic-gate "dowork%debug 'in function dowork'",
5520Sstevel@tonic-gate tnf_long, thread_number, i);
5530Sstevel@tonic-gate
5540Sstevel@tonic-gate to.tv_sec = time(NULL) + random() & 0x3;
5550Sstevel@tonic-gate to.tv_nsec = 0;
5560Sstevel@tonic-gate
5570Sstevel@tonic-gate if (slp > 0.0) {
5580Sstevel@tonic-gate to.tv_sec = time(NULL) + slp;
5590Sstevel@tonic-gate to.tv_nsec = (slp - (double)((int)slp)) * 1000000000.0;
5600Sstevel@tonic-gate } else if (slp < 0.0) {
5610Sstevel@tonic-gate to.tv_sec = time(NULL) + abs((int)slp);
5620Sstevel@tonic-gate to.tv_nsec = (slp + abs((double)((int)slp))) *
5630Sstevel@tonic-gate 1000000000.0;
5640Sstevel@tonic-gate }
5650Sstevel@tonic-gate /* give up processor */
5660Sstevel@tonic-gate if (slp != 0.0) {
5670Sstevel@tonic-gate (void) mutex_unlock(&mtx);
5680Sstevel@tonic-gate (void) cond_timedwait(&never, &mtx, &to);
5690Sstevel@tonic-gate }
5700Sstevel@tonic-gate ops_outstanding++;
5710Sstevel@tonic-gate (void) mutex_unlock(&mtx);
5720Sstevel@tonic-gate
5730Sstevel@tonic-gate if (spawn_helper) {
5740Sstevel@tonic-gate wptr = (work_t *)malloc(sizeof (work_t));
5750Sstevel@tonic-gate wptr->thread = i * 2;
5760Sstevel@tonic-gate wptr->isthreaded = B_TRUE;
5770Sstevel@tonic-gate (void) cond_init(&wptr->cv, USYNC_THREAD, NULL);
5780Sstevel@tonic-gate (void) mutex_init(&wptr->mtx, USYNC_THREAD, NULL);
5790Sstevel@tonic-gate (void) mutex_lock(&wptr->mtx);
5800Sstevel@tonic-gate
5810Sstevel@tonic-gate /* fire up helper thread */
5820Sstevel@tonic-gate if (thr_create(NULL, 0, douwork ? uwork : work,
5830Sstevel@tonic-gate (void *)wptr, 0, &tp[i * 2]) != 0)
5840Sstevel@tonic-gate fprintf(stderr, "can't spawn lthread %d\n", i);
5850Sstevel@tonic-gate
5860Sstevel@tonic-gate /* wait for completion */
5870Sstevel@tonic-gate (void) cond_wait(&wptr->cv, &wptr->mtx);
5880Sstevel@tonic-gate (void) mutex_unlock(&wptr->mtx);
5890Sstevel@tonic-gate (void) thr_join(tp[i * 2], NULL, NULL);
5900Sstevel@tonic-gate free_work_t(wptr);
5910Sstevel@tonic-gate } else {
5920Sstevel@tonic-gate wptr = (work_t *)malloc(sizeof (work_t));
5930Sstevel@tonic-gate wptr->isthreaded = B_FALSE;
5940Sstevel@tonic-gate wptr->thread = i;
5950Sstevel@tonic-gate wptr->dnp = &dn;
5960Sstevel@tonic-gate if (douwork) {
5970Sstevel@tonic-gate (void) uwork((void *)wptr);
5980Sstevel@tonic-gate } else {
5990Sstevel@tonic-gate (void) work((void *)wptr);
6000Sstevel@tonic-gate }
6010Sstevel@tonic-gate free_work_t(wptr);
6020Sstevel@tonic-gate }
6030Sstevel@tonic-gate (void) mutex_lock(&mtx);
6040Sstevel@tonic-gate tops++;
6050Sstevel@tonic-gate ops_outstanding--;
6060Sstevel@tonic-gate TNF_PROBE_0(dowork_end, "dowork", "");
6070Sstevel@tonic-gate }
6080Sstevel@tonic-gate (void) mutex_unlock(&mtx);
6090Sstevel@tonic-gate thr_exit(NULL);
6100Sstevel@tonic-gate
6110Sstevel@tonic-gate return ((void *) NULL);
6120Sstevel@tonic-gate }
6130Sstevel@tonic-gate
6140Sstevel@tonic-gate /*
6150Sstevel@tonic-gate * Signal handler routine. All signals handled by calling thread.
6160Sstevel@tonic-gate */
6170Sstevel@tonic-gate /* ARGSUSED */
6180Sstevel@tonic-gate static void *
sig_handle(void * arg)6190Sstevel@tonic-gate sig_handle(void *arg)
6200Sstevel@tonic-gate {
6210Sstevel@tonic-gate int i;
6220Sstevel@tonic-gate int sig;
6230Sstevel@tonic-gate sigset_t set;
6240Sstevel@tonic-gate timespec_t ts;
6250Sstevel@tonic-gate siginfo_t si;
6260Sstevel@tonic-gate int go;
6270Sstevel@tonic-gate int oldi;
6280Sstevel@tonic-gate ulong_t minavg;
6290Sstevel@tonic-gate time_t minstime;
6300Sstevel@tonic-gate
6310Sstevel@tonic-gate (void) sigfillset(&set); /* catch all signals */
6320Sstevel@tonic-gate
6330Sstevel@tonic-gate ts.tv_sec = sample_time;
6340Sstevel@tonic-gate ts.tv_nsec = 0L;
6350Sstevel@tonic-gate
6360Sstevel@tonic-gate for (;;) {
6370Sstevel@tonic-gate (void) mutex_lock(&mtx);
6380Sstevel@tonic-gate go = time_to_go;
6390Sstevel@tonic-gate (void) mutex_unlock(&mtx);
6400Sstevel@tonic-gate if (go)
6410Sstevel@tonic-gate break;
6420Sstevel@tonic-gate
6430Sstevel@tonic-gate switch (sig = sigtimedwait(&set, &si, &ts)) {
6440Sstevel@tonic-gate case -1:
6450Sstevel@tonic-gate case SIGHUP:
6460Sstevel@tonic-gate old = time(NULL);
6470Sstevel@tonic-gate oldi = new = unstarted = 0;
6480Sstevel@tonic-gate for (i = 0; i < threads; i++) {
6490Sstevel@tonic-gate if (timp[i] == NULL)
6500Sstevel@tonic-gate unstarted++;
6510Sstevel@tonic-gate if (timp[i] && timp[i] < old) {
6520Sstevel@tonic-gate old = timp[i];
6530Sstevel@tonic-gate oldi = i;
6540Sstevel@tonic-gate }
6550Sstevel@tonic-gate if (timp[i] && timp[i] > new)
6560Sstevel@tonic-gate new = timp[i];
6570Sstevel@tonic-gate }
6580Sstevel@tonic-gate
6590Sstevel@tonic-gate if (start == 0) {
6600Sstevel@tonic-gate /* toss initial sample */
6610Sstevel@tonic-gate ostart = start = time(NULL);
6620Sstevel@tonic-gate (void) mutex_lock(&mtx);
6630Sstevel@tonic-gate otops = tops = 0;
6640Sstevel@tonic-gate (void) mutex_unlock(&mtx);
6650Sstevel@tonic-gate minind = 0;
6660Sstevel@tonic-gate } else {
6670Sstevel@tonic-gate minops[minind] = tops - otops;
6680Sstevel@tonic-gate mintim[minind] = ostart;
6690Sstevel@tonic-gate otops = tops;
6700Sstevel@tonic-gate ostart = time(NULL);
6710Sstevel@tonic-gate minind = minind + 1 > nsamples - 1 ? 0 :
6720Sstevel@tonic-gate minind + 1;
6730Sstevel@tonic-gate minstime = 0;
6740Sstevel@tonic-gate minavg = 0;
6750Sstevel@tonic-gate for (i = 0; i < nsamples; i++) {
6760Sstevel@tonic-gate if (mintim[i])
6770Sstevel@tonic-gate minavg += minops[i];
6780Sstevel@tonic-gate if (minstime == 0)
6790Sstevel@tonic-gate minstime = mintim[i];
6800Sstevel@tonic-gate else if (mintim[i] &&
6810Sstevel@tonic-gate mintim[i] < minstime)
6820Sstevel@tonic-gate minstime = mintim[i];
6830Sstevel@tonic-gate }
6840Sstevel@tonic-gate
6850Sstevel@tonic-gate fprintf(stderr, "%9.9d: Totops %d Curr %d "\
6860Sstevel@tonic-gate "Persec %4.2f (%4.2f) Oldest %d (%d) "\
6870Sstevel@tonic-gate "Gap %d Unstarted %d\n",
6880Sstevel@tonic-gate time(NULL),
6890Sstevel@tonic-gate tops,
6900Sstevel@tonic-gate ops_outstanding,
6910Sstevel@tonic-gate (double)tops / (double)(time(NULL)
6920Sstevel@tonic-gate - start),
6930Sstevel@tonic-gate (double)minavg / (double)(time(NULL)
6940Sstevel@tonic-gate - minstime),
6950Sstevel@tonic-gate time(NULL) - old,
6960Sstevel@tonic-gate oldi,
6970Sstevel@tonic-gate new - old,
6980Sstevel@tonic-gate unstarted);
6990Sstevel@tonic-gate }
7000Sstevel@tonic-gate break;
7010Sstevel@tonic-gate default:
7020Sstevel@tonic-gate (void) mutex_lock(&mtx);
7030Sstevel@tonic-gate time_to_go++;
7040Sstevel@tonic-gate (void) mutex_unlock(&mtx);
7050Sstevel@tonic-gate break;
7060Sstevel@tonic-gate }
7070Sstevel@tonic-gate }
7080Sstevel@tonic-gate thr_exit(NULL);
7090Sstevel@tonic-gate return ((void *) sig); /* NOTREACHED */
7100Sstevel@tonic-gate }
7110Sstevel@tonic-gate
7120Sstevel@tonic-gate int fd[0x10000];
7130Sstevel@tonic-gate /*
7140Sstevel@tonic-gate * open handler routine.
7150Sstevel@tonic-gate */
7160Sstevel@tonic-gate /* ARGSUSED */
7170Sstevel@tonic-gate static void *
open_handle(void * arg)7180Sstevel@tonic-gate open_handle(void *arg)
7190Sstevel@tonic-gate {
7200Sstevel@tonic-gate int i;
7210Sstevel@tonic-gate
7220Sstevel@tonic-gate for (;;) {
7230Sstevel@tonic-gate for (i = 0; i < doopen; i++)
7240Sstevel@tonic-gate fd[i] = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
7250Sstevel@tonic-gate for (i = 0; i < doopen; i++)
7260Sstevel@tonic-gate if (fd[i] >= 0)
7270Sstevel@tonic-gate (void) close(fd[i]);
7280Sstevel@tonic-gate }
7290Sstevel@tonic-gate return ((void *) NULL); /* NOTREACHED */
7300Sstevel@tonic-gate }
7310Sstevel@tonic-gate /*
7320Sstevel@tonic-gate * test_dstore network[,network] worktype[,worktype] <thr_create flags>
7330Sstevel@tonic-gate * <spawn_helper> <nlwp> <nthread> <file> <sleeptype>
7340Sstevel@tonic-gate *
7350Sstevel@tonic-gate * network - list of network containers, comma-separated
7360Sstevel@tonic-gate * worktypes:
7370Sstevel@tonic-gate * 0 - random
7380Sstevel@tonic-gate * 1 - cid reads
7390Sstevel@tonic-gate * 2 - cip reads
7400Sstevel@tonic-gate * 3 - whole db reads
7410Sstevel@tonic-gate * 4 - write read write (simulate simple test)
7420Sstevel@tonic-gate * 5 - modify writes
7430Sstevel@tonic-gate * sleeptypes:
7440Sstevel@tonic-gate * N == * condwait N sec.nsec period
7450Sstevel@tonic-gate * -N == condwait a random 1-N sec.nsec period
7460Sstevel@tonic-gate */
main(int c,char ** v)7470Sstevel@tonic-gate main(int c, char **v)
7480Sstevel@tonic-gate {
7490Sstevel@tonic-gate int i;
7500Sstevel@tonic-gate timespec_t to;
7510Sstevel@tonic-gate uint_t flags;
7520Sstevel@tonic-gate int err;
7530Sstevel@tonic-gate sigset_t set;
7540Sstevel@tonic-gate dhcp_confopt_t *dsp = NULL;
7550Sstevel@tonic-gate uint32_t query;
7560Sstevel@tonic-gate dn_rec_t dn;
7570Sstevel@tonic-gate dn_rec_list_t *dncp = NULL;
7580Sstevel@tonic-gate struct rlimit rl;
7590Sstevel@tonic-gate char *np;
7600Sstevel@tonic-gate
7610Sstevel@tonic-gate #ifdef DEBUG
7620Sstevel@tonic-gate mallocctl(MTDEBUGPATTERN, 1);
7630Sstevel@tonic-gate mallocctl(MTINITBUFFER, 1);
7640Sstevel@tonic-gate #endif /* DEBUG */
7650Sstevel@tonic-gate
7660Sstevel@tonic-gate srandom(time(NULL));
7670Sstevel@tonic-gate
7680Sstevel@tonic-gate if (dofork)
7690Sstevel@tonic-gate if (fork() != 0)
7700Sstevel@tonic-gate exit(0);
7710Sstevel@tonic-gate
7720Sstevel@tonic-gate if ((err = getrlimit(RLIMIT_NOFILE, &rl)) < 0) {
7730Sstevel@tonic-gate (void) fprintf(stderr, "Cannot get open file limit: %s\n",
7740Sstevel@tonic-gate strerror(errno));
7750Sstevel@tonic-gate }
7760Sstevel@tonic-gate /* handle cases where limit is infinity */
7770Sstevel@tonic-gate if (rl.rlim_cur == RLIM_INFINITY) {
7780Sstevel@tonic-gate rl.rlim_cur = (rl.rlim_max == RLIM_INFINITY) ?
7790Sstevel@tonic-gate OPEN_MAX : rl.rlim_max;
7800Sstevel@tonic-gate }
7810Sstevel@tonic-gate /* set NOFILE to unlimited */
7820Sstevel@tonic-gate rl.rlim_cur = rl.rlim_max = RLIM_INFINITY;
7830Sstevel@tonic-gate if ((err = setrlimit(RLIMIT_NOFILE, &rl)) < 0) {
7840Sstevel@tonic-gate (void) fprintf(stderr, "Cannot set open file limit: %s\n",
7850Sstevel@tonic-gate strerror(errno));
7860Sstevel@tonic-gate }
787*1914Scasper (void) enable_extended_FILE_stdio(-1, -1);
788*1914Scasper
7890Sstevel@tonic-gate if (c == 1) {
7900Sstevel@tonic-gate (void) fprintf(stderr,
7910Sstevel@tonic-gate "/*\n"\
7920Sstevel@tonic-gate " * test_dstore network[,network] worktype[,"\
7930Sstevel@tonic-gate "worktype] <thr_create flags>\n"\
7940Sstevel@tonic-gate " * <spawn_helper> <nlwp> <nthread> "\
7950Sstevel@tonic-gate "<file> <sleeptype>\n"\
7960Sstevel@tonic-gate " *\n"\
7970Sstevel@tonic-gate " * network - list of network containers, "\
7980Sstevel@tonic-gate "comma-separated\n"\
7990Sstevel@tonic-gate " * worktypes:\n"\
8000Sstevel@tonic-gate " * 0 - random\n"\
8010Sstevel@tonic-gate " * 1 - cid reads\n"\
8020Sstevel@tonic-gate " * 2 - cip reads\n"\
8030Sstevel@tonic-gate " * 3 - whole db reads\n"\
8040Sstevel@tonic-gate " * 4 - write read write (simulate simple"\
8050Sstevel@tonic-gate " test)\n"\
8060Sstevel@tonic-gate " * 5 - modify writes\n"\
8070Sstevel@tonic-gate " * sleeptypes:\n"\
8080Sstevel@tonic-gate " * N == * condwait N sec.nsec period\n"\
8090Sstevel@tonic-gate " * -N == condwait a random 1-N sec.nsec "\
8100Sstevel@tonic-gate "period\n"\
8110Sstevel@tonic-gate " */\n");
8120Sstevel@tonic-gate return (0);
8130Sstevel@tonic-gate }
8140Sstevel@tonic-gate network = v[1];
8150Sstevel@tonic-gate
8160Sstevel@tonic-gate worktype = strtoul(v[2], 0L, 0L);
8170Sstevel@tonic-gate flags = strtoul(v[3], 0L, 0L);
8180Sstevel@tonic-gate spawn_helper = strtoul(v[4], 0L, 0L);
8190Sstevel@tonic-gate if (strtoul(v[5], 0L, 0L) > 0)
8200Sstevel@tonic-gate (void) thr_setconcurrency(strtoul(v[5], 0L, 0L));
8210Sstevel@tonic-gate threads = strtoul(v[6], 0L, 0L);
8220Sstevel@tonic-gate fl = v[7];
8230Sstevel@tonic-gate if (c > 8)
8240Sstevel@tonic-gate slp = atof(v[8]);
8250Sstevel@tonic-gate
8260Sstevel@tonic-gate if (douwork == 0) {
8270Sstevel@tonic-gate /* Load current datastore. */
8280Sstevel@tonic-gate (void) read_dsvc_conf(&dsp);
8290Sstevel@tonic-gate if ((i = confopt_to_datastore(dsp, &datastore))
8300Sstevel@tonic-gate != DSVC_SUCCESS) {
8310Sstevel@tonic-gate (void) fprintf(stderr, "Invalid datastore: %s\n",
8320Sstevel@tonic-gate dhcpsvc_errmsg(i));
8330Sstevel@tonic-gate return (EINVAL);
8340Sstevel@tonic-gate }
8350Sstevel@tonic-gate for (i = 0, np = strtok(network, ","); np; i++,
8360Sstevel@tonic-gate np = strtok(NULL, ",")) {
8370Sstevel@tonic-gate net[i].s_addr = inet_addr(np);
8380Sstevel@tonic-gate
8390Sstevel@tonic-gate err = open_dd(&dh[i], &datastore, DSVC_DHCPNETWORK, np,
8400Sstevel@tonic-gate DSVC_READ | DSVC_WRITE);
8410Sstevel@tonic-gate
8420Sstevel@tonic-gate if (err != DSVC_SUCCESS) {
8430Sstevel@tonic-gate (void) fprintf(stderr, "Invalid network: "\
8440Sstevel@tonic-gate "%s %s\n", np,
8450Sstevel@tonic-gate dhcpsvc_errmsg(err));
8460Sstevel@tonic-gate return (err);
8470Sstevel@tonic-gate }
8480Sstevel@tonic-gate /*
8490Sstevel@tonic-gate * XXXX: bug: currently can't get the count as
8500Sstevel@tonic-gate * advertised
8510Sstevel@tonic-gate */
8520Sstevel@tonic-gate (void) memset(&dn, '\0', sizeof (dn));
8530Sstevel@tonic-gate DSVC_QINIT(query);
8540Sstevel@tonic-gate err = lookup_dd(dh[i], B_FALSE, query, -1,
8550Sstevel@tonic-gate (const void *) &dn, (void **) &dncp,
8560Sstevel@tonic-gate &nrecords[i]);
8570Sstevel@tonic-gate if (dncp)
8580Sstevel@tonic-gate free_dd_list(dh[i], dncp);
8590Sstevel@tonic-gate
8600Sstevel@tonic-gate if (err != DSVC_SUCCESS) {
8610Sstevel@tonic-gate (void) fprintf(stderr, "Bad nrecords: %s "
8620Sstevel@tonic-gate "[%d]\n", dhcpsvc_errmsg(err),
8630Sstevel@tonic-gate nrecords[i]);
8640Sstevel@tonic-gate return (err);
8650Sstevel@tonic-gate }
8660Sstevel@tonic-gate }
8670Sstevel@tonic-gate ntable = i;
8680Sstevel@tonic-gate }
8690Sstevel@tonic-gate TNF_PROBE_2(main, "main",
8700Sstevel@tonic-gate "main%debug 'in function main'",
8710Sstevel@tonic-gate tnf_ulong, threads, threads,
8720Sstevel@tonic-gate tnf_ulong, nrecords, nrecords[i]);
8730Sstevel@tonic-gate
8740Sstevel@tonic-gate (void) sigfillset(&set);
8750Sstevel@tonic-gate
8760Sstevel@tonic-gate (void) sigdelset(&set, SIGABRT); /* allow for user abort */
8770Sstevel@tonic-gate
8780Sstevel@tonic-gate (void) thr_sigsetmask(SIG_SETMASK, &set, NULL);
8790Sstevel@tonic-gate
8800Sstevel@tonic-gate tms = threads * sizeof (thread_t);
8810Sstevel@tonic-gate if (spawn_helper)
8820Sstevel@tonic-gate tms *= 2;
8830Sstevel@tonic-gate tp = malloc(tms);
8840Sstevel@tonic-gate tms = (threads * sizeof (time_t) + 0x200) & ~(0x200 - 1);
8850Sstevel@tonic-gate if (spawn_helper)
8860Sstevel@tonic-gate tms *= 2;
8870Sstevel@tonic-gate timp = malloc(tms);
8880Sstevel@tonic-gate (void) memset((char *)timp, NULL, tms);
8890Sstevel@tonic-gate
8900Sstevel@tonic-gate (void) mutex_init(&mtx, USYNC_THREAD, 0);
8910Sstevel@tonic-gate
8920Sstevel@tonic-gate /*
8930Sstevel@tonic-gate * Create signal handling thread. XXXX: due to threads library
8940Sstevel@tonic-gate * limitations, this must currently be directly called in the main
8950Sstevel@tonic-gate * program thread.
8960Sstevel@tonic-gate */
8970Sstevel@tonic-gate if ((err = thr_create(NULL, 0, sig_handle, NULL,
8980Sstevel@tonic-gate THR_NEW_LWP | THR_DAEMON | THR_BOUND |
8990Sstevel@tonic-gate THR_DETACHED, &sigthread)) != 0) {
9000Sstevel@tonic-gate (void) fprintf(stderr,
9010Sstevel@tonic-gate gettext("Cannot start signal handling thread, error: %d\n"),
9020Sstevel@tonic-gate err);
9030Sstevel@tonic-gate return (err);
9040Sstevel@tonic-gate }
9050Sstevel@tonic-gate for (i = 0; i < threads; i++)
9060Sstevel@tonic-gate /* fire up monitor thread */
9070Sstevel@tonic-gate if (thr_create(NULL, 0, dowork, (void *) i,
9080Sstevel@tonic-gate flags, &tp[i]) != 0)
9090Sstevel@tonic-gate fprintf(stderr, "can't spawn thread %d\n", i);
9100Sstevel@tonic-gate
9110Sstevel@tonic-gate /*
9120Sstevel@tonic-gate * Create open handling thread.
9130Sstevel@tonic-gate */
9140Sstevel@tonic-gate if (doopen && (err = thr_create(NULL, 0, open_handle, NULL,
9150Sstevel@tonic-gate THR_NEW_LWP | THR_DAEMON | THR_BOUND | THR_DETACHED,
9160Sstevel@tonic-gate &opnthread)) != 0) {
9170Sstevel@tonic-gate (void) fprintf(stderr,
9180Sstevel@tonic-gate gettext("Cannot start open handling thread, error: %d\n"),
9190Sstevel@tonic-gate err);
9200Sstevel@tonic-gate return (err);
9210Sstevel@tonic-gate }
9220Sstevel@tonic-gate
9230Sstevel@tonic-gate (void) mutex_lock(&mtx);
9240Sstevel@tonic-gate for (; time_to_go == 0; ) {
9250Sstevel@tonic-gate to.tv_sec = time(NULL) + 10;
9260Sstevel@tonic-gate to.tv_nsec = 0L;
9270Sstevel@tonic-gate (void) cond_timedwait(&never, &mtx, &to);
9280Sstevel@tonic-gate (void) mutex_unlock(&mtx);
9290Sstevel@tonic-gate }
9300Sstevel@tonic-gate
9310Sstevel@tonic-gate /*
9320Sstevel@tonic-gate * Attempt to join threads.
9330Sstevel@tonic-gate */
9340Sstevel@tonic-gate for (i = 0; i < threads; i++)
9350Sstevel@tonic-gate (void) thr_join(tp[i], NULL, NULL);
9360Sstevel@tonic-gate
9370Sstevel@tonic-gate (void) sleep(5);
9380Sstevel@tonic-gate
9390Sstevel@tonic-gate TNF_PROBE_0(main_end, "main", "");
9400Sstevel@tonic-gate
9410Sstevel@tonic-gate return (0);
9420Sstevel@tonic-gate }
943