Exemple #1
0
static int
test_block_manager ()
{
    SeafBlockManager *mgr = seaf->block_mgr;
    char *block_id = "c882e263e9d02c63ca6b61c68508761cbc74c358";
    char wr_buf[1024], rd_buf[1024];
    BlockHandle *handle;
    BlockMetadata *md;
    int n;

    printf ("\n=== Test block manager\n\n");

    memset (wr_buf, 1, sizeof(wr_buf));

    handle = seaf_block_manager_open_block (mgr, block_id, BLOCK_WRITE);
    g_assert (handle != NULL);

    n = seaf_block_manager_write_block (mgr, handle, wr_buf, sizeof(wr_buf));
    g_assert (n == sizeof(wr_buf));

    md = seaf_block_manager_stat_block_by_handle (mgr, handle);
    g_assert (md->size == sizeof(wr_buf));
    g_free (md);

    g_assert (seaf_block_manager_close_block(mgr, handle) == 0);
    g_assert (seaf_block_manager_commit_block(mgr, handle) == 0);

    seaf_block_manager_block_handle_free (mgr, handle);

    handle = seaf_block_manager_open_block (mgr, block_id, BLOCK_READ);
    g_assert (handle != NULL);

    n = seaf_block_manager_read_block (mgr, handle, rd_buf, sizeof(rd_buf));
    g_assert (n == sizeof(rd_buf));

    md = seaf_block_manager_stat_block_by_handle (mgr, handle);
    g_assert (md->size == sizeof(wr_buf));
    g_free (md);

    g_assert (seaf_block_manager_close_block(mgr, handle) == 0);
    seaf_block_manager_block_handle_free (mgr, handle);


    g_assert (memcmp (wr_buf, rd_buf, sizeof(wr_buf)) == 0);

    md = seaf_block_manager_stat_block (mgr, block_id);

    g_assert (strcmp (md->id, block_id) == 0);
    g_assert (md->size == sizeof(wr_buf));

    g_free (md);
    return 0;
}
static int
save_block_content_cb (char *content, int clen, int end, void *cbarg)
{
    BlockTxClient *client = cbarg;
    TransferTask *task = client->info->task;
    int n;

    n = seaf_block_manager_write_block (seaf->block_mgr, client->block,
                                        content, clen);
    if (n < 0) {
        seaf_warning ("Failed to write block %s.\n", client->curr_block_id);
        client->info->result = BLOCK_CLIENT_FAILED;
        return -1;
    }

    /* Update global transferred bytes. */
    g_atomic_int_add (&(task->tx_bytes), clen);
    g_atomic_int_add (&(seaf->sync_mgr->recv_bytes), clen);

    while (1) {
        gint recv_bytes = g_atomic_int_get (&(seaf->sync_mgr->recv_bytes));
        if (seaf->sync_mgr->download_limit > 0 &&
            recv_bytes > seaf->sync_mgr->download_limit) {
            G_USLEEP (100000);
        } else {
            break;
        }
    }

    if (end) {
        seaf_block_manager_close_block (seaf->block_mgr, client->block);

        if (seaf_block_manager_commit_block (seaf->block_mgr, client->block) < 0) {
            seaf_warning ("Failed to commit block %s.\n", client->curr_block_id);
            client->info->result = BLOCK_CLIENT_FAILED;
            return -1;
        }

        seaf_block_manager_block_handle_free (seaf->block_mgr, client->block);
        /* Set this handle to invalid. */
        client->block = NULL;

        seaf_debug ("Get block %s succeeded.\n", client->curr_block_id);

        if (transfer_next_block (client) < 0)
            return -1;
    }

    return 0;
}
Exemple #3
0
gboolean
seaf_block_manager_verify_block (SeafBlockManager *mgr,
                                 const char *store_id,
                                 int version,
                                 const char *block_id,
                                 gboolean *io_error)
{
    BlockHandle *h;
    char buf[10240];
    int n;
    SHA_CTX ctx;
    guint8 sha1[20];
    char check_id[41];

    h = seaf_block_manager_open_block (mgr,
                                       store_id, version,
                                       block_id, BLOCK_READ);
    if (!h) {
        seaf_warning ("Failed to open block %.8s.\n", block_id);
        *io_error = TRUE;
        return FALSE;
    }

    SHA1_Init (&ctx);
    while (1) {
        n = seaf_block_manager_read_block (mgr, h, buf, sizeof(buf));
        if (n < 0) {
            seaf_warning ("Failed to read block %.8s.\n", block_id);
            *io_error = TRUE;
            return FALSE;
        }
        if (n == 0)
            break;

        SHA1_Update (&ctx, buf, n);
    }

    seaf_block_manager_close_block (mgr, h);
    seaf_block_manager_block_handle_free (mgr, h);

    SHA1_Final (sha1, &ctx);
    rawdata_to_hex (sha1, check_id, 20);

    if (strcmp (check_id, block_id) == 0)
        return TRUE;
    else
        return FALSE;
}
static void
shutdown_client (BlockTxClient *client)
{
    if (client->block) {
        seaf_block_manager_close_block (seaf->block_mgr, client->block);
        seaf_block_manager_block_handle_free (seaf->block_mgr, client->block);
        client->block = NULL;
    }

    if (client->parser.enc_init)
        EVP_CIPHER_CTX_cleanup (&client->parser.ctx);

    evbuffer_free (client->recv_buf);
    evutil_closesocket (client->data_fd);

    client->recv_state = RECV_STATE_DONE;
}
Exemple #5
0
static gboolean
write_nonenc_block_to_file (const char *repo_id,
                            int version,
                            const char *block_id,
                            int fd,
                            const char *path)
{
    BlockHandle *handle;
    char buf[64 * 1024];
    gboolean ret = TRUE;
    int n;

    handle = seaf_block_manager_open_block (seaf->block_mgr,
                                            repo_id, version,
                                            block_id, BLOCK_READ);
    if (!handle) {
        return FALSE;
    }

    while (1) {
        n = seaf_block_manager_read_block (seaf->block_mgr, handle, buf, sizeof(buf));
        if (n < 0) {
            seaf_warning ("Failed to read block %s.\n", block_id);
            ret = FALSE;
            break;
        } else if (n == 0) {
            break;
        }

        if (writen (fd, buf, n) != n) {
            seaf_warning ("Failed to write block %s to file %s.\n",
                          block_id, path);
            ret = FALSE;
            break;
        }
    }

    seaf_block_manager_close_block (seaf->block_mgr, handle);
    seaf_block_manager_block_handle_free (seaf->block_mgr, handle);

    return ret;
}
Exemple #6
0
static int
save_block_content_cb (char *content, int clen, int end, void *cbarg)
{
    BlockTxServer *server = cbarg;
    int n;

    n = seaf_block_manager_write_block (seaf->block_mgr, server->block,
                                        content, clen);
    if (n < 0) {
        seaf_warning ("Failed to write block %s.\n", server->curr_block_id);
        send_block_response_header (server, STATUS_INTERNAL_SERVER_ERROR);
        return -1;
    }

    if (end) {
        if (seaf_block_manager_close_block (seaf->block_mgr, server->block) < 0) {
            seaf_warning ("Failed to close block %s.\n", server->curr_block_id);
            send_block_response_header (server, STATUS_INTERNAL_SERVER_ERROR);
            return -1;
        }

        if (seaf_block_manager_commit_block (seaf->block_mgr, server->block) < 0) {
            seaf_warning ("Failed to commit block %s.\n", server->curr_block_id);
            send_block_response_header (server, STATUS_INTERNAL_SERVER_ERROR);
            return -1;
        }

        seaf_block_manager_block_handle_free (seaf->block_mgr, server->block);
        /* Set this handle to invalid. */
        server->block = NULL;

        send_block_response_header (server, STATUS_OK);

        seaf_debug ("Receive block %s done.\n", server->curr_block_id);
        seaf_debug ("recv_state set to HEADER.\n");

        server->recv_state = RECV_STATE_HEADER;
    }

    return 0;
}
Exemple #7
0
static void *
block_tx_server_thread (void *vdata)
{
    BlockTxServer *server = vdata;

    server->recv_buf = evbuffer_new ();

    server_thread_loop (server);

    if (server->block) {
        seaf_block_manager_close_block (seaf->block_mgr, server->block);
        seaf_block_manager_block_handle_free (seaf->block_mgr, server->block);
    }

    if (server->parser.enc_init)
        EVP_CIPHER_CTX_cleanup (&server->parser.ctx);

    evbuffer_free (server->recv_buf);
    evutil_closesocket (server->data_fd);

    return vdata;
}
Exemple #8
0
static int
send_block_content (BlockTxServer *server, int block_size)
{
    BlockHandle *handle = NULL;
    int ret = 0;

    handle = seaf_block_manager_open_block (seaf->block_mgr,
                                            server->store_id,
                                            server->repo_version,
                                            server->curr_block_id,
                                            BLOCK_READ);
    if (!handle) {
        seaf_warning ("Failed to open block %s.\n", server->curr_block_id);
        return -1;
    }

    ret = send_encrypted_block (server, handle, server->curr_block_id, block_size);

    seaf_block_manager_close_block (seaf->block_mgr, handle);
    seaf_block_manager_block_handle_free (seaf->block_mgr, handle);
    return ret;
}
static int
send_block_content (BlockTxClient *client)
{
    TransferTask *task = client->info->task;
    BlockHandle *handle = NULL;
    int ret = 0;

    handle = seaf_block_manager_open_block (seaf->block_mgr,
                                            task->repo_id,
                                            task->repo_version,
                                            client->curr_block_id,
                                            BLOCK_READ);
    if (!handle) {
        seaf_warning ("Failed to open block %s.\n", client->curr_block_id);
        client->info->result = BLOCK_CLIENT_FAILED;
        return -1;
    }

    ret = send_encrypted_block (client, handle, client->curr_block_id);

    seaf_block_manager_close_block (seaf->block_mgr, handle);
    seaf_block_manager_block_handle_free (seaf->block_mgr, handle);
    return ret;
}
Exemple #10
0
int read_file(SeafileSession *seaf, Seafile *file, char *buf, size_t size,
              off_t offset, struct fuse_file_info *info)
{
    BlockHandle *handle = NULL;;
    BlockMetadata *bmd;
    char *blkid;
    char *ptr;
    off_t off = 0, nleft;
    int i, n, ret = -EIO;

    for (i = 0; i < file->n_blocks; i++) {
        blkid = file->blk_sha1s[i];

        bmd = seaf_block_manager_stat_block(seaf->block_mgr, blkid);
        if (!bmd)
            return -EIO;

        if (offset < off + bmd->size) {
            g_free (bmd);
            break;
        }

        off += bmd->size;
        g_free (bmd);
    }

    /* beyond the file size */
    if (i == file->n_blocks)
        return 0;

    nleft = size;
    ptr = buf;
    while (nleft > 0 && i < file->n_blocks) {
        blkid = file->blk_sha1s[i];

        handle = seaf_block_manager_open_block(seaf->block_mgr, blkid, BLOCK_READ);
        if (!handle) {
            seaf_warning ("Failed to open block %s.\n", blkid);
            return -EIO;
        }

        /* trim the offset in a block */
        if (offset > off) {
            char *tmp = (char *)malloc(sizeof(char) * (offset - off));
            if (!tmp)
                return -ENOMEM;

            n = seaf_block_manager_read_block(seaf->block_mgr, handle,
                                              tmp, offset-off);
            if (n != offset - off) {
                seaf_warning ("Failed to read block %s.\n", blkid);
                free (tmp);
                goto out;
            }

            off += n;
            free(tmp);
        }

        if ((n = seaf_block_manager_read_block(seaf->block_mgr,
                                               handle, ptr, nleft)) < 0) {
            seaf_warning ("Failed to read block %s.\n", blkid);
            goto out;
        }

        nleft -= n;
        ptr += n;
        off += n;
        ++i;

        /* At this point we should have read all the content of the block or
         * have read up to @size bytes. So it's safe to close the block.
         */
        seaf_block_manager_close_block(seaf->block_mgr, handle);
        seaf_block_manager_block_handle_free (seaf->block_mgr, handle);
    }

    return size - nleft;

out:
    if (handle) {
        seaf_block_manager_close_block(seaf->block_mgr, handle);
        seaf_block_manager_block_handle_free (seaf->block_mgr, handle);
    }
    return ret;
}