struct log *log_new_fast(struct db *db, uint64_t log_number, struct dir *log_dir, struct dir *index_dir, struct bitmap *bitmap) { struct log *log = _log_new(db, log_number, log_dir, index_dir); if (log == NULL) { return NULL; } char *idx_file = idx_filename(log_number); struct hashdir *hdsets = hashdir_new_load(db, index_dir, idx_file); if (hdsets == NULL) { log_warn(db, "Can't find index file \"%s\".", idx_file); log_free(log); return NULL; /* log_warn(db, "Can't find index file \"%s\". Trying rebuild.", */ /* idx_file); */ /* hdsets = hashdir_new(db); */ /* struct hashdir *hdall = hashdir_new(db); */ /* _log_replay(log->reader, hdall, hdsets); */ /* hashdir_free(hdall); /\* not interested in deletions *\/ */ /* hashdir_freeze(hdsets); */ /* int r = hashdir_save(hdsets, index_dir, idx_file); */ /* if (r == -1) { */ /* log_error(db, "Can't save index file \"%s\".", idx_file); */ /* } */ } int s = 0; int i; int hpos_max = hashdir_size(hdsets); for (i=1; i < hpos_max; i++) { struct hashdir_item hi = hashdir_get(hdsets, i); if (bitmap_get(bitmap, hi.bitmap_pos) == 0) { /* add */ stddev_add(&log->used_size, hi.size); } else { /* delete */ int r = hashdir_del(hdsets, i); if (r != -1) { s += hashdir_del_last(hdsets); /* Visit this element once more. */ i--; } hpos_max--; } } log->hashdir = hdsets; if (s > 4) { int r = hashdir_save(log->hashdir, log->index_dir, idx_filename(log->log_number)); if (r == -1) { log_warn(log->db, "Unable to save index for " "log %llx.", (unsigned long long)log->log_number); } } return log; }
int log_add(struct log *log, struct hashdir_item hdi) { stddev_add(&log->used_size, hdi.size); return hashdir_add(log->hashdir, hdi); }
void thread_loop(void *userdata) { struct state *state = userdata; pthread_spin_init(&state->lock, PTHREAD_PROCESS_PRIVATE); char send_buf[PKT_SIZE], recv_buf[PKT_SIZE]; struct msghdr *msg = calloc(2, sizeof(struct msghdr)); struct iovec *iovec = calloc(2, sizeof(struct iovec)); int i; for (i = 0; i < 2; i++) { msg[i].msg_iov = &iovec[i]; msg[i].msg_iovlen = 1; iovec[i].iov_len = sizeof(send_buf); } iovec[0].iov_base = send_buf; iovec[1].iov_base = recv_buf; char pktinfo[4096]; msg[1].msg_control = pktinfo; msg[1].msg_controllen = sizeof(pktinfo); uint64_t packet_no = 0; while (1) { int fd = net_connect_udp(state->target_addr, state->src_port, state->busy_poll); struct timeval tv = {1, 0}; // 1 second int r = setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)); if (r < 0) { PFATAL("setsockopt(SO_RCVTIMEO)"); } for (;; packet_no++) { memset(send_buf, 0, sizeof(send_buf)); snprintf(send_buf, sizeof(send_buf), "%i-%li-%lu", getpid(), gettid(), packet_no); uint64_t t0 = realtime_now(), t1 = 0, tp = 0; int r = sendmsg(fd, &msg[0], 0); if (r <= 0) { if (errno == EAGAIN || errno == EWOULDBLOCK || errno == ECONNREFUSED) { break; } if (errno == EINTR) { continue; } PFATAL("sendmmsg()"); } msg[1].msg_controllen = sizeof(pktinfo); while (1) { int flags = state->polling ? MSG_DONTWAIT : 0; r = recvmsg(fd, &msg[1], flags); t1 = realtime_now(); if (t1 - t0 >= 1000000000) { /* No msg for 1s */ errno = ECONNREFUSED; break; } if (r <= 0 && (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK)) { continue; } if (r == 0 && state->polling) { continue; } break; } if (r <= 0 && errno == ECONNREFUSED) { sleep(1); break; } if (r <= 0) { PFATAL("recvmmsg()"); } if (memcmp(send_buf, recv_buf, sizeof(recv_buf)) != 0) { fprintf(stderr, "[!] bad message\n"); sleep(1); break; } struct cmsghdr *cmsg; for (cmsg = CMSG_FIRSTHDR(&msg[1]); cmsg; cmsg = CMSG_NXTHDR(&msg[1], cmsg)) { switch (cmsg->cmsg_level) { case SOL_SOCKET: switch (cmsg->cmsg_type) { case SO_TIMESTAMPNS: { struct timespec *ts = (struct timespec *) CMSG_DATA(cmsg); tp = TIMESPEC_NSEC(ts); break; } } break; } } pthread_spin_lock(&state->lock); stddev_add(&state->stddev, t1 - t0); if (tp != 0) { stddev_add(&state->stddev_packet, t1 - tp); } pthread_spin_unlock(&state->lock); } close(fd); } }