Example #1
0
static int tar_export_process(TarExport *e) {
    ssize_t l;
    int r;

    assert(e);

    if (!e->tried_splice && e->compress.type == IMPORT_COMPRESS_UNCOMPRESSED) {

        l = splice(e->tar_fd, NULL, e->output_fd, NULL, COPY_BUFFER_SIZE, 0);
        if (l < 0) {
            if (errno == EAGAIN)
                return 0;

            e->tried_splice = true;
        } else if (l == 0) {
            r = 0;
            goto finish;
        } else {
            e->written_uncompressed += l;
            e->written_compressed += l;

            tar_export_report_progress(e);

            return 0;
        }
    }

    while (e->buffer_size <= 0) {
        uint8_t input[COPY_BUFFER_SIZE];

        if (e->eof) {
            r = 0;
            goto finish;
        }

        l = read(e->tar_fd, input, sizeof(input));
        if (l < 0) {
            r = log_error_errno(errno, "Failed to read tar file: %m");
            goto finish;
        }

        if (l == 0) {
            e->eof = true;
            r = import_compress_finish(&e->compress, &e->buffer, &e->buffer_size, &e->buffer_allocated);
        } else {
            e->written_uncompressed += l;
            r = import_compress(&e->compress, input, l, &e->buffer, &e->buffer_size, &e->buffer_allocated);
        }
        if (r < 0) {
            r = log_error_errno(r, "Failed to encode: %m");
            goto finish;
        }
    }

    l = write(e->output_fd, e->buffer, e->buffer_size);
    if (l < 0) {
        if (errno == EAGAIN)
            return 0;

        r = log_error_errno(errno, "Failed to write output file: %m");
        goto finish;
    }

    assert((size_t) l <= e->buffer_size);
    memmove(e->buffer, (uint8_t*) e->buffer + l, e->buffer_size - l);
    e->buffer_size -= l;
    e->written_compressed += l;

    tar_export_report_progress(e);

    return 0;

finish:
    if (e->on_finished)
        e->on_finished(e, r, e->userdata);
    else
        sd_event_exit(e->event, r);

    return 0;
}
Example #2
0
static int raw_export_process(RawExport *e) {
        ssize_t l;
        int r;

        assert(e);

        if (!e->tried_reflink && e->compress.type == IMPORT_COMPRESS_UNCOMPRESSED) {

                /* If we shall take an uncompressed snapshot we can
                 * reflink source to destination directly. Let's see
                 * if this works. */

                r = btrfs_reflink(e->input_fd, e->output_fd);
                if (r >= 0) {
                        r = 0;
                        goto finish;
                }

                e->tried_reflink = true;
        }

        if (!e->tried_sendfile && e->compress.type == IMPORT_COMPRESS_UNCOMPRESSED) {

                l = sendfile(e->output_fd, e->input_fd, NULL, COPY_BUFFER_SIZE);
                if (l < 0) {
                        if (errno == EAGAIN)
                                return 0;

                        e->tried_sendfile = true;
                } else if (l == 0) {
                        r = 0;
                        goto finish;
                } else {
                        e->written_uncompressed += l;
                        e->written_compressed += l;

                        raw_export_report_progress(e);

                        return 0;
                }
        }

        while (e->buffer_size <= 0) {
                uint8_t input[COPY_BUFFER_SIZE];

                if (e->eof) {
                        r = 0;
                        goto finish;
                }

                l = read(e->input_fd, input, sizeof(input));
                if (l < 0) {
                        r = log_error_errno(errno, "Failed to read raw file: %m");
                        goto finish;
                }

                if (l == 0) {
                        e->eof = true;
                        r = import_compress_finish(&e->compress, &e->buffer, &e->buffer_size, &e->buffer_allocated);
                } else {
                        e->written_uncompressed += l;
                        r = import_compress(&e->compress, input, l, &e->buffer, &e->buffer_size, &e->buffer_allocated);
                }
                if (r < 0) {
                        r = log_error_errno(r, "Failed to encode: %m");
                        goto finish;
                }
        }

        l = write(e->output_fd, e->buffer, e->buffer_size);
        if (l < 0) {
                if (errno == EAGAIN)
                        return 0;

                r = log_error_errno(errno, "Failed to write output file: %m");
                goto finish;
        }

        assert((size_t) l <= e->buffer_size);
        memmove(e->buffer, (uint8_t*) e->buffer + l, e->buffer_size - l);
        e->buffer_size -= l;
        e->written_compressed += l;

        raw_export_report_progress(e);

        return 0;

finish:
        if (r >= 0) {
                (void) copy_times(e->input_fd, e->output_fd);
                (void) copy_xattr(e->input_fd, e->output_fd);
        }

        if (e->on_finished)
                e->on_finished(e, r, e->userdata);
        else
                sd_event_exit(e->event, r);

        return 0;
}