Beispiel #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
send_encrypted_block (BlockTxClient *client,
                      BlockHandle *handle,
                      const char *block_id)
{
    BlockTxInfo *info = client->info;
    BlockMetadata *md;
    int size, n, remain;
    int ret = 0;
    EVP_CIPHER_CTX ctx;
    char send_buf[SEND_BUFFER_SIZE];

    md = seaf_block_manager_stat_block_by_handle (seaf->block_mgr, handle);
    if (!md) {
        seaf_warning ("Failed to stat block %s.\n", block_id);
        client->info->result = BLOCK_CLIENT_FAILED;
        ret = -1;
        goto out;
    }
    size = md->size;
    g_free (md);

    if (client->version == 1)
        blocktx_encrypt_init (&ctx, client->key, client->iv);
    else if (client->version == 2)
        blocktx_encrypt_init (&ctx, client->key_v2, client->iv_v2);

    if (send_encrypted_data_frame_begin (client->data_fd, size) < 0) {
        seaf_warning ("Send block %s: failed to begin.\n", block_id);
        info->result = BLOCK_CLIENT_NET_ERROR;
        ret = -1;
        goto out;
    }

    remain = size;
    while (remain > 0) {
        if (info->task->state == TASK_STATE_CANCELED) {
            info->result = BLOCK_CLIENT_CANCELED;
            ret = -1;
            goto out;
        }

        n = seaf_block_manager_read_block (seaf->block_mgr,
                                           handle,
                                           send_buf, SEND_BUFFER_SIZE);
        if (n < 0) {
            seaf_warning ("Failed to read block %s.\n", block_id);
            info->result = BLOCK_CLIENT_FAILED;
            ret = -1;
            goto out;
        }

        if (send_encrypted_data (&ctx, client->data_fd, send_buf, n) < 0) {
            seaf_warning ("Send block %s: failed to send data.\n", block_id);
            info->result = BLOCK_CLIENT_NET_ERROR;
            ret = -1;
            goto out;
        }

        /* Update global transferred bytes. */
        g_atomic_int_add (&(info->task->tx_bytes), n);
        g_atomic_int_add (&(seaf->sync_mgr->sent_bytes), n);

        /* If uploaded bytes exceeds the limit, wait until the counter
         * is reset. We check the counter every 100 milliseconds, so we
         * can waste up to 100 milliseconds without sending data after
         * the counter is reset.
         */
        while (1) {
            gint sent = g_atomic_int_get(&(seaf->sync_mgr->sent_bytes));
            if (seaf->sync_mgr->upload_limit > 0 &&
                sent > seaf->sync_mgr->upload_limit)
                /* 100 milliseconds */
                G_USLEEP (100000);
            else
                break;
        }

        remain -= n;
    }

    if (send_encrypted_data_frame_end (&ctx, client->data_fd) < 0) {
        seaf_warning ("Send block %s: failed to end.\n", block_id);
        info->result = BLOCK_CLIENT_NET_ERROR;
        ret = -1;
        goto out;
    }

out:
    EVP_CIPHER_CTX_cleanup (&ctx);
    return ret;
}