static void query_usetcp(adns_query qu, struct timeval now) { qu->state= query_tcpw; qu->timeout= now; timevaladd(&qu->timeout,TCPWAITMS); LIST_LINK_TAIL(qu->ads->tcpw,qu); adns__querysend_tcp(qu,now); adns__tcp_tryconnect(qu->ads,now); }
isc_result_t isc_mutex_unlock_profile(isc_mutex_t *mp, const char *file, int line) { struct timeval unlock_t; UNUSED(file); UNUSED(line); if (mp->stats->cur_locker != NULL) { gettimeofday(&unlock_t, NULL); timevalsub(&unlock_t, &mp->stats->lock_t); timevaladd(&mp->stats->locked_total, &unlock_t); timevaladd(&mp->stats->cur_locker->locked_total, &unlock_t); mp->stats->cur_locker = NULL; } return ((pthread_mutex_unlock((&mp->mutex)) == 0) ? \ ISC_R_SUCCESS : ISC_R_UNEXPECTED); }
isc_result_t isc_mutex_lock_profile(isc_mutex_t *mp, const char *file, int line) { struct timeval prelock_t; struct timeval postlock_t; isc_mutexlocker_t *locker = NULL; int i; gettimeofday(&prelock_t, NULL); if (pthread_mutex_lock(&mp->mutex) != 0) return (ISC_R_UNEXPECTED); gettimeofday(&postlock_t, NULL); mp->stats->lock_t = postlock_t; timevalsub(&postlock_t, &prelock_t); mp->stats->count++; timevaladd(&mp->stats->wait_total, &postlock_t); for (i = 0; i < ISC_MUTEX_MAX_LOCKERS; i++) { if (mp->stats->lockers[i].file == NULL) { locker = &mp->stats->lockers[i]; locker->file = file; locker->line = line; break; } else if (mp->stats->lockers[i].file == file && mp->stats->lockers[i].line == line) { locker = &mp->stats->lockers[i]; break; } } if (locker != NULL) { locker->count++; timevaladd(&locker->wait_total, &postlock_t); } mp->stats->cur_locker = locker; return (ISC_R_SUCCESS); }
void adns__query_send( adns_query qu, struct timeval now ) { struct sockaddr_in servaddr; int serv, r; adns_state ads; assert( qu->state == query_tosend ); if( ( qu->flags & adns_qf_usevc ) || ( qu->query_dglen > DNS_MAXUDP ) ) { query_usetcp( qu, now ); return; } if( qu->retries >= UDPMAXRETRIES ) { adns__query_fail( qu, adns_s_timeout ); return; } serv = qu->udpnextserver; os_memset( &servaddr, 0, sizeof( servaddr ) ); ads = qu->ads; servaddr.sin_family = AF_INET; servaddr.sin_addr = ads->servers[serv].addr; servaddr.sin_port = htons(DNS_PORT); r = os_sock_sendto( ads->udpsocket, (char *)qu->query_dgram, qu->query_dglen, 0, ( const struct sockaddr * ) &servaddr, sizeof( servaddr ) ); if( r < 0 && os_sock_errno == OS_SOCK_EMSGSIZE ) { qu->retries = 0; query_usetcp( qu, now ); return; } if( r < 0 && os_sock_errno!= OS_SOCK_EAGAIN ) adns__warn( ads, serv, 0, "sendto failed: %s", os_sock_getlasterrorstring() ); qu->timeout = now; timevaladd( &qu->timeout, UDPRETRYMS ); qu->udpsent |= ( 1 << serv ); qu->udpnextserver = ( serv + 1 ) % ads->nservers; qu->retries++; ALIST_LINK_TAIL( ads->udpw, qu ); }
static int pmtimer_resume(device_t dev) { int pl; u_int second, minute, hour; struct timeval resume_time, tmp_time; /* modified for adjkerntz */ pl = splsoftclock(); timer_restore(); /* restore the all timers */ inittodr(0); /* adjust time to RTC */ microtime(&resume_time); getmicrotime(&tmp_time); timevaladd(&tmp_time, &diff_time); #ifdef FIXME /* XXX THIS DOESN'T WORK!!! */ time = tmp_time; #endif #ifdef PMTIMER_FIXUP_CALLTODO /* Calculate the delta time suspended */ timevalsub(&resume_time, &suspend_time); /* Fixup the calltodo list with the delta time. */ adjust_timeout_calltodo(&resume_time); #endif /* PMTIMER_FIXUP_CALLTODOK */ splx(pl); #ifndef PMTIMER_FIXUP_CALLTODO second = resume_time.tv_sec - suspend_time.tv_sec; #else /* PMTIMER_FIXUP_CALLTODO */ /* * We've already calculated resume_time to be the delta between * the suspend and the resume. */ second = resume_time.tv_sec; #endif /* PMTIMER_FIXUP_CALLTODO */ hour = second / 3600; second %= 3600; minute = second / 60; second %= 60; log(LOG_NOTICE, "wakeup from sleeping state (slept %02d:%02d:%02d)\n", hour, minute, second); return (0); }
int nanosleep(const struct timespec *ts, struct timespec *rts) { struct timeval timeout, endtime, now; int rval; timeout.tv_sec = ts->tv_sec; timeout.tv_usec = ts->tv_nsec / 1000; if (rts != NULL) { gettimeofday(&endtime, NULL); timevaladd(&endtime, &timeout); } rval = select(0, NULL, NULL, NULL, &timeout); if (rts != NULL && rval == -1 && errno == EINTR) { gettimeofday(&now, NULL); timevalsub(&endtime, &now); rts->tv_sec = endtime.tv_sec; rts->tv_nsec = endtime.tv_usec * 1000; } return rval; }
int nandbus_wait_ready(device_t dev, uint8_t *status) { struct timeval tv, tv2; tv2.tv_sec = 0; tv2.tv_usec = 50 * 5000; /* 250ms */ getmicrotime(&tv); timevaladd(&tv, &tv2); do { if (NANDBUS_GET_STATUS(dev, status)) return (ENXIO); if (*status & NAND_STATUS_RDY) return (0); getmicrotime(&tv2); } while (timevalcmp(&tv2, &tv, <=)); return (EBUSY); }
static int nandsim_delay(struct nandsim_chip *chip, int timeout) { struct nandsim_ev *ev; struct timeval delay; int tm; nand_debug(NDBG_SIM,"Chip[%d] Set delay: %d", chip->chip_num, timeout); ev = create_event(chip, NANDSIM_EV_TIMEOUT, 0); if (!ev) return (-1); chip->sm_state = NANDSIM_STATE_TIMEOUT; tm = (timeout/10000) * (hz / 100); if (callout_reset(&chip->ns_callout, tm, nandsim_callout_eh, ev)) return (-1); delay.tv_sec = chip->read_delay / 1000000; delay.tv_usec = chip->read_delay % 1000000; timevaladd(&chip->delay_tv, &delay); return (0); }
ACPI_STATUS AcpiOsWaitSemaphore(ACPI_HANDLE Handle, UINT32 Units, UINT16 Timeout) { #ifndef ACPI_NO_SEMAPHORES ACPI_STATUS result; struct acpi_semaphore *as = (struct acpi_semaphore *)Handle; int rv, tmo; struct timeval timeouttv, currenttv, timelefttv; AS_LOCK_DECL; ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); if (as == NULL) return_ACPI_STATUS (AE_BAD_PARAMETER); if (cold) return_ACPI_STATUS (AE_OK); #if 0 if (as->as_units < Units && as->as_timeouts > 10) { kprintf("%s: semaphore %p too many timeouts, resetting\n", __func__, as); AS_LOCK(as); as->as_units = as->as_maxunits; if (as->as_pendings) as->as_resetting = 1; as->as_timeouts = 0; wakeup(as); AS_UNLOCK(as); return_ACPI_STATUS (AE_TIME); } if (as->as_resetting) return_ACPI_STATUS (AE_TIME); #endif /* a timeout of ACPI_WAIT_FOREVER means "forever" */ if (Timeout == ACPI_WAIT_FOREVER) { tmo = 0; timeouttv.tv_sec = ((0xffff/1000) + 1); /* cf. ACPI spec */ timeouttv.tv_usec = 0; } else { /* compute timeout using microseconds per tick */ tmo = (Timeout * 1000) / (1000000 / hz); if (tmo <= 0) tmo = 1; timeouttv.tv_sec = Timeout / 1000; timeouttv.tv_usec = (Timeout % 1000) * 1000; } /* calculate timeout value in timeval */ getmicrouptime(¤ttv); timevaladd(&timeouttv, ¤ttv); AS_LOCK(as); ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, "get %d units from semaphore %p (has %d), timeout %d\n", Units, as, as->as_units, Timeout)); for (;;) { if (as->as_maxunits == ACPI_NO_UNIT_LIMIT) { result = AE_OK; break; } if (as->as_units >= Units) { as->as_units -= Units; result = AE_OK; break; } /* limit number of pending treads */ if (as->as_pendings >= ACPI_SEMAPHORES_MAX_PENDING) { result = AE_TIME; break; } /* if timeout values of zero is specified, return immediately */ if (Timeout == 0) { result = AE_TIME; break; } ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, "semaphore blocked, calling ssleep(%p, %p, %d, \"acsem\", %d)\n", as, &as->as_spin, PCATCH, tmo)); as->as_pendings++; if (acpi_semaphore_debug) { kprintf("%s: Sleep %jd, pending %jd, semaphore %p, thread %jd\n", __func__, (intmax_t)Timeout, (intmax_t)as->as_pendings, as, (intmax_t)AcpiOsGetThreadId()); } rv = ssleep(as, &as->as_spin, PCATCH, "acsem", tmo); as->as_pendings--; #if 0 if (as->as_resetting) { /* semaphore reset, return immediately */ if (as->as_pendings == 0) { as->as_resetting = 0; } result = AE_TIME; break; } #endif ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, "ssleep(%d) returned %d\n", tmo, rv)); if (rv == EWOULDBLOCK) { result = AE_TIME; break; } /* check if we already awaited enough */ timelefttv = timeouttv; getmicrouptime(¤ttv); timevalsub(&timelefttv, ¤ttv); if (timelefttv.tv_sec < 0) { ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, "await semaphore %p timeout\n", as)); result = AE_TIME; break; } /* adjust timeout for the next sleep */ tmo = (timelefttv.tv_sec * 1000000 + timelefttv.tv_usec) / (1000000 / hz); if (tmo <= 0) tmo = 1; if (acpi_semaphore_debug) { kprintf("%s: Wakeup timeleft(%ju, %ju), tmo %ju, sem %p, thread %jd\n", __func__, (intmax_t)timelefttv.tv_sec, (intmax_t)timelefttv.tv_usec, (intmax_t)tmo, as, (intmax_t)AcpiOsGetThreadId()); } } if (acpi_semaphore_debug) { if (result == AE_TIME && Timeout > 0) { kprintf("%s: Timeout %d, pending %d, semaphore %p\n", __func__, Timeout, as->as_pendings, as); } if (ACPI_SUCCESS(result) && (as->as_timeouts > 0 || as->as_pendings > 0)) { kprintf("%s: Acquire %d, units %d, pending %d, sem %p, thread %jd\n", __func__, Units, as->as_units, as->as_pendings, as, (intmax_t)AcpiOsGetThreadId()); } } if (result == AE_TIME) as->as_timeouts++; else as->as_timeouts = 0; AS_UNLOCK(as); return_ACPI_STATUS (result); #else return_ACPI_STATUS (AE_OK); #endif /* !ACPI_NO_SEMAPHORES */ }
int procfs_doprocstatus(PFS_FILL_ARGS) { struct session *sess; struct thread *tdfirst; struct tty *tp; struct ucred *cr; const char *wmesg; char *pc; char *sep; int pid, ppid, pgid, sid; int i; pid = p->p_pid; PROC_LOCK(p); ppid = p->p_pptr ? p->p_pptr->p_pid : 0; pgid = p->p_pgrp->pg_id; sess = p->p_pgrp->pg_session; SESS_LOCK(sess); sid = sess->s_leader ? sess->s_leader->p_pid : 0; /* comm pid ppid pgid sid tty ctty,sldr start ut st wmsg euid ruid rgid,egid,groups[1 .. ngroups] */ pc = p->p_comm; do { if (*pc < 33 || *pc > 126 || *pc == '\\') sbuf_printf(sb, "\\%03o", *pc); else sbuf_putc(sb, *pc); } while (*++pc); sbuf_printf(sb, " %d %d %d %d ", pid, ppid, pgid, sid); if ((p->p_flag & P_CONTROLT) && (tp = sess->s_ttyp)) sbuf_printf(sb, "%s ", devtoname(tp->t_dev)); else sbuf_printf(sb, "- "); sep = ""; if (sess->s_ttyvp) { sbuf_printf(sb, "%sctty", sep); sep = ","; } if (SESS_LEADER(p)) { sbuf_printf(sb, "%ssldr", sep); sep = ","; } SESS_UNLOCK(sess); if (*sep != ',') { sbuf_printf(sb, "noflags"); } tdfirst = FIRST_THREAD_IN_PROC(p); thread_lock(tdfirst); if (tdfirst->td_wchan != NULL) { KASSERT(tdfirst->td_wmesg != NULL, ("wchan %p has no wmesg", tdfirst->td_wchan)); wmesg = tdfirst->td_wmesg; } else wmesg = "nochan"; thread_unlock(tdfirst); if (p->p_flag & P_INMEM) { struct timeval start, ut, st; PROC_SLOCK(p); calcru(p, &ut, &st); PROC_SUNLOCK(p); start = p->p_stats->p_start; timevaladd(&start, &boottime); sbuf_printf(sb, " %jd,%ld %jd,%ld %jd,%ld", (intmax_t)start.tv_sec, start.tv_usec, (intmax_t)ut.tv_sec, ut.tv_usec, (intmax_t)st.tv_sec, st.tv_usec); } else sbuf_printf(sb, " -1,-1 -1,-1 -1,-1"); sbuf_printf(sb, " %s", wmesg); cr = p->p_ucred; sbuf_printf(sb, " %lu %lu %lu", (u_long)cr->cr_uid, (u_long)cr->cr_ruid, (u_long)cr->cr_rgid); /* egid (cr->cr_svgid) is equal to cr_ngroups[0] see also getegid(2) in /sys/kern/kern_prot.c */ for (i = 0; i < cr->cr_ngroups; i++) { sbuf_printf(sb, ",%lu", (u_long)cr->cr_groups[i]); } if (jailed(cr)) { mtx_lock(&cr->cr_prison->pr_mtx); sbuf_printf(sb, " %s", prison_name(td->td_ucred->cr_prison, cr->cr_prison)); mtx_unlock(&cr->cr_prison->pr_mtx); } else { sbuf_printf(sb, " -"); } PROC_UNLOCK(p); sbuf_printf(sb, "\n"); return (0); }
/* send all of the routing table or just do a flash update */ void rip_bcast(int flash) { #ifdef _HAVE_SIN_LEN static struct sockaddr_in dst = {sizeof(dst), AF_INET, 0, {0}, {0}}; #else static struct sockaddr_in dst = {AF_INET}; #endif struct interface *ifp; enum output_type type; int vers; struct timeval rtime; need_flash = 0; intvl_random(&rtime, MIN_WAITTIME, MAX_WAITTIME); no_flash = rtime; timevaladd(&no_flash, &now); if (rip_sock < 0) return; trace_act("send %s and inhibit dynamic updates for %.3f sec", flash ? "dynamic update" : "all routes", rtime.tv_sec + ((float)rtime.tv_usec)/1000000.0); for (ifp = ifnet; ifp != NULL; ifp = ifp->int_next) { /* Skip interfaces not doing RIP. * Do try broken interfaces to see if they have healed. */ if (IS_RIP_OUT_OFF(ifp->int_state)) continue; /* skip turned off interfaces */ if (!iff_up(ifp->int_if_flags)) continue; vers = (ifp->int_state & IS_NO_RIPV1_OUT) ? RIPv2 : RIPv1; if (ifp->int_if_flags & IFF_BROADCAST) { /* ordinary, hardware interface */ dst.sin_addr.s_addr = ifp->int_brdaddr; if (vers == RIPv2 && !(ifp->int_state & IS_NO_RIP_MCAST)) { type = OUT_MULTICAST; } else { type = OUT_BROADCAST; } } else if (ifp->int_if_flags & IFF_POINTOPOINT) { /* point-to-point hardware interface */ dst.sin_addr.s_addr = ifp->int_dstaddr; type = OUT_UNICAST; } else if (ifp->int_state & IS_REMOTE) { /* remote interface */ dst.sin_addr.s_addr = ifp->int_addr; type = OUT_UNICAST; } else { /* ATM, HIPPI, etc. */ continue; } supply(&dst, ifp, type, flash, vers, 1); } update_seqno++; /* all routes are up to date */ }
struct tsp * readmsg(int type, char *machfrom, struct timeval *intvl, struct netinfo *netfrom) { int length; fd_set ready; static struct tsplist *head = &msgslist; static struct tsplist *tail = &msgslist; static int msgcnt = 0; struct tsplist *prev; register struct netinfo *ntp; register struct tsplist *ptr; ssize_t n; if (trace) { fprintf(fd, "readmsg: looking for %s from %s, %s\n", tsptype[type], machfrom == NULL ? "ANY" : machfrom, netfrom == NULL ? "ANYNET" : inet_ntoa(netfrom->net)); if (head->p != 0) { length = 1; for (ptr = head->p; ptr != 0; ptr = ptr->p) { /* do not repeat the hundreds of messages */ if (++length > 3) { if (ptr == tail) { fprintf(fd,"\t ...%d skipped\n", length); } else { continue; } } fprintf(fd, length > 1 ? "\t" : "queue:\t"); print(&ptr->info, &ptr->addr); } } } ptr = head->p; prev = head; /* * Look for the requested message scanning through the * linked list. If found, return it and free the space */ while (ptr != NULL) { if (LOOKAT(ptr->info, type, machfrom, netfrom, ptr->addr)) { again: msgin = ptr->info; from = ptr->addr; from_when = ptr->when; prev->p = ptr->p; if (ptr == tail) tail = prev; free((char *)ptr); fromnet = NULL; if (netfrom == NULL) for (ntp = nettab; ntp != NULL; ntp = ntp->next) { if ((ntp->mask & from.sin_addr.s_addr) == ntp->net.s_addr) { fromnet = ntp; break; } } else fromnet = netfrom; if (trace) { fprintf(fd, "readmsg: found "); print(&msgin, &from); } /* The protocol can get far behind. When it does, it gets * hopelessly confused. So delete duplicate messages. */ for (ptr = prev; (ptr = ptr->p) != NULL; prev = ptr) { if (ptr->addr.sin_addr.s_addr == from.sin_addr.s_addr && ptr->info.tsp_type == msgin.tsp_type) { if (trace) fprintf(fd, "\tdup "); goto again; } } msgcnt--; return(&msgin); } else { prev = ptr; ptr = ptr->p; } } /* * If the message was not in the linked list, it may still be * coming from the network. Set the timer and wait * on a select to read the next incoming message: if it is the * right one, return it, otherwise insert it in the linked list. */ (void)gettimeofday(&rtout, NULL); timevaladd(&rtout, intvl); FD_ZERO(&ready); for (;;) { (void)gettimeofday(&rtime, NULL); timevalsub(&rwait, &rtout, &rtime); if (rwait.tv_sec < 0) rwait.tv_sec = rwait.tv_usec = 0; else if (rwait.tv_sec == 0 && rwait.tv_usec < 1000000/CLK_TCK) rwait.tv_usec = 1000000/CLK_TCK; if (trace) { fprintf(fd, "readmsg: wait %jd.%6ld at %s\n", (intmax_t)rwait.tv_sec, rwait.tv_usec, date()); /* Notice a full disk, as we flush trace info. * It is better to flush periodically than at * every line because the tracing consists of bursts * of many lines. Without care, tracing slows * down the code enough to break the protocol. */ if (rwait.tv_sec != 0 && EOF == fflush(fd)) traceoff("Tracing ended for cause at %s\n"); } FD_SET(sock, &ready); if (!select(sock+1, &ready, (fd_set *)0, (fd_set *)0, &rwait)) { if (rwait.tv_sec == 0 && rwait.tv_usec == 0) return(0); continue; } length = sizeof(from); if ((n = recvfrom(sock, (char *)&msgin, sizeof(struct tsp), 0, (struct sockaddr*)&from, &length)) < 0) { syslog(LOG_ERR, "recvfrom: %m"); exit(1); } /* * The 4.3BSD protocol spec had a 32-byte tsp_name field, and * this is still OS-dependent. Demand that the packet is at * least long enough to hold a 4.3BSD packet. */ if (n < (ssize_t)(sizeof(struct tsp) - MAXHOSTNAMELEN + 32)) { syslog(LOG_NOTICE, "short packet (%zd/%zu bytes) from %s", n, sizeof(struct tsp) - MAXHOSTNAMELEN + 32, inet_ntoa(from.sin_addr)); continue; } (void)gettimeofday(&from_when, NULL); bytehostorder(&msgin); if (msgin.tsp_vers > TSPVERSION) { if (trace) { fprintf(fd,"readmsg: version mismatch\n"); /* should do a dump of the packet */ } continue; } if (memchr(msgin.tsp_name, '\0', sizeof msgin.tsp_name) == NULL) { syslog(LOG_NOTICE, "hostname field not NUL terminated " "in packet from %s", inet_ntoa(from.sin_addr)); continue; } fromnet = NULL; for (ntp = nettab; ntp != NULL; ntp = ntp->next) if ((ntp->mask & from.sin_addr.s_addr) == ntp->net.s_addr) { fromnet = ntp; break; } /* * drop packets from nets we are ignoring permanently */ if (fromnet == NULL) { /* * The following messages may originate on * this host with an ignored network address */ if (msgin.tsp_type != TSP_TRACEON && msgin.tsp_type != TSP_SETDATE && msgin.tsp_type != TSP_MSITE && msgin.tsp_type != TSP_TEST && msgin.tsp_type != TSP_TRACEOFF) { if (trace) { fprintf(fd,"readmsg: discard null net "); print(&msgin, &from); } continue; } } /* * Throw away messages coming from this machine, * unless they are of some particular type. * This gets rid of broadcast messages and reduces * master processing time. */ if (!strcmp(msgin.tsp_name, hostname) && msgin.tsp_type != TSP_SETDATE && msgin.tsp_type != TSP_TEST && msgin.tsp_type != TSP_MSITE && msgin.tsp_type != TSP_TRACEON && msgin.tsp_type != TSP_TRACEOFF && msgin.tsp_type != TSP_LOOP) { if (trace) { fprintf(fd, "readmsg: discard own "); print(&msgin, &from); } continue; } /* * Send acknowledgements here; this is faster and * avoids deadlocks that would occur if acks were * sent from a higher level routine. Different * acknowledgements are necessary, depending on * status. */ if (fromnet == NULL) /* do not de-reference 0 */ ignoreack(); else if (fromnet->status == MASTER) masterack(); else if (fromnet->status == SLAVE) slaveack(); else ignoreack(); if (LOOKAT(msgin, type, machfrom, netfrom, from)) { if (trace) { fprintf(fd, "readmsg: "); print(&msgin, &from); } return(&msgin); } else if (++msgcnt > NHOSTS*3) { /* The protocol gets hopelessly confused if it gets too far * behind. However, it seems able to recover from all cases of lost * packets. Therefore, if we are swamped, throw everything away. */ if (trace) fprintf(fd, "readmsg: discarding %d msgs\n", msgcnt); msgcnt = 0; while ((ptr=head->p) != NULL) { head->p = ptr->p; free((char *)ptr); } tail = head; } else { tail->p = (struct tsplist *) malloc(sizeof(struct tsplist)); tail = tail->p; tail->p = NULL; tail->info = msgin; tail->addr = from; /* timestamp msgs so SETTIMEs are correct */ tail->when = from_when; } } }
/* * Measures the differences between machines' clocks using * ICMP timestamp messages. * maxmsec wait this many msec at most * wmsec msec to wait for an answer * print print complaints on stderr */ int /* status val defined in globals.h */ measure(u_long maxmsec, u_long wmsec, char *hname, struct sockaddr_in *addr, int print) { int length; int measure_status; int rcvcount, trials; int cc, count; fd_set ready; long sendtime, recvtime, histime1, histime2; long idelta, odelta, total; long min_idelta, min_odelta; struct timeval tdone, tcur, ttrans, twait, tout; u_char packet[PACKET_IN], opacket[64]; register struct icmp *icp = (struct icmp *) packet; register struct icmp *oicp = (struct icmp *) opacket; struct ip *ip = (struct ip *) packet; min_idelta = min_odelta = 0x7fffffff; measure_status = HOSTDOWN; measure_delta = HOSTDOWN; trials = 0; errno = 0; /* open raw socket used to measure time differences */ if (sock_raw < 0) { sock_raw = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP); if (sock_raw < 0) { syslog(LOG_ERR, "opening raw socket: %m"); goto quit; } } /* * empty the icmp input queue */ FD_ZERO(&ready); for (;;) { tout.tv_sec = tout.tv_usec = 0; FD_SET(sock_raw, &ready); if (select(sock_raw+1, &ready, 0,0, &tout)) { length = sizeof(struct sockaddr_in); cc = recvfrom(sock_raw, (char *)packet, PACKET_IN, 0, 0,&length); if (cc < 0) goto quit; continue; } break; } /* * Choose the smallest transmission time in each of the two * directions. Use these two latter quantities to compute the delta * between the two clocks. */ oicp->icmp_type = ICMP_TSTAMP; oicp->icmp_code = 0; oicp->icmp_id = getpid(); oicp->icmp_rtime = 0; oicp->icmp_ttime = 0; oicp->icmp_seq = seqno; FD_ZERO(&ready); (void)gettimeofday(&tdone, NULL); mstotvround(&tout, maxmsec); timevaladd(&tdone, &tout); /* when we give up */ mstotvround(&twait, wmsec); rcvcount = 0; while (rcvcount < MSGS) { (void)gettimeofday(&tcur, NULL); /* * keep sending until we have sent the max */ if (trials < TRIALS) { trials++; oicp->icmp_otime = htonl((tcur.tv_sec % SECDAY) * 1000 + tcur.tv_usec / 1000); oicp->icmp_cksum = 0; oicp->icmp_cksum = in_cksum((u_short*)oicp, sizeof(*oicp)); count = sendto(sock_raw, opacket, sizeof(*oicp), 0, (struct sockaddr*)addr, sizeof(struct sockaddr)); if (count < 0) { if (measure_status == HOSTDOWN) measure_status = UNREACHABLE; goto quit; } ++oicp->icmp_seq; ttrans = tcur; timevaladd(&ttrans, &twait); } else { ttrans = tdone; } while (rcvcount < trials) { timevalsub(&tout, &ttrans, &tcur); if (tout.tv_sec < 0) tout.tv_sec = 0; FD_SET(sock_raw, &ready); count = select(sock_raw+1, &ready, (fd_set *)0, (fd_set *)0, &tout); (void)gettimeofday(&tcur, NULL); if (count <= 0) break; length = sizeof(struct sockaddr_in); cc = recvfrom(sock_raw, (char *)packet, PACKET_IN, 0, 0,&length); if (cc < 0) goto quit; /* * got something. See if it is ours */ icp = (struct icmp *)(packet + (ip->ip_hl << 2)); if (cc < sizeof(*ip) || icp->icmp_type != ICMP_TSTAMPREPLY || icp->icmp_id != oicp->icmp_id || icp->icmp_seq < seqno || icp->icmp_seq >= oicp->icmp_seq) continue; sendtime = ntohl(icp->icmp_otime); recvtime = ((tcur.tv_sec % SECDAY) * 1000 + tcur.tv_usec / 1000); total = recvtime-sendtime; if (total < 0) /* do not hassle midnight */ continue; rcvcount++; histime1 = ntohl(icp->icmp_rtime); histime2 = ntohl(icp->icmp_ttime); /* * a host using a time format different from * msec. since midnight UT (as per RFC792) should * set the high order bit of the 32-bit time * value it transmits. */ if ((histime1 & 0x80000000) != 0) { measure_status = NONSTDTIME; goto quit; } measure_status = GOOD; idelta = recvtime-histime2; odelta = histime1-sendtime; /* do not be confused by midnight */ if (idelta < -MSEC_DAY/2) idelta += MSEC_DAY; else if (idelta > MSEC_DAY/2) idelta -= MSEC_DAY; if (odelta < -MSEC_DAY/2) odelta += MSEC_DAY; else if (odelta > MSEC_DAY/2) odelta -= MSEC_DAY; /* save the quantization error so that we can get a * measurement finer than our system clock. */ if (total < MIN_ROUND) { measure_delta = (odelta - idelta)/2; goto quit; } if (idelta < min_idelta) min_idelta = idelta; if (odelta < min_odelta) min_odelta = odelta; measure_delta = (min_odelta - min_idelta)/2; } if (tcur.tv_sec > tdone.tv_sec || (tcur.tv_sec == tdone.tv_sec && tcur.tv_usec >= tdone.tv_usec)) break; } quit: seqno += TRIALS; /* allocate our sequence numbers */ /* * If no answer is received for TRIALS consecutive times, * the machine is assumed to be down */ if (measure_status == GOOD) { if (trace) { fprintf(fd, "measured delta %4d, %d trials to %-15s %s\n", measure_delta, trials, inet_ntoa(addr->sin_addr), hname); } } else if (print) { if (errno != 0) warn("measure %s", hname); } else { if (errno != 0) { syslog(LOG_ERR, "measure %s: %m", hname); } else { syslog(LOG_ERR, "measure: %s did not respond", hname); } if (trace) { fprintf(fd, "measure: %s failed after %d trials\n", hname, trials); (void)fflush(fd); } } return(measure_status); }
/* * Write out process accounting information, on process exit. * Data to be written out is specified in Leffler, et al. * and are enumerated below. (They're also noted in the system * "acct.h" header file.) */ int acct_process(proc_t p) { struct acct an_acct; struct rusage rup, *r; struct timeval ut, st, tmp; int t; int error; struct vnode *vp; kauth_cred_t safecred; struct session * sessp; boolean_t fstate; /* If accounting isn't enabled, don't bother */ vp = acctp; if (vp == NULLVP) return (0); /* * Get process accounting information. */ /* (1) The name of the command that ran */ bcopy(p->p_comm, an_acct.ac_comm, sizeof an_acct.ac_comm); /* (2) The amount of user and system time that was used */ calcru(p, &ut, &st, NULL); an_acct.ac_utime = encode_comp_t(ut.tv_sec, ut.tv_usec); an_acct.ac_stime = encode_comp_t(st.tv_sec, st.tv_usec); /* (3) The elapsed time the commmand ran (and its starting time) */ an_acct.ac_btime = p->p_start.tv_sec; microtime(&tmp); timevalsub(&tmp, &p->p_start); an_acct.ac_etime = encode_comp_t(tmp.tv_sec, tmp.tv_usec); /* (4) The average amount of memory used */ proc_lock(p); rup = p->p_stats->p_ru; proc_unlock(p); r = &rup; tmp = ut; timevaladd(&tmp, &st); t = tmp.tv_sec * hz + tmp.tv_usec / tick; if (t) an_acct.ac_mem = (r->ru_ixrss + r->ru_idrss + r->ru_isrss) / t; else an_acct.ac_mem = 0; /* (5) The number of disk I/O operations done */ an_acct.ac_io = encode_comp_t(r->ru_inblock + r->ru_oublock, 0); /* (6) The UID and GID of the process */ safecred = kauth_cred_proc_ref(p); an_acct.ac_uid = safecred->cr_ruid; an_acct.ac_gid = safecred->cr_rgid; /* (7) The terminal from which the process was started */ sessp = proc_session(p); if ((p->p_flag & P_CONTROLT) && (sessp != SESSION_NULL) && (sessp->s_ttyp != TTY_NULL)) { fstate = thread_funnel_set(kernel_flock, TRUE); an_acct.ac_tty = sessp->s_ttyp->t_dev; (void) thread_funnel_set(kernel_flock, fstate); }else an_acct.ac_tty = NODEV; if (sessp != SESSION_NULL) session_rele(sessp); /* (8) The boolean flags that tell how the process terminated, etc. */ an_acct.ac_flag = p->p_acflag; /* * Now, just write the accounting information to the file. */ if ((error = vnode_getwithref(vp)) == 0) { error = vn_rdwr(UIO_WRITE, vp, (caddr_t)&an_acct, sizeof (an_acct), (off_t)0, UIO_SYSSPACE32, IO_APPEND|IO_UNIT, safecred, (int *)0, p); vnode_put(vp); } kauth_cred_unref(&safecred); return (error); }