sudo_sendlog: send multiple I/O log records together if possible
Try to fill the write buffer and then send to the server instead of sending records one at a time.
This commit is contained in:
@@ -312,7 +312,7 @@ read_io_buf(struct client_closure *closure)
|
||||
static bool
|
||||
fmt_client_message(struct client_closure *closure, ClientMessage *msg)
|
||||
{
|
||||
struct connection_buffer *buf;
|
||||
struct connection_buffer *buf = NULL;
|
||||
uint32_t msg_len;
|
||||
bool ret = false;
|
||||
size_t len;
|
||||
@@ -327,15 +327,24 @@ fmt_client_message(struct client_closure *closure, ClientMessage *msg)
|
||||
msg_len = htonl((uint32_t)len);
|
||||
len += sizeof(msg_len);
|
||||
|
||||
if (!TAILQ_EMPTY(&closure->write_bufs)) {
|
||||
buf = TAILQ_FIRST(&closure->write_bufs);
|
||||
if (len > buf->size - buf->len) {
|
||||
/* Too small. */
|
||||
buf = NULL;
|
||||
}
|
||||
}
|
||||
if (buf == NULL) {
|
||||
if ((buf = get_free_buf(len, closure)) == NULL) {
|
||||
sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
|
||||
goto done;
|
||||
}
|
||||
|
||||
memcpy(buf->data, &msg_len, sizeof(msg_len));
|
||||
client_message__pack(msg, buf->data + sizeof(msg_len));
|
||||
buf->len = len;
|
||||
TAILQ_INSERT_TAIL(&closure->write_bufs, buf, entries);
|
||||
}
|
||||
|
||||
memcpy(buf->data + buf->len, &msg_len, sizeof(msg_len));
|
||||
client_message__pack(msg, buf->data + buf->len + sizeof(msg_len));
|
||||
buf->len += len;
|
||||
|
||||
ret = true;
|
||||
|
||||
@@ -917,9 +926,10 @@ fmt_next_iolog(struct client_closure *closure)
|
||||
bool ret = false;
|
||||
debug_decl(fmt_next_iolog, SUDO_DEBUG_UTIL);
|
||||
|
||||
/* TODO: fill write buffer with multiple messages */
|
||||
again:
|
||||
switch (iolog_read_timing_record(&closure->iolog_files[IOFD_TIMING], timing)) {
|
||||
for (;;) {
|
||||
const int timing_status = iolog_read_timing_record(
|
||||
&closure->iolog_files[IOFD_TIMING], timing);
|
||||
switch (timing_status) {
|
||||
case 0:
|
||||
/* OK */
|
||||
break;
|
||||
@@ -939,7 +949,8 @@ again:
|
||||
if (sudo_timespecisset(&closure->stop_after)) {
|
||||
if (sudo_timespeccmp(&closure->elapsed, &closure->stop_after, >)) {
|
||||
/* Reached limit, force premature end. */
|
||||
sudo_timespecsub(&closure->elapsed, &timing->delay, &closure->elapsed);
|
||||
sudo_timespecsub(&closure->elapsed, &timing->delay,
|
||||
&closure->elapsed);
|
||||
debug_return_bool(false);
|
||||
}
|
||||
}
|
||||
@@ -947,7 +958,7 @@ again:
|
||||
/* If we have a restart point, ignore records until we hit it. */
|
||||
if (sudo_timespecisset(&closure->restart)) {
|
||||
if (sudo_timespeccmp(&closure->restart, &closure->elapsed, >=))
|
||||
goto again;
|
||||
continue;
|
||||
sudo_timespecclear(&closure->restart); /* caught up */
|
||||
}
|
||||
|
||||
@@ -978,6 +989,13 @@ again:
|
||||
break;
|
||||
}
|
||||
|
||||
/* Keep filling write buffer as long as we only have one of them. */
|
||||
if (!ret)
|
||||
break;
|
||||
if (TAILQ_NEXT(TAILQ_FIRST(&closure->write_bufs), entries) != NULL)
|
||||
break;
|
||||
}
|
||||
|
||||
debug_return_bool(ret);
|
||||
}
|
||||
|
||||
@@ -1486,6 +1504,8 @@ client_closure_free(struct client_closure *closure)
|
||||
free(closure->read_buf.data);
|
||||
free(closure->buf);
|
||||
while ((buf = TAILQ_FIRST(&closure->write_bufs)) != NULL) {
|
||||
sudo_debug_printf(SUDO_DEBUG_WARN|SUDO_DEBUG_LINENO,
|
||||
"discarding write buffer %p, len %u", buf, buf->len - buf->off);
|
||||
TAILQ_REMOVE(&closure->write_bufs, buf, entries);
|
||||
free(buf->data);
|
||||
free(buf);
|
||||
@@ -1511,6 +1531,7 @@ client_closure_alloc(int sock, struct sudo_event_base *base,
|
||||
struct timespec *restart, struct timespec *stop_after, const char *iolog_id,
|
||||
char *reject_reason, bool accept_only, struct eventlog *evlog)
|
||||
{
|
||||
struct connection_buffer *buf;
|
||||
struct client_closure *closure;
|
||||
debug_decl(client_closure_alloc, SUDO_DEBUG_UTIL);
|
||||
|
||||
@@ -1546,6 +1567,11 @@ client_closure_alloc(int sock, struct sudo_event_base *base,
|
||||
if (closure->read_ev == NULL)
|
||||
goto bad;
|
||||
|
||||
buf = get_free_buf(64 * 1024, closure);
|
||||
if (buf == NULL)
|
||||
goto bad;
|
||||
TAILQ_INSERT_TAIL(&closure->free_bufs, buf, entries);
|
||||
|
||||
closure->write_ev = sudo_ev_alloc(sock, SUDO_EV_WRITE|SUDO_EV_PERSIST,
|
||||
client_msg_cb, closure);
|
||||
if (closure->write_ev == NULL)
|
||||
|
Reference in New Issue
Block a user