Verify second-block SQL failure and propagate local download errors
This commit is contained in:
1 parent
fd6155aa4a
commit
6a14be05f5
2 files changed
+23
-8
No files matched your search
@@ -230,8 +230,8 @@ static int md_dl_pump(struct media_download* dl) {
|
||||
if (dl->err) return -1;
|
||||
for (int bi = 0; bi < dl->num_blocks; bi++) {
|
||||
struct media_download_block* b = &dl->blocks[bi];
|
||||
if ((b->state == MD_BLK_IDLE || b->state == MD_BLK_WAIT)
|
||||
&& md_dl_request_block(dl, bi) < 0 && md_dl_failover_block(dl, bi, get_time_tb()) < 0) return -1;
|
||||
if (b->state != MD_BLK_IDLE && b->state != MD_BLK_WAIT) continue;
|
||||
if (md_dl_request_block(dl, bi) < 0 && (dl->err || md_dl_failover_block(dl, bi, get_time_tb()) < 0)) return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -243,10 +243,15 @@ int md_dl_failover_block(struct media_download* dl, int bi, uint64_t now_tb) {
|
||||
if (md_dl_block_inflight(b) && dl->inflight > 0) dl->inflight--;
|
||||
b->state = MD_BLK_IDLE; b->bytes_received = 0; b->last_progress_tb = now_tb; b->retry_at_tb = 0;
|
||||
do {
|
||||
if (dl->err) return -1;
|
||||
b->attempts++;
|
||||
DEBUG_WARN(DEBUG_CATEGORY_MEDIA, "%s: failover block=%d attempts=%d/%d holder=%d/%d",
|
||||
MDL_ID, bi, b->attempts, md_dl_max_attempts(dl->inst), b->holder_idx, b->num_holders);
|
||||
if (b->attempts >= md_dl_max_attempts(dl->inst)) { b->state = MD_BLK_FAILED; return -1; }
|
||||
if (b->attempts >= md_dl_max_attempts(dl->inst)) {
|
||||
b->state = MD_BLK_FAILED;
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_MEDIA, "%s: block attempts exhausted block=%d attempts=%d", MDL_ID, bi, b->attempts);
|
||||
return -1;
|
||||
}
|
||||
if (++b->holder_idx >= b->num_holders) {
|
||||
b->num_holders = 0; b->holder_idx = -1; b->state = MD_BLK_WAIT; b->wait_reason = MD_WAIT_SEARCH;
|
||||
return 0;
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include "../src/media_delivery/media_index.h"
|
||||
#include "../src/media_delivery/media_download.h"
|
||||
#include "../src/routing_layer/etcp_router.h"
|
||||
#include "../src/transport_layer/etcp.h"
|
||||
#include "../lib/debug_config.h"
|
||||
#include "../lib/mem.h"
|
||||
#include "../lib/platform_compat.h"
|
||||
@@ -53,7 +54,7 @@ int __wrap_etcp_route_send(struct UTUN_INSTANCE* inst, uint64_t group, uint64_t
|
||||
}
|
||||
|
||||
/* u_malloc округляет выделение: ASAN защищает именно логическую границу входного payload. */
|
||||
static void release_injected(void* data) {
|
||||
static void release_injected(uint8_t* data) {
|
||||
#ifdef __SANITIZE_ADDRESS__
|
||||
if (data == injected) __asan_unpoison_memory_region(poison_tail, 64);
|
||||
#endif
|
||||
@@ -263,22 +264,31 @@ static void test_peer_reuse_and_completion(void) {
|
||||
puts("65 blocks from 13 holders, peer slot reuse, file contents and registration: PASS");
|
||||
}
|
||||
|
||||
static int denied_reads;
|
||||
static int denied_reads, started_selects;
|
||||
static int trace_query(unsigned event, void* arg, void* statement, void* sql) {
|
||||
(void)arg; (void)sql;
|
||||
if (event == SQLITE_TRACE_STMT && !strncmp(sqlite3_sql(statement), "SELECT node_id FROM (", 21)) started_selects++;
|
||||
return 0;
|
||||
}
|
||||
static int deny_second_block(void* arg, int action, const char* table, const char* column, const char* db, const char* trigger) {
|
||||
(void)arg; (void)db; (void)trigger;
|
||||
if (action == SQLITE_READ && table && column && !strcmp(table, "block_availability") && !strcmp(column, "block_uuid"))
|
||||
if (++denied_reads == 2) return SQLITE_DENY;
|
||||
if (started_selects) { denied_reads++; return SQLITE_DENY; }
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
static void test_failures_and_restart(void) {
|
||||
reset(); struct UTUN_INSTANCE* s = instance(SERVER); struct UTUN_INSTANCE* c = instance(CLIENT);
|
||||
struct media_index_result r = result(2); seed(s, &r, 2, 2, 0); start(c, &r);
|
||||
denied_reads = 0; sqlite3_set_authorizer(s->topo_sqlite_db, deny_second_block, NULL);
|
||||
denied_reads = started_selects = 0;
|
||||
sqlite3_trace_v2(s->topo_sqlite_db, SQLITE_TRACE_STMT, trace_query, NULL);
|
||||
sqlite3_set_authorizer(s->topo_sqlite_db, deny_second_block, NULL);
|
||||
struct packet error = answer(s);
|
||||
struct media_pkt_query_resp* header = (struct media_pkt_query_resp*)error.data;
|
||||
REQUIRE(denied_reads == 2 && header->status == MEDIA_QUERY_DB_ERROR && !header->num_blocks && error.len == MEDIA_QUERY_RESP_HDR_SIZE);
|
||||
REQUIRE(denied_reads == 1 && started_selects == 1 && header->status == MEDIA_QUERY_DB_ERROR
|
||||
&& !header->num_blocks && error.len == MEDIA_QUERY_RESP_HDR_SIZE);
|
||||
sqlite3_set_authorizer(s->topo_sqlite_db, NULL, NULL);
|
||||
sqlite3_trace_v2(s->topo_sqlite_db, 0, NULL, NULL);
|
||||
struct media_download* dl = download(c);
|
||||
REQUIRE(!media_download_cancel(c, dl->media_id, NULL, 0) && done_count == 1);
|
||||
start(c, &r); dl = download(c); struct media_download snapshot = *dl;
|
||||
|
||||
Reference in new issue
Block a user