Check all SQL results during DM storage release

This commit is contained in:
evgeny committed 2026-10-26 17:54:45 +01:00
1 parent 5788d2557b
commit 59e694bd83
2 files changed
+22 -17

No files matched your search

+21 -16
View File
@@ -114,23 +114,28 @@ static void dm_job_receipt(struct dm_mb_media* media, uint64_t group, uint64_t s
static int dm_job_release(struct dm_mb_media* media, const uint8_t id[16], uint64_t holder, int expired) {
struct UTUN_INSTANCE* inst = media->inst;
if (dm_media_exec(inst, "BEGIN IMMEDIATE")) return -1;
sqlite3_stmt* st = dm_media_prepare(inst, "UPDATE dm_media_holders SET released=1 WHERE id=? AND node_id=? AND released=0");
if (!st) goto rollback;
sqlite3_bind_blob(st, 1, id, 16, SQLITE_STATIC); sqlite3_bind_int64(st, 2, (sqlite3_int64)holder);
if (dm_media_step(inst, st)) goto rollback;
int released = sqlite3_changes(inst->topo_sqlite_db);
const char* sql = expired ?
const char* sql[] = { "UPDATE dm_media_holders SET released=1 WHERE id=? AND node_id=? AND released=0", expired ?
"UPDATE dm_media_jobs SET holder=0,stored=0,expired=1,retry_at=0 WHERE id=? AND holder=? AND receipt IS NULL" :
"UPDATE dm_media_jobs SET holder=0,stored=0,retry_at=0 WHERE id=? AND holder=? AND receipt IS NULL";
st = dm_media_prepare(inst, sql);
if (!st) goto rollback;
sqlite3_bind_blob(st, 1, id, 16, SQLITE_STATIC); sqlite3_bind_int64(st, 2, (sqlite3_int64)holder);
if (dm_media_step(inst, st)) goto rollback;
int reset = sqlite3_changes(inst->topo_sqlite_db);
"UPDATE dm_media_jobs SET holder=0,stored=0,retry_at=0 WHERE id=? AND holder=? AND receipt IS NULL" };
int changed[2];
for (int i = 0; i < 2; i++) {
sqlite3_stmt* st = dm_media_prepare(inst, sql[i]);
if (!st) goto rollback;
int rc = sqlite3_bind_blob(st, 1, id, 16, SQLITE_STATIC);
if (rc == SQLITE_OK) rc = sqlite3_bind_int64(st, 2, (sqlite3_int64)holder);
if (rc == SQLITE_OK) rc = sqlite3_step(st);
int final = sqlite3_finalize(st);
if (rc != SQLITE_DONE || final != SQLITE_OK) {
DEBUG_ERROR(DEBUG_CATEGORY_DM, "dm_mailbox_media: release SQL failed M=%llu rc=%d finalize=%d error=%s statement=%s",
(unsigned long long)holder, rc, final, sqlite3_errmsg(inst->topo_sqlite_db), sql[i]);
goto rollback;
}
changed[i] = sqlite3_changes(inst->topo_sqlite_db);
}
if (dm_media_exec(inst, "COMMIT")) goto rollback;
if (released || reset) DEBUG_INFO(DEBUG_CATEGORY_DM,
if (changed[0] || changed[1]) DEBUG_INFO(DEBUG_CATEGORY_DM,
"dm_mailbox_media: storage released M=%llu reason=%s released=%d reset=%d",
(unsigned long long)holder, expired ? "expired" : "rejected", released, reset);
(unsigned long long)holder, expired ? "expired" : "rejected", changed[0], changed[1]);
return 0;
rollback:
DEBUG_WARN(DEBUG_CATEGORY_DM, "dm_mailbox_media: storage release rolled back M=%llu reason=%s; retry retained",
@@ -210,7 +215,7 @@ static uint64_t dm_job_storage(struct dm_mb_media* media, uint64_t group, const
return found;
}
/* Удаление каждого когда-либо выданного назначения повторяется до signed DELETE_ACK. */
/* Удаление неосвобождённых назначений повторяется до DELETE_ACK; истёкшие завершаются по TTL. */
static void dm_job_cleanup(struct dm_mb_media* media, const uint8_t id[16], const uint8_t* receipt) {
struct UTUN_INSTANCE* inst = media->inst;
sqlite3_stmt* st = dm_media_prepare(inst, "SELECT node_id,group_id FROM dm_media_holders WHERE id=? AND released=0 LIMIT 16");
@@ -230,7 +235,7 @@ static void dm_job_cleanup(struct dm_mb_media* media, const uint8_t id[16], cons
if (!st) return;
sqlite3_bind_blob(st, 1, id, 16, SQLITE_STATIC);
if (!dm_media_step(inst, st) && sqlite3_changes(inst->topo_sqlite_db))
DEBUG_INFO(DEBUG_CATEGORY_DM, "dm_mailbox_media: all custody copies deleted; message body removed");
DEBUG_INFO(DEBUG_CATEGORY_DM, "dm_mailbox_media: all storage assignments released; message body removed");
}
}
+1 -1
View File
@@ -1,5 +1,5 @@
/* dm_mailbox_media — durable задания суперузла: размещение на M, доставка
* метаданных получателю и удаление всех выданных копий до DELETE_ACK.
* метаданных получателю и освобождение назначений по DELETE_ACK/EXPIRED либо подтверждённому TTL.
* Жизненный цикл принадлежит dm_mailbox, control принимает dm_media. Все API в uasync.
* Координатор хранится в dm_media_jobs/dm_media_holders SQLite ядра; таймер — только триггер повторов.
*/