int tap_ctl_send_and_receive_with_logpath(int sfd, tapdisk_message_t *message, const char *logpath, struct timeval *timeout) { int err, ret; err = tap_ctl_write_message(sfd, message, timeout); if (err) { EPRINTF("failed to send '%s' message\n", tapdisk_message_name(message->type)); return err; } char buf[TAPDISK_MESSAGE_MAX_PATH_LENGTH]; snprintf(buf, TAPDISK_MESSAGE_MAX_PATH_LENGTH - 1, "%s", logpath); ret = write(sfd, &buf, sizeof(buf)); if (ret == -1) { EPRINTF("Failed to send logpath with '%s' message\n", tapdisk_message_name(message->type)); } err = tap_ctl_read_message(sfd, message, timeout); if (err) { EPRINTF("failed to receive '%s' message\n", tapdisk_message_name(message->type)); return err; } return 0; }
int _tap_ctl_stats_connect_and_send(pid_t pid, int minor) { struct timeval timeout = { .tv_sec = 10, .tv_usec = 0 }; tapdisk_message_t message; int sfd, err; err = tap_ctl_connect_id(pid, &sfd); if (err) return err; memset(&message, 0, sizeof(message)); message.type = TAPDISK_MESSAGE_STATS; message.cookie = minor; err = tap_ctl_write_message(sfd, &message, &timeout); if (err) return err; return sfd; } ssize_t tap_ctl_stats(pid_t pid, int minor, char *buf, size_t size) { tapdisk_message_t message; int sfd, err; size_t len; sfd = _tap_ctl_stats_connect_and_send(pid, minor); if (sfd < 0) return sfd; err = tap_ctl_read_message(sfd, &message, NULL); if (err) return err; len= message.u.info.length; if (len < 0) { err = len; goto out; } if (size < len + 1) len = size - 1; err = tap_ctl_read_raw(sfd, buf, len, NULL); if (err) goto out; buf[len] = 0; out: close(sfd); return err; }
int tap_ctl_send_and_receive(int sfd, tapdisk_message_t * message, struct timeval *timeout) { int err; err = tap_ctl_write_message(sfd, message, timeout); if (err) { EPRINTF("failed to send '%s' message\n", tapdisk_message_name(message->type)); return err; } err = tap_ctl_read_message(sfd, message, timeout); if (err) { EPRINTF("failed to receive '%s' message\n", tapdisk_message_name(message->type)); return err; } return 0; }
int tap_ctl_stats_fwrite(pid_t pid, int minor, FILE *stream) { tapdisk_message_t message; int sfd = -1, prot, flags, err; size_t len, bufsz; char *buf = MAP_FAILED; prot = PROT_READ|PROT_WRITE; flags = MAP_ANONYMOUS|MAP_PRIVATE; bufsz = sysconf(_SC_PAGE_SIZE); buf = mmap(NULL, bufsz, prot, flags, -1, 0); if (buf == MAP_FAILED) { buf = NULL; err = -ENOMEM; goto out; } sfd = _tap_ctl_stats_connect_and_send(pid, minor); if (sfd < 0) { err = sfd; goto out; } err = tap_ctl_read_message(sfd, &message, NULL); if (err) goto out; len = message.u.info.length; err = len; if (len < 0) goto out; while (len) { fd_set rfds; size_t in, out; int n; FD_ZERO(&rfds); FD_SET(sfd, &rfds); n = select(sfd + 1, &rfds, NULL, NULL, NULL); err = n; if (n < 0) goto out; in = read(sfd, buf, bufsz); err = in; if (in <= 0) goto out; len -= in; out = fwrite(buf, in, 1, stream); if (out != in) { err = -errno; goto out; } } out: if (sfd >= 0) close(sfd); if (buf != MAP_FAILED) munmap(buf, bufsz); return err; }