Ejemplo n.º 1
0
static ssize_t compress_iov_to_buffer(struct trace_record *target, const struct iovec *iov, int iovcnt)
{
    if (NULL == iov) {
        errno = EFAULT;
        return -1;
    }

    if (iovcnt < 1) {
        return 0;
    }

    char *src_buf = iov[0].iov_base;
    size_t input_len = iov[0].iov_len;
    size_t compressed_length = 0;
    struct snappy_env env;
    int rc = snappy_init_env(&env);
    if (rc < 0) {
        goto finish;
    }

    if (iovcnt > 1) {
        /* TODO: Snappy should be able to accept an input IOV directly. Since this support is currently broken we use a workaround instead. */
        input_len = total_iovec_len(iov, iovcnt);
        src_buf = malloc(input_len);
        if ((NULL == src_buf) || (copy_iov_to_buffer(src_buf, iov, iovcnt) != (ssize_t) input_len)) {
            rc = -errno;
            goto finish;
        }

    }

    if (input_len > 0) {
        /* Don't bother compressing trailing padding chars. Those will be re-inserted by the reader. */
        input_len -= trace_r_count_chr_occurrences(src_buf + 1, input_len - 1, TRACE_UNUSED_SPACE_FILL_VALUE);
        rc = snappy_compress(&env, src_buf, input_len, (char *)target, &compressed_length);
    }

finish:
    snappy_free_env(&env);

    if (src_buf != iov[0].iov_base) {
        free(src_buf);
    }

    if (0 != rc) {
        errno = -rc;
        ERR("Buffer compression failed with err", errno, strerror(errno));
        return (ssize_t) -1;
    }

    TRACE_ASSERT(((ssize_t) compressed_length > 0) || (0 == input_len));
    return (ssize_t) compressed_length;
}
Ejemplo n.º 2
0
ssize_t internal_buf_write_compressed(struct trace_internal_buf *buf, const struct iovec *iov, int iovcnt)
{
    const size_t max_size = snappy_max_compressed_length(total_iovec_len(iov, iovcnt));
    const size_t max_recs = internal_buf_bytes_to_recs(max_size);
    const unsigned start_idx = internal_buf_alloc_space(buf, max_recs);
    if (INTERNAL_BUF_INVALID_INDEX == start_idx) {
        return -1;
    }

    const ssize_t compressed_len = compress_iov_to_buffer(buf->records + start_idx, iov, iovcnt);
    if (compressed_len < 0) {
        compactify_buffer(buf, start_idx, 0);
        return -1;
    }

    compactify_buffer(buf, start_idx, internal_buf_bytes_to_recs(compressed_len));
    fill_compression_remainder_with_pattern(buf, compressed_len);

    return compressed_len;
}
Ejemplo n.º 3
0
static int trace_dumper_write(struct trace_dumper_configuration_s *conf, struct trace_record_file *record_file, const struct iovec *iov, int iovcnt)
{
    int expected_bytes = total_iovec_len(iov, iovcnt);
    int rc = 0;
    if (conf->record_file.fd >= 0) {
        rc = writev(record_file->fd, iov, iovcnt);
        if (rc != expected_bytes) {
            return -1;
        }
        record_file->records_written += expected_bytes / sizeof(struct trace_record);
    }

    if (conf->online) {
        int parser_rc = dump_iovector_to_parser(conf, &conf->parser, iov, iovcnt);
        if (parser_rc != 0) {
            return -1;
        }
    }

    return expected_bytes;
}